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