isp.c revision 201758
1248590Smm/*-
2248590Smm *  Copyright (c) 1997-2009 by Matthew Jacob
3248590Smm *  All rights reserved.
4248590Smm *
5248590Smm *  Redistribution and use in source and binary forms, with or without
6248590Smm *  modification, are permitted provided that the following conditions
7248590Smm *  are met:
8248590Smm *
9248590Smm *  1. Redistributions of source code must retain the above copyright
10248590Smm *     notice, this list of conditions and the following disclaimer.
11248590Smm *  2. Redistributions in binary form must reproduce the above copyright
12248590Smm *     notice, this list of conditions and the following disclaimer in the
13248590Smm *     documentation and/or other materials provided with the distribution.
14248590Smm *
15248590Smm *  THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16248590Smm *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17248590Smm *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18248590Smm *  ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19248590Smm *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20248590Smm *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21248590Smm *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22248590Smm *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23248590Smm *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24248590Smm *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25248590Smm *  SUCH DAMAGE.
26248590Smm *
27248590Smm */
28248590Smm
29248590Smm/*
30248590Smm * Machine and OS Independent (well, as best as possible)
31248590Smm * code for the Qlogic ISP SCSI and FC-SCSI adapters.
32248590Smm */
33248590Smm
34248590Smm/*
35248590Smm * Inspiration and ideas about this driver are from Erik Moe's Linux driver
36248590Smm * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
37248590Smm * ideas dredged from the Solaris driver.
38248590Smm */
39248590Smm
40248590Smm/*
41248590Smm * Include header file appropriate for platform we're building on.
42248590Smm */
43248590Smm#ifdef	__NetBSD__
44248590Smm#include <sys/cdefs.h>
45248590Smm__KERNEL_RCSID(0, "$NetBSD$");
46248590Smm#include <dev/ic/isp_netbsd.h>
47248590Smm#endif
48248590Smm#ifdef	__FreeBSD__
49#include <sys/cdefs.h>
50__FBSDID("$FreeBSD: head/sys/dev/isp/isp.c 201758 2010-01-07 21:01:37Z mbr $");
51#include <dev/isp/isp_freebsd.h>
52#endif
53#ifdef	__OpenBSD__
54#include <dev/ic/isp_openbsd.h>
55#endif
56#ifdef	__linux__
57#include "isp_linux.h"
58#endif
59#ifdef	__svr4__
60#include "isp_solaris.h"
61#endif
62
63/*
64 * General defines
65 */
66#define	MBOX_DELAY_COUNT	1000000 / 100
67#define	ISP_MARK_PORTDB(a, b, c)				\
68    isp_prt(isp, ISP_LOGSANCFG, 				\
69	"Chan %d ISP_MARK_PORTDB@LINE %d", b, __LINE__);	\
70    isp_mark_portdb(a, b, c)
71
72/*
73 * Local static data
74 */
75static const char fconf[] = "Chan %d PortDB[%d] changed:\n current =(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)\n database=(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)";
76static const char notresp[] = "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
77static const char xact1[] = "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
78static const char xact2[] = "HBA attempted queued transaction to target routine %d on target %d bus %d";
79static const char xact3[] = "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
80static const char pskip[] = "SCSI phase skipped for target %d.%d.%d";
81static const char topology[] = "Chan %d WWPN 0x%08x%08x PortID 0x%06x N-Port Handle %d, Connection '%s'";
82static const char finmsg[] = "%d.%d.%d: FIN dl%d resid %ld STS 0x%x SKEY %c XS_ERR=0x%x";
83static const char sc4[] = "NVRAM";
84static const char bun[] = "bad underrun for %d.%d (count %d, resid %d, status %s)";
85static const char lipd[] = "Chan %d LIP destroyed %d active commands";
86static const char sacq[] = "unable to acquire scratch area";
87
88static const uint8_t alpa_map[] = {
89	0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda,
90	0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce,
91	0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5,
92	0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3,
93	0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
94	0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b,
95	0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81,
96	0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73,
97	0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69,
98	0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
99	0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c,
100	0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c,
101	0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
102	0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26,
103	0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
104	0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00
105};
106
107/*
108 * Local function prototypes.
109 */
110static int isp_parse_async(ispsoftc_t *, uint16_t);
111static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *);
112static void isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *); static void
113isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *);
114static void isp_fastpost_complete(ispsoftc_t *, uint16_t);
115static int isp_mbox_continue(ispsoftc_t *);
116static void isp_scsi_init(ispsoftc_t *);
117static void isp_scsi_channel_init(ispsoftc_t *, int);
118static void isp_fibre_init(ispsoftc_t *);
119static void isp_fibre_init_2400(ispsoftc_t *);
120static void isp_mark_portdb(ispsoftc_t *, int, int);
121static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int, int);
122static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t);
123static int isp_port_logout(ispsoftc_t *, uint16_t, uint32_t);
124static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *, int);
125static void isp_dump_chip_portdb(ispsoftc_t *, int, int);
126static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int);
127static int isp_fclink_test(ispsoftc_t *, int, int);
128static int isp_pdb_sync(ispsoftc_t *, int);
129static int isp_scan_loop(ispsoftc_t *, int);
130static int isp_gid_ft_sns(ispsoftc_t *, int);
131static int isp_gid_ft_ct_passthru(ispsoftc_t *, int);
132static int isp_scan_fabric(ispsoftc_t *, int);
133static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *);
134static int isp_register_fc4_type(ispsoftc_t *, int);
135static int isp_register_fc4_type_24xx(ispsoftc_t *, int);
136static uint16_t isp_nxt_handle(ispsoftc_t *, int, uint16_t);
137static void isp_fw_state(ispsoftc_t *, int);
138static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int);
139static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
140
141static void isp_spi_update(ispsoftc_t *, int);
142static void isp_setdfltsdparm(ispsoftc_t *);
143static void isp_setdfltfcparm(ispsoftc_t *, int);
144static int isp_read_nvram(ispsoftc_t *, int);
145static int isp_read_nvram_2400(ispsoftc_t *, uint8_t *);
146static void isp_rdnvram_word(ispsoftc_t *, int, uint16_t *);
147static void isp_rd_2400_nvram(ispsoftc_t *, uint32_t, uint32_t *);
148static void isp_parse_nvram_1020(ispsoftc_t *, uint8_t *);
149static void isp_parse_nvram_1080(ispsoftc_t *, int, uint8_t *);
150static void isp_parse_nvram_12160(ispsoftc_t *, int, uint8_t *);
151static void isp_parse_nvram_2100(ispsoftc_t *, uint8_t *);
152static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
153
154/*
155 * Reset Hardware.
156 *
157 * Hit the chip over the head, download new f/w if available and set it running.
158 *
159 * Locking done elsewhere.
160 */
161
162void
163isp_reset(ispsoftc_t *isp, int do_load_defaults)
164{
165	mbreg_t mbs;
166	uint32_t code_org, val;
167	int loops, i, dodnld = 1;
168	const char *btype = "????";
169	static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
170
171	isp->isp_state = ISP_NILSTATE;
172	if (isp->isp_dead) {
173		isp_shutdown(isp);
174		ISP_DISABLE_INTS(isp);
175		return;
176	}
177
178	/*
179	 * Basic types (SCSI, FibreChannel and PCI or SBus)
180	 * have been set in the MD code. We figure out more
181	 * here. Possibly more refined types based upon PCI
182	 * identification. Chip revision has been gathered.
183	 *
184	 * After we've fired this chip up, zero out the conf1 register
185	 * for SCSI adapters and do other settings for the 2100.
186	 */
187
188	ISP_DISABLE_INTS(isp);
189
190	/*
191	 * Pick an initial maxcmds value which will be used
192	 * to allocate xflist pointer space. It may be changed
193	 * later by the firmware.
194	 */
195	if (IS_24XX(isp)) {
196		isp->isp_maxcmds = 4096;
197	} else if (IS_2322(isp)) {
198		isp->isp_maxcmds = 2048;
199	} else if (IS_23XX(isp) || IS_2200(isp)) {
200		isp->isp_maxcmds = 1024;
201 	} else {
202		isp->isp_maxcmds = 512;
203	}
204
205	/*
206	 * Set up DMA for the request and response queues.
207	 *
208	 * We do this now so we can use the request queue
209	 * for dma to load firmware from.
210	 */
211	if (ISP_MBOXDMASETUP(isp) != 0) {
212		isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
213		return;
214	}
215
216	/*
217	 * Set up default request/response queue in-pointer/out-pointer
218	 * register indices.
219	 */
220	if (IS_24XX(isp)) {
221		isp->isp_rqstinrp = BIU2400_REQINP;
222		isp->isp_rqstoutrp = BIU2400_REQOUTP;
223		isp->isp_respinrp = BIU2400_RSPINP;
224		isp->isp_respoutrp = BIU2400_RSPOUTP;
225	} else if (IS_23XX(isp)) {
226		isp->isp_rqstinrp = BIU_REQINP;
227		isp->isp_rqstoutrp = BIU_REQOUTP;
228		isp->isp_respinrp = BIU_RSPINP;
229		isp->isp_respoutrp = BIU_RSPOUTP;
230	} else {
231		isp->isp_rqstinrp = INMAILBOX4;
232		isp->isp_rqstoutrp = OUTMAILBOX4;
233		isp->isp_respinrp = OUTMAILBOX5;
234		isp->isp_respoutrp = INMAILBOX5;
235	}
236
237	/*
238	 * Put the board into PAUSE mode (so we can read the SXP registers
239	 * or write FPM/FBM registers).
240	 */
241	if (IS_24XX(isp)) {
242		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT);
243		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
244		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
245	} else {
246		ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
247	}
248
249	if (IS_FC(isp)) {
250		switch (isp->isp_type) {
251		case ISP_HA_FC_2100:
252			btype = "2100";
253			break;
254		case ISP_HA_FC_2200:
255			btype = "2200";
256			break;
257		case ISP_HA_FC_2300:
258			btype = "2300";
259			break;
260		case ISP_HA_FC_2312:
261			btype = "2312";
262			break;
263		case ISP_HA_FC_2322:
264			btype = "2322";
265			break;
266		case ISP_HA_FC_2400:
267			btype = "2422";
268			break;
269		case ISP_HA_FC_2500:
270			btype = "2532";
271			break;
272		default:
273			break;
274		}
275
276		if (!IS_24XX(isp)) {
277			/*
278			 * While we're paused, reset the FPM module and FBM
279			 * fifos.
280			 */
281			ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
282			ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
283			ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
284			ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
285			ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
286		}
287	} else if (IS_1240(isp)) {
288		sdparam *sdp;
289
290		btype = "1240";
291		isp->isp_clock = 60;
292		sdp = SDPARAM(isp, 0);
293		sdp->isp_ultramode = 1;
294		sdp = SDPARAM(isp, 1);
295		sdp->isp_ultramode = 1;
296		/*
297		 * XXX: Should probably do some bus sensing.
298		 */
299	} else if (IS_ULTRA3(isp)) {
300		sdparam *sdp = isp->isp_param;
301
302		isp->isp_clock = 100;
303
304		if (IS_10160(isp))
305			btype = "10160";
306		else if (IS_12160(isp))
307			btype = "12160";
308		else
309			btype = "<UNKLVD>";
310		sdp->isp_lvdmode = 1;
311
312		if (IS_DUALBUS(isp)) {
313			sdp++;
314			sdp->isp_lvdmode = 1;
315		}
316	} else if (IS_ULTRA2(isp)) {
317		static const char m[] = "bus %d is in %s Mode";
318		uint16_t l;
319		sdparam *sdp = SDPARAM(isp, 0);
320
321		isp->isp_clock = 100;
322
323		if (IS_1280(isp))
324			btype = "1280";
325		else if (IS_1080(isp))
326			btype = "1080";
327		else
328			btype = "<UNKLVD>";
329
330		l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
331		switch (l) {
332		case ISP1080_LVD_MODE:
333			sdp->isp_lvdmode = 1;
334			isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD");
335			break;
336		case ISP1080_HVD_MODE:
337			sdp->isp_diffmode = 1;
338			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential");
339			break;
340		case ISP1080_SE_MODE:
341			sdp->isp_ultramode = 1;
342			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended");
343			break;
344		default:
345			isp_prt(isp, ISP_LOGERR,
346			    "unknown mode on bus %d (0x%x)", 0, l);
347			break;
348		}
349
350		if (IS_DUALBUS(isp)) {
351			sdp = SDPARAM(isp, 1);
352			l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
353			l &= ISP1080_MODE_MASK;
354			switch (l) {
355			case ISP1080_LVD_MODE:
356				sdp->isp_lvdmode = 1;
357				isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
358				break;
359			case ISP1080_HVD_MODE:
360				sdp->isp_diffmode = 1;
361				isp_prt(isp, ISP_LOGCONFIG,
362				    m, 1, "Differential");
363				break;
364			case ISP1080_SE_MODE:
365				sdp->isp_ultramode = 1;
366				isp_prt(isp, ISP_LOGCONFIG,
367				    m, 1, "Single-Ended");
368				break;
369			default:
370				isp_prt(isp, ISP_LOGERR,
371				    "unknown mode on bus %d (0x%x)", 1, l);
372				break;
373			}
374		}
375	} else {
376		sdparam *sdp = SDPARAM(isp, 0);
377		i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
378		switch (i) {
379		default:
380			isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
381			/* FALLTHROUGH */
382		case 1:
383			btype = "1020";
384			isp->isp_type = ISP_HA_SCSI_1020;
385			isp->isp_clock = 40;
386			break;
387		case 2:
388			/*
389			 * Some 1020A chips are Ultra Capable, but don't
390			 * run the clock rate up for that unless told to
391			 * do so by the Ultra Capable bits being set.
392			 */
393			btype = "1020A";
394			isp->isp_type = ISP_HA_SCSI_1020A;
395			isp->isp_clock = 40;
396			break;
397		case 3:
398			btype = "1040";
399			isp->isp_type = ISP_HA_SCSI_1040;
400			isp->isp_clock = 60;
401			break;
402		case 4:
403			btype = "1040A";
404			isp->isp_type = ISP_HA_SCSI_1040A;
405			isp->isp_clock = 60;
406			break;
407		case 5:
408			btype = "1040B";
409			isp->isp_type = ISP_HA_SCSI_1040B;
410			isp->isp_clock = 60;
411			break;
412		case 6:
413			btype = "1040C";
414			isp->isp_type = ISP_HA_SCSI_1040C;
415			isp->isp_clock = 60;
416                        break;
417		}
418		/*
419		 * Now, while we're at it, gather info about ultra
420		 * and/or differential mode.
421		 */
422		if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
423			isp_prt(isp, ISP_LOGCONFIG, "Differential Mode");
424			sdp->isp_diffmode = 1;
425		} else {
426			sdp->isp_diffmode = 0;
427		}
428		i = ISP_READ(isp, RISC_PSR);
429		if (isp->isp_bustype == ISP_BT_SBUS) {
430			i &= RISC_PSR_SBUS_ULTRA;
431		} else {
432			i &= RISC_PSR_PCI_ULTRA;
433		}
434		if (i != 0) {
435			isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable");
436			sdp->isp_ultramode = 1;
437			/*
438			 * If we're in Ultra Mode, we have to be 60MHz clock-
439			 * even for the SBus version.
440			 */
441			isp->isp_clock = 60;
442		} else {
443			sdp->isp_ultramode = 0;
444			/*
445			 * Clock is known. Gronk.
446			 */
447		}
448
449		/*
450		 * Machine dependent clock (if set) overrides
451		 * our generic determinations.
452		 */
453		if (isp->isp_mdvec->dv_clock) {
454			if (isp->isp_mdvec->dv_clock < isp->isp_clock) {
455				isp->isp_clock = isp->isp_mdvec->dv_clock;
456			}
457		}
458
459	}
460
461	/*
462	 * Clear instrumentation
463	 */
464	isp->isp_intcnt = isp->isp_intbogus = 0;
465
466	/*
467	 * Do MD specific pre initialization
468	 */
469	ISP_RESET0(isp);
470
471	/*
472	 * Hit the chip over the head with hammer,
473	 * and give it a chance to recover.
474	 */
475
476	if (IS_SCSI(isp)) {
477		ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
478		/*
479		 * A slight delay...
480		 */
481		ISP_DELAY(100);
482
483		/*
484		 * Clear data && control DMA engines.
485		 */
486		ISP_WRITE(isp, CDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
487		ISP_WRITE(isp, DDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
488
489
490	} else if (IS_24XX(isp)) {
491		/*
492		 * Stop DMA and wait for it to stop.
493		 */
494		ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
495		for (val = loops = 0; loops < 30000; loops++) {
496			ISP_DELAY(10);
497			val = ISP_READ(isp, BIU2400_CSR);
498			if ((val & BIU2400_DMA_ACTIVE) == 0) {
499				break;
500			}
501		}
502		if (val & BIU2400_DMA_ACTIVE) {
503			ISP_RESET0(isp);
504			isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
505			return;
506		}
507		/*
508		 * Hold it in SOFT_RESET and STOP state for 100us.
509		 */
510		ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
511		ISP_DELAY(100);
512		for (loops = 0; loops < 10000; loops++) {
513			ISP_DELAY(5);
514			val = ISP_READ(isp, OUTMAILBOX0);
515		}
516		for (val = loops = 0; loops < 500000; loops ++) {
517			val = ISP_READ(isp, BIU2400_CSR);
518			if ((val & BIU2400_SOFT_RESET) == 0) {
519				break;
520			}
521		}
522		if (val & BIU2400_SOFT_RESET) {
523			ISP_RESET0(isp);
524			isp_prt(isp, ISP_LOGERR, "Failed to come out of reset");
525			return;
526		}
527	} else {
528		ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
529		/*
530		 * A slight delay...
531		 */
532		ISP_DELAY(100);
533
534		/*
535		 * Clear data && control DMA engines.
536		 */
537		ISP_WRITE(isp, CDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
538		ISP_WRITE(isp, TDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
539		ISP_WRITE(isp, RDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
540	}
541
542	/*
543	 * Wait for ISP to be ready to go...
544	 */
545	loops = MBOX_DELAY_COUNT;
546	for (;;) {
547		if (IS_SCSI(isp)) {
548			if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET)) {
549				break;
550			}
551		} else if (IS_24XX(isp)) {
552			if (ISP_READ(isp, OUTMAILBOX0) == 0) {
553				break;
554			}
555		} else {
556			if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
557				break;
558		}
559		ISP_DELAY(100);
560		if (--loops < 0) {
561			ISP_DUMPREGS(isp, "chip reset timed out");
562			ISP_RESET0(isp);
563			return;
564		}
565	}
566
567	/*
568	 * After we've fired this chip up, zero out the conf1 register
569	 * for SCSI adapters and other settings for the 2100.
570	 */
571
572	if (IS_SCSI(isp)) {
573		ISP_WRITE(isp, BIU_CONF1, 0);
574	} else if (!IS_24XX(isp)) {
575		ISP_WRITE(isp, BIU2100_CSR, 0);
576	}
577
578	/*
579	 * Reset RISC Processor
580	 */
581	if (IS_24XX(isp)) {
582		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
583		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE);
584		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
585	} else {
586		ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
587		ISP_DELAY(100);
588		ISP_WRITE(isp, BIU_SEMA, 0);
589	}
590
591	/*
592	 * Post-RISC Reset stuff.
593	 */
594	if (IS_24XX(isp)) {
595		for (val = loops = 0; loops < 5000000; loops++) {
596			ISP_DELAY(5);
597			val = ISP_READ(isp, OUTMAILBOX0);
598			if (val == 0) {
599				break;
600			}
601		}
602		if (val != 0) {
603			ISP_RESET0(isp);
604			isp_prt(isp, ISP_LOGERR, "reset didn't clear");
605			return;
606		}
607	} else if (IS_SCSI(isp)) {
608		uint16_t tmp = isp->isp_mdvec->dv_conf1;
609		/*
610		 * Busted FIFO. Turn off all but burst enables.
611		 */
612		if (isp->isp_type == ISP_HA_SCSI_1040A) {
613			tmp &= BIU_BURST_ENABLE;
614		}
615		ISP_SETBITS(isp, BIU_CONF1, tmp);
616		if (tmp & BIU_BURST_ENABLE) {
617			ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
618			ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
619		}
620		if (SDPARAM(isp, 0)->isp_ptisp) {
621			if (SDPARAM(isp, 0)->isp_ultramode) {
622				while (ISP_READ(isp, RISC_MTR) != 0x1313) {
623					ISP_WRITE(isp, RISC_MTR, 0x1313);
624					ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
625				}
626			} else {
627				ISP_WRITE(isp, RISC_MTR, 0x1212);
628			}
629			/*
630			 * PTI specific register
631			 */
632			ISP_WRITE(isp, RISC_EMB, DUAL_BANK);
633		} else {
634			ISP_WRITE(isp, RISC_MTR, 0x1212);
635		}
636		ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
637	} else {
638		ISP_WRITE(isp, RISC_MTR2100, 0x1212);
639		if (IS_2200(isp) || IS_23XX(isp)) {
640			ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
641		}
642		ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
643	}
644
645	ISP_WRITE(isp, isp->isp_rqstinrp, 0);
646	ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
647	ISP_WRITE(isp, isp->isp_respinrp, 0);
648	ISP_WRITE(isp, isp->isp_respoutrp, 0);
649	if (IS_24XX(isp)) {
650		ISP_WRITE(isp, BIU2400_PRI_REQINP, 0);
651		ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0);
652		ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0);
653		ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
654	}
655
656	/*
657	 * Do MD specific post initialization
658	 */
659	ISP_RESET1(isp);
660
661	/*
662	 * Wait for everything to finish firing up.
663	 *
664	 * Avoid doing this on early 2312s because you can generate a PCI
665	 * parity error (chip breakage).
666	 */
667	if (IS_2312(isp) && isp->isp_revision < 2) {
668		ISP_DELAY(100);
669	} else {
670		loops = MBOX_DELAY_COUNT;
671		while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
672			ISP_DELAY(100);
673			if (--loops < 0) {
674				ISP_RESET0(isp);
675				isp_prt(isp, ISP_LOGERR,
676				    "MBOX_BUSY never cleared on reset");
677				return;
678			}
679		}
680	}
681
682	/*
683	 * Up until this point we've done everything by just reading or
684	 * setting registers. From this point on we rely on at least *some*
685	 * kind of firmware running in the card.
686	 */
687
688	/*
689	 * Do some sanity checking by running a NOP command.
690	 * If it succeeds, the ROM firmware is now running.
691	 */
692	ISP_MEMZERO(&mbs, sizeof (mbs));
693	mbs.param[0] = MBOX_NO_OP;
694	mbs.logval = MBLOGALL;
695	isp_mboxcmd(isp, &mbs);
696	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
697		isp_prt(isp, ISP_LOGERR, "NOP ommand failed (%x)", mbs.param[0]);
698		ISP_RESET0(isp);
699		return;
700	}
701
702	/*
703	 * Do some operational tests
704	 */
705
706	if (IS_SCSI(isp) || IS_24XX(isp)) {
707		ISP_MEMZERO(&mbs, sizeof (mbs));
708		mbs.param[0] = MBOX_MAILBOX_REG_TEST;
709		mbs.param[1] = 0xdead;
710		mbs.param[2] = 0xbeef;
711		mbs.param[3] = 0xffff;
712		mbs.param[4] = 0x1111;
713		mbs.param[5] = 0xa5a5;
714		mbs.param[6] = 0x0000;
715		mbs.param[7] = 0x0000;
716		mbs.logval = MBLOGALL;
717		isp_mboxcmd(isp, &mbs);
718		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
719			ISP_RESET0(isp);
720			return;
721		}
722		if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
723		    mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
724		    mbs.param[5] != 0xa5a5) {
725			ISP_RESET0(isp);
726			isp_prt(isp, ISP_LOGERR, "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)", mbs.param[1], mbs.param[2], mbs.param[3], mbs.param[4], mbs.param[5]);
727			return;
728		}
729
730	}
731
732	/*
733	 * Download new Firmware, unless requested not to do so.
734	 * This is made slightly trickier in some cases where the
735	 * firmware of the ROM revision is newer than the revision
736	 * compiled into the driver. So, where we used to compare
737	 * versions of our f/w and the ROM f/w, now we just see
738	 * whether we have f/w at all and whether a config flag
739	 * has disabled our download.
740	 */
741	if ((isp->isp_mdvec->dv_ispfw == NULL) || (isp->isp_confopts & ISP_CFG_NORELOAD)) {
742		dodnld = 0;
743	}
744
745	if (IS_24XX(isp)) {
746		code_org = ISP_CODE_ORG_2400;
747	} else if (IS_23XX(isp)) {
748		code_org = ISP_CODE_ORG_2300;
749	} else {
750		code_org = ISP_CODE_ORG;
751	}
752
753	if (dodnld && IS_24XX(isp)) {
754		const uint32_t *ptr = isp->isp_mdvec->dv_ispfw;
755
756		/*
757		 * Keep loading until we run out of f/w.
758		 */
759		code_org = ptr[2];	/* 1st load address is our start addr */
760
761		for (;;) {
762			uint32_t la, wi, wl;
763
764			isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], ptr[2]);
765
766			wi = 0;
767			la = ptr[2];
768			wl = ptr[3];
769
770			while (wi < ptr[3]) {
771				uint32_t *cp;
772				uint32_t nw;
773
774				nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 2;
775				if (nw > wl) {
776					nw = wl;
777				}
778				cp = isp->isp_rquest;
779				for (i = 0; i < nw; i++) {
780					ISP_IOXPUT_32(isp,  ptr[wi++], &cp[i]);
781					wl--;
782				}
783				MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
784				ISP_MEMZERO(&mbs, sizeof (mbs));
785				if (la < 0x10000 && nw < 0x10000) {
786					mbs.param[0] = MBOX_LOAD_RISC_RAM_2100;
787					mbs.param[1] = la;
788					mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
789					mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
790					mbs.param[4] = nw;
791					mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
792					mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
793				} else {
794					mbs.param[0] = MBOX_LOAD_RISC_RAM;
795					mbs.param[1] = la;
796					mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
797					mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
798					mbs.param[4] = nw >> 16;
799					mbs.param[5] = nw;
800					mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
801					mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
802					mbs.param[8] = la >> 16;
803				}
804				mbs.logval = MBLOGALL;
805				isp_mboxcmd(isp, &mbs);
806				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
807					isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
808					ISP_RESET0(isp);
809					return;
810				}
811				la += nw;
812			}
813
814			if (ptr[1] == 0) {
815				break;
816			}
817			ptr += ptr[3];
818		}
819		isp->isp_loaded_fw = 1;
820	} else if (dodnld && IS_23XX(isp)) {
821		const uint16_t *ptr = isp->isp_mdvec->dv_ispfw;
822		uint16_t wi, wl, segno;
823		uint32_t la;
824
825		la = code_org;
826		segno = 0;
827
828		for (;;) {
829			uint32_t nxtaddr;
830
831			isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], la);
832
833			wi = 0;
834			wl = ptr[3];
835
836			while (wi < ptr[3]) {
837				uint16_t *cp;
838				uint16_t nw;
839
840				nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 1;
841				if (nw > wl) {
842					nw = wl;
843				}
844				if (nw > (1 << 15)) {
845					nw = 1 << 15;
846				}
847				cp = isp->isp_rquest;
848				for (i = 0; i < nw; i++) {
849					ISP_IOXPUT_16(isp,  ptr[wi++], &cp[i]);
850					wl--;
851				}
852				MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
853				ISP_MEMZERO(&mbs, sizeof (mbs));
854				if (la < 0x10000) {
855					mbs.param[0] = MBOX_LOAD_RISC_RAM_2100;
856					mbs.param[1] = la;
857					mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
858					mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
859					mbs.param[4] = nw;
860					mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
861					mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
862				} else {
863					mbs.param[0] = MBOX_LOAD_RISC_RAM;
864					mbs.param[1] = la;
865					mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
866					mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
867					mbs.param[4] = nw;
868					mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
869					mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
870					mbs.param[8] = la >> 16;
871				}
872				mbs.logval = MBLOGALL;
873				isp_mboxcmd(isp, &mbs);
874				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
875					isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
876					ISP_RESET0(isp);
877					return;
878				}
879				la += nw;
880			}
881
882			if (!IS_2322(isp)) {
883				break;
884			}
885
886			if (++segno == 3) {
887				break;
888			}
889
890			/*
891			 * If we're a 2322, the firmware actually comes in
892			 * three chunks. We loaded the first at the code_org
893			 * address. The other two chunks, which follow right
894			 * after each other in memory here, get loaded at
895			 * addresses specfied at offset 0x9..0xB.
896			 */
897
898			nxtaddr = ptr[3];
899			ptr = &ptr[nxtaddr];
900			la = ptr[5] | ((ptr[4] & 0x3f) << 16);
901		}
902		isp->isp_loaded_fw = 1;
903	} else if (dodnld) {
904		union {
905			const uint16_t *cp;
906			uint16_t *np;
907		} ucd;
908		ucd.cp = isp->isp_mdvec->dv_ispfw;
909		isp->isp_mbxworkp = &ucd.np[1];
910		isp->isp_mbxwrk0 = ucd.np[3] - 1;
911		isp->isp_mbxwrk1 = code_org + 1;
912		ISP_MEMZERO(&mbs, sizeof (mbs));
913		mbs.param[0] = MBOX_WRITE_RAM_WORD;
914		mbs.param[1] = code_org;
915		mbs.param[2] = ucd.np[0];
916		mbs.logval = MBLOGNONE;
917		isp_mboxcmd(isp, &mbs);
918		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
919			isp_prt(isp, ISP_LOGERR, "F/W download failed at word %d", isp->isp_mbxwrk1 - code_org);
920			ISP_RESET0(isp);
921			return;
922		}
923	} else {
924		isp->isp_loaded_fw = 0;
925		isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
926	}
927
928	/*
929	 * If we loaded firmware, verify its checksum
930	 */
931	if (isp->isp_loaded_fw) {
932		ISP_MEMZERO(&mbs, sizeof (mbs));
933		mbs.param[0] = MBOX_VERIFY_CHECKSUM;
934		if (IS_24XX(isp)) {
935			mbs.param[1] = code_org >> 16;
936			mbs.param[2] = code_org;
937		} else {
938			mbs.param[1] = code_org;
939		}
940		isp_mboxcmd(isp, &mbs);
941		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
942			isp_prt(isp, ISP_LOGERR, dcrc);
943			ISP_RESET0(isp);
944			return;
945		}
946	}
947
948	/*
949	 * Now start it rolling.
950	 *
951	 * If we didn't actually download f/w,
952	 * we still need to (re)start it.
953	 */
954
955
956	MBSINIT(&mbs, MBOX_EXEC_FIRMWARE, MBLOGALL, 1000000);
957	if (IS_24XX(isp)) {
958		mbs.param[1] = code_org >> 16;
959		mbs.param[2] = code_org;
960		if (isp->isp_loaded_fw) {
961			mbs.param[3] = 0;
962		} else {
963			mbs.param[3] = 1;
964		}
965		if (IS_25XX(isp)) {
966			mbs.ibits |= 0x10;
967		}
968	} else if (IS_2322(isp)) {
969		mbs.param[1] = code_org;
970		if (isp->isp_loaded_fw) {
971			mbs.param[2] = 0;
972		} else {
973			mbs.param[2] = 1;
974		}
975	} else {
976		mbs.param[1] = code_org;
977	}
978	isp_mboxcmd(isp, &mbs);
979	if (IS_2322(isp) || IS_24XX(isp)) {
980		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
981			ISP_RESET0(isp);
982			return;
983		}
984	}
985
986	/*
987	 * Give it a chance to finish starting up.
988	 * Give the 24XX more time.
989	 */
990	if (IS_24XX(isp)) {
991		ISP_DELAY(500000);
992		/*
993		 * Check to see if the 24XX firmware really started.
994		 */
995		if (mbs.param[1] == 0xdead) {
996			isp_prt(isp, ISP_LOGERR, "f/w didn't *really* start");
997			ISP_RESET0(isp);
998			return;
999		}
1000	} else {
1001		ISP_DELAY(250000);
1002		if (IS_SCSI(isp)) {
1003			/*
1004			 * Set CLOCK RATE, but only if asked to.
1005			 */
1006			if (isp->isp_clock) {
1007				mbs.param[0] = MBOX_SET_CLOCK_RATE;
1008				mbs.param[1] = isp->isp_clock;
1009				mbs.logval = MBLOGNONE;
1010				isp_mboxcmd(isp, &mbs);
1011				/* we will try not to care if this fails */
1012			}
1013		}
1014	}
1015
1016	/*
1017	 * Ask the chip for the current firmware version.
1018	 * This should prove that the new firmware is working.
1019	 */
1020	MBSINIT(&mbs, MBOX_ABOUT_FIRMWARE, MBLOGALL, 0);
1021	isp_mboxcmd(isp, &mbs);
1022	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1023		ISP_RESET0(isp);
1024		return;
1025	}
1026
1027	/*
1028	 * The SBus firmware that we are using apparently does not return
1029	 * major, minor, micro revisions in the mailbox registers, which
1030	 * is really, really, annoying.
1031	 */
1032	if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {
1033		if (dodnld) {
1034#ifdef	ISP_TARGET_MODE
1035			isp->isp_fwrev[0] = 7;
1036			isp->isp_fwrev[1] = 55;
1037#else
1038			isp->isp_fwrev[0] = 1;
1039			isp->isp_fwrev[1] = 37;
1040#endif
1041			isp->isp_fwrev[2] = 0;
1042		}
1043	} else {
1044		isp->isp_fwrev[0] = mbs.param[1];
1045		isp->isp_fwrev[1] = mbs.param[2];
1046		isp->isp_fwrev[2] = mbs.param[3];
1047	}
1048
1049	isp_prt(isp, ISP_LOGCONFIG, "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
1050	    btype, isp->isp_revision, dodnld? "loaded" : "resident", isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
1051
1052	if (IS_FC(isp)) {
1053		/*
1054		 * We do not believe firmware attributes for 2100 code less
1055		 * than 1.17.0, unless it's the firmware we specifically
1056		 * are loading.
1057		 *
1058		 * Note that all 22XX and later f/w is greater than 1.X.0.
1059		 */
1060		if ((ISP_FW_OLDER_THAN(isp, 1, 17, 1))) {
1061#ifdef	USE_SMALLER_2100_FIRMWARE
1062			isp->isp_fwattr = ISP_FW_ATTR_SCCLUN;
1063#else
1064			isp->isp_fwattr = 0;
1065#endif
1066		} else {
1067			isp->isp_fwattr = mbs.param[6];
1068			isp_prt(isp, ISP_LOGDEBUG0, "Firmware Attributes = 0x%x", mbs.param[6]);
1069		}
1070	} else {
1071#ifndef	ISP_TARGET_MODE
1072		isp->isp_fwattr = ISP_FW_ATTR_TMODE;
1073#else
1074		isp->isp_fwattr = 0;
1075#endif
1076	}
1077
1078	if (!IS_24XX(isp)) {
1079		MBSINIT(&mbs, MBOX_GET_FIRMWARE_STATUS, MBLOGALL, 0);
1080		isp_mboxcmd(isp, &mbs);
1081		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1082			ISP_RESET0(isp);
1083			return;
1084		}
1085		if (isp->isp_maxcmds >= mbs.param[2]) {
1086			isp->isp_maxcmds = mbs.param[2];
1087		}
1088	}
1089	isp_prt(isp, ISP_LOGCONFIG, "%d max I/O command limit set", isp->isp_maxcmds);
1090
1091	/*
1092	 * If we don't have Multi-ID f/w loaded, we need to restrict channels to one.
1093	 * Only make this check for non-SCSI cards (I'm not sure firmware attributes
1094	 * work for them).
1095	 */
1096	if (IS_FC(isp) && ISP_CAP_MULTI_ID(isp) == 0 && isp->isp_nchan > 1) {
1097		isp_prt(isp, ISP_LOGWARN, "non-MULTIID f/w loaded, only can enable 1 of %d channels", isp->isp_nchan);
1098		isp->isp_nchan = 1;
1099	}
1100
1101	for (i = 0; i < isp->isp_nchan; i++) {
1102		isp_fw_state(isp, i);
1103	}
1104	if (isp->isp_dead) {
1105		isp_shutdown(isp);
1106		ISP_DISABLE_INTS(isp);
1107		return;
1108	}
1109
1110	isp->isp_state = ISP_RESETSTATE;
1111
1112	/*
1113	 * Okay- now that we have new firmware running, we now (re)set our
1114	 * notion of how many luns we support. This is somewhat tricky because
1115	 * if we haven't loaded firmware, we sometimes do not have an easy way
1116	 * of knowing how many luns we support.
1117	 *
1118	 * Expanded lun firmware gives you 32 luns for SCSI cards and
1119	 * 16384 luns for Fibre Channel cards.
1120	 *
1121	 * It turns out that even for QLogic 2100s with ROM 1.10 and above
1122	 * we do get a firmware attributes word returned in mailbox register 6.
1123	 *
1124	 * Because the lun is in a different position in the Request Queue
1125	 * Entry structure for Fibre Channel with expanded lun firmware, we
1126	 * can only support one lun (lun zero) when we don't know what kind
1127	 * of firmware we're running.
1128	 */
1129	if (IS_SCSI(isp)) {
1130		if (dodnld) {
1131			if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) {
1132				isp->isp_maxluns = 32;
1133			} else {
1134				isp->isp_maxluns = 8;
1135			}
1136		} else {
1137			isp->isp_maxluns = 8;
1138		}
1139	} else {
1140		if (ISP_CAP_SCCFW(isp)) {
1141			isp->isp_maxluns = 16384;
1142		} else {
1143			isp->isp_maxluns = 16;
1144		}
1145	}
1146
1147	/*
1148	 * We get some default values established. As a side
1149	 * effect, NVRAM is read here (unless overriden by
1150	 * a configuration flag).
1151	 */
1152	if (do_load_defaults) {
1153		if (IS_SCSI(isp)) {
1154			isp_setdfltsdparm(isp);
1155		} else {
1156			for (i = 0; i < isp->isp_nchan; i++) {
1157				isp_setdfltfcparm(isp, i);
1158			}
1159		}
1160	}
1161}
1162
1163/*
1164 * Initialize Parameters of Hardware to a known state.
1165 *
1166 * Locks are held before coming here.
1167 */
1168
1169void
1170isp_init(ispsoftc_t *isp)
1171{
1172	if (IS_FC(isp)) {
1173		if (IS_24XX(isp)) {
1174			isp_fibre_init_2400(isp);
1175		} else {
1176			isp_fibre_init(isp);
1177		}
1178	} else {
1179		isp_scsi_init(isp);
1180	}
1181	GET_NANOTIME(&isp->isp_init_time);
1182}
1183
1184static void
1185isp_scsi_init(ispsoftc_t *isp)
1186{
1187	sdparam *sdp_chan0, *sdp_chan1;
1188	mbreg_t mbs;
1189
1190	sdp_chan0 = SDPARAM(isp, 0);
1191	sdp_chan1 = sdp_chan0;
1192	if (IS_DUALBUS(isp)) {
1193		sdp_chan1 = SDPARAM(isp, 1);
1194	}
1195
1196	/* First do overall per-card settings. */
1197
1198	/*
1199	 * If we have fast memory timing enabled, turn it on.
1200	 */
1201	if (sdp_chan0->isp_fast_mttr) {
1202		ISP_WRITE(isp, RISC_MTR, 0x1313);
1203	}
1204
1205	/*
1206	 * Set Retry Delay and Count.
1207	 * You set both channels at the same time.
1208	 */
1209	MBSINIT(&mbs, MBOX_SET_RETRY_COUNT, MBLOGALL, 0);
1210	mbs.param[1] = sdp_chan0->isp_retry_count;
1211	mbs.param[2] = sdp_chan0->isp_retry_delay;
1212	mbs.param[6] = sdp_chan1->isp_retry_count;
1213	mbs.param[7] = sdp_chan1->isp_retry_delay;
1214	isp_mboxcmd(isp, &mbs);
1215	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1216		return;
1217	}
1218
1219	/*
1220	 * Set ASYNC DATA SETUP time. This is very important.
1221	 */
1222	MBSINIT(&mbs, MBOX_SET_ASYNC_DATA_SETUP_TIME, MBLOGALL, 0);
1223	mbs.param[1] = sdp_chan0->isp_async_data_setup;
1224	mbs.param[2] = sdp_chan1->isp_async_data_setup;
1225	isp_mboxcmd(isp, &mbs);
1226	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1227		return;
1228	}
1229
1230	/*
1231	 * Set ACTIVE Negation State.
1232	 */
1233	MBSINIT(&mbs, MBOX_SET_ACT_NEG_STATE, MBLOGNONE, 0);
1234	mbs.param[1] =
1235	    (sdp_chan0->isp_req_ack_active_neg << 4) |
1236	    (sdp_chan0->isp_data_line_active_neg << 5);
1237	mbs.param[2] =
1238	    (sdp_chan1->isp_req_ack_active_neg << 4) |
1239	    (sdp_chan1->isp_data_line_active_neg << 5);
1240	isp_mboxcmd(isp, &mbs);
1241	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1242		isp_prt(isp, ISP_LOGERR,
1243		    "failed to set active negation state (%d,%d), (%d,%d)",
1244		    sdp_chan0->isp_req_ack_active_neg,
1245		    sdp_chan0->isp_data_line_active_neg,
1246		    sdp_chan1->isp_req_ack_active_neg,
1247		    sdp_chan1->isp_data_line_active_neg);
1248		/*
1249		 * But don't return.
1250		 */
1251	}
1252
1253	/*
1254	 * Set the Tag Aging limit
1255	 */
1256	MBSINIT(&mbs, MBOX_SET_TAG_AGE_LIMIT, MBLOGALL, 0);
1257	mbs.param[1] = sdp_chan0->isp_tag_aging;
1258	mbs.param[2] = sdp_chan1->isp_tag_aging;
1259	isp_mboxcmd(isp, &mbs);
1260	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1261		isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
1262		    sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
1263		return;
1264	}
1265
1266	/*
1267	 * Set selection timeout.
1268	 */
1269	MBSINIT(&mbs, MBOX_SET_SELECT_TIMEOUT, MBLOGALL, 0);
1270	mbs.param[1] = sdp_chan0->isp_selection_timeout;
1271	mbs.param[2] = sdp_chan1->isp_selection_timeout;
1272	isp_mboxcmd(isp, &mbs);
1273	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1274		return;
1275	}
1276
1277	/* now do per-channel settings */
1278	isp_scsi_channel_init(isp, 0);
1279	if (IS_DUALBUS(isp))
1280		isp_scsi_channel_init(isp, 1);
1281
1282	/*
1283	 * Now enable request/response queues
1284	 */
1285
1286	if (IS_ULTRA2(isp) || IS_1240(isp)) {
1287		MBSINIT(&mbs, MBOX_INIT_RES_QUEUE_A64, MBLOGALL, 0);
1288		mbs.param[1] = RESULT_QUEUE_LEN(isp);
1289		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
1290		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
1291		mbs.param[4] = 0;
1292		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
1293		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
1294		isp_mboxcmd(isp, &mbs);
1295		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1296			return;
1297		}
1298		isp->isp_residx = mbs.param[5];
1299
1300		MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE_A64, MBLOGALL, 0);
1301		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
1302		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
1303		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
1304		mbs.param[5] = 0;
1305		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
1306		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
1307		isp_mboxcmd(isp, &mbs);
1308		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1309			return;
1310		}
1311		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
1312	} else {
1313		MBSINIT(&mbs, MBOX_INIT_RES_QUEUE, MBLOGALL, 0);
1314		mbs.param[1] = RESULT_QUEUE_LEN(isp);
1315		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
1316		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
1317		mbs.param[4] = 0;
1318		isp_mboxcmd(isp, &mbs);
1319		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1320			return;
1321		}
1322		isp->isp_residx = mbs.param[5];
1323
1324		MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE, MBLOGALL, 0);
1325		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
1326		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
1327		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
1328		mbs.param[5] = 0;
1329		isp_mboxcmd(isp, &mbs);
1330		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1331			return;
1332		}
1333		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
1334	}
1335
1336	/*
1337	 * Turn on Fast Posting, LVD transitions
1338	 *
1339	 * Ultra2 F/W always has had fast posting (and LVD transitions)
1340	 *
1341	 * Ultra and older (i.e., SBus) cards may not. It's just safer
1342	 * to assume not for them.
1343	 */
1344
1345	MBSINIT(&mbs, MBOX_SET_FW_FEATURES, MBLOGALL, 0);
1346	if (IS_ULTRA2(isp))
1347		mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
1348#ifndef	ISP_NO_RIO
1349	if (IS_ULTRA2(isp) || IS_1240(isp))
1350		mbs.param[1] |= FW_FEATURE_RIO_16BIT;
1351#else
1352	if (IS_ULTRA2(isp) || IS_1240(isp))
1353		mbs.param[1] |= FW_FEATURE_FAST_POST;
1354#endif
1355	if (mbs.param[1] != 0) {
1356		uint16_t sfeat = mbs.param[1];
1357		isp_mboxcmd(isp, &mbs);
1358		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1359			isp_prt(isp, ISP_LOGINFO,
1360			    "Enabled FW features (0x%x)", sfeat);
1361		}
1362	}
1363
1364	isp->isp_state = ISP_INITSTATE;
1365}
1366
1367static void
1368isp_scsi_channel_init(ispsoftc_t *isp, int chan)
1369{
1370	sdparam *sdp;
1371	mbreg_t mbs;
1372	int tgt;
1373
1374	sdp = SDPARAM(isp, chan);
1375
1376	/*
1377	 * Set (possibly new) Initiator ID.
1378	 */
1379	MBSINIT(&mbs, MBOX_SET_INIT_SCSI_ID, MBLOGALL, 0);
1380	mbs.param[1] = (chan << 7) | sdp->isp_initiator_id;
1381	isp_mboxcmd(isp, &mbs);
1382	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1383		return;
1384	}
1385	isp_prt(isp, ISP_LOGINFO, "Chan %d Initiator ID is %d",
1386	    chan, sdp->isp_initiator_id);
1387
1388
1389	/*
1390	 * Set current per-target parameters to an initial safe minimum.
1391	 */
1392	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1393		int lun;
1394		uint16_t sdf;
1395
1396		if (sdp->isp_devparam[tgt].dev_enable == 0) {
1397			continue;
1398		}
1399#ifndef	ISP_TARGET_MODE
1400		sdf = sdp->isp_devparam[tgt].goal_flags;
1401		sdf &= DPARM_SAFE_DFLT;
1402		/*
1403		 * It is not quite clear when this changed over so that
1404		 * we could force narrow and async for 1000/1020 cards,
1405		 * but assume that this is only the case for loaded
1406		 * firmware.
1407		 */
1408		if (isp->isp_loaded_fw) {
1409			sdf |= DPARM_NARROW | DPARM_ASYNC;
1410		}
1411#else
1412		/*
1413		 * The !$*!)$!$)* f/w uses the same index into some
1414		 * internal table to decide how to respond to negotiations,
1415		 * so if we've said "let's be safe" for ID X, and ID X
1416		 * selects *us*, the negotiations will back to 'safe'
1417		 * (as in narrow/async). What the f/w *should* do is
1418		 * use the initiator id settings to decide how to respond.
1419		 */
1420		sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT;
1421#endif
1422		MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGNONE, 0);
1423		mbs.param[1] = (chan << 15) | (tgt << 8);
1424		mbs.param[2] = sdf;
1425		if ((sdf & DPARM_SYNC) == 0) {
1426			mbs.param[3] = 0;
1427		} else {
1428			mbs.param[3] =
1429			    (sdp->isp_devparam[tgt].goal_offset << 8) |
1430			    (sdp->isp_devparam[tgt].goal_period);
1431		}
1432		isp_prt(isp, ISP_LOGDEBUG0,
1433		    "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
1434		    chan, tgt, mbs.param[2], mbs.param[3] >> 8,
1435		    mbs.param[3] & 0xff);
1436		isp_mboxcmd(isp, &mbs);
1437		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1438			sdf = DPARM_SAFE_DFLT;
1439			MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGALL, 0);
1440			mbs.param[1] = (tgt << 8) | (chan << 15);
1441			mbs.param[2] = sdf;
1442			mbs.param[3] = 0;
1443			isp_mboxcmd(isp, &mbs);
1444			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1445				continue;
1446			}
1447		}
1448
1449		/*
1450		 * We don't update any information directly from the f/w
1451		 * because we need to run at least one command to cause a
1452		 * new state to be latched up. So, we just assume that we
1453		 * converge to the values we just had set.
1454		 *
1455		 * Ensure that we don't believe tagged queuing is enabled yet.
1456		 * It turns out that sometimes the ISP just ignores our
1457		 * attempts to set parameters for devices that it hasn't
1458		 * seen yet.
1459		 */
1460		sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING;
1461		for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
1462			MBSINIT(&mbs, MBOX_SET_DEV_QUEUE_PARAMS, MBLOGALL, 0);
1463			mbs.param[1] = (chan << 15) | (tgt << 8) | lun;
1464			mbs.param[2] = sdp->isp_max_queue_depth;
1465			mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
1466			isp_mboxcmd(isp, &mbs);
1467			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1468				break;
1469			}
1470		}
1471	}
1472	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1473		if (sdp->isp_devparam[tgt].dev_refresh) {
1474			sdp->sendmarker = 1;
1475			sdp->update = 1;
1476			break;
1477		}
1478	}
1479}
1480
1481/*
1482 * Fibre Channel specific initialization.
1483 */
1484static void
1485isp_fibre_init(ispsoftc_t *isp)
1486{
1487	fcparam *fcp;
1488	isp_icb_t local, *icbp = &local;
1489	mbreg_t mbs;
1490	int ownloopid;
1491
1492	/*
1493	 * We only support one channel on non-24XX cards
1494	 */
1495	fcp = FCPARAM(isp, 0);
1496	if (fcp->role == ISP_ROLE_NONE) {
1497		isp->isp_state = ISP_INITSTATE;
1498		return;
1499	}
1500
1501	ISP_MEMZERO(icbp, sizeof (*icbp));
1502	icbp->icb_version = ICB_VERSION1;
1503	icbp->icb_fwoptions = fcp->isp_fwoptions;
1504
1505	/*
1506	 * Firmware Options are either retrieved from NVRAM or
1507	 * are patched elsewhere. We check them for sanity here
1508	 * and make changes based on board revision, but otherwise
1509	 * let others decide policy.
1510	 */
1511
1512	/*
1513	 * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
1514	 */
1515	if (IS_2100(isp) && isp->isp_revision < 5) {
1516		icbp->icb_fwoptions &= ~ICBOPT_FAIRNESS;
1517	}
1518
1519	/*
1520	 * We have to use FULL LOGIN even though it resets the loop too much
1521	 * because otherwise port database entries don't get updated after
1522	 * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
1523	 */
1524	if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
1525		icbp->icb_fwoptions |= ICBOPT_FULL_LOGIN;
1526	}
1527
1528	/*
1529	 * Insist on Port Database Update Async notifications
1530	 */
1531	icbp->icb_fwoptions |= ICBOPT_PDBCHANGE_AE;
1532
1533	/*
1534	 * Make sure that target role reflects into fwoptions.
1535	 */
1536	if (fcp->role & ISP_ROLE_TARGET) {
1537		icbp->icb_fwoptions |= ICBOPT_TGT_ENABLE;
1538	} else {
1539		icbp->icb_fwoptions &= ~ICBOPT_TGT_ENABLE;
1540	}
1541
1542	if (fcp->role & ISP_ROLE_INITIATOR) {
1543		icbp->icb_fwoptions &= ~ICBOPT_INI_DISABLE;
1544	} else {
1545		icbp->icb_fwoptions |= ICBOPT_INI_DISABLE;
1546	}
1547
1548	icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
1549	if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
1550		isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
1551		icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
1552	}
1553	icbp->icb_maxalloc = fcp->isp_maxalloc;
1554	if (icbp->icb_maxalloc < 1) {
1555		isp_prt(isp, ISP_LOGERR, "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
1556		icbp->icb_maxalloc = 16;
1557	}
1558	icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
1559	if (icbp->icb_execthrottle < 1) {
1560		isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
1561		icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
1562	}
1563	icbp->icb_retry_delay = fcp->isp_retry_delay;
1564	icbp->icb_retry_count = fcp->isp_retry_count;
1565	icbp->icb_hardaddr = fcp->isp_loopid;
1566	ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
1567	if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
1568		icbp->icb_hardaddr = 0;
1569		ownloopid = 0;
1570	}
1571
1572	/*
1573	 * Our life seems so much better with 2200s and later with
1574	 * the latest f/w if we set Hard Address.
1575	 */
1576	if (ownloopid || ISP_FW_NEWER_THAN(isp, 2, 2, 5)) {
1577		icbp->icb_fwoptions |= ICBOPT_HARD_ADDRESS;
1578	}
1579
1580	/*
1581	 * Right now we just set extended options to prefer point-to-point
1582	 * over loop based upon some soft config options.
1583	 *
1584	 * NB: for the 2300, ICBOPT_EXTENDED is required.
1585	 */
1586	if (IS_2200(isp) || IS_23XX(isp)) {
1587		icbp->icb_fwoptions |= ICBOPT_EXTENDED;
1588		/*
1589		 * Prefer or force Point-To-Point instead Loop?
1590		 */
1591		switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
1592		case ISP_CFG_NPORT:
1593			icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP;
1594			break;
1595		case ISP_CFG_NPORT_ONLY:
1596			icbp->icb_xfwoptions |= ICBXOPT_PTP_ONLY;
1597			break;
1598		case ISP_CFG_LPORT_ONLY:
1599			icbp->icb_xfwoptions |= ICBXOPT_LOOP_ONLY;
1600			break;
1601		default:
1602			icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
1603			break;
1604		}
1605		if (IS_2200(isp)) {
1606			/*
1607			 * There seems to just be too much breakage here
1608			 * with RIO and Fast Posting- it probably actually
1609			 * works okay but this driver is messing it up.
1610			 * This card is really ancient by now, so let's
1611			 * just opt for safety and not use the feature.
1612			 */
1613#if	0
1614			if (ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
1615				icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
1616				icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
1617				icbp->icb_racctimer = 4;
1618				icbp->icb_idelaytimer = 8;
1619			} else {
1620				icbp->icb_fwoptions |= ICBOPT_FAST_POST;
1621			}
1622#else
1623			icbp->icb_xfwoptions &= ~ICBXOPT_RIO_16BIT;
1624			icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
1625#endif
1626		} else {
1627			/*
1628			 * QLogic recommends that FAST Posting be turned
1629			 * off for 23XX cards and instead allow the HBA
1630			 * to write response queue entries and interrupt
1631			 * after a delay (ZIO).
1632			 */
1633			icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
1634			if ((fcp->isp_xfwoptions & ICBXOPT_TIMER_MASK) == ICBXOPT_ZIO) {
1635				icbp->icb_xfwoptions |= ICBXOPT_ZIO;
1636				icbp->icb_idelaytimer = 10;
1637			}
1638			if (isp->isp_confopts & ISP_CFG_ONEGB) {
1639				icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
1640			} else if (isp->isp_confopts & ISP_CFG_TWOGB) {
1641				icbp->icb_zfwoptions |= ICBZOPT_RATE_TWOGB;
1642			} else {
1643				icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
1644			}
1645			if (fcp->isp_zfwoptions & ICBZOPT_50_OHM) {
1646				icbp->icb_zfwoptions |= ICBZOPT_50_OHM;
1647			}
1648		}
1649	}
1650
1651
1652	/*
1653	 * For 22XX > 2.1.26 && 23XX, set some options.
1654	 */
1655	if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
1656		MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
1657		mbs.param[1] = IFCOPT1_DISF7SWTCH|IFCOPT1_LIPASYNC|IFCOPT1_LIPF8;
1658		mbs.param[2] = 0;
1659		mbs.param[3] = 0;
1660		if (ISP_FW_NEWER_THAN(isp, 3, 16, 0)) {
1661			mbs.param[1] |= IFCOPT1_EQFQASYNC|IFCOPT1_CTIO_RETRY;
1662			if (fcp->role & ISP_ROLE_TARGET) {
1663				mbs.param[3] = IFCOPT3_NOPRLI;
1664			}
1665		}
1666		isp_mboxcmd(isp, &mbs);
1667		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1668			return;
1669		}
1670	}
1671	icbp->icb_logintime = ICB_LOGIN_TOV;
1672	icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV;
1673
1674	if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
1675		icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
1676		MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
1677		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1678		isp_prt(isp, ISP_LOGDEBUG1,
1679		    "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
1680		    ((uint32_t) (fcp->isp_wwnn >> 32)),
1681		    ((uint32_t) (fcp->isp_wwnn)),
1682		    ((uint32_t) (fcp->isp_wwpn >> 32)),
1683		    ((uint32_t) (fcp->isp_wwpn)));
1684	} else if (fcp->isp_wwpn) {
1685		icbp->icb_fwoptions &= ~ICBOPT_BOTH_WWNS;
1686		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1687		isp_prt(isp, ISP_LOGDEBUG1,
1688		    "Setting ICB Port 0x%08x%08x",
1689		    ((uint32_t) (fcp->isp_wwpn >> 32)),
1690		    ((uint32_t) (fcp->isp_wwpn)));
1691	} else {
1692		isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
1693		return;
1694	}
1695	icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
1696	if (icbp->icb_rqstqlen < 1) {
1697		isp_prt(isp, ISP_LOGERR, "bad request queue length");
1698	}
1699	icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
1700	if (icbp->icb_rsltqlen < 1) {
1701		isp_prt(isp, ISP_LOGERR, "bad result queue length");
1702	}
1703	icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
1704	icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
1705	icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
1706	icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
1707	icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
1708	icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
1709	icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
1710	icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
1711
1712	if (FC_SCRATCH_ACQUIRE(isp, 0)) {
1713		isp_prt(isp, ISP_LOGERR, sacq);
1714		return;
1715	}
1716	isp_prt(isp, ISP_LOGDEBUG0,
1717	    "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
1718	    icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
1719
1720	isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
1721
1722	/*
1723	 * Init the firmware
1724	 */
1725	MBSINIT(&mbs, MBOX_INIT_FIRMWARE, MBLOGALL, 30000000);
1726	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1727	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1728	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1729	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1730	mbs.logval = MBLOGALL;
1731	isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %p (%08x%08x)",
1732	    fcp->isp_scratch, (uint32_t) ((uint64_t)fcp->isp_scdma >> 32),
1733	    (uint32_t) fcp->isp_scdma);
1734	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp));
1735	isp_mboxcmd(isp, &mbs);
1736	FC_SCRATCH_RELEASE(isp, 0);
1737	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1738		isp_print_bytes(isp, "isp_fibre_init", sizeof (*icbp), icbp);
1739		return;
1740	}
1741	isp->isp_reqidx = 0;
1742	isp->isp_reqodx = 0;
1743	isp->isp_residx = 0;
1744
1745	/*
1746	 * Whatever happens, we're now committed to being here.
1747	 */
1748	isp->isp_state = ISP_INITSTATE;
1749}
1750
1751static void
1752isp_fibre_init_2400(ispsoftc_t *isp)
1753{
1754	fcparam *fcp;
1755	isp_icb_2400_t local, *icbp = &local;
1756	mbreg_t mbs;
1757	int chan;
1758
1759	/*
1760	 * Check to see whether all channels have *some* kind of role
1761	 */
1762	for (chan = 0; chan < isp->isp_nchan; chan++) {
1763		fcp = FCPARAM(isp, chan);
1764		if (fcp->role != ISP_ROLE_NONE) {
1765			break;
1766		}
1767	}
1768	if (chan == isp->isp_nchan) {
1769		isp_prt(isp, ISP_LOGDEBUG0, "all %d channels with role 'none'", chan);
1770		isp->isp_state = ISP_INITSTATE;
1771		return;
1772	}
1773
1774	/*
1775	 * Start with channel 0.
1776	 */
1777	fcp = FCPARAM(isp, 0);
1778
1779	/*
1780	 * Turn on LIP F8 async event (1)
1781	 */
1782	MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
1783	mbs.param[1] = 1;
1784	isp_mboxcmd(isp, &mbs);
1785	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1786		return;
1787	}
1788
1789	ISP_MEMZERO(icbp, sizeof (*icbp));
1790	icbp->icb_fwoptions1 = fcp->isp_fwoptions;
1791	if (fcp->role & ISP_ROLE_TARGET) {
1792		icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
1793	} else {
1794		icbp->icb_fwoptions1 &= ~ICB2400_OPT1_TGT_ENABLE;
1795	}
1796
1797	if (fcp->role & ISP_ROLE_INITIATOR) {
1798		icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
1799	} else {
1800		icbp->icb_fwoptions1 |= ICB2400_OPT1_INI_DISABLE;
1801	}
1802
1803	icbp->icb_version = ICB_VERSION1;
1804	icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
1805	if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
1806		isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
1807		icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
1808	}
1809
1810	icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
1811	if (icbp->icb_execthrottle < 1) {
1812		isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
1813		icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
1814	}
1815
1816	if (icbp->icb_fwoptions1 & ICB2400_OPT1_TGT_ENABLE) {
1817		/*
1818		 * Get current resource count
1819		 */
1820		MBSINIT(&mbs, MBOX_GET_RESOURCE_COUNT, MBLOGALL, 0);
1821		mbs.obits = 0x4cf;
1822		isp_mboxcmd(isp, &mbs);
1823		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1824			return;
1825		}
1826		icbp->icb_xchgcnt = mbs.param[3];
1827	}
1828
1829
1830	icbp->icb_hardaddr = fcp->isp_loopid;
1831	if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
1832		icbp->icb_hardaddr = 0;
1833	}
1834
1835	/*
1836	 * Force this on.
1837	 */
1838	icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS;
1839
1840	icbp->icb_fwoptions2 = fcp->isp_xfwoptions;
1841	switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
1842#if	0
1843	case ISP_CFG_NPORT:
1844		/*
1845		 * XXX: This causes the f/w to crash.
1846		 */
1847		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1848		icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_2_LOOP;
1849		break;
1850#endif
1851	case ISP_CFG_NPORT_ONLY:
1852		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1853		icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY;
1854		break;
1855	case ISP_CFG_LPORT_ONLY:
1856		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1857		icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_ONLY;
1858		break;
1859	default:
1860		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1861		icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
1862		break;
1863	}
1864
1865	/* force this on for now */
1866	icbp->icb_fwoptions2 |= ICB2400_OPT2_ZIO;
1867
1868	switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) {
1869	case ICB2400_OPT2_ZIO:
1870	case ICB2400_OPT2_ZIO1:
1871		icbp->icb_idelaytimer = 0;
1872		break;
1873	case 0:
1874		break;
1875	default:
1876		isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field", icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
1877		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK;
1878		break;
1879	}
1880
1881	/*
1882	 * We don't support FCTAPE, so clear it.
1883	 */
1884	icbp->icb_fwoptions2 &= ~ICB2400_OPT2_FCTAPE;
1885
1886	icbp->icb_fwoptions3 = fcp->isp_zfwoptions;
1887	icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_AUTO;
1888	if (isp->isp_confopts & ISP_CFG_ONEGB) {
1889		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_ONEGB;
1890	} else if (isp->isp_confopts & ISP_CFG_TWOGB) {
1891		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_TWOGB;
1892	} else if (isp->isp_confopts & ISP_CFG_FOURGB) {
1893		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_FOURGB;
1894	} else {
1895		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
1896	}
1897
1898	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
1899		icbp->icb_fwoptions3 |= ICB2400_OPT3_SOFTID;
1900	}
1901	icbp->icb_logintime = ICB_LOGIN_TOV;
1902
1903	if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
1904		icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS;
1905		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1906		MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
1907		isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node 0x%08x%08x Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwnn >> 32)), ((uint32_t) (fcp->isp_wwnn)),
1908		    ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
1909	} else if (fcp->isp_wwpn) {
1910		icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS;
1911		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1912		isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node to be same as Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
1913	} else {
1914		isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
1915		return;
1916	}
1917	icbp->icb_retry_count = fcp->isp_retry_count;
1918
1919	icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
1920	if (icbp->icb_rqstqlen < 8) {
1921		isp_prt(isp, ISP_LOGERR, "bad request queue length %d", icbp->icb_rqstqlen);
1922		return;
1923	}
1924	icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
1925	if (icbp->icb_rsltqlen < 8) {
1926		isp_prt(isp, ISP_LOGERR, "bad result queue length %d",
1927		    icbp->icb_rsltqlen);
1928		return;
1929	}
1930	icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
1931	icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
1932	icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
1933	icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
1934
1935	icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
1936	icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
1937	icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
1938	icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
1939
1940#ifdef	ISP_TARGET_MODE
1941	/* unconditionally set up the ATIO queue if we support target mode */
1942	icbp->icb_atioqlen = RESULT_QUEUE_LEN(isp);
1943	if (icbp->icb_atioqlen < 8) {
1944		isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d", icbp->icb_atioqlen);
1945		return;
1946	}
1947	icbp->icb_atioqaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_atioq_dma);
1948	icbp->icb_atioqaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_atioq_dma);
1949	icbp->icb_atioqaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_atioq_dma);
1950	icbp->icb_atioqaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_atioq_dma);
1951	isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: atioq %04x%04x%04x%04x", DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma),
1952	    DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma));
1953#endif
1954
1955	isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3);
1956
1957	isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x", DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma),
1958	    DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma), DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
1959	    DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma));
1960
1961	if (isp->isp_dblev & ISP_LOGDEBUG1) {
1962		isp_print_bytes(isp, "isp_fibre_init_2400", sizeof (*icbp), icbp);
1963	}
1964
1965	if (FC_SCRATCH_ACQUIRE(isp, 0)) {
1966		isp_prt(isp, ISP_LOGERR, sacq);
1967		return;
1968	}
1969	ISP_MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN);
1970	isp_put_icb_2400(isp, icbp, fcp->isp_scratch);
1971
1972	/*
1973	 * Now fill in information about any additional channels
1974	 */
1975	if (isp->isp_nchan > 1) {
1976		isp_icb_2400_vpinfo_t vpinfo, *vdst;
1977		vp_port_info_t pi, *pdst;
1978		size_t amt = 0;
1979		uint8_t *off;
1980
1981		vpinfo.vp_count = isp->isp_nchan - 1;
1982		vpinfo.vp_global_options = 0;
1983		off = fcp->isp_scratch;
1984		off += ICB2400_VPINFO_OFF;
1985		vdst = (isp_icb_2400_vpinfo_t *) off;
1986		isp_put_icb_2400_vpinfo(isp, &vpinfo, vdst);
1987		amt = ICB2400_VPINFO_OFF + sizeof (isp_icb_2400_vpinfo_t);
1988		for (chan = 1; chan < isp->isp_nchan; chan++) {
1989			fcparam *fcp2;
1990
1991			ISP_MEMZERO(&pi, sizeof (pi));
1992			fcp2 = FCPARAM(isp, chan);
1993			if (fcp2->role != ISP_ROLE_NONE) {
1994				pi.vp_port_options = ICB2400_VPOPT_ENABLED;
1995				if (fcp2->role & ISP_ROLE_INITIATOR) {
1996					pi.vp_port_options |= ICB2400_VPOPT_INI_ENABLE;
1997				}
1998				if ((fcp2->role & ISP_ROLE_TARGET) == 0) {
1999					pi.vp_port_options |= ICB2400_VPOPT_TGT_DISABLE;
2000				}
2001				MAKE_NODE_NAME_FROM_WWN(pi.vp_port_portname, fcp2->isp_wwpn);
2002				MAKE_NODE_NAME_FROM_WWN(pi.vp_port_nodename, fcp2->isp_wwnn);
2003			}
2004			off = fcp->isp_scratch;
2005			off += ICB2400_VPINFO_PORT_OFF(chan);
2006			pdst = (vp_port_info_t *) off;
2007			isp_put_vp_port_info(isp, &pi, pdst);
2008			amt += ICB2400_VPOPT_WRITE_SIZE;
2009		}
2010	}
2011
2012	/*
2013	 * Init the firmware
2014	 */
2015	MBSINIT(&mbs, 0, MBLOGALL, 30000000);
2016	if (isp->isp_nchan > 1) {
2017		mbs.param[0] = MBOX_INIT_FIRMWARE_MULTI_ID;
2018	} else {
2019		mbs.param[0] = MBOX_INIT_FIRMWARE;
2020	}
2021	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2022	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2023	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2024	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2025	isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %04x%04x%04x%04x", DMA_WD3(fcp->isp_scdma), DMA_WD2(fcp->isp_scdma), DMA_WD1(fcp->isp_scdma), DMA_WD0(fcp->isp_scdma));
2026	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp));
2027	isp_mboxcmd(isp, &mbs);
2028	FC_SCRATCH_RELEASE(isp, 0);
2029
2030	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2031		return;
2032	}
2033	isp->isp_reqidx = 0;
2034	isp->isp_reqodx = 0;
2035	isp->isp_residx = 0;
2036
2037	/*
2038	 * Whatever happens, we're now committed to being here.
2039	 */
2040	isp->isp_state = ISP_INITSTATE;
2041}
2042
2043static void
2044isp_mark_portdb(ispsoftc_t *isp, int chan, int disposition)
2045{
2046	fcparam *fcp = FCPARAM(isp, chan);
2047	int i;
2048
2049	if (chan < 0 || chan >= isp->isp_nchan) {
2050		isp_prt(isp, ISP_LOGWARN, "isp_mark_portdb: bad channel %d", chan);
2051		return;
2052	}
2053	for (i = 0; i < MAX_FC_TARG; i++) {
2054		if (fcp->portdb[i].target_mode) {
2055			if (disposition < 0) {
2056				isp_prt(isp, ISP_LOGTINFO, "isp_mark_portdb: Chan %d zeroing handle 0x" "%04x port 0x%06x", chan,
2057				    fcp->portdb[i].handle, fcp->portdb[i].portid);
2058				ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
2059			}
2060			continue;
2061		}
2062		if (disposition == 0) {
2063			ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
2064		} else {
2065			switch (fcp->portdb[i].state) {
2066			case FC_PORTDB_STATE_CHANGED:
2067			case FC_PORTDB_STATE_PENDING_VALID:
2068			case FC_PORTDB_STATE_VALID:
2069			case FC_PORTDB_STATE_PROBATIONAL:
2070				fcp->portdb[i].state = FC_PORTDB_STATE_PROBATIONAL;
2071				break;
2072			case FC_PORTDB_STATE_ZOMBIE:
2073				break;
2074			case FC_PORTDB_STATE_NIL:
2075			default:
2076				ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
2077				fcp->portdb[i].state = FC_PORTDB_STATE_NIL;
2078				break;
2079			}
2080		}
2081	}
2082}
2083
2084/*
2085 * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards
2086 * or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
2087 */
2088static int
2089isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags, int gs)
2090{
2091	mbreg_t mbs;
2092	uint8_t q[QENTRY_LEN];
2093	isp_plogx_t *plp;
2094	fcparam *fcp;
2095	uint8_t *scp;
2096	uint32_t sst, parm1;
2097	int rval, lev;
2098	const char *msg;
2099	char buf[64];
2100
2101	if (!IS_24XX(isp)) {
2102		int action = flags & PLOGX_FLG_CMD_MASK;
2103		if (action == PLOGX_FLG_CMD_PLOGI) {
2104			return (isp_port_login(isp, handle, portid));
2105		} else if (action == PLOGX_FLG_CMD_LOGO) {
2106			return (isp_port_logout(isp, handle, portid));
2107		} else {
2108			return (MBOX_INVALID_COMMAND);
2109		}
2110	}
2111
2112	ISP_MEMZERO(q, QENTRY_LEN);
2113	plp = (isp_plogx_t *) q;
2114	plp->plogx_header.rqs_entry_count = 1;
2115	plp->plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
2116	plp->plogx_handle = 0xffffffff;
2117	plp->plogx_nphdl = handle;
2118	plp->plogx_vphdl = chan;
2119	plp->plogx_portlo = portid;
2120	plp->plogx_rspsz_porthi = (portid >> 16) & 0xff;
2121	plp->plogx_flags = flags;
2122
2123	if (isp->isp_dblev & ISP_LOGDEBUG1) {
2124		isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, plp);
2125	}
2126
2127	if (gs == 0) {
2128		if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2129			isp_prt(isp, ISP_LOGERR, sacq);
2130			return (-1);
2131		}
2132	}
2133	fcp = FCPARAM(isp, chan);
2134	scp = fcp->isp_scratch;
2135	isp_put_plogx(isp, plp, (isp_plogx_t *) scp);
2136
2137	MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
2138	mbs.param[1] = QENTRY_LEN;
2139	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2140	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2141	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2142	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2143	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN);
2144	isp_mboxcmd(isp, &mbs);
2145	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2146		rval = mbs.param[0];
2147		goto out;
2148	}
2149	MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN);
2150	scp += QENTRY_LEN;
2151	isp_get_plogx(isp, (isp_plogx_t *) scp, plp);
2152	if (isp->isp_dblev & ISP_LOGDEBUG1) {
2153		isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, plp);
2154	}
2155
2156	if (plp->plogx_status == PLOGX_STATUS_OK) {
2157		rval = 0;
2158		goto out;
2159	} else if (plp->plogx_status != PLOGX_STATUS_IOCBERR) {
2160		isp_prt(isp, ISP_LOGWARN,
2161		    "status 0x%x on port login IOCB chanel %d",
2162		    plp->plogx_status, chan);
2163		rval = -1;
2164		goto out;
2165	}
2166
2167	sst = plp->plogx_ioparm[0].lo16 | (plp->plogx_ioparm[0].hi16 << 16);
2168	parm1 = plp->plogx_ioparm[1].lo16 | (plp->plogx_ioparm[1].hi16 << 16);
2169
2170	rval = -1;
2171	lev = ISP_LOGERR;
2172	msg = NULL;
2173
2174	switch (sst) {
2175	case PLOGX_IOCBERR_NOLINK:
2176		msg = "no link";
2177		break;
2178	case PLOGX_IOCBERR_NOIOCB:
2179		msg = "no IOCB buffer";
2180		break;
2181	case PLOGX_IOCBERR_NOXGHG:
2182		msg = "no Exchange Control Block";
2183		break;
2184	case PLOGX_IOCBERR_FAILED:
2185		ISP_SNPRINTF(buf, sizeof (buf),
2186		    "reason 0x%x (last LOGIN state 0x%x)",
2187		    parm1 & 0xff, (parm1 >> 8) & 0xff);
2188		msg = buf;
2189		break;
2190	case PLOGX_IOCBERR_NOFABRIC:
2191		msg = "no fabric";
2192		break;
2193	case PLOGX_IOCBERR_NOTREADY:
2194		msg = "firmware not ready";
2195		break;
2196	case PLOGX_IOCBERR_NOLOGIN:
2197		ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)",
2198		    parm1);
2199		msg = buf;
2200		rval = MBOX_NOT_LOGGED_IN;
2201		break;
2202	case PLOGX_IOCBERR_REJECT:
2203		ISP_SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1);
2204		msg = buf;
2205		break;
2206	case PLOGX_IOCBERR_NOPCB:
2207		msg = "no PCB allocated";
2208		break;
2209	case PLOGX_IOCBERR_EINVAL:
2210		ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x",
2211		    parm1);
2212		msg = buf;
2213		break;
2214	case PLOGX_IOCBERR_PORTUSED:
2215		lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
2216		ISP_SNPRINTF(buf, sizeof (buf),
2217		    "already logged in with N-Port handle 0x%x", parm1);
2218		msg = buf;
2219		rval = MBOX_PORT_ID_USED | (parm1 << 16);
2220		break;
2221	case PLOGX_IOCBERR_HNDLUSED:
2222		lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
2223		ISP_SNPRINTF(buf, sizeof (buf),
2224		    "handle already used for PortID 0x%06x", parm1);
2225		msg = buf;
2226		rval = MBOX_LOOP_ID_USED;
2227		break;
2228	case PLOGX_IOCBERR_NOHANDLE:
2229		msg = "no handle allocated";
2230		break;
2231	case PLOGX_IOCBERR_NOFLOGI:
2232		msg = "no FLOGI_ACC";
2233		break;
2234	default:
2235		ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x",
2236		    plp->plogx_status, flags);
2237		msg = buf;
2238		break;
2239	}
2240	if (msg) {
2241		isp_prt(isp, ISP_LOGERR,
2242		    "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s",
2243		    chan, portid, handle, msg);
2244	}
2245out:
2246	if (gs == 0) {
2247		FC_SCRATCH_RELEASE(isp, chan);
2248	}
2249	return (rval);
2250}
2251
2252static int
2253isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
2254{
2255	mbreg_t mbs;
2256
2257	MBSINIT(&mbs, MBOX_FABRIC_LOGIN, MBLOGNONE, 500000);
2258	if (ISP_CAP_2KLOGIN(isp)) {
2259		mbs.param[1] = handle;
2260		mbs.ibits = (1 << 10);
2261	} else {
2262		mbs.param[1] = handle << 8;
2263	}
2264	mbs.param[2] = portid >> 16;
2265	mbs.param[3] = portid;
2266	mbs.logval = MBLOGNONE;
2267	mbs.timeout = 500000;
2268	isp_mboxcmd(isp, &mbs);
2269
2270	switch (mbs.param[0]) {
2271	case MBOX_PORT_ID_USED:
2272		isp_prt(isp, ISP_LOGDEBUG0,
2273		    "isp_port_login: portid 0x%06x already logged in as %u",
2274		    portid, mbs.param[1]);
2275		return (MBOX_PORT_ID_USED | (mbs.param[1] << 16));
2276
2277	case MBOX_LOOP_ID_USED:
2278		isp_prt(isp, ISP_LOGDEBUG0,
2279		    "isp_port_login: handle 0x%04x in use for port id 0x%02xXXXX",
2280		    handle, mbs.param[1] & 0xff);
2281		return (MBOX_LOOP_ID_USED);
2282
2283	case MBOX_COMMAND_COMPLETE:
2284		return (0);
2285
2286	case MBOX_COMMAND_ERROR:
2287		isp_prt(isp, ISP_LOGINFO,
2288		    "isp_port_login: error 0x%x in PLOGI to port 0x%06x",
2289		    mbs.param[1], portid);
2290		return (MBOX_COMMAND_ERROR);
2291
2292	case MBOX_ALL_IDS_USED:
2293		isp_prt(isp, ISP_LOGINFO,
2294		    "isp_port_login: all IDs used for fabric login");
2295		return (MBOX_ALL_IDS_USED);
2296
2297	default:
2298		isp_prt(isp, ISP_LOGINFO,
2299		    "isp_port_login: error 0x%x on port login of 0x%06x@0x%0x",
2300		    mbs.param[0], portid, handle);
2301		return (mbs.param[0]);
2302	}
2303}
2304
2305static int
2306isp_port_logout(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
2307{
2308	mbreg_t mbs;
2309
2310	MBSINIT(&mbs, MBOX_FABRIC_LOGOUT, MBLOGNONE, 500000);
2311	if (ISP_CAP_2KLOGIN(isp)) {
2312		mbs.param[1] = handle;
2313		mbs.ibits = (1 << 10);
2314	} else {
2315		mbs.param[1] = handle << 8;
2316	}
2317	isp_mboxcmd(isp, &mbs);
2318	return (mbs.param[0] == MBOX_COMMAND_COMPLETE? 0 : mbs.param[0]);
2319}
2320
2321static int
2322isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
2323{
2324	fcparam *fcp = FCPARAM(isp, chan);
2325	mbreg_t mbs;
2326	union {
2327		isp_pdb_21xx_t fred;
2328		isp_pdb_24xx_t bill;
2329	} un;
2330
2331	MBSINIT(&mbs, MBOX_GET_PORT_DB, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 250000);
2332	if (IS_24XX(isp)) {
2333		mbs.ibits = (1 << 9)|(1 << 10);
2334		mbs.param[1] = id;
2335		mbs.param[9] = chan;
2336	} else if (ISP_CAP_2KLOGIN(isp)) {
2337		mbs.param[1] = id;
2338	} else {
2339		mbs.param[1] = id << 8;
2340	}
2341	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2342	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2343	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2344	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2345	if (dolock) {
2346		if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2347			isp_prt(isp, ISP_LOGERR, sacq);
2348			return (-1);
2349		}
2350	}
2351	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (un));
2352	isp_mboxcmd(isp, &mbs);
2353	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2354		if (dolock) {
2355			FC_SCRATCH_RELEASE(isp, chan);
2356		}
2357		return (mbs.param[0]);
2358	}
2359	if (IS_24XX(isp)) {
2360		isp_get_pdb_24xx(isp, fcp->isp_scratch, &un.bill);
2361		pdb->handle = un.bill.pdb_handle;
2362		pdb->s3_role = un.bill.pdb_prli_svc3;
2363		pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
2364		ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
2365		ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
2366		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2367		    "Chan %d Port 0x%06x flags 0x%x curstate %x",
2368		    chan, pdb->portid, un.bill.pdb_flags,
2369		    un.bill.pdb_curstate);
2370		if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE ||
2371		    un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) {
2372			mbs.param[0] = MBOX_NOT_LOGGED_IN;
2373			if (dolock) {
2374				FC_SCRATCH_RELEASE(isp, chan);
2375			}
2376			return (mbs.param[0]);
2377		}
2378	} else {
2379		isp_get_pdb_21xx(isp, fcp->isp_scratch, &un.fred);
2380		pdb->handle = un.fred.pdb_loopid;
2381		pdb->s3_role = un.fred.pdb_prli_svc3;
2382		pdb->portid = BITS2WORD(un.fred.pdb_portid_bits);
2383		ISP_MEMCPY(pdb->portname, un.fred.pdb_portname, 8);
2384		ISP_MEMCPY(pdb->nodename, un.fred.pdb_nodename, 8);
2385	}
2386	if (dolock) {
2387		FC_SCRATCH_RELEASE(isp, chan);
2388	}
2389	return (0);
2390}
2391
2392static void
2393isp_dump_chip_portdb(ispsoftc_t *isp, int chan, int dolock)
2394{
2395	isp_pdb_t pdb;
2396	int lim, loopid;
2397
2398	if (ISP_CAP_2KLOGIN(isp)) {
2399		lim = NPH_MAX_2K;
2400	} else {
2401		lim = NPH_MAX;
2402	}
2403	for (loopid = 0; loopid != lim; loopid++) {
2404		if (isp_getpdb(isp, chan, loopid, &pdb, dolock)) {
2405			continue;
2406		}
2407		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGINFO, "Chan %d Loopid 0x%04x "
2408		    "PortID 0x%06x WWPN 0x%02x%02x%02x%02x%02x%02x%02x%02x",
2409		    chan, loopid, pdb.portid, pdb.portname[0], pdb.portname[1],
2410		    pdb.portname[2], pdb.portname[3], pdb.portname[4],
2411		    pdb.portname[5], pdb.portname[6], pdb.portname[7]);
2412	}
2413}
2414
2415static uint64_t
2416isp_get_wwn(ispsoftc_t *isp, int chan, int loopid, int nodename)
2417{
2418	uint64_t wwn = INI_NONE;
2419	fcparam *fcp = FCPARAM(isp, chan);
2420	mbreg_t mbs;
2421
2422	if (fcp->isp_fwstate < FW_READY ||
2423	    fcp->isp_loopstate < LOOP_PDB_RCVD) {
2424		return (wwn);
2425	}
2426	MBSINIT(&mbs, MBOX_GET_PORT_NAME, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 500000);
2427	if (ISP_CAP_2KLOGIN(isp)) {
2428		mbs.param[1] = loopid;
2429		mbs.ibits = (1 << 10);
2430		if (nodename) {
2431			mbs.param[10] = 1;
2432		}
2433		if (ISP_CAP_MULTI_ID(isp)) {
2434			mbs.ibits |= (1 << 9);
2435			mbs.param[9] = chan;
2436		}
2437	} else {
2438		mbs.param[1] = loopid << 8;
2439		if (nodename) {
2440			mbs.param[1] |= 1;
2441		}
2442	}
2443	isp_mboxcmd(isp, &mbs);
2444	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2445		return (wwn);
2446	}
2447	if (IS_24XX(isp)) {
2448		wwn =
2449		    (((uint64_t)(mbs.param[2] >> 8))	<< 56) |
2450		    (((uint64_t)(mbs.param[2] & 0xff))	<< 48) |
2451		    (((uint64_t)(mbs.param[3] >> 8))	<< 40) |
2452		    (((uint64_t)(mbs.param[3] & 0xff))	<< 32) |
2453		    (((uint64_t)(mbs.param[6] >> 8))	<< 24) |
2454		    (((uint64_t)(mbs.param[6] & 0xff))	<< 16) |
2455		    (((uint64_t)(mbs.param[7] >> 8))	<<  8) |
2456		    (((uint64_t)(mbs.param[7] & 0xff)));
2457	} else {
2458		wwn =
2459		    (((uint64_t)(mbs.param[2] & 0xff))  << 56) |
2460		    (((uint64_t)(mbs.param[2] >> 8))	<< 48) |
2461		    (((uint64_t)(mbs.param[3] & 0xff))	<< 40) |
2462		    (((uint64_t)(mbs.param[3] >> 8))	<< 32) |
2463		    (((uint64_t)(mbs.param[6] & 0xff))	<< 24) |
2464		    (((uint64_t)(mbs.param[6] >> 8))	<< 16) |
2465		    (((uint64_t)(mbs.param[7] & 0xff))	<<  8) |
2466		    (((uint64_t)(mbs.param[7] >> 8)));
2467	}
2468	return (wwn);
2469}
2470
2471/*
2472 * Make sure we have good FC link.
2473 */
2474
2475static int
2476isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
2477{
2478	mbreg_t mbs;
2479	int count, check_for_fabric, r;
2480	uint8_t lwfs;
2481	int loopid;
2482	fcparam *fcp;
2483	fcportdb_t *lp;
2484	isp_pdb_t pdb;
2485
2486	fcp = FCPARAM(isp, chan);
2487
2488	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d FC Link Test Entry", chan);
2489	ISP_MARK_PORTDB(isp, chan, 1);
2490
2491	/*
2492	 * Wait up to N microseconds for F/W to go to a ready state.
2493	 */
2494	lwfs = FW_CONFIG_WAIT;
2495	count = 0;
2496	while (count < usdelay) {
2497		uint64_t enano;
2498		uint32_t wrk;
2499		NANOTIME_T hra, hrb;
2500
2501		GET_NANOTIME(&hra);
2502		isp_fw_state(isp, chan);
2503		if (lwfs != fcp->isp_fwstate) {
2504			isp_prt(isp, ISP_LOGCONFIG|ISP_LOGSANCFG, "Chan %d Firmware State <%s->%s>", chan, isp_fc_fw_statename((int)lwfs), isp_fc_fw_statename((int)fcp->isp_fwstate));
2505			lwfs = fcp->isp_fwstate;
2506		}
2507		if (fcp->isp_fwstate == FW_READY) {
2508			break;
2509		}
2510		GET_NANOTIME(&hrb);
2511
2512		/*
2513		 * Get the elapsed time in nanoseconds.
2514		 * Always guaranteed to be non-zero.
2515		 */
2516		enano = NANOTIME_SUB(&hrb, &hra);
2517
2518		isp_prt(isp, ISP_LOGDEBUG1, "usec%d: 0x%lx->0x%lx enano 0x%x%08x", count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb), (uint32_t)(enano >> 32), (uint32_t)(enano));
2519
2520		/*
2521		 * If the elapsed time is less than 1 millisecond,
2522		 * delay a period of time up to that millisecond of
2523		 * waiting.
2524		 *
2525		 * This peculiar code is an attempt to try and avoid
2526		 * invoking uint64_t math support functions for some
2527		 * platforms where linkage is a problem.
2528		 */
2529		if (enano < (1000 * 1000)) {
2530			count += 1000;
2531			enano = (1000 * 1000) - enano;
2532			while (enano > (uint64_t) 4000000000U) {
2533				ISP_SLEEP(isp, 4000000);
2534				enano -= (uint64_t) 4000000000U;
2535			}
2536			wrk = enano;
2537			wrk /= 1000;
2538			ISP_SLEEP(isp, wrk);
2539		} else {
2540			while (enano > (uint64_t) 4000000000U) {
2541				count += 4000000;
2542				enano -= (uint64_t) 4000000000U;
2543			}
2544			wrk = enano;
2545			count += (wrk / 1000);
2546		}
2547	}
2548
2549
2550
2551	/*
2552	 * If we haven't gone to 'ready' state, return.
2553	 */
2554	if (fcp->isp_fwstate != FW_READY) {
2555		isp_prt(isp, ISP_LOGSANCFG, "%s: chan %d not at FW_READY state", __func__, chan);
2556		return (-1);
2557	}
2558
2559	/*
2560	 * Get our Loop ID and Port ID.
2561	 */
2562	MBSINIT(&mbs, MBOX_GET_LOOP_ID, MBLOGALL, 0);
2563	if (ISP_CAP_MULTI_ID(isp)) {
2564		mbs.param[9] = chan;
2565		mbs.ibits = (1 << 9);
2566		mbs.obits = (1 << 7);
2567	}
2568	isp_mboxcmd(isp, &mbs);
2569	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2570		return (-1);
2571	}
2572
2573	if (ISP_CAP_2KLOGIN(isp)) {
2574		fcp->isp_loopid = mbs.param[1];
2575	} else {
2576		fcp->isp_loopid = mbs.param[1] & 0xff;
2577	}
2578
2579	if (IS_2100(isp)) {
2580		fcp->isp_topo = TOPO_NL_PORT;
2581	} else {
2582		int topo = (int) mbs.param[6];
2583		if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB) {
2584			topo = TOPO_PTP_STUB;
2585		}
2586		fcp->isp_topo = topo;
2587	}
2588	fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16);
2589
2590	if (IS_2100(isp)) {
2591		/*
2592		 * Don't bother with fabric if we are using really old
2593		 * 2100 firmware. It's just not worth it.
2594		 */
2595		if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) {
2596			check_for_fabric = 1;
2597		} else {
2598			check_for_fabric = 0;
2599		}
2600	} else if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_F_PORT) {
2601		check_for_fabric = 1;
2602	} else {
2603		check_for_fabric = 0;
2604	}
2605
2606	/*
2607	 * Check to make sure we got a valid loopid
2608	 * The 24XX seems to mess this up for multiple channels.
2609	 */
2610	if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT) {
2611		uint8_t alpa = fcp->isp_portid;
2612
2613		if (alpa == 0) {
2614			/* "Cannot Happen" */
2615			isp_prt(isp, ISP_LOGWARN, "Zero AL_PA for Loop Topology?");
2616		} else {
2617			int i;
2618			for (i = 0; alpa_map[i]; i++) {
2619				if (alpa_map[i] == alpa) {
2620					break;
2621				}
2622			}
2623			if (alpa_map[i] && fcp->isp_loopid != i) {
2624				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d deriving loopid %d from AL_PA map  (AL_PA 0x%x) and ignoring returned value %d (AL_PA 0x%x)", chan, i, alpa_map[i], fcp->isp_loopid, alpa);
2625				fcp->isp_loopid = i;
2626			}
2627		}
2628	}
2629
2630
2631	if (IS_24XX(isp)) { /* XXX SHOULDN'T THIS BE FOR 2K F/W? XXX */
2632		loopid = NPH_FL_ID;
2633	} else {
2634		loopid = FL_ID;
2635	}
2636	if (check_for_fabric) {
2637		r = isp_getpdb(isp, chan, loopid, &pdb, 1);
2638		if (r && (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT)) {
2639			isp_prt(isp, ISP_LOGWARN, "fabric topology but cannot get info about fabric controller (0x%x)", r);
2640			fcp->isp_topo = TOPO_PTP_STUB;
2641		}
2642	} else {
2643		r = -1;
2644	}
2645	if (r == 0) {
2646		if (IS_2100(isp)) {
2647			fcp->isp_topo = TOPO_FL_PORT;
2648		}
2649		if (pdb.portid == 0) {
2650			/*
2651			 * Crock.
2652			 */
2653			fcp->isp_topo = TOPO_NL_PORT;
2654			goto not_on_fabric;
2655		}
2656
2657		/*
2658		 * Save the Fabric controller's port database entry.
2659		 */
2660		lp = &fcp->portdb[FL_ID];
2661		lp->state = FC_PORTDB_STATE_PENDING_VALID;
2662		MAKE_WWN_FROM_NODE_NAME(lp->node_wwn, pdb.nodename);
2663		MAKE_WWN_FROM_NODE_NAME(lp->port_wwn, pdb.portname);
2664		lp->roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
2665		lp->portid = pdb.portid;
2666		lp->handle = pdb.handle;
2667		lp->new_portid = lp->portid;
2668		lp->new_roles = lp->roles;
2669		if (IS_24XX(isp)) {
2670			fcp->inorder = (mbs.param[7] & ISP24XX_INORDER) != 0;
2671			if (ISP_FW_NEWER_THAN(isp, 4, 0, 27)) {
2672				fcp->npiv_fabric = (mbs.param[7] & ISP24XX_NPIV_SAN) != 0;
2673				if (fcp->npiv_fabric) {
2674					isp_prt(isp, ISP_LOGCONFIG, "fabric supports NP-IV");
2675				}
2676			}
2677			if (chan) {
2678				fcp->isp_sns_hdl = NPH_SNS_HDLBASE + chan;
2679				r = isp_plogx(isp, chan, fcp->isp_sns_hdl, SNS_PORT_ID, PLOGX_FLG_CMD_PLOGI | PLOGX_FLG_COND_PLOGI | PLOGX_FLG_SKIP_PRLI, 0);
2680				if (r) {
2681					isp_prt(isp, ISP_LOGWARN, "%s: Chan %d cannot log into SNS", __func__, chan);
2682					return (-1);
2683				}
2684			} else {
2685				fcp->isp_sns_hdl = NPH_SNS_ID;
2686			}
2687			r = isp_register_fc4_type_24xx(isp, chan);
2688		} else {
2689			fcp->isp_sns_hdl = SNS_ID;
2690			r = isp_register_fc4_type(isp, chan);
2691		}
2692		if (r) {
2693			isp_prt(isp, ISP_LOGWARN|ISP_LOGSANCFG, "%s: register fc4 type failed", __func__);
2694			return (-1);
2695		}
2696	} else {
2697not_on_fabric:
2698		fcp->portdb[FL_ID].state = FC_PORTDB_STATE_NIL;
2699	}
2700
2701	fcp->isp_gbspeed = 1;
2702	if (IS_23XX(isp) || IS_24XX(isp)) {
2703		MBSINIT(&mbs, MBOX_GET_SET_DATA_RATE, MBLOGALL, 3000000);
2704		mbs.param[1] = MBGSD_GET_RATE;
2705		/* mbs.param[2] undefined if we're just getting rate */
2706		isp_mboxcmd(isp, &mbs);
2707		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
2708			if (mbs.param[1] == MBGSD_EIGHTGB) {
2709				isp_prt(isp, ISP_LOGINFO, "Chan %d 8Gb link speed", chan);
2710				fcp->isp_gbspeed = 8;
2711			} else if (mbs.param[1] == MBGSD_FOURGB) {
2712				isp_prt(isp, ISP_LOGINFO, "Chan %d 4Gb link speed", chan);
2713				fcp->isp_gbspeed = 4;
2714			} else if (mbs.param[1] == MBGSD_TWOGB) {
2715				isp_prt(isp, ISP_LOGINFO, "Chan %d 2Gb link speed", chan);
2716				fcp->isp_gbspeed = 2;
2717			} else if (mbs.param[1] == MBGSD_ONEGB) {
2718				isp_prt(isp, ISP_LOGINFO, "Chan %d 1Gb link speed", chan);
2719				fcp->isp_gbspeed = 1;
2720			}
2721		}
2722	}
2723
2724	/*
2725	 * Announce ourselves, too.
2726	 */
2727	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGCONFIG, topology, chan, (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) fcp->isp_wwpn, fcp->isp_portid, fcp->isp_loopid, isp_fc_toponame(fcp));
2728	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d FC Link Test Complete", chan);
2729	return (0);
2730}
2731
2732/*
2733 * Complete the synchronization of our Port Database.
2734 *
2735 * At this point, we've scanned the local loop (if any) and the fabric
2736 * and performed fabric logins on all new devices.
2737 *
2738 * Our task here is to go through our port database and remove any entities
2739 * that are still marked probational (issuing PLOGO for ones which we had
2740 * PLOGI'd into) or are dead.
2741 *
2742 * Our task here is to also check policy to decide whether devices which
2743 * have *changed* in some way should still be kept active. For example,
2744 * if a device has just changed PortID, we can either elect to treat it
2745 * as an old device or as a newly arrived device (and notify the outer
2746 * layer appropriately).
2747 *
2748 * We also do initiator map target id assignment here for new initiator
2749 * devices and refresh old ones ot make sure that they point to the corret
2750 * entities.
2751 */
2752static int
2753isp_pdb_sync(ispsoftc_t *isp, int chan)
2754{
2755	fcparam *fcp = FCPARAM(isp, chan);
2756	fcportdb_t *lp;
2757	uint16_t dbidx;
2758
2759	if (fcp->isp_loopstate == LOOP_READY) {
2760		return (0);
2761	}
2762
2763	/*
2764	 * Make sure we're okay for doing this right now.
2765	 */
2766	if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
2767	    fcp->isp_loopstate != LOOP_FSCAN_DONE &&
2768	    fcp->isp_loopstate != LOOP_LSCAN_DONE) {
2769		isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d",
2770		    fcp->isp_loopstate);
2771		return (-1);
2772	}
2773
2774	if (fcp->isp_topo == TOPO_FL_PORT ||
2775	    fcp->isp_topo == TOPO_NL_PORT ||
2776	    fcp->isp_topo == TOPO_N_PORT) {
2777		if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
2778			if (isp_scan_loop(isp, chan) != 0) {
2779				isp_prt(isp, ISP_LOGWARN,
2780				    "isp_pdb_sync: isp_scan_loop failed");
2781				return (-1);
2782			}
2783		}
2784	}
2785
2786	if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
2787		if (fcp->isp_loopstate < LOOP_FSCAN_DONE) {
2788			if (isp_scan_fabric(isp, chan) != 0) {
2789				isp_prt(isp, ISP_LOGWARN,
2790				    "isp_pdb_sync: isp_scan_fabric failed");
2791				return (-1);
2792			}
2793		}
2794	}
2795
2796	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2797	    "Chan %d Synchronizing PDBs", chan);
2798
2799	fcp->isp_loopstate = LOOP_SYNCING_PDB;
2800
2801	for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
2802		lp = &fcp->portdb[dbidx];
2803
2804		if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode) {
2805			continue;
2806		}
2807
2808		if (lp->state == FC_PORTDB_STATE_VALID) {
2809			if (dbidx != FL_ID) {
2810				isp_prt(isp,
2811				    ISP_LOGERR, "portdb idx %d already valid",
2812			    	    dbidx);
2813			}
2814			continue;
2815		}
2816
2817		switch (lp->state) {
2818		case FC_PORTDB_STATE_PROBATIONAL:
2819		case FC_PORTDB_STATE_DEAD:
2820			/*
2821			 * It's up to the outer layers to clear isp_dev_map.
2822			 */
2823			lp->state = FC_PORTDB_STATE_NIL;
2824			isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
2825			if (lp->autologin == 0) {
2826				(void) isp_plogx(isp, chan, lp->handle,
2827				    lp->portid,
2828				    PLOGX_FLG_CMD_LOGO |
2829				    PLOGX_FLG_IMPLICIT |
2830				    PLOGX_FLG_FREE_NPHDL, 0);
2831			} else {
2832				lp->autologin = 0;
2833			}
2834			lp->new_roles = 0;
2835			lp->new_portid = 0;
2836			/*
2837			 * Note that we might come out of this with our state
2838			 * set to FC_PORTDB_STATE_ZOMBIE.
2839			 */
2840			break;
2841		case FC_PORTDB_STATE_NEW:
2842			/*
2843			 * It's up to the outer layers to assign a virtual
2844			 * target id in isp_dev_map (if any).
2845			 */
2846			lp->portid = lp->new_portid;
2847			lp->roles = lp->new_roles;
2848			lp->state = FC_PORTDB_STATE_VALID;
2849			isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
2850			lp->new_roles = 0;
2851			lp->new_portid = 0;
2852			lp->reserved = 0;
2853			lp->new_reserved = 0;
2854			break;
2855		case FC_PORTDB_STATE_CHANGED:
2856/*
2857 * XXXX FIX THIS
2858 */
2859			lp->state = FC_PORTDB_STATE_VALID;
2860			isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
2861			lp->new_roles = 0;
2862			lp->new_portid = 0;
2863			lp->reserved = 0;
2864			lp->new_reserved = 0;
2865			break;
2866		case FC_PORTDB_STATE_PENDING_VALID:
2867			lp->portid = lp->new_portid;
2868			lp->roles = lp->new_roles;
2869			if (lp->dev_map_idx) {
2870				int t = lp->dev_map_idx - 1;
2871				fcp->isp_dev_map[t] = dbidx + 1;
2872			}
2873			lp->state = FC_PORTDB_STATE_VALID;
2874			isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
2875			if (dbidx != FL_ID) {
2876				lp->new_roles = 0;
2877				lp->new_portid = 0;
2878			}
2879			lp->reserved = 0;
2880			lp->new_reserved = 0;
2881			break;
2882		case FC_PORTDB_STATE_ZOMBIE:
2883			break;
2884		default:
2885			isp_prt(isp, ISP_LOGWARN,
2886			    "isp_scan_loop: state %d for idx %d",
2887			    lp->state, dbidx);
2888			isp_dump_portdb(isp, chan);
2889		}
2890	}
2891
2892	/*
2893	 * If we get here, we've for sure seen not only a valid loop
2894	 * but know what is or isn't on it, so mark this for usage
2895	 * in isp_start.
2896	 */
2897	fcp->loop_seen_once = 1;
2898	fcp->isp_loopstate = LOOP_READY;
2899	return (0);
2900}
2901
2902/*
2903 * Scan local loop for devices.
2904 */
2905static int
2906isp_scan_loop(ispsoftc_t *isp, int chan)
2907{
2908	fcportdb_t *lp, tmp;
2909	fcparam *fcp = FCPARAM(isp, chan);
2910	int i;
2911	isp_pdb_t pdb;
2912	uint16_t handle, lim = 0;
2913
2914	if (fcp->isp_fwstate < FW_READY ||
2915	    fcp->isp_loopstate < LOOP_PDB_RCVD) {
2916		return (-1);
2917	}
2918
2919	if (fcp->isp_loopstate > LOOP_SCANNING_LOOP) {
2920		return (0);
2921	}
2922
2923	/*
2924	 * Check our connection topology.
2925	 *
2926	 * If we're a public or private loop, we scan 0..125 as handle values.
2927	 * The firmware has (typically) peformed a PLOGI for us. We skip this
2928	 * step if we're a ISP_24XX in NP-IV mode.
2929	 *
2930	 * If we're a N-port connection, we treat this is a short loop (0..1).
2931	 */
2932	switch (fcp->isp_topo) {
2933	case TOPO_NL_PORT:
2934		lim = LOCAL_LOOP_LIM;
2935		break;
2936	case TOPO_FL_PORT:
2937		if (IS_24XX(isp) && isp->isp_nchan > 1) {
2938			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2939			    "Chan %d Skipping Local Loop Scan", chan);
2940			fcp->isp_loopstate = LOOP_LSCAN_DONE;
2941			return (0);
2942		}
2943		lim = LOCAL_LOOP_LIM;
2944		break;
2945	case TOPO_N_PORT:
2946		lim = 2;
2947		break;
2948	default:
2949		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2950		    "Chan %d no loop topology to scan", chan);
2951		fcp->isp_loopstate = LOOP_LSCAN_DONE;
2952		return (0);
2953	}
2954
2955	fcp->isp_loopstate = LOOP_SCANNING_LOOP;
2956
2957	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2958	    "Chan %d FC scan loop 0..%d", chan, lim-1);
2959
2960
2961	/*
2962	 * Run through the list and get the port database info for each one.
2963	 */
2964	for (handle = 0; handle < lim; handle++) {
2965		int r;
2966		/*
2967		 * Don't scan "special" ids.
2968		 */
2969		if (handle >= FL_ID && handle <= SNS_ID) {
2970			continue;
2971		}
2972		if (ISP_CAP_2KLOGIN(isp)) {
2973			if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
2974				continue;
2975			}
2976		}
2977		/*
2978		 * In older cards with older f/w GET_PORT_DATABASE has been
2979		 * known to hang. This trick gets around that problem.
2980		 */
2981		if (IS_2100(isp) || IS_2200(isp)) {
2982			uint64_t node_wwn = isp_get_wwn(isp, chan, handle, 1);
2983			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2984				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2985				    "Chan %d FC scan loop DONE (bad)", chan);
2986				return (-1);
2987			}
2988			if (node_wwn == INI_NONE) {
2989				continue;
2990			}
2991		}
2992
2993		/*
2994		 * Get the port database entity for this index.
2995		 */
2996		r = isp_getpdb(isp, chan, handle, &pdb, 1);
2997		if (r != 0) {
2998			isp_prt(isp, ISP_LOGDEBUG1,
2999			    "Chan %d FC scan loop handle %d returned %x",
3000			    chan, handle, r);
3001			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
3002				ISP_MARK_PORTDB(isp, chan, 1);
3003				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3004				    "Chan %d FC scan loop DONE (bad)", chan);
3005				return (-1);
3006			}
3007			continue;
3008		}
3009
3010		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
3011			ISP_MARK_PORTDB(isp, chan, 1);
3012			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3013			    "Chan %d FC scan loop DONE (bad)", chan);
3014			return (-1);
3015		}
3016
3017		/*
3018		 * On *very* old 2100 firmware we would end up sometimes
3019		 * with the firmware returning the port database entry
3020		 * for something else. We used to restart this, but
3021		 * now we just punt.
3022		 */
3023		if (IS_2100(isp) && pdb.handle != handle) {
3024			isp_prt(isp, ISP_LOGWARN,
3025			    "Chan %d cannot synchronize port database", chan);
3026			ISP_MARK_PORTDB(isp, chan, 1);
3027			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3028			    "Chan %d FC scan loop DONE (bad)", chan);
3029			return (-1);
3030		}
3031
3032		/*
3033		 * Save the pertinent info locally.
3034		 */
3035		MAKE_WWN_FROM_NODE_NAME(tmp.node_wwn, pdb.nodename);
3036		MAKE_WWN_FROM_NODE_NAME(tmp.port_wwn, pdb.portname);
3037		tmp.roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
3038		tmp.portid = pdb.portid;
3039		tmp.handle = pdb.handle;
3040
3041		/*
3042		 * Check to make sure it's still a valid entry. The 24XX seems
3043		 * to return a portid but not a WWPN/WWNN or role for devices
3044		 * which shift on a loop.
3045		 */
3046		if (tmp.node_wwn == 0 || tmp.port_wwn == 0 || tmp.portid == 0) {
3047			int a, b, c;
3048			a = (tmp.node_wwn == 0);
3049			b = (tmp.port_wwn == 0);
3050			c = (tmp.portid == 0);
3051			if (a == 0 && b == 0) {
3052				tmp.node_wwn =
3053				    isp_get_wwn(isp, chan, handle, 1);
3054				tmp.port_wwn =
3055				    isp_get_wwn(isp, chan, handle, 0);
3056				if (tmp.node_wwn && tmp.port_wwn) {
3057					isp_prt(isp, ISP_LOGINFO, "DODGED!");
3058					goto cont;
3059				}
3060			}
3061			isp_prt(isp, ISP_LOGWARN,
3062			    "Chan %d bad pdb (%1d%1d%1d) @ handle 0x%x", chan,
3063			    a, b, c, handle);
3064			isp_dump_portdb(isp, chan);
3065			continue;
3066		}
3067  cont:
3068
3069		/*
3070		 * Now search the entire port database
3071		 * for the same Port and Node WWN.
3072		 */
3073		for (i = 0; i < MAX_FC_TARG; i++) {
3074			lp = &fcp->portdb[i];
3075
3076			if (lp->state == FC_PORTDB_STATE_NIL ||
3077			    lp->target_mode) {
3078				continue;
3079			}
3080			if (lp->node_wwn != tmp.node_wwn) {
3081				continue;
3082			}
3083			if (lp->port_wwn != tmp.port_wwn) {
3084				continue;
3085			}
3086
3087			/*
3088			 * Okay- we've found a non-nil entry that matches.
3089			 * Check to make sure it's probational or a zombie.
3090			 */
3091			if (lp->state != FC_PORTDB_STATE_PROBATIONAL &&
3092			    lp->state != FC_PORTDB_STATE_ZOMBIE) {
3093				isp_prt(isp, ISP_LOGERR,
3094				    "Chan %d [%d] not probational/zombie (0x%x)",
3095				    chan, i, lp->state);
3096				isp_dump_portdb(isp, chan);
3097				ISP_MARK_PORTDB(isp, chan, 1);
3098				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3099				    "Chan %d FC scan loop DONE (bad)", chan);
3100				return (-1);
3101			}
3102
3103			/*
3104			 * Mark the device as something the f/w logs into
3105			 * automatically.
3106			 */
3107			lp->autologin = 1;
3108
3109			/*
3110			 * Check to make see if really still the same
3111			 * device. If it is, we mark it pending valid.
3112			 */
3113			if (lp->portid == tmp.portid &&
3114			    lp->handle == tmp.handle &&
3115			    lp->roles == tmp.roles) {
3116				lp->new_portid = tmp.portid;
3117				lp->new_roles = tmp.roles;
3118				lp->state = FC_PORTDB_STATE_PENDING_VALID;
3119				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3120				    "Chan %d Loop Port 0x%06x@0x%04x Pending "
3121				    "Valid", chan, tmp.portid, tmp.handle);
3122				break;
3123			}
3124
3125			/*
3126			 * We can wipe out the old handle value
3127			 * here because it's no longer valid.
3128			 */
3129			lp->handle = tmp.handle;
3130
3131			/*
3132			 * Claim that this has changed and let somebody else
3133			 * decide what to do.
3134			 */
3135			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3136			    "Chan %d Loop Port 0x%06x@0x%04x changed",
3137			    chan, tmp.portid, tmp.handle);
3138			lp->state = FC_PORTDB_STATE_CHANGED;
3139			lp->new_portid = tmp.portid;
3140			lp->new_roles = tmp.roles;
3141			break;
3142		}
3143
3144		/*
3145		 * Did we find and update an old entry?
3146		 */
3147		if (i < MAX_FC_TARG) {
3148			continue;
3149		}
3150
3151		/*
3152		 * Ah. A new device entry. Find an empty slot
3153		 * for it and save info for later disposition.
3154		 */
3155		for (i = 0; i < MAX_FC_TARG; i++) {
3156			if (fcp->portdb[i].target_mode) {
3157				continue;
3158			}
3159			if (fcp->portdb[i].state == FC_PORTDB_STATE_NIL) {
3160				break;
3161			}
3162		}
3163		if (i == MAX_FC_TARG) {
3164			isp_prt(isp, ISP_LOGERR,
3165			    "Chan %d out of portdb entries", chan);
3166			continue;
3167		}
3168		lp = &fcp->portdb[i];
3169
3170		ISP_MEMZERO(lp, sizeof (fcportdb_t));
3171		lp->autologin = 1;
3172		lp->state = FC_PORTDB_STATE_NEW;
3173		lp->new_portid = tmp.portid;
3174		lp->new_roles = tmp.roles;
3175		lp->handle = tmp.handle;
3176		lp->port_wwn = tmp.port_wwn;
3177		lp->node_wwn = tmp.node_wwn;
3178		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3179		    "Chan %d Loop Port 0x%06x@0x%04x is New Entry",
3180		    chan, tmp.portid, tmp.handle);
3181	}
3182	fcp->isp_loopstate = LOOP_LSCAN_DONE;
3183	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3184	    "Chan %d FC scan loop DONE", chan);
3185	return (0);
3186}
3187
3188/*
3189 * Scan the fabric for devices and add them to our port database.
3190 *
3191 * Use the GID_FT command to get all Port IDs for FC4 SCSI devices it knows.
3192 *
3193 * For 2100-23XX cards, we can use the SNS mailbox command to pass simple
3194 * name server commands to the switch management server via the QLogic f/w.
3195 *
3196 * For the 24XX card, we have to use CT-Pass through run via the Execute IOCB
3197 * mailbox command.
3198 *
3199 * The net result is to leave the list of Port IDs setting untranslated in
3200 * offset IGPOFF of the FC scratch area, whereupon we'll canonicalize it to
3201 * host order at OGPOFF.
3202 */
3203
3204/*
3205 * Take less than half of our scratch area to store Port IDs
3206 */
3207#define	GIDLEN	((ISP_FC_SCRLEN >> 1) - 16 - SNS_GID_FT_REQ_SIZE)
3208#define	NGENT	((GIDLEN - 16) >> 2)
3209
3210#define	IGPOFF	(2 * QENTRY_LEN)
3211#define	OGPOFF	(ISP_FC_SCRLEN >> 1)
3212#define	ZTXOFF	(ISP_FC_SCRLEN - (1 * QENTRY_LEN))
3213#define	CTXOFF	(ISP_FC_SCRLEN - (2 * QENTRY_LEN))
3214#define	XTXOFF	(ISP_FC_SCRLEN - (3 * QENTRY_LEN))
3215
3216static int
3217isp_gid_ft_sns(ispsoftc_t *isp, int chan)
3218{
3219	union {
3220		sns_gid_ft_req_t _x;
3221		uint8_t _y[SNS_GID_FT_REQ_SIZE];
3222	} un;
3223	fcparam *fcp = FCPARAM(isp, chan);
3224	sns_gid_ft_req_t *rq = &un._x;
3225	mbreg_t mbs;
3226
3227	isp_prt(isp, ISP_LOGDEBUG0,
3228	    "Chan %d scanning fabric (GID_FT) via SNS", chan);
3229
3230	ISP_MEMZERO(rq, SNS_GID_FT_REQ_SIZE);
3231	rq->snscb_rblen = GIDLEN >> 1;
3232	rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + IGPOFF);
3233	rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + IGPOFF);
3234	rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + IGPOFF);
3235	rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + IGPOFF);
3236	rq->snscb_sblen = 6;
3237	rq->snscb_cmd = SNS_GID_FT;
3238	rq->snscb_mword_div_2 = NGENT;
3239	rq->snscb_fc4_type = FC4_SCSI;
3240
3241	isp_put_gid_ft_request(isp, rq, fcp->isp_scratch);
3242	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE);
3243
3244	MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 10000000);
3245	mbs.param[0] = MBOX_SEND_SNS;
3246	mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
3247	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
3248	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
3249	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
3250	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
3251	isp_mboxcmd(isp, &mbs);
3252	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3253		if (mbs.param[0] == MBOX_INVALID_COMMAND) {
3254			return (1);
3255		} else {
3256			return (-1);
3257		}
3258	}
3259	return (0);
3260}
3261
3262static int
3263isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
3264{
3265	mbreg_t mbs;
3266	fcparam *fcp = FCPARAM(isp, chan);
3267	union {
3268		isp_ct_pt_t plocal;
3269		ct_hdr_t clocal;
3270		uint8_t q[QENTRY_LEN];
3271	} un;
3272	isp_ct_pt_t *pt;
3273	ct_hdr_t *ct;
3274	uint32_t *rp;
3275	uint8_t *scp = fcp->isp_scratch;
3276
3277	isp_prt(isp, ISP_LOGDEBUG0,
3278	    "Chan %d scanning fabric (GID_FT) via CT", chan);
3279
3280	if (!IS_24XX(isp)) {
3281		return (1);
3282	}
3283
3284	/*
3285	 * Build a Passthrough IOCB in memory.
3286	 */
3287	pt = &un.plocal;
3288	ISP_MEMZERO(un.q, QENTRY_LEN);
3289	pt->ctp_header.rqs_entry_count = 1;
3290	pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
3291	pt->ctp_handle = 0xffffffff;
3292	pt->ctp_nphdl = fcp->isp_sns_hdl;
3293	pt->ctp_cmd_cnt = 1;
3294	pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
3295	pt->ctp_time = 30;
3296	pt->ctp_rsp_cnt = 1;
3297	pt->ctp_rsp_bcnt = GIDLEN;
3298	pt->ctp_cmd_bcnt = sizeof (*ct) + sizeof (uint32_t);
3299	pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
3300	pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
3301	pt->ctp_dataseg[0].ds_count = sizeof (*ct) + sizeof (uint32_t);
3302	pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
3303	pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
3304	pt->ctp_dataseg[1].ds_count = GIDLEN;
3305	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3306		isp_print_bytes(isp, "ct IOCB", QENTRY_LEN, pt);
3307	}
3308	isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
3309
3310	/*
3311	 * Build the CT header and command in memory.
3312	 *
3313	 * Note that the CT header has to end up as Big Endian format in memory.
3314	 */
3315	ct = &un.clocal;
3316	ISP_MEMZERO(ct, sizeof (*ct));
3317	ct->ct_revision = CT_REVISION;
3318	ct->ct_fcs_type = CT_FC_TYPE_FC;
3319	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
3320	ct->ct_cmd_resp = SNS_GID_FT;
3321	ct->ct_bcnt_resid = (GIDLEN - 16) >> 2;
3322
3323	isp_put_ct_hdr(isp, ct, (ct_hdr_t *) &scp[XTXOFF]);
3324	rp = (uint32_t *) &scp[XTXOFF+sizeof (*ct)];
3325	ISP_IOZPUT_32(isp, FC4_SCSI, rp);
3326	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3327		isp_print_bytes(isp, "CT HDR + payload after put",
3328		    sizeof (*ct) + sizeof (uint32_t), &scp[XTXOFF]);
3329	}
3330	ISP_MEMZERO(&scp[ZTXOFF], QENTRY_LEN);
3331	MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
3332	mbs.param[1] = QENTRY_LEN;
3333	mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
3334	mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
3335	mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
3336	mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
3337	MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN);
3338	isp_mboxcmd(isp, &mbs);
3339	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3340		return (-1);
3341	}
3342	MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN);
3343	pt = &un.plocal;
3344	isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
3345	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3346		isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
3347	}
3348
3349	if (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) {
3350		isp_prt(isp, ISP_LOGWARN,
3351		    "Chan %d ISP GID FT CT Passthrough returned 0x%x",
3352		    chan, pt->ctp_status);
3353		return (-1);
3354	}
3355	MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN + 16);
3356	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3357		isp_print_bytes(isp, "CT response", GIDLEN+16, &scp[IGPOFF]);
3358	}
3359	return (0);
3360}
3361
3362static int
3363isp_scan_fabric(ispsoftc_t *isp, int chan)
3364{
3365	fcparam *fcp = FCPARAM(isp, chan);
3366	uint32_t portid;
3367	uint16_t handle, oldhandle, loopid;
3368	isp_pdb_t pdb;
3369	int portidx, portlim, r;
3370	sns_gid_ft_rsp_t *rs0, *rs1;
3371
3372	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3373	    "Chan %d FC Scan Fabric", chan);
3374	if (fcp->isp_fwstate != FW_READY ||
3375	    fcp->isp_loopstate < LOOP_LSCAN_DONE) {
3376		return (-1);
3377	}
3378	if (fcp->isp_loopstate > LOOP_SCANNING_FABRIC) {
3379		return (0);
3380	}
3381	if (fcp->isp_topo != TOPO_FL_PORT && fcp->isp_topo != TOPO_F_PORT) {
3382		fcp->isp_loopstate = LOOP_FSCAN_DONE;
3383		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3384		    "Chan %d FC Scan Fabric Done (no fabric)", chan);
3385		return (0);
3386	}
3387
3388	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
3389	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
3390		isp_prt(isp, ISP_LOGERR, sacq);
3391		ISP_MARK_PORTDB(isp, chan, 1);
3392		return (-1);
3393	}
3394	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3395		FC_SCRATCH_RELEASE(isp, chan);
3396		ISP_MARK_PORTDB(isp, chan, 1);
3397		return (-1);
3398	}
3399
3400	/*
3401	 * Make sure we still are logged into the fabric controller.
3402	 */
3403	if (IS_24XX(isp)) {	/* XXX SHOULDN'T THIS BE TRUE FOR 2K F/W? XXX */
3404		loopid = NPH_FL_ID;
3405	} else {
3406		loopid = FL_ID;
3407	}
3408	r = isp_getpdb(isp, chan, loopid, &pdb, 0);
3409	if (r == MBOX_NOT_LOGGED_IN) {
3410		isp_dump_chip_portdb(isp, chan, 0);
3411	}
3412	if (r) {
3413		fcp->isp_loopstate = LOOP_PDB_RCVD;
3414		FC_SCRATCH_RELEASE(isp, chan);
3415		ISP_MARK_PORTDB(isp, chan, 1);
3416		return (-1);
3417	}
3418
3419	if (IS_24XX(isp)) {
3420		r = isp_gid_ft_ct_passthru(isp, chan);
3421	} else {
3422		r = isp_gid_ft_sns(isp, chan);
3423	}
3424
3425	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3426		FC_SCRATCH_RELEASE(isp, chan);
3427		ISP_MARK_PORTDB(isp, chan, 1);
3428		return (-1);
3429	}
3430
3431	if (r > 0) {
3432		fcp->isp_loopstate = LOOP_FSCAN_DONE;
3433		FC_SCRATCH_RELEASE(isp, chan);
3434		return (0);
3435	} else if (r < 0) {
3436		fcp->isp_loopstate = LOOP_PDB_RCVD;	/* try again */
3437		FC_SCRATCH_RELEASE(isp, chan);
3438		return (0);
3439	}
3440
3441	MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN);
3442	rs0 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+IGPOFF);
3443	rs1 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+OGPOFF);
3444	isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
3445	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3446		FC_SCRATCH_RELEASE(isp, chan);
3447		ISP_MARK_PORTDB(isp, chan, 1);
3448		return (-1);
3449	}
3450	if (rs1->snscb_cthdr.ct_cmd_resp != LS_ACC) {
3451		int level;
3452		if (rs1->snscb_cthdr.ct_reason == 9 &&
3453		    rs1->snscb_cthdr.ct_explanation == 7) {
3454			level = ISP_LOGSANCFG|ISP_LOGDEBUG0;
3455		} else {
3456			level = ISP_LOGWARN;
3457		}
3458		isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_FT"
3459		    " (Reason=0x%x Expl=0x%x)", chan,
3460		    rs1->snscb_cthdr.ct_reason,
3461		    rs1->snscb_cthdr.ct_explanation);
3462		FC_SCRATCH_RELEASE(isp, chan);
3463		fcp->isp_loopstate = LOOP_FSCAN_DONE;
3464		return (0);
3465	}
3466
3467
3468	/*
3469	 * If we get this far, we certainly still have the fabric controller.
3470	 */
3471	fcp->portdb[FL_ID].state = FC_PORTDB_STATE_PENDING_VALID;
3472
3473	/*
3474	 * Prime the handle we will start using.
3475	 */
3476	oldhandle = FCPARAM(isp, 0)->isp_lasthdl;
3477
3478	/*
3479	 * Go through the list and remove duplicate port ids.
3480	 */
3481
3482	portlim = 0;
3483	portidx = 0;
3484	for (portidx = 0; portidx < NGENT-1; portidx++) {
3485		if (rs1->snscb_ports[portidx].control & 0x80) {
3486			break;
3487		}
3488	}
3489
3490	/*
3491	 * If we're not at the last entry, our list wasn't big enough.
3492	 */
3493	if ((rs1->snscb_ports[portidx].control & 0x80) == 0) {
3494		isp_prt(isp, ISP_LOGWARN,
3495		    "fabric too big for scratch area: increase ISP_FC_SCRLEN");
3496	}
3497	portlim = portidx + 1;
3498	isp_prt(isp, ISP_LOGSANCFG,
3499	    "Chan %d got %d ports back from name server", chan, portlim);
3500
3501	for (portidx = 0; portidx < portlim; portidx++) {
3502		int npidx;
3503
3504		portid =
3505		    ((rs1->snscb_ports[portidx].portid[0]) << 16) |
3506		    ((rs1->snscb_ports[portidx].portid[1]) << 8) |
3507		    ((rs1->snscb_ports[portidx].portid[2]));
3508
3509		for (npidx = portidx + 1; npidx < portlim; npidx++) {
3510			uint32_t new_portid =
3511			    ((rs1->snscb_ports[npidx].portid[0]) << 16) |
3512			    ((rs1->snscb_ports[npidx].portid[1]) << 8) |
3513			    ((rs1->snscb_ports[npidx].portid[2]));
3514			if (new_portid == portid) {
3515				break;
3516			}
3517		}
3518
3519		if (npidx < portlim) {
3520			rs1->snscb_ports[npidx].portid[0] = 0;
3521			rs1->snscb_ports[npidx].portid[1] = 0;
3522			rs1->snscb_ports[npidx].portid[2] = 0;
3523			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3524			    "Chan %d removing duplicate PortID 0x%06x"
3525			    " entry from list", chan, portid);
3526		}
3527	}
3528
3529	/*
3530	 * We now have a list of Port IDs for all FC4 SCSI devices
3531	 * that the Fabric Name server knows about.
3532	 *
3533	 * For each entry on this list go through our port database looking
3534	 * for probational entries- if we find one, then an old entry is
3535	 * maybe still this one. We get some information to find out.
3536	 *
3537	 * Otherwise, it's a new fabric device, and we log into it
3538	 * (unconditionally). After searching the entire database
3539	 * again to make sure that we never ever ever ever have more
3540	 * than one entry that has the same PortID or the same
3541	 * WWNN/WWPN duple, we enter the device into our database.
3542	 */
3543
3544	for (portidx = 0; portidx < portlim; portidx++) {
3545		fcportdb_t *lp;
3546		uint64_t wwnn, wwpn;
3547		int dbidx, nr;
3548
3549		portid =
3550		    ((rs1->snscb_ports[portidx].portid[0]) << 16) |
3551		    ((rs1->snscb_ports[portidx].portid[1]) << 8) |
3552		    ((rs1->snscb_ports[portidx].portid[2]));
3553
3554		if (portid == 0) {
3555			isp_prt(isp, ISP_LOGSANCFG,
3556			    "Chan %d skipping null PortID at idx %d",
3557			    chan, portidx);
3558			continue;
3559		}
3560
3561		/*
3562		 * Skip ourselves here and on other channels. If we're
3563		 * multi-id, we can't check the portids in other FCPARAM
3564		 * arenas because the resolutions here aren't synchronized.
3565		 * The best way to do this is to exclude looking at portids
3566		 * that have the same domain and area code as our own
3567		 * portid.
3568		 */
3569		if (ISP_CAP_MULTI_ID(isp)) {
3570			if ((portid >> 8) == (fcp->isp_portid >> 8)) {
3571				isp_prt(isp, ISP_LOGSANCFG,
3572				    "Chan %d skip PortID 0x%06x",
3573				    chan, portid);
3574				continue;
3575			}
3576		} else if (portid == fcp->isp_portid) {
3577			isp_prt(isp, ISP_LOGSANCFG,
3578			    "Chan %d skip ourselves on @ PortID 0x%06x",
3579			    chan, portid);
3580			continue;
3581		}
3582
3583		isp_prt(isp, ISP_LOGSANCFG,
3584		    "Chan %d Checking Fabric Port 0x%06x", chan, portid);
3585
3586		/*
3587		 * We now search our Port Database for any
3588		 * probational entries with this PortID. We don't
3589		 * look for zombies here- only probational
3590		 * entries (we've already logged out of zombies).
3591		 */
3592		for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
3593			lp = &fcp->portdb[dbidx];
3594
3595			if (lp->state != FC_PORTDB_STATE_PROBATIONAL ||
3596			    lp->target_mode) {
3597				continue;
3598			}
3599			if (lp->portid == portid) {
3600				break;
3601			}
3602		}
3603
3604		/*
3605		 * We found a probational entry with this Port ID.
3606		 */
3607		if (dbidx < MAX_FC_TARG) {
3608			int handle_changed = 0;
3609
3610			lp = &fcp->portdb[dbidx];
3611
3612			/*
3613			 * See if we're still logged into it.
3614			 *
3615			 * If we aren't, mark it as a dead device and
3616			 * leave the new portid in the database entry
3617			 * for somebody further along to decide what to
3618			 * do (policy choice).
3619			 *
3620			 * If we are, check to see if it's the same
3621			 * device still (it should be). If for some
3622			 * reason it isn't, mark it as a changed device
3623			 * and leave the new portid and role in the
3624			 * database entry for somebody further along to
3625			 * decide what to do (policy choice).
3626			 *
3627			 */
3628
3629			r = isp_getpdb(isp, chan, lp->handle, &pdb, 0);
3630			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3631				FC_SCRATCH_RELEASE(isp, chan);
3632				ISP_MARK_PORTDB(isp, chan, 1);
3633				return (-1);
3634			}
3635			if (r != 0) {
3636				lp->new_portid = portid;
3637				lp->state = FC_PORTDB_STATE_DEAD;
3638				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3639				    "Chan %d Fabric Port 0x%06x is dead",
3640				    chan, portid);
3641				continue;
3642			}
3643
3644
3645			/*
3646			 * Check to make sure that handle, portid, WWPN and
3647			 * WWNN agree. If they don't, then the association
3648			 * between this PortID and the stated handle has been
3649			 * broken by the firmware.
3650			 */
3651			MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
3652			MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3653			if (pdb.handle != lp->handle ||
3654			    pdb.portid != portid ||
3655			    wwpn != lp->port_wwn ||
3656			    wwnn != lp->node_wwn) {
3657				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3658				    fconf, chan, dbidx, pdb.handle, pdb.portid,
3659				    (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
3660				    (uint32_t) (wwpn >> 32), (uint32_t) wwpn,
3661				    lp->handle, portid,
3662				    (uint32_t) (lp->node_wwn >> 32),
3663				    (uint32_t) lp->node_wwn,
3664				    (uint32_t) (lp->port_wwn >> 32),
3665				    (uint32_t) lp->port_wwn);
3666				/*
3667				 * Try to re-login to this device using a
3668				 * new handle. If that fails, mark it dead.
3669				 *
3670				 * isp_login_device will check for handle and
3671				 * portid consistency after re-login.
3672				 *
3673				 */
3674				if (isp_login_device(isp, chan, portid, &pdb,
3675				    &oldhandle)) {
3676					lp->new_portid = portid;
3677					lp->state = FC_PORTDB_STATE_DEAD;
3678					if (fcp->isp_loopstate !=
3679					    LOOP_SCANNING_FABRIC) {
3680						FC_SCRATCH_RELEASE(isp, chan);
3681						ISP_MARK_PORTDB(isp, chan, 1);
3682						return (-1);
3683					}
3684					continue;
3685				}
3686				if (fcp->isp_loopstate !=
3687				    LOOP_SCANNING_FABRIC) {
3688					FC_SCRATCH_RELEASE(isp, chan);
3689					ISP_MARK_PORTDB(isp, chan, 1);
3690					return (-1);
3691				}
3692				FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
3693				MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
3694				MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3695				if (wwpn != lp->port_wwn ||
3696				    wwnn != lp->node_wwn) {
3697					isp_prt(isp, ISP_LOGWARN, "changed WWN"
3698					    " after relogin");
3699					lp->new_portid = portid;
3700					lp->state = FC_PORTDB_STATE_DEAD;
3701					continue;
3702				}
3703
3704				lp->handle = pdb.handle;
3705				handle_changed++;
3706			}
3707
3708			nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
3709
3710			/*
3711			 * Check to see whether the portid and roles have
3712			 * stayed the same. If they have stayed the same,
3713			 * we believe that this is the same device and it
3714			 * hasn't become disconnected and reconnected, so
3715			 * mark it as pending valid.
3716			 *
3717			 * If they aren't the same, mark the device as a
3718			 * changed device and save the new port id and role
3719			 * and let somebody else decide.
3720			 */
3721
3722			lp->new_portid = portid;
3723			lp->new_roles = nr;
3724			if (pdb.portid != lp->portid || nr != lp->roles ||
3725			    handle_changed) {
3726				isp_prt(isp, ISP_LOGSANCFG,
3727				    "Chan %d Fabric Port 0x%06x changed",
3728				    chan, portid);
3729				lp->state = FC_PORTDB_STATE_CHANGED;
3730			} else {
3731				isp_prt(isp, ISP_LOGSANCFG,
3732				    "Chan %d Fabric Port 0x%06x "
3733				    "Now Pending Valid", chan, portid);
3734				lp->state = FC_PORTDB_STATE_PENDING_VALID;
3735			}
3736			continue;
3737		}
3738
3739		/*
3740		 * Ah- a new entry. Search the database again for all non-NIL
3741		 * entries to make sure we never ever make a new database entry
3742		 * with the same port id. While we're at it, mark where the
3743		 * last free entry was.
3744		 */
3745
3746		dbidx = MAX_FC_TARG;
3747		for (lp = fcp->portdb; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
3748			if (lp >= &fcp->portdb[FL_ID] &&
3749			    lp <= &fcp->portdb[SNS_ID]) {
3750				continue;
3751			}
3752			/*
3753			 * Skip any target mode entries.
3754			 */
3755			if (lp->target_mode) {
3756				continue;
3757			}
3758			if (lp->state == FC_PORTDB_STATE_NIL) {
3759				if (dbidx == MAX_FC_TARG) {
3760					dbidx = lp - fcp->portdb;
3761				}
3762				continue;
3763			}
3764			if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
3765				continue;
3766			}
3767			if (lp->portid == portid) {
3768				break;
3769			}
3770		}
3771
3772		if (lp < &fcp->portdb[MAX_FC_TARG]) {
3773			isp_prt(isp, ISP_LOGWARN, "Chan %d PortID 0x%06x "
3774			    "already at %d handle %d state %d",
3775			    chan, portid, dbidx, lp->handle, lp->state);
3776			continue;
3777		}
3778
3779		/*
3780		 * We should have the index of the first free entry seen.
3781		 */
3782		if (dbidx == MAX_FC_TARG) {
3783			isp_prt(isp, ISP_LOGERR,
3784			    "port database too small to login PortID 0x%06x"
3785			    "- increase MAX_FC_TARG", portid);
3786			continue;
3787		}
3788
3789		/*
3790		 * Otherwise, point to our new home.
3791		 */
3792		lp = &fcp->portdb[dbidx];
3793
3794		/*
3795		 * Try to see if we are logged into this device,
3796		 * and maybe log into it.
3797		 *
3798		 * isp_login_device will check for handle and
3799		 * portid consistency after login.
3800		 */
3801		if (isp_login_device(isp, chan, portid, &pdb, &oldhandle)) {
3802			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3803				FC_SCRATCH_RELEASE(isp, chan);
3804				ISP_MARK_PORTDB(isp, chan, 1);
3805				return (-1);
3806			}
3807			continue;
3808		}
3809		if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3810			FC_SCRATCH_RELEASE(isp, chan);
3811			ISP_MARK_PORTDB(isp, chan, 1);
3812			return (-1);
3813		}
3814		FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
3815
3816		handle = pdb.handle;
3817		MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
3818		MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3819		nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
3820
3821		/*
3822		 * And go through the database *one* more time to make sure
3823		 * that we do not make more than one entry that has the same
3824		 * WWNN/WWPN duple
3825		 */
3826		for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
3827			if (dbidx >= FL_ID && dbidx <= SNS_ID) {
3828				continue;
3829			}
3830			if (fcp->portdb[dbidx].target_mode) {
3831				continue;
3832			}
3833			if (fcp->portdb[dbidx].node_wwn == wwnn &&
3834			    fcp->portdb[dbidx].port_wwn == wwpn) {
3835				break;
3836			}
3837		}
3838
3839		if (dbidx == MAX_FC_TARG) {
3840			ISP_MEMZERO(lp, sizeof (fcportdb_t));
3841			lp->handle = handle;
3842			lp->node_wwn = wwnn;
3843			lp->port_wwn = wwpn;
3844			lp->new_portid = portid;
3845			lp->new_roles = nr;
3846			lp->state = FC_PORTDB_STATE_NEW;
3847			isp_prt(isp, ISP_LOGSANCFG,
3848			    "Chan %d Fabric Port 0x%06x is a New Entry",
3849			    chan, portid);
3850			continue;
3851		}
3852
3853    		if (fcp->portdb[dbidx].state != FC_PORTDB_STATE_ZOMBIE) {
3854			isp_prt(isp, ISP_LOGWARN,
3855			    "Chan %d PortID 0x%x 0x%08x%08x/0x%08x%08x %ld "
3856			    "already at idx %d, state 0x%x", chan, portid,
3857			    (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
3858			    (uint32_t) (wwpn >> 32), (uint32_t) wwpn,
3859			    (long) (lp - fcp->portdb), dbidx,
3860			    fcp->portdb[dbidx].state);
3861			continue;
3862		}
3863
3864		/*
3865		 * We found a zombie entry that matches us.
3866		 * Revive it. We know that WWN and WWPN
3867		 * are the same. For fabric devices, we
3868		 * don't care that handle is different
3869		 * as we assign that. If role or portid
3870		 * are different, it maybe a changed device.
3871		 */
3872		lp = &fcp->portdb[dbidx];
3873		lp->handle = handle;
3874		lp->new_portid = portid;
3875		lp->new_roles = nr;
3876		if (lp->portid != portid || lp->roles != nr) {
3877			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3878			    "Chan %d Zombie Fabric Port 0x%06x Now Changed",
3879			    chan, portid);
3880			lp->state = FC_PORTDB_STATE_CHANGED;
3881		} else {
3882			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3883			    "Chan %d Zombie Fabric Port 0x%06x "
3884			    "Now Pending Valid", chan, portid);
3885			lp->state = FC_PORTDB_STATE_PENDING_VALID;
3886		}
3887	}
3888
3889	FC_SCRATCH_RELEASE(isp, chan);
3890	if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3891		ISP_MARK_PORTDB(isp, chan, 1);
3892		return (-1);
3893	}
3894	fcp->isp_loopstate = LOOP_FSCAN_DONE;
3895	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3896	    "Chan %d FC Scan Fabric Done", chan);
3897	return (0);
3898}
3899
3900/*
3901 * Find an unused handle and try and use to login to a port.
3902 */
3903static int
3904isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p,
3905    uint16_t *ohp)
3906{
3907	int lim, i, r;
3908	uint16_t handle;
3909
3910	if (ISP_CAP_2KLOGIN(isp)) {
3911		lim = NPH_MAX_2K;
3912	} else {
3913		lim = NPH_MAX;
3914	}
3915
3916	handle = isp_nxt_handle(isp, chan, *ohp);
3917	for (i = 0; i < lim; i++) {
3918		/*
3919		 * See if we're still logged into something with
3920		 * this handle and that something agrees with this
3921		 * port id.
3922		 */
3923		r = isp_getpdb(isp, chan, handle, p, 0);
3924		if (r == 0 && p->portid != portid) {
3925			(void) isp_plogx(isp, chan, handle, portid,
3926			    PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT, 1);
3927		} else if (r == 0) {
3928			break;
3929		}
3930		if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3931			return (-1);
3932		}
3933		/*
3934		 * Now try and log into the device
3935		 */
3936		r = isp_plogx(isp, chan, handle, portid,
3937		    PLOGX_FLG_CMD_PLOGI, 1);
3938		if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3939			return (-1);
3940		}
3941		if (r == 0) {
3942			*ohp = handle;
3943			break;
3944		} else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
3945			handle = r >> 16;
3946			break;
3947		} else if (r != MBOX_LOOP_ID_USED) {
3948			i = lim;
3949			break;
3950		} else if (r == MBOX_TIMEOUT) {
3951			return (-1);
3952		} else {
3953			*ohp = handle;
3954			handle = isp_nxt_handle(isp, chan, *ohp);
3955		}
3956	}
3957
3958	if (i == lim) {
3959		isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed",
3960		    chan, portid);
3961		return (-1);
3962	}
3963
3964	/*
3965	 * If we successfully logged into it, get the PDB for it
3966	 * so we can crosscheck that it is still what we think it
3967	 * is and that we also have the role it plays
3968	 */
3969	r = isp_getpdb(isp, chan, handle, p, 0);
3970	if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3971		return (-1);
3972	}
3973	if (r != 0) {
3974		isp_prt(isp, ISP_LOGERR,
3975		    "Chan %d new device 0x%06x@0x%x disappeared",
3976		    chan, portid, handle);
3977		return (-1);
3978	}
3979
3980	if (p->handle != handle || p->portid != portid) {
3981		isp_prt(isp, ISP_LOGERR,
3982		    "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
3983		    chan, portid, handle, p->portid, p->handle);
3984		return (-1);
3985	}
3986	return (0);
3987}
3988
3989static int
3990isp_register_fc4_type(ispsoftc_t *isp, int chan)
3991{
3992	fcparam *fcp = FCPARAM(isp, chan);
3993	uint8_t local[SNS_RFT_ID_REQ_SIZE];
3994	sns_screq_t *reqp = (sns_screq_t *) local;
3995	mbreg_t mbs;
3996
3997	ISP_MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
3998	reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
3999	reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
4000	reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
4001	reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
4002	reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
4003	reqp->snscb_sblen = 22;
4004	reqp->snscb_data[0] = SNS_RFT_ID;
4005	reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
4006	reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
4007	reqp->snscb_data[6] = (1 << FC4_SCSI);
4008	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4009		isp_prt(isp, ISP_LOGERR, sacq);
4010		return (-1);
4011	}
4012	isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
4013	MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 1000000);
4014	mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
4015	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4016	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4017	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4018	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4019	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE);
4020	isp_mboxcmd(isp, &mbs);
4021	FC_SCRATCH_RELEASE(isp, chan);
4022	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
4023		return (0);
4024	} else {
4025		return (-1);
4026	}
4027}
4028
4029static int
4030isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
4031{
4032	mbreg_t mbs;
4033	fcparam *fcp = FCPARAM(isp, chan);
4034	union {
4035		isp_ct_pt_t plocal;
4036		rft_id_t clocal;
4037		uint8_t q[QENTRY_LEN];
4038	} un;
4039	isp_ct_pt_t *pt;
4040	ct_hdr_t *ct;
4041	rft_id_t *rp;
4042	uint8_t *scp = fcp->isp_scratch;
4043
4044	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4045		isp_prt(isp, ISP_LOGERR, sacq);
4046		return (-1);
4047	}
4048
4049	/*
4050	 * Build a Passthrough IOCB in memory.
4051	 */
4052	ISP_MEMZERO(un.q, QENTRY_LEN);
4053	pt = &un.plocal;
4054	pt->ctp_header.rqs_entry_count = 1;
4055	pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
4056	pt->ctp_handle = 0xffffffff;
4057	pt->ctp_nphdl = fcp->isp_sns_hdl;
4058	pt->ctp_cmd_cnt = 1;
4059	pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
4060	pt->ctp_time = 1;
4061	pt->ctp_rsp_cnt = 1;
4062	pt->ctp_rsp_bcnt = sizeof (ct_hdr_t);
4063	pt->ctp_cmd_bcnt = sizeof (rft_id_t);
4064	pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
4065	pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
4066	pt->ctp_dataseg[0].ds_count = sizeof (rft_id_t);
4067	pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
4068	pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
4069	pt->ctp_dataseg[1].ds_count = sizeof (ct_hdr_t);
4070	isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
4071	if (isp->isp_dblev & ISP_LOGDEBUG1) {
4072		isp_print_bytes(isp, "IOCB CT Request", QENTRY_LEN, pt);
4073	}
4074
4075	/*
4076	 * Build the CT header and command in memory.
4077	 *
4078	 * Note that the CT header has to end up as Big Endian format in memory.
4079	 */
4080	ISP_MEMZERO(&un.clocal, sizeof (un.clocal));
4081	ct = &un.clocal.rftid_hdr;
4082	ct->ct_revision = CT_REVISION;
4083	ct->ct_fcs_type = CT_FC_TYPE_FC;
4084	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
4085	ct->ct_cmd_resp = SNS_RFT_ID;
4086	ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
4087	rp = &un.clocal;
4088	rp->rftid_portid[0] = fcp->isp_portid >> 16;
4089	rp->rftid_portid[1] = fcp->isp_portid >> 8;
4090	rp->rftid_portid[2] = fcp->isp_portid;
4091	rp->rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
4092	isp_put_rft_id(isp, rp, (rft_id_t *) &scp[XTXOFF]);
4093	if (isp->isp_dblev & ISP_LOGDEBUG1) {
4094		isp_print_bytes(isp, "CT Header", QENTRY_LEN, &scp[XTXOFF]);
4095	}
4096
4097	ISP_MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
4098
4099	MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 1000000);
4100	mbs.param[1] = QENTRY_LEN;
4101	mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
4102	mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
4103	mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
4104	mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
4105	MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN);
4106	isp_mboxcmd(isp, &mbs);
4107	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4108		FC_SCRATCH_RELEASE(isp, chan);
4109		return (-1);
4110	}
4111	MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN);
4112	pt = &un.plocal;
4113	isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
4114	if (isp->isp_dblev & ISP_LOGDEBUG1) {
4115		isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
4116	}
4117	if (pt->ctp_status) {
4118		FC_SCRATCH_RELEASE(isp, chan);
4119		isp_prt(isp, ISP_LOGWARN,
4120		    "Chan %d Register FC4 Type CT Passthrough returned 0x%x",
4121		    chan, pt->ctp_status);
4122		return (1);
4123	}
4124
4125	isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct);
4126	FC_SCRATCH_RELEASE(isp, chan);
4127
4128	if (ct->ct_cmd_resp == LS_RJT) {
4129		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
4130		    "Chan %d Register FC4 Type rejected", chan);
4131		return (-1);
4132	} else if (ct->ct_cmd_resp == LS_ACC) {
4133		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
4134		    "Chan %d Register FC4 Type accepted", chan);
4135		return (0);
4136	} else {
4137		isp_prt(isp, ISP_LOGWARN,
4138		    "Chan %d Register FC4 Type: 0x%x",
4139		    chan, ct->ct_cmd_resp);
4140		return (-1);
4141	}
4142}
4143
4144static uint16_t
4145isp_nxt_handle(ispsoftc_t *isp, int chan, uint16_t handle)
4146{
4147	int i;
4148	if (handle == NIL_HANDLE) {
4149		if (FCPARAM(isp, chan)->isp_topo == TOPO_F_PORT) {
4150			handle = 0;
4151		} else {
4152			handle = SNS_ID+1;
4153		}
4154	} else {
4155		handle += 1;
4156		if (handle >= FL_ID && handle <= SNS_ID) {
4157			handle = SNS_ID+1;
4158		}
4159		if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
4160			handle = NPH_FL_ID+1;
4161		}
4162		if (ISP_CAP_2KLOGIN(isp)) {
4163			if (handle == NPH_MAX_2K) {
4164				handle = 0;
4165			}
4166		} else {
4167			if (handle == NPH_MAX) {
4168				handle = 0;
4169			}
4170		}
4171	}
4172	if (handle == FCPARAM(isp, chan)->isp_loopid) {
4173		return (isp_nxt_handle(isp, chan, handle));
4174	}
4175	for (i = 0; i < MAX_FC_TARG; i++) {
4176		if (FCPARAM(isp, chan)->portdb[i].state ==
4177		    FC_PORTDB_STATE_NIL) {
4178			continue;
4179		}
4180		if (FCPARAM(isp, chan)->portdb[i].handle == handle) {
4181			return (isp_nxt_handle(isp, chan, handle));
4182		}
4183	}
4184	return (handle);
4185}
4186
4187/*
4188 * Start a command. Locking is assumed done in the caller.
4189 */
4190
4191int
4192isp_start(XS_T *xs)
4193{
4194	ispsoftc_t *isp;
4195	uint32_t handle;
4196	uint8_t local[QENTRY_LEN];
4197	ispreq_t *reqp;
4198	void *cdbp, *qep;
4199	uint16_t *tptr;
4200	int target, dmaresult, hdlidx = 0;
4201
4202	XS_INITERR(xs);
4203	isp = XS_ISP(xs);
4204
4205	/*
4206	 * Now make sure we're running.
4207	 */
4208
4209	if (isp->isp_state != ISP_RUNSTATE) {
4210		isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
4211		XS_SETERR(xs, HBA_BOTCH);
4212		return (CMD_COMPLETE);
4213	}
4214
4215	/*
4216	 * Check command CDB length, etc.. We really are limited to 16 bytes
4217	 * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
4218	 * but probably only if we're running fairly new firmware (we'll
4219	 * let the old f/w choke on an extended command queue entry).
4220	 */
4221
4222	if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
4223		isp_prt(isp, ISP_LOGERR, "unsupported cdb length (%d, CDB[0]=0x%x)", XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
4224		XS_SETERR(xs, HBA_BOTCH);
4225		return (CMD_COMPLETE);
4226	}
4227
4228	/*
4229	 * Translate the target to device handle as appropriate, checking
4230	 * for correct device state as well.
4231	 */
4232	target = XS_TGT(xs);
4233	if (IS_FC(isp)) {
4234		fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
4235
4236		if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
4237			XS_SETERR(xs, HBA_SELTIMEOUT);
4238			return (CMD_COMPLETE);
4239		}
4240
4241		/*
4242		 * Try again later.
4243		 */
4244		if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate != LOOP_READY) {
4245			return (CMD_RQLATER);
4246		}
4247
4248		if (XS_TGT(xs) >= MAX_FC_TARG) {
4249			XS_SETERR(xs, HBA_SELTIMEOUT);
4250			return (CMD_COMPLETE);
4251		}
4252
4253		hdlidx = fcp->isp_dev_map[XS_TGT(xs)] - 1;
4254		isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d- hdlidx value %d", XS_TGT(xs), hdlidx);
4255		if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
4256			XS_SETERR(xs, HBA_SELTIMEOUT);
4257			return (CMD_COMPLETE);
4258		}
4259		if (fcp->portdb[hdlidx].state == FC_PORTDB_STATE_ZOMBIE) {
4260			return (CMD_RQLATER);
4261		}
4262		if (fcp->portdb[hdlidx].state != FC_PORTDB_STATE_VALID) {
4263			XS_SETERR(xs, HBA_SELTIMEOUT);
4264			return (CMD_COMPLETE);
4265		}
4266		target = fcp->portdb[hdlidx].handle;
4267		fcp->portdb[hdlidx].dirty = 1;
4268	} else {
4269		sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
4270		if ((sdp->role & ISP_ROLE_INITIATOR) == 0) {
4271			XS_SETERR(xs, HBA_SELTIMEOUT);
4272			return (CMD_COMPLETE);
4273		}
4274		if (sdp->update) {
4275			isp_spi_update(isp, XS_CHANNEL(xs));
4276		}
4277	}
4278
4279 start_again:
4280
4281	qep = isp_getrqentry(isp);
4282	if (qep == NULL) {
4283		isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
4284		XS_SETERR(xs, HBA_BOTCH);
4285		return (CMD_EAGAIN);
4286	}
4287	XS_SETERR(xs, HBA_NOERROR);
4288
4289	/*
4290	 * Now see if we need to synchronize the ISP with respect to anything.
4291	 * We do dual duty here (cough) for synchronizing for busses other
4292	 * than which we got here to send a command to.
4293	 */
4294	reqp = (ispreq_t *) local;
4295	ISP_MEMZERO(local, QENTRY_LEN);
4296	if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) {
4297		if (IS_24XX(isp)) {
4298			isp_marker_24xx_t *m = (isp_marker_24xx_t *) reqp;
4299			m->mrk_header.rqs_entry_count = 1;
4300			m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
4301			m->mrk_modifier = SYNC_ALL;
4302			isp_put_marker_24xx(isp, m, qep);
4303		} else {
4304			isp_marker_t *m = (isp_marker_t *) reqp;
4305			m->mrk_header.rqs_entry_count = 1;
4306			m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
4307			m->mrk_target = (XS_CHANNEL(xs) << 7);	/* bus # */
4308			m->mrk_modifier = SYNC_ALL;
4309			isp_put_marker(isp, m, qep);
4310		}
4311		ISP_SYNC_REQUEST(isp);
4312		ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 0);
4313		goto start_again;
4314	}
4315
4316	reqp->req_header.rqs_entry_count = 1;
4317	if (IS_24XX(isp)) {
4318		reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
4319	} else if (IS_FC(isp)) {
4320		reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
4321	} else {
4322		if (XS_CDBLEN(xs) > 12) {
4323			reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
4324		} else {
4325			reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
4326		}
4327	}
4328	/* reqp->req_header.rqs_flags = 0; */
4329	/* reqp->req_header.rqs_seqno = 0; */
4330	if (IS_24XX(isp)) {
4331		int ttype;
4332		if (XS_TAG_P(xs)) {
4333			ttype = XS_TAG_TYPE(xs);
4334		} else {
4335			if (XS_CDBP(xs)[0] == 0x3) {
4336				ttype = REQFLAG_HTAG;
4337			} else {
4338				ttype = REQFLAG_STAG;
4339			}
4340		}
4341		if (ttype == REQFLAG_OTAG) {
4342			ttype = FCP_CMND_TASK_ATTR_ORDERED;
4343		} else if (ttype == REQFLAG_HTAG) {
4344			ttype = FCP_CMND_TASK_ATTR_HEAD;
4345		} else {
4346			ttype = FCP_CMND_TASK_ATTR_SIMPLE;
4347		}
4348		((ispreqt7_t *)reqp)->req_task_attribute = ttype;
4349	} else if (IS_FC(isp)) {
4350		/*
4351		 * See comment in isp_intr
4352		 */
4353		/* XS_SET_RESID(xs, 0); */
4354
4355		/*
4356		 * Fibre Channel always requires some kind of tag.
4357		 * The Qlogic drivers seem be happy not to use a tag,
4358		 * but this breaks for some devices (IBM drives).
4359		 */
4360		if (XS_TAG_P(xs)) {
4361			((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
4362		} else {
4363			/*
4364			 * If we don't know what tag to use, use HEAD OF QUEUE
4365			 * for Request Sense or Simple.
4366			 */
4367			if (XS_CDBP(xs)[0] == 0x3)	/* REQUEST SENSE */
4368				((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
4369			else
4370				((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
4371		}
4372	} else {
4373		sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
4374		if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) && XS_TAG_P(xs)) {
4375			reqp->req_flags = XS_TAG_TYPE(xs);
4376		}
4377	}
4378	cdbp = reqp->req_cdb;
4379	tptr = &reqp->req_time;
4380
4381	if (IS_SCSI(isp)) {
4382		reqp->req_target = target | (XS_CHANNEL(xs) << 7);
4383		reqp->req_lun_trn = XS_LUN(xs);
4384		reqp->req_cdblen = XS_CDBLEN(xs);
4385	} else if (IS_24XX(isp)) {
4386		fcportdb_t *lp;
4387
4388		lp = &FCPARAM(isp, XS_CHANNEL(xs))->portdb[hdlidx];
4389		((ispreqt7_t *)reqp)->req_nphdl = target;
4390		((ispreqt7_t *)reqp)->req_tidlo = lp->portid;
4391		((ispreqt7_t *)reqp)->req_tidhi = lp->portid >> 16;
4392		((ispreqt7_t *)reqp)->req_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(xs));
4393		if (XS_LUN(xs) > 256) {
4394			((ispreqt7_t *)reqp)->req_lun[0] = XS_LUN(xs) >> 8;
4395			((ispreqt7_t *)reqp)->req_lun[0] |= 0x40;
4396		}
4397		((ispreqt7_t *)reqp)->req_lun[1] = XS_LUN(xs);
4398		cdbp = ((ispreqt7_t *)reqp)->req_cdb;
4399		tptr = &((ispreqt7_t *)reqp)->req_time;
4400	} else if (ISP_CAP_2KLOGIN(isp)) {
4401		((ispreqt2e_t *)reqp)->req_target = target;
4402		((ispreqt2e_t *)reqp)->req_scclun = XS_LUN(xs);
4403	} else if (ISP_CAP_SCCFW(isp)) {
4404		((ispreqt2_t *)reqp)->req_target = target;
4405		((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
4406	} else {
4407		((ispreqt2_t *)reqp)->req_target = target;
4408		((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
4409	}
4410	ISP_MEMCPY(cdbp, XS_CDBP(xs), XS_CDBLEN(xs));
4411
4412	*tptr = XS_TIME(xs) / 1000;
4413	if (*tptr == 0 && XS_TIME(xs)) {
4414		*tptr = 1;
4415	}
4416	if (IS_24XX(isp) && *tptr > 0x1999) {
4417		*tptr = 0x1999;
4418	}
4419
4420	if (isp_save_xs(isp, xs, &handle)) {
4421		isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
4422		XS_SETERR(xs, HBA_BOTCH);
4423		return (CMD_EAGAIN);
4424	}
4425	/* Whew. Thankfully the same for type 7 requests */
4426	reqp->req_handle = handle;
4427
4428	/*
4429	 * Set up DMA and/or do any platform dependent swizzling of the request entry
4430	 * so that the Qlogic F/W understands what is being asked of it.
4431	 *
4432	 * The callee is responsible for adding all requests at this point.
4433	 */
4434	dmaresult = ISP_DMASETUP(isp, xs, reqp);
4435	if (dmaresult != CMD_QUEUED) {
4436		isp_destroy_handle(isp, handle);
4437		/*
4438		 * dmasetup sets actual error in packet, and
4439		 * return what we were given to return.
4440		 */
4441		return (dmaresult);
4442	}
4443	isp_prt(isp, ISP_LOGDEBUG0, "START cmd for %d.%d.%d cmd 0x%x datalen %ld", XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0], (long) XS_XFRLEN(xs));
4444	isp->isp_nactive++;
4445	return (CMD_QUEUED);
4446}
4447
4448/*
4449 * isp control
4450 * Locks (ints blocked) assumed held.
4451 */
4452
4453int
4454isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
4455{
4456	XS_T *xs;
4457	mbreg_t *mbr, mbs;
4458	int chan, tgt;
4459	uint32_t handle;
4460	va_list ap;
4461
4462	switch (ctl) {
4463	case ISPCTL_RESET_BUS:
4464		/*
4465		 * Issue a bus reset.
4466		 */
4467		if (IS_24XX(isp)) {
4468			isp_prt(isp, ISP_LOGWARN, "RESET BUS NOT IMPLEMENTED");
4469			break;
4470		} else if (IS_FC(isp)) {
4471			mbs.param[1] = 10;
4472			chan = 0;
4473		} else {
4474			va_start(ap, ctl);
4475			chan = va_arg(ap, int);
4476			va_end(ap);
4477			mbs.param[1] = SDPARAM(isp, chan)->isp_bus_reset_delay;
4478			if (mbs.param[1] < 2) {
4479				mbs.param[1] = 2;
4480			}
4481			mbs.param[2] = chan;
4482		}
4483		MBSINIT(&mbs, MBOX_BUS_RESET, MBLOGALL, 0);
4484		ISP_SET_SENDMARKER(isp, chan, 1);
4485		isp_mboxcmd(isp, &mbs);
4486		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4487			break;
4488		}
4489		isp_prt(isp, ISP_LOGINFO,
4490		    "driver initiated bus reset of bus %d", chan);
4491		return (0);
4492
4493	case ISPCTL_RESET_DEV:
4494		va_start(ap, ctl);
4495		chan = va_arg(ap, int);
4496		tgt = va_arg(ap, int);
4497		va_end(ap);
4498		if (IS_24XX(isp)) {
4499			uint8_t local[QENTRY_LEN];
4500			isp24xx_tmf_t *tmf;
4501			isp24xx_statusreq_t *sp;
4502			fcparam *fcp = FCPARAM(isp, chan);
4503			fcportdb_t *lp;
4504			int hdlidx;
4505
4506			hdlidx = fcp->isp_dev_map[tgt] - 1;
4507			if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
4508				isp_prt(isp, ISP_LOGWARN,
4509				    "Chan %d bad handle %d trying to reset"
4510				    "target %d", chan, hdlidx, tgt);
4511				break;
4512			}
4513			lp = &fcp->portdb[hdlidx];
4514			if (lp->state != FC_PORTDB_STATE_VALID) {
4515				isp_prt(isp, ISP_LOGWARN,
4516				    "Chan %d handle %d for abort of target %d "
4517				    "no longer valid", chan,
4518				    hdlidx, tgt);
4519				break;
4520			}
4521
4522			tmf = (isp24xx_tmf_t *) local;
4523			ISP_MEMZERO(tmf, QENTRY_LEN);
4524			tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
4525			tmf->tmf_header.rqs_entry_count = 1;
4526			tmf->tmf_nphdl = lp->handle;
4527			tmf->tmf_delay = 2;
4528			tmf->tmf_timeout = 2;
4529			tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
4530			tmf->tmf_tidlo = lp->portid;
4531			tmf->tmf_tidhi = lp->portid >> 16;
4532			tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
4533			isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
4534			MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
4535			mbs.param[1] = QENTRY_LEN;
4536			mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4537			mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4538			mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4539			mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4540
4541			if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4542				isp_prt(isp, ISP_LOGERR, sacq);
4543				break;
4544			}
4545			isp_put_24xx_tmf(isp, tmf, fcp->isp_scratch);
4546			MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN);
4547			fcp->sendmarker = 1;
4548			isp_mboxcmd(isp, &mbs);
4549			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4550				FC_SCRATCH_RELEASE(isp, chan);
4551				break;
4552			}
4553			MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
4554			    QENTRY_LEN);
4555			sp = (isp24xx_statusreq_t *) local;
4556			isp_get_24xx_response(isp,
4557			    &((isp24xx_statusreq_t *)fcp->isp_scratch)[1], sp);
4558			FC_SCRATCH_RELEASE(isp, chan);
4559			if (sp->req_completion_status == 0) {
4560				return (0);
4561			}
4562			isp_prt(isp, ISP_LOGWARN,
4563			    "Chan %d reset of target %d returned 0x%x",
4564			    chan, tgt, sp->req_completion_status);
4565			break;
4566		} else if (IS_FC(isp)) {
4567			if (ISP_CAP_2KLOGIN(isp)) {
4568				mbs.param[1] = tgt;
4569				mbs.ibits = (1 << 10);
4570			} else {
4571				mbs.param[1] = (tgt << 8);
4572			}
4573		} else {
4574			mbs.param[1] = (chan << 15) | (tgt << 8);
4575		}
4576		MBSINIT(&mbs, MBOX_ABORT_TARGET, MBLOGALL, 0);
4577		mbs.param[2] = 3;	/* 'delay', in seconds */
4578		isp_mboxcmd(isp, &mbs);
4579		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4580			break;
4581		}
4582		isp_prt(isp, ISP_LOGINFO,
4583		    "Target %d on Bus %d Reset Succeeded", tgt, chan);
4584		ISP_SET_SENDMARKER(isp, chan, 1);
4585		return (0);
4586
4587	case ISPCTL_ABORT_CMD:
4588		va_start(ap, ctl);
4589		xs = va_arg(ap, XS_T *);
4590		va_end(ap);
4591
4592		tgt = XS_TGT(xs);
4593		chan = XS_CHANNEL(xs);
4594
4595		handle = isp_find_handle(isp, xs);
4596		if (handle == 0) {
4597			isp_prt(isp, ISP_LOGWARN,
4598			    "cannot find handle for command to abort");
4599			break;
4600		}
4601		if (IS_24XX(isp)) {
4602			isp24xx_abrt_t local, *ab = &local, *ab2;
4603			fcparam *fcp;
4604			fcportdb_t *lp;
4605			int hdlidx;
4606
4607			fcp = FCPARAM(isp, chan);
4608			hdlidx = fcp->isp_dev_map[tgt] - 1;
4609			if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
4610				isp_prt(isp, ISP_LOGWARN,
4611				    "Chan %d bad handle %d trying to abort"
4612				    "target %d", chan, hdlidx, tgt);
4613				break;
4614			}
4615			lp = &fcp->portdb[hdlidx];
4616			if (lp->state != FC_PORTDB_STATE_VALID) {
4617				isp_prt(isp, ISP_LOGWARN,
4618				    "Chan %d handle %d for abort of target %d "
4619				    "no longer valid", chan, hdlidx, tgt);
4620				break;
4621			}
4622			isp_prt(isp, ISP_LOGALL,
4623			    "Chan %d Abort Cmd for N-Port 0x%04x @ Port "
4624			    "0x%06x %p", chan, lp->handle, lp->portid, xs);
4625			ISP_MEMZERO(ab, QENTRY_LEN);
4626			ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO;
4627			ab->abrt_header.rqs_entry_count = 1;
4628			ab->abrt_handle = lp->handle;
4629			ab->abrt_cmd_handle = handle;
4630			ab->abrt_tidlo = lp->portid;
4631			ab->abrt_tidhi = lp->portid >> 16;
4632			ab->abrt_vpidx = ISP_GET_VPIDX(isp, chan);
4633
4634			ISP_MEMZERO(&mbs, sizeof (mbs));
4635			MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
4636			mbs.param[1] = QENTRY_LEN;
4637			mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4638			mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4639			mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4640			mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4641
4642			if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4643				isp_prt(isp, ISP_LOGERR, sacq);
4644				break;
4645			}
4646			isp_put_24xx_abrt(isp, ab, fcp->isp_scratch);
4647			ab2 = (isp24xx_abrt_t *)
4648			    &((uint8_t *)fcp->isp_scratch)[QENTRY_LEN];
4649			ab2->abrt_nphdl = 0xdeaf;
4650			MEMORYBARRIER(isp, SYNC_SFORDEV, 0, 2 * QENTRY_LEN);
4651			isp_mboxcmd(isp, &mbs);
4652			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4653				FC_SCRATCH_RELEASE(isp, chan);
4654				break;
4655			}
4656			MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
4657			    QENTRY_LEN);
4658			isp_get_24xx_abrt(isp, ab2, ab);
4659			FC_SCRATCH_RELEASE(isp, chan);
4660			if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY) {
4661				return (0);
4662			}
4663			isp_prt(isp, ISP_LOGWARN,
4664			    "Chan %d handle %d abort returned 0x%x", chan,
4665			    hdlidx, ab->abrt_nphdl);
4666			break;
4667		} else if (IS_FC(isp)) {
4668			if (ISP_CAP_SCCFW(isp)) {
4669				if (ISP_CAP_2KLOGIN(isp)) {
4670					mbs.param[1] = tgt;
4671				} else {
4672					mbs.param[1] = tgt << 8;
4673				}
4674				mbs.param[6] = XS_LUN(xs);
4675			} else {
4676				mbs.param[1] = tgt << 8 | XS_LUN(xs);
4677			}
4678		} else {
4679			mbs.param[1] = (chan << 15) | (tgt << 8) | XS_LUN(xs);
4680		}
4681		MBSINIT(&mbs, MBOX_ABORT, MBLOGALL & ~MBOX_COMMAND_ERROR, 0);
4682		mbs.param[2] = handle;
4683		isp_mboxcmd(isp, &mbs);
4684		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4685			break;
4686		}
4687		return (0);
4688
4689	case ISPCTL_UPDATE_PARAMS:
4690
4691		va_start(ap, ctl);
4692		chan = va_arg(ap, int);
4693		va_end(ap);
4694		isp_spi_update(isp, chan);
4695		return (0);
4696
4697	case ISPCTL_FCLINK_TEST:
4698
4699		if (IS_FC(isp)) {
4700			int usdelay;
4701			va_start(ap, ctl);
4702			chan = va_arg(ap, int);
4703			usdelay = va_arg(ap, int);
4704			va_end(ap);
4705			if (usdelay == 0) {
4706				usdelay =  250000;
4707			}
4708			return (isp_fclink_test(isp, chan, usdelay));
4709		}
4710		break;
4711
4712	case ISPCTL_SCAN_FABRIC:
4713
4714		if (IS_FC(isp)) {
4715			va_start(ap, ctl);
4716			chan = va_arg(ap, int);
4717			va_end(ap);
4718			return (isp_scan_fabric(isp, chan));
4719		}
4720		break;
4721
4722	case ISPCTL_SCAN_LOOP:
4723
4724		if (IS_FC(isp)) {
4725			va_start(ap, ctl);
4726			chan = va_arg(ap, int);
4727			va_end(ap);
4728			return (isp_scan_loop(isp, chan));
4729		}
4730		break;
4731
4732	case ISPCTL_PDB_SYNC:
4733
4734		if (IS_FC(isp)) {
4735			va_start(ap, ctl);
4736			chan = va_arg(ap, int);
4737			va_end(ap);
4738			return (isp_pdb_sync(isp, chan));
4739		}
4740		break;
4741
4742	case ISPCTL_SEND_LIP:
4743
4744		if (IS_FC(isp) && !IS_24XX(isp)) {
4745			MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
4746			if (ISP_CAP_2KLOGIN(isp)) {
4747				mbs.ibits = (1 << 10);
4748			}
4749			isp_mboxcmd(isp, &mbs);
4750			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
4751				return (0);
4752			}
4753		}
4754		break;
4755
4756	case ISPCTL_GET_PDB:
4757		if (IS_FC(isp)) {
4758			isp_pdb_t *pdb;
4759			va_start(ap, ctl);
4760			chan = va_arg(ap, int);
4761			tgt = va_arg(ap, int);
4762			pdb = va_arg(ap, isp_pdb_t *);
4763			va_end(ap);
4764			return (isp_getpdb(isp, chan, tgt, pdb, 1));
4765		}
4766		break;
4767
4768	case ISPCTL_GET_NAMES:
4769	{
4770		uint64_t *wwnn, *wwnp;
4771		va_start(ap, ctl);
4772		chan = va_arg(ap, int);
4773		tgt = va_arg(ap, int);
4774		wwnn = va_arg(ap, uint64_t *);
4775		wwnp = va_arg(ap, uint64_t *);
4776		va_end(ap);
4777		if (wwnn == NULL && wwnp == NULL) {
4778			break;
4779		}
4780		if (wwnn) {
4781			*wwnn = isp_get_wwn(isp, chan, tgt, 1);
4782			if (*wwnn == INI_NONE) {
4783				break;
4784			}
4785		}
4786		if (wwnp) {
4787			*wwnp = isp_get_wwn(isp, chan, tgt, 0);
4788			if (*wwnp == INI_NONE) {
4789				break;
4790			}
4791		}
4792		return (0);
4793	}
4794	case ISPCTL_RUN_MBOXCMD:
4795	{
4796		va_start(ap, ctl);
4797		mbr = va_arg(ap, mbreg_t *);
4798		va_end(ap);
4799		isp_mboxcmd(isp, mbr);
4800		return (0);
4801	}
4802	case ISPCTL_PLOGX:
4803	{
4804		isp_plcmd_t *p;
4805		int r;
4806
4807		va_start(ap, ctl);
4808		p = va_arg(ap, isp_plcmd_t *);
4809		va_end(ap);
4810
4811		if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) {
4812			return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0));
4813		}
4814		do {
4815			p->handle = isp_nxt_handle(isp, p->channel, p->handle);
4816			r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0);
4817			if ((r & 0xffff) == MBOX_PORT_ID_USED) {
4818				p->handle = r >> 16;
4819				r = 0;
4820				break;
4821			}
4822		} while ((r & 0xffff) == MBOX_LOOP_ID_USED);
4823		return (r);
4824	}
4825	default:
4826		isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
4827		break;
4828
4829	}
4830	return (-1);
4831}
4832
4833/*
4834 * Interrupt Service Routine(s).
4835 *
4836 * External (OS) framework has done the appropriate locking,
4837 * and the locking will be held throughout this function.
4838 */
4839
4840/*
4841 * Limit our stack depth by sticking with the max likely number
4842 * of completions on a request queue at any one time.
4843 */
4844#ifndef	MAX_REQUESTQ_COMPLETIONS
4845#define	MAX_REQUESTQ_COMPLETIONS	32
4846#endif
4847
4848void
4849isp_intr(ispsoftc_t *isp, uint32_t isr, uint16_t sema, uint16_t mbox)
4850{
4851	XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
4852	uint32_t iptr, optr, junk;
4853	int i, nlooked = 0, ndone = 0;
4854
4855again:
4856	optr = isp->isp_residx;
4857	/*
4858	 * Is this a mailbox related interrupt?
4859	 * The mailbox semaphore will be nonzero if so.
4860	 */
4861	if (sema) {
4862 fmbox:
4863		if (mbox & 0x4000) {
4864			isp->isp_intmboxc++;
4865			if (isp->isp_mboxbsy) {
4866				int obits = isp->isp_obits;
4867				isp->isp_mboxtmp[0] = mbox;
4868				for (i = 1; i < MAX_MAILBOX(isp); i++) {
4869					if ((obits & (1 << i)) == 0) {
4870						continue;
4871					}
4872					isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
4873				}
4874				if (isp->isp_mbxwrk0) {
4875					if (isp_mbox_continue(isp) == 0) {
4876						return;
4877					}
4878				}
4879				MBOX_NOTIFY_COMPLETE(isp);
4880			} else {
4881				isp_prt(isp, ISP_LOGWARN, "mailbox cmd (0x%x) with no waiters", mbox);
4882			}
4883		} else if (isp_parse_async(isp, mbox) < 0) {
4884			return;
4885		}
4886		if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) || isp->isp_state != ISP_RUNSTATE) {
4887			goto out;
4888		}
4889	}
4890
4891	/*
4892	 * We can't be getting this now.
4893	 */
4894	if (isp->isp_state != ISP_RUNSTATE) {
4895		/*
4896		 * This seems to happen to 23XX and 24XX cards- don't know why.
4897		 */
4898		 if (isp->isp_mboxbsy && isp->isp_lastmbxcmd == MBOX_ABOUT_FIRMWARE) {
4899			goto fmbox;
4900		}
4901		isp_prt(isp, ISP_LOGINFO, "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
4902		/*
4903		 * Thank you very much!  *Burrrp*!
4904		 */
4905		ISP_WRITE(isp, isp->isp_respoutrp, ISP_READ(isp, isp->isp_respinrp));
4906		if (IS_24XX(isp)) {
4907			ISP_DISABLE_INTS(isp);
4908		}
4909		goto out;
4910	}
4911
4912#ifdef	ISP_TARGET_MODE
4913	/*
4914	 * Check for ATIO Queue entries.
4915	 */
4916	if (IS_24XX(isp)) {
4917		iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
4918		optr = ISP_READ(isp, BIU2400_ATIO_RSPOUTP);
4919
4920		while (optr != iptr) {
4921			uint8_t qe[QENTRY_LEN];
4922			isphdr_t *hp;
4923			uint32_t oop;
4924			void *addr;
4925
4926			oop = optr;
4927			MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN);
4928			addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
4929			isp_get_hdr(isp, addr, (isphdr_t *)qe);
4930			hp = (isphdr_t *)qe;
4931			switch (hp->rqs_entry_type) {
4932			case RQSTYPE_NOTIFY:
4933			case RQSTYPE_ATIO:
4934				(void) isp_target_notify(isp, addr, &oop);
4935				break;
4936			default:
4937				isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
4938				break;
4939			}
4940			optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
4941			ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
4942		}
4943		optr = isp->isp_residx;
4944	}
4945#endif
4946
4947	/*
4948	 * Get the current Response Queue Out Pointer.
4949	 *
4950	 * If we're a 2300 or 2400, we can ask what hardware what it thinks.
4951	 */
4952	if (IS_23XX(isp) || IS_24XX(isp)) {
4953		optr = ISP_READ(isp, isp->isp_respoutrp);
4954		/*
4955		 * Debug: to be taken out eventually
4956		 */
4957		if (isp->isp_residx != optr) {
4958			isp_prt(isp, ISP_LOGINFO, "isp_intr: hard optr=%x, soft optr %x", optr, isp->isp_residx);
4959			isp->isp_residx = optr;
4960		}
4961	} else {
4962		optr = isp->isp_residx;
4963	}
4964
4965	/*
4966	 * You *must* read the Response Queue In Pointer
4967	 * prior to clearing the RISC interrupt.
4968	 *
4969	 * Debounce the 2300 if revision less than 2.
4970	 */
4971	if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
4972		i = 0;
4973		do {
4974			iptr = ISP_READ(isp, isp->isp_respinrp);
4975			junk = ISP_READ(isp, isp->isp_respinrp);
4976		} while (junk != iptr && ++i < 1000);
4977
4978		if (iptr != junk) {
4979			isp_prt(isp, ISP_LOGWARN, "Response Queue Out Pointer Unstable (%x, %x)", iptr, junk);
4980			goto out;
4981		}
4982	} else {
4983		iptr = ISP_READ(isp, isp->isp_respinrp);
4984	}
4985	isp->isp_resodx = iptr;
4986
4987
4988	if (optr == iptr && sema == 0) {
4989		/*
4990		 * There are a lot of these- reasons unknown- mostly on
4991		 * faster Alpha machines.
4992		 *
4993		 * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
4994		 * make sure the old interrupt went away (to avoid 'ringing'
4995		 * effects), but that didn't stop this from occurring.
4996		 */
4997		if (IS_24XX(isp)) {
4998			junk = 0;
4999		} else if (IS_23XX(isp)) {
5000			ISP_DELAY(100);
5001			iptr = ISP_READ(isp, isp->isp_respinrp);
5002			junk = ISP_READ(isp, BIU_R2HSTSLO);
5003		} else {
5004			junk = ISP_READ(isp, BIU_ISR);
5005		}
5006		if (optr == iptr) {
5007			if (IS_23XX(isp) || IS_24XX(isp)) {
5008				;
5009			} else {
5010				sema = ISP_READ(isp, BIU_SEMA);
5011				mbox = ISP_READ(isp, OUTMAILBOX0);
5012				if ((sema & 0x3) && (mbox & 0x8000)) {
5013					goto again;
5014				}
5015			}
5016			isp->isp_intbogus++;
5017			isp_prt(isp, ISP_LOGDEBUG1, "bogus intr- isr %x (%x) iptr %x optr %x", isr, junk, iptr, optr);
5018		}
5019	}
5020	isp->isp_resodx = iptr;
5021
5022	while (optr != iptr) {
5023		uint8_t qe[QENTRY_LEN];
5024		ispstatusreq_t *sp = (ispstatusreq_t *) qe;
5025		isphdr_t *hp;
5026		int buddaboom, etype, scsi_status, completion_status;
5027		int req_status_flags, req_state_flags;
5028		uint8_t *snsp, *resp;
5029		uint32_t rlen, slen;
5030		long resid;
5031		uint16_t oop;
5032
5033		hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
5034		oop = optr;
5035		optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
5036		nlooked++;
5037 read_again:
5038		buddaboom = req_status_flags = req_state_flags = 0;
5039		resid = 0L;
5040
5041		/*
5042		 * Synchronize our view of this response queue entry.
5043		 */
5044		MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN);
5045		isp_get_hdr(isp, hp, &sp->req_header);
5046		etype = sp->req_header.rqs_entry_type;
5047
5048		if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) {
5049			isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe;
5050			isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp2);
5051			if (isp->isp_dblev & ISP_LOGDEBUG1) {
5052				isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp2);
5053			}
5054			scsi_status = sp2->req_scsi_status;
5055			completion_status = sp2->req_completion_status;
5056			req_state_flags = 0;
5057			resid = sp2->req_resid;
5058		} else if (etype == RQSTYPE_RESPONSE) {
5059			isp_get_response(isp, (ispstatusreq_t *) hp, sp);
5060			if (isp->isp_dblev & ISP_LOGDEBUG1) {
5061				isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp);
5062			}
5063			scsi_status = sp->req_scsi_status;
5064			completion_status = sp->req_completion_status;
5065			req_status_flags = sp->req_status_flags;
5066			req_state_flags = sp->req_state_flags;
5067			resid = sp->req_resid;
5068		} else if (etype == RQSTYPE_RIO2) {
5069			isp_rio2_t *rio = (isp_rio2_t *)qe;
5070			isp_get_rio2(isp, (isp_rio2_t *) hp, rio);
5071			if (isp->isp_dblev & ISP_LOGDEBUG1) {
5072				isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, rio);
5073			}
5074			for (i = 0; i < rio->req_header.rqs_seqno; i++) {
5075				isp_fastpost_complete(isp, rio->req_handles[i]);
5076			}
5077			if (isp->isp_fpcchiwater < rio->req_header.rqs_seqno) {
5078				isp->isp_fpcchiwater = rio->req_header.rqs_seqno;
5079			}
5080			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5081			continue;
5082		} else {
5083			/*
5084			 * Somebody reachable via isp_handle_other_response
5085			 * may have updated the response queue pointers for
5086			 * us, so we reload our goal index.
5087			 */
5088			int r;
5089			uint32_t tsto = oop;
5090			r = isp_handle_other_response(isp, etype, hp, &tsto);
5091			if (r < 0) {
5092				goto read_again;
5093			}
5094			/*
5095			 * If somebody updated the output pointer, then reset
5096			 * optr to be one more than the updated amount.
5097			 */
5098			while (tsto != oop) {
5099				optr = ISP_NXT_QENTRY(tsto,
5100				    RESULT_QUEUE_LEN(isp));
5101			}
5102			if (r > 0) {
5103				ISP_WRITE(isp, isp->isp_respoutrp, optr);
5104				ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5105				continue;
5106			}
5107
5108			/*
5109			 * After this point, we'll just look at the header as
5110			 * we don't know how to deal with the rest of the
5111			 * response.
5112			 */
5113
5114			/*
5115			 * It really has to be a bounced request just copied
5116			 * from the request queue to the response queue. If
5117			 * not, something bad has happened.
5118			 */
5119			if (etype != RQSTYPE_REQUEST) {
5120				isp_prt(isp, ISP_LOGERR, notresp,
5121				    etype, oop, optr, nlooked);
5122				isp_print_bytes(isp,
5123				    "Request Queue Entry", QENTRY_LEN, sp);
5124				ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5125				continue;
5126			}
5127			buddaboom = 1;
5128			scsi_status = sp->req_scsi_status;
5129			completion_status = sp->req_completion_status;
5130			req_status_flags = sp->req_status_flags;
5131			req_state_flags = sp->req_state_flags;
5132			resid = sp->req_resid;
5133		}
5134
5135		if (sp->req_header.rqs_flags & RQSFLAG_MASK) {
5136			if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
5137				isp_print_bytes(isp, "unexpected continuation segment", QENTRY_LEN, sp);
5138				ISP_WRITE(isp, isp->isp_respoutrp, optr);
5139				continue;
5140			}
5141			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
5142				isp_prt(isp, ISP_LOGDEBUG0, "internal queues full");
5143				/*
5144				 * We'll synthesize a QUEUE FULL message below.
5145				 */
5146			}
5147			if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
5148				isp_print_bytes(isp, "bad header flag", QENTRY_LEN, sp);
5149				buddaboom++;
5150			}
5151			if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
5152				isp_print_bytes(isp, "bad request packet", QENTRY_LEN, sp);
5153				buddaboom++;
5154			}
5155			if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
5156				isp_print_bytes(isp, "invalid entry count", QENTRY_LEN, sp);
5157				buddaboom++;
5158			}
5159			if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
5160				isp_print_bytes(isp, "invalid IOCB ordering", QENTRY_LEN, sp);
5161				ISP_WRITE(isp, isp->isp_respoutrp, optr);
5162				continue;
5163			}
5164		}
5165
5166		if ((sp->req_handle != ISP_SPCL_HANDLE) && (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1)) {
5167			isp_prt(isp, ISP_LOGERR, "bad request handle %d (type 0x%x)", sp->req_handle, etype);
5168			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5169			ISP_WRITE(isp, isp->isp_respoutrp, optr);
5170			continue;
5171		}
5172		xs = isp_find_xs(isp, sp->req_handle);
5173		if (xs == NULL) {
5174			uint8_t ts = completion_status & 0xff;
5175			/*
5176			 * Only whine if this isn't the expected fallout of
5177			 * aborting the command or resetting the target.
5178			 */
5179			if (etype != RQSTYPE_RESPONSE) {
5180				isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (type 0x%x)", sp->req_handle, etype);
5181			} else if (ts != RQCS_ABORTED && ts != RQCS_RESET_OCCURRED && sp->req_handle != ISP_SPCL_HANDLE) {
5182				isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)", sp->req_handle, ts);
5183			}
5184			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5185			ISP_WRITE(isp, isp->isp_respoutrp, optr);
5186			continue;
5187		}
5188		isp_destroy_handle(isp, sp->req_handle);
5189		if (req_status_flags & RQSTF_BUS_RESET) {
5190			XS_SETERR(xs, HBA_BUSRESET);
5191			ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
5192		}
5193		if (buddaboom) {
5194			XS_SETERR(xs, HBA_BOTCH);
5195		}
5196
5197		resp = NULL;
5198		rlen = 0;
5199		snsp = NULL;
5200		slen = 0;
5201		if (IS_24XX(isp) && (scsi_status & (RQCS_RV|RQCS_SV)) != 0) {
5202			resp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
5203			rlen = ((isp24xx_statusreq_t *)sp)->req_response_len;
5204		} else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) {
5205			resp = sp->req_response;
5206			rlen = sp->req_response_len;
5207		}
5208		if (IS_FC(isp) && (scsi_status & RQCS_SV) != 0) {
5209			/*
5210			 * Fibre Channel F/W doesn't say we got status
5211			 * if there's Sense Data instead. I guess they
5212			 * think it goes w/o saying.
5213			 */
5214			req_state_flags |= RQSF_GOT_STATUS|RQSF_GOT_SENSE;
5215			if (IS_24XX(isp)) {
5216				snsp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
5217				snsp += rlen;
5218				slen = ((isp24xx_statusreq_t *)sp)->req_sense_len;
5219			} else {
5220				snsp = sp->req_sense_data;
5221				slen = sp->req_sense_len;
5222			}
5223		} else if (IS_SCSI(isp) && (req_state_flags & RQSF_GOT_SENSE)) {
5224			snsp = sp->req_sense_data;
5225			slen = sp->req_sense_len;
5226		}
5227		if (req_state_flags & RQSF_GOT_STATUS) {
5228			*XS_STSP(xs) = scsi_status & 0xff;
5229		}
5230
5231		switch (etype) {
5232		case RQSTYPE_RESPONSE:
5233			if (resp && rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
5234				const char *ptr;
5235				char lb[64];
5236				const char *rnames[6] = {
5237					"Task Management Function Done",
5238					"Data Length Differs From Burst Length",
5239					"Invalid FCP Cmnd",
5240					"FCP DATA RO mismatch with FCP DATA_XFR_RDY RO",
5241					"Task Management Function Rejected",
5242					"Task Management Function Failed",
5243				};
5244				if (resp[FCP_RSPNS_CODE_OFFSET] > 5) {
5245					ISP_SNPRINTF(lb, sizeof lb, "Unknown FCP Response Code 0x%x", resp[FCP_RSPNS_CODE_OFFSET]);
5246					ptr = lb;
5247				} else {
5248					ptr = rnames[resp[FCP_RSPNS_CODE_OFFSET]];
5249				}
5250				isp_prt(isp, ISP_LOGWARN, "%d.%d.%d FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x", XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), rlen, ptr, XS_CDBP(xs)[0] & 0xff);
5251				if (resp[FCP_RSPNS_CODE_OFFSET] != 0) {
5252					XS_SETERR(xs, HBA_BOTCH);
5253				}
5254			}
5255			if (IS_24XX(isp)) {
5256				isp_parse_status_24xx(isp, (isp24xx_statusreq_t *)sp, xs, &resid);
5257			} else {
5258				isp_parse_status(isp, (void *)sp, xs, &resid);
5259			}
5260			if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) && (*XS_STSP(xs) == SCSI_BUSY)) {
5261				XS_SETERR(xs, HBA_TGTBSY);
5262			}
5263			if (IS_SCSI(isp)) {
5264				XS_SET_RESID(xs, resid);
5265				/*
5266				 * A new synchronous rate was negotiated for
5267				 * this target. Mark state such that we'll go
5268				 * look up that which has changed later.
5269				 */
5270				if (req_status_flags & RQSTF_NEGOTIATION) {
5271					int t = XS_TGT(xs);
5272					sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
5273					sdp->isp_devparam[t].dev_refresh = 1;
5274					sdp->update = 1;
5275				}
5276			} else {
5277				if (req_status_flags & RQSF_XFER_COMPLETE) {
5278					XS_SET_RESID(xs, 0);
5279				} else if (scsi_status & RQCS_RESID) {
5280					XS_SET_RESID(xs, resid);
5281				} else {
5282					XS_SET_RESID(xs, 0);
5283				}
5284			}
5285			if (snsp && slen) {
5286				XS_SAVE_SENSE(xs, snsp, slen);
5287			} else if ((req_status_flags & RQSF_GOT_STATUS) && (scsi_status & 0xff) == SCSI_CHECK && IS_FC(isp)) {
5288				isp_prt(isp, ISP_LOGWARN, "CHECK CONDITION w/o sense data for CDB=0x%x", XS_CDBP(xs)[0] & 0xff);
5289				isp_print_bytes(isp, "CC with no Sense", QENTRY_LEN, qe);
5290			}
5291			isp_prt(isp, ISP_LOGDEBUG2, "asked for %ld got raw resid %ld settled for %ld", (long) XS_XFRLEN(xs), resid, (long) XS_GET_RESID(xs));
5292			break;
5293		case RQSTYPE_REQUEST:
5294		case RQSTYPE_A64:
5295		case RQSTYPE_T2RQS:
5296		case RQSTYPE_T3RQS:
5297		case RQSTYPE_T7RQS:
5298			if (!IS_24XX(isp) && (sp->req_header.rqs_flags & RQSFLAG_FULL)) {
5299				/*
5300				 * Force Queue Full status.
5301				 */
5302				*XS_STSP(xs) = SCSI_QFULL;
5303				XS_SETERR(xs, HBA_NOERROR);
5304			} else if (XS_NOERR(xs)) {
5305				XS_SETERR(xs, HBA_BOTCH);
5306			}
5307			XS_SET_RESID(xs, XS_XFRLEN(xs));
5308			break;
5309		default:
5310			isp_print_bytes(isp, "Unhandled Response Type", QENTRY_LEN, qe);
5311			if (XS_NOERR(xs)) {
5312				XS_SETERR(xs, HBA_BOTCH);
5313			}
5314			break;
5315		}
5316
5317		/*
5318		 * Free any DMA resources. As a side effect, this may
5319		 * also do any cache flushing necessary for data coherence.
5320		 */
5321		if (XS_XFRLEN(xs)) {
5322			ISP_DMAFREE(isp, xs, sp->req_handle);
5323		}
5324
5325		if (((isp->isp_dblev & (ISP_LOGDEBUG1|ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
5326		    ((isp->isp_dblev & ISP_LOGDEBUG0) && ((!XS_NOERR(xs)) ||
5327		    (*XS_STSP(xs) != SCSI_GOOD)))) {
5328			char skey;
5329			if (req_state_flags & RQSF_GOT_SENSE) {
5330				skey = XS_SNSKEY(xs) & 0xf;
5331				if (skey < 10)
5332					skey += '0';
5333				else
5334					skey += 'a' - 10;
5335			} else if (*XS_STSP(xs) == SCSI_CHECK) {
5336				skey = '?';
5337			} else {
5338				skey = '.';
5339			}
5340			isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs),
5341			    XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), (long) XS_GET_RESID(xs),
5342			    *XS_STSP(xs), skey, XS_ERR(xs));
5343		}
5344
5345		if (isp->isp_nactive > 0) {
5346		    isp->isp_nactive--;
5347		}
5348		complist[ndone++] = xs;	/* defer completion call until later */
5349		ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5350		if (ndone == MAX_REQUESTQ_COMPLETIONS) {
5351			break;
5352		}
5353	}
5354
5355	/*
5356	 * If we looked at any commands, then it's valid to find out
5357	 * what the outpointer is. It also is a trigger to update the
5358	 * ISP's notion of what we've seen so far.
5359	 */
5360	if (nlooked) {
5361		ISP_WRITE(isp, isp->isp_respoutrp, optr);
5362		/*
5363		 * While we're at it, read the requst queue out pointer.
5364		 */
5365		isp->isp_reqodx = ISP_READ(isp, isp->isp_rqstoutrp);
5366		if (isp->isp_rscchiwater < ndone) {
5367			isp->isp_rscchiwater = ndone;
5368		}
5369	}
5370
5371out:
5372
5373	if (IS_24XX(isp)) {
5374		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
5375	} else {
5376		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
5377		ISP_WRITE(isp, BIU_SEMA, 0);
5378	}
5379
5380	isp->isp_residx = optr;
5381	for (i = 0; i < ndone; i++) {
5382		xs = complist[i];
5383		if (xs) {
5384			isp->isp_rsltccmplt++;
5385			isp_done(xs);
5386		}
5387	}
5388}
5389
5390/*
5391 * Support routines.
5392 */
5393
5394#define	GET_24XX_BUS(isp, chan, msg)										\
5395	if (IS_24XX(isp)) {											\
5396		chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;							\
5397		if (chan >= isp->isp_nchan) {									\
5398			isp_prt(isp, ISP_LOGERR, "bogus channel %u for %s at line %d",	chan, msg, __LINE__);	\
5399			break;											\
5400		}												\
5401	}
5402
5403static int
5404isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
5405{
5406	int rval = 0;
5407	int pattern = 0;
5408	uint16_t chan;
5409
5410	if (IS_DUALBUS(isp)) {
5411		chan = ISP_READ(isp, OUTMAILBOX6);
5412	} else {
5413		chan = 0;
5414	}
5415	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
5416
5417	switch (mbox) {
5418	case ASYNC_BUS_RESET:
5419		if (IS_FC(isp)) {
5420			isp_prt(isp, ISP_LOGWARN,
5421			    "ILLEGAL ASYNC_BUS_RESET for FC card");
5422			break;
5423		}
5424		ISP_SET_SENDMARKER(isp, chan, 1);
5425#ifdef	ISP_TARGET_MODE
5426		if (isp_target_async(isp, chan, mbox)) {
5427			rval = -1;
5428		}
5429#endif
5430		isp_async(isp, ISPASYNC_BUS_RESET, chan);
5431		break;
5432	case ASYNC_SYSTEM_ERROR:
5433		isp->isp_dead = 1;
5434		isp->isp_state = ISP_CRASHED;
5435		if (IS_FC(isp)) {
5436			FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
5437			FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
5438		}
5439		/*
5440		 * Were we waiting for a mailbox command to complete?
5441		 * If so, it's dead, so wake up the waiter.
5442		 */
5443		if (isp->isp_mboxbsy) {
5444			isp->isp_obits = 1;
5445			isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
5446			MBOX_NOTIFY_COMPLETE(isp);
5447		}
5448		/*
5449		 * It's up to the handler for isp_async to reinit stuff and
5450		 * restart the firmware
5451		 */
5452		isp_async(isp, ISPASYNC_FW_CRASH);
5453		rval = -1;
5454		break;
5455
5456	case ASYNC_RQS_XFER_ERR:
5457		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
5458		break;
5459
5460	case ASYNC_RSP_XFER_ERR:
5461		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
5462		break;
5463
5464	case ASYNC_QWAKEUP:
5465#ifdef	ISP_TARGET_MODE
5466		if (IS_24XX(isp)) {
5467			isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
5468			break;
5469		}
5470#endif
5471		if (IS_FC(isp)) {
5472			isp_prt(isp, ISP_LOGWARN,
5473			    "ILLEGAL ASYNC_QWAKEUP for FC card");
5474			break;
5475		}
5476		/*
5477		 * We've just been notified that the Queue has woken up.
5478		 * We don't need to be chatty about this- just unlatch things
5479		 * and move on.
5480		 */
5481		mbox = ISP_READ(isp, isp->isp_rqstoutrp);
5482		break;
5483
5484	case ASYNC_TIMEOUT_RESET:
5485		if (IS_FC(isp)) {
5486			isp_prt(isp, ISP_LOGWARN,
5487			    "ILLEGAL ASYNC_TIMEOUT_RESET for FC card");
5488			break;
5489		}
5490		isp_prt(isp, ISP_LOGWARN,
5491		    "timeout initiated SCSI bus reset of chan %d", chan);
5492		ISP_SET_SENDMARKER(isp, chan, 1);
5493#ifdef	ISP_TARGET_MODE
5494		if (isp_target_async(isp, chan, mbox)) {
5495			rval = -1;
5496		}
5497#endif
5498		break;
5499
5500	case ASYNC_DEVICE_RESET:
5501		if (IS_FC(isp)) {
5502			isp_prt(isp, ISP_LOGWARN,
5503			    "ILLEGAL DEVICE_RESET for FC card");
5504			break;
5505		}
5506		isp_prt(isp, ISP_LOGINFO, "device reset on chan %d", chan);
5507		ISP_SET_SENDMARKER(isp, chan, 1);
5508#ifdef	ISP_TARGET_MODE
5509		if (isp_target_async(isp, chan, mbox)) {
5510			rval = -1;
5511		}
5512#endif
5513		break;
5514
5515	case ASYNC_EXTMSG_UNDERRUN:
5516		if (IS_FC(isp)) {
5517			isp_prt(isp, ISP_LOGWARN,
5518			    "ILLEGAL ASYNC_EXTMSG_UNDERRUN for FC card");
5519			break;
5520		}
5521		isp_prt(isp, ISP_LOGWARN, "extended message underrun");
5522		break;
5523
5524	case ASYNC_SCAM_INT:
5525		if (IS_FC(isp)) {
5526			isp_prt(isp, ISP_LOGWARN,
5527			    "ILLEGAL ASYNC_SCAM_INT for FC card");
5528			break;
5529		}
5530		isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
5531		break;
5532
5533	case ASYNC_HUNG_SCSI:
5534		if (IS_FC(isp)) {
5535			isp_prt(isp, ISP_LOGWARN,
5536			    "ILLEGAL ASYNC_HUNG_SCSI for FC card");
5537			break;
5538		}
5539		isp_prt(isp, ISP_LOGERR,
5540		    "stalled SCSI Bus after DATA Overrun");
5541		/* XXX: Need to issue SCSI reset at this point */
5542		break;
5543
5544	case ASYNC_KILLED_BUS:
5545		if (IS_FC(isp)) {
5546			isp_prt(isp, ISP_LOGWARN,
5547			    "ILLEGAL ASYNC_KILLED_BUS for FC card");
5548			break;
5549		}
5550		isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
5551		break;
5552
5553	case ASYNC_BUS_TRANSIT:
5554		if (IS_FC(isp)) {
5555			isp_prt(isp, ISP_LOGWARN,
5556			    "ILLEGAL ASYNC_BUS_TRANSIT for FC card");
5557			break;
5558		}
5559		mbox = ISP_READ(isp, OUTMAILBOX2);
5560		switch (mbox & 0x1c00) {
5561		case SXP_PINS_LVD_MODE:
5562			isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
5563			SDPARAM(isp, chan)->isp_diffmode = 0;
5564			SDPARAM(isp, chan)->isp_ultramode = 0;
5565			SDPARAM(isp, chan)->isp_lvdmode = 1;
5566			break;
5567		case SXP_PINS_HVD_MODE:
5568			isp_prt(isp, ISP_LOGINFO,
5569			    "Transition to Differential mode");
5570			SDPARAM(isp, chan)->isp_diffmode = 1;
5571			SDPARAM(isp, chan)->isp_ultramode = 0;
5572			SDPARAM(isp, chan)->isp_lvdmode = 0;
5573			break;
5574		case SXP_PINS_SE_MODE:
5575			isp_prt(isp, ISP_LOGINFO,
5576			    "Transition to Single Ended mode");
5577			SDPARAM(isp, chan)->isp_diffmode = 0;
5578			SDPARAM(isp, chan)->isp_ultramode = 1;
5579			SDPARAM(isp, chan)->isp_lvdmode = 0;
5580			break;
5581		default:
5582			isp_prt(isp, ISP_LOGWARN,
5583			    "Transition to Unknown Mode 0x%x", mbox);
5584			break;
5585		}
5586		/*
5587		 * XXX: Set up to renegotiate again!
5588		 */
5589		/* Can only be for a 1080... */
5590		ISP_SET_SENDMARKER(isp, chan, 1);
5591		break;
5592
5593	case ASYNC_RIO5:
5594		pattern = 0xce;	/* outgoing mailbox regs 1-3, 6-7 */
5595		break;
5596
5597	case ASYNC_RIO4:
5598		pattern = 0x4e;	/* outgoing mailbox regs 1-3, 6 */
5599		break;
5600
5601	case ASYNC_RIO3:
5602		pattern = 0x0e;	/* outgoing mailbox regs 1-3 */
5603		break;
5604
5605	case ASYNC_RIO2:
5606		pattern = 0x06;	/* outgoing mailbox regs 1-2 */
5607		break;
5608
5609	case ASYNC_RIO1:
5610	case ASYNC_CMD_CMPLT:
5611		pattern = 0x02;	/* outgoing mailbox regs 1 */
5612		break;
5613
5614	case ASYNC_RIO_RESP:
5615		return (rval);
5616
5617	case ASYNC_CTIO_DONE:
5618	{
5619#ifdef	ISP_TARGET_MODE
5620		int handle;
5621		if (IS_SCSI(isp) || IS_24XX(isp)) {
5622			isp_prt(isp, ISP_LOGWARN,
5623			    "bad ASYNC_CTIO_DONE for %s cards",
5624			    IS_SCSI(isp)? "SCSI" : "24XX");
5625			break;
5626		}
5627		handle =
5628		    (ISP_READ(isp, OUTMAILBOX2) << 16) |
5629		    (ISP_READ(isp, OUTMAILBOX1));
5630		if (isp_target_async(isp, handle, mbox)) {
5631			rval = -1;
5632		} else {
5633			/* count it as a fast posting intr */
5634			isp->isp_fphccmplt++;
5635		}
5636#else
5637		if (IS_SCSI(isp) || IS_24XX(isp)) {
5638			isp_prt(isp, ISP_LOGWARN,
5639			    "bad ASYNC_CTIO_DONE for %s cards",
5640			    IS_SCSI(isp)? "SCSI" : "24XX");
5641			break;
5642		}
5643		isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
5644		isp->isp_fphccmplt++;	/* count it as a fast posting intr */
5645#endif
5646		break;
5647	}
5648	case ASYNC_LIP_ERROR:
5649	case ASYNC_LIP_F8:
5650	case ASYNC_LIP_OCCURRED:
5651	case ASYNC_PTPMODE:
5652		if (IS_SCSI(isp)) {
5653			isp_prt(isp, ISP_LOGWARN,
5654			    "bad LIP event for SCSI cards");
5655			break;
5656		}
5657		/*
5658		 * These are broadcast events that have to be sent across
5659		 * all active channels.
5660		 */
5661		for (chan = 0; chan < isp->isp_nchan; chan++) {
5662			fcparam *fcp = FCPARAM(isp, chan);
5663			int topo = fcp->isp_topo;
5664
5665			if (fcp->role == ISP_ROLE_NONE) {
5666				continue;
5667			}
5668
5669			fcp->isp_fwstate = FW_CONFIG_WAIT;
5670			fcp->isp_loopstate = LOOP_LIP_RCVD;
5671			ISP_SET_SENDMARKER(isp, chan, 1);
5672			ISP_MARK_PORTDB(isp, chan, 1);
5673			isp_async(isp, ISPASYNC_LIP, chan);
5674#ifdef	ISP_TARGET_MODE
5675			if (isp_target_async(isp, chan, mbox)) {
5676				rval = -1;
5677			}
5678#endif
5679			/*
5680			 * We've had problems with data corruption occuring on
5681			 * commands that complete (with no apparent error) after
5682			 * we receive a LIP. This has been observed mostly on
5683			 * Local Loop topologies. To be safe, let's just mark
5684			 * all active commands as dead.
5685			 */
5686			if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
5687				int i, j;
5688				for (i = j = 0; i < isp->isp_maxcmds; i++) {
5689					XS_T *xs;
5690					xs = isp->isp_xflist[i];
5691					if (xs == NULL) {
5692						continue;
5693					}
5694					if (XS_CHANNEL(xs) != chan) {
5695						continue;
5696					}
5697					j++;
5698					XS_SETERR(xs, HBA_BUSRESET);
5699				}
5700				if (j) {
5701					isp_prt(isp, ISP_LOGERR, lipd, chan, j);
5702				}
5703			}
5704		}
5705		break;
5706
5707	case ASYNC_LOOP_UP:
5708		if (IS_SCSI(isp)) {
5709			isp_prt(isp, ISP_LOGWARN,
5710			    "bad LOOP UP event for SCSI cards");
5711			break;
5712		}
5713		/*
5714		 * This is a broadcast event that has to be sent across
5715		 * all active channels.
5716		 */
5717		for (chan = 0; chan < isp->isp_nchan; chan++) {
5718			fcparam *fcp = FCPARAM(isp, chan);
5719
5720			if (fcp->role == ISP_ROLE_NONE) {
5721				continue;
5722			}
5723
5724			ISP_SET_SENDMARKER(isp, chan, 1);
5725
5726			fcp->isp_fwstate = FW_CONFIG_WAIT;
5727			fcp->isp_loopstate = LOOP_LIP_RCVD;
5728			ISP_MARK_PORTDB(isp, chan, 1);
5729			isp_async(isp, ISPASYNC_LOOP_UP, chan);
5730#ifdef	ISP_TARGET_MODE
5731			if (isp_target_async(isp, chan, mbox)) {
5732				rval = -1;
5733			}
5734#endif
5735		}
5736		break;
5737
5738	case ASYNC_LOOP_DOWN:
5739		if (IS_SCSI(isp)) {
5740			isp_prt(isp, ISP_LOGWARN,
5741			    "bad LOOP DOWN event for SCSI cards");
5742			break;
5743		}
5744		/*
5745		 * This is a broadcast event that has to be sent across
5746		 * all active channels.
5747		 */
5748		for (chan = 0; chan < isp->isp_nchan; chan++) {
5749			fcparam *fcp = FCPARAM(isp, chan);
5750
5751			if (fcp->role == ISP_ROLE_NONE) {
5752				continue;
5753			}
5754
5755			ISP_SET_SENDMARKER(isp, chan, 1);
5756			fcp->isp_fwstate = FW_CONFIG_WAIT;
5757			fcp->isp_loopstate = LOOP_NIL;
5758			ISP_MARK_PORTDB(isp, chan, 1);
5759			isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
5760#ifdef	ISP_TARGET_MODE
5761			if (isp_target_async(isp, chan, mbox)) {
5762				rval = -1;
5763			}
5764#endif
5765		}
5766		break;
5767
5768	case ASYNC_LOOP_RESET:
5769		if (IS_SCSI(isp)) {
5770			isp_prt(isp, ISP_LOGWARN,
5771			    "bad LIP RESET event for SCSI cards");
5772			break;
5773		}
5774		/*
5775		 * This is a broadcast event that has to be sent across
5776		 * all active channels.
5777		 */
5778		for (chan = 0; chan < isp->isp_nchan; chan++) {
5779			fcparam *fcp = FCPARAM(isp, chan);
5780
5781			if (fcp->role == ISP_ROLE_NONE) {
5782				continue;
5783			}
5784
5785			ISP_SET_SENDMARKER(isp, chan, 1);
5786			fcp->isp_fwstate = FW_CONFIG_WAIT;
5787			fcp->isp_loopstate = LOOP_NIL;
5788			ISP_MARK_PORTDB(isp, chan, 1);
5789			isp_async(isp, ISPASYNC_LOOP_RESET, chan);
5790#ifdef	ISP_TARGET_MODE
5791			if (isp_target_async(isp, chan, mbox)) {
5792				rval = -1;
5793			}
5794#endif
5795		}
5796		break;
5797
5798	case ASYNC_PDB_CHANGED:
5799	{
5800		int nphdl, nlstate, reason;
5801		if (IS_SCSI(isp)) {
5802			isp_prt(isp, ISP_LOGWARN,
5803			    "bad PDB CHANGED event for SCSI cards");
5804			break;
5805		}
5806		/*
5807		 * We *should* get a channel out of the 24XX, but we don't seem
5808		 * to get more than a PDB CHANGED on channel 0, so turn it into
5809		 * a broadcast event.
5810		 */
5811		if (IS_24XX(isp)) {
5812			nphdl = ISP_READ(isp, OUTMAILBOX1);
5813			nlstate = ISP_READ(isp, OUTMAILBOX2);
5814			reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
5815		} else {
5816			nphdl = NIL_HANDLE;
5817			nlstate = reason = 0;
5818		}
5819		for (chan = 0; chan < isp->isp_nchan; chan++) {
5820			fcparam *fcp = FCPARAM(isp, chan);
5821
5822			if (fcp->role == ISP_ROLE_NONE) {
5823				continue;
5824			}
5825			ISP_SET_SENDMARKER(isp, chan, 1);
5826			fcp->isp_loopstate = LOOP_PDB_RCVD;
5827			ISP_MARK_PORTDB(isp, chan, 1);
5828			isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
5829			    ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
5830		}
5831		break;
5832	}
5833	case ASYNC_CHANGE_NOTIFY:
5834	{
5835		int lochan, hichan;
5836
5837		if (IS_SCSI(isp)) {
5838			isp_prt(isp, ISP_LOGWARN,
5839			    "bad CHANGE NOTIFY event for SCSI cards");
5840			break;
5841		}
5842		if (ISP_FW_NEWER_THAN(isp, 4, 0, 25) && ISP_CAP_MULTI_ID(isp)) {
5843			GET_24XX_BUS(isp, chan, "ASYNC_CHANGE_NOTIFY");
5844			lochan = chan;
5845			hichan = chan + 1;
5846		} else {
5847			lochan = 0;
5848			hichan = isp->isp_nchan;
5849		}
5850		for (chan = lochan; chan < hichan; chan++) {
5851			fcparam *fcp = FCPARAM(isp, chan);
5852
5853			if (fcp->role == ISP_ROLE_NONE) {
5854				continue;
5855			}
5856
5857			if (fcp->isp_topo == TOPO_F_PORT) {
5858				fcp->isp_loopstate = LOOP_LSCAN_DONE;
5859			} else {
5860				fcp->isp_loopstate = LOOP_PDB_RCVD;
5861			}
5862			ISP_MARK_PORTDB(isp, chan, 1);
5863			isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
5864			    ISPASYNC_CHANGE_SNS);
5865		}
5866		break;
5867	}
5868
5869	case ASYNC_CONNMODE:
5870		/*
5871		 * This only applies to 2100 amd 2200 cards
5872		 */
5873		if (!IS_2200(isp) && !IS_2100(isp)) {
5874			isp_prt(isp, ISP_LOGWARN,
5875			    "bad card for ASYNC_CONNMODE event");
5876			break;
5877		}
5878		chan = 0;
5879		mbox = ISP_READ(isp, OUTMAILBOX1);
5880		ISP_MARK_PORTDB(isp, chan, 1);
5881		switch (mbox) {
5882		case ISP_CONN_LOOP:
5883			isp_prt(isp, ISP_LOGINFO,
5884			    "Point-to-Point -> Loop mode");
5885			break;
5886		case ISP_CONN_PTP:
5887			isp_prt(isp, ISP_LOGINFO,
5888			    "Loop -> Point-to-Point mode");
5889			break;
5890		case ISP_CONN_BADLIP:
5891			isp_prt(isp, ISP_LOGWARN,
5892			    "Point-to-Point -> Loop mode (BAD LIP)");
5893			break;
5894		case ISP_CONN_FATAL:
5895			isp->isp_dead = 1;
5896			isp->isp_state = ISP_CRASHED;
5897			isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
5898			isp_async(isp, ISPASYNC_FW_CRASH);
5899			return (-1);
5900		case ISP_CONN_LOOPBACK:
5901			isp_prt(isp, ISP_LOGWARN,
5902			    "Looped Back in Point-to-Point mode");
5903			break;
5904		default:
5905			isp_prt(isp, ISP_LOGWARN,
5906			    "Unknown connection mode (0x%x)", mbox);
5907			break;
5908		}
5909		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
5910		    ISPASYNC_CHANGE_OTHER);
5911		FCPARAM(isp, chan)->sendmarker = 1;
5912		FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
5913		FCPARAM(isp, chan)->isp_loopstate = LOOP_LIP_RCVD;
5914		break;
5915
5916	case ASYNC_RCV_ERR:
5917		if (IS_24XX(isp)) {
5918			isp_prt(isp, ISP_LOGWARN, "Receive Error");
5919		} else {
5920			isp_prt(isp, ISP_LOGWARN,
5921			    "Unknown Async Code 0x%x", mbox);
5922		}
5923		break;
5924	case ASYNC_RJT_SENT:	/* same as ASYNC_QFULL_SENT */
5925		if (IS_24XX(isp)) {
5926			isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
5927			break;
5928		} else if (IS_2200(isp)) {
5929			isp_prt(isp, ISP_LOGTDEBUG0, "QFULL sent");
5930			break;
5931		}
5932		/* FALLTHROUGH */
5933	default:
5934		isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
5935		break;
5936	}
5937
5938	if (pattern) {
5939		int i, nh;
5940		uint16_t handles[16];
5941
5942		for (nh = 0, i = 1; i < MAX_MAILBOX(isp); i++) {
5943			if ((pattern & (1 << i)) == 0) {
5944				continue;
5945			}
5946			handles[nh++] = ISP_READ(isp, MBOX_OFF(i));
5947		}
5948		for (i = 0; i < nh; i++) {
5949			isp_fastpost_complete(isp, handles[i]);
5950			isp_prt(isp,  ISP_LOGDEBUG3,
5951			    "fast post completion of %u", handles[i]);
5952		}
5953		if (isp->isp_fpcchiwater < nh) {
5954			isp->isp_fpcchiwater = nh;
5955		}
5956	} else {
5957		isp->isp_intoasync++;
5958	}
5959	return (rval);
5960}
5961
5962/*
5963 * Handle other response entries. A pointer to the request queue output
5964 * index is here in case we want to eat several entries at once, although
5965 * this is not used currently.
5966 */
5967
5968static int
5969isp_handle_other_response(ispsoftc_t *isp, int type,
5970    isphdr_t *hp, uint32_t *optrp)
5971{
5972	switch (type) {
5973	case RQSTYPE_STATUS_CONT:
5974		isp_prt(isp, ISP_LOGDEBUG0, "Ignored Continuation Response");
5975		return (1);
5976	case RQSTYPE_MARKER:
5977		isp_prt(isp, ISP_LOGDEBUG0, "Marker Response");
5978		return (1);
5979	case RQSTYPE_ATIO:
5980	case RQSTYPE_CTIO:
5981	case RQSTYPE_ENABLE_LUN:
5982	case RQSTYPE_MODIFY_LUN:
5983	case RQSTYPE_NOTIFY:
5984	case RQSTYPE_NOTIFY_ACK:
5985	case RQSTYPE_CTIO1:
5986	case RQSTYPE_ATIO2:
5987	case RQSTYPE_CTIO2:
5988	case RQSTYPE_CTIO3:
5989	case RQSTYPE_CTIO7:
5990	case RQSTYPE_ABTS_RCVD:
5991	case RQSTYPE_ABTS_RSP:
5992		isp->isp_rsltccmplt++;	/* count as a response completion */
5993#ifdef	ISP_TARGET_MODE
5994		if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
5995			return (1);
5996		}
5997#endif
5998		/* FALLTHROUGH */
5999	case RQSTYPE_RPT_ID_ACQ:
6000		if (IS_24XX(isp)) {
6001			isp_ridacq_t rid;
6002			isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
6003			if (rid.ridacq_format == 0) {
6004			}
6005			return (1);
6006		}
6007		/* FALLTHROUGH */
6008	case RQSTYPE_REQUEST:
6009	default:
6010		ISP_DELAY(100);
6011		if (type != isp_get_response_type(isp, hp)) {
6012			/*
6013			 * This is questionable- we're just papering over
6014			 * something we've seen on SMP linux in target
6015			 * mode- we don't really know what's happening
6016			 * here that causes us to think we've gotten
6017			 * an entry, but that either the entry isn't
6018			 * filled out yet or our CPU read data is stale.
6019			 */
6020			isp_prt(isp, ISP_LOGINFO,
6021				"unstable type in response queue");
6022			return (-1);
6023		}
6024		isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
6025		    isp_get_response_type(isp, hp));
6026		return (0);
6027	}
6028}
6029
6030static void
6031isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
6032{
6033	switch (sp->req_completion_status & 0xff) {
6034	case RQCS_COMPLETE:
6035		if (XS_NOERR(xs)) {
6036			XS_SETERR(xs, HBA_NOERROR);
6037		}
6038		return;
6039
6040	case RQCS_INCOMPLETE:
6041		if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
6042			isp_prt(isp, ISP_LOGDEBUG1,
6043			    "Selection Timeout for %d.%d.%d",
6044			    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6045			if (XS_NOERR(xs)) {
6046				XS_SETERR(xs, HBA_SELTIMEOUT);
6047				*rp = XS_XFRLEN(xs);
6048			}
6049			return;
6050		}
6051		isp_prt(isp, ISP_LOGERR,
6052		    "command incomplete for %d.%d.%d, state 0x%x",
6053		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
6054		    sp->req_state_flags);
6055		break;
6056
6057	case RQCS_DMA_ERROR:
6058		isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
6059		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6060		*rp = XS_XFRLEN(xs);
6061		break;
6062
6063	case RQCS_TRANSPORT_ERROR:
6064	{
6065		char buf[172];
6066		ISP_SNPRINTF(buf, sizeof (buf), "states=>");
6067		if (sp->req_state_flags & RQSF_GOT_BUS) {
6068			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
6069		}
6070		if (sp->req_state_flags & RQSF_GOT_TARGET) {
6071			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
6072		}
6073		if (sp->req_state_flags & RQSF_SENT_CDB) {
6074			ISP_SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
6075		}
6076		if (sp->req_state_flags & RQSF_XFRD_DATA) {
6077			ISP_SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
6078		}
6079		if (sp->req_state_flags & RQSF_GOT_STATUS) {
6080			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
6081		}
6082		if (sp->req_state_flags & RQSF_GOT_SENSE) {
6083			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
6084		}
6085		if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
6086			ISP_SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
6087		}
6088		ISP_SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
6089		if (sp->req_status_flags & RQSTF_DISCONNECT) {
6090			ISP_SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
6091		}
6092		if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
6093			ISP_SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
6094		}
6095		if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
6096			ISP_SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
6097		}
6098		if (sp->req_status_flags & RQSTF_BUS_RESET) {
6099			ISP_SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
6100		}
6101		if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
6102			ISP_SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
6103		}
6104		if (sp->req_status_flags & RQSTF_ABORTED) {
6105			ISP_SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
6106		}
6107		if (sp->req_status_flags & RQSTF_TIMEOUT) {
6108			ISP_SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
6109		}
6110		if (sp->req_status_flags & RQSTF_NEGOTIATION) {
6111			ISP_SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
6112		}
6113		isp_prt(isp, ISP_LOGERR, "%s", buf);
6114		isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
6115		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf);
6116		*rp = XS_XFRLEN(xs);
6117		break;
6118	}
6119	case RQCS_RESET_OCCURRED:
6120	{
6121		int chan;
6122		isp_prt(isp, ISP_LOGWARN,
6123		    "bus reset destroyed command for %d.%d.%d",
6124		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6125		for (chan = 0; chan < isp->isp_nchan; chan++) {
6126			FCPARAM(isp, chan)->sendmarker = 1;
6127		}
6128		if (XS_NOERR(xs)) {
6129			XS_SETERR(xs, HBA_BUSRESET);
6130		}
6131		*rp = XS_XFRLEN(xs);
6132		return;
6133	}
6134	case RQCS_ABORTED:
6135		isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
6136		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6137		ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
6138		if (XS_NOERR(xs)) {
6139			XS_SETERR(xs, HBA_ABORTED);
6140		}
6141		return;
6142
6143	case RQCS_TIMEOUT:
6144		isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
6145		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6146		/*
6147	 	 * XXX: Check to see if we logged out of the device.
6148		 */
6149		if (XS_NOERR(xs)) {
6150			XS_SETERR(xs, HBA_CMDTIMEOUT);
6151		}
6152		return;
6153
6154	case RQCS_DATA_OVERRUN:
6155		XS_SET_RESID(xs, sp->req_resid);
6156		isp_prt(isp, ISP_LOGERR, "data overrun (%ld) for command on %d.%d.%d",
6157		    (long) XS_GET_RESID(xs), XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6158		if (XS_NOERR(xs)) {
6159			XS_SETERR(xs, HBA_DATAOVR);
6160		}
6161		return;
6162
6163	case RQCS_COMMAND_OVERRUN:
6164		isp_prt(isp, ISP_LOGERR,
6165		    "command overrun for command on %d.%d.%d",
6166		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6167		break;
6168
6169	case RQCS_STATUS_OVERRUN:
6170		isp_prt(isp, ISP_LOGERR,
6171		    "status overrun for command on %d.%d.%d",
6172		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6173		break;
6174
6175	case RQCS_BAD_MESSAGE:
6176		isp_prt(isp, ISP_LOGERR,
6177		    "msg not COMMAND COMPLETE after status %d.%d.%d",
6178		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6179		break;
6180
6181	case RQCS_NO_MESSAGE_OUT:
6182		isp_prt(isp, ISP_LOGERR,
6183		    "No MESSAGE OUT phase after selection on %d.%d.%d",
6184		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6185		break;
6186
6187	case RQCS_EXT_ID_FAILED:
6188		isp_prt(isp, ISP_LOGERR, "EXTENDED IDENTIFY failed %d.%d.%d",
6189		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6190		break;
6191
6192	case RQCS_IDE_MSG_FAILED:
6193		isp_prt(isp, ISP_LOGERR,
6194		    "INITIATOR DETECTED ERROR rejected by %d.%d.%d",
6195		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6196		break;
6197
6198	case RQCS_ABORT_MSG_FAILED:
6199		isp_prt(isp, ISP_LOGERR, "ABORT OPERATION rejected by %d.%d.%d",
6200		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6201		break;
6202
6203	case RQCS_REJECT_MSG_FAILED:
6204		isp_prt(isp, ISP_LOGERR, "MESSAGE REJECT rejected by %d.%d.%d",
6205		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6206		break;
6207
6208	case RQCS_NOP_MSG_FAILED:
6209		isp_prt(isp, ISP_LOGERR, "NOP rejected by %d.%d.%d",
6210		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6211		break;
6212
6213	case RQCS_PARITY_ERROR_MSG_FAILED:
6214		isp_prt(isp, ISP_LOGERR,
6215		    "MESSAGE PARITY ERROR rejected by %d.%d.%d",
6216		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6217		break;
6218
6219	case RQCS_DEVICE_RESET_MSG_FAILED:
6220		isp_prt(isp, ISP_LOGWARN,
6221		    "BUS DEVICE RESET rejected by %d.%d.%d",
6222		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6223		break;
6224
6225	case RQCS_ID_MSG_FAILED:
6226		isp_prt(isp, ISP_LOGERR, "IDENTIFY rejected by %d.%d.%d",
6227		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6228		break;
6229
6230	case RQCS_UNEXP_BUS_FREE:
6231		isp_prt(isp, ISP_LOGERR, "%d.%d.%d had an unexpected bus free",
6232		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6233		break;
6234
6235	case RQCS_DATA_UNDERRUN:
6236	{
6237		if (IS_FC(isp)) {
6238			int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
6239			if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
6240				isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
6241				    XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
6242				    (ru_marked)? "marked" : "not marked");
6243				if (XS_NOERR(xs)) {
6244					XS_SETERR(xs, HBA_BOTCH);
6245				}
6246				return;
6247			}
6248		}
6249		XS_SET_RESID(xs, sp->req_resid);
6250		if (XS_NOERR(xs)) {
6251			XS_SETERR(xs, HBA_NOERROR);
6252		}
6253		return;
6254	}
6255
6256	case RQCS_XACT_ERR1:
6257		isp_prt(isp, ISP_LOGERR, xact1, XS_CHANNEL(xs),
6258		    XS_TGT(xs), XS_LUN(xs));
6259		break;
6260
6261	case RQCS_XACT_ERR2:
6262		isp_prt(isp, ISP_LOGERR, xact2,
6263		    XS_LUN(xs), XS_TGT(xs), XS_CHANNEL(xs));
6264		break;
6265
6266	case RQCS_XACT_ERR3:
6267		isp_prt(isp, ISP_LOGERR, xact3,
6268		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6269		break;
6270
6271	case RQCS_BAD_ENTRY:
6272		isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
6273		break;
6274
6275	case RQCS_QUEUE_FULL:
6276		isp_prt(isp, ISP_LOGDEBUG0,
6277		    "internal queues full for %d.%d.%d status 0x%x",
6278		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), *XS_STSP(xs));
6279
6280		/*
6281		 * If QFULL or some other status byte is set, then this
6282		 * isn't an error, per se.
6283		 *
6284		 * Unfortunately, some QLogic f/w writers have, in
6285		 * some cases, ommitted to *set* status to QFULL.
6286		 *
6287
6288		if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
6289			XS_SETERR(xs, HBA_NOERROR);
6290			return;
6291		}
6292
6293		 *
6294		 *
6295		 */
6296
6297		*XS_STSP(xs) = SCSI_QFULL;
6298		XS_SETERR(xs, HBA_NOERROR);
6299		return;
6300
6301	case RQCS_PHASE_SKIPPED:
6302		isp_prt(isp, ISP_LOGERR, pskip, XS_CHANNEL(xs),
6303		    XS_TGT(xs), XS_LUN(xs));
6304		break;
6305
6306	case RQCS_ARQS_FAILED:
6307		isp_prt(isp, ISP_LOGERR,
6308		    "Auto Request Sense failed for %d.%d.%d",
6309		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6310		if (XS_NOERR(xs)) {
6311			XS_SETERR(xs, HBA_ARQFAIL);
6312		}
6313		return;
6314
6315	case RQCS_WIDE_FAILED:
6316		isp_prt(isp, ISP_LOGERR,
6317		    "Wide Negotiation failed for %d.%d.%d",
6318		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
6319		if (IS_SCSI(isp)) {
6320			sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
6321			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
6322			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
6323			sdp->update = 1;
6324		}
6325		if (XS_NOERR(xs)) {
6326			XS_SETERR(xs, HBA_NOERROR);
6327		}
6328		return;
6329
6330	case RQCS_SYNCXFER_FAILED:
6331		isp_prt(isp, ISP_LOGERR,
6332		    "SDTR Message failed for target %d.%d.%d",
6333		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
6334		if (IS_SCSI(isp)) {
6335			sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
6336			sdp += XS_CHANNEL(xs);
6337			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
6338			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
6339			sdp->update = 1;
6340		}
6341		break;
6342
6343	case RQCS_LVD_BUSERR:
6344		isp_prt(isp, ISP_LOGERR,
6345		    "Bad LVD condition while talking to %d.%d.%d",
6346		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
6347		break;
6348
6349	case RQCS_PORT_UNAVAILABLE:
6350		/*
6351		 * No such port on the loop. Moral equivalent of SELTIMEO
6352		 */
6353	case RQCS_PORT_LOGGED_OUT:
6354	{
6355		const char *reason;
6356		uint8_t sts = sp->req_completion_status & 0xff;
6357
6358		/*
6359		 * It was there (maybe)- treat as a selection timeout.
6360		 */
6361		if (sts == RQCS_PORT_UNAVAILABLE) {
6362			reason = "unavailable";
6363		} else {
6364			reason = "logout";
6365		}
6366
6367		isp_prt(isp, ISP_LOGINFO, "port %s for target %d",
6368		    reason, XS_TGT(xs));
6369
6370		/*
6371		 * If we're on a local loop, force a LIP (which is overkill)
6372		 * to force a re-login of this unit. If we're on fabric,
6373		 * then we'll have to log in again as a matter of course.
6374		 */
6375		if (FCPARAM(isp, 0)->isp_topo == TOPO_NL_PORT ||
6376		    FCPARAM(isp, 0)->isp_topo == TOPO_FL_PORT) {
6377			mbreg_t mbs;
6378			MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
6379			if (ISP_CAP_2KLOGIN(isp)) {
6380				mbs.ibits = (1 << 10);
6381			}
6382			isp_mboxcmd_qnw(isp, &mbs, 1);
6383		}
6384		if (XS_NOERR(xs)) {
6385			XS_SETERR(xs, HBA_SELTIMEOUT);
6386		}
6387		return;
6388	}
6389	case RQCS_PORT_CHANGED:
6390		isp_prt(isp, ISP_LOGWARN,
6391		    "port changed for target %d", XS_TGT(xs));
6392		if (XS_NOERR(xs)) {
6393			XS_SETERR(xs, HBA_SELTIMEOUT);
6394		}
6395		return;
6396
6397	case RQCS_PORT_BUSY:
6398		isp_prt(isp, ISP_LOGWARN,
6399		    "port busy for target %d", XS_TGT(xs));
6400		if (XS_NOERR(xs)) {
6401			XS_SETERR(xs, HBA_TGTBSY);
6402		}
6403		return;
6404
6405	default:
6406		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
6407		    sp->req_completion_status);
6408		break;
6409	}
6410	if (XS_NOERR(xs)) {
6411		XS_SETERR(xs, HBA_BOTCH);
6412	}
6413}
6414
6415static void
6416isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
6417    XS_T *xs, long *rp)
6418{
6419	int ru_marked, sv_marked;
6420	int chan = XS_CHANNEL(xs);
6421
6422	switch (sp->req_completion_status) {
6423	case RQCS_COMPLETE:
6424		if (XS_NOERR(xs)) {
6425			XS_SETERR(xs, HBA_NOERROR);
6426		}
6427		return;
6428
6429	case RQCS_DMA_ERROR:
6430		isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
6431		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6432		break;
6433
6434	case RQCS_TRANSPORT_ERROR:
6435		isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d",
6436		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6437		break;
6438
6439	case RQCS_RESET_OCCURRED:
6440		isp_prt(isp, ISP_LOGWARN,
6441		    "reset destroyed command for %d.%d.%d",
6442		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6443		FCPARAM(isp, chan)->sendmarker = 1;
6444		if (XS_NOERR(xs)) {
6445			XS_SETERR(xs, HBA_BUSRESET);
6446		}
6447		return;
6448
6449	case RQCS_ABORTED:
6450		isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
6451		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6452		FCPARAM(isp, chan)->sendmarker = 1;
6453		if (XS_NOERR(xs)) {
6454			XS_SETERR(xs, HBA_ABORTED);
6455		}
6456		return;
6457
6458	case RQCS_TIMEOUT:
6459		isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
6460		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6461		if (XS_NOERR(xs)) {
6462			XS_SETERR(xs, HBA_CMDTIMEOUT);
6463		}
6464		return;
6465
6466	case RQCS_DATA_OVERRUN:
6467		XS_SET_RESID(xs, sp->req_resid);
6468		isp_prt(isp, ISP_LOGERR,
6469		    "data overrun for command on %d.%d.%d",
6470		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
6471		if (XS_NOERR(xs)) {
6472			XS_SETERR(xs, HBA_DATAOVR);
6473		}
6474		return;
6475
6476	case RQCS_24XX_DRE:	/* data reassembly error */
6477		isp_prt(isp, ISP_LOGERR,
6478		    "Chan %d data reassembly error for target %d",
6479		    chan, XS_TGT(xs));
6480		if (XS_NOERR(xs)) {
6481			XS_SETERR(xs, HBA_ABORTED);
6482		}
6483		*rp = XS_XFRLEN(xs);
6484		return;
6485
6486	case RQCS_24XX_TABORT:	/* aborted by target */
6487		isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS",
6488		    chan, XS_TGT(xs));
6489		if (XS_NOERR(xs)) {
6490			XS_SETERR(xs, HBA_ABORTED);
6491		}
6492		return;
6493
6494	case RQCS_DATA_UNDERRUN:
6495		ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
6496		/*
6497		 * We can get an underrun w/o things being marked
6498		 * if we got a non-zero status.
6499		 */
6500		sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
6501		if ((ru_marked == 0 && sv_marked == 0) ||
6502		    (sp->req_resid > XS_XFRLEN(xs))) {
6503			isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
6504			    XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
6505			    (ru_marked)? "marked" : "not marked");
6506			if (XS_NOERR(xs)) {
6507				XS_SETERR(xs, HBA_BOTCH);
6508			}
6509			return;
6510		}
6511		XS_SET_RESID(xs, sp->req_resid);
6512		isp_prt(isp, ISP_LOGDEBUG0,
6513		    "%d.%d.%d data underrun (%d) for command 0x%x",
6514		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
6515		    sp->req_resid, XS_CDBP(xs)[0] & 0xff);
6516		if (XS_NOERR(xs)) {
6517			XS_SETERR(xs, HBA_NOERROR);
6518		}
6519		return;
6520
6521	case RQCS_PORT_UNAVAILABLE:
6522		/*
6523		 * No such port on the loop. Moral equivalent of SELTIMEO
6524		 */
6525	case RQCS_PORT_LOGGED_OUT:
6526	{
6527		const char *reason;
6528		uint8_t sts = sp->req_completion_status & 0xff;
6529
6530		/*
6531		 * It was there (maybe)- treat as a selection timeout.
6532		 */
6533		if (sts == RQCS_PORT_UNAVAILABLE) {
6534			reason = "unavailable";
6535		} else {
6536			reason = "logout";
6537		}
6538
6539		isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d",
6540		    chan, reason, XS_TGT(xs));
6541
6542		/*
6543		 * There is no MBOX_INIT_LIP for the 24XX.
6544		 */
6545		if (XS_NOERR(xs)) {
6546			XS_SETERR(xs, HBA_SELTIMEOUT);
6547		}
6548		return;
6549	}
6550	case RQCS_PORT_CHANGED:
6551		isp_prt(isp, ISP_LOGWARN,
6552		    "port changed for target %d chan %d", XS_TGT(xs), chan);
6553		if (XS_NOERR(xs)) {
6554			XS_SETERR(xs, HBA_SELTIMEOUT);
6555		}
6556		return;
6557
6558
6559	case RQCS_24XX_ENOMEM:	/* f/w resource unavailable */
6560		isp_prt(isp, ISP_LOGWARN,
6561		    "f/w resource unavailable for target %d chan %d",
6562		    XS_TGT(xs), chan);
6563		if (XS_NOERR(xs)) {
6564			*XS_STSP(xs) = SCSI_BUSY;
6565			XS_SETERR(xs, HBA_TGTBSY);
6566		}
6567		return;
6568
6569	case RQCS_24XX_TMO:	/* task management overrun */
6570		isp_prt(isp, ISP_LOGWARN,
6571		    "command for target %d overlapped task management for "
6572		    "chan %d", XS_TGT(xs), chan);
6573		if (XS_NOERR(xs)) {
6574			*XS_STSP(xs) = SCSI_BUSY;
6575			XS_SETERR(xs, HBA_TGTBSY);
6576		}
6577		return;
6578
6579	default:
6580		isp_prt(isp, ISP_LOGERR,
6581		    "Unknown Completion Status 0x%x on chan %d",
6582		    sp->req_completion_status, chan);
6583		break;
6584	}
6585	if (XS_NOERR(xs)) {
6586		XS_SETERR(xs, HBA_BOTCH);
6587	}
6588}
6589
6590static void
6591isp_fastpost_complete(ispsoftc_t *isp, uint16_t fph)
6592{
6593	XS_T *xs;
6594
6595	if (fph == 0) {
6596		return;
6597	}
6598	xs = isp_find_xs(isp, fph);
6599	if (xs == NULL) {
6600		isp_prt(isp, ISP_LOGWARN,
6601		    "Command for fast post handle 0x%x not found", fph);
6602		return;
6603	}
6604	isp_destroy_handle(isp, fph);
6605
6606	/*
6607	 * Since we don't have a result queue entry item,
6608	 * we must believe that SCSI status is zero and
6609	 * that all data transferred.
6610	 */
6611	XS_SET_RESID(xs, 0);
6612	*XS_STSP(xs) = SCSI_GOOD;
6613	if (XS_XFRLEN(xs)) {
6614		ISP_DMAFREE(isp, xs, fph);
6615	}
6616	if (isp->isp_nactive) {
6617		isp->isp_nactive--;
6618	}
6619	isp->isp_fphccmplt++;
6620	isp_done(xs);
6621}
6622
6623static int
6624isp_mbox_continue(ispsoftc_t *isp)
6625{
6626	mbreg_t mbs;
6627	uint16_t *ptr;
6628	uint32_t offset;
6629
6630	switch (isp->isp_lastmbxcmd) {
6631	case MBOX_WRITE_RAM_WORD:
6632	case MBOX_READ_RAM_WORD:
6633	case MBOX_WRITE_RAM_WORD_EXTENDED:
6634	case MBOX_READ_RAM_WORD_EXTENDED:
6635		break;
6636	default:
6637		return (1);
6638	}
6639	if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
6640		isp->isp_mbxwrk0 = 0;
6641		return (-1);
6642	}
6643
6644	/*
6645	 * Clear the previous interrupt.
6646	 */
6647	if (IS_24XX(isp)) {
6648		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
6649	} else {
6650		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
6651		ISP_WRITE(isp, BIU_SEMA, 0);
6652	}
6653
6654	/*
6655	 * Continue with next word.
6656	 */
6657	ISP_MEMZERO(&mbs, sizeof (mbs));
6658	ptr = isp->isp_mbxworkp;
6659	switch (isp->isp_lastmbxcmd) {
6660	case MBOX_WRITE_RAM_WORD:
6661		mbs.param[1] = isp->isp_mbxwrk1++;
6662		mbs.param[2] = *ptr++;
6663		break;
6664	case MBOX_READ_RAM_WORD:
6665		*ptr++ = isp->isp_mboxtmp[2];
6666		mbs.param[1] = isp->isp_mbxwrk1++;
6667		break;
6668	case MBOX_WRITE_RAM_WORD_EXTENDED:
6669		offset = isp->isp_mbxwrk1;
6670		offset |= isp->isp_mbxwrk8 << 16;
6671
6672		mbs.param[2] = *ptr++;
6673		mbs.param[1] = offset;
6674		mbs.param[8] = offset >> 16;
6675		isp->isp_mbxwrk1 = ++offset;
6676		isp->isp_mbxwrk8 = offset >> 16;
6677		break;
6678	case MBOX_READ_RAM_WORD_EXTENDED:
6679		offset = isp->isp_mbxwrk1;
6680		offset |= isp->isp_mbxwrk8 << 16;
6681
6682		*ptr++ = isp->isp_mboxtmp[2];
6683		mbs.param[1] = offset;
6684		mbs.param[8] = offset >> 16;
6685		isp->isp_mbxwrk1 = ++offset;
6686		isp->isp_mbxwrk8 = offset >> 16;
6687		break;
6688	}
6689	isp->isp_mbxworkp = ptr;
6690	isp->isp_mbxwrk0--;
6691	mbs.param[0] = isp->isp_lastmbxcmd;
6692	mbs.logval = MBLOGALL;
6693	isp_mboxcmd_qnw(isp, &mbs, 0);
6694	return (0);
6695}
6696
6697#define	HIWRD(x)			((x) >> 16)
6698#define	LOWRD(x)			((x)  & 0xffff)
6699#define	ISPOPMAP(a, b)			(((a) << 16) | (b))
6700static const uint32_t mbpscsi[] = {
6701	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
6702	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
6703	ISPOPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
6704	ISPOPMAP(0x1f, 0x01),	/* 0x03: MBOX_DUMP_RAM */
6705	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
6706	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
6707	ISPOPMAP(0x3f, 0x3f),	/* 0x06: MBOX_MAILBOX_REG_TEST */
6708	ISPOPMAP(0x07, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
6709	ISPOPMAP(0x01, 0x0f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
6710	ISPOPMAP(0x00, 0x00),	/* 0x09: */
6711	ISPOPMAP(0x00, 0x00),	/* 0x0a: */
6712	ISPOPMAP(0x00, 0x00),	/* 0x0b: */
6713	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
6714	ISPOPMAP(0x00, 0x00),	/* 0x0d: */
6715	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
6716	ISPOPMAP(0x00, 0x00),	/* 0x0f: */
6717	ISPOPMAP(0x1f, 0x1f),	/* 0x10: MBOX_INIT_REQ_QUEUE */
6718	ISPOPMAP(0x3f, 0x3f),	/* 0x11: MBOX_INIT_RES_QUEUE */
6719	ISPOPMAP(0x0f, 0x0f),	/* 0x12: MBOX_EXECUTE_IOCB */
6720	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
6721	ISPOPMAP(0x01, 0x3f),	/* 0x14: MBOX_STOP_FIRMWARE */
6722	ISPOPMAP(0x0f, 0x0f),	/* 0x15: MBOX_ABORT */
6723	ISPOPMAP(0x03, 0x03),	/* 0x16: MBOX_ABORT_DEVICE */
6724	ISPOPMAP(0x07, 0x07),	/* 0x17: MBOX_ABORT_TARGET */
6725	ISPOPMAP(0x07, 0x07),	/* 0x18: MBOX_BUS_RESET */
6726	ISPOPMAP(0x03, 0x07),	/* 0x19: MBOX_STOP_QUEUE */
6727	ISPOPMAP(0x03, 0x07),	/* 0x1a: MBOX_START_QUEUE */
6728	ISPOPMAP(0x03, 0x07),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6729	ISPOPMAP(0x03, 0x07),	/* 0x1c: MBOX_ABORT_QUEUE */
6730	ISPOPMAP(0x03, 0x4f),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6731	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
6732	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6733	ISPOPMAP(0x01, 0x07),	/* 0x20: MBOX_GET_INIT_SCSI_ID */
6734	ISPOPMAP(0x01, 0x07),	/* 0x21: MBOX_GET_SELECT_TIMEOUT */
6735	ISPOPMAP(0x01, 0xc7),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
6736	ISPOPMAP(0x01, 0x07),	/* 0x23: MBOX_GET_TAG_AGE_LIMIT */
6737	ISPOPMAP(0x01, 0x03),	/* 0x24: MBOX_GET_CLOCK_RATE */
6738	ISPOPMAP(0x01, 0x07),	/* 0x25: MBOX_GET_ACT_NEG_STATE */
6739	ISPOPMAP(0x01, 0x07),	/* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
6740	ISPOPMAP(0x01, 0x07),	/* 0x27: MBOX_GET_PCI_PARAMS */
6741	ISPOPMAP(0x03, 0x4f),	/* 0x28: MBOX_GET_TARGET_PARAMS */
6742	ISPOPMAP(0x03, 0x0f),	/* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
6743	ISPOPMAP(0x01, 0x07),	/* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
6744	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
6745	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
6746	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
6747	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
6748	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
6749	ISPOPMAP(0x03, 0x03),	/* 0x30: MBOX_SET_INIT_SCSI_ID */
6750	ISPOPMAP(0x07, 0x07),	/* 0x31: MBOX_SET_SELECT_TIMEOUT */
6751	ISPOPMAP(0xc7, 0xc7),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
6752	ISPOPMAP(0x07, 0x07),	/* 0x33: MBOX_SET_TAG_AGE_LIMIT */
6753	ISPOPMAP(0x03, 0x03),	/* 0x34: MBOX_SET_CLOCK_RATE */
6754	ISPOPMAP(0x07, 0x07),	/* 0x35: MBOX_SET_ACT_NEG_STATE */
6755	ISPOPMAP(0x07, 0x07),	/* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
6756	ISPOPMAP(0x07, 0x07),	/* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
6757	ISPOPMAP(0x4f, 0x4f),	/* 0x38: MBOX_SET_TARGET_PARAMS */
6758	ISPOPMAP(0x0f, 0x0f),	/* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
6759	ISPOPMAP(0x07, 0x07),	/* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
6760	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
6761	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
6762	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
6763	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
6764	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
6765	ISPOPMAP(0x01, 0x03),	/* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
6766	ISPOPMAP(0x3f, 0x01),	/* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
6767	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_EXEC_BIOS_IOCB */
6768	ISPOPMAP(0x00, 0x00),	/* 0x43: */
6769	ISPOPMAP(0x00, 0x00),	/* 0x44: */
6770	ISPOPMAP(0x03, 0x03),	/* 0x45: SET SYSTEM PARAMETER */
6771	ISPOPMAP(0x01, 0x03),	/* 0x46: GET SYSTEM PARAMETER */
6772	ISPOPMAP(0x00, 0x00),	/* 0x47: */
6773	ISPOPMAP(0x01, 0xcf),	/* 0x48: GET SCAM CONFIGURATION */
6774	ISPOPMAP(0xcf, 0xcf),	/* 0x49: SET SCAM CONFIGURATION */
6775	ISPOPMAP(0x03, 0x03),	/* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
6776	ISPOPMAP(0x01, 0x03),	/* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
6777	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
6778	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
6779	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
6780	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
6781	ISPOPMAP(0xdf, 0xdf),	/* 0x50: LOAD RAM A64 */
6782	ISPOPMAP(0xdf, 0xdf),	/* 0x51: DUMP RAM A64 */
6783	ISPOPMAP(0xdf, 0xff),	/* 0x52: INITIALIZE REQUEST QUEUE A64 */
6784	ISPOPMAP(0xef, 0xff),	/* 0x53: INITIALIZE RESPONSE QUEUE A64 */
6785	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUCUTE COMMAND IOCB A64 */
6786	ISPOPMAP(0x07, 0x01),	/* 0x55: ENABLE TARGET MODE */
6787	ISPOPMAP(0x03, 0x0f),	/* 0x56: GET TARGET STATUS */
6788	ISPOPMAP(0x00, 0x00),	/* 0x57: */
6789	ISPOPMAP(0x00, 0x00),	/* 0x58: */
6790	ISPOPMAP(0x00, 0x00),	/* 0x59: */
6791	ISPOPMAP(0x03, 0x03),	/* 0x5a: SET DATA OVERRUN RECOVERY MODE */
6792	ISPOPMAP(0x01, 0x03),	/* 0x5b: GET DATA OVERRUN RECOVERY MODE */
6793	ISPOPMAP(0x0f, 0x0f),	/* 0x5c: SET HOST DATA */
6794	ISPOPMAP(0x01, 0x01)	/* 0x5d: GET NOST DATA */
6795};
6796
6797static const char *scsi_mbcmd_names[] = {
6798	"NO-OP",
6799	"LOAD RAM",
6800	"EXEC FIRMWARE",
6801	"DUMP RAM",
6802	"WRITE RAM WORD",
6803	"READ RAM WORD",
6804	"MAILBOX REG TEST",
6805	"VERIFY CHECKSUM",
6806	"ABOUT FIRMWARE",
6807	NULL,
6808	NULL,
6809	NULL,
6810	NULL,
6811	NULL,
6812	"CHECK FIRMWARE",
6813	NULL,
6814	"INIT REQUEST QUEUE",
6815	"INIT RESULT QUEUE",
6816	"EXECUTE IOCB",
6817	"WAKE UP",
6818	"STOP FIRMWARE",
6819	"ABORT",
6820	"ABORT DEVICE",
6821	"ABORT TARGET",
6822	"BUS RESET",
6823	"STOP QUEUE",
6824	"START QUEUE",
6825	"SINGLE STEP QUEUE",
6826	"ABORT QUEUE",
6827	"GET DEV QUEUE STATUS",
6828	NULL,
6829	"GET FIRMWARE STATUS",
6830	"GET INIT SCSI ID",
6831	"GET SELECT TIMEOUT",
6832	"GET RETRY COUNT",
6833	"GET TAG AGE LIMIT",
6834	"GET CLOCK RATE",
6835	"GET ACT NEG STATE",
6836	"GET ASYNC DATA SETUP TIME",
6837	"GET PCI PARAMS",
6838	"GET TARGET PARAMS",
6839	"GET DEV QUEUE PARAMS",
6840	"GET RESET DELAY PARAMS",
6841	NULL,
6842	NULL,
6843	NULL,
6844	NULL,
6845	NULL,
6846	"SET INIT SCSI ID",
6847	"SET SELECT TIMEOUT",
6848	"SET RETRY COUNT",
6849	"SET TAG AGE LIMIT",
6850	"SET CLOCK RATE",
6851	"SET ACT NEG STATE",
6852	"SET ASYNC DATA SETUP TIME",
6853	"SET PCI CONTROL PARAMS",
6854	"SET TARGET PARAMS",
6855	"SET DEV QUEUE PARAMS",
6856	"SET RESET DELAY PARAMS",
6857	NULL,
6858	NULL,
6859	NULL,
6860	NULL,
6861	NULL,
6862	"RETURN BIOS BLOCK ADDR",
6863	"WRITE FOUR RAM WORDS",
6864	"EXEC BIOS IOCB",
6865	NULL,
6866	NULL,
6867	"SET SYSTEM PARAMETER",
6868	"GET SYSTEM PARAMETER",
6869	NULL,
6870	"GET SCAM CONFIGURATION",
6871	"SET SCAM CONFIGURATION",
6872	"SET FIRMWARE FEATURES",
6873	"GET FIRMWARE FEATURES",
6874	NULL,
6875	NULL,
6876	NULL,
6877	NULL,
6878	"LOAD RAM A64",
6879	"DUMP RAM A64",
6880	"INITIALIZE REQUEST QUEUE A64",
6881	"INITIALIZE RESPONSE QUEUE A64",
6882	"EXECUTE IOCB A64",
6883	"ENABLE TARGET MODE",
6884	"GET TARGET MODE STATE",
6885	NULL,
6886	NULL,
6887	NULL,
6888	"SET DATA OVERRUN RECOVERY MODE",
6889	"GET DATA OVERRUN RECOVERY MODE",
6890	"SET HOST DATA",
6891	"GET NOST DATA",
6892};
6893
6894static const uint32_t mbpfc[] = {
6895	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
6896	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
6897	ISPOPMAP(0x0f, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
6898	ISPOPMAP(0xdf, 0x01),	/* 0x03: MBOX_DUMP_RAM */
6899	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
6900	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
6901	ISPOPMAP(0xff, 0xff),	/* 0x06: MBOX_MAILBOX_REG_TEST */
6902	ISPOPMAP(0x07, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
6903	ISPOPMAP(0x01, 0x4f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
6904	ISPOPMAP(0xdf, 0x01),	/* 0x09: MBOX_LOAD_RISC_RAM_2100 */
6905	ISPOPMAP(0xdf, 0x01),	/* 0x0a: DUMP RAM */
6906	ISPOPMAP(0x1ff, 0x01),	/* 0x0b: MBOX_LOAD_RISC_RAM */
6907	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
6908	ISPOPMAP(0x10f, 0x01),	/* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
6909	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
6910	ISPOPMAP(0x10f, 0x05),	/* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
6911	ISPOPMAP(0x1f, 0x11),	/* 0x10: MBOX_INIT_REQ_QUEUE */
6912	ISPOPMAP(0x2f, 0x21),	/* 0x11: MBOX_INIT_RES_QUEUE */
6913	ISPOPMAP(0x0f, 0x01),	/* 0x12: MBOX_EXECUTE_IOCB */
6914	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
6915	ISPOPMAP(0x01, 0xff),	/* 0x14: MBOX_STOP_FIRMWARE */
6916	ISPOPMAP(0x4f, 0x01),	/* 0x15: MBOX_ABORT */
6917	ISPOPMAP(0x07, 0x01),	/* 0x16: MBOX_ABORT_DEVICE */
6918	ISPOPMAP(0x07, 0x01),	/* 0x17: MBOX_ABORT_TARGET */
6919	ISPOPMAP(0x03, 0x03),	/* 0x18: MBOX_BUS_RESET */
6920	ISPOPMAP(0x07, 0x05),	/* 0x19: MBOX_STOP_QUEUE */
6921	ISPOPMAP(0x07, 0x05),	/* 0x1a: MBOX_START_QUEUE */
6922	ISPOPMAP(0x07, 0x05),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6923	ISPOPMAP(0x07, 0x05),	/* 0x1c: MBOX_ABORT_QUEUE */
6924	ISPOPMAP(0x07, 0x03),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6925	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
6926	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6927	ISPOPMAP(0x01, 0x4f),	/* 0x20: MBOX_GET_LOOP_ID */
6928	ISPOPMAP(0x00, 0x00),	/* 0x21: */
6929	ISPOPMAP(0x01, 0x07),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
6930	ISPOPMAP(0x00, 0x00),	/* 0x23: */
6931	ISPOPMAP(0x00, 0x00),	/* 0x24: */
6932	ISPOPMAP(0x00, 0x00),	/* 0x25: */
6933	ISPOPMAP(0x00, 0x00),	/* 0x26: */
6934	ISPOPMAP(0x00, 0x00),	/* 0x27: */
6935	ISPOPMAP(0x01, 0x03),	/* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
6936	ISPOPMAP(0x03, 0x07),	/* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
6937	ISPOPMAP(0x00, 0x00),	/* 0x2a: */
6938	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
6939	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
6940	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
6941	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
6942	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
6943	ISPOPMAP(0x00, 0x00),	/* 0x30: */
6944	ISPOPMAP(0x00, 0x00),	/* 0x31: */
6945	ISPOPMAP(0x07, 0x07),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
6946	ISPOPMAP(0x00, 0x00),	/* 0x33: */
6947	ISPOPMAP(0x00, 0x00),	/* 0x34: */
6948	ISPOPMAP(0x00, 0x00),	/* 0x35: */
6949	ISPOPMAP(0x00, 0x00),	/* 0x36: */
6950	ISPOPMAP(0x00, 0x00),	/* 0x37: */
6951	ISPOPMAP(0x0f, 0x01),	/* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
6952	ISPOPMAP(0x0f, 0x07),	/* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
6953	ISPOPMAP(0x00, 0x00),	/* 0x3a: */
6954	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
6955	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
6956	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
6957	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
6958	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
6959	ISPOPMAP(0x03, 0x01),	/* 0x40: MBOX_LOOP_PORT_BYPASS */
6960	ISPOPMAP(0x03, 0x01),	/* 0x41: MBOX_LOOP_PORT_ENABLE */
6961	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_GET_RESOURCE_COUNT */
6962	ISPOPMAP(0x01, 0x01),	/* 0x43: MBOX_REQUEST_OFFLINE_MODE */
6963	ISPOPMAP(0x00, 0x00),	/* 0x44: */
6964	ISPOPMAP(0x00, 0x00),	/* 0x45: */
6965	ISPOPMAP(0x00, 0x00),	/* 0x46: */
6966	ISPOPMAP(0xcf, 0x03),	/* 0x47: GET PORT_DATABASE ENHANCED */
6967	ISPOPMAP(0xcd, 0x01),	/* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */
6968	ISPOPMAP(0xcd, 0x01),	/* 0x49: MBOX_GET_VP_DATABASE */
6969	ISPOPMAP(0x2cd, 0x01),	/* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */
6970	ISPOPMAP(0x00, 0x00),	/* 0x4b: */
6971	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
6972	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
6973	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
6974	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
6975	ISPOPMAP(0x00, 0x00),	/* 0x50: */
6976	ISPOPMAP(0x00, 0x00),	/* 0x51: */
6977	ISPOPMAP(0x00, 0x00),	/* 0x52: */
6978	ISPOPMAP(0x00, 0x00),	/* 0x53: */
6979	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
6980	ISPOPMAP(0x00, 0x00),	/* 0x55: */
6981	ISPOPMAP(0x00, 0x00),	/* 0x56: */
6982	ISPOPMAP(0x00, 0x00),	/* 0x57: */
6983	ISPOPMAP(0x00, 0x00),	/* 0x58: */
6984	ISPOPMAP(0x00, 0x00),	/* 0x59: */
6985	ISPOPMAP(0x00, 0x00),	/* 0x5a: */
6986	ISPOPMAP(0x03, 0x01),	/* 0x5b: MBOX_DRIVER_HEARTBEAT */
6987	ISPOPMAP(0xcf, 0x01),	/* 0x5c: MBOX_FW_HEARTBEAT */
6988	ISPOPMAP(0x07, 0x03),	/* 0x5d: MBOX_GET_SET_DATA_RATE */
6989	ISPOPMAP(0x00, 0x00),	/* 0x5e: */
6990	ISPOPMAP(0x00, 0x00),	/* 0x5f: */
6991	ISPOPMAP(0xcd, 0x01),	/* 0x60: MBOX_INIT_FIRMWARE */
6992	ISPOPMAP(0x00, 0x00),	/* 0x61: */
6993	ISPOPMAP(0x01, 0x01),	/* 0x62: MBOX_INIT_LIP */
6994	ISPOPMAP(0xcd, 0x03),	/* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
6995	ISPOPMAP(0xcf, 0x01),	/* 0x64: MBOX_GET_PORT_DB */
6996	ISPOPMAP(0x07, 0x01),	/* 0x65: MBOX_CLEAR_ACA */
6997	ISPOPMAP(0x07, 0x01),	/* 0x66: MBOX_TARGET_RESET */
6998	ISPOPMAP(0x07, 0x01),	/* 0x67: MBOX_CLEAR_TASK_SET */
6999	ISPOPMAP(0x07, 0x01),	/* 0x68: MBOX_ABORT_TASK_SET */
7000	ISPOPMAP(0x01, 0x07),	/* 0x69: MBOX_GET_FW_STATE */
7001	ISPOPMAP(0x03, 0xcf),	/* 0x6a: MBOX_GET_PORT_NAME */
7002	ISPOPMAP(0xcf, 0x01),	/* 0x6b: MBOX_GET_LINK_STATUS */
7003	ISPOPMAP(0x0f, 0x01),	/* 0x6c: MBOX_INIT_LIP_RESET */
7004	ISPOPMAP(0x00, 0x00),	/* 0x6d: */
7005	ISPOPMAP(0xcf, 0x03),	/* 0x6e: MBOX_SEND_SNS */
7006	ISPOPMAP(0x0f, 0x07),	/* 0x6f: MBOX_FABRIC_LOGIN */
7007	ISPOPMAP(0x03, 0x01),	/* 0x70: MBOX_SEND_CHANGE_REQUEST */
7008	ISPOPMAP(0x03, 0x03),	/* 0x71: MBOX_FABRIC_LOGOUT */
7009	ISPOPMAP(0x0f, 0x0f),	/* 0x72: MBOX_INIT_LIP_LOGIN */
7010	ISPOPMAP(0x00, 0x00),	/* 0x73: */
7011	ISPOPMAP(0x07, 0x01),	/* 0x74: LOGIN LOOP PORT */
7012	ISPOPMAP(0xcf, 0x03),	/* 0x75: GET PORT/NODE NAME LIST */
7013	ISPOPMAP(0x4f, 0x01),	/* 0x76: SET VENDOR ID */
7014	ISPOPMAP(0xcd, 0x01),	/* 0x77: INITIALIZE IP MAILBOX */
7015	ISPOPMAP(0x00, 0x00),	/* 0x78: */
7016	ISPOPMAP(0x00, 0x00),	/* 0x79: */
7017	ISPOPMAP(0x00, 0x00),	/* 0x7a: */
7018	ISPOPMAP(0x00, 0x00),	/* 0x7b: */
7019	ISPOPMAP(0x4f, 0x03),	/* 0x7c: Get ID List */
7020	ISPOPMAP(0xcf, 0x01),	/* 0x7d: SEND LFA */
7021	ISPOPMAP(0x0f, 0x01)	/* 0x7e: LUN RESET */
7022};
7023/*
7024 * Footnotes
7025 *
7026 * (1): this sets bits 21..16 in mailbox register #8, which we nominally
7027 *	do not access at this time in the core driver. The caller is
7028 *	responsible for setting this register first (Gross!). The assumption
7029 *	is that we won't overflow.
7030 */
7031
7032static const char *fc_mbcmd_names[] = {
7033	"NO-OP",
7034	"LOAD RAM",
7035	"EXEC FIRMWARE",
7036	"DUMP RAM",
7037	"WRITE RAM WORD",
7038	"READ RAM WORD",
7039	"MAILBOX REG TEST",
7040	"VERIFY CHECKSUM",
7041	"ABOUT FIRMWARE",
7042	"LOAD RAM",
7043	"DUMP RAM",
7044	"WRITE RAM WORD EXTENDED",
7045	NULL,
7046	"READ RAM WORD EXTENDED",
7047	"CHECK FIRMWARE",
7048	NULL,
7049	"INIT REQUEST QUEUE",
7050	"INIT RESULT QUEUE",
7051	"EXECUTE IOCB",
7052	"WAKE UP",
7053	"STOP FIRMWARE",
7054	"ABORT",
7055	"ABORT DEVICE",
7056	"ABORT TARGET",
7057	"BUS RESET",
7058	"STOP QUEUE",
7059	"START QUEUE",
7060	"SINGLE STEP QUEUE",
7061	"ABORT QUEUE",
7062	"GET DEV QUEUE STATUS",
7063	NULL,
7064	"GET FIRMWARE STATUS",
7065	"GET LOOP ID",
7066	NULL,
7067	"GET RETRY COUNT",
7068	NULL,
7069	NULL,
7070	NULL,
7071	NULL,
7072	NULL,
7073	"GET FIRMWARE OPTIONS",
7074	"GET PORT QUEUE PARAMS",
7075	NULL,
7076	NULL,
7077	NULL,
7078	NULL,
7079	NULL,
7080	NULL,
7081	NULL,
7082	NULL,
7083	"SET RETRY COUNT",
7084	NULL,
7085	NULL,
7086	NULL,
7087	NULL,
7088	NULL,
7089	"SET FIRMWARE OPTIONS",
7090	"SET PORT QUEUE PARAMS",
7091	NULL,
7092	NULL,
7093	NULL,
7094	NULL,
7095	NULL,
7096	NULL,
7097	"LOOP PORT BYPASS",
7098	"LOOP PORT ENABLE",
7099	"GET RESOURCE COUNT",
7100	"REQUEST NON PARTICIPATING MODE",
7101	NULL,
7102	NULL,
7103	NULL,
7104	"GET PORT DATABASE ENHANCED",
7105	"INIT FIRMWARE MULTI ID",
7106	"GET VP DATABASE",
7107	"GET VP DATABASE ENTRY",
7108	NULL,
7109	NULL,
7110	NULL,
7111	NULL,
7112	NULL,
7113	NULL,
7114	NULL,
7115	NULL,
7116	NULL,
7117	"EXECUTE IOCB A64",
7118	NULL,
7119	NULL,
7120	NULL,
7121	NULL,
7122	NULL,
7123	NULL,
7124	"DRIVER HEARTBEAT",
7125	NULL,
7126	"GET/SET DATA RATE",
7127	NULL,
7128	NULL,
7129	"INIT FIRMWARE",
7130	NULL,
7131	"INIT LIP",
7132	"GET FC-AL POSITION MAP",
7133	"GET PORT DATABASE",
7134	"CLEAR ACA",
7135	"TARGET RESET",
7136	"CLEAR TASK SET",
7137	"ABORT TASK SET",
7138	"GET FW STATE",
7139	"GET PORT NAME",
7140	"GET LINK STATUS",
7141	"INIT LIP RESET",
7142	NULL,
7143	"SEND SNS",
7144	"FABRIC LOGIN",
7145	"SEND CHANGE REQUEST",
7146	"FABRIC LOGOUT",
7147	"INIT LIP LOGIN",
7148	NULL,
7149	"LOGIN LOOP PORT",
7150	"GET PORT/NODE NAME LIST",
7151	"SET VENDOR ID",
7152	"INITIALIZE IP MAILBOX",
7153	NULL,
7154	NULL,
7155	NULL,
7156	NULL,
7157	"Get ID List",
7158	"SEND LFA",
7159	"Lun RESET"
7160};
7161
7162static void
7163isp_mboxcmd_qnw(ispsoftc_t *isp, mbreg_t *mbp, int nodelay)
7164{
7165	unsigned int ibits, obits, box, opcode;
7166	const uint32_t *mcp;
7167
7168	if (IS_FC(isp)) {
7169		mcp = mbpfc;
7170	} else {
7171		mcp = mbpscsi;
7172	}
7173	opcode = mbp->param[0];
7174	ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7175	obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7176	ibits |= mbp->ibits;
7177	obits |= mbp->obits;
7178	for (box = 0; box < MAX_MAILBOX(isp); box++) {
7179		if (ibits & (1 << box)) {
7180			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
7181		}
7182		if (nodelay == 0) {
7183			isp->isp_mboxtmp[box] = mbp->param[box] = 0;
7184		}
7185	}
7186	if (nodelay == 0) {
7187		isp->isp_lastmbxcmd = opcode;
7188		isp->isp_obits = obits;
7189		isp->isp_mboxbsy = 1;
7190	}
7191	if (IS_24XX(isp)) {
7192		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
7193	} else {
7194		ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
7195	}
7196	/*
7197	 * Oddly enough, if we're not delaying for an answer,
7198	 * delay a bit to give the f/w a chance to pick up the
7199	 * command.
7200	 */
7201	if (nodelay) {
7202		ISP_DELAY(1000);
7203	}
7204}
7205
7206static void
7207isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
7208{
7209	const char *cname, *xname;
7210	char tname[16], mname[16];
7211	unsigned int lim, ibits, obits, box, opcode;
7212	const uint32_t *mcp;
7213
7214	if (IS_FC(isp)) {
7215		mcp = mbpfc;
7216		lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
7217	} else {
7218		mcp = mbpscsi;
7219		lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
7220	}
7221
7222	if ((opcode = mbp->param[0]) >= lim) {
7223		mbp->param[0] = MBOX_INVALID_COMMAND;
7224		isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
7225		return;
7226	}
7227
7228	ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7229	obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7230
7231	/*
7232	 * Pick up any additional bits that the caller might have set.
7233	 */
7234	ibits |= mbp->ibits;
7235	obits |= mbp->obits;
7236
7237	if (ibits == 0 && obits == 0) {
7238		mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
7239		isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
7240		return;
7241	}
7242
7243	/*
7244	 * Get exclusive usage of mailbox registers.
7245	 */
7246	if (MBOX_ACQUIRE(isp)) {
7247		mbp->param[0] = MBOX_REGS_BUSY;
7248		goto out;
7249	}
7250
7251	for (box = 0; box < MAX_MAILBOX(isp); box++) {
7252		if (ibits & (1 << box)) {
7253			isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box,
7254			    mbp->param[box]);
7255			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
7256		}
7257		isp->isp_mboxtmp[box] = mbp->param[box] = 0;
7258	}
7259
7260	isp->isp_lastmbxcmd = opcode;
7261
7262	/*
7263	 * We assume that we can't overwrite a previous command.
7264	 */
7265	isp->isp_obits = obits;
7266	isp->isp_mboxbsy = 1;
7267
7268	/*
7269	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
7270	 */
7271	if (IS_24XX(isp)) {
7272		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
7273	} else {
7274		ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
7275	}
7276
7277	/*
7278	 * While we haven't finished the command, spin our wheels here.
7279	 */
7280	MBOX_WAIT_COMPLETE(isp, mbp);
7281
7282	/*
7283	 * Did the command time out?
7284	 */
7285	if (mbp->param[0] == MBOX_TIMEOUT) {
7286		isp->isp_mboxbsy = 0;
7287		MBOX_RELEASE(isp);
7288		goto out;
7289	}
7290
7291	/*
7292	 * Copy back output registers.
7293	 */
7294	for (box = 0; box < MAX_MAILBOX(isp); box++) {
7295		if (obits & (1 << box)) {
7296			mbp->param[box] = isp->isp_mboxtmp[box];
7297			isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box,
7298			    mbp->param[box]);
7299		}
7300	}
7301
7302	isp->isp_mboxbsy = 0;
7303	MBOX_RELEASE(isp);
7304 out:
7305	if (mbp->logval == 0 || opcode == MBOX_EXEC_FIRMWARE) {
7306		return;
7307	}
7308	cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
7309	if (cname == NULL) {
7310		cname = tname;
7311		ISP_SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
7312	}
7313
7314	/*
7315	 * Just to be chatty here...
7316	 */
7317	xname = NULL;
7318	switch (mbp->param[0]) {
7319	case MBOX_COMMAND_COMPLETE:
7320		break;
7321	case MBOX_INVALID_COMMAND:
7322		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_COMPLETE)) {
7323			xname = "INVALID COMMAND";
7324		}
7325		break;
7326	case MBOX_HOST_INTERFACE_ERROR:
7327		if (mbp->logval & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR)) {
7328			xname = "HOST INTERFACE ERROR";
7329		}
7330		break;
7331	case MBOX_TEST_FAILED:
7332		if (mbp->logval & MBLOGMASK(MBOX_TEST_FAILED)) {
7333			xname = "TEST FAILED";
7334		}
7335		break;
7336	case MBOX_COMMAND_ERROR:
7337		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_ERROR)) {
7338			xname = "COMMAND ERROR";
7339		}
7340		break;
7341	case MBOX_COMMAND_PARAM_ERROR:
7342		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR)) {
7343			xname = "COMMAND PARAMETER ERROR";
7344		}
7345		break;
7346	case MBOX_LOOP_ID_USED:
7347		if (mbp->logval & MBLOGMASK(MBOX_LOOP_ID_USED)) {
7348			xname = "LOOP ID ALREADY IN USE";
7349		}
7350		break;
7351	case MBOX_PORT_ID_USED:
7352		if (mbp->logval & MBLOGMASK(MBOX_PORT_ID_USED)) {
7353			xname = "PORT ID ALREADY IN USE";
7354		}
7355		break;
7356	case MBOX_ALL_IDS_USED:
7357		if (mbp->logval & MBLOGMASK(MBOX_ALL_IDS_USED)) {
7358			xname = "ALL LOOP IDS IN USE";
7359		}
7360		break;
7361	case MBOX_REGS_BUSY:
7362		xname = "REGISTERS BUSY";
7363		break;
7364	case MBOX_TIMEOUT:
7365		xname = "TIMEOUT";
7366		break;
7367	default:
7368		ISP_SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
7369		xname = mname;
7370		break;
7371	}
7372	if (xname) {
7373		isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
7374		    cname, xname);
7375	}
7376}
7377
7378static void
7379isp_fw_state(ispsoftc_t *isp, int chan)
7380{
7381	if (IS_FC(isp)) {
7382		mbreg_t mbs;
7383		fcparam *fcp = FCPARAM(isp, chan);
7384
7385		MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0);
7386		isp_mboxcmd(isp, &mbs);
7387		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
7388			fcp->isp_fwstate = mbs.param[1];
7389		}
7390	}
7391}
7392
7393static void
7394isp_spi_update(ispsoftc_t *isp, int chan)
7395{
7396	int tgt;
7397	mbreg_t mbs;
7398	sdparam *sdp;
7399
7400	if (IS_FC(isp)) {
7401		/*
7402		 * There are no 'per-bus' settings for Fibre Channel.
7403		 */
7404		return;
7405	}
7406	sdp = SDPARAM(isp, chan);
7407	sdp->update = 0;
7408
7409	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7410		uint16_t flags, period, offset;
7411		int get;
7412
7413		if (sdp->isp_devparam[tgt].dev_enable == 0) {
7414			sdp->isp_devparam[tgt].dev_update = 0;
7415			sdp->isp_devparam[tgt].dev_refresh = 0;
7416			isp_prt(isp, ISP_LOGDEBUG0,
7417	 		    "skipping target %d bus %d update", tgt, chan);
7418			continue;
7419		}
7420		/*
7421		 * If the goal is to update the status of the device,
7422		 * take what's in goal_flags and try and set the device
7423		 * toward that. Otherwise, if we're just refreshing the
7424		 * current device state, get the current parameters.
7425		 */
7426
7427		MBSINIT(&mbs, 0, MBLOGALL, 0);
7428
7429		/*
7430		 * Refresh overrides set
7431		 */
7432		if (sdp->isp_devparam[tgt].dev_refresh) {
7433			mbs.param[0] = MBOX_GET_TARGET_PARAMS;
7434			get = 1;
7435		} else if (sdp->isp_devparam[tgt].dev_update) {
7436			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
7437
7438			/*
7439			 * Make sure goal_flags has "Renegotiate on Error"
7440			 * on and "Freeze Queue on Error" off.
7441			 */
7442			sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
7443			sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
7444			mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
7445
7446			/*
7447			 * Insist that PARITY must be enabled
7448			 * if SYNC or WIDE is enabled.
7449			 */
7450			if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
7451				mbs.param[2] |= DPARM_PARITY;
7452			}
7453
7454			if (mbs.param[2] & DPARM_SYNC) {
7455				mbs.param[3] =
7456				    (sdp->isp_devparam[tgt].goal_offset << 8) |
7457				    (sdp->isp_devparam[tgt].goal_period);
7458			}
7459			/*
7460			 * A command completion later that has
7461			 * RQSTF_NEGOTIATION set can cause
7462			 * the dev_refresh/announce cycle also.
7463			 *
7464			 * Note: It is really important to update our current
7465			 * flags with at least the state of TAG capabilities-
7466			 * otherwise we might try and send a tagged command
7467			 * when we have it all turned off. So change it here
7468			 * to say that current already matches goal.
7469			 */
7470			sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
7471			sdp->isp_devparam[tgt].actv_flags |=
7472			    (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
7473			isp_prt(isp, ISP_LOGDEBUG0,
7474			    "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
7475			    chan, tgt, mbs.param[2], mbs.param[3] >> 8,
7476			    mbs.param[3] & 0xff);
7477			get = 0;
7478		} else {
7479			continue;
7480		}
7481		mbs.param[1] = (chan << 15) | (tgt << 8);
7482		isp_mboxcmd(isp, &mbs);
7483		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7484			continue;
7485		}
7486		if (get == 0) {
7487			sdp->sendmarker = 1;
7488			sdp->isp_devparam[tgt].dev_update = 0;
7489			sdp->isp_devparam[tgt].dev_refresh = 1;
7490		} else {
7491			sdp->isp_devparam[tgt].dev_refresh = 0;
7492			flags = mbs.param[2];
7493			period = mbs.param[3] & 0xff;
7494			offset = mbs.param[3] >> 8;
7495			sdp->isp_devparam[tgt].actv_flags = flags;
7496			sdp->isp_devparam[tgt].actv_period = period;
7497			sdp->isp_devparam[tgt].actv_offset = offset;
7498			isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, chan, tgt);
7499		}
7500	}
7501
7502	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7503		if (sdp->isp_devparam[tgt].dev_update ||
7504		    sdp->isp_devparam[tgt].dev_refresh) {
7505			sdp->update = 1;
7506			break;
7507		}
7508	}
7509}
7510
7511static void
7512isp_setdfltsdparm(ispsoftc_t *isp)
7513{
7514	int tgt;
7515	sdparam *sdp, *sdp1;
7516
7517	sdp = SDPARAM(isp, 0);
7518	sdp->role = GET_DEFAULT_ROLE(isp, 0);
7519	if (IS_DUALBUS(isp)) {
7520		sdp1 = sdp + 1;
7521		sdp1->role = GET_DEFAULT_ROLE(isp, 1);
7522	} else {
7523		sdp1 = NULL;
7524	}
7525
7526	/*
7527	 * Establish some default parameters.
7528	 */
7529	sdp->isp_cmd_dma_burst_enable = 0;
7530	sdp->isp_data_dma_burst_enabl = 1;
7531	sdp->isp_fifo_threshold = 0;
7532	sdp->isp_initiator_id = DEFAULT_IID(isp, 0);
7533	if (isp->isp_type >= ISP_HA_SCSI_1040) {
7534		sdp->isp_async_data_setup = 9;
7535	} else {
7536		sdp->isp_async_data_setup = 6;
7537	}
7538	sdp->isp_selection_timeout = 250;
7539	sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
7540	sdp->isp_tag_aging = 8;
7541	sdp->isp_bus_reset_delay = 5;
7542	/*
7543	 * Don't retry selection, busy or queue full automatically- reflect
7544	 * these back to us.
7545	 */
7546	sdp->isp_retry_count = 0;
7547	sdp->isp_retry_delay = 0;
7548
7549	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7550		sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
7551		sdp->isp_devparam[tgt].dev_enable = 1;
7552	}
7553
7554	/*
7555	 * The trick here is to establish a default for the default (honk!)
7556	 * state (goal_flags). Then try and get the current status from
7557	 * the card to fill in the current state. We don't, in fact, set
7558	 * the default to the SAFE default state- that's not the goal state.
7559	 */
7560	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7561		uint8_t off, per;
7562		sdp->isp_devparam[tgt].actv_offset = 0;
7563		sdp->isp_devparam[tgt].actv_period = 0;
7564		sdp->isp_devparam[tgt].actv_flags = 0;
7565
7566		sdp->isp_devparam[tgt].goal_flags =
7567		    sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
7568
7569		/*
7570		 * We default to Wide/Fast for versions less than a 1040
7571		 * (unless it's SBus).
7572		 */
7573		if (IS_ULTRA3(isp)) {
7574			off = ISP_80M_SYNCPARMS >> 8;
7575			per = ISP_80M_SYNCPARMS & 0xff;
7576		} else if (IS_ULTRA2(isp)) {
7577			off = ISP_40M_SYNCPARMS >> 8;
7578			per = ISP_40M_SYNCPARMS & 0xff;
7579		} else if (IS_1240(isp)) {
7580			off = ISP_20M_SYNCPARMS >> 8;
7581			per = ISP_20M_SYNCPARMS & 0xff;
7582		} else if ((isp->isp_bustype == ISP_BT_SBUS &&
7583		    isp->isp_type < ISP_HA_SCSI_1020A) ||
7584		    (isp->isp_bustype == ISP_BT_PCI &&
7585		    isp->isp_type < ISP_HA_SCSI_1040) ||
7586		    (isp->isp_clock && isp->isp_clock < 60) ||
7587		    (sdp->isp_ultramode == 0)) {
7588			off = ISP_10M_SYNCPARMS >> 8;
7589			per = ISP_10M_SYNCPARMS & 0xff;
7590		} else {
7591			off = ISP_20M_SYNCPARMS_1040 >> 8;
7592			per = ISP_20M_SYNCPARMS_1040 & 0xff;
7593		}
7594		sdp->isp_devparam[tgt].goal_offset =
7595		    sdp->isp_devparam[tgt].nvrm_offset = off;
7596		sdp->isp_devparam[tgt].goal_period =
7597		    sdp->isp_devparam[tgt].nvrm_period = per;
7598
7599	}
7600
7601	/*
7602	 * If we're a dual bus card, just copy the data over
7603	 */
7604	if (sdp1) {
7605		*sdp1 = *sdp;
7606		sdp1->isp_initiator_id = DEFAULT_IID(isp, 1);
7607	}
7608
7609	/*
7610	 * If we've not been told to avoid reading NVRAM, try and read it.
7611	 * If we're successful reading it, we can then return because NVRAM
7612	 * will tell us what the desired settings are. Otherwise, we establish
7613	 * some reasonable 'fake' nvram and goal defaults.
7614	 */
7615	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7616		mbreg_t mbs;
7617
7618		if (isp_read_nvram(isp, 0) == 0) {
7619			if (IS_DUALBUS(isp)) {
7620				if (isp_read_nvram(isp, 1) == 0) {
7621					return;
7622				}
7623			}
7624		}
7625		MBSINIT(&mbs, MBOX_GET_ACT_NEG_STATE, MBLOGNONE, 0);
7626		isp_mboxcmd(isp, &mbs);
7627		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7628			sdp->isp_req_ack_active_neg = 1;
7629			sdp->isp_data_line_active_neg = 1;
7630			if (sdp1) {
7631				sdp1->isp_req_ack_active_neg = 1;
7632				sdp1->isp_data_line_active_neg = 1;
7633			}
7634		} else {
7635			sdp->isp_req_ack_active_neg =
7636			    (mbs.param[1] >> 4) & 0x1;
7637			sdp->isp_data_line_active_neg =
7638			    (mbs.param[1] >> 5) & 0x1;
7639			if (sdp1) {
7640				sdp1->isp_req_ack_active_neg =
7641				    (mbs.param[2] >> 4) & 0x1;
7642				sdp1->isp_data_line_active_neg =
7643				    (mbs.param[2] >> 5) & 0x1;
7644			}
7645		}
7646	}
7647
7648}
7649
7650static void
7651isp_setdfltfcparm(ispsoftc_t *isp, int chan)
7652{
7653	fcparam *fcp = FCPARAM(isp, chan);
7654
7655	/*
7656	 * Establish some default parameters.
7657	 */
7658	fcp->role = GET_DEFAULT_ROLE(isp, chan);
7659	fcp->isp_maxalloc = ICB_DFLT_ALLOC;
7660	fcp->isp_retry_delay = ICB_DFLT_RDELAY;
7661	fcp->isp_retry_count = ICB_DFLT_RCOUNT;
7662	fcp->isp_loopid = DEFAULT_LOOPID(isp, chan);
7663	fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan);
7664	fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan);
7665	fcp->isp_fwoptions = 0;
7666	fcp->isp_lasthdl = NIL_HANDLE;
7667
7668	if (IS_24XX(isp)) {
7669		fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS;
7670		fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS;
7671		if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
7672			fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX;
7673		}
7674		fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS;
7675	} else {
7676		fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
7677		fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
7678		fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
7679		fcp->isp_fwoptions |= ICBOPT_FAST_POST;
7680		if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
7681			fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
7682		}
7683		/*
7684		 * Make sure this is turned off now until we get
7685		 * extended options from NVRAM
7686		 */
7687		fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
7688	}
7689
7690
7691	/*
7692	 * Now try and read NVRAM unless told to not do so.
7693	 * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
7694	 */
7695	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7696		int i, j = 0;
7697		/*
7698		 * Give a couple of tries at reading NVRAM.
7699		 */
7700		for (i = 0; i < 2; i++) {
7701			j = isp_read_nvram(isp, chan);
7702			if (j == 0) {
7703				break;
7704			}
7705		}
7706		if (j) {
7707			isp->isp_confopts |= ISP_CFG_NONVRAM;
7708		}
7709	}
7710
7711	fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan);
7712	fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan);
7713	isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s",
7714	    chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn),
7715	    (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn),
7716	    isp_class3_roles[fcp->role]);
7717}
7718
7719/*
7720 * Re-initialize the ISP and complete all orphaned commands
7721 * with a 'botched' notice. The reset/init routines should
7722 * not disturb an already active list of commands.
7723 */
7724
7725void
7726isp_reinit(ispsoftc_t *isp, int do_load_defaults)
7727{
7728	int i;
7729
7730	isp_reset(isp, do_load_defaults);
7731
7732	if (isp->isp_state != ISP_RESETSTATE) {
7733		isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
7734		ISP_DISABLE_INTS(isp);
7735		goto cleanup;
7736	}
7737
7738	isp_init(isp);
7739
7740	if (isp->isp_state == ISP_INITSTATE) {
7741		isp->isp_state = ISP_RUNSTATE;
7742	}
7743
7744	if (isp->isp_state != ISP_RUNSTATE) {
7745#ifndef	ISP_TARGET_MODE
7746		isp_prt(isp, ISP_LOGWARN, "%s: not at runstate", __func__);
7747#endif
7748		ISP_DISABLE_INTS(isp);
7749		if (IS_FC(isp)) {
7750			/*
7751			 * If we're in ISP_ROLE_NONE, turn off the lasers.
7752			 */
7753			if (!IS_24XX(isp)) {
7754				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
7755				ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
7756				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
7757				ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
7758				ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
7759			}
7760		}
7761 	}
7762
7763 cleanup:
7764
7765	isp->isp_nactive = 0;
7766
7767	isp_clear_commands(isp);
7768	if (IS_FC(isp)) {
7769		for (i = 0; i < isp->isp_nchan; i++) {
7770			ISP_MARK_PORTDB(isp, i, -1);
7771		}
7772	}
7773}
7774
7775/*
7776 * NVRAM Routines
7777 */
7778static int
7779isp_read_nvram(ispsoftc_t *isp, int bus)
7780{
7781	int i, amt, retval;
7782	uint8_t csum, minversion;
7783	union {
7784		uint8_t _x[ISP2400_NVRAM_SIZE];
7785		uint16_t _s[ISP2400_NVRAM_SIZE>>1];
7786	} _n;
7787#define	nvram_data	_n._x
7788#define	nvram_words	_n._s
7789
7790	if (IS_24XX(isp)) {
7791		return (isp_read_nvram_2400(isp, nvram_data));
7792	} else if (IS_FC(isp)) {
7793		amt = ISP2100_NVRAM_SIZE;
7794		minversion = 1;
7795	} else if (IS_ULTRA2(isp)) {
7796		amt = ISP1080_NVRAM_SIZE;
7797		minversion = 0;
7798	} else {
7799		amt = ISP_NVRAM_SIZE;
7800		minversion = 2;
7801	}
7802
7803	for (i = 0; i < amt>>1; i++) {
7804		isp_rdnvram_word(isp, i, &nvram_words[i]);
7805	}
7806
7807	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7808	    nvram_data[2] != 'P') {
7809		if (isp->isp_bustype != ISP_BT_SBUS) {
7810			isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
7811			isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x",
7812			    nvram_data[0], nvram_data[1], nvram_data[2]);
7813		}
7814		retval = -1;
7815		goto out;
7816	}
7817
7818	for (csum = 0, i = 0; i < amt; i++) {
7819		csum += nvram_data[i];
7820	}
7821	if (csum != 0) {
7822		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7823		retval = -1;
7824		goto out;
7825	}
7826
7827	if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
7828		isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
7829		    ISP_NVRAM_VERSION(nvram_data));
7830		retval = -1;
7831		goto out;
7832	}
7833
7834	if (IS_ULTRA3(isp)) {
7835		isp_parse_nvram_12160(isp, bus, nvram_data);
7836	} else if (IS_1080(isp)) {
7837		isp_parse_nvram_1080(isp, bus, nvram_data);
7838	} else if (IS_1280(isp) || IS_1240(isp)) {
7839		isp_parse_nvram_1080(isp, bus, nvram_data);
7840	} else if (IS_SCSI(isp)) {
7841		isp_parse_nvram_1020(isp, nvram_data);
7842	} else {
7843		isp_parse_nvram_2100(isp, nvram_data);
7844	}
7845	retval = 0;
7846out:
7847	return (retval);
7848#undef	nvram_data
7849#undef	nvram_words
7850}
7851
7852static int
7853isp_read_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
7854{
7855	int retval = 0;
7856	uint32_t addr, csum, lwrds, *dptr;
7857
7858	if (isp->isp_port) {
7859		addr = ISP2400_NVRAM_PORT1_ADDR;
7860	} else {
7861		addr = ISP2400_NVRAM_PORT0_ADDR;
7862	}
7863
7864	dptr = (uint32_t *) nvram_data;
7865	for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7866		isp_rd_2400_nvram(isp, addr++, dptr++);
7867	}
7868	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7869	    nvram_data[2] != 'P') {
7870		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
7871		    nvram_data[0], nvram_data[1], nvram_data[2]);
7872		retval = -1;
7873		goto out;
7874	}
7875	dptr = (uint32_t *) nvram_data;
7876	for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7877		uint32_t tmp;
7878		ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
7879		csum += tmp;
7880	}
7881	if (csum != 0) {
7882		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7883		retval = -1;
7884		goto out;
7885	}
7886	isp_parse_nvram_2400(isp, nvram_data);
7887out:
7888	return (retval);
7889}
7890
7891static void
7892isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
7893{
7894	int i, cbits;
7895	uint16_t bit, rqst, junk;
7896
7897	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7898	ISP_DELAY(10);
7899	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7900	ISP_DELAY(10);
7901
7902	if (IS_FC(isp)) {
7903		wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
7904		if (IS_2312(isp) && isp->isp_port) {
7905			wo += 128;
7906		}
7907		rqst = (ISP_NVRAM_READ << 8) | wo;
7908		cbits = 10;
7909	} else if (IS_ULTRA2(isp)) {
7910		wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
7911		rqst = (ISP_NVRAM_READ << 8) | wo;
7912		cbits = 10;
7913	} else {
7914		wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
7915		rqst = (ISP_NVRAM_READ << 6) | wo;
7916		cbits = 8;
7917	}
7918
7919	/*
7920	 * Clock the word select request out...
7921	 */
7922	for (i = cbits; i >= 0; i--) {
7923		if ((rqst >> i) & 1) {
7924			bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
7925		} else {
7926			bit = BIU_NVRAM_SELECT;
7927		}
7928		ISP_WRITE(isp, BIU_NVRAM, bit);
7929		ISP_DELAY(10);
7930		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7931		ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
7932		ISP_DELAY(10);
7933		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7934		ISP_WRITE(isp, BIU_NVRAM, bit);
7935		ISP_DELAY(10);
7936		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7937	}
7938	/*
7939	 * Now read the result back in (bits come back in MSB format).
7940	 */
7941	*rp = 0;
7942	for (i = 0; i < 16; i++) {
7943		uint16_t rv;
7944		*rp <<= 1;
7945		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7946		ISP_DELAY(10);
7947		rv = ISP_READ(isp, BIU_NVRAM);
7948		if (rv & BIU_NVRAM_DATAIN) {
7949			*rp |= 1;
7950		}
7951		ISP_DELAY(10);
7952		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7953		ISP_DELAY(10);
7954		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7955	}
7956	ISP_WRITE(isp, BIU_NVRAM, 0);
7957	ISP_DELAY(10);
7958	junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7959	ISP_SWIZZLE_NVRAM_WORD(isp, rp);
7960}
7961
7962static void
7963isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
7964{
7965	int loops = 0;
7966	uint32_t base = 0x7ffe0000;
7967	uint32_t tmp = 0;
7968
7969	if (IS_25XX(isp)) {
7970		base = 0x7ff00000 | 0x48000;
7971	}
7972	ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
7973	for (loops = 0; loops < 5000; loops++) {
7974		ISP_DELAY(10);
7975		tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
7976		if ((tmp & (1U << 31)) != 0) {
7977			break;
7978		}
7979	}
7980	if (tmp & (1U << 31)) {
7981		*rp = ISP_READ(isp, BIU2400_FLASH_DATA);
7982		ISP_SWIZZLE_NVRAM_LONG(isp, rp);
7983	} else {
7984		*rp = 0xffffffff;
7985	}
7986}
7987
7988static void
7989isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data)
7990{
7991	sdparam *sdp = SDPARAM(isp, 0);
7992	int tgt;
7993
7994	sdp->isp_fifo_threshold =
7995		ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
7996		(ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
7997
7998	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
7999		sdp->isp_initiator_id =
8000			ISP_NVRAM_INITIATOR_ID(nvram_data);
8001
8002	sdp->isp_bus_reset_delay =
8003		ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
8004
8005	sdp->isp_retry_count =
8006		ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
8007
8008	sdp->isp_retry_delay =
8009		ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
8010
8011	sdp->isp_async_data_setup =
8012		ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
8013
8014	if (isp->isp_type >= ISP_HA_SCSI_1040) {
8015		if (sdp->isp_async_data_setup < 9) {
8016			sdp->isp_async_data_setup = 9;
8017		}
8018	} else {
8019		if (sdp->isp_async_data_setup != 6) {
8020			sdp->isp_async_data_setup = 6;
8021		}
8022	}
8023
8024	sdp->isp_req_ack_active_neg =
8025		ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
8026
8027	sdp->isp_data_line_active_neg =
8028		ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
8029
8030	sdp->isp_data_dma_burst_enabl =
8031		ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
8032
8033	sdp->isp_cmd_dma_burst_enable =
8034		ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
8035
8036	sdp->isp_tag_aging =
8037		ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
8038
8039	sdp->isp_selection_timeout =
8040		ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
8041
8042	sdp->isp_max_queue_depth =
8043		ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
8044
8045	sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
8046
8047	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
8048		sdp->isp_devparam[tgt].dev_enable =
8049			ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
8050		sdp->isp_devparam[tgt].exc_throttle =
8051			ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
8052		sdp->isp_devparam[tgt].nvrm_offset =
8053			ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
8054		sdp->isp_devparam[tgt].nvrm_period =
8055			ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
8056		/*
8057		 * We probably shouldn't lie about this, but it
8058		 * it makes it much safer if we limit NVRAM values
8059		 * to sanity.
8060		 */
8061		if (isp->isp_type < ISP_HA_SCSI_1040) {
8062			/*
8063			 * If we're not ultra, we can't possibly
8064			 * be a shorter period than this.
8065			 */
8066			if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
8067				sdp->isp_devparam[tgt].nvrm_period = 0x19;
8068			}
8069			if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
8070				sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
8071			}
8072		} else {
8073			if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
8074				sdp->isp_devparam[tgt].nvrm_offset = 0x8;
8075			}
8076		}
8077		sdp->isp_devparam[tgt].nvrm_flags = 0;
8078		if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
8079			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8080		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8081		if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
8082			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8083		if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
8084			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8085		if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
8086			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8087		if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
8088			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8089		if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
8090			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8091		sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
8092		sdp->isp_devparam[tgt].goal_offset =
8093		    sdp->isp_devparam[tgt].nvrm_offset;
8094		sdp->isp_devparam[tgt].goal_period =
8095		    sdp->isp_devparam[tgt].nvrm_period;
8096		sdp->isp_devparam[tgt].goal_flags =
8097		    sdp->isp_devparam[tgt].nvrm_flags;
8098	}
8099}
8100
8101static void
8102isp_parse_nvram_1080(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
8103{
8104	sdparam *sdp = SDPARAM(isp, bus);
8105	int tgt;
8106
8107	sdp->isp_fifo_threshold =
8108	    ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
8109
8110	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
8111		sdp->isp_initiator_id =
8112		    ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
8113
8114	sdp->isp_bus_reset_delay =
8115	    ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
8116
8117	sdp->isp_retry_count =
8118	    ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
8119
8120	sdp->isp_retry_delay =
8121	    ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
8122
8123	sdp->isp_async_data_setup =
8124	    ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
8125
8126	sdp->isp_req_ack_active_neg =
8127	    ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
8128
8129	sdp->isp_data_line_active_neg =
8130	    ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
8131
8132	sdp->isp_data_dma_burst_enabl =
8133	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
8134
8135	sdp->isp_cmd_dma_burst_enable =
8136	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
8137
8138	sdp->isp_selection_timeout =
8139	    ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
8140
8141	sdp->isp_max_queue_depth =
8142	     ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
8143
8144	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
8145		sdp->isp_devparam[tgt].dev_enable =
8146		    ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
8147		sdp->isp_devparam[tgt].exc_throttle =
8148			ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
8149		sdp->isp_devparam[tgt].nvrm_offset =
8150			ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
8151		sdp->isp_devparam[tgt].nvrm_period =
8152			ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
8153		sdp->isp_devparam[tgt].nvrm_flags = 0;
8154		if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
8155			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8156		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8157		if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
8158			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8159		if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
8160			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8161		if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
8162			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8163		if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
8164			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8165		if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
8166			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8167		sdp->isp_devparam[tgt].actv_flags = 0;
8168		sdp->isp_devparam[tgt].goal_offset =
8169		    sdp->isp_devparam[tgt].nvrm_offset;
8170		sdp->isp_devparam[tgt].goal_period =
8171		    sdp->isp_devparam[tgt].nvrm_period;
8172		sdp->isp_devparam[tgt].goal_flags =
8173		    sdp->isp_devparam[tgt].nvrm_flags;
8174	}
8175}
8176
8177static void
8178isp_parse_nvram_12160(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
8179{
8180	sdparam *sdp = SDPARAM(isp, bus);
8181	int tgt;
8182
8183	sdp->isp_fifo_threshold =
8184	    ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
8185
8186	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
8187		sdp->isp_initiator_id =
8188		    ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
8189
8190	sdp->isp_bus_reset_delay =
8191	    ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
8192
8193	sdp->isp_retry_count =
8194	    ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
8195
8196	sdp->isp_retry_delay =
8197	    ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
8198
8199	sdp->isp_async_data_setup =
8200	    ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
8201
8202	sdp->isp_req_ack_active_neg =
8203	    ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
8204
8205	sdp->isp_data_line_active_neg =
8206	    ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
8207
8208	sdp->isp_data_dma_burst_enabl =
8209	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
8210
8211	sdp->isp_cmd_dma_burst_enable =
8212	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
8213
8214	sdp->isp_selection_timeout =
8215	    ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
8216
8217	sdp->isp_max_queue_depth =
8218	     ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
8219
8220	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
8221		sdp->isp_devparam[tgt].dev_enable =
8222		    ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
8223		sdp->isp_devparam[tgt].exc_throttle =
8224			ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
8225		sdp->isp_devparam[tgt].nvrm_offset =
8226			ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
8227		sdp->isp_devparam[tgt].nvrm_period =
8228			ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
8229		sdp->isp_devparam[tgt].nvrm_flags = 0;
8230		if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
8231			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8232		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8233		if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
8234			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8235		if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
8236			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8237		if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
8238			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8239		if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
8240			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8241		if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
8242			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8243		sdp->isp_devparam[tgt].actv_flags = 0;
8244		sdp->isp_devparam[tgt].goal_offset =
8245		    sdp->isp_devparam[tgt].nvrm_offset;
8246		sdp->isp_devparam[tgt].goal_period =
8247		    sdp->isp_devparam[tgt].nvrm_period;
8248		sdp->isp_devparam[tgt].goal_flags =
8249		    sdp->isp_devparam[tgt].nvrm_flags;
8250	}
8251}
8252
8253static void
8254isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
8255{
8256	fcparam *fcp = FCPARAM(isp, 0);
8257	uint64_t wwn;
8258
8259	/*
8260	 * There is NVRAM storage for both Port and Node entities-
8261	 * but the Node entity appears to be unused on all the cards
8262	 * I can find. However, we should account for this being set
8263	 * at some point in the future.
8264	 *
8265	 * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
8266	 * bits 48..60. In the case of the 2202, it appears that they do
8267	 * use bit 48 to distinguish between the two instances on the card.
8268	 * The 2204, which I've never seen, *probably* extends this method.
8269	 */
8270	wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
8271	if (wwn) {
8272		isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
8273		    (uint32_t) (wwn >> 32), (uint32_t) (wwn));
8274		if ((wwn >> 60) == 0) {
8275			wwn |= (((uint64_t) 2)<< 60);
8276		}
8277	}
8278	fcp->isp_wwpn_nvram = wwn;
8279	if (IS_2200(isp) || IS_23XX(isp)) {
8280		wwn = ISP2100_NVRAM_NODE_NAME(nvram_data);
8281		if (wwn) {
8282			isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
8283			    (uint32_t) (wwn >> 32),
8284			    (uint32_t) (wwn));
8285			if ((wwn >> 60) == 0) {
8286				wwn |= (((uint64_t) 2)<< 60);
8287			}
8288		} else {
8289			wwn = fcp->isp_wwpn_nvram & ~((uint64_t) 0xfff << 48);
8290		}
8291	} else {
8292		wwn &= ~((uint64_t) 0xfff << 48);
8293	}
8294	fcp->isp_wwnn_nvram = wwn;
8295
8296	fcp->isp_maxalloc = ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
8297	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
8298		DEFAULT_FRAMESIZE(isp) =
8299		    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
8300	}
8301	fcp->isp_retry_delay = ISP2100_NVRAM_RETRY_DELAY(nvram_data);
8302	fcp->isp_retry_count = ISP2100_NVRAM_RETRY_COUNT(nvram_data);
8303	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
8304		fcp->isp_loopid = ISP2100_NVRAM_HARDLOOPID(nvram_data);
8305	}
8306	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
8307		DEFAULT_EXEC_THROTTLE(isp) =
8308			ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
8309	}
8310	fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
8311	isp_prt(isp, ISP_LOGDEBUG0,
8312	    "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d",
8313	    (uint32_t) (fcp->isp_wwnn_nvram >> 32),
8314	    (uint32_t) fcp->isp_wwnn_nvram,
8315	    (uint32_t) (fcp->isp_wwpn_nvram >> 32),
8316	    (uint32_t) fcp->isp_wwpn_nvram,
8317	    ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data),
8318	    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data));
8319	isp_prt(isp, ISP_LOGDEBUG0,
8320	    "execthrottle %d fwoptions 0x%x hardloop %d tov %d",
8321	    ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
8322	    ISP2100_NVRAM_OPTIONS(nvram_data),
8323	    ISP2100_NVRAM_HARDLOOPID(nvram_data),
8324	    ISP2100_NVRAM_TOV(nvram_data));
8325	fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data);
8326	fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data);
8327	isp_prt(isp, ISP_LOGDEBUG0,
8328	    "xfwoptions 0x%x zfw options 0x%x",
8329	    ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data));
8330}
8331
8332static void
8333isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
8334{
8335	fcparam *fcp = FCPARAM(isp, 0);
8336	uint64_t wwn;
8337
8338	isp_prt(isp, ISP_LOGDEBUG0,
8339	    "NVRAM 0x%08x%08x 0x%08x%08x exchg_cnt %d maxframelen %d",
8340	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
8341	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
8342	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
8343	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
8344	    ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data),
8345	    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
8346	isp_prt(isp, ISP_LOGDEBUG0,
8347	    "NVRAM execthr %d loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
8348	    ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data),
8349	    ISP2400_NVRAM_HARDLOOPID(nvram_data),
8350	    ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
8351	    ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
8352	    ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
8353
8354	wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
8355	fcp->isp_wwpn_nvram = wwn;
8356
8357	wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
8358	if (wwn) {
8359		if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
8360			wwn = 0;
8361		}
8362	}
8363	if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) {
8364		wwn = fcp->isp_wwpn_nvram;
8365		wwn &= ~((uint64_t) 0xfff << 48);
8366	}
8367	fcp->isp_wwnn_nvram = wwn;
8368
8369	if (ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data)) {
8370		fcp->isp_maxalloc = ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data);
8371	}
8372	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
8373		DEFAULT_FRAMESIZE(isp) =
8374		    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
8375	}
8376	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
8377		fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
8378	}
8379	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
8380		DEFAULT_EXEC_THROTTLE(isp) =
8381			ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data);
8382	}
8383	fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
8384	fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
8385	fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
8386}
8387