ql_api.c revision 11387:0072514d53c7
1193323Sed/*
2193323Sed * CDDL HEADER START
3193323Sed *
4193323Sed * The contents of this file are subject to the terms of the
5193323Sed * Common Development and Distribution License (the "License").
6193323Sed * You may not use this file except in compliance with the License.
7193323Sed *
8193323Sed * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9193323Sed * or http://www.opensolaris.org/os/licensing.
10193323Sed * See the License for the specific language governing permissions
11193323Sed * and limitations under the License.
12193323Sed *
13193323Sed * When distributing Covered Code, include this CDDL HEADER in each
14193323Sed * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15193323Sed * If applicable, add the following below this CDDL HEADER, with the
16193323Sed * fields enclosed by brackets "[]" replaced with your own identifying
17193323Sed * information: Portions Copyright [yyyy] [name of copyright owner]
18193323Sed *
19193323Sed * CDDL HEADER END
20193323Sed */
21199989Srdivacky
22193323Sed/* Copyright 2009 QLogic Corporation */
23198090Srdivacky
24193323Sed/*
25193323Sed * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
26193323Sed * Use is subject to license terms.
27193323Sed */
28193323Sed
29193323Sed#pragma ident	"Copyright 2009 QLogic Corporation; ql_api.c"
30193323Sed
31193323Sed/*
32193323Sed * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
33198090Srdivacky *
34198090Srdivacky * ***********************************************************************
35198090Srdivacky * *									**
36198090Srdivacky * *				NOTICE					**
37198090Srdivacky * *		COPYRIGHT (C) 1996-2009 QLOGIC CORPORATION		**
38198090Srdivacky * *			ALL RIGHTS RESERVED				**
39198090Srdivacky * *									**
40193323Sed * ***********************************************************************
41193323Sed *
42193323Sed */
43193323Sed
44193323Sed#include <ql_apps.h>
45193323Sed#include <ql_api.h>
46193323Sed#include <ql_debug.h>
47193323Sed#include <ql_init.h>
48193323Sed#include <ql_iocb.h>
49193323Sed#include <ql_ioctl.h>
50193323Sed#include <ql_isr.h>
51193323Sed#include <ql_mbx.h>
52193323Sed#include <ql_xioctl.h>
53193323Sed
54193323Sed/*
55193323Sed * Solaris external defines.
56193323Sed */
57193323Sedextern pri_t minclsyspri;
58193323Sedextern pri_t maxclsyspri;
59193323Sed
60193323Sed/*
61193323Sed * dev_ops functions prototypes
62193323Sed */
63193323Sedstatic int ql_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
64193323Sedstatic int ql_attach(dev_info_t *, ddi_attach_cmd_t);
65193323Sedstatic int ql_detach(dev_info_t *, ddi_detach_cmd_t);
66193323Sedstatic int ql_power(dev_info_t *, int, int);
67193323Sedstatic int ql_quiesce(dev_info_t *);
68193323Sed
69193323Sed/*
70193323Sed * FCA functions prototypes exported by means of the transport table
71193323Sed */
72193323Sedstatic opaque_t ql_bind_port(dev_info_t *, fc_fca_port_info_t *,
73193323Sed    fc_fca_bind_info_t *);
74193323Sedstatic void ql_unbind_port(opaque_t);
75193323Sedstatic int ql_init_pkt(opaque_t, fc_packet_t *, int);
76193323Sedstatic int ql_un_init_pkt(opaque_t, fc_packet_t *);
77193323Sedstatic int ql_els_send(opaque_t, fc_packet_t *);
78193323Sedstatic int ql_get_cap(opaque_t, char *, void *);
79193323Sedstatic int ql_set_cap(opaque_t, char *, void *);
80193323Sedstatic int ql_getmap(opaque_t, fc_lilpmap_t *);
81193323Sedstatic int ql_transport(opaque_t, fc_packet_t *);
82193323Sedstatic int ql_ub_alloc(opaque_t, uint64_t *, uint32_t, uint32_t *, uint32_t);
83193323Sedstatic int ql_ub_free(opaque_t, uint32_t, uint64_t *);
84193323Sedstatic int ql_ub_release(opaque_t, uint32_t, uint64_t *);
85193323Sedstatic int ql_abort(opaque_t, fc_packet_t *, int);
86193323Sedstatic int ql_reset(opaque_t, uint32_t);
87193323Sedstatic int ql_port_manage(opaque_t, fc_fca_pm_t *);
88193323Sedstatic opaque_t ql_get_device(opaque_t, fc_portid_t);
89193323Sed
90193323Sed/*
91193323Sed * FCA Driver Support Function Prototypes.
92193323Sed */
93193323Sedstatic uint16_t	ql_wait_outstanding(ql_adapter_state_t *);
94193323Sedstatic void ql_task_mgmt(ql_adapter_state_t *, ql_tgt_t *, fc_packet_t *,
95193323Sed    ql_srb_t *);
96193323Sedstatic void ql_task_daemon(void *);
97193323Sedstatic void ql_task_thread(ql_adapter_state_t *);
98193323Sedstatic void ql_unsol_callback(ql_srb_t *);
99193323Sedstatic void ql_free_unsolicited_buffer(ql_adapter_state_t *,
100193323Sed    fc_unsol_buf_t *);
101193323Sedstatic void ql_timer(void *);
102193323Sedstatic void ql_watchdog(ql_adapter_state_t *, uint32_t *, uint32_t *);
103193323Sedstatic void ql_cmd_timeout(ql_adapter_state_t *, ql_tgt_t *q, ql_srb_t *,
104193323Sed    uint32_t *, uint32_t *);
105193323Sedstatic void ql_halt(ql_adapter_state_t *, int);
106193323Sedstatic int ql_els_plogi(ql_adapter_state_t *, fc_packet_t *);
107193323Sedstatic int ql_els_flogi(ql_adapter_state_t *, fc_packet_t *);
108193323Sedstatic int ql_els_logo(ql_adapter_state_t *, fc_packet_t *);
109193323Sedstatic int ql_els_prli(ql_adapter_state_t *, fc_packet_t *);
110193323Sedstatic int ql_els_prlo(ql_adapter_state_t *, fc_packet_t *);
111193323Sedstatic int ql_els_adisc(ql_adapter_state_t *, fc_packet_t *);
112193323Sedstatic int ql_els_linit(ql_adapter_state_t *, fc_packet_t *);
113193323Sedstatic int ql_els_lpc(ql_adapter_state_t *, fc_packet_t *);
114193323Sedstatic int ql_els_lsts(ql_adapter_state_t *, fc_packet_t *);
115193323Sedstatic int ql_els_scr(ql_adapter_state_t *, fc_packet_t *);
116193323Sedstatic int ql_els_rscn(ql_adapter_state_t *, fc_packet_t *);
117193323Sedstatic int ql_els_farp_req(ql_adapter_state_t *, fc_packet_t *);
118193323Sedstatic int ql_els_farp_reply(ql_adapter_state_t *, fc_packet_t *);
119193323Sedstatic int ql_els_rls(ql_adapter_state_t *, fc_packet_t *);
120193323Sedstatic int ql_els_rnid(ql_adapter_state_t *, fc_packet_t *);
121193323Sedstatic int ql_login_port(ql_adapter_state_t *, port_id_t);
122193323Sedstatic int ql_login_fabric_port(ql_adapter_state_t *, ql_tgt_t *, uint16_t);
123193323Sedstatic int ql_logout_port(ql_adapter_state_t *, port_id_t);
124193323Sedstatic ql_lun_t *ql_lun_queue(ql_adapter_state_t *, ql_tgt_t *, uint16_t);
125193323Sedstatic int ql_fcp_scsi_cmd(ql_adapter_state_t *, fc_packet_t *, ql_srb_t *);
126193323Sedstatic int ql_fcp_ip_cmd(ql_adapter_state_t *, fc_packet_t *, ql_srb_t *);
127193323Sedstatic int ql_fc_services(ql_adapter_state_t *, fc_packet_t *);
128193323Sedstatic int ql_poll_cmd(ql_adapter_state_t *, ql_srb_t *, time_t);
129193323Sedstatic int ql_start_cmd(ql_adapter_state_t *, ql_tgt_t *, fc_packet_t *,
130193323Sed    ql_srb_t *);
131193323Sedstatic int ql_kstat_update(kstat_t *, int);
132193323Sedstatic ql_adapter_state_t *ql_fca_handle_to_state(opaque_t);
133193323Sedstatic ql_adapter_state_t *ql_cmd_setup(opaque_t, fc_packet_t *, int *);
134193323Sedstatic int ql_program_flash_address(ql_adapter_state_t *, uint32_t, uint8_t);
135193323Sedstatic void ql_rst_aen(ql_adapter_state_t *);
136193323Sedstatic void ql_restart_queues(ql_adapter_state_t *);
137193323Sedstatic void ql_abort_queues(ql_adapter_state_t *);
138193323Sedstatic void ql_abort_device_queues(ql_adapter_state_t *ha, ql_tgt_t *tq);
139193323Sedstatic void ql_idle_check(ql_adapter_state_t *);
140193323Sedstatic int ql_loop_resync(ql_adapter_state_t *);
141193323Sedstatic size_t ql_24xx_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
142193323Sedstatic size_t ql_2581_ascii_fw_dump(ql_adapter_state_t *, caddr_t);
143193323Sedstatic int ql_save_config_regs(dev_info_t *);
144193323Sedstatic int ql_restore_config_regs(dev_info_t *);
145193323Sedstatic int ql_process_rscn(ql_adapter_state_t *, fc_affected_id_t *);
146193323Sedstatic int ql_handle_rscn_update(ql_adapter_state_t *);
147193323Sedstatic int ql_send_plogi(ql_adapter_state_t *, ql_tgt_t *, ql_head_t *);
148193323Sedstatic int ql_process_rscn_for_device(ql_adapter_state_t *, ql_tgt_t *);
149193323Sedstatic int ql_dump_firmware(ql_adapter_state_t *);
150193323Sedstatic int ql_process_logo_for_device(ql_adapter_state_t *, ql_tgt_t *);
151193323Sedstatic int ql_2200_binary_fw_dump(ql_adapter_state_t *, ql_fw_dump_t *);
152193323Sedstatic int ql_2300_binary_fw_dump(ql_adapter_state_t *, ql_fw_dump_t *);
153193323Sedstatic int ql_24xx_binary_fw_dump(ql_adapter_state_t *, ql_24xx_fw_dump_t *);
154193323Sedstatic int ql_25xx_binary_fw_dump(ql_adapter_state_t *, ql_25xx_fw_dump_t *);
155193323Sedstatic int ql_81xx_binary_fw_dump(ql_adapter_state_t *, ql_81xx_fw_dump_t *);
156193323Sedstatic int ql_read_risc_ram(ql_adapter_state_t *, uint32_t, uint32_t,
157193323Sed    void *);
158193323Sedstatic void *ql_read_regs(ql_adapter_state_t *, void *, void *, uint32_t,
159193323Sed    uint8_t);
160193323Sedstatic int ql_busy_plogi(ql_adapter_state_t *, fc_packet_t *, ql_tgt_t *);
161193323Sedstatic int ql_suspend_adapter(ql_adapter_state_t *);
162193323Sedstatic int ql_bstr_to_dec(char *, uint32_t *, uint32_t);
163193323Sedstatic void ql_update_rscn(ql_adapter_state_t *, fc_affected_id_t *);
164193323Sedint ql_alloc_dma_resouce(ql_adapter_state_t *, dma_mem_t *, int);
165193323Sedstatic int ql_bind_dma_buffer(ql_adapter_state_t *, dma_mem_t *, int);
166193323Sedstatic void ql_unbind_dma_buffer(ql_adapter_state_t *, dma_mem_t *);
167193323Sedstatic void ql_timeout_insert(ql_adapter_state_t *, ql_tgt_t *, ql_srb_t *);
168193323Sedstatic int ql_setup_interrupts(ql_adapter_state_t *);
169193323Sedstatic int ql_setup_msi(ql_adapter_state_t *);
170193323Sedstatic int ql_setup_msix(ql_adapter_state_t *);
171193323Sedstatic int ql_setup_fixed(ql_adapter_state_t *);
172193323Sedstatic void ql_release_intr(ql_adapter_state_t *);
173193323Sedstatic void ql_disable_intr(ql_adapter_state_t *);
174193323Sedstatic int ql_legacy_intr(ql_adapter_state_t *);
175193323Sedstatic int ql_init_mutex(ql_adapter_state_t *);
176193323Sedstatic void ql_destroy_mutex(ql_adapter_state_t *);
177193323Sedstatic void ql_iidma(ql_adapter_state_t *);
178193323Sed
179193323Sedstatic int ql_n_port_plogi(ql_adapter_state_t *);
180193323Sedstatic void ql_fca_isp_els_request(ql_adapter_state_t *, fc_packet_t *,
181193323Sed    els_descriptor_t *);
182193323Sedstatic void ql_isp_els_request_ctor(els_descriptor_t *,
183193323Sed    els_passthru_entry_t *);
184193323Sedstatic int ql_p2p_plogi(ql_adapter_state_t *, fc_packet_t *);
185193323Sedstatic int ql_wait_for_td_stop(ql_adapter_state_t *ha);
186193323Sed
187193323Sed/*
188193323Sed * Global data
189226633Sdim */
190226633Sdimstatic uint8_t	ql_enable_pm = 1;
191226633Sdimstatic int	ql_flash_sbus_fpga = 0;
192226633Sdimuint32_t	ql_os_release_level;
193193323Seduint32_t	ql_disable_aif = 0;
194226633Sdimuint32_t	ql_disable_msi = 0;
195226633Sdimuint32_t	ql_disable_msix = 0;
196193323Sed
197226633Sdim/* Timer routine variables. */
198226633Sdimstatic timeout_id_t	ql_timer_timeout_id = NULL;
199226633Sdimstatic clock_t		ql_timer_ticks;
200226633Sdim
201226633Sdim/* Soft state head pointer. */
202226633Sdimvoid *ql_state = NULL;
203226633Sdim
204193323Sed/* Head adapter link. */
205193323Sedql_head_t ql_hba = {
206193323Sed	NULL,
207193323Sed	NULL
208193323Sed};
209193323Sed
210193323Sed/* Global hba index */
211193323Seduint32_t ql_gfru_hba_index = 1;
212193323Sed
213193323Sed/*
214193323Sed * Some IP defines and globals
215193323Sed */
216193323Seduint32_t	ql_ip_buffer_count = 128;
217193323Seduint32_t	ql_ip_low_water = 10;
218193323Seduint8_t		ql_ip_fast_post_count = 5;
219193323Sedstatic int	ql_ip_mtu = 65280;		/* equivalent to FCIPMTU */
220193323Sed
221193323Sed/* Device AL_PA to Device Head Queue index array. */
222193323Seduint8_t ql_alpa_to_index[] = {
223193323Sed	0x7e, 0x7d, 0x7c, 0x00, 0x7b, 0x01, 0x02, 0x03, 0x7a, 0x04,
224212904Sdim	0x05, 0x06, 0x07, 0x08, 0x09, 0x79, 0x78, 0x0a, 0x0b, 0x0c,
225193323Sed	0x0d, 0x0e, 0x0f, 0x77, 0x76, 0x10, 0x11, 0x75, 0x12, 0x74,
226193323Sed	0x73, 0x72, 0x13, 0x14, 0x15, 0x71, 0x16, 0x70, 0x6f, 0x6e,
227193323Sed	0x17, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x18, 0x19, 0x67,
228193323Sed	0x66, 0x65, 0x64, 0x63, 0x62, 0x20, 0x21, 0x61, 0x60, 0x23,
229193323Sed	0x5f, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x5e, 0x2a, 0x5d,
230193323Sed	0x5c, 0x5b, 0x2b, 0x5a, 0x59, 0x58, 0x57, 0x56, 0x55, 0x2c,
231193323Sed	0x2d, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x2e, 0x2f, 0x4e,
232193323Sed	0x4d, 0x30, 0x4c, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x4b,
233193323Sed	0x37, 0x4a, 0x49, 0x48, 0x38, 0x47, 0x46, 0x45, 0x44, 0x43,
234193323Sed	0x42, 0x39, 0x3a, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b,
235193323Sed	0x3c, 0x3b, 0x3a, 0x3d, 0x39, 0x3e, 0x3f, 0x40, 0x38, 0x37,
236193323Sed	0x36, 0x41, 0x35, 0x42, 0x43, 0x44, 0x34, 0x45, 0x46, 0x47,
237193323Sed	0x48, 0x49, 0x4a, 0x33, 0x32, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
238193323Sed	0x50, 0x31, 0x30, 0x51, 0x52, 0x2f, 0x53, 0x2e, 0x2d, 0x2c,
239193323Sed	0x54, 0x55, 0x56, 0x2b, 0x57, 0x2a, 0x29, 0x28, 0x58, 0x27,
240193323Sed	0x26, 0x25, 0x24, 0x23, 0x22, 0x59, 0x5a, 0x21, 0x20, 0x1f,
241193323Sed	0x1e, 0x1d, 0x1c, 0x5b, 0x5c, 0x1b, 0x1a, 0x5d, 0x19, 0x5e,
242212904Sdim	0x5f, 0x60, 0x61, 0x62, 0x63, 0x18, 0x64, 0x17, 0x16, 0x15,
243193323Sed	0x65, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x66, 0x67, 0x0e,
244193323Sed	0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x68, 0x69, 0x08, 0x07, 0x6a,
245193323Sed	0x06, 0x6b, 0x6c, 0x6d, 0x05, 0x04, 0x03, 0x6e, 0x02, 0x6f,
246193323Sed	0x70, 0x71, 0x01, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x00,
247193323Sed	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7f, 0x80, 0x00, 0x01,
248193323Sed	0x02, 0x03, 0x80, 0x7f, 0x7e, 0x04
249193323Sed};
250193323Sed
251193323Sed/* Device loop_id to ALPA array. */
252193323Sedstatic uint8_t ql_index_to_alpa[] = {
253193323Sed	0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda, 0xd9, 0xd6,
254193323Sed	0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce, 0xcd, 0xcc, 0xcb, 0xca,
255193323Sed	0xc9, 0xc7, 0xc6, 0xc5, 0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5,
256193323Sed	0xb4, 0xb3, 0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
257193323Sed	0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b, 0x98, 0x97,
258193323Sed	0x90, 0x8f, 0x88, 0x84, 0x82, 0x81, 0x80, 0x7c, 0x7a, 0x79,
259193323Sed	0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b,
260193323Sed	0x6a, 0x69, 0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
261193323Sed	0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a,
262193323Sed	0x49, 0x47, 0x46, 0x45, 0x43, 0x3c, 0x3a, 0x39, 0x36, 0x35,
263193323Sed	0x34, 0x33, 0x32, 0x31, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29,
264193323Sed	0x27, 0x26, 0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
265193323Sed	0x10, 0x0f, 0x08, 0x04, 0x02, 0x01
266193323Sed};
267193323Sed
268193323Sed/* 2200 register offsets */
269193323Sedstatic reg_off_t reg_off_2200 = {
270199481Srdivacky	0x00, 0x02, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
271199481Srdivacky	0x18, 0x18, 0x1A, 0x1A, /* req in, out, resp in, out */
272199481Srdivacky	0x00, 0x00, /* intr info lo, hi */
273199481Srdivacky	24, /* Number of mailboxes */
274199481Srdivacky	/* Mailbox register offsets */
275199481Srdivacky	0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
276199481Srdivacky	0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee,
277199481Srdivacky	0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
278205218Srdivacky	/* 2200 does not have mailbox 24-31 */
279205218Srdivacky	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
280205218Srdivacky	0x96, 0xa4, 0xb0, 0xb8, 0xc0, 0xcc, 0xce,
281205218Srdivacky	/* host to host sema */
282205218Srdivacky	0x00,
283205218Srdivacky	/* 2200 does not have pri_req_in, pri_req_out, */
284205218Srdivacky	/* atio_req_in, atio_req_out, io_base_addr */
285205218Srdivacky	0xff, 0xff, 0xff, 0xff,	0xff
286205218Srdivacky};
287205218Srdivacky
288205218Srdivacky/* 2300 register offsets */
289205218Srdivackystatic reg_off_t reg_off_2300 = {
290205218Srdivacky	0x00, 0x02, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
291205218Srdivacky	0x10, 0x12, 0x14, 0x16, /* req in, out, resp in, out */
292205218Srdivacky	0x18, 0x1A, /* intr info lo, hi */
293205218Srdivacky	32, /* Number of mailboxes */
294205218Srdivacky	/* Mailbox register offsets */
295205218Srdivacky	0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e,
296205218Srdivacky	0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
297205218Srdivacky	0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e,
298205218Srdivacky	0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
299205218Srdivacky	0x96, 0xa4, 0xb0, 0x80, 0xc0, 0xcc, 0xce,
300193323Sed	/* host to host sema */
301193323Sed	0x1c,
302193323Sed	/* 2300 does not have pri_req_in, pri_req_out, */
303	/* atio_req_in, atio_req_out, io_base_addr */
304	0xff, 0xff, 0xff, 0xff,	0xff
305};
306
307/* 2400/2500 register offsets */
308reg_off_t reg_off_2400_2500 = {
309	0x00, 0x04,		/* flash_address, flash_data */
310	0x08, 0x0c, 0x10,	/* ctrl_status, ictrl, istatus */
311	/* 2400 does not have semaphore, nvram */
312	0x14, 0x18,
313	0x1c, 0x20, 0x24, 0x28, /* req_in, req_out, resp_in, resp_out */
314	0x44, 0x46,		/* intr info lo, hi */
315	32,			/* Number of mailboxes */
316	/* Mailbox register offsets */
317	0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,
318	0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
319	0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae,
320	0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
321	/* 2400 does not have fpm_diag_config, pcr, mctr, fb_cmd */
322	0xff, 0xff, 0xff, 0xff,
323	0x48, 0x4c, 0x50,	/* hccr, gpiod, gpioe */
324	0xff,			/* host to host sema */
325	0x2c, 0x30,		/* pri_req_in, pri_req_out */
326	0x3c, 0x40,		/* atio_req_in, atio_req_out */
327	0x54			/* io_base_addr */
328};
329
330/* mutex for protecting variables shared by all instances of the driver */
331kmutex_t ql_global_mutex;
332kmutex_t ql_global_hw_mutex;
333kmutex_t ql_global_el_mutex;
334
335/* DMA access attribute structure. */
336static ddi_device_acc_attr_t ql_dev_acc_attr = {
337	DDI_DEVICE_ATTR_V0,
338	DDI_STRUCTURE_LE_ACC,
339	DDI_STRICTORDER_ACC
340};
341
342/* I/O DMA attributes structures. */
343static ddi_dma_attr_t ql_64bit_io_dma_attr = {
344	DMA_ATTR_V0,			/* dma_attr_version */
345	QL_DMA_LOW_ADDRESS,		/* low DMA address range */
346	QL_DMA_HIGH_64BIT_ADDRESS,	/* high DMA address range */
347	QL_DMA_XFER_COUNTER,		/* DMA counter register */
348	QL_DMA_ADDRESS_ALIGNMENT,	/* DMA address alignment */
349	QL_DMA_BURSTSIZES,		/* DMA burstsizes */
350	QL_DMA_MIN_XFER_SIZE,		/* min effective DMA size */
351	QL_DMA_MAX_XFER_SIZE,		/* max DMA xfer size */
352	QL_DMA_SEGMENT_BOUNDARY,	/* segment boundary */
353	QL_DMA_SG_LIST_LENGTH,		/* s/g list length */
354	QL_DMA_GRANULARITY,		/* granularity of device */
355	QL_DMA_XFER_FLAGS		/* DMA transfer flags */
356};
357
358static ddi_dma_attr_t ql_32bit_io_dma_attr = {
359	DMA_ATTR_V0,			/* dma_attr_version */
360	QL_DMA_LOW_ADDRESS,		/* low DMA address range */
361	QL_DMA_HIGH_32BIT_ADDRESS,	/* high DMA address range */
362	QL_DMA_XFER_COUNTER,		/* DMA counter register */
363	QL_DMA_ADDRESS_ALIGNMENT,	/* DMA address alignment */
364	QL_DMA_BURSTSIZES,		/* DMA burstsizes */
365	QL_DMA_MIN_XFER_SIZE,		/* min effective DMA size */
366	QL_DMA_MAX_XFER_SIZE,		/* max DMA xfer size */
367	QL_DMA_SEGMENT_BOUNDARY,	/* segment boundary */
368	QL_DMA_SG_LIST_LENGTH,		/* s/g list length */
369	QL_DMA_GRANULARITY,		/* granularity of device */
370	QL_DMA_XFER_FLAGS		/* DMA transfer flags */
371};
372
373/* Load the default dma attributes */
374static	ddi_dma_attr_t	ql_32fcsm_cmd_dma_attr;
375static	ddi_dma_attr_t	ql_64fcsm_cmd_dma_attr;
376static	ddi_dma_attr_t	ql_32fcsm_rsp_dma_attr;
377static	ddi_dma_attr_t	ql_64fcsm_rsp_dma_attr;
378static	ddi_dma_attr_t	ql_32fcip_cmd_dma_attr;
379static	ddi_dma_attr_t	ql_64fcip_cmd_dma_attr;
380static	ddi_dma_attr_t	ql_32fcip_rsp_dma_attr;
381static	ddi_dma_attr_t	ql_64fcip_rsp_dma_attr;
382static	ddi_dma_attr_t	ql_32fcp_cmd_dma_attr;
383static	ddi_dma_attr_t	ql_64fcp_cmd_dma_attr;
384static	ddi_dma_attr_t	ql_32fcp_rsp_dma_attr;
385static	ddi_dma_attr_t	ql_64fcp_rsp_dma_attr;
386static	ddi_dma_attr_t	ql_32fcp_data_dma_attr;
387static	ddi_dma_attr_t	ql_64fcp_data_dma_attr;
388
389/* Static declarations of cb_ops entry point functions... */
390static struct cb_ops ql_cb_ops = {
391	ql_open,			/* b/c open */
392	ql_close,			/* b/c close */
393	nodev,				/* b strategy */
394	nodev,				/* b print */
395	nodev,				/* b dump */
396	nodev,				/* c read */
397	nodev,				/* c write */
398	ql_ioctl,			/* c ioctl */
399	nodev,				/* c devmap */
400	nodev,				/* c mmap */
401	nodev,				/* c segmap */
402	nochpoll,			/* c poll */
403	nodev,				/* cb_prop_op */
404	NULL,				/* streamtab  */
405	D_MP | D_NEW | D_HOTPLUG,	/* Driver compatibility flag */
406	CB_REV,				/* cb_ops revision */
407	nodev,				/* c aread */
408	nodev				/* c awrite */
409};
410
411/* Static declarations of dev_ops entry point functions... */
412static struct dev_ops ql_devops = {
413	DEVO_REV,			/* devo_rev */
414	0,				/* refcnt */
415	ql_getinfo,			/* getinfo */
416	nulldev,			/* identify */
417	nulldev,			/* probe */
418	ql_attach,			/* attach */
419	ql_detach,			/* detach */
420	nodev,				/* reset */
421	&ql_cb_ops,			/* char/block ops */
422	NULL,				/* bus operations */
423	ql_power,			/* power management */
424	ql_quiesce			/* quiesce device */
425};
426
427/* ELS command code to text converter */
428cmd_table_t els_cmd_tbl[] = ELS_CMD_TABLE();
429/* Mailbox command code to text converter */
430cmd_table_t mbox_cmd_tbl[] = MBOX_CMD_TABLE();
431
432char qlc_driver_version[] = QL_VERSION;
433
434/*
435 * Loadable Driver Interface Structures.
436 * Declare and initialize the module configuration section...
437 */
438static struct modldrv modldrv = {
439	&mod_driverops,				/* type of module: driver */
440	"SunFC Qlogic FCA v" QL_VERSION,	/* name of module */
441	&ql_devops				/* driver dev_ops */
442};
443
444static struct modlinkage modlinkage = {
445	MODREV_1,
446	&modldrv,
447	NULL
448};
449
450/* ************************************************************************ */
451/*				Loadable Module Routines.		    */
452/* ************************************************************************ */
453
454/*
455 * _init
456 *	Initializes a loadable module. It is called before any other
457 *	routine in a loadable module.
458 *
459 * Returns:
460 *	0 = success
461 *
462 * Context:
463 *	Kernel context.
464 */
465int
466_init(void)
467{
468	uint16_t	w16;
469	int		rval = 0;
470
471	/* Get OS major release level. */
472	for (w16 = 0; w16 < sizeof (utsname.release); w16++) {
473		if (utsname.release[w16] == '.') {
474			w16++;
475			break;
476		}
477	}
478	if (w16 < sizeof (utsname.release)) {
479		(void) ql_bstr_to_dec(&utsname.release[w16],
480		    &ql_os_release_level, 0);
481	} else {
482		ql_os_release_level = 0;
483	}
484	if (ql_os_release_level < 6) {
485		cmn_err(CE_WARN, "%s Unsupported OS release level = %d",
486		    QL_NAME, ql_os_release_level);
487		rval = EINVAL;
488	}
489	if (ql_os_release_level == 6) {
490		ql_32bit_io_dma_attr.dma_attr_count_max = 0x00ffffff;
491		ql_64bit_io_dma_attr.dma_attr_count_max = 0x00ffffff;
492	}
493
494	if (rval == 0) {
495		rval = ddi_soft_state_init(&ql_state,
496		    sizeof (ql_adapter_state_t), 0);
497	}
498	if (rval == 0) {
499		/* allow the FC Transport to tweak the dev_ops */
500		fc_fca_init(&ql_devops);
501
502		mutex_init(&ql_global_mutex, NULL, MUTEX_DRIVER, NULL);
503		mutex_init(&ql_global_hw_mutex, NULL, MUTEX_DRIVER, NULL);
504		mutex_init(&ql_global_el_mutex, NULL, MUTEX_DRIVER, NULL);
505		rval = mod_install(&modlinkage);
506		if (rval != 0) {
507			mutex_destroy(&ql_global_hw_mutex);
508			mutex_destroy(&ql_global_mutex);
509			mutex_destroy(&ql_global_el_mutex);
510			ddi_soft_state_fini(&ql_state);
511		} else {
512			/*EMPTY*/
513			ql_32fcsm_cmd_dma_attr = ql_32bit_io_dma_attr;
514			ql_64fcsm_cmd_dma_attr = ql_64bit_io_dma_attr;
515			ql_32fcsm_rsp_dma_attr = ql_32bit_io_dma_attr;
516			ql_64fcsm_rsp_dma_attr = ql_64bit_io_dma_attr;
517			ql_32fcip_cmd_dma_attr = ql_32bit_io_dma_attr;
518			ql_64fcip_cmd_dma_attr = ql_64bit_io_dma_attr;
519			ql_32fcip_rsp_dma_attr = ql_32bit_io_dma_attr;
520			ql_64fcip_rsp_dma_attr = ql_64bit_io_dma_attr;
521			ql_32fcp_cmd_dma_attr = ql_32bit_io_dma_attr;
522			ql_64fcp_cmd_dma_attr = ql_64bit_io_dma_attr;
523			ql_32fcp_rsp_dma_attr = ql_32bit_io_dma_attr;
524			ql_64fcp_rsp_dma_attr = ql_64bit_io_dma_attr;
525			ql_32fcp_data_dma_attr = ql_32bit_io_dma_attr;
526			ql_64fcp_data_dma_attr = ql_64bit_io_dma_attr;
527			ql_32fcsm_cmd_dma_attr.dma_attr_sgllen =
528			    ql_64fcsm_cmd_dma_attr.dma_attr_sgllen =
529			    QL_FCSM_CMD_SGLLEN;
530			ql_32fcsm_rsp_dma_attr.dma_attr_sgllen =
531			    ql_64fcsm_rsp_dma_attr.dma_attr_sgllen =
532			    QL_FCSM_RSP_SGLLEN;
533			ql_32fcip_cmd_dma_attr.dma_attr_sgllen =
534			    ql_64fcip_cmd_dma_attr.dma_attr_sgllen =
535			    QL_FCIP_CMD_SGLLEN;
536			ql_32fcip_rsp_dma_attr.dma_attr_sgllen =
537			    ql_64fcip_rsp_dma_attr.dma_attr_sgllen =
538			    QL_FCIP_RSP_SGLLEN;
539			ql_32fcp_cmd_dma_attr.dma_attr_sgllen =
540			    ql_64fcp_cmd_dma_attr.dma_attr_sgllen =
541			    QL_FCP_CMD_SGLLEN;
542			ql_32fcp_rsp_dma_attr.dma_attr_sgllen =
543			    ql_64fcp_rsp_dma_attr.dma_attr_sgllen =
544			    QL_FCP_RSP_SGLLEN;
545		}
546	}
547
548	if (rval != 0) {
549		cmn_err(CE_CONT, "?Unable to install/attach driver '%s'",
550		    QL_NAME);
551	}
552
553	return (rval);
554}
555
556/*
557 * _fini
558 *	Prepares a module for unloading. It is called when the system
559 *	wants to unload a module. If the module determines that it can
560 *	be unloaded, then _fini() returns the value returned by
561 *	mod_remove(). Upon successful return from _fini() no other
562 *	routine in the module will be called before _init() is called.
563 *
564 * Returns:
565 *	0 = success
566 *
567 * Context:
568 *	Kernel context.
569 */
570int
571_fini(void)
572{
573	int	rval;
574
575	rval = mod_remove(&modlinkage);
576	if (rval == 0) {
577		mutex_destroy(&ql_global_hw_mutex);
578		mutex_destroy(&ql_global_mutex);
579		mutex_destroy(&ql_global_el_mutex);
580		ddi_soft_state_fini(&ql_state);
581	}
582
583	return (rval);
584}
585
586/*
587 * _info
588 *	Returns information about loadable module.
589 *
590 * Input:
591 *	modinfo = pointer to module information structure.
592 *
593 * Returns:
594 *	Value returned by mod_info().
595 *
596 * Context:
597 *	Kernel context.
598 */
599int
600_info(struct modinfo *modinfop)
601{
602	return (mod_info(&modlinkage, modinfop));
603}
604
605/* ************************************************************************ */
606/*			dev_ops functions				    */
607/* ************************************************************************ */
608
609/*
610 * ql_getinfo
611 *	Returns the pointer associated with arg when cmd is
612 *	set to DDI_INFO_DEVT2DEVINFO, or it should return the
613 *	instance number associated with arg when cmd is set
614 *	to DDI_INFO_DEV2INSTANCE.
615 *
616 * Input:
617 *	dip = Do not use.
618 *	cmd = command argument.
619 *	arg = command specific argument.
620 *	resultp = pointer to where request information is stored.
621 *
622 * Returns:
623 *	DDI_SUCCESS or DDI_FAILURE.
624 *
625 * Context:
626 *	Kernel context.
627 */
628/* ARGSUSED */
629static int
630ql_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
631{
632	ql_adapter_state_t	*ha;
633	int			minor;
634	int			rval = DDI_FAILURE;
635
636	minor = (int)(getminor((dev_t)arg));
637	ha = ddi_get_soft_state(ql_state, minor);
638	if (ha == NULL) {
639		QL_PRINT_2(CE_CONT, "failed, unknown minor=%d\n",
640		    getminor((dev_t)arg));
641		*resultp = NULL;
642		return (rval);
643	}
644
645	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
646
647	switch (cmd) {
648	case DDI_INFO_DEVT2DEVINFO:
649		*resultp = ha->dip;
650		rval = DDI_SUCCESS;
651		break;
652	case DDI_INFO_DEVT2INSTANCE:
653		*resultp = (void *)(uintptr_t)(ha->instance);
654		rval = DDI_SUCCESS;
655		break;
656	default:
657		EL(ha, "failed, unsupported cmd=%d\n", cmd);
658		rval = DDI_FAILURE;
659		break;
660	}
661
662	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
663
664	return (rval);
665}
666
667/*
668 * ql_attach
669 *	Configure and attach an instance of the driver
670 *	for a port.
671 *
672 * Input:
673 *	dip = pointer to device information structure.
674 *	cmd = attach type.
675 *
676 * Returns:
677 *	DDI_SUCCESS or DDI_FAILURE.
678 *
679 * Context:
680 *	Kernel context.
681 */
682static int
683ql_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
684{
685	uint32_t		size;
686	int			rval;
687	int			instance;
688	uint_t			progress = 0;
689	char			*buf;
690	ushort_t		caps_ptr, cap;
691	fc_fca_tran_t		*tran;
692	ql_adapter_state_t	*ha = NULL;
693
694	static char *pmcomps[] = {
695		NULL,
696		PM_LEVEL_D3_STR,		/* Device OFF */
697		PM_LEVEL_D0_STR,		/* Device ON */
698	};
699
700	QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n",
701	    ddi_get_instance(dip), cmd);
702
703	buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
704
705	switch (cmd) {
706	case DDI_ATTACH:
707		/* first get the instance */
708		instance = ddi_get_instance(dip);
709
710		cmn_err(CE_CONT, "!Qlogic %s(%d) FCA Driver v%s\n",
711		    QL_NAME, instance, QL_VERSION);
712
713		/* Correct OS version? */
714		if (ql_os_release_level != 11) {
715			cmn_err(CE_WARN, "%s(%d): This driver is for Solaris "
716			    "11", QL_NAME, instance);
717			goto attach_failed;
718		}
719
720		/* Hardware is installed in a DMA-capable slot? */
721		if (ddi_slaveonly(dip) == DDI_SUCCESS) {
722			cmn_err(CE_WARN, "%s(%d): slave only", QL_NAME,
723			    instance);
724			goto attach_failed;
725		}
726
727		/* No support for high-level interrupts */
728		if (ddi_intr_hilevel(dip, 0) != 0) {
729			cmn_err(CE_WARN, "%s(%d): High level interrupt"
730			    " not supported", QL_NAME, instance);
731			goto attach_failed;
732		}
733
734		/* Allocate our per-device-instance structure */
735		if (ddi_soft_state_zalloc(ql_state,
736		    instance) != DDI_SUCCESS) {
737			cmn_err(CE_WARN, "%s(%d): soft state alloc failed",
738			    QL_NAME, instance);
739			goto attach_failed;
740		}
741		progress |= QL_SOFT_STATE_ALLOCED;
742
743		ha = ddi_get_soft_state(ql_state, instance);
744		if (ha == NULL) {
745			cmn_err(CE_WARN, "%s(%d): can't get soft state",
746			    QL_NAME, instance);
747			goto attach_failed;
748		}
749		ha->dip = dip;
750		ha->instance = instance;
751		ha->hba.base_address = ha;
752		ha->pha = ha;
753
754		if (ql_el_trace_desc_ctor(ha) != DDI_SUCCESS) {
755			cmn_err(CE_WARN, "%s(%d): can't setup el tracing",
756			    QL_NAME, instance);
757			goto attach_failed;
758		}
759
760		/* Get extended logging and dump flags. */
761		ql_common_properties(ha);
762
763		if (strcmp(ddi_driver_name(ddi_get_parent(dip)),
764		    "sbus") == 0) {
765			EL(ha, "%s SBUS card detected", QL_NAME);
766			ha->cfg_flags |= CFG_SBUS_CARD;
767		}
768
769		ha->dev = kmem_zalloc(sizeof (*ha->dev) *
770		    DEVICE_HEAD_LIST_SIZE, KM_SLEEP);
771
772		ha->outstanding_cmds = kmem_zalloc(
773		    sizeof (*ha->outstanding_cmds) * MAX_OUTSTANDING_COMMANDS,
774		    KM_SLEEP);
775
776		ha->ub_array = kmem_zalloc(sizeof (*ha->ub_array) *
777		    QL_UB_LIMIT, KM_SLEEP);
778
779		ha->adapter_stats = kmem_zalloc(sizeof (*ha->adapter_stats),
780		    KM_SLEEP);
781
782		(void) ddi_pathname(dip, buf);
783		ha->devpath = kmem_zalloc(strlen(buf)+1, KM_SLEEP);
784		if (ha->devpath == NULL) {
785			EL(ha, "devpath mem alloc failed\n");
786		} else {
787			(void) strcpy(ha->devpath, buf);
788			EL(ha, "devpath is: %s\n", ha->devpath);
789		}
790
791		if (CFG_IST(ha, CFG_SBUS_CARD)) {
792			/*
793			 * For cards where PCI is mapped to sbus e.g. Ivory.
794			 *
795			 * 0x00	: 0x000 - 0x0FF PCI Config Space for 2200
796			 *	: 0x100 - 0x3FF PCI IO space for 2200
797			 * 0x01	: 0x000 - 0x0FF PCI Config Space for fpga
798			 *	: 0x100 - 0x3FF PCI IO Space for fpga
799			 */
800			if (ddi_regs_map_setup(dip, 0, (caddr_t *)&ha->iobase,
801			    0x100, 0x300, &ql_dev_acc_attr, &ha->dev_handle)
802			    != DDI_SUCCESS) {
803				cmn_err(CE_WARN, "%s(%d): Unable to map device"
804				    " registers", QL_NAME, instance);
805				goto attach_failed;
806			}
807			if (ddi_regs_map_setup(dip, 1,
808			    (caddr_t *)&ha->sbus_fpga_iobase, 0, 0x400,
809			    &ql_dev_acc_attr, &ha->sbus_fpga_dev_handle)
810			    != DDI_SUCCESS) {
811				/* We should not fail attach here */
812				cmn_err(CE_WARN, "%s(%d): Unable to map FPGA",
813				    QL_NAME, instance);
814				ha->sbus_fpga_iobase = NULL;
815			}
816			progress |= QL_REGS_MAPPED;
817		} else {
818			/*
819			 * Setup the ISP2200 registers address mapping to be
820			 * accessed by this particular driver.
821			 * 0x0   Configuration Space
822			 * 0x1   I/O Space
823			 * 0x2   32-bit Memory Space address
824			 * 0x3   64-bit Memory Space address
825			 */
826			if (ddi_regs_map_setup(dip, 2, (caddr_t *)&ha->iobase,
827			    0, 0x100, &ql_dev_acc_attr,
828			    &ha->dev_handle) != DDI_SUCCESS) {
829				cmn_err(CE_WARN, "%s(%d): regs_map_setup "
830				    "failed", QL_NAME, instance);
831				goto attach_failed;
832			}
833			progress |= QL_REGS_MAPPED;
834
835			/*
836			 * We need I/O space mappings for 23xx HBAs for
837			 * loading flash (FCode). The chip has a bug due to
838			 * which loading flash fails through mem space
839			 * mappings in PCI-X mode.
840			 */
841			if (ddi_regs_map_setup(dip, 1,
842			    (caddr_t *)&ha->iomap_iobase, 0, 0x100,
843			    &ql_dev_acc_attr,
844			    &ha->iomap_dev_handle) != DDI_SUCCESS) {
845				cmn_err(CE_WARN, "%s(%d): regs_map_setup(I/O)"
846				    " failed", QL_NAME, instance);
847				goto attach_failed;
848			}
849			progress |= QL_IOMAP_IOBASE_MAPPED;
850		}
851
852		/*
853		 * We should map config space before adding interrupt
854		 * So that the chip type (2200 or 2300) can be determined
855		 * before the interrupt routine gets a chance to execute.
856		 */
857		if (CFG_IST(ha, CFG_SBUS_CARD)) {
858			if (ddi_regs_map_setup(dip, 0,
859			    (caddr_t *)&ha->sbus_config_base, 0, 0x100,
860			    &ql_dev_acc_attr, &ha->sbus_config_handle) !=
861			    DDI_SUCCESS) {
862				cmn_err(CE_WARN, "%s(%d): Unable to map sbus "
863				    "config registers", QL_NAME, instance);
864				goto attach_failed;
865			}
866		} else {
867			if (pci_config_setup(ha->dip, &ha->pci_handle) !=
868			    DDI_SUCCESS) {
869				cmn_err(CE_WARN, "%s(%d): can't setup PCI "
870				    "config space", QL_NAME, instance);
871				goto attach_failed;
872			}
873		}
874		progress |= QL_CONFIG_SPACE_SETUP;
875
876		ha->subsys_id = (uint16_t)ql_pci_config_get16(ha,
877		    PCI_CONF_SUBSYSID);
878		ha->subven_id = (uint16_t)ql_pci_config_get16(ha,
879		    PCI_CONF_SUBVENID);
880		ha->ven_id = (uint16_t)ql_pci_config_get16(ha,
881		    PCI_CONF_VENID);
882		ha->device_id = (uint16_t)ql_pci_config_get16(ha,
883		    PCI_CONF_DEVID);
884		ha->rev_id = (uint8_t)ql_pci_config_get8(ha,
885		    PCI_CONF_REVID);
886
887		EL(ha, "ISP%x chip detected (RevID=%x, VenID=%x, SVenID=%x, "
888		    "SSysID=%x)\n", ha->device_id, ha->rev_id, ha->ven_id,
889		    ha->subven_id, ha->subsys_id);
890
891		switch (ha->device_id) {
892		case 0x2300:
893		case 0x2312:
894#if !defined(__sparc) || defined(QL_DEBUG_ROUTINES)
895		/*
896		 * per marketing, fibre-lite HBA's are not supported
897		 * on sparc platforms
898		 */
899		case 0x6312:
900		case 0x6322:
901#endif	/* !defined(__sparc) || defined(QL_DEBUG_ROUTINES) */
902			if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) {
903				ha->flags |= FUNCTION_1;
904			}
905			if (ha->device_id == 0x6322) {
906				ha->cfg_flags |= CFG_CTRL_6322;
907				ha->fw_class = 0x6322;
908				ha->risc_dump_size = QL_6322_FW_DUMP_SIZE;
909			} else {
910				ha->cfg_flags |= CFG_CTRL_2300;
911				ha->fw_class = 0x2300;
912				ha->risc_dump_size = QL_2300_FW_DUMP_SIZE;
913			}
914			ha->reg_off = &reg_off_2300;
915			if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
916				goto attach_failed;
917			}
918			ha->fcp_cmd = ql_command_iocb;
919			ha->ip_cmd = ql_ip_iocb;
920			ha->ms_cmd = ql_ms_iocb;
921			if (CFG_IST(ha, CFG_SBUS_CARD)) {
922				ha->cmd_segs = CMD_TYPE_2_DATA_SEGMENTS;
923				ha->cmd_cont_segs = CONT_TYPE_0_DATA_SEGMENTS;
924			} else {
925				ha->cmd_segs = CMD_TYPE_3_DATA_SEGMENTS;
926				ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
927			}
928			break;
929
930		case 0x2200:
931			ha->cfg_flags |= CFG_CTRL_2200;
932			ha->reg_off = &reg_off_2200;
933			ha->fw_class = 0x2200;
934			if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
935				goto attach_failed;
936			}
937			ha->risc_dump_size = QL_2200_FW_DUMP_SIZE;
938			ha->fcp_cmd = ql_command_iocb;
939			ha->ip_cmd = ql_ip_iocb;
940			ha->ms_cmd = ql_ms_iocb;
941			if (CFG_IST(ha, CFG_SBUS_CARD)) {
942				ha->cmd_segs = CMD_TYPE_2_DATA_SEGMENTS;
943				ha->cmd_cont_segs = CONT_TYPE_0_DATA_SEGMENTS;
944			} else {
945				ha->cmd_segs = CMD_TYPE_3_DATA_SEGMENTS;
946				ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
947			}
948			break;
949
950		case 0x2422:
951		case 0x2432:
952		case 0x5422:
953		case 0x5432:
954		case 0x8432:
955#ifdef __sparc
956			/*
957			 * Per marketing, the QLA/QLE-2440's (which
958			 * also use the 2422 & 2432) are only for the
959			 * x86 platform (SMB market).
960			 */
961			if (ha->subsys_id == 0x145 || ha->subsys_id == 0x147 ||
962			    ha->subsys_id == 0x13e) {
963				cmn_err(CE_WARN,
964				    "%s(%d): Unsupported HBA ssid: %x",
965				    QL_NAME, instance, ha->subsys_id);
966				goto attach_failed;
967			}
968#endif	/* __sparc */
969			if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) {
970				ha->flags |= FUNCTION_1;
971			}
972			ha->cfg_flags |= CFG_CTRL_2422;
973			if (ha->device_id == 0x8432) {
974				ha->cfg_flags |= CFG_CTRL_MENLO;
975			} else {
976				ha->flags |= VP_ENABLED;
977			}
978
979			ha->reg_off = &reg_off_2400_2500;
980			ha->fw_class = 0x2400;
981			if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
982				goto attach_failed;
983			}
984			ha->risc_dump_size = QL_24XX_FW_DUMP_SIZE;
985			ha->fcp_cmd = ql_command_24xx_iocb;
986			ha->ip_cmd = ql_ip_24xx_iocb;
987			ha->ms_cmd = ql_ms_24xx_iocb;
988			ha->els_cmd = ql_els_24xx_iocb;
989			ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
990			ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
991			break;
992
993		case 0x2522:
994		case 0x2532:
995			if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 2) {
996				ha->flags |= FUNCTION_1;
997			}
998			ha->cfg_flags |= CFG_CTRL_25XX;
999			ha->flags |= VP_ENABLED;
1000			ha->fw_class = 0x2500;
1001			ha->reg_off = &reg_off_2400_2500;
1002			if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
1003				goto attach_failed;
1004			}
1005			ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE;
1006			ha->fcp_cmd = ql_command_24xx_iocb;
1007			ha->ip_cmd = ql_ip_24xx_iocb;
1008			ha->ms_cmd = ql_ms_24xx_iocb;
1009			ha->els_cmd = ql_els_24xx_iocb;
1010			ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
1011			ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
1012			break;
1013
1014		case 0x8001:
1015			if (ql_pci_config_get8(ha, PCI_CONF_IPIN) == 4) {
1016				ha->flags |= FUNCTION_1;
1017			}
1018			ha->cfg_flags |= CFG_CTRL_81XX;
1019			ha->flags |= VP_ENABLED;
1020			ha->fw_class = 0x8100;
1021			ha->reg_off = &reg_off_2400_2500;
1022			if (ql_fwmodule_resolve(ha) != QL_SUCCESS) {
1023				goto attach_failed;
1024			}
1025			ha->risc_dump_size = QL_25XX_FW_DUMP_SIZE;
1026			ha->fcp_cmd = ql_command_24xx_iocb;
1027			ha->ip_cmd = ql_ip_24xx_iocb;
1028			ha->ms_cmd = ql_ms_24xx_iocb;
1029			ha->cmd_segs = CMD_TYPE_7_DATA_SEGMENTS;
1030			ha->cmd_cont_segs = CONT_TYPE_1_DATA_SEGMENTS;
1031			break;
1032
1033		default:
1034			cmn_err(CE_WARN, "%s(%d): Unsupported device id: %x",
1035			    QL_NAME, instance, ha->device_id);
1036			goto attach_failed;
1037		}
1038
1039		/* Setup hba buffer. */
1040
1041		size = CFG_IST(ha, CFG_CTRL_242581) ?
1042		    (REQUEST_QUEUE_SIZE + RESPONSE_QUEUE_SIZE) :
1043		    (REQUEST_QUEUE_SIZE + RESPONSE_QUEUE_SIZE +
1044		    RCVBUF_QUEUE_SIZE);
1045
1046		if (ql_get_dma_mem(ha, &ha->hba_buf, size, LITTLE_ENDIAN_DMA,
1047		    QL_DMA_RING_ALIGN) != QL_SUCCESS) {
1048			cmn_err(CE_WARN, "%s(%d): request queue DMA memory "
1049			    "alloc failed", QL_NAME, instance);
1050			goto attach_failed;
1051		}
1052		progress |= QL_HBA_BUFFER_SETUP;
1053
1054		/* Setup buffer pointers. */
1055		ha->request_dvma = ha->hba_buf.cookie.dmac_laddress +
1056		    REQUEST_Q_BUFFER_OFFSET;
1057		ha->request_ring_bp = (struct cmd_entry *)
1058		    ((caddr_t)ha->hba_buf.bp + REQUEST_Q_BUFFER_OFFSET);
1059
1060		ha->response_dvma = ha->hba_buf.cookie.dmac_laddress +
1061		    RESPONSE_Q_BUFFER_OFFSET;
1062		ha->response_ring_bp = (struct sts_entry *)
1063		    ((caddr_t)ha->hba_buf.bp + RESPONSE_Q_BUFFER_OFFSET);
1064
1065		ha->rcvbuf_dvma = ha->hba_buf.cookie.dmac_laddress +
1066		    RCVBUF_Q_BUFFER_OFFSET;
1067		ha->rcvbuf_ring_bp = (struct rcvbuf *)
1068		    ((caddr_t)ha->hba_buf.bp + RCVBUF_Q_BUFFER_OFFSET);
1069
1070		/* Allocate resource for QLogic IOCTL */
1071		(void) ql_alloc_xioctl_resource(ha);
1072
1073		/* Setup interrupts */
1074		if ((rval = ql_setup_interrupts(ha)) != DDI_SUCCESS) {
1075			cmn_err(CE_WARN, "%s(%d): Failed to add interrupt, "
1076			    "rval=%xh", QL_NAME, instance, rval);
1077			goto attach_failed;
1078		}
1079
1080		progress |= (QL_INTR_ADDED | QL_MUTEX_CV_INITED);
1081
1082		/*
1083		 * Allocate an N Port information structure
1084		 * for use when in P2P topology.
1085		 */
1086		ha->n_port = (ql_n_port_info_t *)
1087		    kmem_zalloc(sizeof (ql_n_port_info_t), KM_SLEEP);
1088		if (ha->n_port == NULL) {
1089			cmn_err(CE_WARN, "%s(%d): Failed to create N Port info",
1090			    QL_NAME, instance);
1091			goto attach_failed;
1092		}
1093
1094		progress |= QL_N_PORT_INFO_CREATED;
1095
1096		/*
1097		 * Determine support for Power Management
1098		 */
1099		caps_ptr = (uint8_t)ql_pci_config_get8(ha, PCI_CONF_CAP_PTR);
1100
1101		while (caps_ptr != PCI_CAP_NEXT_PTR_NULL) {
1102			cap = (uint8_t)ql_pci_config_get8(ha, caps_ptr);
1103			if (cap == PCI_CAP_ID_PM) {
1104				ha->pm_capable = 1;
1105				break;
1106			}
1107			caps_ptr = (uint8_t)ql_pci_config_get8(ha, caps_ptr +
1108			    PCI_CAP_NEXT_PTR);
1109		}
1110
1111		if (ha->pm_capable) {
1112			/*
1113			 * Enable PM for 2200 based HBAs only.
1114			 */
1115			if (ha->device_id != 0x2200) {
1116				ha->pm_capable = 0;
1117			}
1118		}
1119
1120		if (ha->pm_capable) {
1121			ha->pm_capable = ql_enable_pm;
1122		}
1123
1124		if (ha->pm_capable) {
1125			/*
1126			 * Initialize power management bookkeeping;
1127			 * components are created idle.
1128			 */
1129			(void) sprintf(buf, "NAME=%s(%d)", QL_NAME, instance);
1130			pmcomps[0] = buf;
1131
1132			/*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/
1133			if (ddi_prop_update_string_array(DDI_DEV_T_NONE,
1134			    dip, "pm-components", pmcomps,
1135			    sizeof (pmcomps) / sizeof (pmcomps[0])) !=
1136			    DDI_PROP_SUCCESS) {
1137				cmn_err(CE_WARN, "%s(%d): failed to create"
1138				    " pm-components property", QL_NAME,
1139				    instance);
1140
1141				/* Initialize adapter. */
1142				ha->power_level = PM_LEVEL_D0;
1143				if (ql_initialize_adapter(ha) != QL_SUCCESS) {
1144					cmn_err(CE_WARN, "%s(%d): failed to"
1145					    " initialize adapter", QL_NAME,
1146					    instance);
1147					goto attach_failed;
1148				}
1149			} else {
1150				ha->power_level = PM_LEVEL_D3;
1151				if (pm_raise_power(dip, QL_POWER_COMPONENT,
1152				    PM_LEVEL_D0) != DDI_SUCCESS) {
1153					cmn_err(CE_WARN, "%s(%d): failed to"
1154					    " raise power or initialize"
1155					    " adapter", QL_NAME, instance);
1156				}
1157			}
1158		} else {
1159			/* Initialize adapter. */
1160			ha->power_level = PM_LEVEL_D0;
1161			if (ql_initialize_adapter(ha) != QL_SUCCESS) {
1162				cmn_err(CE_WARN, "%s(%d): failed to initialize"
1163				    " adapter", QL_NAME, instance);
1164			}
1165		}
1166
1167		if (ha->fw_major_version == 0 && ha->fw_minor_version == 0 &&
1168		    ha->fw_subminor_version == 0) {
1169			cmn_err(CE_NOTE, "!%s(%d): Firmware not loaded",
1170			    QL_NAME, ha->instance);
1171		} else {
1172			int	rval;
1173			char	ver_fmt[256];
1174
1175			rval = (int)snprintf(ver_fmt, (size_t)sizeof (ver_fmt),
1176			    "Firmware version %d.%d.%d", ha->fw_major_version,
1177			    ha->fw_minor_version, ha->fw_subminor_version);
1178
1179			if (CFG_IST(ha, CFG_CTRL_81XX)) {
1180				rval = (int)snprintf(ver_fmt + rval,
1181				    (size_t)sizeof (ver_fmt),
1182				    ", MPI fw version %d.%d.%d",
1183				    ha->mpi_fw_major_version,
1184				    ha->mpi_fw_minor_version,
1185				    ha->mpi_fw_subminor_version);
1186
1187				if (ha->subsys_id == 0x17B ||
1188				    ha->subsys_id == 0x17D) {
1189					(void) snprintf(ver_fmt + rval,
1190					    (size_t)sizeof (ver_fmt),
1191					    ", PHY fw version %d.%d.%d",
1192					    ha->phy_fw_major_version,
1193					    ha->phy_fw_minor_version,
1194					    ha->phy_fw_subminor_version);
1195				}
1196			}
1197			cmn_err(CE_NOTE, "!%s(%d): %s",
1198			    QL_NAME, ha->instance, ver_fmt);
1199		}
1200
1201		ha->k_stats = kstat_create(QL_NAME, instance, "statistics",
1202		    "controller", KSTAT_TYPE_RAW,
1203		    (uint32_t)sizeof (ql_adapter_stat_t), KSTAT_FLAG_VIRTUAL);
1204		if (ha->k_stats == NULL) {
1205			cmn_err(CE_WARN, "%s(%d): Failed to create kstat",
1206			    QL_NAME, instance);
1207			goto attach_failed;
1208		}
1209		progress |= QL_KSTAT_CREATED;
1210
1211		ha->adapter_stats->version = 1;
1212		ha->k_stats->ks_data = (void *)ha->adapter_stats;
1213		ha->k_stats->ks_private = ha;
1214		ha->k_stats->ks_update = ql_kstat_update;
1215		ha->k_stats->ks_ndata = 1;
1216		ha->k_stats->ks_data_size = sizeof (ql_adapter_stat_t);
1217		kstat_install(ha->k_stats);
1218
1219		if (ddi_create_minor_node(dip, "devctl", S_IFCHR,
1220		    instance, DDI_NT_NEXUS, 0) != DDI_SUCCESS) {
1221			cmn_err(CE_WARN, "%s(%d): failed to create minor node",
1222			    QL_NAME, instance);
1223			goto attach_failed;
1224		}
1225		progress |= QL_MINOR_NODE_CREATED;
1226
1227		/* Allocate a transport structure for this instance */
1228		tran = kmem_zalloc(sizeof (fc_fca_tran_t), KM_SLEEP);
1229		if (tran == NULL) {
1230			cmn_err(CE_WARN, "%s(%d): failed to allocate transport",
1231			    QL_NAME, instance);
1232			goto attach_failed;
1233		}
1234
1235		progress |= QL_FCA_TRAN_ALLOCED;
1236
1237		/* fill in the structure */
1238		tran->fca_numports = 1;
1239		tran->fca_version = FCTL_FCA_MODREV_5;
1240		if (CFG_IST(ha, CFG_CTRL_2422)) {
1241			tran->fca_num_npivports = MAX_24_VIRTUAL_PORTS;
1242		} else if (CFG_IST(ha, CFG_CTRL_2581)) {
1243			tran->fca_num_npivports = MAX_25_VIRTUAL_PORTS;
1244		}
1245		bcopy(ha->loginparams.node_ww_name.raw_wwn,
1246		    tran->fca_perm_pwwn.raw_wwn, 8);
1247
1248		EL(ha, "FCA version %d\n", tran->fca_version);
1249
1250		/* Specify the amount of space needed in each packet */
1251		tran->fca_pkt_size = sizeof (ql_srb_t);
1252
1253		/* command limits are usually dictated by hardware */
1254		tran->fca_cmd_max = MAX_OUTSTANDING_COMMANDS;
1255
1256		/* dmaattr are static, set elsewhere. */
1257		if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
1258			tran->fca_dma_attr = &ql_64bit_io_dma_attr;
1259			tran->fca_dma_fcp_cmd_attr = &ql_64fcp_cmd_dma_attr;
1260			tran->fca_dma_fcp_rsp_attr = &ql_64fcp_rsp_dma_attr;
1261			tran->fca_dma_fcp_data_attr = &ql_64fcp_data_dma_attr;
1262			tran->fca_dma_fcsm_cmd_attr = &ql_64fcsm_cmd_dma_attr;
1263			tran->fca_dma_fcsm_rsp_attr = &ql_64fcsm_rsp_dma_attr;
1264			tran->fca_dma_fcip_cmd_attr = &ql_64fcip_cmd_dma_attr;
1265			tran->fca_dma_fcip_rsp_attr = &ql_64fcip_rsp_dma_attr;
1266		} else {
1267			tran->fca_dma_attr = &ql_32bit_io_dma_attr;
1268			tran->fca_dma_fcp_cmd_attr = &ql_32fcp_cmd_dma_attr;
1269			tran->fca_dma_fcp_rsp_attr = &ql_32fcp_rsp_dma_attr;
1270			tran->fca_dma_fcp_data_attr = &ql_32fcp_data_dma_attr;
1271			tran->fca_dma_fcsm_cmd_attr = &ql_32fcsm_cmd_dma_attr;
1272			tran->fca_dma_fcsm_rsp_attr = &ql_32fcsm_rsp_dma_attr;
1273			tran->fca_dma_fcip_cmd_attr = &ql_32fcip_cmd_dma_attr;
1274			tran->fca_dma_fcip_rsp_attr = &ql_32fcip_rsp_dma_attr;
1275		}
1276
1277		tran->fca_acc_attr = &ql_dev_acc_attr;
1278		tran->fca_iblock = &(ha->iblock_cookie);
1279
1280		/* the remaining values are simply function vectors */
1281		tran->fca_bind_port = ql_bind_port;
1282		tran->fca_unbind_port = ql_unbind_port;
1283		tran->fca_init_pkt = ql_init_pkt;
1284		tran->fca_un_init_pkt = ql_un_init_pkt;
1285		tran->fca_els_send = ql_els_send;
1286		tran->fca_get_cap = ql_get_cap;
1287		tran->fca_set_cap = ql_set_cap;
1288		tran->fca_getmap = ql_getmap;
1289		tran->fca_transport = ql_transport;
1290		tran->fca_ub_alloc = ql_ub_alloc;
1291		tran->fca_ub_free = ql_ub_free;
1292		tran->fca_ub_release = ql_ub_release;
1293		tran->fca_abort = ql_abort;
1294		tran->fca_reset = ql_reset;
1295		tran->fca_port_manage = ql_port_manage;
1296		tran->fca_get_device = ql_get_device;
1297
1298		/* give it to the FC transport */
1299		if (fc_fca_attach(dip, tran) != DDI_SUCCESS) {
1300			cmn_err(CE_WARN, "%s(%d): FCA attach failed", QL_NAME,
1301			    instance);
1302			goto attach_failed;
1303		}
1304		progress |= QL_FCA_ATTACH_DONE;
1305
1306		/* Stash the structure so it can be freed at detach */
1307		ha->tran = tran;
1308
1309		/* Acquire global state lock. */
1310		GLOBAL_STATE_LOCK();
1311
1312		/* Add adapter structure to link list. */
1313		ql_add_link_b(&ql_hba, &ha->hba);
1314
1315		/* Start one second driver timer. */
1316		if (ql_timer_timeout_id == NULL) {
1317			ql_timer_ticks = drv_usectohz(1000000);
1318			ql_timer_timeout_id = timeout(ql_timer, (void *)0,
1319			    ql_timer_ticks);
1320		}
1321
1322		/* Release global state lock. */
1323		GLOBAL_STATE_UNLOCK();
1324
1325		/* Determine and populate HBA fru info */
1326		ql_setup_fruinfo(ha);
1327
1328		/* Setup task_daemon thread. */
1329		(void) thread_create(NULL, 0, (void (*)())ql_task_daemon, ha,
1330		    0, &p0, TS_RUN, minclsyspri);
1331
1332		progress |= QL_TASK_DAEMON_STARTED;
1333
1334		ddi_report_dev(dip);
1335
1336		/* Disable link reset in panic path */
1337		ha->lip_on_panic = 1;
1338
1339		rval = DDI_SUCCESS;
1340		break;
1341
1342attach_failed:
1343		if (progress & QL_FCA_ATTACH_DONE) {
1344			(void) fc_fca_detach(dip);
1345			progress &= ~QL_FCA_ATTACH_DONE;
1346		}
1347
1348		if (progress & QL_FCA_TRAN_ALLOCED) {
1349			kmem_free(tran, sizeof (fc_fca_tran_t));
1350			progress &= ~QL_FCA_TRAN_ALLOCED;
1351		}
1352
1353		if (progress & QL_MINOR_NODE_CREATED) {
1354			ddi_remove_minor_node(dip, "devctl");
1355			progress &= ~QL_MINOR_NODE_CREATED;
1356		}
1357
1358		if (progress & QL_KSTAT_CREATED) {
1359			kstat_delete(ha->k_stats);
1360			progress &= ~QL_KSTAT_CREATED;
1361		}
1362
1363		if (progress & QL_N_PORT_INFO_CREATED) {
1364			kmem_free(ha->n_port, sizeof (ql_n_port_info_t));
1365			progress &= ~QL_N_PORT_INFO_CREATED;
1366		}
1367
1368		if (progress & QL_TASK_DAEMON_STARTED) {
1369			TASK_DAEMON_LOCK(ha);
1370
1371			ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG;
1372
1373			cv_signal(&ha->cv_task_daemon);
1374
1375			/* Release task daemon lock. */
1376			TASK_DAEMON_UNLOCK(ha);
1377
1378			/* Wait for for task daemon to stop running. */
1379			while (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
1380				ql_delay(ha, 10000);
1381			}
1382			progress &= ~QL_TASK_DAEMON_STARTED;
1383		}
1384
1385		if (progress & QL_IOMAP_IOBASE_MAPPED) {
1386			ddi_regs_map_free(&ha->iomap_dev_handle);
1387			progress &= ~QL_IOMAP_IOBASE_MAPPED;
1388		}
1389
1390		if (progress & QL_CONFIG_SPACE_SETUP) {
1391			if (CFG_IST(ha, CFG_SBUS_CARD)) {
1392				ddi_regs_map_free(&ha->sbus_config_handle);
1393			} else {
1394				pci_config_teardown(&ha->pci_handle);
1395			}
1396			progress &= ~QL_CONFIG_SPACE_SETUP;
1397		}
1398
1399		if (progress & QL_INTR_ADDED) {
1400			ql_disable_intr(ha);
1401			ql_release_intr(ha);
1402			progress &= ~QL_INTR_ADDED;
1403		}
1404
1405		if (progress & QL_MUTEX_CV_INITED) {
1406			ql_destroy_mutex(ha);
1407			progress &= ~QL_MUTEX_CV_INITED;
1408		}
1409
1410		if (progress & QL_HBA_BUFFER_SETUP) {
1411			ql_free_phys(ha, &ha->hba_buf);
1412			progress &= ~QL_HBA_BUFFER_SETUP;
1413		}
1414
1415		if (progress & QL_REGS_MAPPED) {
1416			ddi_regs_map_free(&ha->dev_handle);
1417			if (ha->sbus_fpga_iobase != NULL) {
1418				ddi_regs_map_free(&ha->sbus_fpga_dev_handle);
1419			}
1420			progress &= ~QL_REGS_MAPPED;
1421		}
1422
1423		if (progress & QL_SOFT_STATE_ALLOCED) {
1424
1425			ql_fcache_rel(ha->fcache);
1426
1427			kmem_free(ha->adapter_stats,
1428			    sizeof (*ha->adapter_stats));
1429
1430			kmem_free(ha->ub_array, sizeof (*ha->ub_array) *
1431			    QL_UB_LIMIT);
1432
1433			kmem_free(ha->outstanding_cmds,
1434			    sizeof (*ha->outstanding_cmds) *
1435			    MAX_OUTSTANDING_COMMANDS);
1436
1437			if (ha->devpath != NULL) {
1438				kmem_free(ha->devpath,
1439				    strlen(ha->devpath) + 1);
1440			}
1441
1442			kmem_free(ha->dev, sizeof (*ha->dev) *
1443			    DEVICE_HEAD_LIST_SIZE);
1444
1445			if (ha->xioctl != NULL) {
1446				ql_free_xioctl_resource(ha);
1447			}
1448
1449			if (ha->fw_module != NULL) {
1450				(void) ddi_modclose(ha->fw_module);
1451			}
1452
1453			ddi_soft_state_free(ql_state, instance);
1454			progress &= ~QL_SOFT_STATE_ALLOCED;
1455		}
1456
1457		ddi_prop_remove_all(dip);
1458		rval = DDI_FAILURE;
1459		break;
1460
1461	case DDI_RESUME:
1462		rval = DDI_FAILURE;
1463
1464		ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
1465		if (ha == NULL) {
1466			cmn_err(CE_WARN, "%s(%d): can't get soft state",
1467			    QL_NAME, instance);
1468			break;
1469		}
1470
1471		ha->power_level = PM_LEVEL_D3;
1472		if (ha->pm_capable) {
1473			/*
1474			 * Get ql_power to do power on initialization
1475			 */
1476			if (pm_raise_power(dip, QL_POWER_COMPONENT,
1477			    PM_LEVEL_D0) != DDI_SUCCESS) {
1478				cmn_err(CE_WARN, "%s(%d): can't raise adapter"
1479				    " power", QL_NAME, instance);
1480			}
1481		}
1482
1483		/*
1484		 * There is a bug in DR that prevents PM framework
1485		 * from calling ql_power.
1486		 */
1487		if (ha->power_level == PM_LEVEL_D3) {
1488			ha->power_level = PM_LEVEL_D0;
1489
1490			if (ql_initialize_adapter(ha) != QL_SUCCESS) {
1491				cmn_err(CE_WARN, "%s(%d): can't initialize the"
1492				    " adapter", QL_NAME, instance);
1493			}
1494
1495			/* Wake up task_daemon. */
1496			ql_awaken_task_daemon(ha, NULL, TASK_DAEMON_ALIVE_FLG,
1497			    0);
1498		}
1499
1500		/* Acquire global state lock. */
1501		GLOBAL_STATE_LOCK();
1502
1503		/* Restart driver timer. */
1504		if (ql_timer_timeout_id == NULL) {
1505			ql_timer_timeout_id = timeout(ql_timer, (void *)0,
1506			    ql_timer_ticks);
1507		}
1508
1509		/* Release global state lock. */
1510		GLOBAL_STATE_UNLOCK();
1511
1512		/* Wake up command start routine. */
1513		ADAPTER_STATE_LOCK(ha);
1514		ha->flags &= ~ADAPTER_SUSPENDED;
1515		ADAPTER_STATE_UNLOCK(ha);
1516
1517		/*
1518		 * Transport doesn't make FC discovery in polled
1519		 * mode; So we need the daemon thread's services
1520		 * right here.
1521		 */
1522		(void) callb_generic_cpr(&ha->cprinfo, CB_CODE_CPR_RESUME);
1523
1524		rval = DDI_SUCCESS;
1525
1526		/* Restart IP if it was running. */
1527		if (ha->flags & IP_ENABLED && !(ha->flags & IP_INITIALIZED)) {
1528			(void) ql_initialize_ip(ha);
1529			ql_isp_rcvbuf(ha);
1530		}
1531		break;
1532
1533	default:
1534		cmn_err(CE_WARN, "%s(%d): attach, unknown code:"
1535		    " %x", QL_NAME, ddi_get_instance(dip), cmd);
1536		rval = DDI_FAILURE;
1537		break;
1538	}
1539
1540	kmem_free(buf, MAXPATHLEN);
1541
1542	if (rval != DDI_SUCCESS) {
1543		/*EMPTY*/
1544		QL_PRINT_2(CE_CONT, "(%d): failed, rval = %xh\n",
1545		    ddi_get_instance(dip), rval);
1546	} else {
1547		/*EMPTY*/
1548		QL_PRINT_3(CE_CONT, "(%d): done\n", ddi_get_instance(dip));
1549	}
1550
1551	return (rval);
1552}
1553
1554/*
1555 * ql_detach
1556 *	Used to remove all the states associated with a given
1557 *	instances of a device node prior to the removal of that
1558 *	instance from the system.
1559 *
1560 * Input:
1561 *	dip = pointer to device information structure.
1562 *	cmd = type of detach.
1563 *
1564 * Returns:
1565 *	DDI_SUCCESS or DDI_FAILURE.
1566 *
1567 * Context:
1568 *	Kernel context.
1569 */
1570static int
1571ql_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1572{
1573	ql_adapter_state_t	*ha, *vha;
1574	ql_tgt_t		*tq;
1575	int			delay_cnt;
1576	uint16_t		index;
1577	ql_link_t		*link;
1578	char			*buf;
1579	timeout_id_t		timer_id = NULL;
1580	int			suspend, rval = DDI_SUCCESS;
1581
1582	ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
1583	if (ha == NULL) {
1584		QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
1585		    ddi_get_instance(dip));
1586		return (DDI_FAILURE);
1587	}
1588
1589	QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n", ha->instance, cmd);
1590
1591	buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
1592
1593	switch (cmd) {
1594	case DDI_DETACH:
1595		ADAPTER_STATE_LOCK(ha);
1596		ha->flags |= (ADAPTER_SUSPENDED | ABORT_CMDS_LOOP_DOWN_TMO);
1597		ADAPTER_STATE_UNLOCK(ha);
1598
1599		TASK_DAEMON_LOCK(ha);
1600
1601		if (ha->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) {
1602			ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG;
1603			cv_signal(&ha->cv_task_daemon);
1604
1605			TASK_DAEMON_UNLOCK(ha);
1606
1607			(void) ql_wait_for_td_stop(ha);
1608
1609			TASK_DAEMON_LOCK(ha);
1610			if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
1611				ha->task_daemon_flags &= ~TASK_DAEMON_STOP_FLG;
1612				EL(ha, "failed, could not stop task daemon\n");
1613			}
1614		}
1615		TASK_DAEMON_UNLOCK(ha);
1616
1617		GLOBAL_STATE_LOCK();
1618
1619		/* Disable driver timer if no adapters. */
1620		if (ql_timer_timeout_id && ql_hba.first == &ha->hba &&
1621		    ql_hba.last == &ha->hba) {
1622			timer_id = ql_timer_timeout_id;
1623			ql_timer_timeout_id = NULL;
1624		}
1625		ql_remove_link(&ql_hba, &ha->hba);
1626
1627		GLOBAL_STATE_UNLOCK();
1628
1629		if (timer_id) {
1630			(void) untimeout(timer_id);
1631		}
1632
1633		if (ha->pm_capable) {
1634			if (pm_lower_power(dip, QL_POWER_COMPONENT,
1635			    PM_LEVEL_D3) != DDI_SUCCESS) {
1636				cmn_err(CE_WARN, "%s(%d): failed to lower the"
1637				    " power", QL_NAME, ha->instance);
1638			}
1639		}
1640
1641		/*
1642		 * If pm_lower_power shutdown the adapter, there
1643		 * isn't much else to do
1644		 */
1645		if (ha->power_level != PM_LEVEL_D3) {
1646			ql_halt(ha, PM_LEVEL_D3);
1647		}
1648
1649		/* Remove virtual ports. */
1650		while ((vha = ha->vp_next) != NULL) {
1651			ql_vport_destroy(vha);
1652		}
1653
1654		/* Free target queues. */
1655		for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
1656			link = ha->dev[index].first;
1657			while (link != NULL) {
1658				tq = link->base_address;
1659				link = link->next;
1660				ql_dev_free(ha, tq);
1661			}
1662		}
1663
1664		/*
1665		 * Free unsolicited buffers.
1666		 * If we are here then there are no ULPs still
1667		 * alive that wish to talk to ql so free up
1668		 * any SRB_IP_UB_UNUSED buffers that are
1669		 * lingering around
1670		 */
1671		QL_UB_LOCK(ha);
1672		for (index = 0; index < QL_UB_LIMIT; index++) {
1673			fc_unsol_buf_t *ubp = ha->ub_array[index];
1674
1675			if (ubp != NULL) {
1676				ql_srb_t *sp = ubp->ub_fca_private;
1677
1678				sp->flags |= SRB_UB_FREE_REQUESTED;
1679
1680				while (!(sp->flags & SRB_UB_IN_FCA) ||
1681				    (sp->flags & (SRB_UB_CALLBACK |
1682				    SRB_UB_ACQUIRED))) {
1683					QL_UB_UNLOCK(ha);
1684					delay(drv_usectohz(100000));
1685					QL_UB_LOCK(ha);
1686				}
1687				ha->ub_array[index] = NULL;
1688
1689				QL_UB_UNLOCK(ha);
1690				ql_free_unsolicited_buffer(ha, ubp);
1691				QL_UB_LOCK(ha);
1692			}
1693		}
1694		QL_UB_UNLOCK(ha);
1695
1696		/* Free any saved RISC code. */
1697		if (ha->risc_code != NULL) {
1698			kmem_free(ha->risc_code, ha->risc_code_size);
1699			ha->risc_code = NULL;
1700			ha->risc_code_size = 0;
1701		}
1702
1703		if (ha->fw_module != NULL) {
1704			(void) ddi_modclose(ha->fw_module);
1705			ha->fw_module = NULL;
1706		}
1707
1708		/* Free resources. */
1709		ddi_prop_remove_all(dip);
1710		(void) fc_fca_detach(dip);
1711		kmem_free(ha->tran, sizeof (fc_fca_tran_t));
1712		ddi_remove_minor_node(dip, "devctl");
1713		if (ha->k_stats != NULL) {
1714			kstat_delete(ha->k_stats);
1715		}
1716
1717		if (CFG_IST(ha, CFG_SBUS_CARD)) {
1718			ddi_regs_map_free(&ha->sbus_config_handle);
1719		} else {
1720			ddi_regs_map_free(&ha->iomap_dev_handle);
1721			pci_config_teardown(&ha->pci_handle);
1722		}
1723
1724		ql_disable_intr(ha);
1725		ql_release_intr(ha);
1726
1727		ql_free_xioctl_resource(ha);
1728
1729		ql_destroy_mutex(ha);
1730
1731		ql_free_phys(ha, &ha->hba_buf);
1732		ql_free_phys(ha, &ha->fwexttracebuf);
1733		ql_free_phys(ha, &ha->fwfcetracebuf);
1734
1735		ddi_regs_map_free(&ha->dev_handle);
1736		if (ha->sbus_fpga_iobase != NULL) {
1737			ddi_regs_map_free(&ha->sbus_fpga_dev_handle);
1738		}
1739
1740		ql_fcache_rel(ha->fcache);
1741		if (ha->vcache != NULL) {
1742			kmem_free(ha->vcache, QL_24XX_VPD_SIZE);
1743		}
1744
1745		if (ha->pi_attrs != NULL) {
1746			kmem_free(ha->pi_attrs, sizeof (fca_port_attrs_t));
1747		}
1748
1749		kmem_free(ha->adapter_stats, sizeof (*ha->adapter_stats));
1750
1751		kmem_free(ha->ub_array, sizeof (*ha->ub_array) * QL_UB_LIMIT);
1752
1753		kmem_free(ha->outstanding_cmds,
1754		    sizeof (*ha->outstanding_cmds) * MAX_OUTSTANDING_COMMANDS);
1755
1756		if (ha->n_port != NULL) {
1757			kmem_free(ha->n_port, sizeof (ql_n_port_info_t));
1758		}
1759
1760		if (ha->devpath != NULL) {
1761			kmem_free(ha->devpath, strlen(ha->devpath) + 1);
1762		}
1763
1764		kmem_free(ha->dev, sizeof (*ha->dev) * DEVICE_HEAD_LIST_SIZE);
1765
1766		EL(ha, "detached\n");
1767
1768		ddi_soft_state_free(ql_state, (int)ha->instance);
1769
1770		break;
1771
1772	case DDI_SUSPEND:
1773		ADAPTER_STATE_LOCK(ha);
1774
1775		delay_cnt = 0;
1776		ha->flags |= ADAPTER_SUSPENDED;
1777		while (ha->flags & ADAPTER_TIMER_BUSY && delay_cnt++ < 10) {
1778			ADAPTER_STATE_UNLOCK(ha);
1779			delay(drv_usectohz(1000000));
1780			ADAPTER_STATE_LOCK(ha);
1781		}
1782		if (ha->busy || ha->flags & ADAPTER_TIMER_BUSY) {
1783			ha->flags &= ~ADAPTER_SUSPENDED;
1784			ADAPTER_STATE_UNLOCK(ha);
1785			rval = DDI_FAILURE;
1786			cmn_err(CE_WARN, "!%s(%d): Fail suspend"
1787			    " busy %xh flags %xh", QL_NAME, ha->instance,
1788			    ha->busy, ha->flags);
1789			break;
1790		}
1791
1792		ADAPTER_STATE_UNLOCK(ha);
1793
1794		if (ha->flags & IP_INITIALIZED) {
1795			(void) ql_shutdown_ip(ha);
1796		}
1797
1798		if ((suspend = ql_suspend_adapter(ha)) != QL_SUCCESS) {
1799			ADAPTER_STATE_LOCK(ha);
1800			ha->flags &= ~ADAPTER_SUSPENDED;
1801			ADAPTER_STATE_UNLOCK(ha);
1802			cmn_err(CE_WARN, "%s(%d): Fail suspend rval %xh",
1803			    QL_NAME, ha->instance, suspend);
1804
1805			/* Restart IP if it was running. */
1806			if (ha->flags & IP_ENABLED &&
1807			    !(ha->flags & IP_INITIALIZED)) {
1808				(void) ql_initialize_ip(ha);
1809				ql_isp_rcvbuf(ha);
1810			}
1811			rval = DDI_FAILURE;
1812			break;
1813		}
1814
1815		/* Acquire global state lock. */
1816		GLOBAL_STATE_LOCK();
1817
1818		/* Disable driver timer if last adapter. */
1819		if (ql_timer_timeout_id && ql_hba.first == &ha->hba &&
1820		    ql_hba.last == &ha->hba) {
1821			timer_id = ql_timer_timeout_id;
1822			ql_timer_timeout_id = NULL;
1823		}
1824		GLOBAL_STATE_UNLOCK();
1825
1826		if (timer_id) {
1827			(void) untimeout(timer_id);
1828		}
1829
1830		EL(ha, "suspended\n");
1831
1832		break;
1833
1834	default:
1835		rval = DDI_FAILURE;
1836		break;
1837	}
1838
1839	kmem_free(buf, MAXPATHLEN);
1840
1841	if (rval != DDI_SUCCESS) {
1842		if (ha != NULL) {
1843			EL(ha, "failed, rval = %xh\n", rval);
1844		} else {
1845			/*EMPTY*/
1846			QL_PRINT_2(CE_CONT, "(%d): failed, rval = %xh\n",
1847			    ddi_get_instance(dip), rval);
1848		}
1849	} else {
1850		/*EMPTY*/
1851		QL_PRINT_3(CE_CONT, "(%d): done\n", ddi_get_instance(dip));
1852	}
1853
1854	return (rval);
1855}
1856
1857
1858/*
1859 * ql_power
1860 *	Power a device attached to the system.
1861 *
1862 * Input:
1863 *	dip = pointer to device information structure.
1864 *	component = device.
1865 *	level = power level.
1866 *
1867 * Returns:
1868 *	DDI_SUCCESS or DDI_FAILURE.
1869 *
1870 * Context:
1871 *	Kernel context.
1872 */
1873/* ARGSUSED */
1874static int
1875ql_power(dev_info_t *dip, int component, int level)
1876{
1877	int			rval = DDI_FAILURE;
1878	off_t			csr;
1879	uint8_t			saved_pm_val;
1880	ql_adapter_state_t	*ha;
1881	char			*buf;
1882	char			*path;
1883
1884	ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
1885	if (ha == NULL || ha->pm_capable == 0) {
1886		QL_PRINT_2(CE_CONT, "(%d): no hba or PM not supported\n",
1887		    ddi_get_instance(dip));
1888		return (rval);
1889	}
1890
1891	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
1892
1893	buf = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
1894	path = (char *)(kmem_zalloc(MAXPATHLEN, KM_SLEEP));
1895
1896	if (component != QL_POWER_COMPONENT || (level != PM_LEVEL_D0 &&
1897	    level != PM_LEVEL_D3)) {
1898		EL(ha, "invalid, component=%xh or level=%xh\n",
1899		    component, level);
1900		return (rval);
1901	}
1902
1903	GLOBAL_HW_LOCK();
1904	csr = (uint8_t)ql_pci_config_get8(ha, PCI_CONF_CAP_PTR) + PCI_PMCSR;
1905	GLOBAL_HW_UNLOCK();
1906
1907	(void) snprintf(buf, sizeof (buf),
1908	    "Qlogic %s(%d): %s\n\t", QL_NAME, ddi_get_instance(dip),
1909	    ddi_pathname(dip, path));
1910
1911	switch (level) {
1912	case PM_LEVEL_D0:	/* power up to D0 state - fully on */
1913
1914		QL_PM_LOCK(ha);
1915		if (ha->power_level == PM_LEVEL_D0) {
1916			QL_PM_UNLOCK(ha);
1917			rval = DDI_SUCCESS;
1918			break;
1919		}
1920
1921		/*
1922		 * Enable interrupts now
1923		 */
1924		saved_pm_val = ha->power_level;
1925		ha->power_level = PM_LEVEL_D0;
1926		QL_PM_UNLOCK(ha);
1927
1928		GLOBAL_HW_LOCK();
1929
1930		ql_pci_config_put16(ha, csr, PCI_PMCSR_D0);
1931
1932		/*
1933		 * Delay after reset, for chip to recover.
1934		 * Otherwise causes system PANIC
1935		 */
1936		drv_usecwait(200000);
1937
1938		GLOBAL_HW_UNLOCK();
1939
1940		if (ha->config_saved) {
1941			ha->config_saved = 0;
1942			if (QL_RESTORE_CONFIG_REGS(dip) != DDI_SUCCESS) {
1943				QL_PM_LOCK(ha);
1944				ha->power_level = saved_pm_val;
1945				QL_PM_UNLOCK(ha);
1946				cmn_err(CE_WARN, "%s failed to restore "
1947				    "config regs", buf);
1948				break;
1949			}
1950		}
1951
1952		if (ql_initialize_adapter(ha) != QL_SUCCESS) {
1953			cmn_err(CE_WARN, "%s adapter initialization failed",
1954			    buf);
1955		}
1956
1957		/* Wake up task_daemon. */
1958		ql_awaken_task_daemon(ha, NULL, TASK_DAEMON_ALIVE_FLG |
1959		    TASK_DAEMON_SLEEPING_FLG, 0);
1960
1961		/* Restart IP if it was running. */
1962		if (ha->flags & IP_ENABLED && !(ha->flags & IP_INITIALIZED)) {
1963			(void) ql_initialize_ip(ha);
1964			ql_isp_rcvbuf(ha);
1965		}
1966
1967		cmn_err(CE_NOTE, QL_BANG "ql_power(%d): %s is powered ON\n",
1968		    ha->instance, QL_NAME);
1969
1970		rval = DDI_SUCCESS;
1971		break;
1972
1973	case PM_LEVEL_D3:	/* power down to D3 state - off */
1974
1975		QL_PM_LOCK(ha);
1976
1977		if (ha->busy || ((ha->task_daemon_flags &
1978		    TASK_DAEMON_SLEEPING_FLG) == 0)) {
1979			QL_PM_UNLOCK(ha);
1980			break;
1981		}
1982
1983		if (ha->power_level == PM_LEVEL_D3) {
1984			rval = DDI_SUCCESS;
1985			QL_PM_UNLOCK(ha);
1986			break;
1987		}
1988		QL_PM_UNLOCK(ha);
1989
1990		if (QL_SAVE_CONFIG_REGS(dip) != DDI_SUCCESS) {
1991			cmn_err(CE_WARN, "!Qlogic %s(%d): %s failed to save"
1992			    " config regs", QL_NAME, ha->instance, buf);
1993			break;
1994		}
1995		ha->config_saved = 1;
1996
1997		/*
1998		 * Don't enable interrupts. Running mailbox commands with
1999		 * interrupts enabled could cause hangs since pm_run_scan()
2000		 * runs out of a callout thread and on single cpu systems
2001		 * cv_timedwait(), called from ql_mailbox_command(), would
2002		 * not get to run.
2003		 */
2004		TASK_DAEMON_LOCK(ha);
2005		ha->task_daemon_flags |= TASK_DAEMON_POWERING_DOWN;
2006		TASK_DAEMON_UNLOCK(ha);
2007
2008		ql_halt(ha, PM_LEVEL_D3);
2009
2010		/*
2011		 * Setup ql_intr to ignore interrupts from here on.
2012		 */
2013		QL_PM_LOCK(ha);
2014		ha->power_level = PM_LEVEL_D3;
2015		QL_PM_UNLOCK(ha);
2016
2017		/*
2018		 * Wait for ISR to complete.
2019		 */
2020		INTR_LOCK(ha);
2021		ql_pci_config_put16(ha, csr, PCI_PMCSR_D3HOT);
2022		INTR_UNLOCK(ha);
2023
2024		cmn_err(CE_NOTE, QL_BANG "ql_power(%d): %s is powered OFF\n",
2025		    ha->instance, QL_NAME);
2026
2027		rval = DDI_SUCCESS;
2028		break;
2029	}
2030
2031	kmem_free(buf, MAXPATHLEN);
2032	kmem_free(path, MAXPATHLEN);
2033
2034	QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
2035
2036	return (rval);
2037}
2038
2039/*
2040 * ql_quiesce
2041 *	quiesce a device attached to the system.
2042 *
2043 * Input:
2044 *	dip = pointer to device information structure.
2045 *
2046 * Returns:
2047 *	DDI_SUCCESS
2048 *
2049 * Context:
2050 *	Kernel context.
2051 */
2052static int
2053ql_quiesce(dev_info_t *dip)
2054{
2055	ql_adapter_state_t	*ha;
2056	uint32_t		timer;
2057	uint32_t		stat;
2058
2059	ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
2060	if (ha == NULL) {
2061		/* Oh well.... */
2062		QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
2063		    ddi_get_instance(dip));
2064		return (DDI_SUCCESS);
2065	}
2066
2067	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2068
2069	if (CFG_IST(ha, CFG_CTRL_242581)) {
2070		WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
2071		WRT16_IO_REG(ha, mailbox[0], MBC_STOP_FIRMWARE);
2072		WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
2073		for (timer = 0; timer < 30000; timer++) {
2074			stat = RD32_IO_REG(ha, intr_info_lo);
2075			if (stat & BIT_15) {
2076				if ((stat & 0xff) < 0x12) {
2077					WRT32_IO_REG(ha, hccr,
2078					    HC24_CLR_RISC_INT);
2079					break;
2080				}
2081				WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
2082			}
2083			drv_usecwait(100);
2084		}
2085		/* Reset the chip. */
2086		WRT32_IO_REG(ha, ctrl_status, ISP_RESET | DMA_SHUTDOWN |
2087		    MWB_4096_BYTES);
2088		drv_usecwait(100);
2089
2090	} else {
2091		/* Disable ISP interrupts. */
2092		WRT16_IO_REG(ha, ictrl, 0);
2093		/* Select RISC module registers. */
2094		WRT16_IO_REG(ha, ctrl_status, 0);
2095		/* Reset ISP semaphore. */
2096		WRT16_IO_REG(ha, semaphore, 0);
2097		/* Reset RISC module. */
2098		WRT16_IO_REG(ha, hccr, HC_RESET_RISC);
2099		/* Release RISC module. */
2100		WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
2101	}
2102
2103	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2104
2105	return (DDI_SUCCESS);
2106}
2107
2108/* ************************************************************************ */
2109/*		Fibre Channel Adapter (FCA) Transport Functions.	    */
2110/* ************************************************************************ */
2111
2112/*
2113 * ql_bind_port
2114 *	Handling port binding. The FC Transport attempts to bind an FCA port
2115 *	when it is ready to start transactions on the port. The FC Transport
2116 *	will call the fca_bind_port() function specified in the fca_transport
2117 *	structure it receives. The FCA must fill in the port_info structure
2118 *	passed in the call and also stash the information for future calls.
2119 *
2120 * Input:
2121 *	dip = pointer to FCA information structure.
2122 *	port_info = pointer to port information structure.
2123 *	bind_info = pointer to bind information structure.
2124 *
2125 * Returns:
2126 *	NULL = failure
2127 *
2128 * Context:
2129 *	Kernel context.
2130 */
2131static opaque_t
2132ql_bind_port(dev_info_t *dip, fc_fca_port_info_t *port_info,
2133    fc_fca_bind_info_t *bind_info)
2134{
2135	ql_adapter_state_t	*ha, *vha;
2136	opaque_t		fca_handle = NULL;
2137	port_id_t		d_id;
2138	int			port_npiv = bind_info->port_npiv;
2139	uchar_t			*port_nwwn = bind_info->port_nwwn.raw_wwn;
2140	uchar_t			*port_pwwn = bind_info->port_pwwn.raw_wwn;
2141
2142	/* get state info based on the dip */
2143	ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
2144	if (ha == NULL) {
2145		QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
2146		    ddi_get_instance(dip));
2147		return (NULL);
2148	}
2149	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
2150
2151	/* Verify port number is supported. */
2152	if (port_npiv != 0) {
2153		if (!(ha->flags & VP_ENABLED)) {
2154			QL_PRINT_2(CE_CONT, "(%d): FC_NPIV_NOT_SUPPORTED\n",
2155			    ha->instance);
2156			port_info->pi_error = FC_NPIV_NOT_SUPPORTED;
2157			return (NULL);
2158		}
2159		if (!(ha->flags & POINT_TO_POINT)) {
2160			QL_PRINT_2(CE_CONT, "(%d): FC_NPIV_WRONG_TOPOLOGY\n",
2161			    ha->instance);
2162			port_info->pi_error = FC_NPIV_WRONG_TOPOLOGY;
2163			return (NULL);
2164		}
2165		if (!(ha->flags & FDISC_ENABLED)) {
2166			QL_PRINT_2(CE_CONT, "(%d): switch does not support "
2167			    "FDISC\n", ha->instance);
2168			port_info->pi_error = FC_NPIV_FDISC_FAILED;
2169			return (NULL);
2170		}
2171		if (bind_info->port_num > (CFG_IST(ha, CFG_CTRL_2422) ?
2172		    MAX_24_VIRTUAL_PORTS : MAX_25_VIRTUAL_PORTS)) {
2173			QL_PRINT_2(CE_CONT, "(%d): port number=%d "
2174			    "FC_OUTOFBOUNDS\n", ha->instance);
2175			port_info->pi_error = FC_OUTOFBOUNDS;
2176			return (NULL);
2177		}
2178	} else if (bind_info->port_num != 0) {
2179		QL_PRINT_2(CE_CONT, "(%d): failed, port number=%d is not "
2180		    "supported\n", ha->instance, bind_info->port_num);
2181		port_info->pi_error = FC_OUTOFBOUNDS;
2182		return (NULL);
2183	}
2184
2185	/* Locate port context. */
2186	for (vha = ha; vha != NULL; vha = vha->vp_next) {
2187		if (vha->vp_index == bind_info->port_num) {
2188			break;
2189		}
2190	}
2191
2192	/* If virtual port does not exist. */
2193	if (vha == NULL) {
2194		vha = ql_vport_create(ha, (uint8_t)bind_info->port_num);
2195	}
2196
2197	/* make sure this port isn't already bound */
2198	if (vha->flags & FCA_BOUND) {
2199		port_info->pi_error = FC_ALREADY;
2200	} else {
2201		if (vha->vp_index != 0) {
2202			bcopy(port_nwwn,
2203			    vha->loginparams.node_ww_name.raw_wwn, 8);
2204			bcopy(port_pwwn,
2205			    vha->loginparams.nport_ww_name.raw_wwn, 8);
2206		}
2207		if (vha->vp_index != 0 && !(vha->flags & VP_ENABLED)) {
2208			if (ql_vport_enable(vha) != QL_SUCCESS) {
2209				QL_PRINT_2(CE_CONT, "(%d): failed to enable "
2210				    "virtual port=%d\n", ha->instance,
2211				    vha->vp_index);
2212				port_info->pi_error = FC_NPIV_FDISC_FAILED;
2213				return (NULL);
2214			}
2215			cmn_err(CE_CONT, "!Qlogic %s(%d) NPIV(%d) "
2216			    "WWPN=%02x%02x%02x%02x%02x%02x%02x%02x : "
2217			    "WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
2218			    QL_NAME, ha->instance, vha->vp_index,
2219			    port_pwwn[0], port_pwwn[1], port_pwwn[2],
2220			    port_pwwn[3], port_pwwn[4], port_pwwn[5],
2221			    port_pwwn[6], port_pwwn[7],
2222			    port_nwwn[0], port_nwwn[1], port_nwwn[2],
2223			    port_nwwn[3], port_nwwn[4], port_nwwn[5],
2224			    port_nwwn[6], port_nwwn[7]);
2225		}
2226
2227		/* stash the bind_info supplied by the FC Transport */
2228		vha->bind_info.port_handle = bind_info->port_handle;
2229		vha->bind_info.port_statec_cb =
2230		    bind_info->port_statec_cb;
2231		vha->bind_info.port_unsol_cb = bind_info->port_unsol_cb;
2232
2233		/* Set port's source ID. */
2234		port_info->pi_s_id.port_id = vha->d_id.b24;
2235
2236		/* copy out the default login parameters */
2237		bcopy((void *)&vha->loginparams,
2238		    (void *)&port_info->pi_login_params,
2239		    sizeof (la_els_logi_t));
2240
2241		/* Set port's hard address if enabled. */
2242		port_info->pi_hard_addr.hard_addr = 0;
2243		if (bind_info->port_num == 0) {
2244			d_id.b24 = ha->d_id.b24;
2245			if (CFG_IST(ha, CFG_CTRL_242581)) {
2246				if (ha->init_ctrl_blk.cb24.
2247				    firmware_options_1[0] & BIT_0) {
2248					d_id.b.al_pa = ql_index_to_alpa[ha->
2249					    init_ctrl_blk.cb24.
2250					    hard_address[0]];
2251					port_info->pi_hard_addr.hard_addr =
2252					    d_id.b24;
2253				}
2254			} else if (ha->init_ctrl_blk.cb.firmware_options[0] &
2255			    BIT_0) {
2256				d_id.b.al_pa = ql_index_to_alpa[ha->
2257				    init_ctrl_blk.cb.hard_address[0]];
2258				port_info->pi_hard_addr.hard_addr = d_id.b24;
2259			}
2260
2261			/* Set the node id data */
2262			if (ql_get_rnid_params(ha,
2263			    sizeof (port_info->pi_rnid_params.params),
2264			    (caddr_t)&port_info->pi_rnid_params.params) ==
2265			    QL_SUCCESS) {
2266				port_info->pi_rnid_params.status = FC_SUCCESS;
2267			} else {
2268				port_info->pi_rnid_params.status = FC_FAILURE;
2269			}
2270
2271			/* Populate T11 FC-HBA details */
2272			ql_populate_hba_fru_details(ha, port_info);
2273			ha->pi_attrs = kmem_zalloc(sizeof (fca_port_attrs_t),
2274			    KM_SLEEP);
2275			if (ha->pi_attrs != NULL) {
2276				bcopy(&port_info->pi_attrs, ha->pi_attrs,
2277				    sizeof (fca_port_attrs_t));
2278			}
2279		} else {
2280			port_info->pi_rnid_params.status = FC_FAILURE;
2281			if (ha->pi_attrs != NULL) {
2282				bcopy(ha->pi_attrs, &port_info->pi_attrs,
2283				    sizeof (fca_port_attrs_t));
2284			}
2285		}
2286
2287		/* Generate handle for this FCA. */
2288		fca_handle = (opaque_t)vha;
2289
2290		ADAPTER_STATE_LOCK(ha);
2291		vha->flags |= FCA_BOUND;
2292		ADAPTER_STATE_UNLOCK(ha);
2293		/* Set port's current state. */
2294		port_info->pi_port_state = vha->state;
2295	}
2296
2297	QL_PRINT_10(CE_CONT, "(%d,%d): done, pi_port_state=%xh, "
2298	    "pi_s_id.port_id=%xh\n", ha->instance, ha->vp_index,
2299	    port_info->pi_port_state, port_info->pi_s_id.port_id);
2300
2301	return (fca_handle);
2302}
2303
2304/*
2305 * ql_unbind_port
2306 *	To unbind a Fibre Channel Adapter from an FC Port driver.
2307 *
2308 * Input:
2309 *	fca_handle = handle setup by ql_bind_port().
2310 *
2311 * Context:
2312 *	Kernel context.
2313 */
2314static void
2315ql_unbind_port(opaque_t fca_handle)
2316{
2317	ql_adapter_state_t	*ha;
2318	ql_tgt_t		*tq;
2319	uint32_t		flgs;
2320
2321	ha = ql_fca_handle_to_state(fca_handle);
2322	if (ha == NULL) {
2323		/*EMPTY*/
2324		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2325		    (void *)fca_handle);
2326	} else {
2327		QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance,
2328		    ha->vp_index);
2329
2330		if (!(ha->flags & FCA_BOUND)) {
2331			/*EMPTY*/
2332			QL_PRINT_2(CE_CONT, "(%d): port=%d already unbound\n",
2333			    ha->instance, ha->vp_index);
2334		} else {
2335			if (ha->vp_index != 0 && ha->flags & VP_ENABLED) {
2336				if ((tq = ql_loop_id_to_queue(ha,
2337				    FL_PORT_24XX_HDL)) != NULL) {
2338					(void) ql_logout_fabric_port(ha, tq);
2339				}
2340				(void) ql_vport_control(ha, (uint8_t)
2341				    (CFG_IST(ha, CFG_CTRL_2425) ?
2342				    VPC_DISABLE_INIT : VPC_DISABLE_LOGOUT));
2343				flgs = FCA_BOUND | VP_ENABLED;
2344			} else {
2345				flgs = FCA_BOUND;
2346			}
2347			ADAPTER_STATE_LOCK(ha);
2348			ha->flags &= ~flgs;
2349			ADAPTER_STATE_UNLOCK(ha);
2350		}
2351
2352		QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
2353		    ha->vp_index);
2354	}
2355}
2356
2357/*
2358 * ql_init_pkt
2359 *	Initialize FCA portion of packet.
2360 *
2361 * Input:
2362 *	fca_handle = handle setup by ql_bind_port().
2363 *	pkt = pointer to fc_packet.
2364 *
2365 * Returns:
2366 *	FC_SUCCESS - the packet has successfully been initialized.
2367 *	FC_UNBOUND - the fca_handle specified is not bound.
2368 *	FC_NOMEM - the FCA failed initialization due to an allocation error.
2369 *	FC_FAILURE - the FCA failed initialization for undisclosed reasons
2370 *
2371 * Context:
2372 *	Kernel context.
2373 */
2374/* ARGSUSED */
2375static int
2376ql_init_pkt(opaque_t fca_handle, fc_packet_t *pkt, int sleep)
2377{
2378	ql_adapter_state_t	*ha;
2379	ql_srb_t		*sp;
2380
2381	ha = ql_fca_handle_to_state(fca_handle);
2382	if (ha == NULL) {
2383		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2384		    (void *)fca_handle);
2385		return (FC_UNBOUND);
2386	}
2387	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2388
2389	sp = (ql_srb_t *)pkt->pkt_fca_private;
2390	sp->flags = 0;
2391
2392	/* init cmd links */
2393	sp->cmd.base_address = sp;
2394	sp->cmd.prev = NULL;
2395	sp->cmd.next = NULL;
2396	sp->cmd.head = NULL;
2397
2398	/* init watchdog links */
2399	sp->wdg.base_address = sp;
2400	sp->wdg.prev = NULL;
2401	sp->wdg.next = NULL;
2402	sp->wdg.head = NULL;
2403	sp->pkt = pkt;
2404	sp->ha = ha;
2405	sp->magic_number = QL_FCA_BRAND;
2406
2407	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2408
2409	return (FC_SUCCESS);
2410}
2411
2412/*
2413 * ql_un_init_pkt
2414 *	Release all local resources bound to packet.
2415 *
2416 * Input:
2417 *	fca_handle = handle setup by ql_bind_port().
2418 *	pkt = pointer to fc_packet.
2419 *
2420 * Returns:
2421 *	FC_SUCCESS - the packet has successfully been invalidated.
2422 *	FC_UNBOUND - the fca_handle specified is not bound.
2423 *	FC_BADPACKET - the packet has not been initialized or has
2424 *			already been freed by this FCA.
2425 *
2426 * Context:
2427 *	Kernel context.
2428 */
2429static int
2430ql_un_init_pkt(opaque_t fca_handle, fc_packet_t *pkt)
2431{
2432	ql_adapter_state_t *ha;
2433	int rval;
2434	ql_srb_t *sp;
2435
2436	ha = ql_fca_handle_to_state(fca_handle);
2437	if (ha == NULL) {
2438		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2439		    (void *)fca_handle);
2440		return (FC_UNBOUND);
2441	}
2442	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2443
2444	sp = (ql_srb_t *)pkt->pkt_fca_private;
2445
2446	if (sp->magic_number != QL_FCA_BRAND) {
2447		EL(ha, "failed, FC_BADPACKET\n");
2448		rval = FC_BADPACKET;
2449	} else {
2450		sp->magic_number = NULL;
2451
2452		rval = FC_SUCCESS;
2453	}
2454
2455	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2456
2457	return (rval);
2458}
2459
2460/*
2461 * ql_els_send
2462 *	Issue a extended link service request.
2463 *
2464 * Input:
2465 *	fca_handle = handle setup by ql_bind_port().
2466 *	pkt = pointer to fc_packet.
2467 *
2468 * Returns:
2469 *	FC_SUCCESS - the command was successful.
2470 *	FC_ELS_FREJECT - the command was rejected by a Fabric.
2471 *	FC_ELS_PREJECT - the command was rejected by an N-port.
2472 *	FC_TRANSPORT_ERROR - a transport error occurred.
2473 *	FC_UNBOUND - the fca_handle specified is not bound.
2474 *	FC_ELS_BAD - the FCA can not issue the requested ELS.
2475 *
2476 * Context:
2477 *	Kernel context.
2478 */
2479static int
2480ql_els_send(opaque_t fca_handle, fc_packet_t *pkt)
2481{
2482	ql_adapter_state_t	*ha;
2483	int			rval;
2484	clock_t			timer = drv_usectohz(30000000);
2485	ls_code_t		els;
2486	la_els_rjt_t		rjt;
2487	ql_srb_t		*sp = (ql_srb_t *)pkt->pkt_fca_private;
2488
2489	/* Verify proper command. */
2490	ha = ql_cmd_setup(fca_handle, pkt, &rval);
2491	if (ha == NULL) {
2492		QL_PRINT_2(CE_CONT, "failed, ql_cmd_setup=%xh, fcah=%ph\n",
2493		    rval, fca_handle);
2494		return (FC_INVALID_REQUEST);
2495	}
2496	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2497
2498	/* Wait for suspension to end. */
2499	TASK_DAEMON_LOCK(ha);
2500	while (ha->task_daemon_flags & QL_SUSPENDED) {
2501		ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG;
2502
2503		/* 30 seconds from now */
2504		if (cv_reltimedwait(&ha->pha->cv_dr_suspended,
2505		    &ha->pha->task_daemon_mutex, timer, TR_CLOCK_TICK) == -1) {
2506			/*
2507			 * The timeout time 'timer' was
2508			 * reached without the condition
2509			 * being signaled.
2510			 */
2511			pkt->pkt_state = FC_PKT_TRAN_BSY;
2512			pkt->pkt_reason = FC_REASON_XCHG_BSY;
2513
2514			/* Release task daemon lock. */
2515			TASK_DAEMON_UNLOCK(ha);
2516
2517			EL(ha, "QL_SUSPENDED failed=%xh\n",
2518			    QL_FUNCTION_TIMEOUT);
2519			return (FC_TRAN_BUSY);
2520		}
2521	}
2522	/* Release task daemon lock. */
2523	TASK_DAEMON_UNLOCK(ha);
2524
2525	/* Setup response header. */
2526	bcopy((void *)&pkt->pkt_cmd_fhdr, (void *)&pkt->pkt_resp_fhdr,
2527	    sizeof (fc_frame_hdr_t));
2528
2529	if (pkt->pkt_rsplen) {
2530		bzero((void *)pkt->pkt_resp, pkt->pkt_rsplen);
2531	}
2532
2533	pkt->pkt_resp_fhdr.d_id = ha->d_id.b24;
2534	pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id;
2535	pkt->pkt_resp_fhdr.r_ctl = R_CTL_EXTENDED_SVC |
2536	    R_CTL_SOLICITED_CONTROL;
2537	pkt->pkt_resp_fhdr.f_ctl = F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ |
2538	    F_CTL_END_SEQ;
2539
2540	sp->flags &= ~(SRB_UB_CALLBACK | SRB_UB_RSCN | SRB_UB_FCP |
2541	    SRB_FCP_CMD_PKT | SRB_FCP_DATA_PKT | SRB_FCP_RSP_PKT |
2542	    SRB_IP_PKT | SRB_COMMAND_TIMEOUT | SRB_UB_ACQUIRED | SRB_MS_PKT);
2543
2544	sp->flags |= SRB_ELS_PKT;
2545
2546	/* map the type of ELS to a function */
2547	ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
2548	    (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
2549
2550#if 0
2551	QL_PRINT_3(CE_CONT, "(%d): command fhdr:\n", ha->instance);
2552	QL_DUMP_3((uint8_t *)&pkt->pkt_cmd_fhdr, 32,
2553	    sizeof (fc_frame_hdr_t) / 4);
2554	QL_PRINT_3(CE_CONT, "(%d): command:\n", ha->instance);
2555	QL_DUMP_3((uint8_t *)&els, 32, sizeof (els) / 4);
2556#endif
2557
2558	sp->iocb = ha->els_cmd;
2559	sp->req_cnt = 1;
2560
2561	switch (els.ls_code) {
2562	case LA_ELS_RJT:
2563	case LA_ELS_ACC:
2564		EL(ha, "LA_ELS_RJT\n");
2565		pkt->pkt_state = FC_PKT_SUCCESS;
2566		rval = FC_SUCCESS;
2567		break;
2568	case LA_ELS_PLOGI:
2569	case LA_ELS_PDISC:
2570		rval = ql_els_plogi(ha, pkt);
2571		break;
2572	case LA_ELS_FLOGI:
2573	case LA_ELS_FDISC:
2574		rval = ql_els_flogi(ha, pkt);
2575		break;
2576	case LA_ELS_LOGO:
2577		rval = ql_els_logo(ha, pkt);
2578		break;
2579	case LA_ELS_PRLI:
2580		rval = ql_els_prli(ha, pkt);
2581		break;
2582	case LA_ELS_PRLO:
2583		rval = ql_els_prlo(ha, pkt);
2584		break;
2585	case LA_ELS_ADISC:
2586		rval = ql_els_adisc(ha, pkt);
2587		break;
2588	case LA_ELS_LINIT:
2589		rval = ql_els_linit(ha, pkt);
2590		break;
2591	case LA_ELS_LPC:
2592		rval = ql_els_lpc(ha, pkt);
2593		break;
2594	case LA_ELS_LSTS:
2595		rval = ql_els_lsts(ha, pkt);
2596		break;
2597	case LA_ELS_SCR:
2598		rval = ql_els_scr(ha, pkt);
2599		break;
2600	case LA_ELS_RSCN:
2601		rval = ql_els_rscn(ha, pkt);
2602		break;
2603	case LA_ELS_FARP_REQ:
2604		rval = ql_els_farp_req(ha, pkt);
2605		break;
2606	case LA_ELS_FARP_REPLY:
2607		rval = ql_els_farp_reply(ha, pkt);
2608		break;
2609	case LA_ELS_RLS:
2610		rval = ql_els_rls(ha, pkt);
2611		break;
2612	case LA_ELS_RNID:
2613		rval = ql_els_rnid(ha, pkt);
2614		break;
2615	default:
2616		EL(ha, "LA_ELS_RJT, FC_REASON_CMD_UNSUPPORTED=%xh\n",
2617		    els.ls_code);
2618		/* Build RJT. */
2619		bzero(&rjt, sizeof (rjt));
2620		rjt.ls_code.ls_code = LA_ELS_RJT;
2621		rjt.reason = FC_REASON_CMD_UNSUPPORTED;
2622
2623		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
2624		    (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
2625
2626		pkt->pkt_state = FC_PKT_LOCAL_RJT;
2627		pkt->pkt_reason = FC_REASON_UNSUPPORTED;
2628		rval = FC_SUCCESS;
2629		break;
2630	}
2631
2632#if 0
2633	QL_PRINT_3(CE_CONT, "(%d): response fhdr:\n", ha->instance);
2634	QL_DUMP_3((uint8_t *)&pkt->pkt_resp_fhdr, 32,
2635	    sizeof (fc_frame_hdr_t) / 4);
2636#endif
2637	/*
2638	 * Return success if the srb was consumed by an iocb. The packet
2639	 * completion callback will be invoked by the response handler.
2640	 */
2641	if (rval == QL_CONSUMED) {
2642		rval = FC_SUCCESS;
2643	} else if (rval == FC_SUCCESS &&
2644	    !(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
2645		/* Do command callback only if no error */
2646		ql_awaken_task_daemon(ha, sp, 0, 0);
2647	}
2648
2649	if (rval != FC_SUCCESS) {
2650		EL(ha, "failed, rval = %xh\n", rval);
2651	} else {
2652		/*EMPTY*/
2653		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2654	}
2655	return (rval);
2656}
2657
2658/*
2659 * ql_get_cap
2660 *	Export FCA hardware and software capabilities.
2661 *
2662 * Input:
2663 *	fca_handle = handle setup by ql_bind_port().
2664 *	cap = pointer to the capabilities string.
2665 *	ptr = buffer pointer for return capability.
2666 *
2667 * Returns:
2668 *	FC_CAP_ERROR - no such capability
2669 *	FC_CAP_FOUND - the capability was returned and cannot be set
2670 *	FC_CAP_SETTABLE - the capability was returned and can be set
2671 *	FC_UNBOUND - the fca_handle specified is not bound.
2672 *
2673 * Context:
2674 *	Kernel context.
2675 */
2676static int
2677ql_get_cap(opaque_t fca_handle, char *cap, void *ptr)
2678{
2679	ql_adapter_state_t	*ha;
2680	int			rval;
2681	uint32_t		*rptr = (uint32_t *)ptr;
2682
2683	ha = ql_fca_handle_to_state(fca_handle);
2684	if (ha == NULL) {
2685		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2686		    (void *)fca_handle);
2687		return (FC_UNBOUND);
2688	}
2689	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2690
2691	if (strcmp(cap, FC_NODE_WWN) == 0) {
2692		bcopy((void *)&ha->loginparams.node_ww_name.raw_wwn[0],
2693		    ptr, 8);
2694		rval = FC_CAP_FOUND;
2695	} else if (strcmp(cap, FC_LOGIN_PARAMS) == 0) {
2696		bcopy((void *)&ha->loginparams, ptr,
2697		    sizeof (la_els_logi_t));
2698		rval = FC_CAP_FOUND;
2699	} else if (strcmp(cap, FC_CAP_UNSOL_BUF) == 0) {
2700		*rptr = (uint32_t)QL_UB_LIMIT;
2701		rval = FC_CAP_FOUND;
2702	} else if (strcmp(cap, FC_CAP_NOSTREAM_ON_UNALIGN_BUF) == 0) {
2703
2704		dev_info_t	*psydip = NULL;
2705#ifdef __sparc
2706		/*
2707		 * Disable streaming for certain 2 chip adapters
2708		 * below Psycho to handle Psycho byte hole issue.
2709		 */
2710		if ((CFG_IST(ha, CFG_MULTI_CHIP_ADAPTER)) &&
2711		    (!CFG_IST(ha, CFG_SBUS_CARD))) {
2712			for (psydip = ddi_get_parent(ha->dip); psydip;
2713			    psydip = ddi_get_parent(psydip)) {
2714				if (strcmp(ddi_driver_name(psydip),
2715				    "pcipsy") == 0) {
2716					break;
2717				}
2718			}
2719		}
2720#endif	/* __sparc */
2721
2722		if (psydip) {
2723			*rptr = (uint32_t)FC_NO_STREAMING;
2724			EL(ha, "No Streaming\n");
2725		} else {
2726			*rptr = (uint32_t)FC_ALLOW_STREAMING;
2727			EL(ha, "Allow Streaming\n");
2728		}
2729		rval = FC_CAP_FOUND;
2730	} else if (strcmp(cap, FC_CAP_PAYLOAD_SIZE) == 0) {
2731		if (CFG_IST(ha, CFG_CTRL_242581)) {
2732			*rptr = (uint32_t)CHAR_TO_SHORT(
2733			    ha->init_ctrl_blk.cb24.max_frame_length[0],
2734			    ha->init_ctrl_blk.cb24.max_frame_length[1]);
2735		} else {
2736			*rptr = (uint32_t)CHAR_TO_SHORT(
2737			    ha->init_ctrl_blk.cb.max_frame_length[0],
2738			    ha->init_ctrl_blk.cb.max_frame_length[1]);
2739		}
2740		rval = FC_CAP_FOUND;
2741	} else if (strcmp(cap, FC_CAP_POST_RESET_BEHAVIOR) == 0) {
2742		*rptr = FC_RESET_RETURN_ALL;
2743		rval = FC_CAP_FOUND;
2744	} else if (strcmp(cap, FC_CAP_FCP_DMA) == 0) {
2745		*rptr = FC_NO_DVMA_SPACE;
2746		rval = FC_CAP_FOUND;
2747	} else {
2748		EL(ha, "unknown=%s, FC_CAP_ERROR\n", cap);
2749		rval = FC_CAP_ERROR;
2750	}
2751
2752	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2753
2754	return (rval);
2755}
2756
2757/*
2758 * ql_set_cap
2759 *	Allow the FC Transport to set FCA capabilities if possible.
2760 *
2761 * Input:
2762 *	fca_handle = handle setup by ql_bind_port().
2763 *	cap = pointer to the capabilities string.
2764 *	ptr = buffer pointer for capability.
2765 *
2766 * Returns:
2767 *	FC_CAP_ERROR - no such capability
2768 *	FC_CAP_FOUND - the capability cannot be set by the FC Transport.
2769 *	FC_CAP_SETTABLE - the capability was successfully set.
2770 *	FC_UNBOUND - the fca_handle specified is not bound.
2771 *
2772 * Context:
2773 *	Kernel context.
2774 */
2775/* ARGSUSED */
2776static int
2777ql_set_cap(opaque_t fca_handle, char *cap, void *ptr)
2778{
2779	ql_adapter_state_t	*ha;
2780	int			rval;
2781
2782	ha = ql_fca_handle_to_state(fca_handle);
2783	if (ha == NULL) {
2784		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2785		    (void *)fca_handle);
2786		return (FC_UNBOUND);
2787	}
2788	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2789
2790	if (strcmp(cap, FC_NODE_WWN) == 0) {
2791		rval = FC_CAP_FOUND;
2792	} else if (strcmp(cap, FC_LOGIN_PARAMS) == 0) {
2793		rval = FC_CAP_FOUND;
2794	} else if (strcmp(cap, FC_CAP_UNSOL_BUF) == 0) {
2795		rval = FC_CAP_FOUND;
2796	} else if (strcmp(cap, FC_CAP_PAYLOAD_SIZE) == 0) {
2797		rval = FC_CAP_FOUND;
2798	} else if (strcmp(cap, FC_CAP_POST_RESET_BEHAVIOR) == 0) {
2799		rval = FC_CAP_FOUND;
2800	} else {
2801		EL(ha, "unknown=%s, FC_CAP_ERROR\n", cap);
2802		rval = FC_CAP_ERROR;
2803	}
2804
2805	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2806
2807	return (rval);
2808}
2809
2810/*
2811 * ql_getmap
2812 *	Request of Arbitrated Loop (AL-PA) map.
2813 *
2814 * Input:
2815 *	fca_handle = handle setup by ql_bind_port().
2816 *	mapbuf= buffer pointer for map.
2817 *
2818 * Returns:
2819 *	FC_OLDPORT - the specified port is not operating in loop mode.
2820 *	FC_OFFLINE - the specified port is not online.
2821 *	FC_NOMAP - there is no loop map available for this port.
2822 *	FC_UNBOUND - the fca_handle specified is not bound.
2823 *	FC_SUCCESS - a valid map has been placed in mapbuf.
2824 *
2825 * Context:
2826 *	Kernel context.
2827 */
2828static int
2829ql_getmap(opaque_t fca_handle, fc_lilpmap_t *mapbuf)
2830{
2831	ql_adapter_state_t	*ha;
2832	clock_t			timer = drv_usectohz(30000000);
2833	int			rval = FC_SUCCESS;
2834
2835	ha = ql_fca_handle_to_state(fca_handle);
2836	if (ha == NULL) {
2837		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
2838		    (void *)fca_handle);
2839		return (FC_UNBOUND);
2840	}
2841	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2842
2843	mapbuf->lilp_magic = (uint16_t)MAGIC_LIRP;
2844	mapbuf->lilp_myalpa = ha->d_id.b.al_pa;
2845
2846	/* Wait for suspension to end. */
2847	TASK_DAEMON_LOCK(ha);
2848	while (ha->task_daemon_flags & QL_SUSPENDED) {
2849		ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG;
2850
2851		/* 30 seconds from now */
2852		if (cv_reltimedwait(&ha->pha->cv_dr_suspended,
2853		    &ha->pha->task_daemon_mutex, timer, TR_CLOCK_TICK) == -1) {
2854			/*
2855			 * The timeout time 'timer' was
2856			 * reached without the condition
2857			 * being signaled.
2858			 */
2859
2860			/* Release task daemon lock. */
2861			TASK_DAEMON_UNLOCK(ha);
2862
2863			EL(ha, "QL_SUSPENDED failed, FC_TRAN_BUSY\n");
2864			return (FC_TRAN_BUSY);
2865		}
2866	}
2867	/* Release task daemon lock. */
2868	TASK_DAEMON_UNLOCK(ha);
2869
2870	if (ql_get_loop_position_map(ha, LOOP_POSITION_MAP_SIZE,
2871	    (caddr_t)&mapbuf->lilp_length) != QL_SUCCESS) {
2872		/*
2873		 * Now, since transport drivers cosider this as an
2874		 * offline condition, let's wait for few seconds
2875		 * for any loop transitions before we reset the.
2876		 * chip and restart all over again.
2877		 */
2878		ql_delay(ha, 2000000);
2879		EL(ha, "failed, FC_NOMAP\n");
2880		rval = FC_NOMAP;
2881	} else {
2882		/*EMPTY*/
2883		QL_PRINT_3(CE_CONT, "(%d): my_alpa %xh len %xh "
2884		    "data %xh %xh %xh %xh\n", ha->instance,
2885		    mapbuf->lilp_myalpa, mapbuf->lilp_length,
2886		    mapbuf->lilp_alpalist[0], mapbuf->lilp_alpalist[1],
2887		    mapbuf->lilp_alpalist[2], mapbuf->lilp_alpalist[3]);
2888	}
2889
2890	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2891#if 0
2892	QL_DUMP_3((uint8_t *)mapbuf, 8, sizeof (fc_lilpmap_t));
2893#endif
2894	return (rval);
2895}
2896
2897/*
2898 * ql_transport
2899 *	Issue an I/O request. Handles all regular requests.
2900 *
2901 * Input:
2902 *	fca_handle = handle setup by ql_bind_port().
2903 *	pkt = pointer to fc_packet.
2904 *
2905 * Returns:
2906 *	FC_SUCCESS - the packet was accepted for transport.
2907 *	FC_TRANSPORT_ERROR - a transport error occurred.
2908 *	FC_BADPACKET - the packet to be transported had not been
2909 *			initialized by this FCA.
2910 *	FC_UNBOUND - the fca_handle specified is not bound.
2911 *
2912 * Context:
2913 *	Kernel context.
2914 */
2915static int
2916ql_transport(opaque_t fca_handle, fc_packet_t *pkt)
2917{
2918	ql_adapter_state_t	*ha;
2919	int			rval = FC_TRANSPORT_ERROR;
2920	ql_srb_t		*sp = (ql_srb_t *)pkt->pkt_fca_private;
2921
2922	/* Verify proper command. */
2923	ha = ql_cmd_setup(fca_handle, pkt, &rval);
2924	if (ha == NULL) {
2925		QL_PRINT_2(CE_CONT, "failed, ql_cmd_setup=%xh, fcah=%ph\n",
2926		    rval, fca_handle);
2927		return (rval);
2928	}
2929	QL_PRINT_3(CE_CONT, "(%d): started command:\n", ha->instance);
2930#if 0
2931	QL_DUMP_3((uint8_t *)&pkt->pkt_cmd_fhdr, 32,
2932	    sizeof (fc_frame_hdr_t) / 4);
2933	QL_PRINT_3(CE_CONT, "(%d): command:\n", ha->instance);
2934	QL_DUMP_3((uint8_t *)pkt->pkt_cmd, 8, pkt->pkt_cmdlen);
2935#endif
2936
2937	/* Reset SRB flags. */
2938	sp->flags &= ~(SRB_ISP_STARTED | SRB_ISP_COMPLETED | SRB_RETRY |
2939	    SRB_POLL | SRB_WATCHDOG_ENABLED | SRB_ABORT | SRB_UB_CALLBACK |
2940	    SRB_UB_RSCN | SRB_UB_FCP | SRB_FCP_CMD_PKT | SRB_FCP_DATA_PKT |
2941	    SRB_FCP_RSP_PKT | SRB_IP_PKT | SRB_GENERIC_SERVICES_PKT |
2942	    SRB_COMMAND_TIMEOUT | SRB_ABORTING | SRB_IN_DEVICE_QUEUE |
2943	    SRB_IN_TOKEN_ARRAY | SRB_UB_FREE_REQUESTED | SRB_UB_ACQUIRED |
2944	    SRB_MS_PKT | SRB_ELS_PKT);
2945
2946	pkt->pkt_resp_fhdr.d_id = ha->d_id.b24;
2947	pkt->pkt_resp_fhdr.r_ctl = R_CTL_STATUS;
2948	pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id;
2949	pkt->pkt_resp_fhdr.f_ctl = pkt->pkt_cmd_fhdr.f_ctl;
2950	pkt->pkt_resp_fhdr.type = pkt->pkt_cmd_fhdr.type;
2951
2952	switch (pkt->pkt_cmd_fhdr.r_ctl) {
2953	case R_CTL_COMMAND:
2954		if (pkt->pkt_cmd_fhdr.type == FC_TYPE_SCSI_FCP) {
2955			sp->flags |= SRB_FCP_CMD_PKT;
2956			rval = ql_fcp_scsi_cmd(ha, pkt, sp);
2957		}
2958		break;
2959
2960	default:
2961		/* Setup response header and buffer. */
2962		if (pkt->pkt_rsplen) {
2963			bzero((void *)pkt->pkt_resp, pkt->pkt_rsplen);
2964		}
2965
2966		switch (pkt->pkt_cmd_fhdr.r_ctl) {
2967		case R_CTL_UNSOL_DATA:
2968			if (pkt->pkt_cmd_fhdr.type == FC_TYPE_IS8802_SNAP) {
2969				sp->flags |= SRB_IP_PKT;
2970				rval = ql_fcp_ip_cmd(ha, pkt, sp);
2971			}
2972			break;
2973
2974		case R_CTL_UNSOL_CONTROL:
2975			if (pkt->pkt_cmd_fhdr.type == FC_TYPE_FC_SERVICES) {
2976				sp->flags |= SRB_GENERIC_SERVICES_PKT;
2977				rval = ql_fc_services(ha, pkt);
2978			}
2979			break;
2980
2981		case R_CTL_SOLICITED_DATA:
2982		case R_CTL_STATUS:
2983		default:
2984			pkt->pkt_state = FC_PKT_LOCAL_RJT;
2985			pkt->pkt_reason = FC_REASON_UNSUPPORTED;
2986			rval = FC_TRANSPORT_ERROR;
2987			EL(ha, "unknown, r_ctl=%xh\n",
2988			    pkt->pkt_cmd_fhdr.r_ctl);
2989			break;
2990		}
2991	}
2992
2993	if (rval != FC_SUCCESS) {
2994		EL(ha, "failed, rval = %xh\n", rval);
2995	} else {
2996		/*EMPTY*/
2997		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2998	}
2999
3000	return (rval);
3001}
3002
3003/*
3004 * ql_ub_alloc
3005 *	Allocate buffers for unsolicited exchanges.
3006 *
3007 * Input:
3008 *	fca_handle = handle setup by ql_bind_port().
3009 *	tokens = token array for each buffer.
3010 *	size = size of each buffer.
3011 *	count = pointer to number of buffers.
3012 *	type = the FC-4 type the buffers are reserved for.
3013 *		1 = Extended Link Services, 5 = LLC/SNAP
3014 *
3015 * Returns:
3016 *	FC_FAILURE - buffers could not be allocated.
3017 *	FC_TOOMANY - the FCA could not allocate the requested
3018 *			number of buffers.
3019 *	FC_SUCCESS - unsolicited buffers were allocated.
3020 *	FC_UNBOUND - the fca_handle specified is not bound.
3021 *
3022 * Context:
3023 *	Kernel context.
3024 */
3025static int
3026ql_ub_alloc(opaque_t fca_handle, uint64_t tokens[], uint32_t size,
3027    uint32_t *count, uint32_t type)
3028{
3029	ql_adapter_state_t	*ha;
3030	caddr_t			bufp = NULL;
3031	fc_unsol_buf_t		*ubp;
3032	ql_srb_t		*sp;
3033	uint32_t		index;
3034	uint32_t		cnt;
3035	uint32_t		ub_array_index = 0;
3036	int			rval = FC_SUCCESS;
3037	int			ub_updated = FALSE;
3038
3039	/* Check handle. */
3040	ha = ql_fca_handle_to_state(fca_handle);
3041	if (ha == NULL) {
3042		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3043		    (void *)fca_handle);
3044		return (FC_UNBOUND);
3045	}
3046	QL_PRINT_3(CE_CONT, "(%d,%d): started, count = %xh\n",
3047	    ha->instance, ha->vp_index, *count);
3048
3049	QL_PM_LOCK(ha);
3050	if (ha->power_level != PM_LEVEL_D0) {
3051		QL_PM_UNLOCK(ha);
3052		QL_PRINT_3(CE_CONT, "(%d,%d): down done\n", ha->instance,
3053		    ha->vp_index);
3054		return (FC_FAILURE);
3055	}
3056	QL_PM_UNLOCK(ha);
3057
3058	/* Acquire adapter state lock. */
3059	ADAPTER_STATE_LOCK(ha);
3060
3061	/* Check the count. */
3062	if ((*count + ha->ub_allocated) > QL_UB_LIMIT) {
3063		*count = 0;
3064		EL(ha, "failed, FC_TOOMANY\n");
3065		rval = FC_TOOMANY;
3066	}
3067
3068	/*
3069	 * reset ub_array_index
3070	 */
3071	ub_array_index = 0;
3072
3073	/*
3074	 * Now proceed to allocate any buffers required
3075	 */
3076	for (index = 0; index < *count && rval == FC_SUCCESS; index++) {
3077		/* Allocate all memory needed. */
3078		ubp = (fc_unsol_buf_t *)kmem_zalloc(sizeof (fc_unsol_buf_t),
3079		    KM_SLEEP);
3080		if (ubp == NULL) {
3081			EL(ha, "failed, FC_FAILURE\n");
3082			rval = FC_FAILURE;
3083		} else {
3084			sp = kmem_zalloc(sizeof (ql_srb_t), KM_SLEEP);
3085			if (sp == NULL) {
3086				kmem_free(ubp, sizeof (fc_unsol_buf_t));
3087				rval = FC_FAILURE;
3088			} else {
3089				if (type == FC_TYPE_IS8802_SNAP) {
3090#ifdef	__sparc
3091					if (ql_get_dma_mem(ha,
3092					    &sp->ub_buffer, size,
3093					    BIG_ENDIAN_DMA,
3094					    QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
3095						rval = FC_FAILURE;
3096						kmem_free(ubp,
3097						    sizeof (fc_unsol_buf_t));
3098						kmem_free(sp,
3099						    sizeof (ql_srb_t));
3100					} else {
3101						bufp = sp->ub_buffer.bp;
3102						sp->ub_size = size;
3103					}
3104#else
3105					if (ql_get_dma_mem(ha,
3106					    &sp->ub_buffer, size,
3107					    LITTLE_ENDIAN_DMA,
3108					    QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
3109						rval = FC_FAILURE;
3110						kmem_free(ubp,
3111						    sizeof (fc_unsol_buf_t));
3112						kmem_free(sp,
3113						    sizeof (ql_srb_t));
3114					} else {
3115						bufp = sp->ub_buffer.bp;
3116						sp->ub_size = size;
3117					}
3118#endif
3119				} else {
3120					bufp = kmem_zalloc(size, KM_SLEEP);
3121					if (bufp == NULL) {
3122						rval = FC_FAILURE;
3123						kmem_free(ubp,
3124						    sizeof (fc_unsol_buf_t));
3125						kmem_free(sp,
3126						    sizeof (ql_srb_t));
3127					} else {
3128						sp->ub_size = size;
3129					}
3130				}
3131			}
3132		}
3133
3134		if (rval == FC_SUCCESS) {
3135			/* Find next available slot. */
3136			QL_UB_LOCK(ha);
3137			while (ha->ub_array[ub_array_index] != NULL) {
3138				ub_array_index++;
3139			}
3140
3141			ubp->ub_fca_private = (void *)sp;
3142
3143			/* init cmd links */
3144			sp->cmd.base_address = sp;
3145			sp->cmd.prev = NULL;
3146			sp->cmd.next = NULL;
3147			sp->cmd.head = NULL;
3148
3149			/* init wdg links */
3150			sp->wdg.base_address = sp;
3151			sp->wdg.prev = NULL;
3152			sp->wdg.next = NULL;
3153			sp->wdg.head = NULL;
3154			sp->ha = ha;
3155
3156			ubp->ub_buffer = bufp;
3157			ubp->ub_bufsize = size;
3158			ubp->ub_port_handle = fca_handle;
3159			ubp->ub_token = ub_array_index;
3160
3161			/* Save the token. */
3162			tokens[index] = ub_array_index;
3163
3164			/* Setup FCA private information. */
3165			sp->ub_type = type;
3166			sp->handle = ub_array_index;
3167			sp->flags |= SRB_UB_IN_FCA;
3168
3169			ha->ub_array[ub_array_index] = ubp;
3170			ha->ub_allocated++;
3171			ub_updated = TRUE;
3172			QL_UB_UNLOCK(ha);
3173		}
3174	}
3175
3176	/* Release adapter state lock. */
3177	ADAPTER_STATE_UNLOCK(ha);
3178
3179	/* IP buffer. */
3180	if (ub_updated) {
3181		if ((type == FC_TYPE_IS8802_SNAP) &&
3182		    (!(CFG_IST(ha, (CFG_CTRL_6322 | CFG_CTRL_2581))))) {
3183
3184			ADAPTER_STATE_LOCK(ha);
3185			ha->flags |= IP_ENABLED;
3186			ADAPTER_STATE_UNLOCK(ha);
3187
3188			if (!(ha->flags & IP_INITIALIZED)) {
3189				if (CFG_IST(ha, CFG_CTRL_2422)) {
3190					ha->ip_init_ctrl_blk.cb24.mtu_size[0] =
3191					    LSB(ql_ip_mtu);
3192					ha->ip_init_ctrl_blk.cb24.mtu_size[1] =
3193					    MSB(ql_ip_mtu);
3194					ha->ip_init_ctrl_blk.cb24.buf_size[0] =
3195					    LSB(size);
3196					ha->ip_init_ctrl_blk.cb24.buf_size[1] =
3197					    MSB(size);
3198
3199					cnt = CHAR_TO_SHORT(
3200					    ha->ip_init_ctrl_blk.cb24.cc[0],
3201					    ha->ip_init_ctrl_blk.cb24.cc[1]);
3202
3203					if (cnt < *count) {
3204						ha->ip_init_ctrl_blk.cb24.cc[0]
3205						    = LSB(*count);
3206						ha->ip_init_ctrl_blk.cb24.cc[1]
3207						    = MSB(*count);
3208					}
3209				} else {
3210					ha->ip_init_ctrl_blk.cb.mtu_size[0] =
3211					    LSB(ql_ip_mtu);
3212					ha->ip_init_ctrl_blk.cb.mtu_size[1] =
3213					    MSB(ql_ip_mtu);
3214					ha->ip_init_ctrl_blk.cb.buf_size[0] =
3215					    LSB(size);
3216					ha->ip_init_ctrl_blk.cb.buf_size[1] =
3217					    MSB(size);
3218
3219					cnt = CHAR_TO_SHORT(
3220					    ha->ip_init_ctrl_blk.cb.cc[0],
3221					    ha->ip_init_ctrl_blk.cb.cc[1]);
3222
3223					if (cnt < *count) {
3224						ha->ip_init_ctrl_blk.cb.cc[0] =
3225						    LSB(*count);
3226						ha->ip_init_ctrl_blk.cb.cc[1] =
3227						    MSB(*count);
3228					}
3229				}
3230
3231				(void) ql_initialize_ip(ha);
3232			}
3233			ql_isp_rcvbuf(ha);
3234		}
3235	}
3236
3237	if (rval != FC_SUCCESS) {
3238		EL(ha, "failed=%xh\n", rval);
3239	} else {
3240		/*EMPTY*/
3241		QL_PRINT_3(CE_CONT, "(%d,%d): done\n", ha->instance,
3242		    ha->vp_index);
3243	}
3244	return (rval);
3245}
3246
3247/*
3248 * ql_ub_free
3249 *	Free unsolicited buffers.
3250 *
3251 * Input:
3252 *	fca_handle = handle setup by ql_bind_port().
3253 *	count = number of buffers.
3254 *	tokens = token array for each buffer.
3255 *
3256 * Returns:
3257 *	FC_SUCCESS - the requested buffers have been freed.
3258 *	FC_UNBOUND - the fca_handle specified is not bound.
3259 *	FC_UB_BADTOKEN - an invalid token was encountered.
3260 *			 No buffers have been released.
3261 *
3262 * Context:
3263 *	Kernel context.
3264 */
3265static int
3266ql_ub_free(opaque_t fca_handle, uint32_t count, uint64_t tokens[])
3267{
3268	ql_adapter_state_t	*ha;
3269	ql_srb_t		*sp;
3270	uint32_t		index;
3271	uint64_t		ub_array_index;
3272	int			rval = FC_SUCCESS;
3273
3274	/* Check handle. */
3275	ha = ql_fca_handle_to_state(fca_handle);
3276	if (ha == NULL) {
3277		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3278		    (void *)fca_handle);
3279		return (FC_UNBOUND);
3280	}
3281	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3282
3283	/* Acquire adapter state lock. */
3284	ADAPTER_STATE_LOCK(ha);
3285
3286	/* Check all returned tokens. */
3287	for (index = 0; index < count; index++) {
3288		fc_unsol_buf_t	*ubp;
3289
3290		/* Check the token range. */
3291		if ((ub_array_index = tokens[index]) >= QL_UB_LIMIT) {
3292			EL(ha, "failed, FC_UB_BADTOKEN\n");
3293			rval = FC_UB_BADTOKEN;
3294			break;
3295		}
3296
3297		/* Check the unsolicited buffer array. */
3298		QL_UB_LOCK(ha);
3299		ubp = ha->ub_array[ub_array_index];
3300
3301		if (ubp == NULL) {
3302			EL(ha, "failed, FC_UB_BADTOKEN-2\n");
3303			rval = FC_UB_BADTOKEN;
3304			QL_UB_UNLOCK(ha);
3305			break;
3306		}
3307
3308		/* Check the state of the unsolicited buffer. */
3309		sp = ha->ub_array[ub_array_index]->ub_fca_private;
3310		sp->flags |= SRB_UB_FREE_REQUESTED;
3311
3312		while (!(sp->flags & SRB_UB_IN_FCA) ||
3313		    (sp->flags & (SRB_UB_CALLBACK | SRB_UB_ACQUIRED))) {
3314			QL_UB_UNLOCK(ha);
3315			ADAPTER_STATE_UNLOCK(ha);
3316			delay(drv_usectohz(100000));
3317			ADAPTER_STATE_LOCK(ha);
3318			QL_UB_LOCK(ha);
3319		}
3320		ha->ub_array[ub_array_index] = NULL;
3321		QL_UB_UNLOCK(ha);
3322		ql_free_unsolicited_buffer(ha, ubp);
3323	}
3324
3325	if (rval == FC_SUCCESS) {
3326		/*
3327		 * Signal any pending hardware reset when there are
3328		 * no more unsolicited buffers in use.
3329		 */
3330		if (ha->ub_allocated == 0) {
3331			cv_broadcast(&ha->pha->cv_ub);
3332		}
3333	}
3334
3335	/* Release adapter state lock. */
3336	ADAPTER_STATE_UNLOCK(ha);
3337
3338	if (rval != FC_SUCCESS) {
3339		EL(ha, "failed=%xh\n", rval);
3340	} else {
3341		/*EMPTY*/
3342		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3343	}
3344	return (rval);
3345}
3346
3347/*
3348 * ql_ub_release
3349 *	Release unsolicited buffers from FC Transport
3350 *	to FCA for future use.
3351 *
3352 * Input:
3353 *	fca_handle = handle setup by ql_bind_port().
3354 *	count = number of buffers.
3355 *	tokens = token array for each buffer.
3356 *
3357 * Returns:
3358 *	FC_SUCCESS - the requested buffers have been released.
3359 *	FC_UNBOUND - the fca_handle specified is not bound.
3360 *	FC_UB_BADTOKEN - an invalid token was encountered.
3361 *		No buffers have been released.
3362 *
3363 * Context:
3364 *	Kernel context.
3365 */
3366static int
3367ql_ub_release(opaque_t fca_handle, uint32_t count, uint64_t tokens[])
3368{
3369	ql_adapter_state_t	*ha;
3370	ql_srb_t		*sp;
3371	uint32_t		index;
3372	uint64_t		ub_array_index;
3373	int			rval = FC_SUCCESS;
3374	int			ub_ip_updated = FALSE;
3375
3376	/* Check handle. */
3377	ha = ql_fca_handle_to_state(fca_handle);
3378	if (ha == NULL) {
3379		QL_PRINT_2(CE_CONT, ": failed, no adapter=%ph\n",
3380		    (void *)fca_handle);
3381		return (FC_UNBOUND);
3382	}
3383	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3384
3385	/* Acquire adapter state lock. */
3386	ADAPTER_STATE_LOCK(ha);
3387	QL_UB_LOCK(ha);
3388
3389	/* Check all returned tokens. */
3390	for (index = 0; index < count; index++) {
3391		/* Check the token range. */
3392		if ((ub_array_index = tokens[index]) >= QL_UB_LIMIT) {
3393			EL(ha, "failed, FC_UB_BADTOKEN\n");
3394			rval = FC_UB_BADTOKEN;
3395			break;
3396		}
3397
3398		/* Check the unsolicited buffer array. */
3399		if (ha->ub_array[ub_array_index] == NULL) {
3400			EL(ha, "failed, FC_UB_BADTOKEN-2\n");
3401			rval = FC_UB_BADTOKEN;
3402			break;
3403		}
3404
3405		/* Check the state of the unsolicited buffer. */
3406		sp = ha->ub_array[ub_array_index]->ub_fca_private;
3407		if (sp->flags & SRB_UB_IN_FCA) {
3408			EL(ha, "failed, FC_UB_BADTOKEN-3\n");
3409			rval = FC_UB_BADTOKEN;
3410			break;
3411		}
3412	}
3413
3414	/* If all tokens checkout, release the buffers. */
3415	if (rval == FC_SUCCESS) {
3416		/* Check all returned tokens. */
3417		for (index = 0; index < count; index++) {
3418			fc_unsol_buf_t	*ubp;
3419
3420			ub_array_index = tokens[index];
3421			ubp = ha->ub_array[ub_array_index];
3422			sp = ubp->ub_fca_private;
3423
3424			ubp->ub_resp_flags = 0;
3425			sp->flags &= ~(SRB_UB_ACQUIRED | SRB_UB_CALLBACK);
3426			sp->flags |= SRB_UB_IN_FCA;
3427
3428			/* IP buffer. */
3429			if (sp->ub_type == FC_TYPE_IS8802_SNAP) {
3430				ub_ip_updated = TRUE;
3431			}
3432		}
3433	}
3434
3435	QL_UB_UNLOCK(ha);
3436	/* Release adapter state lock. */
3437	ADAPTER_STATE_UNLOCK(ha);
3438
3439	/*
3440	 * XXX: We should call ql_isp_rcvbuf() to return a
3441	 * buffer to ISP only if the number of buffers fall below
3442	 * the low water mark.
3443	 */
3444	if (ub_ip_updated) {
3445		ql_isp_rcvbuf(ha);
3446	}
3447
3448	if (rval != FC_SUCCESS) {
3449		EL(ha, "failed, rval = %xh\n", rval);
3450	} else {
3451		/*EMPTY*/
3452		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3453	}
3454	return (rval);
3455}
3456
3457/*
3458 * ql_abort
3459 *	Abort a packet.
3460 *
3461 * Input:
3462 *	fca_handle = handle setup by ql_bind_port().
3463 *	pkt = pointer to fc_packet.
3464 *	flags = KM_SLEEP flag.
3465 *
3466 * Returns:
3467 *	FC_SUCCESS - the packet has successfully aborted.
3468 *	FC_ABORTED - the packet has successfully aborted.
3469 *	FC_ABORTING - the packet is being aborted.
3470 *	FC_ABORT_FAILED - the packet could not be aborted.
3471 *	FC_TRANSPORT_ERROR - a transport error occurred while attempting
3472 *		to abort the packet.
3473 *	FC_BADEXCHANGE - no packet found.
3474 *	FC_UNBOUND - the fca_handle specified is not bound.
3475 *
3476 * Context:
3477 *	Kernel context.
3478 */
3479static int
3480ql_abort(opaque_t fca_handle, fc_packet_t *pkt, int flags)
3481{
3482	port_id_t		d_id;
3483	ql_link_t		*link;
3484	ql_adapter_state_t	*ha, *pha;
3485	ql_srb_t		*sp;
3486	ql_tgt_t		*tq;
3487	ql_lun_t		*lq;
3488	int			rval = FC_ABORTED;
3489
3490	ha = ql_fca_handle_to_state(fca_handle);
3491	if (ha == NULL) {
3492		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3493		    (void *)fca_handle);
3494		return (FC_UNBOUND);
3495	}
3496
3497	pha = ha->pha;
3498
3499	QL_PRINT_3(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
3500
3501	/* Get target queue pointer. */
3502	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
3503	tq = ql_d_id_to_queue(ha, d_id);
3504
3505	if ((tq == NULL) || (pha->task_daemon_flags & LOOP_DOWN)) {
3506		if (tq == NULL) {
3507			EL(ha, "failed, FC_TRANSPORT_ERROR\n");
3508			rval = FC_TRANSPORT_ERROR;
3509		} else {
3510			EL(ha, "failed, FC_OFFLINE\n");
3511			rval = FC_OFFLINE;
3512		}
3513		return (rval);
3514	}
3515
3516	sp = (ql_srb_t *)pkt->pkt_fca_private;
3517	lq = sp->lun_queue;
3518
3519	/* Set poll flag if sleep wanted. */
3520	if (flags == KM_SLEEP) {
3521		sp->flags |= SRB_POLL;
3522	}
3523
3524	/* Acquire target queue lock. */
3525	DEVICE_QUEUE_LOCK(tq);
3526	REQUEST_RING_LOCK(ha);
3527
3528	/* If command not already started. */
3529	if (!(sp->flags & SRB_ISP_STARTED)) {
3530		/* Check pending queue for command. */
3531		sp = NULL;
3532		for (link = pha->pending_cmds.first; link != NULL;
3533		    link = link->next) {
3534			sp = link->base_address;
3535			if (sp == (ql_srb_t *)pkt->pkt_fca_private) {
3536				/* Remove srb from q. */
3537				ql_remove_link(&pha->pending_cmds, &sp->cmd);
3538				break;
3539			} else {
3540				sp = NULL;
3541			}
3542		}
3543		REQUEST_RING_UNLOCK(ha);
3544
3545		if (sp == NULL) {
3546			/* Check for cmd on device queue. */
3547			for (link = lq->cmd.first; link != NULL;
3548			    link = link->next) {
3549				sp = link->base_address;
3550				if (sp == (ql_srb_t *)pkt->pkt_fca_private) {
3551					/* Remove srb from q. */
3552					ql_remove_link(&lq->cmd, &sp->cmd);
3553					break;
3554				} else {
3555					sp = NULL;
3556				}
3557			}
3558		}
3559		/* Release device lock */
3560		DEVICE_QUEUE_UNLOCK(tq);
3561
3562		/* If command on target queue. */
3563		if (sp != NULL) {
3564			sp->flags &= ~SRB_IN_DEVICE_QUEUE;
3565
3566			/* Set return status */
3567			pkt->pkt_reason = CS_ABORTED;
3568
3569			sp->cmd.next = NULL;
3570			ql_done(&sp->cmd);
3571			rval = FC_ABORTED;
3572		} else {
3573			EL(ha, "failed, FC_BADEXCHANGE\n");
3574			rval = FC_BADEXCHANGE;
3575		}
3576	} else if (sp->flags & SRB_ISP_COMPLETED) {
3577		/* Release device queue lock. */
3578		REQUEST_RING_UNLOCK(ha);
3579		DEVICE_QUEUE_UNLOCK(tq);
3580		EL(ha, "failed, already done, FC_FAILURE\n");
3581		rval = FC_FAILURE;
3582	} else if ((sp->pkt->pkt_cmd_fhdr.r_ctl == R_CTL_SOLICITED_DATA) ||
3583	    (sp->pkt->pkt_cmd_fhdr.r_ctl == R_CTL_STATUS)) {
3584		/*
3585		 * If here, target data/resp ctio is with Fw.
3586		 * Since firmware is supposed to terminate such I/Os
3587		 * with an error, we need not do any thing. If FW
3588		 * decides not to terminate those IOs and simply keep
3589		 * quite then we need to initiate cleanup here by
3590		 * calling ql_done.
3591		 */
3592		REQUEST_RING_UNLOCK(ha);
3593		DEVICE_QUEUE_UNLOCK(tq);
3594		rval = FC_ABORTED;
3595	} else {
3596		request_t	*ep = pha->request_ring_bp;
3597		uint16_t	cnt;
3598
3599		if (sp->handle != 0) {
3600			for (cnt = 0; cnt < REQUEST_ENTRY_CNT; cnt++) {
3601				if (sp->handle == ddi_get32(
3602				    pha->hba_buf.acc_handle, &ep->handle)) {
3603					ep->entry_type = INVALID_ENTRY_TYPE;
3604					break;
3605				}
3606				ep++;
3607			}
3608		}
3609
3610		/* Release device queue lock. */
3611		REQUEST_RING_UNLOCK(ha);
3612		DEVICE_QUEUE_UNLOCK(tq);
3613
3614		sp->flags |= SRB_ABORTING;
3615		(void) ql_abort_command(ha, sp);
3616		pkt->pkt_reason = CS_ABORTED;
3617		rval = FC_ABORTED;
3618	}
3619
3620	QL_PRINT_3(CE_CONT, "(%d,%d): done\n", ha->instance, ha->vp_index);
3621
3622	return (rval);
3623}
3624
3625/*
3626 * ql_reset
3627 *	Reset link or hardware.
3628 *
3629 * Input:
3630 *	fca_handle = handle setup by ql_bind_port().
3631 *	cmd = reset type command.
3632 *
3633 * Returns:
3634 *	FC_SUCCESS - reset has successfully finished.
3635 *	FC_UNBOUND - the fca_handle specified is not bound.
3636 *	FC_FAILURE - reset failed.
3637 *
3638 * Context:
3639 *	Kernel context.
3640 */
3641static int
3642ql_reset(opaque_t fca_handle, uint32_t cmd)
3643{
3644	ql_adapter_state_t	*ha;
3645	int			rval = FC_SUCCESS, rval2;
3646
3647	ha = ql_fca_handle_to_state(fca_handle);
3648	if (ha == NULL) {
3649		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
3650		    (void *)fca_handle);
3651		return (FC_UNBOUND);
3652	}
3653
3654	QL_PRINT_3(CE_CONT, "(%d,%d): started, cmd=%d\n", ha->instance,
3655	    ha->vp_index, cmd);
3656
3657	switch (cmd) {
3658	case FC_FCA_CORE:
3659		/* dump firmware core if specified. */
3660		if (ha->vp_index == 0) {
3661			if (ql_dump_firmware(ha) != QL_SUCCESS) {
3662				EL(ha, "failed, FC_FAILURE\n");
3663				rval = FC_FAILURE;
3664			}
3665		}
3666		break;
3667	case FC_FCA_LINK_RESET:
3668		if (!(ha->pha->task_daemon_flags & LOOP_DOWN)) {
3669			if (ql_loop_reset(ha) != QL_SUCCESS) {
3670				EL(ha, "failed, FC_FAILURE-2\n");
3671				rval = FC_FAILURE;
3672			}
3673		}
3674		break;
3675	case FC_FCA_RESET_CORE:
3676	case FC_FCA_RESET:
3677		/* if dump firmware core if specified. */
3678		if (cmd == FC_FCA_RESET_CORE) {
3679			if (ha->vp_index != 0) {
3680				rval2 = ha->pha->task_daemon_flags & LOOP_DOWN
3681				    ? QL_SUCCESS : ql_loop_reset(ha);
3682			} else {
3683				rval2 = ql_dump_firmware(ha);
3684			}
3685			if (rval2 != QL_SUCCESS) {
3686				EL(ha, "failed, FC_FAILURE-3\n");
3687				rval = FC_FAILURE;
3688			}
3689		}
3690
3691		/* Free up all unsolicited buffers. */
3692		if (ha->ub_allocated != 0) {
3693			/* Inform to release buffers. */
3694			ha->state = FC_PORT_SPEED_MASK(ha->state);
3695			ha->state |= FC_STATE_RESET_REQUESTED;
3696			if (ha->flags & FCA_BOUND) {
3697				(ha->bind_info.port_statec_cb)
3698				    (ha->bind_info.port_handle,
3699				    ha->state);
3700			}
3701		}
3702
3703		ha->state = FC_PORT_SPEED_MASK(ha->state);
3704
3705		/* All buffers freed */
3706		if (ha->ub_allocated == 0) {
3707			/* Hardware reset. */
3708			if (cmd == FC_FCA_RESET) {
3709				if (ha->vp_index == 0) {
3710					(void) ql_abort_isp(ha);
3711				} else if (!(ha->pha->task_daemon_flags &
3712				    LOOP_DOWN)) {
3713					(void) ql_loop_reset(ha);
3714				}
3715			}
3716
3717			/* Inform that the hardware has been reset */
3718			ha->state |= FC_STATE_RESET;
3719		} else {
3720			/*
3721			 * the port driver expects an online if
3722			 * buffers are not freed.
3723			 */
3724			if (ha->topology & QL_LOOP_CONNECTION) {
3725				ha->state |= FC_STATE_LOOP;
3726			} else {
3727				ha->state |= FC_STATE_ONLINE;
3728			}
3729		}
3730
3731		TASK_DAEMON_LOCK(ha);
3732		ha->task_daemon_flags |= FC_STATE_CHANGE;
3733		TASK_DAEMON_UNLOCK(ha);
3734
3735		ql_awaken_task_daemon(ha, NULL, FC_STATE_CHANGE, 0);
3736
3737		break;
3738	default:
3739		EL(ha, "unknown cmd=%xh\n", cmd);
3740		break;
3741	}
3742
3743	if (rval != FC_SUCCESS) {
3744		EL(ha, "cmd=%xh, failed=%xh\n", cmd, rval);
3745	} else {
3746		/*EMPTY*/
3747		QL_PRINT_3(CE_CONT, "(%d,%d): done\n", ha->instance,
3748		    ha->vp_index);
3749	}
3750
3751	return (rval);
3752}
3753
3754/*
3755 * ql_port_manage
3756 *	Perform port management or diagnostics.
3757 *
3758 * Input:
3759 *	fca_handle = handle setup by ql_bind_port().
3760 *	cmd = pointer to command structure.
3761 *
3762 * Returns:
3763 *	FC_SUCCESS - the request completed successfully.
3764 *	FC_FAILURE - the request did not complete successfully.
3765 *	FC_UNBOUND - the fca_handle specified is not bound.
3766 *
3767 * Context:
3768 *	Kernel context.
3769 */
3770static int
3771ql_port_manage(opaque_t fca_handle, fc_fca_pm_t *cmd)
3772{
3773	clock_t			timer;
3774	uint16_t		index;
3775	uint32_t		*bp;
3776	port_id_t		d_id;
3777	ql_link_t		*link;
3778	ql_adapter_state_t	*ha, *pha;
3779	ql_tgt_t		*tq;
3780	dma_mem_t		buffer_xmt, buffer_rcv;
3781	size_t			length;
3782	uint32_t		cnt;
3783	char			buf[80];
3784	lbp_t			*lb;
3785	ql_mbx_data_t		mr;
3786	app_mbx_cmd_t		*mcp;
3787	int			i0;
3788	uint8_t			*bptr;
3789	int			rval2, rval = FC_SUCCESS;
3790	uint32_t		opcode;
3791	uint32_t		set_flags = 0;
3792
3793	ha = ql_fca_handle_to_state(fca_handle);
3794	if (ha == NULL) {
3795		QL_PRINT_2(CE_CONT, ": failed, no adapter=%ph\n",
3796		    (void *)fca_handle);
3797		return (FC_UNBOUND);
3798	}
3799	pha = ha->pha;
3800
3801	QL_PRINT_3(CE_CONT, "(%d): started=%xh\n", ha->instance,
3802	    cmd->pm_cmd_code);
3803
3804	ql_awaken_task_daemon(ha, NULL, DRIVER_STALL, 0);
3805
3806	/*
3807	 * Wait for all outstanding commands to complete
3808	 */
3809	index = (uint16_t)ql_wait_outstanding(ha);
3810
3811	if (index != MAX_OUTSTANDING_COMMANDS) {
3812		ql_awaken_task_daemon(ha, NULL, 0, DRIVER_STALL);
3813		ql_restart_queues(ha);
3814		EL(ha, "failed, FC_TRAN_BUSY\n");
3815		return (FC_TRAN_BUSY);
3816	}
3817
3818	switch (cmd->pm_cmd_code) {
3819	case FC_PORT_BYPASS:
3820		d_id.b24 = *cmd->pm_cmd_buf;
3821		tq = ql_d_id_to_queue(ha, d_id);
3822		if (tq == NULL || ql_loop_port_bypass(ha, tq) != QL_SUCCESS) {
3823			EL(ha, "failed, FC_PORT_BYPASS FC_FAILURE\n");
3824			rval = FC_FAILURE;
3825		}
3826		break;
3827	case FC_PORT_UNBYPASS:
3828		d_id.b24 = *cmd->pm_cmd_buf;
3829		tq = ql_d_id_to_queue(ha, d_id);
3830		if (tq == NULL || ql_loop_port_enable(ha, tq) != QL_SUCCESS) {
3831			EL(ha, "failed, FC_PORT_UNBYPASS FC_FAILURE\n");
3832			rval = FC_FAILURE;
3833		}
3834		break;
3835	case FC_PORT_GET_FW_REV:
3836		(void) sprintf(buf, "%d.%d.%d", pha->fw_major_version,
3837		    pha->fw_minor_version, pha->fw_subminor_version);
3838		length = strlen(buf) + 1;
3839		if (cmd->pm_data_len < length) {
3840			cmd->pm_data_len = length;
3841			EL(ha, "failed, FC_PORT_GET_FW_REV FC_FAILURE\n");
3842			rval = FC_FAILURE;
3843		} else {
3844			(void) strcpy(cmd->pm_data_buf, buf);
3845		}
3846		break;
3847
3848	case FC_PORT_GET_FCODE_REV: {
3849		caddr_t		fcode_ver_buf = NULL;
3850
3851		i0 = 0;
3852		/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
3853		rval2 = ddi_getlongprop(DDI_DEV_T_ANY, ha->dip,
3854		    DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "version",
3855		    (caddr_t)&fcode_ver_buf, &i0);
3856		length = (uint_t)i0;
3857
3858		if (rval2 != DDI_PROP_SUCCESS) {
3859			EL(ha, "failed, getting version = %xh\n", rval2);
3860			length = 20;
3861			fcode_ver_buf = kmem_alloc(length, KM_SLEEP);
3862			if (fcode_ver_buf != NULL) {
3863				(void) sprintf(fcode_ver_buf,
3864				    "NO FCODE FOUND");
3865			}
3866		}
3867
3868		if (cmd->pm_data_len < length) {
3869			EL(ha, "length error, FC_PORT_GET_FCODE_REV "
3870			    "dst=%ld, src=%ld\n", cmd->pm_data_len, length);
3871			cmd->pm_data_len = length;
3872			rval = FC_FAILURE;
3873		} else if (fcode_ver_buf != NULL) {
3874			bcopy((void *)fcode_ver_buf, (void *)cmd->pm_data_buf,
3875			    length);
3876		}
3877
3878		if (fcode_ver_buf != NULL) {
3879			kmem_free(fcode_ver_buf, length);
3880		}
3881		break;
3882	}
3883
3884	case FC_PORT_GET_DUMP:
3885		QL_DUMP_LOCK(pha);
3886		if (cmd->pm_data_len < (size_t)pha->risc_dump_size) {
3887			EL(ha, "failed, FC_PORT_GET_DUMP incorrect "
3888			    "length=%lxh\n", cmd->pm_data_len);
3889			cmd->pm_data_len = pha->risc_dump_size;
3890			rval = FC_FAILURE;
3891		} else if (pha->ql_dump_state & QL_DUMPING) {
3892			EL(ha, "failed, FC_PORT_GET_DUMP FC_TRAN_BUSY\n");
3893			rval = FC_TRAN_BUSY;
3894		} else if (pha->ql_dump_state & QL_DUMP_VALID) {
3895			(void) ql_ascii_fw_dump(ha, cmd->pm_data_buf);
3896			pha->ql_dump_state |= QL_DUMP_UPLOADED;
3897		} else {
3898			EL(ha, "failed, FC_PORT_GET_DUMP no dump file\n");
3899			rval = FC_FAILURE;
3900		}
3901		QL_DUMP_UNLOCK(pha);
3902		break;
3903	case FC_PORT_FORCE_DUMP:
3904		PORTMANAGE_LOCK(ha);
3905		if (ql_dump_firmware(ha) != QL_SUCCESS) {
3906			EL(ha, "failed, FC_PORT_FORCE_DUMP FC_FAILURE\n");
3907			rval = FC_FAILURE;
3908		}
3909		PORTMANAGE_UNLOCK(ha);
3910		break;
3911	case FC_PORT_DOWNLOAD_FW:
3912		PORTMANAGE_LOCK(ha);
3913		if (CFG_IST(ha, CFG_CTRL_242581)) {
3914			if (ql_24xx_load_flash(ha, (uint8_t *)cmd->pm_data_buf,
3915			    (uint32_t)cmd->pm_data_len,
3916			    ha->flash_fw_addr << 2) != QL_SUCCESS) {
3917				EL(ha, "failed, FC_PORT_DOWNLOAD_FW\n");
3918				rval = FC_FAILURE;
3919			}
3920			ql_reset_chip(ha);
3921			set_flags |= ISP_ABORT_NEEDED;
3922		} else {
3923			/* Save copy of the firmware. */
3924			if (pha->risc_code != NULL) {
3925				kmem_free(pha->risc_code, pha->risc_code_size);
3926				pha->risc_code = NULL;
3927				pha->risc_code_size = 0;
3928			}
3929
3930			pha->risc_code = kmem_alloc(cmd->pm_data_len,
3931			    KM_SLEEP);
3932			if (pha->risc_code != NULL) {
3933				pha->risc_code_size =
3934				    (uint32_t)cmd->pm_data_len;
3935				bcopy(cmd->pm_data_buf, pha->risc_code,
3936				    cmd->pm_data_len);
3937
3938				/* Do abort to force reload. */
3939				ql_reset_chip(ha);
3940				if (ql_abort_isp(ha) != QL_SUCCESS) {
3941					kmem_free(pha->risc_code,
3942					    pha->risc_code_size);
3943					pha->risc_code = NULL;
3944					pha->risc_code_size = 0;
3945					ql_reset_chip(ha);
3946					(void) ql_abort_isp(ha);
3947					EL(ha, "failed, FC_PORT_DOWNLOAD_FW"
3948					    " FC_FAILURE\n");
3949					rval = FC_FAILURE;
3950				}
3951			}
3952		}
3953		PORTMANAGE_UNLOCK(ha);
3954		break;
3955	case FC_PORT_GET_DUMP_SIZE:
3956		bp = (uint32_t *)cmd->pm_data_buf;
3957		*bp = pha->risc_dump_size;
3958		break;
3959	case FC_PORT_DIAG:
3960		/*
3961		 * Prevents concurrent diags
3962		 */
3963		PORTMANAGE_LOCK(ha);
3964
3965		/* Wait for suspension to end. */
3966		for (timer = 0; timer < 3000 &&
3967		    pha->task_daemon_flags & QL_LOOP_TRANSITION; timer++) {
3968			ql_delay(ha, 10000);
3969		}
3970
3971		if (pha->task_daemon_flags & QL_LOOP_TRANSITION) {
3972			EL(ha, "failed, FC_TRAN_BUSY-2\n");
3973			rval = FC_TRAN_BUSY;
3974			PORTMANAGE_UNLOCK(ha);
3975			break;
3976		}
3977
3978		switch (cmd->pm_cmd_flags) {
3979		case QL_DIAG_EXEFMW:
3980			if (ql_start_firmware(ha) != QL_SUCCESS) {
3981				EL(ha, "failed, QL_DIAG_EXEFMW FC_FAILURE\n");
3982				rval = FC_FAILURE;
3983			}
3984			break;
3985		case QL_DIAG_CHKCMDQUE:
3986			for (i0 = 1, cnt = 0; i0 < MAX_OUTSTANDING_COMMANDS;
3987			    i0++) {
3988				cnt += (pha->outstanding_cmds[i0] != NULL);
3989			}
3990			if (cnt != 0) {
3991				EL(ha, "failed, QL_DIAG_CHKCMDQUE "
3992				    "FC_FAILURE\n");
3993				rval = FC_FAILURE;
3994			}
3995			break;
3996		case QL_DIAG_FMWCHKSUM:
3997			if (ql_verify_checksum(ha) != QL_SUCCESS) {
3998				EL(ha, "failed, QL_DIAG_FMWCHKSUM "
3999				    "FC_FAILURE\n");
4000				rval = FC_FAILURE;
4001			}
4002			break;
4003		case QL_DIAG_SLFTST:
4004			if (ql_online_selftest(ha) != QL_SUCCESS) {
4005				EL(ha, "failed, QL_DIAG_SLFTST FC_FAILURE\n");
4006				rval = FC_FAILURE;
4007			}
4008			ql_reset_chip(ha);
4009			set_flags |= ISP_ABORT_NEEDED;
4010			break;
4011		case QL_DIAG_REVLVL:
4012			if (cmd->pm_stat_len <
4013			    sizeof (ql_adapter_revlvl_t)) {
4014				EL(ha, "failed, QL_DIAG_REVLVL FC_NOMEM, "
4015				    "slen=%lxh, rlvllen=%lxh\n",
4016				    cmd->pm_stat_len,
4017				    sizeof (ql_adapter_revlvl_t));
4018				rval = FC_NOMEM;
4019			} else {
4020				bcopy((void *)&(pha->adapter_stats->revlvl),
4021				    cmd->pm_stat_buf,
4022				    (size_t)cmd->pm_stat_len);
4023				cmd->pm_stat_len =
4024				    sizeof (ql_adapter_revlvl_t);
4025			}
4026			break;
4027		case QL_DIAG_LPBMBX:
4028
4029			if (cmd->pm_data_len != sizeof (struct app_mbx_cmd)) {
4030				EL(ha, "failed, QL_DIAG_LPBMBX "
4031				    "FC_INVALID_REQUEST, pmlen=%lxh, "
4032				    "reqd=%lxh\n", cmd->pm_data_len,
4033				    sizeof (struct app_mbx_cmd));
4034				rval = FC_INVALID_REQUEST;
4035				break;
4036			}
4037			/*
4038			 * Don't do the wrap test on a 2200 when the
4039			 * firmware is running.
4040			 */
4041			if (!CFG_IST(ha, CFG_CTRL_2200)) {
4042				mcp = (app_mbx_cmd_t *)cmd->pm_data_buf;
4043				mr.mb[1] = mcp->mb[1];
4044				mr.mb[2] = mcp->mb[2];
4045				mr.mb[3] = mcp->mb[3];
4046				mr.mb[4] = mcp->mb[4];
4047				mr.mb[5] = mcp->mb[5];
4048				mr.mb[6] = mcp->mb[6];
4049				mr.mb[7] = mcp->mb[7];
4050
4051				bcopy(&mr.mb[0], &mr.mb[10],
4052				    sizeof (uint16_t) * 8);
4053
4054				if (ql_mbx_wrap_test(ha, &mr) != QL_SUCCESS) {
4055					EL(ha, "failed, QL_DIAG_LPBMBX "
4056					    "FC_FAILURE\n");
4057					rval = FC_FAILURE;
4058					break;
4059				} else {
4060					for (i0 = 1; i0 < 8; i0++) {
4061						if (mr.mb[i0] !=
4062						    mr.mb[i0 + 10]) {
4063							EL(ha, "failed, "
4064							    "QL_DIAG_LPBMBX "
4065							    "FC_FAILURE-2\n");
4066							rval = FC_FAILURE;
4067							break;
4068						}
4069					}
4070				}
4071
4072				if (rval == FC_FAILURE) {
4073					(void) ql_flash_errlog(ha,
4074					    FLASH_ERRLOG_ISP_ERR, 0,
4075					    RD16_IO_REG(ha, hccr),
4076					    RD16_IO_REG(ha, istatus));
4077					set_flags |= ISP_ABORT_NEEDED;
4078				}
4079			}
4080			break;
4081		case QL_DIAG_LPBDTA:
4082			/*
4083			 * For loopback data, we receive the
4084			 * data back in pm_stat_buf. This provides
4085			 * the user an opportunity to compare the
4086			 * transmitted and received data.
4087			 *
4088			 * NB: lb->options are:
4089			 *	0 --> Ten bit loopback
4090			 *	1 --> One bit loopback
4091			 *	2 --> External loopback
4092			 */
4093			if (cmd->pm_data_len > 65536) {
4094				rval = FC_TOOMANY;
4095				EL(ha, "failed, QL_DIAG_LPBDTA "
4096				    "FC_TOOMANY=%lxh\n", cmd->pm_data_len);
4097				break;
4098			}
4099			if (ql_get_dma_mem(ha, &buffer_xmt,
4100			    (uint32_t)cmd->pm_data_len, LITTLE_ENDIAN_DMA,
4101			    QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
4102				EL(ha, "failed, QL_DIAG_LPBDTA FC_NOMEM\n");
4103				rval = FC_NOMEM;
4104				break;
4105			}
4106			if (ql_get_dma_mem(ha, &buffer_rcv,
4107			    (uint32_t)cmd->pm_data_len, LITTLE_ENDIAN_DMA,
4108			    QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
4109				EL(ha, "failed, QL_DIAG_LPBDTA FC_NOMEM-2\n");
4110				rval = FC_NOMEM;
4111				break;
4112			}
4113			ddi_rep_put8(buffer_xmt.acc_handle,
4114			    (uint8_t *)cmd->pm_data_buf,
4115			    (uint8_t *)buffer_xmt.bp,
4116			    cmd->pm_data_len, DDI_DEV_AUTOINCR);
4117
4118			/* 22xx's adapter must be in loop mode for test. */
4119			if (CFG_IST(ha, CFG_CTRL_2200)) {
4120				bptr = &ha->init_ctrl_blk.cb.add_fw_opt[0];
4121				if (ha->flags & POINT_TO_POINT ||
4122				    (ha->task_daemon_flags & LOOP_DOWN &&
4123				    *bptr & (BIT_6 | BIT_5 | BIT_4))) {
4124					cnt = *bptr;
4125					*bptr = (uint8_t)
4126					    (*bptr & ~(BIT_6|BIT_5|BIT_4));
4127					(void) ql_abort_isp(ha);
4128					*bptr = (uint8_t)cnt;
4129				}
4130			}
4131
4132			/* Shutdown IP. */
4133			if (pha->flags & IP_INITIALIZED) {
4134				(void) ql_shutdown_ip(pha);
4135			}
4136
4137			lb = (lbp_t *)cmd->pm_cmd_buf;
4138			lb->transfer_count =
4139			    (uint32_t)cmd->pm_data_len;
4140			lb->transfer_segment_count = 0;
4141			lb->receive_segment_count = 0;
4142			lb->transfer_data_address =
4143			    buffer_xmt.cookie.dmac_address;
4144			lb->receive_data_address =
4145			    buffer_rcv.cookie.dmac_address;
4146
4147			if ((lb->options & 7) == 2 &&
4148			    pha->task_daemon_flags &
4149			    (QL_LOOP_TRANSITION | LOOP_DOWN)) {
4150				/* Loop must be up for external */
4151				EL(ha, "failed, QL_DIAG_LPBDTA FC_TRAN_BUSY\n");
4152				rval = FC_TRAN_BUSY;
4153			} else if (ql_loop_back(ha, 0, lb,
4154			    buffer_xmt.cookie.dmac_notused,
4155			    buffer_rcv.cookie.dmac_notused) == QL_SUCCESS) {
4156				bzero((void *)cmd->pm_stat_buf,
4157				    cmd->pm_stat_len);
4158				ddi_rep_get8(buffer_rcv.acc_handle,
4159				    (uint8_t *)cmd->pm_stat_buf,
4160				    (uint8_t *)buffer_rcv.bp,
4161				    cmd->pm_stat_len, DDI_DEV_AUTOINCR);
4162			} else {
4163				EL(ha, "failed, QL_DIAG_LPBDTA FC_FAILURE\n");
4164				rval = FC_FAILURE;
4165			}
4166
4167			ql_free_phys(ha, &buffer_xmt);
4168			ql_free_phys(ha, &buffer_rcv);
4169
4170			/* Needed to recover the f/w */
4171			set_flags |= ISP_ABORT_NEEDED;
4172
4173			/* Restart IP if it was shutdown. */
4174			if (pha->flags & IP_ENABLED &&
4175			    !(pha->flags & IP_INITIALIZED)) {
4176				(void) ql_initialize_ip(pha);
4177				ql_isp_rcvbuf(pha);
4178			}
4179
4180			break;
4181		case QL_DIAG_ECHO: {
4182			/*
4183			 * issue an echo command with a user supplied
4184			 * data pattern and destination address
4185			 */
4186			echo_t		echo;		/* temp echo struct */
4187
4188			/* Setup echo cmd & adjust for platform */
4189			opcode = QL_ECHO_CMD;
4190			BIG_ENDIAN_32(&opcode);
4191
4192			/*
4193			 * due to limitations in the ql
4194			 * firmaware the echo data field is
4195			 * limited to 220
4196			 */
4197			if ((cmd->pm_cmd_len > QL_ECHO_CMD_LENGTH) ||
4198			    (cmd->pm_stat_len > QL_ECHO_CMD_LENGTH)) {
4199				EL(ha, "failed, QL_DIAG_ECHO FC_TOOMANY, "
4200				    "cmdl1=%lxh, statl2=%lxh\n",
4201				    cmd->pm_cmd_len, cmd->pm_stat_len);
4202				rval = FC_TOOMANY;
4203				break;
4204			}
4205
4206			/*
4207			 * the input data buffer has the user
4208			 * supplied data pattern.  The "echoed"
4209			 * data will be DMAed into the output
4210			 * data buffer.  Therefore the length
4211			 * of the output buffer must be equal
4212			 * to or greater then the input buffer
4213			 * length
4214			 */
4215			if (cmd->pm_cmd_len > cmd->pm_stat_len) {
4216				EL(ha, "failed, QL_DIAG_ECHO FC_TOOMANY-2,"
4217				    " cmdl1=%lxh, statl2=%lxh\n",
4218				    cmd->pm_cmd_len, cmd->pm_stat_len);
4219				rval = FC_TOOMANY;
4220				break;
4221			}
4222			/* add four bytes for the opcode */
4223			echo.transfer_count = (uint32_t)(cmd->pm_cmd_len + 4);
4224
4225			/*
4226			 * are we 32 or 64 bit addressed???
4227			 * We need to get the appropriate
4228			 * DMA and set the command options;
4229			 * 64 bit (bit 6) or 32 bit
4230			 * (no bit 6) addressing.
4231			 * while we are at it lets ask for
4232			 * real echo (bit 15)
4233			 */
4234			echo.options = BIT_15;
4235			if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING) &&
4236			    !(CFG_IST(ha, CFG_CTRL_81XX))) {
4237				echo.options = (uint16_t)
4238				    (echo.options | BIT_6);
4239			}
4240
4241			/*
4242			 * Set up the DMA mappings for the
4243			 * output and input data buffers.
4244			 * First the output buffer
4245			 */
4246			if (ql_get_dma_mem(ha, &buffer_xmt,
4247			    (uint32_t)(cmd->pm_data_len + 4),
4248			    LITTLE_ENDIAN_DMA,
4249			    QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
4250				EL(ha, "failed, QL_DIAG_ECHO FC_NOMEM\n");
4251				rval = FC_NOMEM;
4252				break;
4253			}
4254			echo.transfer_data_address = buffer_xmt.cookie;
4255
4256			/* Next the input buffer */
4257			if (ql_get_dma_mem(ha, &buffer_rcv,
4258			    (uint32_t)(cmd->pm_data_len + 4),
4259			    LITTLE_ENDIAN_DMA,
4260			    QL_DMA_DATA_ALIGN) != QL_SUCCESS) {
4261				/*
4262				 * since we could not allocate
4263				 * DMA space for the input
4264				 * buffer we need to clean up
4265				 * by freeing the DMA space
4266				 * we allocated for the output
4267				 * buffer
4268				 */
4269				ql_free_phys(ha, &buffer_xmt);
4270				EL(ha, "failed, QL_DIAG_ECHO FC_NOMEM-2\n");
4271				rval = FC_NOMEM;
4272				break;
4273			}
4274			echo.receive_data_address = buffer_rcv.cookie;
4275
4276			/*
4277			 * copy the 4 byte ECHO op code to the
4278			 * allocated DMA space
4279			 */
4280			ddi_rep_put8(buffer_xmt.acc_handle, (uint8_t *)&opcode,
4281			    (uint8_t *)buffer_xmt.bp, 4, DDI_DEV_AUTOINCR);
4282
4283			/*
4284			 * copy the user supplied data to the
4285			 * allocated DMA space
4286			 */
4287			ddi_rep_put8(buffer_xmt.acc_handle,
4288			    (uint8_t *)cmd->pm_cmd_buf,
4289			    (uint8_t *)buffer_xmt.bp + 4, cmd->pm_cmd_len,
4290			    DDI_DEV_AUTOINCR);
4291
4292			/* Shutdown IP. */
4293			if (pha->flags & IP_INITIALIZED) {
4294				(void) ql_shutdown_ip(pha);
4295			}
4296
4297			/* send the echo */
4298			if (ql_echo(ha, 0, &echo) == QL_SUCCESS) {
4299				ddi_rep_put8(buffer_rcv.acc_handle,
4300				    (uint8_t *)buffer_rcv.bp + 4,
4301				    (uint8_t *)cmd->pm_stat_buf,
4302				    cmd->pm_stat_len, DDI_DEV_AUTOINCR);
4303			} else {
4304				EL(ha, "failed, QL_DIAG_ECHO FC_FAILURE\n");
4305				rval = FC_FAILURE;
4306			}
4307
4308			/* Restart IP if it was shutdown. */
4309			if (pha->flags & IP_ENABLED &&
4310			    !(pha->flags & IP_INITIALIZED)) {
4311				(void) ql_initialize_ip(pha);
4312				ql_isp_rcvbuf(pha);
4313			}
4314			/* free up our DMA buffers */
4315			ql_free_phys(ha, &buffer_xmt);
4316			ql_free_phys(ha, &buffer_rcv);
4317			break;
4318		}
4319		default:
4320			EL(ha, "unknown=%xh, FC_PORT_DIAG "
4321			    "FC_INVALID_REQUEST\n", cmd->pm_cmd_flags);
4322			rval = FC_INVALID_REQUEST;
4323			break;
4324		}
4325		PORTMANAGE_UNLOCK(ha);
4326		break;
4327	case FC_PORT_LINK_STATE:
4328		/* Check for name equal to null. */
4329		for (index = 0; index < 8 && index < cmd->pm_cmd_len;
4330		    index++) {
4331			if (cmd->pm_cmd_buf[index] != 0) {
4332				break;
4333			}
4334		}
4335
4336		/* If name not null. */
4337		if (index < 8 && cmd->pm_cmd_len >= 8) {
4338			/* Locate device queue. */
4339			tq = NULL;
4340			for (index = 0; index < DEVICE_HEAD_LIST_SIZE &&
4341			    tq == NULL; index++) {
4342				for (link = ha->dev[index].first; link != NULL;
4343				    link = link->next) {
4344					tq = link->base_address;
4345
4346					if (bcmp((void *)&tq->port_name[0],
4347					    (void *)cmd->pm_cmd_buf, 8) == 0) {
4348						break;
4349					} else {
4350						tq = NULL;
4351					}
4352				}
4353			}
4354
4355			if (tq != NULL && VALID_DEVICE_ID(ha, tq->loop_id)) {
4356				cmd->pm_stat_buf[0] = (int8_t)LSB(ha->state);
4357				cmd->pm_stat_buf[1] = (int8_t)MSB(ha->state);
4358			} else {
4359				cnt = FC_PORT_SPEED_MASK(ha->state) |
4360				    FC_STATE_OFFLINE;
4361				cmd->pm_stat_buf[0] = (int8_t)LSB(cnt);
4362				cmd->pm_stat_buf[1] = (int8_t)MSB(cnt);
4363			}
4364		} else {
4365			cmd->pm_stat_buf[0] = (int8_t)LSB(ha->state);
4366			cmd->pm_stat_buf[1] = (int8_t)MSB(ha->state);
4367		}
4368		break;
4369	case FC_PORT_INITIALIZE:
4370		if (cmd->pm_cmd_len >= 8) {
4371			tq = NULL;
4372			for (index = 0; index < DEVICE_HEAD_LIST_SIZE &&
4373			    tq == NULL; index++) {
4374				for (link = ha->dev[index].first; link != NULL;
4375				    link = link->next) {
4376					tq = link->base_address;
4377
4378					if (bcmp((void *)&tq->port_name[0],
4379					    (void *)cmd->pm_cmd_buf, 8) == 0) {
4380						if (!VALID_DEVICE_ID(ha,
4381						    tq->loop_id)) {
4382							tq = NULL;
4383						}
4384						break;
4385					} else {
4386						tq = NULL;
4387					}
4388				}
4389			}
4390
4391			if (tq == NULL || ql_target_reset(ha, tq,
4392			    ha->loop_reset_delay) != QL_SUCCESS) {
4393				EL(ha, "failed, FC_PORT_INITIALIZE "
4394				    "FC_FAILURE\n");
4395				rval = FC_FAILURE;
4396			}
4397		} else {
4398			EL(ha, "failed, FC_PORT_INITIALIZE FC_FAILURE-2, "
4399			    "clen=%lxh\n", cmd->pm_cmd_len);
4400
4401			rval = FC_FAILURE;
4402		}
4403		break;
4404	case FC_PORT_RLS:
4405		if (cmd->pm_data_len < sizeof (fc_rls_acc_t)) {
4406			EL(ha, "failed, buffer size passed: %lxh, "
4407			    "req: %lxh\n", cmd->pm_data_len,
4408			    (sizeof (fc_rls_acc_t)));
4409			rval = FC_FAILURE;
4410		} else if (LOOP_NOT_READY(pha)) {
4411			EL(ha, "loop NOT ready\n");
4412			bzero(cmd->pm_data_buf, cmd->pm_data_len);
4413		} else if (ql_get_link_status(ha, ha->loop_id,
4414		    cmd->pm_data_len, cmd->pm_data_buf, 0) != QL_SUCCESS) {
4415			EL(ha, "failed, FC_PORT_RLS FC_FAILURE\n");
4416			rval = FC_FAILURE;
4417#ifdef _BIG_ENDIAN
4418		} else {
4419			fc_rls_acc_t		*rls;
4420
4421			rls = (fc_rls_acc_t *)cmd->pm_data_buf;
4422			LITTLE_ENDIAN_32(&rls->rls_link_fail);
4423			LITTLE_ENDIAN_32(&rls->rls_sync_loss);
4424			LITTLE_ENDIAN_32(&rls->rls_sig_loss);
4425			LITTLE_ENDIAN_32(&rls->rls_invalid_crc);
4426#endif /* _BIG_ENDIAN */
4427		}
4428		break;
4429	case FC_PORT_GET_NODE_ID:
4430		if (ql_get_rnid_params(ha, cmd->pm_data_len,
4431		    cmd->pm_data_buf) != QL_SUCCESS) {
4432			EL(ha, "failed, FC_PORT_GET_NODE_ID FC_FAILURE\n");
4433			rval = FC_FAILURE;
4434		}
4435		break;
4436	case FC_PORT_SET_NODE_ID:
4437		if (ql_set_rnid_params(ha, cmd->pm_data_len,
4438		    cmd->pm_data_buf) != QL_SUCCESS) {
4439			EL(ha, "failed, FC_PORT_SET_NODE_ID FC_FAILURE\n");
4440			rval = FC_FAILURE;
4441		}
4442		break;
4443	case FC_PORT_DOWNLOAD_FCODE:
4444		PORTMANAGE_LOCK(ha);
4445		if ((CFG_IST(ha, CFG_CTRL_242581)) == 0) {
4446			rval = ql_load_flash(ha, (uint8_t *)cmd->pm_data_buf,
4447			    (uint32_t)cmd->pm_data_len);
4448		} else {
4449			if (cmd->pm_data_buf[0] == 4 &&
4450			    cmd->pm_data_buf[8] == 0 &&
4451			    cmd->pm_data_buf[9] == 0x10 &&
4452			    cmd->pm_data_buf[10] == 0 &&
4453			    cmd->pm_data_buf[11] == 0) {
4454				rval = ql_24xx_load_flash(ha,
4455				    (uint8_t *)cmd->pm_data_buf,
4456				    (uint32_t)cmd->pm_data_len,
4457				    ha->flash_fw_addr << 2);
4458			} else {
4459				rval = ql_24xx_load_flash(ha,
4460				    (uint8_t *)cmd->pm_data_buf,
4461				    (uint32_t)cmd->pm_data_len, 0);
4462			}
4463		}
4464
4465		if (rval != QL_SUCCESS) {
4466			EL(ha, "failed, FC_PORT_DOWNLOAD_FCODE FC_FAILURE\n");
4467			rval = FC_FAILURE;
4468		} else {
4469			rval = FC_SUCCESS;
4470		}
4471		ql_reset_chip(ha);
4472		set_flags |= ISP_ABORT_NEEDED;
4473		PORTMANAGE_UNLOCK(ha);
4474		break;
4475	default:
4476		EL(ha, "unknown=%xh, FC_BADCMD\n", cmd->pm_cmd_code);
4477		rval = FC_BADCMD;
4478		break;
4479	}
4480
4481	/* Wait for suspension to end. */
4482	ql_awaken_task_daemon(ha, NULL, set_flags, DRIVER_STALL);
4483	timer = 0;
4484
4485	while (timer++ < 3000 &&
4486	    ha->task_daemon_flags & (QL_LOOP_TRANSITION | DRIVER_STALL)) {
4487		ql_delay(ha, 10000);
4488	}
4489
4490	ql_restart_queues(ha);
4491
4492	if (rval != FC_SUCCESS) {
4493		EL(ha, "failed, rval = %xh\n", rval);
4494	} else {
4495		/*EMPTY*/
4496		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4497	}
4498
4499	return (rval);
4500}
4501
4502static opaque_t
4503ql_get_device(opaque_t fca_handle, fc_portid_t d_id)
4504{
4505	port_id_t		id;
4506	ql_adapter_state_t	*ha;
4507	ql_tgt_t		*tq;
4508
4509	id.r.rsvd_1 = 0;
4510	id.b24 = d_id.port_id;
4511
4512	ha = ql_fca_handle_to_state(fca_handle);
4513	if (ha == NULL) {
4514		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
4515		    (void *)fca_handle);
4516		return (NULL);
4517	}
4518	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance, id.b24);
4519
4520	tq = ql_d_id_to_queue(ha, id);
4521
4522	if (tq == NULL) {
4523		EL(ha, "failed, tq=NULL\n");
4524	} else {
4525		/*EMPTY*/
4526		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4527	}
4528	return (tq);
4529}
4530
4531/* ************************************************************************ */
4532/*			FCA Driver Local Support Functions.		    */
4533/* ************************************************************************ */
4534
4535/*
4536 * ql_cmd_setup
4537 *	Verifies proper command.
4538 *
4539 * Input:
4540 *	fca_handle = handle setup by ql_bind_port().
4541 *	pkt = pointer to fc_packet.
4542 *	rval = pointer for return value.
4543 *
4544 * Returns:
4545 *	Adapter state pointer, NULL = failure.
4546 *
4547 * Context:
4548 *	Kernel context.
4549 */
4550static ql_adapter_state_t *
4551ql_cmd_setup(opaque_t fca_handle, fc_packet_t *pkt, int *rval)
4552{
4553	ql_adapter_state_t	*ha, *pha;
4554	ql_srb_t		*sp = (ql_srb_t *)pkt->pkt_fca_private;
4555	ql_tgt_t		*tq;
4556	port_id_t		d_id;
4557
4558	pkt->pkt_resp_resid = 0;
4559	pkt->pkt_data_resid = 0;
4560
4561	/* check that the handle is assigned by this FCA */
4562	ha = ql_fca_handle_to_state(fca_handle);
4563	if (ha == NULL) {
4564		*rval = FC_UNBOUND;
4565		QL_PRINT_2(CE_CONT, "failed, no adapter=%ph\n",
4566		    (void *)fca_handle);
4567		return (NULL);
4568	}
4569	pha = ha->pha;
4570
4571	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4572
4573	if (ddi_in_panic() || pkt->pkt_tran_flags & FC_TRAN_DUMPING) {
4574		return (ha);
4575	}
4576
4577	if (!(pha->flags & ONLINE)) {
4578		pkt->pkt_state = FC_PKT_LOCAL_RJT;
4579		pkt->pkt_reason = FC_REASON_HW_ERROR;
4580		*rval = FC_TRANSPORT_ERROR;
4581		EL(ha, "failed, not online hf=%xh\n", pha->flags);
4582		return (NULL);
4583	}
4584
4585	/* Exit on loop down. */
4586	if (CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING) &&
4587	    pha->task_daemon_flags & LOOP_DOWN &&
4588	    pha->loop_down_timer <= pha->loop_down_abort_time) {
4589		pkt->pkt_state = FC_PKT_PORT_OFFLINE;
4590		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
4591		*rval = FC_OFFLINE;
4592		EL(ha, "failed, loop down tdf=%xh\n", pha->task_daemon_flags);
4593		return (NULL);
4594	}
4595
4596	if (pkt->pkt_cmd_fhdr.r_ctl == R_CTL_COMMAND &&
4597	    pkt->pkt_cmd_fhdr.type == FC_TYPE_SCSI_FCP) {
4598		tq = (ql_tgt_t *)pkt->pkt_fca_device;
4599		if ((tq == NULL) || (!VALID_DEVICE_ID(ha, tq->loop_id))) {
4600			d_id.r.rsvd_1 = 0;
4601			d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
4602			tq = ql_d_id_to_queue(ha, d_id);
4603
4604			pkt->pkt_fca_device = (opaque_t)tq;
4605		}
4606
4607		if (tq != NULL) {
4608			DEVICE_QUEUE_LOCK(tq);
4609			if (tq->flags & (TQF_RSCN_RCVD |
4610			    TQF_NEED_AUTHENTICATION)) {
4611				*rval = FC_DEVICE_BUSY;
4612				DEVICE_QUEUE_UNLOCK(tq);
4613				EL(ha, "failed, busy qf=%xh, d_id=%xh\n",
4614				    tq->flags, tq->d_id.b24);
4615				return (NULL);
4616			}
4617			DEVICE_QUEUE_UNLOCK(tq);
4618		}
4619	}
4620
4621	/*
4622	 * Check DMA pointers.
4623	 */
4624	*rval = DDI_SUCCESS;
4625	if (pkt->pkt_cmd_acc != NULL && pkt->pkt_cmdlen) {
4626		QL_CLEAR_DMA_HANDLE(pkt->pkt_cmd_dma);
4627		*rval = ddi_check_dma_handle(pkt->pkt_cmd_dma);
4628		if (*rval == DDI_SUCCESS) {
4629			*rval = ddi_check_acc_handle(pkt->pkt_cmd_acc);
4630		}
4631	}
4632
4633	if (pkt->pkt_resp_acc != NULL && *rval == DDI_SUCCESS &&
4634	    pkt->pkt_rsplen != 0) {
4635		QL_CLEAR_DMA_HANDLE(pkt->pkt_resp_dma);
4636		*rval = ddi_check_dma_handle(pkt->pkt_resp_dma);
4637		if (*rval == DDI_SUCCESS) {
4638			*rval = ddi_check_acc_handle(pkt->pkt_resp_acc);
4639		}
4640	}
4641
4642	/*
4643	 * Minimum branch conditional; Change it with care.
4644	 */
4645	if (((pkt->pkt_data_acc != NULL) & (*rval == DDI_SUCCESS) &
4646	    (pkt->pkt_datalen != 0)) != 0) {
4647		QL_CLEAR_DMA_HANDLE(pkt->pkt_data_dma);
4648		*rval = ddi_check_dma_handle(pkt->pkt_data_dma);
4649		if (*rval == DDI_SUCCESS) {
4650			*rval = ddi_check_acc_handle(pkt->pkt_data_acc);
4651		}
4652	}
4653
4654	if (*rval != DDI_SUCCESS) {
4655		pkt->pkt_state = FC_PKT_TRAN_ERROR;
4656		pkt->pkt_reason = FC_REASON_DMA_ERROR;
4657
4658		/* Do command callback. */
4659		if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
4660			ql_awaken_task_daemon(ha, sp, 0, 0);
4661		}
4662		*rval = FC_BADPACKET;
4663		EL(ha, "failed, bad DMA pointers\n");
4664		return (NULL);
4665	}
4666
4667	if (sp->magic_number != QL_FCA_BRAND) {
4668		*rval = FC_BADPACKET;
4669		EL(ha, "failed, magic number=%xh\n", sp->magic_number);
4670		return (NULL);
4671	}
4672	*rval = FC_SUCCESS;
4673
4674	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4675
4676	return (ha);
4677}
4678
4679/*
4680 * ql_els_plogi
4681 *	Issue a extended link service port login request.
4682 *
4683 * Input:
4684 *	ha = adapter state pointer.
4685 *	pkt = pointer to fc_packet.
4686 *
4687 * Returns:
4688 *	FC_SUCCESS - the packet was accepted for transport.
4689 *	FC_TRANSPORT_ERROR - a transport error occurred.
4690 *
4691 * Context:
4692 *	Kernel context.
4693 */
4694static int
4695ql_els_plogi(ql_adapter_state_t *ha, fc_packet_t *pkt)
4696{
4697	ql_tgt_t		*tq = NULL;
4698	port_id_t		d_id;
4699	la_els_logi_t		acc;
4700	class_svc_param_t	*class3_param;
4701	int			ret;
4702	int			rval = FC_SUCCESS;
4703
4704	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
4705	    pkt->pkt_cmd_fhdr.d_id);
4706
4707	TASK_DAEMON_LOCK(ha);
4708	if (!(ha->task_daemon_flags & STATE_ONLINE)) {
4709		TASK_DAEMON_UNLOCK(ha);
4710		QL_PRINT_3(CE_CONT, "(%d): offline done\n", ha->instance);
4711		return (FC_OFFLINE);
4712	}
4713	TASK_DAEMON_UNLOCK(ha);
4714
4715	bzero(&acc, sizeof (acc));
4716	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
4717
4718	ret = QL_SUCCESS;
4719
4720	if (CFG_IST(ha, CFG_CTRL_2425) && ha->topology & QL_N_PORT) {
4721		/*
4722		 * In p2p topology he sends a PLOGI after determining
4723		 * he has the N_Port login initiative.
4724		 */
4725		ret = ql_p2p_plogi(ha, pkt);
4726	}
4727	if (ret == QL_CONSUMED) {
4728		return (ret);
4729	}
4730
4731	switch (ret = ql_login_port(ha, d_id)) {
4732	case QL_SUCCESS:
4733		tq = ql_d_id_to_queue(ha, d_id);
4734		break;
4735
4736	case QL_LOOP_ID_USED:
4737		if ((ret = ql_login_port(ha, d_id)) == QL_SUCCESS) {
4738			tq = ql_d_id_to_queue(ha, d_id);
4739		}
4740		break;
4741
4742	default:
4743		break;
4744	}
4745
4746	if (ret != QL_SUCCESS) {
4747		/*
4748		 * Invalidate this entry so as to seek a fresh loop ID
4749		 * in case firmware reassigns it to something else
4750		 */
4751		tq = ql_d_id_to_queue(ha, d_id);
4752		if (tq && (ret != QL_MEMORY_ALLOC_FAILED)) {
4753			tq->loop_id = PORT_NO_LOOP_ID;
4754		}
4755	} else if (tq) {
4756		(void) ql_get_port_database(ha, tq, PDF_ADISC);
4757	}
4758
4759	if (tq != NULL && VALID_DEVICE_ID(ha, tq->loop_id) &&
4760	    (ret != QL_MEMORY_ALLOC_FAILED) && PD_PORT_LOGIN(tq)) {
4761
4762		/* Build ACC. */
4763		acc.ls_code.ls_code = LA_ELS_ACC;
4764		acc.common_service.fcph_version = 0x2006;
4765		acc.common_service.cmn_features = 0x8800;
4766		CFG_IST(ha, CFG_CTRL_242581) ?
4767		    (acc.common_service.rx_bufsize = CHAR_TO_SHORT(
4768		    ha->init_ctrl_blk.cb24.max_frame_length[0],
4769		    ha->init_ctrl_blk.cb24.max_frame_length[1])) :
4770		    (acc.common_service.rx_bufsize = CHAR_TO_SHORT(
4771		    ha->init_ctrl_blk.cb.max_frame_length[0],
4772		    ha->init_ctrl_blk.cb.max_frame_length[1]));
4773		acc.common_service.conc_sequences = 0xff;
4774		acc.common_service.relative_offset = 0x03;
4775		acc.common_service.e_d_tov = 0x7d0;
4776
4777		bcopy((void *)&tq->port_name[0],
4778		    (void *)&acc.nport_ww_name.raw_wwn[0], 8);
4779		bcopy((void *)&tq->node_name[0],
4780		    (void *)&acc.node_ww_name.raw_wwn[0], 8);
4781
4782		class3_param = (class_svc_param_t *)&acc.class_3;
4783		class3_param->class_valid_svc_opt = 0x8000;
4784		class3_param->recipient_ctl = tq->class3_recipient_ctl;
4785		class3_param->rcv_data_size = tq->class3_rcv_data_size;
4786		class3_param->conc_sequences = tq->class3_conc_sequences;
4787		class3_param->open_sequences_per_exch =
4788		    tq->class3_open_sequences_per_exch;
4789
4790		if ((ql_busy_plogi(ha, pkt, tq) == FC_TRAN_BUSY)) {
4791			acc.ls_code.ls_code = LA_ELS_RJT;
4792			pkt->pkt_state = FC_PKT_TRAN_BSY;
4793			pkt->pkt_reason = FC_REASON_XCHG_BSY;
4794			EL(ha, "LA_ELS_RJT, FC_REASON_XCHG_BSY\n");
4795			rval = FC_TRAN_BUSY;
4796		} else {
4797			DEVICE_QUEUE_LOCK(tq);
4798			tq->logout_sent = 0;
4799			tq->flags &= ~TQF_NEED_AUTHENTICATION;
4800			if (CFG_IST(ha, CFG_CTRL_242581)) {
4801				tq->flags |= TQF_IIDMA_NEEDED;
4802			}
4803			DEVICE_QUEUE_UNLOCK(tq);
4804
4805			if (CFG_IST(ha, CFG_CTRL_242581)) {
4806				TASK_DAEMON_LOCK(ha);
4807				ha->task_daemon_flags |= TD_IIDMA_NEEDED;
4808				TASK_DAEMON_UNLOCK(ha);
4809			}
4810
4811			pkt->pkt_state = FC_PKT_SUCCESS;
4812		}
4813	} else {
4814		/* Build RJT. */
4815		acc.ls_code.ls_code = LA_ELS_RJT;
4816
4817		switch (ret) {
4818		case QL_FUNCTION_TIMEOUT:
4819			pkt->pkt_state = FC_PKT_TIMEOUT;
4820			pkt->pkt_reason = FC_REASON_HW_ERROR;
4821			break;
4822
4823		case QL_MEMORY_ALLOC_FAILED:
4824			pkt->pkt_state = FC_PKT_LOCAL_BSY;
4825			pkt->pkt_reason = FC_REASON_NOMEM;
4826			rval = FC_TRAN_BUSY;
4827			break;
4828
4829		case QL_FABRIC_NOT_INITIALIZED:
4830			pkt->pkt_state = FC_PKT_FABRIC_BSY;
4831			pkt->pkt_reason = FC_REASON_NO_CONNECTION;
4832			rval = FC_TRAN_BUSY;
4833			break;
4834
4835		default:
4836			pkt->pkt_state = FC_PKT_TRAN_ERROR;
4837			pkt->pkt_reason = FC_REASON_NO_CONNECTION;
4838			break;
4839		}
4840
4841		EL(ha, "Plogi unsuccess for %xh state %xh reason %xh "
4842		    "ret %xh rval %xh\n", d_id.b24, pkt->pkt_state,
4843		    pkt->pkt_reason, ret, rval);
4844	}
4845
4846	if (tq != NULL) {
4847		DEVICE_QUEUE_LOCK(tq);
4848		tq->flags &= ~(TQF_PLOGI_PROGRS | TQF_QUEUE_SUSPENDED);
4849		if (rval == FC_TRAN_BUSY) {
4850			if (tq->d_id.b24 != BROADCAST_ADDR) {
4851				tq->flags |= TQF_NEED_AUTHENTICATION;
4852			}
4853		}
4854		DEVICE_QUEUE_UNLOCK(tq);
4855	}
4856
4857	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
4858	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
4859
4860	if (rval != FC_SUCCESS) {
4861		EL(ha, "failed, rval = %xh\n", rval);
4862	} else {
4863		/*EMPTY*/
4864		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4865	}
4866	return (rval);
4867}
4868
4869/*
4870 * ql_p2p_plogi
4871 *	Start an extended link service port login request using
4872 *	an ELS Passthru iocb.
4873 *
4874 * Input:
4875 *	ha = adapter state pointer.
4876 *	pkt = pointer to fc_packet.
4877 *
4878 * Returns:
4879 *	QL_CONSUMMED - the iocb was queued for transport.
4880 *
4881 * Context:
4882 *	Kernel context.
4883 */
4884static int
4885ql_p2p_plogi(ql_adapter_state_t *ha, fc_packet_t *pkt)
4886{
4887	uint16_t	id;
4888	ql_tgt_t	tmp;
4889	ql_tgt_t	*tq = &tmp;
4890	int		rval;
4891
4892	tq->d_id.b.al_pa = 0;
4893	tq->d_id.b.area = 0;
4894	tq->d_id.b.domain = 0;
4895
4896	/*
4897	 * Verify that the port database hasn't moved beneath our feet by
4898	 * switching to the appropriate n_port_handle if necessary.  This is
4899	 * less unplesant than the error recovery if the wrong one is used.
4900	 */
4901	for (id = 0; id <= LAST_LOCAL_LOOP_ID; id++) {
4902		tq->loop_id = id;
4903		rval = ql_get_port_database(ha, tq, PDF_NONE);
4904		EL(ha, "rval=%xh\n", rval);
4905		/* check all the ones not logged in for possible use */
4906		if (rval == QL_NOT_LOGGED_IN) {
4907			if (tq->master_state == PD_STATE_PLOGI_PENDING) {
4908				ha->n_port->n_port_handle = tq->loop_id;
4909				EL(ha, "n_port_handle =%xh, master state=%x\n",
4910				    tq->loop_id, tq->master_state);
4911				break;
4912			}
4913			/*
4914			 * Use a 'port unavailable' entry only
4915			 * if we used it before.
4916			 */
4917			if (tq->master_state == PD_STATE_PORT_UNAVAILABLE) {
4918				/* if the port_id matches, reuse it */
4919				if (pkt->pkt_cmd_fhdr.d_id == tq->d_id.b24) {
4920					EL(ha, "n_port_handle =%xh,"
4921					    "master state=%xh\n",
4922					    tq->loop_id, tq->master_state);
4923					break;
4924				} else if (tq->loop_id ==
4925				    ha->n_port->n_port_handle) {
4926				    // avoid a lint error
4927					uint16_t *hndl;
4928					uint16_t val;
4929
4930					hndl = &ha->n_port->n_port_handle;
4931					val = *hndl;
4932					val++;
4933					val++;
4934					*hndl = val;
4935				}
4936			EL(ha, "rval=%xh, id=%d, n_port_handle =%xh, "
4937			    "master state=%x\n", rval, id, tq->loop_id,
4938			    tq->master_state);
4939			}
4940
4941		}
4942		if (rval == QL_SUCCESS) {
4943			if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) {
4944				ha->n_port->n_port_handle = tq->loop_id;
4945				EL(ha, "n_port_handle =%xh, master state=%x\n",
4946				    tq->loop_id, tq->master_state);
4947				break;
4948			}
4949			EL(ha, "rval=%xh, id=%d, n_port_handle =%xh, "
4950			    "master state=%x\n", rval, id, tq->loop_id,
4951			    tq->master_state);
4952		}
4953	}
4954	(void) ddi_dma_sync(pkt->pkt_cmd_dma, 0, 0, DDI_DMA_SYNC_FORDEV);
4955
4956	ql_start_iocb(ha, (ql_srb_t *)pkt->pkt_fca_private);
4957
4958	return (QL_CONSUMED);
4959}
4960
4961
4962/*
4963 * ql_els_flogi
4964 *	Issue a extended link service fabric login request.
4965 *
4966 * Input:
4967 *	ha = adapter state pointer.
4968 *	pkt = pointer to fc_packet.
4969 *
4970 * Returns:
4971 *	FC_SUCCESS - the packet was accepted for transport.
4972 *	FC_TRANSPORT_ERROR - a transport error occurred.
4973 *
4974 * Context:
4975 *	Kernel context.
4976 */
4977static int
4978ql_els_flogi(ql_adapter_state_t *ha, fc_packet_t *pkt)
4979{
4980	ql_tgt_t		*tq = NULL;
4981	port_id_t		d_id;
4982	la_els_logi_t		acc;
4983	class_svc_param_t	*class3_param;
4984	int			rval = FC_SUCCESS;
4985	int			accept = 0;
4986
4987	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
4988	    pkt->pkt_cmd_fhdr.d_id);
4989
4990	bzero(&acc, sizeof (acc));
4991	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
4992
4993	if (CFG_IST(ha, CFG_CTRL_2425) && ha->topology & QL_N_PORT) {
4994		/*
4995		 * d_id of zero in a FLOGI accept response in a point to point
4996		 * topology triggers evaluation of N Port login initiative.
4997		 */
4998		pkt->pkt_resp_fhdr.d_id = 0;
4999		/*
5000		 * An N_Port already logged in with the firmware
5001		 * will have the only database entry.
5002		 */
5003		if (LOCAL_LOOP_ID(ha->n_port->n_port_handle)) {
5004			tq = ql_loop_id_to_queue(ha, ha->n_port->n_port_handle);
5005		}
5006
5007		if (tq != NULL) {
5008			/*
5009			 * If the target port has initiative send
5010			 * up a PLOGI about the new device.
5011			 */
5012			if ((ql_wwn_cmp(ha, (la_wwn_t *)&tq->port_name[0],
5013			    (la_wwn_t *)(CFG_IST(ha, CFG_CTRL_2425) ?
5014			    &ha->init_ctrl_blk.cb24.port_name[0] :
5015			    &ha->init_ctrl_blk.cb.port_name[0])) == 1)) {
5016				ha->send_plogi_timer = 3;
5017			} else {
5018				ha->send_plogi_timer = 0;
5019			}
5020			pkt->pkt_resp_fhdr.s_id = tq->d_id.b24;
5021		} else {
5022			/*
5023			 * An N_Port not logged in with the firmware will not
5024			 * have a database entry.  We accept anyway and rely
5025			 * on a PLOGI from the upper layers to set the d_id
5026			 * and s_id.
5027			 */
5028			accept = 1;
5029		}
5030	} else {
5031		tq = ql_d_id_to_queue(ha, d_id);
5032	}
5033	if ((tq != NULL) || (accept != NULL)) {
5034		/* Build ACC. */
5035		pkt->pkt_state = FC_PKT_SUCCESS;
5036		class3_param = (class_svc_param_t *)&acc.class_3;
5037
5038		acc.ls_code.ls_code = LA_ELS_ACC;
5039		acc.common_service.fcph_version = 0x2006;
5040		if (ha->topology & QL_N_PORT) {
5041			/* clear F_Port indicator */
5042			acc.common_service.cmn_features = 0x0800;
5043		} else {
5044			acc.common_service.cmn_features = 0x1b00;
5045		}
5046		CFG_IST(ha, CFG_CTRL_242581) ?
5047		    (acc.common_service.rx_bufsize = CHAR_TO_SHORT(
5048		    ha->init_ctrl_blk.cb24.max_frame_length[0],
5049		    ha->init_ctrl_blk.cb24.max_frame_length[1])) :
5050		    (acc.common_service.rx_bufsize = CHAR_TO_SHORT(
5051		    ha->init_ctrl_blk.cb.max_frame_length[0],
5052		    ha->init_ctrl_blk.cb.max_frame_length[1]));
5053		acc.common_service.conc_sequences = 0xff;
5054		acc.common_service.relative_offset = 0x03;
5055		acc.common_service.e_d_tov = 0x7d0;
5056		if (accept) {
5057			/* Use the saved N_Port WWNN and WWPN */
5058			if (ha->n_port != NULL) {
5059				bcopy((void *)&ha->n_port->port_name[0],
5060				    (void *)&acc.nport_ww_name.raw_wwn[0], 8);
5061				bcopy((void *)&ha->n_port->node_name[0],
5062				    (void *)&acc.node_ww_name.raw_wwn[0], 8);
5063				/* mark service options invalid */
5064				class3_param->class_valid_svc_opt = 0x0800;
5065			} else {
5066				EL(ha, "ha->n_port is NULL\n");
5067				/* Build RJT. */
5068				acc.ls_code.ls_code = LA_ELS_RJT;
5069
5070				pkt->pkt_state = FC_PKT_TRAN_ERROR;
5071				pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5072			}
5073		} else {
5074			bcopy((void *)&tq->port_name[0],
5075			    (void *)&acc.nport_ww_name.raw_wwn[0], 8);
5076			bcopy((void *)&tq->node_name[0],
5077			    (void *)&acc.node_ww_name.raw_wwn[0], 8);
5078
5079			class3_param = (class_svc_param_t *)&acc.class_3;
5080			class3_param->class_valid_svc_opt = 0x8800;
5081			class3_param->recipient_ctl = tq->class3_recipient_ctl;
5082			class3_param->rcv_data_size = tq->class3_rcv_data_size;
5083			class3_param->conc_sequences =
5084			    tq->class3_conc_sequences;
5085			class3_param->open_sequences_per_exch =
5086			    tq->class3_open_sequences_per_exch;
5087		}
5088	} else {
5089		/* Build RJT. */
5090		acc.ls_code.ls_code = LA_ELS_RJT;
5091
5092		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5093		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5094		EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5095	}
5096
5097	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5098	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5099
5100	if (rval != FC_SUCCESS) {
5101		EL(ha, "failed, rval = %xh\n", rval);
5102	} else {
5103		/*EMPTY*/
5104		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5105	}
5106	return (rval);
5107}
5108
5109/*
5110 * ql_els_logo
5111 *	Issue a extended link service logout request.
5112 *
5113 * Input:
5114 *	ha = adapter state pointer.
5115 *	pkt = pointer to fc_packet.
5116 *
5117 * Returns:
5118 *	FC_SUCCESS - the packet was accepted for transport.
5119 *	FC_TRANSPORT_ERROR - a transport error occurred.
5120 *
5121 * Context:
5122 *	Kernel context.
5123 */
5124static int
5125ql_els_logo(ql_adapter_state_t *ha, fc_packet_t *pkt)
5126{
5127	port_id_t	d_id;
5128	ql_tgt_t	*tq;
5129	la_els_logo_t	acc;
5130	int		rval = FC_SUCCESS;
5131
5132	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
5133	    pkt->pkt_cmd_fhdr.d_id);
5134
5135	bzero(&acc, sizeof (acc));
5136	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5137
5138	tq = ql_d_id_to_queue(ha, d_id);
5139	if (tq) {
5140		DEVICE_QUEUE_LOCK(tq);
5141		if (tq->d_id.b24 == BROADCAST_ADDR) {
5142			DEVICE_QUEUE_UNLOCK(tq);
5143			return (FC_SUCCESS);
5144		}
5145
5146		tq->flags |= TQF_NEED_AUTHENTICATION;
5147
5148		do {
5149			DEVICE_QUEUE_UNLOCK(tq);
5150			(void) ql_abort_device(ha, tq, 1);
5151
5152			/*
5153			 * Wait for commands to drain in F/W (doesn't
5154			 * take more than a few milliseconds)
5155			 */
5156			ql_delay(ha, 10000);
5157
5158			DEVICE_QUEUE_LOCK(tq);
5159		} while (tq->outcnt);
5160
5161		DEVICE_QUEUE_UNLOCK(tq);
5162	}
5163
5164	if (ql_logout_port(ha, d_id) == QL_SUCCESS) {
5165		/* Build ACC. */
5166		acc.ls_code.ls_code = LA_ELS_ACC;
5167
5168		pkt->pkt_state = FC_PKT_SUCCESS;
5169	} else {
5170		/* Build RJT. */
5171		acc.ls_code.ls_code = LA_ELS_RJT;
5172
5173		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5174		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5175		EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5176	}
5177
5178	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5179	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5180
5181	if (rval != FC_SUCCESS) {
5182		EL(ha, "failed, rval = %xh\n", rval);
5183	} else {
5184		/*EMPTY*/
5185		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5186	}
5187	return (rval);
5188}
5189
5190/*
5191 * ql_els_prli
5192 *	Issue a extended link service process login request.
5193 *
5194 * Input:
5195 *	ha = adapter state pointer.
5196 *	pkt = pointer to fc_packet.
5197 *
5198 * Returns:
5199 *	FC_SUCCESS - the packet was accepted for transport.
5200 *	FC_TRANSPORT_ERROR - a transport error occurred.
5201 *
5202 * Context:
5203 *	Kernel context.
5204 */
5205static int
5206ql_els_prli(ql_adapter_state_t *ha, fc_packet_t *pkt)
5207{
5208	ql_tgt_t		*tq;
5209	port_id_t		d_id;
5210	la_els_prli_t		acc;
5211	prli_svc_param_t	*param;
5212	int			rval = FC_SUCCESS;
5213
5214	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
5215	    pkt->pkt_cmd_fhdr.d_id);
5216
5217	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5218
5219	tq = ql_d_id_to_queue(ha, d_id);
5220	if (tq != NULL) {
5221		(void) ql_get_port_database(ha, tq, PDF_NONE);
5222
5223		if ((ha->topology & QL_N_PORT) &&
5224		    (tq->master_state == PD_STATE_PLOGI_COMPLETED)) {
5225			ql_start_iocb(ha, (ql_srb_t *)pkt->pkt_fca_private);
5226			rval = QL_CONSUMED;
5227		} else {
5228			/* Build ACC. */
5229			bzero(&acc, sizeof (acc));
5230			acc.ls_code = LA_ELS_ACC;
5231			acc.page_length = 0x10;
5232			acc.payload_length = tq->prli_payload_length;
5233
5234			param = (prli_svc_param_t *)&acc.service_params[0];
5235			param->type = 0x08;
5236			param->rsvd = 0x00;
5237			param->process_assoc_flags = tq->prli_svc_param_word_0;
5238			param->process_flags = tq->prli_svc_param_word_3;
5239
5240			ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5241			    (uint8_t *)pkt->pkt_resp, sizeof (acc),
5242			    DDI_DEV_AUTOINCR);
5243
5244			pkt->pkt_state = FC_PKT_SUCCESS;
5245		}
5246	} else {
5247		la_els_rjt_t rjt;
5248
5249		/* Build RJT. */
5250		bzero(&rjt, sizeof (rjt));
5251		rjt.ls_code.ls_code = LA_ELS_RJT;
5252
5253		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
5254		    (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
5255
5256		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5257		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5258		EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5259	}
5260
5261	if ((rval != FC_SUCCESS) && (rval != QL_CONSUMED)) {
5262		EL(ha, "failed, rval = %xh\n", rval);
5263	} else {
5264		/*EMPTY*/
5265		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5266	}
5267	return (rval);
5268}
5269
5270/*
5271 * ql_els_prlo
5272 *	Issue a extended link service process logout request.
5273 *
5274 * Input:
5275 *	ha = adapter state pointer.
5276 *	pkt = pointer to fc_packet.
5277 *
5278 * Returns:
5279 *	FC_SUCCESS - the packet was accepted for transport.
5280 *	FC_TRANSPORT_ERROR - a transport error occurred.
5281 *
5282 * Context:
5283 *	Kernel context.
5284 */
5285/* ARGSUSED */
5286static int
5287ql_els_prlo(ql_adapter_state_t *ha, fc_packet_t *pkt)
5288{
5289	la_els_prli_t	acc;
5290	int		rval = FC_SUCCESS;
5291
5292	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
5293	    pkt->pkt_cmd_fhdr.d_id);
5294
5295	/* Build ACC. */
5296	ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&acc,
5297	    (uint8_t *)pkt->pkt_cmd, sizeof (acc), DDI_DEV_AUTOINCR);
5298
5299	acc.ls_code = LA_ELS_ACC;
5300	acc.service_params[2] = 1;
5301
5302	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5303	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5304
5305	pkt->pkt_state = FC_PKT_SUCCESS;
5306
5307	if (rval != FC_SUCCESS) {
5308		EL(ha, "failed, rval = %xh\n", rval);
5309	} else {
5310		/*EMPTY*/
5311		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5312	}
5313	return (rval);
5314}
5315
5316/*
5317 * ql_els_adisc
5318 *	Issue a extended link service address discovery request.
5319 *
5320 * Input:
5321 *	ha = adapter state pointer.
5322 *	pkt = pointer to fc_packet.
5323 *
5324 * Returns:
5325 *	FC_SUCCESS - the packet was accepted for transport.
5326 *	FC_TRANSPORT_ERROR - a transport error occurred.
5327 *
5328 * Context:
5329 *	Kernel context.
5330 */
5331static int
5332ql_els_adisc(ql_adapter_state_t *ha, fc_packet_t *pkt)
5333{
5334	ql_dev_id_list_t	*list;
5335	uint32_t		list_size;
5336	ql_link_t		*link;
5337	ql_tgt_t		*tq;
5338	ql_lun_t		*lq;
5339	port_id_t		d_id;
5340	la_els_adisc_t		acc;
5341	uint16_t		index, loop_id;
5342	ql_mbx_data_t		mr;
5343	int			rval = FC_SUCCESS;
5344
5345	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5346
5347	bzero(&acc, sizeof (acc));
5348	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5349
5350	/*
5351	 * MBC_GET_PORT_DATABASE causes ADISC to go out to
5352	 * the device from the firmware
5353	 */
5354	index = ql_alpa_to_index[d_id.b.al_pa];
5355	tq = NULL;
5356	for (link = ha->dev[index].first; link != NULL; link = link->next) {
5357		tq = link->base_address;
5358		if (tq->d_id.b24 == d_id.b24) {
5359			break;
5360		} else {
5361			tq = NULL;
5362		}
5363	}
5364
5365	if ((tq != NULL) && (!VALID_DEVICE_ID(ha, tq->loop_id))) {
5366		list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES;
5367		list = (ql_dev_id_list_t *)kmem_zalloc(list_size, KM_SLEEP);
5368
5369		if (list != NULL &&
5370		    ql_get_id_list(ha, (caddr_t)list, list_size, &mr) ==
5371		    QL_SUCCESS) {
5372
5373			for (index = 0; index < mr.mb[1]; index++) {
5374				ql_dev_list(ha, list, index, &d_id, &loop_id);
5375
5376				if (tq->d_id.b24 == d_id.b24) {
5377					tq->loop_id = loop_id;
5378					break;
5379				}
5380			}
5381		} else {
5382			cmn_err(CE_WARN, "!%s(%d) didn't get list for %xh",
5383			    QL_NAME, ha->instance, d_id.b24);
5384			tq = NULL;
5385		}
5386		if ((tq != NULL) && (!VALID_DEVICE_ID(ha, tq->loop_id))) {
5387			cmn_err(CE_WARN, "!%s(%d) no loop_id for adisc %xh",
5388			    QL_NAME, ha->instance, tq->d_id.b24);
5389			tq = NULL;
5390		}
5391
5392		if (list != NULL) {
5393			kmem_free(list, list_size);
5394		}
5395	}
5396
5397	if ((tq != NULL) && (VALID_DEVICE_ID(ha, tq->loop_id)) &&
5398	    ql_get_port_database(ha, tq, PDF_ADISC) == QL_SUCCESS) {
5399
5400		/* Build ACC. */
5401
5402		DEVICE_QUEUE_LOCK(tq);
5403		tq->flags &= ~TQF_NEED_AUTHENTICATION;
5404		if (tq->prli_svc_param_word_3 & PRLI_W3_RETRY) {
5405			for (link = tq->lun_queues.first; link != NULL;
5406			    link = link->next) {
5407				lq = link->base_address;
5408
5409				if (lq->cmd.first != NULL) {
5410					ql_next(ha, lq);
5411					DEVICE_QUEUE_LOCK(tq);
5412				}
5413			}
5414		}
5415		DEVICE_QUEUE_UNLOCK(tq);
5416
5417		acc.ls_code.ls_code = LA_ELS_ACC;
5418		acc.hard_addr.hard_addr = tq->hard_addr.b24;
5419
5420		bcopy((void *)&tq->port_name[0],
5421		    (void *)&acc.port_wwn.raw_wwn[0], 8);
5422		bcopy((void *)&tq->node_name[0],
5423		    (void *)&acc.node_wwn.raw_wwn[0], 8);
5424
5425		acc.nport_id.port_id = tq->d_id.b24;
5426
5427		pkt->pkt_state = FC_PKT_SUCCESS;
5428	} else {
5429		/* Build RJT. */
5430		acc.ls_code.ls_code = LA_ELS_RJT;
5431
5432		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5433		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5434		EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5435	}
5436
5437	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5438	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5439
5440	if (rval != FC_SUCCESS) {
5441		EL(ha, "failed, rval = %xh\n", rval);
5442	} else {
5443		/*EMPTY*/
5444		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5445	}
5446	return (rval);
5447}
5448
5449/*
5450 * ql_els_linit
5451 *	Issue a extended link service loop initialize request.
5452 *
5453 * Input:
5454 *	ha = adapter state pointer.
5455 *	pkt = pointer to fc_packet.
5456 *
5457 * Returns:
5458 *	FC_SUCCESS - the packet was accepted for transport.
5459 *	FC_TRANSPORT_ERROR - a transport error occurred.
5460 *
5461 * Context:
5462 *	Kernel context.
5463 */
5464static int
5465ql_els_linit(ql_adapter_state_t *ha, fc_packet_t *pkt)
5466{
5467	ddi_dma_cookie_t	*cp;
5468	uint32_t		cnt;
5469	conv_num_t		n;
5470	port_id_t		d_id;
5471	int			rval = FC_SUCCESS;
5472
5473	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5474
5475	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5476	if (ha->topology & QL_SNS_CONNECTION) {
5477		fc_linit_req_t els;
5478		lfa_cmd_t lfa;
5479
5480		ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
5481		    (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
5482
5483		/* Setup LFA mailbox command data. */
5484		bzero((void *)&lfa, sizeof (lfa_cmd_t));
5485
5486		lfa.resp_buffer_length[0] = 4;
5487
5488		cp = pkt->pkt_resp_cookie;
5489		if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
5490			n.size64 = (uint64_t)cp->dmac_laddress;
5491			LITTLE_ENDIAN_64(&n.size64);
5492		} else {
5493			n.size32[0] = LSD(cp->dmac_laddress);
5494			LITTLE_ENDIAN_32(&n.size32[0]);
5495			n.size32[1] = MSD(cp->dmac_laddress);
5496			LITTLE_ENDIAN_32(&n.size32[1]);
5497		}
5498
5499		/* Set buffer address. */
5500		for (cnt = 0; cnt < 8; cnt++) {
5501			lfa.resp_buffer_address[cnt] = n.size8[cnt];
5502		}
5503
5504		lfa.subcommand_length[0] = 4;
5505		n.size32[0] = d_id.b24;
5506		LITTLE_ENDIAN_32(&n.size32[0]);
5507		lfa.addr[0] = n.size8[0];
5508		lfa.addr[1] = n.size8[1];
5509		lfa.addr[2] = n.size8[2];
5510		lfa.subcommand[1] = 0x70;
5511		lfa.payload[2] = els.func;
5512		lfa.payload[4] = els.lip_b3;
5513		lfa.payload[5] = els.lip_b4;
5514
5515		if (ql_send_lfa(ha, &lfa) != QL_SUCCESS) {
5516			pkt->pkt_state = FC_PKT_TRAN_ERROR;
5517		} else {
5518			pkt->pkt_state = FC_PKT_SUCCESS;
5519		}
5520	} else {
5521		fc_linit_resp_t rjt;
5522
5523		/* Build RJT. */
5524		bzero(&rjt, sizeof (rjt));
5525		rjt.ls_code.ls_code = LA_ELS_RJT;
5526
5527		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
5528		    (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
5529
5530		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5531		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5532		EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5533	}
5534
5535	if (rval != FC_SUCCESS) {
5536		EL(ha, "failed, rval = %xh\n", rval);
5537	} else {
5538		/*EMPTY*/
5539		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5540	}
5541	return (rval);
5542}
5543
5544/*
5545 * ql_els_lpc
5546 *	Issue a extended link service loop control request.
5547 *
5548 * Input:
5549 *	ha = adapter state pointer.
5550 *	pkt = pointer to fc_packet.
5551 *
5552 * Returns:
5553 *	FC_SUCCESS - the packet was accepted for transport.
5554 *	FC_TRANSPORT_ERROR - a transport error occurred.
5555 *
5556 * Context:
5557 *	Kernel context.
5558 */
5559static int
5560ql_els_lpc(ql_adapter_state_t *ha, fc_packet_t *pkt)
5561{
5562	ddi_dma_cookie_t	*cp;
5563	uint32_t		cnt;
5564	conv_num_t		n;
5565	port_id_t		d_id;
5566	int			rval = FC_SUCCESS;
5567
5568	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5569
5570	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5571	if (ha->topology & QL_SNS_CONNECTION) {
5572		ql_lpc_t els;
5573		lfa_cmd_t lfa;
5574
5575		ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
5576		    (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
5577
5578		/* Setup LFA mailbox command data. */
5579		bzero((void *)&lfa, sizeof (lfa_cmd_t));
5580
5581		lfa.resp_buffer_length[0] = 4;
5582
5583		cp = pkt->pkt_resp_cookie;
5584		if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
5585			n.size64 = (uint64_t)(cp->dmac_laddress);
5586			LITTLE_ENDIAN_64(&n.size64);
5587		} else {
5588			n.size32[0] = cp->dmac_address;
5589			LITTLE_ENDIAN_32(&n.size32[0]);
5590			n.size32[1] = 0;
5591		}
5592
5593		/* Set buffer address. */
5594		for (cnt = 0; cnt < 8; cnt++) {
5595			lfa.resp_buffer_address[cnt] = n.size8[cnt];
5596		}
5597
5598		lfa.subcommand_length[0] = 20;
5599		n.size32[0] = d_id.b24;
5600		LITTLE_ENDIAN_32(&n.size32[0]);
5601		lfa.addr[0] = n.size8[0];
5602		lfa.addr[1] = n.size8[1];
5603		lfa.addr[2] = n.size8[2];
5604		lfa.subcommand[1] = 0x71;
5605		lfa.payload[4] = els.port_control;
5606		bcopy((void *)&els.lpb[0], (void *)&lfa.payload[6], 32);
5607
5608		if (ql_send_lfa(ha, &lfa) != QL_SUCCESS) {
5609			pkt->pkt_state = FC_PKT_TRAN_ERROR;
5610		} else {
5611			pkt->pkt_state = FC_PKT_SUCCESS;
5612		}
5613	} else {
5614		ql_lpc_resp_t rjt;
5615
5616		/* Build RJT. */
5617		bzero(&rjt, sizeof (rjt));
5618		rjt.ls_code.ls_code = LA_ELS_RJT;
5619
5620		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
5621		    (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
5622
5623		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5624		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5625		EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5626	}
5627
5628	if (rval != FC_SUCCESS) {
5629		EL(ha, "failed, rval = %xh\n", rval);
5630	} else {
5631		/*EMPTY*/
5632		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5633	}
5634	return (rval);
5635}
5636
5637/*
5638 * ql_els_lsts
5639 *	Issue a extended link service loop status request.
5640 *
5641 * Input:
5642 *	ha = adapter state pointer.
5643 *	pkt = pointer to fc_packet.
5644 *
5645 * Returns:
5646 *	FC_SUCCESS - the packet was accepted for transport.
5647 *	FC_TRANSPORT_ERROR - a transport error occurred.
5648 *
5649 * Context:
5650 *	Kernel context.
5651 */
5652static int
5653ql_els_lsts(ql_adapter_state_t *ha, fc_packet_t *pkt)
5654{
5655	ddi_dma_cookie_t	*cp;
5656	uint32_t		cnt;
5657	conv_num_t		n;
5658	port_id_t		d_id;
5659	int			rval = FC_SUCCESS;
5660
5661	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5662
5663	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5664	if (ha->topology & QL_SNS_CONNECTION) {
5665		fc_lsts_req_t els;
5666		lfa_cmd_t lfa;
5667
5668		ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
5669		    (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
5670
5671		/* Setup LFA mailbox command data. */
5672		bzero((void *)&lfa, sizeof (lfa_cmd_t));
5673
5674		lfa.resp_buffer_length[0] = 84;
5675
5676		cp = pkt->pkt_resp_cookie;
5677		if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
5678			n.size64 = cp->dmac_laddress;
5679			LITTLE_ENDIAN_64(&n.size64);
5680		} else {
5681			n.size32[0] = cp->dmac_address;
5682			LITTLE_ENDIAN_32(&n.size32[0]);
5683			n.size32[1] = 0;
5684		}
5685
5686		/* Set buffer address. */
5687		for (cnt = 0; cnt < 8; cnt++) {
5688			lfa.resp_buffer_address[cnt] = n.size8[cnt];
5689		}
5690
5691		lfa.subcommand_length[0] = 2;
5692		n.size32[0] = d_id.b24;
5693		LITTLE_ENDIAN_32(&n.size32[0]);
5694		lfa.addr[0] = n.size8[0];
5695		lfa.addr[1] = n.size8[1];
5696		lfa.addr[2] = n.size8[2];
5697		lfa.subcommand[1] = 0x72;
5698
5699		if (ql_send_lfa(ha, &lfa) != QL_SUCCESS) {
5700			pkt->pkt_state = FC_PKT_TRAN_ERROR;
5701		} else {
5702			pkt->pkt_state = FC_PKT_SUCCESS;
5703		}
5704	} else {
5705		fc_lsts_resp_t rjt;
5706
5707		/* Build RJT. */
5708		bzero(&rjt, sizeof (rjt));
5709		rjt.lsts_ls_code.ls_code = LA_ELS_RJT;
5710
5711		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
5712		    (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
5713
5714		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5715		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5716		EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5717	}
5718
5719	if (rval != FC_SUCCESS) {
5720		EL(ha, "failed=%xh\n", rval);
5721	} else {
5722		/*EMPTY*/
5723		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5724	}
5725	return (rval);
5726}
5727
5728/*
5729 * ql_els_scr
5730 *	Issue a extended link service state change registration request.
5731 *
5732 * Input:
5733 *	ha = adapter state pointer.
5734 *	pkt = pointer to fc_packet.
5735 *
5736 * Returns:
5737 *	FC_SUCCESS - the packet was accepted for transport.
5738 *	FC_TRANSPORT_ERROR - a transport error occurred.
5739 *
5740 * Context:
5741 *	Kernel context.
5742 */
5743static int
5744ql_els_scr(ql_adapter_state_t *ha, fc_packet_t *pkt)
5745{
5746	fc_scr_resp_t	acc;
5747	int		rval = FC_SUCCESS;
5748
5749	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5750
5751	bzero(&acc, sizeof (acc));
5752	if (ha->topology & QL_SNS_CONNECTION) {
5753		fc_scr_req_t els;
5754
5755		ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
5756		    (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
5757
5758		if (ql_send_change_request(ha, els.scr_func) ==
5759		    QL_SUCCESS) {
5760			/* Build ACC. */
5761			acc.scr_acc = LA_ELS_ACC;
5762
5763			pkt->pkt_state = FC_PKT_SUCCESS;
5764		} else {
5765			/* Build RJT. */
5766			acc.scr_acc = LA_ELS_RJT;
5767
5768			pkt->pkt_state = FC_PKT_TRAN_ERROR;
5769			pkt->pkt_reason = FC_REASON_HW_ERROR;
5770			EL(ha, "LA_ELS_RJT, FC_REASON_HW_ERROR\n");
5771		}
5772	} else {
5773		/* Build RJT. */
5774		acc.scr_acc = LA_ELS_RJT;
5775
5776		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5777		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5778		EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5779	}
5780
5781	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5782	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5783
5784	if (rval != FC_SUCCESS) {
5785		EL(ha, "failed, rval = %xh\n", rval);
5786	} else {
5787		/*EMPTY*/
5788		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5789	}
5790	return (rval);
5791}
5792
5793/*
5794 * ql_els_rscn
5795 *	Issue a extended link service register state
5796 *	change notification request.
5797 *
5798 * Input:
5799 *	ha = adapter state pointer.
5800 *	pkt = pointer to fc_packet.
5801 *
5802 * Returns:
5803 *	FC_SUCCESS - the packet was accepted for transport.
5804 *	FC_TRANSPORT_ERROR - a transport error occurred.
5805 *
5806 * Context:
5807 *	Kernel context.
5808 */
5809static int
5810ql_els_rscn(ql_adapter_state_t *ha, fc_packet_t *pkt)
5811{
5812	ql_rscn_resp_t	acc;
5813	int		rval = FC_SUCCESS;
5814
5815	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5816
5817	bzero(&acc, sizeof (acc));
5818	if (ha->topology & QL_SNS_CONNECTION) {
5819		/* Build ACC. */
5820		acc.scr_acc = LA_ELS_ACC;
5821
5822		pkt->pkt_state = FC_PKT_SUCCESS;
5823	} else {
5824		/* Build RJT. */
5825		acc.scr_acc = LA_ELS_RJT;
5826
5827		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5828		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5829		EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5830	}
5831
5832	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5833	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5834
5835	if (rval != FC_SUCCESS) {
5836		EL(ha, "failed, rval = %xh\n", rval);
5837	} else {
5838		/*EMPTY*/
5839		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5840	}
5841	return (rval);
5842}
5843
5844/*
5845 * ql_els_farp_req
5846 *	Issue FC Address Resolution Protocol (FARP)
5847 *	extended link service request.
5848 *
5849 *	Note: not supported.
5850 *
5851 * Input:
5852 *	ha = adapter state pointer.
5853 *	pkt = pointer to fc_packet.
5854 *
5855 * Returns:
5856 *	FC_SUCCESS - the packet was accepted for transport.
5857 *	FC_TRANSPORT_ERROR - a transport error occurred.
5858 *
5859 * Context:
5860 *	Kernel context.
5861 */
5862static int
5863ql_els_farp_req(ql_adapter_state_t *ha, fc_packet_t *pkt)
5864{
5865	ql_acc_rjt_t	acc;
5866	int		rval = FC_SUCCESS;
5867
5868	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5869
5870	bzero(&acc, sizeof (acc));
5871
5872	/* Build ACC. */
5873	acc.ls_code.ls_code = LA_ELS_ACC;
5874
5875	pkt->pkt_state = FC_PKT_SUCCESS;
5876
5877	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5878	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5879
5880	if (rval != FC_SUCCESS) {
5881		EL(ha, "failed, rval = %xh\n", rval);
5882	} else {
5883		/*EMPTY*/
5884		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5885	}
5886	return (rval);
5887}
5888
5889/*
5890 * ql_els_farp_reply
5891 *	Issue FC Address Resolution Protocol (FARP)
5892 *	extended link service reply.
5893 *
5894 *	Note: not supported.
5895 *
5896 * Input:
5897 *	ha = adapter state pointer.
5898 *	pkt = pointer to fc_packet.
5899 *
5900 * Returns:
5901 *	FC_SUCCESS - the packet was accepted for transport.
5902 *	FC_TRANSPORT_ERROR - a transport error occurred.
5903 *
5904 * Context:
5905 *	Kernel context.
5906 */
5907/* ARGSUSED */
5908static int
5909ql_els_farp_reply(ql_adapter_state_t *ha, fc_packet_t *pkt)
5910{
5911	ql_acc_rjt_t	acc;
5912	int		rval = FC_SUCCESS;
5913
5914	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5915
5916	bzero(&acc, sizeof (acc));
5917
5918	/* Build ACC. */
5919	acc.ls_code.ls_code = LA_ELS_ACC;
5920
5921	pkt->pkt_state = FC_PKT_SUCCESS;
5922
5923	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5924	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5925
5926	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5927
5928	return (rval);
5929}
5930
5931static int
5932ql_els_rnid(ql_adapter_state_t *ha, fc_packet_t *pkt)
5933{
5934	uchar_t			*rnid_acc;
5935	port_id_t		d_id;
5936	ql_link_t		*link;
5937	ql_tgt_t		*tq;
5938	uint16_t		index;
5939	la_els_rnid_acc_t	acc;
5940	la_els_rnid_t		*req;
5941	size_t			req_len;
5942
5943	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
5944
5945	req_len =  FCIO_RNID_MAX_DATA_LEN + sizeof (fc_rnid_hdr_t);
5946	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
5947	index = ql_alpa_to_index[d_id.b.al_pa];
5948
5949	tq = NULL;
5950	for (link = ha->dev[index].first; link != NULL; link = link->next) {
5951		tq = link->base_address;
5952		if (tq->d_id.b24 == d_id.b24) {
5953			break;
5954		} else {
5955			tq = NULL;
5956		}
5957	}
5958
5959	/* Allocate memory for rnid status block */
5960	rnid_acc = kmem_zalloc(req_len, KM_SLEEP);
5961
5962	bzero(&acc, sizeof (acc));
5963
5964	req = (la_els_rnid_t *)pkt->pkt_cmd;
5965	if ((tq == NULL) || (!VALID_DEVICE_ID(ha, tq->loop_id)) ||
5966	    (ql_send_rnid_els(ha, tq->loop_id, req->data_format, req_len,
5967	    (caddr_t)rnid_acc) != QL_SUCCESS)) {
5968
5969		kmem_free(rnid_acc, req_len);
5970		acc.ls_code.ls_code = LA_ELS_RJT;
5971
5972		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5973		    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5974
5975		pkt->pkt_state = FC_PKT_TRAN_ERROR;
5976		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
5977		EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
5978
5979		return (FC_FAILURE);
5980	}
5981
5982	acc.ls_code.ls_code = LA_ELS_ACC;
5983	bcopy(rnid_acc, &acc.hdr, req_len);
5984	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
5985	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
5986
5987	kmem_free(rnid_acc, req_len);
5988	pkt->pkt_state = FC_PKT_SUCCESS;
5989
5990	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
5991
5992	return (FC_SUCCESS);
5993}
5994
5995static int
5996ql_els_rls(ql_adapter_state_t *ha, fc_packet_t *pkt)
5997{
5998	fc_rls_acc_t		*rls_acc;
5999	port_id_t		d_id;
6000	ql_link_t		*link;
6001	ql_tgt_t		*tq;
6002	uint16_t		index;
6003	la_els_rls_acc_t	acc;
6004
6005	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6006
6007	d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
6008	index = ql_alpa_to_index[d_id.b.al_pa];
6009
6010	tq = NULL;
6011	for (link = ha->dev[index].first; link != NULL; link = link->next) {
6012		tq = link->base_address;
6013		if (tq->d_id.b24 == d_id.b24) {
6014			break;
6015		} else {
6016			tq = NULL;
6017		}
6018	}
6019
6020	/* Allocate memory for link error status block */
6021	rls_acc = kmem_zalloc(sizeof (*rls_acc), KM_SLEEP);
6022
6023	bzero(&acc, sizeof (la_els_rls_acc_t));
6024
6025	if ((tq == NULL) || (!VALID_DEVICE_ID(ha, tq->loop_id)) ||
6026	    (ql_get_link_status(ha, tq->loop_id, sizeof (*rls_acc),
6027	    (caddr_t)rls_acc, 0) != QL_SUCCESS)) {
6028
6029		kmem_free(rls_acc, sizeof (*rls_acc));
6030		acc.ls_code.ls_code = LA_ELS_RJT;
6031
6032		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
6033		    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
6034
6035		pkt->pkt_state = FC_PKT_TRAN_ERROR;
6036		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
6037		EL(ha, "LA_ELS_RJT, FC_REASON_NO_CONNECTION\n");
6038
6039		return (FC_FAILURE);
6040	}
6041
6042	LITTLE_ENDIAN_32(&rls_acc->rls_link_fail);
6043	LITTLE_ENDIAN_32(&rls_acc->rls_sync_loss);
6044	LITTLE_ENDIAN_32(&rls_acc->rls_sig_loss);
6045	LITTLE_ENDIAN_32(&rls_acc->rls_invalid_word);
6046	LITTLE_ENDIAN_32(&rls_acc->rls_invalid_crc);
6047
6048	acc.ls_code.ls_code = LA_ELS_ACC;
6049	acc.rls_link_params.rls_link_fail = rls_acc->rls_link_fail;
6050	acc.rls_link_params.rls_sync_loss = rls_acc->rls_sync_loss;
6051	acc.rls_link_params.rls_sig_loss  = rls_acc->rls_sig_loss;
6052	acc.rls_link_params.rls_invalid_word = rls_acc->rls_invalid_word;
6053	acc.rls_link_params.rls_invalid_crc = rls_acc->rls_invalid_crc;
6054	ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&acc,
6055	    (uint8_t *)pkt->pkt_resp, sizeof (acc), DDI_DEV_AUTOINCR);
6056
6057	kmem_free(rls_acc, sizeof (*rls_acc));
6058	pkt->pkt_state = FC_PKT_SUCCESS;
6059
6060	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6061
6062	return (FC_SUCCESS);
6063}
6064
6065static int
6066ql_busy_plogi(ql_adapter_state_t *ha, fc_packet_t *pkt, ql_tgt_t *tq)
6067{
6068	port_id_t	d_id;
6069	ql_srb_t	*sp;
6070	fc_unsol_buf_t  *ubp;
6071	ql_link_t	*link, *next_link;
6072	int		rval = FC_SUCCESS;
6073	int		cnt = 5;
6074
6075	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6076
6077	/*
6078	 * we need to ensure that q->outcnt == 0, otherwise
6079	 * any cmd completed with PKT_PORT_OFFLINE after PLOGI
6080	 * will confuse ulps.
6081	 */
6082
6083	DEVICE_QUEUE_LOCK(tq);
6084	do {
6085		/*
6086		 * wait for the cmds to get drained. If they
6087		 * don't get drained then the transport will
6088		 * retry PLOGI after few secs.
6089		 */
6090		if (tq->outcnt != 0) {
6091			rval = FC_TRAN_BUSY;
6092			DEVICE_QUEUE_UNLOCK(tq);
6093			ql_delay(ha, 10000);
6094			DEVICE_QUEUE_LOCK(tq);
6095			cnt--;
6096			if (!cnt) {
6097				cmn_err(CE_NOTE, "!%s(%d) Plogi busy"
6098				    " for %xh outcount %xh", QL_NAME,
6099				    ha->instance, tq->d_id.b24, tq->outcnt);
6100			}
6101		} else {
6102			rval = FC_SUCCESS;
6103			break;
6104		}
6105	} while (cnt > 0);
6106	DEVICE_QUEUE_UNLOCK(tq);
6107
6108	/*
6109	 * return, if busy or if the plogi was asynchronous.
6110	 */
6111	if ((rval != FC_SUCCESS) ||
6112	    (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) &&
6113	    pkt->pkt_comp)) {
6114		QL_PRINT_3(CE_CONT, "(%d): done, busy or async\n",
6115		    ha->instance);
6116		return (rval);
6117	}
6118
6119	/*
6120	 * Let us give daemon sufficient time and hopefully
6121	 * when transport retries PLOGI, it would have flushed
6122	 * callback queue.
6123	 */
6124	TASK_DAEMON_LOCK(ha);
6125	for (link = ha->callback_queue.first; link != NULL;
6126	    link = next_link) {
6127		next_link = link->next;
6128		sp = link->base_address;
6129		if (sp->flags & SRB_UB_CALLBACK) {
6130			ubp = ha->ub_array[sp->handle];
6131			d_id.b24 = ubp->ub_frame.s_id;
6132		} else {
6133			d_id.b24 = sp->pkt->pkt_cmd_fhdr.d_id;
6134		}
6135		if (tq->d_id.b24 == d_id.b24) {
6136			cmn_err(CE_NOTE, "!%s(%d) Plogi busy for %xh", QL_NAME,
6137			    ha->instance, tq->d_id.b24);
6138			rval = FC_TRAN_BUSY;
6139			break;
6140		}
6141	}
6142	TASK_DAEMON_UNLOCK(ha);
6143
6144	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6145
6146	return (rval);
6147}
6148
6149/*
6150 * ql_login_port
6151 *	Logs in a device if not already logged in.
6152 *
6153 * Input:
6154 *	ha = adapter state pointer.
6155 *	d_id = 24 bit port ID.
6156 *	DEVICE_QUEUE_LOCK must be released.
6157 *
6158 * Returns:
6159 *	QL local function return status code.
6160 *
6161 * Context:
6162 *	Kernel context.
6163 */
6164static int
6165ql_login_port(ql_adapter_state_t *ha, port_id_t d_id)
6166{
6167	ql_adapter_state_t	*vha;
6168	ql_link_t		*link;
6169	uint16_t		index;
6170	ql_tgt_t		*tq, *tq2;
6171	uint16_t		loop_id, first_loop_id, last_loop_id;
6172	int			rval = QL_SUCCESS;
6173
6174	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
6175	    d_id.b24);
6176
6177	/* Get head queue index. */
6178	index = ql_alpa_to_index[d_id.b.al_pa];
6179
6180	/* Check for device already has a queue. */
6181	tq = NULL;
6182	for (link = ha->dev[index].first; link != NULL; link = link->next) {
6183		tq = link->base_address;
6184		if (tq->d_id.b24 == d_id.b24) {
6185			loop_id = tq->loop_id;
6186			break;
6187		} else {
6188			tq = NULL;
6189		}
6190	}
6191
6192	/* Let's stop issuing any IO and unsolicited logo */
6193	if ((tq != NULL) && (!(ddi_in_panic()))) {
6194		DEVICE_QUEUE_LOCK(tq);
6195		tq->flags |= (TQF_QUEUE_SUSPENDED | TQF_PLOGI_PROGRS);
6196		tq->flags &= ~TQF_RSCN_RCVD;
6197		DEVICE_QUEUE_UNLOCK(tq);
6198	}
6199	if ((tq != NULL) && (tq->loop_id & PORT_LOST_ID) &&
6200	    !(tq->flags & TQF_FABRIC_DEVICE)) {
6201		loop_id = (uint16_t)(tq->loop_id & ~PORT_LOST_ID);
6202	}
6203
6204	/* Special case for Nameserver */
6205	if (d_id.b24 == 0xFFFFFC) {
6206		loop_id = (uint16_t)(CFG_IST(ha, CFG_CTRL_242581) ?
6207		    SNS_24XX_HDL : SIMPLE_NAME_SERVER_LOOP_ID);
6208		if (tq == NULL) {
6209			ADAPTER_STATE_LOCK(ha);
6210			tq = ql_dev_init(ha, d_id, loop_id);
6211			ADAPTER_STATE_UNLOCK(ha);
6212			if (tq == NULL) {
6213				EL(ha, "failed=%xh, d_id=%xh\n",
6214				    QL_FUNCTION_FAILED, d_id.b24);
6215				return (QL_FUNCTION_FAILED);
6216			}
6217		}
6218		rval = ql_login_fabric_port(ha, tq, loop_id);
6219		if (rval == QL_SUCCESS) {
6220			tq->loop_id = loop_id;
6221			tq->flags |= TQF_FABRIC_DEVICE;
6222			(void) ql_get_port_database(ha, tq, PDF_NONE);
6223			ha->topology = (uint8_t)
6224			    (ha->topology | QL_SNS_CONNECTION);
6225		}
6226	/* Check for device already logged in. */
6227	} else if (tq != NULL && VALID_DEVICE_ID(ha, loop_id)) {
6228		if (tq->flags & TQF_FABRIC_DEVICE) {
6229			rval = ql_login_fabric_port(ha, tq, loop_id);
6230			if (rval == QL_PORT_ID_USED) {
6231				rval = QL_SUCCESS;
6232			}
6233		} else if (LOCAL_LOOP_ID(loop_id)) {
6234			rval = ql_login_lport(ha, tq, loop_id, (uint16_t)
6235			    (tq->flags & TQF_INITIATOR_DEVICE ?
6236			    LLF_NONE : LLF_PLOGI));
6237			if (rval == QL_SUCCESS) {
6238				DEVICE_QUEUE_LOCK(tq);
6239				tq->loop_id = loop_id;
6240				DEVICE_QUEUE_UNLOCK(tq);
6241			}
6242		}
6243	} else if (ha->topology & QL_SNS_CONNECTION) {
6244		/* Locate unused loop ID. */
6245		if (CFG_IST(ha, CFG_CTRL_242581)) {
6246			first_loop_id = 0;
6247			last_loop_id = LAST_N_PORT_HDL;
6248		} else if (ha->topology & QL_F_PORT) {
6249			first_loop_id = 0;
6250			last_loop_id = SNS_LAST_LOOP_ID;
6251		} else {
6252			first_loop_id = SNS_FIRST_LOOP_ID;
6253			last_loop_id = SNS_LAST_LOOP_ID;
6254		}
6255
6256		/* Acquire adapter state lock. */
6257		ADAPTER_STATE_LOCK(ha);
6258
6259		tq = ql_dev_init(ha, d_id, PORT_NO_LOOP_ID);
6260		if (tq == NULL) {
6261			EL(ha, "failed=%xh, d_id=%xh\n", QL_FUNCTION_FAILED,
6262			    d_id.b24);
6263
6264			ADAPTER_STATE_UNLOCK(ha);
6265
6266			return (QL_FUNCTION_FAILED);
6267		}
6268
6269		rval = QL_FUNCTION_FAILED;
6270		loop_id = ha->pha->free_loop_id++;
6271		for (index = (uint16_t)(last_loop_id - first_loop_id); index;
6272		    index--) {
6273			if (loop_id < first_loop_id ||
6274			    loop_id > last_loop_id) {
6275				loop_id = first_loop_id;
6276				ha->pha->free_loop_id = (uint16_t)
6277				    (loop_id + 1);
6278			}
6279
6280			/* Bypass if loop ID used. */
6281			for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
6282				tq2 = ql_loop_id_to_queue(vha, loop_id);
6283				if (tq2 != NULL && tq2 != tq) {
6284					break;
6285				}
6286			}
6287			if (vha != NULL || RESERVED_LOOP_ID(ha, loop_id) ||
6288			    loop_id == ha->loop_id) {
6289				loop_id = ha->pha->free_loop_id++;
6290				continue;
6291			}
6292
6293			ADAPTER_STATE_UNLOCK(ha);
6294			rval = ql_login_fabric_port(ha, tq, loop_id);
6295
6296			/*
6297			 * If PORT_ID_USED is returned
6298			 * the login_fabric_port() updates
6299			 * with the correct loop ID
6300			 */
6301			switch (rval) {
6302			case QL_PORT_ID_USED:
6303				/*
6304				 * use f/w handle and try to
6305				 * login again.
6306				 */
6307				ADAPTER_STATE_LOCK(ha);
6308				ha->pha->free_loop_id--;
6309				ADAPTER_STATE_UNLOCK(ha);
6310				loop_id = tq->loop_id;
6311				break;
6312
6313			case QL_SUCCESS:
6314				tq->flags |= TQF_FABRIC_DEVICE;
6315				(void) ql_get_port_database(ha,
6316				    tq, PDF_NONE);
6317				index = 1;
6318				break;
6319
6320			case QL_LOOP_ID_USED:
6321				tq->loop_id = PORT_NO_LOOP_ID;
6322				loop_id = ha->pha->free_loop_id++;
6323				break;
6324
6325			case QL_ALL_IDS_IN_USE:
6326				tq->loop_id = PORT_NO_LOOP_ID;
6327				index = 1;
6328				break;
6329
6330			default:
6331				tq->loop_id = PORT_NO_LOOP_ID;
6332				index = 1;
6333				break;
6334			}
6335
6336			ADAPTER_STATE_LOCK(ha);
6337		}
6338
6339		ADAPTER_STATE_UNLOCK(ha);
6340	} else {
6341		rval = QL_FUNCTION_FAILED;
6342	}
6343
6344	if (rval != QL_SUCCESS) {
6345		EL(ha, "failed=%xh, d_id=%xh\n", rval, d_id.b24);
6346	} else {
6347		EL(ha, "d_id=%xh, loop_id=%xh, "
6348		    "wwpn=%02x%02x%02x%02x%02x%02x%02x%02xh\n", tq->d_id.b24,
6349		    tq->loop_id, tq->port_name[0], tq->port_name[1],
6350		    tq->port_name[2], tq->port_name[3], tq->port_name[4],
6351		    tq->port_name[5], tq->port_name[6], tq->port_name[7]);
6352	}
6353	return (rval);
6354}
6355
6356/*
6357 * ql_login_fabric_port
6358 *	Issue login fabric port mailbox command.
6359 *
6360 * Input:
6361 *	ha:		adapter state pointer.
6362 *	tq:		target queue pointer.
6363 *	loop_id:	FC Loop ID.
6364 *
6365 * Returns:
6366 *	ql local function return status code.
6367 *
6368 * Context:
6369 *	Kernel context.
6370 */
6371static int
6372ql_login_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id)
6373{
6374	int		rval;
6375	int		index;
6376	int		retry = 0;
6377	port_id_t	d_id;
6378	ql_tgt_t	*newq;
6379	ql_mbx_data_t	mr;
6380
6381	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
6382	    tq->d_id.b24);
6383
6384	/*
6385	 * QL_PARAMETER_ERROR also means the firmware is
6386	 * not able to allocate PCB entry due to resource
6387	 * issues, or collision.
6388	 */
6389	do {
6390		rval = ql_login_fport(ha, tq, loop_id, LFF_NONE, &mr);
6391		if ((rval == QL_PARAMETER_ERROR) ||
6392		    ((rval == QL_COMMAND_ERROR) && (mr.mb[1] == 2 ||
6393		    mr.mb[1] == 3 || mr.mb[1] == 7 || mr.mb[1] == 0xd))) {
6394			retry++;
6395			drv_usecwait(10 * MILLISEC);
6396		} else {
6397			break;
6398		}
6399	} while (retry < 5);
6400
6401	switch (rval) {
6402	case QL_SUCCESS:
6403		tq->loop_id = loop_id;
6404		break;
6405
6406	case QL_PORT_ID_USED:
6407		/*
6408		 * This Loop ID should NOT be in use in drivers
6409		 */
6410		newq = ql_loop_id_to_queue(ha, mr.mb[1]);
6411
6412		if (newq != NULL && newq != tq && tq->logout_sent == 0) {
6413			cmn_err(CE_WARN, "ql_login_fabric_port(%d): logout of "
6414			    "dup loop_id=%xh, d_id=%xh", ha->instance,
6415			    newq->loop_id, newq->d_id.b24);
6416			ql_send_logo(ha, newq, NULL);
6417		}
6418
6419		tq->loop_id = mr.mb[1];
6420		break;
6421
6422	case QL_LOOP_ID_USED:
6423		d_id.b.al_pa = LSB(mr.mb[2]);
6424		d_id.b.area = MSB(mr.mb[2]);
6425		d_id.b.domain = LSB(mr.mb[1]);
6426
6427		newq = ql_d_id_to_queue(ha, d_id);
6428		if (newq && (newq->loop_id != loop_id)) {
6429			/*
6430			 * This should NEVER ever happen; but this
6431			 * code is needed to bail out when the worst
6432			 * case happens - or as used to happen before
6433			 */
6434			QL_PRINT_2(CE_CONT, "(%d,%d): Loop ID is now "
6435			    "reassigned; old pairs: [%xh, %xh] and [%xh, %xh];"
6436			    "new pairs: [%xh, unknown] and [%xh, %xh]\n",
6437			    ha->instance, ha->vp_index, tq->d_id.b24, loop_id,
6438			    newq->d_id.b24, newq->loop_id, tq->d_id.b24,
6439			    newq->d_id.b24, loop_id);
6440
6441			if ((newq->d_id.b24 & 0xff) != (d_id.b24 & 0xff)) {
6442				ADAPTER_STATE_LOCK(ha);
6443
6444				index = ql_alpa_to_index[newq->d_id.b.al_pa];
6445				ql_add_link_b(&ha->dev[index], &newq->device);
6446
6447				newq->d_id.b24 = d_id.b24;
6448
6449				index = ql_alpa_to_index[d_id.b.al_pa];
6450				ql_add_link_b(&ha->dev[index], &newq->device);
6451
6452				ADAPTER_STATE_UNLOCK(ha);
6453			}
6454
6455			(void) ql_get_port_database(ha, newq, PDF_NONE);
6456
6457		}
6458
6459		/*
6460		 * Invalidate the loop ID for the
6461		 * us to obtain a new one.
6462		 */
6463		tq->loop_id = PORT_NO_LOOP_ID;
6464		break;
6465
6466	case QL_ALL_IDS_IN_USE:
6467		rval = QL_FUNCTION_FAILED;
6468		EL(ha, "no loop id's available\n");
6469		break;
6470
6471	default:
6472		if (rval == QL_COMMAND_ERROR) {
6473			switch (mr.mb[1]) {
6474			case 2:
6475			case 3:
6476				rval = QL_MEMORY_ALLOC_FAILED;
6477				break;
6478
6479			case 4:
6480				rval = QL_FUNCTION_TIMEOUT;
6481				break;
6482			case 7:
6483				rval = QL_FABRIC_NOT_INITIALIZED;
6484				break;
6485			default:
6486				EL(ha, "cmd rtn; mb1=%xh\n", mr.mb[1]);
6487				break;
6488			}
6489		} else {
6490			cmn_err(CE_WARN, "%s(%d): login fabric port failed"
6491			    " D_ID=%xh, rval=%xh, mb1=%xh", QL_NAME,
6492			    ha->instance, tq->d_id.b24, rval, mr.mb[1]);
6493		}
6494		break;
6495	}
6496
6497	if (rval != QL_SUCCESS && rval != QL_PORT_ID_USED &&
6498	    rval != QL_LOOP_ID_USED) {
6499		EL(ha, "failed=%xh\n", rval);
6500	} else {
6501		/*EMPTY*/
6502		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6503	}
6504	return (rval);
6505}
6506
6507/*
6508 * ql_logout_port
6509 *	Logs out a device if possible.
6510 *
6511 * Input:
6512 *	ha:	adapter state pointer.
6513 *	d_id:	24 bit port ID.
6514 *
6515 * Returns:
6516 *	QL local function return status code.
6517 *
6518 * Context:
6519 *	Kernel context.
6520 */
6521static int
6522ql_logout_port(ql_adapter_state_t *ha, port_id_t d_id)
6523{
6524	ql_link_t	*link;
6525	ql_tgt_t	*tq;
6526	uint16_t	index;
6527
6528	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6529
6530	/* Get head queue index. */
6531	index = ql_alpa_to_index[d_id.b.al_pa];
6532
6533	/* Get device queue. */
6534	tq = NULL;
6535	for (link = ha->dev[index].first; link != NULL; link = link->next) {
6536		tq = link->base_address;
6537		if (tq->d_id.b24 == d_id.b24) {
6538			break;
6539		} else {
6540			tq = NULL;
6541		}
6542	}
6543
6544	if (tq != NULL && tq->flags & TQF_FABRIC_DEVICE) {
6545		(void) ql_logout_fabric_port(ha, tq);
6546		tq->loop_id = PORT_NO_LOOP_ID;
6547	}
6548
6549	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6550
6551	return (QL_SUCCESS);
6552}
6553
6554/*
6555 * ql_dev_init
6556 *	Initialize/allocate device queue.
6557 *
6558 * Input:
6559 *	ha:		adapter state pointer.
6560 *	d_id:		device destination ID
6561 *	loop_id:	device loop ID
6562 *	ADAPTER_STATE_LOCK must be already obtained.
6563 *
6564 * Returns:
6565 *	NULL = failure
6566 *
6567 * Context:
6568 *	Kernel context.
6569 */
6570ql_tgt_t *
6571ql_dev_init(ql_adapter_state_t *ha, port_id_t d_id, uint16_t loop_id)
6572{
6573	ql_link_t	*link;
6574	uint16_t	index;
6575	ql_tgt_t	*tq;
6576
6577	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
6578	    ha->instance, d_id.b24, loop_id);
6579
6580	index = ql_alpa_to_index[d_id.b.al_pa];
6581
6582	/* If device queue exists, set proper loop ID. */
6583	tq = NULL;
6584	for (link = ha->dev[index].first; link != NULL; link = link->next) {
6585		tq = link->base_address;
6586		if (tq->d_id.b24 == d_id.b24) {
6587			tq->loop_id = loop_id;
6588
6589			/* Reset port down retry count. */
6590			tq->port_down_retry_count = ha->port_down_retry_count;
6591			tq->qfull_retry_count = ha->qfull_retry_count;
6592
6593			break;
6594		} else {
6595			tq = NULL;
6596		}
6597	}
6598
6599	/* If device does not have queue. */
6600	if (tq == NULL) {
6601		tq = (ql_tgt_t *)kmem_zalloc(sizeof (ql_tgt_t), KM_SLEEP);
6602		if (tq != NULL) {
6603			/*
6604			 * mutex to protect the device queue,
6605			 * does not block interrupts.
6606			 */
6607			mutex_init(&tq->mutex, NULL, MUTEX_DRIVER,
6608			    (ha->iflags & IFLG_INTR_AIF) ?
6609			    (void *)(uintptr_t)ha->intr_pri :
6610			    (void *)(uintptr_t)ha->iblock_cookie);
6611
6612			tq->d_id.b24 = d_id.b24;
6613			tq->loop_id = loop_id;
6614			tq->device.base_address = tq;
6615			tq->iidma_rate = IIDMA_RATE_INIT;
6616
6617			/* Reset port down retry count. */
6618			tq->port_down_retry_count = ha->port_down_retry_count;
6619			tq->qfull_retry_count = ha->qfull_retry_count;
6620
6621			/* Add device to device queue. */
6622			ql_add_link_b(&ha->dev[index], &tq->device);
6623		}
6624	}
6625
6626	if (tq == NULL) {
6627		EL(ha, "failed, d_id=%xh, loop_id=%xh\n", d_id.b24, loop_id);
6628	} else {
6629		/*EMPTY*/
6630		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6631	}
6632	return (tq);
6633}
6634
6635/*
6636 * ql_dev_free
6637 *	Remove queue from device list and frees resources used by queue.
6638 *
6639 * Input:
6640 *	ha:	adapter state pointer.
6641 *	tq:	target queue pointer.
6642 *	ADAPTER_STATE_LOCK must be already obtained.
6643 *
6644 * Context:
6645 *	Kernel context.
6646 */
6647void
6648ql_dev_free(ql_adapter_state_t *ha, ql_tgt_t *tq)
6649{
6650	ql_link_t	*link;
6651	uint16_t	index;
6652	ql_lun_t	*lq;
6653
6654	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6655
6656	for (link = tq->lun_queues.first; link != NULL; link = link->next) {
6657		lq = link->base_address;
6658		if (lq->cmd.first != NULL) {
6659			return;
6660		}
6661	}
6662
6663	if (tq->outcnt == 0) {
6664		/* Get head queue index. */
6665		index = ql_alpa_to_index[tq->d_id.b.al_pa];
6666		for (link = ha->dev[index].first; link != NULL;
6667		    link = link->next) {
6668			if (link->base_address == tq) {
6669				ql_remove_link(&ha->dev[index], link);
6670
6671				link = tq->lun_queues.first;
6672				while (link != NULL) {
6673					lq = link->base_address;
6674					link = link->next;
6675
6676					ql_remove_link(&tq->lun_queues,
6677					    &lq->link);
6678					kmem_free(lq, sizeof (ql_lun_t));
6679				}
6680
6681				mutex_destroy(&tq->mutex);
6682				kmem_free(tq, sizeof (ql_tgt_t));
6683				break;
6684			}
6685		}
6686	}
6687
6688	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6689}
6690
6691/*
6692 * ql_lun_queue
6693 *	Allocate LUN queue if does not exists.
6694 *
6695 * Input:
6696 *	ha:	adapter state pointer.
6697 *	tq:	target queue.
6698 *	lun:	LUN number.
6699 *
6700 * Returns:
6701 *	NULL = failure
6702 *
6703 * Context:
6704 *	Kernel context.
6705 */
6706static ql_lun_t *
6707ql_lun_queue(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
6708{
6709	ql_lun_t	*lq;
6710	ql_link_t	*link;
6711
6712	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6713
6714	/* Fast path. */
6715	if (tq->last_lun_queue != NULL && tq->last_lun_queue->lun_no == lun) {
6716		QL_PRINT_3(CE_CONT, "(%d): fast done\n", ha->instance);
6717		return (tq->last_lun_queue);
6718	}
6719
6720	if (lun >= MAX_LUNS) {
6721		EL(ha, "Exceeded MAX_LUN=%d, lun=%d\n", MAX_LUNS, lun);
6722		return (NULL);
6723	}
6724	/* If device queue exists, set proper loop ID. */
6725	lq = NULL;
6726	for (link = tq->lun_queues.first; link != NULL; link = link->next) {
6727		lq = link->base_address;
6728		if (lq->lun_no == lun) {
6729			QL_PRINT_3(CE_CONT, "(%d): found done\n", ha->instance);
6730			tq->last_lun_queue = lq;
6731			return (lq);
6732		}
6733	}
6734
6735	/* If queue does exist. */
6736	lq = (ql_lun_t *)kmem_zalloc(sizeof (ql_lun_t), KM_SLEEP);
6737
6738	/* Initialize LUN queue. */
6739	if (lq != NULL) {
6740		lq->link.base_address = lq;
6741
6742		lq->lun_no = lun;
6743		lq->target_queue = tq;
6744
6745		DEVICE_QUEUE_LOCK(tq);
6746		ql_add_link_b(&tq->lun_queues, &lq->link);
6747		DEVICE_QUEUE_UNLOCK(tq);
6748		tq->last_lun_queue = lq;
6749	}
6750
6751	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6752
6753	return (lq);
6754}
6755
6756/*
6757 * ql_fcp_scsi_cmd
6758 *	Process fibre channel (FCP) SCSI protocol commands.
6759 *
6760 * Input:
6761 *	ha = adapter state pointer.
6762 *	pkt = pointer to fc_packet.
6763 *	sp = srb pointer.
6764 *
6765 * Returns:
6766 *	FC_SUCCESS - the packet was accepted for transport.
6767 *	FC_TRANSPORT_ERROR - a transport error occurred.
6768 *
6769 * Context:
6770 *	Kernel context.
6771 */
6772static int
6773ql_fcp_scsi_cmd(ql_adapter_state_t *ha, fc_packet_t *pkt, ql_srb_t *sp)
6774{
6775	port_id_t	d_id;
6776	ql_tgt_t	*tq;
6777	uint64_t	*ptr;
6778	uint16_t	lun;
6779
6780	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6781
6782	tq = (ql_tgt_t *)pkt->pkt_fca_device;
6783	if (tq == NULL) {
6784		d_id.r.rsvd_1 = 0;
6785		d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
6786		tq = ql_d_id_to_queue(ha, d_id);
6787	}
6788
6789	sp->fcp = (struct fcp_cmd *)pkt->pkt_cmd;
6790	lun = CHAR_TO_SHORT(lobyte(sp->fcp->fcp_ent_addr.ent_addr_0),
6791	    hibyte(sp->fcp->fcp_ent_addr.ent_addr_0));
6792
6793	if (tq != NULL &&
6794	    (sp->lun_queue = ql_lun_queue(ha, tq, lun)) != NULL) {
6795
6796		/*
6797		 * zero out FCP response; 24 Bytes
6798		 */
6799		ptr = (uint64_t *)pkt->pkt_resp;
6800		*ptr++ = 0; *ptr++ = 0; *ptr++ = 0;
6801
6802		/* Handle task management function. */
6803		if ((sp->fcp->fcp_cntl.cntl_kill_tsk |
6804		    sp->fcp->fcp_cntl.cntl_clr_aca |
6805		    sp->fcp->fcp_cntl.cntl_reset_tgt |
6806		    sp->fcp->fcp_cntl.cntl_reset_lun |
6807		    sp->fcp->fcp_cntl.cntl_clr_tsk |
6808		    sp->fcp->fcp_cntl.cntl_abort_tsk) != 0) {
6809			ql_task_mgmt(ha, tq, pkt, sp);
6810		} else {
6811			ha->pha->xioctl->IosRequested++;
6812			ha->pha->xioctl->BytesRequested += (uint32_t)
6813			    sp->fcp->fcp_data_len;
6814
6815			/*
6816			 * Setup for commands with data transfer
6817			 */
6818			sp->iocb = ha->fcp_cmd;
6819			if (sp->fcp->fcp_data_len != 0) {
6820				/*
6821				 * FCP data is bound to pkt_data_dma
6822				 */
6823				if (sp->fcp->fcp_cntl.cntl_write_data) {
6824					(void) ddi_dma_sync(pkt->pkt_data_dma,
6825					    0, 0, DDI_DMA_SYNC_FORDEV);
6826				}
6827
6828				/* Setup IOCB count. */
6829				if (pkt->pkt_data_cookie_cnt > ha->cmd_segs) {
6830					uint32_t	cnt;
6831
6832					cnt = pkt->pkt_data_cookie_cnt -
6833					    ha->cmd_segs;
6834					sp->req_cnt = (uint16_t)
6835					    (cnt / ha->cmd_cont_segs);
6836					if (cnt % ha->cmd_cont_segs) {
6837						sp->req_cnt = (uint16_t)
6838						    (sp->req_cnt + 2);
6839					} else {
6840						sp->req_cnt++;
6841					}
6842				} else {
6843					sp->req_cnt = 1;
6844				}
6845			} else {
6846				sp->req_cnt = 1;
6847			}
6848			QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6849
6850			return (ql_start_cmd(ha, tq, pkt, sp));
6851		}
6852	} else {
6853		pkt->pkt_state = FC_PKT_LOCAL_RJT;
6854		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
6855
6856		if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp)
6857			ql_awaken_task_daemon(ha, sp, 0, 0);
6858	}
6859
6860	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6861
6862	return (FC_SUCCESS);
6863}
6864
6865/*
6866 * ql_task_mgmt
6867 *	Task management function processor.
6868 *
6869 * Input:
6870 *	ha:	adapter state pointer.
6871 *	tq:	target queue pointer.
6872 *	pkt:	pointer to fc_packet.
6873 *	sp:	SRB pointer.
6874 *
6875 * Context:
6876 *	Kernel context.
6877 */
6878static void
6879ql_task_mgmt(ql_adapter_state_t *ha, ql_tgt_t *tq, fc_packet_t *pkt,
6880    ql_srb_t *sp)
6881{
6882	fcp_rsp_t		*fcpr;
6883	struct fcp_rsp_info	*rsp;
6884	uint16_t		lun;
6885
6886	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6887
6888	fcpr = (fcp_rsp_t *)pkt->pkt_resp;
6889	rsp = (struct fcp_rsp_info *)pkt->pkt_resp + sizeof (fcp_rsp_t);
6890
6891	bzero(fcpr, pkt->pkt_rsplen);
6892
6893	fcpr->fcp_u.fcp_status.rsp_len_set = 1;
6894	fcpr->fcp_response_len = 8;
6895	lun = CHAR_TO_SHORT(lobyte(sp->fcp->fcp_ent_addr.ent_addr_0),
6896	    hibyte(sp->fcp->fcp_ent_addr.ent_addr_0));
6897
6898	if (sp->fcp->fcp_cntl.cntl_clr_aca) {
6899		if (ql_clear_aca(ha, tq, lun) != QL_SUCCESS) {
6900			rsp->rsp_code = FCP_TASK_MGMT_FAILED;
6901		}
6902	} else if (sp->fcp->fcp_cntl.cntl_reset_lun) {
6903		if (ql_lun_reset(ha, tq, lun) != QL_SUCCESS) {
6904			rsp->rsp_code = FCP_TASK_MGMT_FAILED;
6905		}
6906	} else if (sp->fcp->fcp_cntl.cntl_reset_tgt) {
6907		if (ql_target_reset(ha, tq, ha->loop_reset_delay) !=
6908		    QL_SUCCESS) {
6909			rsp->rsp_code = FCP_TASK_MGMT_FAILED;
6910		}
6911	} else if (sp->fcp->fcp_cntl.cntl_clr_tsk) {
6912		if (ql_clear_task_set(ha, tq, lun) != QL_SUCCESS) {
6913			rsp->rsp_code = FCP_TASK_MGMT_FAILED;
6914		}
6915	} else if (sp->fcp->fcp_cntl.cntl_abort_tsk) {
6916		if (ql_abort_task_set(ha, tq, lun) != QL_SUCCESS) {
6917			rsp->rsp_code = FCP_TASK_MGMT_FAILED;
6918		}
6919	} else {
6920		rsp->rsp_code = FCP_TASK_MGMT_NOT_SUPPTD;
6921	}
6922
6923	pkt->pkt_state = FC_PKT_SUCCESS;
6924
6925	/* Do command callback. */
6926	if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
6927		ql_awaken_task_daemon(ha, sp, 0, 0);
6928	}
6929
6930	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6931}
6932
6933/*
6934 * ql_fcp_ip_cmd
6935 *	Process fibre channel (FCP) Internet (IP) protocols commands.
6936 *
6937 * Input:
6938 *	ha:	adapter state pointer.
6939 *	pkt:	pointer to fc_packet.
6940 *	sp:	SRB pointer.
6941 *
6942 * Returns:
6943 *	FC_SUCCESS - the packet was accepted for transport.
6944 *	FC_TRANSPORT_ERROR - a transport error occurred.
6945 *
6946 * Context:
6947 *	Kernel context.
6948 */
6949static int
6950ql_fcp_ip_cmd(ql_adapter_state_t *ha, fc_packet_t *pkt, ql_srb_t *sp)
6951{
6952	port_id_t	d_id;
6953	ql_tgt_t	*tq;
6954
6955	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
6956
6957	tq = (ql_tgt_t *)pkt->pkt_fca_device;
6958	if (tq == NULL) {
6959		d_id.r.rsvd_1 = 0;
6960		d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
6961		tq = ql_d_id_to_queue(ha, d_id);
6962	}
6963
6964	if (tq != NULL && (sp->lun_queue = ql_lun_queue(ha, tq, 0)) != NULL) {
6965		/*
6966		 * IP data is bound to pkt_cmd_dma
6967		 */
6968		(void) ddi_dma_sync(pkt->pkt_cmd_dma,
6969		    0, 0, DDI_DMA_SYNC_FORDEV);
6970
6971		/* Setup IOCB count. */
6972		sp->iocb = ha->ip_cmd;
6973		if (pkt->pkt_cmd_cookie_cnt > ha->cmd_segs) {
6974			uint32_t	cnt;
6975
6976			cnt = pkt->pkt_cmd_cookie_cnt - ha->cmd_segs;
6977			sp->req_cnt = (uint16_t)(cnt / ha->cmd_cont_segs);
6978			if (cnt % ha->cmd_cont_segs) {
6979				sp->req_cnt = (uint16_t)(sp->req_cnt + 2);
6980			} else {
6981				sp->req_cnt++;
6982			}
6983		} else {
6984			sp->req_cnt = 1;
6985		}
6986		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6987
6988		return (ql_start_cmd(ha, tq, pkt, sp));
6989	} else {
6990		pkt->pkt_state = FC_PKT_LOCAL_RJT;
6991		pkt->pkt_reason = FC_REASON_NO_CONNECTION;
6992
6993		if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp)
6994			ql_awaken_task_daemon(ha, sp, 0, 0);
6995	}
6996
6997	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
6998
6999	return (FC_SUCCESS);
7000}
7001
7002/*
7003 * ql_fc_services
7004 *	Process fibre channel services (name server).
7005 *
7006 * Input:
7007 *	ha:	adapter state pointer.
7008 *	pkt:	pointer to fc_packet.
7009 *
7010 * Returns:
7011 *	FC_SUCCESS - the packet was accepted for transport.
7012 *	FC_TRANSPORT_ERROR - a transport error occurred.
7013 *
7014 * Context:
7015 *	Kernel context.
7016 */
7017static int
7018ql_fc_services(ql_adapter_state_t *ha, fc_packet_t *pkt)
7019{
7020	uint32_t	cnt;
7021	fc_ct_header_t	hdr;
7022	la_els_rjt_t	rjt;
7023	port_id_t	d_id;
7024	ql_tgt_t	*tq;
7025	ql_srb_t	*sp;
7026	int		rval;
7027
7028	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7029
7030	ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&hdr,
7031	    (uint8_t *)pkt->pkt_cmd, sizeof (hdr), DDI_DEV_AUTOINCR);
7032
7033	bzero(&rjt, sizeof (rjt));
7034
7035	/* Do some sanity checks */
7036	cnt = (uint32_t)((uint32_t)(hdr.ct_aiusize * 4) +
7037	    sizeof (fc_ct_header_t));
7038	if (cnt > (uint32_t)pkt->pkt_rsplen) {
7039		EL(ha, "FC_ELS_MALFORMED, cnt=%xh, size=%xh\n", cnt,
7040		    pkt->pkt_rsplen);
7041		return (FC_ELS_MALFORMED);
7042	}
7043
7044	switch (hdr.ct_fcstype) {
7045	case FCSTYPE_DIRECTORY:
7046	case FCSTYPE_MGMTSERVICE:
7047		/* An FCA must make sure that the header is in big endian */
7048		ql_cthdr_endian(pkt->pkt_cmd_acc, pkt->pkt_cmd, B_FALSE);
7049
7050		d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
7051		tq = ql_d_id_to_queue(ha, d_id);
7052		sp = (ql_srb_t *)pkt->pkt_fca_private;
7053		if (tq == NULL ||
7054		    (sp->lun_queue = ql_lun_queue(ha, tq, 0)) == NULL) {
7055			pkt->pkt_state = FC_PKT_LOCAL_RJT;
7056			pkt->pkt_reason = FC_REASON_NO_CONNECTION;
7057			rval = QL_SUCCESS;
7058			break;
7059		}
7060
7061		/*
7062		 * Services data is bound to pkt_cmd_dma
7063		 */
7064		(void) ddi_dma_sync(pkt->pkt_cmd_dma, 0, 0,
7065		    DDI_DMA_SYNC_FORDEV);
7066
7067		sp->flags |= SRB_MS_PKT;
7068		sp->retry_count = 32;
7069
7070		/* Setup IOCB count. */
7071		sp->iocb = ha->ms_cmd;
7072		if (pkt->pkt_resp_cookie_cnt > MS_DATA_SEGMENTS) {
7073			cnt = pkt->pkt_resp_cookie_cnt - MS_DATA_SEGMENTS;
7074			sp->req_cnt =
7075			    (uint16_t)(cnt / CONT_TYPE_1_DATA_SEGMENTS);
7076			if (cnt % CONT_TYPE_1_DATA_SEGMENTS) {
7077				sp->req_cnt = (uint16_t)(sp->req_cnt + 2);
7078			} else {
7079				sp->req_cnt++;
7080			}
7081		} else {
7082			sp->req_cnt = 1;
7083		}
7084		rval = ql_start_cmd(ha, tq, pkt, sp);
7085
7086		QL_PRINT_3(CE_CONT, "(%d): done, ql_start_cmd=%xh\n",
7087		    ha->instance, rval);
7088
7089		return (rval);
7090
7091	default:
7092		EL(ha, "unknown fcstype=%xh\n", hdr.ct_fcstype);
7093		rval = QL_FUNCTION_PARAMETER_ERROR;
7094		break;
7095	}
7096
7097	if (rval != QL_SUCCESS) {
7098		/* Build RJT. */
7099		rjt.ls_code.ls_code = LA_ELS_RJT;
7100		rjt.reason = FC_REASON_CMD_UNSUPPORTED;
7101
7102		ddi_rep_put8(pkt->pkt_resp_acc, (uint8_t *)&rjt,
7103		    (uint8_t *)pkt->pkt_resp, sizeof (rjt), DDI_DEV_AUTOINCR);
7104
7105		pkt->pkt_state = FC_PKT_LOCAL_RJT;
7106		pkt->pkt_reason = FC_REASON_UNSUPPORTED;
7107		EL(ha, "LA_ELS_RJT, FC_REASON_UNSUPPORTED\n");
7108	}
7109
7110	/* Do command callback. */
7111	if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) && pkt->pkt_comp) {
7112		ql_awaken_task_daemon(ha, (ql_srb_t *)pkt->pkt_fca_private,
7113		    0, 0);
7114	}
7115
7116	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7117
7118	return (FC_SUCCESS);
7119}
7120
7121/*
7122 * ql_cthdr_endian
7123 *	Change endianess of ct passthrough header and payload.
7124 *
7125 * Input:
7126 *	acc_handle:	DMA buffer access handle.
7127 *	ct_hdr:		Pointer to header.
7128 *	restore:	Restore first flag.
7129 *
7130 * Context:
7131 *	Interrupt or Kernel context, no mailbox commands allowed.
7132 */
7133void
7134ql_cthdr_endian(ddi_acc_handle_t acc_handle, caddr_t ct_hdr,
7135    boolean_t restore)
7136{
7137	uint8_t		i, *bp;
7138	fc_ct_header_t	hdr;
7139	uint32_t	*hdrp = (uint32_t *)&hdr;
7140
7141	ddi_rep_get8(acc_handle, (uint8_t *)&hdr,
7142	    (uint8_t *)ct_hdr, sizeof (hdr), DDI_DEV_AUTOINCR);
7143
7144	if (restore) {
7145		for (i = 0; i < ((sizeof (hdr)) / (sizeof (uint32_t))); i++) {
7146			*hdrp = BE_32(*hdrp);
7147			hdrp++;
7148		}
7149	}
7150
7151	if (hdr.ct_fcstype == FCSTYPE_DIRECTORY) {
7152		bp = (uint8_t *)ct_hdr + sizeof (fc_ct_header_t);
7153
7154		switch (hdr.ct_cmdrsp) {
7155		case NS_GA_NXT:
7156		case NS_GPN_ID:
7157		case NS_GNN_ID:
7158		case NS_GCS_ID:
7159		case NS_GFT_ID:
7160		case NS_GSPN_ID:
7161		case NS_GPT_ID:
7162		case NS_GID_FT:
7163		case NS_GID_PT:
7164		case NS_RPN_ID:
7165		case NS_RNN_ID:
7166		case NS_RSPN_ID:
7167		case NS_DA_ID:
7168			BIG_ENDIAN_32(bp);
7169			break;
7170		case NS_RFT_ID:
7171		case NS_RCS_ID:
7172		case NS_RPT_ID:
7173			BIG_ENDIAN_32(bp);
7174			bp += 4;
7175			BIG_ENDIAN_32(bp);
7176			break;
7177		case NS_GNN_IP:
7178		case NS_GIPA_IP:
7179			BIG_ENDIAN(bp, 16);
7180			break;
7181		case NS_RIP_NN:
7182			bp += 8;
7183			BIG_ENDIAN(bp, 16);
7184			break;
7185		case NS_RIPA_NN:
7186			bp += 8;
7187			BIG_ENDIAN_64(bp);
7188			break;
7189		default:
7190			break;
7191		}
7192	}
7193
7194	if (restore == B_FALSE) {
7195		for (i = 0; i < ((sizeof (hdr)) / (sizeof (uint32_t))); i++) {
7196			*hdrp = BE_32(*hdrp);
7197			hdrp++;
7198		}
7199	}
7200
7201	ddi_rep_put8(acc_handle, (uint8_t *)&hdr,
7202	    (uint8_t *)ct_hdr, sizeof (hdr), DDI_DEV_AUTOINCR);
7203}
7204
7205/*
7206 * ql_start_cmd
7207 *	Finishes starting fibre channel protocol (FCP) command.
7208 *
7209 * Input:
7210 *	ha:	adapter state pointer.
7211 *	tq:	target queue pointer.
7212 *	pkt:	pointer to fc_packet.
7213 *	sp:	SRB pointer.
7214 *
7215 * Context:
7216 *	Kernel context.
7217 */
7218static int
7219ql_start_cmd(ql_adapter_state_t *ha, ql_tgt_t *tq, fc_packet_t *pkt,
7220    ql_srb_t *sp)
7221{
7222	int		rval = FC_SUCCESS;
7223	time_t		poll_wait = 0;
7224	ql_lun_t	*lq = sp->lun_queue;
7225
7226	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7227
7228	sp->handle = 0;
7229
7230	/* Set poll for finish. */
7231	if (pkt->pkt_tran_flags & FC_TRAN_NO_INTR) {
7232		sp->flags |= SRB_POLL;
7233		if (pkt->pkt_timeout == 0) {
7234			pkt->pkt_timeout = SCSI_POLL_TIMEOUT;
7235		}
7236	}
7237
7238	/* Acquire device queue lock. */
7239	DEVICE_QUEUE_LOCK(tq);
7240
7241	/*
7242	 * If we need authentication, report device busy to
7243	 * upper layers to retry later
7244	 */
7245	if (tq->flags & (TQF_RSCN_RCVD | TQF_NEED_AUTHENTICATION)) {
7246		DEVICE_QUEUE_UNLOCK(tq);
7247		EL(ha, "failed, FC_DEVICE_BUSY=%xh, d_id=%xh\n", tq->flags,
7248		    tq->d_id.b24);
7249		return (FC_DEVICE_BUSY);
7250	}
7251
7252	/* Insert command onto watchdog queue. */
7253	if (!(pkt->pkt_tran_flags & FC_TRAN_DUMPING)) {
7254		ql_timeout_insert(ha, tq, sp);
7255	} else {
7256		/*
7257		 * Run dump requests in polled mode as kernel threads
7258		 * and interrupts may have been disabled.
7259		 */
7260		sp->flags |= SRB_POLL;
7261		sp->init_wdg_q_time = 0;
7262		sp->isp_timeout = 0;
7263	}
7264
7265	/* If a polling command setup wait time. */
7266	if (sp->flags & SRB_POLL) {
7267		if (sp->flags & SRB_WATCHDOG_ENABLED) {
7268			poll_wait = (sp->wdg_q_time + 2) * WATCHDOG_TIME;
7269		} else {
7270			poll_wait = pkt->pkt_timeout;
7271		}
7272	}
7273
7274	if (ha->pha->flags & ABORT_CMDS_LOOP_DOWN_TMO &&
7275	    (CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING))) {
7276		/* Set ending status. */
7277		sp->pkt->pkt_reason = CS_PORT_UNAVAILABLE;
7278
7279		/* Call done routine to handle completions. */
7280		sp->cmd.next = NULL;
7281		DEVICE_QUEUE_UNLOCK(tq);
7282		ql_done(&sp->cmd);
7283	} else {
7284		if (ddi_in_panic() && (sp->flags & SRB_POLL)) {
7285			int do_lip = 0;
7286
7287			DEVICE_QUEUE_UNLOCK(tq);
7288
7289			ADAPTER_STATE_LOCK(ha);
7290			if ((do_lip = ha->pha->lip_on_panic) == 0) {
7291				ha->pha->lip_on_panic++;
7292			}
7293			ADAPTER_STATE_UNLOCK(ha);
7294
7295			if (!do_lip) {
7296
7297				/*
7298				 * That Qlogic F/W performs PLOGI, PRLI, etc
7299				 * is helpful here. If a PLOGI fails for some
7300				 * reason, you would get CS_PORT_LOGGED_OUT
7301				 * or some such error; and we should get a
7302				 * careful polled mode login kicked off inside
7303				 * of this driver itself. You don't have FC
7304				 * transport's services as all threads are
7305				 * suspended, interrupts disabled, and so
7306				 * on. Right now we do re-login if the packet
7307				 * state isn't FC_PKT_SUCCESS.
7308				 */
7309				(void) ql_abort_isp(ha);
7310			}
7311
7312			ql_start_iocb(ha, sp);
7313		} else {
7314			/* Add the command to the device queue */
7315			if (pkt->pkt_tran_flags & FC_TRAN_HI_PRIORITY) {
7316				ql_add_link_t(&lq->cmd, &sp->cmd);
7317			} else {
7318				ql_add_link_b(&lq->cmd, &sp->cmd);
7319			}
7320
7321			sp->flags |= SRB_IN_DEVICE_QUEUE;
7322
7323			/* Check whether next message can be processed */
7324			ql_next(ha, lq);
7325		}
7326	}
7327
7328	/* If polling, wait for finish. */
7329	if (poll_wait) {
7330		if (ql_poll_cmd(ha, sp, poll_wait) != QL_SUCCESS) {
7331			int	res;
7332
7333			res = ql_abort((opaque_t)ha, pkt, 0);
7334			if (res != FC_SUCCESS && res != FC_ABORTED) {
7335				DEVICE_QUEUE_LOCK(tq);
7336				ql_remove_link(&lq->cmd, &sp->cmd);
7337				sp->flags &= ~SRB_IN_DEVICE_QUEUE;
7338				DEVICE_QUEUE_UNLOCK(tq);
7339			}
7340		}
7341
7342		if (pkt->pkt_state != FC_PKT_SUCCESS) {
7343			EL(ha, "failed, FC_TRANSPORT_ERROR\n");
7344			rval = FC_TRANSPORT_ERROR;
7345		}
7346
7347		if (ddi_in_panic()) {
7348			if (pkt->pkt_state != FC_PKT_SUCCESS) {
7349				port_id_t d_id;
7350
7351				/*
7352				 * successful LOGIN implies by design
7353				 * that PRLI also succeeded for disks
7354				 * Note also that there is no special
7355				 * mailbox command to send PRLI.
7356				 */
7357				d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
7358				(void) ql_login_port(ha, d_id);
7359			}
7360		}
7361
7362		/*
7363		 * This should only happen during CPR dumping
7364		 */
7365		if (!(pkt->pkt_tran_flags & FC_TRAN_NO_INTR) &&
7366		    pkt->pkt_comp) {
7367			sp->flags &= ~SRB_POLL;
7368			(*pkt->pkt_comp)(pkt);
7369		}
7370	}
7371
7372	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7373
7374	return (rval);
7375}
7376
7377/*
7378 * ql_poll_cmd
7379 *	Polls commands for completion.
7380 *
7381 * Input:
7382 *	ha = adapter state pointer.
7383 *	sp = SRB command pointer.
7384 *	poll_wait = poll wait time in seconds.
7385 *
7386 * Returns:
7387 *	QL local function return status code.
7388 *
7389 * Context:
7390 *	Kernel context.
7391 */
7392static int
7393ql_poll_cmd(ql_adapter_state_t *vha, ql_srb_t *sp, time_t poll_wait)
7394{
7395	int			rval = QL_SUCCESS;
7396	time_t			msecs_left = poll_wait * 100;	/* 10ms inc */
7397	ql_adapter_state_t	*ha = vha->pha;
7398
7399	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7400
7401	while (sp->flags & SRB_POLL) {
7402
7403		if ((ha->flags & INTERRUPTS_ENABLED) == 0 ||
7404		    ha->idle_timer >= 15 || ddi_in_panic()) {
7405
7406			/* If waiting for restart, do it now. */
7407			if (ha->port_retry_timer != 0) {
7408				ADAPTER_STATE_LOCK(ha);
7409				ha->port_retry_timer = 0;
7410				ADAPTER_STATE_UNLOCK(ha);
7411
7412				TASK_DAEMON_LOCK(ha);
7413				ha->task_daemon_flags |= PORT_RETRY_NEEDED;
7414				TASK_DAEMON_UNLOCK(ha);
7415			}
7416
7417			if ((CFG_IST(ha, CFG_CTRL_242581) ?
7418			    RD32_IO_REG(ha, istatus) :
7419			    RD16_IO_REG(ha, istatus)) & RISC_INT) {
7420				(void) ql_isr((caddr_t)ha);
7421				INTR_LOCK(ha);
7422				ha->intr_claimed = TRUE;
7423				INTR_UNLOCK(ha);
7424			}
7425
7426			/*
7427			 * Call task thread function in case the
7428			 * daemon is not running.
7429			 */
7430			TASK_DAEMON_LOCK(ha);
7431
7432			if (!ddi_in_panic() && QL_DAEMON_NOT_ACTIVE(ha) &&
7433			    QL_TASK_PENDING(ha)) {
7434				ha->task_daemon_flags |= TASK_THREAD_CALLED;
7435				ql_task_thread(ha);
7436				ha->task_daemon_flags &= ~TASK_THREAD_CALLED;
7437			}
7438
7439			TASK_DAEMON_UNLOCK(ha);
7440		}
7441
7442		if (msecs_left < 10) {
7443			rval = QL_FUNCTION_TIMEOUT;
7444			break;
7445		}
7446
7447		/*
7448		 * Polling interval is 10 milli seconds; Increasing
7449		 * the polling interval to seconds since disk IO
7450		 * timeout values are ~60 seconds is tempting enough,
7451		 * but CPR dump time increases, and so will the crash
7452		 * dump time; Don't toy with the settings without due
7453		 * consideration for all the scenarios that will be
7454		 * impacted.
7455		 */
7456		ql_delay(ha, 10000);
7457		msecs_left -= 10;
7458	}
7459
7460	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7461
7462	return (rval);
7463}
7464
7465/*
7466 * ql_next
7467 *	Retrieve and process next job in the device queue.
7468 *
7469 * Input:
7470 *	ha:	adapter state pointer.
7471 *	lq:	LUN queue pointer.
7472 *	DEVICE_QUEUE_LOCK must be already obtained.
7473 *
7474 * Output:
7475 *	Releases DEVICE_QUEUE_LOCK upon exit.
7476 *
7477 * Context:
7478 *	Interrupt or Kernel context, no mailbox commands allowed.
7479 */
7480void
7481ql_next(ql_adapter_state_t *vha, ql_lun_t *lq)
7482{
7483	ql_srb_t		*sp;
7484	ql_link_t		*link;
7485	ql_tgt_t		*tq = lq->target_queue;
7486	ql_adapter_state_t	*ha = vha->pha;
7487
7488	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7489
7490	if (ddi_in_panic()) {
7491		DEVICE_QUEUE_UNLOCK(tq);
7492		QL_PRINT_3(CE_CONT, "(%d): panic/active exit\n",
7493		    ha->instance);
7494		return;
7495	}
7496
7497	while ((link = lq->cmd.first) != NULL) {
7498		sp = link->base_address;
7499
7500		/* Exit if can not start commands. */
7501		if (DRIVER_SUSPENDED(ha) ||
7502		    (ha->flags & ONLINE) == 0 ||
7503		    !VALID_DEVICE_ID(ha, tq->loop_id) ||
7504		    sp->flags & SRB_ABORT ||
7505		    tq->flags & (TQF_RSCN_RCVD | TQF_NEED_AUTHENTICATION |
7506		    TQF_QUEUE_SUSPENDED)) {
7507			EL(vha, "break, d_id=%xh, tdf=%xh, tqf=%xh, spf=%xh, "
7508			    "haf=%xh, loop_id=%xh\n", tq->d_id.b24,
7509			    ha->task_daemon_flags, tq->flags, sp->flags,
7510			    ha->flags, tq->loop_id);
7511			break;
7512		}
7513
7514		/*
7515		 * Find out the LUN number for untagged command use.
7516		 * If there is an untagged command pending for the LUN,
7517		 * we would not submit another untagged command
7518		 * or if reached LUN execution throttle.
7519		 */
7520		if (sp->flags & SRB_FCP_CMD_PKT) {
7521			if (lq->flags & LQF_UNTAGGED_PENDING ||
7522			    lq->lun_outcnt >= ha->execution_throttle) {
7523				QL_PRINT_8(CE_CONT, "(%d): break, d_id=%xh, "
7524				    "lf=%xh, lun_outcnt=%xh\n", ha->instance,
7525				    tq->d_id.b24, lq->flags, lq->lun_outcnt);
7526				break;
7527			}
7528			if (sp->fcp->fcp_cntl.cntl_qtype ==
7529			    FCP_QTYPE_UNTAGGED) {
7530				/*
7531				 * Set the untagged-flag for the LUN
7532				 * so that no more untagged commands
7533				 * can be submitted for this LUN.
7534				 */
7535				lq->flags |= LQF_UNTAGGED_PENDING;
7536			}
7537
7538			/* Count command as sent. */
7539			lq->lun_outcnt++;
7540		}
7541
7542		/* Remove srb from device queue. */
7543		ql_remove_link(&lq->cmd, &sp->cmd);
7544		sp->flags &= ~SRB_IN_DEVICE_QUEUE;
7545
7546		tq->outcnt++;
7547
7548		ql_start_iocb(vha, sp);
7549	}
7550
7551	/* Release device queue lock. */
7552	DEVICE_QUEUE_UNLOCK(tq);
7553
7554	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7555}
7556
7557/*
7558 * ql_done
7559 *	Process completed commands.
7560 *
7561 * Input:
7562 *	link:	first command link in chain.
7563 *
7564 * Context:
7565 *	Interrupt or Kernel context, no mailbox commands allowed.
7566 */
7567void
7568ql_done(ql_link_t *link)
7569{
7570	ql_adapter_state_t	*ha;
7571	ql_link_t		*next_link;
7572	ql_srb_t		*sp;
7573	ql_tgt_t		*tq;
7574	ql_lun_t		*lq;
7575
7576	QL_PRINT_3(CE_CONT, "started\n");
7577
7578	for (; link != NULL; link = next_link) {
7579		next_link = link->next;
7580		sp = link->base_address;
7581		ha = sp->ha;
7582
7583		if (sp->flags & SRB_UB_CALLBACK) {
7584			QL_UB_LOCK(ha);
7585			if (sp->flags & SRB_UB_IN_ISP) {
7586				if (ha->ub_outcnt != 0) {
7587					ha->ub_outcnt--;
7588				}
7589				QL_UB_UNLOCK(ha);
7590				ql_isp_rcvbuf(ha);
7591				QL_UB_LOCK(ha);
7592			}
7593			QL_UB_UNLOCK(ha);
7594			ql_awaken_task_daemon(ha, sp, 0, 0);
7595		} else {
7596			/* Free outstanding command slot. */
7597			if (sp->handle != 0) {
7598				ha->outstanding_cmds[
7599				    sp->handle & OSC_INDEX_MASK] = NULL;
7600				sp->handle = 0;
7601				sp->flags &= ~SRB_IN_TOKEN_ARRAY;
7602			}
7603
7604			/* Acquire device queue lock. */
7605			lq = sp->lun_queue;
7606			tq = lq->target_queue;
7607			DEVICE_QUEUE_LOCK(tq);
7608
7609			/* Decrement outstanding commands on device. */
7610			if (tq->outcnt != 0) {
7611				tq->outcnt--;
7612			}
7613
7614			if (sp->flags & SRB_FCP_CMD_PKT) {
7615				if (sp->fcp->fcp_cntl.cntl_qtype ==
7616				    FCP_QTYPE_UNTAGGED) {
7617					/*
7618					 * Clear the flag for this LUN so that
7619					 * untagged commands can be submitted
7620					 * for it.
7621					 */
7622					lq->flags &= ~LQF_UNTAGGED_PENDING;
7623				}
7624
7625				if (lq->lun_outcnt != 0) {
7626					lq->lun_outcnt--;
7627				}
7628			}
7629
7630			/* Reset port down retry count on good completion. */
7631			if (sp->pkt->pkt_reason == CS_COMPLETE) {
7632				tq->port_down_retry_count =
7633				    ha->port_down_retry_count;
7634				tq->qfull_retry_count = ha->qfull_retry_count;
7635			}
7636
7637			/* Place request back on top of target command queue */
7638			if ((sp->flags & (SRB_MS_PKT | SRB_ELS_PKT) ||
7639			    !(tq->flags & TQF_NEED_AUTHENTICATION)) &&
7640			    sp->flags & SRB_RETRY &&
7641			    (sp->flags & SRB_WATCHDOG_ENABLED &&
7642			    sp->wdg_q_time > 1)) {
7643				sp->flags &= ~(SRB_ISP_STARTED |
7644				    SRB_ISP_COMPLETED | SRB_RETRY);
7645
7646				/* Reset watchdog timer */
7647				sp->wdg_q_time = sp->init_wdg_q_time;
7648
7649				/* Issue marker command on reset status. */
7650				if (!(ha->task_daemon_flags & LOOP_DOWN) &&
7651				    (sp->pkt->pkt_reason == CS_RESET ||
7652				    (CFG_IST(ha, CFG_CTRL_242581) &&
7653				    sp->pkt->pkt_reason == CS_ABORTED))) {
7654					(void) ql_marker(ha, tq->loop_id, 0,
7655					    MK_SYNC_ID);
7656				}
7657
7658				ql_add_link_t(&lq->cmd, &sp->cmd);
7659				sp->flags |= SRB_IN_DEVICE_QUEUE;
7660				ql_next(ha, lq);
7661			} else {
7662				/* Remove command from watchdog queue. */
7663				if (sp->flags & SRB_WATCHDOG_ENABLED) {
7664					ql_remove_link(&tq->wdg, &sp->wdg);
7665					sp->flags &= ~SRB_WATCHDOG_ENABLED;
7666				}
7667
7668				if (lq->cmd.first != NULL) {
7669					ql_next(ha, lq);
7670				} else {
7671					/* Release LU queue specific lock. */
7672					DEVICE_QUEUE_UNLOCK(tq);
7673					if (ha->pha->pending_cmds.first !=
7674					    NULL) {
7675						ql_start_iocb(ha, NULL);
7676					}
7677				}
7678
7679				/* Sync buffers if required.  */
7680				if (sp->flags & (SRB_MS_PKT | SRB_ELS_PKT)) {
7681					(void) ddi_dma_sync(
7682					    sp->pkt->pkt_resp_dma,
7683					    0, 0, DDI_DMA_SYNC_FORCPU);
7684				}
7685
7686				/* Map ISP completion codes. */
7687				sp->pkt->pkt_expln = FC_EXPLN_NONE;
7688				sp->pkt->pkt_action = FC_ACTION_RETRYABLE;
7689				switch (sp->pkt->pkt_reason) {
7690				case CS_COMPLETE:
7691					sp->pkt->pkt_state = FC_PKT_SUCCESS;
7692					break;
7693				case CS_RESET:
7694					/* Issue marker command. */
7695					if (!(ha->task_daemon_flags &
7696					    LOOP_DOWN)) {
7697						(void) ql_marker(ha,
7698						    tq->loop_id, 0,
7699						    MK_SYNC_ID);
7700					}
7701					sp->pkt->pkt_state =
7702					    FC_PKT_PORT_OFFLINE;
7703					sp->pkt->pkt_reason =
7704					    FC_REASON_ABORTED;
7705					break;
7706				case CS_RESOUCE_UNAVAILABLE:
7707					sp->pkt->pkt_state = FC_PKT_LOCAL_BSY;
7708					sp->pkt->pkt_reason =
7709					    FC_REASON_PKT_BUSY;
7710					break;
7711
7712				case CS_TIMEOUT:
7713					sp->pkt->pkt_state = FC_PKT_TIMEOUT;
7714					sp->pkt->pkt_reason =
7715					    FC_REASON_HW_ERROR;
7716					break;
7717				case CS_DATA_OVERRUN:
7718					sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
7719					sp->pkt->pkt_reason =
7720					    FC_REASON_OVERRUN;
7721					break;
7722				case CS_PORT_UNAVAILABLE:
7723				case CS_PORT_LOGGED_OUT:
7724					sp->pkt->pkt_state =
7725					    FC_PKT_PORT_OFFLINE;
7726					sp->pkt->pkt_reason =
7727					    FC_REASON_LOGIN_REQUIRED;
7728					ql_send_logo(ha, tq, NULL);
7729					break;
7730				case CS_PORT_CONFIG_CHG:
7731					sp->pkt->pkt_state =
7732					    FC_PKT_PORT_OFFLINE;
7733					sp->pkt->pkt_reason =
7734					    FC_REASON_OFFLINE;
7735					break;
7736				case CS_QUEUE_FULL:
7737					sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
7738					sp->pkt->pkt_reason = FC_REASON_QFULL;
7739					break;
7740
7741				case CS_ABORTED:
7742					DEVICE_QUEUE_LOCK(tq);
7743					if (tq->flags & (TQF_RSCN_RCVD |
7744					    TQF_NEED_AUTHENTICATION)) {
7745						sp->pkt->pkt_state =
7746						    FC_PKT_PORT_OFFLINE;
7747						sp->pkt->pkt_reason =
7748						    FC_REASON_LOGIN_REQUIRED;
7749					} else {
7750						sp->pkt->pkt_state =
7751						    FC_PKT_LOCAL_RJT;
7752						sp->pkt->pkt_reason =
7753						    FC_REASON_ABORTED;
7754					}
7755					DEVICE_QUEUE_UNLOCK(tq);
7756					break;
7757
7758				case CS_TRANSPORT:
7759					sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
7760					sp->pkt->pkt_reason =
7761					    FC_PKT_TRAN_ERROR;
7762					break;
7763
7764				case CS_DATA_UNDERRUN:
7765					sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
7766					sp->pkt->pkt_reason =
7767					    FC_REASON_UNDERRUN;
7768					break;
7769				case CS_DMA_ERROR:
7770				case CS_BAD_PAYLOAD:
7771				case CS_UNKNOWN:
7772				case CS_CMD_FAILED:
7773				default:
7774					sp->pkt->pkt_state = FC_PKT_LOCAL_RJT;
7775					sp->pkt->pkt_reason =
7776					    FC_REASON_HW_ERROR;
7777					break;
7778				}
7779
7780				/* Now call the pkt completion callback */
7781				if (sp->flags & SRB_POLL) {
7782					sp->flags &= ~SRB_POLL;
7783				} else if (sp->pkt->pkt_comp) {
7784					if (sp->pkt->pkt_tran_flags &
7785					    FC_TRAN_IMMEDIATE_CB) {
7786						(*sp->pkt->pkt_comp)(sp->pkt);
7787					} else {
7788						ql_awaken_task_daemon(ha, sp,
7789						    0, 0);
7790					}
7791				}
7792			}
7793		}
7794	}
7795
7796	QL_PRINT_3(CE_CONT, "done\n");
7797}
7798
7799/*
7800 * ql_awaken_task_daemon
7801 *	Adds command completion callback to callback queue and/or
7802 *	awakens task daemon thread.
7803 *
7804 * Input:
7805 *	ha:		adapter state pointer.
7806 *	sp:		srb pointer.
7807 *	set_flags:	task daemon flags to set.
7808 *	reset_flags:	task daemon flags to reset.
7809 *
7810 * Context:
7811 *	Interrupt or Kernel context, no mailbox commands allowed.
7812 */
7813void
7814ql_awaken_task_daemon(ql_adapter_state_t *vha, ql_srb_t *sp,
7815    uint32_t set_flags, uint32_t reset_flags)
7816{
7817	ql_adapter_state_t	*ha = vha->pha;
7818
7819	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7820
7821	/* Acquire task daemon lock. */
7822	TASK_DAEMON_LOCK(ha);
7823
7824	if (set_flags & ISP_ABORT_NEEDED) {
7825		if (ha->task_daemon_flags & ABORT_ISP_ACTIVE) {
7826			set_flags &= ~ISP_ABORT_NEEDED;
7827		}
7828	}
7829
7830	ha->task_daemon_flags |= set_flags;
7831	ha->task_daemon_flags &= ~reset_flags;
7832
7833	if (QL_DAEMON_SUSPENDED(ha)) {
7834		if (sp != NULL) {
7835			TASK_DAEMON_UNLOCK(ha);
7836
7837			/* Do callback. */
7838			if (sp->flags & SRB_UB_CALLBACK) {
7839				ql_unsol_callback(sp);
7840			} else {
7841				(*sp->pkt->pkt_comp)(sp->pkt);
7842			}
7843		} else {
7844			if (!(curthread->t_flag & T_INTR_THREAD) &&
7845			    !(ha->task_daemon_flags & TASK_THREAD_CALLED)) {
7846				ha->task_daemon_flags |= TASK_THREAD_CALLED;
7847				ql_task_thread(ha);
7848				ha->task_daemon_flags &= ~TASK_THREAD_CALLED;
7849			}
7850
7851			TASK_DAEMON_UNLOCK(ha);
7852		}
7853	} else {
7854		if (sp != NULL) {
7855			ql_add_link_b(&ha->callback_queue, &sp->cmd);
7856		}
7857
7858		if (ha->task_daemon_flags & TASK_DAEMON_SLEEPING_FLG) {
7859			cv_broadcast(&ha->cv_task_daemon);
7860		}
7861		TASK_DAEMON_UNLOCK(ha);
7862	}
7863
7864	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7865}
7866
7867/*
7868 * ql_task_daemon
7869 *	Thread that is awaken by the driver when a
7870 *	background needs to be done.
7871 *
7872 * Input:
7873 *	arg = adapter state pointer.
7874 *
7875 * Context:
7876 *	Kernel context.
7877 */
7878static void
7879ql_task_daemon(void *arg)
7880{
7881	ql_adapter_state_t	*ha = (void *)arg;
7882
7883	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
7884
7885	CALLB_CPR_INIT(&ha->cprinfo, &ha->task_daemon_mutex, callb_generic_cpr,
7886	    "ql_task_daemon");
7887
7888	/* Acquire task daemon lock. */
7889	TASK_DAEMON_LOCK(ha);
7890
7891	ha->task_daemon_flags |= TASK_DAEMON_ALIVE_FLG;
7892
7893	while ((ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) == 0) {
7894		ql_task_thread(ha);
7895
7896		QL_PRINT_3(CE_CONT, "(%d): Going to sleep\n", ha->instance);
7897
7898		/*
7899		 * Before we wait on the conditional variable, we
7900		 * need to check if STOP_FLG is set for us to terminate
7901		 */
7902		if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
7903			break;
7904		}
7905
7906		/*LINTED [Solaris CALLB_CPR_SAFE_BEGIN Lint error]*/
7907		CALLB_CPR_SAFE_BEGIN(&ha->cprinfo);
7908
7909		ha->task_daemon_flags |= TASK_DAEMON_SLEEPING_FLG;
7910
7911		/* If killed, stop task daemon */
7912		if (cv_wait_sig(&ha->cv_task_daemon,
7913		    &ha->task_daemon_mutex) == 0) {
7914			ha->task_daemon_flags |= TASK_DAEMON_STOP_FLG;
7915		}
7916
7917		ha->task_daemon_flags &= ~TASK_DAEMON_SLEEPING_FLG;
7918
7919		/*LINTED [Solaris CALLB_CPR_SAFE_END Lint error]*/
7920		CALLB_CPR_SAFE_END(&ha->cprinfo, &ha->task_daemon_mutex);
7921
7922		QL_PRINT_3(CE_CONT, "(%d): Awakened\n", ha->instance);
7923	}
7924
7925	ha->task_daemon_flags &= ~(TASK_DAEMON_STOP_FLG |
7926	    TASK_DAEMON_ALIVE_FLG);
7927
7928	/*LINTED [Solaris CALLB_CPR_EXIT Lint error]*/
7929	CALLB_CPR_EXIT(&ha->cprinfo);
7930
7931	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
7932
7933	thread_exit();
7934}
7935
7936/*
7937 * ql_task_thread
7938 *	Thread run by daemon.
7939 *
7940 * Input:
7941 *	ha = adapter state pointer.
7942 *	TASK_DAEMON_LOCK must be acquired prior to call.
7943 *
7944 * Context:
7945 *	Kernel context.
7946 */
7947static void
7948ql_task_thread(ql_adapter_state_t *ha)
7949{
7950	int			loop_again, rval;
7951	ql_srb_t		*sp;
7952	ql_head_t		*head;
7953	ql_link_t		*link;
7954	caddr_t			msg;
7955	ql_adapter_state_t	*vha;
7956
7957	do {
7958		QL_PRINT_3(CE_CONT, "(%d): task_daemon_flags=%xh\n",
7959		    ha->instance, ha->task_daemon_flags);
7960
7961		loop_again = FALSE;
7962
7963		QL_PM_LOCK(ha);
7964		if (ha->power_level != PM_LEVEL_D0) {
7965			QL_PM_UNLOCK(ha);
7966			ha->task_daemon_flags |= TASK_DAEMON_STALLED_FLG;
7967			break;
7968		}
7969		QL_PM_UNLOCK(ha);
7970
7971		/* IDC acknowledge needed. */
7972		if (ha->task_daemon_flags & IDC_ACK_NEEDED) {
7973			ha->task_daemon_flags &= ~IDC_ACK_NEEDED;
7974			ADAPTER_STATE_LOCK(ha);
7975			switch (ha->idc_mb[2]) {
7976			case IDC_OPC_DRV_START:
7977				if (ha->idc_restart_mpi != 0) {
7978					ha->idc_restart_mpi--;
7979					if (ha->idc_restart_mpi == 0) {
7980						ha->restart_mpi_timer = 0;
7981						ha->task_daemon_flags &=
7982						    ~TASK_DAEMON_STALLED_FLG;
7983					}
7984				}
7985				if (ha->idc_flash_acc != 0) {
7986					ha->idc_flash_acc--;
7987					if (ha->idc_flash_acc == 0) {
7988						ha->flash_acc_timer = 0;
7989						GLOBAL_HW_LOCK();
7990					}
7991				}
7992				break;
7993			case IDC_OPC_FLASH_ACC:
7994				ha->flash_acc_timer = 30;
7995				if (ha->idc_flash_acc == 0) {
7996					GLOBAL_HW_UNLOCK();
7997				}
7998				ha->idc_flash_acc++;
7999				break;
8000			case IDC_OPC_RESTART_MPI:
8001				ha->restart_mpi_timer = 30;
8002				ha->idc_restart_mpi++;
8003				ha->task_daemon_flags |=
8004				    TASK_DAEMON_STALLED_FLG;
8005				break;
8006			default:
8007				EL(ha, "Unknown IDC opcode=%xh\n",
8008				    ha->idc_mb[2]);
8009				break;
8010			}
8011			ADAPTER_STATE_UNLOCK(ha);
8012
8013			if (ha->idc_mb[1] & IDC_TIMEOUT_MASK) {
8014				TASK_DAEMON_UNLOCK(ha);
8015				rval = ql_idc_ack(ha);
8016				if (rval != QL_SUCCESS) {
8017					EL(ha, "idc_ack status=%xh\n", rval);
8018				}
8019				TASK_DAEMON_LOCK(ha);
8020				loop_again = TRUE;
8021			}
8022		}
8023
8024		if (ha->flags & ADAPTER_SUSPENDED ||
8025		    ha->task_daemon_flags & (TASK_DAEMON_STOP_FLG |
8026		    DRIVER_STALL) ||
8027		    (ha->flags & ONLINE) == 0) {
8028			ha->task_daemon_flags |= TASK_DAEMON_STALLED_FLG;
8029			break;
8030		}
8031		ha->task_daemon_flags &= ~TASK_DAEMON_STALLED_FLG;
8032
8033		if (ha->task_daemon_flags & ISP_ABORT_NEEDED) {
8034			TASK_DAEMON_UNLOCK(ha);
8035			ql_port_state(ha, FC_STATE_OFFLINE, FC_STATE_CHANGE);
8036			TASK_DAEMON_LOCK(ha);
8037			loop_again = TRUE;
8038		}
8039
8040		/* Idle Check. */
8041		if (ha->task_daemon_flags & TASK_DAEMON_IDLE_CHK_FLG) {
8042			ha->task_daemon_flags &= ~TASK_DAEMON_IDLE_CHK_FLG;
8043			if (!(ha->task_daemon_flags & QL_SUSPENDED)) {
8044				TASK_DAEMON_UNLOCK(ha);
8045				ql_idle_check(ha);
8046				TASK_DAEMON_LOCK(ha);
8047				loop_again = TRUE;
8048			}
8049		}
8050
8051		/* Crystal+ port#0 bypass transition */
8052		if (ha->task_daemon_flags & HANDLE_PORT_BYPASS_CHANGE) {
8053			ha->task_daemon_flags &= ~HANDLE_PORT_BYPASS_CHANGE;
8054			TASK_DAEMON_UNLOCK(ha);
8055			(void) ql_initiate_lip(ha);
8056			TASK_DAEMON_LOCK(ha);
8057			loop_again = TRUE;
8058		}
8059
8060		/* Abort queues needed. */
8061		if (ha->task_daemon_flags & ABORT_QUEUES_NEEDED) {
8062			ha->task_daemon_flags &= ~ABORT_QUEUES_NEEDED;
8063			TASK_DAEMON_UNLOCK(ha);
8064			ql_abort_queues(ha);
8065			TASK_DAEMON_LOCK(ha);
8066		}
8067
8068		/* Not suspended, awaken waiting routines. */
8069		if (!(ha->task_daemon_flags & QL_SUSPENDED) &&
8070		    ha->task_daemon_flags & SUSPENDED_WAKEUP_FLG) {
8071			ha->task_daemon_flags &= ~SUSPENDED_WAKEUP_FLG;
8072			cv_broadcast(&ha->cv_dr_suspended);
8073			loop_again = TRUE;
8074		}
8075
8076		/* Handle RSCN changes. */
8077		for (vha = ha; vha != NULL; vha = vha->vp_next) {
8078			if (vha->task_daemon_flags & RSCN_UPDATE_NEEDED) {
8079				vha->task_daemon_flags &= ~RSCN_UPDATE_NEEDED;
8080				TASK_DAEMON_UNLOCK(ha);
8081				(void) ql_handle_rscn_update(vha);
8082				TASK_DAEMON_LOCK(ha);
8083				loop_again = TRUE;
8084			}
8085		}
8086
8087		/* Handle state changes. */
8088		for (vha = ha; vha != NULL; vha = vha->vp_next) {
8089			if (vha->task_daemon_flags & FC_STATE_CHANGE &&
8090			    !(ha->task_daemon_flags &
8091			    TASK_DAEMON_POWERING_DOWN)) {
8092				/* Report state change. */
8093				EL(vha, "state change = %xh\n", vha->state);
8094				vha->task_daemon_flags &= ~FC_STATE_CHANGE;
8095
8096				if (vha->task_daemon_flags &
8097				    COMMAND_WAIT_NEEDED) {
8098					vha->task_daemon_flags &=
8099					    ~COMMAND_WAIT_NEEDED;
8100					if (!(ha->task_daemon_flags &
8101					    COMMAND_WAIT_ACTIVE)) {
8102						ha->task_daemon_flags |=
8103						    COMMAND_WAIT_ACTIVE;
8104						TASK_DAEMON_UNLOCK(ha);
8105						ql_cmd_wait(ha);
8106						TASK_DAEMON_LOCK(ha);
8107						ha->task_daemon_flags &=
8108						    ~COMMAND_WAIT_ACTIVE;
8109					}
8110				}
8111
8112				msg = NULL;
8113				if (FC_PORT_STATE_MASK(vha->state) ==
8114				    FC_STATE_OFFLINE) {
8115					if (vha->task_daemon_flags &
8116					    STATE_ONLINE) {
8117						if (ha->topology &
8118						    QL_LOOP_CONNECTION) {
8119							msg = "Loop OFFLINE";
8120						} else {
8121							msg = "Link OFFLINE";
8122						}
8123					}
8124					vha->task_daemon_flags &=
8125					    ~STATE_ONLINE;
8126				} else if (FC_PORT_STATE_MASK(vha->state) ==
8127				    FC_STATE_LOOP) {
8128					if (!(vha->task_daemon_flags &
8129					    STATE_ONLINE)) {
8130						msg = "Loop ONLINE";
8131					}
8132					vha->task_daemon_flags |= STATE_ONLINE;
8133				} else if (FC_PORT_STATE_MASK(vha->state) ==
8134				    FC_STATE_ONLINE) {
8135					if (!(vha->task_daemon_flags &
8136					    STATE_ONLINE)) {
8137						msg = "Link ONLINE";
8138					}
8139					vha->task_daemon_flags |= STATE_ONLINE;
8140				} else {
8141					msg = "Unknown Link state";
8142				}
8143
8144				if (msg != NULL) {
8145					cmn_err(CE_NOTE, "!Qlogic %s(%d,%d): "
8146					    "%s", QL_NAME, ha->instance,
8147					    vha->vp_index, msg);
8148				}
8149
8150				if (vha->flags & FCA_BOUND) {
8151					QL_PRINT_10(CE_CONT, "(%d,%d): statec_"
8152					    "cb state=%xh\n", ha->instance,
8153					    vha->vp_index, vha->state);
8154					TASK_DAEMON_UNLOCK(ha);
8155					(vha->bind_info.port_statec_cb)
8156					    (vha->bind_info.port_handle,
8157					    vha->state);
8158					TASK_DAEMON_LOCK(ha);
8159				}
8160				loop_again = TRUE;
8161			}
8162		}
8163
8164		if (ha->task_daemon_flags & LIP_RESET_PENDING &&
8165		    !(ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN)) {
8166			EL(ha, "processing LIP reset\n");
8167			ha->task_daemon_flags &= ~LIP_RESET_PENDING;
8168			TASK_DAEMON_UNLOCK(ha);
8169			for (vha = ha; vha != NULL; vha = vha->vp_next) {
8170				if (vha->flags & FCA_BOUND) {
8171					QL_PRINT_10(CE_CONT, "(%d,%d): statec_"
8172					    "cb reset\n", ha->instance,
8173					    vha->vp_index);
8174					(vha->bind_info.port_statec_cb)
8175					    (vha->bind_info.port_handle,
8176					    FC_STATE_TARGET_PORT_RESET);
8177				}
8178			}
8179			TASK_DAEMON_LOCK(ha);
8180			loop_again = TRUE;
8181		}
8182
8183		if (QL_IS_SET(ha->task_daemon_flags, NEED_UNSOLICITED_BUFFERS |
8184		    FIRMWARE_UP)) {
8185			/*
8186			 * The firmware needs more unsolicited
8187			 * buffers. We cannot allocate any new
8188			 * buffers unless the ULP module requests
8189			 * for new buffers. All we can do here is
8190			 * to give received buffers from the pool
8191			 * that is already allocated
8192			 */
8193			ha->task_daemon_flags &= ~NEED_UNSOLICITED_BUFFERS;
8194			TASK_DAEMON_UNLOCK(ha);
8195			ql_isp_rcvbuf(ha);
8196			TASK_DAEMON_LOCK(ha);
8197			loop_again = TRUE;
8198		}
8199
8200		if (ha->task_daemon_flags & ISP_ABORT_NEEDED) {
8201			TASK_DAEMON_UNLOCK(ha);
8202			(void) ql_abort_isp(ha);
8203			TASK_DAEMON_LOCK(ha);
8204			loop_again = TRUE;
8205		}
8206
8207		if (!(ha->task_daemon_flags & (LOOP_DOWN | DRIVER_STALL |
8208		    COMMAND_WAIT_NEEDED))) {
8209			if (QL_IS_SET(ha->task_daemon_flags,
8210			    RESET_MARKER_NEEDED | FIRMWARE_UP)) {
8211				ha->task_daemon_flags &= ~RESET_MARKER_NEEDED;
8212				if (!(ha->task_daemon_flags & RESET_ACTIVE)) {
8213					ha->task_daemon_flags |= RESET_ACTIVE;
8214					TASK_DAEMON_UNLOCK(ha);
8215					for (vha = ha; vha != NULL;
8216					    vha = vha->vp_next) {
8217						ql_rst_aen(vha);
8218					}
8219					TASK_DAEMON_LOCK(ha);
8220					ha->task_daemon_flags &= ~RESET_ACTIVE;
8221					loop_again = TRUE;
8222				}
8223			}
8224
8225			if (QL_IS_SET(ha->task_daemon_flags,
8226			    LOOP_RESYNC_NEEDED | FIRMWARE_UP)) {
8227				if (!(ha->task_daemon_flags &
8228				    LOOP_RESYNC_ACTIVE)) {
8229					ha->task_daemon_flags |=
8230					    LOOP_RESYNC_ACTIVE;
8231					TASK_DAEMON_UNLOCK(ha);
8232					(void) ql_loop_resync(ha);
8233					TASK_DAEMON_LOCK(ha);
8234					loop_again = TRUE;
8235				}
8236			}
8237		}
8238
8239		/* Port retry needed. */
8240		if (ha->task_daemon_flags & PORT_RETRY_NEEDED) {
8241			ha->task_daemon_flags &= ~PORT_RETRY_NEEDED;
8242			ADAPTER_STATE_LOCK(ha);
8243			ha->port_retry_timer = 0;
8244			ADAPTER_STATE_UNLOCK(ha);
8245
8246			TASK_DAEMON_UNLOCK(ha);
8247			ql_restart_queues(ha);
8248			TASK_DAEMON_LOCK(ha);
8249			loop_again = B_TRUE;
8250		}
8251
8252		/* iiDMA setting needed? */
8253		if (ha->task_daemon_flags & TD_IIDMA_NEEDED) {
8254			ha->task_daemon_flags &= ~TD_IIDMA_NEEDED;
8255
8256			TASK_DAEMON_UNLOCK(ha);
8257			ql_iidma(ha);
8258			TASK_DAEMON_LOCK(ha);
8259			loop_again = B_TRUE;
8260		}
8261
8262		if (ha->task_daemon_flags & SEND_PLOGI) {
8263			ha->task_daemon_flags &= ~SEND_PLOGI;
8264			TASK_DAEMON_UNLOCK(ha);
8265			(void) ql_n_port_plogi(ha);
8266			TASK_DAEMON_LOCK(ha);
8267		}
8268
8269		head = &ha->callback_queue;
8270		if (head->first != NULL) {
8271			sp = head->first->base_address;
8272			link = &sp->cmd;
8273
8274			/* Dequeue command. */
8275			ql_remove_link(head, link);
8276
8277			/* Release task daemon lock. */
8278			TASK_DAEMON_UNLOCK(ha);
8279
8280			/* Do callback. */
8281			if (sp->flags & SRB_UB_CALLBACK) {
8282				ql_unsol_callback(sp);
8283			} else {
8284				(*sp->pkt->pkt_comp)(sp->pkt);
8285			}
8286
8287			/* Acquire task daemon lock. */
8288			TASK_DAEMON_LOCK(ha);
8289
8290			loop_again = TRUE;
8291		}
8292
8293	} while (loop_again);
8294}
8295
8296/*
8297 * ql_idle_check
8298 *	Test for adapter is alive and well.
8299 *
8300 * Input:
8301 *	ha:	adapter state pointer.
8302 *
8303 * Context:
8304 *	Kernel context.
8305 */
8306static void
8307ql_idle_check(ql_adapter_state_t *ha)
8308{
8309	ddi_devstate_t	state;
8310	int		rval;
8311	ql_mbx_data_t	mr;
8312
8313	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8314
8315	/* Firmware Ready Test. */
8316	rval = ql_get_firmware_state(ha, &mr);
8317	if (!(ha->task_daemon_flags & QL_SUSPENDED) &&
8318	    (rval != QL_SUCCESS || mr.mb[1] != FSTATE_READY)) {
8319		EL(ha, "failed, Firmware Ready Test = %xh\n", rval);
8320		state = ddi_get_devstate(ha->dip);
8321		if (state == DDI_DEVSTATE_UP) {
8322			/*EMPTY*/
8323			ddi_dev_report_fault(ha->dip, DDI_SERVICE_DEGRADED,
8324			    DDI_DEVICE_FAULT, "Firmware Ready Test failed");
8325		}
8326		TASK_DAEMON_LOCK(ha);
8327		if (!(ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
8328			EL(ha, "fstate_ready, isp_abort_needed\n");
8329			ha->task_daemon_flags |= ISP_ABORT_NEEDED;
8330		}
8331		TASK_DAEMON_UNLOCK(ha);
8332	}
8333
8334	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8335}
8336
8337/*
8338 * ql_unsol_callback
8339 *	Handle unsolicited buffer callbacks.
8340 *
8341 * Input:
8342 *	ha = adapter state pointer.
8343 *	sp = srb pointer.
8344 *
8345 * Context:
8346 *	Kernel context.
8347 */
8348static void
8349ql_unsol_callback(ql_srb_t *sp)
8350{
8351	fc_affected_id_t	*af;
8352	fc_unsol_buf_t		*ubp;
8353	uchar_t			r_ctl;
8354	uchar_t			ls_code;
8355	ql_tgt_t		*tq;
8356	ql_adapter_state_t	*ha = sp->ha, *pha = sp->ha->pha;
8357
8358	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8359
8360	ubp = ha->ub_array[sp->handle];
8361	r_ctl = ubp->ub_frame.r_ctl;
8362	ls_code = ubp->ub_buffer[0];
8363
8364	if (sp->lun_queue == NULL) {
8365		tq = NULL;
8366	} else {
8367		tq = sp->lun_queue->target_queue;
8368	}
8369
8370	QL_UB_LOCK(ha);
8371	if (sp->flags & SRB_UB_FREE_REQUESTED ||
8372	    pha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) {
8373		sp->flags &= ~(SRB_UB_IN_ISP | SRB_UB_CALLBACK |
8374		    SRB_UB_RSCN | SRB_UB_FCP | SRB_UB_ACQUIRED);
8375		sp->flags |= SRB_UB_IN_FCA;
8376		QL_UB_UNLOCK(ha);
8377		return;
8378	}
8379
8380	/* Process RSCN */
8381	if (sp->flags & SRB_UB_RSCN) {
8382		int sendup = 1;
8383
8384		/*
8385		 * Defer RSCN posting until commands return
8386		 */
8387		QL_UB_UNLOCK(ha);
8388
8389		af = (fc_affected_id_t *)((caddr_t)ubp->ub_buffer + 4);
8390
8391		/* Abort outstanding commands */
8392		sendup = ql_process_rscn(ha, af);
8393		if (sendup == 0) {
8394
8395			TASK_DAEMON_LOCK(ha);
8396			ql_add_link_b(&pha->callback_queue, &sp->cmd);
8397			TASK_DAEMON_UNLOCK(ha);
8398
8399			/*
8400			 * Wait for commands to drain in F/W (doesn't take
8401			 * more than a few milliseconds)
8402			 */
8403			ql_delay(ha, 10000);
8404
8405			QL_PRINT_2(CE_CONT, "(%d,%d): done rscn_sendup=0, "
8406			    "fmt=%xh, d_id=%xh\n", ha->instance, ha->vp_index,
8407			    af->aff_format, af->aff_d_id);
8408			return;
8409		}
8410
8411		QL_UB_LOCK(ha);
8412
8413		EL(ha, "sending unsol rscn, fmt=%xh, d_id=%xh to transport\n",
8414		    af->aff_format, af->aff_d_id);
8415	}
8416
8417	/* Process UNSOL LOGO */
8418	if ((r_ctl == R_CTL_ELS_REQ) && (ls_code == LA_ELS_LOGO)) {
8419		QL_UB_UNLOCK(ha);
8420
8421		if (tq && (ql_process_logo_for_device(ha, tq) == 0)) {
8422			TASK_DAEMON_LOCK(ha);
8423			ql_add_link_b(&pha->callback_queue, &sp->cmd);
8424			TASK_DAEMON_UNLOCK(ha);
8425			QL_PRINT_2(CE_CONT, "(%d,%d): logo_sendup=0, d_id=%xh"
8426			    "\n", ha->instance, ha->vp_index, tq->d_id.b24);
8427			return;
8428		}
8429
8430		QL_UB_LOCK(ha);
8431		EL(ha, "sending unsol logout for %xh to transport\n",
8432		    ubp->ub_frame.s_id);
8433	}
8434
8435	sp->flags &= ~(SRB_UB_IN_FCA | SRB_UB_IN_ISP | SRB_UB_RSCN |
8436	    SRB_UB_FCP);
8437
8438	if (sp->ub_type == FC_TYPE_IS8802_SNAP) {
8439		(void) ddi_dma_sync(sp->ub_buffer.dma_handle, 0,
8440		    ubp->ub_bufsize, DDI_DMA_SYNC_FORCPU);
8441	}
8442	QL_UB_UNLOCK(ha);
8443
8444	(ha->bind_info.port_unsol_cb)(ha->bind_info.port_handle,
8445	    ubp, sp->ub_type);
8446
8447	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8448}
8449
8450/*
8451 * ql_send_logo
8452 *
8453 * Input:
8454 *	ha:	adapter state pointer.
8455 *	tq:	target queue pointer.
8456 *	done_q:	done queue pointer.
8457 *
8458 * Context:
8459 *	Interrupt or Kernel context, no mailbox commands allowed.
8460 */
8461void
8462ql_send_logo(ql_adapter_state_t *vha, ql_tgt_t *tq, ql_head_t *done_q)
8463{
8464	fc_unsol_buf_t		*ubp;
8465	ql_srb_t		*sp;
8466	la_els_logo_t		*payload;
8467	ql_adapter_state_t	*ha = vha->pha;
8468
8469	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh\n", ha->instance,
8470	    tq->d_id.b24);
8471
8472	if ((tq->d_id.b24 == 0) || (tq->d_id.b24 == 0xffffff)) {
8473		EL(ha, "no device, d_id=%xh\n", tq->d_id.b24);
8474		return;
8475	}
8476
8477	if ((tq->flags & (TQF_RSCN_RCVD | TQF_PLOGI_PROGRS)) == 0 &&
8478	    tq->logout_sent == 0 && (ha->task_daemon_flags & LOOP_DOWN) == 0) {
8479
8480		/* Locate a buffer to use. */
8481		ubp = ql_get_unsolicited_buffer(vha, FC_TYPE_EXTENDED_LS);
8482		if (ubp == NULL) {
8483			EL(vha, "Failed, get_unsolicited_buffer\n");
8484			return;
8485		}
8486
8487		DEVICE_QUEUE_LOCK(tq);
8488		tq->flags |= TQF_NEED_AUTHENTICATION;
8489		tq->logout_sent++;
8490		DEVICE_QUEUE_UNLOCK(tq);
8491
8492		EL(vha, "Received LOGO from = %xh\n", tq->d_id.b24);
8493
8494		sp = ubp->ub_fca_private;
8495
8496		/* Set header. */
8497		ubp->ub_frame.d_id = vha->d_id.b24;
8498		ubp->ub_frame.r_ctl = R_CTL_ELS_REQ;
8499		ubp->ub_frame.s_id = tq->d_id.b24;
8500		ubp->ub_frame.rsvd = 0;
8501		ubp->ub_frame.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ |
8502		    F_CTL_SEQ_INITIATIVE;
8503		ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
8504		ubp->ub_frame.seq_cnt = 0;
8505		ubp->ub_frame.df_ctl = 0;
8506		ubp->ub_frame.seq_id = 0;
8507		ubp->ub_frame.rx_id = 0xffff;
8508		ubp->ub_frame.ox_id = 0xffff;
8509
8510		/* set payload. */
8511		payload = (la_els_logo_t *)ubp->ub_buffer;
8512		bzero(payload, sizeof (la_els_logo_t));
8513		/* Make sure ls_code in payload is always big endian */
8514		ubp->ub_buffer[0] = LA_ELS_LOGO;
8515		ubp->ub_buffer[1] = 0;
8516		ubp->ub_buffer[2] = 0;
8517		ubp->ub_buffer[3] = 0;
8518		bcopy(&vha->loginparams.node_ww_name.raw_wwn[0],
8519		    &payload->nport_ww_name.raw_wwn[0], 8);
8520		payload->nport_id.port_id = tq->d_id.b24;
8521
8522		QL_UB_LOCK(ha);
8523		sp->flags |= SRB_UB_CALLBACK;
8524		QL_UB_UNLOCK(ha);
8525		if (tq->lun_queues.first != NULL) {
8526			sp->lun_queue = (tq->lun_queues.first)->base_address;
8527		} else {
8528			sp->lun_queue = ql_lun_queue(vha, tq, 0);
8529		}
8530		if (done_q) {
8531			ql_add_link_b(done_q, &sp->cmd);
8532		} else {
8533			ql_awaken_task_daemon(ha, sp, 0, 0);
8534		}
8535	}
8536
8537	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8538}
8539
8540static int
8541ql_process_logo_for_device(ql_adapter_state_t *ha, ql_tgt_t *tq)
8542{
8543	port_id_t	d_id;
8544	ql_srb_t	*sp;
8545	ql_link_t	*link;
8546	int		sendup = 1;
8547
8548	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8549
8550	DEVICE_QUEUE_LOCK(tq);
8551	if (tq->outcnt) {
8552		DEVICE_QUEUE_UNLOCK(tq);
8553		sendup = 0;
8554		(void) ql_abort_device(ha, tq, 1);
8555		ql_delay(ha, 10000);
8556	} else {
8557		DEVICE_QUEUE_UNLOCK(tq);
8558		TASK_DAEMON_LOCK(ha);
8559
8560		for (link = ha->pha->callback_queue.first; link != NULL;
8561		    link = link->next) {
8562			sp = link->base_address;
8563			if (sp->flags & SRB_UB_CALLBACK) {
8564				continue;
8565			}
8566			d_id.b24 = sp->pkt->pkt_cmd_fhdr.d_id;
8567
8568			if (tq->d_id.b24 == d_id.b24) {
8569				sendup = 0;
8570				break;
8571			}
8572		}
8573
8574		TASK_DAEMON_UNLOCK(ha);
8575	}
8576
8577	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8578
8579	return (sendup);
8580}
8581
8582static int
8583ql_send_plogi(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_head_t *done_q)
8584{
8585	fc_unsol_buf_t		*ubp;
8586	ql_srb_t		*sp;
8587	la_els_logi_t		*payload;
8588	class_svc_param_t	*class3_param;
8589
8590	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8591
8592	if ((tq->flags & TQF_RSCN_RCVD) || (ha->task_daemon_flags &
8593	    LOOP_DOWN)) {
8594		EL(ha, "Failed, tqf=%xh\n", tq->flags);
8595		return (QL_FUNCTION_FAILED);
8596	}
8597
8598	/* Locate a buffer to use. */
8599	ubp = ql_get_unsolicited_buffer(ha, FC_TYPE_EXTENDED_LS);
8600	if (ubp == NULL) {
8601		EL(ha, "Failed\n");
8602		return (QL_FUNCTION_FAILED);
8603	}
8604
8605	QL_PRINT_3(CE_CONT, "(%d): Received LOGO from = %xh\n",
8606	    ha->instance, tq->d_id.b24);
8607
8608	EL(ha, "Emulate PLOGI from = %xh tq = %x\n", tq->d_id.b24, tq);
8609
8610	sp = ubp->ub_fca_private;
8611
8612	/* Set header. */
8613	ubp->ub_frame.d_id = ha->d_id.b24;
8614	ubp->ub_frame.r_ctl = R_CTL_ELS_REQ;
8615	ubp->ub_frame.s_id = tq->d_id.b24;
8616	ubp->ub_frame.rsvd = 0;
8617	ubp->ub_frame.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ |
8618	    F_CTL_SEQ_INITIATIVE;
8619	ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
8620	ubp->ub_frame.seq_cnt = 0;
8621	ubp->ub_frame.df_ctl = 0;
8622	ubp->ub_frame.seq_id = 0;
8623	ubp->ub_frame.rx_id = 0xffff;
8624	ubp->ub_frame.ox_id = 0xffff;
8625
8626	/* set payload. */
8627	payload = (la_els_logi_t *)ubp->ub_buffer;
8628	bzero(payload, sizeof (payload));
8629
8630	payload->ls_code.ls_code = LA_ELS_PLOGI;
8631	payload->common_service.fcph_version = 0x2006;
8632	payload->common_service.cmn_features = 0x8800;
8633
8634	CFG_IST(ha, CFG_CTRL_242581) ?
8635	    (payload->common_service.rx_bufsize = CHAR_TO_SHORT(
8636	    ha->init_ctrl_blk.cb24.max_frame_length[0],
8637	    ha->init_ctrl_blk.cb24.max_frame_length[1])) :
8638	    (payload->common_service.rx_bufsize = CHAR_TO_SHORT(
8639	    ha->init_ctrl_blk.cb.max_frame_length[0],
8640	    ha->init_ctrl_blk.cb.max_frame_length[1]));
8641
8642	payload->common_service.conc_sequences = 0xff;
8643	payload->common_service.relative_offset = 0x03;
8644	payload->common_service.e_d_tov = 0x7d0;
8645
8646	bcopy((void *)&tq->port_name[0],
8647	    (void *)&payload->nport_ww_name.raw_wwn[0], 8);
8648
8649	bcopy((void *)&tq->node_name[0],
8650	    (void *)&payload->node_ww_name.raw_wwn[0], 8);
8651
8652	class3_param = (class_svc_param_t *)&payload->class_3;
8653	class3_param->class_valid_svc_opt = 0x8000;
8654	class3_param->recipient_ctl = tq->class3_recipient_ctl;
8655	class3_param->rcv_data_size = tq->class3_rcv_data_size;
8656	class3_param->conc_sequences = tq->class3_conc_sequences;
8657	class3_param->open_sequences_per_exch =
8658	    tq->class3_open_sequences_per_exch;
8659
8660	QL_UB_LOCK(ha);
8661	sp->flags |= SRB_UB_CALLBACK;
8662	QL_UB_UNLOCK(ha);
8663
8664	ql_isp_els_handle_endian(ha, (uint8_t *)payload, LA_ELS_PLOGI);
8665
8666	if (done_q) {
8667		ql_add_link_b(done_q, &sp->cmd);
8668	} else {
8669		ql_awaken_task_daemon(ha, sp, 0, 0);
8670	}
8671
8672	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8673
8674	return (QL_SUCCESS);
8675}
8676
8677/*
8678 * Abort outstanding commands in the Firmware, clear internally
8679 * queued commands in the driver, Synchronize the target with
8680 * the Firmware
8681 */
8682int
8683ql_abort_device(ql_adapter_state_t *ha, ql_tgt_t *tq, int drain)
8684{
8685	ql_link_t	*link, *link2;
8686	ql_lun_t	*lq;
8687	int		rval = QL_SUCCESS;
8688	ql_srb_t	*sp;
8689	ql_head_t	done_q = { NULL, NULL };
8690
8691	QL_PRINT_10(CE_CONT, "(%d,%d): started\n", ha->instance, ha->vp_index);
8692
8693	/*
8694	 * First clear, internally queued commands
8695	 */
8696	DEVICE_QUEUE_LOCK(tq);
8697	for (link = tq->lun_queues.first; link != NULL; link = link->next) {
8698		lq = link->base_address;
8699
8700		link2 = lq->cmd.first;
8701		while (link2 != NULL) {
8702			sp = link2->base_address;
8703			link2 = link2->next;
8704
8705			if (sp->flags & SRB_ABORT) {
8706				continue;
8707			}
8708
8709			/* Remove srb from device command queue. */
8710			ql_remove_link(&lq->cmd, &sp->cmd);
8711			sp->flags &= ~SRB_IN_DEVICE_QUEUE;
8712
8713			/* Set ending status. */
8714			sp->pkt->pkt_reason = CS_ABORTED;
8715
8716			/* Call done routine to handle completions. */
8717			ql_add_link_b(&done_q, &sp->cmd);
8718		}
8719	}
8720	DEVICE_QUEUE_UNLOCK(tq);
8721
8722	if (done_q.first != NULL) {
8723		ql_done(done_q.first);
8724	}
8725
8726	if (drain && VALID_TARGET_ID(ha, tq->loop_id) && PD_PORT_LOGIN(tq)) {
8727		rval = ql_abort_target(ha, tq, 0);
8728	}
8729
8730	if (rval != QL_SUCCESS) {
8731		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
8732	} else {
8733		/*EMPTY*/
8734		QL_PRINT_10(CE_CONT, "(%d,%d): done\n", ha->instance,
8735		    ha->vp_index);
8736	}
8737
8738	return (rval);
8739}
8740
8741/*
8742 * ql_rcv_rscn_els
8743 *	Processes received RSCN extended link service.
8744 *
8745 * Input:
8746 *	ha:	adapter state pointer.
8747 *	mb:	array containing input mailbox registers.
8748 *	done_q:	done queue pointer.
8749 *
8750 * Context:
8751 *	Interrupt or Kernel context, no mailbox commands allowed.
8752 */
8753void
8754ql_rcv_rscn_els(ql_adapter_state_t *ha, uint16_t *mb, ql_head_t *done_q)
8755{
8756	fc_unsol_buf_t		*ubp;
8757	ql_srb_t		*sp;
8758	fc_rscn_t		*rn;
8759	fc_affected_id_t	*af;
8760	port_id_t		d_id;
8761
8762	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8763
8764	/* Locate a buffer to use. */
8765	ubp = ql_get_unsolicited_buffer(ha, FC_TYPE_EXTENDED_LS);
8766	if (ubp != NULL) {
8767		sp = ubp->ub_fca_private;
8768
8769		/* Set header. */
8770		ubp->ub_frame.d_id = ha->d_id.b24;
8771		ubp->ub_frame.r_ctl = R_CTL_ELS_REQ;
8772		ubp->ub_frame.s_id = FS_FABRIC_CONTROLLER;
8773		ubp->ub_frame.rsvd = 0;
8774		ubp->ub_frame.f_ctl = F_CTL_FIRST_SEQ | F_CTL_END_SEQ |
8775		    F_CTL_SEQ_INITIATIVE;
8776		ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
8777		ubp->ub_frame.seq_cnt = 0;
8778		ubp->ub_frame.df_ctl = 0;
8779		ubp->ub_frame.seq_id = 0;
8780		ubp->ub_frame.rx_id = 0xffff;
8781		ubp->ub_frame.ox_id = 0xffff;
8782
8783		/* set payload. */
8784		rn = (fc_rscn_t *)ubp->ub_buffer;
8785		af = (fc_affected_id_t *)((caddr_t)ubp->ub_buffer + 4);
8786
8787		rn->rscn_code = LA_ELS_RSCN;
8788		rn->rscn_len = 4;
8789		rn->rscn_payload_len = 8;
8790		d_id.b.al_pa = LSB(mb[2]);
8791		d_id.b.area = MSB(mb[2]);
8792		d_id.b.domain =	LSB(mb[1]);
8793		af->aff_d_id = d_id.b24;
8794		af->aff_format = MSB(mb[1]);
8795
8796		EL(ha, "LA_ELS_RSCN fmt=%xh, d_id=%xh\n", af->aff_format,
8797		    af->aff_d_id);
8798
8799		ql_update_rscn(ha, af);
8800
8801		QL_UB_LOCK(ha);
8802		sp->flags |= SRB_UB_CALLBACK | SRB_UB_RSCN;
8803		QL_UB_UNLOCK(ha);
8804		ql_add_link_b(done_q, &sp->cmd);
8805	}
8806
8807	if (ubp == NULL) {
8808		EL(ha, "Failed, get_unsolicited_buffer\n");
8809	} else {
8810		/*EMPTY*/
8811		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8812	}
8813}
8814
8815/*
8816 * ql_update_rscn
8817 *	Update devices from received RSCN.
8818 *
8819 * Input:
8820 *	ha:	adapter state pointer.
8821 *	af:	pointer to RSCN data.
8822 *
8823 * Context:
8824 *	Interrupt or Kernel context, no mailbox commands allowed.
8825 */
8826static void
8827ql_update_rscn(ql_adapter_state_t *ha, fc_affected_id_t *af)
8828{
8829	ql_link_t	*link;
8830	uint16_t	index;
8831	ql_tgt_t	*tq;
8832
8833	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8834
8835	if (af->aff_format == FC_RSCN_PORT_ADDRESS) {
8836		port_id_t d_id;
8837
8838		d_id.r.rsvd_1 = 0;
8839		d_id.b24 = af->aff_d_id;
8840
8841		tq = ql_d_id_to_queue(ha, d_id);
8842		if (tq) {
8843			EL(ha, "SD_RSCN_RCVD %xh RPA\n", d_id.b24);
8844			DEVICE_QUEUE_LOCK(tq);
8845			tq->flags |= TQF_RSCN_RCVD;
8846			DEVICE_QUEUE_UNLOCK(tq);
8847		}
8848		QL_PRINT_3(CE_CONT, "(%d): FC_RSCN_PORT_ADDRESS done\n",
8849		    ha->instance);
8850
8851		return;
8852	}
8853
8854	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
8855		for (link = ha->dev[index].first; link != NULL;
8856		    link = link->next) {
8857			tq = link->base_address;
8858
8859			switch (af->aff_format) {
8860			case FC_RSCN_FABRIC_ADDRESS:
8861				if (!RESERVED_LOOP_ID(ha, tq->loop_id)) {
8862					EL(ha, "SD_RSCN_RCVD %xh RFA\n",
8863					    tq->d_id.b24);
8864					DEVICE_QUEUE_LOCK(tq);
8865					tq->flags |= TQF_RSCN_RCVD;
8866					DEVICE_QUEUE_UNLOCK(tq);
8867				}
8868				break;
8869
8870			case FC_RSCN_AREA_ADDRESS:
8871				if ((tq->d_id.b24 & 0xffff00) == af->aff_d_id) {
8872					EL(ha, "SD_RSCN_RCVD %xh RAA\n",
8873					    tq->d_id.b24);
8874					DEVICE_QUEUE_LOCK(tq);
8875					tq->flags |= TQF_RSCN_RCVD;
8876					DEVICE_QUEUE_UNLOCK(tq);
8877				}
8878				break;
8879
8880			case FC_RSCN_DOMAIN_ADDRESS:
8881				if ((tq->d_id.b24 & 0xff0000) == af->aff_d_id) {
8882					EL(ha, "SD_RSCN_RCVD %xh RDA\n",
8883					    tq->d_id.b24);
8884					DEVICE_QUEUE_LOCK(tq);
8885					tq->flags |= TQF_RSCN_RCVD;
8886					DEVICE_QUEUE_UNLOCK(tq);
8887				}
8888				break;
8889
8890			default:
8891				break;
8892			}
8893		}
8894	}
8895	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8896}
8897
8898/*
8899 * ql_process_rscn
8900 *
8901 * Input:
8902 *	ha:	adapter state pointer.
8903 *	af:	RSCN payload pointer.
8904 *
8905 * Context:
8906 *	Kernel context.
8907 */
8908static int
8909ql_process_rscn(ql_adapter_state_t *ha, fc_affected_id_t *af)
8910{
8911	int		sendit;
8912	int		sendup = 1;
8913	ql_link_t	*link;
8914	uint16_t	index;
8915	ql_tgt_t	*tq;
8916
8917	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
8918
8919	if (af->aff_format == FC_RSCN_PORT_ADDRESS) {
8920		port_id_t d_id;
8921
8922		d_id.r.rsvd_1 = 0;
8923		d_id.b24 = af->aff_d_id;
8924
8925		tq = ql_d_id_to_queue(ha, d_id);
8926		if (tq) {
8927			sendup = ql_process_rscn_for_device(ha, tq);
8928		}
8929
8930		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8931
8932		return (sendup);
8933	}
8934
8935	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
8936		for (link = ha->dev[index].first; link != NULL;
8937		    link = link->next) {
8938
8939			tq = link->base_address;
8940			if (tq == NULL) {
8941				continue;
8942			}
8943
8944			switch (af->aff_format) {
8945			case FC_RSCN_FABRIC_ADDRESS:
8946				if (!RESERVED_LOOP_ID(ha, tq->loop_id)) {
8947					sendit = ql_process_rscn_for_device(
8948					    ha, tq);
8949					if (sendup) {
8950						sendup = sendit;
8951					}
8952				}
8953				break;
8954
8955			case FC_RSCN_AREA_ADDRESS:
8956				if ((tq->d_id.b24 & 0xffff00) ==
8957				    af->aff_d_id) {
8958					sendit = ql_process_rscn_for_device(
8959					    ha, tq);
8960
8961					if (sendup) {
8962						sendup = sendit;
8963					}
8964				}
8965				break;
8966
8967			case FC_RSCN_DOMAIN_ADDRESS:
8968				if ((tq->d_id.b24 & 0xff0000) ==
8969				    af->aff_d_id) {
8970					sendit = ql_process_rscn_for_device(
8971					    ha, tq);
8972
8973					if (sendup) {
8974						sendup = sendit;
8975					}
8976				}
8977				break;
8978
8979			default:
8980				break;
8981			}
8982		}
8983	}
8984
8985	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
8986
8987	return (sendup);
8988}
8989
8990/*
8991 * ql_process_rscn_for_device
8992 *
8993 * Input:
8994 *	ha:	adapter state pointer.
8995 *	tq:	target queue pointer.
8996 *
8997 * Context:
8998 *	Kernel context.
8999 */
9000static int
9001ql_process_rscn_for_device(ql_adapter_state_t *ha, ql_tgt_t *tq)
9002{
9003	int sendup = 1;
9004
9005	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9006
9007	DEVICE_QUEUE_LOCK(tq);
9008
9009	/*
9010	 * Let FCP-2 compliant devices continue I/Os
9011	 * with their low level recoveries.
9012	 */
9013	if (((tq->flags & TQF_INITIATOR_DEVICE) == 0) &&
9014	    (tq->prli_svc_param_word_3 & PRLI_W3_RETRY)) {
9015		/*
9016		 * Cause ADISC to go out
9017		 */
9018		DEVICE_QUEUE_UNLOCK(tq);
9019
9020		(void) ql_get_port_database(ha, tq, PDF_NONE);
9021
9022		DEVICE_QUEUE_LOCK(tq);
9023		tq->flags &= ~TQF_RSCN_RCVD;
9024
9025	} else if (tq->loop_id != PORT_NO_LOOP_ID) {
9026		if (tq->d_id.b24 != BROADCAST_ADDR) {
9027			tq->flags |= TQF_NEED_AUTHENTICATION;
9028		}
9029
9030		DEVICE_QUEUE_UNLOCK(tq);
9031
9032		(void) ql_abort_device(ha, tq, 1);
9033
9034		DEVICE_QUEUE_LOCK(tq);
9035
9036		if (tq->outcnt) {
9037			sendup = 0;
9038		} else {
9039			tq->flags &= ~TQF_RSCN_RCVD;
9040		}
9041	} else {
9042		tq->flags &= ~TQF_RSCN_RCVD;
9043	}
9044
9045	if (sendup) {
9046		if (tq->d_id.b24 != BROADCAST_ADDR) {
9047			tq->flags |= TQF_NEED_AUTHENTICATION;
9048		}
9049	}
9050
9051	DEVICE_QUEUE_UNLOCK(tq);
9052
9053	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9054
9055	return (sendup);
9056}
9057
9058static int
9059ql_handle_rscn_update(ql_adapter_state_t *ha)
9060{
9061	int			rval;
9062	ql_tgt_t		*tq;
9063	uint16_t		index, loop_id;
9064	ql_dev_id_list_t	*list;
9065	uint32_t		list_size;
9066	port_id_t		d_id;
9067	ql_mbx_data_t		mr;
9068	ql_head_t		done_q = { NULL, NULL };
9069
9070	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9071
9072	list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES;
9073	list = kmem_zalloc(list_size, KM_SLEEP);
9074	if (list == NULL) {
9075		rval = QL_MEMORY_ALLOC_FAILED;
9076		EL(ha, "kmem_zalloc failed=%xh\n", rval);
9077		return (rval);
9078	}
9079
9080	/*
9081	 * Get data from RISC code d_id list to init each device queue.
9082	 */
9083	rval = ql_get_id_list(ha, (caddr_t)list, list_size, &mr);
9084	if (rval != QL_SUCCESS) {
9085		kmem_free(list, list_size);
9086		EL(ha, "get_id_list failed=%xh\n", rval);
9087		return (rval);
9088	}
9089
9090	/* Acquire adapter state lock. */
9091	ADAPTER_STATE_LOCK(ha);
9092
9093	/* Check for new devices */
9094	for (index = 0; index < mr.mb[1]; index++) {
9095		ql_dev_list(ha, list, index, &d_id, &loop_id);
9096
9097		if (VALID_DEVICE_ID(ha, loop_id)) {
9098			d_id.r.rsvd_1 = 0;
9099
9100			tq = ql_d_id_to_queue(ha, d_id);
9101			if (tq != NULL) {
9102				continue;
9103			}
9104
9105			tq = ql_dev_init(ha, d_id, loop_id);
9106
9107			/* Test for fabric device. */
9108			if (d_id.b.domain != ha->d_id.b.domain ||
9109			    d_id.b.area != ha->d_id.b.area) {
9110				tq->flags |= TQF_FABRIC_DEVICE;
9111			}
9112
9113			ADAPTER_STATE_UNLOCK(ha);
9114			if (ql_get_port_database(ha, tq, PDF_NONE) !=
9115			    QL_SUCCESS) {
9116				tq->loop_id = PORT_NO_LOOP_ID;
9117			}
9118			ADAPTER_STATE_LOCK(ha);
9119
9120			/*
9121			 * Send up a PLOGI about the new device
9122			 */
9123			if (VALID_DEVICE_ID(ha, tq->loop_id)) {
9124				(void) ql_send_plogi(ha, tq, &done_q);
9125			}
9126		}
9127	}
9128
9129	/* Release adapter state lock. */
9130	ADAPTER_STATE_UNLOCK(ha);
9131
9132	if (done_q.first != NULL) {
9133		ql_done(done_q.first);
9134	}
9135
9136	kmem_free(list, list_size);
9137
9138	if (rval != QL_SUCCESS) {
9139		EL(ha, "failed=%xh\n", rval);
9140	} else {
9141		/*EMPTY*/
9142		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9143	}
9144
9145	return (rval);
9146}
9147
9148/*
9149 * ql_free_unsolicited_buffer
9150 *	Frees allocated buffer.
9151 *
9152 * Input:
9153 *	ha = adapter state pointer.
9154 *	index = buffer array index.
9155 *	ADAPTER_STATE_LOCK must be already obtained.
9156 *
9157 * Context:
9158 *	Kernel context.
9159 */
9160static void
9161ql_free_unsolicited_buffer(ql_adapter_state_t *ha, fc_unsol_buf_t *ubp)
9162{
9163	ql_srb_t	*sp;
9164	int		status;
9165
9166	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9167
9168	sp = ubp->ub_fca_private;
9169	if (sp->ub_type == FC_TYPE_IS8802_SNAP) {
9170		/* Disconnect IP from system buffers. */
9171		if (ha->flags & IP_INITIALIZED) {
9172			ADAPTER_STATE_UNLOCK(ha);
9173			status = ql_shutdown_ip(ha);
9174			ADAPTER_STATE_LOCK(ha);
9175			if (status != QL_SUCCESS) {
9176				cmn_err(CE_WARN,
9177				    "!Qlogic %s(%d): Failed to shutdown IP",
9178				    QL_NAME, ha->instance);
9179				return;
9180			}
9181
9182			ha->flags &= ~IP_ENABLED;
9183		}
9184
9185		ql_free_phys(ha, &sp->ub_buffer);
9186	} else {
9187		kmem_free(ubp->ub_buffer, ubp->ub_bufsize);
9188	}
9189
9190	kmem_free(sp, sizeof (ql_srb_t));
9191	kmem_free(ubp, sizeof (fc_unsol_buf_t));
9192
9193	if (ha->ub_allocated != 0) {
9194		ha->ub_allocated--;
9195	}
9196
9197	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9198}
9199
9200/*
9201 * ql_get_unsolicited_buffer
9202 *	Locates a free unsolicited buffer.
9203 *
9204 * Input:
9205 *	ha = adapter state pointer.
9206 *	type = buffer type.
9207 *
9208 * Returns:
9209 *	Unsolicited buffer pointer.
9210 *
9211 * Context:
9212 *	Interrupt or Kernel context, no mailbox commands allowed.
9213 */
9214fc_unsol_buf_t *
9215ql_get_unsolicited_buffer(ql_adapter_state_t *ha, uint32_t type)
9216{
9217	fc_unsol_buf_t	*ubp;
9218	ql_srb_t	*sp;
9219	uint16_t	index;
9220
9221	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9222
9223	/* Locate a buffer to use. */
9224	ubp = NULL;
9225
9226	QL_UB_LOCK(ha);
9227	for (index = 0; index < QL_UB_LIMIT; index++) {
9228		ubp = ha->ub_array[index];
9229		if (ubp != NULL) {
9230			sp = ubp->ub_fca_private;
9231			if ((sp->ub_type == type) &&
9232			    (sp->flags & SRB_UB_IN_FCA) &&
9233			    (!(sp->flags & (SRB_UB_CALLBACK |
9234			    SRB_UB_FREE_REQUESTED | SRB_UB_ACQUIRED)))) {
9235				sp->flags |= SRB_UB_ACQUIRED;
9236				ubp->ub_resp_flags = 0;
9237				break;
9238			}
9239			ubp = NULL;
9240		}
9241	}
9242	QL_UB_UNLOCK(ha);
9243
9244	if (ubp) {
9245		ubp->ub_resp_token = NULL;
9246		ubp->ub_class = FC_TRAN_CLASS3;
9247	}
9248
9249	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9250
9251	return (ubp);
9252}
9253
9254/*
9255 * ql_ub_frame_hdr
9256 *	Processes received unsolicited buffers from ISP.
9257 *
9258 * Input:
9259 *	ha:	adapter state pointer.
9260 *	tq:	target queue pointer.
9261 *	index:	unsolicited buffer array index.
9262 *	done_q:	done queue pointer.
9263 *
9264 * Returns:
9265 *	ql local function return status code.
9266 *
9267 * Context:
9268 *	Interrupt or Kernel context, no mailbox commands allowed.
9269 */
9270int
9271ql_ub_frame_hdr(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t index,
9272    ql_head_t *done_q)
9273{
9274	fc_unsol_buf_t	*ubp;
9275	ql_srb_t	*sp;
9276	uint16_t	loop_id;
9277	int		rval = QL_FUNCTION_FAILED;
9278
9279	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9280
9281	QL_UB_LOCK(ha);
9282	if (index >= QL_UB_LIMIT || (ubp = ha->ub_array[index]) == NULL) {
9283		EL(ha, "Invalid buffer index=%xh\n", index);
9284		QL_UB_UNLOCK(ha);
9285		return (rval);
9286	}
9287
9288	sp = ubp->ub_fca_private;
9289	if (sp->flags & SRB_UB_FREE_REQUESTED) {
9290		EL(ha, "buffer freed index=%xh\n", index);
9291		sp->flags &= ~(SRB_UB_IN_ISP | SRB_UB_CALLBACK |
9292		    SRB_UB_RSCN | SRB_UB_FCP | SRB_UB_ACQUIRED);
9293
9294		sp->flags |= SRB_UB_IN_FCA;
9295
9296		QL_UB_UNLOCK(ha);
9297		return (rval);
9298	}
9299
9300	if ((sp->handle == index) &&
9301	    (sp->flags & SRB_UB_IN_ISP) &&
9302	    (sp->ub_type == FC_TYPE_IS8802_SNAP) &&
9303	    (!(sp->flags & SRB_UB_ACQUIRED))) {
9304		/* set broadcast D_ID */
9305		loop_id = (uint16_t)(CFG_IST(ha, CFG_CTRL_242581) ?
9306		    BROADCAST_24XX_HDL : IP_BROADCAST_LOOP_ID);
9307		if (tq->ub_loop_id == loop_id) {
9308			if (ha->topology & QL_FL_PORT) {
9309				ubp->ub_frame.d_id = 0x000000;
9310			} else {
9311				ubp->ub_frame.d_id = 0xffffff;
9312			}
9313		} else {
9314			ubp->ub_frame.d_id = ha->d_id.b24;
9315		}
9316		ubp->ub_frame.r_ctl = R_CTL_UNSOL_DATA;
9317		ubp->ub_frame.rsvd = 0;
9318		ubp->ub_frame.s_id = tq->d_id.b24;
9319		ubp->ub_frame.type = FC_TYPE_IS8802_SNAP;
9320		ubp->ub_frame.seq_cnt = tq->ub_seq_cnt;
9321		ubp->ub_frame.df_ctl = 0;
9322		ubp->ub_frame.seq_id = tq->ub_seq_id;
9323		ubp->ub_frame.rx_id = 0xffff;
9324		ubp->ub_frame.ox_id = 0xffff;
9325		ubp->ub_bufsize = sp->ub_size < tq->ub_sequence_length ?
9326		    sp->ub_size : tq->ub_sequence_length;
9327		ubp->ub_frame.ro = tq->ub_frame_ro;
9328
9329		tq->ub_sequence_length = (uint16_t)
9330		    (tq->ub_sequence_length - ubp->ub_bufsize);
9331		tq->ub_frame_ro += ubp->ub_bufsize;
9332		tq->ub_seq_cnt++;
9333
9334		if (tq->ub_seq_cnt == tq->ub_total_seg_cnt) {
9335			if (tq->ub_seq_cnt == 1) {
9336				ubp->ub_frame.f_ctl = F_CTL_RO_PRESENT |
9337				    F_CTL_FIRST_SEQ | F_CTL_END_SEQ;
9338			} else {
9339				ubp->ub_frame.f_ctl = F_CTL_RO_PRESENT |
9340				    F_CTL_END_SEQ;
9341			}
9342			tq->ub_total_seg_cnt = 0;
9343		} else if (tq->ub_seq_cnt == 1) {
9344			ubp->ub_frame.f_ctl = F_CTL_RO_PRESENT |
9345			    F_CTL_FIRST_SEQ;
9346			ubp->ub_frame.df_ctl = 0x20;
9347		}
9348
9349		QL_PRINT_3(CE_CONT, "(%d): ub_frame.d_id=%xh\n",
9350		    ha->instance, ubp->ub_frame.d_id);
9351		QL_PRINT_3(CE_CONT, "(%d): ub_frame.s_id=%xh\n",
9352		    ha->instance, ubp->ub_frame.s_id);
9353		QL_PRINT_3(CE_CONT, "(%d): ub_frame.seq_cnt=%xh\n",
9354		    ha->instance, ubp->ub_frame.seq_cnt);
9355		QL_PRINT_3(CE_CONT, "(%d): ub_frame.seq_id=%xh\n",
9356		    ha->instance, ubp->ub_frame.seq_id);
9357		QL_PRINT_3(CE_CONT, "(%d): ub_frame.ro=%xh\n",
9358		    ha->instance, ubp->ub_frame.ro);
9359		QL_PRINT_3(CE_CONT, "(%d): ub_frame.f_ctl=%xh\n",
9360		    ha->instance, ubp->ub_frame.f_ctl);
9361		QL_PRINT_3(CE_CONT, "(%d): ub_bufsize=%xh\n",
9362		    ha->instance, ubp->ub_bufsize);
9363		QL_DUMP_3(ubp->ub_buffer, 8,
9364		    ubp->ub_bufsize < 64 ? ubp->ub_bufsize : 64);
9365
9366		sp->flags |= SRB_UB_CALLBACK | SRB_UB_ACQUIRED;
9367		ql_add_link_b(done_q, &sp->cmd);
9368		rval = QL_SUCCESS;
9369	} else {
9370		if (sp->handle != index) {
9371			EL(ha, "Bad index=%xh, expect=%xh\n", index,
9372			    sp->handle);
9373		}
9374		if ((sp->flags & SRB_UB_IN_ISP) == 0) {
9375			EL(ha, "buffer was already in driver, index=%xh\n",
9376			    index);
9377		}
9378		if ((sp->ub_type == FC_TYPE_IS8802_SNAP) == 0) {
9379			EL(ha, "buffer was not an IP buffer, index=%xh\n",
9380			    index);
9381		}
9382		if (sp->flags & SRB_UB_ACQUIRED) {
9383			EL(ha, "buffer was being used by driver, index=%xh\n",
9384			    index);
9385		}
9386	}
9387	QL_UB_UNLOCK(ha);
9388
9389	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9390
9391	return (rval);
9392}
9393
9394/*
9395 * ql_timer
9396 *	One second timer function.
9397 *
9398 * Input:
9399 *	ql_hba.first = first link in adapter list.
9400 *
9401 * Context:
9402 *	Interrupt context, no mailbox commands allowed.
9403 */
9404static void
9405ql_timer(void *arg)
9406{
9407	ql_link_t		*link;
9408	uint32_t		set_flags;
9409	uint32_t		reset_flags;
9410	ql_adapter_state_t	*ha = NULL, *vha;
9411
9412	QL_PRINT_6(CE_CONT, "started\n");
9413
9414	/* Acquire global state lock. */
9415	GLOBAL_STATE_LOCK();
9416	if (ql_timer_timeout_id == NULL) {
9417		/* Release global state lock. */
9418		GLOBAL_STATE_UNLOCK();
9419		return;
9420	}
9421
9422	for (link = ql_hba.first; link != NULL; link = link->next) {
9423		ha = link->base_address;
9424
9425		/* Skip adapter if suspended of stalled. */
9426		ADAPTER_STATE_LOCK(ha);
9427		if (ha->flags & ADAPTER_SUSPENDED ||
9428		    ha->task_daemon_flags & DRIVER_STALL) {
9429			ADAPTER_STATE_UNLOCK(ha);
9430			continue;
9431		}
9432		ha->flags |= ADAPTER_TIMER_BUSY;
9433		ADAPTER_STATE_UNLOCK(ha);
9434
9435		QL_PM_LOCK(ha);
9436		if (ha->power_level != PM_LEVEL_D0) {
9437			QL_PM_UNLOCK(ha);
9438
9439			ADAPTER_STATE_LOCK(ha);
9440			ha->flags &= ~ADAPTER_TIMER_BUSY;
9441			ADAPTER_STATE_UNLOCK(ha);
9442			continue;
9443		}
9444		ha->busy++;
9445		QL_PM_UNLOCK(ha);
9446
9447		set_flags = 0;
9448		reset_flags = 0;
9449
9450		/* Port retry timer handler. */
9451		if (LOOP_READY(ha)) {
9452			ADAPTER_STATE_LOCK(ha);
9453			if (ha->port_retry_timer != 0) {
9454				ha->port_retry_timer--;
9455				if (ha->port_retry_timer == 0) {
9456					set_flags |= PORT_RETRY_NEEDED;
9457				}
9458			}
9459			ADAPTER_STATE_UNLOCK(ha);
9460		}
9461
9462		/* Loop down timer handler. */
9463		if (LOOP_RECONFIGURE(ha) == 0) {
9464			if (ha->loop_down_timer > LOOP_DOWN_TIMER_END) {
9465				ha->loop_down_timer--;
9466				/*
9467				 * give the firmware loop down dump flag
9468				 * a chance to work.
9469				 */
9470				if (ha->loop_down_timer == LOOP_DOWN_RESET) {
9471					if (CFG_IST(ha,
9472					    CFG_DUMP_LOOP_OFFLINE_TIMEOUT)) {
9473						(void) ql_binary_fw_dump(ha,
9474						    TRUE);
9475					}
9476					EL(ha, "loop_down_reset, "
9477					    "isp_abort_needed\n");
9478					set_flags |= ISP_ABORT_NEEDED;
9479				}
9480			}
9481			if (CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING)) {
9482				/* Command abort time handler. */
9483				if (ha->loop_down_timer ==
9484				    ha->loop_down_abort_time) {
9485					ADAPTER_STATE_LOCK(ha);
9486					ha->flags |= ABORT_CMDS_LOOP_DOWN_TMO;
9487					ADAPTER_STATE_UNLOCK(ha);
9488					set_flags |= ABORT_QUEUES_NEEDED;
9489					EL(ha, "loop_down_abort_time, "
9490					    "abort_queues_needed\n");
9491				}
9492
9493				/* Watchdog timer handler. */
9494				if (ha->watchdog_timer == 0) {
9495					ha->watchdog_timer = WATCHDOG_TIME;
9496				} else if (LOOP_READY(ha)) {
9497					ha->watchdog_timer--;
9498					if (ha->watchdog_timer == 0) {
9499						for (vha = ha; vha != NULL;
9500						    vha = vha->vp_next) {
9501							ql_watchdog(vha,
9502							    &set_flags,
9503							    &reset_flags);
9504						}
9505						ha->watchdog_timer =
9506						    WATCHDOG_TIME;
9507					}
9508				}
9509			}
9510		}
9511
9512		/* Idle timer handler. */
9513		if (!DRIVER_SUSPENDED(ha)) {
9514			if (++ha->idle_timer >= IDLE_CHECK_TIMER) {
9515#if defined(QL_DEBUG_LEVEL_6) || !defined(QL_DEBUG_LEVEL_3)
9516				set_flags |= TASK_DAEMON_IDLE_CHK_FLG;
9517#endif
9518				ha->idle_timer = 0;
9519			}
9520			if (ha->send_plogi_timer != NULL) {
9521				ha->send_plogi_timer--;
9522				if (ha->send_plogi_timer == NULL) {
9523					set_flags |= SEND_PLOGI;
9524				}
9525			}
9526		}
9527		ADAPTER_STATE_LOCK(ha);
9528		if (ha->restart_mpi_timer != 0) {
9529			ha->restart_mpi_timer--;
9530			if (ha->restart_mpi_timer == 0 &&
9531			    ha->idc_restart_mpi != 0) {
9532				ha->idc_restart_mpi = 0;
9533				reset_flags |= TASK_DAEMON_STALLED_FLG;
9534			}
9535		}
9536		if (ha->flash_acc_timer != 0) {
9537			ha->flash_acc_timer--;
9538			if (ha->flash_acc_timer == 0 &&
9539			    ha->idc_flash_acc != 0) {
9540				ha->idc_flash_acc = 1;
9541				ha->idc_mb[1] = 0;
9542				ha->idc_mb[2] = IDC_OPC_DRV_START;
9543				set_flags |= IDC_ACK_NEEDED;
9544			}
9545		}
9546		ADAPTER_STATE_UNLOCK(ha);
9547
9548		if (set_flags != 0 || reset_flags != 0) {
9549			ql_awaken_task_daemon(ha, NULL, set_flags,
9550			    reset_flags);
9551		}
9552
9553		if (ha->xioctl->ledstate.BeaconState == BEACON_ON) {
9554			ql_blink_led(ha);
9555		}
9556
9557		/* Update the IO stats */
9558		if (ha->xioctl->IOInputByteCnt >= 0x100000) {
9559			ha->xioctl->IOInputMByteCnt +=
9560			    (ha->xioctl->IOInputByteCnt / 0x100000);
9561			ha->xioctl->IOInputByteCnt %= 0x100000;
9562		}
9563
9564		if (ha->xioctl->IOOutputByteCnt >= 0x100000) {
9565			ha->xioctl->IOOutputMByteCnt +=
9566			    (ha->xioctl->IOOutputByteCnt / 0x100000);
9567			ha->xioctl->IOOutputByteCnt %= 0x100000;
9568		}
9569
9570		ADAPTER_STATE_LOCK(ha);
9571		ha->flags &= ~ADAPTER_TIMER_BUSY;
9572		ADAPTER_STATE_UNLOCK(ha);
9573
9574		QL_PM_LOCK(ha);
9575		ha->busy--;
9576		QL_PM_UNLOCK(ha);
9577	}
9578
9579	/* Restart timer, if not being stopped. */
9580	if (ql_timer_timeout_id != NULL) {
9581		ql_timer_timeout_id = timeout(ql_timer, arg, ql_timer_ticks);
9582	}
9583
9584	/* Release global state lock. */
9585	GLOBAL_STATE_UNLOCK();
9586
9587	QL_PRINT_6(CE_CONT, "done\n");
9588}
9589
9590/*
9591 * ql_timeout_insert
9592 *	Function used to insert a command block onto the
9593 *	watchdog timer queue.
9594 *
9595 *	Note: Must insure that pkt_time is not zero
9596 *			before calling ql_timeout_insert.
9597 *
9598 * Input:
9599 *	ha:	adapter state pointer.
9600 *	tq:	target queue pointer.
9601 *	sp:	SRB pointer.
9602 *	DEVICE_QUEUE_LOCK must be already obtained.
9603 *
9604 * Context:
9605 *	Kernel context.
9606 */
9607/* ARGSUSED */
9608static void
9609ql_timeout_insert(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_srb_t *sp)
9610{
9611	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9612
9613	if (sp->pkt->pkt_timeout != 0 && sp->pkt->pkt_timeout < 0x10000) {
9614		sp->isp_timeout = (uint16_t)(sp->pkt->pkt_timeout);
9615		/*
9616		 * The WATCHDOG_TIME must be rounded up + 1.  As an example,
9617		 * consider a 1 second timeout. If the WATCHDOG_TIME is 1, it
9618		 * will expire in the next watchdog call, which could be in
9619		 * 1 microsecond.
9620		 *
9621		 */
9622		sp->wdg_q_time = (sp->isp_timeout + WATCHDOG_TIME - 1) /
9623		    WATCHDOG_TIME;
9624		/*
9625		 * Added an additional 10 to account for the
9626		 * firmware timer drift which can occur with
9627		 * very long timeout values.
9628		 */
9629		sp->wdg_q_time += 10;
9630
9631		/*
9632		 * Add 6 more to insure watchdog does not timeout at the same
9633		 * time as ISP RISC code timeout.
9634		 */
9635		sp->wdg_q_time += 6;
9636
9637		/* Save initial time for resetting watchdog time. */
9638		sp->init_wdg_q_time = sp->wdg_q_time;
9639
9640		/* Insert command onto watchdog queue. */
9641		ql_add_link_b(&tq->wdg, &sp->wdg);
9642
9643		sp->flags |= SRB_WATCHDOG_ENABLED;
9644	} else {
9645		sp->isp_timeout = 0;
9646		sp->wdg_q_time = 0;
9647		sp->init_wdg_q_time = 0;
9648	}
9649
9650	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9651}
9652
9653/*
9654 * ql_watchdog
9655 *	Timeout handler that runs in interrupt context. The
9656 *	ql_adapter_state_t * argument is the parameter set up when the
9657 *	timeout was initialized (state structure pointer).
9658 *	Function used to update timeout values and if timeout
9659 *	has occurred command will be aborted.
9660 *
9661 * Input:
9662 *	ha:		adapter state pointer.
9663 *	set_flags:	task daemon flags to set.
9664 *	reset_flags:	task daemon flags to reset.
9665 *
9666 * Context:
9667 *	Interrupt context, no mailbox commands allowed.
9668 */
9669static void
9670ql_watchdog(ql_adapter_state_t *ha, uint32_t *set_flags, uint32_t *reset_flags)
9671{
9672	ql_srb_t	*sp;
9673	ql_link_t	*link;
9674	ql_link_t	*next_cmd;
9675	ql_link_t	*next_device;
9676	ql_tgt_t	*tq;
9677	ql_lun_t	*lq;
9678	uint16_t	index;
9679	int		q_sane;
9680
9681	QL_PRINT_6(CE_CONT, "(%d): started\n", ha->instance);
9682
9683	/* Loop through all targets. */
9684	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
9685		for (link = ha->dev[index].first; link != NULL;
9686		    link = next_device) {
9687			tq = link->base_address;
9688
9689			/* Try to acquire device queue lock. */
9690			if (TRY_DEVICE_QUEUE_LOCK(tq) == 0) {
9691				next_device = NULL;
9692				continue;
9693			}
9694
9695			next_device = link->next;
9696
9697			if (!(CFG_IST(ha, CFG_ENABLE_LINK_DOWN_REPORTING)) &&
9698			    (tq->port_down_retry_count == 0)) {
9699				/* Release device queue lock. */
9700				DEVICE_QUEUE_UNLOCK(tq);
9701				continue;
9702			}
9703
9704			/* Find out if this device is in a sane state. */
9705			if (tq->flags & (TQF_RSCN_RCVD |
9706			    TQF_NEED_AUTHENTICATION | TQF_QUEUE_SUSPENDED)) {
9707				q_sane = 0;
9708			} else {
9709				q_sane = 1;
9710			}
9711			/* Loop through commands on watchdog queue. */
9712			for (link = tq->wdg.first; link != NULL;
9713			    link = next_cmd) {
9714				next_cmd = link->next;
9715				sp = link->base_address;
9716				lq = sp->lun_queue;
9717
9718				/*
9719				 * For SCSI commands, if everything seems to
9720				 * be going fine and this packet is stuck
9721				 * because of throttling at LUN or target
9722				 * level then do not decrement the
9723				 * sp->wdg_q_time
9724				 */
9725				if (ha->task_daemon_flags & STATE_ONLINE &&
9726				    (sp->flags & SRB_ISP_STARTED) == 0 &&
9727				    q_sane && sp->flags & SRB_FCP_CMD_PKT &&
9728				    lq->lun_outcnt >= ha->execution_throttle) {
9729					continue;
9730				}
9731
9732				if (sp->wdg_q_time != 0) {
9733					sp->wdg_q_time--;
9734
9735					/* Timeout? */
9736					if (sp->wdg_q_time != 0) {
9737						continue;
9738					}
9739
9740					ql_remove_link(&tq->wdg, &sp->wdg);
9741					sp->flags &= ~SRB_WATCHDOG_ENABLED;
9742
9743					if (sp->flags & SRB_ISP_STARTED) {
9744						ql_cmd_timeout(ha, tq, sp,
9745						    set_flags, reset_flags);
9746
9747						DEVICE_QUEUE_UNLOCK(tq);
9748						tq = NULL;
9749						next_cmd = NULL;
9750						next_device = NULL;
9751						index = DEVICE_HEAD_LIST_SIZE;
9752					} else {
9753						ql_cmd_timeout(ha, tq, sp,
9754						    set_flags, reset_flags);
9755					}
9756				}
9757			}
9758
9759			/* Release device queue lock. */
9760			if (tq != NULL) {
9761				DEVICE_QUEUE_UNLOCK(tq);
9762			}
9763		}
9764	}
9765
9766	QL_PRINT_6(CE_CONT, "(%d): done\n", ha->instance);
9767}
9768
9769/*
9770 * ql_cmd_timeout
9771 *	Command timeout handler.
9772 *
9773 * Input:
9774 *	ha:		adapter state pointer.
9775 *	tq:		target queue pointer.
9776 *	sp:		SRB pointer.
9777 *	set_flags:	task daemon flags to set.
9778 *	reset_flags:	task daemon flags to reset.
9779 *
9780 * Context:
9781 *	Interrupt context, no mailbox commands allowed.
9782 */
9783/* ARGSUSED */
9784static void
9785ql_cmd_timeout(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_srb_t *sp,
9786    uint32_t *set_flags, uint32_t *reset_flags)
9787{
9788
9789	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9790
9791	if (!(sp->flags & SRB_ISP_STARTED)) {
9792
9793		EL(ha, "command timed out in driver = %ph\n", (void *)sp);
9794
9795		REQUEST_RING_LOCK(ha);
9796
9797		/* if it's on a queue */
9798		if (sp->cmd.head) {
9799			/*
9800			 * The pending_cmds que needs to be
9801			 * protected by the ring lock
9802			 */
9803			ql_remove_link(sp->cmd.head, &sp->cmd);
9804		}
9805		sp->flags &= ~SRB_IN_DEVICE_QUEUE;
9806
9807		/* Release device queue lock. */
9808		REQUEST_RING_UNLOCK(ha);
9809		DEVICE_QUEUE_UNLOCK(tq);
9810
9811		/* Set timeout status */
9812		sp->pkt->pkt_reason = CS_TIMEOUT;
9813
9814		/* Ensure no retry */
9815		sp->flags &= ~SRB_RETRY;
9816
9817		/* Call done routine to handle completion. */
9818		ql_done(&sp->cmd);
9819
9820		DEVICE_QUEUE_LOCK(tq);
9821	} else {
9822		EL(ha, "command timed out in isp=%ph, osc=%ph, index=%xh, "
9823		    "isp_abort_needed\n", (void *)sp,
9824		    (void *)ha->outstanding_cmds[sp->handle & OSC_INDEX_MASK],
9825		    sp->handle & OSC_INDEX_MASK);
9826
9827		/* Release device queue lock. */
9828		DEVICE_QUEUE_UNLOCK(tq);
9829
9830		INTR_LOCK(ha);
9831		ha->pha->xioctl->ControllerErrorCount++;
9832		INTR_UNLOCK(ha);
9833
9834		/* Set ISP needs to be reset */
9835		sp->flags |= SRB_COMMAND_TIMEOUT;
9836
9837		if (CFG_IST(ha, CFG_DUMP_DRIVER_COMMAND_TIMEOUT)) {
9838			(void) ql_binary_fw_dump(ha, TRUE);
9839		}
9840
9841		*set_flags |= ISP_ABORT_NEEDED;
9842
9843		DEVICE_QUEUE_LOCK(tq);
9844	}
9845
9846	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9847}
9848
9849/*
9850 * ql_rst_aen
9851 *	Processes asynchronous reset.
9852 *
9853 * Input:
9854 *	ha = adapter state pointer.
9855 *
9856 * Context:
9857 *	Kernel context.
9858 */
9859static void
9860ql_rst_aen(ql_adapter_state_t *ha)
9861{
9862	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9863
9864	/* Issue marker command. */
9865	(void) ql_marker(ha, 0, 0, MK_SYNC_ALL);
9866
9867	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9868}
9869
9870/*
9871 * ql_cmd_wait
9872 *	Stall driver until all outstanding commands are returned.
9873 *
9874 * Input:
9875 *	ha = adapter state pointer.
9876 *
9877 * Context:
9878 *	Kernel context.
9879 */
9880void
9881ql_cmd_wait(ql_adapter_state_t *ha)
9882{
9883	uint16_t		index;
9884	ql_link_t		*link;
9885	ql_tgt_t		*tq;
9886	ql_adapter_state_t	*vha;
9887
9888	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9889
9890	/* Wait for all outstanding commands to be returned. */
9891	(void) ql_wait_outstanding(ha);
9892
9893	/*
9894	 * clear out internally queued commands
9895	 */
9896	for (vha = ha; vha != NULL; vha = vha->vp_next) {
9897		for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
9898			for (link = vha->dev[index].first; link != NULL;
9899			    link = link->next) {
9900				tq = link->base_address;
9901				if (tq &&
9902				    (!(tq->prli_svc_param_word_3 &
9903				    PRLI_W3_RETRY))) {
9904					(void) ql_abort_device(vha, tq, 0);
9905				}
9906			}
9907		}
9908	}
9909
9910	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9911}
9912
9913/*
9914 * ql_wait_outstanding
9915 *	Wait for all outstanding commands to complete.
9916 *
9917 * Input:
9918 *	ha = adapter state pointer.
9919 *
9920 * Returns:
9921 *	index - the index for ql_srb into outstanding_cmds.
9922 *
9923 * Context:
9924 *	Kernel context.
9925 */
9926static uint16_t
9927ql_wait_outstanding(ql_adapter_state_t *ha)
9928{
9929	ql_srb_t	*sp;
9930	uint16_t	index, count;
9931
9932	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9933
9934	count = 3000;
9935	for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
9936		if (ha->pha->pending_cmds.first != NULL) {
9937			ql_start_iocb(ha, NULL);
9938			index = 1;
9939		}
9940		if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
9941		    (sp->flags & SRB_COMMAND_TIMEOUT) == 0) {
9942			if (count-- != 0) {
9943				ql_delay(ha, 10000);
9944				index = 0;
9945			} else {
9946				EL(ha, "failed, sp=%ph\n", (void *)sp);
9947				break;
9948			}
9949		}
9950	}
9951
9952	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
9953
9954	return (index);
9955}
9956
9957/*
9958 * ql_restart_queues
9959 *	Restart device queues.
9960 *
9961 * Input:
9962 *	ha = adapter state pointer.
9963 *	DEVICE_QUEUE_LOCK must be released.
9964 *
9965 * Context:
9966 *	Interrupt or Kernel context, no mailbox commands allowed.
9967 */
9968static void
9969ql_restart_queues(ql_adapter_state_t *ha)
9970{
9971	ql_link_t		*link, *link2;
9972	ql_tgt_t		*tq;
9973	ql_lun_t		*lq;
9974	uint16_t		index;
9975	ql_adapter_state_t	*vha;
9976
9977	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
9978
9979	for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
9980		for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
9981			for (link = vha->dev[index].first; link != NULL;
9982			    link = link->next) {
9983				tq = link->base_address;
9984
9985				/* Acquire device queue lock. */
9986				DEVICE_QUEUE_LOCK(tq);
9987
9988				tq->flags &= ~TQF_QUEUE_SUSPENDED;
9989
9990				for (link2 = tq->lun_queues.first;
9991				    link2 != NULL; link2 = link2->next) {
9992					lq = link2->base_address;
9993
9994					if (lq->cmd.first != NULL) {
9995						ql_next(vha, lq);
9996						DEVICE_QUEUE_LOCK(tq);
9997					}
9998				}
9999
10000				/* Release device queue lock. */
10001				DEVICE_QUEUE_UNLOCK(tq);
10002			}
10003		}
10004	}
10005
10006	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10007}
10008
10009/*
10010 * ql_iidma
10011 *	Setup iiDMA parameters to firmware
10012 *
10013 * Input:
10014 *	ha = adapter state pointer.
10015 *	DEVICE_QUEUE_LOCK must be released.
10016 *
10017 * Context:
10018 *	Interrupt or Kernel context, no mailbox commands allowed.
10019 */
10020static void
10021ql_iidma(ql_adapter_state_t *ha)
10022{
10023	ql_link_t	*link;
10024	ql_tgt_t	*tq;
10025	uint16_t	index;
10026	char		buf[256];
10027	uint32_t	data;
10028
10029	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10030
10031	if ((CFG_IST(ha, CFG_CTRL_242581)) == 0) {
10032		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10033		return;
10034	}
10035
10036	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
10037		for (link = ha->dev[index].first; link != NULL;
10038		    link = link->next) {
10039			tq = link->base_address;
10040
10041			/* Acquire device queue lock. */
10042			DEVICE_QUEUE_LOCK(tq);
10043
10044			if ((tq->flags & TQF_IIDMA_NEEDED) == 0) {
10045				DEVICE_QUEUE_UNLOCK(tq);
10046				continue;
10047			}
10048
10049			tq->flags &= ~TQF_IIDMA_NEEDED;
10050
10051			if ((tq->loop_id > LAST_N_PORT_HDL) ||
10052			    (tq->iidma_rate == IIDMA_RATE_NDEF)) {
10053				DEVICE_QUEUE_UNLOCK(tq);
10054				continue;
10055			}
10056
10057			/* Get the iiDMA persistent data */
10058			if (tq->iidma_rate == IIDMA_RATE_INIT) {
10059				(void) sprintf(buf,
10060				    "iidma-rate-%02x%02x%02x%02x%02x"
10061				    "%02x%02x%02x", tq->port_name[0],
10062				    tq->port_name[1], tq->port_name[2],
10063				    tq->port_name[3], tq->port_name[4],
10064				    tq->port_name[5], tq->port_name[6],
10065				    tq->port_name[7]);
10066
10067				if ((data = ql_get_prop(ha, buf)) ==
10068				    0xffffffff) {
10069					tq->iidma_rate = IIDMA_RATE_NDEF;
10070				} else {
10071					switch (data) {
10072					case IIDMA_RATE_1GB:
10073					case IIDMA_RATE_2GB:
10074					case IIDMA_RATE_4GB:
10075					case IIDMA_RATE_10GB:
10076						tq->iidma_rate = data;
10077						break;
10078					case IIDMA_RATE_8GB:
10079						if (CFG_IST(ha,
10080						    CFG_CTRL_25XX)) {
10081							tq->iidma_rate = data;
10082						} else {
10083							tq->iidma_rate =
10084							    IIDMA_RATE_4GB;
10085						}
10086						break;
10087					default:
10088						EL(ha, "invalid data for "
10089						    "parameter: %s: %xh\n",
10090						    buf, data);
10091						tq->iidma_rate =
10092						    IIDMA_RATE_NDEF;
10093						break;
10094					}
10095				}
10096			}
10097
10098			/* Set the firmware's iiDMA rate */
10099			if (tq->iidma_rate <= IIDMA_RATE_MAX &&
10100			    !(CFG_IST(ha, CFG_CTRL_81XX))) {
10101				data = ql_iidma_rate(ha, tq->loop_id,
10102				    &tq->iidma_rate, EXT_IIDMA_MODE_SET);
10103				if (data != QL_SUCCESS) {
10104					EL(ha, "mbx failed: %xh\n", data);
10105				}
10106			}
10107
10108			/* Release device queue lock. */
10109			DEVICE_QUEUE_UNLOCK(tq);
10110		}
10111	}
10112
10113	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10114}
10115
10116/*
10117 * ql_abort_queues
10118 *	Abort all commands on device queues.
10119 *
10120 * Input:
10121 *	ha = adapter state pointer.
10122 *
10123 * Context:
10124 *	Interrupt or Kernel context, no mailbox commands allowed.
10125 */
10126static void
10127ql_abort_queues(ql_adapter_state_t *ha)
10128{
10129	ql_link_t		*link;
10130	ql_tgt_t		*tq;
10131	ql_srb_t		*sp;
10132	uint16_t		index;
10133	ql_adapter_state_t	*vha;
10134
10135	QL_PRINT_10(CE_CONT, "(%d): started\n", ha->instance);
10136
10137	/* Return all commands in outstanding command list. */
10138	INTR_LOCK(ha);
10139
10140	/* Place all commands in outstanding cmd list on device queue. */
10141	for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
10142		if (ha->pending_cmds.first != NULL) {
10143			INTR_UNLOCK(ha);
10144			ql_start_iocb(ha, NULL);
10145			/* Delay for system */
10146			ql_delay(ha, 10000);
10147			INTR_LOCK(ha);
10148			index = 1;
10149		}
10150		sp = ha->outstanding_cmds[index];
10151
10152		/* skip devices capable of FCP2 retrys */
10153		if ((sp != NULL) &&
10154		    ((tq = sp->lun_queue->target_queue) != NULL) &&
10155		    (!(tq->prli_svc_param_word_3 & PRLI_W3_RETRY))) {
10156			ha->outstanding_cmds[index] = NULL;
10157			sp->handle = 0;
10158			sp->flags &= ~SRB_IN_TOKEN_ARRAY;
10159
10160			INTR_UNLOCK(ha);
10161
10162			/* Set ending status. */
10163			sp->pkt->pkt_reason = CS_PORT_UNAVAILABLE;
10164			sp->flags |= SRB_ISP_COMPLETED;
10165
10166			/* Call done routine to handle completions. */
10167			sp->cmd.next = NULL;
10168			ql_done(&sp->cmd);
10169
10170			INTR_LOCK(ha);
10171		}
10172	}
10173	INTR_UNLOCK(ha);
10174
10175	for (vha = ha; vha != NULL; vha = vha->vp_next) {
10176		QL_PRINT_10(CE_CONT, "(%d,%d): abort instance\n",
10177		    vha->instance, vha->vp_index);
10178		for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
10179			for (link = vha->dev[index].first; link != NULL;
10180			    link = link->next) {
10181				tq = link->base_address;
10182				/* skip devices capable of FCP2 retrys */
10183				if (!(tq->prli_svc_param_word_3 &
10184				    PRLI_W3_RETRY)) {
10185					/*
10186					 * Set port unavailable status and
10187					 * return all commands on a devices
10188					 * queues.
10189					 */
10190					ql_abort_device_queues(ha, tq);
10191				}
10192			}
10193		}
10194	}
10195	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10196}
10197
10198/*
10199 * ql_abort_device_queues
10200 *	Abort all commands on device queues.
10201 *
10202 * Input:
10203 *	ha = adapter state pointer.
10204 *
10205 * Context:
10206 *	Interrupt or Kernel context, no mailbox commands allowed.
10207 */
10208static void
10209ql_abort_device_queues(ql_adapter_state_t *ha, ql_tgt_t *tq)
10210{
10211	ql_link_t	*lun_link, *cmd_link;
10212	ql_srb_t	*sp;
10213	ql_lun_t	*lq;
10214
10215	QL_PRINT_10(CE_CONT, "(%d): started\n", ha->instance);
10216
10217	DEVICE_QUEUE_LOCK(tq);
10218
10219	for (lun_link = tq->lun_queues.first; lun_link != NULL;
10220	    lun_link = lun_link->next) {
10221		lq = lun_link->base_address;
10222
10223		cmd_link = lq->cmd.first;
10224		while (cmd_link != NULL) {
10225			sp = cmd_link->base_address;
10226
10227			if (sp->flags & SRB_ABORT) {
10228				cmd_link = cmd_link->next;
10229				continue;
10230			}
10231
10232			/* Remove srb from device cmd queue. */
10233			ql_remove_link(&lq->cmd, &sp->cmd);
10234
10235			sp->flags &= ~SRB_IN_DEVICE_QUEUE;
10236
10237			DEVICE_QUEUE_UNLOCK(tq);
10238
10239			/* Set ending status. */
10240			sp->pkt->pkt_reason = CS_PORT_UNAVAILABLE;
10241
10242			/* Call done routine to handle completion. */
10243			ql_done(&sp->cmd);
10244
10245			/* Delay for system */
10246			ql_delay(ha, 10000);
10247
10248			DEVICE_QUEUE_LOCK(tq);
10249			cmd_link = lq->cmd.first;
10250		}
10251	}
10252	DEVICE_QUEUE_UNLOCK(tq);
10253
10254	QL_PRINT_10(CE_CONT, "(%d): done\n", ha->instance);
10255}
10256
10257/*
10258 * ql_loop_resync
10259 *	Resync with fibre channel devices.
10260 *
10261 * Input:
10262 *	ha = adapter state pointer.
10263 *	DEVICE_QUEUE_LOCK must be released.
10264 *
10265 * Returns:
10266 *	ql local function return status code.
10267 *
10268 * Context:
10269 *	Kernel context.
10270 */
10271static int
10272ql_loop_resync(ql_adapter_state_t *ha)
10273{
10274	int rval;
10275
10276	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10277
10278	if (ha->flags & IP_INITIALIZED) {
10279		(void) ql_shutdown_ip(ha);
10280	}
10281
10282	rval = ql_fw_ready(ha, 10);
10283
10284	TASK_DAEMON_LOCK(ha);
10285	ha->task_daemon_flags &= ~LOOP_RESYNC_ACTIVE;
10286	TASK_DAEMON_UNLOCK(ha);
10287
10288	/* Set loop online, if it really is. */
10289	if (rval == QL_SUCCESS) {
10290		ql_loop_online(ha);
10291		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10292	} else {
10293		EL(ha, "failed, rval = %xh\n", rval);
10294	}
10295
10296	return (rval);
10297}
10298
10299/*
10300 * ql_loop_online
10301 *	Set loop online status if it really is online.
10302 *
10303 * Input:
10304 *	ha = adapter state pointer.
10305 *	DEVICE_QUEUE_LOCK must be released.
10306 *
10307 * Context:
10308 *	Kernel context.
10309 */
10310void
10311ql_loop_online(ql_adapter_state_t *ha)
10312{
10313	ql_adapter_state_t	*vha;
10314
10315	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10316
10317	/* Inform the FC Transport that the hardware is online. */
10318	for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
10319		if (!(vha->task_daemon_flags &
10320		    (LOOP_RESYNC_NEEDED | LOOP_DOWN))) {
10321			/* Restart IP if it was shutdown. */
10322			if (vha->vp_index == 0 && vha->flags & IP_ENABLED &&
10323			    !(vha->flags & IP_INITIALIZED)) {
10324				(void) ql_initialize_ip(vha);
10325				ql_isp_rcvbuf(vha);
10326			}
10327
10328			if (FC_PORT_STATE_MASK(vha->state) != FC_STATE_LOOP &&
10329			    FC_PORT_STATE_MASK(vha->state) !=
10330			    FC_STATE_ONLINE) {
10331				vha->state = FC_PORT_SPEED_MASK(vha->state);
10332				if (vha->topology & QL_LOOP_CONNECTION) {
10333					vha->state |= FC_STATE_LOOP;
10334				} else {
10335					vha->state |= FC_STATE_ONLINE;
10336				}
10337				TASK_DAEMON_LOCK(ha);
10338				vha->task_daemon_flags |= FC_STATE_CHANGE;
10339				TASK_DAEMON_UNLOCK(ha);
10340			}
10341		}
10342	}
10343
10344	ql_awaken_task_daemon(ha, NULL, 0, 0);
10345
10346	/* Restart device queues that may have been stopped. */
10347	ql_restart_queues(ha);
10348
10349	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10350}
10351
10352/*
10353 * ql_fca_handle_to_state
10354 *	Verifies handle to be correct.
10355 *
10356 * Input:
10357 *	fca_handle = pointer to state structure.
10358 *
10359 * Returns:
10360 *	NULL = failure
10361 *
10362 * Context:
10363 *	Kernel context.
10364 */
10365static ql_adapter_state_t *
10366ql_fca_handle_to_state(opaque_t fca_handle)
10367{
10368#ifdef	QL_DEBUG_ROUTINES
10369	ql_link_t		*link;
10370	ql_adapter_state_t	*ha = NULL;
10371	ql_adapter_state_t	*vha = NULL;
10372
10373	for (link = ql_hba.first; link != NULL; link = link->next) {
10374		ha = link->base_address;
10375		for (vha = ha->vp_next; vha != NULL; vha = vha->vp_next) {
10376			if ((opaque_t)vha == fca_handle) {
10377				ha = vha;
10378				break;
10379			}
10380		}
10381		if ((opaque_t)ha == fca_handle) {
10382			break;
10383		} else {
10384			ha = NULL;
10385		}
10386	}
10387
10388	if (ha == NULL) {
10389		/*EMPTY*/
10390		QL_PRINT_2(CE_CONT, "failed\n");
10391	}
10392
10393#endif /* QL_DEBUG_ROUTINES */
10394
10395	return ((ql_adapter_state_t *)fca_handle);
10396}
10397
10398/*
10399 * ql_d_id_to_queue
10400 *	Locate device queue that matches destination ID.
10401 *
10402 * Input:
10403 *	ha = adapter state pointer.
10404 *	d_id = destination ID
10405 *
10406 * Returns:
10407 *	NULL = failure
10408 *
10409 * Context:
10410 *	Interrupt or Kernel context, no mailbox commands allowed.
10411 */
10412ql_tgt_t *
10413ql_d_id_to_queue(ql_adapter_state_t *ha, port_id_t d_id)
10414{
10415	uint16_t	index;
10416	ql_tgt_t	*tq;
10417	ql_link_t	*link;
10418
10419	/* Get head queue index. */
10420	index = ql_alpa_to_index[d_id.b.al_pa];
10421
10422	for (link = ha->dev[index].first; link != NULL; link = link->next) {
10423		tq = link->base_address;
10424		if (tq->d_id.b24 == d_id.b24 &&
10425		    VALID_DEVICE_ID(ha, tq->loop_id)) {
10426			return (tq);
10427		}
10428	}
10429
10430	return (NULL);
10431}
10432
10433/*
10434 * ql_loop_id_to_queue
10435 *	Locate device queue that matches loop ID.
10436 *
10437 * Input:
10438 *	ha:		adapter state pointer.
10439 *	loop_id:	destination ID
10440 *
10441 * Returns:
10442 *	NULL = failure
10443 *
10444 * Context:
10445 *	Interrupt or Kernel context, no mailbox commands allowed.
10446 */
10447ql_tgt_t *
10448ql_loop_id_to_queue(ql_adapter_state_t *ha, uint16_t loop_id)
10449{
10450	uint16_t	index;
10451	ql_tgt_t	*tq;
10452	ql_link_t	*link;
10453
10454	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
10455		for (link = ha->dev[index].first; link != NULL;
10456		    link = link->next) {
10457			tq = link->base_address;
10458			if (tq->loop_id == loop_id) {
10459				return (tq);
10460			}
10461		}
10462	}
10463
10464	return (NULL);
10465}
10466
10467/*
10468 * ql_kstat_update
10469 *	Updates kernel statistics.
10470 *
10471 * Input:
10472 *	ksp - driver kernel statistics structure pointer.
10473 *	rw - function to perform
10474 *
10475 * Returns:
10476 *	0 or EACCES
10477 *
10478 * Context:
10479 *	Kernel context.
10480 */
10481/* ARGSUSED */
10482static int
10483ql_kstat_update(kstat_t *ksp, int rw)
10484{
10485	int			rval;
10486
10487	QL_PRINT_3(CE_CONT, "started\n");
10488
10489	if (rw == KSTAT_WRITE) {
10490		rval = EACCES;
10491	} else {
10492		rval = 0;
10493	}
10494
10495	if (rval != 0) {
10496		/*EMPTY*/
10497		QL_PRINT_2(CE_CONT, "failed, rval = %xh\n", rval);
10498	} else {
10499		/*EMPTY*/
10500		QL_PRINT_3(CE_CONT, "done\n");
10501	}
10502	return (rval);
10503}
10504
10505/*
10506 * ql_load_flash
10507 *	Loads flash.
10508 *
10509 * Input:
10510 *	ha:	adapter state pointer.
10511 *	dp:	data pointer.
10512 *	size:	data length.
10513 *
10514 * Returns:
10515 *	ql local function return status code.
10516 *
10517 * Context:
10518 *	Kernel context.
10519 */
10520int
10521ql_load_flash(ql_adapter_state_t *ha, uint8_t *dp, uint32_t size)
10522{
10523	uint32_t	cnt;
10524	int		rval;
10525	uint32_t	size_to_offset;
10526	uint32_t	size_to_compare;
10527	int		erase_all;
10528
10529	if (CFG_IST(ha, CFG_CTRL_242581)) {
10530		return (ql_24xx_load_flash(ha, dp, size, 0));
10531	}
10532
10533	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10534
10535	size_to_compare = 0x20000;
10536	size_to_offset = 0;
10537	erase_all = 0;
10538	if (CFG_IST(ha, CFG_SBUS_CARD)) {
10539		if (size == 0x80000) {
10540			/* Request to flash the entire chip. */
10541			size_to_compare = 0x80000;
10542			erase_all = 1;
10543		} else {
10544			size_to_compare = 0x40000;
10545			if (ql_flash_sbus_fpga) {
10546				size_to_offset = 0x40000;
10547			}
10548		}
10549	}
10550	if (size > size_to_compare) {
10551		rval = QL_FUNCTION_PARAMETER_ERROR;
10552		EL(ha, "failed=%xh\n", rval);
10553		return (rval);
10554	}
10555
10556	GLOBAL_HW_LOCK();
10557
10558	/* Enable Flash Read/Write. */
10559	ql_flash_enable(ha);
10560
10561	/* Erase flash prior to write. */
10562	rval = ql_erase_flash(ha, erase_all);
10563
10564	if (rval == QL_SUCCESS) {
10565		/* Write data to flash. */
10566		for (cnt = 0; cnt < size; cnt++) {
10567			/* Allow other system activity. */
10568			if (cnt % 0x1000 == 0) {
10569				ql_delay(ha, 10000);
10570			}
10571			rval = ql_program_flash_address(ha,
10572			    cnt + size_to_offset, *dp++);
10573			if (rval != QL_SUCCESS) {
10574				break;
10575			}
10576		}
10577	}
10578
10579	ql_flash_disable(ha);
10580
10581	GLOBAL_HW_UNLOCK();
10582
10583	if (rval != QL_SUCCESS) {
10584		EL(ha, "failed=%xh\n", rval);
10585	} else {
10586		/*EMPTY*/
10587		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10588	}
10589	return (rval);
10590}
10591
10592/*
10593 * ql_program_flash_address
10594 *	Program flash address.
10595 *
10596 * Input:
10597 *	ha = adapter state pointer.
10598 *	addr = flash byte address.
10599 *	data = data to be written to flash.
10600 *
10601 * Returns:
10602 *	ql local function return status code.
10603 *
10604 * Context:
10605 *	Kernel context.
10606 */
10607static int
10608ql_program_flash_address(ql_adapter_state_t *ha, uint32_t addr, uint8_t data)
10609{
10610	int rval;
10611
10612	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10613
10614	if (CFG_IST(ha, CFG_SBUS_CARD)) {
10615		ql_write_flash_byte(ha, 0x5555, 0xa0);
10616		ql_write_flash_byte(ha, addr, data);
10617	} else {
10618		/* Write Program Command Sequence */
10619		ql_write_flash_byte(ha, 0x5555, 0xaa);
10620		ql_write_flash_byte(ha, 0x2aaa, 0x55);
10621		ql_write_flash_byte(ha, 0x5555, 0xa0);
10622		ql_write_flash_byte(ha, addr, data);
10623	}
10624
10625	/* Wait for write to complete. */
10626	rval = ql_poll_flash(ha, addr, data);
10627
10628	if (rval != QL_SUCCESS) {
10629		EL(ha, "failed=%xh\n", rval);
10630	} else {
10631		/*EMPTY*/
10632		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10633	}
10634	return (rval);
10635}
10636
10637/*
10638 * ql_erase_flash
10639 *	Erases entire flash.
10640 *
10641 * Input:
10642 *	ha = adapter state pointer.
10643 *
10644 * Returns:
10645 *	ql local function return status code.
10646 *
10647 * Context:
10648 *	Kernel context.
10649 */
10650int
10651ql_erase_flash(ql_adapter_state_t *ha, int erase_all)
10652{
10653	int		rval;
10654	uint32_t	erase_delay = 2000000;
10655	uint32_t	sStartAddr;
10656	uint32_t	ssize;
10657	uint32_t	cnt;
10658	uint8_t		*bfp;
10659	uint8_t		*tmp;
10660
10661	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10662
10663	if ((CFG_IST(ha, CFG_SBUS_CARD)) && !erase_all) {
10664
10665		if (ql_flash_sbus_fpga == 1) {
10666			ssize = QL_SBUS_FCODE_SIZE;
10667			sStartAddr = QL_FCODE_OFFSET;
10668		} else {
10669			ssize = QL_FPGA_SIZE;
10670			sStartAddr = QL_FPGA_OFFSET;
10671		}
10672
10673		erase_delay = 20000000;
10674
10675		bfp = (uint8_t *)kmem_zalloc(ssize, KM_SLEEP);
10676
10677		/* Save the section of flash we're not updating to buffer */
10678		tmp = bfp;
10679		for (cnt = sStartAddr; cnt < ssize+sStartAddr; cnt++) {
10680			/* Allow other system activity. */
10681			if (cnt % 0x1000 == 0) {
10682				ql_delay(ha, 10000);
10683			}
10684			*tmp++ = (uint8_t)ql_read_flash_byte(ha, cnt);
10685		}
10686	}
10687
10688	/* Chip Erase Command Sequence */
10689	ql_write_flash_byte(ha, 0x5555, 0xaa);
10690	ql_write_flash_byte(ha, 0x2aaa, 0x55);
10691	ql_write_flash_byte(ha, 0x5555, 0x80);
10692	ql_write_flash_byte(ha, 0x5555, 0xaa);
10693	ql_write_flash_byte(ha, 0x2aaa, 0x55);
10694	ql_write_flash_byte(ha, 0x5555, 0x10);
10695
10696	ql_delay(ha, erase_delay);
10697
10698	/* Wait for erase to complete. */
10699	rval = ql_poll_flash(ha, 0, 0x80);
10700
10701	if (rval != QL_SUCCESS) {
10702		EL(ha, "failed=%xh\n", rval);
10703		if (CFG_IST(ha, CFG_SBUS_CARD)) {
10704			kmem_free(bfp, ssize);
10705		}
10706		return (rval);
10707	}
10708
10709	/* restore the section we saved in the buffer */
10710	if ((CFG_IST(ha, CFG_SBUS_CARD)) && !erase_all) {
10711		/* Restore the section we saved off */
10712		tmp = bfp;
10713		for (cnt = sStartAddr; cnt < ssize+sStartAddr; cnt++) {
10714			/* Allow other system activity. */
10715			if (cnt % 0x1000 == 0) {
10716				ql_delay(ha, 10000);
10717			}
10718			rval = ql_program_flash_address(ha, cnt, *tmp++);
10719			if (rval != QL_SUCCESS) {
10720				break;
10721			}
10722		}
10723
10724		kmem_free(bfp, ssize);
10725	}
10726
10727	if (rval != QL_SUCCESS) {
10728		EL(ha, "failed=%xh\n", rval);
10729	} else {
10730		/*EMPTY*/
10731		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10732	}
10733	return (rval);
10734}
10735
10736/*
10737 * ql_poll_flash
10738 *	Polls flash for completion.
10739 *
10740 * Input:
10741 *	ha = adapter state pointer.
10742 *	addr = flash byte address.
10743 *	data = data to be polled.
10744 *
10745 * Returns:
10746 *	ql local function return status code.
10747 *
10748 * Context:
10749 *	Kernel context.
10750 */
10751int
10752ql_poll_flash(ql_adapter_state_t *ha, uint32_t addr, uint8_t poll_data)
10753{
10754	uint8_t		flash_data;
10755	uint32_t	cnt;
10756	int		rval = QL_FUNCTION_FAILED;
10757
10758	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10759
10760	poll_data = (uint8_t)(poll_data & BIT_7);
10761
10762	/* Wait for 30 seconds for command to finish. */
10763	for (cnt = 30000000; cnt; cnt--) {
10764		flash_data = (uint8_t)ql_read_flash_byte(ha, addr);
10765
10766		if ((flash_data & BIT_7) == poll_data) {
10767			rval = QL_SUCCESS;
10768			break;
10769		}
10770		if (flash_data & BIT_5 && cnt > 2) {
10771			cnt = 2;
10772		}
10773		drv_usecwait(1);
10774	}
10775
10776	if (rval != QL_SUCCESS) {
10777		EL(ha, "failed=%xh\n", rval);
10778	} else {
10779		/*EMPTY*/
10780		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10781	}
10782	return (rval);
10783}
10784
10785/*
10786 * ql_flash_enable
10787 *	Setup flash for reading/writing.
10788 *
10789 * Input:
10790 *	ha = adapter state pointer.
10791 *
10792 * Context:
10793 *	Kernel context.
10794 */
10795void
10796ql_flash_enable(ql_adapter_state_t *ha)
10797{
10798	uint16_t	data;
10799
10800	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10801
10802	/* Enable Flash Read/Write. */
10803	if (CFG_IST(ha, CFG_SBUS_CARD)) {
10804		data = (uint16_t)ddi_get16(ha->sbus_fpga_dev_handle,
10805		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF));
10806		data = (uint16_t)(data | SBUS_FLASH_WRITE_ENABLE);
10807		ddi_put16(ha->sbus_fpga_dev_handle,
10808		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF), data);
10809		/* Read reset command sequence */
10810		ql_write_flash_byte(ha, 0xaaa, 0xaa);
10811		ql_write_flash_byte(ha, 0x555, 0x55);
10812		ql_write_flash_byte(ha, 0xaaa, 0x20);
10813		ql_write_flash_byte(ha, 0x555, 0xf0);
10814	} else {
10815		data = (uint16_t)(RD16_IO_REG(ha, ctrl_status) |
10816		    ISP_FLASH_ENABLE);
10817		WRT16_IO_REG(ha, ctrl_status, data);
10818
10819		/* Read/Reset Command Sequence */
10820		ql_write_flash_byte(ha, 0x5555, 0xaa);
10821		ql_write_flash_byte(ha, 0x2aaa, 0x55);
10822		ql_write_flash_byte(ha, 0x5555, 0xf0);
10823	}
10824	(void) ql_read_flash_byte(ha, 0);
10825
10826	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10827}
10828
10829/*
10830 * ql_flash_disable
10831 *	Disable flash and allow RISC to run.
10832 *
10833 * Input:
10834 *	ha = adapter state pointer.
10835 *
10836 * Context:
10837 *	Kernel context.
10838 */
10839void
10840ql_flash_disable(ql_adapter_state_t *ha)
10841{
10842	uint16_t	data;
10843
10844	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
10845
10846	if (CFG_IST(ha, CFG_SBUS_CARD)) {
10847		/*
10848		 * Lock the flash back up.
10849		 */
10850		ql_write_flash_byte(ha, 0x555, 0x90);
10851		ql_write_flash_byte(ha, 0x555, 0x0);
10852
10853		data = (uint16_t)ddi_get16(ha->sbus_fpga_dev_handle,
10854		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF));
10855		data = (uint16_t)(data & ~SBUS_FLASH_WRITE_ENABLE);
10856		ddi_put16(ha->sbus_fpga_dev_handle,
10857		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_CONF), data);
10858	} else {
10859		data = (uint16_t)(RD16_IO_REG(ha, ctrl_status) &
10860		    ~ISP_FLASH_ENABLE);
10861		WRT16_IO_REG(ha, ctrl_status, data);
10862	}
10863
10864	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
10865}
10866
10867/*
10868 * ql_write_flash_byte
10869 *	Write byte to flash.
10870 *
10871 * Input:
10872 *	ha = adapter state pointer.
10873 *	addr = flash byte address.
10874 *	data = data to be written.
10875 *
10876 * Context:
10877 *	Kernel context.
10878 */
10879void
10880ql_write_flash_byte(ql_adapter_state_t *ha, uint32_t addr, uint8_t data)
10881{
10882	if (CFG_IST(ha, CFG_SBUS_CARD)) {
10883		ddi_put16(ha->sbus_fpga_dev_handle,
10884		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_LOADDR),
10885		    LSW(addr));
10886		ddi_put16(ha->sbus_fpga_dev_handle,
10887		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_HIADDR),
10888		    MSW(addr));
10889		ddi_put16(ha->sbus_fpga_dev_handle,
10890		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_DATA),
10891		    (uint16_t)data);
10892	} else {
10893		uint16_t bank_select;
10894
10895		/* Setup bit 16 of flash address. */
10896		bank_select = (uint16_t)RD16_IO_REG(ha, ctrl_status);
10897
10898		if (CFG_IST(ha, CFG_CTRL_6322)) {
10899			bank_select = (uint16_t)(bank_select & ~0xf0);
10900			bank_select = (uint16_t)(bank_select |
10901			    ((addr >> 12 & 0xf0) | ISP_FLASH_64K_BANK));
10902			WRT16_IO_REG(ha, ctrl_status, bank_select);
10903		} else {
10904			if (addr & BIT_16 && !(bank_select &
10905			    ISP_FLASH_64K_BANK)) {
10906				bank_select = (uint16_t)(bank_select |
10907				    ISP_FLASH_64K_BANK);
10908				WRT16_IO_REG(ha, ctrl_status, bank_select);
10909			} else if (!(addr & BIT_16) && bank_select &
10910			    ISP_FLASH_64K_BANK) {
10911				bank_select = (uint16_t)(bank_select &
10912				    ~ISP_FLASH_64K_BANK);
10913				WRT16_IO_REG(ha, ctrl_status, bank_select);
10914			}
10915		}
10916
10917		if (CFG_IST(ha, CFG_SBUS_CARD)) {
10918			WRT16_IO_REG(ha, flash_address, (uint16_t)addr);
10919			WRT16_IO_REG(ha, flash_data, (uint16_t)data);
10920		} else {
10921			WRT16_IOMAP_REG(ha, flash_address, addr);
10922			WRT16_IOMAP_REG(ha, flash_data, data);
10923		}
10924	}
10925}
10926
10927/*
10928 * ql_read_flash_byte
10929 *	Reads byte from flash, but must read a word from chip.
10930 *
10931 * Input:
10932 *	ha = adapter state pointer.
10933 *	addr = flash byte address.
10934 *
10935 * Returns:
10936 *	byte from flash.
10937 *
10938 * Context:
10939 *	Kernel context.
10940 */
10941uint8_t
10942ql_read_flash_byte(ql_adapter_state_t *ha, uint32_t addr)
10943{
10944	uint8_t	data;
10945
10946	if (CFG_IST(ha, CFG_SBUS_CARD)) {
10947		ddi_put16(ha->sbus_fpga_dev_handle,
10948		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_LOADDR),
10949		    LSW(addr));
10950		ddi_put16(ha->sbus_fpga_dev_handle,
10951		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_HIADDR),
10952		    MSW(addr));
10953		data = (uint8_t)ddi_get16(ha->sbus_fpga_dev_handle,
10954		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_EEPROM_DATA));
10955	} else {
10956		uint16_t	bank_select;
10957
10958		/* Setup bit 16 of flash address. */
10959		bank_select = RD16_IO_REG(ha, ctrl_status);
10960		if (CFG_IST(ha, CFG_CTRL_6322)) {
10961			bank_select = (uint16_t)(bank_select & ~0xf0);
10962			bank_select = (uint16_t)(bank_select |
10963			    ((addr >> 12 & 0xf0) | ISP_FLASH_64K_BANK));
10964			WRT16_IO_REG(ha, ctrl_status, bank_select);
10965		} else {
10966			if (addr & BIT_16 &&
10967			    !(bank_select & ISP_FLASH_64K_BANK)) {
10968				bank_select = (uint16_t)(bank_select |
10969				    ISP_FLASH_64K_BANK);
10970				WRT16_IO_REG(ha, ctrl_status, bank_select);
10971			} else if (!(addr & BIT_16) &&
10972			    bank_select & ISP_FLASH_64K_BANK) {
10973				bank_select = (uint16_t)(bank_select &
10974				    ~ISP_FLASH_64K_BANK);
10975				WRT16_IO_REG(ha, ctrl_status, bank_select);
10976			}
10977		}
10978
10979		if (CFG_IST(ha, CFG_SBUS_CARD)) {
10980			WRT16_IO_REG(ha, flash_address, addr);
10981			data = (uint8_t)RD16_IO_REG(ha, flash_data);
10982		} else {
10983			WRT16_IOMAP_REG(ha, flash_address, addr);
10984			data = (uint8_t)RD16_IOMAP_REG(ha, flash_data);
10985		}
10986	}
10987
10988	return (data);
10989}
10990
10991/*
10992 * ql_24xx_flash_id
10993 *	Get flash IDs.
10994 *
10995 * Input:
10996 *	ha:		adapter state pointer.
10997 *
10998 * Returns:
10999 *	ql local function return status code.
11000 *
11001 * Context:
11002 *	Kernel context.
11003 */
11004int
11005ql_24xx_flash_id(ql_adapter_state_t *vha)
11006{
11007	int			rval;
11008	uint32_t		fdata = 0;
11009	ql_adapter_state_t	*ha = vha->pha;
11010	ql_xioctl_t		*xp = ha->xioctl;
11011
11012	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11013
11014	rval = ql_24xx_read_flash(ha, FLASH_CONF_ADDR | 0x3AB, &fdata);
11015
11016	if (rval != QL_SUCCESS || fdata == 0 || CFG_IST(ha, CFG_CTRL_2581)) {
11017		fdata = 0;
11018		rval = ql_24xx_read_flash(ha, FLASH_CONF_ADDR |
11019		    (CFG_IST(ha, CFG_CTRL_2422) ? 0x39F : 0x49F), &fdata);
11020	}
11021
11022	if (rval != QL_SUCCESS) {
11023		EL(ha, "24xx read_flash failed=%xh\n", rval);
11024	} else if (fdata != 0) {
11025		xp->fdesc.flash_manuf = LSB(LSW(fdata));
11026		xp->fdesc.flash_id = MSB(LSW(fdata));
11027		xp->fdesc.flash_len = LSB(MSW(fdata));
11028	} else {
11029		xp->fdesc.flash_manuf = ATMEL_FLASH;
11030		xp->fdesc.flash_id = ATMEL_FLASHID_1024K;
11031		xp->fdesc.flash_len = 0;
11032	}
11033
11034	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11035
11036	return (rval);
11037}
11038
11039/*
11040 * ql_24xx_load_flash
11041 *	Loads flash.
11042 *
11043 * Input:
11044 *	ha = adapter state pointer.
11045 *	dp = data pointer.
11046 *	size = data length in bytes.
11047 *	faddr = 32bit word flash byte address.
11048 *
11049 * Returns:
11050 *	ql local function return status code.
11051 *
11052 * Context:
11053 *	Kernel context.
11054 */
11055int
11056ql_24xx_load_flash(ql_adapter_state_t *vha, uint8_t *dp, uint32_t size,
11057    uint32_t faddr)
11058{
11059	int			rval;
11060	uint32_t		cnt, rest_addr, fdata, wc;
11061	dma_mem_t		dmabuf = {0};
11062	ql_adapter_state_t	*ha = vha->pha;
11063	ql_xioctl_t		*xp = ha->xioctl;
11064
11065	QL_PRINT_3(CE_CONT, "(%d): started, faddr=%xh, size=%xh\n",
11066	    ha->instance, faddr, size);
11067
11068	/* start address must be 32 bit word aligned */
11069	if ((faddr & 0x3) != 0) {
11070		EL(ha, "incorrect buffer size alignment\n");
11071		return (QL_FUNCTION_PARAMETER_ERROR);
11072	}
11073
11074	/* Allocate DMA buffer */
11075	if (CFG_IST(ha, CFG_CTRL_2581)) {
11076		if ((rval = ql_get_dma_mem(ha, &dmabuf, 0xffff,
11077		    LITTLE_ENDIAN_DMA, QL_DMA_DATA_ALIGN)) !=
11078		    QL_SUCCESS) {
11079			EL(ha, "dma alloc failed, rval=%xh\n", rval);
11080			return (rval);
11081		}
11082	}
11083
11084	GLOBAL_HW_LOCK();
11085
11086	/* Enable flash write */
11087	if ((rval = ql_24xx_unprotect_flash(ha)) != QL_SUCCESS) {
11088		GLOBAL_HW_UNLOCK();
11089		EL(ha, "unprotect_flash failed, rval=%xh\n", rval);
11090		ql_free_phys(ha, &dmabuf);
11091		return (rval);
11092	}
11093
11094	/* setup mask of address range within a sector */
11095	rest_addr = (xp->fdesc.block_size - 1) >> 2;
11096
11097	faddr = faddr >> 2;	/* flash gets 32 bit words */
11098
11099	/*
11100	 * Write data to flash.
11101	 */
11102	cnt = 0;
11103	size = (size + 3) >> 2;	/* Round up & convert to dwords */
11104
11105	while (cnt < size) {
11106		/* Beginning of a sector? */
11107		if ((faddr & rest_addr) == 0) {
11108			if (CFG_IST(ha, CFG_CTRL_81XX)) {
11109				fdata = ha->flash_data_addr | faddr;
11110				rval = ql_flash_access(ha,
11111				    FAC_ERASE_SECTOR, fdata, fdata +
11112				    rest_addr, 0);
11113				if (rval != QL_SUCCESS) {
11114					EL(ha, "erase sector status="
11115					    "%xh, start=%xh, end=%xh"
11116					    "\n", rval, fdata,
11117					    fdata + rest_addr);
11118					break;
11119				}
11120			} else {
11121				fdata = (faddr & ~rest_addr) << 2;
11122				fdata = (fdata & 0xff00) |
11123				    (fdata << 16 & 0xff0000) |
11124				    (fdata >> 16 & 0xff);
11125
11126				if (rest_addr == 0x1fff) {
11127					/* 32kb sector block erase */
11128					rval = ql_24xx_write_flash(ha,
11129					    FLASH_CONF_ADDR | 0x0352,
11130					    fdata);
11131				} else {
11132					/* 64kb sector block erase */
11133					rval = ql_24xx_write_flash(ha,
11134					    FLASH_CONF_ADDR | 0x03d8,
11135					    fdata);
11136				}
11137				if (rval != QL_SUCCESS) {
11138					EL(ha, "Unable to flash sector"
11139					    ": address=%xh\n", faddr);
11140					break;
11141				}
11142			}
11143		}
11144
11145		/* Write data */
11146		if (CFG_IST(ha, CFG_CTRL_2581) &&
11147		    ((faddr & 0x3f) == 0)) {
11148			/*
11149			 * Limit write up to sector boundary.
11150			 */
11151			wc = ((~faddr & (rest_addr>>1)) + 1);
11152
11153			if (size - cnt < wc) {
11154				wc = size - cnt;
11155			}
11156
11157			ddi_rep_put8(dmabuf.acc_handle, (uint8_t *)dp,
11158			    (uint8_t *)dmabuf.bp, wc<<2,
11159			    DDI_DEV_AUTOINCR);
11160
11161			rval = ql_wrt_risc_ram(ha, ha->flash_data_addr |
11162			    faddr, dmabuf.cookie.dmac_laddress, wc);
11163			if (rval != QL_SUCCESS) {
11164				EL(ha, "unable to dma to flash "
11165				    "address=%xh\n", faddr << 2);
11166				break;
11167			}
11168
11169			cnt += wc;
11170			faddr += wc;
11171			dp += wc << 2;
11172		} else {
11173			fdata = *dp++;
11174			fdata |= *dp++ << 8;
11175			fdata |= *dp++ << 16;
11176			fdata |= *dp++ << 24;
11177			rval = ql_24xx_write_flash(ha,
11178			    ha->flash_data_addr | faddr, fdata);
11179			if (rval != QL_SUCCESS) {
11180				EL(ha, "Unable to program flash "
11181				    "address=%xh data=%xh\n", faddr,
11182				    *dp);
11183				break;
11184			}
11185			cnt++;
11186			faddr++;
11187
11188			/* Allow other system activity. */
11189			if (cnt % 0x1000 == 0) {
11190				ql_delay(ha, 10000);
11191			}
11192		}
11193	}
11194
11195	ql_24xx_protect_flash(ha);
11196
11197	ql_free_phys(ha, &dmabuf);
11198
11199	GLOBAL_HW_UNLOCK();
11200
11201	if (rval != QL_SUCCESS) {
11202		EL(ha, "failed=%xh\n", rval);
11203	} else {
11204		/*EMPTY*/
11205		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11206	}
11207	return (rval);
11208}
11209
11210/*
11211 * ql_24xx_read_flash
11212 *	Reads a 32bit word from ISP24xx NVRAM/FLASH.
11213 *
11214 * Input:
11215 *	ha:	adapter state pointer.
11216 *	faddr:	NVRAM/FLASH address.
11217 *	bp:	data pointer.
11218 *
11219 * Returns:
11220 *	ql local function return status code.
11221 *
11222 * Context:
11223 *	Kernel context.
11224 */
11225int
11226ql_24xx_read_flash(ql_adapter_state_t *vha, uint32_t faddr, uint32_t *bp)
11227{
11228	uint32_t		timer;
11229	int			rval = QL_SUCCESS;
11230	ql_adapter_state_t	*ha = vha->pha;
11231
11232	/* Clear access error flag */
11233	WRT32_IO_REG(ha, ctrl_status,
11234	    RD32_IO_REG(ha, ctrl_status) | FLASH_NVRAM_ACCESS_ERROR);
11235
11236	WRT32_IO_REG(ha, flash_address, faddr & ~FLASH_DATA_FLAG);
11237
11238	/* Wait for READ cycle to complete. */
11239	for (timer = 300000; timer; timer--) {
11240		if (RD32_IO_REG(ha, flash_address) & FLASH_DATA_FLAG) {
11241			break;
11242		}
11243		drv_usecwait(10);
11244	}
11245
11246	if (timer == 0) {
11247		EL(ha, "failed, timeout\n");
11248		rval = QL_FUNCTION_TIMEOUT;
11249	} else if (RD32_IO_REG(ha, ctrl_status) & FLASH_NVRAM_ACCESS_ERROR) {
11250		EL(ha, "failed, access error\n");
11251		rval = QL_FUNCTION_FAILED;
11252	}
11253
11254	*bp = RD32_IO_REG(ha, flash_data);
11255
11256	return (rval);
11257}
11258
11259/*
11260 * ql_24xx_write_flash
11261 *	Writes a 32bit word to ISP24xx NVRAM/FLASH.
11262 *
11263 * Input:
11264 *	ha:	adapter state pointer.
11265 *	addr:	NVRAM/FLASH address.
11266 *	value:	data.
11267 *
11268 * Returns:
11269 *	ql local function return status code.
11270 *
11271 * Context:
11272 *	Kernel context.
11273 */
11274int
11275ql_24xx_write_flash(ql_adapter_state_t *vha, uint32_t addr, uint32_t data)
11276{
11277	uint32_t		timer, fdata;
11278	int			rval = QL_SUCCESS;
11279	ql_adapter_state_t	*ha = vha->pha;
11280
11281	/* Clear access error flag */
11282	WRT32_IO_REG(ha, ctrl_status,
11283	    RD32_IO_REG(ha, ctrl_status) | FLASH_NVRAM_ACCESS_ERROR);
11284
11285	WRT32_IO_REG(ha, flash_data, data);
11286	RD32_IO_REG(ha, flash_data);		/* PCI Posting. */
11287	WRT32_IO_REG(ha, flash_address, addr | FLASH_DATA_FLAG);
11288
11289	/* Wait for Write cycle to complete. */
11290	for (timer = 3000000; timer; timer--) {
11291		if ((RD32_IO_REG(ha, flash_address) & FLASH_DATA_FLAG) == 0) {
11292			/* Check flash write in progress. */
11293			if ((addr & FLASH_ADDR_MASK) == FLASH_CONF_ADDR) {
11294				(void) ql_24xx_read_flash(ha,
11295				    FLASH_CONF_ADDR | 0x005, &fdata);
11296				if (!(fdata & BIT_0)) {
11297					break;
11298				}
11299			} else {
11300				break;
11301			}
11302		}
11303		drv_usecwait(10);
11304	}
11305	if (timer == 0) {
11306		EL(ha, "failed, timeout\n");
11307		rval = QL_FUNCTION_TIMEOUT;
11308	} else if (RD32_IO_REG(ha, ctrl_status) & FLASH_NVRAM_ACCESS_ERROR) {
11309		EL(ha, "access error\n");
11310		rval = QL_FUNCTION_FAILED;
11311	}
11312
11313	return (rval);
11314}
11315/*
11316 * ql_24xx_unprotect_flash
11317 *	Enable writes
11318 *
11319 * Input:
11320 *	ha:	adapter state pointer.
11321 *
11322 * Returns:
11323 *	ql local function return status code.
11324 *
11325 * Context:
11326 *	Kernel context.
11327 */
11328int
11329ql_24xx_unprotect_flash(ql_adapter_state_t *vha)
11330{
11331	int			rval;
11332	uint32_t		fdata;
11333	ql_adapter_state_t	*ha = vha->pha;
11334	ql_xioctl_t		*xp = ha->xioctl;
11335
11336	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11337
11338	if (CFG_IST(ha, CFG_CTRL_81XX)) {
11339		if (ha->task_daemon_flags & FIRMWARE_UP) {
11340			if ((rval = ql_flash_access(ha, FAC_WRT_ENABLE, 0, 0,
11341			    0)) != QL_SUCCESS) {
11342				EL(ha, "status=%xh\n", rval);
11343			}
11344			QL_PRINT_3(CE_CONT, "(%d): 8100 done\n",
11345			    ha->instance);
11346			return (rval);
11347		}
11348	} else {
11349		/* Enable flash write. */
11350		WRT32_IO_REG(ha, ctrl_status,
11351		    RD32_IO_REG(ha, ctrl_status) | ISP_FLASH_ENABLE);
11352		RD32_IO_REG(ha, ctrl_status);	/* PCI Posting. */
11353	}
11354
11355	/*
11356	 * Remove block write protection (SST and ST) and
11357	 * Sector/Block Protection Register Lock (SST, ST, ATMEL).
11358	 * Unprotect sectors.
11359	 */
11360	(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x100 |
11361	    xp->fdesc.write_statusreg_cmd, xp->fdesc.write_enable_bits);
11362
11363	if (xp->fdesc.unprotect_sector_cmd != 0) {
11364		for (fdata = 0; fdata < 0x10; fdata++) {
11365			(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR |
11366			    0x300 | xp->fdesc.unprotect_sector_cmd, fdata);
11367		}
11368
11369		(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 |
11370		    xp->fdesc.unprotect_sector_cmd, 0x00400f);
11371		(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 |
11372		    xp->fdesc.unprotect_sector_cmd, 0x00600f);
11373		(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x300 |
11374		    xp->fdesc.unprotect_sector_cmd, 0x00800f);
11375	}
11376
11377	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11378
11379	return (QL_SUCCESS);
11380}
11381
11382/*
11383 * ql_24xx_protect_flash
11384 *	Disable writes
11385 *
11386 * Input:
11387 *	ha:	adapter state pointer.
11388 *
11389 * Context:
11390 *	Kernel context.
11391 */
11392void
11393ql_24xx_protect_flash(ql_adapter_state_t *vha)
11394{
11395	int			rval;
11396	uint32_t		fdata;
11397	ql_adapter_state_t	*ha = vha->pha;
11398	ql_xioctl_t		*xp = ha->xioctl;
11399
11400	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11401
11402	if (CFG_IST(ha, CFG_CTRL_81XX)) {
11403		if (ha->task_daemon_flags & FIRMWARE_UP) {
11404			if ((rval = ql_flash_access(ha, FAC_WRT_PROTECT, 0, 0,
11405			    0)) != QL_SUCCESS) {
11406				EL(ha, "status=%xh\n", rval);
11407			}
11408			QL_PRINT_3(CE_CONT, "(%d): 8100 done\n",
11409			    ha->instance);
11410			return;
11411		}
11412	} else {
11413		/* Enable flash write. */
11414		WRT32_IO_REG(ha, ctrl_status,
11415		    RD32_IO_REG(ha, ctrl_status) | ISP_FLASH_ENABLE);
11416		RD32_IO_REG(ha, ctrl_status);	/* PCI Posting. */
11417	}
11418
11419	/*
11420	 * Protect sectors.
11421	 * Set block write protection (SST and ST) and
11422	 * Sector/Block Protection Register Lock (SST, ST, ATMEL).
11423	 */
11424	if (xp->fdesc.protect_sector_cmd != 0) {
11425		for (fdata = 0; fdata < 0x10; fdata++) {
11426			(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR |
11427			    0x330 | xp->fdesc.protect_sector_cmd, fdata);
11428		}
11429		(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x330 |
11430		    xp->fdesc.protect_sector_cmd, 0x00400f);
11431		(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x330 |
11432		    xp->fdesc.protect_sector_cmd, 0x00600f);
11433		(void) ql_24xx_write_flash(ha, FLASH_CONF_ADDR | 0x330 |
11434		    xp->fdesc.protect_sector_cmd, 0x00800f);
11435
11436		/* TODO: ??? */
11437		(void) ql_24xx_write_flash(ha,
11438		    FLASH_CONF_ADDR | 0x101, 0x80);
11439	} else {
11440		(void) ql_24xx_write_flash(ha,
11441		    FLASH_CONF_ADDR | 0x101, 0x9c);
11442	}
11443
11444	/* Disable flash write. */
11445	if (!(CFG_IST(ha, CFG_CTRL_81XX))) {
11446		WRT32_IO_REG(ha, ctrl_status,
11447		    RD32_IO_REG(ha, ctrl_status) & ~ISP_FLASH_ENABLE);
11448		RD32_IO_REG(ha, ctrl_status);	/* PCI Posting. */
11449	}
11450
11451	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11452}
11453
11454/*
11455 * ql_dump_firmware
11456 *	Save RISC code state information.
11457 *
11458 * Input:
11459 *	ha = adapter state pointer.
11460 *
11461 * Returns:
11462 *	QL local function return status code.
11463 *
11464 * Context:
11465 *	Kernel context.
11466 */
11467static int
11468ql_dump_firmware(ql_adapter_state_t *vha)
11469{
11470	int			rval;
11471	clock_t			timer = drv_usectohz(30000000);
11472	ql_adapter_state_t	*ha = vha->pha;
11473
11474	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11475
11476	QL_DUMP_LOCK(ha);
11477
11478	if (ha->ql_dump_state & QL_DUMPING ||
11479	    (ha->ql_dump_state & QL_DUMP_VALID &&
11480	    !(ha->ql_dump_state & QL_DUMP_UPLOADED))) {
11481		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11482		QL_DUMP_UNLOCK(ha);
11483		return (QL_SUCCESS);
11484	}
11485
11486	QL_DUMP_UNLOCK(ha);
11487
11488	ql_awaken_task_daemon(ha, NULL, DRIVER_STALL, 0);
11489
11490	/*
11491	 * Wait for all outstanding commands to complete
11492	 */
11493	(void) ql_wait_outstanding(ha);
11494
11495	/* Dump firmware. */
11496	rval = ql_binary_fw_dump(ha, TRUE);
11497
11498	/* Do abort to force restart. */
11499	ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED, DRIVER_STALL);
11500	EL(ha, "restarting, isp_abort_needed\n");
11501
11502	/* Acquire task daemon lock. */
11503	TASK_DAEMON_LOCK(ha);
11504
11505	/* Wait for suspension to end. */
11506	while (ha->task_daemon_flags & QL_SUSPENDED) {
11507		ha->task_daemon_flags |= SUSPENDED_WAKEUP_FLG;
11508
11509		/* 30 seconds from now */
11510		if (cv_reltimedwait(&ha->cv_dr_suspended,
11511		    &ha->task_daemon_mutex, timer, TR_CLOCK_TICK) == -1) {
11512			/*
11513			 * The timeout time 'timer' was
11514			 * reached without the condition
11515			 * being signaled.
11516			 */
11517			break;
11518		}
11519	}
11520
11521	/* Release task daemon lock. */
11522	TASK_DAEMON_UNLOCK(ha);
11523
11524	if (rval == QL_SUCCESS || rval == QL_DATA_EXISTS) {
11525		/*EMPTY*/
11526		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11527	} else {
11528		EL(ha, "failed, rval = %xh\n", rval);
11529	}
11530	return (rval);
11531}
11532
11533/*
11534 * ql_binary_fw_dump
11535 *	Dumps binary data from firmware.
11536 *
11537 * Input:
11538 *	ha = adapter state pointer.
11539 *	lock_needed = mailbox lock needed.
11540 *
11541 * Returns:
11542 *	ql local function return status code.
11543 *
11544 * Context:
11545 *	Interrupt or Kernel context, no mailbox commands allowed.
11546 */
11547int
11548ql_binary_fw_dump(ql_adapter_state_t *vha, int lock_needed)
11549{
11550	clock_t			timer;
11551	mbx_cmd_t		mc;
11552	mbx_cmd_t		*mcp = &mc;
11553	int			rval = QL_SUCCESS;
11554	ql_adapter_state_t	*ha = vha->pha;
11555
11556	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11557
11558	QL_DUMP_LOCK(ha);
11559
11560	if (ha->ql_dump_state & QL_DUMPING ||
11561	    (ha->ql_dump_state & QL_DUMP_VALID &&
11562	    !(ha->ql_dump_state & QL_DUMP_UPLOADED))) {
11563		EL(ha, "dump already done, qds=%x\n", ha->ql_dump_state);
11564		QL_DUMP_UNLOCK(ha);
11565		return (QL_DATA_EXISTS);
11566	}
11567
11568	ha->ql_dump_state &= ~(QL_DUMP_VALID | QL_DUMP_UPLOADED);
11569	ha->ql_dump_state |= QL_DUMPING;
11570
11571	QL_DUMP_UNLOCK(ha);
11572
11573	if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE)) {
11574
11575		/* Insert Time Stamp */
11576		rval = ql_fw_etrace(ha, &ha->fwexttracebuf,
11577		    FTO_INSERT_TIME_STAMP);
11578		if (rval != QL_SUCCESS) {
11579			EL(ha, "f/w extended trace insert"
11580			    "time stamp failed: %xh\n", rval);
11581		}
11582	}
11583
11584	if (lock_needed == TRUE) {
11585		/* Acquire mailbox register lock. */
11586		MBX_REGISTER_LOCK(ha);
11587		timer = (ha->mcp->timeout + 2) * drv_usectohz(1000000);
11588		/* Check for mailbox available, if not wait for signal. */
11589		while (ha->mailbox_flags & MBX_BUSY_FLG) {
11590			ha->mailbox_flags = (uint8_t)
11591			    (ha->mailbox_flags | MBX_WANT_FLG);
11592
11593			/* 30 seconds from now */
11594			if (cv_reltimedwait(&ha->cv_mbx_wait, &ha->mbx_mutex,
11595			    timer, TR_CLOCK_TICK) == -1) {
11596				/*
11597				 * The timeout time 'timer' was
11598				 * reached without the condition
11599				 * being signaled.
11600				 */
11601
11602				/* Release mailbox register lock. */
11603				MBX_REGISTER_UNLOCK(ha);
11604
11605				EL(ha, "failed, rval = %xh\n",
11606				    QL_FUNCTION_TIMEOUT);
11607				return (QL_FUNCTION_TIMEOUT);
11608			}
11609		}
11610
11611		/* Set busy flag. */
11612		ha->mailbox_flags = (uint8_t)
11613		    (ha->mailbox_flags | MBX_BUSY_FLG);
11614		mcp->timeout = 120;
11615		ha->mcp = mcp;
11616
11617		/* Release mailbox register lock. */
11618		MBX_REGISTER_UNLOCK(ha);
11619	}
11620
11621	/* Free previous dump buffer. */
11622	if (ha->ql_dump_ptr != NULL) {
11623		kmem_free(ha->ql_dump_ptr, ha->ql_dump_size);
11624		ha->ql_dump_ptr = NULL;
11625	}
11626
11627	if (CFG_IST(ha, CFG_CTRL_2422)) {
11628		ha->ql_dump_size = (uint32_t)(sizeof (ql_24xx_fw_dump_t) +
11629		    ha->fw_ext_memory_size);
11630	} else if (CFG_IST(ha, CFG_CTRL_25XX)) {
11631		ha->ql_dump_size = (uint32_t)(sizeof (ql_25xx_fw_dump_t) +
11632		    ha->fw_ext_memory_size);
11633	} else if (CFG_IST(ha, CFG_CTRL_81XX)) {
11634		ha->ql_dump_size = (uint32_t)(sizeof (ql_81xx_fw_dump_t) +
11635		    ha->fw_ext_memory_size);
11636	} else {
11637		ha->ql_dump_size = sizeof (ql_fw_dump_t);
11638	}
11639
11640	if ((ha->ql_dump_ptr = kmem_zalloc(ha->ql_dump_size, KM_NOSLEEP)) ==
11641	    NULL) {
11642		rval = QL_MEMORY_ALLOC_FAILED;
11643	} else {
11644		if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
11645			rval = ql_2300_binary_fw_dump(ha, ha->ql_dump_ptr);
11646		} else if (CFG_IST(ha, CFG_CTRL_81XX)) {
11647			rval = ql_81xx_binary_fw_dump(ha, ha->ql_dump_ptr);
11648		} else if (CFG_IST(ha, CFG_CTRL_25XX)) {
11649			rval = ql_25xx_binary_fw_dump(ha, ha->ql_dump_ptr);
11650		} else if (CFG_IST(ha, CFG_CTRL_2422)) {
11651			rval = ql_24xx_binary_fw_dump(ha, ha->ql_dump_ptr);
11652		} else {
11653			rval = ql_2200_binary_fw_dump(ha, ha->ql_dump_ptr);
11654		}
11655	}
11656
11657	/* Reset ISP chip. */
11658	ql_reset_chip(ha);
11659
11660	QL_DUMP_LOCK(ha);
11661
11662	if (rval != QL_SUCCESS) {
11663		if (ha->ql_dump_ptr != NULL) {
11664			kmem_free(ha->ql_dump_ptr, ha->ql_dump_size);
11665			ha->ql_dump_ptr = NULL;
11666		}
11667		ha->ql_dump_state &= ~(QL_DUMPING | QL_DUMP_VALID |
11668		    QL_DUMP_UPLOADED);
11669		EL(ha, "failed, rval = %xh\n", rval);
11670	} else {
11671		ha->ql_dump_state &= ~(QL_DUMPING | QL_DUMP_UPLOADED);
11672		ha->ql_dump_state |= QL_DUMP_VALID;
11673		EL(ha, "done\n");
11674	}
11675
11676	QL_DUMP_UNLOCK(ha);
11677
11678	return (rval);
11679}
11680
11681/*
11682 * ql_ascii_fw_dump
11683 *	Converts firmware binary dump to ascii.
11684 *
11685 * Input:
11686 *	ha = adapter state pointer.
11687 *	bptr = buffer pointer.
11688 *
11689 * Returns:
11690 *	Amount of data buffer used.
11691 *
11692 * Context:
11693 *	Kernel context.
11694 */
11695size_t
11696ql_ascii_fw_dump(ql_adapter_state_t *vha, caddr_t bufp)
11697{
11698	uint32_t		cnt;
11699	caddr_t			bp;
11700	int			mbox_cnt;
11701	ql_adapter_state_t	*ha = vha->pha;
11702	ql_fw_dump_t		*fw = ha->ql_dump_ptr;
11703
11704	if (CFG_IST(ha, CFG_CTRL_2422)) {
11705		return (ql_24xx_ascii_fw_dump(ha, bufp));
11706	} else if (CFG_IST(ha, CFG_CTRL_2581)) {
11707		return (ql_2581_ascii_fw_dump(ha, bufp));
11708	}
11709
11710	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
11711
11712	if (CFG_IST(ha, CFG_CTRL_2300)) {
11713		(void) sprintf(bufp, "\nISP 2300IP ");
11714	} else if (CFG_IST(ha, CFG_CTRL_6322)) {
11715		(void) sprintf(bufp, "\nISP 6322FLX ");
11716	} else {
11717		(void) sprintf(bufp, "\nISP 2200IP ");
11718	}
11719
11720	bp = bufp + strlen(bufp);
11721	(void) sprintf(bp, "Firmware Version %d.%d.%d\n",
11722	    ha->fw_major_version, ha->fw_minor_version,
11723	    ha->fw_subminor_version);
11724
11725	(void) strcat(bufp, "\nPBIU Registers:");
11726	bp = bufp + strlen(bufp);
11727	for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) {
11728		if (cnt % 8 == 0) {
11729			*bp++ = '\n';
11730		}
11731		(void) sprintf(bp, "%04x  ", fw->pbiu_reg[cnt]);
11732		bp = bp + 6;
11733	}
11734
11735	if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
11736		(void) strcat(bufp, "\n\nReqQ-RspQ-Risc2Host Status "
11737		    "registers:");
11738		bp = bufp + strlen(bufp);
11739		for (cnt = 0; cnt < sizeof (fw->risc_host_reg) / 2; cnt++) {
11740			if (cnt % 8 == 0) {
11741				*bp++ = '\n';
11742			}
11743			(void) sprintf(bp, "%04x  ", fw->risc_host_reg[cnt]);
11744			bp = bp + 6;
11745		}
11746	}
11747
11748	(void) strcat(bp, "\n\nMailbox Registers:");
11749	bp = bufp + strlen(bufp);
11750	mbox_cnt = (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) ? 16 : 8;
11751	for (cnt = 0; cnt < mbox_cnt; cnt++) {
11752		if (cnt % 8 == 0) {
11753			*bp++ = '\n';
11754		}
11755		(void) sprintf(bp, "%04x  ", fw->mailbox_reg[cnt]);
11756		bp = bp + 6;
11757	}
11758
11759	if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
11760		(void) strcat(bp, "\n\nAuto Request Response DMA Registers:");
11761		bp = bufp + strlen(bufp);
11762		for (cnt = 0; cnt < sizeof (fw->resp_dma_reg) / 2; cnt++) {
11763			if (cnt % 8 == 0) {
11764				*bp++ = '\n';
11765			}
11766			(void) sprintf(bp, "%04x  ", fw->resp_dma_reg[cnt]);
11767			bp = bp + 6;
11768		}
11769	}
11770
11771	(void) strcat(bp, "\n\nDMA Registers:");
11772	bp = bufp + strlen(bufp);
11773	for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) {
11774		if (cnt % 8 == 0) {
11775			*bp++ = '\n';
11776		}
11777		(void) sprintf(bp, "%04x  ", fw->dma_reg[cnt]);
11778		bp = bp + 6;
11779	}
11780
11781	(void) strcat(bp, "\n\nRISC Hardware Registers:");
11782	bp = bufp + strlen(bufp);
11783	for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) {
11784		if (cnt % 8 == 0) {
11785			*bp++ = '\n';
11786		}
11787		(void) sprintf(bp, "%04x  ", fw->risc_hdw_reg[cnt]);
11788		bp = bp + 6;
11789	}
11790
11791	(void) strcat(bp, "\n\nRISC GP0 Registers:");
11792	bp = bufp + strlen(bufp);
11793	for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) {
11794		if (cnt % 8 == 0) {
11795			*bp++ = '\n';
11796		}
11797		(void) sprintf(bp, "%04x  ", fw->risc_gp0_reg[cnt]);
11798		bp = bp + 6;
11799	}
11800
11801	(void) strcat(bp, "\n\nRISC GP1 Registers:");
11802	bp = bufp + strlen(bufp);
11803	for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) {
11804		if (cnt % 8 == 0) {
11805			*bp++ = '\n';
11806		}
11807		(void) sprintf(bp, "%04x  ", fw->risc_gp1_reg[cnt]);
11808		bp = bp + 6;
11809	}
11810
11811	(void) strcat(bp, "\n\nRISC GP2 Registers:");
11812	bp = bufp + strlen(bufp);
11813	for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) {
11814		if (cnt % 8 == 0) {
11815			*bp++ = '\n';
11816		}
11817		(void) sprintf(bp, "%04x  ", fw->risc_gp2_reg[cnt]);
11818		bp = bp + 6;
11819	}
11820
11821	(void) strcat(bp, "\n\nRISC GP3 Registers:");
11822	bp = bufp + strlen(bufp);
11823	for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) {
11824		if (cnt % 8 == 0) {
11825			*bp++ = '\n';
11826		}
11827		(void) sprintf(bp, "%04x  ", fw->risc_gp3_reg[cnt]);
11828		bp = bp + 6;
11829	}
11830
11831	(void) strcat(bp, "\n\nRISC GP4 Registers:");
11832	bp = bufp + strlen(bufp);
11833	for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) {
11834		if (cnt % 8 == 0) {
11835			*bp++ = '\n';
11836		}
11837		(void) sprintf(bp, "%04x  ", fw->risc_gp4_reg[cnt]);
11838		bp = bp + 6;
11839	}
11840
11841	(void) strcat(bp, "\n\nRISC GP5 Registers:");
11842	bp = bufp + strlen(bufp);
11843	for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) {
11844		if (cnt % 8 == 0) {
11845			*bp++ = '\n';
11846		}
11847		(void) sprintf(bp, "%04x  ", fw->risc_gp5_reg[cnt]);
11848		bp = bp + 6;
11849	}
11850
11851	(void) strcat(bp, "\n\nRISC GP6 Registers:");
11852	bp = bufp + strlen(bufp);
11853	for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) {
11854		if (cnt % 8 == 0) {
11855			*bp++ = '\n';
11856		}
11857		(void) sprintf(bp, "%04x  ", fw->risc_gp6_reg[cnt]);
11858		bp = bp + 6;
11859	}
11860
11861	(void) strcat(bp, "\n\nRISC GP7 Registers:");
11862	bp = bufp + strlen(bufp);
11863	for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) {
11864		if (cnt % 8 == 0) {
11865			*bp++ = '\n';
11866		}
11867		(void) sprintf(bp, "%04x  ", fw->risc_gp7_reg[cnt]);
11868		bp = bp + 6;
11869	}
11870
11871	(void) strcat(bp, "\n\nFrame Buffer Hardware Registers:");
11872	bp = bufp + strlen(bufp);
11873	for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) {
11874		if ((cnt == 16) && ((CFG_IST(ha, (CFG_CTRL_2300 |
11875		    CFG_CTRL_6322)) == 0))) {
11876			break;
11877		}
11878		if (cnt % 8 == 0) {
11879			*bp++ = '\n';
11880		}
11881		(void) sprintf(bp, "%04x  ", fw->frame_buf_hdw_reg[cnt]);
11882		bp = bp + 6;
11883	}
11884
11885	(void) strcat(bp, "\n\nFPM B0 Registers:");
11886	bp = bufp + strlen(bufp);
11887	for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) {
11888		if (cnt % 8 == 0) {
11889			*bp++ = '\n';
11890		}
11891		(void) sprintf(bp, "%04x  ", fw->fpm_b0_reg[cnt]);
11892		bp = bp + 6;
11893	}
11894
11895	(void) strcat(bp, "\n\nFPM B1 Registers:");
11896	bp = bufp + strlen(bufp);
11897	for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) {
11898		if (cnt % 8 == 0) {
11899			*bp++ = '\n';
11900		}
11901		(void) sprintf(bp, "%04x  ", fw->fpm_b1_reg[cnt]);
11902		bp = bp + 6;
11903	}
11904
11905	if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
11906		(void) strcat(bp, "\n\nCode RAM Dump:");
11907		bp = bufp + strlen(bufp);
11908		for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) {
11909			if (cnt % 8 == 0) {
11910				(void) sprintf(bp, "\n%05x: ", cnt + 0x0800);
11911				bp = bp + 8;
11912			}
11913			(void) sprintf(bp, "%04x  ", fw->risc_ram[cnt]);
11914			bp = bp + 6;
11915		}
11916
11917		(void) strcat(bp, "\n\nStack RAM Dump:");
11918		bp = bufp + strlen(bufp);
11919		for (cnt = 0; cnt < sizeof (fw->stack_ram) / 2; cnt++) {
11920			if (cnt % 8 == 0) {
11921				(void) sprintf(bp, "\n%05x: ", cnt + 0x010000);
11922				bp = bp + 8;
11923			}
11924			(void) sprintf(bp, "%04x  ", fw->stack_ram[cnt]);
11925			bp = bp + 6;
11926		}
11927
11928		(void) strcat(bp, "\n\nData RAM Dump:");
11929		bp = bufp + strlen(bufp);
11930		for (cnt = 0; cnt < sizeof (fw->data_ram) / 2; cnt++) {
11931			if (cnt % 8 == 0) {
11932				(void) sprintf(bp, "\n%05x: ", cnt + 0x010800);
11933				bp = bp + 8;
11934			}
11935			(void) sprintf(bp, "%04x  ", fw->data_ram[cnt]);
11936			bp = bp + 6;
11937		}
11938	} else {
11939		(void) strcat(bp, "\n\nRISC SRAM:");
11940		bp = bufp + strlen(bufp);
11941		for (cnt = 0; cnt < 0xf000; cnt++) {
11942			if (cnt % 8 == 0) {
11943				(void) sprintf(bp, "\n%04x: ", cnt + 0x1000);
11944				bp = bp + 7;
11945			}
11946			(void) sprintf(bp, "%04x  ", fw->risc_ram[cnt]);
11947			bp = bp + 6;
11948		}
11949	}
11950
11951	(void) strcat(bp, "\n\n[<==END] ISP Debug Dump.");
11952	bp += strlen(bp);
11953
11954	(void) sprintf(bp, "\n\nRequest Queue");
11955	bp += strlen(bp);
11956	for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) {
11957		if (cnt % 8 == 0) {
11958			(void) sprintf(bp, "\n%08x: ", cnt);
11959			bp += strlen(bp);
11960		}
11961		(void) sprintf(bp, "%08x ", fw->req_q[cnt]);
11962		bp += strlen(bp);
11963	}
11964
11965	(void) sprintf(bp, "\n\nResponse Queue");
11966	bp += strlen(bp);
11967	for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) {
11968		if (cnt % 8 == 0) {
11969			(void) sprintf(bp, "\n%08x: ", cnt);
11970			bp += strlen(bp);
11971		}
11972		(void) sprintf(bp, "%08x ", fw->rsp_q[cnt]);
11973		bp += strlen(bp);
11974	}
11975
11976	(void) sprintf(bp, "\n");
11977
11978	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
11979
11980	return (strlen(bufp));
11981}
11982
11983/*
11984 * ql_24xx_ascii_fw_dump
11985 *	Converts ISP24xx firmware binary dump to ascii.
11986 *
11987 * Input:
11988 *	ha = adapter state pointer.
11989 *	bptr = buffer pointer.
11990 *
11991 * Returns:
11992 *	Amount of data buffer used.
11993 *
11994 * Context:
11995 *	Kernel context.
11996 */
11997static size_t
11998ql_24xx_ascii_fw_dump(ql_adapter_state_t *ha, caddr_t bufp)
11999{
12000	uint32_t		cnt;
12001	caddr_t			bp = bufp;
12002	ql_24xx_fw_dump_t	*fw = ha->ql_dump_ptr;
12003
12004	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
12005
12006	(void) sprintf(bp, "ISP FW Version %d.%02d.%02d Attributes %X\n",
12007	    ha->fw_major_version, ha->fw_minor_version,
12008	    ha->fw_subminor_version, ha->fw_attributes);
12009	bp += strlen(bp);
12010
12011	(void) sprintf(bp, "\nHCCR Register\n%08x\n", fw->hccr);
12012
12013	(void) strcat(bp, "\nHost Interface Registers");
12014	bp += strlen(bp);
12015	for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) {
12016		if (cnt % 8 == 0) {
12017			(void) sprintf(bp++, "\n");
12018		}
12019
12020		(void) sprintf(bp, "%08x ", fw->host_reg[cnt]);
12021		bp += 9;
12022	}
12023
12024	(void) sprintf(bp, "\n\nMailbox Registers");
12025	bp += strlen(bp);
12026	for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
12027		if (cnt % 16 == 0) {
12028			(void) sprintf(bp++, "\n");
12029		}
12030
12031		(void) sprintf(bp, "%04x ", fw->mailbox_reg[cnt]);
12032		bp += 5;
12033	}
12034
12035	(void) sprintf(bp, "\n\nXSEQ GP Registers");
12036	bp += strlen(bp);
12037	for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) {
12038		if (cnt % 8 == 0) {
12039			(void) sprintf(bp++, "\n");
12040		}
12041
12042		(void) sprintf(bp, "%08x ", fw->xseq_gp_reg[cnt]);
12043		bp += 9;
12044	}
12045
12046	(void) sprintf(bp, "\n\nXSEQ-0 Registers");
12047	bp += strlen(bp);
12048	for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) {
12049		if (cnt % 8 == 0) {
12050			(void) sprintf(bp++, "\n");
12051		}
12052
12053		(void) sprintf(bp, "%08x ", fw->xseq_0_reg[cnt]);
12054		bp += 9;
12055	}
12056
12057	(void) sprintf(bp, "\n\nXSEQ-1 Registers");
12058	bp += strlen(bp);
12059	for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) {
12060		if (cnt % 8 == 0) {
12061			(void) sprintf(bp++, "\n");
12062		}
12063
12064		(void) sprintf(bp, "%08x ", fw->xseq_1_reg[cnt]);
12065		bp += 9;
12066	}
12067
12068	(void) sprintf(bp, "\n\nRSEQ GP Registers");
12069	bp += strlen(bp);
12070	for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) {
12071		if (cnt % 8 == 0) {
12072			(void) sprintf(bp++, "\n");
12073		}
12074
12075		(void) sprintf(bp, "%08x ", fw->rseq_gp_reg[cnt]);
12076		bp += 9;
12077	}
12078
12079	(void) sprintf(bp, "\n\nRSEQ-0 Registers");
12080	bp += strlen(bp);
12081	for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) {
12082		if (cnt % 8 == 0) {
12083			(void) sprintf(bp++, "\n");
12084		}
12085
12086		(void) sprintf(bp, "%08x ", fw->rseq_0_reg[cnt]);
12087		bp += 9;
12088	}
12089
12090	(void) sprintf(bp, "\n\nRSEQ-1 Registers");
12091	bp += strlen(bp);
12092	for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) {
12093		if (cnt % 8 == 0) {
12094			(void) sprintf(bp++, "\n");
12095		}
12096
12097		(void) sprintf(bp, "%08x ", fw->rseq_1_reg[cnt]);
12098		bp += 9;
12099	}
12100
12101	(void) sprintf(bp, "\n\nRSEQ-2 Registers");
12102	bp += strlen(bp);
12103	for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) {
12104		if (cnt % 8 == 0) {
12105			(void) sprintf(bp++, "\n");
12106		}
12107
12108		(void) sprintf(bp, "%08x ", fw->rseq_2_reg[cnt]);
12109		bp += 9;
12110	}
12111
12112	(void) sprintf(bp, "\n\nCommand DMA Registers");
12113	bp += strlen(bp);
12114	for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) {
12115		if (cnt % 8 == 0) {
12116			(void) sprintf(bp++, "\n");
12117		}
12118
12119		(void) sprintf(bp, "%08x ", fw->cmd_dma_reg[cnt]);
12120		bp += 9;
12121	}
12122
12123	(void) sprintf(bp, "\n\nRequest0 Queue DMA Channel Registers");
12124	bp += strlen(bp);
12125	for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) {
12126		if (cnt % 8 == 0) {
12127			(void) sprintf(bp++, "\n");
12128		}
12129
12130		(void) sprintf(bp, "%08x ", fw->req0_dma_reg[cnt]);
12131		bp += 9;
12132	}
12133
12134	(void) sprintf(bp, "\n\nResponse0 Queue DMA Channel Registers");
12135	bp += strlen(bp);
12136	for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) {
12137		if (cnt % 8 == 0) {
12138			(void) sprintf(bp++, "\n");
12139		}
12140
12141		(void) sprintf(bp, "%08x ", fw->resp0_dma_reg[cnt]);
12142		bp += 9;
12143	}
12144
12145	(void) sprintf(bp, "\n\nRequest1 Queue DMA Channel Registers");
12146	bp += strlen(bp);
12147	for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) {
12148		if (cnt % 8 == 0) {
12149			(void) sprintf(bp++, "\n");
12150		}
12151
12152		(void) sprintf(bp, "%08x ", fw->req1_dma_reg[cnt]);
12153		bp += 9;
12154	}
12155
12156	(void) sprintf(bp, "\n\nXMT0 Data DMA Registers");
12157	bp += strlen(bp);
12158	for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) {
12159		if (cnt % 8 == 0) {
12160			(void) sprintf(bp++, "\n");
12161		}
12162
12163		(void) sprintf(bp, "%08x ", fw->xmt0_dma_reg[cnt]);
12164		bp += 9;
12165	}
12166
12167	(void) sprintf(bp, "\n\nXMT1 Data DMA Registers");
12168	bp += strlen(bp);
12169	for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) {
12170		if (cnt % 8 == 0) {
12171			(void) sprintf(bp++, "\n");
12172		}
12173
12174		(void) sprintf(bp, "%08x ", fw->xmt1_dma_reg[cnt]);
12175		bp += 9;
12176	}
12177
12178	(void) sprintf(bp, "\n\nXMT2 Data DMA Registers");
12179	bp += strlen(bp);
12180	for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) {
12181		if (cnt % 8 == 0) {
12182			(void) sprintf(bp++, "\n");
12183		}
12184
12185		(void) sprintf(bp, "%08x ", fw->xmt2_dma_reg[cnt]);
12186		bp += 9;
12187	}
12188
12189	(void) sprintf(bp, "\n\nXMT3 Data DMA Registers");
12190	bp += strlen(bp);
12191	for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) {
12192		if (cnt % 8 == 0) {
12193			(void) sprintf(bp++, "\n");
12194		}
12195
12196		(void) sprintf(bp, "%08x ", fw->xmt3_dma_reg[cnt]);
12197		bp += 9;
12198	}
12199
12200	(void) sprintf(bp, "\n\nXMT4 Data DMA Registers");
12201	bp += strlen(bp);
12202	for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) {
12203		if (cnt % 8 == 0) {
12204			(void) sprintf(bp++, "\n");
12205		}
12206
12207		(void) sprintf(bp, "%08x ", fw->xmt4_dma_reg[cnt]);
12208		bp += 9;
12209	}
12210
12211	(void) sprintf(bp, "\n\nXMT Data DMA Common Registers");
12212	bp += strlen(bp);
12213	for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) {
12214		if (cnt % 8 == 0) {
12215			(void) sprintf(bp++, "\n");
12216		}
12217
12218		(void) sprintf(bp, "%08x ", fw->xmt_data_dma_reg[cnt]);
12219		bp += 9;
12220	}
12221
12222	(void) sprintf(bp, "\n\nRCV Thread 0 Data DMA Registers");
12223	bp += strlen(bp);
12224	for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) {
12225		if (cnt % 8 == 0) {
12226			(void) sprintf(bp++, "\n");
12227		}
12228
12229		(void) sprintf(bp, "%08x ", fw->rcvt0_data_dma_reg[cnt]);
12230		bp += 9;
12231	}
12232
12233	(void) sprintf(bp, "\n\nRCV Thread 1 Data DMA Registers");
12234	bp += strlen(bp);
12235	for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) {
12236		if (cnt % 8 == 0) {
12237			(void) sprintf(bp++, "\n");
12238		}
12239
12240		(void) sprintf(bp, "%08x ", fw->rcvt1_data_dma_reg[cnt]);
12241		bp += 9;
12242	}
12243
12244	(void) sprintf(bp, "\n\nRISC GP Registers");
12245	bp += strlen(bp);
12246	for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) {
12247		if (cnt % 8 == 0) {
12248			(void) sprintf(bp++, "\n");
12249		}
12250
12251		(void) sprintf(bp, "%08x ", fw->risc_gp_reg[cnt]);
12252		bp += 9;
12253	}
12254
12255	(void) sprintf(bufp + strlen(bufp), "\n\nShadow Registers");
12256	bp += strlen(bp);
12257	for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) {
12258		if (cnt % 8 == 0) {
12259			(void) sprintf(bp++, "\n");
12260		}
12261
12262		(void) sprintf(bp, "%08x ", fw->shadow_reg[cnt]);
12263		bp += 9;
12264	}
12265
12266	(void) sprintf(bp, "\n\nLMC Registers");
12267	bp += strlen(bp);
12268	for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) {
12269		if (cnt % 8 == 0) {
12270			(void) sprintf(bp++, "\n");
12271		}
12272
12273		(void) sprintf(bp, "%08x ", fw->lmc_reg[cnt]);
12274		bp += 9;
12275	}
12276
12277	(void) sprintf(bp, "\n\nFPM Hardware Registers");
12278	bp += strlen(bp);
12279	for (cnt = 0; cnt < sizeof (fw->fpm_hdw_reg) / 4; cnt++) {
12280		if (cnt % 8 == 0) {
12281			(void) sprintf(bp++, "\n");
12282		}
12283
12284		(void) sprintf(bp, "%08x ", fw->fpm_hdw_reg[cnt]);
12285		bp += 9;
12286	}
12287
12288	(void) sprintf(bp, "\n\nFB Hardware Registers");
12289	bp += strlen(bp);
12290	for (cnt = 0; cnt < sizeof (fw->fb_hdw_reg) / 4; cnt++) {
12291		if (cnt % 8 == 0) {
12292			(void) sprintf(bp++, "\n");
12293		}
12294
12295		(void) sprintf(bp, "%08x ", fw->fb_hdw_reg[cnt]);
12296		bp += 9;
12297	}
12298
12299	(void) sprintf(bp, "\n\nCode RAM");
12300	bp += strlen(bp);
12301	for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
12302		if (cnt % 8 == 0) {
12303			(void) sprintf(bp, "\n%08x: ", cnt + 0x20000);
12304			bp += 11;
12305		}
12306
12307		(void) sprintf(bp, "%08x ", fw->code_ram[cnt]);
12308		bp += 9;
12309	}
12310
12311	(void) sprintf(bp, "\n\nExternal Memory");
12312	bp += strlen(bp);
12313	for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) {
12314		if (cnt % 8 == 0) {
12315			(void) sprintf(bp, "\n%08x: ", cnt + 0x100000);
12316			bp += 11;
12317		}
12318		(void) sprintf(bp, "%08x ", fw->ext_mem[cnt]);
12319		bp += 9;
12320	}
12321
12322	(void) sprintf(bp, "\n[<==END] ISP Debug Dump");
12323	bp += strlen(bp);
12324
12325	(void) sprintf(bp, "\n\nRequest Queue");
12326	bp += strlen(bp);
12327	for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) {
12328		if (cnt % 8 == 0) {
12329			(void) sprintf(bp, "\n%08x: ", cnt);
12330			bp += strlen(bp);
12331		}
12332		(void) sprintf(bp, "%08x ", fw->req_q[cnt]);
12333		bp += strlen(bp);
12334	}
12335
12336	(void) sprintf(bp, "\n\nResponse Queue");
12337	bp += strlen(bp);
12338	for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) {
12339		if (cnt % 8 == 0) {
12340			(void) sprintf(bp, "\n%08x: ", cnt);
12341			bp += strlen(bp);
12342		}
12343		(void) sprintf(bp, "%08x ", fw->rsp_q[cnt]);
12344		bp += strlen(bp);
12345	}
12346
12347	if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) &&
12348	    (ha->fwexttracebuf.bp != NULL)) {
12349		uint32_t cnt_b = 0;
12350		uint64_t w64 = (uintptr_t)ha->fwexttracebuf.bp;
12351
12352		(void) sprintf(bp, "\n\nExtended Trace Buffer Memory");
12353		bp += strlen(bp);
12354		/* show data address as a byte address, data as long words */
12355		for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
12356			cnt_b = cnt * 4;
12357			if (cnt_b % 32 == 0) {
12358				(void) sprintf(bp, "\n%08x: ",
12359				    (int)(w64 + cnt_b));
12360				bp += 11;
12361			}
12362			(void) sprintf(bp, "%08x ", fw->ext_trace_buf[cnt]);
12363			bp += 9;
12364		}
12365	}
12366
12367	if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) &&
12368	    (ha->fwfcetracebuf.bp != NULL)) {
12369		uint32_t cnt_b = 0;
12370		uint64_t w64 = (uintptr_t)ha->fwfcetracebuf.bp;
12371
12372		(void) sprintf(bp, "\n\nFC Event Trace Buffer Memory");
12373		bp += strlen(bp);
12374		/* show data address as a byte address, data as long words */
12375		for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
12376			cnt_b = cnt * 4;
12377			if (cnt_b % 32 == 0) {
12378				(void) sprintf(bp, "\n%08x: ",
12379				    (int)(w64 + cnt_b));
12380				bp += 11;
12381			}
12382			(void) sprintf(bp, "%08x ", fw->fce_trace_buf[cnt]);
12383			bp += 9;
12384		}
12385	}
12386
12387	(void) sprintf(bp, "\n\n");
12388	bp += strlen(bp);
12389
12390	cnt = (uint32_t)((uintptr_t)bp - (uintptr_t)bufp);
12391
12392	QL_PRINT_3(CE_CONT, "(%d): done=%xh\n", ha->instance, cnt);
12393
12394	return (cnt);
12395}
12396
12397/*
12398 * ql_2581_ascii_fw_dump
12399 *	Converts ISP25xx or ISP81xx firmware binary dump to ascii.
12400 *
12401 * Input:
12402 *	ha = adapter state pointer.
12403 *	bptr = buffer pointer.
12404 *
12405 * Returns:
12406 *	Amount of data buffer used.
12407 *
12408 * Context:
12409 *	Kernel context.
12410 */
12411static size_t
12412ql_2581_ascii_fw_dump(ql_adapter_state_t *ha, caddr_t bufp)
12413{
12414	uint32_t		cnt;
12415	uint32_t		cnt1;
12416	caddr_t			bp = bufp;
12417	ql_25xx_fw_dump_t	*fw = ha->ql_dump_ptr;
12418
12419	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
12420
12421	(void) sprintf(bp, "\nISP FW Version %d.%02d.%02d Attributes %X\n",
12422	    ha->fw_major_version, ha->fw_minor_version,
12423	    ha->fw_subminor_version, ha->fw_attributes);
12424	bp += strlen(bp);
12425
12426	(void) sprintf(bp, "\nR2H Status Register\n%08x\n", fw->r2h_status);
12427	bp += strlen(bp);
12428
12429	(void) sprintf(bp, "\nHostRisc Registers");
12430	bp += strlen(bp);
12431	for (cnt = 0; cnt < sizeof (fw->hostrisc_reg) / 4; cnt++) {
12432		if (cnt % 8 == 0) {
12433			(void) sprintf(bp++, "\n");
12434		}
12435		(void) sprintf(bp, "%08x ", fw->hostrisc_reg[cnt]);
12436		bp += 9;
12437	}
12438
12439	(void) sprintf(bp, "\n\nPCIe Registers");
12440	bp += strlen(bp);
12441	for (cnt = 0; cnt < sizeof (fw->pcie_reg) / 4; cnt++) {
12442		if (cnt % 8 == 0) {
12443			(void) sprintf(bp++, "\n");
12444		}
12445		(void) sprintf(bp, "%08x ", fw->pcie_reg[cnt]);
12446		bp += 9;
12447	}
12448
12449	(void) strcat(bp, "\n\nHost Interface Registers");
12450	bp += strlen(bp);
12451	for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) {
12452		if (cnt % 8 == 0) {
12453			(void) sprintf(bp++, "\n");
12454		}
12455		(void) sprintf(bp, "%08x ", fw->host_reg[cnt]);
12456		bp += 9;
12457	}
12458
12459	(void) sprintf(bufp + strlen(bufp), "\n\nShadow Registers");
12460	bp += strlen(bp);
12461	for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) {
12462		if (cnt % 8 == 0) {
12463			(void) sprintf(bp++, "\n");
12464		}
12465		(void) sprintf(bp, "%08x ", fw->shadow_reg[cnt]);
12466		bp += 9;
12467	}
12468
12469	(void) sprintf(bufp + strlen(bufp), "\n\nRISC IO Register\n%08x",
12470	    fw->risc_io);
12471	bp += strlen(bp);
12472
12473	(void) sprintf(bp, "\n\nMailbox Registers");
12474	bp += strlen(bp);
12475	for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
12476		if (cnt % 16 == 0) {
12477			(void) sprintf(bp++, "\n");
12478		}
12479		(void) sprintf(bp, "%04x ", fw->mailbox_reg[cnt]);
12480		bp += 5;
12481	}
12482
12483	(void) sprintf(bp, "\n\nXSEQ GP Registers");
12484	bp += strlen(bp);
12485	for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) {
12486		if (cnt % 8 == 0) {
12487			(void) sprintf(bp++, "\n");
12488		}
12489		(void) sprintf(bp, "%08x ", fw->xseq_gp_reg[cnt]);
12490		bp += 9;
12491	}
12492
12493	(void) sprintf(bp, "\n\nXSEQ-0 Registers");
12494	bp += strlen(bp);
12495	for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) {
12496		if (cnt % 8 == 0) {
12497			(void) sprintf(bp++, "\n");
12498		}
12499		(void) sprintf(bp, "%08x ", fw->xseq_0_reg[cnt]);
12500		bp += 9;
12501	}
12502
12503	(void) sprintf(bp, "\n\nXSEQ-1 Registers");
12504	bp += strlen(bp);
12505	for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) {
12506		if (cnt % 8 == 0) {
12507			(void) sprintf(bp++, "\n");
12508		}
12509		(void) sprintf(bp, "%08x ", fw->xseq_1_reg[cnt]);
12510		bp += 9;
12511	}
12512
12513	(void) sprintf(bp, "\n\nRSEQ GP Registers");
12514	bp += strlen(bp);
12515	for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) {
12516		if (cnt % 8 == 0) {
12517			(void) sprintf(bp++, "\n");
12518		}
12519		(void) sprintf(bp, "%08x ", fw->rseq_gp_reg[cnt]);
12520		bp += 9;
12521	}
12522
12523	(void) sprintf(bp, "\n\nRSEQ-0 Registers");
12524	bp += strlen(bp);
12525	for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) {
12526		if (cnt % 8 == 0) {
12527			(void) sprintf(bp++, "\n");
12528		}
12529		(void) sprintf(bp, "%08x ", fw->rseq_0_reg[cnt]);
12530		bp += 9;
12531	}
12532
12533	(void) sprintf(bp, "\n\nRSEQ-1 Registers");
12534	bp += strlen(bp);
12535	for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) {
12536		if (cnt % 8 == 0) {
12537			(void) sprintf(bp++, "\n");
12538		}
12539		(void) sprintf(bp, "%08x ", fw->rseq_1_reg[cnt]);
12540		bp += 9;
12541	}
12542
12543	(void) sprintf(bp, "\n\nRSEQ-2 Registers");
12544	bp += strlen(bp);
12545	for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) {
12546		if (cnt % 8 == 0) {
12547			(void) sprintf(bp++, "\n");
12548		}
12549		(void) sprintf(bp, "%08x ", fw->rseq_2_reg[cnt]);
12550		bp += 9;
12551	}
12552
12553	(void) sprintf(bp, "\n\nASEQ GP Registers");
12554	bp += strlen(bp);
12555	for (cnt = 0; cnt < sizeof (fw->aseq_gp_reg) / 4; cnt++) {
12556		if (cnt % 8 == 0) {
12557			(void) sprintf(bp++, "\n");
12558		}
12559		(void) sprintf(bp, "%08x ", fw->aseq_gp_reg[cnt]);
12560		bp += 9;
12561	}
12562
12563	(void) sprintf(bp, "\n\nASEQ-0 Registers");
12564	bp += strlen(bp);
12565	for (cnt = 0; cnt < sizeof (fw->aseq_0_reg) / 4; cnt++) {
12566		if (cnt % 8 == 0) {
12567			(void) sprintf(bp++, "\n");
12568		}
12569		(void) sprintf(bp, "%08x ", fw->aseq_0_reg[cnt]);
12570		bp += 9;
12571	}
12572
12573	(void) sprintf(bp, "\n\nASEQ-1 Registers");
12574	bp += strlen(bp);
12575	for (cnt = 0; cnt < sizeof (fw->aseq_1_reg) / 4; cnt++) {
12576		if (cnt % 8 == 0) {
12577			(void) sprintf(bp++, "\n");
12578		}
12579		(void) sprintf(bp, "%08x ", fw->aseq_1_reg[cnt]);
12580		bp += 9;
12581	}
12582
12583	(void) sprintf(bp, "\n\nASEQ-2 Registers");
12584	bp += strlen(bp);
12585	for (cnt = 0; cnt < sizeof (fw->aseq_2_reg) / 4; cnt++) {
12586		if (cnt % 8 == 0) {
12587			(void) sprintf(bp++, "\n");
12588		}
12589		(void) sprintf(bp, "%08x ", fw->aseq_2_reg[cnt]);
12590		bp += 9;
12591	}
12592
12593	(void) sprintf(bp, "\n\nCommand DMA Registers");
12594	bp += strlen(bp);
12595	for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) {
12596		if (cnt % 8 == 0) {
12597			(void) sprintf(bp++, "\n");
12598		}
12599		(void)  sprintf(bp, "%08x ", fw->cmd_dma_reg[cnt]);
12600		bp += 9;
12601	}
12602
12603	(void) sprintf(bp, "\n\nRequest0 Queue DMA Channel Registers");
12604	bp += strlen(bp);
12605	for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) {
12606		if (cnt % 8 == 0) {
12607			(void) sprintf(bp++, "\n");
12608		}
12609		(void) sprintf(bp, "%08x ", fw->req0_dma_reg[cnt]);
12610		bp += 9;
12611	}
12612
12613	(void) sprintf(bp, "\n\nResponse0 Queue DMA Channel Registers");
12614	bp += strlen(bp);
12615	for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) {
12616		if (cnt % 8 == 0) {
12617			(void) sprintf(bp++, "\n");
12618		}
12619		(void) sprintf(bp, "%08x ", fw->resp0_dma_reg[cnt]);
12620		bp += 9;
12621	}
12622
12623	(void) sprintf(bp, "\n\nRequest1 Queue DMA Channel Registers");
12624	bp += strlen(bp);
12625	for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) {
12626		if (cnt % 8 == 0) {
12627			(void) sprintf(bp++, "\n");
12628		}
12629		(void) sprintf(bp, "%08x ", fw->req1_dma_reg[cnt]);
12630		bp += 9;
12631	}
12632
12633	(void) sprintf(bp, "\n\nXMT0 Data DMA Registers");
12634	bp += strlen(bp);
12635	for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) {
12636		if (cnt % 8 == 0) {
12637			(void) sprintf(bp++, "\n");
12638		}
12639		(void) sprintf(bp, "%08x ", fw->xmt0_dma_reg[cnt]);
12640		bp += 9;
12641	}
12642
12643	(void) sprintf(bp, "\n\nXMT1 Data DMA Registers");
12644	bp += strlen(bp);
12645	for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) {
12646		if (cnt % 8 == 0) {
12647			(void) sprintf(bp++, "\n");
12648		}
12649		(void) sprintf(bp, "%08x ", fw->xmt1_dma_reg[cnt]);
12650		bp += 9;
12651	}
12652
12653	(void) sprintf(bp, "\n\nXMT2 Data DMA Registers");
12654	bp += strlen(bp);
12655	for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) {
12656		if (cnt % 8 == 0) {
12657			(void) sprintf(bp++, "\n");
12658		}
12659		(void) sprintf(bp, "%08x ", fw->xmt2_dma_reg[cnt]);
12660		bp += 9;
12661	}
12662
12663	(void) sprintf(bp, "\n\nXMT3 Data DMA Registers");
12664	bp += strlen(bp);
12665	for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) {
12666		if (cnt % 8 == 0) {
12667			(void) sprintf(bp++, "\n");
12668		}
12669		(void) sprintf(bp, "%08x ", fw->xmt3_dma_reg[cnt]);
12670		bp += 9;
12671	}
12672
12673	(void) sprintf(bp, "\n\nXMT4 Data DMA Registers");
12674	bp += strlen(bp);
12675	for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) {
12676		if (cnt % 8 == 0) {
12677			(void) sprintf(bp++, "\n");
12678		}
12679		(void) sprintf(bp, "%08x ", fw->xmt4_dma_reg[cnt]);
12680		bp += 9;
12681	}
12682
12683	(void) sprintf(bp, "\n\nXMT Data DMA Common Registers");
12684	bp += strlen(bp);
12685	for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) {
12686		if (cnt % 8 == 0) {
12687			(void) sprintf(bp++, "\n");
12688		}
12689		(void) sprintf(bp, "%08x ", fw->xmt_data_dma_reg[cnt]);
12690		bp += 9;
12691	}
12692
12693	(void) sprintf(bp, "\n\nRCV Thread 0 Data DMA Registers");
12694	bp += strlen(bp);
12695	for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) {
12696		if (cnt % 8 == 0) {
12697			(void) sprintf(bp++, "\n");
12698		}
12699		(void) sprintf(bp, "%08x ", fw->rcvt0_data_dma_reg[cnt]);
12700		bp += 9;
12701	}
12702
12703	(void) sprintf(bp, "\n\nRCV Thread 1 Data DMA Registers");
12704	bp += strlen(bp);
12705	for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) {
12706		if (cnt % 8 == 0) {
12707			(void) sprintf(bp++, "\n");
12708		}
12709		(void) sprintf(bp, "%08x ", fw->rcvt1_data_dma_reg[cnt]);
12710		bp += 9;
12711	}
12712
12713	(void) sprintf(bp, "\n\nRISC GP Registers");
12714	bp += strlen(bp);
12715	for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) {
12716		if (cnt % 8 == 0) {
12717			(void) sprintf(bp++, "\n");
12718		}
12719		(void) sprintf(bp, "%08x ", fw->risc_gp_reg[cnt]);
12720		bp += 9;
12721	}
12722
12723	(void) sprintf(bp, "\n\nLMC Registers");
12724	bp += strlen(bp);
12725	for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) {
12726		if (cnt % 8 == 0) {
12727			(void) sprintf(bp++, "\n");
12728		}
12729		(void) sprintf(bp, "%08x ", fw->lmc_reg[cnt]);
12730		bp += 9;
12731	}
12732
12733	(void) sprintf(bp, "\n\nFPM Hardware Registers");
12734	bp += strlen(bp);
12735	cnt1 = CFG_IST(ha, CFG_CTRL_81XX) ?
12736	    (uint32_t)(sizeof (((ql_81xx_fw_dump_t *)(fw))->fpm_hdw_reg)) :
12737	    (uint32_t)(sizeof (fw->fpm_hdw_reg));
12738	for (cnt = 0; cnt < cnt1 / 4; cnt++) {
12739		if (cnt % 8 == 0) {
12740			(void) sprintf(bp++, "\n");
12741		}
12742		(void) sprintf(bp, "%08x ", fw->fpm_hdw_reg[cnt]);
12743		bp += 9;
12744	}
12745
12746	(void) sprintf(bp, "\n\nFB Hardware Registers");
12747	bp += strlen(bp);
12748	cnt1 = CFG_IST(ha, CFG_CTRL_81XX) ?
12749	    (uint32_t)(sizeof (((ql_81xx_fw_dump_t *)(fw))->fb_hdw_reg)) :
12750	    (uint32_t)(sizeof (fw->fb_hdw_reg));
12751	for (cnt = 0; cnt < cnt1 / 4; cnt++) {
12752		if (cnt % 8 == 0) {
12753			(void) sprintf(bp++, "\n");
12754		}
12755		(void) sprintf(bp, "%08x ", fw->fb_hdw_reg[cnt]);
12756		bp += 9;
12757	}
12758
12759	(void) sprintf(bp, "\n\nCode RAM");
12760	bp += strlen(bp);
12761	for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
12762		if (cnt % 8 == 0) {
12763			(void) sprintf(bp, "\n%08x: ", cnt + 0x20000);
12764			bp += 11;
12765		}
12766		(void) sprintf(bp, "%08x ", fw->code_ram[cnt]);
12767		bp += 9;
12768	}
12769
12770	(void) sprintf(bp, "\n\nExternal Memory");
12771	bp += strlen(bp);
12772	for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) {
12773		if (cnt % 8 == 0) {
12774			(void) sprintf(bp, "\n%08x: ", cnt + 0x100000);
12775			bp += 11;
12776		}
12777		(void) sprintf(bp, "%08x ", fw->ext_mem[cnt]);
12778		bp += 9;
12779	}
12780
12781	(void) sprintf(bp, "\n[<==END] ISP Debug Dump");
12782	bp += strlen(bp);
12783
12784	(void) sprintf(bp, "\n\nRequest Queue");
12785	bp += strlen(bp);
12786	for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) {
12787		if (cnt % 8 == 0) {
12788			(void) sprintf(bp, "\n%08x: ", cnt);
12789			bp += strlen(bp);
12790		}
12791		(void) sprintf(bp, "%08x ", fw->req_q[cnt]);
12792		bp += strlen(bp);
12793	}
12794
12795	(void) sprintf(bp, "\n\nResponse Queue");
12796	bp += strlen(bp);
12797	for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) {
12798		if (cnt % 8 == 0) {
12799			(void) sprintf(bp, "\n%08x: ", cnt);
12800			bp += strlen(bp);
12801		}
12802		(void) sprintf(bp, "%08x ", fw->rsp_q[cnt]);
12803		bp += strlen(bp);
12804	}
12805
12806	if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) &&
12807	    (ha->fwexttracebuf.bp != NULL)) {
12808		uint32_t cnt_b = 0;
12809		uint64_t w64 = (uintptr_t)ha->fwexttracebuf.bp;
12810
12811		(void) sprintf(bp, "\n\nExtended Trace Buffer Memory");
12812		bp += strlen(bp);
12813		/* show data address as a byte address, data as long words */
12814		for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
12815			cnt_b = cnt * 4;
12816			if (cnt_b % 32 == 0) {
12817				(void) sprintf(bp, "\n%08x: ",
12818				    (int)(w64 + cnt_b));
12819				bp += 11;
12820			}
12821			(void) sprintf(bp, "%08x ", fw->ext_trace_buf[cnt]);
12822			bp += 9;
12823		}
12824	}
12825
12826	if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) &&
12827	    (ha->fwfcetracebuf.bp != NULL)) {
12828		uint32_t cnt_b = 0;
12829		uint64_t w64 = (uintptr_t)ha->fwfcetracebuf.bp;
12830
12831		(void) sprintf(bp, "\n\nFC Event Trace Buffer Memory");
12832		bp += strlen(bp);
12833		/* show data address as a byte address, data as long words */
12834		for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
12835			cnt_b = cnt * 4;
12836			if (cnt_b % 32 == 0) {
12837				(void) sprintf(bp, "\n%08x: ",
12838				    (int)(w64 + cnt_b));
12839				bp += 11;
12840			}
12841			(void) sprintf(bp, "%08x ", fw->fce_trace_buf[cnt]);
12842			bp += 9;
12843		}
12844	}
12845
12846	(void) sprintf(bp, "\n\n");
12847	bp += strlen(bp);
12848
12849	cnt = (uint32_t)((uintptr_t)bp - (uintptr_t)bufp);
12850
12851	QL_PRINT_3(CE_CONT, "(%d): done=%xh\n", ha->instance, cnt);
12852
12853	return (cnt);
12854}
12855
12856/*
12857 * ql_2200_binary_fw_dump
12858 *
12859 * Input:
12860 *	ha:	adapter state pointer.
12861 *	fw:	firmware dump context pointer.
12862 *
12863 * Returns:
12864 *	ql local function return status code.
12865 *
12866 * Context:
12867 *	Interrupt or Kernel context, no mailbox commands allowed.
12868 */
12869static int
12870ql_2200_binary_fw_dump(ql_adapter_state_t *ha, ql_fw_dump_t *fw)
12871{
12872	uint32_t	cnt;
12873	uint16_t	risc_address;
12874	clock_t		timer;
12875	mbx_cmd_t	mc;
12876	mbx_cmd_t	*mcp = &mc;
12877	int		rval = QL_SUCCESS;
12878
12879	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
12880
12881	/* Disable ISP interrupts. */
12882	WRT16_IO_REG(ha, ictrl, 0);
12883	ADAPTER_STATE_LOCK(ha);
12884	ha->flags &= ~INTERRUPTS_ENABLED;
12885	ADAPTER_STATE_UNLOCK(ha);
12886
12887	/* Release mailbox registers. */
12888	WRT16_IO_REG(ha, semaphore, 0);
12889
12890	/* Pause RISC. */
12891	WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
12892	timer = 30000;
12893	while ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) == 0) {
12894		if (timer-- != 0) {
12895			drv_usecwait(MILLISEC);
12896		} else {
12897			rval = QL_FUNCTION_TIMEOUT;
12898			break;
12899		}
12900	}
12901
12902	if (rval == QL_SUCCESS) {
12903		(void) ql_read_regs(ha, fw->pbiu_reg, ha->iobase,
12904		    sizeof (fw->pbiu_reg) / 2, 16);
12905
12906		/* In 2200 we only read 8 mailboxes */
12907		(void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x10,
12908		    8, 16);
12909
12910		(void) ql_read_regs(ha, fw->dma_reg, ha->iobase + 0x20,
12911		    sizeof (fw->dma_reg) / 2, 16);
12912
12913		WRT16_IO_REG(ha, ctrl_status, 0);
12914		(void) ql_read_regs(ha, fw->risc_hdw_reg, ha->iobase + 0xA0,
12915		    sizeof (fw->risc_hdw_reg) / 2, 16);
12916
12917		WRT16_IO_REG(ha, pcr, 0x2000);
12918		(void) ql_read_regs(ha, fw->risc_gp0_reg, ha->iobase + 0x80,
12919		    sizeof (fw->risc_gp0_reg) / 2, 16);
12920
12921		WRT16_IO_REG(ha, pcr, 0x2100);
12922		(void) ql_read_regs(ha, fw->risc_gp1_reg, ha->iobase + 0x80,
12923		    sizeof (fw->risc_gp1_reg) / 2, 16);
12924
12925		WRT16_IO_REG(ha, pcr, 0x2200);
12926		(void) ql_read_regs(ha, fw->risc_gp2_reg, ha->iobase + 0x80,
12927		    sizeof (fw->risc_gp2_reg) / 2, 16);
12928
12929		WRT16_IO_REG(ha, pcr, 0x2300);
12930		(void) ql_read_regs(ha, fw->risc_gp3_reg, ha->iobase + 0x80,
12931		    sizeof (fw->risc_gp3_reg) / 2, 16);
12932
12933		WRT16_IO_REG(ha, pcr, 0x2400);
12934		(void) ql_read_regs(ha, fw->risc_gp4_reg, ha->iobase + 0x80,
12935		    sizeof (fw->risc_gp4_reg) / 2, 16);
12936
12937		WRT16_IO_REG(ha, pcr, 0x2500);
12938		(void) ql_read_regs(ha, fw->risc_gp5_reg, ha->iobase + 0x80,
12939		    sizeof (fw->risc_gp5_reg) / 2, 16);
12940
12941		WRT16_IO_REG(ha, pcr, 0x2600);
12942		(void) ql_read_regs(ha, fw->risc_gp6_reg, ha->iobase + 0x80,
12943		    sizeof (fw->risc_gp6_reg) / 2, 16);
12944
12945		WRT16_IO_REG(ha, pcr, 0x2700);
12946		(void) ql_read_regs(ha, fw->risc_gp7_reg, ha->iobase + 0x80,
12947		    sizeof (fw->risc_gp7_reg) / 2, 16);
12948
12949		WRT16_IO_REG(ha, ctrl_status, 0x10);
12950		/* 2200 has only 16 registers */
12951		(void) ql_read_regs(ha, fw->frame_buf_hdw_reg,
12952		    ha->iobase + 0x80, 16, 16);
12953
12954		WRT16_IO_REG(ha, ctrl_status, 0x20);
12955		(void) ql_read_regs(ha, fw->fpm_b0_reg, ha->iobase + 0x80,
12956		    sizeof (fw->fpm_b0_reg) / 2, 16);
12957
12958		WRT16_IO_REG(ha, ctrl_status, 0x30);
12959		(void) ql_read_regs(ha, fw->fpm_b1_reg, ha->iobase + 0x80,
12960		    sizeof (fw->fpm_b1_reg) / 2, 16);
12961
12962		/* Select FPM registers. */
12963		WRT16_IO_REG(ha, ctrl_status, 0x20);
12964
12965		/* FPM Soft Reset. */
12966		WRT16_IO_REG(ha, fpm_diag_config, 0x100);
12967
12968		/* Select frame buffer registers. */
12969		WRT16_IO_REG(ha, ctrl_status, 0x10);
12970
12971		/* Reset frame buffer FIFOs. */
12972		WRT16_IO_REG(ha, fb_cmd, 0xa000);
12973
12974		/* Select RISC module registers. */
12975		WRT16_IO_REG(ha, ctrl_status, 0);
12976
12977		/* Reset RISC module. */
12978		WRT16_IO_REG(ha, hccr, HC_RESET_RISC);
12979
12980		/* Reset ISP semaphore. */
12981		WRT16_IO_REG(ha, semaphore, 0);
12982
12983		/* Release RISC module. */
12984		WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
12985
12986		/* Wait for RISC to recover from reset. */
12987		timer = 30000;
12988		while (RD16_IO_REG(ha, mailbox[0]) == MBS_BUSY) {
12989			if (timer-- != 0) {
12990				drv_usecwait(MILLISEC);
12991			} else {
12992				rval = QL_FUNCTION_TIMEOUT;
12993				break;
12994			}
12995		}
12996
12997		/* Disable RISC pause on FPM parity error. */
12998		WRT16_IO_REG(ha, hccr, HC_DISABLE_PARITY_PAUSE);
12999	}
13000
13001	if (rval == QL_SUCCESS) {
13002		/* Pause RISC. */
13003		WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
13004		timer = 30000;
13005		while ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) == 0) {
13006			if (timer-- != 0) {
13007				drv_usecwait(MILLISEC);
13008			} else {
13009				rval = QL_FUNCTION_TIMEOUT;
13010				break;
13011			}
13012		}
13013	}
13014
13015	if (rval == QL_SUCCESS) {
13016		/* Set memory configuration and timing. */
13017		WRT16_IO_REG(ha, mctr, 0xf2);
13018
13019		/* Release RISC. */
13020		WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
13021
13022		/* Get RISC SRAM. */
13023		risc_address = 0x1000;
13024		WRT16_IO_REG(ha, mailbox[0], MBC_READ_RAM_WORD);
13025		for (cnt = 0; cnt < 0xf000; cnt++) {
13026			WRT16_IO_REG(ha, mailbox[1], risc_address++);
13027			WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT);
13028			for (timer = 6000000; timer != 0; timer--) {
13029				/* Check for pending interrupts. */
13030				if (RD16_IO_REG(ha, istatus) & RISC_INT) {
13031					if (RD16_IO_REG(ha, semaphore) &
13032					    BIT_0) {
13033						WRT16_IO_REG(ha, hccr,
13034						    HC_CLR_RISC_INT);
13035						mcp->mb[0] = RD16_IO_REG(ha,
13036						    mailbox[0]);
13037						fw->risc_ram[cnt] =
13038						    RD16_IO_REG(ha,
13039						    mailbox[2]);
13040						WRT16_IO_REG(ha,
13041						    semaphore, 0);
13042						break;
13043					}
13044					WRT16_IO_REG(ha, hccr,
13045					    HC_CLR_RISC_INT);
13046				}
13047				drv_usecwait(5);
13048			}
13049
13050			if (timer == 0) {
13051				rval = QL_FUNCTION_TIMEOUT;
13052			} else {
13053				rval = mcp->mb[0];
13054			}
13055
13056			if (rval != QL_SUCCESS) {
13057				break;
13058			}
13059		}
13060	}
13061
13062	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
13063
13064	return (rval);
13065}
13066
13067/*
13068 * ql_2300_binary_fw_dump
13069 *
13070 * Input:
13071 *	ha:	adapter state pointer.
13072 *	fw:	firmware dump context pointer.
13073 *
13074 * Returns:
13075 *	ql local function return status code.
13076 *
13077 * Context:
13078 *	Interrupt or Kernel context, no mailbox commands allowed.
13079 */
13080static int
13081ql_2300_binary_fw_dump(ql_adapter_state_t *ha, ql_fw_dump_t *fw)
13082{
13083	clock_t	timer;
13084	int	rval = QL_SUCCESS;
13085
13086	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
13087
13088	/* Disable ISP interrupts. */
13089	WRT16_IO_REG(ha, ictrl, 0);
13090	ADAPTER_STATE_LOCK(ha);
13091	ha->flags &= ~INTERRUPTS_ENABLED;
13092	ADAPTER_STATE_UNLOCK(ha);
13093
13094	/* Release mailbox registers. */
13095	WRT16_IO_REG(ha, semaphore, 0);
13096
13097	/* Pause RISC. */
13098	WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
13099	timer = 30000;
13100	while ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) == 0) {
13101		if (timer-- != 0) {
13102			drv_usecwait(MILLISEC);
13103		} else {
13104			rval = QL_FUNCTION_TIMEOUT;
13105			break;
13106		}
13107	}
13108
13109	if (rval == QL_SUCCESS) {
13110		(void) ql_read_regs(ha, fw->pbiu_reg, ha->iobase,
13111		    sizeof (fw->pbiu_reg) / 2, 16);
13112
13113		(void) ql_read_regs(ha, fw->risc_host_reg, ha->iobase + 0x10,
13114		    sizeof (fw->risc_host_reg) / 2, 16);
13115
13116		(void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x40,
13117		    sizeof (fw->mailbox_reg) / 2, 16);
13118
13119		WRT16_IO_REG(ha, ctrl_status, 0x40);
13120		(void) ql_read_regs(ha, fw->resp_dma_reg, ha->iobase + 0x80,
13121		    sizeof (fw->resp_dma_reg) / 2, 16);
13122
13123		WRT16_IO_REG(ha, ctrl_status, 0x50);
13124		(void) ql_read_regs(ha, fw->dma_reg, ha->iobase + 0x80,
13125		    sizeof (fw->dma_reg) / 2, 16);
13126
13127		WRT16_IO_REG(ha, ctrl_status, 0);
13128		(void) ql_read_regs(ha, fw->risc_hdw_reg, ha->iobase + 0xA0,
13129		    sizeof (fw->risc_hdw_reg) / 2, 16);
13130
13131		WRT16_IO_REG(ha, pcr, 0x2000);
13132		(void) ql_read_regs(ha, fw->risc_gp0_reg, ha->iobase + 0x80,
13133		    sizeof (fw->risc_gp0_reg) / 2, 16);
13134
13135		WRT16_IO_REG(ha, pcr, 0x2200);
13136		(void) ql_read_regs(ha, fw->risc_gp1_reg, ha->iobase + 0x80,
13137		    sizeof (fw->risc_gp1_reg) / 2, 16);
13138
13139		WRT16_IO_REG(ha, pcr, 0x2400);
13140		(void) ql_read_regs(ha, fw->risc_gp2_reg, ha->iobase + 0x80,
13141		    sizeof (fw->risc_gp2_reg) / 2, 16);
13142
13143		WRT16_IO_REG(ha, pcr, 0x2600);
13144		(void) ql_read_regs(ha, fw->risc_gp3_reg, ha->iobase + 0x80,
13145		    sizeof (fw->risc_gp3_reg) / 2, 16);
13146
13147		WRT16_IO_REG(ha, pcr, 0x2800);
13148		(void) ql_read_regs(ha, fw->risc_gp4_reg, ha->iobase + 0x80,
13149		    sizeof (fw->risc_gp4_reg) / 2, 16);
13150
13151		WRT16_IO_REG(ha, pcr, 0x2A00);
13152		(void) ql_read_regs(ha, fw->risc_gp5_reg, ha->iobase + 0x80,
13153		    sizeof (fw->risc_gp5_reg) / 2, 16);
13154
13155		WRT16_IO_REG(ha, pcr, 0x2C00);
13156		(void) ql_read_regs(ha, fw->risc_gp6_reg, ha->iobase + 0x80,
13157		    sizeof (fw->risc_gp6_reg) / 2, 16);
13158
13159		WRT16_IO_REG(ha, pcr, 0x2E00);
13160		(void) ql_read_regs(ha, fw->risc_gp7_reg, ha->iobase + 0x80,
13161		    sizeof (fw->risc_gp7_reg) / 2, 16);
13162
13163		WRT16_IO_REG(ha, ctrl_status, 0x10);
13164		(void) ql_read_regs(ha, fw->frame_buf_hdw_reg,
13165		    ha->iobase + 0x80, sizeof (fw->frame_buf_hdw_reg) / 2, 16);
13166
13167		WRT16_IO_REG(ha, ctrl_status, 0x20);
13168		(void) ql_read_regs(ha, fw->fpm_b0_reg, ha->iobase + 0x80,
13169		    sizeof (fw->fpm_b0_reg) / 2, 16);
13170
13171		WRT16_IO_REG(ha, ctrl_status, 0x30);
13172		(void) ql_read_regs(ha, fw->fpm_b1_reg, ha->iobase + 0x80,
13173		    sizeof (fw->fpm_b1_reg) / 2, 16);
13174
13175		/* Select FPM registers. */
13176		WRT16_IO_REG(ha, ctrl_status, 0x20);
13177
13178		/* FPM Soft Reset. */
13179		WRT16_IO_REG(ha, fpm_diag_config, 0x100);
13180
13181		/* Select frame buffer registers. */
13182		WRT16_IO_REG(ha, ctrl_status, 0x10);
13183
13184		/* Reset frame buffer FIFOs. */
13185		WRT16_IO_REG(ha, fb_cmd, 0xa000);
13186
13187		/* Select RISC module registers. */
13188		WRT16_IO_REG(ha, ctrl_status, 0);
13189
13190		/* Reset RISC module. */
13191		WRT16_IO_REG(ha, hccr, HC_RESET_RISC);
13192
13193		/* Reset ISP semaphore. */
13194		WRT16_IO_REG(ha, semaphore, 0);
13195
13196		/* Release RISC module. */
13197		WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
13198
13199		/* Wait for RISC to recover from reset. */
13200		timer = 30000;
13201		while (RD16_IO_REG(ha, mailbox[0]) == MBS_BUSY) {
13202			if (timer-- != 0) {
13203				drv_usecwait(MILLISEC);
13204			} else {
13205				rval = QL_FUNCTION_TIMEOUT;
13206				break;
13207			}
13208		}
13209
13210		/* Disable RISC pause on FPM parity error. */
13211		WRT16_IO_REG(ha, hccr, HC_DISABLE_PARITY_PAUSE);
13212	}
13213
13214	/* Get RISC SRAM. */
13215	if (rval == QL_SUCCESS) {
13216		rval = ql_read_risc_ram(ha, 0x800, 0xf800, fw->risc_ram);
13217	}
13218	/* Get STACK SRAM. */
13219	if (rval == QL_SUCCESS) {
13220		rval = ql_read_risc_ram(ha, 0x10000, 0x800, fw->stack_ram);
13221	}
13222	/* Get DATA SRAM. */
13223	if (rval == QL_SUCCESS) {
13224		rval = ql_read_risc_ram(ha, 0x10800, 0xf800, fw->data_ram);
13225	}
13226
13227	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
13228
13229	return (rval);
13230}
13231
13232/*
13233 * ql_24xx_binary_fw_dump
13234 *
13235 * Input:
13236 *	ha:	adapter state pointer.
13237 *	fw:	firmware dump context pointer.
13238 *
13239 * Returns:
13240 *	ql local function return status code.
13241 *
13242 * Context:
13243 *	Interrupt or Kernel context, no mailbox commands allowed.
13244 */
13245static int
13246ql_24xx_binary_fw_dump(ql_adapter_state_t *ha, ql_24xx_fw_dump_t *fw)
13247{
13248	uint32_t	*reg32;
13249	void		*bp;
13250	clock_t		timer;
13251	int		rval = QL_SUCCESS;
13252
13253	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
13254
13255	fw->hccr = RD32_IO_REG(ha, hccr);
13256
13257	/* Pause RISC. */
13258	if ((RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0) {
13259		/* Disable ISP interrupts. */
13260		WRT16_IO_REG(ha, ictrl, 0);
13261
13262		WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC);
13263		for (timer = 30000;
13264		    (RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0 &&
13265		    rval == QL_SUCCESS; timer--) {
13266			if (timer) {
13267				drv_usecwait(100);
13268			} else {
13269				rval = QL_FUNCTION_TIMEOUT;
13270			}
13271		}
13272	}
13273
13274	if (rval == QL_SUCCESS) {
13275		/* Host interface registers. */
13276		(void) ql_read_regs(ha, fw->host_reg, ha->iobase,
13277		    sizeof (fw->host_reg) / 4, 32);
13278
13279		/* Disable ISP interrupts. */
13280		WRT32_IO_REG(ha, ictrl, 0);
13281		RD32_IO_REG(ha, ictrl);
13282		ADAPTER_STATE_LOCK(ha);
13283		ha->flags &= ~INTERRUPTS_ENABLED;
13284		ADAPTER_STATE_UNLOCK(ha);
13285
13286		/* Shadow registers. */
13287
13288		WRT32_IO_REG(ha, io_base_addr, 0x0F70);
13289		RD32_IO_REG(ha, io_base_addr);
13290
13291		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13292		WRT_REG_DWORD(ha, reg32, 0xB0000000);
13293		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13294		fw->shadow_reg[0] = RD_REG_DWORD(ha, reg32);
13295
13296		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13297		WRT_REG_DWORD(ha, reg32, 0xB0100000);
13298		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13299		fw->shadow_reg[1] = RD_REG_DWORD(ha, reg32);
13300
13301		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13302		WRT_REG_DWORD(ha, reg32, 0xB0200000);
13303		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13304		fw->shadow_reg[2] = RD_REG_DWORD(ha, reg32);
13305
13306		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13307		WRT_REG_DWORD(ha, reg32, 0xB0300000);
13308		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13309		fw->shadow_reg[3] = RD_REG_DWORD(ha, reg32);
13310
13311		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13312		WRT_REG_DWORD(ha, reg32, 0xB0400000);
13313		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13314		fw->shadow_reg[4] = RD_REG_DWORD(ha, reg32);
13315
13316		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13317		WRT_REG_DWORD(ha, reg32, 0xB0500000);
13318		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13319		fw->shadow_reg[5] = RD_REG_DWORD(ha, reg32);
13320
13321		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13322		WRT_REG_DWORD(ha, reg32, 0xB0600000);
13323		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13324		fw->shadow_reg[6] = RD_REG_DWORD(ha, reg32);
13325
13326		/* Mailbox registers. */
13327		(void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x80,
13328		    sizeof (fw->mailbox_reg) / 2, 16);
13329
13330		/* Transfer sequence registers. */
13331
13332		/* XSEQ GP */
13333		WRT32_IO_REG(ha, io_base_addr, 0xBF00);
13334		bp = ql_read_regs(ha, fw->xseq_gp_reg, ha->iobase + 0xC0,
13335		    16, 32);
13336		WRT32_IO_REG(ha, io_base_addr, 0xBF10);
13337		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13338		WRT32_IO_REG(ha, io_base_addr, 0xBF20);
13339		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13340		WRT32_IO_REG(ha, io_base_addr, 0xBF30);
13341		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13342		WRT32_IO_REG(ha, io_base_addr, 0xBF40);
13343		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13344		WRT32_IO_REG(ha, io_base_addr, 0xBF50);
13345		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13346		WRT32_IO_REG(ha, io_base_addr, 0xBF60);
13347		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13348		WRT32_IO_REG(ha, io_base_addr, 0xBF70);
13349		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13350
13351		/* XSEQ-0 */
13352		WRT32_IO_REG(ha, io_base_addr, 0xBFE0);
13353		(void) ql_read_regs(ha, fw->xseq_0_reg, ha->iobase + 0xC0,
13354		    sizeof (fw->xseq_0_reg) / 4, 32);
13355
13356		/* XSEQ-1 */
13357		WRT32_IO_REG(ha, io_base_addr, 0xBFF0);
13358		(void) ql_read_regs(ha, fw->xseq_1_reg, ha->iobase + 0xC0,
13359		    sizeof (fw->xseq_1_reg) / 4, 32);
13360
13361		/* Receive sequence registers. */
13362
13363		/* RSEQ GP */
13364		WRT32_IO_REG(ha, io_base_addr, 0xFF00);
13365		bp = ql_read_regs(ha, fw->rseq_gp_reg, ha->iobase + 0xC0,
13366		    16, 32);
13367		WRT32_IO_REG(ha, io_base_addr, 0xFF10);
13368		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13369		WRT32_IO_REG(ha, io_base_addr, 0xFF20);
13370		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13371		WRT32_IO_REG(ha, io_base_addr, 0xFF30);
13372		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13373		WRT32_IO_REG(ha, io_base_addr, 0xFF40);
13374		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13375		WRT32_IO_REG(ha, io_base_addr, 0xFF50);
13376		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13377		WRT32_IO_REG(ha, io_base_addr, 0xFF60);
13378		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13379		WRT32_IO_REG(ha, io_base_addr, 0xFF70);
13380		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13381
13382		/* RSEQ-0 */
13383		WRT32_IO_REG(ha, io_base_addr, 0xFFD0);
13384		(void) ql_read_regs(ha, fw->rseq_0_reg, ha->iobase + 0xC0,
13385		    sizeof (fw->rseq_0_reg) / 4, 32);
13386
13387		/* RSEQ-1 */
13388		WRT32_IO_REG(ha, io_base_addr, 0xFFE0);
13389		(void) ql_read_regs(ha, fw->rseq_1_reg, ha->iobase + 0xC0,
13390		    sizeof (fw->rseq_1_reg) / 4, 32);
13391
13392		/* RSEQ-2 */
13393		WRT32_IO_REG(ha, io_base_addr, 0xFFF0);
13394		(void) ql_read_regs(ha, fw->rseq_2_reg, ha->iobase + 0xC0,
13395		    sizeof (fw->rseq_2_reg) / 4, 32);
13396
13397		/* Command DMA registers. */
13398
13399		WRT32_IO_REG(ha, io_base_addr, 0x7100);
13400		(void) ql_read_regs(ha, fw->cmd_dma_reg, ha->iobase + 0xC0,
13401		    sizeof (fw->cmd_dma_reg) / 4, 32);
13402
13403		/* Queues. */
13404
13405		/* RequestQ0 */
13406		WRT32_IO_REG(ha, io_base_addr, 0x7200);
13407		bp = ql_read_regs(ha, fw->req0_dma_reg, ha->iobase + 0xC0,
13408		    8, 32);
13409		(void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
13410
13411		/* ResponseQ0 */
13412		WRT32_IO_REG(ha, io_base_addr, 0x7300);
13413		bp = ql_read_regs(ha, fw->resp0_dma_reg, ha->iobase + 0xC0,
13414		    8, 32);
13415		(void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
13416
13417		/* RequestQ1 */
13418		WRT32_IO_REG(ha, io_base_addr, 0x7400);
13419		bp = ql_read_regs(ha, fw->req1_dma_reg, ha->iobase + 0xC0,
13420		    8, 32);
13421		(void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
13422
13423		/* Transmit DMA registers. */
13424
13425		/* XMT0 */
13426		WRT32_IO_REG(ha, io_base_addr, 0x7600);
13427		bp = ql_read_regs(ha, fw->xmt0_dma_reg, ha->iobase + 0xC0,
13428		    16, 32);
13429		WRT32_IO_REG(ha, io_base_addr, 0x7610);
13430		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13431
13432		/* XMT1 */
13433		WRT32_IO_REG(ha, io_base_addr, 0x7620);
13434		bp = ql_read_regs(ha, fw->xmt1_dma_reg, ha->iobase + 0xC0,
13435		    16, 32);
13436		WRT32_IO_REG(ha, io_base_addr, 0x7630);
13437		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13438
13439		/* XMT2 */
13440		WRT32_IO_REG(ha, io_base_addr, 0x7640);
13441		bp = ql_read_regs(ha, fw->xmt2_dma_reg, ha->iobase + 0xC0,
13442		    16, 32);
13443		WRT32_IO_REG(ha, io_base_addr, 0x7650);
13444		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13445
13446		/* XMT3 */
13447		WRT32_IO_REG(ha, io_base_addr, 0x7660);
13448		bp = ql_read_regs(ha, fw->xmt3_dma_reg, ha->iobase + 0xC0,
13449		    16, 32);
13450		WRT32_IO_REG(ha, io_base_addr, 0x7670);
13451		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13452
13453		/* XMT4 */
13454		WRT32_IO_REG(ha, io_base_addr, 0x7680);
13455		bp = ql_read_regs(ha, fw->xmt4_dma_reg, ha->iobase + 0xC0,
13456		    16, 32);
13457		WRT32_IO_REG(ha, io_base_addr, 0x7690);
13458		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13459
13460		/* XMT Common */
13461		WRT32_IO_REG(ha, io_base_addr, 0x76A0);
13462		(void) ql_read_regs(ha, fw->xmt_data_dma_reg,
13463		    ha->iobase + 0xC0, sizeof (fw->xmt_data_dma_reg) / 4, 32);
13464
13465		/* Receive DMA registers. */
13466
13467		/* RCVThread0 */
13468		WRT32_IO_REG(ha, io_base_addr, 0x7700);
13469		bp = ql_read_regs(ha, fw->rcvt0_data_dma_reg,
13470		    ha->iobase + 0xC0, 16, 32);
13471		WRT32_IO_REG(ha, io_base_addr, 0x7710);
13472		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13473
13474		/* RCVThread1 */
13475		WRT32_IO_REG(ha, io_base_addr, 0x7720);
13476		bp = ql_read_regs(ha, fw->rcvt1_data_dma_reg,
13477		    ha->iobase + 0xC0, 16, 32);
13478		WRT32_IO_REG(ha, io_base_addr, 0x7730);
13479		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13480
13481		/* RISC registers. */
13482
13483		/* RISC GP */
13484		WRT32_IO_REG(ha, io_base_addr, 0x0F00);
13485		bp = ql_read_regs(ha, fw->risc_gp_reg, ha->iobase + 0xC0,
13486		    16, 32);
13487		WRT32_IO_REG(ha, io_base_addr, 0x0F10);
13488		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13489		WRT32_IO_REG(ha, io_base_addr, 0x0F20);
13490		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13491		WRT32_IO_REG(ha, io_base_addr, 0x0F30);
13492		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13493		WRT32_IO_REG(ha, io_base_addr, 0x0F40);
13494		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13495		WRT32_IO_REG(ha, io_base_addr, 0x0F50);
13496		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13497		WRT32_IO_REG(ha, io_base_addr, 0x0F60);
13498		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13499		WRT32_IO_REG(ha, io_base_addr, 0x0F70);
13500		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13501
13502		/* Local memory controller registers. */
13503
13504		/* LMC */
13505		WRT32_IO_REG(ha, io_base_addr, 0x3000);
13506		bp = ql_read_regs(ha, fw->lmc_reg, ha->iobase + 0xC0,
13507		    16, 32);
13508		WRT32_IO_REG(ha, io_base_addr, 0x3010);
13509		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13510		WRT32_IO_REG(ha, io_base_addr, 0x3020);
13511		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13512		WRT32_IO_REG(ha, io_base_addr, 0x3030);
13513		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13514		WRT32_IO_REG(ha, io_base_addr, 0x3040);
13515		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13516		WRT32_IO_REG(ha, io_base_addr, 0x3050);
13517		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13518		WRT32_IO_REG(ha, io_base_addr, 0x3060);
13519		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13520
13521		/* Fibre Protocol Module registers. */
13522
13523		/* FPM hardware */
13524		WRT32_IO_REG(ha, io_base_addr, 0x4000);
13525		bp = ql_read_regs(ha, fw->fpm_hdw_reg, ha->iobase + 0xC0,
13526		    16, 32);
13527		WRT32_IO_REG(ha, io_base_addr, 0x4010);
13528		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13529		WRT32_IO_REG(ha, io_base_addr, 0x4020);
13530		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13531		WRT32_IO_REG(ha, io_base_addr, 0x4030);
13532		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13533		WRT32_IO_REG(ha, io_base_addr, 0x4040);
13534		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13535		WRT32_IO_REG(ha, io_base_addr, 0x4050);
13536		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13537		WRT32_IO_REG(ha, io_base_addr, 0x4060);
13538		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13539		WRT32_IO_REG(ha, io_base_addr, 0x4070);
13540		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13541		WRT32_IO_REG(ha, io_base_addr, 0x4080);
13542		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13543		WRT32_IO_REG(ha, io_base_addr, 0x4090);
13544		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13545		WRT32_IO_REG(ha, io_base_addr, 0x40A0);
13546		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13547		WRT32_IO_REG(ha, io_base_addr, 0x40B0);
13548		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13549
13550		/* Frame Buffer registers. */
13551
13552		/* FB hardware */
13553		WRT32_IO_REG(ha, io_base_addr, 0x6000);
13554		bp = ql_read_regs(ha, fw->fb_hdw_reg, ha->iobase + 0xC0,
13555		    16, 32);
13556		WRT32_IO_REG(ha, io_base_addr, 0x6010);
13557		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13558		WRT32_IO_REG(ha, io_base_addr, 0x6020);
13559		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13560		WRT32_IO_REG(ha, io_base_addr, 0x6030);
13561		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13562		WRT32_IO_REG(ha, io_base_addr, 0x6040);
13563		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13564		WRT32_IO_REG(ha, io_base_addr, 0x6100);
13565		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13566		WRT32_IO_REG(ha, io_base_addr, 0x6130);
13567		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13568		WRT32_IO_REG(ha, io_base_addr, 0x6150);
13569		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13570		WRT32_IO_REG(ha, io_base_addr, 0x6170);
13571		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13572		WRT32_IO_REG(ha, io_base_addr, 0x6190);
13573		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13574		WRT32_IO_REG(ha, io_base_addr, 0x61B0);
13575		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13576	}
13577
13578	/* Get the request queue */
13579	if (rval == QL_SUCCESS) {
13580		uint32_t	cnt;
13581		uint32_t	*w32 = (uint32_t *)ha->request_ring_bp;
13582
13583		/* Sync DMA buffer. */
13584		(void) ddi_dma_sync(ha->hba_buf.dma_handle,
13585		    REQUEST_Q_BUFFER_OFFSET, sizeof (fw->req_q),
13586		    DDI_DMA_SYNC_FORKERNEL);
13587
13588		for (cnt = 0; cnt < sizeof (fw->req_q) / 4; cnt++) {
13589			fw->req_q[cnt] = *w32++;
13590			LITTLE_ENDIAN_32(&fw->req_q[cnt]);
13591		}
13592	}
13593
13594	/* Get the response queue */
13595	if (rval == QL_SUCCESS) {
13596		uint32_t	cnt;
13597		uint32_t	*w32 = (uint32_t *)ha->response_ring_bp;
13598
13599		/* Sync DMA buffer. */
13600		(void) ddi_dma_sync(ha->hba_buf.dma_handle,
13601		    RESPONSE_Q_BUFFER_OFFSET, sizeof (fw->rsp_q),
13602		    DDI_DMA_SYNC_FORKERNEL);
13603
13604		for (cnt = 0; cnt < sizeof (fw->rsp_q) / 4; cnt++) {
13605			fw->rsp_q[cnt] = *w32++;
13606			LITTLE_ENDIAN_32(&fw->rsp_q[cnt]);
13607		}
13608	}
13609
13610	/* Reset RISC. */
13611	ql_reset_chip(ha);
13612
13613	/* Memory. */
13614	if (rval == QL_SUCCESS) {
13615		/* Code RAM. */
13616		rval = ql_read_risc_ram(ha, 0x20000,
13617		    sizeof (fw->code_ram) / 4, fw->code_ram);
13618	}
13619	if (rval == QL_SUCCESS) {
13620		/* External Memory. */
13621		rval = ql_read_risc_ram(ha, 0x100000,
13622		    ha->fw_ext_memory_size / 4, fw->ext_mem);
13623	}
13624
13625	/* Get the extended trace buffer */
13626	if (rval == QL_SUCCESS) {
13627		if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) &&
13628		    (ha->fwexttracebuf.bp != NULL)) {
13629			uint32_t	cnt;
13630			uint32_t	*w32 = ha->fwexttracebuf.bp;
13631
13632			/* Sync DMA buffer. */
13633			(void) ddi_dma_sync(ha->fwexttracebuf.dma_handle, 0,
13634			    FWEXTSIZE, DDI_DMA_SYNC_FORKERNEL);
13635
13636			for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
13637				fw->ext_trace_buf[cnt] = *w32++;
13638			}
13639		}
13640	}
13641
13642	/* Get the FC event trace buffer */
13643	if (rval == QL_SUCCESS) {
13644		if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) &&
13645		    (ha->fwfcetracebuf.bp != NULL)) {
13646			uint32_t	cnt;
13647			uint32_t	*w32 = ha->fwfcetracebuf.bp;
13648
13649			/* Sync DMA buffer. */
13650			(void) ddi_dma_sync(ha->fwfcetracebuf.dma_handle, 0,
13651			    FWFCESIZE, DDI_DMA_SYNC_FORKERNEL);
13652
13653			for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
13654				fw->fce_trace_buf[cnt] = *w32++;
13655			}
13656		}
13657	}
13658
13659	if (rval != QL_SUCCESS) {
13660		EL(ha, "failed=%xh\n", rval);
13661	} else {
13662		/*EMPTY*/
13663		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
13664	}
13665
13666	return (rval);
13667}
13668
13669/*
13670 * ql_25xx_binary_fw_dump
13671 *
13672 * Input:
13673 *	ha:	adapter state pointer.
13674 *	fw:	firmware dump context pointer.
13675 *
13676 * Returns:
13677 *	ql local function return status code.
13678 *
13679 * Context:
13680 *	Interrupt or Kernel context, no mailbox commands allowed.
13681 */
13682static int
13683ql_25xx_binary_fw_dump(ql_adapter_state_t *ha, ql_25xx_fw_dump_t *fw)
13684{
13685	uint32_t	*reg32;
13686	void		*bp;
13687	clock_t		timer;
13688	int		rval = QL_SUCCESS;
13689
13690	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
13691
13692	fw->r2h_status = RD32_IO_REG(ha, intr_info_lo);
13693
13694	/* Pause RISC. */
13695	if ((RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0) {
13696		/* Disable ISP interrupts. */
13697		WRT16_IO_REG(ha, ictrl, 0);
13698
13699		WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC);
13700		for (timer = 30000;
13701		    (RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0 &&
13702		    rval == QL_SUCCESS; timer--) {
13703			if (timer) {
13704				drv_usecwait(100);
13705				if (timer % 10000 == 0) {
13706					EL(ha, "risc pause %d\n", timer);
13707				}
13708			} else {
13709				EL(ha, "risc pause timeout\n");
13710				rval = QL_FUNCTION_TIMEOUT;
13711			}
13712		}
13713	}
13714
13715	if (rval == QL_SUCCESS) {
13716
13717		/* Host Interface registers */
13718
13719		/* HostRisc registers. */
13720		WRT32_IO_REG(ha, io_base_addr, 0x7000);
13721		bp = ql_read_regs(ha, fw->hostrisc_reg, ha->iobase + 0xC0,
13722		    16, 32);
13723		WRT32_IO_REG(ha, io_base_addr, 0x7010);
13724		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13725
13726		/* PCIe registers. */
13727		WRT32_IO_REG(ha, io_base_addr, 0x7c00);
13728		WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x1);
13729		bp = ql_read_regs(ha, fw->pcie_reg, ha->iobase + 0xC4,
13730		    3, 32);
13731		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 1, 32);
13732		WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x0);
13733
13734		/* Host interface registers. */
13735		(void) ql_read_regs(ha, fw->host_reg, ha->iobase,
13736		    sizeof (fw->host_reg) / 4, 32);
13737
13738		/* Disable ISP interrupts. */
13739
13740		WRT32_IO_REG(ha, ictrl, 0);
13741		RD32_IO_REG(ha, ictrl);
13742		ADAPTER_STATE_LOCK(ha);
13743		ha->flags &= ~INTERRUPTS_ENABLED;
13744		ADAPTER_STATE_UNLOCK(ha);
13745
13746		/* Shadow registers. */
13747
13748		WRT32_IO_REG(ha, io_base_addr, 0x0F70);
13749		RD32_IO_REG(ha, io_base_addr);
13750
13751		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13752		WRT_REG_DWORD(ha, reg32, 0xB0000000);
13753		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13754		fw->shadow_reg[0] = RD_REG_DWORD(ha, reg32);
13755
13756		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13757		WRT_REG_DWORD(ha, reg32, 0xB0100000);
13758		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13759		fw->shadow_reg[1] = RD_REG_DWORD(ha, reg32);
13760
13761		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13762		WRT_REG_DWORD(ha, reg32, 0xB0200000);
13763		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13764		fw->shadow_reg[2] = RD_REG_DWORD(ha, reg32);
13765
13766		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13767		WRT_REG_DWORD(ha, reg32, 0xB0300000);
13768		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13769		fw->shadow_reg[3] = RD_REG_DWORD(ha, reg32);
13770
13771		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13772		WRT_REG_DWORD(ha, reg32, 0xB0400000);
13773		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13774		fw->shadow_reg[4] = RD_REG_DWORD(ha, reg32);
13775
13776		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13777		WRT_REG_DWORD(ha, reg32, 0xB0500000);
13778		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13779		fw->shadow_reg[5] = RD_REG_DWORD(ha, reg32);
13780
13781		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13782		WRT_REG_DWORD(ha, reg32, 0xB0600000);
13783		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13784		fw->shadow_reg[6] = RD_REG_DWORD(ha, reg32);
13785
13786		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13787		WRT_REG_DWORD(ha, reg32, 0xB0700000);
13788		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13789		fw->shadow_reg[7] = RD_REG_DWORD(ha, reg32);
13790
13791		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13792		WRT_REG_DWORD(ha, reg32, 0xB0800000);
13793		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13794		fw->shadow_reg[8] = RD_REG_DWORD(ha, reg32);
13795
13796		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13797		WRT_REG_DWORD(ha, reg32, 0xB0900000);
13798		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13799		fw->shadow_reg[9] = RD_REG_DWORD(ha, reg32);
13800
13801		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
13802		WRT_REG_DWORD(ha, reg32, 0xB0A00000);
13803		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
13804		fw->shadow_reg[0xa] = RD_REG_DWORD(ha, reg32);
13805
13806		/* RISC I/O register. */
13807
13808		WRT32_IO_REG(ha, io_base_addr, 0x0010);
13809		(void) ql_read_regs(ha, &fw->risc_io, ha->iobase + 0xC0,
13810		    1, 32);
13811
13812		/* Mailbox registers. */
13813
13814		(void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x80,
13815		    sizeof (fw->mailbox_reg) / 2, 16);
13816
13817		/* Transfer sequence registers. */
13818
13819		/* XSEQ GP */
13820		WRT32_IO_REG(ha, io_base_addr, 0xBF00);
13821		bp = ql_read_regs(ha, fw->xseq_gp_reg, ha->iobase + 0xC0,
13822		    16, 32);
13823		WRT32_IO_REG(ha, io_base_addr, 0xBF10);
13824		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13825		WRT32_IO_REG(ha, io_base_addr, 0xBF20);
13826		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13827		WRT32_IO_REG(ha, io_base_addr, 0xBF30);
13828		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13829		WRT32_IO_REG(ha, io_base_addr, 0xBF40);
13830		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13831		WRT32_IO_REG(ha, io_base_addr, 0xBF50);
13832		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13833		WRT32_IO_REG(ha, io_base_addr, 0xBF60);
13834		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13835		WRT32_IO_REG(ha, io_base_addr, 0xBF70);
13836		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13837
13838		/* XSEQ-0 */
13839		WRT32_IO_REG(ha, io_base_addr, 0xBFC0);
13840		bp = ql_read_regs(ha, fw->xseq_0_reg, ha->iobase + 0xC0,
13841		    16, 32);
13842		WRT32_IO_REG(ha, io_base_addr, 0xBFD0);
13843		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13844		WRT32_IO_REG(ha, io_base_addr, 0xBFE0);
13845		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13846
13847		/* XSEQ-1 */
13848		WRT32_IO_REG(ha, io_base_addr, 0xBFF0);
13849		(void) ql_read_regs(ha, fw->xseq_1_reg, ha->iobase + 0xC0,
13850		    16, 32);
13851
13852		/* Receive sequence registers. */
13853
13854		/* RSEQ GP */
13855		WRT32_IO_REG(ha, io_base_addr, 0xFF00);
13856		bp = ql_read_regs(ha, fw->rseq_gp_reg, ha->iobase + 0xC0,
13857		    16, 32);
13858		WRT32_IO_REG(ha, io_base_addr, 0xFF10);
13859		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13860		WRT32_IO_REG(ha, io_base_addr, 0xFF20);
13861		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13862		WRT32_IO_REG(ha, io_base_addr, 0xFF30);
13863		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13864		WRT32_IO_REG(ha, io_base_addr, 0xFF40);
13865		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13866		WRT32_IO_REG(ha, io_base_addr, 0xFF50);
13867		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13868		WRT32_IO_REG(ha, io_base_addr, 0xFF60);
13869		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13870		WRT32_IO_REG(ha, io_base_addr, 0xFF70);
13871		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13872
13873		/* RSEQ-0 */
13874		WRT32_IO_REG(ha, io_base_addr, 0xFFC0);
13875		bp = ql_read_regs(ha, fw->rseq_0_reg, ha->iobase + 0xC0,
13876		    16, 32);
13877		WRT32_IO_REG(ha, io_base_addr, 0xFFD0);
13878		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13879
13880		/* RSEQ-1 */
13881		WRT32_IO_REG(ha, io_base_addr, 0xFFE0);
13882		(void) ql_read_regs(ha, fw->rseq_1_reg, ha->iobase + 0xC0,
13883		    sizeof (fw->rseq_1_reg) / 4, 32);
13884
13885		/* RSEQ-2 */
13886		WRT32_IO_REG(ha, io_base_addr, 0xFFF0);
13887		(void) ql_read_regs(ha, fw->rseq_2_reg, ha->iobase + 0xC0,
13888		    sizeof (fw->rseq_2_reg) / 4, 32);
13889
13890		/* Auxiliary sequencer registers. */
13891
13892		/* ASEQ GP */
13893		WRT32_IO_REG(ha, io_base_addr, 0xB000);
13894		bp = ql_read_regs(ha, fw->aseq_gp_reg, ha->iobase + 0xC0,
13895		    16, 32);
13896		WRT32_IO_REG(ha, io_base_addr, 0xB010);
13897		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13898		WRT32_IO_REG(ha, io_base_addr, 0xB020);
13899		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13900		WRT32_IO_REG(ha, io_base_addr, 0xB030);
13901		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13902		WRT32_IO_REG(ha, io_base_addr, 0xB040);
13903		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13904		WRT32_IO_REG(ha, io_base_addr, 0xB050);
13905		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13906		WRT32_IO_REG(ha, io_base_addr, 0xB060);
13907		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13908		WRT32_IO_REG(ha, io_base_addr, 0xB070);
13909		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13910
13911		/* ASEQ-0 */
13912		WRT32_IO_REG(ha, io_base_addr, 0xB0C0);
13913		bp = ql_read_regs(ha, fw->aseq_0_reg, ha->iobase + 0xC0,
13914		    16, 32);
13915		WRT32_IO_REG(ha, io_base_addr, 0xB0D0);
13916		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13917
13918		/* ASEQ-1 */
13919		WRT32_IO_REG(ha, io_base_addr, 0xB0E0);
13920		(void) ql_read_regs(ha, fw->aseq_1_reg, ha->iobase + 0xC0,
13921		    16, 32);
13922
13923		/* ASEQ-2 */
13924		WRT32_IO_REG(ha, io_base_addr, 0xB0F0);
13925		(void) ql_read_regs(ha, fw->aseq_2_reg, ha->iobase + 0xC0,
13926		    16, 32);
13927
13928		/* Command DMA registers. */
13929
13930		WRT32_IO_REG(ha, io_base_addr, 0x7100);
13931		(void) ql_read_regs(ha, fw->cmd_dma_reg, ha->iobase + 0xC0,
13932		    sizeof (fw->cmd_dma_reg) / 4, 32);
13933
13934		/* Queues. */
13935
13936		/* RequestQ0 */
13937		WRT32_IO_REG(ha, io_base_addr, 0x7200);
13938		bp = ql_read_regs(ha, fw->req0_dma_reg, ha->iobase + 0xC0,
13939		    8, 32);
13940		(void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
13941
13942		/* ResponseQ0 */
13943		WRT32_IO_REG(ha, io_base_addr, 0x7300);
13944		bp = ql_read_regs(ha, fw->resp0_dma_reg, ha->iobase + 0xC0,
13945		    8, 32);
13946		(void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
13947
13948		/* RequestQ1 */
13949		WRT32_IO_REG(ha, io_base_addr, 0x7400);
13950		bp = ql_read_regs(ha, fw->req1_dma_reg, ha->iobase + 0xC0,
13951		    8, 32);
13952		(void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
13953
13954		/* Transmit DMA registers. */
13955
13956		/* XMT0 */
13957		WRT32_IO_REG(ha, io_base_addr, 0x7600);
13958		bp = ql_read_regs(ha, fw->xmt0_dma_reg, ha->iobase + 0xC0,
13959		    16, 32);
13960		WRT32_IO_REG(ha, io_base_addr, 0x7610);
13961		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13962
13963		/* XMT1 */
13964		WRT32_IO_REG(ha, io_base_addr, 0x7620);
13965		bp = ql_read_regs(ha, fw->xmt1_dma_reg, ha->iobase + 0xC0,
13966		    16, 32);
13967		WRT32_IO_REG(ha, io_base_addr, 0x7630);
13968		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13969
13970		/* XMT2 */
13971		WRT32_IO_REG(ha, io_base_addr, 0x7640);
13972		bp = ql_read_regs(ha, fw->xmt2_dma_reg, ha->iobase + 0xC0,
13973		    16, 32);
13974		WRT32_IO_REG(ha, io_base_addr, 0x7650);
13975		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13976
13977		/* XMT3 */
13978		WRT32_IO_REG(ha, io_base_addr, 0x7660);
13979		bp = ql_read_regs(ha, fw->xmt3_dma_reg, ha->iobase + 0xC0,
13980		    16, 32);
13981		WRT32_IO_REG(ha, io_base_addr, 0x7670);
13982		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13983
13984		/* XMT4 */
13985		WRT32_IO_REG(ha, io_base_addr, 0x7680);
13986		bp = ql_read_regs(ha, fw->xmt4_dma_reg, ha->iobase + 0xC0,
13987		    16, 32);
13988		WRT32_IO_REG(ha, io_base_addr, 0x7690);
13989		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
13990
13991		/* XMT Common */
13992		WRT32_IO_REG(ha, io_base_addr, 0x76A0);
13993		(void) ql_read_regs(ha, fw->xmt_data_dma_reg,
13994		    ha->iobase + 0xC0, sizeof (fw->xmt_data_dma_reg) / 4, 32);
13995
13996		/* Receive DMA registers. */
13997
13998		/* RCVThread0 */
13999		WRT32_IO_REG(ha, io_base_addr, 0x7700);
14000		bp = ql_read_regs(ha, fw->rcvt0_data_dma_reg,
14001		    ha->iobase + 0xC0, 16, 32);
14002		WRT32_IO_REG(ha, io_base_addr, 0x7710);
14003		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14004
14005		/* RCVThread1 */
14006		WRT32_IO_REG(ha, io_base_addr, 0x7720);
14007		bp = ql_read_regs(ha, fw->rcvt1_data_dma_reg,
14008		    ha->iobase + 0xC0, 16, 32);
14009		WRT32_IO_REG(ha, io_base_addr, 0x7730);
14010		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14011
14012		/* RISC registers. */
14013
14014		/* RISC GP */
14015		WRT32_IO_REG(ha, io_base_addr, 0x0F00);
14016		bp = ql_read_regs(ha, fw->risc_gp_reg, ha->iobase + 0xC0,
14017		    16, 32);
14018		WRT32_IO_REG(ha, io_base_addr, 0x0F10);
14019		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14020		WRT32_IO_REG(ha, io_base_addr, 0x0F20);
14021		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14022		WRT32_IO_REG(ha, io_base_addr, 0x0F30);
14023		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14024		WRT32_IO_REG(ha, io_base_addr, 0x0F40);
14025		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14026		WRT32_IO_REG(ha, io_base_addr, 0x0F50);
14027		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14028		WRT32_IO_REG(ha, io_base_addr, 0x0F60);
14029		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14030		WRT32_IO_REG(ha, io_base_addr, 0x0F70);
14031		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14032
14033		/* Local memory controller (LMC) registers. */
14034
14035		/* LMC */
14036		WRT32_IO_REG(ha, io_base_addr, 0x3000);
14037		bp = ql_read_regs(ha, fw->lmc_reg, ha->iobase + 0xC0,
14038		    16, 32);
14039		WRT32_IO_REG(ha, io_base_addr, 0x3010);
14040		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14041		WRT32_IO_REG(ha, io_base_addr, 0x3020);
14042		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14043		WRT32_IO_REG(ha, io_base_addr, 0x3030);
14044		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14045		WRT32_IO_REG(ha, io_base_addr, 0x3040);
14046		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14047		WRT32_IO_REG(ha, io_base_addr, 0x3050);
14048		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14049		WRT32_IO_REG(ha, io_base_addr, 0x3060);
14050		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14051		WRT32_IO_REG(ha, io_base_addr, 0x3070);
14052		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14053
14054		/* Fibre Protocol Module registers. */
14055
14056		/* FPM hardware */
14057		WRT32_IO_REG(ha, io_base_addr, 0x4000);
14058		bp = ql_read_regs(ha, fw->fpm_hdw_reg, ha->iobase + 0xC0,
14059		    16, 32);
14060		WRT32_IO_REG(ha, io_base_addr, 0x4010);
14061		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14062		WRT32_IO_REG(ha, io_base_addr, 0x4020);
14063		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14064		WRT32_IO_REG(ha, io_base_addr, 0x4030);
14065		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14066		WRT32_IO_REG(ha, io_base_addr, 0x4040);
14067		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14068		WRT32_IO_REG(ha, io_base_addr, 0x4050);
14069		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14070		WRT32_IO_REG(ha, io_base_addr, 0x4060);
14071		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14072		WRT32_IO_REG(ha, io_base_addr, 0x4070);
14073		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14074		WRT32_IO_REG(ha, io_base_addr, 0x4080);
14075		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14076		WRT32_IO_REG(ha, io_base_addr, 0x4090);
14077		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14078		WRT32_IO_REG(ha, io_base_addr, 0x40A0);
14079		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14080		WRT32_IO_REG(ha, io_base_addr, 0x40B0);
14081		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14082
14083		/* Frame Buffer registers. */
14084
14085		/* FB hardware */
14086		WRT32_IO_REG(ha, io_base_addr, 0x6000);
14087		bp = ql_read_regs(ha, fw->fb_hdw_reg, ha->iobase + 0xC0,
14088		    16, 32);
14089		WRT32_IO_REG(ha, io_base_addr, 0x6010);
14090		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14091		WRT32_IO_REG(ha, io_base_addr, 0x6020);
14092		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14093		WRT32_IO_REG(ha, io_base_addr, 0x6030);
14094		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14095		WRT32_IO_REG(ha, io_base_addr, 0x6040);
14096		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14097		WRT32_IO_REG(ha, io_base_addr, 0x6100);
14098		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14099		WRT32_IO_REG(ha, io_base_addr, 0x6130);
14100		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14101		WRT32_IO_REG(ha, io_base_addr, 0x6150);
14102		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14103		WRT32_IO_REG(ha, io_base_addr, 0x6170);
14104		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14105		WRT32_IO_REG(ha, io_base_addr, 0x6190);
14106		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14107		WRT32_IO_REG(ha, io_base_addr, 0x61B0);
14108		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14109		WRT32_IO_REG(ha, io_base_addr, 0x6F00);
14110		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14111	}
14112
14113	/* Get the request queue */
14114	if (rval == QL_SUCCESS) {
14115		uint32_t	cnt;
14116		uint32_t	*w32 = (uint32_t *)ha->request_ring_bp;
14117
14118		/* Sync DMA buffer. */
14119		(void) ddi_dma_sync(ha->hba_buf.dma_handle,
14120		    REQUEST_Q_BUFFER_OFFSET, sizeof (fw->req_q),
14121		    DDI_DMA_SYNC_FORKERNEL);
14122
14123		for (cnt = 0; cnt < sizeof (fw->req_q) / 4; cnt++) {
14124			fw->req_q[cnt] = *w32++;
14125			LITTLE_ENDIAN_32(&fw->req_q[cnt]);
14126		}
14127	}
14128
14129	/* Get the respons queue */
14130	if (rval == QL_SUCCESS) {
14131		uint32_t	cnt;
14132		uint32_t	*w32 = (uint32_t *)ha->response_ring_bp;
14133
14134		/* Sync DMA buffer. */
14135		(void) ddi_dma_sync(ha->hba_buf.dma_handle,
14136		    RESPONSE_Q_BUFFER_OFFSET, sizeof (fw->rsp_q),
14137		    DDI_DMA_SYNC_FORKERNEL);
14138
14139		for (cnt = 0; cnt < sizeof (fw->rsp_q) / 4; cnt++) {
14140			fw->rsp_q[cnt] = *w32++;
14141			LITTLE_ENDIAN_32(&fw->rsp_q[cnt]);
14142		}
14143	}
14144
14145	/* Reset RISC. */
14146
14147	ql_reset_chip(ha);
14148
14149	/* Memory. */
14150
14151	if (rval == QL_SUCCESS) {
14152		/* Code RAM. */
14153		rval = ql_read_risc_ram(ha, 0x20000,
14154		    sizeof (fw->code_ram) / 4, fw->code_ram);
14155	}
14156	if (rval == QL_SUCCESS) {
14157		/* External Memory. */
14158		rval = ql_read_risc_ram(ha, 0x100000,
14159		    ha->fw_ext_memory_size / 4, fw->ext_mem);
14160	}
14161
14162	/* Get the FC event trace buffer */
14163	if (rval == QL_SUCCESS) {
14164		if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) &&
14165		    (ha->fwfcetracebuf.bp != NULL)) {
14166			uint32_t	cnt;
14167			uint32_t	*w32 = ha->fwfcetracebuf.bp;
14168
14169			/* Sync DMA buffer. */
14170			(void) ddi_dma_sync(ha->fwfcetracebuf.dma_handle, 0,
14171			    FWFCESIZE, DDI_DMA_SYNC_FORKERNEL);
14172
14173			for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
14174				fw->fce_trace_buf[cnt] = *w32++;
14175			}
14176		}
14177	}
14178
14179	/* Get the extended trace buffer */
14180	if (rval == QL_SUCCESS) {
14181		if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) &&
14182		    (ha->fwexttracebuf.bp != NULL)) {
14183			uint32_t	cnt;
14184			uint32_t	*w32 = ha->fwexttracebuf.bp;
14185
14186			/* Sync DMA buffer. */
14187			(void) ddi_dma_sync(ha->fwexttracebuf.dma_handle, 0,
14188			    FWEXTSIZE, DDI_DMA_SYNC_FORKERNEL);
14189
14190			for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
14191				fw->ext_trace_buf[cnt] = *w32++;
14192			}
14193		}
14194	}
14195
14196	if (rval != QL_SUCCESS) {
14197		EL(ha, "failed=%xh\n", rval);
14198	} else {
14199		/*EMPTY*/
14200		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
14201	}
14202
14203	return (rval);
14204}
14205
14206/*
14207 * ql_81xx_binary_fw_dump
14208 *
14209 * Input:
14210 *	ha:	adapter state pointer.
14211 *	fw:	firmware dump context pointer.
14212 *
14213 * Returns:
14214 *	ql local function return status code.
14215 *
14216 * Context:
14217 *	Interrupt or Kernel context, no mailbox commands allowed.
14218 */
14219static int
14220ql_81xx_binary_fw_dump(ql_adapter_state_t *ha, ql_81xx_fw_dump_t *fw)
14221{
14222	uint32_t	*reg32;
14223	void		*bp;
14224	clock_t		timer;
14225	int		rval = QL_SUCCESS;
14226
14227	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
14228
14229	fw->r2h_status = RD32_IO_REG(ha, intr_info_lo);
14230
14231	/* Pause RISC. */
14232	if ((RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0) {
14233		/* Disable ISP interrupts. */
14234		WRT16_IO_REG(ha, ictrl, 0);
14235
14236		WRT32_IO_REG(ha, hccr, HC24_PAUSE_RISC);
14237		for (timer = 30000;
14238		    (RD32_IO_REG(ha, intr_info_lo) & RH_RISC_PAUSED) == 0 &&
14239		    rval == QL_SUCCESS; timer--) {
14240			if (timer) {
14241				drv_usecwait(100);
14242				if (timer % 10000 == 0) {
14243					EL(ha, "risc pause %d\n", timer);
14244				}
14245			} else {
14246				EL(ha, "risc pause timeout\n");
14247				rval = QL_FUNCTION_TIMEOUT;
14248			}
14249		}
14250	}
14251
14252	if (rval == QL_SUCCESS) {
14253
14254		/* Host Interface registers */
14255
14256		/* HostRisc registers. */
14257		WRT32_IO_REG(ha, io_base_addr, 0x7000);
14258		bp = ql_read_regs(ha, fw->hostrisc_reg, ha->iobase + 0xC0,
14259		    16, 32);
14260		WRT32_IO_REG(ha, io_base_addr, 0x7010);
14261		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14262
14263		/* PCIe registers. */
14264		WRT32_IO_REG(ha, io_base_addr, 0x7c00);
14265		WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x1);
14266		bp = ql_read_regs(ha, fw->pcie_reg, ha->iobase + 0xC4,
14267		    3, 32);
14268		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 1, 32);
14269		WRT_REG_DWORD(ha, ha->iobase + 0xc0, 0x0);
14270
14271		/* Host interface registers. */
14272		(void) ql_read_regs(ha, fw->host_reg, ha->iobase,
14273		    sizeof (fw->host_reg) / 4, 32);
14274
14275		/* Disable ISP interrupts. */
14276
14277		WRT32_IO_REG(ha, ictrl, 0);
14278		RD32_IO_REG(ha, ictrl);
14279		ADAPTER_STATE_LOCK(ha);
14280		ha->flags &= ~INTERRUPTS_ENABLED;
14281		ADAPTER_STATE_UNLOCK(ha);
14282
14283		/* Shadow registers. */
14284
14285		WRT32_IO_REG(ha, io_base_addr, 0x0F70);
14286		RD32_IO_REG(ha, io_base_addr);
14287
14288		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14289		WRT_REG_DWORD(ha, reg32, 0xB0000000);
14290		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14291		fw->shadow_reg[0] = RD_REG_DWORD(ha, reg32);
14292
14293		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14294		WRT_REG_DWORD(ha, reg32, 0xB0100000);
14295		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14296		fw->shadow_reg[1] = RD_REG_DWORD(ha, reg32);
14297
14298		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14299		WRT_REG_DWORD(ha, reg32, 0xB0200000);
14300		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14301		fw->shadow_reg[2] = RD_REG_DWORD(ha, reg32);
14302
14303		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14304		WRT_REG_DWORD(ha, reg32, 0xB0300000);
14305		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14306		fw->shadow_reg[3] = RD_REG_DWORD(ha, reg32);
14307
14308		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14309		WRT_REG_DWORD(ha, reg32, 0xB0400000);
14310		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14311		fw->shadow_reg[4] = RD_REG_DWORD(ha, reg32);
14312
14313		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14314		WRT_REG_DWORD(ha, reg32, 0xB0500000);
14315		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14316		fw->shadow_reg[5] = RD_REG_DWORD(ha, reg32);
14317
14318		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14319		WRT_REG_DWORD(ha, reg32, 0xB0600000);
14320		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14321		fw->shadow_reg[6] = RD_REG_DWORD(ha, reg32);
14322
14323		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14324		WRT_REG_DWORD(ha, reg32, 0xB0700000);
14325		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14326		fw->shadow_reg[7] = RD_REG_DWORD(ha, reg32);
14327
14328		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14329		WRT_REG_DWORD(ha, reg32, 0xB0800000);
14330		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14331		fw->shadow_reg[8] = RD_REG_DWORD(ha, reg32);
14332
14333		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14334		WRT_REG_DWORD(ha, reg32, 0xB0900000);
14335		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14336		fw->shadow_reg[9] = RD_REG_DWORD(ha, reg32);
14337
14338		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xF0);
14339		WRT_REG_DWORD(ha, reg32, 0xB0A00000);
14340		reg32 = (uint32_t *)((caddr_t)ha->iobase + 0xFC);
14341		fw->shadow_reg[0xa] = RD_REG_DWORD(ha, reg32);
14342
14343		/* RISC I/O register. */
14344
14345		WRT32_IO_REG(ha, io_base_addr, 0x0010);
14346		(void) ql_read_regs(ha, &fw->risc_io, ha->iobase + 0xC0,
14347		    1, 32);
14348
14349		/* Mailbox registers. */
14350
14351		(void) ql_read_regs(ha, fw->mailbox_reg, ha->iobase + 0x80,
14352		    sizeof (fw->mailbox_reg) / 2, 16);
14353
14354		/* Transfer sequence registers. */
14355
14356		/* XSEQ GP */
14357		WRT32_IO_REG(ha, io_base_addr, 0xBF00);
14358		bp = ql_read_regs(ha, fw->xseq_gp_reg, ha->iobase + 0xC0,
14359		    16, 32);
14360		WRT32_IO_REG(ha, io_base_addr, 0xBF10);
14361		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14362		WRT32_IO_REG(ha, io_base_addr, 0xBF20);
14363		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14364		WRT32_IO_REG(ha, io_base_addr, 0xBF30);
14365		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14366		WRT32_IO_REG(ha, io_base_addr, 0xBF40);
14367		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14368		WRT32_IO_REG(ha, io_base_addr, 0xBF50);
14369		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14370		WRT32_IO_REG(ha, io_base_addr, 0xBF60);
14371		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14372		WRT32_IO_REG(ha, io_base_addr, 0xBF70);
14373		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14374
14375		/* XSEQ-0 */
14376		WRT32_IO_REG(ha, io_base_addr, 0xBFC0);
14377		bp = ql_read_regs(ha, fw->xseq_0_reg, ha->iobase + 0xC0,
14378		    16, 32);
14379		WRT32_IO_REG(ha, io_base_addr, 0xBFD0);
14380		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14381		WRT32_IO_REG(ha, io_base_addr, 0xBFE0);
14382		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14383
14384		/* XSEQ-1 */
14385		WRT32_IO_REG(ha, io_base_addr, 0xBFF0);
14386		(void) ql_read_regs(ha, fw->xseq_1_reg, ha->iobase + 0xC0,
14387		    16, 32);
14388
14389		/* Receive sequence registers. */
14390
14391		/* RSEQ GP */
14392		WRT32_IO_REG(ha, io_base_addr, 0xFF00);
14393		bp = ql_read_regs(ha, fw->rseq_gp_reg, ha->iobase + 0xC0,
14394		    16, 32);
14395		WRT32_IO_REG(ha, io_base_addr, 0xFF10);
14396		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14397		WRT32_IO_REG(ha, io_base_addr, 0xFF20);
14398		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14399		WRT32_IO_REG(ha, io_base_addr, 0xFF30);
14400		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14401		WRT32_IO_REG(ha, io_base_addr, 0xFF40);
14402		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14403		WRT32_IO_REG(ha, io_base_addr, 0xFF50);
14404		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14405		WRT32_IO_REG(ha, io_base_addr, 0xFF60);
14406		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14407		WRT32_IO_REG(ha, io_base_addr, 0xFF70);
14408		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14409
14410		/* RSEQ-0 */
14411		WRT32_IO_REG(ha, io_base_addr, 0xFFC0);
14412		bp = ql_read_regs(ha, fw->rseq_0_reg, ha->iobase + 0xC0,
14413		    16, 32);
14414		WRT32_IO_REG(ha, io_base_addr, 0xFFD0);
14415		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14416
14417		/* RSEQ-1 */
14418		WRT32_IO_REG(ha, io_base_addr, 0xFFE0);
14419		(void) ql_read_regs(ha, fw->rseq_1_reg, ha->iobase + 0xC0,
14420		    sizeof (fw->rseq_1_reg) / 4, 32);
14421
14422		/* RSEQ-2 */
14423		WRT32_IO_REG(ha, io_base_addr, 0xFFF0);
14424		(void) ql_read_regs(ha, fw->rseq_2_reg, ha->iobase + 0xC0,
14425		    sizeof (fw->rseq_2_reg) / 4, 32);
14426
14427		/* Auxiliary sequencer registers. */
14428
14429		/* ASEQ GP */
14430		WRT32_IO_REG(ha, io_base_addr, 0xB000);
14431		bp = ql_read_regs(ha, fw->aseq_gp_reg, ha->iobase + 0xC0,
14432		    16, 32);
14433		WRT32_IO_REG(ha, io_base_addr, 0xB010);
14434		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14435		WRT32_IO_REG(ha, io_base_addr, 0xB020);
14436		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14437		WRT32_IO_REG(ha, io_base_addr, 0xB030);
14438		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14439		WRT32_IO_REG(ha, io_base_addr, 0xB040);
14440		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14441		WRT32_IO_REG(ha, io_base_addr, 0xB050);
14442		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14443		WRT32_IO_REG(ha, io_base_addr, 0xB060);
14444		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14445		WRT32_IO_REG(ha, io_base_addr, 0xB070);
14446		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14447
14448		/* ASEQ-0 */
14449		WRT32_IO_REG(ha, io_base_addr, 0xB0C0);
14450		bp = ql_read_regs(ha, fw->aseq_0_reg, ha->iobase + 0xC0,
14451		    16, 32);
14452		WRT32_IO_REG(ha, io_base_addr, 0xB0D0);
14453		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14454
14455		/* ASEQ-1 */
14456		WRT32_IO_REG(ha, io_base_addr, 0xB0E0);
14457		(void) ql_read_regs(ha, fw->aseq_1_reg, ha->iobase + 0xC0,
14458		    16, 32);
14459
14460		/* ASEQ-2 */
14461		WRT32_IO_REG(ha, io_base_addr, 0xB0F0);
14462		(void) ql_read_regs(ha, fw->aseq_2_reg, ha->iobase + 0xC0,
14463		    16, 32);
14464
14465		/* Command DMA registers. */
14466
14467		WRT32_IO_REG(ha, io_base_addr, 0x7100);
14468		(void) ql_read_regs(ha, fw->cmd_dma_reg, ha->iobase + 0xC0,
14469		    sizeof (fw->cmd_dma_reg) / 4, 32);
14470
14471		/* Queues. */
14472
14473		/* RequestQ0 */
14474		WRT32_IO_REG(ha, io_base_addr, 0x7200);
14475		bp = ql_read_regs(ha, fw->req0_dma_reg, ha->iobase + 0xC0,
14476		    8, 32);
14477		(void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
14478
14479		/* ResponseQ0 */
14480		WRT32_IO_REG(ha, io_base_addr, 0x7300);
14481		bp = ql_read_regs(ha, fw->resp0_dma_reg, ha->iobase + 0xC0,
14482		    8, 32);
14483		(void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
14484
14485		/* RequestQ1 */
14486		WRT32_IO_REG(ha, io_base_addr, 0x7400);
14487		bp = ql_read_regs(ha, fw->req1_dma_reg, ha->iobase + 0xC0,
14488		    8, 32);
14489		(void) ql_read_regs(ha, bp, ha->iobase + 0xE4, 7, 32);
14490
14491		/* Transmit DMA registers. */
14492
14493		/* XMT0 */
14494		WRT32_IO_REG(ha, io_base_addr, 0x7600);
14495		bp = ql_read_regs(ha, fw->xmt0_dma_reg, ha->iobase + 0xC0,
14496		    16, 32);
14497		WRT32_IO_REG(ha, io_base_addr, 0x7610);
14498		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14499
14500		/* XMT1 */
14501		WRT32_IO_REG(ha, io_base_addr, 0x7620);
14502		bp = ql_read_regs(ha, fw->xmt1_dma_reg, ha->iobase + 0xC0,
14503		    16, 32);
14504		WRT32_IO_REG(ha, io_base_addr, 0x7630);
14505		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14506
14507		/* XMT2 */
14508		WRT32_IO_REG(ha, io_base_addr, 0x7640);
14509		bp = ql_read_regs(ha, fw->xmt2_dma_reg, ha->iobase + 0xC0,
14510		    16, 32);
14511		WRT32_IO_REG(ha, io_base_addr, 0x7650);
14512		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14513
14514		/* XMT3 */
14515		WRT32_IO_REG(ha, io_base_addr, 0x7660);
14516		bp = ql_read_regs(ha, fw->xmt3_dma_reg, ha->iobase + 0xC0,
14517		    16, 32);
14518		WRT32_IO_REG(ha, io_base_addr, 0x7670);
14519		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14520
14521		/* XMT4 */
14522		WRT32_IO_REG(ha, io_base_addr, 0x7680);
14523		bp = ql_read_regs(ha, fw->xmt4_dma_reg, ha->iobase + 0xC0,
14524		    16, 32);
14525		WRT32_IO_REG(ha, io_base_addr, 0x7690);
14526		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14527
14528		/* XMT Common */
14529		WRT32_IO_REG(ha, io_base_addr, 0x76A0);
14530		(void) ql_read_regs(ha, fw->xmt_data_dma_reg,
14531		    ha->iobase + 0xC0, sizeof (fw->xmt_data_dma_reg) / 4, 32);
14532
14533		/* Receive DMA registers. */
14534
14535		/* RCVThread0 */
14536		WRT32_IO_REG(ha, io_base_addr, 0x7700);
14537		bp = ql_read_regs(ha, fw->rcvt0_data_dma_reg,
14538		    ha->iobase + 0xC0, 16, 32);
14539		WRT32_IO_REG(ha, io_base_addr, 0x7710);
14540		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14541
14542		/* RCVThread1 */
14543		WRT32_IO_REG(ha, io_base_addr, 0x7720);
14544		bp = ql_read_regs(ha, fw->rcvt1_data_dma_reg,
14545		    ha->iobase + 0xC0, 16, 32);
14546		WRT32_IO_REG(ha, io_base_addr, 0x7730);
14547		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14548
14549		/* RISC registers. */
14550
14551		/* RISC GP */
14552		WRT32_IO_REG(ha, io_base_addr, 0x0F00);
14553		bp = ql_read_regs(ha, fw->risc_gp_reg, ha->iobase + 0xC0,
14554		    16, 32);
14555		WRT32_IO_REG(ha, io_base_addr, 0x0F10);
14556		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14557		WRT32_IO_REG(ha, io_base_addr, 0x0F20);
14558		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14559		WRT32_IO_REG(ha, io_base_addr, 0x0F30);
14560		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14561		WRT32_IO_REG(ha, io_base_addr, 0x0F40);
14562		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14563		WRT32_IO_REG(ha, io_base_addr, 0x0F50);
14564		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14565		WRT32_IO_REG(ha, io_base_addr, 0x0F60);
14566		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14567		WRT32_IO_REG(ha, io_base_addr, 0x0F70);
14568		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14569
14570		/* Local memory controller (LMC) registers. */
14571
14572		/* LMC */
14573		WRT32_IO_REG(ha, io_base_addr, 0x3000);
14574		bp = ql_read_regs(ha, fw->lmc_reg, ha->iobase + 0xC0,
14575		    16, 32);
14576		WRT32_IO_REG(ha, io_base_addr, 0x3010);
14577		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14578		WRT32_IO_REG(ha, io_base_addr, 0x3020);
14579		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14580		WRT32_IO_REG(ha, io_base_addr, 0x3030);
14581		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14582		WRT32_IO_REG(ha, io_base_addr, 0x3040);
14583		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14584		WRT32_IO_REG(ha, io_base_addr, 0x3050);
14585		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14586		WRT32_IO_REG(ha, io_base_addr, 0x3060);
14587		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14588		WRT32_IO_REG(ha, io_base_addr, 0x3070);
14589		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14590
14591		/* Fibre Protocol Module registers. */
14592
14593		/* FPM hardware */
14594		WRT32_IO_REG(ha, io_base_addr, 0x4000);
14595		bp = ql_read_regs(ha, fw->fpm_hdw_reg, ha->iobase + 0xC0,
14596		    16, 32);
14597		WRT32_IO_REG(ha, io_base_addr, 0x4010);
14598		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14599		WRT32_IO_REG(ha, io_base_addr, 0x4020);
14600		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14601		WRT32_IO_REG(ha, io_base_addr, 0x4030);
14602		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14603		WRT32_IO_REG(ha, io_base_addr, 0x4040);
14604		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14605		WRT32_IO_REG(ha, io_base_addr, 0x4050);
14606		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14607		WRT32_IO_REG(ha, io_base_addr, 0x4060);
14608		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14609		WRT32_IO_REG(ha, io_base_addr, 0x4070);
14610		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14611		WRT32_IO_REG(ha, io_base_addr, 0x4080);
14612		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14613		WRT32_IO_REG(ha, io_base_addr, 0x4090);
14614		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14615		WRT32_IO_REG(ha, io_base_addr, 0x40A0);
14616		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14617		WRT32_IO_REG(ha, io_base_addr, 0x40B0);
14618		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14619		WRT32_IO_REG(ha, io_base_addr, 0x40C0);
14620		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14621		WRT32_IO_REG(ha, io_base_addr, 0x40D0);
14622		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14623
14624		/* Frame Buffer registers. */
14625
14626		/* FB hardware */
14627		WRT32_IO_REG(ha, io_base_addr, 0x6000);
14628		bp = ql_read_regs(ha, fw->fb_hdw_reg, ha->iobase + 0xC0,
14629		    16, 32);
14630		WRT32_IO_REG(ha, io_base_addr, 0x6010);
14631		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14632		WRT32_IO_REG(ha, io_base_addr, 0x6020);
14633		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14634		WRT32_IO_REG(ha, io_base_addr, 0x6030);
14635		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14636		WRT32_IO_REG(ha, io_base_addr, 0x6040);
14637		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14638		WRT32_IO_REG(ha, io_base_addr, 0x6100);
14639		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14640		WRT32_IO_REG(ha, io_base_addr, 0x6130);
14641		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14642		WRT32_IO_REG(ha, io_base_addr, 0x6150);
14643		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14644		WRT32_IO_REG(ha, io_base_addr, 0x6170);
14645		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14646		WRT32_IO_REG(ha, io_base_addr, 0x6190);
14647		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14648		WRT32_IO_REG(ha, io_base_addr, 0x61B0);
14649		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14650		WRT32_IO_REG(ha, io_base_addr, 0x61C0);
14651		bp = ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14652		WRT32_IO_REG(ha, io_base_addr, 0x6F00);
14653		(void) ql_read_regs(ha, bp, ha->iobase + 0xC0, 16, 32);
14654	}
14655
14656	/* Get the request queue */
14657	if (rval == QL_SUCCESS) {
14658		uint32_t	cnt;
14659		uint32_t	*w32 = (uint32_t *)ha->request_ring_bp;
14660
14661		/* Sync DMA buffer. */
14662		(void) ddi_dma_sync(ha->hba_buf.dma_handle,
14663		    REQUEST_Q_BUFFER_OFFSET, sizeof (fw->req_q),
14664		    DDI_DMA_SYNC_FORKERNEL);
14665
14666		for (cnt = 0; cnt < sizeof (fw->req_q) / 4; cnt++) {
14667			fw->req_q[cnt] = *w32++;
14668			LITTLE_ENDIAN_32(&fw->req_q[cnt]);
14669		}
14670	}
14671
14672	/* Get the respons queue */
14673	if (rval == QL_SUCCESS) {
14674		uint32_t	cnt;
14675		uint32_t	*w32 = (uint32_t *)ha->response_ring_bp;
14676
14677		/* Sync DMA buffer. */
14678		(void) ddi_dma_sync(ha->hba_buf.dma_handle,
14679		    RESPONSE_Q_BUFFER_OFFSET, sizeof (fw->rsp_q),
14680		    DDI_DMA_SYNC_FORKERNEL);
14681
14682		for (cnt = 0; cnt < sizeof (fw->rsp_q) / 4; cnt++) {
14683			fw->rsp_q[cnt] = *w32++;
14684			LITTLE_ENDIAN_32(&fw->rsp_q[cnt]);
14685		}
14686	}
14687
14688	/* Reset RISC. */
14689
14690	ql_reset_chip(ha);
14691
14692	/* Memory. */
14693
14694	if (rval == QL_SUCCESS) {
14695		/* Code RAM. */
14696		rval = ql_read_risc_ram(ha, 0x20000,
14697		    sizeof (fw->code_ram) / 4, fw->code_ram);
14698	}
14699	if (rval == QL_SUCCESS) {
14700		/* External Memory. */
14701		rval = ql_read_risc_ram(ha, 0x100000,
14702		    ha->fw_ext_memory_size / 4, fw->ext_mem);
14703	}
14704
14705	/* Get the FC event trace buffer */
14706	if (rval == QL_SUCCESS) {
14707		if (CFG_IST(ha, CFG_ENABLE_FWFCETRACE) &&
14708		    (ha->fwfcetracebuf.bp != NULL)) {
14709			uint32_t	cnt;
14710			uint32_t	*w32 = ha->fwfcetracebuf.bp;
14711
14712			/* Sync DMA buffer. */
14713			(void) ddi_dma_sync(ha->fwfcetracebuf.dma_handle, 0,
14714			    FWFCESIZE, DDI_DMA_SYNC_FORKERNEL);
14715
14716			for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
14717				fw->fce_trace_buf[cnt] = *w32++;
14718			}
14719		}
14720	}
14721
14722	/* Get the extended trace buffer */
14723	if (rval == QL_SUCCESS) {
14724		if (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE) &&
14725		    (ha->fwexttracebuf.bp != NULL)) {
14726			uint32_t	cnt;
14727			uint32_t	*w32 = ha->fwexttracebuf.bp;
14728
14729			/* Sync DMA buffer. */
14730			(void) ddi_dma_sync(ha->fwexttracebuf.dma_handle, 0,
14731			    FWEXTSIZE, DDI_DMA_SYNC_FORKERNEL);
14732
14733			for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
14734				fw->ext_trace_buf[cnt] = *w32++;
14735			}
14736		}
14737	}
14738
14739	if (rval != QL_SUCCESS) {
14740		EL(ha, "failed=%xh\n", rval);
14741	} else {
14742		/*EMPTY*/
14743		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
14744	}
14745
14746	return (rval);
14747}
14748
14749/*
14750 * ql_read_risc_ram
14751 *	Reads RISC RAM one word at a time.
14752 *	Risc interrupts must be disabled when this routine is called.
14753 *
14754 * Input:
14755 *	ha:	adapter state pointer.
14756 *	risc_address:	RISC code start address.
14757 *	len:		Number of words.
14758 *	buf:		buffer pointer.
14759 *
14760 * Returns:
14761 *	ql local function return status code.
14762 *
14763 * Context:
14764 *	Interrupt or Kernel context, no mailbox commands allowed.
14765 */
14766static int
14767ql_read_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint32_t len,
14768    void *buf)
14769{
14770	uint32_t	cnt;
14771	uint16_t	stat;
14772	clock_t		timer;
14773	uint16_t	*buf16 = (uint16_t *)buf;
14774	uint32_t	*buf32 = (uint32_t *)buf;
14775	int		rval = QL_SUCCESS;
14776
14777	for (cnt = 0; cnt < len; cnt++, risc_address++) {
14778		WRT16_IO_REG(ha, mailbox[0], MBC_READ_RAM_EXTENDED);
14779		WRT16_IO_REG(ha, mailbox[1], LSW(risc_address));
14780		WRT16_IO_REG(ha, mailbox[8], MSW(risc_address));
14781		CFG_IST(ha, CFG_CTRL_242581) ?
14782		    WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT) :
14783		    WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT);
14784		for (timer = 6000000; timer && rval == QL_SUCCESS; timer--) {
14785			if (RD16_IO_REG(ha, istatus) & RISC_INT) {
14786				stat = (uint16_t)
14787				    (RD16_IO_REG(ha, intr_info_lo) & 0xff);
14788				if ((stat == 1) || (stat == 0x10)) {
14789					if (CFG_IST(ha, CFG_CTRL_242581)) {
14790						buf32[cnt] = SHORT_TO_LONG(
14791						    RD16_IO_REG(ha,
14792						    mailbox[2]),
14793						    RD16_IO_REG(ha,
14794						    mailbox[3]));
14795					} else {
14796						buf16[cnt] =
14797						    RD16_IO_REG(ha, mailbox[2]);
14798					}
14799
14800					break;
14801				} else if ((stat == 2) || (stat == 0x11)) {
14802					rval = RD16_IO_REG(ha, mailbox[0]);
14803					break;
14804				}
14805				if (CFG_IST(ha, CFG_CTRL_242581)) {
14806					WRT32_IO_REG(ha, hccr,
14807					    HC24_CLR_RISC_INT);
14808					RD32_IO_REG(ha, hccr);
14809				} else {
14810					WRT16_IO_REG(ha, hccr,
14811					    HC_CLR_RISC_INT);
14812				}
14813			}
14814			drv_usecwait(5);
14815		}
14816		if (CFG_IST(ha, CFG_CTRL_242581)) {
14817			WRT32_IO_REG(ha, hccr, HC24_CLR_RISC_INT);
14818			RD32_IO_REG(ha, hccr);
14819		} else {
14820			WRT16_IO_REG(ha, hccr, HC_CLR_RISC_INT);
14821			WRT16_IO_REG(ha, semaphore, 0);
14822		}
14823
14824		if (timer == 0) {
14825			rval = QL_FUNCTION_TIMEOUT;
14826		}
14827	}
14828
14829	return (rval);
14830}
14831
14832/*
14833 * ql_read_regs
14834 *	Reads adapter registers to buffer.
14835 *
14836 * Input:
14837 *	ha:	adapter state pointer.
14838 *	buf:	buffer pointer.
14839 *	reg:	start address.
14840 *	count:	number of registers.
14841 *	wds:	register size.
14842 *
14843 * Context:
14844 *	Interrupt or Kernel context, no mailbox commands allowed.
14845 */
14846static void *
14847ql_read_regs(ql_adapter_state_t *ha, void *buf, void *reg, uint32_t count,
14848    uint8_t wds)
14849{
14850	uint32_t	*bp32, *reg32;
14851	uint16_t	*bp16, *reg16;
14852	uint8_t		*bp8, *reg8;
14853
14854	switch (wds) {
14855	case 32:
14856		bp32 = buf;
14857		reg32 = reg;
14858		while (count--) {
14859			*bp32++ = RD_REG_DWORD(ha, reg32++);
14860		}
14861		return (bp32);
14862	case 16:
14863		bp16 = buf;
14864		reg16 = reg;
14865		while (count--) {
14866			*bp16++ = RD_REG_WORD(ha, reg16++);
14867		}
14868		return (bp16);
14869	case 8:
14870		bp8 = buf;
14871		reg8 = reg;
14872		while (count--) {
14873			*bp8++ = RD_REG_BYTE(ha, reg8++);
14874		}
14875		return (bp8);
14876	default:
14877		EL(ha, "Unknown word size=%d\n", wds);
14878		return (buf);
14879	}
14880}
14881
14882static int
14883ql_save_config_regs(dev_info_t *dip)
14884{
14885	ql_adapter_state_t	*ha;
14886	int			ret;
14887	ql_config_space_t	chs;
14888	caddr_t			prop = "ql-config-space";
14889
14890	ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
14891	if (ha == NULL) {
14892		QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
14893		    ddi_get_instance(dip));
14894		return (DDI_FAILURE);
14895	}
14896
14897	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
14898
14899	/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
14900	if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, prop) ==
14901	    1) {
14902		QL_PRINT_2(CE_CONT, "(%d): no prop exit\n", ha->instance);
14903		return (DDI_SUCCESS);
14904	}
14905
14906	chs.chs_command = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM);
14907	chs.chs_header_type = (uint8_t)ql_pci_config_get8(ha,
14908	    PCI_CONF_HEADER);
14909	if ((chs.chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
14910		chs.chs_bridge_control = (uint8_t)ql_pci_config_get8(ha,
14911		    PCI_BCNF_BCNTRL);
14912	}
14913
14914	chs.chs_cache_line_size = (uint8_t)ql_pci_config_get8(ha,
14915	    PCI_CONF_CACHE_LINESZ);
14916
14917	chs.chs_latency_timer = (uint8_t)ql_pci_config_get8(ha,
14918	    PCI_CONF_LATENCY_TIMER);
14919
14920	if ((chs.chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
14921		chs.chs_sec_latency_timer = (uint8_t)ql_pci_config_get8(ha,
14922		    PCI_BCNF_LATENCY_TIMER);
14923	}
14924
14925	chs.chs_base0 = ql_pci_config_get32(ha, PCI_CONF_BASE0);
14926	chs.chs_base1 = ql_pci_config_get32(ha, PCI_CONF_BASE1);
14927	chs.chs_base2 = ql_pci_config_get32(ha, PCI_CONF_BASE2);
14928	chs.chs_base3 = ql_pci_config_get32(ha, PCI_CONF_BASE3);
14929	chs.chs_base4 = ql_pci_config_get32(ha, PCI_CONF_BASE4);
14930	chs.chs_base5 = ql_pci_config_get32(ha, PCI_CONF_BASE5);
14931
14932	/*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/
14933	ret = ndi_prop_update_byte_array(DDI_DEV_T_NONE, dip, prop,
14934	    (uchar_t *)&chs, sizeof (ql_config_space_t));
14935
14936	if (ret != DDI_PROP_SUCCESS) {
14937		cmn_err(CE_WARN, "!Qlogic %s(%d) can't update prop %s",
14938		    QL_NAME, ddi_get_instance(dip), prop);
14939		return (DDI_FAILURE);
14940	}
14941
14942	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
14943
14944	return (DDI_SUCCESS);
14945}
14946
14947static int
14948ql_restore_config_regs(dev_info_t *dip)
14949{
14950	ql_adapter_state_t	*ha;
14951	uint_t			elements;
14952	ql_config_space_t	*chs_p;
14953	caddr_t			prop = "ql-config-space";
14954
14955	ha = ddi_get_soft_state(ql_state, ddi_get_instance(dip));
14956	if (ha == NULL) {
14957		QL_PRINT_2(CE_CONT, "(%d): no adapter\n",
14958		    ddi_get_instance(dip));
14959		return (DDI_FAILURE);
14960	}
14961
14962	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
14963
14964	/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
14965	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip,
14966	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, prop,
14967	    (uchar_t **)&chs_p, &elements) != DDI_PROP_SUCCESS) {
14968		QL_PRINT_2(CE_CONT, "(%d): no prop exit\n", ha->instance);
14969		return (DDI_FAILURE);
14970	}
14971
14972	ql_pci_config_put16(ha, PCI_CONF_COMM, chs_p->chs_command);
14973
14974	if ((chs_p->chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
14975		ql_pci_config_put16(ha, PCI_BCNF_BCNTRL,
14976		    chs_p->chs_bridge_control);
14977	}
14978
14979	ql_pci_config_put8(ha, PCI_CONF_CACHE_LINESZ,
14980	    chs_p->chs_cache_line_size);
14981
14982	ql_pci_config_put8(ha, PCI_CONF_LATENCY_TIMER,
14983	    chs_p->chs_latency_timer);
14984
14985	if ((chs_p->chs_header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
14986		ql_pci_config_put8(ha, PCI_BCNF_LATENCY_TIMER,
14987		    chs_p->chs_sec_latency_timer);
14988	}
14989
14990	ql_pci_config_put32(ha, PCI_CONF_BASE0, chs_p->chs_base0);
14991	ql_pci_config_put32(ha, PCI_CONF_BASE1, chs_p->chs_base1);
14992	ql_pci_config_put32(ha, PCI_CONF_BASE2, chs_p->chs_base2);
14993	ql_pci_config_put32(ha, PCI_CONF_BASE3, chs_p->chs_base3);
14994	ql_pci_config_put32(ha, PCI_CONF_BASE4, chs_p->chs_base4);
14995	ql_pci_config_put32(ha, PCI_CONF_BASE5, chs_p->chs_base5);
14996
14997	ddi_prop_free(chs_p);
14998
14999	/*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/
15000	if (ndi_prop_remove(DDI_DEV_T_NONE, dip, prop) != DDI_PROP_SUCCESS) {
15001		cmn_err(CE_WARN, "!Qlogic %s(%d): can't remove prop %s",
15002		    QL_NAME, ddi_get_instance(dip), prop);
15003	}
15004
15005	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15006
15007	return (DDI_SUCCESS);
15008}
15009
15010uint8_t
15011ql_pci_config_get8(ql_adapter_state_t *ha, off_t off)
15012{
15013	if (CFG_IST(ha, CFG_SBUS_CARD)) {
15014		return (ddi_get8(ha->sbus_config_handle,
15015		    (uint8_t *)(ha->sbus_config_base + off)));
15016	}
15017
15018#ifdef KERNEL_32
15019	return (pci_config_getb(ha->pci_handle, off));
15020#else
15021	return (pci_config_get8(ha->pci_handle, off));
15022#endif
15023}
15024
15025uint16_t
15026ql_pci_config_get16(ql_adapter_state_t *ha, off_t off)
15027{
15028	if (CFG_IST(ha, CFG_SBUS_CARD)) {
15029		return (ddi_get16(ha->sbus_config_handle,
15030		    (uint16_t *)(ha->sbus_config_base + off)));
15031	}
15032
15033#ifdef KERNEL_32
15034	return (pci_config_getw(ha->pci_handle, off));
15035#else
15036	return (pci_config_get16(ha->pci_handle, off));
15037#endif
15038}
15039
15040uint32_t
15041ql_pci_config_get32(ql_adapter_state_t *ha, off_t off)
15042{
15043	if (CFG_IST(ha, CFG_SBUS_CARD)) {
15044		return (ddi_get32(ha->sbus_config_handle,
15045		    (uint32_t *)(ha->sbus_config_base + off)));
15046	}
15047
15048#ifdef KERNEL_32
15049	return (pci_config_getl(ha->pci_handle, off));
15050#else
15051	return (pci_config_get32(ha->pci_handle, off));
15052#endif
15053}
15054
15055void
15056ql_pci_config_put8(ql_adapter_state_t *ha, off_t off, uint8_t val)
15057{
15058	if (CFG_IST(ha, CFG_SBUS_CARD)) {
15059		ddi_put8(ha->sbus_config_handle,
15060		    (uint8_t *)(ha->sbus_config_base + off), val);
15061	} else {
15062#ifdef KERNEL_32
15063		pci_config_putb(ha->pci_handle, off, val);
15064#else
15065		pci_config_put8(ha->pci_handle, off, val);
15066#endif
15067	}
15068}
15069
15070void
15071ql_pci_config_put16(ql_adapter_state_t *ha, off_t off, uint16_t val)
15072{
15073	if (CFG_IST(ha, CFG_SBUS_CARD)) {
15074		ddi_put16(ha->sbus_config_handle,
15075		    (uint16_t *)(ha->sbus_config_base + off), val);
15076	} else {
15077#ifdef KERNEL_32
15078		pci_config_putw(ha->pci_handle, off, val);
15079#else
15080		pci_config_put16(ha->pci_handle, off, val);
15081#endif
15082	}
15083}
15084
15085void
15086ql_pci_config_put32(ql_adapter_state_t *ha, off_t off, uint32_t val)
15087{
15088	if (CFG_IST(ha, CFG_SBUS_CARD)) {
15089		ddi_put32(ha->sbus_config_handle,
15090		    (uint32_t *)(ha->sbus_config_base + off), val);
15091	} else {
15092#ifdef KERNEL_32
15093		pci_config_putl(ha->pci_handle, off, val);
15094#else
15095		pci_config_put32(ha->pci_handle, off, val);
15096#endif
15097	}
15098}
15099
15100/*
15101 * ql_halt
15102 *	Waits for commands that are running to finish and
15103 *	if they do not, commands are aborted.
15104 *	Finally the adapter is reset.
15105 *
15106 * Input:
15107 *	ha:	adapter state pointer.
15108 *	pwr:	power state.
15109 *
15110 * Context:
15111 *	Kernel context.
15112 */
15113static void
15114ql_halt(ql_adapter_state_t *ha, int pwr)
15115{
15116	uint32_t	cnt;
15117	ql_tgt_t	*tq;
15118	ql_srb_t	*sp;
15119	uint16_t	index;
15120	ql_link_t	*link;
15121
15122	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15123
15124	/* Wait for all commands running to finish. */
15125	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
15126		for (link = ha->dev[index].first; link != NULL;
15127		    link = link->next) {
15128			tq = link->base_address;
15129			(void) ql_abort_device(ha, tq, 0);
15130
15131			/* Wait for 30 seconds for commands to finish. */
15132			for (cnt = 3000; cnt != 0; cnt--) {
15133				/* Acquire device queue lock. */
15134				DEVICE_QUEUE_LOCK(tq);
15135				if (tq->outcnt == 0) {
15136					/* Release device queue lock. */
15137					DEVICE_QUEUE_UNLOCK(tq);
15138					break;
15139				} else {
15140					/* Release device queue lock. */
15141					DEVICE_QUEUE_UNLOCK(tq);
15142					ql_delay(ha, 10000);
15143				}
15144			}
15145
15146			/* Finish any commands waiting for more status. */
15147			if (ha->status_srb != NULL) {
15148				sp = ha->status_srb;
15149				ha->status_srb = NULL;
15150				sp->cmd.next = NULL;
15151				ql_done(&sp->cmd);
15152			}
15153
15154			/* Abort commands that did not finish. */
15155			if (cnt == 0) {
15156				for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS;
15157				    cnt++) {
15158					if (ha->pending_cmds.first != NULL) {
15159						ql_start_iocb(ha, NULL);
15160						cnt = 1;
15161					}
15162					sp = ha->outstanding_cmds[cnt];
15163					if (sp != NULL &&
15164					    sp->lun_queue->target_queue ==
15165					    tq) {
15166						(void) ql_abort((opaque_t)ha,
15167						    sp->pkt, 0);
15168					}
15169				}
15170			}
15171		}
15172	}
15173
15174	/* Shutdown IP. */
15175	if (ha->flags & IP_INITIALIZED) {
15176		(void) ql_shutdown_ip(ha);
15177	}
15178
15179	/* Stop all timers. */
15180	ADAPTER_STATE_LOCK(ha);
15181	ha->port_retry_timer = 0;
15182	ha->loop_down_timer = LOOP_DOWN_TIMER_OFF;
15183	ha->watchdog_timer = 0;
15184	ADAPTER_STATE_UNLOCK(ha);
15185
15186	if (pwr == PM_LEVEL_D3) {
15187		ADAPTER_STATE_LOCK(ha);
15188		ha->flags &= ~ONLINE;
15189		ADAPTER_STATE_UNLOCK(ha);
15190
15191		/* Reset ISP chip. */
15192		ql_reset_chip(ha);
15193	}
15194
15195	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15196}
15197
15198/*
15199 * ql_get_dma_mem
15200 *	Function used to allocate dma memory.
15201 *
15202 * Input:
15203 *	ha:			adapter state pointer.
15204 *	mem:			pointer to dma memory object.
15205 *	size:			size of the request in bytes
15206 *
15207 * Returns:
15208 *	qn local function return status code.
15209 *
15210 * Context:
15211 *	Kernel context.
15212 */
15213int
15214ql_get_dma_mem(ql_adapter_state_t *ha, dma_mem_t *mem, uint32_t size,
15215    mem_alloc_type_t allocation_type, mem_alignment_t alignment)
15216{
15217	int	rval;
15218
15219	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15220
15221	mem->size = size;
15222	mem->type = allocation_type;
15223	mem->cookie_count = 1;
15224
15225	switch (alignment) {
15226	case QL_DMA_DATA_ALIGN:
15227		mem->alignment = QL_DMA_ALIGN_8_BYTE_BOUNDARY;
15228		break;
15229	case QL_DMA_RING_ALIGN:
15230		mem->alignment = QL_DMA_ALIGN_64_BYTE_BOUNDARY;
15231		break;
15232	default:
15233		EL(ha, "failed, unknown alignment type %x\n", alignment);
15234		break;
15235	}
15236
15237	if ((rval = ql_alloc_phys(ha, mem, KM_SLEEP)) != QL_SUCCESS) {
15238		ql_free_phys(ha, mem);
15239		EL(ha, "failed, alloc_phys=%xh\n", rval);
15240	}
15241
15242	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15243
15244	return (rval);
15245}
15246
15247/*
15248 * ql_alloc_phys
15249 *	Function used to allocate memory and zero it.
15250 *	Memory is below 4 GB.
15251 *
15252 * Input:
15253 *	ha:			adapter state pointer.
15254 *	mem:			pointer to dma memory object.
15255 *	sleep:			KM_SLEEP/KM_NOSLEEP flag.
15256 *	mem->cookie_count	number of segments allowed.
15257 *	mem->type		memory allocation type.
15258 *	mem->size		memory size.
15259 *	mem->alignment		memory alignment.
15260 *
15261 * Returns:
15262 *	qn local function return status code.
15263 *
15264 * Context:
15265 *	Kernel context.
15266 */
15267int
15268ql_alloc_phys(ql_adapter_state_t *ha, dma_mem_t *mem, int sleep)
15269{
15270	size_t			rlen;
15271	ddi_dma_attr_t		dma_attr;
15272	ddi_device_acc_attr_t	acc_attr = ql_dev_acc_attr;
15273
15274	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15275
15276	dma_attr = CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING) ?
15277	    ql_64bit_io_dma_attr : ql_32bit_io_dma_attr;
15278
15279	dma_attr.dma_attr_align = mem->alignment; /* DMA address alignment */
15280	dma_attr.dma_attr_sgllen = (int)mem->cookie_count;
15281
15282	/*
15283	 * Workaround for SUN XMITS buffer must end and start on 8 byte
15284	 * boundary. Else, hardware will overrun the buffer. Simple fix is
15285	 * to make sure buffer has enough room for overrun.
15286	 */
15287	if (mem->size & 7) {
15288		mem->size += 8 - (mem->size & 7);
15289	}
15290
15291	mem->flags = DDI_DMA_CONSISTENT;
15292
15293	/*
15294	 * Allocate DMA memory for command.
15295	 */
15296	if (ddi_dma_alloc_handle(ha->dip, &dma_attr, (sleep == KM_SLEEP) ?
15297	    DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &mem->dma_handle) !=
15298	    DDI_SUCCESS) {
15299		EL(ha, "failed, ddi_dma_alloc_handle\n");
15300		mem->dma_handle = NULL;
15301		return (QL_MEMORY_ALLOC_FAILED);
15302	}
15303
15304	switch (mem->type) {
15305	case KERNEL_MEM:
15306		mem->bp = kmem_zalloc(mem->size, sleep);
15307		break;
15308	case BIG_ENDIAN_DMA:
15309	case LITTLE_ENDIAN_DMA:
15310	case NO_SWAP_DMA:
15311		if (mem->type == BIG_ENDIAN_DMA) {
15312			acc_attr.devacc_attr_endian_flags =
15313			    DDI_STRUCTURE_BE_ACC;
15314		} else if (mem->type == NO_SWAP_DMA) {
15315			acc_attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
15316		}
15317		if (ddi_dma_mem_alloc(mem->dma_handle, mem->size, &acc_attr,
15318		    mem->flags, (sleep == KM_SLEEP) ? DDI_DMA_SLEEP :
15319		    DDI_DMA_DONTWAIT, NULL, (caddr_t *)&mem->bp, &rlen,
15320		    &mem->acc_handle) == DDI_SUCCESS) {
15321			bzero(mem->bp, mem->size);
15322			/* ensure we got what we asked for (32bit) */
15323			if (dma_attr.dma_attr_addr_hi == NULL) {
15324				if (mem->cookie.dmac_notused != NULL) {
15325					EL(ha, "failed, ddi_dma_mem_alloc "
15326					    "returned 64 bit DMA address\n");
15327					ql_free_phys(ha, mem);
15328					return (QL_MEMORY_ALLOC_FAILED);
15329				}
15330			}
15331		} else {
15332			mem->acc_handle = NULL;
15333			mem->bp = NULL;
15334		}
15335		break;
15336	default:
15337		EL(ha, "failed, unknown type=%xh\n", mem->type);
15338		mem->acc_handle = NULL;
15339		mem->bp = NULL;
15340		break;
15341	}
15342
15343	if (mem->bp == NULL) {
15344		EL(ha, "failed, ddi_dma_mem_alloc\n");
15345		ddi_dma_free_handle(&mem->dma_handle);
15346		mem->dma_handle = NULL;
15347		return (QL_MEMORY_ALLOC_FAILED);
15348	}
15349
15350	mem->flags |= DDI_DMA_RDWR;
15351
15352	if (ql_bind_dma_buffer(ha, mem, sleep) != DDI_DMA_MAPPED) {
15353		EL(ha, "failed, ddi_dma_addr_bind_handle\n");
15354		ql_free_phys(ha, mem);
15355		return (QL_MEMORY_ALLOC_FAILED);
15356	}
15357
15358	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15359
15360	return (QL_SUCCESS);
15361}
15362
15363/*
15364 * ql_free_phys
15365 *	Function used to free physical memory.
15366 *
15367 * Input:
15368 *	ha:	adapter state pointer.
15369 *	mem:	pointer to dma memory object.
15370 *
15371 * Context:
15372 *	Kernel context.
15373 */
15374void
15375ql_free_phys(ql_adapter_state_t *ha, dma_mem_t *mem)
15376{
15377	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15378
15379	if (mem != NULL && mem->dma_handle != NULL) {
15380		ql_unbind_dma_buffer(ha, mem);
15381		switch (mem->type) {
15382		case KERNEL_MEM:
15383			if (mem->bp != NULL) {
15384				kmem_free(mem->bp, mem->size);
15385			}
15386			break;
15387		case LITTLE_ENDIAN_DMA:
15388		case BIG_ENDIAN_DMA:
15389		case NO_SWAP_DMA:
15390			if (mem->acc_handle != NULL) {
15391				ddi_dma_mem_free(&mem->acc_handle);
15392				mem->acc_handle = NULL;
15393			}
15394			break;
15395		default:
15396			break;
15397		}
15398		mem->bp = NULL;
15399		ddi_dma_free_handle(&mem->dma_handle);
15400		mem->dma_handle = NULL;
15401	}
15402
15403	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15404}
15405
15406/*
15407 * ql_alloc_dma_resouce.
15408 *	Allocates DMA resource for buffer.
15409 *
15410 * Input:
15411 *	ha:			adapter state pointer.
15412 *	mem:			pointer to dma memory object.
15413 *	sleep:			KM_SLEEP/KM_NOSLEEP flag.
15414 *	mem->cookie_count	number of segments allowed.
15415 *	mem->type		memory allocation type.
15416 *	mem->size		memory size.
15417 *	mem->bp			pointer to memory or struct buf
15418 *
15419 * Returns:
15420 *	qn local function return status code.
15421 *
15422 * Context:
15423 *	Kernel context.
15424 */
15425int
15426ql_alloc_dma_resouce(ql_adapter_state_t *ha, dma_mem_t *mem, int sleep)
15427{
15428	ddi_dma_attr_t	dma_attr;
15429
15430	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15431
15432	dma_attr = CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING) ?
15433	    ql_64bit_io_dma_attr : ql_32bit_io_dma_attr;
15434	dma_attr.dma_attr_sgllen = (int)mem->cookie_count;
15435
15436	/*
15437	 * Allocate DMA handle for command.
15438	 */
15439	if (ddi_dma_alloc_handle(ha->dip, &dma_attr, (sleep == KM_SLEEP) ?
15440	    DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &mem->dma_handle) !=
15441	    DDI_SUCCESS) {
15442		EL(ha, "failed, ddi_dma_alloc_handle\n");
15443		mem->dma_handle = NULL;
15444		return (QL_MEMORY_ALLOC_FAILED);
15445	}
15446
15447	mem->flags = DDI_DMA_RDWR | DDI_DMA_CONSISTENT;
15448
15449	if (ql_bind_dma_buffer(ha, mem, sleep) != DDI_DMA_MAPPED) {
15450		EL(ha, "failed, bind_dma_buffer\n");
15451		ddi_dma_free_handle(&mem->dma_handle);
15452		mem->dma_handle = NULL;
15453		return (QL_MEMORY_ALLOC_FAILED);
15454	}
15455
15456	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15457
15458	return (QL_SUCCESS);
15459}
15460
15461/*
15462 * ql_free_dma_resource
15463 *	Frees DMA resources.
15464 *
15465 * Input:
15466 *	ha:		adapter state pointer.
15467 *	mem:		pointer to dma memory object.
15468 *	mem->dma_handle	DMA memory handle.
15469 *
15470 * Context:
15471 *	Kernel context.
15472 */
15473void
15474ql_free_dma_resource(ql_adapter_state_t *ha, dma_mem_t *mem)
15475{
15476	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15477
15478	ql_free_phys(ha, mem);
15479
15480	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15481}
15482
15483/*
15484 * ql_bind_dma_buffer
15485 *	Binds DMA buffer.
15486 *
15487 * Input:
15488 *	ha:			adapter state pointer.
15489 *	mem:			pointer to dma memory object.
15490 *	sleep:			KM_SLEEP or KM_NOSLEEP.
15491 *	mem->dma_handle		DMA memory handle.
15492 *	mem->cookie_count	number of segments allowed.
15493 *	mem->type		memory allocation type.
15494 *	mem->size		memory size.
15495 *	mem->bp			pointer to memory or struct buf
15496 *
15497 * Returns:
15498 *	mem->cookies		pointer to list of cookies.
15499 *	mem->cookie_count	number of cookies.
15500 *	status			success = DDI_DMA_MAPPED
15501 *				DDI_DMA_PARTIAL_MAP, DDI_DMA_INUSE,
15502 *				DDI_DMA_NORESOURCES, DDI_DMA_NOMAPPING or
15503 *				DDI_DMA_TOOBIG
15504 *
15505 * Context:
15506 *	Kernel context.
15507 */
15508static int
15509ql_bind_dma_buffer(ql_adapter_state_t *ha, dma_mem_t *mem, int sleep)
15510{
15511	int			rval;
15512	ddi_dma_cookie_t	*cookiep;
15513	uint32_t		cnt = mem->cookie_count;
15514
15515	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15516
15517	if (mem->type == STRUCT_BUF_MEMORY) {
15518		rval = ddi_dma_buf_bind_handle(mem->dma_handle, mem->bp,
15519		    mem->flags, (sleep == KM_SLEEP) ? DDI_DMA_SLEEP :
15520		    DDI_DMA_DONTWAIT, NULL, &mem->cookie, &mem->cookie_count);
15521	} else {
15522		rval = ddi_dma_addr_bind_handle(mem->dma_handle, NULL, mem->bp,
15523		    mem->size, mem->flags, (sleep == KM_SLEEP) ?
15524		    DDI_DMA_SLEEP : DDI_DMA_DONTWAIT, NULL, &mem->cookie,
15525		    &mem->cookie_count);
15526	}
15527
15528	if (rval == DDI_DMA_MAPPED) {
15529		if (mem->cookie_count > cnt) {
15530			(void) ddi_dma_unbind_handle(mem->dma_handle);
15531			EL(ha, "failed, cookie_count %d > %d\n",
15532			    mem->cookie_count, cnt);
15533			rval = DDI_DMA_TOOBIG;
15534		} else {
15535			if (mem->cookie_count > 1) {
15536				if (mem->cookies = kmem_zalloc(
15537				    sizeof (ddi_dma_cookie_t) *
15538				    mem->cookie_count, sleep)) {
15539					*mem->cookies = mem->cookie;
15540					cookiep = mem->cookies;
15541					for (cnt = 1; cnt < mem->cookie_count;
15542					    cnt++) {
15543						ddi_dma_nextcookie(
15544						    mem->dma_handle,
15545						    ++cookiep);
15546					}
15547				} else {
15548					(void) ddi_dma_unbind_handle(
15549					    mem->dma_handle);
15550					EL(ha, "failed, kmem_zalloc\n");
15551					rval = DDI_DMA_NORESOURCES;
15552				}
15553			} else {
15554				/*
15555				 * It has been reported that dmac_size at times
15556				 * may be incorrect on sparc machines so for
15557				 * sparc machines that only have one segment
15558				 * use the buffer size instead.
15559				 */
15560				mem->cookies = &mem->cookie;
15561				mem->cookies->dmac_size = mem->size;
15562			}
15563		}
15564	}
15565
15566	if (rval != DDI_DMA_MAPPED) {
15567		EL(ha, "failed=%xh\n", rval);
15568	} else {
15569		/*EMPTY*/
15570		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15571	}
15572
15573	return (rval);
15574}
15575
15576/*
15577 * ql_unbind_dma_buffer
15578 *	Unbinds DMA buffer.
15579 *
15580 * Input:
15581 *	ha:			adapter state pointer.
15582 *	mem:			pointer to dma memory object.
15583 *	mem->dma_handle		DMA memory handle.
15584 *	mem->cookies		pointer to cookie list.
15585 *	mem->cookie_count	number of cookies.
15586 *
15587 * Context:
15588 *	Kernel context.
15589 */
15590/* ARGSUSED */
15591static void
15592ql_unbind_dma_buffer(ql_adapter_state_t *ha, dma_mem_t *mem)
15593{
15594	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15595
15596	(void) ddi_dma_unbind_handle(mem->dma_handle);
15597	if (mem->cookie_count > 1) {
15598		kmem_free(mem->cookies, sizeof (ddi_dma_cookie_t) *
15599		    mem->cookie_count);
15600		mem->cookies = NULL;
15601	}
15602	mem->cookie_count = 0;
15603
15604	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15605}
15606
15607static int
15608ql_suspend_adapter(ql_adapter_state_t *ha)
15609{
15610	clock_t timer = 32 * drv_usectohz(1000000);
15611
15612	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15613
15614	/*
15615	 * First we will claim mbox ownership so that no
15616	 * thread using mbox hangs when we disable the
15617	 * interrupt in the middle of it.
15618	 */
15619	MBX_REGISTER_LOCK(ha);
15620
15621	/* Check for mailbox available, if not wait for signal. */
15622	while (ha->mailbox_flags & MBX_BUSY_FLG) {
15623		ha->mailbox_flags = (uint8_t)
15624		    (ha->mailbox_flags | MBX_WANT_FLG);
15625
15626		/* 30 seconds from now */
15627		if (cv_reltimedwait(&ha->cv_mbx_wait, &ha->mbx_mutex,
15628		    timer, TR_CLOCK_TICK) == -1) {
15629
15630			/* Release mailbox register lock. */
15631			MBX_REGISTER_UNLOCK(ha);
15632			EL(ha, "failed, Suspend mbox");
15633			return (QL_FUNCTION_TIMEOUT);
15634		}
15635	}
15636
15637	/* Set busy flag. */
15638	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_BUSY_FLG);
15639	MBX_REGISTER_UNLOCK(ha);
15640
15641	(void) ql_wait_outstanding(ha);
15642
15643	/*
15644	 * here we are sure that there will not be any mbox interrupt.
15645	 * So, let's make sure that we return back all the outstanding
15646	 * cmds as well as internally queued commands.
15647	 */
15648	ql_halt(ha, PM_LEVEL_D0);
15649
15650	if (ha->power_level != PM_LEVEL_D3) {
15651		/* Disable ISP interrupts. */
15652		WRT16_IO_REG(ha, ictrl, 0);
15653	}
15654
15655	ADAPTER_STATE_LOCK(ha);
15656	ha->flags &= ~INTERRUPTS_ENABLED;
15657	ADAPTER_STATE_UNLOCK(ha);
15658
15659	MBX_REGISTER_LOCK(ha);
15660	/* Reset busy status. */
15661	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & ~MBX_BUSY_FLG);
15662
15663	/* If thread is waiting for mailbox go signal it to start. */
15664	if (ha->mailbox_flags & MBX_WANT_FLG) {
15665		ha->mailbox_flags = (uint8_t)
15666		    (ha->mailbox_flags & ~MBX_WANT_FLG);
15667		cv_broadcast(&ha->cv_mbx_wait);
15668	}
15669	/* Release mailbox register lock. */
15670	MBX_REGISTER_UNLOCK(ha);
15671
15672	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
15673
15674	return (QL_SUCCESS);
15675}
15676
15677/*
15678 * ql_add_link_b
15679 *	Add link to the end of the chain.
15680 *
15681 * Input:
15682 *	head = Head of link list.
15683 *	link = link to be added.
15684 *	LOCK must be already obtained.
15685 *
15686 * Context:
15687 *	Interrupt or Kernel context, no mailbox commands allowed.
15688 */
15689void
15690ql_add_link_b(ql_head_t *head, ql_link_t *link)
15691{
15692	/* at the end there isn't a next */
15693	link->next = NULL;
15694
15695	if ((link->prev = head->last) == NULL) {
15696		head->first = link;
15697	} else {
15698		head->last->next = link;
15699	}
15700
15701	head->last = link;
15702	link->head = head;	/* the queue we're on */
15703}
15704
15705/*
15706 * ql_add_link_t
15707 *	Add link to the beginning of the chain.
15708 *
15709 * Input:
15710 *	head = Head of link list.
15711 *	link = link to be added.
15712 *	LOCK must be already obtained.
15713 *
15714 * Context:
15715 *	Interrupt or Kernel context, no mailbox commands allowed.
15716 */
15717void
15718ql_add_link_t(ql_head_t *head, ql_link_t *link)
15719{
15720	link->prev = NULL;
15721
15722	if ((link->next = head->first) == NULL)	{
15723		head->last = link;
15724	} else {
15725		head->first->prev = link;
15726	}
15727
15728	head->first = link;
15729	link->head = head;	/* the queue we're on */
15730}
15731
15732/*
15733 * ql_remove_link
15734 *	Remove a link from the chain.
15735 *
15736 * Input:
15737 *	head = Head of link list.
15738 *	link = link to be removed.
15739 *	LOCK must be already obtained.
15740 *
15741 * Context:
15742 *	Interrupt or Kernel context, no mailbox commands allowed.
15743 */
15744void
15745ql_remove_link(ql_head_t *head, ql_link_t *link)
15746{
15747	if (link->prev != NULL) {
15748		if ((link->prev->next = link->next) == NULL) {
15749			head->last = link->prev;
15750		} else {
15751			link->next->prev = link->prev;
15752		}
15753	} else if ((head->first = link->next) == NULL) {
15754		head->last = NULL;
15755	} else {
15756		head->first->prev = NULL;
15757	}
15758
15759	/* not on a queue any more */
15760	link->prev = link->next = NULL;
15761	link->head = NULL;
15762}
15763
15764/*
15765 * ql_chg_endian
15766 *	Change endianess of byte array.
15767 *
15768 * Input:
15769 *	buf = array pointer.
15770 *	size = size of array in bytes.
15771 *
15772 * Context:
15773 *	Interrupt or Kernel context, no mailbox commands allowed.
15774 */
15775void
15776ql_chg_endian(uint8_t buf[], size_t size)
15777{
15778	uint8_t byte;
15779	size_t  cnt1;
15780	size_t  cnt;
15781
15782	cnt1 = size - 1;
15783	for (cnt = 0; cnt < size / 2; cnt++) {
15784		byte = buf[cnt1];
15785		buf[cnt1] = buf[cnt];
15786		buf[cnt] = byte;
15787		cnt1--;
15788	}
15789}
15790
15791/*
15792 * ql_bstr_to_dec
15793 *	Convert decimal byte string to number.
15794 *
15795 * Input:
15796 *	s:	byte string pointer.
15797 *	ans:	interger pointer for number.
15798 *	size:	number of ascii bytes.
15799 *
15800 * Returns:
15801 *	success = number of ascii bytes processed.
15802 *
15803 * Context:
15804 *	Kernel/Interrupt context.
15805 */
15806static int
15807ql_bstr_to_dec(char *s, uint32_t *ans, uint32_t size)
15808{
15809	int			mul, num, cnt, pos;
15810	char			*str;
15811
15812	/* Calculate size of number. */
15813	if (size == 0) {
15814		for (str = s; *str >= '0' && *str <= '9'; str++) {
15815			size++;
15816		}
15817	}
15818
15819	*ans = 0;
15820	for (cnt = 0; *s != '\0' && size; size--, cnt++) {
15821		if (*s >= '0' && *s <= '9') {
15822			num = *s++ - '0';
15823		} else {
15824			break;
15825		}
15826
15827		for (mul = 1, pos = 1; pos < size; pos++) {
15828			mul *= 10;
15829		}
15830		*ans += num * mul;
15831	}
15832
15833	return (cnt);
15834}
15835
15836/*
15837 * ql_delay
15838 *	Calls delay routine if threads are not suspended, otherwise, busy waits
15839 *	Minimum = 1 tick = 10ms
15840 *
15841 * Input:
15842 *	dly = delay time in microseconds.
15843 *
15844 * Context:
15845 *	Kernel or Interrupt context, no mailbox commands allowed.
15846 */
15847void
15848ql_delay(ql_adapter_state_t *ha, clock_t usecs)
15849{
15850	if (QL_DAEMON_SUSPENDED(ha) || ddi_in_panic()) {
15851		drv_usecwait(usecs);
15852	} else {
15853		delay(drv_usectohz(usecs));
15854	}
15855}
15856
15857/*
15858 * ql_stall_drv
15859 *	Stalls one or all driver instances, waits for 30 seconds.
15860 *
15861 * Input:
15862 *	ha:		adapter state pointer or NULL for all.
15863 *	options:	BIT_0 --> leave driver stalled on exit if
15864 *				  failed.
15865 *
15866 * Returns:
15867 *	ql local function return status code.
15868 *
15869 * Context:
15870 *	Kernel context.
15871 */
15872int
15873ql_stall_driver(ql_adapter_state_t *ha, uint32_t options)
15874{
15875	ql_link_t		*link;
15876	ql_adapter_state_t	*ha2;
15877	uint32_t		timer;
15878
15879	QL_PRINT_3(CE_CONT, "started\n");
15880
15881	/* Wait for 30 seconds for daemons unstall. */
15882	timer = 3000;
15883	link = ha == NULL ? ql_hba.first : &ha->hba;
15884	while (link != NULL && timer) {
15885		ha2 = link->base_address;
15886
15887		ql_awaken_task_daemon(ha2, NULL, DRIVER_STALL, 0);
15888
15889		if ((ha2->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) == 0 ||
15890		    (ha2->task_daemon_flags & TASK_DAEMON_STOP_FLG) != 0 ||
15891		    (ha2->task_daemon_flags & TASK_DAEMON_STALLED_FLG &&
15892		    ql_wait_outstanding(ha2) == MAX_OUTSTANDING_COMMANDS)) {
15893			link = ha == NULL ? link->next : NULL;
15894			continue;
15895		}
15896
15897		ql_delay(ha, 10000);
15898		timer--;
15899		link = ha == NULL ? ql_hba.first : &ha->hba;
15900	}
15901
15902	if (ha2 != NULL && timer == 0) {
15903		EL(ha2, "failed, tdf=%xh, exiting state is: %s\n",
15904		    ha2->task_daemon_flags, (options & BIT_0 ? "stalled" :
15905		    "unstalled"));
15906		if (options & BIT_0) {
15907			ql_awaken_task_daemon(ha2, NULL, 0, DRIVER_STALL);
15908		}
15909		return (QL_FUNCTION_TIMEOUT);
15910	}
15911
15912	QL_PRINT_3(CE_CONT, "done\n");
15913
15914	return (QL_SUCCESS);
15915}
15916
15917/*
15918 * ql_restart_driver
15919 *	Restarts one or all driver instances.
15920 *
15921 * Input:
15922 *	ha:	adapter state pointer or NULL for all.
15923 *
15924 * Context:
15925 *	Kernel context.
15926 */
15927void
15928ql_restart_driver(ql_adapter_state_t *ha)
15929{
15930	ql_link_t		*link;
15931	ql_adapter_state_t	*ha2;
15932	uint32_t		timer;
15933
15934	QL_PRINT_3(CE_CONT, "started\n");
15935
15936	/* Tell all daemons to unstall. */
15937	link = ha == NULL ? ql_hba.first : &ha->hba;
15938	while (link != NULL) {
15939		ha2 = link->base_address;
15940
15941		ql_awaken_task_daemon(ha2, NULL, 0, DRIVER_STALL);
15942
15943		link = ha == NULL ? link->next : NULL;
15944	}
15945
15946	/* Wait for 30 seconds for all daemons unstall. */
15947	timer = 3000;
15948	link = ha == NULL ? ql_hba.first : &ha->hba;
15949	while (link != NULL && timer) {
15950		ha2 = link->base_address;
15951
15952		if ((ha2->task_daemon_flags & TASK_DAEMON_ALIVE_FLG) == 0 ||
15953		    (ha2->task_daemon_flags & TASK_DAEMON_STOP_FLG) != 0 ||
15954		    (ha2->task_daemon_flags & TASK_DAEMON_STALLED_FLG) == 0) {
15955			QL_PRINT_2(CE_CONT, "(%d,%d): restarted\n",
15956			    ha2->instance, ha2->vp_index);
15957			ql_restart_queues(ha2);
15958			link = ha == NULL ? link->next : NULL;
15959			continue;
15960		}
15961
15962		QL_PRINT_2(CE_CONT, "(%d,%d): failed, tdf=%xh\n",
15963		    ha2->instance, ha2->vp_index, ha2->task_daemon_flags);
15964
15965		ql_delay(ha, 10000);
15966		timer--;
15967		link = ha == NULL ? ql_hba.first : &ha->hba;
15968	}
15969
15970	QL_PRINT_3(CE_CONT, "done\n");
15971}
15972
15973/*
15974 * ql_setup_interrupts
15975 *	Sets up interrupts based on the HBA's and platform's
15976 *	capabilities (e.g., legacy / MSI / FIXED).
15977 *
15978 * Input:
15979 *	ha = adapter state pointer.
15980 *
15981 * Returns:
15982 *	DDI_SUCCESS or DDI_FAILURE.
15983 *
15984 * Context:
15985 *	Kernel context.
15986 */
15987static int
15988ql_setup_interrupts(ql_adapter_state_t *ha)
15989{
15990	int32_t		rval = DDI_FAILURE;
15991	int32_t		i;
15992	int32_t		itypes = 0;
15993
15994	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
15995
15996	/*
15997	 * The Solaris Advanced Interrupt Functions (aif) are only
15998	 * supported on s10U1 or greater.
15999	 */
16000	if (ql_os_release_level < 10 || ql_disable_aif != 0) {
16001		EL(ha, "interrupt framework is not supported or is "
16002		    "disabled, using legacy\n");
16003		return (ql_legacy_intr(ha));
16004	} else if (ql_os_release_level == 10) {
16005		/*
16006		 * See if the advanced interrupt functions (aif) are
16007		 * in the kernel
16008		 */
16009		void	*fptr = (void *)&ddi_intr_get_supported_types;
16010
16011		if (fptr == NULL) {
16012			EL(ha, "aif is not supported, using legacy "
16013			    "interrupts (rev)\n");
16014			return (ql_legacy_intr(ha));
16015		}
16016	}
16017
16018	/* See what types of interrupts this HBA and platform support */
16019	if ((i = ddi_intr_get_supported_types(ha->dip, &itypes)) !=
16020	    DDI_SUCCESS) {
16021		EL(ha, "get supported types failed, rval=%xh, "
16022		    "assuming FIXED\n", i);
16023		itypes = DDI_INTR_TYPE_FIXED;
16024	}
16025
16026	EL(ha, "supported types are: %xh\n", itypes);
16027
16028	if ((itypes & DDI_INTR_TYPE_MSIX) &&
16029	    (rval = ql_setup_msix(ha)) == DDI_SUCCESS) {
16030		EL(ha, "successful MSI-X setup\n");
16031	} else if ((itypes & DDI_INTR_TYPE_MSI) &&
16032	    (rval = ql_setup_msi(ha)) == DDI_SUCCESS) {
16033		EL(ha, "successful MSI setup\n");
16034	} else {
16035		rval = ql_setup_fixed(ha);
16036	}
16037
16038	if (rval != DDI_SUCCESS) {
16039		EL(ha, "failed, aif, rval=%xh\n", rval);
16040	} else {
16041		/*EMPTY*/
16042		QL_PRINT_3(CE_CONT, "(%d): done\n");
16043	}
16044
16045	return (rval);
16046}
16047
16048/*
16049 * ql_setup_msi
16050 *	Set up aif MSI interrupts
16051 *
16052 * Input:
16053 *	ha = adapter state pointer.
16054 *
16055 * Returns:
16056 *	DDI_SUCCESS or DDI_FAILURE.
16057 *
16058 * Context:
16059 *	Kernel context.
16060 */
16061static int
16062ql_setup_msi(ql_adapter_state_t *ha)
16063{
16064	int32_t		count = 0;
16065	int32_t		avail = 0;
16066	int32_t		actual = 0;
16067	int32_t		msitype = DDI_INTR_TYPE_MSI;
16068	int32_t		ret;
16069	ql_ifunc_t	itrfun[10] = {0};
16070
16071	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16072
16073	if (ql_disable_msi != 0) {
16074		EL(ha, "MSI is disabled by user\n");
16075		return (DDI_FAILURE);
16076	}
16077
16078	/* MSI support is only suported on 24xx HBA's. */
16079	if (!(CFG_IST(ha, CFG_CTRL_242581))) {
16080		EL(ha, "HBA does not support MSI\n");
16081		return (DDI_FAILURE);
16082	}
16083
16084	/* Get number of MSI interrupts the system supports */
16085	if (((ret = ddi_intr_get_nintrs(ha->dip, msitype, &count)) !=
16086	    DDI_SUCCESS) || count == 0) {
16087		EL(ha, "failed, nintrs ret=%xh, cnt=%xh\n", ret, count);
16088		return (DDI_FAILURE);
16089	}
16090
16091	/* Get number of available MSI interrupts */
16092	if (((ret = ddi_intr_get_navail(ha->dip, msitype, &avail)) !=
16093	    DDI_SUCCESS) || avail == 0) {
16094		EL(ha, "failed, navail ret=%xh, avail=%xh\n", ret, avail);
16095		return (DDI_FAILURE);
16096	}
16097
16098	/* MSI requires only 1.  */
16099	count = 1;
16100	itrfun[0].ifunc = &ql_isr_aif;
16101
16102	/* Allocate space for interrupt handles */
16103	ha->hsize = ((uint32_t)(sizeof (ddi_intr_handle_t)) * count);
16104	ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP);
16105
16106	ha->iflags |= IFLG_INTR_MSI;
16107
16108	/* Allocate the interrupts */
16109	if ((ret = ddi_intr_alloc(ha->dip, ha->htable, msitype, 0, count,
16110	    &actual, 0)) != DDI_SUCCESS || actual < count) {
16111		EL(ha, "failed, intr_alloc ret=%xh, count = %xh, "
16112		    "actual=%xh\n", ret, count, actual);
16113		ql_release_intr(ha);
16114		return (DDI_FAILURE);
16115	}
16116
16117	ha->intr_cnt = actual;
16118
16119	/* Get interrupt priority */
16120	if ((ret = ddi_intr_get_pri(ha->htable[0], &ha->intr_pri)) !=
16121	    DDI_SUCCESS) {
16122		EL(ha, "failed, get_pri ret=%xh\n", ret);
16123		ql_release_intr(ha);
16124		return (ret);
16125	}
16126
16127	/* Add the interrupt handler */
16128	if ((ret = ddi_intr_add_handler(ha->htable[0], itrfun[0].ifunc,
16129	    (caddr_t)ha, (caddr_t)0)) != DDI_SUCCESS) {
16130		EL(ha, "failed, intr_add ret=%xh\n", ret);
16131		ql_release_intr(ha);
16132		return (ret);
16133	}
16134
16135	/* Setup mutexes */
16136	if ((ret = ql_init_mutex(ha)) != DDI_SUCCESS) {
16137		EL(ha, "failed, mutex init ret=%xh\n", ret);
16138		ql_release_intr(ha);
16139		return (ret);
16140	}
16141
16142	/* Get the capabilities */
16143	(void) ddi_intr_get_cap(ha->htable[0], &ha->intr_cap);
16144
16145	/* Enable interrupts */
16146	if (ha->intr_cap & DDI_INTR_FLAG_BLOCK) {
16147		if ((ret = ddi_intr_block_enable(ha->htable, ha->intr_cnt)) !=
16148		    DDI_SUCCESS) {
16149			EL(ha, "failed, block enable, ret=%xh\n", ret);
16150			ql_destroy_mutex(ha);
16151			ql_release_intr(ha);
16152			return (ret);
16153		}
16154	} else {
16155		if ((ret = ddi_intr_enable(ha->htable[0])) != DDI_SUCCESS) {
16156			EL(ha, "failed, intr enable, ret=%xh\n", ret);
16157			ql_destroy_mutex(ha);
16158			ql_release_intr(ha);
16159			return (ret);
16160		}
16161	}
16162
16163	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16164
16165	return (DDI_SUCCESS);
16166}
16167
16168/*
16169 * ql_setup_msix
16170 *	Set up aif MSI-X interrupts
16171 *
16172 * Input:
16173 *	ha = adapter state pointer.
16174 *
16175 * Returns:
16176 *	DDI_SUCCESS or DDI_FAILURE.
16177 *
16178 * Context:
16179 *	Kernel context.
16180 */
16181static int
16182ql_setup_msix(ql_adapter_state_t *ha)
16183{
16184	uint16_t	hwvect;
16185	int32_t		count = 0;
16186	int32_t		avail = 0;
16187	int32_t		actual = 0;
16188	int32_t		msitype = DDI_INTR_TYPE_MSIX;
16189	int32_t		ret;
16190	uint32_t	i;
16191	ql_ifunc_t	itrfun[QL_MSIX_MAXAIF] = {0};
16192
16193	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16194
16195	if (ql_disable_msix != 0) {
16196		EL(ha, "MSI-X is disabled by user\n");
16197		return (DDI_FAILURE);
16198	}
16199
16200	/*
16201	 * MSI-X support is only available on 24xx HBA's that have
16202	 * rev A2 parts (revid = 3) or greater.
16203	 */
16204	if (!((ha->device_id == 0x2532) || (ha->device_id == 0x2432) ||
16205	    (ha->device_id == 0x8432) || (ha->device_id == 0x8001))) {
16206		EL(ha, "HBA does not support MSI-X\n");
16207		return (DDI_FAILURE);
16208	}
16209
16210	if (CFG_IST(ha, CFG_CTRL_2422) && (ha->rev_id < 3)) {
16211		EL(ha, "HBA does not support MSI-X (revid)\n");
16212		return (DDI_FAILURE);
16213	}
16214
16215	/* Per HP, these HP branded HBA's are not supported with MSI-X */
16216	if (ha->ven_id == 0x103C && (ha->subsys_id == 0x7041 ||
16217	    ha->subsys_id == 0x7040 || ha->subsys_id == 0x1705)) {
16218		EL(ha, "HBA does not support MSI-X (subdevid)\n");
16219		return (DDI_FAILURE);
16220	}
16221
16222	/* Get the number of 24xx/25xx MSI-X h/w vectors */
16223	hwvect = (uint16_t)(((CFG_IST(ha, CFG_CTRL_2422) ?
16224	    ql_pci_config_get16(ha, 0x7e) :
16225	    ql_pci_config_get16(ha, 0xa2)) & 0x3ff) + 1);
16226
16227	EL(ha, "pcie config space hwvect = %d\n", hwvect);
16228
16229	if (hwvect < QL_MSIX_MAXAIF) {
16230		EL(ha, "failed, min h/w vectors req'd: %d, avail: %d\n",
16231		    QL_MSIX_MAXAIF, hwvect);
16232		return (DDI_FAILURE);
16233	}
16234
16235	/* Get number of MSI-X interrupts the platform h/w supports */
16236	if (((ret = ddi_intr_get_nintrs(ha->dip, msitype, &count)) !=
16237	    DDI_SUCCESS) || count == 0) {
16238		EL(ha, "failed, nintrs ret=%xh, cnt=%xh\n", ret, count);
16239		return (DDI_FAILURE);
16240	}
16241
16242	/* Get number of available system interrupts */
16243	if (((ret = ddi_intr_get_navail(ha->dip, msitype, &avail)) !=
16244	    DDI_SUCCESS) || avail == 0) {
16245		EL(ha, "failed, navail ret=%xh, avail=%xh\n", ret, avail);
16246		return (DDI_FAILURE);
16247	}
16248
16249	/* Fill out the intr table */
16250	count = QL_MSIX_MAXAIF;
16251	itrfun[QL_MSIX_AIF].ifunc = &ql_isr_aif;
16252	itrfun[QL_MSIX_RSPQ].ifunc = &ql_isr_aif;
16253
16254	/* Allocate space for interrupt handles */
16255	ha->hsize = ((uint32_t)(sizeof (ddi_intr_handle_t)) * hwvect);
16256	if ((ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP)) == NULL) {
16257		ha->hsize = 0;
16258		EL(ha, "failed, unable to allocate htable space\n");
16259		return (DDI_FAILURE);
16260	}
16261
16262	ha->iflags |= IFLG_INTR_MSIX;
16263
16264	/* Allocate the interrupts */
16265	if (((ret = ddi_intr_alloc(ha->dip, ha->htable, msitype,
16266	    DDI_INTR_ALLOC_NORMAL, count, &actual, 0)) != DDI_SUCCESS) ||
16267	    actual < QL_MSIX_MAXAIF) {
16268		EL(ha, "failed, intr_alloc ret=%xh, count = %xh, "
16269		    "actual=%xh\n", ret, count, actual);
16270		ql_release_intr(ha);
16271		return (DDI_FAILURE);
16272	}
16273
16274	ha->intr_cnt = actual;
16275
16276	/* Get interrupt priority */
16277	if ((ret = ddi_intr_get_pri(ha->htable[0], &ha->intr_pri)) !=
16278	    DDI_SUCCESS) {
16279		EL(ha, "failed, get_pri ret=%xh\n", ret);
16280		ql_release_intr(ha);
16281		return (ret);
16282	}
16283
16284	/* Add the interrupt handlers */
16285	for (i = 0; i < actual; i++) {
16286		if ((ret = ddi_intr_add_handler(ha->htable[i], itrfun[i].ifunc,
16287		    (void *)ha, (void *)((ulong_t)i))) != DDI_SUCCESS) {
16288			EL(ha, "failed, addh#=%xh, act=%xh, ret=%xh\n", i,
16289			    actual, ret);
16290			ql_release_intr(ha);
16291			return (ret);
16292		}
16293	}
16294
16295	/*
16296	 * duplicate the rest of the intr's
16297	 * ddi_intr_dup_handler() isn't working on x86 just yet...
16298	 */
16299#ifdef __sparc
16300	for (i = actual; i < hwvect; i++) {
16301		if ((ret = ddi_intr_dup_handler(ha->htable[0], (int)i,
16302		    &ha->htable[i])) != DDI_SUCCESS) {
16303			EL(ha, "failed, intr_dup#=%xh, act=%xh, ret=%xh\n",
16304			    i, actual, ret);
16305			ql_release_intr(ha);
16306			return (ret);
16307		}
16308	}
16309#endif
16310
16311	/* Setup mutexes */
16312	if ((ret = ql_init_mutex(ha)) != DDI_SUCCESS) {
16313		EL(ha, "failed, mutex init ret=%xh\n", ret);
16314		ql_release_intr(ha);
16315		return (ret);
16316	}
16317
16318	/* Get the capabilities */
16319	(void) ddi_intr_get_cap(ha->htable[0], &ha->intr_cap);
16320
16321	/* Enable interrupts */
16322	if (ha->intr_cap & DDI_INTR_FLAG_BLOCK) {
16323		if ((ret = ddi_intr_block_enable(ha->htable, ha->intr_cnt)) !=
16324		    DDI_SUCCESS) {
16325			EL(ha, "failed, block enable, ret=%xh\n", ret);
16326			ql_destroy_mutex(ha);
16327			ql_release_intr(ha);
16328			return (ret);
16329		}
16330	} else {
16331		for (i = 0; i < ha->intr_cnt; i++) {
16332			if ((ret = ddi_intr_enable(ha->htable[i])) !=
16333			    DDI_SUCCESS) {
16334				EL(ha, "failed, intr enable, ret=%xh\n", ret);
16335				ql_destroy_mutex(ha);
16336				ql_release_intr(ha);
16337				return (ret);
16338			}
16339		}
16340	}
16341
16342	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16343
16344	return (DDI_SUCCESS);
16345}
16346
16347/*
16348 * ql_setup_fixed
16349 *	Sets up aif FIXED interrupts
16350 *
16351 * Input:
16352 *	ha = adapter state pointer.
16353 *
16354 * Returns:
16355 *	DDI_SUCCESS or DDI_FAILURE.
16356 *
16357 * Context:
16358 *	Kernel context.
16359 */
16360static int
16361ql_setup_fixed(ql_adapter_state_t *ha)
16362{
16363	int32_t		count = 0;
16364	int32_t		actual = 0;
16365	int32_t		ret;
16366	uint32_t	i;
16367
16368	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16369
16370	/* Get number of fixed interrupts the system supports */
16371	if (((ret = ddi_intr_get_nintrs(ha->dip, DDI_INTR_TYPE_FIXED,
16372	    &count)) != DDI_SUCCESS) || count == 0) {
16373		EL(ha, "failed, nintrs ret=%xh, cnt=%xh\n", ret, count);
16374		return (DDI_FAILURE);
16375	}
16376
16377	ha->iflags |= IFLG_INTR_FIXED;
16378
16379	/* Allocate space for interrupt handles */
16380	ha->hsize = ((uint32_t)(sizeof (ddi_intr_handle_t)) * count);
16381	ha->htable = kmem_zalloc(ha->hsize, KM_SLEEP);
16382
16383	/* Allocate the interrupts */
16384	if (((ret = ddi_intr_alloc(ha->dip, ha->htable, DDI_INTR_TYPE_FIXED,
16385	    0, count, &actual, DDI_INTR_ALLOC_STRICT)) != DDI_SUCCESS) ||
16386	    actual < count) {
16387		EL(ha, "failed, intr_alloc ret=%xh, count=%xh, "
16388		    "actual=%xh\n", ret, count, actual);
16389		ql_release_intr(ha);
16390		return (DDI_FAILURE);
16391	}
16392
16393	ha->intr_cnt = actual;
16394
16395	/* Get interrupt priority */
16396	if ((ret = ddi_intr_get_pri(ha->htable[0], &ha->intr_pri)) !=
16397	    DDI_SUCCESS) {
16398		EL(ha, "failed, get_pri ret=%xh\n", ret);
16399		ql_release_intr(ha);
16400		return (ret);
16401	}
16402
16403	/* Add the interrupt handlers */
16404	for (i = 0; i < ha->intr_cnt; i++) {
16405		if ((ret = ddi_intr_add_handler(ha->htable[i], &ql_isr_aif,
16406		    (void *)ha, (void *)((ulong_t)(i)))) != DDI_SUCCESS) {
16407			EL(ha, "failed, intr_add ret=%xh\n", ret);
16408			ql_release_intr(ha);
16409			return (ret);
16410		}
16411	}
16412
16413	/* Setup mutexes */
16414	if ((ret = ql_init_mutex(ha)) != DDI_SUCCESS) {
16415		EL(ha, "failed, mutex init ret=%xh\n", ret);
16416		ql_release_intr(ha);
16417		return (ret);
16418	}
16419
16420	/* Enable interrupts */
16421	for (i = 0; i < ha->intr_cnt; i++) {
16422		if ((ret = ddi_intr_enable(ha->htable[i])) != DDI_SUCCESS) {
16423			EL(ha, "failed, intr enable, ret=%xh\n", ret);
16424			ql_destroy_mutex(ha);
16425			ql_release_intr(ha);
16426			return (ret);
16427		}
16428	}
16429
16430	EL(ha, "using FIXED interupts\n");
16431
16432	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16433
16434	return (DDI_SUCCESS);
16435}
16436
16437/*
16438 * ql_disable_intr
16439 *	Disables interrupts
16440 *
16441 * Input:
16442 *	ha = adapter state pointer.
16443 *
16444 * Returns:
16445 *
16446 * Context:
16447 *	Kernel context.
16448 */
16449static void
16450ql_disable_intr(ql_adapter_state_t *ha)
16451{
16452	uint32_t	i, rval;
16453
16454	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16455
16456	if (!(ha->iflags & IFLG_INTR_AIF)) {
16457
16458		/* Disable legacy interrupts */
16459		(void) ddi_remove_intr(ha->dip, 0, ha->iblock_cookie);
16460
16461	} else if ((ha->intr_cap & DDI_INTR_FLAG_BLOCK) &&
16462	    (ha->iflags & (IFLG_INTR_MSI | IFLG_INTR_MSIX))) {
16463
16464		/* Remove AIF block interrupts (MSI) */
16465		if ((rval = ddi_intr_block_disable(ha->htable, ha->intr_cnt))
16466		    != DDI_SUCCESS) {
16467			EL(ha, "failed intr block disable, rval=%x\n", rval);
16468		}
16469
16470	} else {
16471
16472		/* Remove AIF non-block interrupts (fixed).  */
16473		for (i = 0; i < ha->intr_cnt; i++) {
16474			if ((rval = ddi_intr_disable(ha->htable[i])) !=
16475			    DDI_SUCCESS) {
16476				EL(ha, "failed intr disable, intr#=%xh, "
16477				    "rval=%xh\n", i, rval);
16478			}
16479		}
16480	}
16481
16482	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16483}
16484
16485/*
16486 * ql_release_intr
16487 *	Releases aif legacy interrupt resources
16488 *
16489 * Input:
16490 *	ha = adapter state pointer.
16491 *
16492 * Returns:
16493 *
16494 * Context:
16495 *	Kernel context.
16496 */
16497static void
16498ql_release_intr(ql_adapter_state_t *ha)
16499{
16500	int32_t 	i;
16501
16502	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16503
16504	if (!(ha->iflags & IFLG_INTR_AIF)) {
16505		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16506		return;
16507	}
16508
16509	ha->iflags &= ~(IFLG_INTR_AIF);
16510	if (ha->htable != NULL && ha->hsize > 0) {
16511		i = (int32_t)ha->hsize / (int32_t)sizeof (ddi_intr_handle_t);
16512		while (i-- > 0) {
16513			if (ha->htable[i] == 0) {
16514				EL(ha, "htable[%x]=0h\n", i);
16515				continue;
16516			}
16517
16518			(void) ddi_intr_disable(ha->htable[i]);
16519
16520			if (i < ha->intr_cnt) {
16521				(void) ddi_intr_remove_handler(ha->htable[i]);
16522			}
16523
16524			(void) ddi_intr_free(ha->htable[i]);
16525		}
16526
16527		kmem_free(ha->htable, ha->hsize);
16528		ha->htable = NULL;
16529	}
16530
16531	ha->hsize = 0;
16532	ha->intr_cnt = 0;
16533	ha->intr_pri = 0;
16534	ha->intr_cap = 0;
16535
16536	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16537}
16538
16539/*
16540 * ql_legacy_intr
16541 *	Sets up legacy interrupts.
16542 *
16543 *	NB: Only to be used if AIF (Advanced Interupt Framework)
16544 *	    if NOT in the kernel.
16545 *
16546 * Input:
16547 *	ha = adapter state pointer.
16548 *
16549 * Returns:
16550 *	DDI_SUCCESS or DDI_FAILURE.
16551 *
16552 * Context:
16553 *	Kernel context.
16554 */
16555static int
16556ql_legacy_intr(ql_adapter_state_t *ha)
16557{
16558	int	rval = DDI_SUCCESS;
16559
16560	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16561
16562	/* Setup mutexes */
16563	if (ql_init_mutex(ha) != DDI_SUCCESS) {
16564		EL(ha, "failed, mutex init\n");
16565		return (DDI_FAILURE);
16566	}
16567
16568	/* Setup standard/legacy interrupt handler */
16569	if (ddi_add_intr(ha->dip, (uint_t)0, &ha->iblock_cookie,
16570	    (ddi_idevice_cookie_t *)0, ql_isr, (caddr_t)ha) != DDI_SUCCESS) {
16571		cmn_err(CE_WARN, "%s(%d): Failed to add legacy interrupt",
16572		    QL_NAME, ha->instance);
16573		ql_destroy_mutex(ha);
16574		rval = DDI_FAILURE;
16575	}
16576
16577	if (rval == DDI_SUCCESS) {
16578		ha->iflags |= IFLG_INTR_LEGACY;
16579		EL(ha, "using legacy interrupts\n");
16580	}
16581
16582	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16583
16584	return (rval);
16585}
16586
16587/*
16588 * ql_init_mutex
16589 *	Initializes mutex's
16590 *
16591 * Input:
16592 *	ha = adapter state pointer.
16593 *
16594 * Returns:
16595 *	DDI_SUCCESS or DDI_FAILURE.
16596 *
16597 * Context:
16598 *	Kernel context.
16599 */
16600static int
16601ql_init_mutex(ql_adapter_state_t *ha)
16602{
16603	int	ret;
16604	void	*intr;
16605
16606	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16607
16608	if (ha->iflags & IFLG_INTR_AIF) {
16609		intr = (void *)(uintptr_t)ha->intr_pri;
16610	} else {
16611		/* Get iblock cookies to initialize mutexes */
16612		if ((ret = ddi_get_iblock_cookie(ha->dip, 0,
16613		    &ha->iblock_cookie)) != DDI_SUCCESS) {
16614			EL(ha, "failed, get_iblock: %xh\n", ret);
16615			return (DDI_FAILURE);
16616		}
16617		intr = (void *)ha->iblock_cookie;
16618	}
16619
16620	/* mutexes to protect the adapter state structure. */
16621	mutex_init(&ha->mutex, NULL, MUTEX_DRIVER, intr);
16622
16623	/* mutex to protect the ISP response ring. */
16624	mutex_init(&ha->intr_mutex, NULL, MUTEX_DRIVER, intr);
16625
16626	/* mutex to protect the mailbox registers. */
16627	mutex_init(&ha->mbx_mutex, NULL, MUTEX_DRIVER, intr);
16628
16629	/* power management protection */
16630	mutex_init(&ha->pm_mutex, NULL, MUTEX_DRIVER, intr);
16631
16632	/* Mailbox wait and interrupt conditional variable. */
16633	cv_init(&ha->cv_mbx_wait, NULL, CV_DRIVER, NULL);
16634	cv_init(&ha->cv_mbx_intr, NULL, CV_DRIVER, NULL);
16635
16636	/* mutex to protect the ISP request ring. */
16637	mutex_init(&ha->req_ring_mutex, NULL, MUTEX_DRIVER, intr);
16638
16639	/* Unsolicited buffer conditional variable. */
16640	cv_init(&ha->cv_ub, NULL, CV_DRIVER, NULL);
16641
16642	mutex_init(&ha->ub_mutex, NULL, MUTEX_DRIVER, intr);
16643	mutex_init(&ha->cache_mutex, NULL, MUTEX_DRIVER, intr);
16644
16645	/* Suspended conditional variable. */
16646	cv_init(&ha->cv_dr_suspended, NULL, CV_DRIVER, NULL);
16647
16648	/* mutex to protect task daemon context. */
16649	mutex_init(&ha->task_daemon_mutex, NULL, MUTEX_DRIVER, intr);
16650
16651	/* Task_daemon thread conditional variable. */
16652	cv_init(&ha->cv_task_daemon, NULL, CV_DRIVER, NULL);
16653
16654	/* mutex to protect diag port manage interface */
16655	mutex_init(&ha->portmutex, NULL, MUTEX_DRIVER, intr);
16656
16657	/* mutex to protect per instance f/w dump flags and buffer */
16658	mutex_init(&ha->dump_mutex, NULL, MUTEX_DRIVER, intr);
16659
16660	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16661
16662	return (DDI_SUCCESS);
16663}
16664
16665/*
16666 * ql_destroy_mutex
16667 *	Destroys mutex's
16668 *
16669 * Input:
16670 *	ha = adapter state pointer.
16671 *
16672 * Returns:
16673 *
16674 * Context:
16675 *	Kernel context.
16676 */
16677static void
16678ql_destroy_mutex(ql_adapter_state_t *ha)
16679{
16680	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16681
16682	mutex_destroy(&ha->dump_mutex);
16683	mutex_destroy(&ha->portmutex);
16684	cv_destroy(&ha->cv_task_daemon);
16685	mutex_destroy(&ha->task_daemon_mutex);
16686	cv_destroy(&ha->cv_dr_suspended);
16687	mutex_destroy(&ha->cache_mutex);
16688	mutex_destroy(&ha->ub_mutex);
16689	cv_destroy(&ha->cv_ub);
16690	mutex_destroy(&ha->req_ring_mutex);
16691	cv_destroy(&ha->cv_mbx_intr);
16692	cv_destroy(&ha->cv_mbx_wait);
16693	mutex_destroy(&ha->pm_mutex);
16694	mutex_destroy(&ha->mbx_mutex);
16695	mutex_destroy(&ha->intr_mutex);
16696	mutex_destroy(&ha->mutex);
16697
16698	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16699}
16700
16701/*
16702 * ql_fwmodule_resolve
16703 *	Loads and resolves external firmware module and symbols
16704 *
16705 * Input:
16706 *	ha:		adapter state pointer.
16707 *
16708 * Returns:
16709 *	ql local function return status code:
16710 *		QL_SUCCESS - external f/w module module and symbols resolved
16711 *		QL_FW_NOT_SUPPORTED - Driver does not support ISP type
16712 *		QL_FWMODLOAD_FAILED - Could not load f/w module (ddi failed)
16713 *		QL_FWSYM_NOT_FOUND - Unable to resolve internal f/w symbol
16714 * Context:
16715 *	Kernel context.
16716 *
16717 * NOTE: We currently ddi_modopen/ddi_modclose at attach/detach time.  We
16718 * could switch to a tighter scope around acutal download (and add an extra
16719 * ddi_modopen for module opens that occur before root is mounted).
16720 *
16721 */
16722uint32_t
16723ql_fwmodule_resolve(ql_adapter_state_t *ha)
16724{
16725	int8_t			module[128];
16726	int8_t			fw_version[128];
16727	uint32_t		rval = QL_SUCCESS;
16728	caddr_t			code, code02;
16729	uint8_t			*p_ucfw;
16730	uint16_t		*p_usaddr, *p_uslen;
16731	uint32_t		*p_uiaddr, *p_uilen, *p_uifw;
16732	uint32_t		*p_uiaddr02, *p_uilen02;
16733	struct fw_table		*fwt;
16734	extern struct fw_table	fw_table[];
16735
16736	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16737
16738	if (ha->fw_module != NULL) {
16739		EL(ha, "%x f/w module %d.%02d.%02d is already loaded\n",
16740		    ha->fw_class, ha->fw_major_version, ha->fw_minor_version,
16741		    ha->fw_subminor_version);
16742		return (rval);
16743	}
16744
16745	/* make sure the fw_class is in the fw_table of supported classes */
16746	for (fwt = &fw_table[0]; fwt->fw_version; fwt++) {
16747		if (fwt->fw_class == ha->fw_class)
16748			break;			/* match */
16749	}
16750	if (fwt->fw_version == NULL) {
16751		cmn_err(CE_WARN, "%s(%d): can't find f/w class %x "
16752		    "in driver's fw_table", QL_NAME, ha->instance,
16753		    ha->fw_class);
16754		return (QL_FW_NOT_SUPPORTED);
16755	}
16756
16757	/*
16758	 * open the module related to the fw_class
16759	 */
16760	(void) snprintf(module, sizeof (module), "misc/qlc/qlc_fw_%x",
16761	    ha->fw_class);
16762
16763	ha->fw_module = ddi_modopen(module, KRTLD_MODE_FIRST, NULL);
16764	if (ha->fw_module == NULL) {
16765		cmn_err(CE_WARN, "%s(%d): can't load firmware file %s",
16766		    QL_NAME, ha->instance, module);
16767		return (QL_FWMODLOAD_FAILED);
16768	}
16769
16770	/*
16771	 * resolve the fw module symbols, data types depend on fw_class
16772	 */
16773
16774	switch (ha->fw_class) {
16775	case 0x2200:
16776	case 0x2300:
16777	case 0x6322:
16778
16779		if ((code = ddi_modsym(ha->fw_module, "risc_code01",
16780		    NULL)) == NULL) {
16781			rval = QL_FWSYM_NOT_FOUND;
16782			EL(ha, "failed, f/w module %d rc01 symbol\n", module);
16783		} else if ((p_usaddr = ddi_modsym(ha->fw_module,
16784		    "risc_code_addr01", NULL)) == NULL) {
16785			rval = QL_FWSYM_NOT_FOUND;
16786			EL(ha, "failed, f/w module %d rca01 symbol\n", module);
16787		} else if ((p_uslen = ddi_modsym(ha->fw_module,
16788		    "risc_code_length01", NULL)) == NULL) {
16789			rval = QL_FWSYM_NOT_FOUND;
16790			EL(ha, "failed, f/w module %d rcl01 symbol\n", module);
16791		} else if ((p_ucfw = ddi_modsym(ha->fw_module,
16792		    "firmware_version", NULL)) == NULL) {
16793			rval = QL_FWSYM_NOT_FOUND;
16794			EL(ha, "failed, f/w module %d fwver symbol\n", module);
16795		}
16796
16797		if (rval == QL_SUCCESS) {
16798			ha->risc_fw[0].code = code;
16799			ha->risc_fw[0].addr = *p_usaddr;
16800			ha->risc_fw[0].length = *p_uslen;
16801
16802			(void) snprintf(fw_version, sizeof (fw_version),
16803			    "%d.%02d.%02d", p_ucfw[0], p_ucfw[1], p_ucfw[2]);
16804		}
16805		break;
16806
16807	case 0x2400:
16808	case 0x2500:
16809	case 0x8100:
16810
16811		if ((code = ddi_modsym(ha->fw_module, "risc_code01",
16812		    NULL)) == NULL) {
16813			rval = QL_FWSYM_NOT_FOUND;
16814			EL(ha, "failed, f/w module %d rc01 symbol\n", module);
16815		} else if ((p_uiaddr = ddi_modsym(ha->fw_module,
16816		    "risc_code_addr01", NULL)) == NULL) {
16817			rval = QL_FWSYM_NOT_FOUND;
16818			EL(ha, "failed, f/w module %d rca01 symbol\n", module);
16819		} else if ((p_uilen = ddi_modsym(ha->fw_module,
16820		    "risc_code_length01", NULL)) == NULL) {
16821			rval = QL_FWSYM_NOT_FOUND;
16822			EL(ha, "failed, f/w module %d rcl01 symbol\n", module);
16823		} else if ((p_uifw = ddi_modsym(ha->fw_module,
16824		    "firmware_version", NULL)) == NULL) {
16825			rval = QL_FWSYM_NOT_FOUND;
16826			EL(ha, "failed, f/w module %d fwver symbol\n", module);
16827		}
16828
16829		if ((code02 = ddi_modsym(ha->fw_module, "risc_code02",
16830		    NULL)) == NULL) {
16831			rval = QL_FWSYM_NOT_FOUND;
16832			EL(ha, "failed, f/w module %d rc02 symbol\n", module);
16833		} else if ((p_uiaddr02 = ddi_modsym(ha->fw_module,
16834		    "risc_code_addr02", NULL)) == NULL) {
16835			rval = QL_FWSYM_NOT_FOUND;
16836			EL(ha, "failed, f/w module %d rca02 symbol\n", module);
16837		} else if ((p_uilen02 = ddi_modsym(ha->fw_module,
16838		    "risc_code_length02", NULL)) == NULL) {
16839			rval = QL_FWSYM_NOT_FOUND;
16840			EL(ha, "failed, f/w module %d rcl02 symbol\n", module);
16841		}
16842
16843		if (rval == QL_SUCCESS) {
16844			ha->risc_fw[0].code = code;
16845			ha->risc_fw[0].addr = *p_uiaddr;
16846			ha->risc_fw[0].length = *p_uilen;
16847			ha->risc_fw[1].code = code02;
16848			ha->risc_fw[1].addr = *p_uiaddr02;
16849			ha->risc_fw[1].length = *p_uilen02;
16850
16851			(void) snprintf(fw_version, sizeof (fw_version),
16852			    "%d.%02d.%02d", p_uifw[0], p_uifw[1], p_uifw[2]);
16853		}
16854		break;
16855
16856	default:
16857		EL(ha, "fw_class: '%x' is not supported\n", ha->fw_class);
16858		rval = QL_FW_NOT_SUPPORTED;
16859	}
16860
16861	if (rval != QL_SUCCESS) {
16862		cmn_err(CE_WARN, "%s(%d): can't resolve firmware "
16863		    "module %s (%x)", QL_NAME, ha->instance, module, rval);
16864		if (ha->fw_module != NULL) {
16865			(void) ddi_modclose(ha->fw_module);
16866			ha->fw_module = NULL;
16867		}
16868	} else {
16869		/*
16870		 * check for firmware version mismatch between module and
16871		 * compiled in fw_table version.
16872		 */
16873
16874		if (strcmp(fwt->fw_version, fw_version) != 0) {
16875
16876			/*
16877			 * If f/w / driver version mismatches then
16878			 * return a successful status -- however warn
16879			 * the user that this is NOT recommended.
16880			 */
16881
16882			cmn_err(CE_WARN, "%s(%d): driver / f/w version "
16883			    "mismatch for %x: driver-%s module-%s", QL_NAME,
16884			    ha->instance, ha->fw_class, fwt->fw_version,
16885			    fw_version);
16886
16887			ha->cfg_flags |= CFG_FW_MISMATCH;
16888		} else {
16889			ha->cfg_flags &= ~CFG_FW_MISMATCH;
16890		}
16891	}
16892
16893	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16894
16895	return (rval);
16896}
16897
16898/*
16899 * ql_port_state
16900 *	Set the state on all adapter ports.
16901 *
16902 * Input:
16903 *	ha:	parent adapter state pointer.
16904 *	state:	port state.
16905 *	flags:	task daemon flags to set.
16906 *
16907 * Context:
16908 *	Interrupt or Kernel context, no mailbox commands allowed.
16909 */
16910void
16911ql_port_state(ql_adapter_state_t *ha, uint32_t state, uint32_t flags)
16912{
16913	ql_adapter_state_t	*vha;
16914
16915	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16916
16917	TASK_DAEMON_LOCK(ha);
16918	for (vha = ha->pha; vha != NULL; vha = vha->vp_next) {
16919		if (FC_PORT_STATE_MASK(vha->state) != state) {
16920			vha->state = state != FC_STATE_OFFLINE ?
16921			    (FC_PORT_SPEED_MASK(vha->state) | state) : state;
16922			vha->task_daemon_flags |= flags;
16923		}
16924	}
16925	ha->pha->task_daemon_flags |= flags & LOOP_DOWN;
16926	TASK_DAEMON_UNLOCK(ha);
16927
16928	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16929}
16930
16931/*
16932 * ql_el_trace_desc_ctor - Construct an extended logging trace descriptor.
16933 *
16934 * Input:	Pointer to the adapter state structure.
16935 * Returns:	Success or Failure.
16936 * Context:	Kernel context.
16937 */
16938int
16939ql_el_trace_desc_ctor(ql_adapter_state_t *ha)
16940{
16941	int	rval = DDI_SUCCESS;
16942
16943	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16944
16945	ha->el_trace_desc =
16946	    (el_trace_desc_t *)kmem_zalloc(sizeof (el_trace_desc_t), KM_SLEEP);
16947
16948	if (ha->el_trace_desc == NULL) {
16949		cmn_err(CE_WARN, "%s(%d): can't construct trace descriptor",
16950		    QL_NAME, ha->instance);
16951		rval = DDI_FAILURE;
16952	} else {
16953		ha->el_trace_desc->next		= 0;
16954		ha->el_trace_desc->trace_buffer =
16955		    (char *)kmem_zalloc(EL_TRACE_BUF_SIZE, KM_SLEEP);
16956
16957		if (ha->el_trace_desc->trace_buffer == NULL) {
16958			cmn_err(CE_WARN, "%s(%d): can't get trace buffer",
16959			    QL_NAME, ha->instance);
16960			kmem_free(ha->el_trace_desc, sizeof (el_trace_desc_t));
16961			rval = DDI_FAILURE;
16962		} else {
16963			ha->el_trace_desc->trace_buffer_size =
16964			    EL_TRACE_BUF_SIZE;
16965			mutex_init(&ha->el_trace_desc->mutex, NULL,
16966			    MUTEX_DRIVER, NULL);
16967		}
16968	}
16969
16970	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
16971
16972	return (rval);
16973}
16974
16975/*
16976 * ql_el_trace_desc_dtor - Destroy an extended logging trace descriptor.
16977 *
16978 * Input:	Pointer to the adapter state structure.
16979 * Returns:	Success or Failure.
16980 * Context:	Kernel context.
16981 */
16982int
16983ql_el_trace_desc_dtor(ql_adapter_state_t *ha)
16984{
16985	int	rval = DDI_SUCCESS;
16986
16987	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
16988
16989	if (ha->el_trace_desc == NULL) {
16990		cmn_err(CE_WARN, "%s(%d): can't destroy el trace descriptor",
16991		    QL_NAME, ha->instance);
16992		rval = DDI_FAILURE;
16993	} else {
16994		if (ha->el_trace_desc->trace_buffer != NULL) {
16995			kmem_free(ha->el_trace_desc->trace_buffer,
16996			    ha->el_trace_desc->trace_buffer_size);
16997		}
16998		mutex_destroy(&ha->el_trace_desc->mutex);
16999		kmem_free(ha->el_trace_desc, sizeof (el_trace_desc_t));
17000	}
17001
17002	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
17003
17004	return (rval);
17005}
17006
17007/*
17008 * els_cmd_text	- Return a pointer to a string describing the command
17009 *
17010 * Input:	els_cmd = the els command opcode.
17011 * Returns:	pointer to a string.
17012 * Context:	Kernel context.
17013 */
17014char *
17015els_cmd_text(int els_cmd)
17016{
17017	cmd_table_t *entry = &els_cmd_tbl[0];
17018
17019	return (cmd_text(entry, els_cmd));
17020}
17021
17022/*
17023 * mbx_cmd_text - Return a pointer to a string describing the command
17024 *
17025 * Input:	mbx_cmd = the mailbox command opcode.
17026 * Returns:	pointer to a string.
17027 * Context:	Kernel context.
17028 */
17029char *
17030mbx_cmd_text(int mbx_cmd)
17031{
17032	cmd_table_t *entry = &mbox_cmd_tbl[0];
17033
17034	return (cmd_text(entry, mbx_cmd));
17035}
17036
17037/*
17038 * cmd_text	Return a pointer to a string describing the command
17039 *
17040 * Input:	entry = the command table
17041 *		cmd = the command.
17042 * Returns:	pointer to a string.
17043 * Context:	Kernel context.
17044 */
17045char *
17046cmd_text(cmd_table_t *entry, int cmd)
17047{
17048	for (; entry->cmd != 0; entry++) {
17049		if (entry->cmd == cmd) {
17050			break;
17051		}
17052	}
17053	return (entry->string);
17054}
17055
17056/*
17057 * ql_els_24xx_mbox_cmd_iocb - els request indication.
17058 *
17059 * Input:	ha = adapter state pointer.
17060 *		srb = scsi request block pointer.
17061 *		arg = els passthru entry iocb pointer.
17062 * Returns:
17063 * Context:	Kernel context.
17064 */
17065void
17066ql_els_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *srb, void *arg)
17067{
17068	els_descriptor_t	els_desc;
17069
17070	/* Extract the ELS information */
17071	ql_fca_isp_els_request(ha, (fc_packet_t *)srb->pkt, &els_desc);
17072
17073	/* Construct the passthru entry */
17074	ql_isp_els_request_ctor(&els_desc, (els_passthru_entry_t *)arg);
17075
17076	/* Ensure correct endianness */
17077	ql_isp_els_handle_cmd_endian(ha, srb);
17078}
17079
17080/*
17081 * ql_fca_isp_els_request - Extract into an els descriptor the info required
17082 *			    to build an els_passthru iocb from an fc packet.
17083 *
17084 * Input:	ha = adapter state pointer.
17085 *		pkt = fc packet pointer
17086 *		els_desc = els descriptor pointer
17087 * Returns:
17088 * Context:	Kernel context.
17089 */
17090static void
17091ql_fca_isp_els_request(ql_adapter_state_t *ha, fc_packet_t *pkt,
17092    els_descriptor_t *els_desc)
17093{
17094	ls_code_t	els;
17095
17096	ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
17097	    (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
17098
17099	els_desc->els = els.ls_code;
17100
17101	els_desc->els_handle = ha->hba_buf.acc_handle;
17102	els_desc->d_id.b24 = pkt->pkt_cmd_fhdr.d_id;
17103	els_desc->s_id.b24 = pkt->pkt_cmd_fhdr.s_id;
17104	/* if n_port_handle is not < 0x7d use 0 */
17105	if (LOCAL_LOOP_ID(ha->n_port->n_port_handle)) {
17106		els_desc->n_port_handle = ha->n_port->n_port_handle;
17107	} else {
17108		els_desc->n_port_handle = 0;
17109	}
17110	els_desc->control_flags = 0;
17111	els_desc->cmd_byte_count = pkt->pkt_cmdlen;
17112	/*
17113	 * Transmit DSD. This field defines the Fibre Channel Frame payload
17114	 * (without the frame header) in system memory.
17115	 */
17116	els_desc->tx_dsd.addr[0] = LSD(pkt->pkt_cmd_cookie->dmac_laddress);
17117	els_desc->tx_dsd.addr[1] = MSD(pkt->pkt_cmd_cookie->dmac_laddress);
17118	els_desc->tx_dsd.length = (uint32_t)pkt->pkt_cmd_cookie->dmac_size;
17119
17120	els_desc->rsp_byte_count = pkt->pkt_rsplen;
17121	/*
17122	 * Receive DSD. This field defines the ELS response payload buffer
17123	 * for the ISP24xx firmware transferring the received ELS
17124	 * response frame to a location in host memory.
17125	 */
17126	els_desc->rx_dsd.addr[0] = LSD(pkt->pkt_resp_cookie->dmac_laddress);
17127	els_desc->rx_dsd.addr[1] = MSD(pkt->pkt_resp_cookie->dmac_laddress);
17128	els_desc->rx_dsd.length = (uint32_t)pkt->pkt_resp_cookie->dmac_size;
17129}
17130
17131/*
17132 * ql_isp_els_request_ctor - Construct an els_passthru_entry iocb
17133 * using the els descriptor.
17134 *
17135 * Input:	ha = adapter state pointer.
17136 *		els_desc = els descriptor pointer.
17137 *		els_entry = els passthru entry iocb pointer.
17138 * Returns:
17139 * Context:	Kernel context.
17140 */
17141static void
17142ql_isp_els_request_ctor(els_descriptor_t *els_desc,
17143    els_passthru_entry_t *els_entry)
17144{
17145	uint32_t	*ptr32;
17146
17147	/*
17148	 * Construct command packet.
17149	 */
17150	ddi_put8(els_desc->els_handle, &els_entry->entry_type,
17151	    (uint8_t)ELS_PASSTHRU_TYPE);
17152	ddi_put16(els_desc->els_handle, &els_entry->n_port_hdl,
17153	    els_desc->n_port_handle);
17154	ddi_put8(els_desc->els_handle, &els_entry->sof_type, (uint8_t)BIT_4);
17155	ddi_put32(els_desc->els_handle, &els_entry->rcv_exch_address,
17156	    (uint32_t)0);
17157	ddi_put8(els_desc->els_handle, &els_entry->els_cmd_opcode,
17158	    els_desc->els);
17159	ddi_put8(els_desc->els_handle, &els_entry->d_id_7_0,
17160	    els_desc->d_id.b.al_pa);
17161	ddi_put8(els_desc->els_handle, &els_entry->d_id_15_8,
17162	    els_desc->d_id.b.area);
17163	ddi_put8(els_desc->els_handle, &els_entry->d_id_23_16,
17164	    els_desc->d_id.b.domain);
17165	ddi_put8(els_desc->els_handle, &els_entry->s_id_7_0,
17166	    els_desc->s_id.b.al_pa);
17167	ddi_put8(els_desc->els_handle, &els_entry->s_id_15_8,
17168	    els_desc->s_id.b.area);
17169	ddi_put8(els_desc->els_handle, &els_entry->s_id_23_16,
17170	    els_desc->s_id.b.domain);
17171	ddi_put16(els_desc->els_handle, &els_entry->control_flags,
17172	    els_desc->control_flags);
17173	ddi_put32(els_desc->els_handle, &els_entry->rcv_payld_data_bcnt,
17174	    els_desc->rsp_byte_count);
17175	ddi_put32(els_desc->els_handle, &els_entry->xmt_payld_data_bcnt,
17176	    els_desc->cmd_byte_count);
17177	/* Load transmit data segments and count. */
17178	ptr32 = (uint32_t *)&els_entry->xmt_dseg_0_address;
17179	ddi_put16(els_desc->els_handle, &els_entry->xmt_dseg_count, 1);
17180	ddi_put32(els_desc->els_handle, ptr32++, els_desc->tx_dsd.addr[0]);
17181	ddi_put32(els_desc->els_handle, ptr32++, els_desc->tx_dsd.addr[1]);
17182	ddi_put32(els_desc->els_handle, ptr32++, els_desc->tx_dsd.length);
17183	ddi_put16(els_desc->els_handle, &els_entry->rcv_dseg_count, 1);
17184	ddi_put32(els_desc->els_handle, ptr32++, els_desc->rx_dsd.addr[0]);
17185	ddi_put32(els_desc->els_handle, ptr32++, els_desc->rx_dsd.addr[1]);
17186	ddi_put32(els_desc->els_handle, ptr32++, els_desc->rx_dsd.length);
17187}
17188
17189/*
17190 * ql_isp_els_handle_cmd_endian - els requests must be in big endian
17191 *				  in host memory.
17192 *
17193 * Input:	ha = adapter state pointer.
17194 *		srb = scsi request block
17195 * Returns:
17196 * Context:	Kernel context.
17197 */
17198void
17199ql_isp_els_handle_cmd_endian(ql_adapter_state_t *ha, ql_srb_t *srb)
17200{
17201	ls_code_t	els;
17202	fc_packet_t	*pkt;
17203	uint8_t		*ptr;
17204
17205	pkt = srb->pkt;
17206
17207	ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
17208	    (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
17209
17210	ptr = (uint8_t *)pkt->pkt_cmd;
17211
17212	ql_isp_els_handle_endian(ha, ptr, els.ls_code);
17213}
17214
17215/*
17216 * ql_isp_els_handle_rsp_endian - els responses must be in big endian
17217 *				  in host memory.
17218 * Input:	ha = adapter state pointer.
17219 *		srb = scsi request block
17220 * Returns:
17221 * Context:	Kernel context.
17222 */
17223void
17224ql_isp_els_handle_rsp_endian(ql_adapter_state_t *ha, ql_srb_t *srb)
17225{
17226	ls_code_t	els;
17227	fc_packet_t	*pkt;
17228	uint8_t		*ptr;
17229
17230	pkt = srb->pkt;
17231
17232	ddi_rep_get8(pkt->pkt_cmd_acc, (uint8_t *)&els,
17233	    (uint8_t *)pkt->pkt_cmd, sizeof (els), DDI_DEV_AUTOINCR);
17234
17235	ptr = (uint8_t *)pkt->pkt_resp;
17236	BIG_ENDIAN_32(&els);
17237	ql_isp_els_handle_endian(ha, ptr, els.ls_code);
17238}
17239
17240/*
17241 * ql_isp_els_handle_endian - els requests/responses must be in big endian
17242 *			      in host memory.
17243 * Input:	ha = adapter state pointer.
17244 *		ptr = els request/response buffer pointer.
17245 *		ls_code = els command code.
17246 * Returns:
17247 * Context:	Kernel context.
17248 */
17249void
17250ql_isp_els_handle_endian(ql_adapter_state_t *ha, uint8_t *ptr, uint8_t ls_code)
17251{
17252	switch (ls_code) {
17253	case LA_ELS_PLOGI: {
17254		BIG_ENDIAN_32(ptr);	/* Command Code */
17255		ptr += 4;
17256		BIG_ENDIAN_16(ptr);	/* FC-PH version */
17257		ptr += 2;
17258		BIG_ENDIAN_16(ptr);	/* b2b credit */
17259		ptr += 2;
17260		BIG_ENDIAN_16(ptr);	/* Cmn Feature flags */
17261		ptr += 2;
17262		BIG_ENDIAN_16(ptr);	/* Rcv data size */
17263		ptr += 2;
17264		BIG_ENDIAN_16(ptr);	/* Concurrent Seq */
17265		ptr += 2;
17266		BIG_ENDIAN_16(ptr);	/* Rel offset */
17267		ptr += 2;
17268		BIG_ENDIAN_32(ptr);	/* E_D_TOV */
17269		ptr += 4;		/* Port Name */
17270		ptr += 8;		/* Node Name */
17271		ptr += 8;		/* Class 1 */
17272		ptr += 16;		/* Class 2 */
17273		ptr += 16;		/* Class 3 */
17274		BIG_ENDIAN_16(ptr);	/* Service options */
17275		ptr += 2;
17276		BIG_ENDIAN_16(ptr);	/* Initiator control */
17277		ptr += 2;
17278		BIG_ENDIAN_16(ptr);	/* Recipient Control */
17279		ptr += 2;
17280		BIG_ENDIAN_16(ptr);	/* Rcv size */
17281		ptr += 2;
17282		BIG_ENDIAN_16(ptr);	/* Concurrent Seq */
17283		ptr += 2;
17284		BIG_ENDIAN_16(ptr);	/* N_Port e2e credit */
17285		ptr += 2;
17286		BIG_ENDIAN_16(ptr);	/* Open Seq/Exch */
17287		break;
17288	}
17289	case LA_ELS_PRLI: {
17290		BIG_ENDIAN_32(ptr);	/* Command Code/Page length */
17291		ptr += 4;		/* Type */
17292		ptr += 2;
17293		BIG_ENDIAN_16(ptr);	/* Flags */
17294		ptr += 2;
17295		BIG_ENDIAN_32(ptr);	/* Originator Process associator  */
17296		ptr += 4;
17297		BIG_ENDIAN_32(ptr);	/* Responder Process associator */
17298		ptr += 4;
17299		BIG_ENDIAN_32(ptr);	/* Flags */
17300		break;
17301	}
17302	default:
17303		EL(ha, "can't handle els code %x\n", ls_code);
17304		break;
17305	}
17306}
17307
17308/*
17309 * ql_n_port_plogi
17310 *	In N port 2 N port topology where an N Port has logged in with the
17311 *	firmware because it has the N_Port login initiative, we send up
17312 *	a plogi by proxy which stimulates the login procedure to continue.
17313 *
17314 * Input:
17315 *	ha = adapter state pointer.
17316 * Returns:
17317 *
17318 * Context:
17319 *	Kernel context.
17320 */
17321static int
17322ql_n_port_plogi(ql_adapter_state_t *ha)
17323{
17324	int		rval;
17325	ql_tgt_t	*tq;
17326	ql_head_t done_q = { NULL, NULL };
17327
17328	rval = QL_SUCCESS;
17329
17330	if (ha->topology & QL_N_PORT) {
17331		/* if we're doing this the n_port_handle must be good */
17332		if (LOCAL_LOOP_ID(ha->n_port->n_port_handle)) {
17333			tq = ql_loop_id_to_queue(ha,
17334			    ha->n_port->n_port_handle);
17335			if (tq != NULL) {
17336				(void) ql_send_plogi(ha, tq, &done_q);
17337			} else {
17338				EL(ha, "n_port_handle = %x, tq = %x\n",
17339				    ha->n_port->n_port_handle, tq);
17340			}
17341		} else {
17342			EL(ha, "n_port_handle = %x, tq = %x\n",
17343			    ha->n_port->n_port_handle, tq);
17344		}
17345		if (done_q.first != NULL) {
17346			ql_done(done_q.first);
17347		}
17348	}
17349	return (rval);
17350}
17351
17352/*
17353 * Compare two WWNs. The NAA is omitted for comparison.
17354 *
17355 * Note particularly that the indentation used in this
17356 * function  isn't according to Sun recommendations. It
17357 * is indented to make reading a bit easy.
17358 *
17359 * Return Values:
17360 *   if first == second return  0
17361 *   if first > second  return  1
17362 *   if first < second  return -1
17363 */
17364int
17365ql_wwn_cmp(ql_adapter_state_t *ha, la_wwn_t *first, la_wwn_t *second)
17366{
17367	la_wwn_t t1, t2;
17368	int rval;
17369
17370	EL(ha, "WWPN=%08x%08x\n",
17371	    BE_32(first->i_wwn[0]), BE_32(first->i_wwn[1]));
17372	EL(ha, "WWPN=%08x%08x\n",
17373	    BE_32(second->i_wwn[0]), BE_32(second->i_wwn[1]));
17374	/*
17375	 * Fibre Channel protocol is big endian, so compare
17376	 * as big endian values
17377	 */
17378	t1.i_wwn[0] = BE_32(first->i_wwn[0]);
17379	t1.i_wwn[1] = BE_32(first->i_wwn[1]);
17380
17381	t2.i_wwn[0] = BE_32(second->i_wwn[0]);
17382	t2.i_wwn[1] = BE_32(second->i_wwn[1]);
17383
17384	if (t1.i_wwn[0] == t2.i_wwn[0]) {
17385		if (t1.i_wwn[1] == t2.i_wwn[1]) {
17386			rval = 0;
17387		} else if (t1.i_wwn[1] > t2.i_wwn[1]) {
17388			rval = 1;
17389		} else {
17390			rval = -1;
17391		}
17392	} else {
17393		if (t1.i_wwn[0] > t2.i_wwn[0]) {
17394			rval = 1;
17395		} else {
17396			rval = -1;
17397		}
17398	}
17399	return (rval);
17400}
17401
17402/*
17403 * ql_wait_for_td_stop
17404 *	Wait for task daemon to stop running.  Internal command timeout
17405 *	is approximately 30 seconds, so it may help in some corner
17406 *	cases to wait that long
17407 *
17408 * Input:
17409 *	ha = adapter state pointer.
17410 *
17411 * Returns:
17412 *	DDI_SUCCESS or DDI_FAILURE.
17413 *
17414 * Context:
17415 *	Kernel context.
17416 */
17417
17418static int
17419ql_wait_for_td_stop(ql_adapter_state_t *ha)
17420{
17421	int	rval = DDI_FAILURE;
17422	UINT16	wait_cnt;
17423
17424	for (wait_cnt = 0; wait_cnt < 3000; wait_cnt++) {
17425		/* The task daemon clears the stop flag on exit. */
17426		if (ha->task_daemon_flags & TASK_DAEMON_STOP_FLG) {
17427			if (ha->cprinfo.cc_events & CALLB_CPR_START ||
17428			    ddi_in_panic()) {
17429				drv_usecwait(10000);
17430			} else {
17431				delay(drv_usectohz(10000));
17432			}
17433		} else {
17434			rval = DDI_SUCCESS;
17435			break;
17436		}
17437	}
17438	return (rval);
17439}
17440