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