1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /* Copyright 2010 QLogic Corporation */
23
24 /*
25 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
26 */
27 /*
28 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
29 * Copyright (c) 2016 by Delphix. All rights reserved.
30 */
31
32 #pragma ident "Copyright 2010 QLogic Corporation; ql_api.c"
33
34 /*
35 * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
36 *
37 * ***********************************************************************
38 * * **
39 * * NOTICE **
40 * * COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION **
41 * * ALL RIGHTS RESERVED **
42 * * **
43 * ***********************************************************************
44 *
45 */
46
47 #include <ql_apps.h>
48 #include <ql_api.h>
49 #include <ql_debug.h>
50 #include <ql_init.h>
51 #include <ql_iocb.h>
52 #include <ql_ioctl.h>
53 #include <ql_isr.h>
54 #include <ql_mbx.h>
55 #include <ql_nx.h>
56 #include <ql_xioctl.h>
57
58 /*
59 * Solaris external defines.
60 */
61 extern pri_t minclsyspri;
62 extern pri_t maxclsyspri;
63
64 /*
65 * dev_ops functions prototypes
66 */
67 static int ql_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
68 static int ql_attach(dev_info_t *, ddi_attach_cmd_t);
69 static int ql_detach(dev_info_t *, ddi_detach_cmd_t);
70 static int ql_power(dev_info_t *, int, int);
71 static int ql_quiesce(dev_info_t *);
72
73 /*
74 * FCA functions prototypes exported by means of the transport table
75 */
76 static opaque_t ql_bind_port(dev_info_t *, fc_fca_port_info_t *,
77 fc_fca_bind_info_t *);
78 static void ql_unbind_port(opaque_t);
79 static int ql_init_pkt(opaque_t, fc_packet_t *, int);
80 static int ql_un_init_pkt(opaque_t, fc_packet_t *);
81 static int ql_els_send(opaque_t, fc_packet_t *);
82 static int ql_get_cap(opaque_t, char *, void *);
83 static int ql_set_cap(opaque_t, char *, void *);
84 static int ql_getmap(opaque_t, fc_lilpmap_t *);
85 static int ql_transport(opaque_t, fc_packet_t *);
86 static int ql_ub_alloc(opaque_t, uint64_t *, uint32_t, uint32_t *, uint32_t);
87 static int ql_ub_free(opaque_t, uint32_t, uint64_t *);
88 static int ql_ub_release(opaque_t, uint32_t, uint64_t *);
89 static int ql_abort(opaque_t, fc_packet_t *, int);
90 static int ql_reset(opaque_t, uint32_t);
91 static int ql_port_manage(opaque_t, fc_fca_pm_t *);
92 static opaque_t ql_get_device(opaque_t, fc_portid_t);
93
94 /*
95 * FCA Driver Support Function Prototypes.
96 */
97 static uint16_t ql_wait_outstanding(ql_adapter_state_t *);
98 static void ql_task_mgmt(ql_adapter_state_t *, ql_tgt_t *, fc_packet_t *,
99 ql_srb_t *);
100 static void ql_task_daemon(void *);
101 static void ql_task_thread(ql_adapter_state_t *);
102 static void ql_unsol_callback(ql_srb_t *);
103 static void ql_free_unsolicited_buffer(ql_adapter_state_t *,
104 fc_unsol_buf_t *);
105 static void ql_timer(void *);
106 static void ql_watchdog(ql_adapter_state_t *, uint32_t *, uint32_t *);
107 static void ql_cmd_timeout(ql_adapter_state_t *, ql_tgt_t *q, ql_srb_t *,
108 uint32_t *, uint32_t *);
109 static void ql_halt(ql_adapter_state_t *, int);
110 static int ql_els_plogi(ql_adapter_state_t *, fc_packet_t *);
111 static int ql_els_flogi(ql_adapter_state_t *, fc_packet_t *);
112 static int ql_els_logo(ql_adapter_state_t *, fc_packet_t *);
113 static int ql_els_prli(ql_adapter_state_t *, fc_packet_t *);
114 static int ql_els_prlo(ql_adapter_state_t *, fc_packet_t *);
115 static int ql_els_adisc(ql_adapter_state_t *, fc_packet_t *);
116 static int ql_els_linit(ql_adapter_state_t *, fc_packet_t *);
117 static int ql_els_lpc(ql_adapter_state_t *, fc_packet_t *);
118 static int ql_els_lsts(ql_adapter_state_t *, fc_packet_t *);
119 static int ql_els_scr(ql_adapter_state_t *, fc_packet_t *);
120 static int ql_els_rscn(ql_adapter_state_t *, fc_packet_t *);
121 static int ql_els_farp_req(ql_adapter_state_t *, fc_packet_t *);
122 static int ql_els_farp_reply(ql_adapter_state_t *, fc_packet_t *);
123 static int ql_els_rls(ql_adapter_state_t *, fc_packet_t *);
124 static int ql_els_rnid(ql_adapter_state_t *, fc_packet_t *);
125 static int ql_login_port(ql_adapter_state_t *, port_id_t);
126 static int ql_login_fabric_port(ql_adapter_state_t *, ql_tgt_t *, uint16_t);
127 static int ql_logout_port(ql_adapter_state_t *, port_id_t);
128 static ql_lun_t *ql_lun_queue(ql_adapter_state_t *, ql_tgt_t *, uint16_t);
129 static int ql_fcp_scsi_cmd(ql_adapter_state_t *, fc_packet_t *, ql_srb_t *);
130 static int ql_fcp_ip_cmd(ql_adapter_state_t *, fc_packet_t *, ql_srb_t *);
131 static int ql_fc_services(ql_adapter_state_t *, fc_packet_t *);
132 static int ql_poll_cmd(ql_adapter_state_t *, ql_srb_t *, time_t);
133 static int ql_start_cmd(ql_adapter_state_t *, ql_tgt_t *, fc_packet_t *,
134 ql_srb_t *);
135 static int ql_kstat_update(kstat_t *, int);
136 static ql_adapter_state_t *ql_fca_handle_to_state(opaque_t);
137 static ql_adapter_state_t *ql_cmd_setup(opaque_t, fc_packet_t *, int *);
138 static int ql_program_flash_address(ql_adapter_state_t *, uint32_t, uint8_t);
139 static void ql_rst_aen(ql_adapter_state_t *);
140 static void ql_restart_queues(ql_adapter_state_t *);
141 static void ql_abort_queues(ql_adapter_state_t *);
142 static void ql_abort_device_queues(ql_adapter_state_t *ha, ql_tgt_t *tq);
143 static void ql_idle_check(ql_adapter_state_t *);
144 static int ql_loop_resync(ql_adapter_state_t *);
145 static size_t ql_24xx_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
146 static size_t ql_2581_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
147 static int ql_save_config_regs(dev_info_t *);
148 static int ql_restore_config_regs(dev_info_t *);
149 static int ql_process_rscn(ql_adapter_state_t *, fc_affected_id_t *);
150 static int ql_handle_rscn_update(ql_adapter_state_t *);
151 static int ql_send_plogi(ql_adapter_state_t *, ql_tgt_t *, ql_head_t *);
152 static int ql_process_rscn_for_device(ql_adapter_state_t *, ql_tgt_t *);
153 static int ql_dump_firmware(ql_adapter_state_t *);
154 static int ql_process_logo_for_device(ql_adapter_state_t *, ql_tgt_t *);
155 static int ql_2200_binary_fw_dump(ql_adapter_state_t *, ql_fw_dump_t *);
156 static int ql_2300_binary_fw_dump(ql_adapter_state_t *, ql_fw_dump_t *);
157 static int ql_24xx_binary_fw_dump(ql_adapter_state_t *, ql_24xx_fw_dump_t *);
158 static int ql_25xx_binary_fw_dump(ql_adapter_state_t *, ql_25xx_fw_dump_t *);
159 static int ql_81xx_binary_fw_dump(ql_adapter_state_t *, ql_81xx_fw_dump_t *);
160 static int ql_read_risc_ram(ql_adapter_state_t *, uint32_t, uint32_t,
161 void *);
162 static void *ql_read_regs(ql_adapter_state_t *, void *, void *, uint32_t,
163 uint8_t);
164 static int ql_busy_plogi(ql_adapter_state_t *, fc_packet_t *, ql_tgt_t *);
165 static int ql_suspend_adapter(ql_adapter_state_t *);
166 static int ql_bstr_to_dec(char *, uint32_t *, uint32_t);
167 static void ql_update_rscn(ql_adapter_state_t *, fc_affected_id_t *);
168 int ql_alloc_dma_resouce(ql_adapter_state_t *, dma_mem_t *, int);
169 static int ql_bind_dma_buffer(ql_adapter_state_t *, dma_mem_t *, int);
170 static void ql_unbind_dma_buffer(ql_adapter_state_t *, dma_mem_t *);
171 static void ql_timeout_insert(ql_adapter_state_t *, ql_tgt_t *, ql_srb_t *);
172 static int ql_setup_interrupts(ql_adapter_state_t *);
173 static int ql_setup_msi(ql_adapter_state_t *);
174 static int ql_setup_msix(ql_adapter_state_t *);
175 static int ql_setup_fixed(ql_adapter_state_t *);
176 static void ql_release_intr(ql_adapter_state_t *);
177 static void ql_disable_intr(ql_adapter_state_t *);
178 static int ql_legacy_intr(ql_adapter_state_t *);
179 static int ql_init_mutex(ql_adapter_state_t *);
180 static void ql_destroy_mutex(ql_adapter_state_t *);
181 static void ql_iidma(ql_adapter_state_t *);
182
183 static int ql_n_port_plogi(ql_adapter_state_t *);
184 static void ql_fca_isp_els_request(ql_adapter_state_t *, fc_packet_t *,
185 els_descriptor_t *);
186 static void ql_isp_els_request_ctor(els_descriptor_t *,
187 els_passthru_entry_t *);
188 static int ql_p2p_plogi(ql_adapter_state_t *, fc_packet_t *);
189 static int ql_wait_for_td_stop(ql_adapter_state_t *);
190 static void ql_process_idc_event(ql_adapter_state_t *);
191
192 /*
193 * Global data
194 */
195 static uint8_t ql_enable_pm = 1;
196 static int ql_flash_sbus_fpga = 0;
197 uint32_t ql_os_release_level;
198 uint32_t ql_disable_aif = 0;
199 uint32_t ql_disable_msi = 0;
200 uint32_t ql_disable_msix = 0;
201 uint32_t ql_enable_ets = 0;
202 uint16_t ql_osc_wait_count = 1000;
203
204 /* Timer routine variables. */
205 static timeout_id_t ql_timer_timeout_id = NULL;
206 static clock_t ql_timer_ticks;
207
208 /* Soft state head pointer. */
209 void *ql_state = NULL;
210
211 /* Head adapter link. */
212 ql_head_t ql_hba = {
213 NULL,
214 NULL
215 };
216
217 /* Global hba index */
218 uint32_t ql_gfru_hba_index = 1;
219
220 /*
221 * Some IP defines and globals
222 */
223 uint32_t ql_ip_buffer_count = 128;
224 uint32_t ql_ip_low_water = 10;
225 uint8_t ql_ip_fast_post_count = 5;
226 static int ql_ip_mtu = 65280; /* equivalent to FCIPMTU */
227
228 /* Device AL_PA to Device Head Queue index array. */
229 uint8_t ql_alpa_to_index[] = {
230 0x7e, 0x7d, 0x7c, 0x00, 0x7b, 0x01, 0x02, 0x03, 0x7a, 0x04,
231 0x05, 0x06, 0x07, 0x08, 0x09, 0x79, 0x78, 0x0a, 0x0b, 0x0c,
232 0x0d, 0x0e, 0x0f, 0x77, 0x76, 0x10, 0x11, 0x75, 0x12, 0x74,
233 0x73, 0x72, 0x13, 0x14, 0x15, 0x71, 0x16, 0x70, 0x6f, 0x6e,
234 0x17, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x18, 0x19, 0x67,
235 0x66, 0x65, 0x64, 0x63, 0x62, 0x20, 0x21, 0x61, 0x60, 0x23,
236 0x5f, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x5e, 0x2a, 0x5d,
237 0x5c, 0x5b, 0x2b, 0x5a, 0x59, 0x58, 0x57, 0x56, 0x55, 0x2c,
238 0x2d, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x2e, 0x2f, 0x4e,
239 0x4d, 0x30, 0x4c, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x4b,
240 0x37, 0x4a, 0x49, 0x48, 0x38, 0x47, 0x46, 0x45, 0x44, 0x43,
241 0x42, 0x39, 0x3a, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b,
242 0x3c, 0x3b, 0x3a, 0x3d, 0x39, 0x3e, 0x3f, 0x40, 0x38, 0x37,
243 0x36, 0x41, 0x35, 0x42, 0x43, 0x44, 0x34, 0x45, 0x46, 0x47,
244 0x48, 0x49, 0x4a, 0x33, 0x32, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
245 0x50, 0x31, 0x30, 0x51, 0x52, 0x2f, 0x53, 0x2e, 0x2d, 0x2c,
246 0x54, 0x55, 0x56, 0x2b, 0x57, 0x2a, 0x29, 0x28, 0x58, 0x27,
247 0x26, 0x25, 0x24, 0x23, 0x22, 0x59, 0x5a, 0x21, 0x20, 0x1f,
248 0x1e, 0x1d, 0x1c, 0x5b, 0x5c, 0x1b, 0x1a, 0x5d, 0x19, 0x5e,
249 0x5f, 0x60, 0x61, 0x62, 0x63, 0x18, 0x64, 0x17, 0x16, 0x15,
250 0x65, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x66, 0x67, 0x0e,
251 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x68, 0x69, 0x08, 0x07, 0x6a,
252 0x06, 0x6b, 0x6c, 0x6d, 0x05, 0x04, 0x03, 0x6e, 0x02, 0x6f,
253 0x70, 0x71, 0x01, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x00,
254 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7f, 0x80, 0x00, 0x01,
255 0x02, 0x03, 0x80, 0x7f, 0x7e, 0x04
256 };
257
258 /* Device loop_id to ALPA array. */
259 static uint8_t ql_index_to_alpa[] = {
260 0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda, 0xd9, 0xd6,
261 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce, 0xcd, 0xcc, 0xcb, 0xca,
262 0xc9, 0xc7, 0xc6, 0xc5, 0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5,
263 0xb4, 0xb3, 0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
264 0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b, 0x98, 0x97,
265 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81, 0x80, 0x7c, 0x7a, 0x79,
266 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b,
267 0x6a, 0x69, 0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
268 0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a,
269 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c, 0x3a, 0x39, 0x36, 0x35,
270 0x34, 0x33, 0x32, 0x31, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29,
271 0x27, 0x26, 0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
272 0x10, 0x0f, 0x08, 0x04, 0x02, 0x01
273 };
274
275 /* 2200 register offsets */
276 static reg_off_t reg_off_2200 = {
277 0x00, /* flash_address */
278 0x02, /* flash_data */
279 0x06, /* ctrl_status */
280 0x08, /* ictrl */
281 0x0a, /* istatus */
282 0x0c, /* semaphore */
283 0x0e, /* nvram */
284 0x18, /* req_in */
285 0x18, /* req_out */
286 0x1a, /* resp_in */
287 0x1a, /* resp_out */
288 0xff, /* risc2host - n/a */
289 24, /* Number of mailboxes */
290
291 /* Mailbox in register offsets 0 - 23 */
292 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
293 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee,
294 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
295 /* 2200 does not have mailbox 24-31 - n/a */
296 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
297
298 /* Mailbox out register offsets 0 - 23 */
299 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
300 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee,
301 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
302 /* 2200 does not have mailbox 24-31 - n/a */
303 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
304
305 0x96, /* fpm_diag_config */
306 0xa4, /* pcr */
307 0xb0, /* mctr */
308 0xb8, /* fb_cmd */
309 0xc0, /* hccr */
310 0xcc, /* gpiod */
311 0xce, /* gpioe */
312 0xff, /* host_to_host_sema - n/a */
313 0xff, /* pri_req_in - n/a */
314 0xff, /* pri_req_out - n/a */
315 0xff, /* atio_req_in - n/a */
316 0xff, /* atio_req_out - n/a */
317 0xff, /* io_base_addr - n/a */
318 0xff, /* nx_host_int - n/a */
319 0xff /* nx_risc_int - n/a */
320 };
321
322 /* 2300 register offsets */
323 static reg_off_t reg_off_2300 = {
324 0x00, /* flash_address */
325 0x02, /* flash_data */
326 0x06, /* ctrl_status */
327 0x08, /* ictrl */
328 0x0a, /* istatus */
329 0x0c, /* semaphore */
330 0x0e, /* nvram */
331 0x10, /* req_in */
332 0x12, /* req_out */
333 0x14, /* resp_in */
334 0x16, /* resp_out */
335 0x18, /* risc2host */
336 32, /* Number of mailboxes */
337
338 /* Mailbox in register offsets 0 - 31 */
339 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e,
340 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
341 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e,
342 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
343
344 /* Mailbox out register offsets 0 - 31 */
345 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e,
346 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
347 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e,
348 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
349
350 0x96, /* fpm_diag_config */
351 0xa4, /* pcr */
352 0xb0, /* mctr */
353 0x80, /* fb_cmd */
354 0xc0, /* hccr */
355 0xcc, /* gpiod */
356 0xce, /* gpioe */
357 0x1c, /* host_to_host_sema */
358 0xff, /* pri_req_in - n/a */
359 0xff, /* pri_req_out - n/a */
360 0xff, /* atio_req_in - n/a */
361 0xff, /* atio_req_out - n/a */
362 0xff, /* io_base_addr - n/a */
363 0xff, /* nx_host_int - n/a */
364 0xff /* nx_risc_int - n/a */
365 };
366
367 /* 2400/2500 register offsets */
368 reg_off_t reg_off_2400_2500 = {
369 0x00, /* flash_address */
370 0x04, /* flash_data */
371 0x08, /* ctrl_status */
372 0x0c, /* ictrl */
373 0x10, /* istatus */
374 0xff, /* semaphore - n/a */
375 0xff, /* nvram - n/a */
376 0x1c, /* req_in */
377 0x20, /* req_out */
378 0x24, /* resp_in */
379 0x28, /* resp_out */
380 0x44, /* risc2host */
381 32, /* Number of mailboxes */
382
383 /* Mailbox in register offsets 0 - 31 */
384 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,
385 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
386 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae,
387 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
388
389 /* Mailbox out register offsets 0 - 31 */
390 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,
391 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
392 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae,
393 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
394
395 0xff, /* fpm_diag_config - n/a */
396 0xff, /* pcr - n/a */
397 0xff, /* mctr - n/a */
398 0xff, /* fb_cmd - n/a */
399 0x48, /* hccr */
400 0x4c, /* gpiod */
401 0x50, /* gpioe */
402 0xff, /* host_to_host_sema - n/a */
403 0x2c, /* pri_req_in */
404 0x30, /* pri_req_out */
405 0x3c, /* atio_req_in */
406 0x40, /* atio_req_out */
407 0x54, /* io_base_addr */
408 0xff, /* nx_host_int - n/a */
409 0xff /* nx_risc_int - n/a */
410 };
411
412 /* P3 register offsets */
413 static reg_off_t reg_off_8021 = {
414 0x00, /* flash_address */
415 0x04, /* flash_data */
416 0x08, /* ctrl_status */
417 0x0c, /* ictrl */
418 0x10, /* istatus */
419 0xff, /* semaphore - n/a */
420 0xff, /* nvram - n/a */
421 0xff, /* req_in - n/a */
422 0x0, /* req_out */
423 0x100, /* resp_in */
424 0x200, /* resp_out */
425 0x500, /* risc2host */
426 32, /* Number of mailboxes */
427
428 /* Mailbox in register offsets 0 - 31 */
429 0x300, 0x302, 0x304, 0x306, 0x308, 0x30a, 0x30c, 0x30e,
430 0x310, 0x312, 0x314, 0x316, 0x318, 0x31a, 0x31c, 0x31e,
431 0x320, 0x322, 0x324, 0x326, 0x328, 0x32a, 0x32c, 0x32e,
432 0x330, 0x332, 0x334, 0x336, 0x338, 0x33a, 0x33c, 0x33e,
433
434 /* Mailbox out register offsets 0 - 31 */
435 0x400, 0x402, 0x404, 0x406, 0x408, 0x40a, 0x40c, 0x40e,
436 0x410, 0x412, 0x414, 0x416, 0x418, 0x41a, 0x41c, 0x41e,
437 0x420, 0x422, 0x424, 0x426, 0x428, 0x42a, 0x42c, 0x42e,
438 0x430, 0x432, 0x434, 0x436, 0x438, 0x43a, 0x43c, 0x43e,
439
440 0xff, /* fpm_diag_config - n/a */
441 0xff, /* pcr - n/a */
442 0xff, /* mctr - n/a */
443 0xff, /* fb_cmd - n/a */
444 0x48, /* hccr */
445 0x4c, /* gpiod */
446 0x50, /* gpioe */
447 0xff, /* host_to_host_sema - n/a */
448 0x2c, /* pri_req_in */
449 0x30, /* pri_req_out */
450 0x3c, /* atio_req_in */
451 0x40, /* atio_req_out */
452 0x54, /* io_base_addr */
453 0x380, /* nx_host_int */
454 0x504 /* nx_risc_int */
455 };
456
457 /* mutex for protecting variables shared by all instances of the driver */
458 kmutex_t ql_global_mutex;
459 kmutex_t ql_global_hw_mutex;
460 kmutex_t ql_global_el_mutex;
461
462 /* DMA access attribute structure. */
463 static ddi_device_acc_attr_t ql_dev_acc_attr = {
464 DDI_DEVICE_ATTR_V0,
465 DDI_STRUCTURE_LE_ACC,
466 DDI_STRICTORDER_ACC
467 };
468
469 /* I/O DMA attributes structures. */
470 static ddi_dma_attr_t ql_64bit_io_dma_attr = {
471 DMA_ATTR_V0, /* dma_attr_version */
472 QL_DMA_LOW_ADDRESS, /* low DMA address range */
473 QL_DMA_HIGH_64BIT_ADDRESS, /* high DMA address range */
474 QL_DMA_XFER_COUNTER, /* DMA counter register */
475 QL_DMA_ADDRESS_ALIGNMENT, /* DMA address alignment */
476 QL_DMA_BURSTSIZES, /* DMA burstsizes */
477 QL_DMA_MIN_XFER_SIZE, /* min effective DMA size */
478 QL_DMA_MAX_XFER_SIZE, /* max DMA xfer size */
479 QL_DMA_SEGMENT_BOUNDARY, /* segment boundary */
480 QL_DMA_SG_LIST_LENGTH, /* s/g list length */
481 QL_DMA_GRANULARITY, /* granularity of device */
482 QL_DMA_XFER_FLAGS /* DMA transfer flags */
483 };
484
485 static ddi_dma_attr_t ql_32bit_io_dma_attr = {
486 DMA_ATTR_V0, /* dma_attr_version */
487 QL_DMA_LOW_ADDRESS, /* low DMA address range */
488 QL_DMA_HIGH_32BIT_ADDRESS, /* high DMA address range */
489 QL_DMA_XFER_COUNTER, /* DMA counter register */
490 QL_DMA_ADDRESS_ALIGNMENT, /* DMA address alignment */
491 QL_DMA_BURSTSIZES, /* DMA burstsizes */
492 QL_DMA_MIN_XFER_SIZE, /* min effective DMA size */
493 QL_DMA_MAX_XFER_SIZE, /* max DMA xfer size */
494 QL_DMA_SEGMENT_BOUNDARY, /* segment boundary */
495 QL_DMA_SG_LIST_LENGTH, /* s/g list length */
496 QL_DMA_GRANULARITY, /* granularity of device */
497 QL_DMA_XFER_FLAGS /* DMA transfer flags */
498 };
499
500 /* Load the default dma attributes */
501 static ddi_dma_attr_t ql_32fcsm_cmd_dma_attr;
502 static ddi_dma_attr_t ql_64fcsm_cmd_dma_attr;
503 static ddi_dma_attr_t ql_32fcsm_rsp_dma_attr;
504 static ddi_dma_attr_t ql_64fcsm_rsp_dma_attr;
505 static ddi_dma_attr_t ql_32fcip_cmd_dma_attr;
506 static ddi_dma_attr_t ql_64fcip_cmd_dma_attr;
507 static ddi_dma_attr_t ql_32fcip_rsp_dma_attr;
508 static ddi_dma_attr_t ql_64fcip_rsp_dma_attr;
509 static ddi_dma_attr_t ql_32fcp_cmd_dma_attr;
510 static ddi_dma_attr_t ql_64fcp_cmd_dma_attr;
511 static ddi_dma_attr_t ql_32fcp_rsp_dma_attr;
512 static ddi_dma_attr_t ql_64fcp_rsp_dma_attr;
513 static ddi_dma_attr_t ql_32fcp_data_dma_attr;
514 static ddi_dma_attr_t ql_64fcp_data_dma_attr;
515
516 /* Static declarations of cb_ops entry point functions... */
517 static struct cb_ops ql_cb_ops = {
518 ql_open, /* b/c open */
519 ql_close, /* b/c close */
520 nodev, /* b strategy */
521 nodev, /* b print */
522 nodev, /* b dump */
523 nodev, /* c read */
524 nodev, /* c write */
525 ql_ioctl, /* c ioctl */
526 nodev, /* c devmap */
527 nodev, /* c mmap */
528 nodev, /* c segmap */
529 nochpoll, /* c poll */
530 nodev, /* cb_prop_op */
531 NULL, /* streamtab */
532 D_MP | D_NEW | D_HOTPLUG, /* Driver compatibility flag */
533 CB_REV, /* cb_ops revision */
534 nodev, /* c aread */
535 nodev /* c awrite */
536 };
537
538 /* Static declarations of dev_ops entry point functions... */
539 static struct dev_ops ql_devops = {
540 DEVO_REV, /* devo_rev */
541 0, /* refcnt */
542 ql_getinfo, /* getinfo */
543 nulldev, /* identify */
544 nulldev, /* probe */
545 ql_attach, /* attach */
546 ql_detach, /* detach */
547 nodev, /* reset */
548 &ql_cb_ops, /* char/block ops */
549 NULL, /* bus operations */
550 ql_power, /* power management */
551 ql_quiesce /* quiesce device */
552 };
553
554 /* ELS command code to text converter */
555 cmd_table_t els_cmd_tbl[] = ELS_CMD_TABLE();
556 /* Mailbox command code to text converter */
557 cmd_table_t mbox_cmd_tbl[] = MBOX_CMD_TABLE();
558
559 char qlc_driver_version[] = QL_VERSION;
560
561 /*
562 * Loadable Driver Interface Structures.
563 * Declare and initialize the module configuration section...
564 */
565 static struct modldrv modldrv = {
566 &mod_driverops, /* type of module: driver */
567 "SunFC Qlogic FCA v" QL_VERSION, /* name of module */
568 &ql_devops /* driver dev_ops */
569 };
570
571 static struct modlinkage modlinkage = {
572 MODREV_1,
573 &modldrv,
574 NULL
575 };
576
577 /* ************************************************************************ */
578 /* Loadable Module Routines. */
579 /* ************************************************************************ */
580
581 /*
582 * _init
583 * Initializes a loadable module. It is called before any other
584 * routine in a loadable module.
585 *
586 * Returns:
587 * 0 = success
588 *
589 * Context:
590 * Kernel context.
591 */
592 int
_init(void)593 _init(void)
594 {
595 uint16_t w16;
596 int rval = 0;
597
598 /* Get OS major release level. */
599 for (w16 = 0; w16 < sizeof (utsname.release); w16++) {
600 if (utsname.release[w16] == '.') {
601 w16++;
602 break;
603 }
604 }
605 if (w16 < sizeof (utsname.release)) {
606 (void) ql_bstr_to_dec(&utsname.release[w16],
607 &ql_os_release_level, 0);
608 } else {
609 ql_os_release_level = 0;
610 }
611 if (ql_os_release_level < 6) {
612 cmn_err(CE_WARN, "%s Unsupported OS release level = %d",
613 QL_NAME, ql_os_release_level);
614 rval = EINVAL;
615 }
616 if (ql_os_release_level == 6) {
617 ql_32bit_io_dma_attr.dma_attr_count_max = 0x00ffffff;
618 ql_64bit_io_dma_attr.dma_attr_count_max = 0x00ffffff;
619 }
620
621 if (rval == 0) {
622 rval = ddi_soft_state_init(&ql_state,
623 sizeof (ql_adapter_state_t), 0);
624 }
625 if (rval == 0) {
626 /* allow the FC Transport to tweak the dev_ops */
627 fc_fca_init(&ql_devops);
628
629 mutex_init(&ql_global_mutex, NULL, MUTEX_DRIVER, NULL);
630 mutex_init(&ql_global_hw_mutex, NULL, MUTEX_DRIVER, NULL);
631 mutex_init(&ql_global_el_mutex, NULL, MUTEX_DRIVER, NULL);
632 rval = mod_install(&modlinkage);
633 if (rval != 0) {
634 mutex_destroy(&ql_global_hw_mutex);
635 mutex_destroy(&ql_global_mutex);
636 mutex_destroy(&ql_global_el_mutex);
637 ddi_soft_state_fini(&ql_state);
638 } else {
639 /*EMPTY*/
640 ql_32fcsm_cmd_dma_attr = ql_32bit_io_dma_attr;
641 ql_64fcsm_cmd_dma_attr = ql_64bit_io_dma_attr;
642 ql_32fcsm_rsp_dma_attr = ql_32bit_io_dma_attr;
643 ql_64fcsm_rsp_dma_attr = ql_64bit_io_dma_attr;
644 ql_32fcip_cmd_dma_attr = ql_32bit_io_dma_attr;
645 ql_64fcip_cmd_dma_attr = ql_64bit_io_dma_attr;
646 ql_32fcip_rsp_dma_attr = ql_32bit_io_dma_attr;
647 ql_64fcip_rsp_dma_attr = ql_64bit_io_dma_attr;
648 ql_32fcp_cmd_dma_attr = ql_32bit_io_dma_attr;
649 ql_64fcp_cmd_dma_attr = ql_64bit_io_dma_attr;
650 ql_32fcp_rsp_dma_attr = ql_32bit_io_dma_attr;
651 ql_64fcp_rsp_dma_attr = ql_64bit_io_dma_attr;
652 ql_32fcp_data_dma_attr = ql_32bit_io_dma_attr;
653 ql_64fcp_data_dma_attr = ql_64bit_io_dma_attr;
654 ql_32fcsm_cmd_dma_attr.dma_attr_sgllen =
655 ql_64fcsm_cmd_dma_attr.dma_attr_sgllen =
656 QL_FCSM_CMD_SGLLEN;
657 ql_32fcsm_rsp_dma_attr.dma_attr_sgllen =
658 ql_64fcsm_rsp_dma_attr.dma_attr_sgllen =
659 QL_FCSM_RSP_SGLLEN;
660 ql_32fcip_cmd_dma_attr.dma_attr_sgllen =
661 ql_64fcip_cmd_dma_attr.dma_attr_sgllen =
662 QL_FCIP_CMD_SGLLEN;
663 ql_32fcip_rsp_dma_attr.dma_attr_sgllen =
664 ql_64fcip_rsp_dma_attr.dma_attr_sgllen =
665 QL_FCIP_RSP_SGLLEN;
666 ql_32fcp_cmd_dma_attr.dma_attr_sgllen =
667 ql_64fcp_cmd_dma_attr.dma_attr_sgllen =
668 QL_FCP_CMD_SGLLEN;
669 ql_32fcp_rsp_dma_attr.dma_attr_sgllen =
670 ql_64fcp_rsp_dma_attr.dma_attr_sgllen =
671 QL_FCP_RSP_SGLLEN;
672 }
673 }
674
675 if (rval != 0) {
676 cmn_err(CE_CONT, "?Unable to install/attach driver '%s'",
677 QL_NAME);
678 }
679
680 return (rval);
681 }
682
683 /*
684 * _fini
685 * Prepares a module for unloading. It is called when the system
686 * wants to unload a module. If the module determines that it can
687 * be unloaded, then _fini() returns the value returned by
688 * mod_remove(). Upon successful return from _fini() no other
689 * routine in the module will be called before _init() is called.
690 *
691 * Returns:
692 * 0 = success
693 *
694 * Context:
695 * Kernel context.
696 */
697 int
_fini(void)698 _fini(void)
699 {
700 int rval;
701
702 rval = mod_remove(&modlinkage);
703 if (rval == 0) {
704 mutex_destroy(&ql_global_hw_mutex);
705 mutex_destroy(&ql_global_mutex);
706 mutex_destroy(&ql_global_el_mutex);
707 ddi_soft_state_fini(&ql_state);
708 }
709
710 return (rval);
711 }
712
713 /*
714 * _info
715 * Returns information about loadable module.
716 *
717 * Input:
718 * modinfo = pointer to module information structure.
719 *
720 * Returns:
721 * Value returned by mod_info().
722 *
723 * Context:
724 * Kernel context.
725 */
726 int
_info(struct modinfo * modinfop)727 _info(struct modinfo *modinfop)
728 {
729 return (mod_info(&modlinkage, modinfop));
730 }
731
732 /* ************************************************************************ */
733 /* dev_ops functions */
734 /* ************************************************************************ */
735
736 /*
737 * ql_getinfo
738 * Returns the pointer associated with arg when cmd is
739 * set to DDI_INFO_DEVT2DEVINFO, or it should return the
740 * instance number associated with arg when cmd is set
741 * to DDI_INFO_DEV2INSTANCE.
742 *
743 * Input:
744 * dip = Do not use.
745 * cmd = command argument.
746 * arg = command specific argument.
747 * resultp = pointer to where request information is stored.
748 *
749 * Returns:
750 * DDI_SUCCESS or DDI_FAILURE.
751 *
752 * Context:
753 * Kernel context.
754 */
755 /* ARGSUSED */
756 static int
ql_getinfo(dev_info_t * dip,ddi_info_cmd_t cmd,void * arg,void ** resultp)757 ql_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
758 {
759 ql_adapter_state_t *ha;
760 int minor;
761 int rval = DDI_FAILURE;
762
763 minor = (int)(getminor((dev_t)arg));
764 ha = ddi_get_soft_state(ql_state, minor);
765 if (ha == NULL) {
766 QL_PRINT_2(CE_CONT, "failed, unknown minor=%d\n",
767 getminor((dev_t)arg));
768 *resultp = NULL;
769 return (rval);
770 }
771
772 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
773
774 switch (cmd) {
775 case DDI_INFO_DEVT2DEVINFO:
776 *resultp = ha->dip;
777 rval = DDI_SUCCESS;
778 break;
779 case DDI_INFO_DEVT2INSTANCE:
780 *resultp = (void *)(uintptr_t)(ha->instance);
781 rval = DDI_SUCCESS;
782 break;
783 default:
784 EL(ha, "failed, unsupported cmd=%d\n", cmd);
785 rval = DDI_FAILURE;
786 break;
787 }
788
789 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
790
791 return (rval);
792 }
793
794 /*
795 * ql_attach
796 * Configure and attach an instance of the driver
797 * for a port.
798 *
799 * Input:
800 * dip = pointer to device information structure.
801 * cmd = attach type.
802 *
803 * Returns:
804 * DDI_SUCCESS or DDI_FAILURE.
805 *
806 * Context:
807 * Kernel context.
808 */
809 static int
ql_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)810 ql_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
811 {
812 off_t regsize;
813 uint32_t size;
814 int rval, *ptr;
815 int instance;
816 uint_t progress = 0;
817 char *buf;
818 ushort_t caps_ptr, cap;
819 fc_fca_tran_t *tran;
820 ql_adapter_state_t *ha = NULL;
821
822 static char *pmcomps[] = {
823 NULL,
824 PM_LEVEL_D3_STR, /* Device OFF */
825 PM_LEVEL_D0_STR, /* Device ON */
826 };
827
828 QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n",
829 ddi_get_instance(dip), cmd);
830
831 buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
832
833 switch (cmd) {
834 case DDI_ATTACH:
835 /* first get the instance */
836 instance = ddi_get_instance(dip);
837
838 cmn_err(CE_CONT, "!Qlogic %s(%d) FCA Driver v%s\n",
839 QL_NAME, instance, QL_VERSION);
840
841 /* Correct OS version? */
842 if (ql_os_release_level != 11) {
843 cmn_err(CE_WARN, "%s(%d): This driver is for Solaris "
844 "11", QL_NAME, instance);
845 goto attach_failed;
846 }
847
848 /* Hardware is installed in a DMA-capable slot? */
849 if (ddi_slaveonly(dip) == DDI_SUCCESS) {
850 cmn_err(CE_WARN, "%s(%d): slave only", QL_NAME,
851 instance);
852 goto attach_failed;
853 }
854
855 /* No support for high-level interrupts */
856 if (ddi_intr_hilevel(dip, 0) != 0) {
857 cmn_err(CE_WARN, "%s(%d): High level interrupt"
858 " not supported", QL_NAME, instance);
859 goto attach_failed;
860 }
861
862 /* Allocate our per-device-instance structure */
863 if (ddi_soft_state_zalloc(ql_state,
864 instance) != DDI_SUCCESS) {
865 cmn_err(CE_WARN, "%s(%d): soft state alloc failed",
866 QL_NAME, instance);
867 goto attach_failed;
868 }
869 progress |= QL_SOFT_STATE_ALLOCED;
870
871 ha = ddi_get_soft_state(ql_state, instance);
872 if (ha == NULL) {
873 cmn_err(CE_WARN, "%s(%d): can't get soft state",
874 QL_NAME, instance);
875 goto attach_failed;
876 }
877 ha->dip = dip;
878 ha->instance = instance;
879 ha->hba.base_address = ha;
880 ha->pha = ha;
881
882 if (ql_el_trace_desc_ctor(ha) != DDI_SUCCESS) {
883 cmn_err(CE_WARN, "%s(%d): can't setup el tracing",
884 QL_NAME, instance);
885 goto attach_failed;
886 }
887
888 /* Get extended logging and dump flags. */
889 ql_common_properties(ha);
890
891 if (strcmp(ddi_driver_name(ddi_get_parent(dip)),
892 "sbus") == 0) {
893 EL(ha, "%s SBUS card detected", QL_NAME);
894 ha->cfg_flags |= CFG_SBUS_CARD;
895 }
896
897 ha->dev = kmem_zalloc(sizeof (*ha->dev) *
898 DEVICE_HEAD_LIST_SIZE, KM_SLEEP);
899
900 ha->outstanding_cmds = kmem_zalloc(
901 sizeof (*ha->outstanding_cmds) * MAX_OUTSTANDING_COMMANDS,
902 KM_SLEEP);
903
904 ha->ub_array = kmem_zalloc(sizeof (*ha->ub_array) *
905 QL_UB_LIMIT, KM_SLEEP);
906
907 ha->adapter_stats = kmem_zalloc(sizeof (*ha->adapter_stats),
908 KM_SLEEP);
909
910 (void) ddi_pathname(dip, buf);
911 ha->devpath = kmem_zalloc(strlen(buf)+1, KM_SLEEP);
912 if (ha->devpath == NULL) {
913 EL(ha, "devpath mem alloc failed\n");
914 } else {
915 (void) strcpy(ha->devpath, buf);
916 EL(ha, "devpath is: %s\n", ha->devpath);
917 }
918
919 if (CFG_IST(ha, CFG_SBUS_CARD)) {
920 /*
921 * For cards where PCI is mapped to sbus e.g. Ivory.
922 *
923 * 0x00 : 0x000 - 0x0FF PCI Config Space for 2200
924 * : 0x100 - 0x3FF PCI IO space for 2200
925 * 0x01 : 0x000 - 0x0FF PCI Config Space for fpga
926 * : 0x100 - 0x3FF PCI IO Space for fpga
927 */
928 if (ddi_regs_map_setup(dip, 0, (caddr_t *)&ha->iobase,
929 0x100, 0x300, &ql_dev_acc_attr, &ha->dev_handle) !=
930 DDI_SUCCESS) {
931 cmn_err(CE_WARN, "%s(%d): Unable to map device"
932 " registers", QL_NAME, instance);
933 goto attach_failed;
934 }
935 if (ddi_regs_map_setup(dip, 1,
936 (caddr_t *)&ha->sbus_fpga_iobase, 0, 0x400,
937 &ql_dev_acc_attr, &ha->sbus_fpga_dev_handle) !=
938 DDI_SUCCESS) {
939 /* We should not fail attach here */
940 cmn_err(CE_WARN, "%s(%d): Unable to map FPGA",
941 QL_NAME, instance);
942 ha->sbus_fpga_iobase = NULL;
943 }
944 progress |= QL_REGS_MAPPED;
945
946 /*
947 * We should map config space before adding interrupt
948 * So that the chip type (2200 or 2300) can be
949 * determined before the interrupt routine gets a
950 * chance to execute.
951 */
952 if (ddi_regs_map_setup(dip, 0,
953 (caddr_t *)&ha->sbus_config_base, 0, 0x100,
954 &ql_dev_acc_attr, &ha->sbus_config_handle) !=
955 DDI_SUCCESS) {
956 cmn_err(CE_WARN, "%s(%d): Unable to map sbus "
957 "config registers", QL_NAME, instance);
958 goto attach_failed;
959 }
960 progress |= QL_CONFIG_SPACE_SETUP;
961 } else {
962 /*LINTED [Solaris DDI_DEV_T_ANY Lint error]*/
963 rval = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
964 DDI_PROP_DONTPASS, "reg", &ptr, &size);
965 if (rval != DDI_PROP_SUCCESS) {
966 cmn_err(CE_WARN, "%s(%d): Unable to get PCI "
967 "address registers", QL_NAME, instance);
968 goto attach_failed;
969 } else {
970 ha->pci_bus_addr = ptr[0];
971 ha->function_number = (uint8_t)
972 (ha->pci_bus_addr >> 8 & 7);
973 ddi_prop_free(ptr);
974 }
975
976 /*
977 * We should map config space before adding interrupt
978 * So that the chip type (2200 or 2300) can be
979 * determined before the interrupt routine gets a
980 * chance to execute.
981 */
982 if (pci_config_setup(ha->dip, &ha->pci_handle) !=
983 DDI_SUCCESS) {
984 cmn_err(CE_WARN, "%s(%d): can't setup PCI "
985 "config space", QL_NAME, instance);
986 goto attach_failed;
987 }
988 progress |= QL_CONFIG_SPACE_SETUP;
989
990 /*
991 * Setup the ISP2200 registers address mapping to be
992 * accessed by this particular driver.
993 * 0x0 Configuration Space
994 * 0x1 I/O Space
995 * 0x2 32-bit Memory Space address
996 * 0x3 64-bit Memory Space address
997 */
998 size = ql_pci_config_get32(ha, PCI_CONF_BASE0) & BIT_0 ?
999 2 : 1;
1000 if (ddi_dev_regsize(dip, size, ®size) !=
1001 DDI_SUCCESS ||
1002 ddi_regs_map_setup(dip, size, &ha->iobase,
1003 0, regsize, &ql_dev_acc_attr, &ha->dev_handle) !=
1004 DDI_SUCCESS) {
1005 cmn_err(CE_WARN, "%s(%d): regs_map_setup(mem) "
1006 "failed", QL_NAME, instance);
1007 goto attach_failed;
1008 }
1009 progress |= QL_REGS_MAPPED;
1010
1011 /*
1012 * We need I/O space mappings for 23xx HBAs for
1013 * loading flash (FCode). The chip has a bug due to
1014 * which loading flash fails through mem space
1015 * mappings in PCI-X mode.
1016 */
1017 if (size == 1) {
1018 ha->iomap_iobase = ha->iobase;
1019 ha->iomap_dev_handle = ha->dev_handle;
1020 } else {
1021 if (ddi_dev_regsize(dip, 1, ®size) !=
1022 DDI_SUCCESS ||
1023 ddi_regs_map_setup(dip, 1,
1024 &ha->iomap_iobase, 0, regsize,
1025 &ql_dev_acc_attr, &ha->iomap_dev_handle) !=
1026 DDI_SUCCESS) {
1027 cmn_err(CE_WARN, "%s(%d): regs_map_"
1028 "setup(I/O) failed", QL_NAME,
1029 instance);
1030 goto attach_failed;
1031 }
1032 progress |= QL_IOMAP_IOBASE_MAPPED;
1033 }
1034 }
1035
1036 ha->subsys_id = (uint16_t)ql_pci_config_get16(ha,
1037 PCI_CONF_SUBSYSID);
1038 ha->subven_id = (uint16_t)ql_pci_config_get16(ha,
1039 PCI_CONF_SUBVENID);
1040 ha->ven_id = (uint16_t)ql_pci_config_get16(ha,
1041 PCI_CONF_VENID);
1042 ha->device_id = (uint16_t)ql_pci_config_get16(ha,
1043 PCI_CONF_DEVID);
1044 ha->rev_id = (uint8_t)ql_pci_config_get8(ha,
1045 PCI_CONF_REVID);
1046
1047 EL(ha, "ISP%x chip detected (RevID=%x, VenID=%x, SVenID=%x, "
1048 "SSysID=%x)\n", ha->device_id, ha->rev_id, ha->ven_id,
1049 ha->subven_id, ha->subsys_id);
1050
1051 switch (ha->device_id) {
1052 case 0x2300:
1053 case 0x2312:
1054 case 0x2322:
1055 case 0x6312:
1056 case 0x6322:
1057 if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) {
1058 ha->flags |= FUNCTION_1;
1059 }
1060 if ((ha->device_id == 0x6322) ||
1061 (ha->device_id == 0x2322)) {
1062 ha->cfg_flags |= CFG_CTRL_6322;
1063 ha->fw_class = 0x6322;
1064 ha->risc_dump_size = QL_6322_FW_DUMP_SIZE;
1065 } else {
1066 ha->cfg_flags |= CFG_CTRL_2300;
1067 ha->fw_class = 0x2300;
1068 ha->risc_dump_size = QL_2300_FW_DUMP_SIZE;
1069 }
1070 ha->reg_off = ®_off_2300;
1071 if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
1072 goto attach_failed;
1073 }
1074 ha->fcp_cmd = ql_command_iocb;
1075 ha->ip_cmd = ql_ip_iocb;
1076 ha->ms_cmd = ql_ms_iocb;
1077 if (CFG_IST(ha, CFG_SBUS_CARD)) {
1078 ha->cmd_segs = CMD_TYPE_2_DATA_SEGMENTS;
1079 ha->cmd_cont_segs = CONT_TYPE_0_DATA_SEGMENTS;
1080 } else {
1081 ha->cmd_segs = CMD_TYPE_3_DATA_SEGMENTS;
1082 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
1083 }
1084 break;
1085
1086 case 0x2200:
1087 ha->cfg_flags |= CFG_CTRL_2200;
1088 ha->reg_off = ®_off_2200;
1089 ha->fw_class = 0x2200;
1090 if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
1091 goto attach_failed;
1092 }
1093 ha->risc_dump_size = QL_2200_FW_DUMP_SIZE;
1094 ha->fcp_cmd = ql_command_iocb;
1095 ha->ip_cmd = ql_ip_iocb;
1096 ha->ms_cmd = ql_ms_iocb;
1097 if (CFG_IST(ha, CFG_SBUS_CARD)) {
1098 ha->cmd_segs = CMD_TYPE_2_DATA_SEGMENTS;
1099 ha->cmd_cont_segs = CONT_TYPE_0_DATA_SEGMENTS;
1100 } else {
1101 ha->cmd_segs = CMD_TYPE_3_DATA_SEGMENTS;
1102 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
1103 }
1104 break;
1105
1106 case 0x2422:
1107 case 0x2432:
1108 case 0x5422:
1109 case 0x5432:
1110 case 0x8432:
1111 if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) {
1112 ha->flags |= FUNCTION_1;
1113 }
1114 ha->cfg_flags |= CFG_CTRL_2422;
1115 if (ha->device_id == 0x8432) {
1116 ha->cfg_flags |= CFG_CTRL_MENLO;
1117 } else {
1118 ha->flags |= VP_ENABLED;
1119 }
1120
1121 ha->reg_off = ®_off_2400_2500;
1122 ha->fw_class = 0x2400;
1123 if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
1124 goto attach_failed;
1125 }
1126 ha->risc_dump_size = QL_24XX_FW_DUMP_SIZE;
1127 ha->fcp_cmd = ql_command_24xx_iocb;
1128 ha->ip_cmd = ql_ip_24xx_iocb;
1129 ha->ms_cmd = ql_ms_24xx_iocb;
1130 ha->els_cmd = ql_els_24xx_iocb;
1131 ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
1132 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
1133 break;
1134
1135 case 0x2522:
1136 case 0x2532:
1137 if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) {
1138 ha->flags |= FUNCTION_1;
1139 }
1140 ha->cfg_flags |= CFG_CTRL_25XX;
1141 ha->flags |= VP_ENABLED;
1142 ha->fw_class = 0x2500;
1143 ha->reg_off = ®_off_2400_2500;
1144 if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
1145 goto attach_failed;
1146 }
1147 ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE;
1148 ha->fcp_cmd = ql_command_24xx_iocb;
1149 ha->ip_cmd = ql_ip_24xx_iocb;
1150 ha->ms_cmd = ql_ms_24xx_iocb;
1151 ha->els_cmd = ql_els_24xx_iocb;
1152 ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
1153 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
1154 break;
1155
1156 case 0x8001:
1157 if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 4) {
1158 ha->flags |= FUNCTION_1;
1159 }
1160 ha->cfg_flags |= CFG_CTRL_81XX;
1161 ha->flags |= VP_ENABLED;
1162 ha->fw_class = 0x8100;
1163 ha->reg_off = ®_off_2400_2500;
1164 if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
1165 goto attach_failed;
1166 }
1167 ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE;
1168 ha->fcp_cmd = ql_command_24xx_iocb;
1169 ha->ip_cmd = ql_ip_24xx_iocb;
1170 ha->ms_cmd = ql_ms_24xx_iocb;
1171 ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
1172 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
1173 break;
1174
1175 case 0x8021:
1176 if (ha->function_number & BIT_0) {
1177 ha->flags |= FUNCTION_1;
1178 }
1179 ha->cfg_flags |= CFG_CTRL_8021;
1180 ha->reg_off = ®_off_8021;
1181 ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE;
1182 ha->fcp_cmd = ql_command_24xx_iocb;
1183 ha->ms_cmd = ql_ms_24xx_iocb;
1184 ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
1185 ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
1186
1187 ha->nx_pcibase = ha->iobase;
1188 ha->iobase += 0xBC000 + (ha->function_number << 11);
1189 ha->iomap_iobase += 0xBC000 +
1190 (ha->function_number << 11);
1191
1192 /* map doorbell */
1193 if (ddi_dev_regsize(dip, 2, ®size) != DDI_SUCCESS ||
1194 ddi_regs_map_setup(dip, 2, &ha->db_iobase,
1195 0, regsize, &ql_dev_acc_attr, &ha->db_dev_handle) !=
1196 DDI_SUCCESS) {
1197 cmn_err(CE_WARN, "%s(%d): regs_map_setup"
1198 "(doorbell) failed", QL_NAME, instance);
1199 goto attach_failed;
1200 }
1201 progress |= QL_DB_IOBASE_MAPPED;
1202
1203 ha->nx_req_in = (uint32_t *)(ha->db_iobase +
1204 (ha->function_number << 12));
1205 ha->db_read = ha->nx_pcibase + (512 * 1024) +
1206 (ha->function_number * 8);
1207
1208 ql_8021_update_crb_int_ptr(ha);
1209 ql_8021_set_drv_active(ha);
1210 break;
1211
1212 default:
1213 cmn_err(CE_WARN, "%s(%d): Unsupported device id: %x",
1214 QL_NAME, instance, ha->device_id);
1215 goto attach_failed;
1216 }
1217
1218 /* Setup hba buffer. */
1219
1220 size = CFG_IST(ha, CFG_CTRL_24258081) ?
1221 (REQUEST_QUEUE_SIZE + RESPONSE_QUEUE_SIZE) :
1222 (REQUEST_QUEUE_SIZE + RESPONSE_QUEUE_SIZE +
1223 RCVBUF_QUEUE_SIZE);
1224
1225 if (ql_get_dma_mem(ha, &ha->hba_buf, size, LITTLE_ENDIAN_DMA,
1226 QL_DMA_RING_ALIGN) != QL_SUCCESS) {
1227 cmn_err(CE_WARN, "%s(%d): request queue DMA memory "
1228 "alloc failed", QL_NAME, instance);
1229 goto attach_failed;
1230 }
1231 progress |= QL_HBA_BUFFER_SETUP;
1232
1233 /* Setup buffer pointers. */
1234 ha->request_dvma = ha->hba_buf.cookie.dmac_laddress +
1235 REQUEST_Q_BUFFER_OFFSET;
1236 ha->request_ring_bp = (struct cmd_entry *)
1237 ((caddr_t)ha->hba_buf.bp + REQUEST_Q_BUFFER_OFFSET);
1238
1239 ha->response_dvma = ha->hba_buf.cookie.dmac_laddress +
1240 RESPONSE_Q_BUFFER_OFFSET;
1241 ha->response_ring_bp = (struct sts_entry *)
1242 ((caddr_t)ha->hba_buf.bp + RESPONSE_Q_BUFFER_OFFSET);
1243
1244 ha->rcvbuf_dvma = ha->hba_buf.cookie.dmac_laddress +
1245 RCVBUF_Q_BUFFER_OFFSET;
1246 ha->rcvbuf_ring_bp = (struct rcvbuf *)
1247 ((caddr_t)ha->hba_buf.bp + RCVBUF_Q_BUFFER_OFFSET);
1248
1249 /* Allocate resource for QLogic IOCTL */
1250 (void) ql_alloc_xioctl_resource(ha);
1251
1252 /* Setup interrupts */
1253 if ((rval = ql_setup_interrupts(ha)) != DDI_SUCCESS) {
1254 cmn_err(CE_WARN, "%s(%d): Failed to add interrupt, "
1255 "rval=%xh", QL_NAME, instance, rval);
1256 goto attach_failed;
1257 }
1258
1259 progress |= (QL_INTR_ADDED | QL_MUTEX_CV_INITED);
1260
1261 if (ql_nvram_cache_desc_ctor(ha) != DDI_SUCCESS) {
1262 cmn_err(CE_WARN, "%s(%d): can't setup nvram cache",
1263 QL_NAME, instance);
1264 goto attach_failed;
1265 }
1266
1267 /*
1268 * Allocate an N Port information structure
1269 * for use when in P2P topology.
1270 */
1271 ha->n_port = (ql_n_port_info_t *)
1272 kmem_zalloc(sizeof (ql_n_port_info_t), KM_SLEEP);
1273 if (ha->n_port == NULL) {
1274 cmn_err(CE_WARN, "%s(%d): Failed to create N Port info",
1275 QL_NAME, instance);
1276 goto attach_failed;
1277 }
1278
1279 progress |= QL_N_PORT_INFO_CREATED;
1280
1281 /*
1282 * Determine support for Power Management
1283 */
1284 caps_ptr = (uint8_t)ql_pci_config_get8(ha, PCI_CONF_CAP_PTR);
1285
1286 while (caps_ptr != PCI_CAP_NEXT_PTR_NULL) {
1287 cap = (uint8_t)ql_pci_config_get8(ha, caps_ptr);
1288 if (cap == PCI_CAP_ID_PM) {
1289 ha->pm_capable = 1;
1290 break;
1291 }
1292 caps_ptr = (uint8_t)ql_pci_config_get8(ha, caps_ptr +
1293 PCI_CAP_NEXT_PTR);
1294 }
1295
1296 if (ha->pm_capable) {
1297 /*
1298 * Enable PM for 2200 based HBAs only.
1299 */
1300 if (ha->device_id != 0x2200) {
1301 ha->pm_capable = 0;
1302 }
1303 }
1304
1305 if (ha->pm_capable) {
1306 ha->pm_capable = ql_enable_pm;
1307 }
1308
1309 if (ha->pm_capable) {
1310 /*
1311 * Initialize power management bookkeeping;
1312 * components are created idle.
1313 */
1314 (void) sprintf(buf, "NAME=%s(%d)", QL_NAME, instance);
1315 pmcomps[0] = buf;
1316
1317 /*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/
1318 if (ddi_prop_update_string_array(DDI_DEV_T_NONE,
1319 dip, "pm-components", pmcomps,
1320 sizeof (pmcomps) / sizeof (pmcomps[0])) !=
1321 DDI_PROP_SUCCESS) {
1322 cmn_err(CE_WARN, "%s(%d): failed to create"
1323 " pm-components property", QL_NAME,
1324 instance);
1325
1326 /* Initialize adapter. */
1327 ha->power_level = PM_LEVEL_D0;
1328 if (ql_initialize_adapter(ha) != QL_SUCCESS) {
1329 cmn_err(CE_WARN, "%s(%d): failed to"
1330 " initialize adapter", QL_NAME,
1331 instance);
1332 goto attach_failed;
1333 }
1334 } else {
1335 ha->power_level = PM_LEVEL_D3;
1336 if (pm_raise_power(dip, QL_POWER_COMPONENT,
1337 PM_LEVEL_D0) != DDI_SUCCESS) {
1338 cmn_err(CE_WARN, "%s(%d): failed to"
1339 " raise power or initialize"
1340 " adapter", QL_NAME, instance);
1341 }
1342 }
1343 } else {
1344 /* Initialize adapter. */
1345 ha->power_level = PM_LEVEL_D0;
1346 if (ql_initialize_adapter(ha) != QL_SUCCESS) {
1347 cmn_err(CE_WARN, "%s(%d): failed to initialize"
1348 " adapter", QL_NAME, instance);
1349 }
1350 }
1351
1352 if (ha->fw_major_version == 0 && ha->fw_minor_version == 0 &&
1353 ha->fw_subminor_version == 0) {
1354 cmn_err(CE_NOTE, "!%s(%d): Firmware not loaded",
1355 QL_NAME, ha->instance);
1356 } else {
1357 int rval;
1358 char ver_fmt[256];
1359
1360 rval = (int)snprintf(ver_fmt, (size_t)sizeof (ver_fmt),
1361 "Firmware version %d.%d.%d", ha->fw_major_version,
1362 ha->fw_minor_version, ha->fw_subminor_version);
1363
1364 if (CFG_IST(ha, CFG_CTRL_81XX)) {
1365 rval = (int)snprintf(ver_fmt + rval,
1366 (size_t)sizeof (ver_fmt),
1367 ", MPI fw version %d.%d.%d",
1368 ha->mpi_fw_major_version,
1369 ha->mpi_fw_minor_version,
1370 ha->mpi_fw_subminor_version);
1371
1372 if (ha->subsys_id == 0x17B ||
1373 ha->subsys_id == 0x17D) {
1374 (void) snprintf(ver_fmt + rval,
1375 (size_t)sizeof (ver_fmt),
1376 ", PHY fw version %d.%d.%d",
1377 ha->phy_fw_major_version,
1378 ha->phy_fw_minor_version,
1379 ha->phy_fw_subminor_version);
1380 }
1381 }
1382 cmn_err(CE_NOTE, "!%s(%d): %s",
1383 QL_NAME, ha->instance, ver_fmt);
1384 }
1385
1386 ha->k_stats = kstat_create(QL_NAME, instance, "statistics",
1387 "controller", KSTAT_TYPE_RAW,
1388 (uint32_t)sizeof (ql_adapter_stat_t), KSTAT_FLAG_VIRTUAL);
1389 if (ha->k_stats == NULL) {
1390 cmn_err(CE_WARN, "%s(%d): Failed to create kstat",
1391 QL_NAME, instance);
1392 goto attach_failed;
1393 }
1394 progress |= QL_KSTAT_CREATED;
1395
1396 ha->adapter_stats->version = 1;
1397 ha->k_stats->ks_data = (void *)ha->adapter_stats;
1398 ha->k_stats->ks_private = ha;
1399 ha->k_stats->ks_update = ql_kstat_update;
1400 ha->k_stats->ks_ndata = 1;
1401 ha->k_stats->ks_data_size = sizeof (ql_adapter_stat_t);
1402 kstat_install(ha->k_stats);
1403
1404 if (ddi_create_minor_node(dip, "devctl", S_IFCHR,
1405 instance, DDI_NT_NEXUS, 0) != DDI_SUCCESS) {
1406 cmn_err(CE_WARN, "%s(%d): failed to create minor node",
1407 QL_NAME, instance);
1408 goto attach_failed;
1409 }
1410 progress |= QL_MINOR_NODE_CREATED;
1411
1412 /* Allocate a transport structure for this instance */
1413 tran = kmem_zalloc(sizeof (fc_fca_tran_t), KM_SLEEP);
1414 if (tran == NULL) {
1415 cmn_err(CE_WARN, "%s(%d): failed to allocate transport",
1416 QL_NAME, instance);
1417 goto attach_failed;
1418 }
1419
1420 progress |= QL_FCA_TRAN_ALLOCED;
1421
1422 /* fill in the structure */
1423 tran->fca_numports = 1;
1424 tran->fca_version = FCTL_FCA_MODREV_5;
1425 if (CFG_IST(ha, CFG_CTRL_2422)) {
1426 tran->fca_num_npivports = MAX_24_VIRTUAL_PORTS;
1427 } else if (CFG_IST(ha, CFG_CTRL_2581)) {
1428 tran->fca_num_npivports = MAX_25_VIRTUAL_PORTS;
1429 }
1430 bcopy(ha->loginparams.node_ww_name.raw_wwn,
1431 tran->fca_perm_pwwn.raw_wwn, 8);
1432
1433 EL(ha, "FCA version %d\n", tran->fca_version);
1434
1435 /* Specify the amount of space needed in each packet */
1436 tran->fca_pkt_size = sizeof (ql_srb_t);
1437
1438 /* command limits are usually dictated by hardware */
1439 tran->fca_cmd_max = MAX_OUTSTANDING_COMMANDS;
1440
1441 /* dmaattr are static, set elsewhere. */
1442 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
1443 tran->fca_dma_attr = &ql_64bit_io_dma_attr;
1444 tran->fca_dma_fcp_cmd_attr = &ql_64fcp_cmd_dma_attr;
1445 tran->fca_dma_fcp_rsp_attr = &ql_64fcp_rsp_dma_attr;
1446 tran->fca_dma_fcp_data_attr = &ql_64fcp_data_dma_attr;
1447 tran->fca_dma_fcsm_cmd_attr = &ql_64fcsm_cmd_dma_attr;
1448 tran->fca_dma_fcsm_rsp_attr = &ql_64fcsm_rsp_dma_attr;
1449 tran->fca_dma_fcip_cmd_attr = &ql_64fcip_cmd_dma_attr;
1450 tran->fca_dma_fcip_rsp_attr = &ql_64fcip_rsp_dma_attr;
1451 } else {
1452 tran->fca_dma_attr = &ql_32bit_io_dma_attr;
1453 tran->fca_dma_fcp_cmd_attr = &ql_32fcp_cmd_dma_attr;
1454 tran->fca_dma_fcp_rsp_attr = &ql_32fcp_rsp_dma_attr;
1455 tran->fca_dma_fcp_data_attr = &ql_32fcp_data_dma_attr;
1456 tran->fca_dma_fcsm_cmd_attr = &ql_32fcsm_cmd_dma_attr;
1457 tran->fca_dma_fcsm_rsp_attr = &ql_32fcsm_rsp_dma_attr;
1458 tran->fca_dma_fcip_cmd_attr = &ql_32fcip_cmd_dma_attr;
1459 tran->fca_dma_fcip_rsp_attr = &ql_32fcip_rsp_dma_attr;
1460 }
1461
1462 tran->fca_acc_attr = &ql_dev_acc_attr;
1463 tran->fca_iblock = &(ha->iblock_cookie);
1464
1465 /* the remaining values are simply function vectors */
1466 tran->fca_bind_port = ql_bind_port;
1467 tran->fca_unbind_port = ql_unbind_port;
1468 tran->fca_init_pkt = ql_init_pkt;
1469 tran->fca_un_init_pkt = ql_un_init_pkt;
1470 tran->fca_els_send = ql_els_send;
1471 tran->fca_get_cap = ql_get_cap;
1472 tran->fca_set_cap = ql_set_cap;
1473 tran->fca_getmap = ql_getmap;
1474 tran->fca_transport = ql_transport;
1475 tran->fca_ub_alloc = ql_ub_alloc;
1476 tran->fca_ub_free = ql_ub_free;
1477 tran->fca_ub_release = ql_ub_release;
1478 tran->fca_abort = ql_abort;
1479 tran->fca_reset = ql_reset;
1480 tran->fca_port_manage = ql_port_manage;
1481 tran->fca_get_device = ql_get_device;
1482
1483 /* give it to the FC transport */
1484 if (fc_fca_attach(dip, tran) != DDI_SUCCESS) {
1485 cmn_err(CE_WARN, "%s(%d): FCA attach failed", QL_NAME,
1486 instance);
1487 goto attach_failed;
1488 }
1489 progress |= QL_FCA_ATTACH_DONE;
1490
1491 /* Stash the structure so it can be freed at detach */
1492 ha->tran = tran;
1493
1494 /* Acquire global state lock. */
1495 GLOBAL_STATE_LOCK();
1496
1497 /* Add adapter structure to link list. */
1498 ql_add_link_b(&ql_hba, &ha->hba);
1499
1500 /* Start one second driver timer. */
1501 if (ql_timer_timeout_id == NULL) {
1502 ql_timer_ticks = drv_usectohz(1000000);
1503 ql_timer_timeout_id = timeout(ql_timer, (void *)0,
1504 ql_timer_ticks);
1505 }
1506
1507 /* Release global state lock. */
1508 GLOBAL_STATE_UNLOCK();
1509
1510 /* Determine and populate HBA fru info */
1511 ql_setup_fruinfo(ha);
1512
1513 /* Setup task_daemon thread. */
1514 (void) thread_create(NULL, 0, (void (*)())ql_task_daemon, ha,
1515 0, &p0, TS_RUN, minclsyspri);
1516
1517 progress |= QL_TASK_DAEMON_STARTED;
1518
1519 ddi_report_dev(dip);
1520
1521 /* Disable link reset in panic path */
1522 ha->lip_on_panic = 1;
1523
1524 rval = DDI_SUCCESS;
1525 break;
1526
1527 attach_failed:
1528 if (progress & QL_FCA_ATTACH_DONE) {
1529 (void) fc_fca_detach(dip);
1530 progress &= ~QL_FCA_ATTACH_DONE;
1531 }
1532
1533 if (progress & QL_FCA_TRAN_ALLOCED) {
1534 kmem_free(tran, sizeof (fc_fca_tran_t));
1535 progress &= ~QL_FCA_TRAN_ALLOCED;
1536 }
1537
1538 if (progress & QL_MINOR_NODE_CREATED) {
1539 ddi_remove_minor_node(dip, "devctl");
1540 progress &= ~QL_MINOR_NODE_CREATED;
1541 }
1542
1543 if (progress & QL_KSTAT_CREATED) {
1544 kstat_delete(ha->k_stats);
1545 progress &= ~QL_KSTAT_CREATED;
1546 }
1547
1548 if (progress & QL_N_PORT_INFO_CREATED) {
1549 kmem_free(ha->n_port, sizeof (ql_n_port_info_t));
1550 progress &= ~QL_N_PORT_INFO_CREATED;
1551 }
1552
1553 if (progress & QL_TASK_DAEMON_STARTED) {
1554 TASK_DAEMON_LOCK(ha);
1555
1556 ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG;
1557
1558 cv_signal(&ha->cv_task_daemon);
1559
1560 /* Release task daemon lock. */
1561 TASK_DAEMON_UNLOCK(ha);
1562
1563 /* Wait for for task daemon to stop running. */
1564 while (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
1565 ql_delay(ha, 10000);
1566 }
1567 progress &= ~QL_TASK_DAEMON_STARTED;
1568 }
1569
1570 if (progress & QL_DB_IOBASE_MAPPED) {
1571 ql_8021_clr_drv_active(ha);
1572 ddi_regs_map_free(&ha->db_dev_handle);
1573 progress &= ~QL_DB_IOBASE_MAPPED;
1574 }
1575 if (progress & QL_IOMAP_IOBASE_MAPPED) {
1576 ddi_regs_map_free(&ha->iomap_dev_handle);
1577 progress &= ~QL_IOMAP_IOBASE_MAPPED;
1578 }
1579
1580 if (progress & QL_CONFIG_SPACE_SETUP) {
1581 if (CFG_IST(ha, CFG_SBUS_CARD)) {
1582 ddi_regs_map_free(&ha->sbus_config_handle);
1583 } else {
1584 pci_config_teardown(&ha->pci_handle);
1585 }
1586 progress &= ~QL_CONFIG_SPACE_SETUP;
1587 }
1588
1589 if (progress & QL_INTR_ADDED) {
1590 ql_disable_intr(ha);
1591 ql_release_intr(ha);
1592 progress &= ~QL_INTR_ADDED;
1593 }
1594
1595 if (progress & QL_MUTEX_CV_INITED) {
1596 ql_destroy_mutex(ha);
1597 progress &= ~QL_MUTEX_CV_INITED;
1598 }
1599
1600 if (progress & QL_HBA_BUFFER_SETUP) {
1601 ql_free_phys(ha, &ha->hba_buf);
1602 progress &= ~QL_HBA_BUFFER_SETUP;
1603 }
1604
1605 if (progress & QL_REGS_MAPPED) {
1606 ddi_regs_map_free(&ha->dev_handle);
1607 if (ha->sbus_fpga_iobase != NULL) {
1608 ddi_regs_map_free(&ha->sbus_fpga_dev_handle);
1609 }
1610 progress &= ~QL_REGS_MAPPED;
1611 }
1612
1613 if (progress & QL_SOFT_STATE_ALLOCED) {
1614
1615 ql_fcache_rel(ha->fcache);
1616
1617 kmem_free(ha->adapter_stats,
1618 sizeof (*ha->adapter_stats));
1619
1620 kmem_free(ha->ub_array, sizeof (*ha->ub_array) *
1621 QL_UB_LIMIT);
1622
1623 kmem_free(ha->outstanding_cmds,
1624 sizeof (*ha->outstanding_cmds) *
1625 MAX_OUTSTANDING_COMMANDS);
1626
1627 if (ha->devpath != NULL) {
1628 kmem_free(ha->devpath,
1629 strlen(ha->devpath) + 1);
1630 }
1631
1632 kmem_free(ha->dev, sizeof (*ha->dev) *
1633 DEVICE_HEAD_LIST_SIZE);
1634
1635 if (ha->xioctl != NULL) {
1636 ql_free_xioctl_resource(ha);
1637 }
1638
1639 if (ha->fw_module != NULL) {
1640 (void) ddi_modclose(ha->fw_module);
1641 }
1642 (void) ql_el_trace_desc_dtor(ha);
1643 (void) ql_nvram_cache_desc_dtor(ha);
1644
1645 ddi_soft_state_free(ql_state, instance);
1646 progress &= ~QL_SOFT_STATE_ALLOCED;
1647 }
1648
1649 ddi_prop_remove_all(dip);
1650 rval = DDI_FAILURE;
1651 break;
1652
1653 case DDI_RESUME:
1654 rval = DDI_FAILURE;
1655
1656 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
1657 if (ha == NULL) {
1658 cmn_err(CE_WARN, "%s(%d): can't get soft state",
1659 QL_NAME, instance);
1660 break;
1661 }
1662
1663 ha->power_level = PM_LEVEL_D3;
1664 if (ha->pm_capable) {
1665 /*
1666 * Get ql_power to do power on initialization
1667 */
1668 if (pm_raise_power(dip, QL_POWER_COMPONENT,
1669 PM_LEVEL_D0) != DDI_SUCCESS) {
1670 cmn_err(CE_WARN, "%s(%d): can't raise adapter"
1671 " power", QL_NAME, instance);
1672 }
1673 }
1674
1675 /*
1676 * There is a bug in DR that prevents PM framework
1677 * from calling ql_power.
1678 */
1679 if (ha->power_level == PM_LEVEL_D3) {
1680 ha->power_level = PM_LEVEL_D0;
1681
1682 if (ql_initialize_adapter(ha) != QL_SUCCESS) {
1683 cmn_err(CE_WARN, "%s(%d): can't initialize the"
1684 " adapter", QL_NAME, instance);
1685 }
1686
1687 /* Wake up task_daemon. */
1688 ql_awaken_task_daemon(ha, NULL, TASK_DAEMON_ALIVE_FLG,
1689 0);
1690 }
1691
1692 /* Acquire global state lock. */
1693 GLOBAL_STATE_LOCK();
1694
1695 /* Restart driver timer. */
1696 if (ql_timer_timeout_id == NULL) {
1697 ql_timer_timeout_id = timeout(ql_timer, (void *)0,
1698 ql_timer_ticks);
1699 }
1700
1701 /* Release global state lock. */
1702 GLOBAL_STATE_UNLOCK();
1703
1704 /* Wake up command start routine. */
1705 ADAPTER_STATE_LOCK(ha);
1706 ha->flags &= ~ADAPTER_SUSPENDED;
1707 ADAPTER_STATE_UNLOCK(ha);
1708
1709 /*
1710 * Transport doesn't make FC discovery in polled
1711 * mode; So we need the daemon thread's services
1712 * right here.
1713 */
1714 (void) callb_generic_cpr(&ha->cprinfo, CB_CODE_CPR_RESUME);
1715
1716 rval = DDI_SUCCESS;
1717
1718 /* Restart IP if it was running. */
1719 if (ha->flags & IP_ENABLED && !(ha->flags & IP_INITIALIZED)) {
1720 (void) ql_initialize_ip(ha);
1721 ql_isp_rcvbuf(ha);
1722 }
1723 break;
1724
1725 default:
1726 cmn_err(CE_WARN, "%s(%d): attach, unknown code:"
1727 " %x", QL_NAME, ddi_get_instance(dip), cmd);
1728 rval = DDI_FAILURE;
1729 break;
1730 }
1731
1732 kmem_free(buf, MAXPATHLEN);
1733
1734 if (rval != DDI_SUCCESS) {
1735 /*EMPTY*/
1736 QL_PRINT_2(CE_CONT, "(%d): failed, rval = %xh\n",
1737 ddi_get_instance(dip), rval);
1738 } else {
1739 /*EMPTY*/
1740 QL_PRINT_3(CE_CONT, "(%d): done\n", ddi_get_instance(dip));
1741 }
1742
1743 return (rval);
1744 }
1745
1746 /*
1747 * ql_detach
1748 * Used to remove all the states associated with a given
1749 * instances of a device node prior to the removal of that
1750 * instance from the system.
1751 *
1752 * Input:
1753 * dip = pointer to device information structure.
1754 * cmd = type of detach.
1755 *
1756 * Returns:
1757 * DDI_SUCCESS or DDI_FAILURE.
1758 *
1759 * Context:
1760 * Kernel context.
1761 */
1762 static int
ql_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)1763 ql_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1764 {
1765 ql_adapter_state_t *ha, *vha;
1766 ql_tgt_t *tq;
1767 int delay_cnt;
1768 uint16_t index;
1769 ql_link_t *link;
1770 char *buf;
1771 timeout_id_t timer_id = NULL;
1772 int suspend, rval = DDI_SUCCESS;
1773
1774 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
1775 if (ha == NULL) {
1776 QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
1777 ddi_get_instance(dip));
1778 return (DDI_FAILURE);
1779 }
1780
1781 QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n", ha->instance, cmd);
1782
1783 buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
1784
1785 switch (cmd) {
1786 case DDI_DETACH:
1787 ADAPTER_STATE_LOCK(ha);
1788 ha->flags |= (ADAPTER_SUSPENDED | ABORT_CMDS_LOOP_DOWN_TMO);
1789 ADAPTER_STATE_UNLOCK(ha);
1790
1791 TASK_DAEMON_LOCK(ha);
1792
1793 if (ha->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) {
1794 ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG;
1795 cv_signal(&ha->cv_task_daemon);
1796
1797 TASK_DAEMON_UNLOCK(ha);
1798
1799 (void) ql_wait_for_td_stop(ha);
1800
1801 TASK_DAEMON_LOCK(ha);
1802 if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
1803 ha->task_daemon_flags &= ~TASK_DAEMON_STOP_FLG;
1804 EL(ha, "failed, could not stop task daemon\n");
1805 }
1806 }
1807 TASK_DAEMON_UNLOCK(ha);
1808
1809 GLOBAL_STATE_LOCK();
1810
1811 /* Disable driver timer if no adapters. */
1812 if (ql_timer_timeout_id && ql_hba.first == &ha->hba &&
1813 ql_hba.last == &ha->hba) {
1814 timer_id = ql_timer_timeout_id;
1815 ql_timer_timeout_id = NULL;
1816 }
1817 ql_remove_link(&ql_hba, &ha->hba);
1818
1819 GLOBAL_STATE_UNLOCK();
1820
1821 if (timer_id) {
1822 (void) untimeout(timer_id);
1823 }
1824
1825 if (ha->pm_capable) {
1826 if (pm_lower_power(dip, QL_POWER_COMPONENT,
1827 PM_LEVEL_D3) != DDI_SUCCESS) {
1828 cmn_err(CE_WARN, "%s(%d): failed to lower the"
1829 " power", QL_NAME, ha->instance);
1830 }
1831 }
1832
1833 /*
1834 * If pm_lower_power shutdown the adapter, there
1835 * isn't much else to do
1836 */
1837 if (ha->power_level != PM_LEVEL_D3) {
1838 ql_halt(ha, PM_LEVEL_D3);
1839 }
1840
1841 /* Remove virtual ports. */
1842 while ((vha = ha->vp_next) != NULL) {
1843 ql_vport_destroy(vha);
1844 }
1845
1846 /* Free target queues. */
1847 for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
1848 link = ha->dev[index].first;
1849 while (link != NULL) {
1850 tq = link->base_address;
1851 link = link->next;
1852 ql_dev_free(ha, tq);
1853 }
1854 }
1855
1856 /*
1857 * Free unsolicited buffers.
1858 * If we are here then there are no ULPs still
1859 * alive that wish to talk to ql so free up
1860 * any SRB_IP_UB_UNUSED buffers that are
1861 * lingering around
1862 */
1863 QL_UB_LOCK(ha);
1864 for (index = 0; index < QL_UB_LIMIT; index++) {
1865 fc_unsol_buf_t *ubp = ha->ub_array[index];
1866
1867 if (ubp != NULL) {
1868 ql_srb_t *sp = ubp->ub_fca_private;
1869
1870 sp->flags |= SRB_UB_FREE_REQUESTED;
1871
1872 while (!(sp->flags & SRB_UB_IN_FCA) ||
1873 (sp->flags & (SRB_UB_CALLBACK |
1874 SRB_UB_ACQUIRED))) {
1875 QL_UB_UNLOCK(ha);
1876 delay(drv_usectohz(100000));
1877 QL_UB_LOCK(ha);
1878 }
1879 ha->ub_array[index] = NULL;
1880
1881 QL_UB_UNLOCK(ha);
1882 ql_free_unsolicited_buffer(ha, ubp);
1883 QL_UB_LOCK(ha);
1884 }
1885 }
1886 QL_UB_UNLOCK(ha);
1887
1888 /* Free any saved RISC code. */
1889 if (ha->risc_code != NULL) {
1890 kmem_free(ha->risc_code, ha->risc_code_size);
1891 ha->risc_code = NULL;
1892 ha->risc_code_size = 0;
1893 }
1894
1895 if (ha->fw_module != NULL) {
1896 (void) ddi_modclose(ha->fw_module);
1897 ha->fw_module = NULL;
1898 }
1899
1900 /* Free resources. */
1901 ddi_prop_remove_all(dip);
1902 (void) fc_fca_detach(dip);
1903 kmem_free(ha->tran, sizeof (fc_fca_tran_t));
1904 ddi_remove_minor_node(dip, "devctl");
1905 if (ha->k_stats != NULL) {
1906 kstat_delete(ha->k_stats);
1907 }
1908
1909 if (CFG_IST(ha, CFG_SBUS_CARD)) {
1910 ddi_regs_map_free(&ha->sbus_config_handle);
1911 } else {
1912 if (CFG_IST(ha, CFG_CTRL_8021)) {
1913 ql_8021_clr_drv_active(ha);
1914 ddi_regs_map_free(&ha->db_dev_handle);
1915 }
1916 if (ha->iomap_dev_handle != ha->dev_handle) {
1917 ddi_regs_map_free(&ha->iomap_dev_handle);
1918 }
1919 pci_config_teardown(&ha->pci_handle);
1920 }
1921
1922 ql_disable_intr(ha);
1923 ql_release_intr(ha);
1924
1925 ql_free_xioctl_resource(ha);
1926
1927 ql_destroy_mutex(ha);
1928
1929 ql_free_phys(ha, &ha->hba_buf);
1930 ql_free_phys(ha, &ha->fwexttracebuf);
1931 ql_free_phys(ha, &ha->fwfcetracebuf);
1932
1933 ddi_regs_map_free(&ha->dev_handle);
1934 if (ha->sbus_fpga_iobase != NULL) {
1935 ddi_regs_map_free(&ha->sbus_fpga_dev_handle);
1936 }
1937
1938 ql_fcache_rel(ha->fcache);
1939 if (ha->vcache != NULL) {
1940 kmem_free(ha->vcache, QL_24XX_VPD_SIZE);
1941 }
1942
1943 if (ha->pi_attrs != NULL) {
1944 kmem_free(ha->pi_attrs, sizeof (fca_port_attrs_t));
1945 }
1946
1947 kmem_free(ha->adapter_stats, sizeof (*ha->adapter_stats));
1948
1949 kmem_free(ha->ub_array, sizeof (*ha->ub_array) * QL_UB_LIMIT);
1950
1951 kmem_free(ha->outstanding_cmds,
1952 sizeof (*ha->outstanding_cmds) * MAX_OUTSTANDING_COMMANDS);
1953
1954 if (ha->n_port != NULL) {
1955 kmem_free(ha->n_port, sizeof (ql_n_port_info_t));
1956 }
1957
1958 if (ha->devpath != NULL) {
1959 kmem_free(ha->devpath, strlen(ha->devpath) + 1);
1960 }
1961
1962 kmem_free(ha->dev, sizeof (*ha->dev) * DEVICE_HEAD_LIST_SIZE);
1963
1964 EL(ha, "detached\n");
1965
1966 ddi_soft_state_free(ql_state, (int)ha->instance);
1967
1968 break;
1969
1970 case DDI_SUSPEND:
1971 ADAPTER_STATE_LOCK(ha);
1972
1973 delay_cnt = 0;
1974 ha->flags |= ADAPTER_SUSPENDED;
1975 while (ha->flags & ADAPTER_TIMER_BUSY && delay_cnt++ < 10) {
1976 ADAPTER_STATE_UNLOCK(ha);
1977 delay(drv_usectohz(1000000));
1978 ADAPTER_STATE_LOCK(ha);
1979 }
1980 if (ha->busy || ha->flags & ADAPTER_TIMER_BUSY) {
1981 ha->flags &= ~ADAPTER_SUSPENDED;
1982 ADAPTER_STATE_UNLOCK(ha);
1983 rval = DDI_FAILURE;
1984 cmn_err(CE_WARN, "!%s(%d): Fail suspend"
1985 " busy %xh flags %xh", QL_NAME, ha->instance,
1986 ha->busy, ha->flags);
1987 break;
1988 }
1989
1990 ADAPTER_STATE_UNLOCK(ha);
1991
1992 if (ha->flags & IP_INITIALIZED) {
1993 (void) ql_shutdown_ip(ha);
1994 }
1995
1996 if ((suspend = ql_suspend_adapter(ha)) != QL_SUCCESS) {
1997 ADAPTER_STATE_LOCK(ha);
1998 ha->flags &= ~ADAPTER_SUSPENDED;
1999 ADAPTER_STATE_UNLOCK(ha);
2000 cmn_err(CE_WARN, "%s(%d): Fail suspend rval %xh",
2001 QL_NAME, ha->instance, suspend);
2002
2003 /* Restart IP if it was running. */
2004 if (ha->flags & IP_ENABLED &&
2005 !(ha->flags & IP_INITIALIZED)) {
2006 (void) ql_initialize_ip(ha);
2007 ql_isp_rcvbuf(ha);
2008 }
2009 rval = DDI_FAILURE;
2010 break;
2011 }
2012
2013 /* Acquire global state lock. */
2014 GLOBAL_STATE_LOCK();
2015
2016 /* Disable driver timer if last adapter. */
2017 if (ql_timer_timeout_id && ql_hba.first == &ha->hba &&
2018 ql_hba.last == &ha->hba) {
2019 timer_id = ql_timer_timeout_id;
2020 ql_timer_timeout_id = NULL;
2021 }
2022 GLOBAL_STATE_UNLOCK();
2023
2024 if (timer_id) {
2025 (void) untimeout(timer_id);
2026 }
2027
2028 EL(ha, "suspended\n");
2029
2030 break;
2031
2032 default:
2033 rval = DDI_FAILURE;
2034 break;
2035 }
2036
2037 kmem_free(buf, MAXPATHLEN);
2038
2039 if (rval != DDI_SUCCESS) {
2040 if (ha != NULL) {
2041 EL(ha, "failed, rval = %xh\n", rval);
2042 } else {
2043 /*EMPTY*/
2044 QL_PRINT_2(CE_CONT, "(%d): failed, rval = %xh\n",
2045 ddi_get_instance(dip), rval);
2046 }
2047 } else {
2048 /*EMPTY*/
2049 QL_PRINT_3(CE_CONT, "(%d): done\n", ddi_get_instance(dip));
2050 }
2051
2052 return (rval);
2053 }
2054
2055
2056 /*
2057 * ql_power
2058 * Power a device attached to the system.
2059 *
2060 * Input:
2061 * dip = pointer to device information structure.
2062 * component = device.
2063 * level = power level.
2064 *
2065 * Returns:
2066 * DDI_SUCCESS or DDI_FAILURE.
2067 *
2068 * Context:
2069 * Kernel context.
2070 */
2071 /* ARGSUSED */
2072 static int
ql_power(dev_info_t * dip,int component,int level)2073 ql_power(dev_info_t *dip, int component, int level)
2074 {
2075 int rval = DDI_FAILURE;
2076 off_t csr;
2077 uint8_t saved_pm_val;
2078 ql_adapter_state_t *ha;
2079 char *buf;
2080 char *path;
2081
2082 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
2083 if (ha == NULL || ha->pm_capable == 0) {
2084 QL_PRINT_2(CE_CONT, "(%d): no hba or PM not supported\n",
2085 ddi_get_instance(dip));
2086 return (rval);
2087 }
2088
2089 QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
2090
2091 buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
2092 path = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
2093
2094 if (component != QL_POWER_COMPONENT || (level != PM_LEVEL_D0 &&
2095 level != PM_LEVEL_D3)) {
2096 EL(ha, "invalid, component=%xh or level=%xh\n",
2097 component, level);
2098 return (rval);
2099 }
2100
2101 GLOBAL_HW_LOCK();
2102 csr = (uint8_t)ql_pci_config_get8(ha, PCI_CONF_CAP_PTR) + PCI_PMCSR;
2103 GLOBAL_HW_UNLOCK();
2104
2105 (void) snprintf(buf, sizeof (buf),
2106 "Qlogic %s(%d): %s\n\t", QL_NAME, ddi_get_instance(dip),
2107 ddi_pathname(dip, path));
2108
2109 switch (level) {
2110 case PM_LEVEL_D0: /* power up to D0 state - fully on */
2111
2112 QL_PM_LOCK(ha);
2113 if (ha->power_level == PM_LEVEL_D0) {
2114 QL_PM_UNLOCK(ha);
2115 rval = DDI_SUCCESS;
2116 break;
2117 }
2118
2119 /*
2120 * Enable interrupts now
2121 */
2122 saved_pm_val = ha->power_level;
2123 ha->power_level = PM_LEVEL_D0;
2124 QL_PM_UNLOCK(ha);
2125
2126 GLOBAL_HW_LOCK();
2127
2128 ql_pci_config_put16(ha, csr, PCI_PMCSR_D0);
2129
2130 /*
2131 * Delay after reset, for chip to recover.
2132 * Otherwise causes system PANIC
2133 */
2134 drv_usecwait(200000);
2135
2136 GLOBAL_HW_UNLOCK();
2137
2138 if (ha->config_saved) {
2139 ha->config_saved = 0;
2140 if (QL_RESTORE_CONFIG_REGS(dip) != DDI_SUCCESS) {
2141 QL_PM_LOCK(ha);
2142 ha->power_level = saved_pm_val;
2143 QL_PM_UNLOCK(ha);
2144 cmn_err(CE_WARN, "%s failed to restore "
2145 "config regs", buf);
2146 break;
2147 }
2148 }
2149
2150 if (ql_initialize_adapter(ha) != QL_SUCCESS) {
2151 cmn_err(CE_WARN, "%s adapter initialization failed",
2152 buf);
2153 }
2154
2155 /* Wake up task_daemon. */
2156 ql_awaken_task_daemon(ha, NULL, TASK_DAEMON_ALIVE_FLG |
2157 TASK_DAEMON_SLEEPING_FLG, 0);
2158
2159 /* Restart IP if it was running. */
2160 if (ha->flags & IP_ENABLED && !(ha->flags & IP_INITIALIZED)) {
2161 (void) ql_initialize_ip(ha);
2162 ql_isp_rcvbuf(ha);
2163 }
2164
2165 cmn_err(CE_NOTE, QL_BANG "ql_power(%d): %s is powered ON\n",
2166 ha->instance, QL_NAME);
2167
2168 rval = DDI_SUCCESS;
2169 break;
2170
2171 case PM_LEVEL_D3: /* power down to D3 state - off */
2172
2173 QL_PM_LOCK(ha);
2174
2175 if (ha->busy || ((ha->task_daemon_flags &
2176 TASK_DAEMON_SLEEPING_FLG) == 0)) {
2177 QL_PM_UNLOCK(ha);
2178 break;
2179 }
2180
2181 if (ha->power_level == PM_LEVEL_D3) {
2182 rval = DDI_SUCCESS;
2183 QL_PM_UNLOCK(ha);
2184 break;
2185 }
2186 QL_PM_UNLOCK(ha);
2187
2188 if (QL_SAVE_CONFIG_REGS(dip) != DDI_SUCCESS) {
2189 cmn_err(CE_WARN, "!Qlogic %s(%d): %s failed to save"
2190 " config regs", QL_NAME, ha->instance, buf);
2191 break;
2192 }
2193 ha->config_saved = 1;
2194
2195 /*
2196 * Don't enable interrupts. Running mailbox commands with
2197 * interrupts enabled could cause hangs since pm_run_scan()
2198 * runs out of a callout thread and on single cpu systems
2199 * cv_reltimedwait_sig(), called from ql_mailbox_command(),
2200 * would not get to run.
2201 */
2202 TASK_DAEMON_LOCK(ha);
2203 ha->task_daemon_flags |= TASK_DAEMON_POWERING_DOWN;
2204 TASK_DAEMON_UNLOCK(ha);
2205
2206 ql_halt(ha, PM_LEVEL_D3);
2207
2208 /*
2209 * Setup ql_intr to ignore interrupts from here on.
2210 */
2211 QL_PM_LOCK(ha);
2212 ha->power_level = PM_LEVEL_D3;
2213 QL_PM_UNLOCK(ha);
2214
2215 /*
2216 * Wait for ISR to complete.
2217 */
2218 INTR_LOCK(ha);
2219 ql_pci_config_put16(ha, csr, PCI_PMCSR_D3HOT);
2220 INTR_UNLOCK(ha);
2221
2222 cmn_err(CE_NOTE, QL_BANG "ql_power(%d): %s is powered OFF\n",
2223 ha->instance, QL_NAME);
2224
2225 rval = DDI_SUCCESS;
2226 break;
2227 }
2228
2229 kmem_free(buf, MAXPATHLEN);
2230 kmem_free(path, MAXPATHLEN);
2231
2232 QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
2233
2234 return (rval);
2235 }
2236
2237 /*
2238 * ql_quiesce
2239 * quiesce a device attached to the system.
2240 *
2241 * Input:
2242 * dip = pointer to device information structure.
2243 *
2244 * Returns:
2245 * DDI_SUCCESS
2246 *
2247 * Context:
2248 * Kernel context.
2249 */
2250 static int
ql_quiesce(dev_info_t * dip)2251 ql_quiesce(dev_info_t *dip)
2252 {
2253 ql_adapter_state_t *ha;
2254 uint32_t timer;
2255 uint32_t stat;
2256
2257 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
2258 if (ha == NULL) {
2259 /* Oh well.... */
2260 QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
2261 ddi_get_instance(dip));
2262 return (DDI_SUCCESS);
2263 }
2264
2265 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2266
2267 if (CFG_IST(ha, CFG_CTRL_8021)) {
2268 (void) ql_stop_firmware(ha);
2269 } else if (CFG_IST(ha, CFG_CTRL_242581)) {
2270 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
2271 WRT16_IO_REG(ha, mailbox_in[0], MBC_STOP_FIRMWARE);
2272 WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
2273 for (timer = 0; timer < 30000; timer++) {
2274 stat = RD32_IO_REG(ha, risc2host);
2275 if (stat & BIT_15) {
2276 if ((stat & 0xff) < 0x12) {
2277 WRT32_IO_REG(ha, hccr,
2278 HC24_CLR_RISC_INT);
2279 break;
2280 }
2281 WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
2282 }
2283 drv_usecwait(100);
2284 }
2285 /* Reset the chip. */
2286 WRT32_IO_REG(ha, ctrl_status, ISP_RESET | DMA_SHUTDOWN |
2287 MWB_4096_BYTES);
2288 drv_usecwait(100);
2289
2290 } else {
2291 /* Disable ISP interrupts. */
2292 WRT16_IO_REG(ha, ictrl, 0);
2293 /* Select RISC module registers. */
2294 WRT16_IO_REG(ha, ctrl_status, 0);
2295 /* Reset ISP semaphore. */
2296 WRT16_IO_REG(ha, semaphore, 0);
2297 /* Reset RISC module. */
2298 WRT16_IO_REG(ha, hccr, HC_RESET_RISC);
2299 /* Release RISC module. */
2300 WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
2301 }
2302
2303 ql_disable_intr(ha);
2304
2305 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2306
2307 return (DDI_SUCCESS);
2308 }
2309
2310 /* ************************************************************************ */
2311 /* Fibre Channel Adapter (FCA) Transport Functions. */
2312 /* ************************************************************************ */
2313
2314 /*
2315 * ql_bind_port
2316 * Handling port binding. The FC Transport attempts to bind an FCA port
2317 * when it is ready to start transactions on the port. The FC Transport
2318 * will call the fca_bind_port() function specified in the fca_transport
2319 * structure it receives. The FCA must fill in the port_info structure
2320 * passed in the call and also stash the information for future calls.
2321 *
2322 * Input:
2323 * dip = pointer to FCA information structure.
2324 * port_info = pointer to port information structure.
2325 * bind_info = pointer to bind information structure.
2326 *
2327 * Returns:
2328 * NULL = failure
2329 *
2330 * Context:
2331 * Kernel context.
2332 */
2333 static opaque_t
ql_bind_port(dev_info_t * dip,fc_fca_port_info_t * port_info,fc_fca_bind_info_t * bind_info)2334 ql_bind_port(dev_info_t *dip, fc_fca_port_info_t *port_info,
2335 fc_fca_bind_info_t *bind_info)
2336 {
2337 ql_adapter_state_t *ha, *vha;
2338 opaque_t fca_handle = NULL;
2339 port_id_t d_id;
2340 int port_npiv = bind_info->port_npiv;
2341 uchar_t *port_nwwn = bind_info->port_nwwn.raw_wwn;
2342 uchar_t *port_pwwn = bind_info->port_pwwn.raw_wwn;
2343
2344 /* get state info based on the dip */
2345 ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
2346 if (ha == NULL) {
2347 QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
2348 ddi_get_instance(dip));
2349 return (NULL);
2350 }
2351 QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
2352
2353 /* Verify port number is supported. */
2354 if (port_npiv != 0) {
2355 if (!(ha->flags & VP_ENABLED)) {
2356 QL_PRINT_2(CE_CONT, "(%d): FC_NPIV_NOT_SUPPORTED\n",
2357 ha->instance);
2358 port_info->pi_error = FC_NPIV_NOT_SUPPORTED;
2359 return (NULL);
2360 }
2361 if (!(ha->flags & POINT_TO_POINT)) {
2362 QL_PRINT_2(CE_CONT, "(%d): FC_NPIV_WRONG_TOPOLOGY\n",
2363 ha->instance);
2364 port_info->pi_error = FC_NPIV_WRONG_TOPOLOGY;
2365 return (NULL);
2366 }
2367 if (!(ha->flags & FDISC_ENABLED)) {
2368 QL_PRINT_2(CE_CONT, "(%d): switch does not support "
2369 "FDISC\n", ha->instance);
2370 port_info->pi_error = FC_NPIV_FDISC_FAILED;
2371 return (NULL);
2372 }
2373 if (bind_info->port_num > (CFG_IST(ha, CFG_CTRL_2422) ?
2374 MAX_24_VIRTUAL_PORTS : MAX_25_VIRTUAL_PORTS)) {
2375 QL_PRINT_2(CE_CONT, "(%d): port number=%d "
2376 "FC_OUTOFBOUNDS\n", ha->instance);
2377 port_info->pi_error = FC_OUTOFBOUNDS;
2378 return (NULL);
2379 }
2380 } else if (bind_info->port_num != 0) {
2381 QL_PRINT_2(CE_CONT, "(%d): failed, port number=%d is not "
2382 "supported\n", ha->instance, bind_info->port_num);
2383 port_info->pi_error = FC_OUTOFBOUNDS;
2384 return (NULL);
2385 }
2386
2387 /* Locate port context. */
2388 for (vha = ha; vha != NULL; vha = vha->vp_next) {
2389 if (vha->vp_index == bind_info->port_num) {
2390 break;
2391 }
2392 }
2393
2394 /* If virtual port does not exist. */
2395 if (vha == NULL) {
2396 vha = ql_vport_create(ha, (uint8_t)bind_info->port_num);
2397 }
2398
2399 /* make sure this port isn't already bound */
2400 if (vha->flags & FCA_BOUND) {
2401 port_info->pi_error = FC_ALREADY;
2402 } else {
2403 if (vha->vp_index != 0) {
2404 bcopy(port_nwwn,
2405 vha->loginparams.node_ww_name.raw_wwn, 8);
2406 bcopy(port_pwwn,
2407 vha->loginparams.nport_ww_name.raw_wwn, 8);
2408 }
2409 if (vha->vp_index != 0 && !(vha->flags & VP_ENABLED)) {
2410 if (ql_vport_enable(vha) != QL_SUCCESS) {
2411 QL_PRINT_2(CE_CONT, "(%d): failed to enable "
2412 "virtual port=%d\n", ha->instance,
2413 vha->vp_index);
2414 port_info->pi_error = FC_NPIV_FDISC_FAILED;
2415 return (NULL);
2416 }
2417 cmn_err(CE_CONT, "!Qlogic %s(%d) NPIV(%d) "
2418 "WWPN=%02x%02x%02x%02x%02x%02x%02x%02x : "
2419 "WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
2420 QL_NAME, ha->instance, vha->vp_index,
2421 port_pwwn[0], port_pwwn[1], port_pwwn[2],
2422 port_pwwn[3], port_pwwn[4], port_pwwn[5],
2423 port_pwwn[6], port_pwwn[7],
2424 port_nwwn[0], port_nwwn[1], port_nwwn[2],
2425 port_nwwn[3], port_nwwn[4], port_nwwn[5],
2426 port_nwwn[6], port_nwwn[7]);
2427 }
2428
2429 /* stash the bind_info supplied by the FC Transport */
2430 vha->bind_info.port_handle = bind_info->port_handle;
2431 vha->bind_info.port_statec_cb =
2432 bind_info->port_statec_cb;
2433 vha->bind_info.port_unsol_cb = bind_info->port_unsol_cb;
2434
2435 /* Set port's source ID. */
2436 port_info->pi_s_id.port_id = vha->d_id.b24;
2437
2438 /* copy out the default login parameters */
2439 bcopy((void *)&vha->loginparams,
2440 (void *)&port_info->pi_login_params,
2441 sizeof (la_els_logi_t));
2442
2443 /* Set port's hard address if enabled. */
2444 port_info->pi_hard_addr.hard_addr = 0;
2445 if (bind_info->port_num == 0) {
2446 d_id.b24 = ha->d_id.b24;
2447 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2448 if (ha->init_ctrl_blk.cb24.
2449 firmware_options_1[0] & BIT_0) {
2450 d_id.b.al_pa = ql_index_to_alpa[ha->
2451 init_ctrl_blk.cb24.
2452 hard_address[0]];
2453 port_info->pi_hard_addr.hard_addr =
2454 d_id.b24;
2455 }
2456 } else if (ha->init_ctrl_blk.cb.firmware_options[0] &
2457 BIT_0) {
2458 d_id.b.al_pa = ql_index_to_alpa[ha->
2459 init_ctrl_blk.cb.hard_address[0]];
2460 port_info->pi_hard_addr.hard_addr = d_id.b24;
2461 }
2462
2463 /* Set the node id data */
2464 if (ql_get_rnid_params(ha,
2465 sizeof (port_info->pi_rnid_params.params),
2466 (caddr_t)&port_info->pi_rnid_params.params) ==
2467 QL_SUCCESS) {
2468 port_info->pi_rnid_params.status = FC_SUCCESS;
2469 } else {
2470 port_info->pi_rnid_params.status = FC_FAILURE;
2471 }
2472
2473 /* Populate T11 FC-HBA details */
2474 ql_populate_hba_fru_details(ha, port_info);
2475 ha->pi_attrs = kmem_zalloc(sizeof (fca_port_attrs_t),
2476 KM_SLEEP);
2477 if (ha->pi_attrs != NULL) {
2478 bcopy(&port_info->pi_attrs, ha->pi_attrs,
2479 sizeof (fca_port_attrs_t));
2480 }
2481 } else {
2482 port_info->pi_rnid_params.status = FC_FAILURE;
2483 if (ha->pi_attrs != NULL) {
2484 bcopy(ha->pi_attrs, &port_info->pi_attrs,
2485 sizeof (fca_port_attrs_t));
2486 }
2487 }
2488
2489 /* Generate handle for this FCA. */
2490 fca_handle = (opaque_t)vha;
2491
2492 ADAPTER_STATE_LOCK(ha);
2493 vha->flags |= FCA_BOUND;
2494 ADAPTER_STATE_UNLOCK(ha);
2495 /* Set port's current state. */
2496 port_info->pi_port_state = vha->state;
2497 }
2498
2499 QL_PRINT_10(CE_CONT, "(%d,%d): done, pi_port_state=%xh, "
2500 "pi_s_id.port_id=%xh\n", ha->instance, ha->vp_index,
2501 port_info->pi_port_state, port_info->pi_s_id.port_id);
2502
2503 return (fca_handle);
2504 }
2505
2506 /*
2507 * ql_unbind_port
2508 * To unbind a Fibre Channel Adapter from an FC Port driver.
2509 *
2510 * Input:
2511 * fca_handle = handle setup by ql_bind_port().
2512 *
2513 * Context:
2514 * Kernel context.
2515 */
2516 static void
ql_unbind_port(opaque_t fca_handle)2517 ql_unbind_port(opaque_t fca_handle)
2518 {
2519 ql_adapter_state_t *ha;
2520 ql_tgt_t *tq;
2521 uint32_t flgs;
2522
2523 ha = ql_fca_handle_to_state(fca_handle);
2524 if (ha == NULL) {
2525 /*EMPTY*/
2526 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2527 (void *)fca_handle);
2528 } else {
2529 QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance,
2530 ha->vp_index);
2531
2532 if (!(ha->flags & FCA_BOUND)) {
2533 /*EMPTY*/
2534 QL_PRINT_2(CE_CONT, "(%d): port=%d already unbound\n",
2535 ha->instance, ha->vp_index);
2536 } else {
2537 if (ha->vp_index != 0 && ha->flags & VP_ENABLED) {
2538 if ((tq = ql_loop_id_to_queue(ha,
2539 FL_PORT_24XX_HDL)) != NULL) {
2540 (void) ql_logout_fabric_port(ha, tq);
2541 }
2542 (void) ql_vport_control(ha, (uint8_t)
2543 (CFG_IST(ha, CFG_CTRL_2425) ?
2544 VPC_DISABLE_INIT : VPC_DISABLE_LOGOUT));
2545 flgs = FCA_BOUND | VP_ENABLED;
2546 } else {
2547 flgs = FCA_BOUND;
2548 }
2549 ADAPTER_STATE_LOCK(ha);
2550 ha->flags &= ~flgs;
2551 ADAPTER_STATE_UNLOCK(ha);
2552 }
2553
2554 QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
2555 ha->vp_index);
2556 }
2557 }
2558
2559 /*
2560 * ql_init_pkt
2561 * Initialize FCA portion of packet.
2562 *
2563 * Input:
2564 * fca_handle = handle setup by ql_bind_port().
2565 * pkt = pointer to fc_packet.
2566 *
2567 * Returns:
2568 * FC_SUCCESS - the packet has successfully been initialized.
2569 * FC_UNBOUND - the fca_handle specified is not bound.
2570 * FC_NOMEM - the FCA failed initialization due to an allocation error.
2571 * FC_FAILURE - the FCA failed initialization for undisclosed reasons
2572 *
2573 * Context:
2574 * Kernel context.
2575 */
2576 /* ARGSUSED */
2577 static int
ql_init_pkt(opaque_t fca_handle,fc_packet_t * pkt,int sleep)2578 ql_init_pkt(opaque_t fca_handle, fc_packet_t *pkt, int sleep)
2579 {
2580 ql_adapter_state_t *ha;
2581 ql_srb_t *sp;
2582 int rval = FC_SUCCESS;
2583
2584 ha = ql_fca_handle_to_state(fca_handle);
2585 if (ha == NULL) {
2586 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2587 (void *)fca_handle);
2588 return (FC_UNBOUND);
2589 }
2590 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2591
2592 sp = (ql_srb_t *)pkt->pkt_fca_private;
2593 sp->flags = 0;
2594
2595 /* init cmd links */
2596 sp->cmd.base_address = sp;
2597 sp->cmd.prev = NULL;
2598 sp->cmd.next = NULL;
2599 sp->cmd.head = NULL;
2600
2601 /* init watchdog links */
2602 sp->wdg.base_address = sp;
2603 sp->wdg.prev = NULL;
2604 sp->wdg.next = NULL;
2605 sp->wdg.head = NULL;
2606 sp->pkt = pkt;
2607 sp->ha = ha;
2608 sp->magic_number = QL_FCA_BRAND;
2609 sp->sg_dma.dma_handle = NULL;
2610 #ifndef __sparc
2611 if (CFG_IST(ha, CFG_CTRL_8021)) {
2612 /* Setup DMA for scatter gather list. */
2613 sp->sg_dma.size = sizeof (cmd6_2400_dma_t);
2614 sp->sg_dma.type = LITTLE_ENDIAN_DMA;
2615 sp->sg_dma.cookie_count = 1;
2616 sp->sg_dma.alignment = 64;
2617 if (ql_alloc_phys(ha, &sp->sg_dma, KM_SLEEP) != QL_SUCCESS) {
2618 rval = FC_NOMEM;
2619 }
2620 }
2621 #endif /* __sparc */
2622
2623 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2624
2625 return (rval);
2626 }
2627
2628 /*
2629 * ql_un_init_pkt
2630 * Release all local resources bound to packet.
2631 *
2632 * Input:
2633 * fca_handle = handle setup by ql_bind_port().
2634 * pkt = pointer to fc_packet.
2635 *
2636 * Returns:
2637 * FC_SUCCESS - the packet has successfully been invalidated.
2638 * FC_UNBOUND - the fca_handle specified is not bound.
2639 * FC_BADPACKET - the packet has not been initialized or has
2640 * already been freed by this FCA.
2641 *
2642 * Context:
2643 * Kernel context.
2644 */
2645 static int
ql_un_init_pkt(opaque_t fca_handle,fc_packet_t * pkt)2646 ql_un_init_pkt(opaque_t fca_handle, fc_packet_t *pkt)
2647 {
2648 ql_adapter_state_t *ha;
2649 int rval;
2650 ql_srb_t *sp;
2651
2652 ha = ql_fca_handle_to_state(fca_handle);
2653 if (ha == NULL) {
2654 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2655 (void *)fca_handle);
2656 return (FC_UNBOUND);
2657 }
2658 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2659
2660 sp = (ql_srb_t *)pkt->pkt_fca_private;
2661
2662 if (sp->magic_number != QL_FCA_BRAND) {
2663 EL(ha, "failed, FC_BADPACKET\n");
2664 rval = FC_BADPACKET;
2665 } else {
2666 sp->magic_number = 0;
2667 ql_free_phys(ha, &sp->sg_dma);
2668 rval = FC_SUCCESS;
2669 }
2670
2671 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2672
2673 return (rval);
2674 }
2675
2676 /*
2677 * ql_els_send
2678 * Issue a extended link service request.
2679 *
2680 * Input:
2681 * fca_handle = handle setup by ql_bind_port().
2682 * pkt = pointer to fc_packet.
2683 *
2684 * Returns:
2685 * FC_SUCCESS - the command was successful.
2686 * FC_ELS_FREJECT - the command was rejected by a Fabric.
2687 * FC_ELS_PREJECT - the command was rejected by an N-port.
2688 * FC_TRANSPORT_ERROR - a transport error occurred.
2689 * FC_UNBOUND - the fca_handle specified is not bound.
2690 * FC_ELS_BAD - the FCA can not issue the requested ELS.
2691 *
2692 * Context:
2693 * Kernel context.
2694 */
2695 static int
ql_els_send(opaque_t fca_handle,fc_packet_t * pkt)2696 ql_els_send(opaque_t fca_handle, fc_packet_t *pkt)
2697 {
2698 ql_adapter_state_t *ha;
2699 int rval;
2700 clock_t timer = drv_usectohz(30000000);
2701 ls_code_t els;
2702 la_els_rjt_t rjt;
2703 ql_srb_t *sp = (ql_srb_t *)pkt->pkt_fca_private;
2704
2705 /* Verify proper command. */
2706 ha = ql_cmd_setup(fca_handle, pkt, &rval);
2707 if (ha == NULL) {
2708 QL_PRINT_2(CE_CONT, "failed, ql_cmd_setup=%xh, fcah=%ph\n",
2709 rval, fca_handle);
2710 return (FC_INVALID_REQUEST);
2711 }
2712 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2713
2714 /* Wait for suspension to end. */
2715 TASK_DAEMON_LOCK(ha);
2716 while (ha->task_daemon_flags & QL_SUSPENDED) {
2717 ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG;
2718
2719 /* 30 seconds from now */
2720 if (cv_reltimedwait(&ha->pha->cv_dr_suspended,
2721 &ha->pha->task_daemon_mutex, timer, TR_CLOCK_TICK) == -1) {
2722 /*
2723 * The timeout time 'timer' was
2724 * reached without the condition
2725 * being signaled.
2726 */
2727 pkt->pkt_state = FC_PKT_TRAN_BSY;
2728 pkt->pkt_reason = FC_REASON_XCHG_BSY;
2729
2730 /* Release task daemon lock. */
2731 TASK_DAEMON_UNLOCK(ha);
2732
2733 EL(ha, "QL_SUSPENDED failed=%xh\n",
2734 QL_FUNCTION_TIMEOUT);
2735 return (FC_TRAN_BUSY);
2736 }
2737 }
2738 /* Release task daemon lock. */
2739 TASK_DAEMON_UNLOCK(ha);
2740
2741 /* Setup response header. */
2742 bcopy((void *)&pkt->pkt_cmd_fhdr, (void *)&pkt->pkt_resp_fhdr,
2743 sizeof (fc_frame_hdr_t));
2744
2745 if (pkt->pkt_rsplen) {
2746 bzero((void *)pkt->pkt_resp, pkt->pkt_rsplen);
2747 }
2748
2749 pkt->pkt_resp_fhdr.d_id = ha->d_id.b24;
2750 pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id;
2751 pkt->pkt_resp_fhdr.r_ctl = R_CTL_EXTENDED_SVC |
2752 R_CTL_SOLICITED_CONTROL;
2753 pkt->pkt_resp_fhdr.f_ctl = F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ |
2754 F_CTL_END_SEQ;
2755
2756 sp->flags &= ~(SRB_UB_CALLBACK | SRB_UB_RSCN | SRB_UB_FCP |
2757 SRB_FCP_CMD_PKT | SRB_FCP_DATA_PKT | SRB_FCP_RSP_PKT |
2758 SRB_IP_PKT | SRB_COMMAND_TIMEOUT | SRB_UB_ACQUIRED | SRB_MS_PKT);
2759
2760 sp->flags |= SRB_ELS_PKT;
2761
2762 /* map the type of ELS to a function */
2763 ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
2764 (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
2765
2766 #if 0
2767 QL_PRINT_3(CE_CONT, "(%d): command fhdr:\n", ha->instance);
2768 QL_DUMP_3((uint8_t *)&pkt->pkt_cmd_fhdr, 32,
2769 sizeof (fc_frame_hdr_t) / 4);
2770 QL_PRINT_3(CE_CONT, "(%d): command:\n", ha->instance);
2771 QL_DUMP_3((uint8_t *)&els, 32, sizeof (els) / 4);
2772 #endif
2773
2774 sp->iocb = ha->els_cmd;
2775 sp->req_cnt = 1;
2776
2777 switch (els.ls_code) {
2778 case LA_ELS_RJT:
2779 case LA_ELS_ACC:
2780 EL(ha, "LA_ELS_RJT\n");
2781 pkt->pkt_state = FC_PKT_SUCCESS;
2782 rval = FC_SUCCESS;
2783 break;
2784 case LA_ELS_PLOGI:
2785 case LA_ELS_PDISC:
2786 rval = ql_els_plogi(ha, pkt);
2787 break;
2788 case LA_ELS_FLOGI:
2789 case LA_ELS_FDISC:
2790 rval = ql_els_flogi(ha, pkt);
2791 break;
2792 case LA_ELS_LOGO:
2793 rval = ql_els_logo(ha, pkt);
2794 break;
2795 case LA_ELS_PRLI:
2796 rval = ql_els_prli(ha, pkt);
2797 break;
2798 case LA_ELS_PRLO:
2799 rval = ql_els_prlo(ha, pkt);
2800 break;
2801 case LA_ELS_ADISC:
2802 rval = ql_els_adisc(ha, pkt);
2803 break;
2804 case LA_ELS_LINIT:
2805 rval = ql_els_linit(ha, pkt);
2806 break;
2807 case LA_ELS_LPC:
2808 rval = ql_els_lpc(ha, pkt);
2809 break;
2810 case LA_ELS_LSTS:
2811 rval = ql_els_lsts(ha, pkt);
2812 break;
2813 case LA_ELS_SCR:
2814 rval = ql_els_scr(ha, pkt);
2815 break;
2816 case LA_ELS_RSCN:
2817 rval = ql_els_rscn(ha, pkt);
2818 break;
2819 case LA_ELS_FARP_REQ:
2820 rval = ql_els_farp_req(ha, pkt);
2821 break;
2822 case LA_ELS_FARP_REPLY:
2823 rval = ql_els_farp_reply(ha, pkt);
2824 break;
2825 case LA_ELS_RLS:
2826 rval = ql_els_rls(ha, pkt);
2827 break;
2828 case LA_ELS_RNID:
2829 rval = ql_els_rnid(ha, pkt);
2830 break;
2831 default:
2832 EL(ha, "LA_ELS_RJT, FC_REASON_CMD_UNSUPPORTED=%xh\n",
2833 els.ls_code);
2834 /* Build RJT. */
2835 bzero(&rjt, sizeof (rjt));
2836 rjt.ls_code.ls_code = LA_ELS_RJT;
2837 rjt.reason = FC_REASON_CMD_UNSUPPORTED;
2838
2839 ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
2840 (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
2841
2842 pkt->pkt_state = FC_PKT_LOCAL_RJT;
2843 pkt->pkt_reason = FC_REASON_UNSUPPORTED;
2844 rval = FC_SUCCESS;
2845 break;
2846 }
2847
2848 #if 0
2849 QL_PRINT_3(CE_CONT, "(%d): response fhdr:\n", ha->instance);
2850 QL_DUMP_3((uint8_t *)&pkt->pkt_resp_fhdr, 32,
2851 sizeof (fc_frame_hdr_t) / 4);
2852 #endif
2853 /*
2854 * Return success if the srb was consumed by an iocb. The packet
2855 * completion callback will be invoked by the response handler.
2856 */
2857 if (rval == QL_CONSUMED) {
2858 rval = FC_SUCCESS;
2859 } else if (rval == FC_SUCCESS &&
2860 !(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
2861 /* Do command callback only if no error */
2862 ql_awaken_task_daemon(ha, sp, 0, 0);
2863 }
2864
2865 if (rval != FC_SUCCESS) {
2866 EL(ha, "failed, rval = %xh\n", rval);
2867 } else {
2868 /*EMPTY*/
2869 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2870 }
2871 return (rval);
2872 }
2873
2874 /*
2875 * ql_get_cap
2876 * Export FCA hardware and software capabilities.
2877 *
2878 * Input:
2879 * fca_handle = handle setup by ql_bind_port().
2880 * cap = pointer to the capabilities string.
2881 * ptr = buffer pointer for return capability.
2882 *
2883 * Returns:
2884 * FC_CAP_ERROR - no such capability
2885 * FC_CAP_FOUND - the capability was returned and cannot be set
2886 * FC_CAP_SETTABLE - the capability was returned and can be set
2887 * FC_UNBOUND - the fca_handle specified is not bound.
2888 *
2889 * Context:
2890 * Kernel context.
2891 */
2892 static int
ql_get_cap(opaque_t fca_handle,char * cap,void * ptr)2893 ql_get_cap(opaque_t fca_handle, char *cap, void *ptr)
2894 {
2895 ql_adapter_state_t *ha;
2896 int rval;
2897 uint32_t *rptr = (uint32_t *)ptr;
2898
2899 ha = ql_fca_handle_to_state(fca_handle);
2900 if (ha == NULL) {
2901 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2902 (void *)fca_handle);
2903 return (FC_UNBOUND);
2904 }
2905 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2906
2907 if (strcmp(cap, FC_NODE_WWN) == 0) {
2908 bcopy((void *)&ha->loginparams.node_ww_name.raw_wwn[0],
2909 ptr, 8);
2910 rval = FC_CAP_FOUND;
2911 } else if (strcmp(cap, FC_LOGIN_PARAMS) == 0) {
2912 bcopy((void *)&ha->loginparams, ptr,
2913 sizeof (la_els_logi_t));
2914 rval = FC_CAP_FOUND;
2915 } else if (strcmp(cap, FC_CAP_UNSOL_BUF) == 0) {
2916 *rptr = (uint32_t)QL_UB_LIMIT;
2917 rval = FC_CAP_FOUND;
2918 } else if (strcmp(cap, FC_CAP_NOSTREAM_ON_UNALIGN_BUF) == 0) {
2919
2920 dev_info_t *psydip = NULL;
2921 #ifdef __sparc
2922 /*
2923 * Disable streaming for certain 2 chip adapters
2924 * below Psycho to handle Psycho byte hole issue.
2925 */
2926 if ((CFG_IST(ha, CFG_MULTI_CHIP_ADAPTER)) &&
2927 (!CFG_IST(ha, CFG_SBUS_CARD))) {
2928 for (psydip = ddi_get_parent(ha->dip); psydip;
2929 psydip = ddi_get_parent(psydip)) {
2930 if (strcmp(ddi_driver_name(psydip),
2931 "pcipsy") == 0) {
2932 break;
2933 }
2934 }
2935 }
2936 #endif /* __sparc */
2937
2938 if (psydip) {
2939 *rptr = (uint32_t)FC_NO_STREAMING;
2940 EL(ha, "No Streaming\n");
2941 } else {
2942 *rptr = (uint32_t)FC_ALLOW_STREAMING;
2943 EL(ha, "Allow Streaming\n");
2944 }
2945 rval = FC_CAP_FOUND;
2946 } else if (strcmp(cap, FC_CAP_PAYLOAD_SIZE) == 0) {
2947 if (CFG_IST(ha, CFG_CTRL_24258081)) {
2948 *rptr = (uint32_t)CHAR_TO_SHORT(
2949 ha->init_ctrl_blk.cb24.max_frame_length[0],
2950 ha->init_ctrl_blk.cb24.max_frame_length[1]);
2951 } else {
2952 *rptr = (uint32_t)CHAR_TO_SHORT(
2953 ha->init_ctrl_blk.cb.max_frame_length[0],
2954 ha->init_ctrl_blk.cb.max_frame_length[1]);
2955 }
2956 rval = FC_CAP_FOUND;
2957 } else if (strcmp(cap, FC_CAP_POST_RESET_BEHAVIOR) == 0) {
2958 *rptr = FC_RESET_RETURN_ALL;
2959 rval = FC_CAP_FOUND;
2960 } else if (strcmp(cap, FC_CAP_FCP_DMA) == 0) {
2961 *rptr = FC_NO_DVMA_SPACE;
2962 rval = FC_CAP_FOUND;
2963 } else {
2964 EL(ha, "unknown=%s, FC_CAP_ERROR\n", cap);
2965 rval = FC_CAP_ERROR;
2966 }
2967
2968 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2969
2970 return (rval);
2971 }
2972
2973 /*
2974 * ql_set_cap
2975 * Allow the FC Transport to set FCA capabilities if possible.
2976 *
2977 * Input:
2978 * fca_handle = handle setup by ql_bind_port().
2979 * cap = pointer to the capabilities string.
2980 * ptr = buffer pointer for capability.
2981 *
2982 * Returns:
2983 * FC_CAP_ERROR - no such capability
2984 * FC_CAP_FOUND - the capability cannot be set by the FC Transport.
2985 * FC_CAP_SETTABLE - the capability was successfully set.
2986 * FC_UNBOUND - the fca_handle specified is not bound.
2987 *
2988 * Context:
2989 * Kernel context.
2990 */
2991 /* ARGSUSED */
2992 static int
ql_set_cap(opaque_t fca_handle,char * cap,void * ptr)2993 ql_set_cap(opaque_t fca_handle, char *cap, void *ptr)
2994 {
2995 ql_adapter_state_t *ha;
2996 int rval;
2997
2998 ha = ql_fca_handle_to_state(fca_handle);
2999 if (ha == NULL) {
3000 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3001 (void *)fca_handle);
3002 return (FC_UNBOUND);
3003 }
3004 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3005
3006 if (strcmp(cap, FC_NODE_WWN) == 0) {
3007 rval = FC_CAP_FOUND;
3008 } else if (strcmp(cap, FC_LOGIN_PARAMS) == 0) {
3009 rval = FC_CAP_FOUND;
3010 } else if (strcmp(cap, FC_CAP_UNSOL_BUF) == 0) {
3011 rval = FC_CAP_FOUND;
3012 } else if (strcmp(cap, FC_CAP_PAYLOAD_SIZE) == 0) {
3013 rval = FC_CAP_FOUND;
3014 } else if (strcmp(cap, FC_CAP_POST_RESET_BEHAVIOR) == 0) {
3015 rval = FC_CAP_FOUND;
3016 } else {
3017 EL(ha, "unknown=%s, FC_CAP_ERROR\n", cap);
3018 rval = FC_CAP_ERROR;
3019 }
3020
3021 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3022
3023 return (rval);
3024 }
3025
3026 /*
3027 * ql_getmap
3028 * Request of Arbitrated Loop (AL-PA) map.
3029 *
3030 * Input:
3031 * fca_handle = handle setup by ql_bind_port().
3032 * mapbuf= buffer pointer for map.
3033 *
3034 * Returns:
3035 * FC_OLDPORT - the specified port is not operating in loop mode.
3036 * FC_OFFLINE - the specified port is not online.
3037 * FC_NOMAP - there is no loop map available for this port.
3038 * FC_UNBOUND - the fca_handle specified is not bound.
3039 * FC_SUCCESS - a valid map has been placed in mapbuf.
3040 *
3041 * Context:
3042 * Kernel context.
3043 */
3044 static int
ql_getmap(opaque_t fca_handle,fc_lilpmap_t * mapbuf)3045 ql_getmap(opaque_t fca_handle, fc_lilpmap_t *mapbuf)
3046 {
3047 ql_adapter_state_t *ha;
3048 clock_t timer = drv_usectohz(30000000);
3049 int rval = FC_SUCCESS;
3050
3051 ha = ql_fca_handle_to_state(fca_handle);
3052 if (ha == NULL) {
3053 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3054 (void *)fca_handle);
3055 return (FC_UNBOUND);
3056 }
3057 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3058
3059 mapbuf->lilp_magic = (uint16_t)MAGIC_LIRP;
3060 mapbuf->lilp_myalpa = ha->d_id.b.al_pa;
3061
3062 /* Wait for suspension to end. */
3063 TASK_DAEMON_LOCK(ha);
3064 while (ha->task_daemon_flags & QL_SUSPENDED) {
3065 ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG;
3066
3067 /* 30 seconds from now */
3068 if (cv_reltimedwait(&ha->pha->cv_dr_suspended,
3069 &ha->pha->task_daemon_mutex, timer, TR_CLOCK_TICK) == -1) {
3070 /*
3071 * The timeout time 'timer' was
3072 * reached without the condition
3073 * being signaled.
3074 */
3075
3076 /* Release task daemon lock. */
3077 TASK_DAEMON_UNLOCK(ha);
3078
3079 EL(ha, "QL_SUSPENDED failed, FC_TRAN_BUSY\n");
3080 return (FC_TRAN_BUSY);
3081 }
3082 }
3083 /* Release task daemon lock. */
3084 TASK_DAEMON_UNLOCK(ha);
3085
3086 if (ql_get_loop_position_map(ha, LOOP_POSITION_MAP_SIZE,
3087 (caddr_t)&mapbuf->lilp_length) != QL_SUCCESS) {
3088 /*
3089 * Now, since transport drivers cosider this as an
3090 * offline condition, let's wait for few seconds
3091 * for any loop transitions before we reset the.
3092 * chip and restart all over again.
3093 */
3094 ql_delay(ha, 2000000);
3095 EL(ha, "failed, FC_NOMAP\n");
3096 rval = FC_NOMAP;
3097 } else {
3098 /*EMPTY*/
3099 QL_PRINT_3(CE_CONT, "(%d): my_alpa %xh len %xh "
3100 "data %xh %xh %xh %xh\n", ha->instance,
3101 mapbuf->lilp_myalpa, mapbuf->lilp_length,
3102 mapbuf->lilp_alpalist[0], mapbuf->lilp_alpalist[1],
3103 mapbuf->lilp_alpalist[2], mapbuf->lilp_alpalist[3]);
3104 }
3105
3106 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3107 #if 0
3108 QL_DUMP_3((uint8_t *)mapbuf, 8, sizeof (fc_lilpmap_t));
3109 #endif
3110 return (rval);
3111 }
3112
3113 /*
3114 * ql_transport
3115 * Issue an I/O request. Handles all regular requests.
3116 *
3117 * Input:
3118 * fca_handle = handle setup by ql_bind_port().
3119 * pkt = pointer to fc_packet.
3120 *
3121 * Returns:
3122 * FC_SUCCESS - the packet was accepted for transport.
3123 * FC_TRANSPORT_ERROR - a transport error occurred.
3124 * FC_BADPACKET - the packet to be transported had not been
3125 * initialized by this FCA.
3126 * FC_UNBOUND - the fca_handle specified is not bound.
3127 *
3128 * Context:
3129 * Kernel context.
3130 */
3131 static int
ql_transport(opaque_t fca_handle,fc_packet_t * pkt)3132 ql_transport(opaque_t fca_handle, fc_packet_t *pkt)
3133 {
3134 ql_adapter_state_t *ha;
3135 int rval = FC_TRANSPORT_ERROR;
3136 ql_srb_t *sp = (ql_srb_t *)pkt->pkt_fca_private;
3137
3138 /* Verify proper command. */
3139 ha = ql_cmd_setup(fca_handle, pkt, &rval);
3140 if (ha == NULL) {
3141 QL_PRINT_2(CE_CONT, "failed, ql_cmd_setup=%xh, fcah=%ph\n",
3142 rval, fca_handle);
3143 return (rval);
3144 }
3145 QL_PRINT_3(CE_CONT, "(%d): started command:\n", ha->instance);
3146 #if 0
3147 QL_DUMP_3((uint8_t *)&pkt->pkt_cmd_fhdr, 32,
3148 sizeof (fc_frame_hdr_t) / 4);
3149 QL_PRINT_3(CE_CONT, "(%d): command:\n", ha->instance);
3150 QL_DUMP_3((uint8_t *)pkt->pkt_cmd, 8, pkt->pkt_cmdlen);
3151 #endif
3152
3153 /* Reset SRB flags. */
3154 sp->flags &= ~(SRB_ISP_STARTED | SRB_ISP_COMPLETED | SRB_RETRY |
3155 SRB_POLL | SRB_WATCHDOG_ENABLED | SRB_ABORT | SRB_UB_CALLBACK |
3156 SRB_UB_RSCN | SRB_UB_FCP | SRB_FCP_CMD_PKT | SRB_FCP_DATA_PKT |
3157 SRB_FCP_RSP_PKT | SRB_IP_PKT | SRB_GENERIC_SERVICES_PKT |
3158 SRB_COMMAND_TIMEOUT | SRB_ABORTING | SRB_IN_DEVICE_QUEUE |
3159 SRB_IN_TOKEN_ARRAY | SRB_UB_FREE_REQUESTED | SRB_UB_ACQUIRED |
3160 SRB_MS_PKT | SRB_ELS_PKT);
3161
3162 pkt->pkt_resp_fhdr.d_id = ha->d_id.b24;
3163 pkt->pkt_resp_fhdr.r_ctl = R_CTL_STATUS;
3164 pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id;
3165 pkt->pkt_resp_fhdr.f_ctl = pkt->pkt_cmd_fhdr.f_ctl;
3166 pkt->pkt_resp_fhdr.type = pkt->pkt_cmd_fhdr.type;
3167
3168 switch (pkt->pkt_cmd_fhdr.r_ctl) {
3169 case R_CTL_COMMAND:
3170 if (pkt->pkt_cmd_fhdr.type == FC_TYPE_SCSI_FCP) {
3171 sp->flags |= SRB_FCP_CMD_PKT;
3172 rval = ql_fcp_scsi_cmd(ha, pkt, sp);
3173 }
3174 break;
3175
3176 default:
3177 /* Setup response header and buffer. */
3178 if (pkt->pkt_rsplen) {
3179 bzero((void *)pkt->pkt_resp, pkt->pkt_rsplen);
3180 }
3181
3182 switch (pkt->pkt_cmd_fhdr.r_ctl) {
3183 case R_CTL_UNSOL_DATA:
3184 if (pkt->pkt_cmd_fhdr.type == FC_TYPE_IS8802_SNAP) {
3185 sp->flags |= SRB_IP_PKT;
3186 rval = ql_fcp_ip_cmd(ha, pkt, sp);
3187 }
3188 break;
3189
3190 case R_CTL_UNSOL_CONTROL:
3191 if (pkt->pkt_cmd_fhdr.type == FC_TYPE_FC_SERVICES) {
3192 sp->flags |= SRB_GENERIC_SERVICES_PKT;
3193 rval = ql_fc_services(ha, pkt);
3194 }
3195 break;
3196
3197 case R_CTL_SOLICITED_DATA:
3198 case R_CTL_STATUS:
3199 default:
3200 pkt->pkt_state = FC_PKT_LOCAL_RJT;
3201 pkt->pkt_reason = FC_REASON_UNSUPPORTED;
3202 rval = FC_TRANSPORT_ERROR;
3203 EL(ha, "unknown, r_ctl=%xh\n",
3204 pkt->pkt_cmd_fhdr.r_ctl);
3205 break;
3206 }
3207 }
3208
3209 if (rval != FC_SUCCESS) {
3210 EL(ha, "failed, rval = %xh\n", rval);
3211 } else {
3212 /*EMPTY*/
3213 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3214 }
3215
3216 return (rval);
3217 }
3218
3219 /*
3220 * ql_ub_alloc
3221 * Allocate buffers for unsolicited exchanges.
3222 *
3223 * Input:
3224 * fca_handle = handle setup by ql_bind_port().
3225 * tokens = token array for each buffer.
3226 * size = size of each buffer.
3227 * count = pointer to number of buffers.
3228 * type = the FC-4 type the buffers are reserved for.
3229 * 1 = Extended Link Services, 5 = LLC/SNAP
3230 *
3231 * Returns:
3232 * FC_FAILURE - buffers could not be allocated.
3233 * FC_TOOMANY - the FCA could not allocate the requested
3234 * number of buffers.
3235 * FC_SUCCESS - unsolicited buffers were allocated.
3236 * FC_UNBOUND - the fca_handle specified is not bound.
3237 *
3238 * Context:
3239 * Kernel context.
3240 */
3241 static int
ql_ub_alloc(opaque_t fca_handle,uint64_t tokens[],uint32_t size,uint32_t * count,uint32_t type)3242 ql_ub_alloc(opaque_t fca_handle, uint64_t tokens[], uint32_t size,
3243 uint32_t *count, uint32_t type)
3244 {
3245 ql_adapter_state_t *ha;
3246 caddr_t bufp = NULL;
3247 fc_unsol_buf_t *ubp;
3248 ql_srb_t *sp;
3249 uint32_t index;
3250 uint32_t cnt;
3251 uint32_t ub_array_index = 0;
3252 int rval = FC_SUCCESS;
3253 int ub_updated = FALSE;
3254
3255 /* Check handle. */
3256 ha = ql_fca_handle_to_state(fca_handle);
3257 if (ha == NULL) {
3258 QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3259 (void *)fca_handle);
3260 return (FC_UNBOUND);
3261 }
3262 QL_PRINT_3(CE_CONT, "(%d,%d): started, count = %xh\n",
3263 ha->instance, ha->vp_index, *count);
3264
3265 QL_PM_LOCK(ha);
3266 if (ha->power_level != PM_LEVEL_D0) {
3267 QL_PM_UNLOCK(ha);
3268 QL_PRINT_3(CE_CONT, "(%d,%d): down done\n", ha->instance,
3269 ha->vp_index);
3270 return (FC_FAILURE);
3271 }
3272 QL_PM_UNLOCK(ha);
3273
3274 /* Acquire adapter state lock. */
3275 ADAPTER_STATE_LOCK(ha);
3276
3277 /* Check the count. */
3278 if ((*count + ha->ub_allocated) > QL_UB_LIMIT) {
3279 *count = 0;
3280 EL(ha, "failed, FC_TOOMANY\n");
3281 rval = FC_TOOMANY;
3282 }
3283
3284 /*
3285 * reset ub_array_index
3286 */
3287 ub_array_index = 0;
3288
3289 /*
3290 * Now proceed to allocate any buffers required
3291 */
3292 for (index = 0; index < *count && rval == FC_SUCCESS; index++) {
3293 /* Allocate all memory needed. */
3294 ubp = (fc_unsol_buf_t *)kmem_zalloc(sizeof (fc_unsol_buf_t),
3295 KM_SLEEP);
3296 if (ubp == NULL) {
3297 EL(ha, "failed, FC_FAILURE\n");
3298 rval = FC_FAILURE;
3299 } else {
3300 sp = kmem_zalloc(sizeof (ql_srb_t), KM_SLEEP);
3301 if (sp == NULL) {
3302 kmem_free(ubp, sizeof (fc_unsol_buf_t));
3303 rval = FC_FAILURE;
3304 } else {
3305 if (type == FC_TYPE_IS8802_SNAP) {
3306 #ifdef __sparc
3307 if (ql_get_dma_mem(ha,
3308 &sp->ub_buffer, size,
3309 BIG_ENDIAN_DMA,
3310 QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
3311 rval = FC_FAILURE;
3312 kmem_free(ubp,
3313 sizeof (fc_unsol_buf_t));
3314 kmem_free(sp,
3315 sizeof (ql_srb_t));
3316 } else {
3317 bufp = sp->ub_buffer.bp;
3318 sp->ub_size = size;
3319 }
3320 #else
3321 if (ql_get_dma_mem(ha,
3322 &sp->ub_buffer, size,
3323 LITTLE_ENDIAN_DMA,
3324 QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
3325 rval = FC_FAILURE;
3326 kmem_free(ubp,
3327 sizeof (fc_unsol_buf_t));
3328 kmem_free(sp,
3329 sizeof (ql_srb_t));
3330 } else {
3331 bufp = sp->ub_buffer.bp;
3332 sp->ub_size = size;
3333 }
3334 #endif
3335 } else {
3336 bufp = kmem_zalloc(size, KM_SLEEP);
3337 if (bufp == NULL) {
3338 rval = FC_FAILURE;
3339 kmem_free(ubp,
3340 sizeof (fc_unsol_buf_t));
3341 kmem_free(sp,
3342 sizeof (ql_srb_t));
3343 } else {
3344 sp->ub_size = size;
3345 }
3346 }
3347 }
3348 }
3349
3350 if (rval == FC_SUCCESS) {
3351 /* Find next available slot. */
3352 QL_UB_LOCK(ha);
3353 while (ha->ub_array[ub_array_index] != NULL) {
3354 ub_array_index++;
3355 }
3356
3357 ubp->ub_fca_private = (void *)sp;
3358
3359 /* init cmd links */
3360 sp->cmd.base_address = sp;
3361 sp->cmd.prev = NULL;
3362 sp->cmd.next = NULL;
3363 sp->cmd.head = NULL;
3364
3365 /* init wdg links */
3366 sp->wdg.base_address = sp;
3367 sp->wdg.prev = NULL;
3368 sp->wdg.next = NULL;
3369 sp->wdg.head = NULL;
3370 sp->ha = ha;
3371
3372 ubp->ub_buffer = bufp;
3373 ubp->ub_bufsize = size;
3374 ubp->ub_port_handle = fca_handle;
3375 ubp->ub_token = ub_array_index;
3376
3377 /* Save the token. */
3378 tokens[index] = ub_array_index;
3379
3380 /* Setup FCA private information. */
3381 sp->ub_type = type;
3382 sp->handle = ub_array_index;
3383 sp->flags |= SRB_UB_IN_FCA;
3384
3385 ha->ub_array[ub_array_index] = ubp;
3386 ha->ub_allocated++;
3387 ub_updated = TRUE;
3388 QL_UB_UNLOCK(ha);
3389 }
3390 }
3391
3392 /* Release adapter state lock. */
3393 ADAPTER_STATE_UNLOCK(ha);
3394
3395 /* IP buffer. */
3396 if (ub_updated) {
3397 if ((type == FC_TYPE_IS8802_SNAP) &&
3398 (!(CFG_IST(ha, (CFG_CTRL_6322 | CFG_CTRL_2581))))) {
3399
3400 ADAPTER_STATE_LOCK(ha);
3401 ha->flags |= IP_ENABLED;
3402 ADAPTER_STATE_UNLOCK(ha);
3403
3404 if (!(ha->flags & IP_INITIALIZED)) {
3405 if (CFG_IST(ha, CFG_CTRL_2422)) {
3406 ha->ip_init_ctrl_blk.cb24.mtu_size[0] =
3407 LSB(ql_ip_mtu);
3408 ha->ip_init_ctrl_blk.cb24.mtu_size[1] =
3409 MSB(ql_ip_mtu);
3410 ha->ip_init_ctrl_blk.cb24.buf_size[0] =
3411 LSB(size);
3412 ha->ip_init_ctrl_blk.cb24.buf_size[1] =
3413 MSB(size);
3414
3415 cnt = CHAR_TO_SHORT(
3416 ha->ip_init_ctrl_blk.cb24.cc[0],
3417 ha->ip_init_ctrl_blk.cb24.cc[1]);
3418
3419 if (cnt < *count) {
3420 ha->ip_init_ctrl_blk.cb24.cc[0]
3421 = LSB(*count);
3422 ha->ip_init_ctrl_blk.cb24.cc[1]
3423 = MSB(*count);
3424 }
3425 } else {
3426 ha->ip_init_ctrl_blk.cb.mtu_size[0] =
3427 LSB(ql_ip_mtu);
3428 ha->ip_init_ctrl_blk.cb.mtu_size[1] =
3429 MSB(ql_ip_mtu);
3430 ha->ip_init_ctrl_blk.cb.buf_size[0] =
3431 LSB(