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