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