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