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