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