ql_api.c revision 9156:4f14e395f46b
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/* Copyright 2009 QLogic Corporation */
23
24/*
25 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
26 * Use is subject to license terms.
27 */
28
29#pragma ident	"Copyright 2009 QLogic Corporation; ql_api.c"
30
31/*
32 * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
33 *
34 * ***********************************************************************
35 * *									**
36 * *				NOTICE					**
37 * *		COPYRIGHT (C) 1996-2009 QLOGIC CORPORATION		**
38 * *			ALL RIGHTS RESERVED				**
39 * *									**
40 * ***********************************************************************
41 *
42 */
43
44#include <ql_apps.h>
45#include <ql_api.h>
46#include <ql_debug.h>
47#include <ql_init.h>
48#include <ql_iocb.h>
49#include <ql_ioctl.h>
50#include <ql_isr.h>
51#include <ql_mbx.h>
52#include <ql_xioctl.h>
53
54/*
55 * Solaris external defines.
56 */
57extern pri_t minclsyspri;
58extern pri_t maxclsyspri;
59
60/*
61 * dev_ops functions prototypes
62 */
63static int ql_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
64static int ql_attach(dev_info_t *, ddi_attach_cmd_t);
65static int ql_detach(dev_info_t *, ddi_detach_cmd_t);
66static int ql_power(dev_info_t *, int, int);
67static int ql_quiesce(dev_info_t *);
68
69/*
70 * FCA functions prototypes exported by means of the transport table
71 */
72static opaque_t ql_bind_port(dev_info_t *, fc_fca_port_info_t *,
73    fc_fca_bind_info_t *);
74static void ql_unbind_port(opaque_t);
75static int ql_init_pkt(opaque_t, fc_packet_t *, int);
76static int ql_un_init_pkt(opaque_t, fc_packet_t *);
77static int ql_els_send(opaque_t, fc_packet_t *);
78static int ql_get_cap(opaque_t, char *, void *);
79static int ql_set_cap(opaque_t, char *, void *);
80static int ql_getmap(opaque_t, fc_lilpmap_t *);
81static int ql_transport(opaque_t, fc_packet_t *);
82static int ql_ub_alloc(opaque_t, uint64_t *, uint32_t, uint32_t *, uint32_t);
83static int ql_ub_free(opaque_t, uint32_t, uint64_t *);
84static int ql_ub_release(opaque_t, uint32_t, uint64_t *);
85static int ql_abort(opaque_t, fc_packet_t *, int);
86static int ql_reset(opaque_t, uint32_t);
87static int ql_notify(opaque_t, uint32_t);
88static int ql_port_manage(opaque_t, fc_fca_pm_t *);
89static opaque_t ql_get_device(opaque_t, fc_portid_t);
90
91/*
92 * FCA Driver Support Function Prototypes.
93 */
94static uint16_t	ql_wait_outstanding(ql_adapter_state_t *);
95static void ql_task_mgmt(ql_adapter_state_t *, ql_tgt_t *, fc_packet_t *,
96    ql_srb_t *);
97static void ql_task_daemon(void *);
98static void ql_task_thread(ql_adapter_state_t *);
99static void ql_unsol_callback(ql_srb_t *);
100static void ql_dev_free(ql_adapter_state_t *, ql_tgt_t *);
101static void ql_free_unsolicited_buffer(ql_adapter_state_t *,
102    fc_unsol_buf_t *);
103static void ql_timer(void *);
104static void ql_watchdog(ql_adapter_state_t *, uint32_t *, uint32_t *);
105static void ql_cmd_timeout(ql_adapter_state_t *, ql_tgt_t *q, ql_srb_t *,
106    uint32_t *, uint32_t *);
107static void ql_halt(ql_adapter_state_t *, int);
108static int ql_els_plogi(ql_adapter_state_t *, fc_packet_t *);
109static int ql_els_flogi(ql_adapter_state_t *, fc_packet_t *);
110static int ql_els_logo(ql_adapter_state_t *, fc_packet_t *);
111static int ql_els_prli(ql_adapter_state_t *, fc_packet_t *);
112static int ql_els_prlo(ql_adapter_state_t *, fc_packet_t *);
113static int ql_els_adisc(ql_adapter_state_t *, fc_packet_t *);
114static int ql_els_linit(ql_adapter_state_t *, fc_packet_t *);
115static int ql_els_lpc(ql_adapter_state_t *, fc_packet_t *);
116static int ql_els_lsts(ql_adapter_state_t *, fc_packet_t *);
117static int ql_els_scr(ql_adapter_state_t *, fc_packet_t *);
118static int ql_els_rscn(ql_adapter_state_t *, fc_packet_t *);
119static int ql_els_farp_req(ql_adapter_state_t *, fc_packet_t *);
120static int ql_els_farp_reply(ql_adapter_state_t *, fc_packet_t *);
121static int ql_els_rls(ql_adapter_state_t *, fc_packet_t *);
122static int ql_els_rnid(ql_adapter_state_t *, fc_packet_t *);
123static int ql_login_port(ql_adapter_state_t *, port_id_t);
124static int ql_login_fabric_port(ql_adapter_state_t *, ql_tgt_t *, uint16_t);
125static int ql_logout_port(ql_adapter_state_t *, port_id_t);
126static ql_lun_t *ql_lun_queue(ql_adapter_state_t *, ql_tgt_t *, uint16_t);
127static int ql_fcp_scsi_cmd(ql_adapter_state_t *, fc_packet_t *, ql_srb_t *);
128static int ql_fcp_ip_cmd(ql_adapter_state_t *, fc_packet_t *, ql_srb_t *);
129static int ql_fcp_data_rsp(ql_adapter_state_t *, fc_packet_t *, ql_srb_t *);
130static int ql_fc_services(ql_adapter_state_t *, fc_packet_t *);
131static int ql_poll_cmd(ql_adapter_state_t *, ql_srb_t *, time_t);
132static int ql_start_cmd(ql_adapter_state_t *, ql_tgt_t *, fc_packet_t *,
133    ql_srb_t *);
134static int ql_kstat_update(kstat_t *, int);
135static ql_adapter_state_t *ql_fca_handle_to_state(opaque_t);
136static ql_adapter_state_t *ql_cmd_setup(opaque_t, fc_packet_t *, int *);
137static int ql_program_flash_address(ql_adapter_state_t *, uint32_t, uint8_t);
138static void ql_rst_aen(ql_adapter_state_t *);
139static void ql_restart_queues(ql_adapter_state_t *);
140static void ql_abort_queues(ql_adapter_state_t *);
141static void ql_idle_check(ql_adapter_state_t *);
142static int ql_loop_resync(ql_adapter_state_t *);
143static size_t ql_24xx_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
144static size_t ql_25xx_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
145static int ql_save_config_regs(dev_info_t *);
146static int ql_restore_config_regs(dev_info_t *);
147static int ql_process_rscn(ql_adapter_state_t *, fc_affected_id_t *);
148static int ql_handle_rscn_update(ql_adapter_state_t *);
149static int ql_send_plogi(ql_adapter_state_t *, ql_tgt_t *, ql_head_t *);
150static int ql_process_rscn_for_device(ql_adapter_state_t *, ql_tgt_t *);
151static int ql_dump_firmware(ql_adapter_state_t *);
152static int ql_process_logo_for_device(ql_adapter_state_t *, ql_tgt_t *);
153static int ql_2200_binary_fw_dump(ql_adapter_state_t *, ql_fw_dump_t *);
154static int ql_2300_binary_fw_dump(ql_adapter_state_t *, ql_fw_dump_t *);
155static int ql_24xx_binary_fw_dump(ql_adapter_state_t *, ql_24xx_fw_dump_t *);
156static int ql_25xx_binary_fw_dump(ql_adapter_state_t *, ql_25xx_fw_dump_t *);
157static int ql_read_risc_ram(ql_adapter_state_t *, uint32_t, uint32_t,
158    void *);
159static void *ql_read_regs(ql_adapter_state_t *, void *, void *, uint32_t,
160    uint8_t);
161static int ql_busy_plogi(ql_adapter_state_t *, fc_packet_t *, ql_tgt_t *);
162static int ql_suspend_adapter(ql_adapter_state_t *);
163static int ql_bstr_to_dec(char *, uint32_t *, uint32_t);
164static void ql_update_rscn(ql_adapter_state_t *, fc_affected_id_t *);
165int ql_alloc_dma_resouce(ql_adapter_state_t *, dma_mem_t *, int);
166static int ql_bind_dma_buffer(ql_adapter_state_t *, dma_mem_t *, int);
167static void ql_unbind_dma_buffer(ql_adapter_state_t *, dma_mem_t *);
168static void ql_timeout_insert(ql_adapter_state_t *, ql_tgt_t *, ql_srb_t *);
169static int ql_setup_interrupts(ql_adapter_state_t *);
170static int ql_setup_msi(ql_adapter_state_t *);
171static int ql_setup_msix(ql_adapter_state_t *);
172static int ql_setup_fixed(ql_adapter_state_t *);
173static void ql_release_intr(ql_adapter_state_t *);
174static void ql_disable_intr(ql_adapter_state_t *);
175static int ql_legacy_intr(ql_adapter_state_t *);
176static int ql_init_mutex(ql_adapter_state_t *);
177static void ql_destroy_mutex(ql_adapter_state_t *);
178static void ql_iidma(ql_adapter_state_t *);
179
180int ql_el_trace_desc_ctor(ql_adapter_state_t *ha);
181int ql_el_trace_desc_dtor(ql_adapter_state_t *ha);
182/*
183 * Global data
184 */
185static uint8_t	ql_enable_pm = 1;
186static int	ql_flash_sbus_fpga = 0;
187uint32_t	ql_os_release_level;
188uint32_t	ql_disable_aif = 0;
189uint32_t	ql_disable_msi = 0;
190uint32_t	ql_disable_msix = 0;
191
192/* Timer routine variables. */
193static timeout_id_t	ql_timer_timeout_id = NULL;
194static clock_t		ql_timer_ticks;
195
196/* Soft state head pointer. */
197void *ql_state = NULL;
198
199/* Head adapter link. */
200ql_head_t ql_hba = {
201	NULL,
202	NULL
203};
204
205/* Global hba index */
206uint32_t ql_gfru_hba_index = 1;
207
208/*
209 * Some IP defines and globals
210 */
211uint32_t	ql_ip_buffer_count = 128;
212uint32_t	ql_ip_low_water = 10;
213uint8_t		ql_ip_fast_post_count = 5;
214static int	ql_ip_mtu = 65280;		/* equivalent to FCIPMTU */
215
216/* Device AL_PA to Device Head Queue index array. */
217uint8_t ql_alpa_to_index[] = {
218	0x7e, 0x7d, 0x7c, 0x00, 0x7b, 0x01, 0x02, 0x03, 0x7a, 0x04,
219	0x05, 0x06, 0x07, 0x08, 0x09, 0x79, 0x78, 0x0a, 0x0b, 0x0c,
220	0x0d, 0x0e, 0x0f, 0x77, 0x76, 0x10, 0x11, 0x75, 0x12, 0x74,
221	0x73, 0x72, 0x13, 0x14, 0x15, 0x71, 0x16, 0x70, 0x6f, 0x6e,
222	0x17, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x18, 0x19, 0x67,
223	0x66, 0x65, 0x64, 0x63, 0x62, 0x20, 0x21, 0x61, 0x60, 0x23,
224	0x5f, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x5e, 0x2a, 0x5d,
225	0x5c, 0x5b, 0x2b, 0x5a, 0x59, 0x58, 0x57, 0x56, 0x55, 0x2c,
226	0x2d, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x2e, 0x2f, 0x4e,
227	0x4d, 0x30, 0x4c, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x4b,
228	0x37, 0x4a, 0x49, 0x48, 0x38, 0x47, 0x46, 0x45, 0x44, 0x43,
229	0x42, 0x39, 0x3a, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b,
230	0x3c, 0x3b, 0x3a, 0x3d, 0x39, 0x3e, 0x3f, 0x40, 0x38, 0x37,
231	0x36, 0x41, 0x35, 0x42, 0x43, 0x44, 0x34, 0x45, 0x46, 0x47,
232	0x48, 0x49, 0x4a, 0x33, 0x32, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
233	0x50, 0x31, 0x30, 0x51, 0x52, 0x2f, 0x53, 0x2e, 0x2d, 0x2c,
234	0x54, 0x55, 0x56, 0x2b, 0x57, 0x2a, 0x29, 0x28, 0x58, 0x27,
235	0x26, 0x25, 0x24, 0x23, 0x22, 0x59, 0x5a, 0x21, 0x20, 0x1f,
236	0x1e, 0x1d, 0x1c, 0x5b, 0x5c, 0x1b, 0x1a, 0x5d, 0x19, 0x5e,
237	0x5f, 0x60, 0x61, 0x62, 0x63, 0x18, 0x64, 0x17, 0x16, 0x15,
238	0x65, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x66, 0x67, 0x0e,
239	0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x68, 0x69, 0x08, 0x07, 0x6a,
240	0x06, 0x6b, 0x6c, 0x6d, 0x05, 0x04, 0x03, 0x6e, 0x02, 0x6f,
241	0x70, 0x71, 0x01, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x00,
242	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7f, 0x80, 0x00, 0x01,
243	0x02, 0x03, 0x80, 0x7f, 0x7e, 0x04
244};
245
246/* Device loop_id to ALPA array. */
247static uint8_t ql_index_to_alpa[] = {
248	0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda, 0xd9, 0xd6,
249	0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce, 0xcd, 0xcc, 0xcb, 0xca,
250	0xc9, 0xc7, 0xc6, 0xc5, 0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5,
251	0xb4, 0xb3, 0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
252	0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b, 0x98, 0x97,
253	0x90, 0x8f, 0x88, 0x84, 0x82, 0x81, 0x80, 0x7c, 0x7a, 0x79,
254	0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b,
255	0x6a, 0x69, 0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
256	0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a,
257	0x49, 0x47, 0x46, 0x45, 0x43, 0x3c, 0x3a, 0x39, 0x36, 0x35,
258	0x34, 0x33, 0x32, 0x31, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29,
259	0x27, 0x26, 0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
260	0x10, 0x0f, 0x08, 0x04, 0x02, 0x01
261};
262
263/* 2200 register offsets */
264static reg_off_t reg_off_2200 = {
265	0x00, 0x02, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
266	0x18, 0x18, 0x1A, 0x1A, /* req in, out, resp in, out */
267	0x00, 0x00, /* intr info lo, hi */
268	24, /* Number of mailboxes */
269	/* Mailbox register offsets */
270	0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
271	0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee,
272	0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
273	/* 2200 does not have mailbox 24-31 */
274	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275	0x96, 0xa4, 0xb0, 0xb8, 0xc0, 0xcc, 0xce,
276	/* host to host sema */
277	0x00,
278	/* 2200 does not have pri_req_in, pri_req_out, */
279	/* atio_req_in, atio_req_out, io_base_addr */
280	0xff, 0xff, 0xff, 0xff,	0xff
281};
282
283/* 2300 register offsets */
284static reg_off_t reg_off_2300 = {
285	0x00, 0x02, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
286	0x10, 0x12, 0x14, 0x16, /* req in, out, resp in, out */
287	0x18, 0x1A, /* intr info lo, hi */
288	32, /* Number of mailboxes */
289	/* Mailbox register offsets */
290	0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e,
291	0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
292	0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e,
293	0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
294	0x96, 0xa4, 0xb0, 0x80, 0xc0, 0xcc, 0xce,
295	/* host to host sema */
296	0x1c,
297	/* 2300 does not have pri_req_in, pri_req_out, */
298	/* atio_req_in, atio_req_out, io_base_addr */
299	0xff, 0xff, 0xff, 0xff,	0xff
300};
301
302/* 2400/2500 register offsets */
303reg_off_t reg_off_2400_2500 = {
304	0x00, 0x04,		/* flash_address, flash_data */
305	0x08, 0x0c, 0x10,	/* ctrl_status, ictrl, istatus */
306	/* 2400 does not have semaphore, nvram */
307	0x14, 0x18,
308	0x1c, 0x20, 0x24, 0x28, /* req_in, req_out, resp_in, resp_out */
309	0x44, 0x46,		/* intr info lo, hi */
310	32,			/* Number of mailboxes */
311	/* Mailbox register offsets */
312	0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,
313	0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
314	0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae,
315	0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
316	/* 2400 does not have fpm_diag_config, pcr, mctr, fb_cmd */
317	0xff, 0xff, 0xff, 0xff,
318	0x48, 0x4c, 0x50,	/* hccr, gpiod, gpioe */
319	0xff,			/* host to host sema */
320	0x2c, 0x30,		/* pri_req_in, pri_req_out */
321	0x3c, 0x40,		/* atio_req_in, atio_req_out */
322	0x54			/* io_base_addr */
323};
324
325/* mutex for protecting variables shared by all instances of the driver */
326kmutex_t ql_global_mutex;
327kmutex_t ql_global_hw_mutex;
328kmutex_t ql_global_el_mutex;
329
330/* DMA access attribute structure. */
331static ddi_device_acc_attr_t ql_dev_acc_attr = {
332	DDI_DEVICE_ATTR_V0,
333	DDI_STRUCTURE_LE_ACC,
334	DDI_STRICTORDER_ACC
335};
336
337/* I/O DMA attributes structures. */
338static ddi_dma_attr_t ql_64bit_io_dma_attr = {
339	DMA_ATTR_V0,			/* dma_attr_version */
340	QL_DMA_LOW_ADDRESS,		/* low DMA address range */
341	QL_DMA_HIGH_64BIT_ADDRESS,	/* high DMA address range */
342	QL_DMA_XFER_COUNTER,		/* DMA counter register */
343	QL_DMA_ADDRESS_ALIGNMENT,	/* DMA address alignment */
344	QL_DMA_BURSTSIZES,		/* DMA burstsizes */
345	QL_DMA_MIN_XFER_SIZE,		/* min effective DMA size */
346	QL_DMA_MAX_XFER_SIZE,		/* max DMA xfer size */
347	QL_DMA_SEGMENT_BOUNDARY,	/* segment boundary */
348	QL_DMA_SG_LIST_LENGTH,		/* s/g list length */
349	QL_DMA_GRANULARITY,		/* granularity of device */
350	QL_DMA_XFER_FLAGS		/* DMA transfer flags */
351};
352
353static ddi_dma_attr_t ql_32bit_io_dma_attr = {
354	DMA_ATTR_V0,			/* dma_attr_version */
355	QL_DMA_LOW_ADDRESS,		/* low DMA address range */
356	QL_DMA_HIGH_32BIT_ADDRESS,	/* high DMA address range */
357	QL_DMA_XFER_COUNTER,		/* DMA counter register */
358	QL_DMA_ADDRESS_ALIGNMENT,	/* DMA address alignment */
359	QL_DMA_BURSTSIZES,		/* DMA burstsizes */
360	QL_DMA_MIN_XFER_SIZE,		/* min effective DMA size */
361	QL_DMA_MAX_XFER_SIZE,		/* max DMA xfer size */
362	QL_DMA_SEGMENT_BOUNDARY,	/* segment boundary */
363	QL_DMA_SG_LIST_LENGTH,		/* s/g list length */
364	QL_DMA_GRANULARITY,		/* granularity of device */
365	QL_DMA_XFER_FLAGS		/* DMA transfer flags */
366};
367
368/* Load the default dma attributes */
369static	ddi_dma_attr_t	ql_32fcsm_cmd_dma_attr;
370static	ddi_dma_attr_t	ql_64fcsm_cmd_dma_attr;
371static	ddi_dma_attr_t	ql_32fcsm_rsp_dma_attr;
372static	ddi_dma_attr_t	ql_64fcsm_rsp_dma_attr;
373static	ddi_dma_attr_t	ql_32fcip_cmd_dma_attr;
374static	ddi_dma_attr_t	ql_64fcip_cmd_dma_attr;
375static	ddi_dma_attr_t	ql_32fcip_rsp_dma_attr;
376static	ddi_dma_attr_t	ql_64fcip_rsp_dma_attr;
377static	ddi_dma_attr_t	ql_32fcp_cmd_dma_attr;
378static	ddi_dma_attr_t	ql_64fcp_cmd_dma_attr;
379static	ddi_dma_attr_t	ql_32fcp_rsp_dma_attr;
380static	ddi_dma_attr_t	ql_64fcp_rsp_dma_attr;
381static	ddi_dma_attr_t	ql_32fcp_data_dma_attr;
382static	ddi_dma_attr_t	ql_64fcp_data_dma_attr;
383
384/* Static declarations of cb_ops entry point functions... */
385static struct cb_ops ql_cb_ops = {
386	ql_open,			/* b/c open */
387	ql_close,			/* b/c close */
388	nodev,				/* b strategy */
389	nodev,				/* b print */
390	nodev,				/* b dump */
391	nodev,				/* c read */
392	nodev,				/* c write */
393	ql_ioctl,			/* c ioctl */
394	nodev,				/* c devmap */
395	nodev,				/* c mmap */
396	nodev,				/* c segmap */
397	nochpoll,			/* c poll */
398	nodev,				/* cb_prop_op */
399	NULL,				/* streamtab  */
400	D_MP | D_NEW | D_HOTPLUG,	/* Driver compatibility flag */
401	CB_REV,				/* cb_ops revision */
402	nodev,				/* c aread */
403	nodev				/* c awrite */
404};
405
406/* Static declarations of dev_ops entry point functions... */
407static struct dev_ops ql_devops = {
408	DEVO_REV,			/* devo_rev */
409	0,				/* refcnt */
410	ql_getinfo,			/* getinfo */
411	nulldev,			/* identify */
412	nulldev,			/* probe */
413	ql_attach,			/* attach */
414	ql_detach,			/* detach */
415	nodev,				/* reset */
416	&ql_cb_ops,			/* char/block ops */
417	NULL,				/* bus operations */
418	ql_power,			/* power management */
419	ql_quiesce			/* quiesce device */
420};
421
422/* ELS command code to text converter */
423cmd_table_t els_cmd_tbl[] = ELS_CMD_TABLE();
424/* Mailbox command code to text converter */
425cmd_table_t mbox_cmd_tbl[] = MBOX_CMD_TABLE();
426
427char qlc_driver_version[] = QL_VERSION;
428
429/*
430 * Loadable Driver Interface Structures.
431 * Declare and initialize the module configuration section...
432 */
433static struct modldrv modldrv = {
434	&mod_driverops,				/* type of module: driver */
435	"SunFC Qlogic FCA v" QL_VERSION,	/* name of module */
436	&ql_devops				/* driver dev_ops */
437};
438
439static struct modlinkage modlinkage = {
440	MODREV_1,
441	&modldrv,
442	NULL
443};
444
445/* ************************************************************************ */
446/*				Loadable Module Routines.		    */
447/* ************************************************************************ */
448
449/*
450 * _init
451 *	Initializes a loadable module. It is called before any other
452 *	routine in a loadable module.
453 *
454 * Returns:
455 *	0 = success
456 *
457 * Context:
458 *	Kernel context.
459 */
460int
461_init(void)
462{
463	uint16_t	w16;
464	int		rval = 0;
465
466	/* Get OS major release level. */
467	for (w16 = 0; w16 < sizeof (utsname.release); w16++) {
468		if (utsname.release[w16] == '.') {
469			w16++;
470			break;
471		}
472	}
473	if (w16 < sizeof (utsname.release)) {
474		(void) ql_bstr_to_dec(&utsname.release[w16],
475		    &ql_os_release_level, 0);
476	} else {
477		ql_os_release_level = 0;
478	}
479	if (ql_os_release_level < 6) {
480		cmn_err(CE_WARN, "%s Unsupported OS release level = %d",
481		    QL_NAME, ql_os_release_level);
482		rval = EINVAL;
483	}
484	if (ql_os_release_level == 6) {
485		ql_32bit_io_dma_attr.dma_attr_count_max = 0x00ffffff;
486		ql_64bit_io_dma_attr.dma_attr_count_max = 0x00ffffff;
487	}
488
489	if (rval == 0) {
490		rval = ddi_soft_state_init(&ql_state,
491		    sizeof (ql_adapter_state_t), 0);
492	}
493	if (rval == 0) {
494		/* allow the FC Transport to tweak the dev_ops */
495		fc_fca_init(&ql_devops);
496
497		mutex_init(&ql_global_mutex, NULL, MUTEX_DRIVER, NULL);
498		mutex_init(&ql_global_hw_mutex, NULL, MUTEX_DRIVER, NULL);
499		mutex_init(&ql_global_el_mutex, NULL, MUTEX_DRIVER, NULL);
500		rval = mod_install(&modlinkage);
501		if (rval != 0) {
502			mutex_destroy(&ql_global_hw_mutex);
503			mutex_destroy(&ql_global_mutex);
504			mutex_destroy(&ql_global_el_mutex);
505			ddi_soft_state_fini(&ql_state);
506		} else {
507			/*EMPTY*/
508			ql_32fcsm_cmd_dma_attr = ql_32bit_io_dma_attr;
509			ql_64fcsm_cmd_dma_attr = ql_64bit_io_dma_attr;
510			ql_32fcsm_rsp_dma_attr = ql_32bit_io_dma_attr;
511			ql_64fcsm_rsp_dma_attr = ql_64bit_io_dma_attr;
512			ql_32fcip_cmd_dma_attr = ql_32bit_io_dma_attr;
513			ql_64fcip_cmd_dma_attr = ql_64bit_io_dma_attr;
514			ql_32fcip_rsp_dma_attr = ql_32bit_io_dma_attr;
515			ql_64fcip_rsp_dma_attr = ql_64bit_io_dma_attr;
516			ql_32fcp_cmd_dma_attr = ql_32bit_io_dma_attr;
517			ql_64fcp_cmd_dma_attr = ql_64bit_io_dma_attr;
518			ql_32fcp_rsp_dma_attr = ql_32bit_io_dma_attr;
519			ql_64fcp_rsp_dma_attr = ql_64bit_io_dma_attr;
520			ql_32fcp_data_dma_attr = ql_32bit_io_dma_attr;
521			ql_64fcp_data_dma_attr = ql_64bit_io_dma_attr;
522			ql_32fcsm_cmd_dma_attr.dma_attr_sgllen =
523			    ql_64fcsm_cmd_dma_attr.dma_attr_sgllen =
524			    QL_FCSM_CMD_SGLLEN;
525			ql_32fcsm_rsp_dma_attr.dma_attr_sgllen =
526			    ql_64fcsm_rsp_dma_attr.dma_attr_sgllen =
527			    QL_FCSM_RSP_SGLLEN;
528			ql_32fcip_cmd_dma_attr.dma_attr_sgllen =
529			    ql_64fcip_cmd_dma_attr.dma_attr_sgllen =
530			    QL_FCIP_CMD_SGLLEN;
531			ql_32fcip_rsp_dma_attr.dma_attr_sgllen =
532			    ql_64fcip_rsp_dma_attr.dma_attr_sgllen =
533			    QL_FCIP_RSP_SGLLEN;
534			ql_32fcp_cmd_dma_attr.dma_attr_sgllen =
535			    ql_64fcp_cmd_dma_attr.dma_attr_sgllen =
536			    QL_FCP_CMD_SGLLEN;
537			ql_32fcp_rsp_dma_attr.dma_attr_sgllen =
538			    ql_64fcp_rsp_dma_attr.dma_attr_sgllen =
539			    QL_FCP_RSP_SGLLEN;
540		}
541	}
542
543	if (rval != 0) {
544		cmn_err(CE_CONT, "?Unable to install/attach driver '%s'",
545		    QL_NAME);
546	}
547
548	return (rval);
549}
550
551/*
552 * _fini
553 *	Prepares a module for unloading. It is called when the system
554 *	wants to unload a module. If the module determines that it can
555 *	be unloaded, then _fini() returns the value returned by
556 *	mod_remove(). Upon successful return from _fini() no other
557 *	routine in the module will be called before _init() is called.
558 *
559 * Returns:
560 *	0 = success
561 *
562 * Context:
563 *	Kernel context.
564 */
565int
566_fini(void)
567{
568	int	rval;
569
570	rval = mod_remove(&modlinkage);
571	if (rval == 0) {
572		mutex_destroy(&ql_global_hw_mutex);
573		mutex_destroy(&ql_global_mutex);
574		mutex_destroy(&ql_global_el_mutex);
575		ddi_soft_state_fini(&ql_state);
576	}
577
578	return (rval);
579}
580
581/*
582 * _info
583 *	Returns information about loadable module.
584 *
585 * Input:
586 *	modinfo = pointer to module information structure.
587 *
588 * Returns:
589 *	Value returned by mod_info().
590 *
591 * Context:
592 *	Kernel context.
593 */
594int
595_info(struct modinfo *modinfop)
596{
597	return (mod_info(&modlinkage, modinfop));
598}
599
600/* ************************************************************************ */
601/*			dev_ops functions				    */
602/* ************************************************************************ */
603
604/*
605 * ql_getinfo
606 *	Returns the pointer associated with arg when cmd is
607 *	set to DDI_INFO_DEVT2DEVINFO, or it should return the
608 *	instance number associated with arg when cmd is set
609 *	to DDI_INFO_DEV2INSTANCE.
610 *
611 * Input:
612 *	dip = Do not use.
613 *	cmd = command argument.
614 *	arg = command specific argument.
615 *	resultp = pointer to where request information is stored.
616 *
617 * Returns:
618 *	DDI_SUCCESS or DDI_FAILURE.
619 *
620 * Context:
621 *	Kernel context.
622 */
623/* ARGSUSED */
624static int
625ql_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
626{
627	ql_adapter_state_t	*ha;
628	int			minor;
629	int			rval = DDI_FAILURE;
630
631	minor = (int)(getminor((dev_t)arg));
632	ha = ddi_get_soft_state(ql_state, minor);
633	if (ha == NULL) {
634		QL_PRINT_2(CE_CONT, "failed, unknown minor=%d\n",
635		    getminor((dev_t)arg));
636		*resultp = NULL;
637		return (rval);
638	}
639
640	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
641
642	switch (cmd) {
643	case DDI_INFO_DEVT2DEVINFO:
644		*resultp = ha->dip;
645		rval = DDI_SUCCESS;
646		break;
647	case DDI_INFO_DEVT2INSTANCE:
648		*resultp = (void *)(uintptr_t)(ha->instance);
649		rval = DDI_SUCCESS;
650		break;
651	default:
652		EL(ha, "failed, unsupported cmd=%d\n", cmd);
653		rval = DDI_FAILURE;
654		break;
655	}
656
657	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
658
659	return (rval);
660}
661
662/*
663 * ql_attach
664 *	Configure and attach an instance of the driver
665 *	for a port.
666 *
667 * Input:
668 *	dip = pointer to device information structure.
669 *	cmd = attach type.
670 *
671 * Returns:
672 *	DDI_SUCCESS or DDI_FAILURE.
673 *
674 * Context:
675 *	Kernel context.
676 */
677static int
678ql_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
679{
680	uint32_t		size;
681	int			rval;
682	int			instance;
683	uint_t			progress = 0;
684	char			*buf;
685	ushort_t		caps_ptr, cap;
686	fc_fca_tran_t		*tran;
687	ql_adapter_state_t	*ha = NULL;
688
689	static char *pmcomps[] = {
690		NULL,
691		PM_LEVEL_D3_STR,		/* Device OFF */
692		PM_LEVEL_D0_STR,		/* Device ON */
693	};
694
695	QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n",
696	    ddi_get_instance(dip), cmd);
697
698	buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
699
700	switch (cmd) {
701	case DDI_ATTACH:
702		/* first get the instance */
703		instance = ddi_get_instance(dip);
704
705		cmn_err(CE_CONT, "!Qlogic %s(%d) FCA Driver v%s\n",
706		    QL_NAME, instance, QL_VERSION);
707
708		/* Correct OS version? */
709		if (ql_os_release_level != 11) {
710			cmn_err(CE_WARN, "%s(%d): This driver is for Solaris "
711			    "11", QL_NAME, instance);
712			goto attach_failed;
713		}
714
715		/* Hardware is installed in a DMA-capable slot? */
716		if (ddi_slaveonly(dip) == DDI_SUCCESS) {
717			cmn_err(CE_WARN, "%s(%d): slave only", QL_NAME,
718			    instance);
719			goto attach_failed;
720		}
721
722		/* No support for high-level interrupts */
723		if (ddi_intr_hilevel(dip, 0) != 0) {
724			cmn_err(CE_WARN, "%s(%d): High level interrupt"
725			    " not supported", QL_NAME, instance);
726			goto attach_failed;
727		}
728
729		/* Allocate our per-device-instance structure */
730		if (ddi_soft_state_zalloc(ql_state,
731		    instance) != DDI_SUCCESS) {
732			cmn_err(CE_WARN, "%s(%d): soft state alloc failed",
733			    QL_NAME, instance);
734			goto attach_failed;
735		}
736		progress |= QL_SOFT_STATE_ALLOCED;
737
738		ha = ddi_get_soft_state(ql_state, instance);
739		if (ha == NULL) {
740			cmn_err(CE_WARN, "%s(%d): can't get soft state",
741			    QL_NAME, instance);
742			goto attach_failed;
743		}
744		ha->dip = dip;
745		ha->instance = instance;
746		ha->hba.base_address = ha;
747		ha->pha = ha;
748
749		if (ql_el_trace_desc_ctor(ha) != DDI_SUCCESS) {
750			cmn_err(CE_WARN, "%s(%d): can't setup el tracing",
751			    QL_NAME, instance);
752			goto attach_failed;
753		}
754
755		/* Get extended logging and dump flags. */
756		ql_common_properties(ha);
757
758		if (strcmp(ddi_driver_name(ddi_get_parent(dip)),
759		    "sbus") == 0) {
760			EL(ha, "%s SBUS card detected", QL_NAME);
761			ha->cfg_flags |= CFG_SBUS_CARD;
762		}
763
764		ha->dev = kmem_zalloc(sizeof (*ha->dev) *
765		    DEVICE_HEAD_LIST_SIZE, KM_SLEEP);
766
767		ha->outstanding_cmds = kmem_zalloc(
768		    sizeof (*ha->outstanding_cmds) * MAX_OUTSTANDING_COMMANDS,
769		    KM_SLEEP);
770
771		ha->ub_array = kmem_zalloc(sizeof (*ha->ub_array) *
772		    QL_UB_LIMIT, KM_SLEEP);
773
774		ha->adapter_stats = kmem_zalloc(sizeof (*ha->adapter_stats),
775		    KM_SLEEP);
776
777		(void) ddi_pathname(dip, buf);
778		ha->devpath = kmem_zalloc(strlen(buf)+1, KM_SLEEP);
779		if (ha->devpath == NULL) {
780			EL(ha, "devpath mem alloc failed\n");
781		} else {
782			(void) strcpy(ha->devpath, buf);
783			EL(ha, "devpath is: %s\n", ha->devpath);
784		}
785
786		if (CFG_IST(ha, CFG_SBUS_CARD)) {
787			/*
788			 * For cards where PCI is mapped to sbus e.g. Ivory.
789			 *
790			 * 0x00	: 0x000 - 0x0FF PCI Config Space for 2200
791			 *	: 0x100 - 0x3FF PCI IO space for 2200
792			 * 0x01	: 0x000 - 0x0FF PCI Config Space for fpga
793			 *	: 0x100 - 0x3FF PCI IO Space for fpga
794			 */
795			if (ddi_regs_map_setup(dip, 0, (caddr_t *)&ha->iobase,
796			    0x100, 0x300, &ql_dev_acc_attr, &ha->dev_handle)
797			    != DDI_SUCCESS) {
798				cmn_err(CE_WARN, "%s(%d): Unable to map device"
799				    " registers", QL_NAME, instance);
800				goto attach_failed;
801			}
802			if (ddi_regs_map_setup(dip, 1,
803			    (caddr_t *)&ha->sbus_fpga_iobase, 0, 0x400,
804			    &ql_dev_acc_attr, &ha->sbus_fpga_dev_handle)
805			    != DDI_SUCCESS) {
806				/* We should not fail attach here */
807				cmn_err(CE_WARN, "%s(%d): Unable to map FPGA",
808				    QL_NAME, instance);
809				ha->sbus_fpga_iobase = NULL;
810			}
811			progress |= QL_REGS_MAPPED;
812		} else {
813			/*
814			 * Setup the ISP2200 registers address mapping to be
815			 * accessed by this particular driver.
816			 * 0x0   Configuration Space
817			 * 0x1   I/O Space
818			 * 0x2   32-bit Memory Space address
819			 * 0x3   64-bit Memory Space address
820			 */
821			if (ddi_regs_map_setup(dip, 2, (caddr_t *)&ha->iobase,
822			    0, 0x100, &ql_dev_acc_attr,
823			    &ha->dev_handle) != DDI_SUCCESS) {
824				cmn_err(CE_WARN, "%s(%d): regs_map_setup "
825				    "failed", QL_NAME, instance);
826				goto attach_failed;
827			}
828			progress |= QL_REGS_MAPPED;
829
830			/*
831			 * We need I/O space mappings for 23xx HBAs for
832			 * loading flash (FCode). The chip has a bug due to
833			 * which loading flash fails through mem space
834			 * mappings in PCI-X mode.
835			 */
836			if (ddi_regs_map_setup(dip, 1,
837			    (caddr_t *)&ha->iomap_iobase, 0, 0x100,
838			    &ql_dev_acc_attr,
839			    &ha->iomap_dev_handle) != DDI_SUCCESS) {
840				cmn_err(CE_WARN, "%s(%d): regs_map_setup(I/O)"
841				    " failed", QL_NAME, instance);
842				goto attach_failed;
843			}
844			progress |= QL_IOMAP_IOBASE_MAPPED;
845		}
846
847		/*
848		 * We should map config space before adding interrupt
849		 * So that the chip type (2200 or 2300) can be determined
850		 * before the interrupt routine gets a chance to execute.
851		 */
852		if (CFG_IST(ha, CFG_SBUS_CARD)) {
853			if (ddi_regs_map_setup(dip, 0,
854			    (caddr_t *)&ha->sbus_config_base, 0, 0x100,
855			    &ql_dev_acc_attr, &ha->sbus_config_handle) !=
856			    DDI_SUCCESS) {
857				cmn_err(CE_WARN, "%s(%d): Unable to map sbus "
858				    "config registers", QL_NAME, instance);
859				goto attach_failed;
860			}
861		} else {
862			if (pci_config_setup(ha->dip, &ha->pci_handle) !=
863			    DDI_SUCCESS) {
864				cmn_err(CE_WARN, "%s(%d): can't setup PCI "
865				    "config space", QL_NAME, instance);
866				goto attach_failed;
867			}
868		}
869		progress |= QL_CONFIG_SPACE_SETUP;
870
871		ha->subsys_id = (uint16_t)ql_pci_config_get16(ha,
872		    PCI_CONF_SUBSYSID);
873		ha->subven_id = (uint16_t)ql_pci_config_get16(ha,
874		    PCI_CONF_SUBVENID);
875		ha->ven_id = (uint16_t)ql_pci_config_get16(ha,
876		    PCI_CONF_VENID);
877		ha->device_id = (uint16_t)ql_pci_config_get16(ha,
878		    PCI_CONF_DEVID);
879		ha->rev_id = (uint8_t)ql_pci_config_get8(ha,
880		    PCI_CONF_REVID);
881
882		EL(ha, "ISP%x chip detected (RevID=%x, VenID=%x, SVenID=%x, "
883		    "SSysID=%x)\n", ha->device_id, ha->rev_id, ha->ven_id,
884		    ha->subven_id, ha->subsys_id);
885
886		switch (ha->device_id) {
887		case 0x2300:
888		case 0x2312:
889#if !defined(__sparc) || defined(QL_DEBUG_ROUTINES)
890		case 0x6312:
891#endif	/* !defined(__sparc) || defined(QL_DEBUG_ROUTINES) */
892			ha->cfg_flags |= CFG_CTRL_2300;
893			ha->fw_class = 0x2300;
894			ha->reg_off = &reg_off_2300;
895			if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
896				goto attach_failed;
897			}
898			ha->risc_dump_size = QL_2300_FW_DUMP_SIZE;
899			ha->fcp_cmd = ql_command_iocb;
900			ha->ip_cmd = ql_ip_iocb;
901			ha->ms_cmd = ql_ms_iocb;
902			ha->ctio_cmd = ql_continue_target_io_iocb;
903			break;
904
905#if !defined(__sparc) || defined(QL_DEBUG_ROUTINES)
906		case 0x6322:
907			/*
908			 * per marketing, fibre-lite HBA's are not supported
909			 * on sparc platforms
910			 */
911			ha->cfg_flags |= CFG_CTRL_6322;
912			ha->fw_class = 0x6322;
913			ha->reg_off = &reg_off_2300;
914			if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
915				goto attach_failed;
916			}
917			ha->risc_dump_size = QL_6322_FW_DUMP_SIZE;
918			ha->fcp_cmd = ql_command_iocb;
919			ha->ip_cmd = ql_ip_iocb;
920			ha->ms_cmd = ql_ms_iocb;
921			ha->ctio_cmd = ql_continue_target_io_iocb;
922			break;
923
924#endif	/* !defined(__sparc) || defined(QL_DEBUG_ROUTINES) */
925		case 0x2200:
926			ha->cfg_flags |= CFG_CTRL_2200;
927			ha->reg_off = &reg_off_2200;
928			ha->fw_class = 0x2200;
929			if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
930				goto attach_failed;
931			}
932			ha->risc_dump_size = QL_2200_FW_DUMP_SIZE;
933			ha->fcp_cmd = ql_command_iocb;
934			ha->ip_cmd = ql_ip_iocb;
935			ha->ms_cmd = ql_ms_iocb;
936			ha->ctio_cmd = ql_continue_target_io_iocb;
937			break;
938
939		case 0x2422:
940		case 0x2432:
941		case 0x5422:
942		case 0x5432:
943		case 0x8432:
944#ifdef __sparc
945			/*
946			 * Per marketing, the QLA/QLE-2440's (which
947			 * also use the 2422 & 2432) are only for the
948			 * x86 platform (SMB market).
949			 */
950			if (ha->subsys_id == 0x145 || ha->subsys_id == 0x147 ||
951			    ha->subsys_id == 0x13e) {
952				cmn_err(CE_WARN,
953				    "%s(%d): Unsupported HBA ssid: %x",
954				    QL_NAME, instance, ha->subsys_id);
955				goto attach_failed;
956			}
957#endif	/* __sparc */
958			ha->cfg_flags |= CFG_CTRL_2422;
959			if (ha->device_id == 0x8432) {
960				ha->cfg_flags |= CFG_CTRL_MENLO;
961			} else {
962				ha->flags |= VP_ENABLED;
963			}
964
965			ha->reg_off = &reg_off_2400_2500;
966			ha->fw_class = 0x2400;
967			if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
968				goto attach_failed;
969			}
970			ha->risc_dump_size = QL_24XX_FW_DUMP_SIZE;
971			ha->fcp_cmd = ql_command_24xx_iocb;
972			ha->ip_cmd = ql_ip_24xx_iocb;
973			ha->ms_cmd = ql_ms_24xx_iocb;
974			ha->ctio_cmd = ql_continue_target_io_2400_iocb;
975			ha->flash_errlog_start = RD32_IO_REG(ha, ctrl_status) &
976			    FUNCTION_NUMBER ? FLASH_2400_ERRLOG_START_ADDR_1 :
977			    FLASH_2400_ERRLOG_START_ADDR_0;
978			break;
979
980		case 0x2522:
981		case 0x2532:
982			ha->cfg_flags |= CFG_CTRL_25XX;
983			ha->flags |= VP_ENABLED;
984			ha->fw_class = 0x2500;
985			ha->reg_off = &reg_off_2400_2500;
986			if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
987				goto attach_failed;
988			}
989			ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE;
990			ha->fcp_cmd = ql_command_24xx_iocb;
991			ha->ip_cmd = ql_ip_24xx_iocb;
992			ha->ms_cmd = ql_ms_24xx_iocb;
993			ha->ctio_cmd = ql_continue_target_io_2400_iocb;
994			ha->flash_errlog_start = RD32_IO_REG(ha, ctrl_status) &
995			    FUNCTION_NUMBER ? FLASH_2500_ERRLOG_START_ADDR_1 :
996			    FLASH_2500_ERRLOG_START_ADDR_0;
997			break;
998
999		default:
1000			cmn_err(CE_WARN, "%s(%d): Unsupported device id: %x",
1001			    QL_NAME, instance, ha->device_id);
1002			goto attach_failed;
1003		}
1004
1005		/* Setup hba buffer. */
1006
1007		size = CFG_IST(ha, CFG_CTRL_2425) ?
1008		    (REQUEST_QUEUE_SIZE + RESPONSE_QUEUE_SIZE) :
1009		    (REQUEST_QUEUE_SIZE + RESPONSE_QUEUE_SIZE +
1010		    RCVBUF_QUEUE_SIZE);
1011
1012		if (ql_get_dma_mem(ha, &ha->hba_buf, size, LITTLE_ENDIAN_DMA,
1013		    QL_DMA_RING_ALIGN) != QL_SUCCESS) {
1014			cmn_err(CE_WARN, "%s(%d): request queue DMA memory "
1015			    "alloc failed", QL_NAME, instance);
1016			goto attach_failed;
1017		}
1018		progress |= QL_HBA_BUFFER_SETUP;
1019
1020		/* Setup buffer pointers. */
1021		ha->request_dvma = ha->hba_buf.cookie.dmac_laddress +
1022		    REQUEST_Q_BUFFER_OFFSET;
1023		ha->request_ring_bp = (struct cmd_entry *)
1024		    ((caddr_t)ha->hba_buf.bp + REQUEST_Q_BUFFER_OFFSET);
1025
1026		ha->response_dvma = ha->hba_buf.cookie.dmac_laddress +
1027		    RESPONSE_Q_BUFFER_OFFSET;
1028		ha->response_ring_bp = (struct sts_entry *)
1029		    ((caddr_t)ha->hba_buf.bp + RESPONSE_Q_BUFFER_OFFSET);
1030
1031		ha->rcvbuf_dvma = ha->hba_buf.cookie.dmac_laddress +
1032		    RCVBUF_Q_BUFFER_OFFSET;
1033		ha->rcvbuf_ring_bp = (struct rcvbuf *)
1034		    ((caddr_t)ha->hba_buf.bp + RCVBUF_Q_BUFFER_OFFSET);
1035
1036		/* Allocate resource for QLogic IOCTL */
1037		(void) ql_alloc_xioctl_resource(ha);
1038
1039		/* Setup interrupts */
1040		if ((rval = ql_setup_interrupts(ha)) != DDI_SUCCESS) {
1041			cmn_err(CE_WARN, "%s(%d): Failed to add interrupt, "
1042			    "rval=%xh", QL_NAME, instance, rval);
1043			goto attach_failed;
1044		}
1045
1046		progress |= (QL_INTR_ADDED | QL_MUTEX_CV_INITED);
1047
1048		/*
1049		 * Determine support for Power Management
1050		 */
1051		caps_ptr = (uint8_t)ql_pci_config_get8(ha, PCI_CONF_CAP_PTR);
1052
1053		while (caps_ptr != PCI_CAP_NEXT_PTR_NULL) {
1054			cap = (uint8_t)ql_pci_config_get8(ha, caps_ptr);
1055			if (cap == PCI_CAP_ID_PM) {
1056				ha->pm_capable = 1;
1057				break;
1058			}
1059			caps_ptr = (uint8_t)ql_pci_config_get8(ha, caps_ptr +
1060			    PCI_CAP_NEXT_PTR);
1061		}
1062
1063		if (ha->pm_capable) {
1064			/*
1065			 * Enable PM for 2200 based HBAs only.
1066			 */
1067			if (ha->device_id != 0x2200) {
1068				ha->pm_capable = 0;
1069			}
1070		}
1071
1072		if (ha->pm_capable) {
1073			ha->pm_capable = ql_enable_pm;
1074		}
1075
1076		if (ha->pm_capable) {
1077			/*
1078			 * Initialize power management bookkeeping;
1079			 * components are created idle.
1080			 */
1081			(void) sprintf(buf, "NAME=%s(%d)", QL_NAME, instance);
1082			pmcomps[0] = buf;
1083
1084			/*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/
1085			if (ddi_prop_update_string_array(DDI_DEV_T_NONE,
1086			    dip, "pm-components", pmcomps,
1087			    sizeof (pmcomps) / sizeof (pmcomps[0])) !=
1088			    DDI_PROP_SUCCESS) {
1089				cmn_err(CE_WARN, "%s(%d): failed to create"
1090				    " pm-components property", QL_NAME,
1091				    instance);
1092
1093				/* Initialize adapter. */
1094				ha->power_level = PM_LEVEL_D0;
1095				if (ql_initialize_adapter(ha) != QL_SUCCESS) {
1096					cmn_err(CE_WARN, "%s(%d): failed to"
1097					    " initialize adapter", QL_NAME,
1098					    instance);
1099					goto attach_failed;
1100				}
1101			} else {
1102				ha->power_level = PM_LEVEL_D3;
1103				if (pm_raise_power(dip, QL_POWER_COMPONENT,
1104				    PM_LEVEL_D0) != DDI_SUCCESS) {
1105					cmn_err(CE_WARN, "%s(%d): failed to"
1106					    " raise power or initialize"
1107					    " adapter", QL_NAME, instance);
1108				}
1109				ASSERT(ha->power_level == PM_LEVEL_D0);
1110			}
1111		} else {
1112			/* Initialize adapter. */
1113			ha->power_level = PM_LEVEL_D0;
1114			if (ql_initialize_adapter(ha) != QL_SUCCESS) {
1115				cmn_err(CE_WARN, "%s(%d): failed to initialize"
1116				    " adapter", QL_NAME, instance);
1117			}
1118		}
1119
1120		if (ha->fw_major_version == 0 && ha->fw_minor_version == 0 &&
1121		    ha->fw_subminor_version == 0) {
1122			cmn_err(CE_NOTE, "!%s(%d): Firmware not loaded",
1123			    QL_NAME, ha->instance);
1124		} else {
1125			cmn_err(CE_NOTE, "!%s(%d): Firmware version %d.%d.%d",
1126			    QL_NAME, ha->instance, ha->fw_major_version,
1127			    ha->fw_minor_version, ha->fw_subminor_version);
1128		}
1129
1130		ha->k_stats = kstat_create(QL_NAME, instance, "statistics",
1131		    "controller", KSTAT_TYPE_RAW,
1132		    (uint32_t)sizeof (ql_adapter_stat_t), KSTAT_FLAG_VIRTUAL);
1133		if (ha->k_stats == NULL) {
1134			cmn_err(CE_WARN, "%s(%d): Failed to create kstat",
1135			    QL_NAME, instance);
1136			goto attach_failed;
1137		}
1138		progress |= QL_KSTAT_CREATED;
1139
1140		ha->adapter_stats->version = 1;
1141		ha->k_stats->ks_data = (void *)ha->adapter_stats;
1142		ha->k_stats->ks_private = ha;
1143		ha->k_stats->ks_update = ql_kstat_update;
1144		ha->k_stats->ks_ndata = 1;
1145		ha->k_stats->ks_data_size = sizeof (ql_adapter_stat_t);
1146		kstat_install(ha->k_stats);
1147
1148		if (ddi_create_minor_node(dip, "devctl", S_IFCHR,
1149		    instance, DDI_NT_NEXUS, 0) != DDI_SUCCESS) {
1150			cmn_err(CE_WARN, "%s(%d): failed to create minor node",
1151			    QL_NAME, instance);
1152			goto attach_failed;
1153		}
1154		progress |= QL_MINOR_NODE_CREATED;
1155
1156		/* Allocate a transport structure for this instance */
1157		tran = kmem_zalloc(sizeof (fc_fca_tran_t), KM_SLEEP);
1158		ASSERT(tran != NULL);
1159
1160		progress |= QL_FCA_TRAN_ALLOCED;
1161
1162		/* fill in the structure */
1163		tran->fca_numports = 1;
1164		tran->fca_version = FCTL_FCA_MODREV_5;
1165		if (CFG_IST(ha, CFG_CTRL_2422)) {
1166			tran->fca_num_npivports = MAX_24_VIRTUAL_PORTS;
1167		} else if (CFG_IST(ha, CFG_CTRL_25XX)) {
1168			tran->fca_num_npivports = MAX_25_VIRTUAL_PORTS;
1169		}
1170		bcopy(ha->loginparams.node_ww_name.raw_wwn,
1171		    tran->fca_perm_pwwn.raw_wwn, 8);
1172
1173		EL(ha, "FCA version %d\n", tran->fca_version);
1174
1175		/* Specify the amount of space needed in each packet */
1176		tran->fca_pkt_size = sizeof (ql_srb_t);
1177
1178		/* command limits are usually dictated by hardware */
1179		tran->fca_cmd_max = MAX_OUTSTANDING_COMMANDS;
1180
1181		/* dmaattr are static, set elsewhere. */
1182		if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
1183			tran->fca_dma_attr = &ql_64bit_io_dma_attr;
1184			tran->fca_dma_fcp_cmd_attr = &ql_64fcp_cmd_dma_attr;
1185			tran->fca_dma_fcp_rsp_attr = &ql_64fcp_rsp_dma_attr;
1186			tran->fca_dma_fcp_data_attr = &ql_64fcp_data_dma_attr;
1187			tran->fca_dma_fcsm_cmd_attr = &ql_64fcsm_cmd_dma_attr;
1188			tran->fca_dma_fcsm_rsp_attr = &ql_64fcsm_rsp_dma_attr;
1189			tran->fca_dma_fcip_cmd_attr = &ql_64fcip_cmd_dma_attr;
1190			tran->fca_dma_fcip_rsp_attr = &ql_64fcip_rsp_dma_attr;
1191		} else {
1192			tran->fca_dma_attr = &ql_32bit_io_dma_attr;
1193			tran->fca_dma_fcp_cmd_attr = &ql_32fcp_cmd_dma_attr;
1194			tran->fca_dma_fcp_rsp_attr = &ql_32fcp_rsp_dma_attr;
1195			tran->fca_dma_fcp_data_attr = &ql_32fcp_data_dma_attr;
1196			tran->fca_dma_fcsm_cmd_attr = &ql_32fcsm_cmd_dma_attr;
1197			tran->fca_dma_fcsm_rsp_attr = &ql_32fcsm_rsp_dma_attr;
1198			tran->fca_dma_fcip_cmd_attr = &ql_32fcip_cmd_dma_attr;
1199			tran->fca_dma_fcip_rsp_attr = &ql_32fcip_rsp_dma_attr;
1200		}
1201
1202		tran->fca_acc_attr = &ql_dev_acc_attr;
1203		tran->fca_iblock = &(ha->iblock_cookie);
1204
1205		/* the remaining values are simply function vectors */
1206		tran->fca_bind_port = ql_bind_port;
1207		tran->fca_unbind_port = ql_unbind_port;
1208		tran->fca_init_pkt = ql_init_pkt;
1209		tran->fca_un_init_pkt = ql_un_init_pkt;
1210		tran->fca_els_send = ql_els_send;
1211		tran->fca_get_cap = ql_get_cap;
1212		tran->fca_set_cap = ql_set_cap;
1213		tran->fca_getmap = ql_getmap;
1214		tran->fca_transport = ql_transport;
1215		tran->fca_ub_alloc = ql_ub_alloc;
1216		tran->fca_ub_free = ql_ub_free;
1217		tran->fca_ub_release = ql_ub_release;
1218		tran->fca_abort = ql_abort;
1219		tran->fca_reset = ql_reset;
1220		tran->fca_port_manage = ql_port_manage;
1221		tran->fca_get_device = ql_get_device;
1222		tran->fca_notify = ql_notify;
1223
1224		/* give it to the FC transport */
1225		if (fc_fca_attach(dip, tran) != DDI_SUCCESS) {
1226			cmn_err(CE_WARN, "%s(%d): FCA attach failed", QL_NAME,
1227			    instance);
1228			goto attach_failed;
1229		}
1230		progress |= QL_FCA_ATTACH_DONE;
1231
1232		/* Stash the structure so it can be freed at detach */
1233		ha->tran = tran;
1234
1235		/* Acquire global state lock. */
1236		GLOBAL_STATE_LOCK();
1237
1238		/* Add adapter structure to link list. */
1239		ql_add_link_b(&ql_hba, &ha->hba);
1240
1241		/* Start one second driver timer. */
1242		if (ql_timer_timeout_id == NULL) {
1243			ql_timer_ticks = drv_usectohz(1000000);
1244			ql_timer_timeout_id = timeout(ql_timer, (void *)0,
1245			    ql_timer_ticks);
1246		}
1247
1248		/* Release global state lock. */
1249		GLOBAL_STATE_UNLOCK();
1250
1251		/* Determine and populate HBA fru info */
1252		ql_setup_fruinfo(ha);
1253
1254		/* Setup task_daemon thread. */
1255		(void) thread_create(NULL, 0, (void (*)())ql_task_daemon, ha,
1256		    0, &p0, TS_RUN, minclsyspri);
1257
1258		progress |= QL_TASK_DAEMON_STARTED;
1259
1260		ddi_report_dev(dip);
1261
1262		/* Disable link reset in panic path */
1263		ha->lip_on_panic = 1;
1264
1265		rval = DDI_SUCCESS;
1266		break;
1267
1268attach_failed:
1269		if (progress & QL_FCA_ATTACH_DONE) {
1270			(void) fc_fca_detach(dip);
1271			progress &= ~QL_FCA_ATTACH_DONE;
1272		}
1273
1274		if (progress & QL_FCA_TRAN_ALLOCED) {
1275			kmem_free(tran, sizeof (fc_fca_tran_t));
1276			progress &= ~QL_FCA_TRAN_ALLOCED;
1277		}
1278
1279		if (progress & QL_MINOR_NODE_CREATED) {
1280			ddi_remove_minor_node(dip, "devctl");
1281			progress &= ~QL_MINOR_NODE_CREATED;
1282		}
1283
1284		if (progress & QL_KSTAT_CREATED) {
1285			kstat_delete(ha->k_stats);
1286			progress &= ~QL_KSTAT_CREATED;
1287		}
1288
1289		if (progress & QL_TASK_DAEMON_STARTED) {
1290			TASK_DAEMON_LOCK(ha);
1291
1292			ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG;
1293
1294			cv_signal(&ha->cv_task_daemon);
1295
1296			/* Release task daemon lock. */
1297			TASK_DAEMON_UNLOCK(ha);
1298
1299			/* Wait for for task daemon to stop running. */
1300			while (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
1301				ql_delay(ha, 10000);
1302			}
1303			progress &= ~QL_TASK_DAEMON_STARTED;
1304		}
1305
1306		if (progress & QL_IOMAP_IOBASE_MAPPED) {
1307			ddi_regs_map_free(&ha->iomap_dev_handle);
1308			progress &= ~QL_IOMAP_IOBASE_MAPPED;
1309		}
1310
1311		if (progress & QL_CONFIG_SPACE_SETUP) {
1312			if (CFG_IST(ha, CFG_SBUS_CARD)) {
1313				ddi_regs_map_free(&ha->sbus_config_handle);
1314			} else {
1315				pci_config_teardown(&ha->pci_handle);
1316			}
1317			progress &= ~QL_CONFIG_SPACE_SETUP;
1318		}
1319
1320		if (progress & QL_INTR_ADDED) {
1321			ql_disable_intr(ha);
1322			ql_release_intr(ha);
1323			progress &= ~QL_INTR_ADDED;
1324		}
1325
1326		if (progress & QL_MUTEX_CV_INITED) {
1327			ql_destroy_mutex(ha);
1328			progress &= ~QL_MUTEX_CV_INITED;
1329		}
1330
1331		if (progress & QL_HBA_BUFFER_SETUP) {
1332			ql_free_phys(ha, &ha->hba_buf);
1333			progress &= ~QL_HBA_BUFFER_SETUP;
1334		}
1335
1336		if (progress & QL_REGS_MAPPED) {
1337			ddi_regs_map_free(&ha->dev_handle);
1338			if (ha->sbus_fpga_iobase != NULL) {
1339				ddi_regs_map_free(&ha->sbus_fpga_dev_handle);
1340			}
1341			progress &= ~QL_REGS_MAPPED;
1342		}
1343
1344		if (progress & QL_SOFT_STATE_ALLOCED) {
1345
1346			ql_fcache_rel(ha->fcache);
1347
1348			ASSERT(ha->dev && ha->outstanding_cmds &&
1349			    ha->ub_array && ha->adapter_stats);
1350
1351			kmem_free(ha->adapter_stats,
1352			    sizeof (*ha->adapter_stats));
1353
1354			kmem_free(ha->ub_array, sizeof (*ha->ub_array) *
1355			    QL_UB_LIMIT);
1356
1357			kmem_free(ha->outstanding_cmds,
1358			    sizeof (*ha->outstanding_cmds) *
1359			    MAX_OUTSTANDING_COMMANDS);
1360
1361			if (ha->devpath != NULL) {
1362				kmem_free(ha->devpath,
1363				    strlen(ha->devpath) + 1);
1364			}
1365
1366			kmem_free(ha->dev, sizeof (*ha->dev) *
1367			    DEVICE_HEAD_LIST_SIZE);
1368
1369			if (ha->xioctl != NULL) {
1370				ql_free_xioctl_resource(ha);
1371			}
1372
1373			if (ha->fw_module != NULL) {
1374				(void) ddi_modclose(ha->fw_module);
1375			}
1376
1377			ddi_soft_state_free(ql_state, instance);
1378			progress &= ~QL_SOFT_STATE_ALLOCED;
1379		}
1380		ASSERT(progress == 0);
1381
1382		ddi_prop_remove_all(dip);
1383		rval = DDI_FAILURE;
1384		break;
1385
1386	case DDI_RESUME:
1387		rval = DDI_FAILURE;
1388
1389		ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
1390		if (ha == NULL) {
1391			cmn_err(CE_WARN, "%s(%d): can't get soft state",
1392			    QL_NAME, instance);
1393			break;
1394		}
1395
1396		if (ha->flags & TARGET_MODE_INITIALIZED) {
1397			/* Enable Target Mode */
1398			ha->init_ctrl_blk.cb.lun_enables[0] = (uint8_t)
1399			    (ha->init_ctrl_blk.cb.lun_enables[0] | 0x01);
1400			ha->init_ctrl_blk.cb.immediate_notify_resouce_count =
1401			    ha->ub_notify_count;
1402			ha->init_ctrl_blk.cb.command_resouce_count =
1403			    ha->ub_command_count;
1404		} else {
1405			ha->init_ctrl_blk.cb.lun_enables[0] = 0;
1406			ha->init_ctrl_blk.cb.lun_enables[1] = 0;
1407			ha->init_ctrl_blk.cb.immediate_notify_resouce_count =
1408			    0;
1409			ha->init_ctrl_blk.cb.command_resouce_count = 0;
1410		}
1411
1412		ha->power_level = PM_LEVEL_D3;
1413		if (ha->pm_capable) {
1414			/*
1415			 * Get ql_power to do power on initialization
1416			 */
1417			if (pm_raise_power(dip, QL_POWER_COMPONENT,
1418			    PM_LEVEL_D0) != DDI_SUCCESS) {
1419				cmn_err(CE_WARN, "%s(%d): can't raise adapter"
1420				    " power", QL_NAME, instance);
1421			}
1422		}
1423
1424		/*
1425		 * There is a bug in DR that prevents PM framework
1426		 * from calling ql_power.
1427		 */
1428		if (ha->power_level == PM_LEVEL_D3) {
1429			ha->power_level = PM_LEVEL_D0;
1430
1431			if (ql_initialize_adapter(ha) != QL_SUCCESS) {
1432				cmn_err(CE_WARN, "%s(%d): can't initialize the"
1433				    " adapter", QL_NAME, instance);
1434			}
1435
1436			/* Wake up task_daemon. */
1437			ql_awaken_task_daemon(ha, NULL, TASK_DAEMON_ALIVE_FLG,
1438			    0);
1439		}
1440
1441		/* Acquire global state lock. */
1442		GLOBAL_STATE_LOCK();
1443
1444		/* Restart driver timer. */
1445		if (ql_timer_timeout_id == NULL) {
1446			ql_timer_timeout_id = timeout(ql_timer, (void *)0,
1447			    ql_timer_ticks);
1448		}
1449
1450		/* Release global state lock. */
1451		GLOBAL_STATE_UNLOCK();
1452
1453		/* Wake up command start routine. */
1454		ADAPTER_STATE_LOCK(ha);
1455		ha->flags &= ~ADAPTER_SUSPENDED;
1456		ADAPTER_STATE_UNLOCK(ha);
1457
1458		/*
1459		 * Transport doesn't make FC discovery in polled
1460		 * mode; So we need the daemon thread's services
1461		 * right here.
1462		 */
1463		(void) callb_generic_cpr(&ha->cprinfo, CB_CODE_CPR_RESUME);
1464
1465		rval = DDI_SUCCESS;
1466
1467		/* Restart IP if it was running. */
1468		if (ha->flags & IP_ENABLED && !(ha->flags & IP_INITIALIZED)) {
1469			(void) ql_initialize_ip(ha);
1470			ql_isp_rcvbuf(ha);
1471		}
1472		break;
1473
1474	default:
1475		cmn_err(CE_WARN, "%s(%d): attach, unknown code:"
1476		    " %x", QL_NAME, ddi_get_instance(dip), cmd);
1477		rval = DDI_FAILURE;
1478		break;
1479	}
1480
1481	kmem_free(buf, MAXPATHLEN);
1482
1483	if (rval != DDI_SUCCESS) {
1484		/*EMPTY*/
1485		QL_PRINT_2(CE_CONT, "(%d): failed, rval = %xh\n",
1486		    ddi_get_instance(dip), rval);
1487	} else {
1488		/*EMPTY*/
1489		QL_PRINT_3(CE_CONT, "(%d): done\n", ddi_get_instance(dip));
1490	}
1491
1492	return (rval);
1493}
1494
1495/*
1496 * ql_detach
1497 *	Used to remove all the states associated with a given
1498 *	instances of a device node prior to the removal of that
1499 *	instance from the system.
1500 *
1501 * Input:
1502 *	dip = pointer to device information structure.
1503 *	cmd = type of detach.
1504 *
1505 * Returns:
1506 *	DDI_SUCCESS or DDI_FAILURE.
1507 *
1508 * Context:
1509 *	Kernel context.
1510 */
1511static int
1512ql_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1513{
1514	ql_adapter_state_t	*ha, *vha;
1515	ql_tgt_t		*tq;
1516	int			try;
1517	uint16_t		index;
1518	ql_link_t		*link;
1519	char			*buf;
1520	timeout_id_t		timer_id = NULL;
1521	int			rval = DDI_SUCCESS;
1522
1523	ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
1524	if (ha == NULL) {
1525		QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
1526		    ddi_get_instance(dip));
1527		return (DDI_FAILURE);
1528	}
1529
1530	QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n", ha->instance, cmd);
1531
1532	buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
1533
1534	switch (cmd) {
1535	case DDI_DETACH:
1536		ADAPTER_STATE_LOCK(ha);
1537		ha->flags |= (ADAPTER_SUSPENDED | ABORT_CMDS_LOOP_DOWN_TMO);
1538		ADAPTER_STATE_UNLOCK(ha);
1539
1540		/* Acquire task daemon lock. */
1541		TASK_DAEMON_LOCK(ha);
1542
1543		ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG;
1544		cv_signal(&ha->cv_task_daemon);
1545
1546		/* Release task daemon lock. */
1547		TASK_DAEMON_UNLOCK(ha);
1548
1549		/*
1550		 * Wait for task daemon to stop running.
1551		 * Internal command timeout is approximately
1552		 * 30 seconds, so it would help in some corner
1553		 * cases to wait that long
1554		 */
1555		try = 0;
1556		while ((ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) &&
1557		    try < 3000) {
1558			ql_delay(ha, 10000);
1559			try++;
1560		}
1561
1562		TASK_DAEMON_LOCK(ha);
1563		if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
1564			ha->task_daemon_flags &= ~TASK_DAEMON_STOP_FLG;
1565			TASK_DAEMON_UNLOCK(ha);
1566			EL(ha, "failed, could not stop task daemon\n");
1567			return (DDI_FAILURE);
1568		}
1569		TASK_DAEMON_UNLOCK(ha);
1570
1571		/* Acquire global state lock. */
1572		GLOBAL_STATE_LOCK();
1573
1574		/* Disable driver timer if no adapters. */
1575		if (ql_timer_timeout_id && ql_hba.first == &ha->hba &&
1576		    ql_hba.last == &ha->hba) {
1577			timer_id = ql_timer_timeout_id;
1578			ql_timer_timeout_id = NULL;
1579		}
1580		ql_remove_link(&ql_hba, &ha->hba);
1581
1582		GLOBAL_STATE_UNLOCK();
1583
1584		if (timer_id) {
1585			(void) untimeout(timer_id);
1586		}
1587
1588		if (ha->pm_capable) {
1589			if (pm_lower_power(dip, QL_POWER_COMPONENT,
1590			    PM_LEVEL_D3) != DDI_SUCCESS) {
1591				cmn_err(CE_WARN, "%s(%d): failed to lower the"
1592				    " power", QL_NAME, ha->instance);
1593			}
1594		}
1595
1596		/*
1597		 * If pm_lower_power shutdown the adapter, there
1598		 * isn't much else to do
1599		 */
1600		if (ha->power_level != PM_LEVEL_D3) {
1601			ql_halt(ha, PM_LEVEL_D3);
1602		}
1603
1604		/* Remove virtual ports. */
1605		while ((vha = ha->vp_next) != NULL) {
1606			ql_vport_destroy(vha);
1607		}
1608
1609		/* Free target queues. */
1610		for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
1611			link = ha->dev[index].first;
1612			while (link != NULL) {
1613				tq = link->base_address;
1614				link = link->next;
1615				ql_dev_free(ha, tq);
1616			}
1617		}
1618
1619		/*
1620		 * Free unsolicited buffers.
1621		 * If we are here then there are no ULPs still
1622		 * alive that wish to talk to ql so free up
1623		 * any SRB_IP_UB_UNUSED buffers that are
1624		 * lingering around
1625		 */
1626		QL_UB_LOCK(ha);
1627		for (index = 0; index < QL_UB_LIMIT; index++) {
1628			fc_unsol_buf_t *ubp = ha->ub_array[index];
1629
1630			if (ubp != NULL) {
1631				ql_srb_t *sp = ubp->ub_fca_private;
1632
1633				sp->flags |= SRB_UB_FREE_REQUESTED;
1634
1635				while (!(sp->flags & SRB_UB_IN_FCA) ||
1636				    (sp->flags & (SRB_UB_CALLBACK |
1637				    SRB_UB_ACQUIRED))) {
1638					QL_UB_UNLOCK(ha);
1639					delay(drv_usectohz(100000));
1640					QL_UB_LOCK(ha);
1641				}
1642				ha->ub_array[index] = NULL;
1643
1644				QL_UB_UNLOCK(ha);
1645				ql_free_unsolicited_buffer(ha, ubp);
1646				QL_UB_LOCK(ha);
1647			}
1648		}
1649		QL_UB_UNLOCK(ha);
1650
1651		/* Free any saved RISC code. */
1652		if (ha->risc_code != NULL) {
1653			kmem_free(ha->risc_code, ha->risc_code_size);
1654			ha->risc_code = NULL;
1655			ha->risc_code_size = 0;
1656		}
1657
1658		if (ha->fw_module != NULL) {
1659			(void) ddi_modclose(ha->fw_module);
1660			ha->fw_module = NULL;
1661		}
1662
1663		/* Free resources. */
1664		ddi_prop_remove_all(dip);
1665		(void) fc_fca_detach(dip);
1666		kmem_free(ha->tran, sizeof (fc_fca_tran_t));
1667		ddi_remove_minor_node(dip, "devctl");
1668		if (ha->k_stats != NULL) {
1669			kstat_delete(ha->k_stats);
1670		}
1671
1672		if (CFG_IST(ha, CFG_SBUS_CARD)) {
1673			ddi_regs_map_free(&ha->sbus_config_handle);
1674		} else {
1675			ddi_regs_map_free(&ha->iomap_dev_handle);
1676			pci_config_teardown(&ha->pci_handle);
1677		}
1678
1679		ql_disable_intr(ha);
1680		ql_release_intr(ha);
1681
1682		ql_free_xioctl_resource(ha);
1683
1684		ql_destroy_mutex(ha);
1685
1686		ql_free_phys(ha, &ha->hba_buf);
1687		ql_free_phys(ha, &ha->fwexttracebuf);
1688		ql_free_phys(ha, &ha->fwfcetracebuf);
1689
1690		ddi_regs_map_free(&ha->dev_handle);
1691		if (ha->sbus_fpga_iobase != NULL) {
1692			ddi_regs_map_free(&ha->sbus_fpga_dev_handle);
1693		}
1694
1695		ql_fcache_rel(ha->fcache);
1696		if (ha->vcache != NULL) {
1697			kmem_free(ha->vcache, QL_24XX_VPD_SIZE);
1698		}
1699
1700		if (ha->pi_attrs != NULL) {
1701			kmem_free(ha->pi_attrs, sizeof (fca_port_attrs_t));
1702		}
1703
1704		ASSERT(ha->dev && ha->outstanding_cmds && ha->ub_array &&
1705		    ha->adapter_stats);
1706
1707		kmem_free(ha->adapter_stats, sizeof (*ha->adapter_stats));
1708
1709		kmem_free(ha->ub_array, sizeof (*ha->ub_array) * QL_UB_LIMIT);
1710
1711		kmem_free(ha->outstanding_cmds,
1712		    sizeof (*ha->outstanding_cmds) * MAX_OUTSTANDING_COMMANDS);
1713
1714		if (ha->devpath != NULL) {
1715			kmem_free(ha->devpath, strlen(ha->devpath) + 1);
1716		}
1717
1718		kmem_free(ha->dev, sizeof (*ha->dev) * DEVICE_HEAD_LIST_SIZE);
1719
1720		EL(ha, "detached\n");
1721
1722		ddi_soft_state_free(ql_state, (int)ha->instance);
1723
1724		break;
1725
1726	case DDI_SUSPEND:
1727		ADAPTER_STATE_LOCK(ha);
1728
1729		try = 0;
1730		ha->flags |= ADAPTER_SUSPENDED;
1731		while (ha->flags & ADAPTER_TIMER_BUSY && try++ < 10) {
1732			ADAPTER_STATE_UNLOCK(ha);
1733			delay(drv_usectohz(1000000));
1734			ADAPTER_STATE_LOCK(ha);
1735		}
1736		if (ha->busy || ha->flags & ADAPTER_TIMER_BUSY) {
1737			ha->flags &= ~ADAPTER_SUSPENDED;
1738			ADAPTER_STATE_UNLOCK(ha);
1739			rval = DDI_FAILURE;
1740			cmn_err(CE_WARN, "!%s(%d): Fail suspend"
1741			    " busy %xh flags %xh", QL_NAME, ha->instance,
1742			    ha->busy, ha->flags);
1743			break;
1744		}
1745
1746		ADAPTER_STATE_UNLOCK(ha);
1747
1748		if (ha->flags & IP_INITIALIZED) {
1749			(void) ql_shutdown_ip(ha);
1750		}
1751
1752		try = ql_suspend_adapter(ha);
1753		if (try != QL_SUCCESS) {
1754			ADAPTER_STATE_LOCK(ha);
1755			ha->flags &= ~ADAPTER_SUSPENDED;
1756			ADAPTER_STATE_UNLOCK(ha);
1757			cmn_err(CE_WARN, "%s(%d): Fail suspend rval %xh",
1758			    QL_NAME, ha->instance, try);
1759
1760			/* Restart IP if it was running. */
1761			if (ha->flags & IP_ENABLED &&
1762			    !(ha->flags & IP_INITIALIZED)) {
1763				(void) ql_initialize_ip(ha);
1764				ql_isp_rcvbuf(ha);
1765			}
1766			rval = DDI_FAILURE;
1767			break;
1768		}
1769
1770		/* Acquire global state lock. */
1771		GLOBAL_STATE_LOCK();
1772
1773		/* Disable driver timer if last adapter. */
1774		if (ql_timer_timeout_id && ql_hba.first == &ha->hba &&
1775		    ql_hba.last == &ha->hba) {
1776			timer_id = ql_timer_timeout_id;
1777			ql_timer_timeout_id = NULL;
1778		}
1779		GLOBAL_STATE_UNLOCK();
1780
1781		if (timer_id) {
1782			(void) untimeout(timer_id);
1783		}
1784
1785		break;
1786
1787	default:
1788		rval = DDI_FAILURE;
1789		break;
1790	}
1791
1792	kmem_free(buf, MAXPATHLEN);
1793
1794	if (rval != DDI_SUCCESS) {
1795		if (ha != NULL) {
1796			EL(ha, "failed, rval = %xh\n", rval);
1797		} else {
1798			/*EMPTY*/
1799			QL_PRINT_2(CE_CONT, "(%d): failed, rval = %xh\n",
1800			    ddi_get_instance(dip), rval);
1801		}
1802	} else {
1803		/*EMPTY*/
1804		QL_PRINT_3(CE_CONT, "(%d): done\n", ddi_get_instance(dip));
1805	}
1806
1807	return (rval);
1808}
1809
1810/*
1811 * ql_power
1812 *	Power a device attached to the system.
1813 *
1814 * Input:
1815 *	dip = pointer to device information structure.
1816 *	component = device.
1817 *	level = power level.
1818 *
1819 * Returns:
1820 *	DDI_SUCCESS or DDI_FAILURE.
1821 *
1822 * Context:
1823 *	Kernel context.
1824 */
1825/* ARGSUSED */
1826static int
1827ql_power(dev_info_t *dip, int component, int level)
1828{
1829	int			rval = DDI_FAILURE;
1830	off_t			csr;
1831	uint8_t			saved_pm_val;
1832	ql_adapter_state_t	*ha;
1833	char			*buf;
1834	char			*path;
1835
1836	ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
1837	if (ha == NULL || ha->pm_capable == 0) {
1838		QL_PRINT_2(CE_CONT, "(%d): no hba or PM not supported\n",
1839		    ddi_get_instance(dip));
1840		return (rval);
1841	}
1842
1843	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
1844
1845	buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
1846	path = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
1847
1848	if (component != QL_POWER_COMPONENT || (level != PM_LEVEL_D0 &&
1849	    level != PM_LEVEL_D3)) {
1850		EL(ha, "invalid, component=%xh or level=%xh\n",
1851		    component, level);
1852		return (rval);
1853	}
1854
1855	GLOBAL_HW_LOCK();
1856	csr = (uint8_t)ql_pci_config_get8(ha, PCI_CONF_CAP_PTR) + PCI_PMCSR;
1857	GLOBAL_HW_UNLOCK();
1858
1859	ASSERT(csr == QL_PM_CS_REG);
1860
1861	(void) snprintf(buf, sizeof (buf),
1862	    "Qlogic %s(%d): %s\n\t", QL_NAME, ddi_get_instance(dip),
1863	    ddi_pathname(dip, path));
1864
1865	switch (level) {
1866	case PM_LEVEL_D0:	/* power up to D0 state - fully on */
1867
1868		QL_PM_LOCK(ha);
1869		if (ha->power_level == PM_LEVEL_D0) {
1870			QL_PM_UNLOCK(ha);
1871			rval = DDI_SUCCESS;
1872			break;
1873		}
1874
1875		/*
1876		 * Enable interrupts now
1877		 */
1878		saved_pm_val = ha->power_level;
1879		ha->power_level = PM_LEVEL_D0;
1880		QL_PM_UNLOCK(ha);
1881
1882		GLOBAL_HW_LOCK();
1883
1884		ql_pci_config_put16(ha, csr, PCI_PMCSR_D0);
1885
1886		/*
1887		 * Delay after reset, for chip to recover.
1888		 * Otherwise causes system PANIC
1889		 */
1890		drv_usecwait(200000);
1891
1892		GLOBAL_HW_UNLOCK();
1893
1894		if (ha->config_saved) {
1895			ha->config_saved = 0;
1896			if (QL_RESTORE_CONFIG_REGS(dip) != DDI_SUCCESS) {
1897				QL_PM_LOCK(ha);
1898				ha->power_level = saved_pm_val;
1899				QL_PM_UNLOCK(ha);
1900				cmn_err(CE_WARN, "%s failed to restore "
1901				    "config regs", buf);
1902				break;
1903			}
1904		}
1905
1906		if (ql_initialize_adapter(ha) != QL_SUCCESS) {
1907			cmn_err(CE_WARN, "%s adapter initialization failed",
1908			    buf);
1909		}
1910
1911		/* Wake up task_daemon. */
1912		ql_awaken_task_daemon(ha, NULL, TASK_DAEMON_ALIVE_FLG |
1913		    TASK_DAEMON_SLEEPING_FLG, 0);
1914
1915		/* Restart IP if it was running. */
1916		if (ha->flags & IP_ENABLED && !(ha->flags & IP_INITIALIZED)) {
1917			(void) ql_initialize_ip(ha);
1918			ql_isp_rcvbuf(ha);
1919		}
1920
1921		cmn_err(CE_NOTE, QL_BANG "ql_power(%d): %s is powered ON\n",
1922		    ha->instance, QL_NAME);
1923
1924		rval = DDI_SUCCESS;
1925		break;
1926
1927	case PM_LEVEL_D3:	/* power down to D3 state - off */
1928
1929		QL_PM_LOCK(ha);
1930
1931		if (ha->busy || ((ha->task_daemon_flags &
1932		    TASK_DAEMON_SLEEPING_FLG) == 0)) {
1933			QL_PM_UNLOCK(ha);
1934			break;
1935		}
1936
1937		if (ha->power_level == PM_LEVEL_D3) {
1938			rval = DDI_SUCCESS;
1939			QL_PM_UNLOCK(ha);
1940			break;
1941		}
1942		QL_PM_UNLOCK(ha);
1943
1944		if (QL_SAVE_CONFIG_REGS(dip) != DDI_SUCCESS) {
1945			cmn_err(CE_WARN, "!Qlogic %s(%d): %s failed to save"
1946			    " config regs", QL_NAME, ha->instance, buf);
1947			break;
1948		}
1949		ha->config_saved = 1;
1950
1951		/*
1952		 * Don't enable interrupts. Running mailbox commands with
1953		 * interrupts enabled could cause hangs since pm_run_scan()
1954		 * runs out of a callout thread and on single cpu systems
1955		 * cv_timedwait(), called from ql_mailbox_command(), would
1956		 * not get to run.
1957		 */
1958		TASK_DAEMON_LOCK(ha);
1959		ha->task_daemon_flags |= TASK_DAEMON_POWERING_DOWN;
1960		TASK_DAEMON_UNLOCK(ha);
1961
1962		ql_halt(ha, PM_LEVEL_D3);
1963
1964		/*
1965		 * Setup ql_intr to ignore interrupts from here on.
1966		 */
1967		QL_PM_LOCK(ha);
1968		ha->power_level = PM_LEVEL_D3;
1969		QL_PM_UNLOCK(ha);
1970
1971		/*
1972		 * Wait for ISR to complete.
1973		 */
1974		INTR_LOCK(ha);
1975		ql_pci_config_put16(ha, csr, PCI_PMCSR_D3HOT);
1976		INTR_UNLOCK(ha);
1977
1978		cmn_err(CE_NOTE, QL_BANG "ql_power(%d): %s is powered OFF\n",
1979		    ha->instance, QL_NAME);
1980
1981		rval = DDI_SUCCESS;
1982		break;
1983	}
1984
1985	kmem_free(buf, MAXPATHLEN);
1986	kmem_free(path, MAXPATHLEN);
1987
1988	QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
1989
1990	return (rval);
1991}
1992
1993/*
1994 * ql_quiesce
1995 *	quiesce a device attached to the system.
1996 *
1997 * Input:
1998 *	dip = pointer to device information structure.
1999 *
2000 * Returns:
2001 *	DDI_SUCCESS
2002 *
2003 * Context:
2004 *	Kernel context.
2005 */
2006/* ARGSUSED */
2007static int
2008ql_quiesce(dev_info_t *dip)
2009{
2010	ql_adapter_state_t	*ha;
2011	uint32_t		timer;
2012	uint32_t		stat;
2013
2014	ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
2015	if (ha == NULL) {
2016		/* Oh well.... */
2017		return (DDI_SUCCESS);
2018	}
2019
2020	if (CFG_IST(ha, CFG_CTRL_2425)) {
2021		WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
2022		WRT16_IO_REG(ha, mailbox[0], MBC_STOP_FIRMWARE);
2023		WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
2024		for (timer = 0; timer < 30000; timer++) {
2025			stat = RD32_IO_REG(ha, intr_info_lo);
2026			if (stat & BIT_15) {
2027				if ((stat & 0xff) < 0x12) {
2028					WRT32_IO_REG(ha, hccr,
2029					    HC24_CLR_RISC_INT);
2030					break;
2031				}
2032				WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
2033			}
2034			drv_usecwait(100);
2035		}
2036		/* Reset the chip. */
2037		WRT32_IO_REG(ha, ctrl_status, ISP_RESET | DMA_SHUTDOWN |
2038		    MWB_4096_BYTES);
2039		drv_usecwait(100);
2040
2041	} else {
2042		/* Disable ISP interrupts. */
2043		WRT16_IO_REG(ha, ictrl, 0);
2044		/* Select RISC module registers. */
2045		WRT16_IO_REG(ha, ctrl_status, 0);
2046		/* Reset ISP semaphore. */
2047		WRT16_IO_REG(ha, semaphore, 0);
2048		/* Reset RISC module. */
2049		WRT16_IO_REG(ha, hccr, HC_RESET_RISC);
2050		/* Release RISC module. */
2051		WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
2052	}
2053
2054	return (DDI_SUCCESS);
2055}
2056
2057
2058/* ************************************************************************ */
2059/*		Fibre Channel Adapter (FCA) Transport Functions.	    */
2060/* ************************************************************************ */
2061
2062/*
2063 * ql_bind_port
2064 *	Handling port binding. The FC Transport attempts to bind an FCA port
2065 *	when it is ready to start transactions on the port. The FC Transport
2066 *	will call the fca_bind_port() function specified in the fca_transport
2067 *	structure it receives. The FCA must fill in the port_info structure
2068 *	passed in the call and also stash the information for future calls.
2069 *
2070 * Input:
2071 *	dip = pointer to FCA information structure.
2072 *	port_info = pointer to port information structure.
2073 *	bind_info = pointer to bind information structure.
2074 *
2075 * Returns:
2076 *	NULL = failure
2077 *
2078 * Context:
2079 *	Kernel context.
2080 */
2081static opaque_t
2082ql_bind_port(dev_info_t *dip, fc_fca_port_info_t *port_info,
2083    fc_fca_bind_info_t *bind_info)
2084{
2085	ql_adapter_state_t	*ha, *vha;
2086	opaque_t		fca_handle = NULL;
2087	port_id_t		d_id;
2088	int			port_npiv = bind_info->port_npiv;
2089	uchar_t			*port_nwwn = bind_info->port_nwwn.raw_wwn;
2090	uchar_t			*port_pwwn = bind_info->port_pwwn.raw_wwn;
2091
2092	/* get state info based on the dip */
2093	ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
2094	if (ha == NULL) {
2095		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2096		    (void *)fca_handle);
2097		return (NULL);
2098	}
2099	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
2100
2101	/* Verify port number is supported. */
2102	if (port_npiv != 0) {
2103		if (!(ha->flags & VP_ENABLED)) {
2104			QL_PRINT_2(CE_CONT, "(%d): FC_NPIV_NOT_SUPPORTED\n",
2105			    ha->instance);
2106			port_info->pi_error = FC_NPIV_NOT_SUPPORTED;
2107			return (NULL);
2108		}
2109		if (!(ha->flags & POINT_TO_POINT)) {
2110			QL_PRINT_2(CE_CONT, "(%d): FC_NPIV_WRONG_TOPOLOGY\n",
2111			    ha->instance);
2112			port_info->pi_error = FC_NPIV_WRONG_TOPOLOGY;
2113			return (NULL);
2114		}
2115		if (!(ha->flags & FDISC_ENABLED)) {
2116			QL_PRINT_2(CE_CONT, "(%d): switch does not support "
2117			    "FDISC\n", ha->instance);
2118			port_info->pi_error = FC_NPIV_FDISC_FAILED;
2119			return (NULL);
2120		}
2121		if (bind_info->port_num > (CFG_IST(ha, CFG_CTRL_2422) ?
2122		    MAX_24_VIRTUAL_PORTS : MAX_25_VIRTUAL_PORTS)) {
2123			QL_PRINT_2(CE_CONT, "(%d): port number=%d "
2124			    "FC_OUTOFBOUNDS\n", ha->instance);
2125			port_info->pi_error = FC_OUTOFBOUNDS;
2126			return (NULL);
2127		}
2128	} else if (bind_info->port_num != 0) {
2129		QL_PRINT_2(CE_CONT, "(%d): failed, port number=%d is not "
2130		    "supported\n", ha->instance, bind_info->port_num);
2131		port_info->pi_error = FC_OUTOFBOUNDS;
2132		return (NULL);
2133	}
2134
2135	/* Locate port context. */
2136	for (vha = ha; vha != NULL; vha = vha->vp_next) {
2137		if (vha->vp_index == bind_info->port_num) {
2138			break;
2139		}
2140	}
2141
2142	/* If virtual port does not exist. */
2143	if (vha == NULL) {
2144		vha = ql_vport_create(ha, (uint8_t)bind_info->port_num);
2145	}
2146
2147	/* make sure this port isn't already bound */
2148	if (vha->flags & FCA_BOUND) {
2149		port_info->pi_error = FC_ALREADY;
2150	} else {
2151		if (vha->vp_index != 0) {
2152			bcopy(port_nwwn,
2153			    vha->loginparams.node_ww_name.raw_wwn, 8);
2154			bcopy(port_pwwn,
2155			    vha->loginparams.nport_ww_name.raw_wwn, 8);
2156		}
2157		if (vha->vp_index != 0 && !(vha->flags & VP_ENABLED)) {
2158			if (ql_vport_enable(vha) != QL_SUCCESS) {
2159				QL_PRINT_2(CE_CONT, "(%d): failed to enable "
2160				    "virtual port=%d\n", ha->instance,
2161				    vha->vp_index);
2162				port_info->pi_error = FC_NPIV_FDISC_FAILED;
2163				return (NULL);
2164			}
2165			cmn_err(CE_CONT, "!Qlogic %s(%d) NPIV(%d) "
2166			    "WWPN=%02x%02x%02x%02x%02x%02x%02x%02x : "
2167			    "WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
2168			    QL_NAME, ha->instance, vha->vp_index,
2169			    port_pwwn[0], port_pwwn[1], port_pwwn[2],
2170			    port_pwwn[3], port_pwwn[4], port_pwwn[5],
2171			    port_pwwn[6], port_pwwn[7],
2172			    port_nwwn[0], port_nwwn[1], port_nwwn[2],
2173			    port_nwwn[3], port_nwwn[4], port_nwwn[5],
2174			    port_nwwn[6], port_nwwn[7]);
2175		}
2176
2177		/* stash the bind_info supplied by the FC Transport */
2178		vha->bind_info.port_handle = bind_info->port_handle;
2179		vha->bind_info.port_statec_cb =
2180		    bind_info->port_statec_cb;
2181		vha->bind_info.port_unsol_cb = bind_info->port_unsol_cb;
2182
2183		/* Set port's source ID. */
2184		port_info->pi_s_id.port_id = vha->d_id.b24;
2185
2186		/* copy out the default login parameters */
2187		bcopy((void *)&vha->loginparams,
2188		    (void *)&port_info->pi_login_params,
2189		    sizeof (la_els_logi_t));
2190
2191		/* Set port's hard address if enabled. */
2192		port_info->pi_hard_addr.hard_addr = 0;
2193		if (bind_info->port_num == 0) {
2194			d_id.b24 = ha->d_id.b24;
2195			if (CFG_IST(ha, CFG_CTRL_2425)) {
2196				if (ha->init_ctrl_blk.cb24.
2197				    firmware_options_1[0] & BIT_0) {
2198					d_id.b.al_pa = ql_index_to_alpa[ha->
2199					    init_ctrl_blk.cb24.
2200					    hard_address[0]];
2201					port_info->pi_hard_addr.hard_addr =
2202					    d_id.b24;
2203				}
2204			} else if (ha->init_ctrl_blk.cb.firmware_options[0] &
2205			    BIT_0) {
2206				d_id.b.al_pa = ql_index_to_alpa[ha->
2207				    init_ctrl_blk.cb.hard_address[0]];
2208				port_info->pi_hard_addr.hard_addr = d_id.b24;
2209			}
2210
2211			/* Set the node id data */
2212			if (ql_get_rnid_params(ha,
2213			    sizeof (port_info->pi_rnid_params.params),
2214			    (caddr_t)&port_info->pi_rnid_params.params) ==
2215			    QL_SUCCESS) {
2216				port_info->pi_rnid_params.status = FC_SUCCESS;
2217			} else {
2218				port_info->pi_rnid_params.status = FC_FAILURE;
2219			}
2220
2221			/* Populate T11 FC-HBA details */
2222			ql_populate_hba_fru_details(ha, port_info);
2223			ha->pi_attrs = kmem_zalloc(sizeof (fca_port_attrs_t),
2224			    KM_SLEEP);
2225			if (ha->pi_attrs != NULL) {
2226				bcopy(&port_info->pi_attrs, ha->pi_attrs,
2227				    sizeof (fca_port_attrs_t));
2228			}
2229		} else {
2230			port_info->pi_rnid_params.status = FC_FAILURE;
2231			if (ha->pi_attrs != NULL) {
2232				bcopy(ha->pi_attrs, &port_info->pi_attrs,
2233				    sizeof (fca_port_attrs_t));
2234			}
2235		}
2236
2237		/* Generate handle for this FCA. */
2238		fca_handle = (opaque_t)vha;
2239
2240		ADAPTER_STATE_LOCK(ha);
2241		vha->flags |= FCA_BOUND;
2242		ADAPTER_STATE_UNLOCK(ha);
2243		/* Set port's current state. */
2244		port_info->pi_port_state = vha->state;
2245	}
2246
2247	QL_PRINT_10(CE_CONT, "(%d,%d): done, pi_port_state=%xh, "
2248	    "pi_s_id.port_id=%xh\n", ha->instance, ha->vp_index,
2249	    port_info->pi_port_state, port_info->pi_s_id.port_id);
2250
2251	return (fca_handle);
2252}
2253
2254/*
2255 * ql_unbind_port
2256 *	To unbind a Fibre Channel Adapter from an FC Port driver.
2257 *
2258 * Input:
2259 *	fca_handle = handle setup by ql_bind_port().
2260 *
2261 * Context:
2262 *	Kernel context.
2263 */
2264static void
2265ql_unbind_port(opaque_t fca_handle)
2266{
2267	ql_adapter_state_t	*ha;
2268	ql_tgt_t		*tq;
2269	uint32_t		flgs;
2270
2271	ha = ql_fca_handle_to_state(fca_handle);
2272	if (ha == NULL) {
2273		/*EMPTY*/
2274		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2275		    (void *)fca_handle);
2276	} else {
2277		QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance,
2278		    ha->vp_index);
2279
2280		if (!(ha->flags & FCA_BOUND)) {
2281			/*EMPTY*/
2282			QL_PRINT_2(CE_CONT, "(%d): port=%d already unbound\n",
2283			    ha->instance, ha->vp_index);
2284		} else {
2285			if (ha->vp_index != 0 && ha->flags & VP_ENABLED) {
2286				if ((tq = ql_loop_id_to_queue(ha,
2287				    FL_PORT_24XX_HDL)) != NULL) {
2288					(void) ql_log_iocb(ha, tq, tq->loop_id,
2289					    CFO_FREE_N_PORT_HANDLE |
2290					    CFO_EXPLICIT_LOGO | CF_CMD_LOGO,
2291					    NULL);
2292				}
2293				(void) ql_vport_control(ha,
2294				    VPC_DISABLE_INIT);
2295				flgs = FCA_BOUND | VP_ENABLED;
2296			} else {
2297				flgs = FCA_BOUND;
2298			}
2299			ADAPTER_STATE_LOCK(ha);
2300			ha->flags &= ~flgs;
2301			ADAPTER_STATE_UNLOCK(ha);
2302		}
2303
2304		QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
2305		    ha->vp_index);
2306	}
2307}
2308
2309/*
2310 * ql_init_pkt
2311 *	Initialize FCA portion of packet.
2312 *
2313 * Input:
2314 *	fca_handle = handle setup by ql_bind_port().
2315 *	pkt = pointer to fc_packet.
2316 *
2317 * Returns:
2318 *	FC_SUCCESS - the packet has successfully been initialized.
2319 *	FC_UNBOUND - the fca_handle specified is not bound.
2320 *	FC_NOMEM - the FCA failed initialization due to an allocation error.
2321 *	FC_FAILURE - the FCA failed initialization for undisclosed reasons
2322 *
2323 * Context:
2324 *	Kernel context.
2325 */
2326/* ARGSUSED */
2327static int
2328ql_init_pkt(opaque_t fca_handle, fc_packet_t *pkt, int sleep)
2329{
2330	ql_adapter_state_t	*ha;
2331	ql_srb_t		*sp;
2332
2333	ha = ql_fca_handle_to_state(fca_handle);
2334	if (ha == NULL) {
2335		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2336		    (void *)fca_handle);
2337		return (FC_UNBOUND);
2338	}
2339	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2340
2341	ASSERT(ha->power_level == PM_LEVEL_D0);
2342
2343	sp = (ql_srb_t *)pkt->pkt_fca_private;
2344	sp->flags = 0;
2345
2346	/* init cmd links */
2347	sp->cmd.base_address = sp;
2348	sp->cmd.prev = NULL;
2349	sp->cmd.next = NULL;
2350	sp->cmd.head = NULL;
2351
2352	/* init watchdog links */
2353	sp->wdg.base_address = sp;
2354	sp->wdg.prev = NULL;
2355	sp->wdg.next = NULL;
2356	sp->wdg.head = NULL;
2357	sp->pkt = pkt;
2358	sp->ha = ha;
2359	sp->magic_number = QL_FCA_BRAND;
2360
2361	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2362
2363	return (FC_SUCCESS);
2364}
2365
2366/*
2367 * ql_un_init_pkt
2368 *	Release all local resources bound to packet.
2369 *
2370 * Input:
2371 *	fca_handle = handle setup by ql_bind_port().
2372 *	pkt = pointer to fc_packet.
2373 *
2374 * Returns:
2375 *	FC_SUCCESS - the packet has successfully been invalidated.
2376 *	FC_UNBOUND - the fca_handle specified is not bound.
2377 *	FC_BADPACKET - the packet has not been initialized or has
2378 *			already been freed by this FCA.
2379 *
2380 * Context:
2381 *	Kernel context.
2382 */
2383static int
2384ql_un_init_pkt(opaque_t fca_handle, fc_packet_t *pkt)
2385{
2386	ql_adapter_state_t *ha;
2387	int rval;
2388	ql_srb_t *sp;
2389
2390	ha = ql_fca_handle_to_state(fca_handle);
2391	if (ha == NULL) {
2392		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2393		    (void *)fca_handle);
2394		return (FC_UNBOUND);
2395	}
2396	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2397
2398	sp = (ql_srb_t *)pkt->pkt_fca_private;
2399	ASSERT(sp->magic_number == QL_FCA_BRAND);
2400
2401	if (sp->magic_number != QL_FCA_BRAND) {
2402		EL(ha, "failed, FC_BADPACKET\n");
2403		rval = FC_BADPACKET;
2404	} else {
2405		sp->magic_number = NULL;
2406
2407		ASSERT((sp->flags & (SRB_IN_DEVICE_QUEUE |
2408		    SRB_IN_TOKEN_ARRAY)) == 0);
2409
2410		rval = FC_SUCCESS;
2411	}
2412
2413	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2414
2415	return (rval);
2416}
2417
2418/*
2419 * ql_els_send
2420 *	Issue a extended link service request.
2421 *
2422 * Input:
2423 *	fca_handle = handle setup by ql_bind_port().
2424 *	pkt = pointer to fc_packet.
2425 *
2426 * Returns:
2427 *	FC_SUCCESS - the command was successful.
2428 *	FC_ELS_FREJECT - the command was rejected by a Fabric.
2429 *	FC_ELS_PREJECT - the command was rejected by an N-port.
2430 *	FC_TRANSPORT_ERROR - a transport error occurred.
2431 *	FC_UNBOUND - the fca_handle specified is not bound.
2432 *	FC_ELS_BAD - the FCA can not issue the requested ELS.
2433 *
2434 * Context:
2435 *	Kernel context.
2436 */
2437static int
2438ql_els_send(opaque_t fca_handle, fc_packet_t *pkt)
2439{
2440	ql_adapter_state_t	*ha;
2441	int			rval;
2442	clock_t			timer;
2443	ls_code_t		els;
2444	la_els_rjt_t		rjt;
2445	ql_srb_t		*sp = (ql_srb_t *)pkt->pkt_fca_private;
2446
2447	/* Verify proper command. */
2448	ha = ql_cmd_setup(fca_handle, pkt, &rval);
2449	if (ha == NULL) {
2450		QL_PRINT_2(CE_CONT, "failed, ql_cmd_setup=%xh, fcah=%ph\n",
2451		    rval, fca_handle);
2452		return (FC_INVALID_REQUEST);
2453	}
2454	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2455
2456	ASSERT(ha->power_level == PM_LEVEL_D0);
2457
2458	/* Wait for suspension to end. */
2459	TASK_DAEMON_LOCK(ha);
2460	while (ha->task_daemon_flags & QL_SUSPENDED) {
2461		ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG;
2462
2463		/* 30 seconds from now */
2464		timer = ddi_get_lbolt();
2465		timer += drv_usectohz(30000000);
2466
2467		if (cv_timedwait(&ha->pha->cv_dr_suspended,
2468		    &ha->pha->task_daemon_mutex, timer) == -1) {
2469			/*
2470			 * The timeout time 'timer' was
2471			 * reached without the condition
2472			 * being signaled.
2473			 */
2474			pkt->pkt_state = FC_PKT_TRAN_BSY;
2475			pkt->pkt_reason = FC_REASON_XCHG_BSY;
2476
2477			/* Release task daemon lock. */
2478			TASK_DAEMON_UNLOCK(ha);
2479
2480			EL(ha, "QL_SUSPENDED failed=%xh\n",
2481			    QL_FUNCTION_TIMEOUT);
2482			return (FC_TRAN_BUSY);
2483		}
2484	}
2485	/* Release task daemon lock. */
2486	TASK_DAEMON_UNLOCK(ha);
2487
2488	/* Setup response header. */
2489	bcopy((void *)&pkt->pkt_cmd_fhdr, (void *)&pkt->pkt_resp_fhdr,
2490	    sizeof (fc_frame_hdr_t));
2491	pkt->pkt_resp_fhdr.d_id = ha->d_id.b24;
2492	pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id;
2493	pkt->pkt_resp_fhdr.r_ctl = R_CTL_EXTENDED_SVC |
2494	    R_CTL_SOLICITED_CONTROL;
2495	pkt->pkt_resp_fhdr.f_ctl = F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ |
2496	    F_CTL_END_SEQ;
2497
2498	sp->flags &= ~(SRB_UB_CALLBACK | SRB_UB_RSCN | SRB_UB_FCP |
2499	    SRB_FCP_CMD_PKT | SRB_FCP_DATA_PKT | SRB_FCP_RSP_PKT |
2500	    SRB_IP_PKT | SRB_COMMAND_TIMEOUT | SRB_UB_ACQUIRED | SRB_MS_PKT);
2501
2502	/* map the type of ELS to a function */
2503	ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
2504	    (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
2505
2506#if 0
2507	QL_PRINT_3(CE_CONT, "(%d): command fhdr:\n", ha->instance);
2508	QL_DUMP_3((uint8_t *)&pkt->pkt_cmd_fhdr, 32,
2509	    sizeof (fc_frame_hdr_t) / 4);
2510	QL_PRINT_3(CE_CONT, "(%d): command:\n", ha->instance);
2511	QL_DUMP_3((uint8_t *)&els, 32, sizeof (els) / 4);
2512#endif
2513	switch (els.ls_code) {
2514	case LA_ELS_RJT:
2515	case LA_ELS_ACC:
2516		pkt->pkt_state = FC_PKT_SUCCESS;
2517		rval = FC_SUCCESS;
2518		break;
2519	case LA_ELS_PLOGI:
2520	case LA_ELS_PDISC:
2521		rval = ql_els_plogi(ha, pkt);
2522		break;
2523	case LA_ELS_FLOGI:
2524	case LA_ELS_FDISC:
2525		rval = ql_els_flogi(ha, pkt);
2526		break;
2527	case LA_ELS_LOGO:
2528		rval = ql_els_logo(ha, pkt);
2529		break;
2530	case LA_ELS_PRLI:
2531		rval = ql_els_prli(ha, pkt);
2532		break;
2533	case LA_ELS_PRLO:
2534		rval = ql_els_prlo(ha, pkt);
2535		break;
2536	case LA_ELS_ADISC:
2537		rval = ql_els_adisc(ha, pkt);
2538		break;
2539	case LA_ELS_LINIT:
2540		rval = ql_els_linit(ha, pkt);
2541		break;
2542	case LA_ELS_LPC:
2543		rval = ql_els_lpc(ha, pkt);
2544		break;
2545	case LA_ELS_LSTS:
2546		rval = ql_els_lsts(ha, pkt);
2547		break;
2548	case LA_ELS_SCR:
2549		rval = ql_els_scr(ha, pkt);
2550		break;
2551	case LA_ELS_RSCN:
2552		rval = ql_els_rscn(ha, pkt);
2553		break;
2554	case LA_ELS_FARP_REQ:
2555		rval = ql_els_farp_req(ha, pkt);
2556		break;
2557	case LA_ELS_FARP_REPLY:
2558		rval = ql_els_farp_reply(ha, pkt);
2559		break;
2560	case LA_ELS_RLS:
2561		rval = ql_els_rls(ha, pkt);
2562		break;
2563	case LA_ELS_RNID:
2564		rval = ql_els_rnid(ha, pkt);
2565		break;
2566	default:
2567		EL(ha, "failed=%xh, UNSUPPORTED\n", els.ls_code);
2568		/* Build RJT. */
2569		bzero(&rjt, sizeof (rjt));
2570		rjt.ls_code.ls_code = LA_ELS_RJT;
2571		rjt.reason = FC_REASON_CMD_UNSUPPORTED;
2572
2573		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
2574		    (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
2575
2576		pkt->pkt_state = FC_PKT_LOCAL_RJT;
2577		pkt->pkt_reason = FC_REASON_UNSUPPORTED;
2578		rval = FC_SUCCESS;
2579		break;
2580	}
2581
2582#if 0
2583	QL_PRINT_3(CE_CONT, "(%d): response fhdr:\n", ha->instance);
2584	QL_DUMP_3((uint8_t *)&pkt->pkt_resp_fhdr, 32,
2585	    sizeof (fc_frame_hdr_t) / 4);
2586#endif
2587	/* Do command callback only on error */
2588	if (rval == FC_SUCCESS && !(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) &&
2589	    pkt->pkt_comp) {
2590		ql_awaken_task_daemon(ha, sp, 0, 0);
2591	}
2592
2593	if (rval != FC_SUCCESS) {
2594		EL(ha, "failed, rval = %xh\n", rval);
2595	} else {
2596		/*EMPTY*/
2597		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2598	}
2599	return (rval);
2600}
2601
2602/*
2603 * ql_get_cap
2604 *	Export FCA hardware and software capabilities.
2605 *
2606 * Input:
2607 *	fca_handle = handle setup by ql_bind_port().
2608 *	cap = pointer to the capabilities string.
2609 *	ptr = buffer pointer for return capability.
2610 *
2611 * Returns:
2612 *	FC_CAP_ERROR - no such capability
2613 *	FC_CAP_FOUND - the capability was returned and cannot be set
2614 *	FC_CAP_SETTABLE - the capability was returned and can be set
2615 *	FC_UNBOUND - the fca_handle specified is not bound.
2616 *
2617 * Context:
2618 *	Kernel context.
2619 */
2620static int
2621ql_get_cap(opaque_t fca_handle, char *cap, void *ptr)
2622{
2623	ql_adapter_state_t	*ha;
2624	int			rval;
2625	uint32_t		*rptr = (uint32_t *)ptr;
2626
2627	ha = ql_fca_handle_to_state(fca_handle);
2628	if (ha == NULL) {
2629		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2630		    (void *)fca_handle);
2631		return (FC_UNBOUND);
2632	}
2633	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2634
2635	if (strcmp(cap, FC_NODE_WWN) == 0) {
2636		bcopy((void *)&ha->loginparams.node_ww_name.raw_wwn[0],
2637		    ptr, 8);
2638		rval = FC_CAP_FOUND;
2639	} else if (strcmp(cap, FC_LOGIN_PARAMS) == 0) {
2640		bcopy((void *)&ha->loginparams, ptr,
2641		    sizeof (la_els_logi_t));
2642		rval = FC_CAP_FOUND;
2643	} else if (strcmp(cap, FC_CAP_UNSOL_BUF) == 0) {
2644		*rptr = (uint32_t)QL_UB_LIMIT;
2645		rval = FC_CAP_FOUND;
2646	} else if (strcmp(cap, FC_CAP_NOSTREAM_ON_UNALIGN_BUF) == 0) {
2647
2648		dev_info_t	*psydip = NULL;
2649#ifdef __sparc
2650		/*
2651		 * Disable streaming for certain 2 chip adapters
2652		 * below Psycho to handle Psycho byte hole issue.
2653		 */
2654		if ((CFG_IST(ha, CFG_MULTI_CHIP_ADAPTER)) &&
2655		    (!CFG_IST(ha, CFG_SBUS_CARD))) {
2656			for (psydip = ddi_get_parent(ha->dip); psydip;
2657			    psydip = ddi_get_parent(psydip)) {
2658				if (strcmp(ddi_driver_name(psydip),
2659				    "pcipsy") == 0) {
2660					break;
2661				}
2662			}
2663		}
2664#endif	/* __sparc */
2665
2666		if (psydip) {
2667			*rptr = (uint32_t)FC_NO_STREAMING;
2668			EL(ha, "No Streaming\n");
2669		} else {
2670			*rptr = (uint32_t)FC_ALLOW_STREAMING;
2671			EL(ha, "Allow Streaming\n");
2672		}
2673		rval = FC_CAP_FOUND;
2674	} else if (strcmp(cap, FC_CAP_PAYLOAD_SIZE) == 0) {
2675		if (CFG_IST(ha, CFG_CTRL_2425)) {
2676			*rptr = (uint32_t)CHAR_TO_SHORT(
2677			    ha->init_ctrl_blk.cb24.max_frame_length[0],
2678			    ha->init_ctrl_blk.cb24.max_frame_length[1]);
2679		} else {
2680			*rptr = (uint32_t)CHAR_TO_SHORT(
2681			    ha->init_ctrl_blk.cb.max_frame_length[0],
2682			    ha->init_ctrl_blk.cb.max_frame_length[1]);
2683		}
2684		rval = FC_CAP_FOUND;
2685	} else if (strcmp(cap, FC_CAP_POST_RESET_BEHAVIOR) == 0) {
2686		*rptr = FC_RESET_RETURN_ALL;
2687		rval = FC_CAP_FOUND;
2688	} else if (strcmp(cap, FC_CAP_FCP_DMA) == 0) {
2689		*rptr = FC_NO_DVMA_SPACE;
2690		rval = FC_CAP_FOUND;
2691	} else {
2692		EL(ha, "unknown=%s, FC_CAP_ERROR\n", cap);
2693		rval = FC_CAP_ERROR;
2694	}
2695
2696	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2697
2698	return (rval);
2699}
2700
2701/*
2702 * ql_set_cap
2703 *	Allow the FC Transport to set FCA capabilities if possible.
2704 *
2705 * Input:
2706 *	fca_handle = handle setup by ql_bind_port().
2707 *	cap = pointer to the capabilities string.
2708 *	ptr = buffer pointer for capability.
2709 *
2710 * Returns:
2711 *	FC_CAP_ERROR - no such capability
2712 *	FC_CAP_FOUND - the capability cannot be set by the FC Transport.
2713 *	FC_CAP_SETTABLE - the capability was successfully set.
2714 *	FC_UNBOUND - the fca_handle specified is not bound.
2715 *
2716 * Context:
2717 *	Kernel context.
2718 */
2719/* ARGSUSED */
2720static int
2721ql_set_cap(opaque_t fca_handle, char *cap, void *ptr)
2722{
2723	ql_adapter_state_t	*ha;
2724	int			rval;
2725
2726	ha = ql_fca_handle_to_state(fca_handle);
2727	if (ha == NULL) {
2728		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2729		    (void *)fca_handle);
2730		return (FC_UNBOUND);
2731	}
2732	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2733
2734	if (strcmp(cap, FC_NODE_WWN) == 0) {
2735		rval = FC_CAP_FOUND;
2736	} else if (strcmp(cap, FC_LOGIN_PARAMS) == 0) {
2737		rval = FC_CAP_FOUND;
2738	} else if (strcmp(cap, FC_CAP_UNSOL_BUF) == 0) {
2739		rval = FC_CAP_FOUND;
2740	} else if (strcmp(cap, FC_CAP_PAYLOAD_SIZE) == 0) {
2741		rval = FC_CAP_FOUND;
2742	} else if (strcmp(cap, FC_CAP_POST_RESET_BEHAVIOR) == 0) {
2743		rval = FC_CAP_FOUND;
2744	} else {
2745		EL(ha, "unknown=%s, FC_CAP_ERROR\n", cap);
2746		rval = FC_CAP_ERROR;
2747	}
2748
2749	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2750
2751	return (rval);
2752}
2753
2754/*
2755 * ql_getmap
2756 *	Request of Arbitrated Loop (AL-PA) map.
2757 *
2758 * Input:
2759 *	fca_handle = handle setup by ql_bind_port().
2760 *	mapbuf= buffer pointer for map.
2761 *
2762 * Returns:
2763 *	FC_OLDPORT - the specified port is not operating in loop mode.
2764 *	FC_OFFLINE - the specified port is not online.
2765 *	FC_NOMAP - there is no loop map available for this port.
2766 *	FC_UNBOUND - the fca_handle specified is not bound.
2767 *	FC_SUCCESS - a valid map has been placed in mapbuf.
2768 *
2769 * Context:
2770 *	Kernel context.
2771 */
2772static int
2773ql_getmap(opaque_t fca_handle, fc_lilpmap_t *mapbuf)
2774{
2775	ql_adapter_state_t	*ha;
2776	clock_t			timer;
2777	int			rval = FC_SUCCESS;
2778
2779	ha = ql_fca_handle_to_state(fca_handle);
2780	if (ha == NULL) {
2781		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2782		    (void *)fca_handle);
2783		return (FC_UNBOUND);
2784	}
2785	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2786
2787	ASSERT(ha->power_level == PM_LEVEL_D0);
2788
2789	mapbuf->lilp_magic = (uint16_t)MAGIC_LIRP;
2790	mapbuf->lilp_myalpa = ha->d_id.b.al_pa;
2791
2792	/* Wait for suspension to end. */
2793	TASK_DAEMON_LOCK(ha);
2794	while (ha->task_daemon_flags & QL_SUSPENDED) {
2795		ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG;
2796
2797		/* 30 seconds from now */
2798		timer = ddi_get_lbolt();
2799		timer += drv_usectohz(30000000);
2800
2801		if (cv_timedwait(&ha->pha->cv_dr_suspended,
2802		    &ha->pha->task_daemon_mutex, timer) == -1) {
2803			/*
2804			 * The timeout time 'timer' was
2805			 * reached without the condition
2806			 * being signaled.
2807			 */
2808
2809			/* Release task daemon lock. */
2810			TASK_DAEMON_UNLOCK(ha);
2811
2812			EL(ha, "QL_SUSPENDED failed, FC_TRAN_BUSY\n");
2813			return (FC_TRAN_BUSY);
2814		}
2815	}
2816	/* Release task daemon lock. */
2817	TASK_DAEMON_UNLOCK(ha);
2818
2819	if (ql_get_loop_position_map(ha, LOOP_POSITION_MAP_SIZE,
2820	    (caddr_t)&mapbuf->lilp_length) != QL_SUCCESS) {
2821		/*
2822		 * Now, since transport drivers cosider this as an
2823		 * offline condition, let's wait for few seconds
2824		 * for any loop transitions before we reset the.
2825		 * chip and restart all over again.
2826		 */
2827		ql_delay(ha, 2000000);
2828		EL(ha, "failed, FC_NOMAP\n");
2829		rval = FC_NOMAP;
2830	} else {
2831		/*EMPTY*/
2832		QL_PRINT_3(CE_CONT, "(%d): my_alpa %xh len %xh "
2833		    "data %xh %xh %xh %xh\n", ha->instance,
2834		    mapbuf->lilp_myalpa, mapbuf->lilp_length,
2835		    mapbuf->lilp_alpalist[0], mapbuf->lilp_alpalist[1],
2836		    mapbuf->lilp_alpalist[2], mapbuf->lilp_alpalist[3]);
2837	}
2838
2839	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2840#if 0
2841	QL_DUMP_3((uint8_t *)mapbuf, 8, sizeof (fc_lilpmap_t));
2842#endif
2843	return (rval);
2844}
2845
2846/*
2847 * ql_transport
2848 *	Issue an I/O request. Handles all regular requests.
2849 *
2850 * Input:
2851 *	fca_handle = handle setup by ql_bind_port().
2852 *	pkt = pointer to fc_packet.
2853 *
2854 * Returns:
2855 *	FC_SUCCESS - the packet was accepted for transport.
2856 *	FC_TRANSPORT_ERROR - a transport error occurred.
2857 *	FC_BADPACKET - the packet to be transported had not been
2858 *			initialized by this FCA.
2859 *	FC_UNBOUND - the fca_handle specified is not bound.
2860 *
2861 * Context:
2862 *	Kernel context.
2863 */
2864static int
2865ql_transport(opaque_t fca_handle, fc_packet_t *pkt)
2866{
2867	ql_adapter_state_t	*ha;
2868	int			rval = FC_TRANSPORT_ERROR;
2869	ql_srb_t		*sp = (ql_srb_t *)pkt->pkt_fca_private;
2870
2871	/* Verify proper command. */
2872	ha = ql_cmd_setup(fca_handle, pkt, &rval);
2873	if (ha == NULL) {
2874		QL_PRINT_2(CE_CONT, "failed, ql_cmd_setup=%xh, fcah=%ph\n",
2875		    rval, fca_handle);
2876		return (rval);
2877	}
2878	QL_PRINT_3(CE_CONT, "(%d): started command:\n", ha->instance);
2879#if 0
2880	QL_DUMP_3((uint8_t *)&pkt->pkt_cmd_fhdr, 32,
2881	    sizeof (fc_frame_hdr_t) / 4);
2882	QL_PRINT_3(CE_CONT, "(%d): command:\n", ha->instance);
2883	QL_DUMP_3((uint8_t *)pkt->pkt_cmd, 8, pkt->pkt_cmdlen);
2884#endif
2885	if (ha->flags & ADAPTER_SUSPENDED) {
2886		ASSERT(pkt->pkt_tran_flags & FC_TRAN_DUMPING);
2887	}
2888
2889	ASSERT(ha->power_level == PM_LEVEL_D0);
2890
2891	/* Reset SRB flags. */
2892	sp->flags &= ~(SRB_ISP_STARTED | SRB_ISP_COMPLETED | SRB_RETRY |
2893	    SRB_POLL | SRB_WATCHDOG_ENABLED | SRB_ABORT | SRB_UB_CALLBACK |
2894	    SRB_UB_RSCN | SRB_UB_FCP | SRB_FCP_CMD_PKT | SRB_FCP_DATA_PKT |
2895	    SRB_FCP_RSP_PKT | SRB_IP_PKT | SRB_GENERIC_SERVICES_PKT |
2896	    SRB_COMMAND_TIMEOUT | SRB_ABORTING | SRB_IN_DEVICE_QUEUE |
2897	    SRB_IN_TOKEN_ARRAY | SRB_UB_FREE_REQUESTED | SRB_UB_ACQUIRED |
2898	    SRB_MS_PKT);
2899
2900	pkt->pkt_resp_fhdr.d_id = ha->d_id.b24;
2901	pkt->pkt_resp_fhdr.r_ctl = R_CTL_STATUS;
2902	pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id;
2903	pkt->pkt_resp_fhdr.f_ctl = pkt->pkt_cmd_fhdr.f_ctl;
2904	pkt->pkt_resp_fhdr.type = pkt->pkt_cmd_fhdr.type;
2905
2906	switch (pkt->pkt_cmd_fhdr.r_ctl) {
2907	case R_CTL_COMMAND:
2908		if (pkt->pkt_cmd_fhdr.type == FC_TYPE_SCSI_FCP) {
2909			sp->flags |= SRB_FCP_CMD_PKT;
2910			rval = ql_fcp_scsi_cmd(ha, pkt, sp);
2911		}
2912		break;
2913
2914	default:
2915		/* Setup response header and buffer. */
2916		if (pkt->pkt_rsplen) {
2917			bzero((void *)pkt->pkt_resp, pkt->pkt_rsplen);
2918		}
2919
2920		switch (pkt->pkt_cmd_fhdr.r_ctl) {
2921		case R_CTL_SOLICITED_DATA:
2922			if (pkt->pkt_cmd_fhdr.type == FC_TYPE_SCSI_FCP) {
2923				sp->flags |= SRB_FCP_DATA_PKT;
2924				rval = ql_fcp_data_rsp(ha, pkt, sp);
2925			}
2926			break;
2927
2928		case R_CTL_STATUS:
2929			if (pkt->pkt_cmd_fhdr.type == FC_TYPE_SCSI_FCP) {
2930				sp->flags |= SRB_FCP_RSP_PKT;
2931				rval = ql_fcp_data_rsp(ha, pkt, sp);
2932			}
2933			break;
2934
2935		case R_CTL_UNSOL_DATA:
2936			if (pkt->pkt_cmd_fhdr.type == FC_TYPE_IS8802_SNAP) {
2937				sp->flags |= SRB_IP_PKT;
2938				rval = ql_fcp_ip_cmd(ha, pkt, sp);
2939			}
2940			break;
2941
2942		case R_CTL_UNSOL_CONTROL:
2943			if (pkt->pkt_cmd_fhdr.type == FC_TYPE_FC_SERVICES) {
2944				sp->flags |= SRB_GENERIC_SERVICES_PKT;
2945				rval = ql_fc_services(ha, pkt);
2946			}
2947			break;
2948
2949		default:
2950			pkt->pkt_state = FC_PKT_LOCAL_RJT;
2951			pkt->pkt_reason = FC_REASON_UNSUPPORTED;
2952			rval = FC_TRANSPORT_ERROR;
2953			EL(ha, "unknown, r_ctl=%xh\n",
2954			    pkt->pkt_cmd_fhdr.r_ctl);
2955			break;
2956		}
2957	}
2958
2959	if (rval != FC_SUCCESS) {
2960		EL(ha, "failed, rval = %xh\n", rval);
2961	} else {
2962		/*EMPTY*/
2963		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2964	}
2965
2966	return (rval);
2967}
2968
2969/*
2970 * ql_ub_alloc
2971 *	Allocate buffers for unsolicited exchanges.
2972 *
2973 * Input:
2974 *	fca_handle = handle setup by ql_bind_port().
2975 *	tokens = token array for each buffer.
2976 *	size = size of each buffer.
2977 *	count = pointer to number of buffers.
2978 *	type = the FC-4 type the buffers are reserved for.
2979 *		1 = Extended Link Services, 5 = LLC/SNAP
2980 *
2981 * Returns:
2982 *	FC_FAILURE - buffers could not be allocated.
2983 *	FC_TOOMANY - the FCA could not allocate the requested
2984 *			number of buffers.
2985 *	FC_SUCCESS - unsolicited buffers were allocated.
2986 *	FC_UNBOUND - the fca_handle specified is not bound.
2987 *
2988 * Context:
2989 *	Kernel context.
2990 */
2991static int
2992ql_ub_alloc(opaque_t fca_handle, uint64_t tokens[], uint32_t size,
2993    uint32_t *count, uint32_t type)
2994{
2995	ql_adapter_state_t	*ha;
2996	caddr_t			bufp = NULL;
2997	fc_unsol_buf_t		*ubp;
2998	ql_srb_t		*sp;
2999	uint32_t		index;
3000	uint32_t		cnt;
3001	uint32_t		ub_array_index = 0;
3002	int			rval = FC_SUCCESS;
3003	int			ub_updated = FALSE;
3004
3005	/* Check handle. */
3006	ha = ql_fca_handle_to_state(fca_handle);
3007	if (ha == NULL) {
3008		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3009		    (void *)fca_handle);
3010		return (FC_UNBOUND);
3011	}
3012	QL_PRINT_10(CE_CONT, "(%d,%d): started, count = %xh\n",
3013	    ha->instance, ha->vp_index, *count);
3014
3015	QL_PM_LOCK(ha);
3016	if (ha->power_level != PM_LEVEL_D0) {
3017		QL_PM_UNLOCK(ha);
3018		QL_PRINT_3(CE_CONT, "(%d,%d): down done\n", ha->instance,
3019		    ha->vp_index);
3020		return (FC_FAILURE);
3021	}
3022	QL_PM_UNLOCK(ha);
3023
3024	/* Acquire adapter state lock. */
3025	ADAPTER_STATE_LOCK(ha);
3026
3027	/* Check the count. */
3028	if ((*count + ha->ub_allocated) > QL_UB_LIMIT) {
3029		*count = 0;
3030		EL(ha, "failed, FC_TOOMANY\n");
3031		rval = FC_TOOMANY;
3032	}
3033
3034	/*
3035	 * reset ub_array_index
3036	 */
3037	ub_array_index = 0;
3038
3039	/*
3040	 * Now proceed to allocate any buffers required
3041	 */
3042	for (index = 0; index < *count && rval == FC_SUCCESS; index++) {
3043		/* Allocate all memory needed. */
3044		ubp = (fc_unsol_buf_t *)kmem_zalloc(
3045		    sizeof (fc_unsol_buf_t), KM_SLEEP);
3046		if (ubp == NULL) {
3047			EL(ha, "failed, FC_FAILURE\n");
3048			rval = FC_FAILURE;
3049		} else {
3050			sp = kmem_zalloc(sizeof (ql_srb_t), KM_SLEEP);
3051			if (sp == NULL) {
3052				kmem_free(ubp, sizeof (fc_unsol_buf_t));
3053				rval = FC_FAILURE;
3054			} else {
3055				if (type == FC_TYPE_IS8802_SNAP) {
3056#ifdef	__sparc
3057					if (ql_get_dma_mem(ha,
3058					    &sp->ub_buffer, size,
3059					    BIG_ENDIAN_DMA,
3060					    QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
3061						rval = FC_FAILURE;
3062						kmem_free(ubp,
3063						    sizeof (fc_unsol_buf_t));
3064						kmem_free(sp,
3065						    sizeof (ql_srb_t));
3066					} else {
3067						bufp = sp->ub_buffer.bp;
3068						sp->ub_size = size;
3069					}
3070#else
3071					if (ql_get_dma_mem(ha,
3072					    &sp->ub_buffer, size,
3073					    LITTLE_ENDIAN_DMA,
3074					    QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
3075						rval = FC_FAILURE;
3076						kmem_free(ubp,
3077						    sizeof (fc_unsol_buf_t));
3078						kmem_free(sp,
3079						    sizeof (ql_srb_t));
3080					} else {
3081						bufp = sp->ub_buffer.bp;
3082						sp->ub_size = size;
3083					}
3084#endif
3085				} else {
3086					bufp = kmem_zalloc(size, KM_SLEEP);
3087					if (bufp == NULL) {
3088						rval = FC_FAILURE;
3089						kmem_free(ubp,
3090						    sizeof (fc_unsol_buf_t));
3091						kmem_free(sp,
3092						    sizeof (ql_srb_t));
3093					} else {
3094						sp->ub_size = size;
3095					}
3096				}
3097			}
3098		}
3099
3100		if (rval == FC_SUCCESS) {
3101			/* Find next available slot. */
3102			QL_UB_LOCK(ha);
3103			while (ha->ub_array[ub_array_index] != NULL) {
3104				ub_array_index++;
3105			}
3106
3107			ubp->ub_fca_private = (void *)sp;
3108
3109			/* init cmd links */
3110			sp->cmd.base_address = sp;
3111			sp->cmd.prev = NULL;
3112			sp->cmd.next = NULL;
3113			sp->cmd.head = NULL;
3114
3115			/* init wdg links */
3116			sp->wdg.base_address = sp;
3117			sp->wdg.prev = NULL;
3118			sp->wdg.next = NULL;
3119			sp->wdg.head = NULL;
3120			sp->ha = ha;
3121
3122			ubp->ub_buffer = bufp;
3123			ubp->ub_bufsize = size;
3124			ubp->ub_port_handle = fca_handle;
3125			ubp->ub_token = ub_array_index;
3126
3127			/* Save the token. */
3128			tokens[index] = ub_array_index;
3129
3130			/* Setup FCA private information. */
3131			sp->ub_type = type;
3132			sp->handle = ub_array_index;
3133			sp->flags |= SRB_UB_IN_FCA;
3134
3135			ha->ub_array[ub_array_index] = ubp;
3136			ha->ub_allocated++;
3137			ub_updated = TRUE;
3138			QL_UB_UNLOCK(ha);
3139		}
3140	}
3141
3142	/* Release adapter state lock. */
3143	ADAPTER_STATE_UNLOCK(ha);
3144
3145	/* IP buffer. */
3146	if (ub_updated) {
3147		if ((type == FC_TYPE_IS8802_SNAP) &&
3148		    (!(CFG_IST(ha, (CFG_CTRL_6322 | CFG_CTRL_25XX))))) {
3149
3150			ADAPTER_STATE_LOCK(ha);
3151			ha->flags |= IP_ENABLED;
3152			ADAPTER_STATE_UNLOCK(ha);
3153
3154			if (!(ha->flags & IP_INITIALIZED)) {
3155				if (CFG_IST(ha, CFG_CTRL_2425)) {
3156					ha->ip_init_ctrl_blk.cb24.mtu_size[0] =
3157					    LSB(ql_ip_mtu);
3158					ha->ip_init_ctrl_blk.cb24.mtu_size[1] =
3159					    MSB(ql_ip_mtu);
3160					ha->ip_init_ctrl_blk.cb24.buf_size[0] =
3161					    LSB(size);
3162					ha->ip_init_ctrl_blk.cb24.buf_size[1] =
3163					    MSB(size);
3164
3165					cnt = CHAR_TO_SHORT(
3166					    ha->ip_init_ctrl_blk.cb24.cc[0],
3167					    ha->ip_init_ctrl_blk.cb24.cc[1]);
3168
3169					if (cnt < *count) {
3170						ha->ip_init_ctrl_blk.cb24.cc[0]
3171						    = LSB(*count);
3172						ha->ip_init_ctrl_blk.cb24.cc[1]
3173						    = MSB(*count);
3174					}
3175				} else {
3176					ha->ip_init_ctrl_blk.cb.mtu_size[0] =
3177					    LSB(ql_ip_mtu);
3178					ha->ip_init_ctrl_blk.cb.mtu_size[1] =
3179					    MSB(ql_ip_mtu);
3180					ha->ip_init_ctrl_blk.cb.buf_size[0] =
3181					    LSB(size);
3182					ha->ip_init_ctrl_blk.cb.buf_size[1] =
3183					    MSB(size);
3184
3185					cnt = CHAR_TO_SHORT(
3186					    ha->ip_init_ctrl_blk.cb.cc[0],
3187					    ha->ip_init_ctrl_blk.cb.cc[1]);
3188
3189					if (cnt < *count) {
3190						ha->ip_init_ctrl_blk.cb.cc[0] =
3191						    LSB(*count);
3192						ha->ip_init_ctrl_blk.cb.cc[1] =
3193						    MSB(*count);
3194					}
3195				}
3196
3197				(void) ql_initialize_ip(ha);
3198			}
3199			ql_isp_rcvbuf(ha);
3200		}
3201
3202		if (CFG_IST(ha, CFG_TARGET_MODE_ENABLE) &&
3203		    (type == FC_TYPE_SCSI_FCP)) {
3204			(void) ql_modify_lun(ha);
3205		}
3206	}
3207
3208	if (rval != FC_SUCCESS) {
3209		EL(ha, "failed=%xh\n", rval);
3210	} else {
3211		/*EMPTY*/
3212		QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
3213		    ha->vp_index);
3214	}
3215	return (rval);
3216}
3217
3218/*
3219 * ql_ub_free
3220 *	Free unsolicited buffers.
3221 *
3222 * Input:
3223 *	fca_handle = handle setup by ql_bind_port().
3224 *	count = number of buffers.
3225 *	tokens = token array for each buffer.
3226 *
3227 * Returns:
3228 *	FC_SUCCESS - the requested buffers have been freed.
3229 *	FC_UNBOUND - the fca_handle specified is not bound.
3230 *	FC_UB_BADTOKEN - an invalid token was encountered.
3231 *			 No buffers have been released.
3232 *
3233 * Context:
3234 *	Kernel context.
3235 */
3236static int
3237ql_ub_free(opaque_t fca_handle, uint32_t count, uint64_t tokens[])
3238{
3239	ql_adapter_state_t	*ha;
3240	ql_srb_t		*sp;
3241	uint32_t		index;
3242	uint64_t		ub_array_index;
3243	int			rval = FC_SUCCESS;
3244
3245	/* Check handle. */
3246	ha = ql_fca_handle_to_state(fca_handle);
3247	if (ha == NULL) {
3248		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3249		    (void *)fca_handle);
3250		return (FC_UNBOUND);
3251	}
3252	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3253
3254	/* Acquire adapter state lock. */
3255	ADAPTER_STATE_LOCK(ha);
3256
3257	/* Check all returned tokens. */
3258	for (index = 0; index < count; index++) {
3259		fc_unsol_buf_t	*ubp;
3260
3261		/* Check the token range. */
3262		if ((ub_array_index = tokens[index]) >=
3263		    QL_UB_LIMIT) {
3264			EL(ha, "failed, FC_UB_BADTOKEN\n");
3265			rval = FC_UB_BADTOKEN;
3266			break;
3267		}
3268
3269		/* Check the unsolicited buffer array. */
3270		QL_UB_LOCK(ha);
3271		ubp = ha->ub_array[ub_array_index];
3272
3273		if (ubp == NULL) {
3274			EL(ha, "failed, FC_UB_BADTOKEN-2\n");
3275			rval = FC_UB_BADTOKEN;
3276			QL_UB_UNLOCK(ha);
3277			break;
3278		}
3279
3280		/* Check the state of the unsolicited buffer. */
3281		sp = ha->ub_array[ub_array_index]->ub_fca_private;
3282		sp->flags |= SRB_UB_FREE_REQUESTED;
3283
3284		while (!(sp->flags & SRB_UB_IN_FCA) ||
3285		    (sp->flags & (SRB_UB_CALLBACK |
3286		    SRB_UB_ACQUIRED))) {
3287			QL_UB_UNLOCK(ha);
3288			ADAPTER_STATE_UNLOCK(ha);
3289			delay(drv_usectohz(100000));
3290			ADAPTER_STATE_LOCK(ha);
3291			QL_UB_LOCK(ha);
3292		}
3293		ha->ub_array[ub_array_index] = NULL;
3294		QL_UB_UNLOCK(ha);
3295		ql_free_unsolicited_buffer(ha, ubp);
3296	}
3297
3298	if (rval == FC_SUCCESS) {
3299		/*
3300		 * Signal any pending hardware reset when there are
3301		 * no more unsolicited buffers in use.
3302		 */
3303		if (ha->ub_allocated == 0) {
3304			cv_broadcast(&ha->pha->cv_ub);
3305		}
3306	}
3307
3308	/* Release adapter state lock. */
3309	ADAPTER_STATE_UNLOCK(ha);
3310
3311	/*
3312	 * Inform the firmware about the change of scsi target
3313	 * mode buffers.
3314	 */
3315	if (ha->flags & TARGET_MODE_INITIALIZED) {
3316		(void) ql_modify_lun(ha);
3317	}
3318
3319	if (rval != FC_SUCCESS) {
3320		EL(ha, "failed=%xh\n", rval);
3321	} else {
3322		/*EMPTY*/
3323		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3324	}
3325	return (rval);
3326}
3327
3328/*
3329 * ql_ub_release
3330 *	Release unsolicited buffers from FC Transport
3331 *	to FCA for future use.
3332 *
3333 * Input:
3334 *	fca_handle = handle setup by ql_bind_port().
3335 *	count = number of buffers.
3336 *	tokens = token array for each buffer.
3337 *
3338 * Returns:
3339 *	FC_SUCCESS - the requested buffers have been released.
3340 *	FC_UNBOUND - the fca_handle specified is not bound.
3341 *	FC_UB_BADTOKEN - an invalid token was encountered.
3342 *		No buffers have been released.
3343 *
3344 * Context:
3345 *	Kernel context.
3346 */
3347static int
3348ql_ub_release(opaque_t fca_handle, uint32_t count, uint64_t tokens[])
3349{
3350	ql_adapter_state_t	*ha;
3351	ql_srb_t		*sp;
3352	ql_tgt_t		*tq;
3353	port_id_t		d_id;
3354	uint32_t		index;
3355	uint64_t		ub_array_index;
3356	int			rval = FC_SUCCESS;
3357	int			ub_ip_updated = FALSE;
3358
3359	/* Check handle. */
3360	ha = ql_fca_handle_to_state(fca_handle);
3361	if (ha == NULL) {
3362		QL_PRINT_2(CE_CONT, ": failed, no adapter=%ph\n",
3363		    (void *)fca_handle);
3364		return (FC_UNBOUND);
3365	}
3366	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3367
3368	/* Acquire adapter state lock. */
3369	ADAPTER_STATE_LOCK(ha);
3370	QL_UB_LOCK(ha);
3371
3372	/* Check all returned tokens. */
3373	for (index = 0; index < count; index++) {
3374		/* Check the token range. */
3375		if ((ub_array_index = tokens[index]) >=
3376		    QL_UB_LIMIT) {
3377			EL(ha, "failed, FC_UB_BADTOKEN\n");
3378			rval = FC_UB_BADTOKEN;
3379			break;
3380		}
3381
3382		/* Check the unsolicited buffer array. */
3383		if (ha->ub_array[ub_array_index] == NULL) {
3384			EL(ha, "failed, FC_UB_BADTOKEN-2\n");
3385			rval = FC_UB_BADTOKEN;
3386			break;
3387		}
3388
3389		/* Check the state of the unsolicited buffer. */
3390		sp = ha->ub_array[ub_array_index]->ub_fca_private;
3391		if (sp->flags & SRB_UB_IN_FCA) {
3392			EL(ha, "failed, FC_UB_BADTOKEN-3\n");
3393			rval = FC_UB_BADTOKEN;
3394			break;
3395		}
3396	}
3397
3398	/* If all tokens checkout, release the buffers. */
3399	if (rval == FC_SUCCESS) {
3400		/* Check all returned tokens. */
3401		for (index = 0; index < count; index++) {
3402			fc_unsol_buf_t	*ubp;
3403
3404			ub_array_index = tokens[index];
3405			ubp = ha->ub_array[ub_array_index];
3406			sp = ubp->ub_fca_private;
3407			d_id.b24 = ubp->ub_frame.s_id;
3408			tq = ql_d_id_to_queue(ha, d_id);
3409
3410			if (sp->ub_type == FC_TYPE_SCSI_FCP &&
3411			    ubp->ub_resp_flags & FC_UB_RESP_LOGIN_REQUIRED &&
3412			    tq != NULL) {
3413				ctio_entry_t	*ctio;
3414
3415				if (ql_req_pkt(ha, (request_t **)
3416				    &ctio) == QL_SUCCESS) {
3417					ctio->entry_type = CTIO_TYPE_2;
3418
3419					if (CFG_IST(ha,
3420					    CFG_EXT_FW_INTERFACE)) {
3421						ctio->initiator_id_l =
3422						    LSB(tq->loop_id);
3423						ctio->initiator_id_h =
3424						    MSB(tq->loop_id);
3425					} else {
3426						ctio->initiator_id_h =
3427						    LSB(tq->loop_id);
3428					}
3429					ctio->rx_id = ubp->ub_frame.rx_id;
3430					ctio->flags_l = BIT_7 | BIT_6;
3431					ctio->flags_h = BIT_7 | BIT_1 | BIT_0;
3432					ctio->timeout = 0xffff;
3433					ctio->type.s0_32bit.scsi_status_l =
3434					    STATUS_BUSY;
3435					/* Issue command to ISP */
3436					ql_isp_cmd(ha);
3437				}
3438			}
3439
3440			ubp->ub_resp_flags = 0;
3441			sp->flags &= ~(SRB_UB_ACQUIRED | SRB_UB_CALLBACK);
3442			sp->flags |= SRB_UB_IN_FCA;
3443
3444			/* IP buffer. */
3445			if (sp->ub_type == FC_TYPE_IS8802_SNAP) {
3446				ub_ip_updated = TRUE;
3447			}
3448		}
3449	}
3450
3451	QL_UB_UNLOCK(ha);
3452	/* Release adapter state lock. */
3453	ADAPTER_STATE_UNLOCK(ha);
3454
3455	/*
3456	 * XXX: We should call ql_isp_rcvbuf() to return a
3457	 * buffer to ISP only if the number of buffers fall below
3458	 * the low water mark.
3459	 */
3460	if (ub_ip_updated) {
3461		ql_isp_rcvbuf(ha);
3462	}
3463
3464	if (rval != FC_SUCCESS) {
3465		EL(ha, "failed, rval = %xh\n", rval);
3466	} else {
3467		/*EMPTY*/
3468		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3469	}
3470	return (rval);
3471}
3472
3473/*
3474 * ql_abort
3475 *	Abort a packet.
3476 *
3477 * Input:
3478 *	fca_handle = handle setup by ql_bind_port().
3479 *	pkt = pointer to fc_packet.
3480 *	flags = KM_SLEEP flag.
3481 *
3482 * Returns:
3483 *	FC_SUCCESS - the packet has successfully aborted.
3484 *	FC_ABORTED - the packet has successfully aborted.
3485 *	FC_ABORTING - the packet is being aborted.
3486 *	FC_ABORT_FAILED - the packet could not be aborted.
3487 *	FC_TRANSPORT_ERROR - a transport error occurred while attempting
3488 *		to abort the packet.
3489 *	FC_BADEXCHANGE - no packet found.
3490 *	FC_UNBOUND - the fca_handle specified is not bound.
3491 *
3492 * Context:
3493 *	Kernel context.
3494 */
3495static int
3496ql_abort(opaque_t fca_handle, fc_packet_t *pkt, int flags)
3497{
3498	port_id_t		d_id;
3499	ql_link_t		*link;
3500	ql_adapter_state_t	*ha, *pha;
3501	ql_srb_t		*sp;
3502	ql_tgt_t		*tq;
3503	ql_lun_t		*lq;
3504	int			rval = FC_ABORTED;
3505
3506	ha = ql_fca_handle_to_state(fca_handle);
3507	if (ha == NULL) {
3508		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3509		    (void *)fca_handle);
3510		return (FC_UNBOUND);
3511	}
3512
3513	pha = ha->pha;
3514
3515	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3516
3517	ASSERT(pha->power_level == PM_LEVEL_D0);
3518
3519	/* Get target queue pointer. */
3520	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
3521	tq = ql_d_id_to_queue(ha, d_id);
3522
3523	if ((tq == NULL) || (pha->task_daemon_flags & LOOP_DOWN)) {
3524		if (tq == NULL) {
3525			EL(ha, "failed, FC_TRANSPORT_ERROR\n");
3526			rval = FC_TRANSPORT_ERROR;
3527		} else {
3528			EL(ha, "failed, FC_OFFLINE\n");
3529			rval = FC_OFFLINE;
3530		}
3531		return (rval);
3532	}
3533
3534	sp = (ql_srb_t *)pkt->pkt_fca_private;
3535	lq = sp->lun_queue;
3536
3537	/* Set poll flag if sleep wanted. */
3538	if (flags == KM_SLEEP) {
3539		sp->flags |= SRB_POLL;
3540	}
3541
3542	/* Acquire target queue lock. */
3543	DEVICE_QUEUE_LOCK(tq);
3544	REQUEST_RING_LOCK(ha);
3545
3546	/* If command not already started. */
3547	if (!(sp->flags & SRB_ISP_STARTED)) {
3548		/* Check pending queue for command. */
3549		sp = NULL;
3550		for (link = pha->pending_cmds.first; link != NULL;
3551		    link = link->next) {
3552			sp = link->base_address;
3553			if (sp == (ql_srb_t *)pkt->pkt_fca_private) {
3554				/* Remove srb from q. */
3555				ql_remove_link(&pha->pending_cmds, &sp->cmd);
3556				break;
3557			} else {
3558				sp = NULL;
3559			}
3560		}
3561		REQUEST_RING_UNLOCK(ha);
3562
3563		if (sp == NULL) {
3564			/* Check for cmd on device queue. */
3565			for (link = lq->cmd.first; link != NULL;
3566			    link = link->next) {
3567				sp = link->base_address;
3568				if (sp == (ql_srb_t *)pkt->pkt_fca_private) {
3569					/* Remove srb from q. */
3570					ql_remove_link(&lq->cmd, &sp->cmd);
3571					break;
3572				} else {
3573					sp = NULL;
3574				}
3575			}
3576		}
3577		/* Release device lock */
3578		DEVICE_QUEUE_UNLOCK(tq);
3579
3580		/* If command on target queue. */
3581		if (sp != NULL) {
3582			sp->flags &= ~SRB_IN_DEVICE_QUEUE;
3583
3584			/* Set return status */
3585			pkt->pkt_reason = CS_ABORTED;
3586
3587			sp->cmd.next = NULL;
3588			ql_done(&sp->cmd);
3589			rval = FC_ABORTED;
3590		} else {
3591			EL(ha, "failed, FC_BADEXCHANGE\n");
3592			rval = FC_BADEXCHANGE;
3593		}
3594	} else if (sp->flags & SRB_ISP_COMPLETED) {
3595		/* Release device queue lock. */
3596		REQUEST_RING_UNLOCK(ha);
3597		DEVICE_QUEUE_UNLOCK(tq);
3598		EL(ha, "failed, already done, FC_FAILURE\n");
3599		rval = FC_FAILURE;
3600	} else if ((sp->pkt->pkt_cmd_fhdr.r_ctl == R_CTL_SOLICITED_DATA) ||
3601	    (sp->pkt->pkt_cmd_fhdr.r_ctl == R_CTL_STATUS)) {
3602		/*
3603		 * If here, target data/resp ctio is with Fw.
3604		 * Since firmware is supposed to terminate such I/Os
3605		 * with an error, we need not do any thing. If FW
3606		 * decides not to terminate those IOs and simply keep
3607		 * quite then we need to initiate cleanup here by
3608		 * calling ql_done.
3609		 */
3610		REQUEST_RING_UNLOCK(ha);
3611		DEVICE_QUEUE_UNLOCK(tq);
3612		rval = FC_ABORTED;
3613	} else {
3614		request_t	*ep = pha->request_ring_bp;
3615		uint16_t	cnt;
3616
3617		if (sp->handle != 0) {
3618			for (cnt = 0; cnt < REQUEST_ENTRY_CNT; cnt++) {
3619				if (sp->handle == ddi_get32(
3620				    pha->hba_buf.acc_handle, &ep->handle)) {
3621					ep->entry_type = INVALID_ENTRY_TYPE;
3622					break;
3623				}
3624				ep++;
3625			}
3626		}
3627
3628		/* Release device queue lock. */
3629		REQUEST_RING_UNLOCK(ha);
3630		DEVICE_QUEUE_UNLOCK(tq);
3631
3632		sp->flags |= SRB_ABORTING;
3633		(void) ql_abort_command(ha, sp);
3634		pkt->pkt_reason = CS_ABORTED;
3635		rval = FC_ABORTED;
3636	}
3637
3638	QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
3639
3640	return (rval);
3641}
3642
3643/*
3644 * ql_reset
3645 *	Reset link or hardware.
3646 *
3647 * Input:
3648 *	fca_handle = handle setup by ql_bind_port().
3649 *	cmd = reset type command.
3650 *
3651 * Returns:
3652 *	FC_SUCCESS - reset has successfully finished.
3653 *	FC_UNBOUND - the fca_handle specified is not bound.
3654 *	FC_FAILURE - reset failed.
3655 *
3656 * Context:
3657 *	Kernel context.
3658 */
3659static int
3660ql_reset(opaque_t fca_handle, uint32_t cmd)
3661{
3662	ql_adapter_state_t	*ha;
3663	int			rval = FC_SUCCESS, rval2;
3664
3665	ha = ql_fca_handle_to_state(fca_handle);
3666	if (ha == NULL) {
3667		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3668		    (void *)fca_handle);
3669		return (FC_UNBOUND);
3670	}
3671
3672	QL_PRINT_10(CE_CONT, "(%d,%d): started, cmd=%d\n", ha->instance,
3673	    ha->vp_index, cmd);
3674
3675	ASSERT(ha->power_level == PM_LEVEL_D0);
3676
3677	switch (cmd) {
3678	case FC_FCA_CORE:
3679		/* dump firmware core if specified. */
3680		if (ha->vp_index == 0) {
3681			if (ql_dump_firmware(ha) != QL_SUCCESS) {
3682				EL(ha, "failed, FC_FAILURE\n");
3683				rval = FC_FAILURE;
3684			}
3685		}
3686		break;
3687	case FC_FCA_LINK_RESET:
3688		if (!(ha->pha->task_daemon_flags & LOOP_DOWN)) {
3689			if (ql_loop_reset(ha) != QL_SUCCESS) {
3690				EL(ha, "failed, FC_FAILURE-2\n");
3691				rval = FC_FAILURE;
3692			}
3693		}
3694		break;
3695	case FC_FCA_RESET_CORE:
3696	case FC_FCA_RESET:
3697		/* if dump firmware core if specified. */
3698		if (cmd == FC_FCA_RESET_CORE) {
3699			if (ha->vp_index != 0) {
3700				rval2 = ha->pha->task_daemon_flags & LOOP_DOWN
3701				    ? QL_SUCCESS : ql_loop_reset(ha);
3702			} else {
3703				rval2 = ql_dump_firmware(ha);
3704			}
3705			if (rval2 != QL_SUCCESS) {
3706				EL(ha, "failed, FC_FAILURE-3\n");
3707				rval = FC_FAILURE;
3708			}
3709		}
3710
3711		/* Free up all unsolicited buffers. */
3712		if (ha->ub_allocated != 0) {
3713			/* Inform to release buffers. */
3714			ha->state = FC_PORT_SPEED_MASK(ha->state);
3715			ha->state |= FC_STATE_RESET_REQUESTED;
3716			if (ha->flags & FCA_BOUND) {
3717				(ha->bind_info.port_statec_cb)
3718				    (ha->bind_info.port_handle,
3719				    ha->state);
3720			}
3721		}
3722
3723		ha->state = FC_PORT_SPEED_MASK(ha->state);
3724
3725		/* All buffers freed */
3726		if (ha->ub_allocated == 0) {
3727			/* Hardware reset. */
3728			if (cmd == FC_FCA_RESET) {
3729				if (ha->vp_index == 0) {
3730					(void) ql_abort_isp(ha);
3731				} else if (!(ha->pha->task_daemon_flags &
3732				    LOOP_DOWN)) {
3733					(void) ql_loop_reset(ha);
3734				}
3735			}
3736
3737			/* Inform that the hardware has been reset */
3738			ha->state |= FC_STATE_RESET;
3739		} else {
3740			/*
3741			 * the port driver expects an online if
3742			 * buffers are not freed.
3743			 */
3744			if (ha->topology & QL_LOOP_CONNECTION) {
3745				ha->state |= FC_STATE_LOOP;
3746			} else {
3747				ha->state |= FC_STATE_ONLINE;
3748			}
3749		}
3750
3751		TASK_DAEMON_LOCK(ha);
3752		ha->task_daemon_flags |= FC_STATE_CHANGE;
3753		TASK_DAEMON_UNLOCK(ha);
3754
3755		ql_awaken_task_daemon(ha, NULL, FC_STATE_CHANGE, 0);
3756
3757		break;
3758	default:
3759		EL(ha, "unknown cmd=%xh\n", cmd);
3760		break;
3761	}
3762
3763	if (rval != FC_SUCCESS) {
3764		EL(ha, "cmd=%xh, failed=%xh\n", cmd, rval);
3765	} else {
3766		/*EMPTY*/
3767		QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
3768		    ha->vp_index);
3769	}
3770
3771	return (rval);
3772}
3773
3774/*
3775 * ql_port_manage
3776 *	Perform port management or diagnostics.
3777 *
3778 * Input:
3779 *	fca_handle = handle setup by ql_bind_port().
3780 *	cmd = pointer to command structure.
3781 *
3782 * Returns:
3783 *	FC_SUCCESS - the request completed successfully.
3784 *	FC_FAILURE - the request did not complete successfully.
3785 *	FC_UNBOUND - the fca_handle specified is not bound.
3786 *
3787 * Context:
3788 *	Kernel context.
3789 */
3790static int
3791ql_port_manage(opaque_t fca_handle, fc_fca_pm_t *cmd)
3792{
3793	clock_t			timer;
3794	uint16_t		index;
3795	uint32_t		*bp;
3796	port_id_t		d_id;
3797	ql_link_t		*link;
3798	ql_adapter_state_t	*ha, *pha;
3799	ql_tgt_t		*tq;
3800	dma_mem_t		buffer_xmt, buffer_rcv;
3801	size_t			length;
3802	uint32_t		cnt;
3803	char			buf[80];
3804	lbp_t			*lb;
3805	ql_mbx_data_t		mr;
3806	app_mbx_cmd_t		*mcp;
3807	int			i0;
3808	uint8_t			*bptr;
3809	int			rval2, rval = FC_SUCCESS;
3810	uint32_t		opcode;
3811
3812	ha = ql_fca_handle_to_state(fca_handle);
3813	if (ha == NULL) {
3814		QL_PRINT_2(CE_CONT, ": failed, no adapter=%ph\n",
3815		    (void *)fca_handle);
3816		return (FC_UNBOUND);
3817	}
3818	pha = ha->pha;
3819
3820	QL_PRINT_3(CE_CONT, "(%d): started=%xh\n", ha->instance,
3821	    cmd->pm_cmd_code);
3822
3823	ASSERT(pha->power_level == PM_LEVEL_D0);
3824
3825	ql_awaken_task_daemon(ha, NULL, DRIVER_STALL, 0);
3826
3827	/*
3828	 * Wait for all outstanding commands to complete
3829	 */
3830	index = (uint16_t)ql_wait_outstanding(ha);
3831
3832	if (index != MAX_OUTSTANDING_COMMANDS) {
3833		ql_awaken_task_daemon(ha, NULL, 0, DRIVER_STALL);
3834		ql_restart_queues(ha);
3835		EL(ha, "failed, FC_TRAN_BUSY\n");
3836		return (FC_TRAN_BUSY);
3837	}
3838
3839	switch (cmd->pm_cmd_code) {
3840	case FC_PORT_BYPASS:
3841		d_id.b24 = *cmd->pm_cmd_buf;
3842		tq = ql_d_id_to_queue(ha, d_id);
3843		if (tq == NULL || ql_loop_port_bypass(ha, tq) != QL_SUCCESS) {
3844			EL(ha, "failed, FC_PORT_BYPASS FC_FAILURE\n");
3845			rval = FC_FAILURE;
3846		}
3847		break;
3848	case FC_PORT_UNBYPASS:
3849		d_id.b24 = *cmd->pm_cmd_buf;
3850		tq = ql_d_id_to_queue(ha, d_id);
3851		if (tq == NULL || ql_loop_port_enable(ha, tq) != QL_SUCCESS) {
3852			EL(ha, "failed, FC_PORT_UNBYPASS FC_FAILURE\n");
3853			rval = FC_FAILURE;
3854		}
3855		break;
3856	case FC_PORT_GET_FW_REV:
3857		(void) sprintf(buf, "%d.%d.%d", pha->fw_major_version,
3858		    pha->fw_minor_version, pha->fw_subminor_version);
3859		length = strlen(buf) + 1;
3860		if (cmd->pm_data_len < length) {
3861			cmd->pm_data_len = length;
3862			EL(ha, "failed, FC_PORT_GET_FW_REV FC_FAILURE\n");
3863			rval = FC_FAILURE;
3864		} else {
3865			(void) strcpy(cmd->pm_data_buf, buf);
3866		}
3867		break;
3868
3869	case FC_PORT_GET_FCODE_REV: {
3870		caddr_t		fcode_ver_buf = NULL;
3871
3872		i0 = 0;
3873		/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
3874		rval2 = ddi_getlongprop(DDI_DEV_T_ANY, ha->dip,
3875		    DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "version",
3876		    (caddr_t)&fcode_ver_buf, &i0);
3877		length = (uint_t)i0;
3878
3879		if (rval2 != DDI_PROP_SUCCESS) {
3880			EL(ha, "failed, getting version = %xh\n", rval2);
3881			length = 20;
3882			fcode_ver_buf = kmem_alloc(length, KM_SLEEP);
3883			if (fcode_ver_buf != NULL) {
3884				(void) sprintf(fcode_ver_buf,
3885				    "NO FCODE FOUND");
3886			}
3887		}
3888
3889		if (cmd->pm_data_len < length) {
3890			EL(ha, "length error, FC_PORT_GET_FCODE_REV "
3891			    "dst=%ld, src=%ld\n", cmd->pm_data_len, length);
3892			cmd->pm_data_len = length;
3893			rval = FC_FAILURE;
3894		} else if (fcode_ver_buf != NULL) {
3895			bcopy((void *)fcode_ver_buf, (void *)cmd->pm_data_buf,
3896			    length);
3897		}
3898
3899		if (fcode_ver_buf != NULL) {
3900			kmem_free(fcode_ver_buf, length);
3901		}
3902		break;
3903	}
3904
3905	case FC_PORT_GET_DUMP:
3906		QL_DUMP_LOCK(pha);
3907		if (cmd->pm_data_len < (size_t)pha->risc_dump_size) {
3908			EL(ha, "failed, FC_PORT_GET_DUMP incorrect "
3909			    "length=%lxh\n", cmd->pm_data_len);
3910			cmd->pm_data_len = pha->risc_dump_size;
3911			rval = FC_FAILURE;
3912		} else if (pha->ql_dump_state & QL_DUMPING) {
3913			EL(ha, "failed, FC_PORT_GET_DUMP FC_TRAN_BUSY\n");
3914			rval = FC_TRAN_BUSY;
3915		} else if (pha->ql_dump_state & QL_DUMP_VALID) {
3916			(void) ql_ascii_fw_dump(ha, cmd->pm_data_buf);
3917			pha->ql_dump_state |= QL_DUMP_UPLOADED;
3918		} else {
3919			EL(ha, "failed, FC_PORT_GET_DUMP no dump file\n");
3920			rval = FC_FAILURE;
3921		}
3922		QL_DUMP_UNLOCK(pha);
3923		break;
3924	case FC_PORT_FORCE_DUMP:
3925		PORTMANAGE_LOCK(ha);
3926		if (ql_dump_firmware(ha) != QL_SUCCESS) {
3927			EL(ha, "failed, FC_PORT_FORCE_DUMP FC_FAILURE\n");
3928			rval = FC_FAILURE;
3929		}
3930		PORTMANAGE_UNLOCK(ha);
3931		break;
3932	case FC_PORT_DOWNLOAD_FW:
3933		PORTMANAGE_LOCK(ha);
3934		if (CFG_IST(ha, CFG_CTRL_2425)) {
3935			if (ql_24xx_load_flash(ha, (uint8_t *)cmd->pm_data_buf,
3936			    (uint32_t)cmd->pm_data_len,
3937			    FLASH_24XX_FIRMWARE_ADDR) != QL_SUCCESS) {
3938				EL(ha, "failed, FC_PORT_DOWNLOAD_FW\n");
3939				rval = FC_FAILURE;
3940			}
3941			ql_reset_chip(ha);
3942			(void) ql_abort_isp(ha);
3943		} else {
3944			/* Save copy of the firmware. */
3945			if (pha->risc_code != NULL) {
3946				kmem_free(pha->risc_code, pha->risc_code_size);
3947				pha->risc_code = NULL;
3948				pha->risc_code_size = 0;
3949			}
3950
3951			pha->risc_code = kmem_alloc(cmd->pm_data_len,
3952			    KM_SLEEP);
3953			if (pha->risc_code != NULL) {
3954				pha->risc_code_size =
3955				    (uint32_t)cmd->pm_data_len;
3956				bcopy(cmd->pm_data_buf, pha->risc_code,
3957				    cmd->pm_data_len);
3958
3959				/* Do abort to force reload. */
3960				ql_reset_chip(ha);
3961				if (ql_abort_isp(ha) != QL_SUCCESS) {
3962					kmem_free(pha->risc_code,
3963					    pha->risc_code_size);
3964					pha->risc_code = NULL;
3965					pha->risc_code_size = 0;
3966					ql_reset_chip(ha);
3967					(void) ql_abort_isp(ha);
3968					EL(ha, "failed, FC_PORT_DOWNLOAD_FW"
3969					    " FC_FAILURE\n");
3970					rval = FC_FAILURE;
3971				}
3972			}
3973		}
3974		PORTMANAGE_UNLOCK(ha);
3975		break;
3976	case FC_PORT_GET_DUMP_SIZE:
3977		bp = (uint32_t *)cmd->pm_data_buf;
3978		*bp = pha->risc_dump_size;
3979		break;
3980	case FC_PORT_DIAG:
3981		/*
3982		 * Prevents concurrent diags
3983		 */
3984		PORTMANAGE_LOCK(ha);
3985
3986		/* Wait for suspension to end. */
3987		for (timer = 0; timer < 3000 &&
3988		    pha->task_daemon_flags & QL_LOOP_TRANSITION; timer++) {
3989			ql_delay(ha, 10000);
3990		}
3991
3992		if (pha->task_daemon_flags & QL_LOOP_TRANSITION) {
3993			EL(ha, "failed, FC_TRAN_BUSY-2\n");
3994			rval = FC_TRAN_BUSY;
3995			PORTMANAGE_UNLOCK(ha);
3996			break;
3997		}
3998
3999		switch (cmd->pm_cmd_flags) {
4000		case QL_DIAG_EXEFMW:
4001			if (ql_start_firmware(ha) != QL_SUCCESS) {
4002				EL(ha, "failed, QL_DIAG_EXEFMW FC_FAILURE\n");
4003				rval = FC_FAILURE;
4004			}
4005			break;
4006		case QL_DIAG_CHKCMDQUE:
4007			for (i0 = 1, cnt = 0; i0 < MAX_OUTSTANDING_COMMANDS;
4008			    i0++) {
4009				cnt += (pha->outstanding_cmds[i0] != NULL);
4010			}
4011			if (cnt != 0) {
4012				EL(ha, "failed, QL_DIAG_CHKCMDQUE "
4013				    "FC_FAILURE\n");
4014				rval = FC_FAILURE;
4015			}
4016			break;
4017		case QL_DIAG_FMWCHKSUM:
4018			if (ql_verify_checksum(ha) != QL_SUCCESS) {
4019				EL(ha, "failed, QL_DIAG_FMWCHKSUM "
4020				    "FC_FAILURE\n");
4021				rval = FC_FAILURE;
4022			}
4023			break;
4024		case QL_DIAG_SLFTST:
4025			if (ql_online_selftest(ha) != QL_SUCCESS) {
4026				EL(ha, "failed, QL_DIAG_SLFTST FC_FAILURE\n");
4027				rval = FC_FAILURE;
4028			}
4029			ql_reset_chip(ha);
4030			(void) ql_abort_isp(ha);
4031			break;
4032		case QL_DIAG_REVLVL:
4033			if (cmd->pm_stat_len <
4034			    sizeof (ql_adapter_revlvl_t)) {
4035				EL(ha, "failed, QL_DIAG_REVLVL FC_NOMEM, "
4036				    "slen=%lxh, rlvllen=%lxh\n",
4037				    cmd->pm_stat_len,
4038				    sizeof (ql_adapter_revlvl_t));
4039				rval = FC_NOMEM;
4040			} else {
4041				bcopy((void *)&(pha->adapter_stats->revlvl),
4042				    cmd->pm_stat_buf,
4043				    (size_t)cmd->pm_stat_len);
4044				cmd->pm_stat_len =
4045				    sizeof (ql_adapter_revlvl_t);
4046			}
4047			break;
4048		case QL_DIAG_LPBMBX:
4049
4050			if (cmd->pm_data_len != sizeof (struct app_mbx_cmd)) {
4051				EL(ha, "failed, QL_DIAG_LPBMBX "
4052				    "FC_INVALID_REQUEST, pmlen=%lxh, "
4053				    "reqd=%lxh\n", cmd->pm_data_len,
4054				    sizeof (struct app_mbx_cmd));
4055				rval = FC_INVALID_REQUEST;
4056				break;
4057			}
4058			/*
4059			 * Don't do the wrap test on a 2200 when the
4060			 * firmware is running.
4061			 */
4062			if (!CFG_IST(ha, CFG_CTRL_2200)) {
4063				mcp = (app_mbx_cmd_t *)cmd->pm_data_buf;
4064				mr.mb[1] = mcp->mb[1];
4065				mr.mb[2] = mcp->mb[2];
4066				mr.mb[3] = mcp->mb[3];
4067				mr.mb[4] = mcp->mb[4];
4068				mr.mb[5] = mcp->mb[5];
4069				mr.mb[6] = mcp->mb[6];
4070				mr.mb[7] = mcp->mb[7];
4071
4072				bcopy(&mr.mb[0], &mr.mb[10],
4073				    sizeof (uint16_t) * 8);
4074				if (ql_mbx_wrap_test(ha, &mr) != QL_SUCCESS) {
4075					EL(ha, "failed, QL_DIAG_LPBMBX "
4076					    "FC_FAILURE\n");
4077					rval = FC_FAILURE;
4078					break;
4079				}
4080				if (mr.mb[i0] != mr.mb[i0 + 10]) {
4081					EL(ha, "failed, QL_DIAG_LPBMBX "
4082					    "FC_FAILURE-2\n");
4083
4084					(void) ql_flash_errlog(ha,
4085					    FLASH_ERRLOG_ISP_ERR, 0,
4086					    RD16_IO_REG(ha, hccr),
4087					    RD16_IO_REG(ha, istatus));
4088
4089					rval = FC_FAILURE;
4090					break;
4091				}
4092			}
4093			(void) ql_abort_isp(ha);
4094			break;
4095		case QL_DIAG_LPBDTA:
4096			/*
4097			 * For loopback data, we receive the
4098			 * data back in pm_stat_buf. This provides
4099			 * the user an opportunity to compare the
4100			 * transmitted and received data.
4101			 *
4102			 * NB: lb->options are:
4103			 *	0 --> Ten bit loopback
4104			 *	1 --> One bit loopback
4105			 *	2 --> External loopback
4106			 */
4107			if (cmd->pm_data_len > 65536) {
4108				rval = FC_TOOMANY;
4109				EL(ha, "failed, QL_DIAG_LPBDTA "
4110				    "FC_TOOMANY=%lxh\n", cmd->pm_data_len);
4111				break;
4112			}
4113			if (ql_get_dma_mem(ha, &buffer_xmt,
4114			    (uint32_t)cmd->pm_data_len, LITTLE_ENDIAN_DMA,
4115			    QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
4116				EL(ha, "failed, QL_DIAG_LPBDTA FC_NOMEM\n");
4117				rval = FC_NOMEM;
4118				break;
4119			}
4120			if (ql_get_dma_mem(ha, &buffer_rcv,
4121			    (uint32_t)cmd->pm_data_len, LITTLE_ENDIAN_DMA,
4122			    QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
4123				EL(ha, "failed, QL_DIAG_LPBDTA FC_NOMEM-2\n");
4124				rval = FC_NOMEM;
4125				break;
4126			}
4127			ddi_rep_put8(buffer_xmt.acc_handle,
4128			    (uint8_t *)cmd->pm_data_buf,
4129			    (uint8_t *)buffer_xmt.bp,
4130			    cmd->pm_data_len, DDI_DEV_AUTOINCR);
4131
4132			/* 22xx's adapter must be in loop mode for test. */
4133			if (CFG_IST(ha, CFG_CTRL_2200)) {
4134				bptr = &ha->init_ctrl_blk.cb.add_fw_opt[0];
4135				if (ha->flags & POINT_TO_POINT ||
4136				    (ha->task_daemon_flags & LOOP_DOWN &&
4137				    *bptr & (BIT_6 | BIT_5 | BIT_4))) {
4138					cnt = *bptr;
4139					*bptr = (uint8_t)
4140					    (*bptr & ~(BIT_6|BIT_5|BIT_4));
4141					(void) ql_abort_isp(ha);
4142					*bptr = (uint8_t)cnt;
4143				}
4144			}
4145
4146			/* Shutdown IP. */
4147			if (pha->flags & IP_INITIALIZED) {
4148				(void) ql_shutdown_ip(pha);
4149			}
4150
4151			lb = (lbp_t *)cmd->pm_cmd_buf;
4152			lb->transfer_count =
4153			    (uint32_t)cmd->pm_data_len;
4154			lb->transfer_segment_count = 0;
4155			lb->receive_segment_count = 0;
4156			lb->transfer_data_address =
4157			    buffer_xmt.cookie.dmac_address;
4158			lb->receive_data_address =
4159			    buffer_rcv.cookie.dmac_address;
4160
4161			if ((lb->options & 7) == 2 &&
4162			    pha->task_daemon_flags &
4163			    (QL_LOOP_TRANSITION | LOOP_DOWN)) {
4164				/* Loop must be up for external */
4165				EL(ha, "failed, QL_DIAG_LPBDTA FC_TRAN_BUSY\n");
4166				rval = FC_TRAN_BUSY;
4167			} else if (ql_loop_back(ha, lb,
4168			    buffer_xmt.cookie.dmac_notused,
4169			    buffer_rcv.cookie.dmac_notused) == QL_SUCCESS) {
4170				bzero((void *)cmd->pm_stat_buf,
4171				    cmd->pm_stat_len);
4172				ddi_rep_get8(buffer_rcv.acc_handle,
4173				    (uint8_t *)cmd->pm_stat_buf,
4174				    (uint8_t *)buffer_rcv.bp,
4175				    cmd->pm_stat_len, DDI_DEV_AUTOINCR);
4176			} else {
4177				EL(ha, "failed, QL_DIAG_LPBDTA FC_FAILURE\n");
4178				rval = FC_FAILURE;
4179			}
4180
4181			ql_free_phys(ha, &buffer_xmt);
4182			ql_free_phys(ha, &buffer_rcv);
4183
4184			/* Needed to recover the f/w */
4185			(void) ql_abort_isp(ha);
4186
4187			/* Restart IP if it was shutdown. */
4188			if (pha->flags & IP_ENABLED &&
4189			    !(pha->flags & IP_INITIALIZED)) {
4190				(void) ql_initialize_ip(pha);
4191				ql_isp_rcvbuf(pha);
4192			}
4193
4194			break;
4195		case QL_DIAG_ECHO: {
4196			/*
4197			 * issue an echo command with a user supplied
4198			 * data pattern and destination address
4199			 */
4200			echo_t		echo;		/* temp echo struct */
4201
4202			/* Setup echo cmd & adjust for platform */
4203			opcode = QL_ECHO_CMD;
4204			BIG_ENDIAN_32(&opcode);
4205
4206			/*
4207			 * due to limitations in the ql
4208			 * firmaware the echo data field is
4209			 * limited to 220
4210			 */
4211			if ((cmd->pm_cmd_len > QL_ECHO_CMD_LENGTH) ||
4212			    (cmd->pm_stat_len > QL_ECHO_CMD_LENGTH)) {
4213				EL(ha, "failed, QL_DIAG_ECHO FC_TOOMANY, "
4214				    "cmdl1=%lxh, statl2=%lxh\n",
4215				    cmd->pm_cmd_len, cmd->pm_stat_len);
4216				rval = FC_TOOMANY;
4217				break;
4218			}
4219
4220			/*
4221			 * the input data buffer has the user
4222			 * supplied data pattern.  The "echoed"
4223			 * data will be DMAed into the output
4224			 * data buffer.  Therefore the length
4225			 * of the output buffer must be equal
4226			 * to or greater then the input buffer
4227			 * length
4228			 */
4229			if (cmd->pm_cmd_len > cmd->pm_stat_len) {
4230				EL(ha, "failed, QL_DIAG_ECHO FC_TOOMANY-2,"
4231				    " cmdl1=%lxh, statl2=%lxh\n",
4232				    cmd->pm_cmd_len, cmd->pm_stat_len);
4233				rval = FC_TOOMANY;
4234				break;
4235			}
4236			/* add four bytes for the opcode */
4237			echo.transfer_count = (uint32_t)(cmd->pm_cmd_len + 4);
4238
4239			/*
4240			 * are we 32 or 64 bit addressed???
4241			 * We need to get the appropriate
4242			 * DMA and set the command options;
4243			 * 64 bit (bit 6) or 32 bit
4244			 * (no bit 6) addressing.
4245			 * while we are at it lets ask for
4246			 * real echo (bit 15)
4247			 */
4248			echo.options = BIT_15;
4249			if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
4250				echo.options = (uint16_t)
4251				    (echo.options | BIT_6);
4252			}
4253
4254			/*
4255			 * Set up the DMA mappings for the
4256			 * output and input data buffers.
4257			 * First the output buffer
4258			 */
4259			if (ql_get_dma_mem(ha, &buffer_xmt,
4260			    (uint32_t)(cmd->pm_data_len + 4),
4261			    LITTLE_ENDIAN_DMA,
4262			    QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
4263				EL(ha, "failed, QL_DIAG_ECHO FC_NOMEM\n");
4264				rval = FC_NOMEM;
4265				break;
4266			}
4267			echo.transfer_data_address = buffer_xmt.cookie;
4268
4269			/* Next the input buffer */
4270			if (ql_get_dma_mem(ha, &buffer_rcv,
4271			    (uint32_t)(cmd->pm_data_len + 4),
4272			    LITTLE_ENDIAN_DMA,
4273			    QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
4274				/*
4275				 * since we could not allocate
4276				 * DMA space for the input
4277				 * buffer we need to clean up
4278				 * by freeing the DMA space
4279				 * we allocated for the output
4280				 * buffer
4281				 */
4282				ql_free_phys(ha, &buffer_xmt);
4283				EL(ha, "failed, QL_DIAG_ECHO FC_NOMEM-2\n");
4284				rval = FC_NOMEM;
4285				break;
4286			}
4287			echo.receive_data_address = buffer_rcv.cookie;
4288
4289			/*
4290			 * copy the 4 byte ECHO op code to the
4291			 * allocated DMA space
4292			 */
4293			ddi_rep_put8(buffer_xmt.acc_handle, (uint8_t *)&opcode,
4294			    (uint8_t *)buffer_xmt.bp, 4, DDI_DEV_AUTOINCR);
4295
4296			/*
4297			 * copy the user supplied data to the
4298			 * allocated DMA space
4299			 */
4300			ddi_rep_put8(buffer_xmt.acc_handle,
4301			    (uint8_t *)cmd->pm_cmd_buf,
4302			    (uint8_t *)buffer_xmt.bp + 4, cmd->pm_cmd_len,
4303			    DDI_DEV_AUTOINCR);
4304
4305			/* Shutdown IP. */
4306			if (pha->flags & IP_INITIALIZED) {
4307				(void) ql_shutdown_ip(pha);
4308			}
4309
4310			/* send the echo */
4311			if (ql_echo(ha, &echo) == QL_SUCCESS) {
4312				ddi_rep_put8(buffer_rcv.acc_handle,
4313				    (uint8_t *)buffer_rcv.bp + 4,
4314				    (uint8_t *)cmd->pm_stat_buf,
4315				    cmd->pm_stat_len, DDI_DEV_AUTOINCR);
4316			} else {
4317				EL(ha, "failed, QL_DIAG_ECHO FC_FAILURE\n");
4318				rval = FC_FAILURE;
4319			}
4320
4321			/* Restart IP if it was shutdown. */
4322			if (pha->flags & IP_ENABLED &&
4323			    !(pha->flags & IP_INITIALIZED)) {
4324				(void) ql_initialize_ip(pha);
4325				ql_isp_rcvbuf(pha);
4326			}
4327			/* free up our DMA buffers */
4328			ql_free_phys(ha, &buffer_xmt);
4329			ql_free_phys(ha, &buffer_rcv);
4330			break;
4331		}
4332		default:
4333			EL(ha, "unknown=%xh, FC_PORT_DIAG "
4334			    "FC_INVALID_REQUEST\n", cmd->pm_cmd_flags);
4335			rval = FC_INVALID_REQUEST;
4336			break;
4337		}
4338		PORTMANAGE_UNLOCK(ha);
4339		break;
4340	case FC_PORT_LINK_STATE:
4341		/* Check for name equal to null. */
4342		for (index = 0; index < 8 && index < cmd->pm_cmd_len;
4343		    index++) {
4344			if (cmd->pm_cmd_buf[index] != 0) {
4345				break;
4346			}
4347		}
4348
4349		/* If name not null. */
4350		if (index < 8 && cmd->pm_cmd_len >= 8) {
4351			/* Locate device queue. */
4352			tq = NULL;
4353			for (index = 0; index < DEVICE_HEAD_LIST_SIZE &&
4354			    tq == NULL; index++) {
4355				for (link = ha->dev[index].first; link != NULL;
4356				    link = link->next) {
4357					tq = link->base_address;
4358
4359					if (bcmp((void *)&tq->port_name[0],
4360					    (void *)cmd->pm_cmd_buf, 8) == 0) {
4361						break;
4362					} else {
4363						tq = NULL;
4364					}
4365				}
4366			}
4367
4368			if (tq != NULL && VALID_DEVICE_ID(ha, tq->loop_id)) {
4369				cmd->pm_stat_buf[0] = (int8_t)LSB(ha->state);
4370				cmd->pm_stat_buf[1] = (int8_t)MSB(ha->state);
4371			} else {
4372				cnt = FC_PORT_SPEED_MASK(ha->state) |
4373				    FC_STATE_OFFLINE;
4374				cmd->pm_stat_buf[0] = (int8_t)LSB(cnt);
4375				cmd->pm_stat_buf[1] = (int8_t)MSB(cnt);
4376			}
4377		} else {
4378			cmd->pm_stat_buf[0] = (int8_t)LSB(ha->state);
4379			cmd->pm_stat_buf[1] = (int8_t)MSB(ha->state);
4380		}
4381		break;
4382	case FC_PORT_INITIALIZE:
4383		if (cmd->pm_cmd_len >= 8) {
4384			tq = NULL;
4385			for (index = 0; index < DEVICE_HEAD_LIST_SIZE &&
4386			    tq == NULL; index++) {
4387				for (link = ha->dev[index].first; link != NULL;
4388				    link = link->next) {
4389					tq = link->base_address;
4390
4391					if (bcmp((void *)&tq->port_name[0],
4392					    (void *)cmd->pm_cmd_buf, 8) == 0) {
4393						if (!VALID_DEVICE_ID(ha,
4394						    tq->loop_id)) {
4395							tq = NULL;
4396						}
4397						break;
4398					} else {
4399						tq = NULL;
4400					}
4401				}
4402			}
4403
4404			if (tq == NULL || ql_target_reset(ha, tq,
4405			    ha->loop_reset_delay) != QL_SUCCESS) {
4406				EL(ha, "failed, FC_PORT_INITIALIZE "
4407				    "FC_FAILURE\n");
4408				rval = FC_FAILURE;
4409			}
4410		} else {
4411			EL(ha, "failed, FC_PORT_INITIALIZE FC_FAILURE-2, "
4412			    "clen=%lxh\n", cmd->pm_cmd_len);
4413
4414			rval = FC_FAILURE;
4415		}
4416		break;
4417	case FC_PORT_RLS:
4418		if (cmd->pm_data_len < sizeof (fc_rls_acc_t)) {
4419			EL(ha, "failed, buffer size passed: %lxh, "
4420			    "req: %lxh\n", cmd->pm_data_len,
4421			    (sizeof (fc_rls_acc_t)));
4422			rval = FC_FAILURE;
4423		} else if (LOOP_NOT_READY(pha)) {
4424			EL(ha, "loop NOT ready\n");
4425			bzero(cmd->pm_data_buf, cmd->pm_data_len);
4426		} else if (ql_get_link_status(ha, ha->loop_id,
4427		    cmd->pm_data_len, cmd->pm_data_buf, 0) != QL_SUCCESS) {
4428			EL(ha, "failed, FC_PORT_RLS FC_FAILURE\n");
4429			rval = FC_FAILURE;
4430#ifdef _BIG_ENDIAN
4431		} else {
4432			fc_rls_acc_t		*rls;
4433
4434			rls = (fc_rls_acc_t *)cmd->pm_data_buf;
4435			LITTLE_ENDIAN_32(&rls->rls_link_fail);
4436			LITTLE_ENDIAN_32(&rls->rls_sync_loss);
4437			LITTLE_ENDIAN_32(&rls->rls_sig_loss);
4438			LITTLE_ENDIAN_32(&rls->rls_invalid_crc);
4439#endif /* _BIG_ENDIAN */
4440		}
4441		break;
4442	case FC_PORT_GET_NODE_ID:
4443		if (ql_get_rnid_params(ha, cmd->pm_data_len,
4444		    cmd->pm_data_buf) != QL_SUCCESS) {
4445			EL(ha, "failed, FC_PORT_GET_NODE_ID FC_FAILURE\n");
4446			rval = FC_FAILURE;
4447		}
4448		break;
4449	case FC_PORT_SET_NODE_ID:
4450		if (ql_set_rnid_params(ha, cmd->pm_data_len,
4451		    cmd->pm_data_buf) != QL_SUCCESS) {
4452			EL(ha, "failed, FC_PORT_SET_NODE_ID FC_FAILURE\n");
4453			rval = FC_FAILURE;
4454		}
4455		break;
4456	case FC_PORT_DOWNLOAD_FCODE:
4457		PORTMANAGE_LOCK(ha);
4458		if ((CFG_IST(ha, CFG_CTRL_2425)) == 0) {
4459			rval = ql_load_flash(ha, (uint8_t *)cmd->pm_data_buf,
4460			    (uint32_t)cmd->pm_data_len);
4461		} else {
4462			if (cmd->pm_data_buf[0] == 4 &&
4463			    cmd->pm_data_buf[8] == 0 &&
4464			    cmd->pm_data_buf[9] == 0x10 &&
4465			    cmd->pm_data_buf[10] == 0 &&
4466			    cmd->pm_data_buf[11] == 0) {
4467				rval = ql_24xx_load_flash(ha,
4468				    (uint8_t *)cmd->pm_data_buf,
4469				    (uint32_t)cmd->pm_data_len,
4470				    FLASH_24XX_FIRMWARE_ADDR);
4471			} else {
4472				rval = ql_24xx_load_flash(ha,
4473				    (uint8_t *)cmd->pm_data_buf,
4474				    (uint32_t)cmd->pm_data_len, 0);
4475			}
4476		}
4477
4478		if (rval != QL_SUCCESS) {
4479			EL(ha, "failed, FC_PORT_DOWNLOAD_FCODE FC_FAILURE\n");
4480			rval = FC_FAILURE;
4481		} else {
4482			rval = FC_SUCCESS;
4483		}
4484		ql_reset_chip(ha);
4485		(void) ql_abort_isp(ha);
4486		PORTMANAGE_UNLOCK(ha);
4487		break;
4488	default:
4489		EL(ha, "unknown=%xh, FC_BADCMD\n", cmd->pm_cmd_code);
4490		rval = FC_BADCMD;
4491		break;
4492	}
4493
4494	/* Wait for suspension to end. */
4495	ql_awaken_task_daemon(ha, NULL, 0, DRIVER_STALL);
4496	timer = 0;
4497
4498	while (timer++ < 3000 &&
4499	    ha->task_daemon_flags & (QL_LOOP_TRANSITION | DRIVER_STALL)) {
4500		ql_delay(ha, 10000);
4501	}
4502
4503	ql_restart_queues(ha);
4504
4505	if (rval != FC_SUCCESS) {
4506		EL(ha, "failed, rval = %xh\n", rval);
4507	} else {
4508		/*EMPTY*/
4509		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4510	}
4511
4512	return (rval);
4513}
4514
4515static opaque_t
4516ql_get_device(opaque_t fca_handle, fc_portid_t d_id)
4517{
4518	port_id_t		id;
4519	ql_adapter_state_t	*ha;
4520
4521	id.r.rsvd_1 = 0;
4522	id.b24 = d_id.port_id;
4523
4524	ha = ql_fca_handle_to_state(fca_handle);
4525	if (ha == NULL) {
4526		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
4527		    (void *)fca_handle);
4528		return (NULL);
4529	}
4530
4531	return (ql_d_id_to_queue(ha, id));
4532}
4533
4534/*
4535 * ql_notify
4536 *	Receive notifications from ULPs regarding particular actions
4537 *
4538 * Input:
4539 *	fca_handle = handle set up by ql_bind_port().
4540 *	cmd = flag indicating the action to take
4541 *
4542 * Output:
4543 *	FC_SUCCESS - action was taken successfully or no action was needed.
4544 *	FC_FAILURE - action was attempted and failed.
4545 *	FC_UNBOUND - the specified handle is not bound to a port.
4546 */
4547static int
4548ql_notify(opaque_t fca_handle, uint32_t cmd)
4549{
4550	ql_adapter_state_t		*ha;
4551	int				rval = FC_SUCCESS;
4552	tgt_cmd_t			*tgtcmd;
4553	notify_acknowledge_entry_t	*nack;
4554
4555	ha = ql_fca_handle_to_state(fca_handle);
4556	if (ha == NULL) {
4557		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
4558		    (void *)fca_handle);
4559		return (FC_UNBOUND);
4560	}
4561	QL_PRINT_3(CE_CONT, "(%d): started cmd = %xh\n", ha->instance, cmd);
4562
4563	switch (FC_NOTIFY_GET_FLAG(cmd)) {
4564	case FC_NOTIFY_RECOVERY_DONE:
4565
4566		QL_PRINT_3(CE_CONT, "(%d): got NOTIFY_RECOVERY cmd=%xh\n",
4567		    ha->instance, cmd);
4568
4569		mutex_enter(&ha->ql_nack_mtx);
4570		tgtcmd = ha->ql_nack;
4571		ha->ql_nack = NULL;
4572		mutex_exit(&ha->ql_nack_mtx);
4573
4574		if (tgtcmd != NULL) {
4575			QL_PRINT_3(CE_CONT, "(%d): N_ACK pending\n",
4576			    ha->instance);
4577
4578			rval = ql_req_pkt(ha, (request_t **)&nack);
4579			if (rval == QL_SUCCESS) {
4580				ql_notify_acknowledge_iocb(ha, tgtcmd, nack);
4581
4582				QL_PRINT_3(CE_CONT, "(%d): send notify_ack: "
4583				    "status=%xh flag=%xh\n", ha->instance,
4584				    tgtcmd->status, nack->flags_l);
4585
4586				kmem_free(tgtcmd, sizeof (tgt_cmd_t));
4587				/* Issue command to ISP */
4588				ql_isp_cmd(ha);
4589			} else {
4590				kmem_free(tgtcmd, sizeof (tgt_cmd_t));
4591			}
4592		}
4593		break;
4594
4595	case FC_NOTIFY_RECOVERY_CLEANUP:
4596		break;
4597
4598	case FC_NOTIFY_TARGET_MODE:
4599		if (CFG_IST(ha, CFG_TARGET_MODE_ENABLE)) {
4600			break;
4601		}
4602
4603		ha->cfg_flags |= (CFG_ENABLE_TARGET_MODE |
4604		    CFG_ENABLE_HARD_ADDRESS);
4605		ha->port_hard_address.r.d_id[0] =
4606		    LSB(LSW(FC_NOTIFY_GET_VALUE(cmd)));
4607		ha->port_hard_address.r.d_id[1] =
4608		    MSB(LSW(FC_NOTIFY_GET_VALUE(cmd)));
4609		ha->port_hard_address.r.d_id[2] =
4610		    LSB(MSW(FC_NOTIFY_GET_VALUE(cmd)));
4611		QL_PRINT_3(CE_CONT, "(%d): Target mode set, hard address ="
4612		    " %xh\n", ha->instance, ha->port_hard_address.b24);
4613		rval = ql_initialize_adapter(ha);
4614		ql_awaken_task_daemon(ha, NULL, 0, 0);
4615		break;
4616
4617	case FC_NOTIFY_NO_TARGET_MODE:
4618		if (!CFG_IST(ha, CFG_TARGET_MODE_ENABLE)) {
4619			break;
4620		}
4621		ha->cfg_flags &= ~(CFG_ENABLE_TARGET_MODE |
4622		    CFG_ENABLE_HARD_ADDRESS);
4623		QL_PRINT_3(CE_CONT, "(%d): Target mode cleared\n",
4624		    ha->instance);
4625		rval = ql_initialize_adapter(ha);
4626		ql_awaken_task_daemon(ha, NULL, 0, LOOP_DOWN);
4627		break;
4628
4629	case FC_NOTIFY_THROTTLE:
4630		cmn_err(CE_NOTE, "!%s(%d) max cmds per target %xh", QL_NAME,
4631		    ha->instance, FC_NOTIFY_GET_VALUE(cmd));
4632		break;
4633
4634	default:
4635		break;
4636	}
4637
4638	if (rval != FC_SUCCESS) {
4639		EL(ha, "failed=%xh\n", rval);
4640	} else {
4641		/*EMPTY*/
4642		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4643	}
4644	return (rval);
4645}
4646
4647/* ************************************************************************ */
4648/*			FCA Driver Local Support Functions.		    */
4649/* ************************************************************************ */
4650
4651/*
4652 * ql_cmd_setup
4653 *	Verifies proper command.
4654 *
4655 * Input:
4656 *	fca_handle = handle setup by ql_bind_port().
4657 *	pkt = pointer to fc_packet.
4658 *	rval = pointer for return value.
4659 *
4660 * Returns:
4661 *	Adapter state pointer, NULL = failure.
4662 *
4663 * Context:
4664 *	Kernel context.
4665 */
4666static ql_adapter_state_t *
4667ql_cmd_setup(opaque_t fca_handle, fc_packet_t *pkt, int *rval)
4668{
4669	ql_adapter_state_t	*ha, *pha;
4670	ql_srb_t		*sp = (ql_srb_t *)pkt->pkt_fca_private;
4671	ql_tgt_t		*tq;
4672	port_id_t		d_id;
4673
4674	pkt->pkt_resp_resid = 0;
4675	pkt->pkt_data_resid = 0;
4676
4677	/* check that the handle is assigned by this FCA */
4678	ha = ql_fca_handle_to_state(fca_handle);
4679	if (ha == NULL) {
4680		*rval = FC_UNBOUND;
4681		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
4682		    (void *)fca_handle);
4683		return (NULL);
4684	}
4685	pha = ha->pha;
4686
4687	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4688
4689	if (ddi_in_panic() || pkt->pkt_tran_flags & FC_TRAN_DUMPING) {
4690		return (ha);
4691	}
4692
4693	if (!(pha->flags & ONLINE)) {
4694		pkt->pkt_state = FC_PKT_LOCAL_RJT;
4695		pkt->pkt_reason = FC_REASON_HW_ERROR;
4696		*rval = FC_TRANSPORT_ERROR;
4697		EL(ha, "failed, not online hf=%xh\n", pha->flags);
4698		return (NULL);
4699	}
4700
4701	/* Exit on loop down. */
4702	if (CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING) &&
4703	    pha->task_daemon_flags & LOOP_DOWN &&
4704	    pha->loop_down_timer <= pha->loop_down_abort_time) {
4705		pkt->pkt_state = FC_PKT_PORT_OFFLINE;
4706		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
4707		*rval = FC_OFFLINE;
4708		EL(ha, "failed, loop down tdf=%xh\n", pha->task_daemon_flags);
4709		return (NULL);
4710	}
4711
4712	if (pkt->pkt_cmd_fhdr.r_ctl == R_CTL_COMMAND &&
4713	    pkt->pkt_cmd_fhdr.type == FC_TYPE_SCSI_FCP) {
4714		tq = (ql_tgt_t *)pkt->pkt_fca_device;
4715		if ((tq == NULL) || (!VALID_DEVICE_ID(ha, tq->loop_id))) {
4716			d_id.r.rsvd_1 = 0;
4717			d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
4718			tq = ql_d_id_to_queue(ha, d_id);
4719
4720			pkt->pkt_fca_device = (opaque_t)tq;
4721		}
4722
4723		if (tq != NULL) {
4724			DEVICE_QUEUE_LOCK(tq);
4725			if (tq->flags & (TQF_RSCN_RCVD |
4726			    TQF_NEED_AUTHENTICATION)) {
4727				*rval = FC_DEVICE_BUSY;
4728				DEVICE_QUEUE_UNLOCK(tq);
4729				EL(ha, "failed, busy qf=%xh, d_id=%xh\n",
4730				    tq->flags, tq->d_id.b24);
4731				return (NULL);
4732			}
4733			DEVICE_QUEUE_UNLOCK(tq);
4734		}
4735	}
4736
4737	/*
4738	 * Check DMA pointers.
4739	 */
4740	*rval = DDI_SUCCESS;
4741	if (pkt->pkt_cmd_acc != NULL && pkt->pkt_cmdlen) {
4742		QL_CLEAR_DMA_HANDLE(pkt->pkt_cmd_dma);
4743		*rval = ddi_check_dma_handle(pkt->pkt_cmd_dma);
4744		if (*rval == DDI_SUCCESS) {
4745			*rval = ddi_check_acc_handle(pkt->pkt_cmd_acc);
4746		}
4747	}
4748
4749	if (pkt->pkt_resp_acc != NULL && *rval == DDI_SUCCESS &&
4750	    pkt->pkt_rsplen != 0) {
4751		QL_CLEAR_DMA_HANDLE(pkt->pkt_resp_dma);
4752		*rval = ddi_check_dma_handle(pkt->pkt_resp_dma);
4753		if (*rval == DDI_SUCCESS) {
4754			*rval = ddi_check_acc_handle(pkt->pkt_resp_acc);
4755		}
4756	}
4757
4758	/*
4759	 * Minimum branch conditional; Change it with care.
4760	 */
4761	if (((pkt->pkt_data_acc != NULL) & (*rval == DDI_SUCCESS) &
4762	    (pkt->pkt_datalen != 0)) != 0) {
4763		QL_CLEAR_DMA_HANDLE(pkt->pkt_data_dma);
4764		*rval = ddi_check_dma_handle(pkt->pkt_data_dma);
4765		if (*rval == DDI_SUCCESS) {
4766			*rval = ddi_check_acc_handle(pkt->pkt_data_acc);
4767		}
4768	}
4769
4770	if (*rval != DDI_SUCCESS) {
4771		pkt->pkt_state = FC_PKT_TRAN_ERROR;
4772		pkt->pkt_reason = FC_REASON_DMA_ERROR;
4773
4774		/* Do command callback. */
4775		if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
4776			ql_awaken_task_daemon(ha, sp, 0, 0);
4777		}
4778		*rval = FC_BADPACKET;
4779		EL(ha, "failed, bad DMA pointers\n");
4780		return (NULL);
4781	}
4782
4783	if (sp->magic_number != QL_FCA_BRAND) {
4784		*rval = FC_BADPACKET;
4785		EL(ha, "failed, magic number=%xh\n", sp->magic_number);
4786		return (NULL);
4787	}
4788	*rval = FC_SUCCESS;
4789
4790	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4791
4792	return (ha);
4793}
4794
4795/*
4796 * ql_els_plogi
4797 *	Issue a extended link service port login request.
4798 *
4799 * Input:
4800 *	ha = adapter state pointer.
4801 *	pkt = pointer to fc_packet.
4802 *
4803 * Returns:
4804 *	FC_SUCCESS - the packet was accepted for transport.
4805 *	FC_TRANSPORT_ERROR - a transport error occurred.
4806 *
4807 * Context:
4808 *	Kernel context.
4809 */
4810static int
4811ql_els_plogi(ql_adapter_state_t *ha, fc_packet_t *pkt)
4812{
4813	ql_tgt_t		*tq = NULL;
4814	port_id_t		d_id;
4815	la_els_logi_t		acc;
4816	class_svc_param_t	*class3_param;
4817	int			ret;
4818	int			rval = FC_SUCCESS;
4819
4820	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4821
4822	TASK_DAEMON_LOCK(ha);
4823	if (!(ha->task_daemon_flags & STATE_ONLINE)) {
4824		TASK_DAEMON_UNLOCK(ha);
4825		QL_PRINT_3(CE_CONT, "(%d): offline done\n", ha->instance);
4826		return (FC_OFFLINE);
4827	}
4828	TASK_DAEMON_UNLOCK(ha);
4829
4830	bzero(&acc, sizeof (acc));
4831	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
4832
4833	switch (ret = ql_login_port(ha, d_id)) {
4834	case QL_SUCCESS:
4835		tq = ql_d_id_to_queue(ha, d_id);
4836		break;
4837
4838	case QL_LOOP_ID_USED:
4839		if ((ret = ql_login_port(ha, d_id)) == QL_SUCCESS) {
4840			tq = ql_d_id_to_queue(ha, d_id);
4841		}
4842		break;
4843
4844	default:
4845		break;
4846	}
4847
4848	if (ret != QL_SUCCESS) {
4849		/*
4850		 * Invalidate this entry so as to seek a fresh loop ID
4851		 * in case firmware reassigns it to something else
4852		 */
4853		tq = ql_d_id_to_queue(ha, d_id);
4854		if (tq && (ret != QL_MEMORY_ALLOC_FAILED)) {
4855			tq->loop_id = PORT_NO_LOOP_ID;
4856		}
4857	} else if (tq) {
4858		(void) ql_get_port_database(ha, tq, PDF_ADISC);
4859	}
4860
4861	if (tq != NULL && VALID_DEVICE_ID(ha, tq->loop_id) &&
4862	    (ret != QL_MEMORY_ALLOC_FAILED) && PD_PORT_LOGIN(tq)) {
4863
4864		/* Build ACC. */
4865		acc.ls_code.ls_code = LA_ELS_ACC;
4866		acc.common_service.fcph_version = 0x2006;
4867		acc.common_service.cmn_features = 0x8800;
4868		CFG_IST(ha, CFG_CTRL_2425) ?
4869		    (acc.common_service.rx_bufsize = CHAR_TO_SHORT(
4870		    ha->init_ctrl_blk.cb24.max_frame_length[0],
4871		    ha->init_ctrl_blk.cb24.max_frame_length[1])) :
4872		    (acc.common_service.rx_bufsize = CHAR_TO_SHORT(
4873		    ha->init_ctrl_blk.cb.max_frame_length[0],
4874		    ha->init_ctrl_blk.cb.max_frame_length[1]));
4875		acc.common_service.conc_sequences = 0xff;
4876		acc.common_service.relative_offset = 0x03;
4877		acc.common_service.e_d_tov = 0x7d0;
4878
4879		bcopy((void *)&tq->port_name[0],
4880		    (void *)&acc.nport_ww_name.raw_wwn[0], 8);
4881		bcopy((void *)&tq->node_name[0],
4882		    (void *)&acc.node_ww_name.raw_wwn[0], 8);
4883
4884		class3_param = (class_svc_param_t *)&acc.class_3;
4885		class3_param->class_valid_svc_opt = 0x8000;
4886		class3_param->recipient_ctl = tq->class3_recipient_ctl;
4887		class3_param->rcv_data_size = tq->class3_rcv_data_size;
4888		class3_param->conc_sequences = tq->class3_conc_sequences;
4889		class3_param->open_sequences_per_exch =
4890		    tq->class3_open_sequences_per_exch;
4891
4892		if ((ql_busy_plogi(ha, pkt, tq) == FC_TRAN_BUSY)) {
4893			acc.ls_code.ls_code = LA_ELS_RJT;
4894			pkt->pkt_state = FC_PKT_TRAN_BSY;
4895			pkt->pkt_reason = FC_REASON_XCHG_BSY;
4896			rval = FC_TRAN_BUSY;
4897		} else {
4898			DEVICE_QUEUE_LOCK(tq);
4899			tq->logout_sent = 0;
4900			tq->flags &= ~TQF_NEED_AUTHENTICATION;
4901			if (CFG_IST(ha, CFG_CTRL_2425)) {
4902				tq->flags |= TQF_IIDMA_NEEDED;
4903			}
4904			DEVICE_QUEUE_UNLOCK(tq);
4905
4906			if (CFG_IST(ha, CFG_CTRL_2425)) {
4907				TASK_DAEMON_LOCK(ha);
4908				ha->task_daemon_flags |= TD_IIDMA_NEEDED;
4909				TASK_DAEMON_UNLOCK(ha);
4910			}
4911
4912			pkt->pkt_state = FC_PKT_SUCCESS;
4913		}
4914	} else {
4915		/* Build RJT. */
4916		acc.ls_code.ls_code = LA_ELS_RJT;
4917
4918		switch (ret) {
4919		case QL_FUNCTION_TIMEOUT:
4920			pkt->pkt_state = FC_PKT_TIMEOUT;
4921			pkt->pkt_reason = FC_REASON_HW_ERROR;
4922			break;
4923
4924		case QL_MEMORY_ALLOC_FAILED:
4925			pkt->pkt_state = FC_PKT_LOCAL_BSY;
4926			pkt->pkt_reason = FC_REASON_NOMEM;
4927			rval = FC_TRAN_BUSY;
4928			break;
4929
4930		case QL_FABRIC_NOT_INITIALIZED:
4931			pkt->pkt_state = FC_PKT_FABRIC_BSY;
4932			pkt->pkt_reason = FC_REASON_NO_CONNECTION;
4933			rval = FC_TRAN_BUSY;
4934			break;
4935
4936		default:
4937			pkt->pkt_state = FC_PKT_TRAN_ERROR;
4938			pkt->pkt_reason = FC_REASON_NO_CONNECTION;
4939			break;
4940		}
4941
4942		EL(ha, "Plogi unsuccess for %xh state %xh reason %xh "
4943		    "ret %xh rval %xh\n", d_id.b24, pkt->pkt_state,
4944		    pkt->pkt_reason, ret, rval);
4945	}
4946
4947	if (tq != NULL) {
4948		DEVICE_QUEUE_LOCK(tq);
4949		tq->flags &= ~(TQF_PLOGI_PROGRS | TQF_QUEUE_SUSPENDED);
4950		if (rval == FC_TRAN_BUSY) {
4951			if (tq->d_id.b24 != BROADCAST_ADDR) {
4952				tq->flags |= TQF_NEED_AUTHENTICATION;
4953			}
4954		}
4955		DEVICE_QUEUE_UNLOCK(tq);
4956	}
4957
4958	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
4959	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
4960
4961	if (rval != FC_SUCCESS) {
4962		EL(ha, "failed, rval = %xh\n", rval);
4963	} else {
4964		/*EMPTY*/
4965		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4966	}
4967	return (rval);
4968}
4969
4970/*
4971 * ql_els_flogi
4972 *	Issue a extended link service fabric login request.
4973 *
4974 * Input:
4975 *	ha = adapter state pointer.
4976 *	pkt = pointer to fc_packet.
4977 *
4978 * Returns:
4979 *	FC_SUCCESS - the packet was accepted for transport.
4980 *	FC_TRANSPORT_ERROR - a transport error occurred.
4981 *
4982 * Context:
4983 *	Kernel context.
4984 */
4985static int
4986ql_els_flogi(ql_adapter_state_t *ha, fc_packet_t *pkt)
4987{
4988	ql_tgt_t		*tq = NULL;
4989	port_id_t		d_id;
4990	la_els_logi_t		acc;
4991	class_svc_param_t	*class3_param;
4992	int			rval = FC_SUCCESS;
4993
4994	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4995
4996	bzero(&acc, sizeof (acc));
4997	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
4998
4999	tq = ql_d_id_to_queue(ha, d_id);
5000	if (tq != NULL) {
5001		/* Build ACC. */
5002		acc.ls_code.ls_code = LA_ELS_ACC;
5003		acc.common_service.fcph_version = 0x2006;
5004		acc.common_service.cmn_features = 0x1b00;
5005		CFG_IST(ha, CFG_CTRL_2425) ?
5006		    (acc.common_service.rx_bufsize = CHAR_TO_SHORT(
5007		    ha->init_ctrl_blk.cb24.max_frame_length[0],
5008		    ha->init_ctrl_blk.cb24.max_frame_length[1])) :
5009		    (acc.common_service.rx_bufsize = CHAR_TO_SHORT(
5010		    ha->init_ctrl_blk.cb.max_frame_length[0],
5011		    ha->init_ctrl_blk.cb.max_frame_length[1]));
5012		acc.common_service.conc_sequences = 0xff;
5013		acc.common_service.relative_offset = 0x03;
5014		acc.common_service.e_d_tov = 0x7d0;
5015
5016		bcopy((void *)&tq->port_name[0],
5017		    (void *)&acc.nport_ww_name.raw_wwn[0], 8);
5018		bcopy((void *)&tq->node_name[0],
5019		    (void *)&acc.node_ww_name.raw_wwn[0], 8);
5020
5021		class3_param = (class_svc_param_t *)&acc.class_3;
5022		class3_param->class_valid_svc_opt = 0x8800;
5023		class3_param->recipient_ctl = tq->class3_recipient_ctl;
5024		class3_param->rcv_data_size = tq->class3_rcv_data_size;
5025		class3_param->conc_sequences = tq->class3_conc_sequences;
5026		class3_param->open_sequences_per_exch =
5027		    tq->class3_open_sequences_per_exch;
5028
5029		pkt->pkt_state = FC_PKT_SUCCESS;
5030	} else {
5031		/* Build RJT. */
5032		acc.ls_code.ls_code = LA_ELS_RJT;
5033
5034		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5035		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5036	}
5037
5038	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5039	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5040
5041	if (rval != FC_SUCCESS) {
5042		EL(ha, "failed, rval = %xh\n", rval);
5043	} else {
5044		/*EMPTY*/
5045		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5046	}
5047	return (rval);
5048}
5049
5050/*
5051 * ql_els_logo
5052 *	Issue a extended link service logout request.
5053 *
5054 * Input:
5055 *	ha = adapter state pointer.
5056 *	pkt = pointer to fc_packet.
5057 *
5058 * Returns:
5059 *	FC_SUCCESS - the packet was accepted for transport.
5060 *	FC_TRANSPORT_ERROR - a transport error occurred.
5061 *
5062 * Context:
5063 *	Kernel context.
5064 */
5065static int
5066ql_els_logo(ql_adapter_state_t *ha, fc_packet_t *pkt)
5067{
5068	port_id_t	d_id;
5069	ql_tgt_t	*tq;
5070	la_els_logo_t	acc;
5071	int		rval = FC_SUCCESS;
5072
5073	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5074
5075	bzero(&acc, sizeof (acc));
5076	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5077
5078	tq = ql_d_id_to_queue(ha, d_id);
5079	if (tq) {
5080		DEVICE_QUEUE_LOCK(tq);
5081		if (tq->d_id.b24 == BROADCAST_ADDR) {
5082			DEVICE_QUEUE_UNLOCK(tq);
5083			return (FC_SUCCESS);
5084		}
5085
5086		tq->flags |= TQF_NEED_AUTHENTICATION;
5087
5088		do {
5089			DEVICE_QUEUE_UNLOCK(tq);
5090			(void) ql_abort_device(ha, tq, 1);
5091
5092			/*
5093			 * Wait for commands to drain in F/W (doesn't
5094			 * take more than a few milliseconds)
5095			 */
5096			ql_delay(ha, 10000);
5097
5098			DEVICE_QUEUE_LOCK(tq);
5099		} while (tq->outcnt);
5100
5101		DEVICE_QUEUE_UNLOCK(tq);
5102	}
5103
5104	if (ql_logout_port(ha, d_id) == QL_SUCCESS) {
5105		/* Build ACC. */
5106		acc.ls_code.ls_code = LA_ELS_ACC;
5107
5108		pkt->pkt_state = FC_PKT_SUCCESS;
5109	} else {
5110		/* Build RJT. */
5111		acc.ls_code.ls_code = LA_ELS_RJT;
5112
5113		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5114		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5115	}
5116
5117	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5118	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5119
5120	if (rval != FC_SUCCESS) {
5121		EL(ha, "failed, rval = %xh\n", rval);
5122	} else {
5123		/*EMPTY*/
5124		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5125	}
5126	return (rval);
5127}
5128
5129/*
5130 * ql_els_prli
5131 *	Issue a extended link service process login request.
5132 *
5133 * Input:
5134 *	ha = adapter state pointer.
5135 *	pkt = pointer to fc_packet.
5136 *
5137 * Returns:
5138 *	FC_SUCCESS - the packet was accepted for transport.
5139 *	FC_TRANSPORT_ERROR - a transport error occurred.
5140 *
5141 * Context:
5142 *	Kernel context.
5143 */
5144static int
5145ql_els_prli(ql_adapter_state_t *ha, fc_packet_t *pkt)
5146{
5147	ql_tgt_t		*tq;
5148	port_id_t		d_id;
5149	la_els_prli_t		acc;
5150	prli_svc_param_t	*param;
5151	int			rval = FC_SUCCESS;
5152
5153	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5154
5155	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5156
5157	tq = ql_d_id_to_queue(ha, d_id);
5158	if (tq != NULL) {
5159
5160		/* Build ACC. */
5161		bzero(&acc, sizeof (acc));
5162		acc.ls_code = LA_ELS_ACC;
5163		acc.page_length = 0x10;
5164		acc.payload_length = tq->prli_payload_length;
5165
5166		param = (prli_svc_param_t *)&acc.service_params[0];
5167		param->type = 0x08;
5168		param->rsvd = 0x00;
5169		param->process_assoc_flags = tq->prli_svc_param_word_0;
5170		param->process_flags = tq->prli_svc_param_word_3;
5171
5172		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5173		    (uint8_t *)pkt->pkt_resp, sizeof (acc),
5174		    DDI_DEV_AUTOINCR);
5175
5176		pkt->pkt_state = FC_PKT_SUCCESS;
5177	} else {
5178		la_els_rjt_t rjt;
5179
5180		/* Build RJT. */
5181		bzero(&rjt, sizeof (rjt));
5182		rjt.ls_code.ls_code = LA_ELS_RJT;
5183
5184		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
5185		    (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
5186
5187		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5188		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5189	}
5190
5191	if (rval != FC_SUCCESS) {
5192		EL(ha, "failed, rval = %xh\n", rval);
5193	} else {
5194		/*EMPTY*/
5195		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5196	}
5197	return (rval);
5198}
5199
5200/*
5201 * ql_els_prlo
5202 *	Issue a extended link service process logout request.
5203 *
5204 * Input:
5205 *	ha = adapter state pointer.
5206 *	pkt = pointer to fc_packet.
5207 *
5208 * Returns:
5209 *	FC_SUCCESS - the packet was accepted for transport.
5210 *	FC_TRANSPORT_ERROR - a transport error occurred.
5211 *
5212 * Context:
5213 *	Kernel context.
5214 */
5215/* ARGSUSED */
5216static int
5217ql_els_prlo(ql_adapter_state_t *ha, fc_packet_t *pkt)
5218{
5219	la_els_prli_t	acc;
5220	int		rval = FC_SUCCESS;
5221
5222	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5223
5224	/* Build ACC. */
5225	ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&acc,
5226	    (uint8_t *)pkt->pkt_cmd, sizeof (acc), DDI_DEV_AUTOINCR);
5227
5228	acc.ls_code = LA_ELS_ACC;
5229	acc.service_params[2] = 1;
5230
5231	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5232	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5233
5234	pkt->pkt_state = FC_PKT_SUCCESS;
5235
5236	if (rval != FC_SUCCESS) {
5237		EL(ha, "failed, rval = %xh\n", rval);
5238	} else {
5239		/*EMPTY*/
5240		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5241	}
5242	return (rval);
5243}
5244
5245/*
5246 * ql_els_adisc
5247 *	Issue a extended link service address discovery request.
5248 *
5249 * Input:
5250 *	ha = adapter state pointer.
5251 *	pkt = pointer to fc_packet.
5252 *
5253 * Returns:
5254 *	FC_SUCCESS - the packet was accepted for transport.
5255 *	FC_TRANSPORT_ERROR - a transport error occurred.
5256 *
5257 * Context:
5258 *	Kernel context.
5259 */
5260static int
5261ql_els_adisc(ql_adapter_state_t *ha, fc_packet_t *pkt)
5262{
5263	ql_dev_id_list_t	*list;
5264	uint32_t		list_size;
5265	ql_link_t		*link;
5266	ql_tgt_t		*tq;
5267	ql_lun_t		*lq;
5268	port_id_t		d_id;
5269	la_els_adisc_t		acc;
5270	uint16_t		index, loop_id;
5271	ql_mbx_data_t		mr;
5272	int			rval = FC_SUCCESS;
5273
5274	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5275
5276	bzero(&acc, sizeof (acc));
5277	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5278
5279	/*
5280	 * MBC_GET_PORT_DATABASE causes ADISC to go out to
5281	 * the device from the firmware
5282	 */
5283	index = ql_alpa_to_index[d_id.b.al_pa];
5284	tq = NULL;
5285	for (link = ha->dev[index].first; link != NULL; link = link->next) {
5286		tq = link->base_address;
5287		if (tq->d_id.b24 == d_id.b24) {
5288			break;
5289		} else {
5290			tq = NULL;
5291		}
5292	}
5293
5294	if ((tq != NULL) && (!VALID_DEVICE_ID(ha, tq->loop_id))) {
5295		list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES;
5296		list = (ql_dev_id_list_t *)kmem_zalloc(list_size, KM_SLEEP);
5297
5298		if (list != NULL &&
5299		    ql_get_id_list(ha, (caddr_t)list, list_size, &mr) ==
5300		    QL_SUCCESS) {
5301
5302			for (index = 0; index < mr.mb[1]; index++) {
5303				ql_dev_list(ha, list, index, &d_id, &loop_id);
5304
5305				if (tq->d_id.b24 == d_id.b24) {
5306					tq->loop_id = loop_id;
5307					break;
5308				}
5309			}
5310		} else {
5311			cmn_err(CE_WARN, "!%s(%d) didn't get list for %xh",
5312			    QL_NAME, ha->instance, d_id.b24);
5313			tq = NULL;
5314		}
5315		if ((tq != NULL) && (!VALID_DEVICE_ID(ha, tq->loop_id))) {
5316			cmn_err(CE_WARN, "!%s(%d) no loop_id for adisc %xh",
5317			    QL_NAME, ha->instance, tq->d_id.b24);
5318			tq = NULL;
5319		}
5320
5321		if (list != NULL) {
5322			kmem_free(list, list_size);
5323		}
5324	}
5325
5326	if ((tq != NULL) && (VALID_DEVICE_ID(ha, tq->loop_id)) &&
5327	    ql_get_port_database(ha, tq, PDF_ADISC) == QL_SUCCESS) {
5328
5329		/* Build ACC. */
5330
5331		DEVICE_QUEUE_LOCK(tq);
5332		tq->flags &= ~TQF_NEED_AUTHENTICATION;
5333		if (tq->prli_svc_param_word_3 & PRLI_W3_RETRY) {
5334			for (link = tq->lun_queues.first; link != NULL;
5335			    link = link->next) {
5336				lq = link->base_address;
5337
5338				if (lq->cmd.first != NULL) {
5339					ql_next(ha, lq);
5340					DEVICE_QUEUE_LOCK(tq);
5341				}
5342			}
5343		}
5344		DEVICE_QUEUE_UNLOCK(tq);
5345
5346		acc.ls_code.ls_code = LA_ELS_ACC;
5347		acc.hard_addr.hard_addr = tq->hard_addr.b24;
5348
5349		bcopy((void *)&tq->port_name[0],
5350		    (void *)&acc.port_wwn.raw_wwn[0], 8);
5351		bcopy((void *)&tq->node_name[0],
5352		    (void *)&acc.node_wwn.raw_wwn[0], 8);
5353
5354		acc.nport_id.port_id = tq->d_id.b24;
5355
5356		pkt->pkt_state = FC_PKT_SUCCESS;
5357	} else {
5358		/* Build RJT. */
5359		acc.ls_code.ls_code = LA_ELS_RJT;
5360
5361		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5362		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5363	}
5364
5365	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5366	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5367
5368	if (rval != FC_SUCCESS) {
5369		EL(ha, "failed, rval = %xh\n", rval);
5370	} else {
5371		/*EMPTY*/
5372		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5373	}
5374	return (rval);
5375}
5376
5377/*
5378 * ql_els_linit
5379 *	Issue a extended link service loop initialize request.
5380 *
5381 * Input:
5382 *	ha = adapter state pointer.
5383 *	pkt = pointer to fc_packet.
5384 *
5385 * Returns:
5386 *	FC_SUCCESS - the packet was accepted for transport.
5387 *	FC_TRANSPORT_ERROR - a transport error occurred.
5388 *
5389 * Context:
5390 *	Kernel context.
5391 */
5392static int
5393ql_els_linit(ql_adapter_state_t *ha, fc_packet_t *pkt)
5394{
5395	ddi_dma_cookie_t	*cp;
5396	uint32_t		cnt;
5397	conv_num_t		n;
5398	port_id_t		d_id;
5399	int			rval = FC_SUCCESS;
5400
5401	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5402
5403	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5404	if (ha->topology & QL_SNS_CONNECTION) {
5405		fc_linit_req_t els;
5406		lfa_cmd_t lfa;
5407
5408		ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
5409		    (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
5410
5411		/* Setup LFA mailbox command data. */
5412		bzero((void *)&lfa, sizeof (lfa_cmd_t));
5413
5414		lfa.resp_buffer_length[0] = 4;
5415
5416		cp = pkt->pkt_resp_cookie;
5417		if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
5418			n.size64 = (uint64_t)cp->dmac_laddress;
5419			LITTLE_ENDIAN_64(&n.size64);
5420		} else {
5421			n.size32[0] = LSD(cp->dmac_laddress);
5422			LITTLE_ENDIAN_32(&n.size32[0]);
5423			n.size32[1] = MSD(cp->dmac_laddress);
5424			LITTLE_ENDIAN_32(&n.size32[1]);
5425		}
5426
5427		/* Set buffer address. */
5428		for (cnt = 0; cnt < 8; cnt++) {
5429			lfa.resp_buffer_address[cnt] = n.size8[cnt];
5430		}
5431
5432		lfa.subcommand_length[0] = 4;
5433		n.size32[0] = d_id.b24;
5434		LITTLE_ENDIAN_32(&n.size32[0]);
5435		lfa.addr[0] = n.size8[0];
5436		lfa.addr[1] = n.size8[1];
5437		lfa.addr[2] = n.size8[2];
5438		lfa.subcommand[1] = 0x70;
5439		lfa.payload[2] = els.func;
5440		lfa.payload[4] = els.lip_b3;
5441		lfa.payload[5] = els.lip_b4;
5442
5443		if (ql_send_lfa(ha, &lfa) != QL_SUCCESS) {
5444			pkt->pkt_state = FC_PKT_TRAN_ERROR;
5445		} else {
5446			pkt->pkt_state = FC_PKT_SUCCESS;
5447		}
5448	} else {
5449		fc_linit_resp_t rjt;
5450
5451		/* Build RJT. */
5452		bzero(&rjt, sizeof (rjt));
5453		rjt.ls_code.ls_code = LA_ELS_RJT;
5454
5455		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
5456		    (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
5457
5458		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5459		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5460	}
5461
5462	if (rval != FC_SUCCESS) {
5463		EL(ha, "failed, rval = %xh\n", rval);
5464	} else {
5465		/*EMPTY*/
5466		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5467	}
5468	return (rval);
5469}
5470
5471/*
5472 * ql_els_lpc
5473 *	Issue a extended link service loop control request.
5474 *
5475 * Input:
5476 *	ha = adapter state pointer.
5477 *	pkt = pointer to fc_packet.
5478 *
5479 * Returns:
5480 *	FC_SUCCESS - the packet was accepted for transport.
5481 *	FC_TRANSPORT_ERROR - a transport error occurred.
5482 *
5483 * Context:
5484 *	Kernel context.
5485 */
5486static int
5487ql_els_lpc(ql_adapter_state_t *ha, fc_packet_t *pkt)
5488{
5489	ddi_dma_cookie_t	*cp;
5490	uint32_t		cnt;
5491	conv_num_t		n;
5492	port_id_t		d_id;
5493	int			rval = FC_SUCCESS;
5494
5495	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5496
5497	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5498	if (ha->topology & QL_SNS_CONNECTION) {
5499		ql_lpc_t els;
5500		lfa_cmd_t lfa;
5501
5502		ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
5503		    (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
5504
5505		/* Setup LFA mailbox command data. */
5506		bzero((void *)&lfa, sizeof (lfa_cmd_t));
5507
5508		lfa.resp_buffer_length[0] = 4;
5509
5510		cp = pkt->pkt_resp_cookie;
5511		if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
5512			n.size64 = (uint64_t)(cp->dmac_laddress);
5513			LITTLE_ENDIAN_64(&n.size64);
5514		} else {
5515			n.size32[0] = cp->dmac_address;
5516			LITTLE_ENDIAN_32(&n.size32[0]);
5517			n.size32[1] = 0;
5518		}
5519
5520		/* Set buffer address. */
5521		for (cnt = 0; cnt < 8; cnt++) {
5522			lfa.resp_buffer_address[cnt] = n.size8[cnt];
5523		}
5524
5525		lfa.subcommand_length[0] = 20;
5526		n.size32[0] = d_id.b24;
5527		LITTLE_ENDIAN_32(&n.size32[0]);
5528		lfa.addr[0] = n.size8[0];
5529		lfa.addr[1] = n.size8[1];
5530		lfa.addr[2] = n.size8[2];
5531		lfa.subcommand[1] = 0x71;
5532		lfa.payload[4] = els.port_control;
5533		bcopy((void *)&els.lpb[0], (void *)&lfa.payload[6], 32);
5534
5535		if (ql_send_lfa(ha, &lfa) != QL_SUCCESS) {
5536			pkt->pkt_state = FC_PKT_TRAN_ERROR;
5537		} else {
5538			pkt->pkt_state = FC_PKT_SUCCESS;
5539		}
5540	} else {
5541		ql_lpc_resp_t rjt;
5542
5543		/* Build RJT. */
5544		bzero(&rjt, sizeof (rjt));
5545		rjt.ls_code.ls_code = LA_ELS_RJT;
5546
5547		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
5548		    (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
5549
5550		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5551		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5552	}
5553
5554	if (rval != FC_SUCCESS) {
5555		EL(ha, "failed, rval = %xh\n", rval);
5556	} else {
5557		/*EMPTY*/
5558		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5559	}
5560	return (rval);
5561}
5562
5563/*
5564 * ql_els_lsts
5565 *	Issue a extended link service loop status request.
5566 *
5567 * Input:
5568 *	ha = adapter state pointer.
5569 *	pkt = pointer to fc_packet.
5570 *
5571 * Returns:
5572 *	FC_SUCCESS - the packet was accepted for transport.
5573 *	FC_TRANSPORT_ERROR - a transport error occurred.
5574 *
5575 * Context:
5576 *	Kernel context.
5577 */
5578static int
5579ql_els_lsts(ql_adapter_state_t *ha, fc_packet_t *pkt)
5580{
5581	ddi_dma_cookie_t	*cp;
5582	uint32_t		cnt;
5583	conv_num_t		n;
5584	port_id_t		d_id;
5585	int			rval = FC_SUCCESS;
5586
5587	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5588
5589	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5590	if (ha->topology & QL_SNS_CONNECTION) {
5591		fc_lsts_req_t els;
5592		lfa_cmd_t lfa;
5593
5594		ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
5595		    (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
5596
5597		/* Setup LFA mailbox command data. */
5598		bzero((void *)&lfa, sizeof (lfa_cmd_t));
5599
5600		lfa.resp_buffer_length[0] = 84;
5601
5602		cp = pkt->pkt_resp_cookie;
5603		if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
5604			n.size64 = cp->dmac_laddress;
5605			LITTLE_ENDIAN_64(&n.size64);
5606		} else {
5607			n.size32[0] = cp->dmac_address;
5608			LITTLE_ENDIAN_32(&n.size32[0]);
5609			n.size32[1] = 0;
5610		}
5611
5612		/* Set buffer address. */
5613		for (cnt = 0; cnt < 8; cnt++) {
5614			lfa.resp_buffer_address[cnt] = n.size8[cnt];
5615		}
5616
5617		lfa.subcommand_length[0] = 2;
5618		n.size32[0] = d_id.b24;
5619		LITTLE_ENDIAN_32(&n.size32[0]);
5620		lfa.addr[0] = n.size8[0];
5621		lfa.addr[1] = n.size8[1];
5622		lfa.addr[2] = n.size8[2];
5623		lfa.subcommand[1] = 0x72;
5624
5625		if (ql_send_lfa(ha, &lfa) != QL_SUCCESS) {
5626			pkt->pkt_state = FC_PKT_TRAN_ERROR;
5627		} else {
5628			pkt->pkt_state = FC_PKT_SUCCESS;
5629		}
5630	} else {
5631		fc_lsts_resp_t rjt;
5632
5633		/* Build RJT. */
5634		bzero(&rjt, sizeof (rjt));
5635		rjt.lsts_ls_code.ls_code = LA_ELS_RJT;
5636
5637		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
5638		    (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
5639
5640		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5641		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5642	}
5643
5644	if (rval != FC_SUCCESS) {
5645		EL(ha, "failed=%xh\n", rval);
5646	} else {
5647		/*EMPTY*/
5648		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5649	}
5650	return (rval);
5651}
5652
5653/*
5654 * ql_els_scr
5655 *	Issue a extended link service state change registration request.
5656 *
5657 * Input:
5658 *	ha = adapter state pointer.
5659 *	pkt = pointer to fc_packet.
5660 *
5661 * Returns:
5662 *	FC_SUCCESS - the packet was accepted for transport.
5663 *	FC_TRANSPORT_ERROR - a transport error occurred.
5664 *
5665 * Context:
5666 *	Kernel context.
5667 */
5668static int
5669ql_els_scr(ql_adapter_state_t *ha, fc_packet_t *pkt)
5670{
5671	fc_scr_resp_t	acc;
5672	int		rval = FC_SUCCESS;
5673
5674	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5675
5676	bzero(&acc, sizeof (acc));
5677	if (ha->topology & QL_SNS_CONNECTION) {
5678		fc_scr_req_t els;
5679
5680		ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
5681		    (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
5682
5683		if (ql_send_change_request(ha, els.scr_func) ==
5684		    QL_SUCCESS) {
5685			/* Build ACC. */
5686			acc.scr_acc = LA_ELS_ACC;
5687
5688			pkt->pkt_state = FC_PKT_SUCCESS;
5689		} else {
5690			/* Build RJT. */
5691			acc.scr_acc = LA_ELS_RJT;
5692
5693			pkt->pkt_state = FC_PKT_TRAN_ERROR;
5694			pkt->pkt_reason = FC_REASON_HW_ERROR;
5695		}
5696	} else {
5697		/* Build RJT. */
5698		acc.scr_acc = LA_ELS_RJT;
5699
5700		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5701		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5702	}
5703
5704	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5705	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5706
5707	if (rval != FC_SUCCESS) {
5708		EL(ha, "failed, rval = %xh\n", rval);
5709	} else {
5710		/*EMPTY*/
5711		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5712	}
5713	return (rval);
5714}
5715
5716/*
5717 * ql_els_rscn
5718 *	Issue a extended link service register state
5719 *	change notification request.
5720 *
5721 * Input:
5722 *	ha = adapter state pointer.
5723 *	pkt = pointer to fc_packet.
5724 *
5725 * Returns:
5726 *	FC_SUCCESS - the packet was accepted for transport.
5727 *	FC_TRANSPORT_ERROR - a transport error occurred.
5728 *
5729 * Context:
5730 *	Kernel context.
5731 */
5732static int
5733ql_els_rscn(ql_adapter_state_t *ha, fc_packet_t *pkt)
5734{
5735	ql_rscn_resp_t	acc;
5736	int		rval = FC_SUCCESS;
5737
5738	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5739
5740	bzero(&acc, sizeof (acc));
5741	if (ha->topology & QL_SNS_CONNECTION) {
5742		/* Build ACC. */
5743		acc.scr_acc = LA_ELS_ACC;
5744
5745		pkt->pkt_state = FC_PKT_SUCCESS;
5746	} else {
5747		/* Build RJT. */
5748		acc.scr_acc = LA_ELS_RJT;
5749
5750		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5751		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5752	}
5753
5754	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5755	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5756
5757	if (rval != FC_SUCCESS) {
5758		EL(ha, "failed, rval = %xh\n", rval);
5759	} else {
5760		/*EMPTY*/
5761		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5762	}
5763	return (rval);
5764}
5765
5766/*
5767 * ql_els_farp_req
5768 *	Issue FC Address Resolution Protocol (FARP)
5769 *	extended link service request.
5770 *
5771 *	Note: not supported.
5772 *
5773 * Input:
5774 *	ha = adapter state pointer.
5775 *	pkt = pointer to fc_packet.
5776 *
5777 * Returns:
5778 *	FC_SUCCESS - the packet was accepted for transport.
5779 *	FC_TRANSPORT_ERROR - a transport error occurred.
5780 *
5781 * Context:
5782 *	Kernel context.
5783 */
5784static int
5785ql_els_farp_req(ql_adapter_state_t *ha, fc_packet_t *pkt)
5786{
5787	ql_acc_rjt_t	acc;
5788	int		rval = FC_SUCCESS;
5789
5790	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5791
5792	bzero(&acc, sizeof (acc));
5793
5794	/* Build ACC. */
5795	acc.ls_code.ls_code = LA_ELS_ACC;
5796
5797	pkt->pkt_state = FC_PKT_SUCCESS;
5798
5799	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5800	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5801
5802	if (rval != FC_SUCCESS) {
5803		EL(ha, "failed, rval = %xh\n", rval);
5804	} else {
5805		/*EMPTY*/
5806		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5807	}
5808	return (rval);
5809}
5810
5811/*
5812 * ql_els_farp_reply
5813 *	Issue FC Address Resolution Protocol (FARP)
5814 *	extended link service reply.
5815 *
5816 *	Note: not supported.
5817 *
5818 * Input:
5819 *	ha = adapter state pointer.
5820 *	pkt = pointer to fc_packet.
5821 *
5822 * Returns:
5823 *	FC_SUCCESS - the packet was accepted for transport.
5824 *	FC_TRANSPORT_ERROR - a transport error occurred.
5825 *
5826 * Context:
5827 *	Kernel context.
5828 */
5829/* ARGSUSED */
5830static int
5831ql_els_farp_reply(ql_adapter_state_t *ha, fc_packet_t *pkt)
5832{
5833	ql_acc_rjt_t	acc;
5834	int		rval = FC_SUCCESS;
5835
5836	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5837
5838	bzero(&acc, sizeof (acc));
5839
5840	/* Build ACC. */
5841	acc.ls_code.ls_code = LA_ELS_ACC;
5842
5843	pkt->pkt_state = FC_PKT_SUCCESS;
5844
5845	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5846	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5847
5848	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5849
5850	return (rval);
5851}
5852
5853static int
5854ql_els_rnid(ql_adapter_state_t *ha, fc_packet_t *pkt)
5855{
5856	uchar_t			*rnid_acc;
5857	port_id_t		d_id;
5858	ql_link_t		*link;
5859	ql_tgt_t		*tq;
5860	uint16_t		index;
5861	la_els_rnid_acc_t	acc;
5862	la_els_rnid_t		*req;
5863	size_t			req_len;
5864
5865	req_len =  FCIO_RNID_MAX_DATA_LEN + sizeof (fc_rnid_hdr_t);
5866	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5867	index = ql_alpa_to_index[d_id.b.al_pa];
5868
5869	tq = NULL;
5870	for (link = ha->dev[index].first; link != NULL; link = link->next) {
5871		tq = link->base_address;
5872		if (tq->d_id.b24 == d_id.b24) {
5873			break;
5874		} else {
5875			tq = NULL;
5876		}
5877	}
5878
5879	/* Allocate memory for rnid status block */
5880	rnid_acc = kmem_zalloc(req_len, KM_SLEEP);
5881	ASSERT(rnid_acc != NULL);
5882
5883	bzero(&acc, sizeof (acc));
5884
5885	req = (la_els_rnid_t *)pkt->pkt_cmd;
5886	if ((tq == NULL) || (!VALID_DEVICE_ID(ha, tq->loop_id)) ||
5887	    (ql_send_rnid_els(ha, tq->loop_id, req->data_format, req_len,
5888	    (caddr_t)rnid_acc) != QL_SUCCESS)) {
5889
5890		kmem_free(rnid_acc, req_len);
5891		acc.ls_code.ls_code = LA_ELS_RJT;
5892
5893		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5894		    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5895
5896		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5897		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5898
5899		return (FC_FAILURE);
5900	}
5901
5902	acc.ls_code.ls_code = LA_ELS_ACC;
5903	bcopy(rnid_acc, &acc.hdr, req_len);
5904	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5905	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5906
5907	kmem_free(rnid_acc, req_len);
5908	pkt->pkt_state = FC_PKT_SUCCESS;
5909
5910	return (FC_SUCCESS);
5911}
5912
5913static int
5914ql_els_rls(ql_adapter_state_t *ha, fc_packet_t *pkt)
5915{
5916	fc_rls_acc_t		*rls_acc;
5917	port_id_t		d_id;
5918	ql_link_t		*link;
5919	ql_tgt_t		*tq;
5920	uint16_t		index;
5921	la_els_rls_acc_t	acc;
5922
5923	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5924	index = ql_alpa_to_index[d_id.b.al_pa];
5925
5926	tq = NULL;
5927	for (link = ha->dev[index].first; link != NULL; link = link->next) {
5928		tq = link->base_address;
5929		if (tq->d_id.b24 == d_id.b24) {
5930			break;
5931		} else {
5932			tq = NULL;
5933		}
5934	}
5935
5936	/* Allocate memory for link error status block */
5937	rls_acc = kmem_zalloc(sizeof (*rls_acc), KM_SLEEP);
5938	ASSERT(rls_acc != NULL);
5939
5940	bzero(&acc, sizeof (la_els_rls_acc_t));
5941
5942	if ((tq == NULL) || (!VALID_DEVICE_ID(ha, tq->loop_id)) ||
5943	    (ql_get_link_status(ha, tq->loop_id, sizeof (*rls_acc),
5944	    (caddr_t)rls_acc, 0) != QL_SUCCESS)) {
5945
5946		kmem_free(rls_acc, sizeof (*rls_acc));
5947		acc.ls_code.ls_code = LA_ELS_RJT;
5948
5949		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5950		    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5951
5952		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5953		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5954
5955		return (FC_FAILURE);
5956	}
5957
5958	LITTLE_ENDIAN_32(&rls_acc->rls_link_fail);
5959	LITTLE_ENDIAN_32(&rls_acc->rls_sync_loss);
5960	LITTLE_ENDIAN_32(&rls_acc->rls_sig_loss);
5961	LITTLE_ENDIAN_32(&rls_acc->rls_invalid_word);
5962	LITTLE_ENDIAN_32(&rls_acc->rls_invalid_crc);
5963
5964	acc.ls_code.ls_code = LA_ELS_ACC;
5965	acc.rls_link_params.rls_link_fail = rls_acc->rls_link_fail;
5966	acc.rls_link_params.rls_sync_loss = rls_acc->rls_sync_loss;
5967	acc.rls_link_params.rls_sig_loss  = rls_acc->rls_sig_loss;
5968	acc.rls_link_params.rls_invalid_word = rls_acc->rls_invalid_word;
5969	acc.rls_link_params.rls_invalid_crc = rls_acc->rls_invalid_crc;
5970	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5971	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5972
5973	kmem_free(rls_acc, sizeof (*rls_acc));
5974	pkt->pkt_state = FC_PKT_SUCCESS;
5975
5976	return (FC_SUCCESS);
5977}
5978
5979static int
5980ql_busy_plogi(ql_adapter_state_t *ha, fc_packet_t *pkt, ql_tgt_t *tq)
5981{
5982	port_id_t	d_id;
5983	ql_srb_t	*sp;
5984	fc_unsol_buf_t  *ubp;
5985	ql_link_t	*link, *next_link;
5986	int		rval = FC_SUCCESS;
5987	int		cnt = 5;
5988
5989	/*
5990	 * we need to ensure that q->outcnt == 0, otherwise
5991	 * any cmd completed with PKT_PORT_OFFLINE after PLOGI
5992	 * will confuse ulps.
5993	 */
5994
5995	DEVICE_QUEUE_LOCK(tq);
5996	do {
5997		/*
5998		 * wait for the cmds to get drained. If they
5999		 * don't get drained then the transport will
6000		 * retry PLOGI after few secs.
6001		 */
6002		if (tq->outcnt != 0) {
6003			rval = FC_TRAN_BUSY;
6004			DEVICE_QUEUE_UNLOCK(tq);
6005			ql_delay(ha, 10000);
6006			DEVICE_QUEUE_LOCK(tq);
6007			cnt--;
6008			if (!cnt) {
6009				cmn_err(CE_NOTE, "!%s(%d) Plogi busy"
6010				    " for %xh outcount %xh", QL_NAME,
6011				    ha->instance, tq->d_id.b24, tq->outcnt);
6012			}
6013		} else {
6014			rval = FC_SUCCESS;
6015			break;
6016		}
6017	} while (cnt > 0);
6018	DEVICE_QUEUE_UNLOCK(tq);
6019
6020	/*
6021	 * return, if busy or if the plogi was asynchronous.
6022	 */
6023	if ((rval != FC_SUCCESS) ||
6024	    (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) &&
6025	    pkt->pkt_comp)) {
6026		return (rval);
6027	}
6028
6029	/*
6030	 * Let us give daemon sufficient time and hopefully
6031	 * when transport retries PLOGI, it would have flushed
6032	 * callback queue.
6033	 */
6034	TASK_DAEMON_LOCK(ha);
6035	for (link = ha->callback_queue.first; link != NULL;
6036	    link = next_link) {
6037		next_link = link->next;
6038		sp = link->base_address;
6039		if (sp->flags & SRB_UB_CALLBACK) {
6040			ubp = ha->ub_array[sp->handle];
6041			d_id.b24 = ubp->ub_frame.s_id;
6042		} else {
6043			d_id.b24 = sp->pkt->pkt_cmd_fhdr.d_id;
6044		}
6045		if (tq->d_id.b24 == d_id.b24) {
6046			cmn_err(CE_NOTE, "!%s(%d) Plogi busy for %xh", QL_NAME,
6047			    ha->instance, tq->d_id.b24);
6048			rval = FC_TRAN_BUSY;
6049			break;
6050		}
6051	}
6052	TASK_DAEMON_UNLOCK(ha);
6053
6054	return (rval);
6055}
6056
6057/*
6058 * ql_login_port
6059 *	Logs in a device if not already logged in.
6060 *
6061 * Input:
6062 *	ha = adapter state pointer.
6063 *	d_id = 24 bit port ID.
6064 *	DEVICE_QUEUE_LOCK must be released.
6065 *
6066 * Returns:
6067 *	QL local function return status code.
6068 *
6069 * Context:
6070 *	Kernel context.
6071 */
6072static int
6073ql_login_port(ql_adapter_state_t *ha, port_id_t d_id)
6074{
6075	ql_adapter_state_t	*vha;
6076	ql_link_t		*link;
6077	uint16_t		index;
6078	ql_tgt_t		*tq, *tq2;
6079	uint16_t		loop_id, first_loop_id, last_loop_id;
6080	int			rval = QL_SUCCESS;
6081
6082	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6083
6084	/* Get head queue index. */
6085	index = ql_alpa_to_index[d_id.b.al_pa];
6086
6087	/* Check for device already has a queue. */
6088	tq = NULL;
6089	for (link = ha->dev[index].first; link != NULL; link = link->next) {
6090		tq = link->base_address;
6091		if (tq->d_id.b24 == d_id.b24) {
6092			loop_id = tq->loop_id;
6093			break;
6094		} else {
6095			tq = NULL;
6096		}
6097	}
6098
6099	/* Let's stop issuing any IO and unsolicited logo */
6100	if ((tq != NULL) && (!(ddi_in_panic()))) {
6101		DEVICE_QUEUE_LOCK(tq);
6102		tq->flags |= (TQF_QUEUE_SUSPENDED | TQF_PLOGI_PROGRS);
6103		tq->flags &= ~TQF_RSCN_RCVD;
6104		DEVICE_QUEUE_UNLOCK(tq);
6105	}
6106	if ((tq != NULL) && (tq->loop_id & PORT_LOST_ID) &&
6107	    !(tq->flags & TQF_FABRIC_DEVICE)) {
6108		loop_id = (uint16_t)(tq->loop_id & ~PORT_LOST_ID);
6109	}
6110
6111	/* Special case for Nameserver */
6112	if (d_id.b24 == 0xFFFFFC) {
6113		loop_id = (uint16_t)(CFG_IST(ha, CFG_CTRL_2425) ?
6114		    SNS_24XX_HDL : SIMPLE_NAME_SERVER_LOOP_ID);
6115		if (tq == NULL) {
6116			ADAPTER_STATE_LOCK(ha);
6117			tq = ql_dev_init(ha, d_id, loop_id);
6118			ADAPTER_STATE_UNLOCK(ha);
6119			if (tq == NULL) {
6120				EL(ha, "failed=%xh, d_id=%xh\n",
6121				    QL_FUNCTION_FAILED, d_id.b24);
6122				return (QL_FUNCTION_FAILED);
6123			}
6124		}
6125		rval = ql_login_fabric_port(ha, tq, loop_id);
6126		if (rval == QL_SUCCESS) {
6127			tq->loop_id = loop_id;
6128			tq->flags |= TQF_FABRIC_DEVICE;
6129			(void) ql_get_port_database(ha, tq, PDF_NONE);
6130			ha->topology = (uint8_t)
6131			    (ha->topology | QL_SNS_CONNECTION);
6132		}
6133	/* Check for device already logged in. */
6134	} else if (tq != NULL && VALID_DEVICE_ID(ha, loop_id)) {
6135		if (tq->flags & TQF_FABRIC_DEVICE) {
6136			rval = ql_login_fabric_port(ha, tq, loop_id);
6137			if (rval == QL_PORT_ID_USED) {
6138				rval = QL_SUCCESS;
6139			}
6140		} else if (LOCAL_LOOP_ID(loop_id)) {
6141			rval = ql_login_lport(ha, tq, loop_id, (uint16_t)
6142			    (tq->flags & TQF_INITIATOR_DEVICE ?
6143			    LLF_NONE : LLF_PLOGI));
6144			if (rval == QL_SUCCESS) {
6145				DEVICE_QUEUE_LOCK(tq);
6146				tq->loop_id = loop_id;
6147				DEVICE_QUEUE_UNLOCK(tq);
6148			}
6149		}
6150	} else if (ha->topology & QL_SNS_CONNECTION) {
6151		/* Locate unused loop ID. */
6152		if (CFG_IST(ha, CFG_CTRL_2425)) {
6153			first_loop_id = 0;
6154			last_loop_id = LAST_N_PORT_HDL;
6155		} else if (ha->topology & QL_F_PORT) {
6156			first_loop_id = 0;
6157			last_loop_id = SNS_LAST_LOOP_ID;
6158		} else {
6159			first_loop_id = SNS_FIRST_LOOP_ID;
6160			last_loop_id = SNS_LAST_LOOP_ID;
6161		}
6162
6163		/* Acquire adapter state lock. */
6164		ADAPTER_STATE_LOCK(ha);
6165
6166		tq = ql_dev_init(ha, d_id, PORT_NO_LOOP_ID);
6167		if (tq == NULL) {
6168			EL(ha, "failed=%xh, d_id=%xh\n", QL_FUNCTION_FAILED,
6169			    d_id.b24);
6170
6171			ADAPTER_STATE_UNLOCK(ha);
6172
6173			return (QL_FUNCTION_FAILED);
6174		}
6175
6176		rval = QL_FUNCTION_FAILED;
6177		loop_id = ha->pha->free_loop_id++;
6178		for (index = (uint16_t)(last_loop_id - first_loop_id); index;
6179		    index--) {
6180			if (loop_id < first_loop_id ||
6181			    loop_id > last_loop_id) {
6182				loop_id = first_loop_id;
6183				ha->pha->free_loop_id = (uint16_t)
6184				    (loop_id + 1);
6185			}
6186
6187			/* Bypass if loop ID used. */
6188			for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
6189				tq2 = ql_loop_id_to_queue(vha, loop_id);
6190				if (tq2 != NULL && tq2 != tq) {
6191					break;
6192				}
6193			}
6194			if (vha != NULL || RESERVED_LOOP_ID(ha, loop_id) ||
6195			    loop_id == ha->loop_id) {
6196				loop_id = ha->pha->free_loop_id++;
6197				continue;
6198			}
6199
6200			ADAPTER_STATE_UNLOCK(ha);
6201			rval = ql_login_fabric_port(ha, tq, loop_id);
6202
6203			/*
6204			 * If PORT_ID_USED is returned
6205			 * the login_fabric_port() updates
6206			 * with the correct loop ID
6207			 */
6208			switch (rval) {
6209			case QL_PORT_ID_USED:
6210				/*
6211				 * use f/w handle and try to
6212				 * login again.
6213				 */
6214				ADAPTER_STATE_LOCK(ha);
6215				ha->pha->free_loop_id--;
6216				ADAPTER_STATE_UNLOCK(ha);
6217				loop_id = tq->loop_id;
6218				break;
6219			case QL_SUCCESS:
6220				tq->flags |= TQF_FABRIC_DEVICE;
6221				(void) ql_get_port_database(ha,
6222				    tq, PDF_NONE);
6223				index = 1;
6224				break;
6225
6226			case QL_LOOP_ID_USED:
6227				tq->loop_id = PORT_NO_LOOP_ID;
6228				loop_id = ha->pha->free_loop_id++;
6229				break;
6230
6231			case QL_ALL_IDS_IN_USE:
6232				tq->loop_id = PORT_NO_LOOP_ID;
6233				index = 1;
6234				break;
6235
6236			default:
6237				tq->loop_id = PORT_NO_LOOP_ID;
6238				index = 1;
6239				break;
6240			}
6241
6242			ADAPTER_STATE_LOCK(ha);
6243		}
6244
6245		ADAPTER_STATE_UNLOCK(ha);
6246	} else {
6247		rval = QL_FUNCTION_FAILED;
6248	}
6249
6250	if (rval != QL_SUCCESS) {
6251		EL(ha, "failed=%xh, d_id=%xh\n", rval, d_id.b24);
6252	} else {
6253		EL(ha, "d_id=%xh, loop_id=%xh, "
6254		    "wwpn=%02x%02x%02x%02x%02x%02x%02x%02xh\n", tq->d_id.b24,
6255		    tq->loop_id, tq->port_name[0], tq->port_name[1],
6256		    tq->port_name[2], tq->port_name[3], tq->port_name[4],
6257		    tq->port_name[5], tq->port_name[6], tq->port_name[7]);
6258	}
6259	return (rval);
6260}
6261
6262/*
6263 * ql_login_fabric_port
6264 *	Issue login fabric port mailbox command.
6265 *
6266 * Input:
6267 *	ha:		adapter state pointer.
6268 *	tq:		target queue pointer.
6269 *	loop_id:	FC Loop ID.
6270 *
6271 * Returns:
6272 *	ql local function return status code.
6273 *
6274 * Context:
6275 *	Kernel context.
6276 */
6277static int
6278ql_login_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id)
6279{
6280	int		rval;
6281	int		index;
6282	int		retry = 0;
6283	port_id_t	d_id;
6284	ql_tgt_t	*newq;
6285	ql_mbx_data_t	mr;
6286
6287	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6288
6289	/*
6290	 * QL_PARAMETER_ERROR also means the firmware is
6291	 * not able to allocate PCB entry due to resource
6292	 * issues, or collision.
6293	 */
6294	do {
6295		rval = ql_login_fport(ha, tq, loop_id, LFF_NONE, &mr);
6296		if ((rval == QL_PARAMETER_ERROR) ||
6297		    ((rval == QL_COMMAND_ERROR) && (mr.mb[1] == 2 ||
6298		    mr.mb[1] == 3 || mr.mb[1] == 7 || mr.mb[1] == 0xd))) {
6299			retry++;
6300			drv_usecwait(10 * MILLISEC);
6301		} else {
6302			break;
6303		}
6304	} while (retry < 5);
6305
6306	switch (rval) {
6307	case QL_SUCCESS:
6308		tq->loop_id = loop_id;
6309		break;
6310
6311	case QL_PORT_ID_USED:
6312		/*
6313		 * This Loop ID should NOT be in use in drivers
6314		 */
6315		newq = ql_loop_id_to_queue(ha, mr.mb[1]);
6316
6317		if (newq != NULL && newq != tq && tq->logout_sent == 0) {
6318			cmn_err(CE_WARN, "ql_login_fabric_port(%d): logout of "
6319			    "dup loop_id=%xh, d_id=%xh", ha->instance,
6320			    newq->loop_id, newq->d_id.b24);
6321			ql_send_logo(ha, newq, NULL);
6322		}
6323
6324		tq->loop_id = mr.mb[1];
6325		break;
6326
6327	case QL_LOOP_ID_USED:
6328		d_id.b.al_pa = LSB(mr.mb[2]);
6329		d_id.b.area = MSB(mr.mb[2]);
6330		d_id.b.domain = LSB(mr.mb[1]);
6331
6332		newq = ql_d_id_to_queue(ha, d_id);
6333		if (newq && (newq->loop_id != loop_id)) {
6334			/*
6335			 * This should NEVER ever happen; but this
6336			 * code is needed to bail out when the worst
6337			 * case happens - or as used to happen before
6338			 */
6339			ASSERT(newq->d_id.b24 == d_id.b24);
6340
6341			QL_PRINT_2(CE_CONT, "(%d,%d): Loop ID is now "
6342			    "reassigned; old pairs: [%xh, %xh] and [%xh, %xh];"
6343			    "new pairs: [%xh, unknown] and [%xh, %xh]\n",
6344			    ha->instance, ha->vp_index, tq->d_id.b24, loop_id,
6345			    newq->d_id.b24, newq->loop_id, tq->d_id.b24,
6346			    newq->d_id.b24, loop_id);
6347
6348			if ((newq->d_id.b24 & 0xff) != (d_id.b24 & 0xff)) {
6349				ADAPTER_STATE_LOCK(ha);
6350
6351				index = ql_alpa_to_index[newq->d_id.b.al_pa];
6352				ql_add_link_b(&ha->dev[index], &newq->device);
6353
6354				newq->d_id.b24 = d_id.b24;
6355
6356				index = ql_alpa_to_index[d_id.b.al_pa];
6357				ql_add_link_b(&ha->dev[index], &newq->device);
6358
6359				ADAPTER_STATE_UNLOCK(ha);
6360			}
6361
6362			(void) ql_get_port_database(ha, newq, PDF_NONE);
6363
6364		}
6365
6366		/*
6367		 * Invalidate the loop ID for the
6368		 * us to obtain a new one.
6369		 */
6370		tq->loop_id = PORT_NO_LOOP_ID;
6371		break;
6372
6373	case QL_ALL_IDS_IN_USE:
6374		rval = QL_FUNCTION_FAILED;
6375		EL(ha, "no loop id's available\n");
6376		break;
6377
6378	default:
6379		if (rval == QL_COMMAND_ERROR) {
6380			switch (mr.mb[1]) {
6381			case 2:
6382			case 3:
6383				rval = QL_MEMORY_ALLOC_FAILED;
6384				break;
6385
6386			case 4:
6387				rval = QL_FUNCTION_TIMEOUT;
6388				break;
6389			case 7:
6390				rval = QL_FABRIC_NOT_INITIALIZED;
6391				break;
6392			default:
6393				EL(ha, "cmd rtn; mb1=%xh\n", mr.mb[1]);
6394				break;
6395			}
6396		} else {
6397			cmn_err(CE_WARN, "%s(%d): login fabric port failed"
6398			    " D_ID=%xh, rval=%xh, mb1=%xh", QL_NAME,
6399			    ha->instance, tq->d_id.b24, rval, mr.mb[1]);
6400		}
6401		break;
6402	}
6403
6404	if (rval != QL_SUCCESS && rval != QL_PORT_ID_USED &&
6405	    rval != QL_LOOP_ID_USED) {
6406		EL(ha, "failed=%xh\n", rval);
6407	} else {
6408		/*EMPTY*/
6409		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6410	}
6411	return (rval);
6412}
6413
6414/*
6415 * ql_logout_port
6416 *	Logs out a device if possible.
6417 *
6418 * Input:
6419 *	ha:	adapter state pointer.
6420 *	d_id:	24 bit port ID.
6421 *
6422 * Returns:
6423 *	QL local function return status code.
6424 *
6425 * Context:
6426 *	Kernel context.
6427 */
6428static int
6429ql_logout_port(ql_adapter_state_t *ha, port_id_t d_id)
6430{
6431	ql_link_t	*link;
6432	ql_tgt_t	*tq;
6433	uint16_t	index;
6434
6435	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6436
6437	/* Get head queue index. */
6438	index = ql_alpa_to_index[d_id.b.al_pa];
6439
6440	/* Get device queue. */
6441	tq = NULL;
6442	for (link = ha->dev[index].first; link != NULL; link = link->next) {
6443		tq = link->base_address;
6444		if (tq->d_id.b24 == d_id.b24) {
6445			break;
6446		} else {
6447			tq = NULL;
6448		}
6449	}
6450
6451	if (tq != NULL && tq->flags & TQF_FABRIC_DEVICE) {
6452		(void) ql_logout_fabric_port(ha, tq);
6453		tq->loop_id = PORT_NO_LOOP_ID;
6454	}
6455
6456	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6457
6458	return (QL_SUCCESS);
6459}
6460
6461/*
6462 * ql_dev_init
6463 *	Initialize/allocate device queue.
6464 *
6465 * Input:
6466 *	ha:		adapter state pointer.
6467 *	d_id:		device destination ID
6468 *	loop_id:	device loop ID
6469 *	ADAPTER_STATE_LOCK must be already obtained.
6470 *
6471 * Returns:
6472 *	NULL = failure
6473 *
6474 * Context:
6475 *	Kernel context.
6476 */
6477ql_tgt_t *
6478ql_dev_init(ql_adapter_state_t *ha, port_id_t d_id, uint16_t loop_id)
6479{
6480	ql_link_t	*link;
6481	uint16_t	index;
6482	ql_tgt_t	*tq;
6483
6484	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
6485	    ha->instance, d_id.b24, loop_id);
6486
6487	index = ql_alpa_to_index[d_id.b.al_pa];
6488
6489	/* If device queue exists, set proper loop ID. */
6490	tq = NULL;
6491	for (link = ha->dev[index].first; link != NULL; link = link->next) {
6492		tq = link->base_address;
6493		if (tq->d_id.b24 == d_id.b24) {
6494			tq->loop_id = loop_id;
6495
6496			/* Reset port down retry count. */
6497			tq->port_down_retry_count = ha->port_down_retry_count;
6498			tq->qfull_retry_count = ha->qfull_retry_count;
6499
6500			break;
6501		} else {
6502			tq = NULL;
6503		}
6504	}
6505
6506	/* If device does not have queue. */
6507	if (tq == NULL) {
6508		tq = (ql_tgt_t *)kmem_zalloc(sizeof (ql_tgt_t), KM_SLEEP);
6509		if (tq != NULL) {
6510			/*
6511			 * mutex to protect the device queue,
6512			 * does not block interrupts.
6513			 */
6514			mutex_init(&tq->mutex, NULL, MUTEX_DRIVER,
6515			    (ha->iflags & IFLG_INTR_AIF) ?
6516			    (void *)(uintptr_t)ha->intr_pri :
6517			    (void *)(uintptr_t)ha->iblock_cookie);
6518
6519			tq->d_id.b24 = d_id.b24;
6520			tq->loop_id = loop_id;
6521			tq->device.base_address = tq;
6522			tq->iidma_rate = IIDMA_RATE_INIT;
6523
6524			/* Reset port down retry count. */
6525			tq->port_down_retry_count = ha->port_down_retry_count;
6526			tq->qfull_retry_count = ha->qfull_retry_count;
6527
6528			/* Add device to device queue. */
6529			ql_add_link_b(&ha->dev[index], &tq->device);
6530		}
6531	}
6532
6533	if (tq == NULL) {
6534		EL(ha, "failed, d_id=%xh, loop_id=%xh\n", d_id.b24, loop_id);
6535	} else {
6536		/*EMPTY*/
6537		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6538	}
6539	return (tq);
6540}
6541
6542/*
6543 * ql_dev_free
6544 *	Remove queue from device list and frees resources used by queue.
6545 *
6546 * Input:
6547 *	ha:	adapter state pointer.
6548 *	tq:	target queue pointer.
6549 *	ADAPTER_STATE_LOCK must be already obtained.
6550 *
6551 * Context:
6552 *	Kernel context.
6553 */
6554static void
6555ql_dev_free(ql_adapter_state_t *ha, ql_tgt_t *tq)
6556{
6557	ql_link_t	*link;
6558	uint16_t	index;
6559	ql_lun_t	*lq;
6560
6561	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6562
6563	for (link = tq->lun_queues.first; link != NULL; link = link->next) {
6564		lq = link->base_address;
6565		if (lq->cmd.first != NULL) {
6566			return;
6567		}
6568	}
6569
6570	if (tq->outcnt == 0) {
6571		/* Get head queue index. */
6572		index = ql_alpa_to_index[tq->d_id.b.al_pa];
6573		for (link = ha->dev[index].first; link != NULL;
6574		    link = link->next) {
6575			if (link->base_address == tq) {
6576				ql_remove_link(&ha->dev[index], link);
6577
6578				for (link = tq->lun_queues.first;
6579				    link != NULL; /* CSTYLE */) {
6580					lq = link->base_address;
6581					link = link->next;
6582
6583					ql_remove_link(&tq->lun_queues,
6584					    &lq->link);
6585					kmem_free(lq, sizeof (ql_lun_t));
6586				}
6587
6588				mutex_destroy(&tq->mutex);
6589				kmem_free(tq, sizeof (ql_tgt_t));
6590				break;
6591			}
6592		}
6593	}
6594
6595	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6596}
6597
6598/*
6599 * ql_lun_queue
6600 *	Allocate LUN queue if does not exists.
6601 *
6602 * Input:
6603 *	ha:	adapter state pointer.
6604 *	tq:	target queue.
6605 *	lun:	LUN number.
6606 *
6607 * Returns:
6608 *	NULL = failure
6609 *
6610 * Context:
6611 *	Kernel context.
6612 */
6613static ql_lun_t *
6614ql_lun_queue(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
6615{
6616	ql_lun_t	*lq;
6617	ql_link_t	*link;
6618
6619	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6620
6621	/* Fast path. */
6622	if (tq->last_lun_queue != NULL && tq->last_lun_queue->lun_no == lun) {
6623		QL_PRINT_3(CE_CONT, "(%d): fast done\n", ha->instance);
6624		return (tq->last_lun_queue);
6625	}
6626
6627	if (lun >= MAX_LUNS) {
6628		EL(ha, "Exceeded MAX_LUN=%d, lun=%d\n", MAX_LUNS, lun);
6629		return (NULL);
6630	}
6631	/* If device queue exists, set proper loop ID. */
6632	lq = NULL;
6633	for (link = tq->lun_queues.first; link != NULL; link = link->next) {
6634		lq = link->base_address;
6635		if (lq->lun_no == lun) {
6636			QL_PRINT_3(CE_CONT, "(%d): found done\n",
6637			    ha->instance);
6638			tq->last_lun_queue = lq;
6639			return (lq);
6640		}
6641	}
6642
6643	/* If queue does exist. */
6644	lq = (ql_lun_t *)kmem_zalloc(sizeof (ql_lun_t), KM_SLEEP);
6645
6646	/* Initialize LUN queue. */
6647	if (lq != NULL) {
6648		lq->link.base_address = lq;
6649
6650		lq->lun_no = lun;
6651		lq->target_queue = tq;
6652
6653		DEVICE_QUEUE_LOCK(tq);
6654		ql_add_link_b(&tq->lun_queues, &lq->link);
6655		DEVICE_QUEUE_UNLOCK(tq);
6656		tq->last_lun_queue = lq;
6657	}
6658
6659	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6660
6661	return (lq);
6662}
6663
6664/*
6665 * ql_fcp_scsi_cmd
6666 *	Process fibre channel (FCP) SCSI protocol commands.
6667 *
6668 * Input:
6669 *	ha = adapter state pointer.
6670 *	pkt = pointer to fc_packet.
6671 *	sp = srb pointer.
6672 *
6673 * Returns:
6674 *	FC_SUCCESS - the packet was accepted for transport.
6675 *	FC_TRANSPORT_ERROR - a transport error occurred.
6676 *
6677 * Context:
6678 *	Kernel context.
6679 */
6680static int
6681ql_fcp_scsi_cmd(ql_adapter_state_t *ha, fc_packet_t *pkt, ql_srb_t *sp)
6682{
6683	port_id_t	d_id;
6684	ql_tgt_t	*tq;
6685	uint64_t	*ptr;
6686	uint16_t	lun;
6687
6688	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6689
6690	tq = (ql_tgt_t *)pkt->pkt_fca_device;
6691	if (tq == NULL) {
6692		d_id.r.rsvd_1 = 0;
6693		d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
6694		tq = ql_d_id_to_queue(ha, d_id);
6695	}
6696
6697	sp->fcp = (struct fcp_cmd *)pkt->pkt_cmd;
6698	lun = CHAR_TO_SHORT(lobyte(sp->fcp->fcp_ent_addr.ent_addr_0),
6699	    hibyte(sp->fcp->fcp_ent_addr.ent_addr_0));
6700
6701	if (tq != NULL &&
6702	    (sp->lun_queue = ql_lun_queue(ha, tq, lun)) != NULL) {
6703
6704		/*
6705		 * zero out FCP response; 24 Bytes
6706		 */
6707		ptr = (uint64_t *)pkt->pkt_resp;
6708		*ptr++ = 0; *ptr++ = 0; *ptr++ = 0;
6709
6710		/* Handle task management function. */
6711		if ((sp->fcp->fcp_cntl.cntl_kill_tsk |
6712		    sp->fcp->fcp_cntl.cntl_clr_aca |
6713		    sp->fcp->fcp_cntl.cntl_reset_tgt |
6714		    sp->fcp->fcp_cntl.cntl_reset_lun |
6715		    sp->fcp->fcp_cntl.cntl_clr_tsk |
6716		    sp->fcp->fcp_cntl.cntl_abort_tsk) != 0) {
6717			ql_task_mgmt(ha, tq, pkt, sp);
6718		} else {
6719			ha->pha->xioctl->IosRequested++;
6720			ha->pha->xioctl->BytesRequested += (uint32_t)
6721			    sp->fcp->fcp_data_len;
6722
6723			/*
6724			 * Setup for commands with data transfer
6725			 */
6726			sp->iocb = ha->fcp_cmd;
6727			if (sp->fcp->fcp_data_len != 0) {
6728				/*
6729				 * FCP data is bound to pkt_data_dma
6730				 */
6731				if (sp->fcp->fcp_cntl.cntl_write_data) {
6732					(void) ddi_dma_sync(pkt->pkt_data_dma,
6733					    0, 0, DDI_DMA_SYNC_FORDEV);
6734				}
6735
6736				/* Setup IOCB count. */
6737				if (pkt->pkt_data_cookie_cnt > ha->cmd_segs) {
6738					uint32_t	cnt;
6739
6740					cnt = pkt->pkt_data_cookie_cnt -
6741					    ha->cmd_segs;
6742					sp->req_cnt = (uint16_t)
6743					    (cnt / ha->cmd_cont_segs);
6744					if (cnt % ha->cmd_cont_segs) {
6745						sp->req_cnt = (uint16_t)
6746						    (sp->req_cnt + 2);
6747					} else {
6748						sp->req_cnt++;
6749					}
6750				} else {
6751					sp->req_cnt = 1;
6752				}
6753			} else {
6754				sp->req_cnt = 1;
6755			}
6756			QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6757
6758			return (ql_start_cmd(ha, tq, pkt, sp));
6759		}
6760	} else {
6761		pkt->pkt_state = FC_PKT_LOCAL_RJT;
6762		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
6763
6764		if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp)
6765			ql_awaken_task_daemon(ha, sp, 0, 0);
6766	}
6767
6768	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6769
6770	return (FC_SUCCESS);
6771}
6772
6773/*
6774 * ql_task_mgmt
6775 *	Task management function processor.
6776 *
6777 * Input:
6778 *	ha:	adapter state pointer.
6779 *	tq:	target queue pointer.
6780 *	pkt:	pointer to fc_packet.
6781 *	sp:	SRB pointer.
6782 *
6783 * Context:
6784 *	Kernel context.
6785 */
6786static void
6787ql_task_mgmt(ql_adapter_state_t *ha, ql_tgt_t *tq, fc_packet_t *pkt,
6788    ql_srb_t *sp)
6789{
6790	fcp_rsp_t		*fcpr;
6791	struct fcp_rsp_info	*rsp;
6792	uint16_t		lun;
6793
6794	ASSERT(pkt->pkt_cmd_dma == NULL && pkt->pkt_resp_dma == NULL);
6795
6796	fcpr = (fcp_rsp_t *)pkt->pkt_resp;
6797	rsp = (struct fcp_rsp_info *)pkt->pkt_resp + sizeof (fcp_rsp_t);
6798
6799	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6800
6801	bzero(fcpr, pkt->pkt_rsplen);
6802
6803	fcpr->fcp_u.fcp_status.rsp_len_set = 1;
6804	fcpr->fcp_response_len = 8;
6805	lun = CHAR_TO_SHORT(lobyte(sp->fcp->fcp_ent_addr.ent_addr_0),
6806	    hibyte(sp->fcp->fcp_ent_addr.ent_addr_0));
6807
6808	if (sp->fcp->fcp_cntl.cntl_clr_aca) {
6809		if (ql_clear_aca(ha, tq, lun) != QL_SUCCESS) {
6810			rsp->rsp_code = FCP_TASK_MGMT_FAILED;
6811		}
6812	} else if (sp->fcp->fcp_cntl.cntl_reset_lun) {
6813		if (ql_lun_reset(ha, tq, lun) != QL_SUCCESS) {
6814			rsp->rsp_code = FCP_TASK_MGMT_FAILED;
6815		}
6816	} else if (sp->fcp->fcp_cntl.cntl_reset_tgt) {
6817		if (ql_target_reset(ha, tq, ha->loop_reset_delay) !=
6818		    QL_SUCCESS) {
6819			rsp->rsp_code = FCP_TASK_MGMT_FAILED;
6820		}
6821	} else if (sp->fcp->fcp_cntl.cntl_clr_tsk) {
6822		if (ql_clear_task_set(ha, tq, lun) != QL_SUCCESS) {
6823			rsp->rsp_code = FCP_TASK_MGMT_FAILED;
6824		}
6825	} else if (sp->fcp->fcp_cntl.cntl_abort_tsk) {
6826		if (ql_abort_task_set(ha, tq, lun) != QL_SUCCESS) {
6827			rsp->rsp_code = FCP_TASK_MGMT_FAILED;
6828		}
6829	} else {
6830		rsp->rsp_code = FCP_TASK_MGMT_NOT_SUPPTD;
6831	}
6832
6833	pkt->pkt_state = FC_PKT_SUCCESS;
6834
6835	/* Do command callback. */
6836	if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
6837		ql_awaken_task_daemon(ha, sp, 0, 0);
6838	}
6839
6840	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6841}
6842
6843/*
6844 * ql_fcp_ip_cmd
6845 *	Process fibre channel (FCP) Internet (IP) protocols commands.
6846 *
6847 * Input:
6848 *	ha:	adapter state pointer.
6849 *	pkt:	pointer to fc_packet.
6850 *	sp:	SRB pointer.
6851 *
6852 * Returns:
6853 *	FC_SUCCESS - the packet was accepted for transport.
6854 *	FC_TRANSPORT_ERROR - a transport error occurred.
6855 *
6856 * Context:
6857 *	Kernel context.
6858 */
6859static int
6860ql_fcp_ip_cmd(ql_adapter_state_t *ha, fc_packet_t *pkt, ql_srb_t *sp)
6861{
6862	port_id_t	d_id;
6863	ql_tgt_t	*tq;
6864
6865	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6866
6867	tq = (ql_tgt_t *)pkt->pkt_fca_device;
6868	if (tq == NULL) {
6869		d_id.r.rsvd_1 = 0;
6870		d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
6871		tq = ql_d_id_to_queue(ha, d_id);
6872	}
6873
6874	if (tq != NULL && (sp->lun_queue = ql_lun_queue(ha, tq, 0)) != NULL) {
6875		/*
6876		 * IP data is bound to pkt_cmd_dma
6877		 */
6878		(void) ddi_dma_sync(pkt->pkt_cmd_dma,
6879		    0, 0, DDI_DMA_SYNC_FORDEV);
6880
6881		/* Setup IOCB count. */
6882		sp->iocb = ha->ip_cmd;
6883		if (pkt->pkt_cmd_cookie_cnt > ha->cmd_segs) {
6884			uint32_t	cnt;
6885
6886			cnt = pkt->pkt_cmd_cookie_cnt - ha->cmd_segs;
6887			sp->req_cnt = (uint16_t)(cnt / ha->cmd_cont_segs);
6888			if (cnt % ha->cmd_cont_segs) {
6889				sp->req_cnt = (uint16_t)(sp->req_cnt + 2);
6890			} else {
6891				sp->req_cnt++;
6892			}
6893		} else {
6894			sp->req_cnt = 1;
6895		}
6896		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6897
6898		return (ql_start_cmd(ha, tq, pkt, sp));
6899	} else {
6900		pkt->pkt_state = FC_PKT_LOCAL_RJT;
6901		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
6902
6903		if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp)
6904			ql_awaken_task_daemon(ha, sp, 0, 0);
6905	}
6906
6907	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6908
6909	return (FC_SUCCESS);
6910}
6911
6912/*
6913 * ql_fcp_data_rsp
6914 *	Process fibre channel protocol (FCP) data and response.
6915 *
6916 * Input:
6917 *	ha:	adapter state pointer.
6918 *	pkt:	pointer to fc_packet.
6919 *	sp:	SRB pointer.
6920 *
6921 * Returns:
6922 *	FC_SUCCESS - the packet was accepted for transport.
6923 *	FC_TRANSPORT_ERROR - a transport error occurred.
6924 *
6925 * Context:
6926 *	Kernel context.
6927 */
6928static int
6929ql_fcp_data_rsp(ql_adapter_state_t *ha, fc_packet_t *pkt, ql_srb_t *sp)
6930{
6931	port_id_t	d_id;
6932	ql_tgt_t	*tq;
6933	uint16_t	lun;
6934
6935	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6936
6937	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
6938	tq = ql_d_id_to_queue(ha, d_id);
6939
6940	sp->fcp = (struct fcp_cmd *)pkt->pkt_cmd;
6941	lun = CHAR_TO_SHORT(lobyte(sp->fcp->fcp_ent_addr.ent_addr_0),
6942	    hibyte(sp->fcp->fcp_ent_addr.ent_addr_0));
6943
6944	if (tq != NULL &&
6945	    (sp->lun_queue = ql_lun_queue(ha, tq, lun)) != NULL) {
6946		sp->fcp = (struct fcp_cmd *)pkt->pkt_cmd;
6947
6948		/*
6949		 * Setup for commands with data transfer
6950		 */
6951		if (pkt->pkt_cmdlen != 0 &&
6952		    ((pkt->pkt_tran_type == FC_PKT_OUTBOUND) ||
6953		    sp->flags & SRB_FCP_RSP_PKT)) {
6954			(void) ddi_dma_sync(pkt->pkt_cmd_dma, 0, 0,
6955			    DDI_DMA_SYNC_FORDEV);
6956		}
6957
6958		/* Setup IOCB count. */
6959		sp->iocb = ha->ctio_cmd;
6960		sp->req_cnt = 1;
6961
6962		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6963
6964		return (ql_start_cmd(ha, tq, pkt, sp));
6965	} else {
6966		pkt->pkt_state = FC_PKT_LOCAL_RJT;
6967		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
6968
6969		if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp)
6970			ql_awaken_task_daemon(ha, sp, 0, 0);
6971	}
6972
6973	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6974
6975	return (FC_SUCCESS);
6976}
6977
6978/*
6979 * ql_fc_services
6980 *	Process fibre channel services (name server).
6981 *
6982 * Input:
6983 *	ha:	adapter state pointer.
6984 *	pkt:	pointer to fc_packet.
6985 *
6986 * Returns:
6987 *	FC_SUCCESS - the packet was accepted for transport.
6988 *	FC_TRANSPORT_ERROR - a transport error occurred.
6989 *
6990 * Context:
6991 *	Kernel context.
6992 */
6993static int
6994ql_fc_services(ql_adapter_state_t *ha, fc_packet_t *pkt)
6995{
6996	uint32_t	cnt;
6997	fc_ct_header_t	hdr;
6998	la_els_rjt_t	rjt;
6999	port_id_t	d_id;
7000	ql_tgt_t	*tq;
7001	ql_srb_t	*sp;
7002	int		rval;
7003
7004	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7005
7006	ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&hdr,
7007	    (uint8_t *)pkt->pkt_cmd, sizeof (hdr), DDI_DEV_AUTOINCR);
7008
7009	bzero(&rjt, sizeof (rjt));
7010
7011	/* Do some sanity checks */
7012	cnt = (uint32_t)((uint32_t)(hdr.ct_aiusize * 4) +
7013	    sizeof (fc_ct_header_t));
7014	ASSERT(cnt <= (uint32_t)pkt->pkt_rsplen);
7015	if (cnt > (uint32_t)pkt->pkt_rsplen) {
7016		EL(ha, "FC_ELS_MALFORMED, cnt=%xh, size=%xh\n", cnt,
7017		    pkt->pkt_rsplen);
7018		return (FC_ELS_MALFORMED);
7019	}
7020
7021	switch (hdr.ct_fcstype) {
7022	case FCSTYPE_DIRECTORY:
7023	case FCSTYPE_MGMTSERVICE:
7024		/* An FCA must make sure that the header is in big endian */
7025		ql_cthdr_endian(pkt->pkt_cmd_acc, pkt->pkt_cmd, B_FALSE);
7026
7027		d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
7028		tq = ql_d_id_to_queue(ha, d_id);
7029		sp = (ql_srb_t *)pkt->pkt_fca_private;
7030		if (tq == NULL ||
7031		    (sp->lun_queue = ql_lun_queue(ha, tq, 0)) == NULL) {
7032			pkt->pkt_state = FC_PKT_LOCAL_RJT;
7033			pkt->pkt_reason = FC_REASON_NO_CONNECTION;
7034			rval = QL_SUCCESS;
7035			break;
7036		}
7037
7038		/*
7039		 * Services data is bound to pkt_cmd_dma
7040		 */
7041		(void) ddi_dma_sync(pkt->pkt_cmd_dma, 0, 0,
7042		    DDI_DMA_SYNC_FORDEV);
7043
7044		sp->flags |= SRB_MS_PKT;
7045		sp->retry_count = 32;
7046
7047		/* Setup IOCB count. */
7048		sp->iocb = ha->ms_cmd;
7049		if (pkt->pkt_resp_cookie_cnt > MS_DATA_SEGMENTS) {
7050			cnt = pkt->pkt_resp_cookie_cnt - MS_DATA_SEGMENTS;
7051			sp->req_cnt =
7052			    (uint16_t)(cnt / CONT_TYPE_1_DATA_SEGMENTS);
7053			if (cnt % CONT_TYPE_1_DATA_SEGMENTS) {
7054				sp->req_cnt = (uint16_t)(sp->req_cnt + 2);
7055			} else {
7056				sp->req_cnt++;
7057			}
7058		} else {
7059			sp->req_cnt = 1;
7060		}
7061		rval = ql_start_cmd(ha, tq, pkt, sp);
7062
7063		QL_PRINT_3(CE_CONT, "(%d): done, ql_start_cmd=%xh\n",
7064		    ha->instance, rval);
7065
7066		return (rval);
7067
7068	default:
7069		EL(ha, "unknown fcstype=%xh\n", hdr.ct_fcstype);
7070		rval = QL_FUNCTION_PARAMETER_ERROR;
7071		break;
7072	}
7073
7074	if (rval != QL_SUCCESS) {
7075
7076		/* Build RJT. */
7077		rjt.ls_code.ls_code = LA_ELS_RJT;
7078		rjt.reason = FC_REASON_CMD_UNSUPPORTED;
7079
7080		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
7081		    (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
7082
7083		pkt->pkt_state = FC_PKT_LOCAL_RJT;
7084		pkt->pkt_reason = FC_REASON_UNSUPPORTED;
7085	}
7086
7087	/* Do command callback. */
7088	if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
7089		ql_awaken_task_daemon(ha, (ql_srb_t *)pkt->pkt_fca_private,
7090		    0, 0);
7091	}
7092
7093	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7094
7095	return (FC_SUCCESS);
7096}
7097
7098/*
7099 * ql_cthdr_endian
7100 *	Change endianess of ct passthrough header and payload.
7101 *
7102 * Input:
7103 *	acc_handle:	DMA buffer access handle.
7104 *	ct_hdr:		Pointer to header.
7105 *	restore:	Restore first flag.
7106 *
7107 * Context:
7108 *	Interrupt or Kernel context, no mailbox commands allowed.
7109 */
7110void
7111ql_cthdr_endian(ddi_acc_handle_t acc_handle, caddr_t ct_hdr,
7112    boolean_t restore)
7113{
7114	uint8_t		i, *bp;
7115	fc_ct_header_t	hdr;
7116	uint32_t	*hdrp = (uint32_t *)&hdr;
7117
7118	ddi_rep_get8(acc_handle, (uint8_t *)&hdr,
7119	    (uint8_t *)ct_hdr, sizeof (hdr), DDI_DEV_AUTOINCR);
7120
7121	if (restore) {
7122		for (i = 0; i < ((sizeof (hdr)) / (sizeof (uint32_t))); i++) {
7123			*hdrp = BE_32(*hdrp);
7124			hdrp++;
7125		}
7126	}
7127
7128	if (hdr.ct_fcstype == FCSTYPE_DIRECTORY) {
7129		bp = (uint8_t *)ct_hdr + sizeof (fc_ct_header_t);
7130
7131		switch (hdr.ct_cmdrsp) {
7132		case NS_GA_NXT:
7133		case NS_GPN_ID:
7134		case NS_GNN_ID:
7135		case NS_GCS_ID:
7136		case NS_GFT_ID:
7137		case NS_GSPN_ID:
7138		case NS_GPT_ID:
7139		case NS_GID_FT:
7140		case NS_GID_PT:
7141		case NS_RPN_ID:
7142		case NS_RNN_ID:
7143		case NS_RSPN_ID:
7144		case NS_DA_ID:
7145			BIG_ENDIAN_32(bp);
7146			break;
7147		case NS_RFT_ID:
7148		case NS_RCS_ID:
7149		case NS_RPT_ID:
7150			BIG_ENDIAN_32(bp);
7151			bp += 4;
7152			BIG_ENDIAN_32(bp);
7153			break;
7154		case NS_GNN_IP:
7155		case NS_GIPA_IP:
7156			BIG_ENDIAN(bp, 16);
7157			break;
7158		case NS_RIP_NN:
7159			bp += 8;
7160			BIG_ENDIAN(bp, 16);
7161			break;
7162		case NS_RIPA_NN:
7163			bp += 8;
7164			BIG_ENDIAN_64(bp);
7165			break;
7166		default:
7167			break;
7168		}
7169	}
7170
7171	if (restore == B_FALSE) {
7172		for (i = 0; i < ((sizeof (hdr)) / (sizeof (uint32_t))); i++) {
7173			*hdrp = BE_32(*hdrp);
7174			hdrp++;
7175		}
7176	}
7177
7178	ddi_rep_put8(acc_handle, (uint8_t *)&hdr,
7179	    (uint8_t *)ct_hdr, sizeof (hdr), DDI_DEV_AUTOINCR);
7180}
7181
7182/*
7183 * ql_start_cmd
7184 *	Finishes starting fibre channel protocol (FCP) command.
7185 *
7186 * Input:
7187 *	ha:	adapter state pointer.
7188 *	tq:	target queue pointer.
7189 *	pkt:	pointer to fc_packet.
7190 *	sp:	SRB pointer.
7191 *
7192 * Context:
7193 *	Kernel context.
7194 */
7195static int
7196ql_start_cmd(ql_adapter_state_t *ha, ql_tgt_t *tq, fc_packet_t *pkt,
7197    ql_srb_t *sp)
7198{
7199	int		rval = FC_SUCCESS;
7200	time_t		poll_wait = 0;
7201	ql_lun_t	*lq = sp->lun_queue;
7202
7203	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7204
7205	sp->handle = 0;
7206
7207	/* Set poll for finish. */
7208	if (pkt->pkt_tran_flags & FC_TRAN_NO_INTR) {
7209		sp->flags |= SRB_POLL;
7210		if (pkt->pkt_timeout == 0) {
7211			pkt->pkt_timeout = SCSI_POLL_TIMEOUT;
7212		}
7213	}
7214
7215	/* Acquire device queue lock. */
7216	DEVICE_QUEUE_LOCK(tq);
7217
7218	/*
7219	 * If we need authentication, report device busy to
7220	 * upper layers to retry later
7221	 */
7222	if (tq->flags & (TQF_RSCN_RCVD | TQF_NEED_AUTHENTICATION)) {
7223		DEVICE_QUEUE_UNLOCK(tq);
7224		EL(ha, "failed, FC_DEVICE_BUSY=%xh, d_id=%xh\n", tq->flags,
7225		    tq->d_id.b24);
7226		return (FC_DEVICE_BUSY);
7227	}
7228
7229	/* Insert command onto watchdog queue. */
7230	if (!(pkt->pkt_tran_flags & FC_TRAN_DUMPING)) {
7231		ql_timeout_insert(ha, tq, sp);
7232	} else {
7233		/*
7234		 * Run dump requests in polled mode as kernel threads
7235		 * and interrupts may have been disabled.
7236		 */
7237		sp->flags |= SRB_POLL;
7238		sp->init_wdg_q_time = 0;
7239		sp->isp_timeout = 0;
7240	}
7241
7242	/* If a polling command setup wait time. */
7243	if (sp->flags & SRB_POLL) {
7244		if (sp->flags & SRB_WATCHDOG_ENABLED) {
7245			poll_wait = (sp->wdg_q_time + 2) * WATCHDOG_TIME;
7246		} else {
7247			poll_wait = pkt->pkt_timeout;
7248		}
7249		ASSERT(poll_wait != 0);
7250	}
7251
7252	if (ha->pha->flags & ABORT_CMDS_LOOP_DOWN_TMO &&
7253	    (CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING))) {
7254		/* Set ending status. */
7255		sp->pkt->pkt_reason = CS_PORT_UNAVAILABLE;
7256
7257		/* Call done routine to handle completions. */
7258		sp->cmd.next = NULL;
7259		DEVICE_QUEUE_UNLOCK(tq);
7260		ql_done(&sp->cmd);
7261	} else {
7262		if (ddi_in_panic() && (sp->flags & SRB_POLL)) {
7263			int do_lip = 0;
7264
7265			ASSERT(ha->pha->outstanding_cmds[0] == NULL);
7266
7267			DEVICE_QUEUE_UNLOCK(tq);
7268
7269			ADAPTER_STATE_LOCK(ha);
7270			if ((do_lip = ha->pha->lip_on_panic) == 0) {
7271				ha->pha->lip_on_panic++;
7272			}
7273			ADAPTER_STATE_UNLOCK(ha);
7274
7275			if (!do_lip) {
7276
7277				/*
7278				 * That Qlogic F/W performs PLOGI, PRLI, etc
7279				 * is helpful here. If a PLOGI fails for some
7280				 * reason, you would get CS_PORT_LOGGED_OUT
7281				 * or some such error; and we should get a
7282				 * careful polled mode login kicked off inside
7283				 * of this driver itself. You don't have FC
7284				 * transport's services as all threads are
7285				 * suspended, interrupts disabled, and so
7286				 * on. Right now we do re-login if the packet
7287				 * state isn't FC_PKT_SUCCESS.
7288				 */
7289				(void) ql_abort_isp(ha);
7290			}
7291
7292			ql_start_iocb(ha, sp);
7293		} else {
7294			/* Add the command to the device queue */
7295			if (pkt->pkt_tran_flags & FC_TRAN_HI_PRIORITY) {
7296				ql_add_link_t(&lq->cmd, &sp->cmd);
7297			} else {
7298				ql_add_link_b(&lq->cmd, &sp->cmd);
7299			}
7300
7301			sp->flags |= SRB_IN_DEVICE_QUEUE;
7302
7303			/* Check whether next message can be processed */
7304			ql_next(ha, lq);
7305		}
7306	}
7307
7308	/* If polling, wait for finish. */
7309	if (poll_wait) {
7310		ASSERT(sp->flags & SRB_POLL);
7311
7312		if (ql_poll_cmd(ha, sp, poll_wait) != QL_SUCCESS) {
7313			int	res;
7314
7315			res = ql_abort((opaque_t)ha, pkt, 0);
7316			if (res != FC_SUCCESS && res != FC_ABORTED) {
7317				ASSERT(res == FC_OFFLINE ||
7318				    res == FC_ABORT_FAILED);
7319
7320				DEVICE_QUEUE_LOCK(tq);
7321				ql_remove_link(&lq->cmd, &sp->cmd);
7322				sp->flags &= ~SRB_IN_DEVICE_QUEUE;
7323				DEVICE_QUEUE_UNLOCK(tq);
7324			}
7325		}
7326
7327		if (pkt->pkt_state != FC_PKT_SUCCESS) {
7328			EL(ha, "failed, FC_TRANSPORT_ERROR\n");
7329			rval = FC_TRANSPORT_ERROR;
7330		}
7331
7332		ASSERT((sp->flags & (SRB_IN_DEVICE_QUEUE |
7333		    SRB_IN_TOKEN_ARRAY)) == 0);
7334
7335		if (ddi_in_panic()) {
7336			ASSERT(ha->pha->outstanding_cmds[0] == NULL);
7337			if (pkt->pkt_state != FC_PKT_SUCCESS) {
7338				port_id_t d_id;
7339
7340				/*
7341				 * successful LOGIN implies by design
7342				 * that PRLI also succeeded for disks
7343				 * Note also that there is no special
7344				 * mailbox command to send PRLI.
7345				 */
7346				d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
7347				(void) ql_login_port(ha, d_id);
7348			}
7349		}
7350
7351		/*
7352		 * This should only happen during CPR dumping
7353		 */
7354		if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) &&
7355		    pkt->pkt_comp) {
7356			ASSERT(pkt->pkt_tran_flags & FC_TRAN_DUMPING);
7357			sp->flags &= ~SRB_POLL;
7358			(*pkt->pkt_comp)(pkt);
7359		}
7360	}
7361
7362	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7363
7364	return (rval);
7365}
7366
7367/*
7368 * ql_poll_cmd
7369 *	Polls commands for completion.
7370 *
7371 * Input:
7372 *	ha = adapter state pointer.
7373 *	sp = SRB command pointer.
7374 *	poll_wait = poll wait time in seconds.
7375 *
7376 * Returns:
7377 *	QL local function return status code.
7378 *
7379 * Context:
7380 *	Kernel context.
7381 */
7382static int
7383ql_poll_cmd(ql_adapter_state_t *vha, ql_srb_t *sp, time_t poll_wait)
7384{
7385	int			rval = QL_SUCCESS;
7386	time_t			msecs_left = poll_wait * 100;	/* 10ms inc */
7387	ql_adapter_state_t	*ha = vha->pha;
7388
7389	while (sp->flags & SRB_POLL) {
7390
7391		if ((ha->flags & INTERRUPTS_ENABLED) == 0 ||
7392		    ha->idle_timer >= 15 || ddi_in_panic()) {
7393
7394			/* If waiting for restart, do it now. */
7395			if (ha->port_retry_timer != 0) {
7396				ADAPTER_STATE_LOCK(ha);
7397				ha->port_retry_timer = 0;
7398				ADAPTER_STATE_UNLOCK(ha);
7399
7400				TASK_DAEMON_LOCK(ha);
7401				ha->task_daemon_flags |= PORT_RETRY_NEEDED;
7402				TASK_DAEMON_UNLOCK(ha);
7403			}
7404
7405			if ((CFG_IST(ha, CFG_CTRL_2425) ?
7406			    RD32_IO_REG(ha, istatus) :
7407			    RD16_IO_REG(ha, istatus)) & RISC_INT) {
7408				(void) ql_isr((caddr_t)ha);
7409				INTR_LOCK(ha);
7410				ha->intr_claimed = TRUE;
7411				INTR_UNLOCK(ha);
7412			}
7413
7414			/*
7415			 * Call task thread function in case the
7416			 * daemon is not running.
7417			 */
7418			TASK_DAEMON_LOCK(ha);
7419
7420			if (!ddi_in_panic() && QL_DAEMON_NOT_ACTIVE(ha) &&
7421			    QL_TASK_PENDING(ha)) {
7422				ha->task_daemon_flags |= TASK_THREAD_CALLED;
7423				ql_task_thread(ha);
7424				ha->task_daemon_flags &= ~TASK_THREAD_CALLED;
7425			}
7426
7427			TASK_DAEMON_UNLOCK(ha);
7428		}
7429
7430		if (msecs_left < 10) {
7431			rval = QL_FUNCTION_TIMEOUT;
7432			break;
7433		}
7434
7435		/*
7436		 * Polling interval is 10 milli seconds; Increasing
7437		 * the polling interval to seconds since disk IO
7438		 * timeout values are ~60 seconds is tempting enough,
7439		 * but CPR dump time increases, and so will the crash
7440		 * dump time; Don't toy with the settings without due
7441		 * consideration for all the scenarios that will be
7442		 * impacted.
7443		 */
7444		ql_delay(ha, 10000);
7445		msecs_left -= 10;
7446	}
7447
7448	return (rval);
7449}
7450
7451/*
7452 * ql_next
7453 *	Retrieve and process next job in the device queue.
7454 *
7455 * Input:
7456 *	ha:	adapter state pointer.
7457 *	lq:	LUN queue pointer.
7458 *	DEVICE_QUEUE_LOCK must be already obtained.
7459 *
7460 * Output:
7461 *	Releases DEVICE_QUEUE_LOCK upon exit.
7462 *
7463 * Context:
7464 *	Interrupt or Kernel context, no mailbox commands allowed.
7465 */
7466void
7467ql_next(ql_adapter_state_t *vha, ql_lun_t *lq)
7468{
7469	ql_srb_t		*sp;
7470	ql_link_t		*link;
7471	ql_tgt_t		*tq = lq->target_queue;
7472	ql_adapter_state_t	*ha = vha->pha;
7473
7474	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7475
7476	if (ddi_in_panic()) {
7477		DEVICE_QUEUE_UNLOCK(tq);
7478		QL_PRINT_3(CE_CONT, "(%d): panic/active exit\n",
7479		    ha->instance);
7480		return;
7481	}
7482
7483	while ((link = lq->cmd.first) != NULL) {
7484		sp = link->base_address;
7485
7486		/* Exit if can not start commands. */
7487		if (DRIVER_SUSPENDED(ha) ||
7488		    (ha->flags & ONLINE) == 0 ||
7489		    !VALID_DEVICE_ID(ha, tq->loop_id) ||
7490		    sp->flags & SRB_ABORT ||
7491		    tq->flags & (TQF_RSCN_RCVD | TQF_NEED_AUTHENTICATION |
7492		    TQF_QUEUE_SUSPENDED)) {
7493			EL(vha, "break, d_id=%xh, tdf=%xh, tqf=%xh, spf=%xh, "
7494			    "haf=%xh, loop_id=%xh\n", tq->d_id.b24,
7495			    ha->task_daemon_flags, tq->flags, sp->flags,
7496			    ha->flags, tq->loop_id);
7497			break;
7498		}
7499
7500		/*
7501		 * Find out the LUN number for untagged command use.
7502		 * If there is an untagged command pending for the LUN,
7503		 * we would not submit another untagged command
7504		 * or if reached LUN execution throttle.
7505		 */
7506		if (sp->flags & SRB_FCP_CMD_PKT) {
7507			if (lq->flags & LQF_UNTAGGED_PENDING ||
7508			    lq->lun_outcnt >= ha->execution_throttle) {
7509				QL_PRINT_8(CE_CONT, "(%d): break, d_id=%xh, "
7510				    "lf=%xh, lun_outcnt=%xh\n", ha->instance,
7511				    tq->d_id.b24, lq->flags, lq->lun_outcnt);
7512				break;
7513			}
7514			if (sp->fcp->fcp_cntl.cntl_qtype ==
7515			    FCP_QTYPE_UNTAGGED) {
7516				/*
7517				 * Set the untagged-flag for the LUN
7518				 * so that no more untagged commands
7519				 * can be submitted for this LUN.
7520				 */
7521				lq->flags |= LQF_UNTAGGED_PENDING;
7522			}
7523
7524			/* Count command as sent. */
7525			lq->lun_outcnt++;
7526		}
7527
7528		/* Remove srb from device queue. */
7529		ql_remove_link(&lq->cmd, &sp->cmd);
7530		sp->flags &= ~SRB_IN_DEVICE_QUEUE;
7531
7532		tq->outcnt++;
7533
7534		ql_start_iocb(vha, sp);
7535	}
7536
7537	/* Release device queue lock. */
7538	DEVICE_QUEUE_UNLOCK(tq);
7539
7540	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7541}
7542
7543/*
7544 * ql_done
7545 *	Process completed commands.
7546 *
7547 * Input:
7548 *	link:	first command link in chain.
7549 *
7550 * Context:
7551 *	Interrupt or Kernel context, no mailbox commands allowed.
7552 */
7553void
7554ql_done(ql_link_t *link)
7555{
7556	ql_adapter_state_t	*ha;
7557	ql_link_t		*next_link;
7558	ql_srb_t		*sp;
7559	ql_tgt_t		*tq;
7560	ql_lun_t		*lq;
7561
7562	QL_PRINT_3(CE_CONT, "started\n");
7563
7564	for (; link != NULL; link = next_link) {
7565		next_link = link->next;
7566		sp = link->base_address;
7567		ha = sp->ha;
7568
7569		if (sp->flags & SRB_UB_CALLBACK) {
7570			QL_UB_LOCK(ha);
7571			if (sp->flags & SRB_UB_IN_ISP) {
7572				if (ha->ub_outcnt != 0) {
7573					ha->ub_outcnt--;
7574				}
7575				QL_UB_UNLOCK(ha);
7576				ql_isp_rcvbuf(ha);
7577				QL_UB_LOCK(ha);
7578			}
7579			QL_UB_UNLOCK(ha);
7580			ql_awaken_task_daemon(ha, sp, 0, 0);
7581		} else {
7582			/* Free outstanding command slot. */
7583			if (sp->handle != 0) {
7584				ha->outstanding_cmds[
7585				    sp->handle & OSC_INDEX_MASK] = NULL;
7586				sp->handle = 0;
7587				sp->flags &= ~SRB_IN_TOKEN_ARRAY;
7588			}
7589
7590			/* Acquire device queue lock. */
7591			lq = sp->lun_queue;
7592			tq = lq->target_queue;
7593			DEVICE_QUEUE_LOCK(tq);
7594
7595			/* Decrement outstanding commands on device. */
7596			if (tq->outcnt != 0) {
7597				tq->outcnt--;
7598			}
7599
7600			if (sp->flags & SRB_FCP_CMD_PKT) {
7601				if (sp->fcp->fcp_cntl.cntl_qtype ==
7602				    FCP_QTYPE_UNTAGGED) {
7603					/*
7604					 * Clear the flag for this LUN so that
7605					 * untagged commands can be submitted
7606					 * for it.
7607					 */
7608					lq->flags &= ~LQF_UNTAGGED_PENDING;
7609				}
7610
7611				if (lq->lun_outcnt != 0) {
7612					lq->lun_outcnt--;
7613				}
7614			}
7615
7616			/* Reset port down retry count on good completion. */
7617			if (sp->pkt->pkt_reason == CS_COMPLETE) {
7618				tq->port_down_retry_count =
7619				    ha->port_down_retry_count;
7620				tq->qfull_retry_count = ha->qfull_retry_count;
7621			}
7622
7623			/* Place request back on top of target command queue */
7624			if ((sp->flags & SRB_MS_PKT ||
7625			    !(tq->flags & TQF_NEED_AUTHENTICATION)) &&
7626			    sp->flags & SRB_RETRY &&
7627			    (sp->flags & SRB_WATCHDOG_ENABLED &&
7628			    sp->wdg_q_time > 1)) {
7629				sp->flags &= ~(SRB_ISP_STARTED |
7630				    SRB_ISP_COMPLETED | SRB_RETRY);
7631
7632				/* Reset watchdog timer */
7633				sp->wdg_q_time = sp->init_wdg_q_time;
7634
7635				/* Issue marker command on reset status. */
7636				if (!(ha->task_daemon_flags & LOOP_DOWN) &&
7637				    (sp->pkt->pkt_reason == CS_RESET ||
7638				    (CFG_IST(ha, CFG_CTRL_2425) &&
7639				    sp->pkt->pkt_reason == CS_ABORTED))) {
7640					(void) ql_marker(ha, tq->loop_id, 0,
7641					    MK_SYNC_ID);
7642				}
7643
7644				ql_add_link_t(&lq->cmd, &sp->cmd);
7645				sp->flags |= SRB_IN_DEVICE_QUEUE;
7646				ql_next(ha, lq);
7647			} else {
7648				/* Remove command from watchdog queue. */
7649				if (sp->flags & SRB_WATCHDOG_ENABLED) {
7650					ql_remove_link(&tq->wdg, &sp->wdg);
7651					sp->flags &= ~SRB_WATCHDOG_ENABLED;
7652				}
7653
7654				if (lq->cmd.first != NULL) {
7655					ql_next(ha, lq);
7656				} else {
7657					/* Release LU queue specific lock. */
7658					DEVICE_QUEUE_UNLOCK(tq);
7659					if (ha->pha->pending_cmds.first !=
7660					    NULL) {
7661						ql_start_iocb(ha, NULL);
7662					}
7663				}
7664
7665				/* Sync buffers if required.  */
7666				if (sp->flags & SRB_MS_PKT) {
7667					(void) ddi_dma_sync(
7668					    sp->pkt->pkt_resp_dma,
7669					    0, 0, DDI_DMA_SYNC_FORCPU);
7670				}
7671
7672				/* Map ISP completion codes. */
7673				sp->pkt->pkt_expln = FC_EXPLN_NONE;
7674				sp->pkt->pkt_action = FC_ACTION_RETRYABLE;
7675				switch (sp->pkt->pkt_reason) {
7676				case CS_COMPLETE:
7677					sp->pkt->pkt_state = FC_PKT_SUCCESS;
7678					break;
7679				case CS_RESET:
7680					/* Issue marker command. */
7681					if (!(ha->task_daemon_flags &
7682					    LOOP_DOWN)) {
7683						(void) ql_marker(ha,
7684						    tq->loop_id, 0,
7685						    MK_SYNC_ID);
7686					}
7687					sp->pkt->pkt_state =
7688					    FC_PKT_PORT_OFFLINE;
7689					sp->pkt->pkt_reason =
7690					    FC_REASON_ABORTED;
7691					break;
7692				case CS_RESOUCE_UNAVAILABLE:
7693					sp->pkt->pkt_state = FC_PKT_LOCAL_BSY;
7694					sp->pkt->pkt_reason =
7695					    FC_REASON_PKT_BUSY;
7696					break;
7697
7698				case CS_TIMEOUT:
7699					sp->pkt->pkt_state = FC_PKT_TIMEOUT;
7700					sp->pkt->pkt_reason =
7701					    FC_REASON_HW_ERROR;
7702					break;
7703				case CS_DATA_OVERRUN:
7704					sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
7705					sp->pkt->pkt_reason =
7706					    FC_REASON_OVERRUN;
7707					break;
7708				case CS_PORT_UNAVAILABLE:
7709				case CS_PORT_LOGGED_OUT:
7710					sp->pkt->pkt_state =
7711					    FC_PKT_PORT_OFFLINE;
7712					sp->pkt->pkt_reason =
7713					    FC_REASON_LOGIN_REQUIRED;
7714					ql_send_logo(ha, tq, NULL);
7715					break;
7716				case CS_PORT_CONFIG_CHG:
7717					sp->pkt->pkt_state =
7718					    FC_PKT_PORT_OFFLINE;
7719					sp->pkt->pkt_reason =
7720					    FC_REASON_OFFLINE;
7721					break;
7722				case CS_QUEUE_FULL:
7723					sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
7724					sp->pkt->pkt_reason = FC_REASON_QFULL;
7725					break;
7726
7727				case CS_ABORTED:
7728					DEVICE_QUEUE_LOCK(tq);
7729					if (tq->flags & (TQF_RSCN_RCVD |
7730					    TQF_NEED_AUTHENTICATION)) {
7731						sp->pkt->pkt_state =
7732						    FC_PKT_PORT_OFFLINE;
7733						sp->pkt->pkt_reason =
7734						    FC_REASON_LOGIN_REQUIRED;
7735					} else {
7736						sp->pkt->pkt_state =
7737						    FC_PKT_LOCAL_RJT;
7738						sp->pkt->pkt_reason =
7739						    FC_REASON_ABORTED;
7740					}
7741					DEVICE_QUEUE_UNLOCK(tq);
7742					break;
7743
7744				case CS_TRANSPORT:
7745					sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
7746					sp->pkt->pkt_reason =
7747					    FC_PKT_TRAN_ERROR;
7748					break;
7749
7750				case CS_DATA_UNDERRUN:
7751					sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
7752					sp->pkt->pkt_reason =
7753					    FC_REASON_UNDERRUN;
7754					break;
7755				case CS_DMA_ERROR:
7756				case CS_BAD_PAYLOAD:
7757				case CS_UNKNOWN:
7758				case CS_CMD_FAILED:
7759				default:
7760					sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
7761					sp->pkt->pkt_reason =
7762					    FC_REASON_HW_ERROR;
7763					break;
7764				}
7765
7766				/* Now call the pkt completion callback */
7767				if (sp->flags & SRB_POLL) {
7768					sp->flags &= ~SRB_POLL;
7769				} else if (sp->pkt->pkt_comp) {
7770					if (sp->pkt->pkt_tran_flags &
7771					    FC_TRAN_IMMEDIATE_CB) {
7772						(*sp->pkt->pkt_comp)(sp->pkt);
7773					} else {
7774						ql_awaken_task_daemon(ha, sp,
7775						    0, 0);
7776					}
7777				}
7778			}
7779		}
7780	}
7781
7782	QL_PRINT_3(CE_CONT, "done\n");
7783}
7784
7785/*
7786 * ql_awaken_task_daemon
7787 *	Adds command completion callback to callback queue and/or
7788 *	awakens task daemon thread.
7789 *
7790 * Input:
7791 *	ha:		adapter state pointer.
7792 *	sp:		srb pointer.
7793 *	set_flags:	task daemon flags to set.
7794 *	reset_flags:	task daemon flags to reset.
7795 *
7796 * Context:
7797 *	Interrupt or Kernel context, no mailbox commands allowed.
7798 */
7799void
7800ql_awaken_task_daemon(ql_adapter_state_t *vha, ql_srb_t *sp,
7801    uint32_t set_flags, uint32_t reset_flags)
7802{
7803	ql_adapter_state_t	*ha = vha->pha;
7804
7805	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7806
7807	/* Acquire task daemon lock. */
7808	TASK_DAEMON_LOCK(ha);
7809
7810	if (set_flags & ISP_ABORT_NEEDED) {
7811		if (ha->task_daemon_flags & ABORT_ISP_ACTIVE) {
7812			set_flags &= ~ISP_ABORT_NEEDED;
7813		}
7814	}
7815
7816	ha->task_daemon_flags |= set_flags;
7817	ha->task_daemon_flags &= ~reset_flags;
7818
7819	if (QL_DAEMON_SUSPENDED(ha)) {
7820		if (sp != NULL) {
7821			TASK_DAEMON_UNLOCK(ha);
7822
7823			/* Do callback. */
7824			if (sp->flags & SRB_UB_CALLBACK) {
7825				ql_unsol_callback(sp);
7826			} else {
7827				(*sp->pkt->pkt_comp)(sp->pkt);
7828			}
7829		} else {
7830			if (!(curthread->t_flag & T_INTR_THREAD) &&
7831			    !(ha->task_daemon_flags & TASK_THREAD_CALLED)) {
7832				ha->task_daemon_flags |= TASK_THREAD_CALLED;
7833				ql_task_thread(ha);
7834				ha->task_daemon_flags &= ~TASK_THREAD_CALLED;
7835			}
7836
7837			TASK_DAEMON_UNLOCK(ha);
7838		}
7839	} else {
7840		if (sp != NULL) {
7841			ql_add_link_b(&ha->callback_queue, &sp->cmd);
7842		}
7843
7844		if (ha->task_daemon_flags & TASK_DAEMON_SLEEPING_FLG) {
7845			cv_broadcast(&ha->cv_task_daemon);
7846		}
7847		TASK_DAEMON_UNLOCK(ha);
7848	}
7849
7850	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7851}
7852
7853/*
7854 * ql_task_daemon
7855 *	Thread that is awaken by the driver when a
7856 *	background needs to be done.
7857 *
7858 * Input:
7859 *	arg = adapter state pointer.
7860 *
7861 * Context:
7862 *	Kernel context.
7863 */
7864static void
7865ql_task_daemon(void *arg)
7866{
7867	ql_adapter_state_t	*ha = (void *)arg;
7868
7869	QL_PRINT_3(CE_CONT, "\n(%d): started\n", ha->instance);
7870
7871	CALLB_CPR_INIT(&ha->cprinfo, &ha->task_daemon_mutex, callb_generic_cpr,
7872	    "ql_task_daemon");
7873
7874	/* Acquire task daemon lock. */
7875	TASK_DAEMON_LOCK(ha);
7876
7877	ha->task_daemon_flags |= TASK_DAEMON_ALIVE_FLG;
7878
7879	while ((ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) == 0) {
7880		ql_task_thread(ha);
7881
7882		QL_PRINT_3(CE_CONT, "(%d): Going to sleep\n", ha->instance);
7883
7884		/*
7885		 * Before we wait on the conditional variable, we
7886		 * need to check if STOP_FLG is set for us to terminate
7887		 */
7888		if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
7889			break;
7890		}
7891
7892		/*LINTED [Solaris CALLB_CPR_SAFE_BEGIN Lint error]*/
7893		CALLB_CPR_SAFE_BEGIN(&ha->cprinfo);
7894
7895		ha->task_daemon_flags |= TASK_DAEMON_SLEEPING_FLG;
7896
7897		/* If killed, stop task daemon */
7898		if (cv_wait_sig(&ha->cv_task_daemon,
7899		    &ha->task_daemon_mutex) == 0) {
7900			ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG;
7901		}
7902
7903		ha->task_daemon_flags &= ~TASK_DAEMON_SLEEPING_FLG;
7904
7905		/*LINTED [Solaris CALLB_CPR_SAFE_END Lint error]*/
7906		CALLB_CPR_SAFE_END(&ha->cprinfo, &ha->task_daemon_mutex);
7907
7908		QL_PRINT_3(CE_CONT, "(%d): Awakened\n", ha->instance);
7909	}
7910
7911	ha->task_daemon_flags &= ~(TASK_DAEMON_STOP_FLG |
7912	    TASK_DAEMON_ALIVE_FLG);
7913
7914	/*LINTED [Solaris CALLB_CPR_EXIT Lint error]*/
7915	CALLB_CPR_EXIT(&ha->cprinfo);
7916
7917	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7918
7919	thread_exit();
7920}
7921
7922/*
7923 * ql_task_thread
7924 *	Thread run by daemon.
7925 *
7926 * Input:
7927 *	ha = adapter state pointer.
7928 *	TASK_DAEMON_LOCK must be acquired prior to call.
7929 *
7930 * Context:
7931 *	Kernel context.
7932 */
7933static void
7934ql_task_thread(ql_adapter_state_t *ha)
7935{
7936	int			loop_again;
7937	ql_srb_t		*sp;
7938	ql_head_t		*head;
7939	ql_link_t		*link;
7940	caddr_t			msg;
7941	ql_adapter_state_t	*vha;
7942
7943	do {
7944		QL_PRINT_3(CE_CONT, "(%d): task_daemon_flags=%xh\n",
7945		    ha->instance, ha->task_daemon_flags);
7946
7947		loop_again = FALSE;
7948
7949		QL_PM_LOCK(ha);
7950		if (ha->power_level != PM_LEVEL_D0 ||
7951		    ha->flags & ADAPTER_SUSPENDED ||
7952		    ha->task_daemon_flags & (TASK_DAEMON_STOP_FLG |
7953		    DRIVER_STALL) ||
7954		    (ha->flags & ONLINE) == 0) {
7955			QL_PM_UNLOCK(ha);
7956			ha->task_daemon_flags |= TASK_DAEMON_STALLED_FLG;
7957			break;
7958		}
7959		QL_PM_UNLOCK(ha);
7960
7961		ha->task_daemon_flags &= ~TASK_DAEMON_STALLED_FLG;
7962
7963		if (ha->task_daemon_flags & ISP_ABORT_NEEDED) {
7964			TASK_DAEMON_UNLOCK(ha);
7965			ql_port_state(ha, FC_STATE_OFFLINE, FC_STATE_CHANGE);
7966			TASK_DAEMON_LOCK(ha);
7967			loop_again = TRUE;
7968		}
7969
7970		/* Idle Check. */
7971		if (ha->task_daemon_flags & TASK_DAEMON_IDLE_CHK_FLG) {
7972			ha->task_daemon_flags &= ~TASK_DAEMON_IDLE_CHK_FLG;
7973			if (!(ha->task_daemon_flags & QL_SUSPENDED)) {
7974				TASK_DAEMON_UNLOCK(ha);
7975				ql_idle_check(ha);
7976				TASK_DAEMON_LOCK(ha);
7977				loop_again = TRUE;
7978			}
7979		}
7980
7981		/* Crystal+ port#0 bypass transition */
7982		if (ha->task_daemon_flags & HANDLE_PORT_BYPASS_CHANGE) {
7983			ha->task_daemon_flags &= ~HANDLE_PORT_BYPASS_CHANGE;
7984			TASK_DAEMON_UNLOCK(ha);
7985			(void) ql_initiate_lip(ha);
7986			TASK_DAEMON_LOCK(ha);
7987			loop_again = TRUE;
7988		}
7989
7990		/* Abort queues needed. */
7991		if (ha->task_daemon_flags & ABORT_QUEUES_NEEDED) {
7992			ha->task_daemon_flags &= ~ABORT_QUEUES_NEEDED;
7993			TASK_DAEMON_UNLOCK(ha);
7994			ql_abort_queues(ha);
7995			TASK_DAEMON_LOCK(ha);
7996		}
7997
7998		/* Not suspended, awaken waiting routines. */
7999		if (!(ha->task_daemon_flags & QL_SUSPENDED) &&
8000		    ha->task_daemon_flags & SUSPENDED_WAKEUP_FLG) {
8001			ha->task_daemon_flags &= ~SUSPENDED_WAKEUP_FLG;
8002			cv_broadcast(&ha->cv_dr_suspended);
8003			loop_again = TRUE;
8004		}
8005
8006		/* Handle RSCN changes. */
8007		for (vha = ha; vha != NULL; vha = vha->vp_next) {
8008			if (vha->task_daemon_flags & RSCN_UPDATE_NEEDED) {
8009				vha->task_daemon_flags &= ~RSCN_UPDATE_NEEDED;
8010				TASK_DAEMON_UNLOCK(ha);
8011				(void) ql_handle_rscn_update(vha);
8012				TASK_DAEMON_LOCK(ha);
8013				loop_again = TRUE;
8014			}
8015		}
8016
8017		/* Handle state changes. */
8018		for (vha = ha; vha != NULL; vha = vha->vp_next) {
8019			if (vha->task_daemon_flags & FC_STATE_CHANGE &&
8020			    !(ha->task_daemon_flags &
8021			    TASK_DAEMON_POWERING_DOWN)) {
8022				/* Report state change. */
8023				EL(vha, "state change = %xh\n", vha->state);
8024				vha->task_daemon_flags &= ~FC_STATE_CHANGE;
8025
8026				if (vha->task_daemon_flags &
8027				    COMMAND_WAIT_NEEDED) {
8028					vha->task_daemon_flags &=
8029					    ~COMMAND_WAIT_NEEDED;
8030					if (!(ha->task_daemon_flags &
8031					    COMMAND_WAIT_ACTIVE)) {
8032						ha->task_daemon_flags |=
8033						    COMMAND_WAIT_ACTIVE;
8034						TASK_DAEMON_UNLOCK(ha);
8035						ql_cmd_wait(ha);
8036						TASK_DAEMON_LOCK(ha);
8037						ha->task_daemon_flags &=
8038						    ~COMMAND_WAIT_ACTIVE;
8039					}
8040				}
8041
8042				msg = NULL;
8043				if (FC_PORT_STATE_MASK(vha->state) ==
8044				    FC_STATE_OFFLINE) {
8045					if (vha->task_daemon_flags &
8046					    STATE_ONLINE) {
8047						if (ha->topology &
8048						    QL_LOOP_CONNECTION) {
8049							msg = "Loop OFFLINE";
8050						} else {
8051							msg = "Link OFFLINE";
8052						}
8053					}
8054					vha->task_daemon_flags &=
8055					    ~STATE_ONLINE;
8056				} else if (FC_PORT_STATE_MASK(vha->state) ==
8057				    FC_STATE_LOOP) {
8058					if (!(vha->task_daemon_flags &
8059					    STATE_ONLINE)) {
8060						msg = "Loop ONLINE";
8061					}
8062					vha->task_daemon_flags |= STATE_ONLINE;
8063				} else if (FC_PORT_STATE_MASK(vha->state) ==
8064				    FC_STATE_ONLINE) {
8065					if (!(vha->task_daemon_flags &
8066					    STATE_ONLINE)) {
8067						msg = "Link ONLINE";
8068					}
8069					vha->task_daemon_flags |= STATE_ONLINE;
8070				} else {
8071					msg = "Unknown Link state";
8072				}
8073
8074				if (msg != NULL) {
8075					cmn_err(CE_NOTE, "!Qlogic %s(%d,%d): "
8076					    "%s", QL_NAME, ha->instance,
8077					    vha->vp_index, msg);
8078				}
8079
8080				if (vha->flags & FCA_BOUND) {
8081					QL_PRINT_10(CE_CONT, "(%d,%d): statec_"
8082					    "cb state=%xh\n", ha->instance,
8083					    vha->vp_index, vha->state);
8084					TASK_DAEMON_UNLOCK(ha);
8085					(vha->bind_info.port_statec_cb)
8086					    (vha->bind_info.port_handle,
8087					    vha->state);
8088					TASK_DAEMON_LOCK(ha);
8089				}
8090				loop_again = TRUE;
8091			}
8092		}
8093
8094		if (ha->task_daemon_flags & LIP_RESET_PENDING &&
8095		    !(ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN)) {
8096			EL(ha, "processing LIP reset\n");
8097			ha->task_daemon_flags &= ~LIP_RESET_PENDING;
8098			TASK_DAEMON_UNLOCK(ha);
8099			for (vha = ha; vha != NULL; vha = vha->vp_next) {
8100				if (vha->flags & FCA_BOUND) {
8101					QL_PRINT_10(CE_CONT, "(%d,%d): statec_"
8102					    "cb reset\n", ha->instance,
8103					    vha->vp_index);
8104					(vha->bind_info.port_statec_cb)
8105					    (vha->bind_info.port_handle,
8106					    FC_STATE_TARGET_PORT_RESET);
8107				}
8108			}
8109			TASK_DAEMON_LOCK(ha);
8110			loop_again = TRUE;
8111		}
8112
8113		if (QL_IS_SET(ha->task_daemon_flags, NEED_UNSOLICITED_BUFFERS |
8114		    FIRMWARE_UP)) {
8115			/*
8116			 * The firmware needs more unsolicited
8117			 * buffers. We cannot allocate any new
8118			 * buffers unless the ULP module requests
8119			 * for new buffers. All we can do here is
8120			 * to give received buffers from the pool
8121			 * that is already allocated
8122			 */
8123			ha->task_daemon_flags &= ~NEED_UNSOLICITED_BUFFERS;
8124			TASK_DAEMON_UNLOCK(ha);
8125			ql_isp_rcvbuf(ha);
8126			TASK_DAEMON_LOCK(ha);
8127			loop_again = TRUE;
8128		}
8129
8130		if (ha->task_daemon_flags & ISP_ABORT_NEEDED) {
8131			TASK_DAEMON_UNLOCK(ha);
8132			(void) ql_abort_isp(ha);
8133			TASK_DAEMON_LOCK(ha);
8134			loop_again = TRUE;
8135		}
8136
8137		if (!(ha->task_daemon_flags & (LOOP_DOWN | DRIVER_STALL |
8138		    COMMAND_WAIT_NEEDED))) {
8139			if (QL_IS_SET(ha->task_daemon_flags,
8140			    RESET_MARKER_NEEDED | FIRMWARE_UP)) {
8141				ha->task_daemon_flags &= ~RESET_MARKER_NEEDED;
8142				if (!(ha->task_daemon_flags & RESET_ACTIVE)) {
8143					ha->task_daemon_flags |= RESET_ACTIVE;
8144					TASK_DAEMON_UNLOCK(ha);
8145					for (vha = ha; vha != NULL;
8146					    vha = vha->vp_next) {
8147						ql_rst_aen(vha);
8148					}
8149					TASK_DAEMON_LOCK(ha);
8150					ha->task_daemon_flags &= ~RESET_ACTIVE;
8151					loop_again = TRUE;
8152				}
8153			}
8154
8155			if (QL_IS_SET(ha->task_daemon_flags,
8156			    LOOP_RESYNC_NEEDED | FIRMWARE_UP)) {
8157				if (!(ha->task_daemon_flags &
8158				    LOOP_RESYNC_ACTIVE)) {
8159					ha->task_daemon_flags |=
8160					    LOOP_RESYNC_ACTIVE;
8161					TASK_DAEMON_UNLOCK(ha);
8162					(void) ql_loop_resync(ha);
8163					TASK_DAEMON_LOCK(ha);
8164					loop_again = TRUE;
8165				}
8166			}
8167		}
8168
8169		/* Port retry needed. */
8170		if (ha->task_daemon_flags & PORT_RETRY_NEEDED) {
8171			ha->task_daemon_flags &= ~PORT_RETRY_NEEDED;
8172			ADAPTER_STATE_LOCK(ha);
8173			ha->port_retry_timer = 0;
8174			ADAPTER_STATE_UNLOCK(ha);
8175
8176			TASK_DAEMON_UNLOCK(ha);
8177			ql_restart_queues(ha);
8178			TASK_DAEMON_LOCK(ha);
8179			loop_again = B_TRUE;
8180		}
8181
8182		/* iiDMA setting needed? */
8183		if (ha->task_daemon_flags & TD_IIDMA_NEEDED) {
8184			ha->task_daemon_flags &= ~TD_IIDMA_NEEDED;
8185
8186			TASK_DAEMON_UNLOCK(ha);
8187			ql_iidma(ha);
8188			TASK_DAEMON_LOCK(ha);
8189			loop_again = B_TRUE;
8190		}
8191
8192		head = &ha->callback_queue;
8193		if (head->first != NULL) {
8194			sp = head->first->base_address;
8195			link = &sp->cmd;
8196
8197			/* Dequeue command. */
8198			ql_remove_link(head, link);
8199
8200			/* Release task daemon lock. */
8201			TASK_DAEMON_UNLOCK(ha);
8202
8203			ASSERT((sp->flags & (SRB_IN_DEVICE_QUEUE |
8204			    SRB_IN_TOKEN_ARRAY)) == 0);
8205
8206			/* Do callback. */
8207			if (sp->flags & SRB_UB_CALLBACK) {
8208				ql_unsol_callback(sp);
8209			} else {
8210				(*sp->pkt->pkt_comp)(sp->pkt);
8211			}
8212
8213			/* Acquire task daemon lock. */
8214			TASK_DAEMON_LOCK(ha);
8215
8216			loop_again = TRUE;
8217		}
8218
8219	} while (loop_again);
8220}
8221
8222/*
8223 * ql_idle_check
8224 *	Test for adapter is alive and well.
8225 *
8226 * Input:
8227 *	ha:	adapter state pointer.
8228 *
8229 * Context:
8230 *	Kernel context.
8231 */
8232static void
8233ql_idle_check(ql_adapter_state_t *ha)
8234{
8235	ddi_devstate_t	state;
8236	int		rval;
8237	ql_mbx_data_t	mr;
8238
8239	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8240
8241	/* Firmware Ready Test. */
8242	rval = ql_get_firmware_state(ha, &mr);
8243	if (!(ha->task_daemon_flags & QL_SUSPENDED) &&
8244	    (rval != QL_SUCCESS || mr.mb[1] != FSTATE_READY)) {
8245		EL(ha, "failed, Firmware Ready Test = %xh\n", rval);
8246		state = ddi_get_devstate(ha->dip);
8247		if (state == DDI_DEVSTATE_UP) {
8248			/*EMPTY*/
8249			ddi_dev_report_fault(ha->dip, DDI_SERVICE_DEGRADED,
8250			    DDI_DEVICE_FAULT, "Firmware Ready Test failed");
8251		}
8252		TASK_DAEMON_LOCK(ha);
8253		if (!(ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
8254			EL(ha, "fstate_ready, isp_abort_needed\n");
8255			ha->task_daemon_flags |= ISP_ABORT_NEEDED;
8256		}
8257		TASK_DAEMON_UNLOCK(ha);
8258	}
8259
8260	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8261}
8262
8263/*
8264 * ql_unsol_callback
8265 *	Handle unsolicited buffer callbacks.
8266 *
8267 * Input:
8268 *	ha = adapter state pointer.
8269 *	sp = srb pointer.
8270 *
8271 * Context:
8272 *	Kernel context.
8273 */
8274static void
8275ql_unsol_callback(ql_srb_t *sp)
8276{
8277	fc_affected_id_t	*af;
8278	fc_unsol_buf_t		*ubp;
8279	uchar_t			r_ctl;
8280	uchar_t			ls_code;
8281	ql_tgt_t		*tq;
8282	ql_adapter_state_t	*ha = sp->ha, *pha = sp->ha->pha;
8283
8284	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8285
8286	ubp = ha->ub_array[sp->handle];
8287	r_ctl = ubp->ub_frame.r_ctl;
8288	ls_code = ubp->ub_buffer[0];
8289
8290	if (sp->lun_queue == NULL) {
8291		tq = NULL;
8292	} else {
8293		tq = sp->lun_queue->target_queue;
8294	}
8295
8296	QL_UB_LOCK(ha);
8297	if (sp->flags & SRB_UB_FREE_REQUESTED ||
8298	    pha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) {
8299		sp->flags &= ~(SRB_UB_IN_ISP | SRB_UB_CALLBACK |
8300		    SRB_UB_RSCN | SRB_UB_FCP | SRB_UB_ACQUIRED);
8301		sp->flags |= SRB_UB_IN_FCA;
8302		QL_UB_UNLOCK(ha);
8303		return;
8304	}
8305
8306	/* Process RSCN */
8307	if (sp->flags & SRB_UB_RSCN) {
8308		int sendup = 1;
8309
8310		/*
8311		 * Defer RSCN posting until commands return
8312		 */
8313		QL_UB_UNLOCK(ha);
8314
8315		af = (fc_affected_id_t *)((caddr_t)ubp->ub_buffer + 4);
8316
8317		/* Abort outstanding commands */
8318		sendup = ql_process_rscn(ha, af);
8319		if (sendup == 0) {
8320
8321			TASK_DAEMON_LOCK(ha);
8322			ql_add_link_b(&pha->callback_queue, &sp->cmd);
8323			TASK_DAEMON_UNLOCK(ha);
8324
8325			/*
8326			 * Wait for commands to drain in F/W (doesn't take
8327			 * more than a few milliseconds)
8328			 */
8329			ql_delay(ha, 10000);
8330
8331			QL_PRINT_2(CE_CONT, "(%d,%d): done rscn_sendup=0, "
8332			    "fmt=%xh, d_id=%xh\n", ha->instance, ha->vp_index,
8333			    af->aff_format, af->aff_d_id);
8334			return;
8335		}
8336
8337		QL_UB_LOCK(ha);
8338
8339		EL(ha, "sending unsol rscn, fmt=%xh, d_id=%xh to transport\n",
8340		    af->aff_format, af->aff_d_id);
8341	}
8342
8343	/* Process UNSOL LOGO */
8344	if ((r_ctl == R_CTL_ELS_REQ) && (ls_code == LA_ELS_LOGO)) {
8345		QL_UB_UNLOCK(ha);
8346
8347		if (tq && (ql_process_logo_for_device(ha, tq) == 0)) {
8348			TASK_DAEMON_LOCK(ha);
8349			ql_add_link_b(&pha->callback_queue, &sp->cmd);
8350			TASK_DAEMON_UNLOCK(ha);
8351			QL_PRINT_2(CE_CONT, "(%d,%d): logo_sendup=0, d_id=%xh"
8352			    "\n", ha->instance, ha->vp_index, tq->d_id.b24);
8353			return;
8354		}
8355
8356		QL_UB_LOCK(ha);
8357		EL(ha, "sending unsol logout for %xh to transport\n",
8358		    ubp->ub_frame.s_id);
8359	}
8360
8361	sp->flags &= ~(SRB_UB_IN_FCA | SRB_UB_IN_ISP | SRB_UB_RSCN |
8362	    SRB_UB_FCP);
8363
8364	if (sp->ub_type == FC_TYPE_IS8802_SNAP) {
8365		(void) ddi_dma_sync(sp->ub_buffer.dma_handle, 0,
8366		    ubp->ub_bufsize, DDI_DMA_SYNC_FORCPU);
8367	}
8368	QL_UB_UNLOCK(ha);
8369
8370	(ha->bind_info.port_unsol_cb)(ha->bind_info.port_handle,
8371	    ubp, sp->ub_type);
8372
8373	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8374}
8375
8376/*
8377 * ql_send_logo
8378 *
8379 * Input:
8380 *	ha:	adapter state pointer.
8381 *	tq:	target queue pointer.
8382 *	done_q:	done queue pointer.
8383 *
8384 * Context:
8385 *	Interrupt or Kernel context, no mailbox commands allowed.
8386 */
8387void
8388ql_send_logo(ql_adapter_state_t *vha, ql_tgt_t *tq, ql_head_t *done_q)
8389{
8390	fc_unsol_buf_t		*ubp;
8391	ql_srb_t		*sp;
8392	la_els_logo_t		*payload;
8393	ql_adapter_state_t	*ha = vha->pha;
8394
8395	if ((tq->d_id.b24 == 0) || (tq->d_id.b24 == 0xffffff)) {
8396		return;
8397	}
8398
8399	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
8400	    tq->d_id.b24);
8401
8402	if ((tq->flags & (TQF_RSCN_RCVD | TQF_PLOGI_PROGRS)) == 0 &&
8403	    tq->logout_sent == 0 && (ha->task_daemon_flags & LOOP_DOWN) == 0) {
8404
8405		/* Locate a buffer to use. */
8406		ubp = ql_get_unsolicited_buffer(vha, FC_TYPE_EXTENDED_LS);
8407		if (ubp == NULL) {
8408			EL(vha, "Failed, get_unsolicited_buffer\n");
8409			return;
8410		}
8411
8412		DEVICE_QUEUE_LOCK(tq);
8413		tq->flags |= TQF_NEED_AUTHENTICATION;
8414		tq->logout_sent++;
8415		DEVICE_QUEUE_UNLOCK(tq);
8416
8417		EL(vha, "Received LOGO from = %xh\n", tq->d_id.b24);
8418
8419		sp = ubp->ub_fca_private;
8420
8421		/* Set header. */
8422		ubp->ub_frame.d_id = vha->d_id.b24;
8423		ubp->ub_frame.r_ctl = R_CTL_ELS_REQ;
8424		ubp->ub_frame.s_id = tq->d_id.b24;
8425		ubp->ub_frame.rsvd = 0;
8426		ubp->ub_frame.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ |
8427		    F_CTL_SEQ_INITIATIVE;
8428		ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
8429		ubp->ub_frame.seq_cnt = 0;
8430		ubp->ub_frame.df_ctl = 0;
8431		ubp->ub_frame.seq_id = 0;
8432		ubp->ub_frame.rx_id = 0xffff;
8433		ubp->ub_frame.ox_id = 0xffff;
8434
8435		/* set payload. */
8436		payload = (la_els_logo_t *)ubp->ub_buffer;
8437		bzero(payload, sizeof (la_els_logo_t));
8438		/* Make sure ls_code in payload is always big endian */
8439		ubp->ub_buffer[0] = LA_ELS_LOGO;
8440		ubp->ub_buffer[1] = 0;
8441		ubp->ub_buffer[2] = 0;
8442		ubp->ub_buffer[3] = 0;
8443		bcopy(&vha->loginparams.node_ww_name.raw_wwn[0],
8444		    &payload->nport_ww_name.raw_wwn[0], 8);
8445		payload->nport_id.port_id = tq->d_id.b24;
8446
8447		QL_UB_LOCK(ha);
8448		sp->flags |= SRB_UB_CALLBACK;
8449		QL_UB_UNLOCK(ha);
8450		if (tq->lun_queues.first != NULL) {
8451			sp->lun_queue = (tq->lun_queues.first)->base_address;
8452		} else {
8453			sp->lun_queue = ql_lun_queue(vha, tq, 0);
8454		}
8455		if (done_q) {
8456			ql_add_link_b(done_q, &sp->cmd);
8457		} else {
8458			ql_awaken_task_daemon(ha, sp, 0, 0);
8459		}
8460	}
8461
8462	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8463}
8464
8465static int
8466ql_process_logo_for_device(ql_adapter_state_t *ha, ql_tgt_t *tq)
8467{
8468	port_id_t	d_id;
8469	ql_srb_t	*sp;
8470	ql_link_t	*link;
8471	int		sendup = 1;
8472
8473	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8474
8475	DEVICE_QUEUE_LOCK(tq);
8476	if (tq->outcnt) {
8477		DEVICE_QUEUE_UNLOCK(tq);
8478		sendup = 0;
8479		(void) ql_abort_device(ha, tq, 1);
8480		ql_delay(ha, 10000);
8481	} else {
8482		DEVICE_QUEUE_UNLOCK(tq);
8483		TASK_DAEMON_LOCK(ha);
8484
8485		for (link = ha->pha->callback_queue.first; link != NULL;
8486		    link = link->next) {
8487			sp = link->base_address;
8488			if (sp->flags & SRB_UB_CALLBACK) {
8489				continue;
8490			}
8491			d_id.b24 = sp->pkt->pkt_cmd_fhdr.d_id;
8492
8493			if (tq->d_id.b24 == d_id.b24) {
8494				sendup = 0;
8495				break;
8496			}
8497		}
8498
8499		TASK_DAEMON_UNLOCK(ha);
8500	}
8501
8502	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8503
8504	return (sendup);
8505}
8506
8507static int
8508ql_send_plogi(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_head_t *done_q)
8509{
8510	fc_unsol_buf_t		*ubp;
8511	ql_srb_t		*sp;
8512	la_els_logi_t		*payload;
8513	class_svc_param_t	*class3_param;
8514
8515	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8516
8517	if ((tq->flags & TQF_RSCN_RCVD) || (ha->task_daemon_flags &
8518	    LOOP_DOWN)) {
8519		EL(ha, "Failed, tqf=%xh\n", tq->flags);
8520		return (QL_FUNCTION_FAILED);
8521	}
8522
8523	/* Locate a buffer to use. */
8524	ubp = ql_get_unsolicited_buffer(ha, FC_TYPE_EXTENDED_LS);
8525	if (ubp == NULL) {
8526		EL(ha, "Failed\n");
8527		return (QL_FUNCTION_FAILED);
8528	}
8529
8530	QL_PRINT_3(CE_CONT, "(%d): Received LOGO from = %xh\n",
8531	    ha->instance, tq->d_id.b24);
8532
8533	sp = ubp->ub_fca_private;
8534
8535	/* Set header. */
8536	ubp->ub_frame.d_id = ha->d_id.b24;
8537	ubp->ub_frame.r_ctl = R_CTL_ELS_REQ;
8538	ubp->ub_frame.s_id = tq->d_id.b24;
8539	ubp->ub_frame.rsvd = 0;
8540	ubp->ub_frame.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ |
8541	    F_CTL_SEQ_INITIATIVE;
8542	ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
8543	ubp->ub_frame.seq_cnt = 0;
8544	ubp->ub_frame.df_ctl = 0;
8545	ubp->ub_frame.seq_id = 0;
8546	ubp->ub_frame.rx_id = 0xffff;
8547	ubp->ub_frame.ox_id = 0xffff;
8548
8549	/* set payload. */
8550	payload = (la_els_logi_t *)ubp->ub_buffer;
8551	bzero(payload, sizeof (payload));
8552
8553	payload->ls_code.ls_code = LA_ELS_PLOGI;
8554	payload->common_service.fcph_version = 0x2006;
8555	payload->common_service.cmn_features = 0x8800;
8556
8557	CFG_IST(ha, CFG_CTRL_2425) ?
8558	    (payload->common_service.rx_bufsize = CHAR_TO_SHORT(
8559	    ha->init_ctrl_blk.cb24.max_frame_length[0],
8560	    ha->init_ctrl_blk.cb24.max_frame_length[1])) :
8561	    (payload->common_service.rx_bufsize = CHAR_TO_SHORT(
8562	    ha->init_ctrl_blk.cb.max_frame_length[0],
8563	    ha->init_ctrl_blk.cb.max_frame_length[1]));
8564
8565	payload->common_service.conc_sequences = 0xff;
8566	payload->common_service.relative_offset = 0x03;
8567	payload->common_service.e_d_tov = 0x7d0;
8568
8569	bcopy((void *)&tq->port_name[0],
8570	    (void *)&payload->nport_ww_name.raw_wwn[0], 8);
8571
8572	bcopy((void *)&tq->node_name[0],
8573	    (void *)&payload->node_ww_name.raw_wwn[0], 8);
8574
8575	class3_param = (class_svc_param_t *)&payload->class_3;
8576	class3_param->class_valid_svc_opt = 0x8000;
8577	class3_param->recipient_ctl = tq->class3_recipient_ctl;
8578	class3_param->rcv_data_size = tq->class3_rcv_data_size;
8579	class3_param->conc_sequences = tq->class3_conc_sequences;
8580	class3_param->open_sequences_per_exch =
8581	    tq->class3_open_sequences_per_exch;
8582
8583	QL_UB_LOCK(ha);
8584	sp->flags |= SRB_UB_CALLBACK;
8585	QL_UB_UNLOCK(ha);
8586
8587	if (done_q) {
8588		ql_add_link_b(done_q, &sp->cmd);
8589	} else {
8590		ql_awaken_task_daemon(ha, sp, 0, 0);
8591	}
8592
8593	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8594
8595	return (QL_SUCCESS);
8596}
8597
8598/*
8599 * Abort outstanding commands in the Firmware, clear internally
8600 * queued commands in the driver, Synchronize the target with
8601 * the Firmware
8602 */
8603int
8604ql_abort_device(ql_adapter_state_t *ha, ql_tgt_t *tq, int drain)
8605{
8606	ql_link_t	*link, *link2;
8607	ql_lun_t	*lq;
8608	int		rval = QL_SUCCESS;
8609	ql_srb_t	*sp;
8610	ql_head_t	done_q = { NULL, NULL };
8611
8612	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
8613
8614	/*
8615	 * First clear, internally queued commands
8616	 */
8617	DEVICE_QUEUE_LOCK(tq);
8618	for (link = tq->lun_queues.first; link != NULL; link = link->next) {
8619		lq = link->base_address;
8620
8621		link2 = lq->cmd.first;
8622		while (link2 != NULL) {
8623			sp = link2->base_address;
8624			link2 = link2->next;
8625
8626			if (sp->flags & SRB_ABORT) {
8627				continue;
8628			}
8629
8630			/* Remove srb from device command queue. */
8631			ql_remove_link(&lq->cmd, &sp->cmd);
8632			sp->flags &= ~SRB_IN_DEVICE_QUEUE;
8633
8634			/* Set ending status. */
8635			sp->pkt->pkt_reason = CS_ABORTED;
8636
8637			/* Call done routine to handle completions. */
8638			ql_add_link_b(&done_q, &sp->cmd);
8639		}
8640	}
8641	DEVICE_QUEUE_UNLOCK(tq);
8642
8643	if (done_q.first != NULL) {
8644		ql_done(done_q.first);
8645	}
8646
8647	if (drain && VALID_TARGET_ID(ha, tq->loop_id) && PD_PORT_LOGIN(tq)) {
8648		rval = ql_abort_target(ha, tq, 0);
8649	}
8650
8651	if (rval != QL_SUCCESS) {
8652		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
8653	} else {
8654		/*EMPTY*/
8655		QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
8656		    ha->vp_index);
8657	}
8658
8659	return (rval);
8660}
8661
8662/*
8663 * ql_rcv_rscn_els
8664 *	Processes received RSCN extended link service.
8665 *
8666 * Input:
8667 *	ha:	adapter state pointer.
8668 *	mb:	array containing input mailbox registers.
8669 *	done_q:	done queue pointer.
8670 *
8671 * Context:
8672 *	Interrupt or Kernel context, no mailbox commands allowed.
8673 */
8674void
8675ql_rcv_rscn_els(ql_adapter_state_t *ha, uint16_t *mb, ql_head_t *done_q)
8676{
8677	fc_unsol_buf_t		*ubp;
8678	ql_srb_t		*sp;
8679	fc_rscn_t		*rn;
8680	fc_affected_id_t	*af;
8681	port_id_t		d_id;
8682
8683	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8684
8685	/* Locate a buffer to use. */
8686	ubp = ql_get_unsolicited_buffer(ha, FC_TYPE_EXTENDED_LS);
8687	if (ubp != NULL) {
8688		sp = ubp->ub_fca_private;
8689
8690		/* Set header. */
8691		ubp->ub_frame.d_id = ha->d_id.b24;
8692		ubp->ub_frame.r_ctl = R_CTL_ELS_REQ;
8693		ubp->ub_frame.s_id = FS_FABRIC_CONTROLLER;
8694		ubp->ub_frame.rsvd = 0;
8695		ubp->ub_frame.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ |
8696		    F_CTL_SEQ_INITIATIVE;
8697		ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
8698		ubp->ub_frame.seq_cnt = 0;
8699		ubp->ub_frame.df_ctl = 0;
8700		ubp->ub_frame.seq_id = 0;
8701		ubp->ub_frame.rx_id = 0xffff;
8702		ubp->ub_frame.ox_id = 0xffff;
8703
8704		/* set payload. */
8705		rn = (fc_rscn_t *)ubp->ub_buffer;
8706		af = (fc_affected_id_t *)((caddr_t)ubp->ub_buffer + 4);
8707
8708		rn->rscn_code = LA_ELS_RSCN;
8709		rn->rscn_len = 4;
8710		rn->rscn_payload_len = 8;
8711		d_id.b.al_pa = LSB(mb[2]);
8712		d_id.b.area = MSB(mb[2]);
8713		d_id.b.domain =	LSB(mb[1]);
8714		af->aff_d_id = d_id.b24;
8715		af->aff_format = MSB(mb[1]);
8716
8717		EL(ha, "LA_ELS_RSCN fmt=%xh, d_id=%xh\n", af->aff_format,
8718		    af->aff_d_id);
8719
8720		ql_update_rscn(ha, af);
8721
8722		QL_UB_LOCK(ha);
8723		sp->flags |= SRB_UB_CALLBACK | SRB_UB_RSCN;
8724		QL_UB_UNLOCK(ha);
8725		ql_add_link_b(done_q, &sp->cmd);
8726	}
8727
8728	if (ubp == NULL) {
8729		EL(ha, "Failed, get_unsolicited_buffer\n");
8730	} else {
8731		/*EMPTY*/
8732		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8733	}
8734}
8735
8736/*
8737 * ql_update_rscn
8738 *	Update devices from received RSCN.
8739 *
8740 * Input:
8741 *	ha:	adapter state pointer.
8742 *	af:	pointer to RSCN data.
8743 *
8744 * Context:
8745 *	Interrupt or Kernel context, no mailbox commands allowed.
8746 */
8747static void
8748ql_update_rscn(ql_adapter_state_t *ha, fc_affected_id_t *af)
8749{
8750	ql_link_t	*link;
8751	uint16_t	index;
8752	ql_tgt_t	*tq;
8753
8754	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8755
8756	if (af->aff_format == FC_RSCN_PORT_ADDRESS) {
8757		port_id_t d_id;
8758
8759		d_id.r.rsvd_1 = 0;
8760		d_id.b24 = af->aff_d_id;
8761
8762		tq = ql_d_id_to_queue(ha, d_id);
8763		if (tq) {
8764			EL(ha, "SD_RSCN_RCVD %xh RPA\n", d_id.b24);
8765			DEVICE_QUEUE_LOCK(tq);
8766			tq->flags |= TQF_RSCN_RCVD;
8767			DEVICE_QUEUE_UNLOCK(tq);
8768		}
8769		QL_PRINT_3(CE_CONT, "(%d): FC_RSCN_PORT_ADDRESS done\n",
8770		    ha->instance);
8771
8772		return;
8773	}
8774
8775	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
8776		for (link = ha->dev[index].first; link != NULL;
8777		    link = link->next) {
8778			tq = link->base_address;
8779
8780			switch (af->aff_format) {
8781			case FC_RSCN_FABRIC_ADDRESS:
8782				if (!RESERVED_LOOP_ID(ha, tq->loop_id)) {
8783					EL(ha, "SD_RSCN_RCVD %xh RFA\n",
8784					    tq->d_id.b24);
8785					DEVICE_QUEUE_LOCK(tq);
8786					tq->flags |= TQF_RSCN_RCVD;
8787					DEVICE_QUEUE_UNLOCK(tq);
8788				}
8789				break;
8790
8791			case FC_RSCN_AREA_ADDRESS:
8792				if ((tq->d_id.b24 & 0xffff00) == af->aff_d_id) {
8793					EL(ha, "SD_RSCN_RCVD %xh RAA\n",
8794					    tq->d_id.b24);
8795					DEVICE_QUEUE_LOCK(tq);
8796					tq->flags |= TQF_RSCN_RCVD;
8797					DEVICE_QUEUE_UNLOCK(tq);
8798				}
8799				break;
8800
8801			case FC_RSCN_DOMAIN_ADDRESS:
8802				if ((tq->d_id.b24 & 0xff0000) == af->aff_d_id) {
8803					EL(ha, "SD_RSCN_RCVD %xh RDA\n",
8804					    tq->d_id.b24);
8805					DEVICE_QUEUE_LOCK(tq);
8806					tq->flags |= TQF_RSCN_RCVD;
8807					DEVICE_QUEUE_UNLOCK(tq);
8808				}
8809				break;
8810
8811			default:
8812				break;
8813			}
8814		}
8815	}
8816	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8817}
8818
8819/*
8820 * ql_process_rscn
8821 *
8822 * Input:
8823 *	ha:	adapter state pointer.
8824 *	af:	RSCN payload pointer.
8825 *
8826 * Context:
8827 *	Kernel context.
8828 */
8829static int
8830ql_process_rscn(ql_adapter_state_t *ha, fc_affected_id_t *af)
8831{
8832	int		sendit;
8833	int		sendup = 1;
8834	ql_link_t	*link;
8835	uint16_t	index;
8836	ql_tgt_t	*tq;
8837
8838	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8839
8840	if (af->aff_format == FC_RSCN_PORT_ADDRESS) {
8841		port_id_t d_id;
8842
8843		d_id.r.rsvd_1 = 0;
8844		d_id.b24 = af->aff_d_id;
8845
8846		tq = ql_d_id_to_queue(ha, d_id);
8847		if (tq) {
8848			sendup = ql_process_rscn_for_device(ha, tq);
8849		}
8850
8851		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8852
8853		return (sendup);
8854	}
8855
8856	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
8857		for (link = ha->dev[index].first; link != NULL;
8858		    link = link->next) {
8859
8860			tq = link->base_address;
8861			if (tq == NULL) {
8862				continue;
8863			}
8864
8865			switch (af->aff_format) {
8866			case FC_RSCN_FABRIC_ADDRESS:
8867				if (!RESERVED_LOOP_ID(ha, tq->loop_id)) {
8868					sendit = ql_process_rscn_for_device(
8869					    ha, tq);
8870					if (sendup) {
8871						sendup = sendit;
8872					}
8873				}
8874				break;
8875
8876			case FC_RSCN_AREA_ADDRESS:
8877				if ((tq->d_id.b24 & 0xffff00) ==
8878				    af->aff_d_id) {
8879					sendit = ql_process_rscn_for_device(
8880					    ha, tq);
8881
8882					if (sendup) {
8883						sendup = sendit;
8884					}
8885				}
8886				break;
8887
8888			case FC_RSCN_DOMAIN_ADDRESS:
8889				if ((tq->d_id.b24 & 0xff0000) ==
8890				    af->aff_d_id) {
8891					sendit = ql_process_rscn_for_device(
8892					    ha, tq);
8893
8894					if (sendup) {
8895						sendup = sendit;
8896					}
8897				}
8898				break;
8899
8900			default:
8901				break;
8902			}
8903		}
8904	}
8905
8906	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8907
8908	return (sendup);
8909}
8910
8911/*
8912 * ql_process_rscn_for_device
8913 *
8914 * Input:
8915 *	ha:	adapter state pointer.
8916 *	tq:	target queue pointer.
8917 *
8918 * Context:
8919 *	Kernel context.
8920 */
8921static int
8922ql_process_rscn_for_device(ql_adapter_state_t *ha, ql_tgt_t *tq)
8923{
8924	int sendup = 1;
8925
8926	DEVICE_QUEUE_LOCK(tq);
8927
8928	/*
8929	 * Let FCP-2 compliant devices continue I/Os
8930	 * with their low level recoveries.
8931	 */
8932	if (((tq->flags & TQF_INITIATOR_DEVICE) == 0) &&
8933	    (tq->prli_svc_param_word_3 & PRLI_W3_RETRY)) {
8934		/*
8935		 * Cause ADISC to go out
8936		 */
8937		DEVICE_QUEUE_UNLOCK(tq);
8938
8939		(void) ql_get_port_database(ha, tq, PDF_NONE);
8940
8941		DEVICE_QUEUE_LOCK(tq);
8942		tq->flags &= ~TQF_RSCN_RCVD;
8943
8944	} else if (tq->loop_id != PORT_NO_LOOP_ID) {
8945		if (tq->d_id.b24 != BROADCAST_ADDR) {
8946			tq->flags |= TQF_NEED_AUTHENTICATION;
8947		}
8948
8949		DEVICE_QUEUE_UNLOCK(tq);
8950
8951		(void) ql_abort_device(ha, tq, 1);
8952
8953		DEVICE_QUEUE_LOCK(tq);
8954
8955		if (tq->outcnt) {
8956			sendup = 0;
8957		} else {
8958			tq->flags &= ~TQF_RSCN_RCVD;
8959		}
8960	} else {
8961		tq->flags &= ~TQF_RSCN_RCVD;
8962	}
8963
8964	if (sendup) {
8965		if (tq->d_id.b24 != BROADCAST_ADDR) {
8966			tq->flags |= TQF_NEED_AUTHENTICATION;
8967		}
8968	}
8969
8970	DEVICE_QUEUE_UNLOCK(tq);
8971
8972	return (sendup);
8973}
8974
8975static int
8976ql_handle_rscn_update(ql_adapter_state_t *ha)
8977{
8978	int			rval;
8979	ql_tgt_t		*tq;
8980	uint16_t		index, loop_id;
8981	ql_dev_id_list_t	*list;
8982	uint32_t		list_size;
8983	port_id_t		d_id;
8984	ql_mbx_data_t		mr;
8985	ql_head_t		done_q = { NULL, NULL };
8986
8987	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8988
8989	list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES;
8990	list = kmem_zalloc(list_size, KM_SLEEP);
8991	if (list == NULL) {
8992		rval = QL_MEMORY_ALLOC_FAILED;
8993		EL(ha, "kmem_zalloc failed=%xh\n", rval);
8994		return (rval);
8995	}
8996
8997	/*
8998	 * Get data from RISC code d_id list to init each device queue.
8999	 */
9000	rval = ql_get_id_list(ha, (caddr_t)list, list_size, &mr);
9001	if (rval != QL_SUCCESS) {
9002		kmem_free(list, list_size);
9003		EL(ha, "get_id_list failed=%xh\n", rval);
9004		return (rval);
9005	}
9006
9007	/* Acquire adapter state lock. */
9008	ADAPTER_STATE_LOCK(ha);
9009
9010	/* Check for new devices */
9011	for (index = 0; index < mr.mb[1]; index++) {
9012		ql_dev_list(ha, list, index, &d_id, &loop_id);
9013
9014		if (VALID_DEVICE_ID(ha, loop_id)) {
9015			d_id.r.rsvd_1 = 0;
9016
9017			tq = ql_d_id_to_queue(ha, d_id);
9018			if (tq != NULL) {
9019				continue;
9020			}
9021
9022			tq = ql_dev_init(ha, d_id, loop_id);
9023
9024			/* Test for fabric device. */
9025			if (d_id.b.domain != ha->d_id.b.domain ||
9026			    d_id.b.area != ha->d_id.b.area) {
9027				tq->flags |= TQF_FABRIC_DEVICE;
9028			}
9029
9030			ADAPTER_STATE_UNLOCK(ha);
9031			if (ql_get_port_database(ha, tq, PDF_NONE) !=
9032			    QL_SUCCESS) {
9033				tq->loop_id = PORT_NO_LOOP_ID;
9034			}
9035			ADAPTER_STATE_LOCK(ha);
9036
9037			/*
9038			 * Send up a PLOGI about the new device
9039			 */
9040			if (VALID_DEVICE_ID(ha, tq->loop_id)) {
9041				(void) ql_send_plogi(ha, tq, &done_q);
9042			}
9043		}
9044	}
9045
9046	/* Release adapter state lock. */
9047	ADAPTER_STATE_UNLOCK(ha);
9048
9049	if (done_q.first != NULL) {
9050		ql_done(done_q.first);
9051	}
9052
9053	kmem_free(list, list_size);
9054
9055	if (rval != QL_SUCCESS) {
9056		EL(ha, "failed=%xh\n", rval);
9057	} else {
9058		/*EMPTY*/
9059		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9060	}
9061
9062	return (rval);
9063}
9064
9065/*
9066 * ql_free_unsolicited_buffer
9067 *	Frees allocated buffer.
9068 *
9069 * Input:
9070 *	ha = adapter state pointer.
9071 *	index = buffer array index.
9072 *	ADAPTER_STATE_LOCK must be already obtained.
9073 *
9074 * Context:
9075 *	Kernel context.
9076 */
9077static void
9078ql_free_unsolicited_buffer(ql_adapter_state_t *ha, fc_unsol_buf_t *ubp)
9079{
9080	ql_srb_t	*sp;
9081	int		status;
9082
9083	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9084
9085	sp = ubp->ub_fca_private;
9086	if (sp->ub_type == FC_TYPE_IS8802_SNAP) {
9087		/* Disconnect IP from system buffers. */
9088		if (ha->flags & IP_INITIALIZED) {
9089			ADAPTER_STATE_UNLOCK(ha);
9090			status = ql_shutdown_ip(ha);
9091			ADAPTER_STATE_LOCK(ha);
9092			if (status != QL_SUCCESS) {
9093				cmn_err(CE_WARN,
9094				    "!Qlogic %s(%d): Failed to shutdown IP",
9095				    QL_NAME, ha->instance);
9096				return;
9097			}
9098
9099			ha->flags &= ~IP_ENABLED;
9100		}
9101
9102		ql_free_phys(ha, &sp->ub_buffer);
9103	} else {
9104		kmem_free(ubp->ub_buffer, ubp->ub_bufsize);
9105	}
9106
9107	kmem_free(sp, sizeof (ql_srb_t));
9108	kmem_free(ubp, sizeof (fc_unsol_buf_t));
9109
9110	if (ha->ub_allocated != 0) {
9111		ha->ub_allocated--;
9112	}
9113
9114	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9115}
9116
9117/*
9118 * ql_get_unsolicited_buffer
9119 *	Locates a free unsolicited buffer.
9120 *
9121 * Input:
9122 *	ha = adapter state pointer.
9123 *	type = buffer type.
9124 *
9125 * Returns:
9126 *	Unsolicited buffer pointer.
9127 *
9128 * Context:
9129 *	Interrupt or Kernel context, no mailbox commands allowed.
9130 */
9131fc_unsol_buf_t *
9132ql_get_unsolicited_buffer(ql_adapter_state_t *ha, uint32_t type)
9133{
9134	fc_unsol_buf_t	*ubp;
9135	ql_srb_t	*sp;
9136	uint16_t	index;
9137
9138	/* Locate a buffer to use. */
9139	ubp = NULL;
9140
9141	QL_UB_LOCK(ha);
9142	for (index = 0; index < QL_UB_LIMIT; index++) {
9143		ubp = ha->ub_array[index];
9144		if (ubp != NULL) {
9145			sp = ubp->ub_fca_private;
9146			if ((sp->ub_type == type) &&
9147			    (sp->flags & SRB_UB_IN_FCA) &&
9148			    (!(sp->flags & (SRB_UB_CALLBACK |
9149			    SRB_UB_FREE_REQUESTED | SRB_UB_ACQUIRED)))) {
9150				sp->flags |= SRB_UB_ACQUIRED;
9151				ubp->ub_resp_flags = 0;
9152				break;
9153			}
9154			ubp = NULL;
9155		}
9156	}
9157	QL_UB_UNLOCK(ha);
9158
9159	if (ubp) {
9160		ubp->ub_resp_token = NULL;
9161		ubp->ub_class = FC_TRAN_CLASS3;
9162	}
9163
9164	return (ubp);
9165}
9166
9167/*
9168 * ql_ub_frame_hdr
9169 *	Processes received unsolicited buffers from ISP.
9170 *
9171 * Input:
9172 *	ha:	adapter state pointer.
9173 *	tq:	target queue pointer.
9174 *	index:	unsolicited buffer array index.
9175 *	done_q:	done queue pointer.
9176 *
9177 * Returns:
9178 *	ql local function return status code.
9179 *
9180 * Context:
9181 *	Interrupt or Kernel context, no mailbox commands allowed.
9182 */
9183int
9184ql_ub_frame_hdr(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t index,
9185    ql_head_t *done_q)
9186{
9187	fc_unsol_buf_t	*ubp;
9188	ql_srb_t	*sp;
9189	uint16_t	loop_id;
9190	int		rval = QL_FUNCTION_FAILED;
9191
9192	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9193
9194	QL_UB_LOCK(ha);
9195	if (index >= QL_UB_LIMIT || (ubp = ha->ub_array[index]) == NULL) {
9196		EL(ha, "Invalid buffer index=%xh\n", index);
9197		QL_UB_UNLOCK(ha);
9198		return (rval);
9199	}
9200
9201	sp = ubp->ub_fca_private;
9202	if (sp->flags & SRB_UB_FREE_REQUESTED) {
9203		EL(ha, "buffer freed index=%xh\n", index);
9204		sp->flags &= ~(SRB_UB_IN_ISP | SRB_UB_CALLBACK |
9205		    SRB_UB_RSCN | SRB_UB_FCP | SRB_UB_ACQUIRED);
9206
9207		sp->flags |= SRB_UB_IN_FCA;
9208
9209		QL_UB_UNLOCK(ha);
9210		return (rval);
9211	}
9212
9213	if ((sp->handle == index) &&
9214	    (sp->flags & SRB_UB_IN_ISP) &&
9215	    (sp->ub_type == FC_TYPE_IS8802_SNAP) &&
9216	    (!(sp->flags & SRB_UB_ACQUIRED))) {
9217		/* set broadcast D_ID */
9218		loop_id = (uint16_t)(CFG_IST(ha, CFG_CTRL_2425) ?
9219		    BROADCAST_24XX_HDL : IP_BROADCAST_LOOP_ID);
9220		if (tq->ub_loop_id == loop_id) {
9221			if (ha->topology & QL_FL_PORT) {
9222				ubp->ub_frame.d_id = 0x000000;
9223			} else {
9224				ubp->ub_frame.d_id = 0xffffff;
9225			}
9226		} else {
9227			ubp->ub_frame.d_id = ha->d_id.b24;
9228		}
9229		ubp->ub_frame.r_ctl = R_CTL_UNSOL_DATA;
9230		ubp->ub_frame.rsvd = 0;
9231		ubp->ub_frame.s_id = tq->d_id.b24;
9232		ubp->ub_frame.type = FC_TYPE_IS8802_SNAP;
9233		ubp->ub_frame.seq_cnt = tq->ub_seq_cnt;
9234		ubp->ub_frame.df_ctl = 0;
9235		ubp->ub_frame.seq_id = tq->ub_seq_id;
9236		ubp->ub_frame.rx_id = 0xffff;
9237		ubp->ub_frame.ox_id = 0xffff;
9238		ubp->ub_bufsize = sp->ub_size < tq->ub_sequence_length ?
9239		    sp->ub_size : tq->ub_sequence_length;
9240		ubp->ub_frame.ro = tq->ub_frame_ro;
9241
9242		tq->ub_sequence_length = (uint16_t)
9243		    (tq->ub_sequence_length - ubp->ub_bufsize);
9244		tq->ub_frame_ro += ubp->ub_bufsize;
9245		tq->ub_seq_cnt++;
9246
9247		if (tq->ub_seq_cnt == tq->ub_total_seg_cnt) {
9248			if (tq->ub_seq_cnt == 1) {
9249				ubp->ub_frame.f_ctl = F_CTL_RO_PRESENT |
9250				    F_CTL_FIRST_SEQ | F_CTL_END_SEQ;
9251			} else {
9252				ubp->ub_frame.f_ctl = F_CTL_RO_PRESENT |
9253				    F_CTL_END_SEQ;
9254			}
9255			tq->ub_total_seg_cnt = 0;
9256		} else if (tq->ub_seq_cnt == 1) {
9257			ubp->ub_frame.f_ctl = F_CTL_RO_PRESENT |
9258			    F_CTL_FIRST_SEQ;
9259			ubp->ub_frame.df_ctl = 0x20;
9260		}
9261
9262		QL_PRINT_3(CE_CONT, "(%d): ub_frame.d_id=%xh\n",
9263		    ha->instance, ubp->ub_frame.d_id);
9264		QL_PRINT_3(CE_CONT, "(%d): ub_frame.s_id=%xh\n",
9265		    ha->instance, ubp->ub_frame.s_id);
9266		QL_PRINT_3(CE_CONT, "(%d): ub_frame.seq_cnt=%xh\n",
9267		    ha->instance, ubp->ub_frame.seq_cnt);
9268		QL_PRINT_3(CE_CONT, "(%d): ub_frame.seq_id=%xh\n",
9269		    ha->instance, ubp->ub_frame.seq_id);
9270		QL_PRINT_3(CE_CONT, "(%d): ub_frame.ro=%xh\n",
9271		    ha->instance, ubp->ub_frame.ro);
9272		QL_PRINT_3(CE_CONT, "(%d): ub_frame.f_ctl=%xh\n",
9273		    ha->instance, ubp->ub_frame.f_ctl);
9274		QL_PRINT_3(CE_CONT, "(%d): ub_bufsize=%xh\n",
9275		    ha->instance, ubp->ub_bufsize);
9276		QL_DUMP_3(ubp->ub_buffer, 8,
9277		    ubp->ub_bufsize < 64 ? ubp->ub_bufsize : 64);
9278
9279		sp->flags |= SRB_UB_CALLBACK | SRB_UB_ACQUIRED;
9280		ql_add_link_b(done_q, &sp->cmd);
9281		rval = QL_SUCCESS;
9282	} else {
9283		if (sp->handle != index) {
9284			EL(ha, "Bad index=%xh, expect=%xh\n", index,
9285			    sp->handle);
9286		}
9287		if ((sp->flags & SRB_UB_IN_ISP) == 0) {
9288			EL(ha, "buffer was already in driver, index=%xh\n",
9289			    index);
9290		}
9291		if ((sp->ub_type == FC_TYPE_IS8802_SNAP) == 0) {
9292			EL(ha, "buffer was not an IP buffer, index=%xh\n",
9293			    index);
9294		}
9295		if (sp->flags & SRB_UB_ACQUIRED) {
9296			EL(ha, "buffer was being used by driver, index=%xh\n",
9297			    index);
9298		}
9299	}
9300	QL_UB_UNLOCK(ha);
9301
9302	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9303
9304	return (rval);
9305}
9306
9307/*
9308 * ql_timer
9309 *	One second timer function.
9310 *
9311 * Input:
9312 *	ql_hba.first = first link in adapter list.
9313 *
9314 * Context:
9315 *	Interrupt context, no mailbox commands allowed.
9316 */
9317static void
9318ql_timer(void *arg)
9319{
9320	ql_link_t		*link;
9321	uint32_t		set_flags;
9322	uint32_t		reset_flags;
9323	ql_adapter_state_t	*ha = NULL, *vha;
9324
9325	QL_PRINT_6(CE_CONT, "started\n");
9326
9327	/* Acquire global state lock. */
9328	GLOBAL_STATE_LOCK();
9329	if (ql_timer_timeout_id == NULL) {
9330		/* Release global state lock. */
9331		GLOBAL_STATE_UNLOCK();
9332		return;
9333	}
9334
9335	for (link = ql_hba.first; link != NULL; link = link->next) {
9336		ha = link->base_address;
9337
9338		/* Skip adapter if suspended of stalled. */
9339		ADAPTER_STATE_LOCK(ha);
9340		if (ha->flags & ADAPTER_SUSPENDED ||
9341		    ha->task_daemon_flags & DRIVER_STALL) {
9342			ADAPTER_STATE_UNLOCK(ha);
9343			continue;
9344		}
9345		ha->flags |= ADAPTER_TIMER_BUSY;
9346		ADAPTER_STATE_UNLOCK(ha);
9347
9348		QL_PM_LOCK(ha);
9349		if (ha->power_level != PM_LEVEL_D0) {
9350			QL_PM_UNLOCK(ha);
9351
9352			ADAPTER_STATE_LOCK(ha);
9353			ha->flags &= ~ADAPTER_TIMER_BUSY;
9354			ADAPTER_STATE_UNLOCK(ha);
9355			continue;
9356		}
9357		ha->busy++;
9358		QL_PM_UNLOCK(ha);
9359
9360		set_flags = 0;
9361		reset_flags = 0;
9362
9363		/* Port retry timer handler. */
9364		if (LOOP_READY(ha)) {
9365			ADAPTER_STATE_LOCK(ha);
9366			if (ha->port_retry_timer != 0) {
9367				ha->port_retry_timer--;
9368				if (ha->port_retry_timer == 0) {
9369					set_flags |= PORT_RETRY_NEEDED;
9370				}
9371			}
9372			ADAPTER_STATE_UNLOCK(ha);
9373		}
9374
9375		/* Loop down timer handler. */
9376		if (LOOP_RECONFIGURE(ha) == 0) {
9377			if (ha->loop_down_timer > LOOP_DOWN_TIMER_END) {
9378				ha->loop_down_timer--;
9379				/*
9380				 * give the firmware loop down dump flag
9381				 * a chance to work.
9382				 */
9383				if (ha->loop_down_timer == LOOP_DOWN_RESET) {
9384					if (CFG_IST(ha,
9385					    CFG_DUMP_LOOP_OFFLINE_TIMEOUT)) {
9386						(void) ql_binary_fw_dump(ha,
9387						    TRUE);
9388					}
9389					EL(ha, "loop_down_reset, "
9390					    "isp_abort_needed\n");
9391					set_flags |= ISP_ABORT_NEEDED;
9392				}
9393			}
9394			if (CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING)) {
9395				/* Command abort time handler. */
9396				if (ha->loop_down_timer ==
9397				    ha->loop_down_abort_time) {
9398					ADAPTER_STATE_LOCK(ha);
9399					ha->flags |= ABORT_CMDS_LOOP_DOWN_TMO;
9400					ADAPTER_STATE_UNLOCK(ha);
9401					set_flags |= ABORT_QUEUES_NEEDED;
9402					EL(ha, "loop_down_abort_time, "
9403					    "abort_queues_needed\n");
9404				}
9405
9406				/* Watchdog timer handler. */
9407				if (ha->watchdog_timer == 0) {
9408					ha->watchdog_timer = WATCHDOG_TIME;
9409				} else if (LOOP_READY(ha)) {
9410					ha->watchdog_timer--;
9411					if (ha->watchdog_timer == 0) {
9412						for (vha = ha; vha != NULL;
9413						    vha = vha->vp_next) {
9414							ql_watchdog(vha,
9415							    &set_flags,
9416							    &reset_flags);
9417						}
9418						ha->watchdog_timer =
9419						    WATCHDOG_TIME;
9420					}
9421				}
9422			}
9423		}
9424
9425		/* Idle timer handler. */
9426		if (!DRIVER_SUSPENDED(ha)) {
9427			if (++ha->idle_timer >= IDLE_CHECK_TIMER) {
9428#if defined(QL_DEBUG_LEVEL_6) || !defined(QL_DEBUG_LEVEL_3)
9429				set_flags |= TASK_DAEMON_IDLE_CHK_FLG;
9430#endif
9431				ha->idle_timer = 0;
9432			}
9433		}
9434		if (set_flags != 0 || reset_flags != 0) {
9435			ql_awaken_task_daemon(ha, NULL, set_flags,
9436			    reset_flags);
9437		}
9438
9439		if (ha->xioctl->ledstate.BeaconState == BEACON_ON) {
9440			ql_blink_led(ha);
9441		}
9442
9443		/* Update the IO stats */
9444		if (ha->xioctl->IOInputByteCnt >= 0x100000) {
9445			ha->xioctl->IOInputMByteCnt +=
9446			    (ha->xioctl->IOInputByteCnt / 0x100000);
9447			ha->xioctl->IOInputByteCnt %= 0x100000;
9448		}
9449
9450		if (ha->xioctl->IOOutputByteCnt >= 0x100000) {
9451			ha->xioctl->IOOutputMByteCnt +=
9452			    (ha->xioctl->IOOutputByteCnt / 0x100000);
9453			ha->xioctl->IOOutputByteCnt %= 0x100000;
9454		}
9455
9456		ADAPTER_STATE_LOCK(ha);
9457		ha->flags &= ~ADAPTER_TIMER_BUSY;
9458		ADAPTER_STATE_UNLOCK(ha);
9459
9460		QL_PM_LOCK(ha);
9461		ha->busy--;
9462		QL_PM_UNLOCK(ha);
9463	}
9464
9465	/* Restart timer, if not being stopped. */
9466	if (ql_timer_timeout_id != NULL) {
9467		ql_timer_timeout_id = timeout(ql_timer, arg, ql_timer_ticks);
9468	}
9469
9470	/* Release global state lock. */
9471	GLOBAL_STATE_UNLOCK();
9472
9473	QL_PRINT_6(CE_CONT, "done\n");
9474}
9475
9476/*
9477 * ql_timeout_insert
9478 *	Function used to insert a command block onto the
9479 *	watchdog timer queue.
9480 *
9481 *	Note: Must insure that pkt_time is not zero
9482 *			before calling ql_timeout_insert.
9483 *
9484 * Input:
9485 *	ha:	adapter state pointer.
9486 *	tq:	target queue pointer.
9487 *	sp:	SRB pointer.
9488 *	DEVICE_QUEUE_LOCK must be already obtained.
9489 *
9490 * Context:
9491 *	Kernel context.
9492 */
9493/* ARGSUSED */
9494static void
9495ql_timeout_insert(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_srb_t *sp)
9496{
9497	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9498
9499	if (sp->pkt->pkt_timeout != 0 && sp->pkt->pkt_timeout < 0x10000) {
9500		/* Make sure timeout >= 2 * R_A_TOV */
9501		sp->isp_timeout = (uint16_t)
9502		    (sp->pkt->pkt_timeout < ha->r_a_tov ? ha->r_a_tov :
9503		    sp->pkt->pkt_timeout);
9504
9505		/*
9506		 * The WATCHDOG_TIME must be rounded up + 1.  As an example,
9507		 * consider a 1 second timeout. If the WATCHDOG_TIME is 1, it
9508		 * will expire in the next watchdog call, which could be in
9509		 * 1 microsecond.
9510		 *
9511		 * Add 6 more to insure watchdog does not timeout at the same
9512		 * time as ISP RISC code timeout.
9513		 */
9514		sp->wdg_q_time = (sp->isp_timeout + WATCHDOG_TIME - 1) /
9515		    WATCHDOG_TIME;
9516		sp->wdg_q_time += 6;
9517
9518		/* Save initial time for resetting watchdog time. */
9519		sp->init_wdg_q_time = sp->wdg_q_time;
9520
9521		/* Insert command onto watchdog queue. */
9522		ql_add_link_b(&tq->wdg, &sp->wdg);
9523
9524		sp->flags |= SRB_WATCHDOG_ENABLED;
9525	} else {
9526		sp->isp_timeout = 0;
9527		sp->wdg_q_time = 0;
9528		sp->init_wdg_q_time = 0;
9529	}
9530
9531	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9532}
9533
9534/*
9535 * ql_watchdog
9536 *	Timeout handler that runs in interrupt context. The
9537 *	ql_adapter_state_t * argument is the parameter set up when the
9538 *	timeout was initialized (state structure pointer).
9539 *	Function used to update timeout values and if timeout
9540 *	has occurred command will be aborted.
9541 *
9542 * Input:
9543 *	ha:		adapter state pointer.
9544 *	set_flags:	task daemon flags to set.
9545 *	reset_flags:	task daemon flags to reset.
9546 *
9547 * Context:
9548 *	Interrupt context, no mailbox commands allowed.
9549 */
9550static void
9551ql_watchdog(ql_adapter_state_t *ha, uint32_t *set_flags, uint32_t *reset_flags)
9552{
9553	ql_srb_t	*sp;
9554	ql_link_t	*link;
9555	ql_link_t	*next_cmd;
9556	ql_link_t	*next_device;
9557	ql_tgt_t	*tq;
9558	ql_lun_t	*lq;
9559	uint16_t	index;
9560	int		q_sane;
9561
9562	QL_PRINT_6(CE_CONT, "(%d): started\n", ha->instance);
9563
9564	/* Loop through all targets. */
9565	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
9566		for (link = ha->dev[index].first; link != NULL;
9567		    link = next_device) {
9568			tq = link->base_address;
9569
9570			/* Try to acquire device queue lock. */
9571			if (TRY_DEVICE_QUEUE_LOCK(tq) == 0) {
9572				next_device = NULL;
9573				continue;
9574			}
9575
9576			next_device = link->next;
9577
9578			if (!(CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING)) &&
9579			    (tq->port_down_retry_count == 0)) {
9580				/* Release device queue lock. */
9581				DEVICE_QUEUE_UNLOCK(tq);
9582				continue;
9583			}
9584
9585			/* Find out if this device is in a sane state. */
9586			if (tq->flags & (TQF_RSCN_RCVD |
9587			    TQF_NEED_AUTHENTICATION | TQF_QUEUE_SUSPENDED)) {
9588				q_sane = 0;
9589			} else {
9590				q_sane = 1;
9591			}
9592			/* Loop through commands on watchdog queue. */
9593			for (link = tq->wdg.first; link != NULL;
9594			    link = next_cmd) {
9595				next_cmd = link->next;
9596				sp = link->base_address;
9597				lq = sp->lun_queue;
9598
9599				/*
9600				 * For SCSI commands, if everything seems to
9601				 * be going fine and this packet is stuck
9602				 * because of throttling at LUN or target
9603				 * level then do not decrement the
9604				 * sp->wdg_q_time
9605				 */
9606				if (ha->task_daemon_flags & STATE_ONLINE &&
9607				    (sp->flags & SRB_ISP_STARTED) == 0 &&
9608				    q_sane && sp->flags & SRB_FCP_CMD_PKT &&
9609				    lq->lun_outcnt >= ha->execution_throttle) {
9610					continue;
9611				}
9612
9613				if (sp->wdg_q_time != 0) {
9614					sp->wdg_q_time--;
9615
9616					/* Timeout? */
9617					if (sp->wdg_q_time != 0) {
9618						continue;
9619					}
9620
9621					ql_remove_link(&tq->wdg, &sp->wdg);
9622					sp->flags &= ~SRB_WATCHDOG_ENABLED;
9623
9624					if (sp->flags & SRB_ISP_STARTED) {
9625						ql_cmd_timeout(ha, tq, sp,
9626						    set_flags, reset_flags);
9627
9628						DEVICE_QUEUE_UNLOCK(tq);
9629						tq = NULL;
9630						next_cmd = NULL;
9631						next_device = NULL;
9632						index = DEVICE_HEAD_LIST_SIZE;
9633					} else {
9634						ql_cmd_timeout(ha, tq, sp,
9635						    set_flags, reset_flags);
9636					}
9637				}
9638			}
9639
9640			/* Release device queue lock. */
9641			if (tq != NULL) {
9642				DEVICE_QUEUE_UNLOCK(tq);
9643			}
9644		}
9645	}
9646
9647	QL_PRINT_6(CE_CONT, "(%d): done\n", ha->instance);
9648}
9649
9650/*
9651 * ql_cmd_timeout
9652 *	Command timeout handler.
9653 *
9654 * Input:
9655 *	ha:		adapter state pointer.
9656 *	tq:		target queue pointer.
9657 *	sp:		SRB pointer.
9658 *	set_flags:	task daemon flags to set.
9659 *	reset_flags:	task daemon flags to reset.
9660 *
9661 * Context:
9662 *	Interrupt context, no mailbox commands allowed.
9663 */
9664/* ARGSUSED */
9665static void
9666ql_cmd_timeout(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_srb_t *sp,
9667    uint32_t *set_flags, uint32_t *reset_flags)
9668{
9669
9670	if (!(sp->flags & SRB_ISP_STARTED)) {
9671
9672		EL(ha, "command timed out in driver = %ph\n", (void *)sp);
9673
9674		REQUEST_RING_LOCK(ha);
9675
9676		/* if it's on a queue */
9677		if (sp->cmd.head) {
9678			/*
9679			 * The pending_cmds que needs to be
9680			 * protected by the ring lock
9681			 */
9682			ql_remove_link(sp->cmd.head, &sp->cmd);
9683		}
9684		sp->flags &= ~SRB_IN_DEVICE_QUEUE;
9685
9686		/* Release device queue lock. */
9687		REQUEST_RING_UNLOCK(ha);
9688		DEVICE_QUEUE_UNLOCK(tq);
9689
9690		/* Set timeout status */
9691		sp->pkt->pkt_reason = CS_TIMEOUT;
9692
9693		/* Ensure no retry */
9694		sp->flags &= ~SRB_RETRY;
9695
9696		/* Call done routine to handle completion. */
9697		ql_done(&sp->cmd);
9698
9699		DEVICE_QUEUE_LOCK(tq);
9700	} else {
9701		EL(ha, "command timed out in isp=%ph, osc=%ph, index=%xh, "
9702		    "isp_abort_needed\n", (void *)sp,
9703		    (void *)ha->outstanding_cmds[sp->handle & OSC_INDEX_MASK],
9704		    sp->handle & OSC_INDEX_MASK);
9705
9706		/* Release device queue lock. */
9707		DEVICE_QUEUE_UNLOCK(tq);
9708
9709		INTR_LOCK(ha);
9710		ha->pha->xioctl->ControllerErrorCount++;
9711		INTR_UNLOCK(ha);
9712
9713		/* Set ISP needs to be reset */
9714		sp->flags |= SRB_COMMAND_TIMEOUT;
9715
9716		if (CFG_IST(ha, CFG_DUMP_DRIVER_COMMAND_TIMEOUT)) {
9717			(void) ql_binary_fw_dump(ha, TRUE);
9718		}
9719
9720		*set_flags |= ISP_ABORT_NEEDED;
9721
9722		DEVICE_QUEUE_LOCK(tq);
9723	}
9724}
9725
9726/*
9727 * ql_rst_aen
9728 *	Processes asynchronous reset.
9729 *
9730 * Input:
9731 *	ha = adapter state pointer.
9732 *
9733 * Context:
9734 *	Kernel context.
9735 */
9736static void
9737ql_rst_aen(ql_adapter_state_t *ha)
9738{
9739	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9740
9741	/* Issue marker command. */
9742	(void) ql_marker(ha, 0, 0, MK_SYNC_ALL);
9743
9744	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9745}
9746
9747/*
9748 * ql_cmd_wait
9749 *	Stall driver until all outstanding commands are returned.
9750 *
9751 * Input:
9752 *	ha = adapter state pointer.
9753 *
9754 * Context:
9755 *	Kernel context.
9756 */
9757void
9758ql_cmd_wait(ql_adapter_state_t *ha)
9759{
9760	uint16_t		index;
9761	ql_link_t		*link;
9762	ql_tgt_t		*tq;
9763	ql_adapter_state_t	*vha;
9764
9765	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9766
9767	/* Wait for all outstanding commands to be returned. */
9768	(void) ql_wait_outstanding(ha);
9769
9770	/*
9771	 * clear out internally queued commands
9772	 */
9773	for (vha = ha; vha != NULL; vha = vha->vp_next) {
9774		for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
9775			for (link = vha->dev[index].first; link != NULL;
9776			    link = link->next) {
9777				tq = link->base_address;
9778				if (tq &&
9779				    (!(tq->prli_svc_param_word_3 &
9780				    PRLI_W3_RETRY))) {
9781					(void) ql_abort_device(vha, tq, 0);
9782				}
9783			}
9784		}
9785	}
9786
9787	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9788}
9789
9790/*
9791 * ql_wait_outstanding
9792 *	Wait for all outstanding commands to complete.
9793 *
9794 * Input:
9795 *	ha = adapter state pointer.
9796 *
9797 * Returns:
9798 *	index - the index for ql_srb into outstanding_cmds.
9799 *
9800 * Context:
9801 *	Kernel context.
9802 */
9803static uint16_t
9804ql_wait_outstanding(ql_adapter_state_t *ha)
9805{
9806	ql_srb_t	*sp;
9807	uint16_t	index, count;
9808
9809	count = 3000;
9810	for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
9811		if (ha->pha->pending_cmds.first != NULL) {
9812			ql_start_iocb(ha, NULL);
9813			index = 1;
9814		}
9815		if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
9816		    (sp->flags & SRB_COMMAND_TIMEOUT) == 0) {
9817			if (count-- != 0) {
9818				ql_delay(ha, 10000);
9819				index = 0;
9820			} else {
9821				EL(ha, "failed, sp=%ph\n", (void *)sp);
9822				break;
9823			}
9824		}
9825	}
9826
9827	return (index);
9828}
9829
9830/*
9831 * ql_restart_queues
9832 *	Restart device queues.
9833 *
9834 * Input:
9835 *	ha = adapter state pointer.
9836 *	DEVICE_QUEUE_LOCK must be released.
9837 *
9838 * Context:
9839 *	Interrupt or Kernel context, no mailbox commands allowed.
9840 */
9841static void
9842ql_restart_queues(ql_adapter_state_t *ha)
9843{
9844	ql_link_t		*link, *link2;
9845	ql_tgt_t		*tq;
9846	ql_lun_t		*lq;
9847	uint16_t		index;
9848	ql_adapter_state_t	*vha;
9849
9850	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9851
9852	for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
9853		for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
9854			for (link = vha->dev[index].first; link != NULL;
9855			    link = link->next) {
9856				tq = link->base_address;
9857
9858				/* Acquire device queue lock. */
9859				DEVICE_QUEUE_LOCK(tq);
9860
9861				tq->flags &= ~TQF_QUEUE_SUSPENDED;
9862
9863				for (link2 = tq->lun_queues.first;
9864				    link2 != NULL; link2 = link2->next) {
9865					lq = link2->base_address;
9866
9867					if (lq->cmd.first != NULL) {
9868						ql_next(vha, lq);
9869						DEVICE_QUEUE_LOCK(tq);
9870					}
9871				}
9872
9873				/* Release device queue lock. */
9874				DEVICE_QUEUE_UNLOCK(tq);
9875			}
9876		}
9877	}
9878
9879	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9880}
9881
9882
9883/*
9884 * ql_iidma
9885 *	Setup iiDMA parameters to firmware
9886 *
9887 * Input:
9888 *	ha = adapter state pointer.
9889 *	DEVICE_QUEUE_LOCK must be released.
9890 *
9891 * Context:
9892 *	Interrupt or Kernel context, no mailbox commands allowed.
9893 */
9894static void
9895ql_iidma(ql_adapter_state_t *ha)
9896{
9897	ql_link_t	*link;
9898	ql_tgt_t	*tq;
9899	uint16_t	index;
9900	char		buf[256];
9901	uint32_t	data;
9902
9903	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9904
9905	if ((CFG_IST(ha, CFG_CTRL_2425)) == 0) {
9906		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9907		return;
9908	}
9909
9910	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
9911		for (link = ha->dev[index].first; link != NULL;
9912		    link = link->next) {
9913			tq = link->base_address;
9914
9915			/* Acquire device queue lock. */
9916			DEVICE_QUEUE_LOCK(tq);
9917
9918			if ((tq->flags & TQF_IIDMA_NEEDED) == 0) {
9919				DEVICE_QUEUE_UNLOCK(tq);
9920				continue;
9921			}
9922
9923			tq->flags &= ~TQF_IIDMA_NEEDED;
9924
9925			if ((tq->loop_id > LAST_N_PORT_HDL) ||
9926			    (tq->iidma_rate == IIDMA_RATE_NDEF)) {
9927				DEVICE_QUEUE_UNLOCK(tq);
9928				continue;
9929			}
9930
9931			/* Get the iiDMA persistent data */
9932			if (tq->iidma_rate == IIDMA_RATE_INIT) {
9933				(void) sprintf(buf,
9934				    "iidma-rate-%02x%02x%02x%02x%02x"
9935				    "%02x%02x%02x", tq->port_name[0],
9936				    tq->port_name[1], tq->port_name[2],
9937				    tq->port_name[3], tq->port_name[4],
9938				    tq->port_name[5], tq->port_name[6],
9939				    tq->port_name[7]);
9940
9941				if ((data = ql_get_prop(ha, buf)) ==
9942				    0xffffffff) {
9943					tq->iidma_rate = IIDMA_RATE_NDEF;
9944				} else {
9945					switch (data) {
9946					case IIDMA_RATE_1GB:
9947					case IIDMA_RATE_2GB:
9948					case IIDMA_RATE_4GB:
9949						tq->iidma_rate = data;
9950						break;
9951					case IIDMA_RATE_8GB:
9952						if (CFG_IST(ha,
9953						    CFG_CTRL_25XX)) {
9954							tq->iidma_rate = data;
9955						} else {
9956							tq->iidma_rate =
9957							    IIDMA_RATE_4GB;
9958						}
9959						break;
9960					default:
9961						EL(ha, "invalid data for "
9962						    "parameter: %s: %xh\n",
9963						    buf, data);
9964						tq->iidma_rate =
9965						    IIDMA_RATE_NDEF;
9966						break;
9967					}
9968				}
9969			}
9970
9971			/* Set the firmware's iiDMA rate */
9972			if (tq->iidma_rate <= IIDMA_RATE_MAX) {
9973				data = ql_iidma_rate(ha, tq->loop_id,
9974				    &tq->iidma_rate, EXT_IIDMA_MODE_SET);
9975				if (data != QL_SUCCESS) {
9976					EL(ha, "mbx failed: %xh\n", data);
9977				}
9978			}
9979
9980			/* Release device queue lock. */
9981			DEVICE_QUEUE_UNLOCK(tq);
9982		}
9983	}
9984
9985	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9986}
9987
9988/*
9989 * ql_abort_queues
9990 *	Abort all commands on device queues.
9991 *
9992 * Input:
9993 *	ha = adapter state pointer.
9994 *
9995 * Context:
9996 *	Interrupt or Kernel context, no mailbox commands allowed.
9997 */
9998static void
9999ql_abort_queues(ql_adapter_state_t *ha)
10000{
10001	ql_link_t		*link, *link1, *link2;
10002	ql_tgt_t		*tq;
10003	ql_lun_t		*lq;
10004	ql_srb_t		*sp;
10005	uint16_t		index;
10006	ql_adapter_state_t	*vha;
10007
10008	QL_PRINT_10(CE_CONT, "(%d): started\n", ha->instance);
10009
10010	/* Return all commands in outstanding command list. */
10011	INTR_LOCK(ha);
10012
10013	/* Place all commands in outstanding cmd list on device queue. */
10014	for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
10015		if (ha->pending_cmds.first != NULL) {
10016			INTR_UNLOCK(ha);
10017			ql_start_iocb(ha, NULL);
10018			/* Delay for system */
10019			ql_delay(ha, 10000);
10020			INTR_LOCK(ha);
10021			index = 1;
10022		}
10023		sp = ha->outstanding_cmds[index];
10024		if (sp != NULL) {
10025			ha->outstanding_cmds[index] = NULL;
10026			sp->handle = 0;
10027			sp->flags &= ~SRB_IN_TOKEN_ARRAY;
10028
10029			INTR_UNLOCK(ha);
10030
10031			/* Set ending status. */
10032			sp->pkt->pkt_reason = CS_PORT_UNAVAILABLE;
10033			sp->flags |= SRB_ISP_COMPLETED;
10034
10035			/* Call done routine to handle completions. */
10036			sp->cmd.next = NULL;
10037			ql_done(&sp->cmd);
10038
10039			INTR_LOCK(ha);
10040		}
10041	}
10042	INTR_UNLOCK(ha);
10043
10044	for (vha = ha; vha != NULL; vha = vha->vp_next) {
10045		QL_PRINT_10(CE_CONT, "(%d,%d): abort instance\n",
10046		    vha->instance, vha->vp_index);
10047		for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
10048			for (link = vha->dev[index].first; link != NULL;
10049			    link = link->next) {
10050				tq = link->base_address;
10051
10052				/*
10053				 * Set port unavailable status for
10054				 * all commands on device queue.
10055				 */
10056				DEVICE_QUEUE_LOCK(tq);
10057
10058				for (link1 = tq->lun_queues.first;
10059				    link1 != NULL; link1 = link1->next) {
10060					lq = link1->base_address;
10061
10062					link2 = lq->cmd.first;
10063					while (link2 != NULL) {
10064						sp = link2->base_address;
10065
10066						if (sp->flags & SRB_ABORT) {
10067							link2 = link2->next;
10068							continue;
10069						}
10070
10071						/* Rem srb from dev cmd q. */
10072						ql_remove_link(&lq->cmd,
10073						    &sp->cmd);
10074						sp->flags &=
10075						    ~SRB_IN_DEVICE_QUEUE;
10076
10077						/* Release device queue lock */
10078						DEVICE_QUEUE_UNLOCK(tq);
10079
10080						/* Set ending status. */
10081						sp->pkt->pkt_reason =
10082						    CS_PORT_UNAVAILABLE;
10083
10084						/*
10085						 * Call done routine to handle
10086						 * completions.
10087						 */
10088						ql_done(&sp->cmd);
10089
10090						/* Delay for system */
10091						ql_delay(ha, 10000);
10092
10093						/* Acquire device queue lock */
10094						DEVICE_QUEUE_LOCK(tq);
10095						link2 = lq->cmd.first;
10096					}
10097				}
10098				/* Release device queue lock. */
10099				DEVICE_QUEUE_UNLOCK(tq);
10100			}
10101		}
10102	}
10103
10104	QL_PRINT_10(CE_CONT, "(%d): done\n", ha->instance);
10105}
10106
10107/*
10108 * ql_loop_resync
10109 *	Resync with fibre channel devices.
10110 *
10111 * Input:
10112 *	ha = adapter state pointer.
10113 *	DEVICE_QUEUE_LOCK must be released.
10114 *
10115 * Returns:
10116 *	ql local function return status code.
10117 *
10118 * Context:
10119 *	Kernel context.
10120 */
10121static int
10122ql_loop_resync(ql_adapter_state_t *ha)
10123{
10124	int rval;
10125
10126	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10127
10128	if (ha->flags & IP_INITIALIZED) {
10129		(void) ql_shutdown_ip(ha);
10130	}
10131
10132	rval = ql_fw_ready(ha, 10);
10133
10134	TASK_DAEMON_LOCK(ha);
10135	ha->task_daemon_flags &= ~LOOP_RESYNC_ACTIVE;
10136	TASK_DAEMON_UNLOCK(ha);
10137
10138	/* Set loop online, if it really is. */
10139	if (rval == QL_SUCCESS) {
10140		ql_loop_online(ha);
10141		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10142	} else {
10143		EL(ha, "failed, rval = %xh\n", rval);
10144	}
10145
10146	return (rval);
10147}
10148
10149/*
10150 * ql_loop_online
10151 *	Set loop online status if it really is online.
10152 *
10153 * Input:
10154 *	ha = adapter state pointer.
10155 *	DEVICE_QUEUE_LOCK must be released.
10156 *
10157 * Context:
10158 *	Kernel context.
10159 */
10160void
10161ql_loop_online(ql_adapter_state_t *ha)
10162{
10163	ql_adapter_state_t	*vha;
10164
10165	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10166
10167	/* Inform the FC Transport that the hardware is online. */
10168	for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
10169		if (!(vha->task_daemon_flags &
10170		    (LOOP_RESYNC_NEEDED | LOOP_DOWN))) {
10171			/* Restart IP if it was shutdown. */
10172			if (vha->vp_index == 0 && vha->flags & IP_ENABLED &&
10173			    !(vha->flags & IP_INITIALIZED)) {
10174				(void) ql_initialize_ip(vha);
10175				ql_isp_rcvbuf(vha);
10176			}
10177
10178			if (FC_PORT_STATE_MASK(vha->state) != FC_STATE_LOOP &&
10179			    FC_PORT_STATE_MASK(vha->state) !=
10180			    FC_STATE_ONLINE) {
10181				vha->state = FC_PORT_SPEED_MASK(vha->state);
10182				if (vha->topology & QL_LOOP_CONNECTION) {
10183					vha->state |= FC_STATE_LOOP;
10184				} else {
10185					vha->state |= FC_STATE_ONLINE;
10186				}
10187				TASK_DAEMON_LOCK(ha);
10188				vha->task_daemon_flags |= FC_STATE_CHANGE;
10189				TASK_DAEMON_UNLOCK(ha);
10190			}
10191		}
10192	}
10193
10194	ql_awaken_task_daemon(ha, NULL, 0, 0);
10195
10196	/* Restart device queues that may have been stopped. */
10197	ql_restart_queues(ha);
10198
10199	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10200}
10201
10202/*
10203 * ql_fca_handle_to_state
10204 *	Verifies handle to be correct.
10205 *
10206 * Input:
10207 *	fca_handle = pointer to state structure.
10208 *
10209 * Returns:
10210 *	NULL = failure
10211 *
10212 * Context:
10213 *	Kernel context.
10214 */
10215static ql_adapter_state_t *
10216ql_fca_handle_to_state(opaque_t fca_handle)
10217{
10218#ifdef	QL_DEBUG_ROUTINES
10219	ql_link_t		*link;
10220	ql_adapter_state_t	*ha = NULL;
10221	ql_adapter_state_t	*vha = NULL;
10222
10223	for (link = ql_hba.first; link != NULL; link = link->next) {
10224		ha = link->base_address;
10225		for (vha = ha->vp_next; vha != NULL; vha = vha->vp_next) {
10226			if ((opaque_t)vha == fca_handle) {
10227				ha = vha;
10228				break;
10229			}
10230		}
10231		if ((opaque_t)ha == fca_handle) {
10232			break;
10233		} else {
10234			ha = NULL;
10235		}
10236	}
10237
10238	if (ha == NULL) {
10239		/*EMPTY*/
10240		QL_PRINT_2(CE_CONT, "failed\n");
10241	}
10242
10243	ASSERT(ha != NULL);
10244#endif /* QL_DEBUG_ROUTINES */
10245
10246	return ((ql_adapter_state_t *)fca_handle);
10247}
10248
10249/*
10250 * ql_d_id_to_queue
10251 *	Locate device queue that matches destination ID.
10252 *
10253 * Input:
10254 *	ha = adapter state pointer.
10255 *	d_id = destination ID
10256 *
10257 * Returns:
10258 *	NULL = failure
10259 *
10260 * Context:
10261 *	Interrupt or Kernel context, no mailbox commands allowed.
10262 */
10263ql_tgt_t *
10264ql_d_id_to_queue(ql_adapter_state_t *ha, port_id_t d_id)
10265{
10266	uint16_t	index;
10267	ql_tgt_t	*tq;
10268	ql_link_t	*link;
10269
10270	/* Get head queue index. */
10271	index = ql_alpa_to_index[d_id.b.al_pa];
10272
10273	for (link = ha->dev[index].first; link != NULL; link = link->next) {
10274		tq = link->base_address;
10275		if (tq->d_id.b24 == d_id.b24 &&
10276		    VALID_DEVICE_ID(ha, tq->loop_id)) {
10277			return (tq);
10278		}
10279	}
10280
10281	return (NULL);
10282}
10283
10284/*
10285 * ql_loop_id_to_queue
10286 *	Locate device queue that matches loop ID.
10287 *
10288 * Input:
10289 *	ha:		adapter state pointer.
10290 *	loop_id:	destination ID
10291 *
10292 * Returns:
10293 *	NULL = failure
10294 *
10295 * Context:
10296 *	Interrupt or Kernel context, no mailbox commands allowed.
10297 */
10298ql_tgt_t *
10299ql_loop_id_to_queue(ql_adapter_state_t *ha, uint16_t loop_id)
10300{
10301	uint16_t	index;
10302	ql_tgt_t	*tq;
10303	ql_link_t	*link;
10304
10305	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
10306		for (link = ha->dev[index].first; link != NULL;
10307		    link = link->next) {
10308			tq = link->base_address;
10309			if (tq->loop_id == loop_id) {
10310				return (tq);
10311			}
10312		}
10313	}
10314
10315	return (NULL);
10316}
10317
10318/*
10319 * ql_kstat_update
10320 *	Updates kernel statistics.
10321 *
10322 * Input:
10323 *	ksp - driver kernel statistics structure pointer.
10324 *	rw - function to perform
10325 *
10326 * Returns:
10327 *	0 or EACCES
10328 *
10329 * Context:
10330 *	Kernel context.
10331 */
10332/* ARGSUSED */
10333static int
10334ql_kstat_update(kstat_t *ksp, int rw)
10335{
10336	int			rval;
10337
10338	QL_PRINT_3(CE_CONT, "started\n");
10339
10340	if (rw == KSTAT_WRITE) {
10341		rval = EACCES;
10342	} else {
10343		rval = 0;
10344	}
10345
10346	if (rval != 0) {
10347		/*EMPTY*/
10348		QL_PRINT_2(CE_CONT, "failed, rval = %xh\n", rval);
10349	} else {
10350		/*EMPTY*/
10351		QL_PRINT_3(CE_CONT, "done\n");
10352	}
10353	return (rval);
10354}
10355
10356/*
10357 * ql_load_flash
10358 *	Loads flash.
10359 *
10360 * Input:
10361 *	ha:	adapter state pointer.
10362 *	dp:	data pointer.
10363 *	size:	data length.
10364 *
10365 * Returns:
10366 *	ql local function return status code.
10367 *
10368 * Context:
10369 *	Kernel context.
10370 */
10371int
10372ql_load_flash(ql_adapter_state_t *ha, uint8_t *dp, uint32_t size)
10373{
10374	uint32_t	cnt;
10375	int		rval;
10376	uint32_t	size_to_offset;
10377	uint32_t	size_to_compare;
10378	int		erase_all;
10379
10380	if (CFG_IST(ha, CFG_CTRL_2425)) {
10381		return (ql_24xx_load_flash(ha, dp, size, 0));
10382	}
10383
10384	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10385
10386	size_to_compare = 0x20000;
10387	size_to_offset = 0;
10388	erase_all = 0;
10389	if (CFG_IST(ha, CFG_SBUS_CARD)) {
10390		if (size == 0x80000) {
10391			/* Request to flash the entire chip. */
10392			size_to_compare = 0x80000;
10393			erase_all = 1;
10394		} else {
10395			size_to_compare = 0x40000;
10396			if (ql_flash_sbus_fpga) {
10397				size_to_offset = 0x40000;
10398			}
10399		}
10400	}
10401	if (size > size_to_compare) {
10402		rval = QL_FUNCTION_PARAMETER_ERROR;
10403		EL(ha, "failed=%xh\n", rval);
10404		return (rval);
10405	}
10406
10407	GLOBAL_HW_LOCK();
10408
10409	/* Enable Flash Read/Write. */
10410	ql_flash_enable(ha);
10411
10412	/* Erase flash prior to write. */
10413	rval = ql_erase_flash(ha, erase_all);
10414
10415	if (rval == QL_SUCCESS) {
10416		/* Write data to flash. */
10417		for (cnt = 0; cnt < size; cnt++) {
10418			/* Allow other system activity. */
10419			if (cnt % 0x1000 == 0) {
10420				ql_delay(ha, 10000);
10421			}
10422			rval = ql_program_flash_address(ha,
10423			    cnt + size_to_offset, *dp++);
10424			if (rval != QL_SUCCESS) {
10425				break;
10426			}
10427		}
10428	}
10429
10430	ql_flash_disable(ha);
10431
10432	GLOBAL_HW_UNLOCK();
10433
10434	if (rval != QL_SUCCESS) {
10435		EL(ha, "failed=%xh\n", rval);
10436	} else {
10437		/*EMPTY*/
10438		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10439	}
10440	return (rval);
10441}
10442
10443/*
10444 * ql_program_flash_address
10445 *	Program flash address.
10446 *
10447 * Input:
10448 *	ha = adapter state pointer.
10449 *	addr = flash byte address.
10450 *	data = data to be written to flash.
10451 *
10452 * Returns:
10453 *	ql local function return status code.
10454 *
10455 * Context:
10456 *	Kernel context.
10457 */
10458static int
10459ql_program_flash_address(ql_adapter_state_t *ha, uint32_t addr, uint8_t data)
10460{
10461	int rval;
10462
10463	if (CFG_IST(ha, CFG_SBUS_CARD)) {
10464		ql_write_flash_byte(ha, 0x5555, 0xa0);
10465		ql_write_flash_byte(ha, addr, data);
10466	} else {
10467		/* Write Program Command Sequence */
10468		ql_write_flash_byte(ha, 0x5555, 0xaa);
10469		ql_write_flash_byte(ha, 0x2aaa, 0x55);
10470		ql_write_flash_byte(ha, 0x5555, 0xa0);
10471		ql_write_flash_byte(ha, addr, data);
10472	}
10473
10474	/* Wait for write to complete. */
10475	rval = ql_poll_flash(ha, addr, data);
10476
10477	if (rval != QL_SUCCESS) {
10478		EL(ha, "failed=%xh\n", rval);
10479	}
10480	return (rval);
10481}
10482
10483/*
10484 * ql_erase_flash
10485 *	Erases entire flash.
10486 *
10487 * Input:
10488 *	ha = adapter state pointer.
10489 *
10490 * Returns:
10491 *	ql local function return status code.
10492 *
10493 * Context:
10494 *	Kernel context.
10495 */
10496int
10497ql_erase_flash(ql_adapter_state_t *ha, int erase_all)
10498{
10499	int		rval;
10500	uint32_t	erase_delay = 2000000;
10501	uint32_t	sStartAddr;
10502	uint32_t	ssize;
10503	uint32_t	cnt;
10504	uint8_t		*bfp;
10505	uint8_t		*tmp;
10506
10507	if ((CFG_IST(ha, CFG_SBUS_CARD)) && !erase_all) {
10508
10509		if (ql_flash_sbus_fpga == 1) {
10510			ssize = QL_SBUS_FCODE_SIZE;
10511			sStartAddr = QL_FCODE_OFFSET;
10512		} else {
10513			ssize = QL_FPGA_SIZE;
10514			sStartAddr = QL_FPGA_OFFSET;
10515		}
10516
10517		erase_delay = 20000000;
10518
10519		bfp = (uint8_t *)kmem_zalloc(ssize, KM_SLEEP);
10520
10521		/* Save the section of flash we're not updating to buffer */
10522		tmp = bfp;
10523		for (cnt = sStartAddr; cnt < ssize+sStartAddr; cnt++) {
10524			/* Allow other system activity. */
10525			if (cnt % 0x1000 == 0) {
10526				ql_delay(ha, 10000);
10527			}
10528			*tmp++ = (uint8_t)ql_read_flash_byte(ha, cnt);
10529		}
10530	}
10531
10532	/* Chip Erase Command Sequence */
10533	ql_write_flash_byte(ha, 0x5555, 0xaa);
10534	ql_write_flash_byte(ha, 0x2aaa, 0x55);
10535	ql_write_flash_byte(ha, 0x5555, 0x80);
10536	ql_write_flash_byte(ha, 0x5555, 0xaa);
10537	ql_write_flash_byte(ha, 0x2aaa, 0x55);
10538	ql_write_flash_byte(ha, 0x5555, 0x10);
10539
10540	ql_delay(ha, erase_delay);
10541
10542	/* Wait for erase to complete. */
10543	rval = ql_poll_flash(ha, 0, 0x80);
10544
10545	if (rval != QL_SUCCESS) {
10546		EL(ha, "failed=%xh\n", rval);
10547		if (CFG_IST(ha, CFG_SBUS_CARD)) {
10548			kmem_free(bfp, ssize);
10549		}
10550		return (rval);
10551	}
10552
10553	/* restore the section we saved in the buffer */
10554	if ((CFG_IST(ha, CFG_SBUS_CARD)) && !erase_all) {
10555		/* Restore the section we saved off */
10556		tmp = bfp;
10557		for (cnt = sStartAddr; cnt < ssize+sStartAddr; cnt++) {
10558			/* Allow other system activity. */
10559			if (cnt % 0x1000 == 0) {
10560				ql_delay(ha, 10000);
10561			}
10562			rval = ql_program_flash_address(ha, cnt, *tmp++);
10563			if (rval != QL_SUCCESS) {
10564				break;
10565			}
10566		}
10567
10568		kmem_free(bfp, ssize);
10569	}
10570
10571	if (rval != QL_SUCCESS) {
10572		EL(ha, "failed=%xh\n", rval);
10573	}
10574	return (rval);
10575}
10576
10577/*
10578 * ql_poll_flash
10579 *	Polls flash for completion.
10580 *
10581 * Input:
10582 *	ha = adapter state pointer.
10583 *	addr = flash byte address.
10584 *	data = data to be polled.
10585 *
10586 * Returns:
10587 *	ql local function return status code.
10588 *
10589 * Context:
10590 *	Kernel context.
10591 */
10592int
10593ql_poll_flash(ql_adapter_state_t *ha, uint32_t addr, uint8_t poll_data)
10594{
10595	uint8_t		flash_data;
10596	uint32_t	cnt;
10597	int		rval = QL_FUNCTION_FAILED;
10598
10599	poll_data = (uint8_t)(poll_data & BIT_7);
10600
10601	/* Wait for 30 seconds for command to finish. */
10602	for (cnt = 30000000; cnt; cnt--) {
10603		flash_data = (uint8_t)ql_read_flash_byte(ha, addr);
10604
10605		if ((flash_data & BIT_7) == poll_data) {
10606			rval = QL_SUCCESS;
10607			break;
10608		}
10609		if (flash_data & BIT_5 && cnt > 2) {
10610			cnt = 2;
10611		}
10612		drv_usecwait(1);
10613	}
10614
10615	if (rval != QL_SUCCESS) {
10616		EL(ha, "failed=%xh\n", rval);
10617	}
10618	return (rval);
10619}
10620
10621/*
10622 * ql_flash_enable
10623 *	Setup flash for reading/writing.
10624 *
10625 * Input:
10626 *	ha = adapter state pointer.
10627 *
10628 * Context:
10629 *	Kernel context.
10630 */
10631void
10632ql_flash_enable(ql_adapter_state_t *ha)
10633{
10634	uint16_t	data;
10635
10636	/* Enable Flash Read/Write. */
10637	if (CFG_IST(ha, CFG_SBUS_CARD)) {
10638		data = (uint16_t)ddi_get16(ha->sbus_fpga_dev_handle,
10639		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF));
10640		data = (uint16_t)(data | SBUS_FLASH_WRITE_ENABLE);
10641		ddi_put16(ha->sbus_fpga_dev_handle,
10642		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF), data);
10643		/* Read reset command sequence */
10644		ql_write_flash_byte(ha, 0xaaa, 0xaa);
10645		ql_write_flash_byte(ha, 0x555, 0x55);
10646		ql_write_flash_byte(ha, 0xaaa, 0x20);
10647		ql_write_flash_byte(ha, 0x555, 0xf0);
10648	} else {
10649		data = (uint16_t)(RD16_IO_REG(ha, ctrl_status) |
10650		    ISP_FLASH_ENABLE);
10651		WRT16_IO_REG(ha, ctrl_status, data);
10652
10653		/* Read/Reset Command Sequence */
10654		ql_write_flash_byte(ha, 0x5555, 0xaa);
10655		ql_write_flash_byte(ha, 0x2aaa, 0x55);
10656		ql_write_flash_byte(ha, 0x5555, 0xf0);
10657	}
10658	(void) ql_read_flash_byte(ha, 0);
10659}
10660
10661/*
10662 * ql_flash_disable
10663 *	Disable flash and allow RISC to run.
10664 *
10665 * Input:
10666 *	ha = adapter state pointer.
10667 *
10668 * Context:
10669 *	Kernel context.
10670 */
10671void
10672ql_flash_disable(ql_adapter_state_t *ha)
10673{
10674	uint16_t	data;
10675
10676	if (CFG_IST(ha, CFG_SBUS_CARD)) {
10677		/*
10678		 * Lock the flash back up.
10679		 */
10680		ql_write_flash_byte(ha, 0x555, 0x90);
10681		ql_write_flash_byte(ha, 0x555, 0x0);
10682
10683		data = (uint16_t)ddi_get16(ha->sbus_fpga_dev_handle,
10684		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF));
10685		data = (uint16_t)(data & ~SBUS_FLASH_WRITE_ENABLE);
10686		ddi_put16(ha->sbus_fpga_dev_handle,
10687		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF), data);
10688	} else {
10689		data = (uint16_t)(RD16_IO_REG(ha, ctrl_status) &
10690		    ~ISP_FLASH_ENABLE);
10691		WRT16_IO_REG(ha, ctrl_status, data);
10692	}
10693}
10694
10695/*
10696 * ql_write_flash_byte
10697 *	Write byte to flash.
10698 *
10699 * Input:
10700 *	ha = adapter state pointer.
10701 *	addr = flash byte address.
10702 *	data = data to be written.
10703 *
10704 * Context:
10705 *	Kernel context.
10706 */
10707void
10708ql_write_flash_byte(ql_adapter_state_t *ha, uint32_t addr, uint8_t data)
10709{
10710	if (CFG_IST(ha, CFG_SBUS_CARD)) {
10711		ddi_put16(ha->sbus_fpga_dev_handle,
10712		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_LOADDR),
10713		    LSW(addr));
10714		ddi_put16(ha->sbus_fpga_dev_handle,
10715		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_HIADDR),
10716		    MSW(addr));
10717		ddi_put16(ha->sbus_fpga_dev_handle,
10718		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_DATA),
10719		    (uint16_t)data);
10720	} else {
10721		uint16_t bank_select;
10722
10723		/* Setup bit 16 of flash address. */
10724		bank_select = (uint16_t)RD16_IO_REG(ha, ctrl_status);
10725
10726		if (CFG_IST(ha, CFG_CTRL_6322)) {
10727			bank_select = (uint16_t)(bank_select & ~0xf0);
10728			bank_select = (uint16_t)(bank_select |
10729			    ((addr >> 12 & 0xf0) | ISP_FLASH_64K_BANK));
10730			WRT16_IO_REG(ha, ctrl_status, bank_select);
10731		} else {
10732			if (addr & BIT_16 && !(bank_select &
10733			    ISP_FLASH_64K_BANK)) {
10734				bank_select = (uint16_t)(bank_select |
10735				    ISP_FLASH_64K_BANK);
10736				WRT16_IO_REG(ha, ctrl_status, bank_select);
10737			} else if (!(addr & BIT_16) && bank_select &
10738			    ISP_FLASH_64K_BANK) {
10739				bank_select = (uint16_t)(bank_select &
10740				    ~ISP_FLASH_64K_BANK);
10741				WRT16_IO_REG(ha, ctrl_status, bank_select);
10742			}
10743		}
10744
10745		if (CFG_IST(ha, CFG_SBUS_CARD)) {
10746			WRT16_IO_REG(ha, flash_address, (uint16_t)addr);
10747			WRT16_IO_REG(ha, flash_data, (uint16_t)data);
10748		} else {
10749			WRT16_IOMAP_REG(ha, flash_address, addr);
10750			WRT16_IOMAP_REG(ha, flash_data, data);
10751		}
10752	}
10753}
10754
10755/*
10756 * ql_read_flash_byte
10757 *	Reads byte from flash, but must read a word from chip.
10758 *
10759 * Input:
10760 *	ha = adapter state pointer.
10761 *	addr = flash byte address.
10762 *
10763 * Returns:
10764 *	byte from flash.
10765 *
10766 * Context:
10767 *	Kernel context.
10768 */
10769uint8_t
10770ql_read_flash_byte(ql_adapter_state_t *ha, uint32_t addr)
10771{
10772	uint8_t	data;
10773
10774	if (CFG_IST(ha, CFG_SBUS_CARD)) {
10775		ddi_put16(ha->sbus_fpga_dev_handle,
10776		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_LOADDR),
10777		    LSW(addr));
10778		ddi_put16(ha->sbus_fpga_dev_handle,
10779		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_HIADDR),
10780		    MSW(addr));
10781		data = (uint8_t)ddi_get16(ha->sbus_fpga_dev_handle,
10782		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_DATA));
10783	} else {
10784		uint16_t	bank_select;
10785
10786		/* Setup bit 16 of flash address. */
10787		bank_select = RD16_IO_REG(ha, ctrl_status);
10788		if (CFG_IST(ha, CFG_CTRL_6322)) {
10789			bank_select = (uint16_t)(bank_select & ~0xf0);
10790			bank_select = (uint16_t)(bank_select |
10791			    ((addr >> 12 & 0xf0) | ISP_FLASH_64K_BANK));
10792			WRT16_IO_REG(ha, ctrl_status, bank_select);
10793		} else {
10794			if (addr & BIT_16 &&
10795			    !(bank_select & ISP_FLASH_64K_BANK)) {
10796				bank_select = (uint16_t)(bank_select |
10797				    ISP_FLASH_64K_BANK);
10798				WRT16_IO_REG(ha, ctrl_status, bank_select);
10799			} else if (!(addr & BIT_16) &&
10800			    bank_select & ISP_FLASH_64K_BANK) {
10801				bank_select = (uint16_t)(bank_select &
10802				    ~ISP_FLASH_64K_BANK);
10803				WRT16_IO_REG(ha, ctrl_status, bank_select);
10804			}
10805		}
10806
10807		if (CFG_IST(ha, CFG_SBUS_CARD)) {
10808			WRT16_IO_REG(ha, flash_address, addr);
10809			data = (uint8_t)RD16_IO_REG(ha, flash_data);
10810		} else {
10811			WRT16_IOMAP_REG(ha, flash_address, addr);
10812			data = (uint8_t)RD16_IOMAP_REG(ha, flash_data);
10813		}
10814	}
10815
10816	return (data);
10817}
10818
10819/*
10820 * ql_24xx_flash_id
10821 *	Get flash IDs.
10822 *
10823 * Input:
10824 *	ha:		adapter state pointer.
10825 *
10826 * Returns:
10827 *	ql local function return status code.
10828 *
10829 * Context:
10830 *	Kernel context.
10831 */
10832int
10833ql_24xx_flash_id(ql_adapter_state_t *vha)
10834{
10835	int			rval;
10836	uint32_t		fdata = 0;
10837	ql_adapter_state_t	*ha = vha->pha;
10838	ql_xioctl_t		*xp = ha->xioctl;
10839
10840
10841	rval = ql_24xx_read_flash(ha, FLASH_CONF_ADDR | 0x3AB, &fdata);
10842
10843	if (rval != QL_SUCCESS || fdata == 0 || CFG_IST(ha, CFG_CTRL_25XX)) {
10844		fdata = 0;
10845		rval = ql_24xx_read_flash(ha, FLASH_CONF_ADDR |
10846		    (CFG_IST(ha, CFG_CTRL_2422) ? 0x39F : 0x49F), &fdata);
10847	}
10848
10849	if (rval != QL_SUCCESS) {
10850		EL(ha, "24xx read_flash failed=%xh\n", rval);
10851	} else if (fdata != 0) {
10852		xp->fdesc.flash_manuf = LSB(LSW(fdata));
10853		xp->fdesc.flash_id = MSB(LSW(fdata));
10854		xp->fdesc.flash_len = LSB(MSW(fdata));
10855	} else {
10856		xp->fdesc.flash_manuf = ATMEL_FLASH;
10857		xp->fdesc.flash_id = ATMEL_FLASHID_1024K;
10858		xp->fdesc.flash_len = 0;
10859	}
10860
10861	return (rval);
10862}
10863
10864/*
10865 * ql_24xx_load_flash
10866 *	Loads flash.
10867 *
10868 * Input:
10869 *	ha = adapter state pointer.
10870 *	dp = data pointer.
10871 *	size = data length.
10872 *	faddr = 32bit word flash address.
10873 *
10874 * Returns:
10875 *	ql local function return status code.
10876 *
10877 * Context:
10878 *	Kernel context.
10879 */
10880int
10881ql_24xx_load_flash(ql_adapter_state_t *vha, uint8_t *dp, uint32_t size,
10882    uint32_t faddr)
10883{
10884	int			rval;
10885	uint32_t		cnt, rest_addr, fdata, wc;
10886	dma_mem_t		dmabuf = {0};
10887	ql_adapter_state_t	*ha = vha->pha;
10888	ql_xioctl_t		*xp = ha->xioctl;
10889
10890	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10891
10892	/* start address must be 32 bit word aligned */
10893	if ((faddr & 0x3) != 0) {
10894		EL(ha, "incorrect buffer size alignment\n");
10895		return (QL_FUNCTION_PARAMETER_ERROR);
10896	}
10897
10898	GLOBAL_HW_LOCK();
10899
10900	if ((rval = ql_setup_flash(ha)) != QL_SUCCESS) {
10901		EL(ha, "ql_setup_flash failed=%xh\n", rval);
10902	} else {
10903		/* Allocate DMA buffer */
10904		if (CFG_IST(ha, CFG_CTRL_25XX)) {
10905			if ((rval = ql_get_dma_mem(ha, &dmabuf, 0xffff,
10906			    LITTLE_ENDIAN_DMA,
10907			    QL_DMA_DATA_ALIGN)) != QL_SUCCESS) {
10908				EL(ha, "dma alloc failed, rval=%xh\n", rval);
10909				return (rval);
10910			}
10911		}
10912
10913		/* setup mask of address range within a sector */
10914		rest_addr = (xp->fdesc.block_size - 1) >> 2;
10915
10916		/* Enable flash write */
10917		ql_24xx_unprotect_flash(ha);
10918
10919		faddr = faddr >> 2;	/* flash gets 32 bit words */
10920
10921		/*
10922		 * Write data to flash.
10923		 */
10924		cnt = 0;
10925		size = (size + 3) >> 2;	/* Round up & convert to dwords */
10926
10927		while (cnt < size) {
10928			/* Beginning of a sector? */
10929			if ((faddr & rest_addr) == 0) {
10930				fdata = (faddr & ~rest_addr) << 2;
10931				fdata = (fdata & 0xff00) |
10932				    (fdata << 16 & 0xff0000) |
10933				    (fdata >> 16 & 0xff);
10934
10935				if (rest_addr == 0x1fff) {
10936					/* 32kb sector block erase */
10937					rval = ql_24xx_write_flash(ha,
10938					    FLASH_CONF_ADDR | 0x0352, fdata);
10939				} else {
10940					/* 64kb sector block erase */
10941					rval = ql_24xx_write_flash(ha,
10942					    FLASH_CONF_ADDR | 0x03d8, fdata);
10943				}
10944				if (rval != QL_SUCCESS) {
10945					EL(ha, "Unable to flash sector: "
10946					    "address=%xh\n", faddr);
10947					break;
10948				}
10949			}
10950
10951			/* Write data */
10952			if (CFG_IST(ha, CFG_CTRL_25XX) &&
10953			    ((faddr & 0x3f) == 0)) {
10954				/*
10955				 * Limit write up to sector boundary.
10956				 */
10957				wc = ((~faddr & (rest_addr>>1)) + 1);
10958
10959				if (size - cnt < wc) {
10960					wc = size - cnt;
10961				}
10962
10963				ddi_rep_put8(dmabuf.acc_handle, (uint8_t *)dp,
10964				    (uint8_t *)dmabuf.bp, wc<<2,
10965				    DDI_DEV_AUTOINCR);
10966
10967				rval = ql_wrt_risc_ram(ha, FLASH_DATA_ADDR |
10968				    faddr, dmabuf.cookie.dmac_laddress, wc);
10969				if (rval != QL_SUCCESS) {
10970					EL(ha, "unable to dma to flash "
10971					    "address=%xh\n", faddr << 2);
10972					break;
10973				}
10974
10975				cnt += wc;
10976				faddr += wc;
10977				dp += wc << 2;
10978			} else {
10979				fdata = *dp++;
10980				fdata |= *dp++ << 8;
10981				fdata |= *dp++ << 16;
10982				fdata |= *dp++ << 24;
10983				rval = ql_24xx_write_flash(ha,
10984				    FLASH_DATA_ADDR | faddr, fdata);
10985				if (rval != QL_SUCCESS) {
10986					EL(ha, "Unable to program flash "
10987					    "address=%xh data=%xh\n", faddr,
10988					    *dp);
10989					break;
10990				}
10991				cnt++;
10992				faddr++;
10993
10994				/* Allow other system activity. */
10995				if (cnt % 0x1000 == 0) {
10996					ql_delay(ha, 10000);
10997				}
10998			}
10999		}
11000
11001		ql_24xx_protect_flash(ha);
11002
11003		ql_free_phys(ha, &dmabuf);
11004	}
11005
11006	GLOBAL_HW_UNLOCK();
11007
11008	if (rval != QL_SUCCESS) {
11009		EL(ha, "failed=%xh\n", rval);
11010	} else {
11011		/*EMPTY*/
11012		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11013	}
11014	return (rval);
11015}
11016
11017/*
11018 * ql_24xx_read_flash
11019 *	Reads a 32bit word from ISP24xx NVRAM/FLASH.
11020 *
11021 * Input:
11022 *	ha:	adapter state pointer.
11023 *	faddr:	NVRAM/FLASH address.
11024 *	bp:	data pointer.
11025 *
11026 * Returns:
11027 *	ql local function return status code.
11028 *
11029 * Context:
11030 *	Kernel context.
11031 */
11032int
11033ql_24xx_read_flash(ql_adapter_state_t *vha, uint32_t faddr, uint32_t *bp)
11034{
11035	uint32_t		timer;
11036	int			rval = QL_SUCCESS;
11037	ql_adapter_state_t	*ha = vha->pha;
11038
11039	/* Clear access error flag */
11040	WRT32_IO_REG(ha, ctrl_status,
11041	    RD32_IO_REG(ha, ctrl_status) | FLASH_NVRAM_ACCESS_ERROR);
11042
11043	WRT32_IO_REG(ha, flash_address, faddr & ~FLASH_DATA_FLAG);
11044
11045	/* Wait for READ cycle to complete. */
11046	for (timer = 300000; timer; timer--) {
11047		if (RD32_IO_REG(ha, flash_address) & FLASH_DATA_FLAG) {
11048			break;
11049		}
11050		drv_usecwait(10);
11051	}
11052
11053	if (timer == 0) {
11054		EL(ha, "failed, timeout\n");
11055		rval = QL_FUNCTION_TIMEOUT;
11056	} else if (RD32_IO_REG(ha, ctrl_status) & FLASH_NVRAM_ACCESS_ERROR) {
11057		EL(ha, "failed, access error\n");
11058		rval = QL_FUNCTION_FAILED;
11059	}
11060
11061	*bp = RD32_IO_REG(ha, flash_data);
11062
11063	return (rval);
11064}
11065
11066/*
11067 * ql_24xx_write_flash
11068 *	Writes a 32bit word to ISP24xx NVRAM/FLASH.
11069 *
11070 * Input:
11071 *	ha:	adapter state pointer.
11072 *	addr:	NVRAM/FLASH address.
11073 *	value:	data.
11074 *
11075 * Returns:
11076 *	ql local function return status code.
11077 *
11078 * Context:
11079 *	Kernel context.
11080 */
11081int
11082ql_24xx_write_flash(ql_adapter_state_t *vha, uint32_t addr, uint32_t data)
11083{
11084	uint32_t		timer, fdata;
11085	int			rval = QL_SUCCESS;
11086	ql_adapter_state_t	*ha = vha->pha;
11087
11088	/* Clear access error flag */
11089	WRT32_IO_REG(ha, ctrl_status,
11090	    RD32_IO_REG(ha, ctrl_status) | FLASH_NVRAM_ACCESS_ERROR);
11091
11092	WRT32_IO_REG(ha, flash_data, data);
11093	RD32_IO_REG(ha, flash_data);		/* PCI Posting. */
11094	WRT32_IO_REG(ha, flash_address, addr | FLASH_DATA_FLAG);
11095
11096	/* Wait for Write cycle to complete. */
11097	for (timer = 3000000; timer; timer--) {
11098		if ((RD32_IO_REG(ha, flash_address) & FLASH_DATA_FLAG) == 0) {
11099			/* Check flash write in progress. */
11100			if ((addr & FLASH_ADDR_MASK) == FLASH_CONF_ADDR) {
11101				(void) ql_24xx_read_flash(ha,
11102				    FLASH_CONF_ADDR | 0x005, &fdata);
11103				if (!(fdata & BIT_0)) {
11104					break;
11105				}
11106			} else {
11107				break;
11108			}
11109		}
11110		drv_usecwait(10);
11111	}
11112	if (timer == 0) {
11113		EL(ha, "failed, timeout\n");
11114		rval = QL_FUNCTION_TIMEOUT;
11115	} else if (RD32_IO_REG(ha, ctrl_status) & FLASH_NVRAM_ACCESS_ERROR) {
11116		EL(ha, "access error\n");
11117		rval = QL_FUNCTION_FAILED;
11118	}
11119
11120	return (rval);
11121}
11122/*
11123 * ql_24xx_unprotect_flash
11124 *	Enable writes
11125 *
11126 * Input:
11127 *	ha:	adapter state pointer.
11128 *
11129 * Context:
11130 *	Kernel context.
11131 */
11132void
11133ql_24xx_unprotect_flash(ql_adapter_state_t *vha)
11134{
11135	uint32_t		fdata;
11136	ql_adapter_state_t	*ha = vha->pha;
11137	ql_xioctl_t		*xp = ha->xioctl;
11138
11139	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
11140
11141	/* Enable flash write. */
11142	WRT32_IO_REG(ha, ctrl_status,
11143	    RD32_IO_REG(ha, ctrl_status) | ISP_FLASH_ENABLE);
11144	RD32_IO_REG(ha, ctrl_status);	/* PCI Posting. */
11145
11146	/*
11147	 * Remove block write protection (SST and ST) and
11148	 * Sector/Block Protection Register Lock (SST, ST, ATMEL).
11149	 * Unprotect sectors.
11150	 */
11151	(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x100 |
11152	    xp->fdesc.write_statusreg_cmd, xp->fdesc.write_enable_bits);
11153
11154	if (xp->fdesc.unprotect_sector_cmd != 0) {
11155		for (fdata = 0; fdata < 0x10; fdata++) {
11156			(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR |
11157			    0x300 | xp->fdesc.unprotect_sector_cmd, fdata);
11158		}
11159
11160		(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 |
11161		    xp->fdesc.unprotect_sector_cmd, 0x00400f);
11162		(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 |
11163		    xp->fdesc.unprotect_sector_cmd, 0x00600f);
11164		(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 |
11165		    xp->fdesc.unprotect_sector_cmd, 0x00800f);
11166	}
11167
11168	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
11169}
11170
11171/*
11172 * ql_24xx_protect_flash
11173 *	Disable writes
11174 *
11175 * Input:
11176 *	ha:	adapter state pointer.
11177 *
11178 * Context:
11179 *	Kernel context.
11180 */
11181void
11182ql_24xx_protect_flash(ql_adapter_state_t *vha)
11183{
11184	uint32_t		fdata;
11185	ql_adapter_state_t	*ha = vha->pha;
11186	ql_xioctl_t		*xp = ha->xioctl;
11187
11188	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
11189
11190	/* Enable flash write. */
11191	WRT32_IO_REG(ha, ctrl_status,
11192	    RD32_IO_REG(ha, ctrl_status) | ISP_FLASH_ENABLE);
11193	RD32_IO_REG(ha, ctrl_status);	/* PCI Posting. */
11194
11195	/*
11196	 * Protect sectors.
11197	 * Set block write protection (SST and ST) and
11198	 * Sector/Block Protection Register Lock (SST, ST, ATMEL).
11199	 */
11200	if (xp->fdesc.protect_sector_cmd != 0) {
11201		for (fdata = 0; fdata < 0x10; fdata++) {
11202			(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR |
11203			    0x330 | xp->fdesc.protect_sector_cmd, fdata);
11204		}
11205		(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x330 |
11206		    xp->fdesc.protect_sector_cmd, 0x00400f);
11207		(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x330 |
11208		    xp->fdesc.protect_sector_cmd, 0x00600f);
11209		(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x330 |
11210		    xp->fdesc.protect_sector_cmd, 0x00800f);
11211
11212		/* TODO: ??? */
11213		(void) ql_24xx_write_flash(ha,
11214		    FLASH_CONF_ADDR | 0x101, 0x80);
11215	} else {
11216		(void) ql_24xx_write_flash(ha,
11217		    FLASH_CONF_ADDR | 0x101, 0x9c);
11218	}
11219
11220	/* Disable flash write. */
11221	WRT32_IO_REG(ha, ctrl_status,
11222	    RD32_IO_REG(ha, ctrl_status) & ~ISP_FLASH_ENABLE);
11223	RD32_IO_REG(ha, ctrl_status);	/* PCI Posting. */
11224
11225	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
11226}
11227
11228/*
11229 * ql_dump_firmware
11230 *	Save RISC code state information.
11231 *
11232 * Input:
11233 *	ha = adapter state pointer.
11234 *
11235 * Returns:
11236 *	QL local function return status code.
11237 *
11238 * Context:
11239 *	Kernel context.
11240 */
11241static int
11242ql_dump_firmware(ql_adapter_state_t *vha)
11243{
11244	int			rval;
11245	clock_t			timer;
11246	ql_adapter_state_t	*ha = vha->pha;
11247
11248	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11249
11250	QL_DUMP_LOCK(ha);
11251
11252	if (ha->ql_dump_state & QL_DUMPING ||
11253	    (ha->ql_dump_state & QL_DUMP_VALID &&
11254	    !(ha->ql_dump_state & QL_DUMP_UPLOADED))) {
11255		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11256		QL_DUMP_UNLOCK(ha);
11257		return (QL_SUCCESS);
11258	}
11259
11260	QL_DUMP_UNLOCK(ha);
11261
11262	ql_awaken_task_daemon(ha, NULL, DRIVER_STALL, 0);
11263
11264	/*
11265	 * Wait for all outstanding commands to complete
11266	 */
11267	(void) ql_wait_outstanding(ha);
11268
11269	/* Dump firmware. */
11270	rval = ql_binary_fw_dump(ha, TRUE);
11271
11272	/* Do abort to force restart. */
11273	ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED, DRIVER_STALL);
11274	EL(ha, "restarting, isp_abort_needed\n");
11275
11276	/* Acquire task daemon lock. */
11277	TASK_DAEMON_LOCK(ha);
11278
11279	/* Wait for suspension to end. */
11280	while (ha->task_daemon_flags & QL_SUSPENDED) {
11281		ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG;
11282
11283		/* 30 seconds from now */
11284		timer = ddi_get_lbolt();
11285		timer += drv_usectohz(30000000);
11286
11287		if (cv_timedwait(&ha->cv_dr_suspended,
11288		    &ha->task_daemon_mutex, timer) == -1) {
11289			/*
11290			 * The timeout time 'timer' was
11291			 * reached without the condition
11292			 * being signaled.
11293			 */
11294			break;
11295		}
11296	}
11297
11298	/* Release task daemon lock. */
11299	TASK_DAEMON_UNLOCK(ha);
11300
11301	if (rval == QL_SUCCESS || rval == QL_DATA_EXISTS) {
11302		/*EMPTY*/
11303		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11304	} else {
11305		EL(ha, "failed, rval = %xh\n", rval);
11306	}
11307	return (rval);
11308}
11309
11310/*
11311 * ql_binary_fw_dump
11312 *	Dumps binary data from firmware.
11313 *
11314 * Input:
11315 *	ha = adapter state pointer.
11316 *	lock_needed = mailbox lock needed.
11317 *
11318 * Returns:
11319 *	ql local function return status code.
11320 *
11321 * Context:
11322 *	Interrupt or Kernel context, no mailbox commands allowed.
11323 */
11324int
11325ql_binary_fw_dump(ql_adapter_state_t *vha, int lock_needed)
11326{
11327	clock_t			timer;
11328	mbx_cmd_t		mc;
11329	mbx_cmd_t		*mcp = &mc;
11330	int			rval = QL_SUCCESS;
11331	ql_adapter_state_t	*ha = vha->pha;
11332
11333	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11334
11335	QL_DUMP_LOCK(ha);
11336
11337	if (ha->ql_dump_state & QL_DUMPING ||
11338	    (ha->ql_dump_state & QL_DUMP_VALID &&
11339	    !(ha->ql_dump_state & QL_DUMP_UPLOADED))) {
11340		EL(ha, "dump already done, qds=%x\n", ha->ql_dump_state);
11341		QL_DUMP_UNLOCK(ha);
11342		return (QL_DATA_EXISTS);
11343	}
11344
11345	ha->ql_dump_state &= ~(QL_DUMP_VALID | QL_DUMP_UPLOADED);
11346	ha->ql_dump_state |= QL_DUMPING;
11347
11348	QL_DUMP_UNLOCK(ha);
11349
11350	if (ha->cfg_flags & CFG_ENABLE_FWEXTTRACE) {
11351
11352		/* Insert Time Stamp */
11353		rval = ql_fw_etrace(ha, &ha->fwexttracebuf,
11354		    FTO_INSERT_TIME_STAMP);
11355		if (rval != QL_SUCCESS) {
11356			EL(ha, "f/w extended trace insert"
11357			    "time stamp failed: %xh\n", rval);
11358		}
11359	}
11360
11361	if (lock_needed == TRUE) {
11362		/* Acquire mailbox register lock. */
11363		MBX_REGISTER_LOCK(ha);
11364
11365		/* Check for mailbox available, if not wait for signal. */
11366		while (ha->mailbox_flags & MBX_BUSY_FLG) {
11367			ha->mailbox_flags = (uint8_t)
11368			    (ha->mailbox_flags | MBX_WANT_FLG);
11369
11370			/* 30 seconds from now */
11371			timer = ddi_get_lbolt();
11372			timer += (ha->mcp->timeout + 2) *
11373			    drv_usectohz(1000000);
11374			if (cv_timedwait(&ha->cv_mbx_wait, &ha->mbx_mutex,
11375			    timer) == -1) {
11376				/*
11377				 * The timeout time 'timer' was
11378				 * reached without the condition
11379				 * being signaled.
11380				 */
11381
11382				/* Release mailbox register lock. */
11383				MBX_REGISTER_UNLOCK(ha);
11384
11385				EL(ha, "failed, rval = %xh\n",
11386				    QL_FUNCTION_TIMEOUT);
11387				return (QL_FUNCTION_TIMEOUT);
11388			}
11389		}
11390
11391		/* Set busy flag. */
11392		ha->mailbox_flags = (uint8_t)
11393		    (ha->mailbox_flags | MBX_BUSY_FLG);
11394		mcp->timeout = 120;
11395		ha->mcp = mcp;
11396
11397		/* Release mailbox register lock. */
11398		MBX_REGISTER_UNLOCK(ha);
11399	}
11400
11401	/* Free previous dump buffer. */
11402	if (ha->ql_dump_ptr != NULL) {
11403		kmem_free(ha->ql_dump_ptr, ha->ql_dump_size);
11404		ha->ql_dump_ptr = NULL;
11405	}
11406
11407	if (CFG_IST(ha, CFG_CTRL_2422)) {
11408		ha->ql_dump_size = (uint32_t)(sizeof (ql_24xx_fw_dump_t) +
11409		    ha->fw_ext_memory_size);
11410	} else if (CFG_IST(ha, CFG_CTRL_25XX)) {
11411		ha->ql_dump_size = (uint32_t)(sizeof (ql_25xx_fw_dump_t) +
11412		    ha->fw_ext_memory_size);
11413	} else {
11414		ha->ql_dump_size = sizeof (ql_fw_dump_t);
11415	}
11416
11417	if ((ha->ql_dump_ptr = kmem_zalloc(ha->ql_dump_size, KM_NOSLEEP)) ==
11418	    NULL) {
11419		rval = QL_MEMORY_ALLOC_FAILED;
11420	} else {
11421		if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
11422			rval = ql_2300_binary_fw_dump(ha, ha->ql_dump_ptr);
11423		} else if (CFG_IST(ha, CFG_CTRL_25XX)) {
11424			rval = ql_25xx_binary_fw_dump(ha, ha->ql_dump_ptr);
11425		} else if (CFG_IST(ha, CFG_CTRL_2422)) {
11426			rval = ql_24xx_binary_fw_dump(ha, ha->ql_dump_ptr);
11427		} else {
11428			rval = ql_2200_binary_fw_dump(ha, ha->ql_dump_ptr);
11429		}
11430	}
11431
11432	/* Reset ISP chip. */
11433	ql_reset_chip(ha);
11434
11435	QL_DUMP_LOCK(ha);
11436
11437	if (rval != QL_SUCCESS) {
11438		if (ha->ql_dump_ptr != NULL) {
11439			kmem_free(ha->ql_dump_ptr, ha->ql_dump_size);
11440			ha->ql_dump_ptr = NULL;
11441		}
11442		ha->ql_dump_state &= ~(QL_DUMPING | QL_DUMP_VALID |
11443		    QL_DUMP_UPLOADED);
11444		EL(ha, "failed, rval = %xh\n", rval);
11445	} else {
11446		ha->ql_dump_state &= ~(QL_DUMPING | QL_DUMP_UPLOADED);
11447		ha->ql_dump_state |= QL_DUMP_VALID;
11448		EL(ha, "done\n");
11449	}
11450
11451	QL_DUMP_UNLOCK(ha);
11452
11453	return (rval);
11454}
11455
11456/*
11457 * ql_ascii_fw_dump
11458 *	Converts firmware binary dump to ascii.
11459 *
11460 * Input:
11461 *	ha = adapter state pointer.
11462 *	bptr = buffer pointer.
11463 *
11464 * Returns:
11465 *	Amount of data buffer used.
11466 *
11467 * Context:
11468 *	Kernel context.
11469 */
11470size_t
11471ql_ascii_fw_dump(ql_adapter_state_t *vha, caddr_t bufp)
11472{
11473	uint32_t		cnt;
11474	caddr_t			bp;
11475	int			mbox_cnt;
11476	ql_adapter_state_t	*ha = vha->pha;
11477	ql_fw_dump_t		*fw = ha->ql_dump_ptr;
11478
11479	if (CFG_IST(ha, CFG_CTRL_2422)) {
11480		return (ql_24xx_ascii_fw_dump(ha, bufp));
11481	} else if (CFG_IST(ha, CFG_CTRL_25XX)) {
11482		return (ql_25xx_ascii_fw_dump(ha, bufp));
11483	}
11484
11485	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11486
11487	if (CFG_IST(ha, CFG_CTRL_2300)) {
11488		(void) sprintf(bufp, "\nISP 2300IP ");
11489	} else if (CFG_IST(ha, CFG_CTRL_6322)) {
11490		(void) sprintf(bufp, "\nISP 6322FLX ");
11491	} else {
11492		(void) sprintf(bufp, "\nISP 2200IP ");
11493	}
11494
11495	bp = bufp + strlen(bufp);
11496	(void) sprintf(bp, "Firmware Version %d.%d.%d\n",
11497	    ha->fw_major_version, ha->fw_minor_version,
11498	    ha->fw_subminor_version);
11499
11500	(void) strcat(bufp, "\nPBIU Registers:");
11501	bp = bufp + strlen(bufp);
11502	for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) {
11503		if (cnt % 8 == 0) {
11504			*bp++ = '\n';
11505		}
11506		(void) sprintf(bp, "%04x  ", fw->pbiu_reg[cnt]);
11507		bp = bp + 6;
11508	}
11509
11510	if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
11511		(void) strcat(bufp, "\n\nReqQ-RspQ-Risc2Host Status "
11512		    "registers:");
11513		bp = bufp + strlen(bufp);
11514		for (cnt = 0; cnt < sizeof (fw->risc_host_reg) / 2; cnt++) {
11515			if (cnt % 8 == 0) {
11516				*bp++ = '\n';
11517			}
11518			(void) sprintf(bp, "%04x  ", fw->risc_host_reg[cnt]);
11519			bp = bp + 6;
11520		}
11521	}
11522
11523	(void) strcat(bp, "\n\nMailbox Registers:");
11524	bp = bufp + strlen(bufp);
11525	mbox_cnt = (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) ? 16 : 8;
11526	for (cnt = 0; cnt < mbox_cnt; cnt++) {
11527		if (cnt % 8 == 0) {
11528			*bp++ = '\n';
11529		}
11530		(void) sprintf(bp, "%04x  ", fw->mailbox_reg[cnt]);
11531		bp = bp + 6;
11532	}
11533
11534	if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
11535		(void) strcat(bp, "\n\nAuto Request Response DMA Registers:");
11536		bp = bufp + strlen(bufp);
11537		for (cnt = 0; cnt < sizeof (fw->resp_dma_reg) / 2; cnt++) {
11538			if (cnt % 8 == 0) {
11539				*bp++ = '\n';
11540			}
11541			(void) sprintf(bp, "%04x  ", fw->resp_dma_reg[cnt]);
11542			bp = bp + 6;
11543		}
11544	}
11545
11546	(void) strcat(bp, "\n\nDMA Registers:");
11547	bp = bufp + strlen(bufp);
11548	for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) {
11549		if (cnt % 8 == 0) {
11550			*bp++ = '\n';
11551		}
11552		(void) sprintf(bp, "%04x  ", fw->dma_reg[cnt]);
11553		bp = bp + 6;
11554	}
11555
11556	(void) strcat(bp, "\n\nRISC Hardware Registers:");
11557	bp = bufp + strlen(bufp);
11558	for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) {
11559		if (cnt % 8 == 0) {
11560			*bp++ = '\n';
11561		}
11562		(void) sprintf(bp, "%04x  ", fw->risc_hdw_reg[cnt]);
11563		bp = bp + 6;
11564	}
11565
11566	(void) strcat(bp, "\n\nRISC GP0 Registers:");
11567	bp = bufp + strlen(bufp);
11568	for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) {
11569		if (cnt % 8 == 0) {
11570			*bp++ = '\n';
11571		}
11572		(void) sprintf(bp, "%04x  ", fw->risc_gp0_reg[cnt]);
11573		bp = bp + 6;
11574	}
11575
11576	(void) strcat(bp, "\n\nRISC GP1 Registers:");
11577	bp = bufp + strlen(bufp);
11578	for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) {
11579		if (cnt % 8 == 0) {
11580			*bp++ = '\n';
11581		}
11582		(void) sprintf(bp, "%04x  ", fw->risc_gp1_reg[cnt]);
11583		bp = bp + 6;
11584	}
11585
11586	(void) strcat(bp, "\n\nRISC GP2 Registers:");
11587	bp = bufp + strlen(bufp);
11588	for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) {
11589		if (cnt % 8 == 0) {
11590			*bp++ = '\n';
11591		}
11592		(void) sprintf(bp, "%04x  ", fw->risc_gp2_reg[cnt]);
11593		bp = bp + 6;
11594	}
11595
11596	(void) strcat(bp, "\n\nRISC GP3 Registers:");
11597	bp = bufp + strlen(bufp);
11598	for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) {
11599		if (cnt % 8 == 0) {
11600			*bp++ = '\n';
11601		}
11602		(void) sprintf(bp, "%04x  ", fw->risc_gp3_reg[cnt]);
11603		bp = bp + 6;
11604	}
11605
11606	(void) strcat(bp, "\n\nRISC GP4 Registers:");
11607	bp = bufp + strlen(bufp);
11608	for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) {
11609		if (cnt % 8 == 0) {
11610			*bp++ = '\n';
11611		}
11612		(void) sprintf(bp, "%04x  ", fw->risc_gp4_reg[cnt]);
11613		bp = bp + 6;
11614	}
11615
11616	(void) strcat(bp, "\n\nRISC GP5 Registers:");
11617	bp = bufp + strlen(bufp);
11618	for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) {
11619		if (cnt % 8 == 0) {
11620			*bp++ = '\n';
11621		}
11622		(void) sprintf(bp, "%04x  ", fw->risc_gp5_reg[cnt]);
11623		bp = bp + 6;
11624	}
11625
11626	(void) strcat(bp, "\n\nRISC GP6 Registers:");
11627	bp = bufp + strlen(bufp);
11628	for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) {
11629		if (cnt % 8 == 0) {
11630			*bp++ = '\n';
11631		}
11632		(void) sprintf(bp, "%04x  ", fw->risc_gp6_reg[cnt]);
11633		bp = bp + 6;
11634	}
11635
11636	(void) strcat(bp, "\n\nRISC GP7 Registers:");
11637	bp = bufp + strlen(bufp);
11638	for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) {
11639		if (cnt % 8 == 0) {
11640			*bp++ = '\n';
11641		}
11642		(void) sprintf(bp, "%04x  ", fw->risc_gp7_reg[cnt]);
11643		bp = bp + 6;
11644	}
11645
11646	(void) strcat(bp, "\n\nFrame Buffer Hardware Registers:");
11647	bp = bufp + strlen(bufp);
11648	for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) {
11649		if ((cnt == 16) && ((CFG_IST(ha, (CFG_CTRL_2300 |
11650		    CFG_CTRL_6322)) == 0))) {
11651			break;
11652		}
11653		if (cnt % 8 == 0) {
11654			*bp++ = '\n';
11655		}
11656		(void) sprintf(bp, "%04x  ", fw->frame_buf_hdw_reg[cnt]);
11657		bp = bp + 6;
11658	}
11659
11660	(void) strcat(bp, "\n\nFPM B0 Registers:");
11661	bp = bufp + strlen(bufp);
11662	for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) {
11663		if (cnt % 8 == 0) {
11664			*bp++ = '\n';
11665		}
11666		(void) sprintf(bp, "%04x  ", fw->fpm_b0_reg[cnt]);
11667		bp = bp + 6;
11668	}
11669
11670	(void) strcat(bp, "\n\nFPM B1 Registers:");
11671	bp = bufp + strlen(bufp);
11672	for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) {
11673		if (cnt % 8 == 0) {
11674			*bp++ = '\n';
11675		}
11676		(void) sprintf(bp, "%04x  ", fw->fpm_b1_reg[cnt]);
11677		bp = bp + 6;
11678	}
11679
11680	if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
11681		(void) strcat(bp, "\n\nCode RAM Dump:");
11682		bp = bufp + strlen(bufp);
11683		for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) {
11684			if (cnt % 8 == 0) {
11685				(void) sprintf(bp, "\n%05x: ", cnt + 0x0800);
11686				bp = bp + 8;
11687			}
11688			(void) sprintf(bp, "%04x  ", fw->risc_ram[cnt]);
11689			bp = bp + 6;
11690		}
11691
11692		(void) strcat(bp, "\n\nStack RAM Dump:");
11693		bp = bufp + strlen(bufp);
11694		for (cnt = 0; cnt < sizeof (fw->stack_ram) / 2; cnt++) {
11695			if (cnt % 8 == 0) {
11696				(void) sprintf(bp, "\n%05x: ", cnt + 0x010000);
11697				bp = bp + 8;
11698			}
11699			(void) sprintf(bp, "%04x  ", fw->stack_ram[cnt]);
11700			bp = bp + 6;
11701		}
11702
11703		(void) strcat(bp, "\n\nData RAM Dump:");
11704		bp = bufp + strlen(bufp);
11705		for (cnt = 0; cnt < sizeof (fw->data_ram) / 2; cnt++) {
11706			if (cnt % 8 == 0) {
11707				(void) sprintf(bp, "\n%05x: ", cnt + 0x010800);
11708				bp = bp + 8;
11709			}
11710			(void) sprintf(bp, "%04x  ", fw->data_ram[cnt]);
11711			bp = bp + 6;
11712		}
11713	} else {
11714		(void) strcat(bp, "\n\nRISC SRAM:");
11715		bp = bufp + strlen(bufp);
11716		for (cnt = 0; cnt < 0xf000; cnt++) {
11717			if (cnt % 8 == 0) {
11718				(void) sprintf(bp, "\n%04x: ", cnt + 0x1000);
11719				bp = bp + 7;
11720			}
11721			(void) sprintf(bp, "%04x  ", fw->risc_ram[cnt]);
11722			bp = bp + 6;
11723		}
11724	}
11725
11726	(void) strcat(bp, "\n\n[<==END] ISP Debug Dump.");
11727	bp += strlen(bp);
11728
11729	(void) sprintf(bp, "\n\nRequest Queue");
11730	bp += strlen(bp);
11731	for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) {
11732		if (cnt % 8 == 0) {
11733			(void) sprintf(bp, "\n%08x: ", cnt);
11734			bp += strlen(bp);
11735		}
11736		(void) sprintf(bp, "%08x ", fw->req_q[cnt]);
11737		bp += strlen(bp);
11738	}
11739
11740	(void) sprintf(bp, "\n\nResponse Queue");
11741	bp += strlen(bp);
11742	for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) {
11743		if (cnt % 8 == 0) {
11744			(void) sprintf(bp, "\n%08x: ", cnt);
11745			bp += strlen(bp);
11746		}
11747		(void) sprintf(bp, "%08x ", fw->rsp_q[cnt]);
11748		bp += strlen(bp);
11749	}
11750
11751	(void) sprintf(bp, "\n");
11752
11753	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11754
11755	return (strlen(bufp));
11756}
11757
11758/*
11759 * ql_24xx_ascii_fw_dump
11760 *	Converts ISP24xx firmware binary dump to ascii.
11761 *
11762 * Input:
11763 *	ha = adapter state pointer.
11764 *	bptr = buffer pointer.
11765 *
11766 * Returns:
11767 *	Amount of data buffer used.
11768 *
11769 * Context:
11770 *	Kernel context.
11771 */
11772static size_t
11773ql_24xx_ascii_fw_dump(ql_adapter_state_t *ha, caddr_t bufp)
11774{
11775	uint32_t		cnt;
11776	caddr_t			bp = bufp;
11777	ql_24xx_fw_dump_t	*fw = ha->ql_dump_ptr;
11778
11779	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11780
11781	(void) sprintf(bp, "ISP FW Version %d.%02d.%02d Attributes %X\n",
11782	    ha->fw_major_version, ha->fw_minor_version,
11783	    ha->fw_subminor_version, ha->fw_attributes);
11784	bp += strlen(bp);
11785
11786	(void) sprintf(bp, "\nHCCR Register\n%08x\n", fw->hccr);
11787
11788	(void) strcat(bp, "\nHost Interface Registers");
11789	bp += strlen(bp);
11790	for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) {
11791		if (cnt % 8 == 0) {
11792			(void) sprintf(bp++, "\n");
11793		}
11794
11795		(void) sprintf(bp, "%08x ", fw->host_reg[cnt]);
11796		bp += 9;
11797	}
11798
11799	(void) sprintf(bp, "\n\nMailbox Registers");
11800	bp += strlen(bp);
11801	for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
11802		if (cnt % 16 == 0) {
11803			(void) sprintf(bp++, "\n");
11804		}
11805
11806		(void) sprintf(bp, "%04x ", fw->mailbox_reg[cnt]);
11807		bp += 5;
11808	}
11809
11810	(void) sprintf(bp, "\n\nXSEQ GP Registers");
11811	bp += strlen(bp);
11812	for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) {
11813		if (cnt % 8 == 0) {
11814			(void) sprintf(bp++, "\n");
11815		}
11816
11817		(void) sprintf(bp, "%08x ", fw->xseq_gp_reg[cnt]);
11818		bp += 9;
11819	}
11820
11821	(void) sprintf(bp, "\n\nXSEQ-0 Registers");
11822	bp += strlen(bp);
11823	for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) {
11824		if (cnt % 8 == 0) {
11825			(void) sprintf(bp++, "\n");
11826		}
11827
11828		(void) sprintf(bp, "%08x ", fw->xseq_0_reg[cnt]);
11829		bp += 9;
11830	}
11831
11832	(void) sprintf(bp, "\n\nXSEQ-1 Registers");
11833	bp += strlen(bp);
11834	for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) {
11835		if (cnt % 8 == 0) {
11836			(void) sprintf(bp++, "\n");
11837		}
11838
11839		(void) sprintf(bp, "%08x ", fw->xseq_1_reg[cnt]);
11840		bp += 9;
11841	}
11842
11843	(void) sprintf(bp, "\n\nRSEQ GP Registers");
11844	bp += strlen(bp);
11845	for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) {
11846		if (cnt % 8 == 0) {
11847			(void) sprintf(bp++, "\n");
11848		}
11849
11850		(void) sprintf(bp, "%08x ", fw->rseq_gp_reg[cnt]);
11851		bp += 9;
11852	}
11853
11854	(void) sprintf(bp, "\n\nRSEQ-0 Registers");
11855	bp += strlen(bp);
11856	for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) {
11857		if (cnt % 8 == 0) {
11858			(void) sprintf(bp++, "\n");
11859		}
11860
11861		(void) sprintf(bp, "%08x ", fw->rseq_0_reg[cnt]);
11862		bp += 9;
11863	}
11864
11865	(void) sprintf(bp, "\n\nRSEQ-1 Registers");
11866	bp += strlen(bp);
11867	for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) {
11868		if (cnt % 8 == 0) {
11869			(void) sprintf(bp++, "\n");
11870		}
11871
11872		(void) sprintf(bp, "%08x ", fw->rseq_1_reg[cnt]);
11873		bp += 9;
11874	}
11875
11876	(void) sprintf(bp, "\n\nRSEQ-2 Registers");
11877	bp += strlen(bp);
11878	for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) {
11879		if (cnt % 8 == 0) {
11880			(void) sprintf(bp++, "\n");
11881		}
11882
11883		(void) sprintf(bp, "%08x ", fw->rseq_2_reg[cnt]);
11884		bp += 9;
11885	}
11886
11887	(void) sprintf(bp, "\n\nCommand DMA Registers");
11888	bp += strlen(bp);
11889	for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) {
11890		if (cnt % 8 == 0) {
11891			(void) sprintf(bp++, "\n");
11892		}
11893
11894		(void) sprintf(bp, "%08x ", fw->cmd_dma_reg[cnt]);
11895		bp += 9;
11896	}
11897
11898	(void) sprintf(bp, "\n\nRequest0 Queue DMA Channel Registers");
11899	bp += strlen(bp);
11900	for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) {
11901		if (cnt % 8 == 0) {
11902			(void) sprintf(bp++, "\n");
11903		}
11904
11905		(void) sprintf(bp, "%08x ", fw->req0_dma_reg[cnt]);
11906		bp += 9;
11907	}
11908
11909	(void) sprintf(bp, "\n\nResponse0 Queue DMA Channel Registers");
11910	bp += strlen(bp);
11911	for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) {
11912		if (cnt % 8 == 0) {
11913			(void) sprintf(bp++, "\n");
11914		}
11915
11916		(void) sprintf(bp, "%08x ", fw->resp0_dma_reg[cnt]);
11917		bp += 9;
11918	}
11919
11920	(void) sprintf(bp, "\n\nRequest1 Queue DMA Channel Registers");
11921	bp += strlen(bp);
11922	for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) {
11923		if (cnt % 8 == 0) {
11924			(void) sprintf(bp++, "\n");
11925		}
11926
11927		(void) sprintf(bp, "%08x ", fw->req1_dma_reg[cnt]);
11928		bp += 9;
11929	}
11930
11931	(void) sprintf(bp, "\n\nXMT0 Data DMA Registers");
11932	bp += strlen(bp);
11933	for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) {
11934		if (cnt % 8 == 0) {
11935			(void) sprintf(bp++, "\n");
11936		}
11937
11938		(void) sprintf(bp, "%08x ", fw->xmt0_dma_reg[cnt]);
11939		bp += 9;
11940	}
11941
11942	(void) sprintf(bp, "\n\nXMT1 Data DMA Registers");
11943	bp += strlen(bp);
11944	for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) {
11945		if (cnt % 8 == 0) {
11946			(void) sprintf(bp++, "\n");
11947		}
11948
11949		(void) sprintf(bp, "%08x ", fw->xmt1_dma_reg[cnt]);
11950		bp += 9;
11951	}
11952
11953	(void) sprintf(bp, "\n\nXMT2 Data DMA Registers");
11954	bp += strlen(bp);
11955	for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) {
11956		if (cnt % 8 == 0) {
11957			(void) sprintf(bp++, "\n");
11958		}
11959
11960		(void) sprintf(bp, "%08x ", fw->xmt2_dma_reg[cnt]);
11961		bp += 9;
11962	}
11963
11964	(void) sprintf(bp, "\n\nXMT3 Data DMA Registers");
11965	bp += strlen(bp);
11966	for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) {
11967		if (cnt % 8 == 0) {
11968			(void) sprintf(bp++, "\n");
11969		}
11970
11971		(void) sprintf(bp, "%08x ", fw->xmt3_dma_reg[cnt]);
11972		bp += 9;
11973	}
11974
11975	(void) sprintf(bp, "\n\nXMT4 Data DMA Registers");
11976	bp += strlen(bp);
11977	for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) {
11978		if (cnt % 8 == 0) {
11979			(void) sprintf(bp++, "\n");
11980		}
11981
11982		(void) sprintf(bp, "%08x ", fw->xmt4_dma_reg[cnt]);
11983		bp += 9;
11984	}
11985
11986	(void) sprintf(bp, "\n\nXMT Data DMA Common Registers");
11987	bp += strlen(bp);
11988	for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) {
11989		if (cnt % 8 == 0) {
11990			(void) sprintf(bp++, "\n");
11991		}
11992
11993		(void) sprintf(bp, "%08x ", fw->xmt_data_dma_reg[cnt]);
11994		bp += 9;
11995	}
11996
11997	(void) sprintf(bp, "\n\nRCV Thread 0 Data DMA Registers");
11998	bp += strlen(bp);
11999	for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) {
12000		if (cnt % 8 == 0) {
12001			(void) sprintf(bp++, "\n");
12002		}
12003
12004		(void) sprintf(bp, "%08x ", fw->rcvt0_data_dma_reg[cnt]);
12005		bp += 9;
12006	}
12007
12008	(void) sprintf(bp, "\n\nRCV Thread 1 Data DMA Registers");
12009	bp += strlen(bp);
12010	for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) {
12011		if (cnt % 8 == 0) {
12012			(void) sprintf(bp++, "\n");
12013		}
12014
12015		(void) sprintf(bp, "%08x ", fw->rcvt1_data_dma_reg[cnt]);
12016		bp += 9;
12017	}
12018
12019	(void) sprintf(bp, "\n\nRISC GP Registers");
12020	bp += strlen(bp);
12021	for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) {
12022		if (cnt % 8 == 0) {
12023			(void) sprintf(bp++, "\n");
12024		}
12025
12026		(void) sprintf(bp, "%08x ", fw->risc_gp_reg[cnt]);
12027		bp += 9;
12028	}
12029
12030	(void) sprintf(bufp + strlen(bufp), "\n\nShadow Registers");
12031	bp += strlen(bp);
12032	for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) {
12033		if (cnt % 8 == 0) {
12034			(void) sprintf(bp++, "\n");
12035		}
12036
12037		(void) sprintf(bp, "%08x ", fw->shadow_reg[cnt]);
12038		bp += 9;
12039	}
12040
12041	(void) sprintf(bp, "\n\nLMC Registers");
12042	bp += strlen(bp);
12043	for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) {
12044		if (cnt % 8 == 0) {
12045			(void) sprintf(bp++, "\n");
12046		}
12047
12048		(void) sprintf(bp, "%08x ", fw->lmc_reg[cnt]);
12049		bp += 9;
12050	}
12051
12052	(void) sprintf(bp, "\n\nFPM Hardware Registers");
12053	bp += strlen(bp);
12054	for (cnt = 0; cnt < sizeof (fw->fpm_hdw_reg) / 4; cnt++) {
12055		if (cnt % 8 == 0) {
12056			(void) sprintf(bp++, "\n");
12057		}
12058
12059		(void) sprintf(bp, "%08x ", fw->fpm_hdw_reg[cnt]);
12060		bp += 9;
12061	}
12062
12063	(void) sprintf(bp, "\n\nFB Hardware Registers");
12064	bp += strlen(bp);
12065	for (cnt = 0; cnt < sizeof (fw->fb_hdw_reg) / 4; cnt++) {
12066		if (cnt % 8 == 0) {
12067			(void) sprintf(bp++, "\n");
12068		}
12069
12070		(void) sprintf(bp, "%08x ", fw->fb_hdw_reg[cnt]);
12071		bp += 9;
12072	}
12073
12074	(void) sprintf(bp, "\n\nCode RAM");
12075	bp += strlen(bp);
12076	for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
12077		if (cnt % 8 == 0) {
12078			(void) sprintf(bp, "\n%08x: ", cnt + 0x20000);
12079			bp += 11;
12080		}
12081
12082		(void) sprintf(bp, "%08x ", fw->code_ram[cnt]);
12083		bp += 9;
12084	}
12085
12086	(void) sprintf(bp, "\n\nExternal Memory");
12087	bp += strlen(bp);
12088	for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) {
12089		if (cnt % 8 == 0) {
12090			(void) sprintf(bp, "\n%08x: ", cnt + 0x100000);
12091			bp += 11;
12092		}
12093		(void) sprintf(bp, "%08x ", fw->ext_mem[cnt]);
12094		bp += 9;
12095	}
12096
12097	(void) sprintf(bp, "\n[<==END] ISP Debug Dump");
12098	bp += strlen(bp);
12099
12100	(void) sprintf(bp, "\n\nRequest Queue");
12101	bp += strlen(bp);
12102	for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) {
12103		if (cnt % 8 == 0) {
12104			(void) sprintf(bp, "\n%08x: ", cnt);
12105			bp += strlen(bp);
12106		}
12107		(void) sprintf(bp, "%08x ", fw->req_q[cnt]);
12108		bp += strlen(bp);
12109	}
12110
12111	(void) sprintf(bp, "\n\nResponse Queue");
12112	bp += strlen(bp);
12113	for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) {
12114		if (cnt % 8 == 0) {
12115			(void) sprintf(bp, "\n%08x: ", cnt);
12116			bp += strlen(bp);
12117		}
12118		(void) sprintf(bp, "%08x ", fw->rsp_q[cnt]);
12119		bp += strlen(bp);
12120	}
12121
12122
12123
12124	if ((ha->cfg_flags & CFG_ENABLE_FWEXTTRACE) &&
12125	    (ha->fwexttracebuf.bp != NULL)) {
12126		uint32_t cnt_b = 0;
12127		uint64_t w64 = (uintptr_t)ha->fwexttracebuf.bp;
12128
12129		(void) sprintf(bp, "\n\nExtended Trace Buffer Memory");
12130		bp += strlen(bp);
12131		/* show data address as a byte address, data as long words */
12132		for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
12133			cnt_b = cnt * 4;
12134			if (cnt_b % 32 == 0) {
12135				(void) sprintf(bp, "\n%08x: ",
12136				    (int)(w64 + cnt_b));
12137				bp += 11;
12138			}
12139			(void) sprintf(bp, "%08x ", fw->ext_trace_buf[cnt]);
12140			bp += 9;
12141		}
12142	}
12143
12144	if ((ha->cfg_flags & CFG_ENABLE_FWFCETRACE) &&
12145	    (ha->fwfcetracebuf.bp != NULL)) {
12146		uint32_t cnt_b = 0;
12147		uint64_t w64 = (uintptr_t)ha->fwfcetracebuf.bp;
12148
12149		(void) sprintf(bp, "\n\nFC Event Trace Buffer Memory");
12150		bp += strlen(bp);
12151		/* show data address as a byte address, data as long words */
12152		for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
12153			cnt_b = cnt * 4;
12154			if (cnt_b % 32 == 0) {
12155				(void) sprintf(bp, "\n%08x: ",
12156				    (int)(w64 + cnt_b));
12157				bp += 11;
12158			}
12159			(void) sprintf(bp, "%08x ", fw->fce_trace_buf[cnt]);
12160			bp += 9;
12161		}
12162	}
12163
12164	(void) sprintf(bp, "\n\n");
12165	bp += strlen(bp);
12166
12167	cnt = (uintptr_t)bp - (uintptr_t)bufp;
12168
12169	QL_PRINT_3(CE_CONT, "(%d): done=%xh\n", ha->instance, cnt);
12170
12171	return (cnt);
12172}
12173
12174/*
12175 * ql_25xx_ascii_fw_dump
12176 *	Converts ISP25xx firmware binary dump to ascii.
12177 *
12178 * Input:
12179 *	ha = adapter state pointer.
12180 *	bptr = buffer pointer.
12181 *
12182 * Returns:
12183 *	Amount of data buffer used.
12184 *
12185 * Context:
12186 *	Kernel context.
12187 */
12188static size_t
12189ql_25xx_ascii_fw_dump(ql_adapter_state_t *ha, caddr_t bufp)
12190{
12191	uint32_t		cnt;
12192	caddr_t			bp = bufp;
12193	ql_25xx_fw_dump_t	*fw = ha->ql_dump_ptr;
12194
12195	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
12196
12197	(void) sprintf(bp, "\nISP FW Version %d.%02d.%02d Attributes %X\n",
12198	    ha->fw_major_version, ha->fw_minor_version,
12199	    ha->fw_subminor_version, ha->fw_attributes);
12200	bp += strlen(bp);
12201
12202	(void) sprintf(bp, "\nR2H Status Register\n%08x\n", fw->r2h_status);
12203	bp += strlen(bp);
12204
12205	(void) sprintf(bp, "\nHostRisc Registers");
12206	bp += strlen(bp);
12207	for (cnt = 0; cnt < sizeof (fw->hostrisc_reg) / 4; cnt++) {
12208		if (cnt % 8 == 0) {
12209			(void) sprintf(bp++, "\n");
12210		}
12211		(void) sprintf(bp, "%08x ", fw->hostrisc_reg[cnt]);
12212		bp += 9;
12213	}
12214
12215	(void) sprintf(bp, "\n\nPCIe Registers");
12216	bp += strlen(bp);
12217	for (cnt = 0; cnt < sizeof (fw->pcie_reg) / 4; cnt++) {
12218		if (cnt % 8 == 0) {
12219			(void) sprintf(bp++, "\n");
12220		}
12221		(void) sprintf(bp, "%08x ", fw->pcie_reg[cnt]);
12222		bp += 9;
12223	}
12224
12225	(void) strcat(bp, "\n\nHost Interface Registers");
12226	bp += strlen(bp);
12227	for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) {
12228		if (cnt % 8 == 0) {
12229			(void) sprintf(bp++, "\n");
12230		}
12231		(void) sprintf(bp, "%08x ", fw->host_reg[cnt]);
12232		bp += 9;
12233	}
12234
12235	(void) sprintf(bufp + strlen(bufp), "\n\nShadow Registers");
12236	bp += strlen(bp);
12237	for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) {
12238		if (cnt % 8 == 0) {
12239			(void) sprintf(bp++, "\n");
12240		}
12241		(void) sprintf(bp, "%08x ", fw->shadow_reg[cnt]);
12242		bp += 9;
12243	}
12244
12245	(void) sprintf(bufp + strlen(bufp), "\n\nRISC IO Register\n%08x",
12246	    fw->risc_io);
12247	bp += strlen(bp);
12248
12249	(void) sprintf(bp, "\n\nMailbox Registers");
12250	bp += strlen(bp);
12251	for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
12252		if (cnt % 16 == 0) {
12253			(void) sprintf(bp++, "\n");
12254		}
12255		(void) sprintf(bp, "%04x ", fw->mailbox_reg[cnt]);
12256		bp += 5;
12257	}
12258
12259	(void) sprintf(bp, "\n\nXSEQ GP Registers");
12260	bp += strlen(bp);
12261	for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) {
12262		if (cnt % 8 == 0) {
12263			(void) sprintf(bp++, "\n");
12264		}
12265		(void) sprintf(bp, "%08x ", fw->xseq_gp_reg[cnt]);
12266		bp += 9;
12267	}
12268
12269	(void) sprintf(bp, "\n\nXSEQ-0 Registers");
12270	bp += strlen(bp);
12271	for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) {
12272		if (cnt % 8 == 0) {
12273			(void) sprintf(bp++, "\n");
12274		}
12275		(void) sprintf(bp, "%08x ", fw->xseq_0_reg[cnt]);
12276		bp += 9;
12277	}
12278
12279	(void) sprintf(bp, "\n\nXSEQ-1 Registers");
12280	bp += strlen(bp);
12281	for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) {
12282		if (cnt % 8 == 0) {
12283			(void) sprintf(bp++, "\n");
12284		}
12285		(void) sprintf(bp, "%08x ", fw->xseq_1_reg[cnt]);
12286		bp += 9;
12287	}
12288
12289	(void) sprintf(bp, "\n\nRSEQ GP Registers");
12290	bp += strlen(bp);
12291	for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) {
12292		if (cnt % 8 == 0) {
12293			(void) sprintf(bp++, "\n");
12294		}
12295		(void) sprintf(bp, "%08x ", fw->rseq_gp_reg[cnt]);
12296		bp += 9;
12297	}
12298
12299	(void) sprintf(bp, "\n\nRSEQ-0 Registers");
12300	bp += strlen(bp);
12301	for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) {
12302		if (cnt % 8 == 0) {
12303			(void) sprintf(bp++, "\n");
12304		}
12305		(void) sprintf(bp, "%08x ", fw->rseq_0_reg[cnt]);
12306		bp += 9;
12307	}
12308
12309	(void) sprintf(bp, "\n\nRSEQ-1 Registers");
12310	bp += strlen(bp);
12311	for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) {
12312		if (cnt % 8 == 0) {
12313			(void) sprintf(bp++, "\n");
12314		}
12315		(void) sprintf(bp, "%08x ", fw->rseq_1_reg[cnt]);
12316		bp += 9;
12317	}
12318
12319	(void) sprintf(bp, "\n\nRSEQ-2 Registers");
12320	bp += strlen(bp);
12321	for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) {
12322		if (cnt % 8 == 0) {
12323			(void) sprintf(bp++, "\n");
12324		}
12325		(void) sprintf(bp, "%08x ", fw->rseq_2_reg[cnt]);
12326		bp += 9;
12327	}
12328
12329	(void) sprintf(bp, "\n\nASEQ GP Registers");
12330	bp += strlen(bp);
12331	for (cnt = 0; cnt < sizeof (fw->aseq_gp_reg) / 4; cnt++) {
12332		if (cnt % 8 == 0) {
12333			(void) sprintf(bp++, "\n");
12334		}
12335		(void) sprintf(bp, "%08x ", fw->aseq_gp_reg[cnt]);
12336		bp += 9;
12337	}
12338
12339	(void) sprintf(bp, "\n\nASEQ-0 GP Registers");
12340	bp += strlen(bp);
12341	for (cnt = 0; cnt < sizeof (fw->aseq_0_reg) / 4; cnt++) {
12342		if (cnt % 8 == 0) {
12343			(void) sprintf(bp++, "\n");
12344		}
12345		(void) sprintf(bp, "%08x ", fw->aseq_0_reg[cnt]);
12346		bp += 9;
12347	}
12348
12349	(void) sprintf(bp, "\n\nASEQ-1 GP Registers");
12350	bp += strlen(bp);
12351	for (cnt = 0; cnt < sizeof (fw->aseq_1_reg) / 4; cnt++) {
12352		if (cnt % 8 == 0) {
12353			(void) sprintf(bp++, "\n");
12354		}
12355		(void) sprintf(bp, "%08x ", fw->aseq_1_reg[cnt]);
12356		bp += 9;
12357	}
12358
12359	(void) sprintf(bp, "\n\nASEQ-2 GP Registers");
12360	bp += strlen(bp);
12361	for (cnt = 0; cnt < sizeof (fw->aseq_2_reg) / 4; cnt++) {
12362		if (cnt % 8 == 0) {
12363			(void) sprintf(bp++, "\n");
12364		}
12365		(void) sprintf(bp, "%08x ", fw->aseq_2_reg[cnt]);
12366		bp += 9;
12367	}
12368
12369	(void) sprintf(bp, "\n\nCommand DMA Registers");
12370	bp += strlen(bp);
12371	for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) {
12372		if (cnt % 8 == 0) {
12373			(void) sprintf(bp++, "\n");
12374		}
12375		(void)  sprintf(bp, "%08x ", fw->cmd_dma_reg[cnt]);
12376		bp += 9;
12377	}
12378
12379	(void) sprintf(bp, "\n\nRequest0 Queue DMA Channel Registers");
12380	bp += strlen(bp);
12381	for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) {
12382		if (cnt % 8 == 0) {
12383			(void) sprintf(bp++, "\n");
12384		}
12385		(void) sprintf(bp, "%08x ", fw->req0_dma_reg[cnt]);
12386		bp += 9;
12387	}
12388
12389	(void) sprintf(bp, "\n\nResponse0 Queue DMA Channel Registers");
12390	bp += strlen(bp);
12391	for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) {
12392		if (cnt % 8 == 0) {
12393			(void) sprintf(bp++, "\n");
12394		}
12395		(void) sprintf(bp, "%08x ", fw->resp0_dma_reg[cnt]);
12396		bp += 9;
12397	}
12398
12399	(void) sprintf(bp, "\n\nRequest1 Queue DMA Channel Registers");
12400	bp += strlen(bp);
12401	for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) {
12402		if (cnt % 8 == 0) {
12403			(void) sprintf(bp++, "\n");
12404		}
12405		(void) sprintf(bp, "%08x ", fw->req1_dma_reg[cnt]);
12406		bp += 9;
12407	}
12408
12409	(void) sprintf(bp, "\n\nXMT0 Data DMA Registers");
12410	bp += strlen(bp);
12411	for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) {
12412		if (cnt % 8 == 0) {
12413			(void) sprintf(bp++, "\n");
12414		}
12415		(void) sprintf(bp, "%08x ", fw->xmt0_dma_reg[cnt]);
12416		bp += 9;
12417	}
12418
12419	(void) sprintf(bp, "\n\nXMT1 Data DMA Registers");
12420	bp += strlen(bp);
12421	for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) {
12422		if (cnt % 8 == 0) {
12423			(void) sprintf(bp++, "\n");
12424		}
12425		(void) sprintf(bp, "%08x ", fw->xmt1_dma_reg[cnt]);
12426		bp += 9;
12427	}
12428
12429	(void) sprintf(bp, "\n\nXMT2 Data DMA Registers");
12430	bp += strlen(bp);
12431	for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) {
12432		if (cnt % 8 == 0) {
12433			(void) sprintf(bp++, "\n");
12434		}
12435		(void) sprintf(bp, "%08x ", fw->xmt2_dma_reg[cnt]);
12436		bp += 9;
12437	}
12438
12439	(void) sprintf(bp, "\n\nXMT3 Data DMA Registers");
12440	bp += strlen(bp);
12441	for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) {
12442		if (cnt % 8 == 0) {
12443			(void) sprintf(bp++, "\n");
12444		}
12445		(void) sprintf(bp, "%08x ", fw->xmt3_dma_reg[cnt]);
12446		bp += 9;
12447	}
12448
12449	(void) sprintf(bp, "\n\nXMT4 Data DMA Registers");
12450	bp += strlen(bp);
12451	for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) {
12452		if (cnt % 8 == 0) {
12453			(void) sprintf(bp++, "\n");
12454		}
12455		(void) sprintf(bp, "%08x ", fw->xmt4_dma_reg[cnt]);
12456		bp += 9;
12457	}
12458
12459	(void) sprintf(bp, "\n\nXMT Data DMA Common Registers");
12460	bp += strlen(bp);
12461	for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) {
12462		if (cnt % 8 == 0) {
12463			(void) sprintf(bp++, "\n");
12464		}
12465		(void) sprintf(bp, "%08x ", fw->xmt_data_dma_reg[cnt]);
12466		bp += 9;
12467	}
12468
12469	(void) sprintf(bp, "\n\nRCV Thread 0 Data DMA Registers");
12470	bp += strlen(bp);
12471	for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) {
12472		if (cnt % 8 == 0) {
12473			(void) sprintf(bp++, "\n");
12474		}
12475		(void) sprintf(bp, "%08x ", fw->rcvt0_data_dma_reg[cnt]);
12476		bp += 9;
12477	}
12478
12479	(void) sprintf(bp, "\n\nRCV Thread 1 Data DMA Registers");
12480	bp += strlen(bp);
12481	for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) {
12482		if (cnt % 8 == 0) {
12483			(void) sprintf(bp++, "\n");
12484		}
12485		(void) sprintf(bp, "%08x ", fw->rcvt1_data_dma_reg[cnt]);
12486		bp += 9;
12487	}
12488
12489	(void) sprintf(bp, "\n\nRISC GP Registers");
12490	bp += strlen(bp);
12491	for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) {
12492		if (cnt % 8 == 0) {
12493			(void) sprintf(bp++, "\n");
12494		}
12495		(void) sprintf(bp, "%08x ", fw->risc_gp_reg[cnt]);
12496		bp += 9;
12497	}
12498
12499	(void) sprintf(bp, "\n\nLMC Registers");
12500	bp += strlen(bp);
12501	for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) {
12502		if (cnt % 8 == 0) {
12503			(void) sprintf(bp++, "\n");
12504		}
12505		(void) sprintf(bp, "%08x ", fw->lmc_reg[cnt]);
12506		bp += 9;
12507	}
12508
12509	(void) sprintf(bp, "\n\nFPM Hardware Registers");
12510	bp += strlen(bp);
12511	for (cnt = 0; cnt < sizeof (fw->fpm_hdw_reg) / 4; cnt++) {
12512		if (cnt % 8 == 0) {
12513			(void) sprintf(bp++, "\n");
12514		}
12515		(void) sprintf(bp, "%08x ", fw->fpm_hdw_reg[cnt]);
12516		bp += 9;
12517	}
12518
12519	(void) sprintf(bp, "\n\nFB Hardware Registers");
12520	bp += strlen(bp);
12521	for (cnt = 0; cnt < sizeof (fw->fb_hdw_reg) / 4; cnt++) {
12522		if (cnt % 8 == 0) {
12523			(void) sprintf(bp++, "\n");
12524		}
12525		(void) sprintf(bp, "%08x ", fw->fb_hdw_reg[cnt]);
12526		bp += 9;
12527	}
12528
12529	(void) sprintf(bp, "\n\nCode RAM");
12530	bp += strlen(bp);
12531	for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
12532		if (cnt % 8 == 0) {
12533			(void) sprintf(bp, "\n%08x: ", cnt + 0x20000);
12534			bp += 11;
12535		}
12536		(void) sprintf(bp, "%08x ", fw->code_ram[cnt]);
12537		bp += 9;
12538	}
12539
12540	(void) sprintf(bp, "\n\nExternal Memory");
12541	bp += strlen(bp);
12542	for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) {
12543		if (cnt % 8 == 0) {
12544			(void) sprintf(bp, "\n%08x: ", cnt + 0x100000);
12545			bp += 11;
12546		}
12547		(void) sprintf(bp, "%08x ", fw->ext_mem[cnt]);
12548		bp += 9;
12549	}
12550
12551	(void) sprintf(bp, "\n[<==END] ISP Debug Dump");
12552	bp += strlen(bp);
12553
12554	(void) sprintf(bp, "\n\nRequest Queue");
12555	bp += strlen(bp);
12556	for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) {
12557		if (cnt % 8 == 0) {
12558			(void) sprintf(bp, "\n%08x: ", cnt);
12559			bp += strlen(bp);
12560		}
12561		(void) sprintf(bp, "%08x ", fw->req_q[cnt]);
12562		bp += strlen(bp);
12563	}
12564
12565	(void) sprintf(bp, "\n\nResponse Queue");
12566	bp += strlen(bp);
12567	for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) {
12568		if (cnt % 8 == 0) {
12569			(void) sprintf(bp, "\n%08x: ", cnt);
12570			bp += strlen(bp);
12571		}
12572		(void) sprintf(bp, "%08x ", fw->rsp_q[cnt]);
12573		bp += strlen(bp);
12574	}
12575
12576	if ((ha->cfg_flags & CFG_ENABLE_FWEXTTRACE) &&
12577	    (ha->fwexttracebuf.bp != NULL)) {
12578		uint32_t cnt_b = 0;
12579		uint64_t w64 = (uintptr_t)ha->fwexttracebuf.bp;
12580
12581		(void) sprintf(bp, "\n\nExtended Trace Buffer Memory");
12582		bp += strlen(bp);
12583		/* show data address as a byte address, data as long words */
12584		for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
12585			cnt_b = cnt * 4;
12586			if (cnt_b % 32 == 0) {
12587				(void) sprintf(bp, "\n%08x: ",
12588				    (int)(w64 + cnt_b));
12589				bp += 11;
12590			}
12591			(void) sprintf(bp, "%08x ", fw->ext_trace_buf[cnt]);
12592			bp += 9;
12593		}
12594	}
12595
12596	if ((ha->cfg_flags & CFG_ENABLE_FWFCETRACE) &&
12597	    (ha->fwfcetracebuf.bp != NULL)) {
12598		uint32_t cnt_b = 0;
12599		uint64_t w64 = (uintptr_t)ha->fwfcetracebuf.bp;
12600
12601		(void) sprintf(bp, "\n\nFC Event Trace Buffer Memory");
12602		bp += strlen(bp);
12603		/* show data address as a byte address, data as long words */
12604		for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
12605			cnt_b = cnt * 4;
12606			if (cnt_b % 32 == 0) {
12607				(void) sprintf(bp, "\n%08x: ",
12608				    (int)(w64 + cnt_b));
12609				bp += 11;
12610			}
12611			(void) sprintf(bp, "%08x ", fw->fce_trace_buf[cnt]);
12612			bp += 9;
12613		}
12614	}
12615
12616	(void) sprintf(bp, "\n\n");
12617	bp += strlen(bp);
12618
12619	cnt = (uintptr_t)bp - (uintptr_t)bufp;
12620
12621	QL_PRINT_3(CE_CONT, "(%d): done=%xh\n", ha->instance, cnt);
12622
12623	return (cnt);
12624}
12625
12626/*
12627 * ql_2200_binary_fw_dump
12628 *
12629 * Input:
12630 *	ha:	adapter state pointer.
12631 *	fw:	firmware dump context pointer.
12632 *
12633 * Returns:
12634 *	ql local function return status code.
12635 *
12636 * Context:
12637 *	Interrupt or Kernel context, no mailbox commands allowed.
12638 */
12639static int
12640ql_2200_binary_fw_dump(ql_adapter_state_t *ha, ql_fw_dump_t *fw)
12641{
12642	uint32_t	cnt;
12643	uint16_t	risc_address;
12644	clock_t		timer;
12645	mbx_cmd_t	mc;
12646	mbx_cmd_t	*mcp = &mc;
12647	int		rval = QL_SUCCESS;
12648
12649	/* Disable ISP interrupts. */
12650	WRT16_IO_REG(ha, ictrl, 0);
12651	ADAPTER_STATE_LOCK(ha);
12652	ha->flags &= ~INTERRUPTS_ENABLED;
12653	ADAPTER_STATE_UNLOCK(ha);
12654
12655	/* Release mailbox registers. */
12656	WRT16_IO_REG(ha, semaphore, 0);
12657
12658	/* Pause RISC. */
12659	WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
12660	timer = 30000;
12661	while ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) == 0) {
12662		if (timer-- != 0) {
12663			drv_usecwait(MILLISEC);
12664		} else {
12665			rval = QL_FUNCTION_TIMEOUT;
12666			break;
12667		}
12668	}
12669
12670	if (rval == QL_SUCCESS) {
12671		(void) ql_read_regs(ha, fw->pbiu_reg, ha->iobase,
12672		    sizeof (fw->pbiu_reg) / 2, 16);
12673
12674		/* In 2200 we only read 8 mailboxes */
12675		(void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x10,
12676		    8, 16);
12677
12678		(void) ql_read_regs(ha, fw->dma_reg, ha->iobase + 0x20,
12679		    sizeof (fw->dma_reg) / 2, 16);
12680
12681		WRT16_IO_REG(ha, ctrl_status, 0);
12682		(void) ql_read_regs(ha, fw->risc_hdw_reg, ha->iobase + 0xA0,
12683		    sizeof (fw->risc_hdw_reg) / 2, 16);
12684
12685		WRT16_IO_REG(ha, pcr, 0x2000);
12686		(void) ql_read_regs(ha, fw->risc_gp0_reg, ha->iobase + 0x80,
12687		    sizeof (fw->risc_gp0_reg) / 2, 16);
12688
12689		WRT16_IO_REG(ha, pcr, 0x2100);
12690		(void) ql_read_regs(ha, fw->risc_gp1_reg, ha->iobase + 0x80,
12691		    sizeof (fw->risc_gp1_reg) / 2, 16);
12692
12693		WRT16_IO_REG(ha, pcr, 0x2200);
12694		(void) ql_read_regs(ha, fw->risc_gp2_reg, ha->iobase + 0x80,
12695		    sizeof (fw->risc_gp2_reg) / 2, 16);
12696
12697		WRT16_IO_REG(ha, pcr, 0x2300);
12698		(void) ql_read_regs(ha, fw->risc_gp3_reg, ha->iobase + 0x80,
12699		    sizeof (fw->risc_gp3_reg) / 2, 16);
12700
12701		WRT16_IO_REG(ha, pcr, 0x2400);
12702		(void) ql_read_regs(ha, fw->risc_gp4_reg, ha->iobase + 0x80,
12703		    sizeof (fw->risc_gp4_reg) / 2, 16);
12704
12705		WRT16_IO_REG(ha, pcr, 0x2500);
12706		(void) ql_read_regs(ha, fw->risc_gp5_reg, ha->iobase + 0x80,
12707		    sizeof (fw->risc_gp5_reg) / 2, 16);
12708
12709		WRT16_IO_REG(ha, pcr, 0x2600);
12710		(void) ql_read_regs(ha, fw->risc_gp6_reg, ha->iobase + 0x80,
12711		    sizeof (fw->risc_gp6_reg) / 2, 16);
12712
12713		WRT16_IO_REG(ha, pcr, 0x2700);
12714		(void) ql_read_regs(ha, fw->risc_gp7_reg, ha->iobase + 0x80,
12715		    sizeof (fw->risc_gp7_reg) / 2, 16);
12716
12717		WRT16_IO_REG(ha, ctrl_status, 0x10);
12718		/* 2200 has only 16 registers */
12719		(void) ql_read_regs(ha, fw->frame_buf_hdw_reg,
12720		    ha->iobase + 0x80, 16, 16);
12721
12722		WRT16_IO_REG(ha, ctrl_status, 0x20);
12723		(void) ql_read_regs(ha, fw->fpm_b0_reg, ha->iobase + 0x80,
12724		    sizeof (fw->fpm_b0_reg) / 2, 16);
12725
12726		WRT16_IO_REG(ha, ctrl_status, 0x30);
12727		(void) ql_read_regs(ha, fw->fpm_b1_reg, ha->iobase + 0x80,
12728		    sizeof (fw->fpm_b1_reg) / 2, 16);
12729
12730		/* Select FPM registers. */
12731		WRT16_IO_REG(ha, ctrl_status, 0x20);
12732
12733		/* FPM Soft Reset. */
12734		WRT16_IO_REG(ha, fpm_diag_config, 0x100);
12735
12736		/* Select frame buffer registers. */
12737		WRT16_IO_REG(ha, ctrl_status, 0x10);
12738
12739		/* Reset frame buffer FIFOs. */
12740		WRT16_IO_REG(ha, fb_cmd, 0xa000);
12741
12742		/* Select RISC module registers. */
12743		WRT16_IO_REG(ha, ctrl_status, 0);
12744
12745		/* Reset RISC module. */
12746		WRT16_IO_REG(ha, hccr, HC_RESET_RISC);
12747
12748		/* Reset ISP semaphore. */
12749		WRT16_IO_REG(ha, semaphore, 0);
12750
12751		/* Release RISC module. */
12752		WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
12753
12754		/* Wait for RISC to recover from reset. */
12755		timer = 30000;
12756		while (RD16_IO_REG(ha, mailbox[0]) == MBS_BUSY) {
12757			if (timer-- != 0) {
12758				drv_usecwait(MILLISEC);
12759			} else {
12760				rval = QL_FUNCTION_TIMEOUT;
12761				break;
12762			}
12763		}
12764
12765		/* Disable RISC pause on FPM parity error. */
12766		WRT16_IO_REG(ha, hccr, HC_DISABLE_PARITY_PAUSE);
12767	}
12768
12769	if (rval == QL_SUCCESS) {
12770		/* Pause RISC. */
12771		WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
12772		timer = 30000;
12773		while ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) == 0) {
12774			if (timer-- != 0) {
12775				drv_usecwait(MILLISEC);
12776			} else {
12777				rval = QL_FUNCTION_TIMEOUT;
12778				break;
12779			}
12780		}
12781	}
12782
12783	if (rval == QL_SUCCESS) {
12784		/* Set memory configuration and timing. */
12785		WRT16_IO_REG(ha, mctr, 0xf2);
12786
12787		/* Release RISC. */
12788		WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
12789
12790		/* Get RISC SRAM. */
12791		risc_address = 0x1000;
12792		WRT16_IO_REG(ha, mailbox[0], MBC_READ_RAM_WORD);
12793		for (cnt = 0; cnt < 0xf000; cnt++) {
12794			WRT16_IO_REG(ha, mailbox[1], risc_address++);
12795			WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT);
12796			for (timer = 6000000; timer != 0; timer--) {
12797				/* Check for pending interrupts. */
12798				if (RD16_IO_REG(ha, istatus) & RISC_INT) {
12799					if (RD16_IO_REG(ha, semaphore) &
12800					    BIT_0) {
12801						WRT16_IO_REG(ha, hccr,
12802						    HC_CLR_RISC_INT);
12803						mcp->mb[0] = RD16_IO_REG(ha,
12804						    mailbox[0]);
12805						fw->risc_ram[cnt] =
12806						    RD16_IO_REG(ha,
12807						    mailbox[2]);
12808						WRT16_IO_REG(ha,
12809						    semaphore, 0);
12810						break;
12811					}
12812					WRT16_IO_REG(ha, hccr,
12813					    HC_CLR_RISC_INT);
12814				}
12815				drv_usecwait(5);
12816			}
12817
12818			if (timer == 0) {
12819				rval = QL_FUNCTION_TIMEOUT;
12820			} else {
12821				rval = mcp->mb[0];
12822			}
12823
12824			if (rval != QL_SUCCESS) {
12825				break;
12826			}
12827		}
12828	}
12829
12830	return (rval);
12831}
12832
12833/*
12834 * ql_2300_binary_fw_dump
12835 *
12836 * Input:
12837 *	ha:	adapter state pointer.
12838 *	fw:	firmware dump context pointer.
12839 *
12840 * Returns:
12841 *	ql local function return status code.
12842 *
12843 * Context:
12844 *	Interrupt or Kernel context, no mailbox commands allowed.
12845 */
12846static int
12847ql_2300_binary_fw_dump(ql_adapter_state_t *ha, ql_fw_dump_t *fw)
12848{
12849	clock_t	timer;
12850	int	rval = QL_SUCCESS;
12851
12852	/* Disable ISP interrupts. */
12853	WRT16_IO_REG(ha, ictrl, 0);
12854	ADAPTER_STATE_LOCK(ha);
12855	ha->flags &= ~INTERRUPTS_ENABLED;
12856	ADAPTER_STATE_UNLOCK(ha);
12857
12858	/* Release mailbox registers. */
12859	WRT16_IO_REG(ha, semaphore, 0);
12860
12861	/* Pause RISC. */
12862	WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
12863	timer = 30000;
12864	while ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) == 0) {
12865		if (timer-- != 0) {
12866			drv_usecwait(MILLISEC);
12867		} else {
12868			rval = QL_FUNCTION_TIMEOUT;
12869			break;
12870		}
12871	}
12872
12873	if (rval == QL_SUCCESS) {
12874		(void) ql_read_regs(ha, fw->pbiu_reg, ha->iobase,
12875		    sizeof (fw->pbiu_reg) / 2, 16);
12876
12877		(void) ql_read_regs(ha, fw->risc_host_reg, ha->iobase + 0x10,
12878		    sizeof (fw->risc_host_reg) / 2, 16);
12879
12880		(void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x40,
12881		    sizeof (fw->mailbox_reg) / 2, 16);
12882
12883		WRT16_IO_REG(ha, ctrl_status, 0x40);
12884		(void) ql_read_regs(ha, fw->resp_dma_reg, ha->iobase + 0x80,
12885		    sizeof (fw->resp_dma_reg) / 2, 16);
12886
12887		WRT16_IO_REG(ha, ctrl_status, 0x50);
12888		(void) ql_read_regs(ha, fw->dma_reg, ha->iobase + 0x80,
12889		    sizeof (fw->dma_reg) / 2, 16);
12890
12891		WRT16_IO_REG(ha, ctrl_status, 0);
12892		(void) ql_read_regs(ha, fw->risc_hdw_reg, ha->iobase + 0xA0,
12893		    sizeof (fw->risc_hdw_reg) / 2, 16);
12894
12895		WRT16_IO_REG(ha, pcr, 0x2000);
12896		(void) ql_read_regs(ha, fw->risc_gp0_reg, ha->iobase + 0x80,
12897		    sizeof (fw->risc_gp0_reg) / 2, 16);
12898
12899		WRT16_IO_REG(ha, pcr, 0x2200);
12900		(void) ql_read_regs(ha, fw->risc_gp1_reg, ha->iobase + 0x80,
12901		    sizeof (fw->risc_gp1_reg) / 2, 16);
12902
12903		WRT16_IO_REG(ha, pcr, 0x2400);
12904		(void) ql_read_regs(ha, fw->risc_gp2_reg, ha->iobase + 0x80,
12905		    sizeof (fw->risc_gp2_reg) / 2, 16);
12906
12907		WRT16_IO_REG(ha, pcr, 0x2600);
12908		(void) ql_read_regs(ha, fw->risc_gp3_reg, ha->iobase + 0x80,
12909		    sizeof (fw->risc_gp3_reg) / 2, 16);
12910
12911		WRT16_IO_REG(ha, pcr, 0x2800);
12912		(void) ql_read_regs(ha, fw->risc_gp4_reg, ha->iobase + 0x80,
12913		    sizeof (fw->risc_gp4_reg) / 2, 16);
12914
12915		WRT16_IO_REG(ha, pcr, 0x2A00);
12916		(void) ql_read_regs(ha, fw->risc_gp5_reg, ha->iobase + 0x80,
12917		    sizeof (fw->risc_gp5_reg) / 2, 16);
12918
12919		WRT16_IO_REG(ha, pcr, 0x2C00);
12920		(void) ql_read_regs(ha, fw->risc_gp6_reg, ha->iobase + 0x80,
12921		    sizeof (fw->risc_gp6_reg) / 2, 16);
12922
12923		WRT16_IO_REG(ha, pcr, 0x2E00);
12924		(void) ql_read_regs(ha, fw->risc_gp7_reg, ha->iobase + 0x80,
12925		    sizeof (fw->risc_gp7_reg) / 2, 16);
12926
12927		WRT16_IO_REG(ha, ctrl_status, 0x10);
12928		(void) ql_read_regs(ha, fw->frame_buf_hdw_reg,
12929		    ha->iobase + 0x80, sizeof (fw->frame_buf_hdw_reg) / 2, 16);
12930
12931		WRT16_IO_REG(ha, ctrl_status, 0x20);
12932		(void) ql_read_regs(ha, fw->fpm_b0_reg, ha->iobase + 0x80,
12933		    sizeof (fw->fpm_b0_reg) / 2, 16);
12934
12935		WRT16_IO_REG(ha, ctrl_status, 0x30);
12936		(void) ql_read_regs(ha, fw->fpm_b1_reg, ha->iobase + 0x80,
12937		    sizeof (fw->fpm_b1_reg) / 2, 16);
12938
12939		/* Select FPM registers. */
12940		WRT16_IO_REG(ha, ctrl_status, 0x20);
12941
12942		/* FPM Soft Reset. */
12943		WRT16_IO_REG(ha, fpm_diag_config, 0x100);
12944
12945		/* Select frame buffer registers. */
12946		WRT16_IO_REG(ha, ctrl_status, 0x10);
12947
12948		/* Reset frame buffer FIFOs. */
12949		WRT16_IO_REG(ha, fb_cmd, 0xa000);
12950
12951		/* Select RISC module registers. */
12952		WRT16_IO_REG(ha, ctrl_status, 0);
12953
12954		/* Reset RISC module. */
12955		WRT16_IO_REG(ha, hccr, HC_RESET_RISC);
12956
12957		/* Reset ISP semaphore. */
12958		WRT16_IO_REG(ha, semaphore, 0);
12959
12960		/* Release RISC module. */
12961		WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
12962
12963		/* Wait for RISC to recover from reset. */
12964		timer = 30000;
12965		while (RD16_IO_REG(ha, mailbox[0]) == MBS_BUSY) {
12966			if (timer-- != 0) {
12967				drv_usecwait(MILLISEC);
12968			} else {
12969				rval = QL_FUNCTION_TIMEOUT;
12970				break;
12971			}
12972		}
12973
12974		/* Disable RISC pause on FPM parity error. */
12975		WRT16_IO_REG(ha, hccr, HC_DISABLE_PARITY_PAUSE);
12976	}
12977
12978	/* Get RISC SRAM. */
12979	if (rval == QL_SUCCESS) {
12980		rval = ql_read_risc_ram(ha, 0x800, 0xf800, fw->risc_ram);
12981	}
12982	/* Get STACK SRAM. */
12983	if (rval == QL_SUCCESS) {
12984		rval = ql_read_risc_ram(ha, 0x10000, 0x800, fw->stack_ram);
12985	}
12986	/* Get DATA SRAM. */
12987	if (rval == QL_SUCCESS) {
12988		rval = ql_read_risc_ram(ha, 0x10800, 0xf800, fw->data_ram);
12989	}
12990
12991	return (rval);
12992}
12993
12994/*
12995 * ql_24xx_binary_fw_dump
12996 *
12997 * Input:
12998 *	ha:	adapter state pointer.
12999 *	fw:	firmware dump context pointer.
13000 *
13001 * Returns:
13002 *	ql local function return status code.
13003 *
13004 * Context:
13005 *	Interrupt or Kernel context, no mailbox commands allowed.
13006 */
13007static int
13008ql_24xx_binary_fw_dump(ql_adapter_state_t *ha, ql_24xx_fw_dump_t *fw)
13009{
13010	uint32_t	*reg32;
13011	void		*bp;
13012	clock_t		timer;
13013	int		rval = QL_SUCCESS;
13014
13015	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
13016
13017	fw->hccr = RD32_IO_REG(ha, hccr);
13018
13019	/* Pause RISC. */
13020	if ((RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0) {
13021		/* Disable ISP interrupts. */
13022		WRT16_IO_REG(ha, ictrl, 0);
13023
13024		WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC);
13025		for (timer = 30000;
13026		    (RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0 &&
13027		    rval == QL_SUCCESS; timer--) {
13028			if (timer) {
13029				drv_usecwait(100);
13030			} else {
13031				rval = QL_FUNCTION_TIMEOUT;
13032			}
13033		}
13034	}
13035
13036	if (rval == QL_SUCCESS) {
13037		/* Host interface registers. */
13038		(void) ql_read_regs(ha, fw->host_reg, ha->iobase,
13039		    sizeof (fw->host_reg) / 4, 32);
13040
13041		/* Disable ISP interrupts. */
13042		WRT32_IO_REG(ha, ictrl, 0);
13043		RD32_IO_REG(ha, ictrl);
13044		ADAPTER_STATE_LOCK(ha);
13045		ha->flags &= ~INTERRUPTS_ENABLED;
13046		ADAPTER_STATE_UNLOCK(ha);
13047
13048		/* Shadow registers. */
13049
13050		WRT32_IO_REG(ha, io_base_addr, 0x0F70);
13051		RD32_IO_REG(ha, io_base_addr);
13052
13053		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13054		WRT_REG_DWORD(ha, reg32, 0xB0000000);
13055		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13056		fw->shadow_reg[0] = RD_REG_DWORD(ha, reg32);
13057
13058		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13059		WRT_REG_DWORD(ha, reg32, 0xB0100000);
13060		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13061		fw->shadow_reg[1] = RD_REG_DWORD(ha, reg32);
13062
13063		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13064		WRT_REG_DWORD(ha, reg32, 0xB0200000);
13065		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13066		fw->shadow_reg[2] = RD_REG_DWORD(ha, reg32);
13067
13068		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13069		WRT_REG_DWORD(ha, reg32, 0xB0300000);
13070		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13071		fw->shadow_reg[3] = RD_REG_DWORD(ha, reg32);
13072
13073		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13074		WRT_REG_DWORD(ha, reg32, 0xB0400000);
13075		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13076		fw->shadow_reg[4] = RD_REG_DWORD(ha, reg32);
13077
13078		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13079		WRT_REG_DWORD(ha, reg32, 0xB0500000);
13080		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13081		fw->shadow_reg[5] = RD_REG_DWORD(ha, reg32);
13082
13083		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13084		WRT_REG_DWORD(ha, reg32, 0xB0600000);
13085		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13086		fw->shadow_reg[6] = RD_REG_DWORD(ha, reg32);
13087
13088		/* Mailbox registers. */
13089		(void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x80,
13090		    sizeof (fw->mailbox_reg) / 2, 16);
13091
13092		/* Transfer sequence registers. */
13093
13094		/* XSEQ GP */
13095		WRT32_IO_REG(ha, io_base_addr, 0xBF00);
13096		bp = ql_read_regs(ha, fw->xseq_gp_reg, ha->iobase + 0xC0,
13097		    16, 32);
13098		WRT32_IO_REG(ha, io_base_addr, 0xBF10);
13099		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13100		WRT32_IO_REG(ha, io_base_addr, 0xBF20);
13101		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13102		WRT32_IO_REG(ha, io_base_addr, 0xBF30);
13103		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13104		WRT32_IO_REG(ha, io_base_addr, 0xBF40);
13105		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13106		WRT32_IO_REG(ha, io_base_addr, 0xBF50);
13107		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13108		WRT32_IO_REG(ha, io_base_addr, 0xBF60);
13109		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13110		WRT32_IO_REG(ha, io_base_addr, 0xBF70);
13111		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13112
13113		/* XSEQ-0 */
13114		WRT32_IO_REG(ha, io_base_addr, 0xBFE0);
13115		(void) ql_read_regs(ha, fw->xseq_0_reg, ha->iobase + 0xC0,
13116		    sizeof (fw->xseq_0_reg) / 4, 32);
13117
13118		/* XSEQ-1 */
13119		WRT32_IO_REG(ha, io_base_addr, 0xBFF0);
13120		(void) ql_read_regs(ha, fw->xseq_1_reg, ha->iobase + 0xC0,
13121		    sizeof (fw->xseq_1_reg) / 4, 32);
13122
13123		/* Receive sequence registers. */
13124
13125		/* RSEQ GP */
13126		WRT32_IO_REG(ha, io_base_addr, 0xFF00);
13127		bp = ql_read_regs(ha, fw->rseq_gp_reg, ha->iobase + 0xC0,
13128		    16, 32);
13129		WRT32_IO_REG(ha, io_base_addr, 0xFF10);
13130		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13131		WRT32_IO_REG(ha, io_base_addr, 0xFF20);
13132		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13133		WRT32_IO_REG(ha, io_base_addr, 0xFF30);
13134		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13135		WRT32_IO_REG(ha, io_base_addr, 0xFF40);
13136		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13137		WRT32_IO_REG(ha, io_base_addr, 0xFF50);
13138		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13139		WRT32_IO_REG(ha, io_base_addr, 0xFF60);
13140		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13141		WRT32_IO_REG(ha, io_base_addr, 0xFF70);
13142		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13143
13144		/* RSEQ-0 */
13145		WRT32_IO_REG(ha, io_base_addr, 0xFFD0);
13146		(void) ql_read_regs(ha, fw->rseq_0_reg, ha->iobase + 0xC0,
13147		    sizeof (fw->rseq_0_reg) / 4, 32);
13148
13149		/* RSEQ-1 */
13150		WRT32_IO_REG(ha, io_base_addr, 0xFFE0);
13151		(void) ql_read_regs(ha, fw->rseq_1_reg, ha->iobase + 0xC0,
13152		    sizeof (fw->rseq_1_reg) / 4, 32);
13153
13154		/* RSEQ-2 */
13155		WRT32_IO_REG(ha, io_base_addr, 0xFFF0);
13156		(void) ql_read_regs(ha, fw->rseq_2_reg, ha->iobase + 0xC0,
13157		    sizeof (fw->rseq_2_reg) / 4, 32);
13158
13159		/* Command DMA registers. */
13160
13161		WRT32_IO_REG(ha, io_base_addr, 0x7100);
13162		(void) ql_read_regs(ha, fw->cmd_dma_reg, ha->iobase + 0xC0,
13163		    sizeof (fw->cmd_dma_reg) / 4, 32);
13164
13165		/* Queues. */
13166
13167		/* RequestQ0 */
13168		WRT32_IO_REG(ha, io_base_addr, 0x7200);
13169		bp = ql_read_regs(ha, fw->req0_dma_reg, ha->iobase + 0xC0,
13170		    8, 32);
13171		(void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
13172
13173		/* ResponseQ0 */
13174		WRT32_IO_REG(ha, io_base_addr, 0x7300);
13175		bp = ql_read_regs(ha, fw->resp0_dma_reg, ha->iobase + 0xC0,
13176		    8, 32);
13177		(void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
13178
13179		/* RequestQ1 */
13180		WRT32_IO_REG(ha, io_base_addr, 0x7400);
13181		bp = ql_read_regs(ha, fw->req1_dma_reg, ha->iobase + 0xC0,
13182		    8, 32);
13183		(void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
13184
13185		/* Transmit DMA registers. */
13186
13187		/* XMT0 */
13188		WRT32_IO_REG(ha, io_base_addr, 0x7600);
13189		bp = ql_read_regs(ha, fw->xmt0_dma_reg, ha->iobase + 0xC0,
13190		    16, 32);
13191		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13192		WRT32_IO_REG(ha, io_base_addr, 0x7610);
13193		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13194
13195		/* XMT1 */
13196		WRT32_IO_REG(ha, io_base_addr, 0x7620);
13197		bp = ql_read_regs(ha, fw->xmt1_dma_reg, ha->iobase + 0xC0,
13198		    16, 32);
13199		WRT32_IO_REG(ha, io_base_addr, 0x7630);
13200		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13201
13202		/* XMT2 */
13203		WRT32_IO_REG(ha, io_base_addr, 0x7640);
13204		bp = ql_read_regs(ha, fw->xmt2_dma_reg, ha->iobase + 0xC0,
13205		    16, 32);
13206		WRT32_IO_REG(ha, io_base_addr, 0x7650);
13207		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13208
13209		/* XMT3 */
13210		WRT32_IO_REG(ha, io_base_addr, 0x7660);
13211		bp = ql_read_regs(ha, fw->xmt3_dma_reg, ha->iobase + 0xC0,
13212		    16, 32);
13213		WRT32_IO_REG(ha, io_base_addr, 0x7670);
13214		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13215
13216		/* XMT4 */
13217		WRT32_IO_REG(ha, io_base_addr, 0x7680);
13218		bp = ql_read_regs(ha, fw->xmt4_dma_reg, ha->iobase + 0xC0,
13219		    16, 32);
13220		WRT32_IO_REG(ha, io_base_addr, 0x7690);
13221		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13222
13223		/* XMT Common */
13224		WRT32_IO_REG(ha, io_base_addr, 0x76A0);
13225		(void) ql_read_regs(ha, fw->xmt_data_dma_reg,
13226		    ha->iobase + 0xC0, sizeof (fw->xmt_data_dma_reg) / 4, 32);
13227
13228		/* Receive DMA registers. */
13229
13230		/* RCVThread0 */
13231		WRT32_IO_REG(ha, io_base_addr, 0x7700);
13232		bp = ql_read_regs(ha, fw->rcvt0_data_dma_reg,
13233		    ha->iobase + 0xC0, 16, 32);
13234		WRT32_IO_REG(ha, io_base_addr, 0x7710);
13235		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13236
13237		/* RCVThread1 */
13238		WRT32_IO_REG(ha, io_base_addr, 0x7720);
13239		bp = ql_read_regs(ha, fw->rcvt1_data_dma_reg,
13240		    ha->iobase + 0xC0, 16, 32);
13241		WRT32_IO_REG(ha, io_base_addr, 0x7730);
13242		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13243
13244		/* RISC registers. */
13245
13246		/* RISC GP */
13247		WRT32_IO_REG(ha, io_base_addr, 0x0F00);
13248		bp = ql_read_regs(ha, fw->risc_gp_reg, ha->iobase + 0xC0,
13249		    16, 32);
13250		WRT32_IO_REG(ha, io_base_addr, 0x0F10);
13251		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13252		WRT32_IO_REG(ha, io_base_addr, 0x0F20);
13253		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13254		WRT32_IO_REG(ha, io_base_addr, 0x0F30);
13255		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13256		WRT32_IO_REG(ha, io_base_addr, 0x0F40);
13257		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13258		WRT32_IO_REG(ha, io_base_addr, 0x0F50);
13259		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13260		WRT32_IO_REG(ha, io_base_addr, 0x0F60);
13261		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13262		WRT32_IO_REG(ha, io_base_addr, 0x0F70);
13263		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13264
13265		/* Local memory controller registers. */
13266
13267		/* LMC */
13268		WRT32_IO_REG(ha, io_base_addr, 0x3000);
13269		bp = ql_read_regs(ha, fw->lmc_reg, ha->iobase + 0xC0,
13270		    16, 32);
13271		WRT32_IO_REG(ha, io_base_addr, 0x3010);
13272		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13273		WRT32_IO_REG(ha, io_base_addr, 0x3020);
13274		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13275		WRT32_IO_REG(ha, io_base_addr, 0x3030);
13276		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13277		WRT32_IO_REG(ha, io_base_addr, 0x3040);
13278		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13279		WRT32_IO_REG(ha, io_base_addr, 0x3050);
13280		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13281		WRT32_IO_REG(ha, io_base_addr, 0x3060);
13282		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13283
13284		/* Fibre Protocol Module registers. */
13285
13286		/* FPM hardware */
13287		WRT32_IO_REG(ha, io_base_addr, 0x4000);
13288		bp = ql_read_regs(ha, fw->fpm_hdw_reg, ha->iobase + 0xC0,
13289		    16, 32);
13290		WRT32_IO_REG(ha, io_base_addr, 0x4010);
13291		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13292		WRT32_IO_REG(ha, io_base_addr, 0x4020);
13293		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13294		WRT32_IO_REG(ha, io_base_addr, 0x4030);
13295		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13296		WRT32_IO_REG(ha, io_base_addr, 0x4040);
13297		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13298		WRT32_IO_REG(ha, io_base_addr, 0x4050);
13299		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13300		WRT32_IO_REG(ha, io_base_addr, 0x4060);
13301		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13302		WRT32_IO_REG(ha, io_base_addr, 0x4070);
13303		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13304		WRT32_IO_REG(ha, io_base_addr, 0x4080);
13305		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13306		WRT32_IO_REG(ha, io_base_addr, 0x4090);
13307		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13308		WRT32_IO_REG(ha, io_base_addr, 0x40A0);
13309		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13310		WRT32_IO_REG(ha, io_base_addr, 0x40B0);
13311		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13312
13313		/* Frame Buffer registers. */
13314
13315		/* FB hardware */
13316		WRT32_IO_REG(ha, io_base_addr, 0x6000);
13317		bp = ql_read_regs(ha, fw->fb_hdw_reg, ha->iobase + 0xC0,
13318		    16, 32);
13319		WRT32_IO_REG(ha, io_base_addr, 0x6010);
13320		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13321		WRT32_IO_REG(ha, io_base_addr, 0x6020);
13322		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13323		WRT32_IO_REG(ha, io_base_addr, 0x6030);
13324		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13325		WRT32_IO_REG(ha, io_base_addr, 0x6040);
13326		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13327		WRT32_IO_REG(ha, io_base_addr, 0x6100);
13328		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13329		WRT32_IO_REG(ha, io_base_addr, 0x6130);
13330		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13331		WRT32_IO_REG(ha, io_base_addr, 0x6150);
13332		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13333		WRT32_IO_REG(ha, io_base_addr, 0x6170);
13334		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13335		WRT32_IO_REG(ha, io_base_addr, 0x6190);
13336		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13337		WRT32_IO_REG(ha, io_base_addr, 0x61B0);
13338		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13339	}
13340
13341	/* Get the request queue */
13342	if (rval == QL_SUCCESS) {
13343		uint32_t	cnt;
13344		uint32_t	*w32 = (uint32_t *)ha->request_ring_bp;
13345
13346		/* Sync DMA buffer. */
13347		(void) ddi_dma_sync(ha->hba_buf.dma_handle,
13348		    REQUEST_Q_BUFFER_OFFSET, sizeof (fw->req_q),
13349		    DDI_DMA_SYNC_FORKERNEL);
13350
13351		for (cnt = 0; cnt < sizeof (fw->req_q) / 4; cnt++) {
13352			fw->req_q[cnt] = *w32++;
13353			LITTLE_ENDIAN_32(&fw->req_q[cnt]);
13354		}
13355	}
13356
13357	/* Get the respons queue */
13358	if (rval == QL_SUCCESS) {
13359		uint32_t	cnt;
13360		uint32_t	*w32 = (uint32_t *)ha->response_ring_bp;
13361
13362		/* Sync DMA buffer. */
13363		(void) ddi_dma_sync(ha->hba_buf.dma_handle,
13364		    RESPONSE_Q_BUFFER_OFFSET, sizeof (fw->rsp_q),
13365		    DDI_DMA_SYNC_FORKERNEL);
13366
13367		for (cnt = 0; cnt < sizeof (fw->rsp_q) / 4; cnt++) {
13368			fw->rsp_q[cnt] = *w32++;
13369			LITTLE_ENDIAN_32(&fw->rsp_q[cnt]);
13370		}
13371	}
13372
13373	/* Reset RISC. */
13374	ql_reset_chip(ha);
13375
13376	/* Memory. */
13377	if (rval == QL_SUCCESS) {
13378		/* Code RAM. */
13379		rval = ql_read_risc_ram(ha, 0x20000,
13380		    sizeof (fw->code_ram) / 4, fw->code_ram);
13381	}
13382	if (rval == QL_SUCCESS) {
13383		/* External Memory. */
13384		rval = ql_read_risc_ram(ha, 0x100000,
13385		    ha->fw_ext_memory_size / 4, fw->ext_mem);
13386	}
13387
13388	/* Get the extended trace buffer */
13389	if (rval == QL_SUCCESS) {
13390		if ((ha->cfg_flags & CFG_ENABLE_FWEXTTRACE) &&
13391		    (ha->fwexttracebuf.bp != NULL)) {
13392			uint32_t	cnt;
13393			uint32_t	*w32 = ha->fwexttracebuf.bp;
13394
13395			/* Sync DMA buffer. */
13396			(void) ddi_dma_sync(ha->fwexttracebuf.dma_handle, 0,
13397			    FWEXTSIZE, DDI_DMA_SYNC_FORKERNEL);
13398
13399			for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
13400				fw->ext_trace_buf[cnt] = *w32++;
13401			}
13402		}
13403	}
13404
13405	/* Get the FC event trace buffer */
13406	if (rval == QL_SUCCESS) {
13407		if ((ha->cfg_flags & CFG_ENABLE_FWFCETRACE) &&
13408		    (ha->fwfcetracebuf.bp != NULL)) {
13409			uint32_t	cnt;
13410			uint32_t	*w32 = ha->fwfcetracebuf.bp;
13411
13412			/* Sync DMA buffer. */
13413			(void) ddi_dma_sync(ha->fwfcetracebuf.dma_handle, 0,
13414			    FWFCESIZE, DDI_DMA_SYNC_FORKERNEL);
13415
13416			for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
13417				fw->fce_trace_buf[cnt] = *w32++;
13418			}
13419		}
13420	}
13421
13422	if (rval != QL_SUCCESS) {
13423		EL(ha, "failed=%xh\n", rval);
13424	} else {
13425		/*EMPTY*/
13426		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
13427	}
13428
13429	return (rval);
13430}
13431
13432/*
13433 * ql_25xx_binary_fw_dump
13434 *
13435 * Input:
13436 *	ha:	adapter state pointer.
13437 *	fw:	firmware dump context pointer.
13438 *
13439 * Returns:
13440 *	ql local function return status code.
13441 *
13442 * Context:
13443 *	Interrupt or Kernel context, no mailbox commands allowed.
13444 */
13445static int
13446ql_25xx_binary_fw_dump(ql_adapter_state_t *ha, ql_25xx_fw_dump_t *fw)
13447{
13448	uint32_t	*reg32;
13449	void		*bp;
13450	clock_t		timer;
13451	int		rval = QL_SUCCESS;
13452
13453	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
13454	EL(ha, " started\n");
13455
13456	fw->r2h_status = RD32_IO_REG(ha, intr_info_lo);
13457
13458	/* Pause RISC. */
13459	if ((RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0) {
13460		/* Disable ISP interrupts. */
13461		WRT16_IO_REG(ha, ictrl, 0);
13462
13463		WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC);
13464		for (timer = 30000;
13465		    (RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0 &&
13466		    rval == QL_SUCCESS; timer--) {
13467			if (timer) {
13468				drv_usecwait(100);
13469				if (timer % 10000 == 0) {
13470					EL(ha, "risc pause %d\n", timer);
13471				}
13472			} else {
13473				EL(ha, "risc pause timeout\n");
13474				rval = QL_FUNCTION_TIMEOUT;
13475			}
13476		}
13477	}
13478
13479	if (rval == QL_SUCCESS) {
13480
13481		/* Host Interface registers */
13482
13483		/* HostRisc registers. */
13484		WRT32_IO_REG(ha, io_base_addr, 0x7000);
13485		bp = ql_read_regs(ha, fw->hostrisc_reg, ha->iobase + 0xC0,
13486		    16, 32);
13487		WRT32_IO_REG(ha, io_base_addr, 0x7010);
13488		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13489
13490		/* PCIe registers. */
13491		WRT32_IO_REG(ha, io_base_addr, 0x7c00);
13492		WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x1);
13493		bp = ql_read_regs(ha, fw->pcie_reg, ha->iobase + 0xC4,
13494		    3, 32);
13495		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 1, 32);
13496		WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x0);
13497
13498		/* Host interface registers. */
13499		(void) ql_read_regs(ha, fw->host_reg, ha->iobase,
13500		    sizeof (fw->host_reg) / 4, 32);
13501
13502		/* Disable ISP interrupts. */
13503
13504		WRT32_IO_REG(ha, ictrl, 0);
13505		RD32_IO_REG(ha, ictrl);
13506		ADAPTER_STATE_LOCK(ha);
13507		ha->flags &= ~INTERRUPTS_ENABLED;
13508		ADAPTER_STATE_UNLOCK(ha);
13509
13510		/* Shadow registers. */
13511
13512		WRT32_IO_REG(ha, io_base_addr, 0x0F70);
13513		RD32_IO_REG(ha, io_base_addr);
13514
13515		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13516		WRT_REG_DWORD(ha, reg32, 0xB0000000);
13517		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13518		fw->shadow_reg[0] = RD_REG_DWORD(ha, reg32);
13519
13520		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13521		WRT_REG_DWORD(ha, reg32, 0xB0100000);
13522		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13523		fw->shadow_reg[1] = RD_REG_DWORD(ha, reg32);
13524
13525		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13526		WRT_REG_DWORD(ha, reg32, 0xB0200000);
13527		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13528		fw->shadow_reg[2] = RD_REG_DWORD(ha, reg32);
13529
13530		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13531		WRT_REG_DWORD(ha, reg32, 0xB0300000);
13532		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13533		fw->shadow_reg[3] = RD_REG_DWORD(ha, reg32);
13534
13535		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13536		WRT_REG_DWORD(ha, reg32, 0xB0400000);
13537		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13538		fw->shadow_reg[4] = RD_REG_DWORD(ha, reg32);
13539
13540		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13541		WRT_REG_DWORD(ha, reg32, 0xB0500000);
13542		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13543		fw->shadow_reg[5] = RD_REG_DWORD(ha, reg32);
13544
13545		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13546		WRT_REG_DWORD(ha, reg32, 0xB0600000);
13547		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13548		fw->shadow_reg[6] = RD_REG_DWORD(ha, reg32);
13549
13550		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13551		WRT_REG_DWORD(ha, reg32, 0xB0700000);
13552		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13553		fw->shadow_reg[7] = RD_REG_DWORD(ha, reg32);
13554
13555		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13556		WRT_REG_DWORD(ha, reg32, 0xB0800000);
13557		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13558		fw->shadow_reg[8] = RD_REG_DWORD(ha, reg32);
13559
13560		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13561		WRT_REG_DWORD(ha, reg32, 0xB0900000);
13562		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13563		fw->shadow_reg[9] = RD_REG_DWORD(ha, reg32);
13564
13565		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13566		WRT_REG_DWORD(ha, reg32, 0xB0A00000);
13567		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13568		fw->shadow_reg[0xa] = RD_REG_DWORD(ha, reg32);
13569
13570		/* RISC I/O register. */
13571
13572		WRT32_IO_REG(ha, io_base_addr, 0x0010);
13573		(void) ql_read_regs(ha, &fw->risc_io, ha->iobase + 0xC0,
13574		    1, 32);
13575
13576		/* Mailbox registers. */
13577
13578		(void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x80,
13579		    sizeof (fw->mailbox_reg) / 2, 16);
13580
13581		/* Transfer sequence registers. */
13582
13583		/* XSEQ GP */
13584		WRT32_IO_REG(ha, io_base_addr, 0xBF00);
13585		bp = ql_read_regs(ha, fw->xseq_gp_reg, ha->iobase + 0xC0,
13586		    16, 32);
13587		WRT32_IO_REG(ha, io_base_addr, 0xBF10);
13588		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13589		WRT32_IO_REG(ha, io_base_addr, 0xBF20);
13590		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13591		WRT32_IO_REG(ha, io_base_addr, 0xBF30);
13592		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13593		WRT32_IO_REG(ha, io_base_addr, 0xBF40);
13594		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13595		WRT32_IO_REG(ha, io_base_addr, 0xBF50);
13596		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13597		WRT32_IO_REG(ha, io_base_addr, 0xBF60);
13598		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13599		WRT32_IO_REG(ha, io_base_addr, 0xBF70);
13600		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13601
13602		/* XSEQ-0 */
13603		WRT32_IO_REG(ha, io_base_addr, 0xBFC0);
13604		bp = ql_read_regs(ha, fw->xseq_0_reg, ha->iobase + 0xC0,
13605		    16, 32);
13606		WRT32_IO_REG(ha, io_base_addr, 0xBFD0);
13607		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13608		WRT32_IO_REG(ha, io_base_addr, 0xBFE0);
13609		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13610
13611		/* XSEQ-1 */
13612		WRT32_IO_REG(ha, io_base_addr, 0xBFF0);
13613		(void) ql_read_regs(ha, fw->xseq_1_reg, ha->iobase + 0xC0,
13614		    16, 32);
13615
13616		/* Receive sequence registers. */
13617
13618		/* RSEQ GP */
13619		WRT32_IO_REG(ha, io_base_addr, 0xFF00);
13620		bp = ql_read_regs(ha, fw->rseq_gp_reg, ha->iobase + 0xC0,
13621		    16, 32);
13622		WRT32_IO_REG(ha, io_base_addr, 0xFF10);
13623		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13624		WRT32_IO_REG(ha, io_base_addr, 0xFF20);
13625		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13626		WRT32_IO_REG(ha, io_base_addr, 0xFF30);
13627		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13628		WRT32_IO_REG(ha, io_base_addr, 0xFF40);
13629		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13630		WRT32_IO_REG(ha, io_base_addr, 0xFF50);
13631		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13632		WRT32_IO_REG(ha, io_base_addr, 0xFF60);
13633		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13634		WRT32_IO_REG(ha, io_base_addr, 0xFF70);
13635		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13636
13637		/* RSEQ-0 */
13638		WRT32_IO_REG(ha, io_base_addr, 0xFFC0);
13639		bp = ql_read_regs(ha, fw->rseq_0_reg, ha->iobase + 0xC0,
13640		    16, 32);
13641		WRT32_IO_REG(ha, io_base_addr, 0xFFD0);
13642		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13643
13644		/* RSEQ-1 */
13645		WRT32_IO_REG(ha, io_base_addr, 0xFFE0);
13646		(void) ql_read_regs(ha, fw->rseq_1_reg, ha->iobase + 0xC0,
13647		    sizeof (fw->rseq_1_reg) / 4, 32);
13648
13649		/* RSEQ-2 */
13650		WRT32_IO_REG(ha, io_base_addr, 0xFFF0);
13651		(void) ql_read_regs(ha, fw->rseq_2_reg, ha->iobase + 0xC0,
13652		    sizeof (fw->rseq_2_reg) / 4, 32);
13653
13654		/* Auxiliary sequencer registers. */
13655
13656		/* ASEQ GP */
13657		WRT32_IO_REG(ha, io_base_addr, 0xB000);
13658		bp = ql_read_regs(ha, fw->aseq_gp_reg, ha->iobase + 0xC0,
13659		    16, 32);
13660		WRT32_IO_REG(ha, io_base_addr, 0xB010);
13661		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13662		WRT32_IO_REG(ha, io_base_addr, 0xB020);
13663		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13664		WRT32_IO_REG(ha, io_base_addr, 0xB030);
13665		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13666		WRT32_IO_REG(ha, io_base_addr, 0xB040);
13667		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13668		WRT32_IO_REG(ha, io_base_addr, 0xB050);
13669		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13670		WRT32_IO_REG(ha, io_base_addr, 0xB060);
13671		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13672		WRT32_IO_REG(ha, io_base_addr, 0xB070);
13673		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13674
13675		/* ASEQ-0 */
13676		WRT32_IO_REG(ha, io_base_addr, 0xB0C0);
13677		bp = ql_read_regs(ha, fw->aseq_0_reg, ha->iobase + 0xC0,
13678		    16, 32);
13679		WRT32_IO_REG(ha, io_base_addr, 0xB0D0);
13680		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13681
13682		/* ASEQ-1 */
13683		WRT32_IO_REG(ha, io_base_addr, 0xB0E0);
13684		(void) ql_read_regs(ha, fw->aseq_1_reg, ha->iobase + 0xC0,
13685		    16, 32);
13686
13687		/* ASEQ-2 */
13688		WRT32_IO_REG(ha, io_base_addr, 0xB0F0);
13689		(void) ql_read_regs(ha, fw->aseq_2_reg, ha->iobase + 0xC0,
13690		    16, 32);
13691
13692		/* Command DMA registers. */
13693
13694		WRT32_IO_REG(ha, io_base_addr, 0x7100);
13695		(void) ql_read_regs(ha, fw->cmd_dma_reg, ha->iobase + 0xC0,
13696		    sizeof (fw->cmd_dma_reg) / 4, 32);
13697
13698		/* Queues. */
13699
13700		/* RequestQ0 */
13701		WRT32_IO_REG(ha, io_base_addr, 0x7200);
13702		bp = ql_read_regs(ha, fw->req0_dma_reg, ha->iobase + 0xC0,
13703		    8, 32);
13704		(void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
13705
13706		/* ResponseQ0 */
13707		WRT32_IO_REG(ha, io_base_addr, 0x7300);
13708		bp = ql_read_regs(ha, fw->resp0_dma_reg, ha->iobase + 0xC0,
13709		    8, 32);
13710		(void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
13711
13712		/* RequestQ1 */
13713		WRT32_IO_REG(ha, io_base_addr, 0x7400);
13714		bp = ql_read_regs(ha, fw->req1_dma_reg, ha->iobase + 0xC0,
13715		    8, 32);
13716		(void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
13717
13718		/* Transmit DMA registers. */
13719
13720		/* XMT0 */
13721		WRT32_IO_REG(ha, io_base_addr, 0x7600);
13722		bp = ql_read_regs(ha, fw->xmt0_dma_reg, ha->iobase + 0xC0,
13723		    16, 32);
13724		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13725		WRT32_IO_REG(ha, io_base_addr, 0x7610);
13726		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13727
13728		/* XMT1 */
13729		WRT32_IO_REG(ha, io_base_addr, 0x7620);
13730		bp = ql_read_regs(ha, fw->xmt1_dma_reg, ha->iobase + 0xC0,
13731		    16, 32);
13732		WRT32_IO_REG(ha, io_base_addr, 0x7630);
13733		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13734
13735		/* XMT2 */
13736		WRT32_IO_REG(ha, io_base_addr, 0x7640);
13737		bp = ql_read_regs(ha, fw->xmt2_dma_reg, ha->iobase + 0xC0,
13738		    16, 32);
13739		WRT32_IO_REG(ha, io_base_addr, 0x7650);
13740		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13741
13742		/* XMT3 */
13743		WRT32_IO_REG(ha, io_base_addr, 0x7660);
13744		bp = ql_read_regs(ha, fw->xmt3_dma_reg, ha->iobase + 0xC0,
13745		    16, 32);
13746		WRT32_IO_REG(ha, io_base_addr, 0x7670);
13747		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13748
13749		/* XMT4 */
13750		WRT32_IO_REG(ha, io_base_addr, 0x7680);
13751		bp = ql_read_regs(ha, fw->xmt4_dma_reg, ha->iobase + 0xC0,
13752		    16, 32);
13753		WRT32_IO_REG(ha, io_base_addr, 0x7690);
13754		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13755
13756		/* XMT Common */
13757		WRT32_IO_REG(ha, io_base_addr, 0x76A0);
13758		(void) ql_read_regs(ha, fw->xmt_data_dma_reg,
13759		    ha->iobase + 0xC0, sizeof (fw->xmt_data_dma_reg) / 4, 32);
13760
13761		/* Receive DMA registers. */
13762
13763		/* RCVThread0 */
13764		WRT32_IO_REG(ha, io_base_addr, 0x7700);
13765		bp = ql_read_regs(ha, fw->rcvt0_data_dma_reg,
13766		    ha->iobase + 0xC0, 16, 32);
13767		WRT32_IO_REG(ha, io_base_addr, 0x7710);
13768		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13769
13770		/* RCVThread1 */
13771		WRT32_IO_REG(ha, io_base_addr, 0x7720);
13772		bp = ql_read_regs(ha, fw->rcvt1_data_dma_reg,
13773		    ha->iobase + 0xC0, 16, 32);
13774		WRT32_IO_REG(ha, io_base_addr, 0x7730);
13775		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13776
13777		/* RISC registers. */
13778
13779		/* RISC GP */
13780		WRT32_IO_REG(ha, io_base_addr, 0x0F00);
13781		bp = ql_read_regs(ha, fw->risc_gp_reg, ha->iobase + 0xC0,
13782		    16, 32);
13783		WRT32_IO_REG(ha, io_base_addr, 0x0F10);
13784		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13785		WRT32_IO_REG(ha, io_base_addr, 0x0F20);
13786		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13787		WRT32_IO_REG(ha, io_base_addr, 0x0F30);
13788		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13789		WRT32_IO_REG(ha, io_base_addr, 0x0F40);
13790		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13791		WRT32_IO_REG(ha, io_base_addr, 0x0F50);
13792		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13793		WRT32_IO_REG(ha, io_base_addr, 0x0F60);
13794		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13795		WRT32_IO_REG(ha, io_base_addr, 0x0F70);
13796		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13797
13798		/* Local memory controller (LMC) registers. */
13799
13800		/* LMC */
13801		WRT32_IO_REG(ha, io_base_addr, 0x3000);
13802		bp = ql_read_regs(ha, fw->lmc_reg, ha->iobase + 0xC0,
13803		    16, 32);
13804		WRT32_IO_REG(ha, io_base_addr, 0x3010);
13805		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13806		WRT32_IO_REG(ha, io_base_addr, 0x3020);
13807		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13808		WRT32_IO_REG(ha, io_base_addr, 0x3030);
13809		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13810		WRT32_IO_REG(ha, io_base_addr, 0x3040);
13811		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13812		WRT32_IO_REG(ha, io_base_addr, 0x3050);
13813		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13814		WRT32_IO_REG(ha, io_base_addr, 0x3060);
13815		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13816		WRT32_IO_REG(ha, io_base_addr, 0x3070);
13817		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13818
13819		/* Fibre Protocol Module registers. */
13820
13821		/* FPM hardware */
13822		WRT32_IO_REG(ha, io_base_addr, 0x4000);
13823		bp = ql_read_regs(ha, fw->fpm_hdw_reg, ha->iobase + 0xC0,
13824		    16, 32);
13825		WRT32_IO_REG(ha, io_base_addr, 0x4010);
13826		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13827		WRT32_IO_REG(ha, io_base_addr, 0x4020);
13828		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13829		WRT32_IO_REG(ha, io_base_addr, 0x4030);
13830		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13831		WRT32_IO_REG(ha, io_base_addr, 0x4040);
13832		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13833		WRT32_IO_REG(ha, io_base_addr, 0x4050);
13834		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13835		WRT32_IO_REG(ha, io_base_addr, 0x4060);
13836		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13837		WRT32_IO_REG(ha, io_base_addr, 0x4070);
13838		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13839		WRT32_IO_REG(ha, io_base_addr, 0x4080);
13840		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13841		WRT32_IO_REG(ha, io_base_addr, 0x4090);
13842		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13843		WRT32_IO_REG(ha, io_base_addr, 0x40A0);
13844		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13845		WRT32_IO_REG(ha, io_base_addr, 0x40B0);
13846		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13847
13848		/* Frame Buffer registers. */
13849
13850		/* FB hardware */
13851		WRT32_IO_REG(ha, io_base_addr, 0x6000);
13852		bp = ql_read_regs(ha, fw->fb_hdw_reg, ha->iobase + 0xC0,
13853		    16, 32);
13854		WRT32_IO_REG(ha, io_base_addr, 0x6010);
13855		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13856		WRT32_IO_REG(ha, io_base_addr, 0x6020);
13857		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13858		WRT32_IO_REG(ha, io_base_addr, 0x6030);
13859		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13860		WRT32_IO_REG(ha, io_base_addr, 0x6040);
13861		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13862		WRT32_IO_REG(ha, io_base_addr, 0x6100);
13863		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13864		WRT32_IO_REG(ha, io_base_addr, 0x6130);
13865		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13866		WRT32_IO_REG(ha, io_base_addr, 0x6150);
13867		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13868		WRT32_IO_REG(ha, io_base_addr, 0x6170);
13869		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13870		WRT32_IO_REG(ha, io_base_addr, 0x6190);
13871		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13872		WRT32_IO_REG(ha, io_base_addr, 0x61B0);
13873		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13874		WRT32_IO_REG(ha, io_base_addr, 0x6F00);
13875		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13876	}
13877
13878	/* Get the request queue */
13879	if (rval == QL_SUCCESS) {
13880		uint32_t	cnt;
13881		uint32_t	*w32 = (uint32_t *)ha->request_ring_bp;
13882
13883		/* Sync DMA buffer. */
13884		(void) ddi_dma_sync(ha->hba_buf.dma_handle,
13885		    REQUEST_Q_BUFFER_OFFSET, sizeof (fw->req_q),
13886		    DDI_DMA_SYNC_FORKERNEL);
13887
13888		for (cnt = 0; cnt < sizeof (fw->req_q) / 4; cnt++) {
13889			fw->req_q[cnt] = *w32++;
13890			LITTLE_ENDIAN_32(&fw->req_q[cnt]);
13891		}
13892	}
13893
13894	/* Get the respons queue */
13895	if (rval == QL_SUCCESS) {
13896		uint32_t	cnt;
13897		uint32_t	*w32 = (uint32_t *)ha->response_ring_bp;
13898
13899		/* Sync DMA buffer. */
13900		(void) ddi_dma_sync(ha->hba_buf.dma_handle,
13901		    RESPONSE_Q_BUFFER_OFFSET, sizeof (fw->rsp_q),
13902		    DDI_DMA_SYNC_FORKERNEL);
13903
13904		for (cnt = 0; cnt < sizeof (fw->rsp_q) / 4; cnt++) {
13905			fw->rsp_q[cnt] = *w32++;
13906			LITTLE_ENDIAN_32(&fw->rsp_q[cnt]);
13907		}
13908	}
13909
13910	/* Reset RISC. */
13911
13912	ql_reset_chip(ha);
13913
13914	/* Memory. */
13915
13916	if (rval == QL_SUCCESS) {
13917		/* Code RAM. */
13918		rval = ql_read_risc_ram(ha, 0x20000,
13919		    sizeof (fw->code_ram) / 4, fw->code_ram);
13920	}
13921	if (rval == QL_SUCCESS) {
13922		/* External Memory. */
13923		rval = ql_read_risc_ram(ha, 0x100000,
13924		    ha->fw_ext_memory_size / 4, fw->ext_mem);
13925	}
13926
13927	/* Get the FC event trace buffer */
13928	if (rval == QL_SUCCESS) {
13929		if ((ha->cfg_flags & CFG_ENABLE_FWFCETRACE) &&
13930		    (ha->fwfcetracebuf.bp != NULL)) {
13931			uint32_t	cnt;
13932			uint32_t	*w32 = ha->fwfcetracebuf.bp;
13933
13934			/* Sync DMA buffer. */
13935			(void) ddi_dma_sync(ha->fwfcetracebuf.dma_handle, 0,
13936			    FWFCESIZE, DDI_DMA_SYNC_FORKERNEL);
13937
13938			for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
13939				fw->fce_trace_buf[cnt] = *w32++;
13940			}
13941		}
13942	}
13943
13944	/* Get the extended trace buffer */
13945	if (rval == QL_SUCCESS) {
13946		if ((ha->cfg_flags & CFG_ENABLE_FWEXTTRACE) &&
13947		    (ha->fwexttracebuf.bp != NULL)) {
13948			uint32_t	cnt;
13949			uint32_t	*w32 = ha->fwexttracebuf.bp;
13950
13951			/* Sync DMA buffer. */
13952			(void) ddi_dma_sync(ha->fwexttracebuf.dma_handle, 0,
13953			    FWEXTSIZE, DDI_DMA_SYNC_FORKERNEL);
13954
13955			for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
13956				fw->ext_trace_buf[cnt] = *w32++;
13957			}
13958		}
13959	}
13960
13961	if (rval != QL_SUCCESS) {
13962		EL(ha, "failed=%xh\n", rval);
13963	} else {
13964		/*EMPTY*/
13965		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
13966	}
13967
13968	return (rval);
13969}
13970
13971/*
13972 * ql_read_risc_ram
13973 *	Reads RISC RAM one word at a time.
13974 *	Risc interrupts must be disabled when this routine is called.
13975 *
13976 * Input:
13977 *	ha:	adapter state pointer.
13978 *	risc_address:	RISC code start address.
13979 *	len:		Number of words.
13980 *	buf:		buffer pointer.
13981 *
13982 * Returns:
13983 *	ql local function return status code.
13984 *
13985 * Context:
13986 *	Interrupt or Kernel context, no mailbox commands allowed.
13987 */
13988static int
13989ql_read_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint32_t len,
13990    void *buf)
13991{
13992	uint32_t	cnt;
13993	uint16_t	stat;
13994	clock_t		timer;
13995	uint16_t	*buf16 = (uint16_t *)buf;
13996	uint32_t	*buf32 = (uint32_t *)buf;
13997	int		rval = QL_SUCCESS;
13998
13999	for (cnt = 0; cnt < len; cnt++, risc_address++) {
14000		WRT16_IO_REG(ha, mailbox[0], MBC_READ_RAM_EXTENDED);
14001		WRT16_IO_REG(ha, mailbox[1], LSW(risc_address));
14002		WRT16_IO_REG(ha, mailbox[8], MSW(risc_address));
14003		CFG_IST(ha, CFG_CTRL_2425) ?
14004		    WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT) :
14005		    WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT);
14006		for (timer = 6000000; timer && rval == QL_SUCCESS; timer--) {
14007			if (RD16_IO_REG(ha, istatus) & RISC_INT) {
14008				stat = (uint16_t)
14009				    (RD16_IO_REG(ha, intr_info_lo) & 0xff);
14010				if ((stat == 1) || (stat == 0x10)) {
14011					if (CFG_IST(ha, CFG_CTRL_2425)) {
14012						buf32[cnt] = SHORT_TO_LONG(
14013						    RD16_IO_REG(ha,
14014						    mailbox[2]),
14015						    RD16_IO_REG(ha,
14016						    mailbox[3]));
14017					} else {
14018						buf16[cnt] =
14019						    RD16_IO_REG(ha, mailbox[2]);
14020					}
14021
14022					break;
14023				} else if ((stat == 2) || (stat == 0x11)) {
14024					rval = RD16_IO_REG(ha, mailbox[0]);
14025					break;
14026				}
14027				if (CFG_IST(ha, CFG_CTRL_2425)) {
14028					WRT32_IO_REG(ha, hccr,
14029					    HC24_CLR_RISC_INT);
14030					RD32_IO_REG(ha, hccr);
14031				} else {
14032					WRT16_IO_REG(ha, hccr,
14033					    HC_CLR_RISC_INT);
14034				}
14035			}
14036			drv_usecwait(5);
14037		}
14038		if (CFG_IST(ha, CFG_CTRL_2425)) {
14039			WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
14040			RD32_IO_REG(ha, hccr);
14041		} else {
14042			WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
14043			WRT16_IO_REG(ha, semaphore, 0);
14044		}
14045
14046		if (timer == 0) {
14047			rval = QL_FUNCTION_TIMEOUT;
14048		}
14049	}
14050
14051	return (rval);
14052}
14053
14054/*
14055 * ql_read_regs
14056 *	Reads adapter registers to buffer.
14057 *
14058 * Input:
14059 *	ha:	adapter state pointer.
14060 *	buf:	buffer pointer.
14061 *	reg:	start address.
14062 *	count:	number of registers.
14063 *	wds:	register size.
14064 *
14065 * Context:
14066 *	Interrupt or Kernel context, no mailbox commands allowed.
14067 */
14068static void *
14069ql_read_regs(ql_adapter_state_t *ha, void *buf, void *reg, uint32_t count,
14070    uint8_t wds)
14071{
14072	uint32_t	*bp32, *reg32;
14073	uint16_t	*bp16, *reg16;
14074	uint8_t		*bp8, *reg8;
14075
14076	switch (wds) {
14077	case 32:
14078		bp32 = buf;
14079		reg32 = reg;
14080		while (count--) {
14081			*bp32++ = RD_REG_DWORD(ha, reg32++);
14082		}
14083		return (bp32);
14084	case 16:
14085		bp16 = buf;
14086		reg16 = reg;
14087		while (count--) {
14088			*bp16++ = RD_REG_WORD(ha, reg16++);
14089		}
14090		return (bp16);
14091	case 8:
14092		bp8 = buf;
14093		reg8 = reg;
14094		while (count--) {
14095			*bp8++ = RD_REG_BYTE(ha, reg8++);
14096		}
14097		return (bp8);
14098	default:
14099		EL(ha, "Unknown word size=%d\n", wds);
14100		return (buf);
14101	}
14102}
14103
14104static int
14105ql_save_config_regs(dev_info_t *dip)
14106{
14107	ql_adapter_state_t	*ha;
14108	int			ret;
14109	ql_config_space_t	chs;
14110	caddr_t			prop = "ql-config-space";
14111
14112	ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
14113	ASSERT(ha != NULL);
14114	if (ha == NULL) {
14115		QL_PRINT_2(CE_CONT, "no adapter ptr\n");
14116		return (DDI_FAILURE);
14117	}
14118
14119	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
14120
14121	/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
14122	if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, prop) ==
14123	    1) {
14124		QL_PRINT_2(CE_CONT, "(%d): no prop exit\n", ha->instance);
14125		return (DDI_SUCCESS);
14126	}
14127
14128	chs.chs_command = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM);
14129	chs.chs_header_type = (uint8_t)ql_pci_config_get8(ha,
14130	    PCI_CONF_HEADER);
14131	if ((chs.chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
14132		chs.chs_bridge_control = (uint8_t)ql_pci_config_get8(ha,
14133		    PCI_BCNF_BCNTRL);
14134	}
14135
14136	chs.chs_cache_line_size = (uint8_t)ql_pci_config_get8(ha,
14137	    PCI_CONF_CACHE_LINESZ);
14138
14139	chs.chs_latency_timer = (uint8_t)ql_pci_config_get8(ha,
14140	    PCI_CONF_LATENCY_TIMER);
14141
14142	if ((chs.chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
14143		chs.chs_sec_latency_timer = (uint8_t)ql_pci_config_get8(ha,
14144		    PCI_BCNF_LATENCY_TIMER);
14145	}
14146
14147	chs.chs_base0 = ql_pci_config_get32(ha, PCI_CONF_BASE0);
14148	chs.chs_base1 = ql_pci_config_get32(ha, PCI_CONF_BASE1);
14149	chs.chs_base2 = ql_pci_config_get32(ha, PCI_CONF_BASE2);
14150	chs.chs_base3 = ql_pci_config_get32(ha, PCI_CONF_BASE3);
14151	chs.chs_base4 = ql_pci_config_get32(ha, PCI_CONF_BASE4);
14152	chs.chs_base5 = ql_pci_config_get32(ha, PCI_CONF_BASE5);
14153
14154	/*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/
14155	ret = ndi_prop_update_byte_array(DDI_DEV_T_NONE, dip, prop,
14156	    (uchar_t *)&chs, sizeof (ql_config_space_t));
14157
14158	if (ret != DDI_PROP_SUCCESS) {
14159		cmn_err(CE_WARN, "!Qlogic %s(%d) can't update prop %s",
14160		    QL_NAME, ddi_get_instance(dip), prop);
14161		return (DDI_FAILURE);
14162	}
14163
14164	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
14165
14166	return (DDI_SUCCESS);
14167}
14168
14169static int
14170ql_restore_config_regs(dev_info_t *dip)
14171{
14172	ql_adapter_state_t	*ha;
14173	uint_t			elements;
14174	ql_config_space_t	*chs_p;
14175	caddr_t			prop = "ql-config-space";
14176
14177	ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
14178	ASSERT(ha != NULL);
14179	if (ha == NULL) {
14180		QL_PRINT_2(CE_CONT, "no adapter ptr\n");
14181		return (DDI_FAILURE);
14182	}
14183
14184	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
14185
14186	/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
14187	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip,
14188	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, prop,
14189	    (uchar_t **)&chs_p, &elements) != DDI_PROP_SUCCESS) {
14190		QL_PRINT_2(CE_CONT, "(%d): no prop exit\n", ha->instance);
14191		return (DDI_FAILURE);
14192	}
14193
14194	ql_pci_config_put16(ha, PCI_CONF_COMM, chs_p->chs_command);
14195
14196	if ((chs_p->chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
14197		ql_pci_config_put16(ha, PCI_BCNF_BCNTRL,
14198		    chs_p->chs_bridge_control);
14199	}
14200
14201	ql_pci_config_put8(ha, PCI_CONF_CACHE_LINESZ,
14202	    chs_p->chs_cache_line_size);
14203
14204	ql_pci_config_put8(ha, PCI_CONF_LATENCY_TIMER,
14205	    chs_p->chs_latency_timer);
14206
14207	if ((chs_p->chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
14208		ql_pci_config_put8(ha, PCI_BCNF_LATENCY_TIMER,
14209		    chs_p->chs_sec_latency_timer);
14210	}
14211
14212	ql_pci_config_put32(ha, PCI_CONF_BASE0, chs_p->chs_base0);
14213	ql_pci_config_put32(ha, PCI_CONF_BASE1, chs_p->chs_base1);
14214	ql_pci_config_put32(ha, PCI_CONF_BASE2, chs_p->chs_base2);
14215	ql_pci_config_put32(ha, PCI_CONF_BASE3, chs_p->chs_base3);
14216	ql_pci_config_put32(ha, PCI_CONF_BASE4, chs_p->chs_base4);
14217	ql_pci_config_put32(ha, PCI_CONF_BASE5, chs_p->chs_base5);
14218
14219	ddi_prop_free(chs_p);
14220
14221	/*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/
14222	if (ndi_prop_remove(DDI_DEV_T_NONE, dip, prop) != DDI_PROP_SUCCESS) {
14223		cmn_err(CE_WARN, "!Qlogic %s(%d): can't remove prop %s",
14224		    QL_NAME, ddi_get_instance(dip), prop);
14225	}
14226
14227	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
14228
14229	return (DDI_SUCCESS);
14230}
14231
14232uint8_t
14233ql_pci_config_get8(ql_adapter_state_t *ha, off_t off)
14234{
14235	if (CFG_IST(ha, CFG_SBUS_CARD)) {
14236		return (ddi_get8(ha->sbus_config_handle,
14237		    (uint8_t *)(ha->sbus_config_base + off)));
14238	}
14239
14240#ifdef KERNEL_32
14241	return (pci_config_getb(ha->pci_handle, off));
14242#else
14243	return (pci_config_get8(ha->pci_handle, off));
14244#endif
14245}
14246
14247uint16_t
14248ql_pci_config_get16(ql_adapter_state_t *ha, off_t off)
14249{
14250	if (CFG_IST(ha, CFG_SBUS_CARD)) {
14251		return (ddi_get16(ha->sbus_config_handle,
14252		    (uint16_t *)(ha->sbus_config_base + off)));
14253	}
14254
14255#ifdef KERNEL_32
14256	return (pci_config_getw(ha->pci_handle, off));
14257#else
14258	return (pci_config_get16(ha->pci_handle, off));
14259#endif
14260}
14261
14262uint32_t
14263ql_pci_config_get32(ql_adapter_state_t *ha, off_t off)
14264{
14265	if (CFG_IST(ha, CFG_SBUS_CARD)) {
14266		return (ddi_get32(ha->sbus_config_handle,
14267		    (uint32_t *)(ha->sbus_config_base + off)));
14268	}
14269
14270#ifdef KERNEL_32
14271	return (pci_config_getl(ha->pci_handle, off));
14272#else
14273	return (pci_config_get32(ha->pci_handle, off));
14274#endif
14275}
14276
14277void
14278ql_pci_config_put8(ql_adapter_state_t *ha, off_t off, uint8_t val)
14279{
14280	if (CFG_IST(ha, CFG_SBUS_CARD)) {
14281		ddi_put8(ha->sbus_config_handle,
14282		    (uint8_t *)(ha->sbus_config_base + off), val);
14283	} else {
14284#ifdef KERNEL_32
14285		pci_config_putb(ha->pci_handle, off, val);
14286#else
14287		pci_config_put8(ha->pci_handle, off, val);
14288#endif
14289	}
14290}
14291
14292void
14293ql_pci_config_put16(ql_adapter_state_t *ha, off_t off, uint16_t val)
14294{
14295	if (CFG_IST(ha, CFG_SBUS_CARD)) {
14296		ddi_put16(ha->sbus_config_handle,
14297		    (uint16_t *)(ha->sbus_config_base + off), val);
14298	} else {
14299#ifdef KERNEL_32
14300		pci_config_putw(ha->pci_handle, off, val);
14301#else
14302		pci_config_put16(ha->pci_handle, off, val);
14303#endif
14304	}
14305}
14306
14307void
14308ql_pci_config_put32(ql_adapter_state_t *ha, off_t off, uint32_t val)
14309{
14310	if (CFG_IST(ha, CFG_SBUS_CARD)) {
14311		ddi_put32(ha->sbus_config_handle,
14312		    (uint32_t *)(ha->sbus_config_base + off), val);
14313	} else {
14314#ifdef KERNEL_32
14315		pci_config_putl(ha->pci_handle, off, val);
14316#else
14317		pci_config_put32(ha->pci_handle, off, val);
14318#endif
14319	}
14320}
14321
14322/*
14323 * ql_halt
14324 *	Waits for commands that are running to finish and
14325 *	if they do not, commands are aborted.
14326 *	Finally the adapter is reset.
14327 *
14328 * Input:
14329 *	ha:	adapter state pointer.
14330 *	pwr:	power state.
14331 *
14332 * Context:
14333 *	Kernel context.
14334 */
14335static void
14336ql_halt(ql_adapter_state_t *ha, int pwr)
14337{
14338	uint32_t	cnt;
14339	ql_tgt_t	*tq;
14340	ql_srb_t	*sp;
14341	uint16_t	index;
14342	ql_link_t	*link;
14343
14344	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
14345
14346	/* Wait for all commands running to finish. */
14347	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
14348		for (link = ha->dev[index].first; link != NULL;
14349		    link = link->next) {
14350			tq = link->base_address;
14351			(void) ql_abort_device(ha, tq, 0);
14352
14353			/* Wait for 30 seconds for commands to finish. */
14354			for (cnt = 3000; cnt != 0; cnt--) {
14355				/* Acquire device queue lock. */
14356				DEVICE_QUEUE_LOCK(tq);
14357				if (tq->outcnt == 0) {
14358					/* Release device queue lock. */
14359					DEVICE_QUEUE_UNLOCK(tq);
14360					break;
14361				} else {
14362					/* Release device queue lock. */
14363					DEVICE_QUEUE_UNLOCK(tq);
14364					ql_delay(ha, 10000);
14365				}
14366			}
14367
14368			/* Finish any commands waiting for more status. */
14369			if (ha->status_srb != NULL) {
14370				sp = ha->status_srb;
14371				ha->status_srb = NULL;
14372				sp->cmd.next = NULL;
14373				ql_done(&sp->cmd);
14374			}
14375
14376			/* Abort commands that did not finish. */
14377			if (cnt == 0) {
14378				for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS;
14379				    cnt++) {
14380					if (ha->pending_cmds.first != NULL) {
14381						ql_start_iocb(ha, NULL);
14382						cnt = 1;
14383					}
14384					sp = ha->outstanding_cmds[cnt];
14385					if (sp != NULL &&
14386					    sp->lun_queue->target_queue ==
14387					    tq) {
14388						(void) ql_abort((opaque_t)ha,
14389						    sp->pkt, 0);
14390					}
14391				}
14392			}
14393		}
14394	}
14395
14396	/* Shutdown IP. */
14397	if (ha->flags & IP_INITIALIZED) {
14398		(void) ql_shutdown_ip(ha);
14399	}
14400
14401	/* Stop all timers. */
14402	ADAPTER_STATE_LOCK(ha);
14403	ha->port_retry_timer = 0;
14404	ha->loop_down_timer = LOOP_DOWN_TIMER_OFF;
14405	ha->watchdog_timer = 0;
14406	ADAPTER_STATE_UNLOCK(ha);
14407
14408	if (pwr == PM_LEVEL_D3) {
14409		ADAPTER_STATE_LOCK(ha);
14410		ha->flags &= ~ONLINE;
14411		ADAPTER_STATE_UNLOCK(ha);
14412
14413		/* Reset ISP chip. */
14414		ql_reset_chip(ha);
14415	}
14416
14417	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
14418}
14419
14420/*
14421 * ql_get_dma_mem
14422 *	Function used to allocate dma memory.
14423 *
14424 * Input:
14425 *	ha:			adapter state pointer.
14426 *	mem:			pointer to dma memory object.
14427 *	size:			size of the request in bytes
14428 *
14429 * Returns:
14430 *	qn local function return status code.
14431 *
14432 * Context:
14433 *	Kernel context.
14434 */
14435int
14436ql_get_dma_mem(ql_adapter_state_t *ha, dma_mem_t *mem, uint32_t size,
14437    mem_alloc_type_t allocation_type, mem_alignment_t alignment)
14438{
14439	int	rval;
14440
14441	QL_PRINT_9(CE_CONT, "(%d): entered\n", ha->instance);
14442
14443	mem->size = size;
14444	mem->type = allocation_type;
14445	mem->cookie_count = 1;
14446
14447	switch (alignment) {
14448	case QL_DMA_DATA_ALIGN:
14449		mem->alignment = QL_DMA_ALIGN_8_BYTE_BOUNDARY;
14450		break;
14451	case QL_DMA_RING_ALIGN:
14452		mem->alignment = QL_DMA_ALIGN_64_BYTE_BOUNDARY;
14453		break;
14454	default:
14455		EL(ha, "failed, unknown alignment type %x\n", alignment);
14456		break;
14457	}
14458
14459	if ((rval = ql_alloc_phys(ha, mem, KM_SLEEP)) != QL_SUCCESS) {
14460		ql_free_phys(ha, mem);
14461		EL(ha, "failed, alloc_phys=%xh\n", rval);
14462	}
14463
14464	QL_PRINT_9(CE_CONT, "(%d): exiting\n", ha->instance);
14465
14466	return (rval);
14467}
14468
14469/*
14470 * ql_alloc_phys
14471 *	Function used to allocate memory and zero it.
14472 *	Memory is below 4 GB.
14473 *
14474 * Input:
14475 *	ha:			adapter state pointer.
14476 *	mem:			pointer to dma memory object.
14477 *	sleep:			KM_SLEEP/KM_NOSLEEP flag.
14478 *	mem->cookie_count	number of segments allowed.
14479 *	mem->type		memory allocation type.
14480 *	mem->size		memory size.
14481 *	mem->alignment		memory alignment.
14482 *
14483 * Returns:
14484 *	qn local function return status code.
14485 *
14486 * Context:
14487 *	Kernel context.
14488 */
14489int
14490ql_alloc_phys(ql_adapter_state_t *ha, dma_mem_t *mem, int sleep)
14491{
14492	size_t			rlen;
14493	ddi_dma_attr_t		dma_attr;
14494	ddi_device_acc_attr_t	acc_attr = ql_dev_acc_attr;
14495
14496	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
14497
14498	dma_attr = CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING) ?
14499	    ql_64bit_io_dma_attr : ql_32bit_io_dma_attr;
14500
14501	dma_attr.dma_attr_align = mem->alignment; /* DMA address alignment */
14502	dma_attr.dma_attr_sgllen = (int)mem->cookie_count;
14503
14504	/*
14505	 * Workaround for SUN XMITS buffer must end and start on 8 byte
14506	 * boundary. Else, hardware will overrun the buffer. Simple fix is
14507	 * to make sure buffer has enough room for overrun.
14508	 */
14509	if (mem->size & 7) {
14510		mem->size += 8 - (mem->size & 7);
14511	}
14512
14513	mem->flags = DDI_DMA_CONSISTENT;
14514
14515	/*
14516	 * Allocate DMA memory for command.
14517	 */
14518	if (ddi_dma_alloc_handle(ha->dip, &dma_attr, (sleep == KM_SLEEP) ?
14519	    DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &mem->dma_handle) !=
14520	    DDI_SUCCESS) {
14521		EL(ha, "failed, ddi_dma_alloc_handle\n");
14522		mem->dma_handle = NULL;
14523		return (QL_MEMORY_ALLOC_FAILED);
14524	}
14525
14526	switch (mem->type) {
14527	case KERNEL_MEM:
14528		mem->bp = kmem_zalloc(mem->size, sleep);
14529		break;
14530	case BIG_ENDIAN_DMA:
14531	case LITTLE_ENDIAN_DMA:
14532	case NO_SWAP_DMA:
14533		if (mem->type == BIG_ENDIAN_DMA) {
14534			acc_attr.devacc_attr_endian_flags =
14535			    DDI_STRUCTURE_BE_ACC;
14536		} else if (mem->type == NO_SWAP_DMA) {
14537			acc_attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
14538		}
14539		if (ddi_dma_mem_alloc(mem->dma_handle, mem->size, &acc_attr,
14540		    mem->flags, (sleep == KM_SLEEP) ? DDI_DMA_SLEEP :
14541		    DDI_DMA_DONTWAIT, NULL, (caddr_t *)&mem->bp, &rlen,
14542		    &mem->acc_handle) == DDI_SUCCESS) {
14543			bzero(mem->bp, mem->size);
14544			/* ensure we got what we asked for (32bit) */
14545			if (dma_attr.dma_attr_addr_hi == NULL) {
14546				if (mem->cookie.dmac_notused != NULL) {
14547					EL(ha, "failed, ddi_dma_mem_alloc "
14548					    "returned 64 bit DMA address\n");
14549					ql_free_phys(ha, mem);
14550					return (QL_MEMORY_ALLOC_FAILED);
14551				}
14552			}
14553		} else {
14554			mem->acc_handle = NULL;
14555			mem->bp = NULL;
14556		}
14557		break;
14558	default:
14559		EL(ha, "failed, unknown type=%xh\n", mem->type);
14560		mem->acc_handle = NULL;
14561		mem->bp = NULL;
14562		break;
14563	}
14564
14565	if (mem->bp == NULL) {
14566		EL(ha, "failed, ddi_dma_mem_alloc\n");
14567		ddi_dma_free_handle(&mem->dma_handle);
14568		mem->dma_handle = NULL;
14569		return (QL_MEMORY_ALLOC_FAILED);
14570	}
14571
14572	mem->flags |= DDI_DMA_RDWR;
14573
14574	if (ql_bind_dma_buffer(ha, mem, sleep) != DDI_DMA_MAPPED) {
14575		EL(ha, "failed, ddi_dma_addr_bind_handle\n");
14576		ql_free_phys(ha, mem);
14577		return (QL_MEMORY_ALLOC_FAILED);
14578	}
14579
14580	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
14581
14582	return (QL_SUCCESS);
14583}
14584
14585/*
14586 * ql_free_phys
14587 *	Function used to free physical memory.
14588 *
14589 * Input:
14590 *	ha:	adapter state pointer.
14591 *	mem:	pointer to dma memory object.
14592 *
14593 * Context:
14594 *	Kernel context.
14595 */
14596void
14597ql_free_phys(ql_adapter_state_t *ha, dma_mem_t *mem)
14598{
14599	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
14600
14601	if (mem != NULL && mem->dma_handle != NULL) {
14602		ql_unbind_dma_buffer(ha, mem);
14603		switch (mem->type) {
14604		case KERNEL_MEM:
14605			if (mem->bp != NULL) {
14606				kmem_free(mem->bp, mem->size);
14607			}
14608			break;
14609		case LITTLE_ENDIAN_DMA:
14610		case BIG_ENDIAN_DMA:
14611		case NO_SWAP_DMA:
14612			if (mem->acc_handle != NULL) {
14613				ddi_dma_mem_free(&mem->acc_handle);
14614				mem->acc_handle = NULL;
14615			}
14616			break;
14617		default:
14618			break;
14619		}
14620		mem->bp = NULL;
14621		ddi_dma_free_handle(&mem->dma_handle);
14622		mem->dma_handle = NULL;
14623	}
14624
14625	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
14626}
14627
14628/*
14629 * ql_alloc_dma_resouce.
14630 *	Allocates DMA resource for buffer.
14631 *
14632 * Input:
14633 *	ha:			adapter state pointer.
14634 *	mem:			pointer to dma memory object.
14635 *	sleep:			KM_SLEEP/KM_NOSLEEP flag.
14636 *	mem->cookie_count	number of segments allowed.
14637 *	mem->type		memory allocation type.
14638 *	mem->size		memory size.
14639 *	mem->bp			pointer to memory or struct buf
14640 *
14641 * Returns:
14642 *	qn local function return status code.
14643 *
14644 * Context:
14645 *	Kernel context.
14646 */
14647int
14648ql_alloc_dma_resouce(ql_adapter_state_t *ha, dma_mem_t *mem, int sleep)
14649{
14650	ddi_dma_attr_t	dma_attr;
14651
14652	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
14653
14654	dma_attr = CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING) ?
14655	    ql_64bit_io_dma_attr : ql_32bit_io_dma_attr;
14656	dma_attr.dma_attr_sgllen = (int)mem->cookie_count;
14657
14658	/*
14659	 * Allocate DMA handle for command.
14660	 */
14661	if (ddi_dma_alloc_handle(ha->dip, &dma_attr, (sleep == KM_SLEEP) ?
14662	    DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &mem->dma_handle) !=
14663	    DDI_SUCCESS) {
14664		EL(ha, "failed, ddi_dma_alloc_handle\n");
14665		mem->dma_handle = NULL;
14666		return (QL_MEMORY_ALLOC_FAILED);
14667	}
14668
14669	mem->flags = DDI_DMA_RDWR | DDI_DMA_CONSISTENT;
14670
14671	if (ql_bind_dma_buffer(ha, mem, sleep) != DDI_DMA_MAPPED) {
14672		EL(ha, "failed, bind_dma_buffer\n");
14673		ddi_dma_free_handle(&mem->dma_handle);
14674		mem->dma_handle = NULL;
14675		return (QL_MEMORY_ALLOC_FAILED);
14676	}
14677
14678	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
14679
14680	return (QL_SUCCESS);
14681}
14682
14683/*
14684 * ql_free_dma_resource
14685 *	Frees DMA resources.
14686 *
14687 * Input:
14688 *	ha:		adapter state pointer.
14689 *	mem:		pointer to dma memory object.
14690 *	mem->dma_handle	DMA memory handle.
14691 *
14692 * Context:
14693 *	Kernel context.
14694 */
14695void
14696ql_free_dma_resource(ql_adapter_state_t *ha, dma_mem_t *mem)
14697{
14698	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
14699
14700	ql_free_phys(ha, mem);
14701
14702	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
14703}
14704
14705/*
14706 * ql_bind_dma_buffer
14707 *	Binds DMA buffer.
14708 *
14709 * Input:
14710 *	ha:			adapter state pointer.
14711 *	mem:			pointer to dma memory object.
14712 *	sleep:			KM_SLEEP or KM_NOSLEEP.
14713 *	mem->dma_handle		DMA memory handle.
14714 *	mem->cookie_count	number of segments allowed.
14715 *	mem->type		memory allocation type.
14716 *	mem->size		memory size.
14717 *	mem->bp			pointer to memory or struct buf
14718 *
14719 * Returns:
14720 *	mem->cookies		pointer to list of cookies.
14721 *	mem->cookie_count	number of cookies.
14722 *	status			success = DDI_DMA_MAPPED
14723 *				DDI_DMA_PARTIAL_MAP, DDI_DMA_INUSE,
14724 *				DDI_DMA_NORESOURCES, DDI_DMA_NOMAPPING or
14725 *				DDI_DMA_TOOBIG
14726 *
14727 * Context:
14728 *	Kernel context.
14729 */
14730static int
14731ql_bind_dma_buffer(ql_adapter_state_t *ha, dma_mem_t *mem, int sleep)
14732{
14733	int			rval;
14734	ddi_dma_cookie_t	*cookiep;
14735	uint32_t		cnt = mem->cookie_count;
14736
14737	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
14738
14739	if (mem->type == STRUCT_BUF_MEMORY) {
14740		rval = ddi_dma_buf_bind_handle(mem->dma_handle, mem->bp,
14741		    mem->flags, (sleep == KM_SLEEP) ? DDI_DMA_SLEEP :
14742		    DDI_DMA_DONTWAIT, NULL, &mem->cookie, &mem->cookie_count);
14743	} else {
14744		rval = ddi_dma_addr_bind_handle(mem->dma_handle, NULL, mem->bp,
14745		    mem->size, mem->flags, (sleep == KM_SLEEP) ?
14746		    DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &mem->cookie,
14747		    &mem->cookie_count);
14748	}
14749
14750	if (rval == DDI_DMA_MAPPED) {
14751		if (mem->cookie_count > cnt) {
14752			(void) ddi_dma_unbind_handle(mem->dma_handle);
14753			EL(ha, "failed, cookie_count %d > %d\n",
14754			    mem->cookie_count, cnt);
14755			rval = DDI_DMA_TOOBIG;
14756		} else {
14757			if (mem->cookie_count > 1) {
14758				if (mem->cookies = kmem_zalloc(
14759				    sizeof (ddi_dma_cookie_t) *
14760				    mem->cookie_count, sleep)) {
14761					*mem->cookies = mem->cookie;
14762					cookiep = mem->cookies;
14763					for (cnt = 1; cnt < mem->cookie_count;
14764					    cnt++) {
14765						ddi_dma_nextcookie(
14766						    mem->dma_handle,
14767						    ++cookiep);
14768					}
14769				} else {
14770					(void) ddi_dma_unbind_handle(
14771					    mem->dma_handle);
14772					EL(ha, "failed, kmem_zalloc\n");
14773					rval = DDI_DMA_NORESOURCES;
14774				}
14775			} else {
14776				/*
14777				 * It has been reported that dmac_size at times
14778				 * may be incorrect on sparc machines so for
14779				 * sparc machines that only have one segment
14780				 * use the buffer size instead.
14781				 */
14782				mem->cookies = &mem->cookie;
14783				mem->cookies->dmac_size = mem->size;
14784			}
14785		}
14786	}
14787
14788	if (rval != DDI_DMA_MAPPED) {
14789		EL(ha, "failed=%xh\n", rval);
14790	} else {
14791		/*EMPTY*/
14792		QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
14793	}
14794
14795	return (rval);
14796}
14797
14798/*
14799 * ql_unbind_dma_buffer
14800 *	Unbinds DMA buffer.
14801 *
14802 * Input:
14803 *	ha:			adapter state pointer.
14804 *	mem:			pointer to dma memory object.
14805 *	mem->dma_handle		DMA memory handle.
14806 *	mem->cookies		pointer to cookie list.
14807 *	mem->cookie_count	number of cookies.
14808 *
14809 * Context:
14810 *	Kernel context.
14811 */
14812/* ARGSUSED */
14813static void
14814ql_unbind_dma_buffer(ql_adapter_state_t *ha, dma_mem_t *mem)
14815{
14816	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
14817
14818	(void) ddi_dma_unbind_handle(mem->dma_handle);
14819	if (mem->cookie_count > 1) {
14820		kmem_free(mem->cookies, sizeof (ddi_dma_cookie_t) *
14821		    mem->cookie_count);
14822		mem->cookies = NULL;
14823	}
14824	mem->cookie_count = 0;
14825
14826	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
14827}
14828
14829static int
14830ql_suspend_adapter(ql_adapter_state_t *ha)
14831{
14832	clock_t timer;
14833
14834	/*
14835	 * First we will claim mbox ownership so that no
14836	 * thread using mbox hangs when we disable the
14837	 * interrupt in the middle of it.
14838	 */
14839	MBX_REGISTER_LOCK(ha);
14840
14841	/* Check for mailbox available, if not wait for signal. */
14842	while (ha->mailbox_flags & MBX_BUSY_FLG) {
14843		ha->mailbox_flags = (uint8_t)
14844		    (ha->mailbox_flags | MBX_WANT_FLG);
14845
14846		/* 30 seconds from now */
14847		timer = ddi_get_lbolt();
14848		timer += 32 * drv_usectohz(1000000);
14849		if (cv_timedwait(&ha->cv_mbx_wait, &ha->mbx_mutex,
14850		    timer) == -1) {
14851
14852			/* Release mailbox register lock. */
14853			MBX_REGISTER_UNLOCK(ha);
14854			EL(ha, "failed, Suspend mbox");
14855			return (QL_FUNCTION_TIMEOUT);
14856		}
14857	}
14858
14859	/* Set busy flag. */
14860	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_BUSY_FLG);
14861	MBX_REGISTER_UNLOCK(ha);
14862
14863	(void) ql_wait_outstanding(ha);
14864
14865	/*
14866	 * here we are sure that there will not be any mbox interrupt.
14867	 * So, let's make sure that we return back all the outstanding
14868	 * cmds as well as internally queued commands.
14869	 */
14870	ql_halt(ha, PM_LEVEL_D0);
14871
14872	if (ha->power_level != PM_LEVEL_D3) {
14873		/* Disable ISP interrupts. */
14874		WRT16_IO_REG(ha, ictrl, 0);
14875	}
14876
14877	ADAPTER_STATE_LOCK(ha);
14878	ha->flags &= ~INTERRUPTS_ENABLED;
14879	ADAPTER_STATE_UNLOCK(ha);
14880
14881	MBX_REGISTER_LOCK(ha);
14882	/* Reset busy status. */
14883	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & ~MBX_BUSY_FLG);
14884
14885	/* If thread is waiting for mailbox go signal it to start. */
14886	if (ha->mailbox_flags & MBX_WANT_FLG) {
14887		ha->mailbox_flags = (uint8_t)
14888		    (ha->mailbox_flags & ~MBX_WANT_FLG);
14889		cv_broadcast(&ha->cv_mbx_wait);
14890	}
14891	/* Release mailbox register lock. */
14892	MBX_REGISTER_UNLOCK(ha);
14893
14894	return (QL_SUCCESS);
14895}
14896
14897/*
14898 * ql_add_link_b
14899 *	Add link to the end of the chain.
14900 *
14901 * Input:
14902 *	head = Head of link list.
14903 *	link = link to be added.
14904 *	LOCK must be already obtained.
14905 *
14906 * Context:
14907 *	Interrupt or Kernel context, no mailbox commands allowed.
14908 */
14909void
14910ql_add_link_b(ql_head_t *head, ql_link_t *link)
14911{
14912	ASSERT(link->base_address != NULL);
14913
14914	/* at the end there isn't a next */
14915	link->next = NULL;
14916
14917	if ((link->prev = head->last) == NULL) {
14918		head->first = link;
14919	} else {
14920		head->last->next = link;
14921	}
14922
14923	head->last = link;
14924	link->head = head;	/* the queue we're on */
14925}
14926
14927/*
14928 * ql_add_link_t
14929 *	Add link to the beginning of the chain.
14930 *
14931 * Input:
14932 *	head = Head of link list.
14933 *	link = link to be added.
14934 *	LOCK must be already obtained.
14935 *
14936 * Context:
14937 *	Interrupt or Kernel context, no mailbox commands allowed.
14938 */
14939void
14940ql_add_link_t(ql_head_t *head, ql_link_t *link)
14941{
14942	ASSERT(link->base_address != NULL);
14943
14944	link->prev = NULL;
14945
14946	if ((link->next = head->first) == NULL)	{
14947		head->last = link;
14948	} else {
14949		head->first->prev = link;
14950	}
14951
14952	head->first = link;
14953	link->head = head;	/* the queue we're on */
14954}
14955
14956/*
14957 * ql_remove_link
14958 *	Remove a link from the chain.
14959 *
14960 * Input:
14961 *	head = Head of link list.
14962 *	link = link to be removed.
14963 *	LOCK must be already obtained.
14964 *
14965 * Context:
14966 *	Interrupt or Kernel context, no mailbox commands allowed.
14967 */
14968void
14969ql_remove_link(ql_head_t *head, ql_link_t *link)
14970{
14971	ASSERT(link->base_address != NULL);
14972
14973	if (link->prev != NULL) {
14974		if ((link->prev->next = link->next) == NULL) {
14975			head->last = link->prev;
14976		} else {
14977			link->next->prev = link->prev;
14978		}
14979	} else if ((head->first = link->next) == NULL) {
14980		head->last = NULL;
14981	} else {
14982		head->first->prev = NULL;
14983	}
14984
14985	/* not on a queue any more */
14986	link->prev = link->next = NULL;
14987	link->head = NULL;
14988}
14989
14990/*
14991 * ql_chg_endian
14992 *	Change endianess of byte array.
14993 *
14994 * Input:
14995 *	buf = array pointer.
14996 *	size = size of array in bytes.
14997 *
14998 * Context:
14999 *	Interrupt or Kernel context, no mailbox commands allowed.
15000 */
15001void
15002ql_chg_endian(uint8_t buf[], size_t size)
15003{
15004	uint8_t byte;
15005	size_t  cnt1;
15006	size_t  cnt;
15007
15008	cnt1 = size - 1;
15009	for (cnt = 0; cnt < size / 2; cnt++) {
15010		byte = buf[cnt1];
15011		buf[cnt1] = buf[cnt];
15012		buf[cnt] = byte;
15013		cnt1--;
15014	}
15015}
15016
15017/*
15018 * ql_bstr_to_dec
15019 *	Convert decimal byte string to number.
15020 *
15021 * Input:
15022 *	s:	byte string pointer.
15023 *	ans:	interger pointer for number.
15024 *	size:	number of ascii bytes.
15025 *
15026 * Returns:
15027 *	success = number of ascii bytes processed.
15028 *
15029 * Context:
15030 *	Kernel/Interrupt context.
15031 */
15032static int
15033ql_bstr_to_dec(char *s, uint32_t *ans, uint32_t size)
15034{
15035	int			mul, num, cnt, pos;
15036	char			*str;
15037
15038	/* Calculate size of number. */
15039	if (size == 0) {
15040		for (str = s; *str >= '0' && *str <= '9'; str++) {
15041			size++;
15042		}
15043	}
15044
15045	*ans = 0;
15046	for (cnt = 0; *s != '\0' && size; size--, cnt++) {
15047		if (*s >= '0' && *s <= '9') {
15048			num = *s++ - '0';
15049		} else {
15050			break;
15051		}
15052
15053		for (mul = 1, pos = 1; pos < size; pos++) {
15054			mul *= 10;
15055		}
15056		*ans += num * mul;
15057	}
15058
15059	return (cnt);
15060}
15061
15062/*
15063 * ql_delay
15064 *	Calls delay routine if threads are not suspended, otherwise, busy waits
15065 *	Minimum = 1 tick = 10ms
15066 *
15067 * Input:
15068 *	dly = delay time in microseconds.
15069 *
15070 * Context:
15071 *	Kernel or Interrupt context, no mailbox commands allowed.
15072 */
15073void
15074ql_delay(ql_adapter_state_t *ha, clock_t usecs)
15075{
15076	if (QL_DAEMON_SUSPENDED(ha) || ddi_in_panic()) {
15077		drv_usecwait(usecs);
15078	} else {
15079		delay(drv_usectohz(usecs));
15080	}
15081}
15082
15083/*
15084 * ql_stall_drv
15085 *	Stalls one or all driver instances, waits for 30 seconds.
15086 *
15087 * Input:
15088 *	ha:		adapter state pointer or NULL for all.
15089 *	options:	BIT_0 --> leave driver stalled on exit if
15090 *				  failed.
15091 *
15092 * Returns:
15093 *	ql local function return status code.
15094 *
15095 * Context:
15096 *	Kernel context.
15097 */
15098int
15099ql_stall_driver(ql_adapter_state_t *ha, uint32_t options)
15100{
15101	ql_link_t		*link;
15102	ql_adapter_state_t	*ha2;
15103	uint32_t		timer;
15104
15105	/* Wait for 30 seconds for daemons unstall. */
15106	timer = 3000;
15107	link = ha == NULL ? ql_hba.first : &ha->hba;
15108	while (link != NULL && timer) {
15109		ha2 = link->base_address;
15110
15111		ql_awaken_task_daemon(ha2, NULL, DRIVER_STALL, 0);
15112
15113		if ((ha2->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) == 0 ||
15114		    (ha2->task_daemon_flags & TASK_DAEMON_STOP_FLG) != 0 ||
15115		    (ha2->task_daemon_flags & TASK_DAEMON_STALLED_FLG &&
15116		    ql_wait_outstanding(ha2) == MAX_OUTSTANDING_COMMANDS)) {
15117			link = ha == NULL ? link->next : NULL;
15118			continue;
15119		}
15120
15121		ql_delay(ha, 10000);
15122		timer--;
15123		link = ha == NULL ? ql_hba.first : &ha->hba;
15124	}
15125
15126	if (ha2 != NULL && timer == 0) {
15127		EL(ha2, "failed, tdf=%xh, exiting state is: %s\n",
15128		    ha2->task_daemon_flags, (options & BIT_0 ? "stalled" :
15129		    "unstalled"));
15130		if (options & BIT_0) {
15131			ql_awaken_task_daemon(ha2, NULL, 0, DRIVER_STALL);
15132		}
15133		return (QL_FUNCTION_TIMEOUT);
15134	}
15135
15136	QL_PRINT_3(CE_CONT, "done\n");
15137
15138	return (QL_SUCCESS);
15139}
15140
15141/*
15142 * ql_restart_driver
15143 *	Restarts one or all driver instances.
15144 *
15145 * Input:
15146 *	ha:	adapter state pointer or NULL for all.
15147 *
15148 * Context:
15149 *	Kernel context.
15150 */
15151void
15152ql_restart_driver(ql_adapter_state_t *ha)
15153{
15154	ql_link_t		*link;
15155	ql_adapter_state_t	*ha2;
15156	uint32_t		timer;
15157
15158	QL_PRINT_3(CE_CONT, "entered\n");
15159
15160	/* Tell all daemons to unstall. */
15161	link = ha == NULL ? ql_hba.first : &ha->hba;
15162	while (link != NULL) {
15163		ha2 = link->base_address;
15164
15165		ql_awaken_task_daemon(ha2, NULL, 0, DRIVER_STALL);
15166
15167		link = ha == NULL ? link->next : NULL;
15168	}
15169
15170	/* Wait for 30 seconds for all daemons unstall. */
15171	timer = 3000;
15172	link = ha == NULL ? ql_hba.first : &ha->hba;
15173	while (link != NULL && timer) {
15174		ha2 = link->base_address;
15175
15176		if ((ha2->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) == 0 ||
15177		    (ha2->task_daemon_flags & TASK_DAEMON_STOP_FLG) != 0 ||
15178		    (ha2->task_daemon_flags & TASK_DAEMON_STALLED_FLG) == 0) {
15179			QL_PRINT_2(CE_CONT, "(%d,%d): restarted\n",
15180			    ha2->instance, ha2->vp_index);
15181			ql_restart_queues(ha2);
15182			link = ha == NULL ? link->next : NULL;
15183			continue;
15184		}
15185
15186		QL_PRINT_2(CE_CONT, "(%d,%d): failed, tdf=%xh\n",
15187		    ha2->instance, ha2->vp_index, ha2->task_daemon_flags);
15188
15189		ql_delay(ha, 10000);
15190		timer--;
15191		link = ha == NULL ? ql_hba.first : &ha->hba;
15192	}
15193
15194	QL_PRINT_3(CE_CONT, "exiting\n");
15195}
15196
15197/*
15198 * ql_setup_interrupts
15199 *	Sets up interrupts based on the HBA's and platform's
15200 *	capabilities (e.g., legacy / MSI / FIXED).
15201 *
15202 * Input:
15203 *	ha = adapter state pointer.
15204 *
15205 * Returns:
15206 *	DDI_SUCCESS or DDI_FAILURE.
15207 *
15208 * Context:
15209 *	Kernel context.
15210 */
15211static int
15212ql_setup_interrupts(ql_adapter_state_t *ha)
15213{
15214	int32_t		rval = DDI_FAILURE;
15215	int32_t		i;
15216	int32_t		itypes = 0;
15217
15218	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
15219
15220	/*
15221	 * The Solaris Advanced Interrupt Functions (aif) are only
15222	 * supported on s10U1 or greater.
15223	 */
15224	if (ql_os_release_level < 10 || ql_disable_aif != 0) {
15225		EL(ha, "interrupt framework is not supported or is "
15226		    "disabled, using legacy\n");
15227		return (ql_legacy_intr(ha));
15228	} else if (ql_os_release_level == 10) {
15229		/*
15230		 * See if the advanced interrupt functions (aif) are
15231		 * in the kernel
15232		 */
15233		void	*fptr = (void *)&ddi_intr_get_supported_types;
15234
15235		if (fptr == NULL) {
15236			EL(ha, "aif is not supported, using legacy "
15237			    "interrupts (rev)\n");
15238			return (ql_legacy_intr(ha));
15239		}
15240	}
15241
15242	/* See what types of interrupts this HBA and platform support */
15243	if ((i = ddi_intr_get_supported_types(ha->dip, &itypes)) !=
15244	    DDI_SUCCESS) {
15245		EL(ha, "get supported types failed, rval=%xh, "
15246		    "assuming FIXED\n", i);
15247		itypes = DDI_INTR_TYPE_FIXED;
15248	}
15249
15250	EL(ha, "supported types are: %xh\n", itypes);
15251
15252	if ((itypes & DDI_INTR_TYPE_MSIX) &&
15253	    (rval = ql_setup_msix(ha)) == DDI_SUCCESS) {
15254		EL(ha, "successful MSI-X setup\n");
15255	} else if ((itypes & DDI_INTR_TYPE_MSI) &&
15256	    (rval = ql_setup_msi(ha)) == DDI_SUCCESS) {
15257		EL(ha, "successful MSI setup\n");
15258	} else {
15259		rval = ql_setup_fixed(ha);
15260	}
15261
15262	if (rval != DDI_SUCCESS) {
15263		EL(ha, "failed, aif, rval=%xh\n", rval);
15264	} else {
15265		/*EMPTY*/
15266		QL_PRINT_3(CE_CONT, "(%d): exiting\n");
15267	}
15268
15269	return (rval);
15270}
15271
15272/*
15273 * ql_setup_msi
15274 *	Set up aif MSI interrupts
15275 *
15276 * Input:
15277 *	ha = adapter state pointer.
15278 *
15279 * Returns:
15280 *	DDI_SUCCESS or DDI_FAILURE.
15281 *
15282 * Context:
15283 *	Kernel context.
15284 */
15285static int
15286ql_setup_msi(ql_adapter_state_t *ha)
15287{
15288	int32_t		count = 0;
15289	int32_t		avail = 0;
15290	int32_t		actual = 0;
15291	int32_t		msitype = DDI_INTR_TYPE_MSI;
15292	int32_t		ret;
15293	ql_ifunc_t	itrfun[10] = {0};
15294
15295	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
15296
15297	if (ql_disable_msi != 0) {
15298		EL(ha, "MSI is disabled by user\n");
15299		return (DDI_FAILURE);
15300	}
15301
15302	/* MSI support is only suported on 24xx HBA's. */
15303	if (!(CFG_IST(ha, CFG_CTRL_2425))) {
15304		EL(ha, "HBA does not support MSI\n");
15305		return (DDI_FAILURE);
15306	}
15307
15308	/* Get number of MSI interrupts the system supports */
15309	if (((ret = ddi_intr_get_nintrs(ha->dip, msitype, &count)) !=
15310	    DDI_SUCCESS) || count == 0) {
15311		EL(ha, "failed, nintrs ret=%xh, cnt=%xh\n", ret, count);
15312		return (DDI_FAILURE);
15313	}
15314
15315	/* Get number of available MSI interrupts */
15316	if (((ret = ddi_intr_get_navail(ha->dip, msitype, &avail)) !=
15317	    DDI_SUCCESS) || avail == 0) {
15318		EL(ha, "failed, navail ret=%xh, avail=%xh\n", ret, avail);
15319		return (DDI_FAILURE);
15320	}
15321
15322	/* MSI requires only 1.  */
15323	count = 1;
15324	itrfun[0].ifunc = &ql_isr_aif;
15325
15326	/* Allocate space for interrupt handles */
15327	ha->hsize = ((uint32_t)(sizeof (ddi_intr_handle_t)) * count);
15328	ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP);
15329
15330	ha->iflags |= IFLG_INTR_MSI;
15331
15332	/* Allocate the interrupts */
15333	if ((ret = ddi_intr_alloc(ha->dip, ha->htable, msitype, 0, count,
15334	    &actual, 0)) != DDI_SUCCESS || actual < count) {
15335		EL(ha, "failed, intr_alloc ret=%xh, count = %xh, "
15336		    "actual=%xh\n", ret, count, actual);
15337		ql_release_intr(ha);
15338		return (DDI_FAILURE);
15339	}
15340
15341	ha->intr_cnt = actual;
15342
15343	/* Get interrupt priority */
15344	if ((ret = ddi_intr_get_pri(ha->htable[0], &ha->intr_pri)) !=
15345	    DDI_SUCCESS) {
15346		EL(ha, "failed, get_pri ret=%xh\n", ret);
15347		ql_release_intr(ha);
15348		return (ret);
15349	}
15350
15351	/* Add the interrupt handler */
15352	if ((ret = ddi_intr_add_handler(ha->htable[0], itrfun[0].ifunc,
15353	    (caddr_t)ha, (caddr_t)0)) != DDI_SUCCESS) {
15354		EL(ha, "failed, intr_add ret=%xh\n", ret);
15355		ql_release_intr(ha);
15356		return (ret);
15357	}
15358
15359	/* Setup mutexes */
15360	if ((ret = ql_init_mutex(ha)) != DDI_SUCCESS) {
15361		EL(ha, "failed, mutex init ret=%xh\n", ret);
15362		ql_release_intr(ha);
15363		return (ret);
15364	}
15365
15366	/* Get the capabilities */
15367	(void) ddi_intr_get_cap(ha->htable[0], &ha->intr_cap);
15368
15369	/* Enable interrupts */
15370	if (ha->intr_cap & DDI_INTR_FLAG_BLOCK) {
15371		if ((ret = ddi_intr_block_enable(ha->htable, ha->intr_cnt)) !=
15372		    DDI_SUCCESS) {
15373			EL(ha, "failed, block enable, ret=%xh\n", ret);
15374			ql_destroy_mutex(ha);
15375			ql_release_intr(ha);
15376			return (ret);
15377		}
15378	} else {
15379		if ((ret = ddi_intr_enable(ha->htable[0])) != DDI_SUCCESS) {
15380			EL(ha, "failed, intr enable, ret=%xh\n", ret);
15381			ql_destroy_mutex(ha);
15382			ql_release_intr(ha);
15383			return (ret);
15384		}
15385	}
15386
15387	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
15388
15389	return (DDI_SUCCESS);
15390}
15391
15392/*
15393 * ql_setup_msix
15394 *	Set up aif MSI-X interrupts
15395 *
15396 * Input:
15397 *	ha = adapter state pointer.
15398 *
15399 * Returns:
15400 *	DDI_SUCCESS or DDI_FAILURE.
15401 *
15402 * Context:
15403 *	Kernel context.
15404 */
15405static int
15406ql_setup_msix(ql_adapter_state_t *ha)
15407{
15408	uint16_t	hwvect;
15409	int32_t		count = 0;
15410	int32_t		avail = 0;
15411	int32_t		actual = 0;
15412	int32_t		msitype = DDI_INTR_TYPE_MSIX;
15413	int32_t		ret;
15414	uint32_t	i;
15415	ql_ifunc_t	itrfun[QL_MSIX_MAXAIF] = {0};
15416
15417	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
15418
15419	if (ql_disable_msix != 0) {
15420		EL(ha, "MSI-X is disabled by user\n");
15421		return (DDI_FAILURE);
15422	}
15423
15424	/*
15425	 * MSI-X support is only available on 24xx HBA's that have
15426	 * rev A2 parts (revid = 3) or greater.
15427	 */
15428	if (!((ha->device_id == 0x2532) || (ha->device_id == 0x2432) ||
15429	    (ha->device_id == 0x8432))) {
15430		EL(ha, "HBA does not support MSI-X\n");
15431		return (DDI_FAILURE);
15432	}
15433
15434	if (CFG_IST(ha, CFG_CTRL_2422) && (ha->rev_id < 3)) {
15435		EL(ha, "HBA does not support MSI-X (revid)\n");
15436		return (DDI_FAILURE);
15437	}
15438
15439	/* Per HP, these HP branded HBA's are not supported with MSI-X */
15440	if (ha->ven_id == 0x103C && (ha->subsys_id == 0x7041 ||
15441	    ha->subsys_id == 0x7040 || ha->subsys_id == 0x1705)) {
15442		EL(ha, "HBA does not support MSI-X (subdevid)\n");
15443		return (DDI_FAILURE);
15444	}
15445
15446	/* Get the number of 24xx/25xx MSI-X h/w vectors */
15447	hwvect = (uint16_t)(((CFG_IST(ha, CFG_CTRL_2422) ?
15448	    ql_pci_config_get16(ha, 0x7e) :
15449	    ql_pci_config_get16(ha, 0xa2)) & 0x3ff) + 1);
15450
15451	EL(ha, "pcie config space hwvect = %d\n", hwvect);
15452
15453	if (hwvect < QL_MSIX_MAXAIF) {
15454		EL(ha, "failed, min h/w vectors req'd: %d, avail: %d\n",
15455		    QL_MSIX_MAXAIF, hwvect);
15456		return (DDI_FAILURE);
15457	}
15458
15459	/* Get number of MSI-X interrupts the platform h/w supports */
15460	if (((ret = ddi_intr_get_nintrs(ha->dip, msitype, &count)) !=
15461	    DDI_SUCCESS) || count == 0) {
15462		EL(ha, "failed, nintrs ret=%xh, cnt=%xh\n", ret, count);
15463		return (DDI_FAILURE);
15464	}
15465
15466	/* Get number of available system interrupts */
15467	if (((ret = ddi_intr_get_navail(ha->dip, msitype, &avail)) !=
15468	    DDI_SUCCESS) || avail == 0) {
15469		EL(ha, "failed, navail ret=%xh, avail=%xh\n", ret, avail);
15470		return (DDI_FAILURE);
15471	}
15472
15473	/* Fill out the intr table */
15474	count = QL_MSIX_MAXAIF;
15475	itrfun[QL_MSIX_AIF].ifunc = &ql_isr_aif;
15476	itrfun[QL_MSIX_RSPQ].ifunc = &ql_isr_aif;
15477
15478	/* Allocate space for interrupt handles */
15479	ha->hsize = ((uint32_t)(sizeof (ddi_intr_handle_t)) * hwvect);
15480	if ((ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP)) == NULL) {
15481		ha->hsize = 0;
15482		EL(ha, "failed, unable to allocate htable space\n");
15483		return (DDI_FAILURE);
15484	}
15485
15486	ha->iflags |= IFLG_INTR_MSIX;
15487
15488	/* Allocate the interrupts */
15489	if (((ret = ddi_intr_alloc(ha->dip, ha->htable, msitype,
15490	    DDI_INTR_ALLOC_NORMAL, count, &actual, 0)) != DDI_SUCCESS) ||
15491	    actual < QL_MSIX_MAXAIF) {
15492		EL(ha, "failed, intr_alloc ret=%xh, count = %xh, "
15493		    "actual=%xh\n", ret, count, actual);
15494		ql_release_intr(ha);
15495		return (DDI_FAILURE);
15496	}
15497
15498	ha->intr_cnt = actual;
15499
15500	/* Get interrupt priority */
15501	if ((ret = ddi_intr_get_pri(ha->htable[0], &ha->intr_pri)) !=
15502	    DDI_SUCCESS) {
15503		EL(ha, "failed, get_pri ret=%xh\n", ret);
15504		ql_release_intr(ha);
15505		return (ret);
15506	}
15507
15508	/* Add the interrupt handlers */
15509	for (i = 0; i < actual; i++) {
15510		if ((ret = ddi_intr_add_handler(ha->htable[i], itrfun[i].ifunc,
15511		    (void *)ha, (void *)((ulong_t)i))) != DDI_SUCCESS) {
15512			EL(ha, "failed, addh#=%xh, act=%xh, ret=%xh\n", i,
15513			    actual, ret);
15514			ql_release_intr(ha);
15515			return (ret);
15516		}
15517	}
15518
15519	/*
15520	 * duplicate the rest of the intr's
15521	 * ddi_intr_dup_handler() isn't working on x86 just yet...
15522	 */
15523#ifdef __sparc
15524	for (i = actual; i < hwvect; i++) {
15525		if ((ret = ddi_intr_dup_handler(ha->htable[0], (int)i,
15526		    &ha->htable[i])) != DDI_SUCCESS) {
15527			EL(ha, "failed, intr_dup#=%xh, act=%xh, ret=%xh\n",
15528			    i, actual, ret);
15529			ql_release_intr(ha);
15530			return (ret);
15531		}
15532	}
15533#endif
15534
15535	/* Setup mutexes */
15536	if ((ret = ql_init_mutex(ha)) != DDI_SUCCESS) {
15537		EL(ha, "failed, mutex init ret=%xh\n", ret);
15538		ql_release_intr(ha);
15539		return (ret);
15540	}
15541
15542	/* Get the capabilities */
15543	(void) ddi_intr_get_cap(ha->htable[0], &ha->intr_cap);
15544
15545	/* Enable interrupts */
15546	if (ha->intr_cap & DDI_INTR_FLAG_BLOCK) {
15547		if ((ret = ddi_intr_block_enable(ha->htable, ha->intr_cnt)) !=
15548		    DDI_SUCCESS) {
15549			EL(ha, "failed, block enable, ret=%xh\n", ret);
15550			ql_destroy_mutex(ha);
15551			ql_release_intr(ha);
15552			return (ret);
15553		}
15554	} else {
15555		for (i = 0; i < ha->intr_cnt; i++) {
15556			if ((ret = ddi_intr_enable(ha->htable[i])) !=
15557			    DDI_SUCCESS) {
15558				EL(ha, "failed, intr enable, ret=%xh\n", ret);
15559				ql_destroy_mutex(ha);
15560				ql_release_intr(ha);
15561				return (ret);
15562			}
15563		}
15564	}
15565
15566	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
15567
15568	return (DDI_SUCCESS);
15569}
15570
15571/*
15572 * ql_setup_fixed
15573 *	Sets up aif FIXED interrupts
15574 *
15575 * Input:
15576 *	ha = adapter state pointer.
15577 *
15578 * Returns:
15579 *	DDI_SUCCESS or DDI_FAILURE.
15580 *
15581 * Context:
15582 *	Kernel context.
15583 */
15584static int
15585ql_setup_fixed(ql_adapter_state_t *ha)
15586{
15587	int32_t		count = 0;
15588	int32_t		actual = 0;
15589	int32_t		ret;
15590	uint32_t	i;
15591
15592	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
15593
15594	/* Get number of fixed interrupts the system supports */
15595	if (((ret = ddi_intr_get_nintrs(ha->dip, DDI_INTR_TYPE_FIXED,
15596	    &count)) != DDI_SUCCESS) || count == 0) {
15597		EL(ha, "failed, nintrs ret=%xh, cnt=%xh\n", ret, count);
15598		return (DDI_FAILURE);
15599	}
15600
15601	ha->iflags |= IFLG_INTR_FIXED;
15602
15603	/* Allocate space for interrupt handles */
15604	ha->hsize = ((uint32_t)(sizeof (ddi_intr_handle_t)) * count);
15605	ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP);
15606
15607	/* Allocate the interrupts */
15608	if (((ret = ddi_intr_alloc(ha->dip, ha->htable, DDI_INTR_TYPE_FIXED,
15609	    0, count, &actual, DDI_INTR_ALLOC_STRICT)) != DDI_SUCCESS) ||
15610	    actual < count) {
15611		EL(ha, "failed, intr_alloc ret=%xh, count=%xh, "
15612		    "actual=%xh\n", ret, count, actual);
15613		ql_release_intr(ha);
15614		return (DDI_FAILURE);
15615	}
15616
15617	ha->intr_cnt = actual;
15618
15619	/* Get interrupt priority */
15620	if ((ret = ddi_intr_get_pri(ha->htable[0], &ha->intr_pri)) !=
15621	    DDI_SUCCESS) {
15622		EL(ha, "failed, get_pri ret=%xh\n", ret);
15623		ql_release_intr(ha);
15624		return (ret);
15625	}
15626
15627	/* Add the interrupt handlers */
15628	for (i = 0; i < ha->intr_cnt; i++) {
15629		if ((ret = ddi_intr_add_handler(ha->htable[i], &ql_isr_aif,
15630		    (void *)ha, (void *)((ulong_t)(i)))) != DDI_SUCCESS) {
15631			EL(ha, "failed, intr_add ret=%xh\n", ret);
15632			ql_release_intr(ha);
15633			return (ret);
15634		}
15635	}
15636
15637	/* Setup mutexes */
15638	if ((ret = ql_init_mutex(ha)) != DDI_SUCCESS) {
15639		EL(ha, "failed, mutex init ret=%xh\n", ret);
15640		ql_release_intr(ha);
15641		return (ret);
15642	}
15643
15644	/* Enable interrupts */
15645	for (i = 0; i < ha->intr_cnt; i++) {
15646		if ((ret = ddi_intr_enable(ha->htable[i])) != DDI_SUCCESS) {
15647			EL(ha, "failed, intr enable, ret=%xh\n", ret);
15648			ql_destroy_mutex(ha);
15649			ql_release_intr(ha);
15650			return (ret);
15651		}
15652	}
15653
15654	EL(ha, "using FIXED interupts\n");
15655
15656	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
15657
15658	return (DDI_SUCCESS);
15659}
15660
15661/*
15662 * ql_disable_intr
15663 *	Disables interrupts
15664 *
15665 * Input:
15666 *	ha = adapter state pointer.
15667 *
15668 * Returns:
15669 *
15670 * Context:
15671 *	Kernel context.
15672 */
15673static void
15674ql_disable_intr(ql_adapter_state_t *ha)
15675{
15676	uint32_t	i, rval;
15677
15678	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
15679
15680	if (!(ha->iflags & IFLG_INTR_AIF)) {
15681
15682		/* Disable legacy interrupts */
15683		(void) ddi_remove_intr(ha->dip, 0, ha->iblock_cookie);
15684
15685	} else if ((ha->intr_cap & DDI_INTR_FLAG_BLOCK) &&
15686	    (ha->iflags & (IFLG_INTR_MSI | IFLG_INTR_MSIX))) {
15687
15688		/* Remove AIF block interrupts (MSI) */
15689		if ((rval = ddi_intr_block_disable(ha->htable, ha->intr_cnt))
15690		    != DDI_SUCCESS) {
15691			EL(ha, "failed intr block disable, rval=%x\n", rval);
15692		}
15693
15694	} else {
15695
15696		/* Remove AIF non-block interrupts (fixed).  */
15697		for (i = 0; i < ha->intr_cnt; i++) {
15698			if ((rval = ddi_intr_disable(ha->htable[i])) !=
15699			    DDI_SUCCESS) {
15700				EL(ha, "failed intr disable, intr#=%xh, "
15701				    "rval=%xh\n", i, rval);
15702			}
15703		}
15704	}
15705
15706	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
15707}
15708
15709/*
15710 * ql_release_intr
15711 *	Releases aif legacy interrupt resources
15712 *
15713 * Input:
15714 *	ha = adapter state pointer.
15715 *
15716 * Returns:
15717 *
15718 * Context:
15719 *	Kernel context.
15720 */
15721static void
15722ql_release_intr(ql_adapter_state_t *ha)
15723{
15724	int32_t 	i;
15725
15726	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
15727
15728	if (!(ha->iflags & IFLG_INTR_AIF)) {
15729		QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
15730		return;
15731	}
15732
15733	ha->iflags &= ~(IFLG_INTR_AIF);
15734	if (ha->htable != NULL && ha->hsize > 0) {
15735		i = (int32_t)ha->hsize / (int32_t)sizeof (ddi_intr_handle_t);
15736		while (i-- > 0) {
15737			if (ha->htable[i] == 0) {
15738				EL(ha, "htable[%x]=0h\n", i);
15739				continue;
15740			}
15741
15742			(void) ddi_intr_disable(ha->htable[i]);
15743
15744			if (i < ha->intr_cnt) {
15745				(void) ddi_intr_remove_handler(ha->htable[i]);
15746			}
15747
15748			(void) ddi_intr_free(ha->htable[i]);
15749		}
15750
15751		kmem_free(ha->htable, ha->hsize);
15752		ha->htable = NULL;
15753	}
15754
15755	ha->hsize = 0;
15756	ha->intr_cnt = 0;
15757	ha->intr_pri = 0;
15758	ha->intr_cap = 0;
15759
15760	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
15761}
15762
15763/*
15764 * ql_legacy_intr
15765 *	Sets up legacy interrupts.
15766 *
15767 *	NB: Only to be used if AIF (Advanced Interupt Framework)
15768 *	    if NOT in the kernel.
15769 *
15770 * Input:
15771 *	ha = adapter state pointer.
15772 *
15773 * Returns:
15774 *	DDI_SUCCESS or DDI_FAILURE.
15775 *
15776 * Context:
15777 *	Kernel context.
15778 */
15779static int
15780ql_legacy_intr(ql_adapter_state_t *ha)
15781{
15782	int	rval = DDI_SUCCESS;
15783
15784	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
15785
15786	/* Setup mutexes */
15787	if (ql_init_mutex(ha) != DDI_SUCCESS) {
15788		EL(ha, "failed, mutex init\n");
15789		return (DDI_FAILURE);
15790	}
15791
15792	/* Setup standard/legacy interrupt handler */
15793	if (ddi_add_intr(ha->dip, (uint_t)0, &ha->iblock_cookie,
15794	    (ddi_idevice_cookie_t *)0, ql_isr, (caddr_t)ha) != DDI_SUCCESS) {
15795		cmn_err(CE_WARN, "%s(%d): Failed to add legacy interrupt",
15796		    QL_NAME, ha->instance);
15797		ql_destroy_mutex(ha);
15798		rval = DDI_FAILURE;
15799	}
15800
15801	if (rval == DDI_SUCCESS) {
15802		ha->iflags |= IFLG_INTR_LEGACY;
15803		EL(ha, "using legacy interrupts\n");
15804	}
15805
15806	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
15807
15808	return (rval);
15809}
15810
15811/*
15812 * ql_init_mutex
15813 *	Initializes mutex's
15814 *
15815 * Input:
15816 *	ha = adapter state pointer.
15817 *
15818 * Returns:
15819 *	DDI_SUCCESS or DDI_FAILURE.
15820 *
15821 * Context:
15822 *	Kernel context.
15823 */
15824static int
15825ql_init_mutex(ql_adapter_state_t *ha)
15826{
15827	int	ret;
15828	void	*intr;
15829
15830	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
15831
15832	if (ha->iflags & IFLG_INTR_AIF) {
15833		intr = (void *)(uintptr_t)ha->intr_pri;
15834	} else {
15835		/* Get iblock cookies to initialize mutexes */
15836		if ((ret = ddi_get_iblock_cookie(ha->dip, 0,
15837		    &ha->iblock_cookie)) != DDI_SUCCESS) {
15838			EL(ha, "failed, get_iblock: %xh\n", ret);
15839			return (DDI_FAILURE);
15840		}
15841		intr = (void *)ha->iblock_cookie;
15842	}
15843
15844	/* mutexes to protect the adapter state structure. */
15845	mutex_init(&ha->mutex, NULL, MUTEX_DRIVER, intr);
15846
15847	/* mutex to protect the ISP response ring. */
15848	mutex_init(&ha->intr_mutex, NULL, MUTEX_DRIVER, intr);
15849
15850	/* mutex to protect the mailbox registers. */
15851	mutex_init(&ha->mbx_mutex, NULL, MUTEX_DRIVER, intr);
15852
15853	/* power management protection */
15854	mutex_init(&ha->pm_mutex, NULL, MUTEX_DRIVER, intr);
15855
15856	/* Mailbox wait and interrupt conditional variable. */
15857	cv_init(&ha->cv_mbx_wait, NULL, CV_DRIVER, NULL);
15858	cv_init(&ha->cv_mbx_intr, NULL, CV_DRIVER, NULL);
15859
15860	/* mutex to protect the ISP request ring. */
15861	mutex_init(&ha->req_ring_mutex, NULL, MUTEX_DRIVER, intr);
15862
15863	/* Unsolicited buffer conditional variable. */
15864	cv_init(&ha->cv_ub, NULL, CV_DRIVER, NULL);
15865
15866	mutex_init(&ha->ub_mutex, NULL, MUTEX_DRIVER, intr);
15867	mutex_init(&ha->cache_mutex, NULL, MUTEX_DRIVER, intr);
15868
15869	/* Suspended conditional variable. */
15870	cv_init(&ha->cv_dr_suspended, NULL, CV_DRIVER, NULL);
15871
15872	/* mutex to protect task daemon context. */
15873	mutex_init(&ha->task_daemon_mutex, NULL, MUTEX_DRIVER, intr);
15874
15875	/* Task_daemon thread conditional variable. */
15876	cv_init(&ha->cv_task_daemon, NULL, CV_DRIVER, NULL);
15877
15878	/* mutex to protect notify acknowledge list */
15879	mutex_init(&ha->ql_nack_mtx, NULL, MUTEX_DRIVER, intr);
15880	ha->ql_nack = NULL;
15881
15882	/* mutex to protect diag port manage interface */
15883	mutex_init(&ha->portmutex, NULL, MUTEX_DRIVER, intr);
15884
15885	/* mutex to protect per instance f/w dump flags and buffer */
15886	mutex_init(&ha->dump_mutex, NULL, MUTEX_DRIVER, intr);
15887
15888	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
15889
15890	return (DDI_SUCCESS);
15891}
15892
15893/*
15894 * ql_destroy_mutex
15895 *	Destroys mutex's
15896 *
15897 * Input:
15898 *	ha = adapter state pointer.
15899 *
15900 * Returns:
15901 *
15902 * Context:
15903 *	Kernel context.
15904 */
15905static void
15906ql_destroy_mutex(ql_adapter_state_t *ha)
15907{
15908	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
15909
15910	mutex_destroy(&ha->task_daemon_mutex);
15911	cv_destroy(&ha->cv_task_daemon);
15912	cv_destroy(&ha->cv_dr_suspended);
15913	mutex_destroy(&ha->ub_mutex);
15914	cv_destroy(&ha->cv_ub);
15915	mutex_destroy(&ha->req_ring_mutex);
15916	mutex_destroy(&ha->mbx_mutex);
15917	cv_destroy(&ha->cv_mbx_intr);
15918	cv_destroy(&ha->cv_mbx_wait);
15919	mutex_destroy(&ha->pm_mutex);
15920	mutex_destroy(&ha->intr_mutex);
15921	mutex_destroy(&ha->portmutex);
15922	mutex_destroy(&ha->mutex);
15923	mutex_destroy(&ha->ql_nack_mtx);
15924	mutex_destroy(&ha->cache_mutex);
15925	mutex_destroy(&ha->dump_mutex);
15926
15927	QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
15928}
15929
15930/*
15931 * ql_fwmodule_resolve
15932 *	Loads and resolves external firmware module and symbols
15933 *
15934 * Input:
15935 *	ha:		adapter state pointer.
15936 *
15937 * Returns:
15938 *	ql local function return status code:
15939 *		QL_SUCCESS - external f/w module module and symbols resolved
15940 *		QL_FW_NOT_SUPPORTED - Driver does not support ISP type
15941 *		QL_FWMODLOAD_FAILED - Could not load f/w module (ddi failed)
15942 *		QL_FWSYM_NOT_FOUND - Unable to resolve internal f/w symbol
15943 * Context:
15944 *	Kernel context.
15945 *
15946 * NOTE: We currently ddi_modopen/ddi_modclose at attach/detach time.  We
15947 * could switch to a tighter scope around acutal download (and add an extra
15948 * ddi_modopen for module opens that occur before root is mounted).
15949 *
15950 */
15951uint32_t
15952ql_fwmodule_resolve(ql_adapter_state_t *ha)
15953{
15954	int8_t			module[128];
15955	int8_t			fw_version[128];
15956	uint32_t		rval = QL_SUCCESS;
15957	caddr_t			code, code02;
15958	uint8_t			*p_ucfw;
15959	uint16_t		*p_usaddr, *p_uslen;
15960	uint32_t		*p_uiaddr, *p_uilen, *p_uifw;
15961	uint32_t		*p_uiaddr02, *p_uilen02;
15962	struct fw_table		*fwt;
15963	extern struct fw_table	fw_table[];
15964
15965	if (ha->fw_module != NULL) {
15966		EL(ha, "%x f/w module %d.%02d.%02d is already loaded\n",
15967		    ha->fw_class, ha->fw_major_version, ha->fw_minor_version,
15968		    ha->fw_subminor_version);
15969		return (rval);
15970	}
15971
15972	/* make sure the fw_class is in the fw_table of supported classes */
15973	for (fwt = &fw_table[0]; fwt->fw_version; fwt++) {
15974		if (fwt->fw_class == ha->fw_class)
15975			break;			/* match */
15976	}
15977	if (fwt->fw_version == NULL) {
15978		cmn_err(CE_WARN, "%s(%d): can't find f/w class %x "
15979		    "in driver's fw_table", QL_NAME, ha->instance,
15980		    ha->fw_class);
15981		return (QL_FW_NOT_SUPPORTED);
15982	}
15983
15984	/*
15985	 * open the module related to the fw_class
15986	 */
15987	(void) snprintf(module, sizeof (module), "misc/qlc/qlc_fw_%x",
15988	    ha->fw_class);
15989
15990	ha->fw_module = ddi_modopen(module, KRTLD_MODE_FIRST, NULL);
15991	if (ha->fw_module == NULL) {
15992		cmn_err(CE_WARN, "%s(%d): can't load firmware file %s",
15993		    QL_NAME, ha->instance, module);
15994		return (QL_FWMODLOAD_FAILED);
15995	}
15996
15997	/*
15998	 * resolve the fw module symbols, data types depend on fw_class
15999	 */
16000
16001	switch (ha->fw_class) {
16002	case 0x2200:
16003	case 0x2300:
16004	case 0x6322:
16005
16006		if ((code = ddi_modsym(ha->fw_module, "risc_code01",
16007		    NULL)) == NULL) {
16008			rval = QL_FWSYM_NOT_FOUND;
16009			EL(ha, "failed, f/w module %d rc01 symbol\n", module);
16010		} else if ((p_usaddr = ddi_modsym(ha->fw_module,
16011		    "risc_code_addr01", NULL)) == NULL) {
16012			rval = QL_FWSYM_NOT_FOUND;
16013			EL(ha, "failed, f/w module %d rca01 symbol\n", module);
16014		} else if ((p_uslen = ddi_modsym(ha->fw_module,
16015		    "risc_code_length01", NULL)) == NULL) {
16016			rval = QL_FWSYM_NOT_FOUND;
16017			EL(ha, "failed, f/w module %d rcl01 symbol\n", module);
16018		} else if ((p_ucfw = ddi_modsym(ha->fw_module,
16019		    "firmware_version", NULL)) == NULL) {
16020			rval = QL_FWSYM_NOT_FOUND;
16021			EL(ha, "failed, f/w module %d fwver symbol\n", module);
16022		}
16023
16024		if (rval == QL_SUCCESS) {
16025			ha->risc_fw[0].code = code;
16026			ha->risc_fw[0].addr = *p_usaddr;
16027			ha->risc_fw[0].length = *p_uslen;
16028
16029			(void) snprintf(fw_version, sizeof (fw_version),
16030			    "%d.%02d.%02d", p_ucfw[0], p_ucfw[1], p_ucfw[2]);
16031		}
16032		break;
16033
16034	case 0x2400:
16035	case 0x2500:
16036
16037		if ((code = ddi_modsym(ha->fw_module, "risc_code01",
16038		    NULL)) == NULL) {
16039			rval = QL_FWSYM_NOT_FOUND;
16040			EL(ha, "failed, f/w module %d rc01 symbol\n", module);
16041		} else if ((p_uiaddr = ddi_modsym(ha->fw_module,
16042		    "risc_code_addr01", NULL)) == NULL) {
16043			rval = QL_FWSYM_NOT_FOUND;
16044			EL(ha, "failed, f/w module %d rca01 symbol\n", module);
16045		} else if ((p_uilen = ddi_modsym(ha->fw_module,
16046		    "risc_code_length01", NULL)) == NULL) {
16047			rval = QL_FWSYM_NOT_FOUND;
16048			EL(ha, "failed, f/w module %d rcl01 symbol\n", module);
16049		} else if ((p_uifw = ddi_modsym(ha->fw_module,
16050		    "firmware_version", NULL)) == NULL) {
16051			rval = QL_FWSYM_NOT_FOUND;
16052			EL(ha, "failed, f/w module %d fwver symbol\n", module);
16053		}
16054
16055		if ((code02 = ddi_modsym(ha->fw_module, "risc_code02",
16056		    NULL)) == NULL) {
16057			rval = QL_FWSYM_NOT_FOUND;
16058			EL(ha, "failed, f/w module %d rc02 symbol\n", module);
16059		} else if ((p_uiaddr02 = ddi_modsym(ha->fw_module,
16060		    "risc_code_addr02", NULL)) == NULL) {
16061			rval = QL_FWSYM_NOT_FOUND;
16062			EL(ha, "failed, f/w module %d rca02 symbol\n", module);
16063		} else if ((p_uilen02 = ddi_modsym(ha->fw_module,
16064		    "risc_code_length02", NULL)) == NULL) {
16065			rval = QL_FWSYM_NOT_FOUND;
16066			EL(ha, "failed, f/w module %d rcl02 symbol\n", module);
16067		}
16068
16069		if (rval == QL_SUCCESS) {
16070			ha->risc_fw[0].code = code;
16071			ha->risc_fw[0].addr = *p_uiaddr;
16072			ha->risc_fw[0].length = *p_uilen;
16073			ha->risc_fw[1].code = code02;
16074			ha->risc_fw[1].addr = *p_uiaddr02;
16075			ha->risc_fw[1].length = *p_uilen02;
16076
16077			(void) snprintf(fw_version, sizeof (fw_version),
16078			    "%d.%02d.%02d", p_uifw[0], p_uifw[1], p_uifw[2]);
16079		}
16080		break;
16081
16082	default:
16083		EL(ha, "fw_class: '%x' is not supported\n", ha->fw_class);
16084		rval = QL_FW_NOT_SUPPORTED;
16085	}
16086
16087	if (rval != QL_SUCCESS) {
16088		cmn_err(CE_WARN, "%s(%d): can't resolve firmware "
16089		    "module %s (%x)", QL_NAME, ha->instance, module, rval);
16090		if (ha->fw_module != NULL) {
16091			(void) ddi_modclose(ha->fw_module);
16092			ha->fw_module = NULL;
16093		}
16094	} else {
16095		/*
16096		 * check for firmware version mismatch between module and
16097		 * compiled in fw_table version.
16098		 */
16099
16100		if (strcmp(fwt->fw_version, fw_version) != 0) {
16101
16102			/*
16103			 * If f/w / driver version mismatches then
16104			 * return a successful status -- however warn
16105			 * the user that this is NOT recommended.
16106			 */
16107
16108			cmn_err(CE_WARN, "%s(%d): driver / f/w version "
16109			    "mismatch for %x: driver-%s module-%s", QL_NAME,
16110			    ha->instance, ha->fw_class, fwt->fw_version,
16111			    fw_version);
16112
16113			ha->cfg_flags |= CFG_FW_MISMATCH;
16114		} else {
16115			ha->cfg_flags &= ~CFG_FW_MISMATCH;
16116		}
16117	}
16118
16119	return (rval);
16120}
16121
16122/*
16123 * ql_port_state
16124 *	Set the state on all adapter ports.
16125 *
16126 * Input:
16127 *	ha:	parent adapter state pointer.
16128 *	state:	port state.
16129 *	flags:	task daemon flags to set.
16130 *
16131 * Context:
16132 *	Interrupt or Kernel context, no mailbox commands allowed.
16133 */
16134void
16135ql_port_state(ql_adapter_state_t *ha, uint32_t state, uint32_t flags)
16136{
16137	ql_adapter_state_t	*vha;
16138
16139	TASK_DAEMON_LOCK(ha);
16140	for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
16141		if (FC_PORT_STATE_MASK(vha->state) != state) {
16142			vha->state = state != FC_STATE_OFFLINE ?
16143			    (FC_PORT_SPEED_MASK(vha->state) | state) : state;
16144			vha->task_daemon_flags |= flags;
16145		}
16146	}
16147	ha->pha->task_daemon_flags |= flags & LOOP_DOWN;
16148	TASK_DAEMON_UNLOCK(ha);
16149}
16150
16151
16152/*
16153 * ql_el_trace_desc_ctor - Construct an extended logging trace descriptor.
16154 *
16155 * Input:	Pointer to the adapter state structure.
16156 * Returns:	Success or Failure.
16157 * Context:	Kernel context.
16158 */
16159int
16160ql_el_trace_desc_ctor(ql_adapter_state_t *ha)
16161{
16162	int	rval;
16163
16164	rval = DDI_SUCCESS;
16165
16166	ha->el_trace_desc =
16167	    (el_trace_desc_t *)kmem_zalloc(sizeof (el_trace_desc_t), KM_SLEEP);
16168
16169	if (ha->el_trace_desc == NULL) {
16170		cmn_err(CE_WARN, "%s(%d): can't construct trace descriptor",
16171		    QL_NAME, ha->instance);
16172		rval = DDI_FAILURE;
16173	} else {
16174		ha->el_trace_desc->next		= 0;
16175		ha->el_trace_desc->trace_buffer =
16176		    (char *)kmem_zalloc(EL_TRACE_BUF_SIZE, KM_SLEEP);
16177
16178		if (ha->el_trace_desc->trace_buffer == NULL) {
16179			cmn_err(CE_WARN, "%s(%d): can't get trace buffer",
16180			    QL_NAME, ha->instance);
16181			kmem_free(ha->el_trace_desc, sizeof (el_trace_desc_t));
16182			rval = DDI_FAILURE;
16183		} else {
16184			ha->el_trace_desc->trace_buffer_size =
16185			    EL_TRACE_BUF_SIZE;
16186			mutex_init(&ha->el_trace_desc->mutex, NULL,
16187			    MUTEX_DRIVER, NULL);
16188		}
16189	}
16190	return (rval);
16191}
16192
16193/*
16194 * ql_el_trace_desc_dtor - Destroy an extended logging trace descriptor.
16195 *
16196 * Input:	Pointer to the adapter state structure.
16197 * Returns:	Success or Failure.
16198 * Context:	Kernel context.
16199 */
16200int
16201ql_el_trace_desc_dtor(ql_adapter_state_t *ha)
16202{
16203	int	rval;
16204
16205	rval = DDI_SUCCESS;
16206
16207	if (ha->el_trace_desc == NULL) {
16208		cmn_err(CE_WARN, "%s(%d): can't destroy el trace descriptor",
16209		    QL_NAME, ha->instance);
16210		rval = DDI_FAILURE;
16211	} else {
16212		if (ha->el_trace_desc->trace_buffer != NULL) {
16213			kmem_free(ha->el_trace_desc->trace_buffer,
16214			    ha->el_trace_desc->trace_buffer_size);
16215		}
16216		mutex_destroy(&ha->el_trace_desc->mutex);
16217		kmem_free(ha->el_trace_desc, sizeof (el_trace_desc_t));
16218	}
16219	return (rval);
16220}
16221
16222/*
16223 * els_cmd_text	- Return a pointer to a string describing the command
16224 *
16225 * Input:	els_cmd = the els command opcode.
16226 * Returns:	pointer to a string.
16227 * Context:	Kernel context.
16228 */
16229char *
16230els_cmd_text(int els_cmd)
16231{
16232	cmd_table_t *entry = &els_cmd_tbl[0];
16233
16234	return (cmd_text(entry, els_cmd));
16235}
16236
16237/*
16238 * mbx_cmd_text - Return a pointer to a string describing the command
16239 *
16240 * Input:	mbx_cmd = the mailbox command opcode.
16241 * Returns:	pointer to a string.
16242 * Context:	Kernel context.
16243 */
16244char *
16245mbx_cmd_text(int mbx_cmd)
16246{
16247	cmd_table_t *entry = &mbox_cmd_tbl[0];
16248
16249	return (cmd_text(entry, mbx_cmd));
16250}
16251
16252/*
16253 * cmd_text	Return a pointer to a string describing the command
16254 *
16255 * Input:	entry = the command table
16256 *		cmd = the command.
16257 * Returns:	pointer to a string.
16258 * Context:	Kernel context.
16259 */
16260char *
16261cmd_text(cmd_table_t *entry, int cmd)
16262{
16263	for (; entry->cmd != 0; entry++) {
16264		if (entry->cmd == cmd) {
16265			break;
16266		}
16267	}
16268	return (entry->string);
16269}
16270