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