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