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