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