isp.c revision 171014
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 171014 2007-06-24 01:41:16Z 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					ISP_IOXPUT_32(isp,  ptr[wi++], &cp[i]);
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					ISP_IOXPUT_16(isp,  ptr[wi++], &cp[i]);
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- hdlidx 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 IMPLEMENTED");
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 IMPLEMENTED");
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 IMPLEMENTED");
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		/*
5125		 * It's up to the handler for isp_async to reinit stuff and
5126		 * restart the firmware
5127		 */
5128		isp_async(isp, ISPASYNC_FW_CRASH, NULL);
5129		rval = -1;
5130		break;
5131
5132	case ASYNC_RQS_XFER_ERR:
5133		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
5134		break;
5135
5136	case ASYNC_RSP_XFER_ERR:
5137		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
5138		break;
5139
5140	case ASYNC_QWAKEUP:
5141		/*
5142		 * We've just been notified that the Queue has woken up.
5143		 * We don't need to be chatty about this- just unlatch things
5144		 * and move on.
5145		 */
5146		mbox = ISP_READ(isp, isp->isp_rqstoutrp);
5147		break;
5148
5149	case ASYNC_TIMEOUT_RESET:
5150		isp_prt(isp, ISP_LOGWARN,
5151		    "timeout initiated SCSI bus reset of bus %d", bus);
5152		isp->isp_sendmarker |= (1 << bus);
5153#ifdef	ISP_TARGET_MODE
5154		if (isp_target_async(isp, bus, mbox)) {
5155			rval = -1;
5156		}
5157#endif
5158		break;
5159
5160	case ASYNC_DEVICE_RESET:
5161		isp_prt(isp, ISP_LOGINFO, "device reset on bus %d", bus);
5162		isp->isp_sendmarker |= (1 << bus);
5163#ifdef	ISP_TARGET_MODE
5164		if (isp_target_async(isp, bus, mbox)) {
5165			rval = -1;
5166		}
5167#endif
5168		break;
5169
5170	case ASYNC_EXTMSG_UNDERRUN:
5171		isp_prt(isp, ISP_LOGWARN, "extended message underrun");
5172		break;
5173
5174	case ASYNC_SCAM_INT:
5175		isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
5176		break;
5177
5178	case ASYNC_HUNG_SCSI:
5179		isp_prt(isp, ISP_LOGERR,
5180		    "stalled SCSI Bus after DATA Overrun");
5181		/* XXX: Need to issue SCSI reset at this point */
5182		break;
5183
5184	case ASYNC_KILLED_BUS:
5185		isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
5186		break;
5187
5188	case ASYNC_BUS_TRANSIT:
5189		mbox = ISP_READ(isp, OUTMAILBOX2);
5190		switch (mbox & 0x1c00) {
5191		case SXP_PINS_LVD_MODE:
5192			isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
5193			SDPARAM(isp)->isp_diffmode = 0;
5194			SDPARAM(isp)->isp_ultramode = 0;
5195			SDPARAM(isp)->isp_lvdmode = 1;
5196			break;
5197		case SXP_PINS_HVD_MODE:
5198			isp_prt(isp, ISP_LOGINFO,
5199			    "Transition to Differential mode");
5200			SDPARAM(isp)->isp_diffmode = 1;
5201			SDPARAM(isp)->isp_ultramode = 0;
5202			SDPARAM(isp)->isp_lvdmode = 0;
5203			break;
5204		case SXP_PINS_SE_MODE:
5205			isp_prt(isp, ISP_LOGINFO,
5206			    "Transition to Single Ended mode");
5207			SDPARAM(isp)->isp_diffmode = 0;
5208			SDPARAM(isp)->isp_ultramode = 1;
5209			SDPARAM(isp)->isp_lvdmode = 0;
5210			break;
5211		default:
5212			isp_prt(isp, ISP_LOGWARN,
5213			    "Transition to Unknown Mode 0x%x", mbox);
5214			break;
5215		}
5216		/*
5217		 * XXX: Set up to renegotiate again!
5218		 */
5219		/* Can only be for a 1080... */
5220		isp->isp_sendmarker |= (1 << bus);
5221		break;
5222
5223	/*
5224	 * We can use bus, which will always be zero for FC cards,
5225	 * as a mailbox pattern accumulator to be checked below.
5226	 */
5227	case ASYNC_RIO5:
5228		bus = 0x1ce;	/* outgoing mailbox regs 1-3, 6-7 */
5229		break;
5230
5231	case ASYNC_RIO4:
5232		bus = 0x14e;	/* outgoing mailbox regs 1-3, 6 */
5233		break;
5234
5235	case ASYNC_RIO3:
5236		bus = 0x10e;	/* outgoing mailbox regs 1-3 */
5237		break;
5238
5239	case ASYNC_RIO2:
5240		bus = 0x106;	/* outgoing mailbox regs 1-2 */
5241		break;
5242
5243	case ASYNC_RIO1:
5244	case ASYNC_CMD_CMPLT:
5245		bus = 0x102;	/* outgoing mailbox regs 1 */
5246		break;
5247
5248	case ASYNC_RIO_RESP:
5249		return (rval);
5250
5251	case ASYNC_CTIO_DONE:
5252	{
5253#ifdef	ISP_TARGET_MODE
5254		int handle =
5255		    (ISP_READ(isp, OUTMAILBOX2) << 16) |
5256		    (ISP_READ(isp, OUTMAILBOX1));
5257		if (isp_target_async(isp, handle, mbox)) {
5258			rval = -1;
5259		} else {
5260			/* count it as a fast posting intr */
5261			isp->isp_fphccmplt++;
5262		}
5263#else
5264		isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
5265		isp->isp_fphccmplt++;	/* count it as a fast posting intr */
5266#endif
5267		break;
5268	}
5269	case ASYNC_LIP_ERROR:
5270	case ASYNC_LIP_F8:
5271	case ASYNC_LIP_OCCURRED:
5272		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
5273		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
5274		isp->isp_sendmarker = 1;
5275		ISP_MARK_PORTDB(isp, 1);
5276		isp_async(isp, ISPASYNC_LIP, NULL);
5277#ifdef	ISP_TARGET_MODE
5278		if (isp_target_async(isp, bus, mbox)) {
5279			rval = -1;
5280		}
5281#endif
5282		/*
5283		 * We've had problems with data corruption occuring on
5284		 * commands that complete (with no apparent error) after
5285		 * we receive a LIP. This has been observed mostly on
5286		 * Local Loop topologies. To be safe, let's just mark
5287		 * all active commands as dead.
5288		 */
5289		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
5290		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
5291			int i, j;
5292			for (i = j = 0; i < isp->isp_maxcmds; i++) {
5293				XS_T *xs;
5294				xs = isp->isp_xflist[i];
5295				if (xs != NULL) {
5296					j++;
5297					XS_SETERR(xs, HBA_BUSRESET);
5298				}
5299			}
5300			if (j) {
5301				isp_prt(isp, ISP_LOGERR,
5302				    "LIP destroyed %d active commands", j);
5303			}
5304		}
5305		break;
5306
5307	case ASYNC_LOOP_UP:
5308		isp->isp_sendmarker = 1;
5309		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
5310		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
5311		ISP_MARK_PORTDB(isp, 1);
5312		isp_async(isp, ISPASYNC_LOOP_UP, NULL);
5313#ifdef	ISP_TARGET_MODE
5314		if (isp_target_async(isp, bus, mbox)) {
5315			rval = -1;
5316		}
5317#endif
5318		break;
5319
5320	case ASYNC_LOOP_DOWN:
5321		isp->isp_sendmarker = 1;
5322		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
5323		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
5324		ISP_MARK_PORTDB(isp, 1);
5325		isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
5326#ifdef	ISP_TARGET_MODE
5327		if (isp_target_async(isp, bus, mbox)) {
5328			rval = -1;
5329		}
5330#endif
5331		break;
5332
5333	case ASYNC_LOOP_RESET:
5334		isp->isp_sendmarker = 1;
5335		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
5336		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
5337		ISP_MARK_PORTDB(isp, 1);
5338		isp_async(isp, ISPASYNC_LOOP_RESET, NULL);
5339#ifdef	ISP_TARGET_MODE
5340		if (isp_target_async(isp, bus, mbox)) {
5341			rval = -1;
5342		}
5343#endif
5344		break;
5345
5346	case ASYNC_PDB_CHANGED:
5347		isp->isp_sendmarker = 1;
5348		FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
5349		ISP_MARK_PORTDB(isp, 1);
5350		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_PDB);
5351		break;
5352
5353	case ASYNC_CHANGE_NOTIFY:
5354	    	if (FCPARAM(isp)->isp_topo == TOPO_F_PORT) {
5355			FCPARAM(isp)->isp_loopstate = LOOP_LSCAN_DONE;
5356		} else {
5357			FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
5358		}
5359		ISP_MARK_PORTDB(isp, 1);
5360		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_SNS);
5361		break;
5362
5363	case ASYNC_PTPMODE:
5364		ISP_MARK_PORTDB(isp, 1);
5365		isp->isp_sendmarker = 1;
5366		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
5367		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
5368		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
5369#ifdef	ISP_TARGET_MODE
5370		if (isp_target_async(isp, bus, mbox)) {
5371			rval = -1;
5372		}
5373#endif
5374		isp_prt(isp, ISP_LOGINFO, "Point-to-Point mode");
5375		break;
5376
5377	case ASYNC_CONNMODE:
5378		mbox = ISP_READ(isp, OUTMAILBOX1);
5379		ISP_MARK_PORTDB(isp, 1);
5380		switch (mbox) {
5381		case ISP_CONN_LOOP:
5382			isp_prt(isp, ISP_LOGINFO,
5383			    "Point-to-Point -> Loop mode");
5384			break;
5385		case ISP_CONN_PTP:
5386			isp_prt(isp, ISP_LOGINFO,
5387			    "Loop -> Point-to-Point mode");
5388			break;
5389		case ISP_CONN_BADLIP:
5390			isp_prt(isp, ISP_LOGWARN,
5391			    "Point-to-Point -> Loop mode (BAD LIP)");
5392			break;
5393		case ISP_CONN_FATAL:
5394			isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
5395			isp_async(isp, ISPASYNC_FW_CRASH, NULL);
5396			return (-1);
5397		case ISP_CONN_LOOPBACK:
5398			isp_prt(isp, ISP_LOGWARN,
5399			    "Looped Back in Point-to-Point mode");
5400			break;
5401		default:
5402			isp_prt(isp, ISP_LOGWARN,
5403			    "Unknown connection mode (0x%x)", mbox);
5404			break;
5405		}
5406		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
5407		isp->isp_sendmarker = 1;
5408		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
5409		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
5410		break;
5411
5412	case ASYNC_RJT_SENT:	/* same as ASYNC_QFULL_SENT */
5413		if (IS_24XX(isp)) {
5414			isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
5415			break;
5416		} else if (IS_2200(isp)) {
5417			isp_prt(isp, ISP_LOGTDEBUG0, "QFULL sent");
5418			break;
5419		}
5420		/* FALLTHROUGH */
5421	default:
5422		isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
5423		break;
5424	}
5425
5426	if (bus & 0x100) {
5427		int i, nh;
5428		uint16_t handles[16];
5429
5430		for (nh = 0, i = 1; i < MAX_MAILBOX(isp); i++) {
5431			if ((bus & (1 << i)) == 0) {
5432				continue;
5433			}
5434			handles[nh++] = ISP_READ(isp, MBOX_OFF(i));
5435		}
5436		for (i = 0; i < nh; i++) {
5437			isp_fastpost_complete(isp, handles[i]);
5438			isp_prt(isp,  ISP_LOGDEBUG3,
5439			    "fast post completion of %u", handles[i]);
5440		}
5441		if (isp->isp_fpcchiwater < nh) {
5442			isp->isp_fpcchiwater = nh;
5443		}
5444	} else {
5445		isp->isp_intoasync++;
5446	}
5447	return (rval);
5448}
5449
5450/*
5451 * Handle other response entries. A pointer to the request queue output
5452 * index is here in case we want to eat several entries at once, although
5453 * this is not used currently.
5454 */
5455
5456static int
5457isp_handle_other_response(ispsoftc_t *isp, int type,
5458    isphdr_t *hp, uint32_t *optrp)
5459{
5460	switch (type) {
5461	case RQSTYPE_STATUS_CONT:
5462		isp_prt(isp, ISP_LOGDEBUG0, "Ignored Continuation Response");
5463		return (1);
5464	case RQSTYPE_MARKER:
5465		isp_prt(isp, ISP_LOGDEBUG0, "Marker Response");
5466		return (1);
5467	case RQSTYPE_ATIO:
5468	case RQSTYPE_CTIO:
5469	case RQSTYPE_ENABLE_LUN:
5470	case RQSTYPE_MODIFY_LUN:
5471	case RQSTYPE_NOTIFY:
5472	case RQSTYPE_NOTIFY_ACK:
5473	case RQSTYPE_CTIO1:
5474	case RQSTYPE_ATIO2:
5475	case RQSTYPE_CTIO2:
5476	case RQSTYPE_CTIO3:
5477	case RQSTYPE_CTIO7:
5478	case RQSTYPE_ABTS_RCVD:
5479	case RQSTYPE_ABTS_RSP:
5480		isp->isp_rsltccmplt++;	/* count as a response completion */
5481#ifdef	ISP_TARGET_MODE
5482		if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
5483			return (1);
5484		}
5485#endif
5486		/* FALLTHROUGH */
5487	case RQSTYPE_REQUEST:
5488	default:
5489		USEC_DELAY(100);
5490		if (type != isp_get_response_type(isp, hp)) {
5491			/*
5492			 * This is questionable- we're just papering over
5493			 * something we've seen on SMP linux in target
5494			 * mode- we don't really know what's happening
5495			 * here that causes us to think we've gotten
5496			 * an entry, but that either the entry isn't
5497			 * filled out yet or our CPU read data is stale.
5498			 */
5499			isp_prt(isp, ISP_LOGINFO,
5500				"unstable type in response queue");
5501			return (-1);
5502		}
5503		isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
5504		    isp_get_response_type(isp, hp));
5505		if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) {
5506			return (1);
5507		}
5508		return (0);
5509	}
5510}
5511
5512static void
5513isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
5514{
5515	switch (sp->req_completion_status & 0xff) {
5516	case RQCS_COMPLETE:
5517		if (XS_NOERR(xs)) {
5518			XS_SETERR(xs, HBA_NOERROR);
5519		}
5520		return;
5521
5522	case RQCS_INCOMPLETE:
5523		if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
5524			isp_prt(isp, ISP_LOGDEBUG1,
5525			    "Selection Timeout for %d.%d.%d",
5526			    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5527			if (XS_NOERR(xs)) {
5528				XS_SETERR(xs, HBA_SELTIMEOUT);
5529				*rp = XS_XFRLEN(xs);
5530			}
5531			return;
5532		}
5533		isp_prt(isp, ISP_LOGERR,
5534		    "command incomplete for %d.%d.%d, state 0x%x",
5535		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
5536		    sp->req_state_flags);
5537		break;
5538
5539	case RQCS_DMA_ERROR:
5540		isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
5541		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5542		*rp = XS_XFRLEN(xs);
5543		break;
5544
5545	case RQCS_TRANSPORT_ERROR:
5546	{
5547		char buf[172];
5548		SNPRINTF(buf, sizeof (buf), "states=>");
5549		if (sp->req_state_flags & RQSF_GOT_BUS) {
5550			SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
5551		}
5552		if (sp->req_state_flags & RQSF_GOT_TARGET) {
5553			SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
5554		}
5555		if (sp->req_state_flags & RQSF_SENT_CDB) {
5556			SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
5557		}
5558		if (sp->req_state_flags & RQSF_XFRD_DATA) {
5559			SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
5560		}
5561		if (sp->req_state_flags & RQSF_GOT_STATUS) {
5562			SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
5563		}
5564		if (sp->req_state_flags & RQSF_GOT_SENSE) {
5565			SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
5566		}
5567		if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
5568			SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
5569		}
5570		SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
5571		if (sp->req_status_flags & RQSTF_DISCONNECT) {
5572			SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
5573		}
5574		if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
5575			SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
5576		}
5577		if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
5578			SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
5579		}
5580		if (sp->req_status_flags & RQSTF_BUS_RESET) {
5581			SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
5582		}
5583		if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
5584			SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
5585		}
5586		if (sp->req_status_flags & RQSTF_ABORTED) {
5587			SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
5588		}
5589		if (sp->req_status_flags & RQSTF_TIMEOUT) {
5590			SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
5591		}
5592		if (sp->req_status_flags & RQSTF_NEGOTIATION) {
5593			SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
5594		}
5595		isp_prt(isp, ISP_LOGERR, "%s", buf);
5596		isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
5597		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf);
5598		*rp = XS_XFRLEN(xs);
5599		break;
5600	}
5601	case RQCS_RESET_OCCURRED:
5602		isp_prt(isp, ISP_LOGWARN,
5603		    "bus reset destroyed command for %d.%d.%d",
5604		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5605		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
5606		if (XS_NOERR(xs)) {
5607			XS_SETERR(xs, HBA_BUSRESET);
5608		}
5609		*rp = XS_XFRLEN(xs);
5610		return;
5611
5612	case RQCS_ABORTED:
5613		isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
5614		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5615		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
5616		if (XS_NOERR(xs)) {
5617			XS_SETERR(xs, HBA_ABORTED);
5618		}
5619		return;
5620
5621	case RQCS_TIMEOUT:
5622		isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
5623		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5624		/*
5625	 	 * XXX: Check to see if we logged out of the device.
5626		 */
5627		if (XS_NOERR(xs)) {
5628			XS_SETERR(xs, HBA_CMDTIMEOUT);
5629		}
5630		return;
5631
5632	case RQCS_DATA_OVERRUN:
5633		XS_RESID(xs) = sp->req_resid;
5634		isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d",
5635		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5636		if (XS_NOERR(xs)) {
5637			XS_SETERR(xs, HBA_DATAOVR);
5638		}
5639		return;
5640
5641	case RQCS_COMMAND_OVERRUN:
5642		isp_prt(isp, ISP_LOGERR,
5643		    "command overrun for command on %d.%d.%d",
5644		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5645		break;
5646
5647	case RQCS_STATUS_OVERRUN:
5648		isp_prt(isp, ISP_LOGERR,
5649		    "status overrun for command on %d.%d.%d",
5650		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5651		break;
5652
5653	case RQCS_BAD_MESSAGE:
5654		isp_prt(isp, ISP_LOGERR,
5655		    "msg not COMMAND COMPLETE after status %d.%d.%d",
5656		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5657		break;
5658
5659	case RQCS_NO_MESSAGE_OUT:
5660		isp_prt(isp, ISP_LOGERR,
5661		    "No MESSAGE OUT phase after selection on %d.%d.%d",
5662		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5663		break;
5664
5665	case RQCS_EXT_ID_FAILED:
5666		isp_prt(isp, ISP_LOGERR, "EXTENDED IDENTIFY failed %d.%d.%d",
5667		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5668		break;
5669
5670	case RQCS_IDE_MSG_FAILED:
5671		isp_prt(isp, ISP_LOGERR,
5672		    "INITIATOR DETECTED ERROR rejected by %d.%d.%d",
5673		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5674		break;
5675
5676	case RQCS_ABORT_MSG_FAILED:
5677		isp_prt(isp, ISP_LOGERR, "ABORT OPERATION rejected by %d.%d.%d",
5678		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5679		break;
5680
5681	case RQCS_REJECT_MSG_FAILED:
5682		isp_prt(isp, ISP_LOGERR, "MESSAGE REJECT rejected by %d.%d.%d",
5683		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5684		break;
5685
5686	case RQCS_NOP_MSG_FAILED:
5687		isp_prt(isp, ISP_LOGERR, "NOP rejected by %d.%d.%d",
5688		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5689		break;
5690
5691	case RQCS_PARITY_ERROR_MSG_FAILED:
5692		isp_prt(isp, ISP_LOGERR,
5693		    "MESSAGE PARITY ERROR rejected by %d.%d.%d",
5694		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5695		break;
5696
5697	case RQCS_DEVICE_RESET_MSG_FAILED:
5698		isp_prt(isp, ISP_LOGWARN,
5699		    "BUS DEVICE RESET rejected by %d.%d.%d",
5700		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5701		break;
5702
5703	case RQCS_ID_MSG_FAILED:
5704		isp_prt(isp, ISP_LOGERR, "IDENTIFY rejected by %d.%d.%d",
5705		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5706		break;
5707
5708	case RQCS_UNEXP_BUS_FREE:
5709		isp_prt(isp, ISP_LOGERR, "%d.%d.%d had an unexpected bus free",
5710		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5711		break;
5712
5713	case RQCS_DATA_UNDERRUN:
5714	{
5715		if (IS_FC(isp)) {
5716			int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
5717			if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
5718				isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
5719				    XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
5720				    (ru_marked)? "marked" : "not marked");
5721				if (XS_NOERR(xs)) {
5722					XS_SETERR(xs, HBA_BOTCH);
5723				}
5724				return;
5725			}
5726		}
5727		XS_RESID(xs) = sp->req_resid;
5728		if (XS_NOERR(xs)) {
5729			XS_SETERR(xs, HBA_NOERROR);
5730		}
5731		return;
5732	}
5733
5734	case RQCS_XACT_ERR1:
5735		isp_prt(isp, ISP_LOGERR, xact1, XS_CHANNEL(xs),
5736		    XS_TGT(xs), XS_LUN(xs));
5737		break;
5738
5739	case RQCS_XACT_ERR2:
5740		isp_prt(isp, ISP_LOGERR, xact2,
5741		    XS_LUN(xs), XS_TGT(xs), XS_CHANNEL(xs));
5742		break;
5743
5744	case RQCS_XACT_ERR3:
5745		isp_prt(isp, ISP_LOGERR, xact3,
5746		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5747		break;
5748
5749	case RQCS_BAD_ENTRY:
5750		isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
5751		break;
5752
5753	case RQCS_QUEUE_FULL:
5754		isp_prt(isp, ISP_LOGDEBUG0,
5755		    "internal queues full for %d.%d.%d status 0x%x",
5756		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), *XS_STSP(xs));
5757
5758		/*
5759		 * If QFULL or some other status byte is set, then this
5760		 * isn't an error, per se.
5761		 *
5762		 * Unfortunately, some QLogic f/w writers have, in
5763		 * some cases, ommitted to *set* status to QFULL.
5764		 *
5765
5766		if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
5767			XS_SETERR(xs, HBA_NOERROR);
5768			return;
5769		}
5770
5771		 *
5772		 *
5773		 */
5774
5775		*XS_STSP(xs) = SCSI_QFULL;
5776		XS_SETERR(xs, HBA_NOERROR);
5777		return;
5778
5779	case RQCS_PHASE_SKIPPED:
5780		isp_prt(isp, ISP_LOGERR, pskip, XS_CHANNEL(xs),
5781		    XS_TGT(xs), XS_LUN(xs));
5782		break;
5783
5784	case RQCS_ARQS_FAILED:
5785		isp_prt(isp, ISP_LOGERR,
5786		    "Auto Request Sense failed for %d.%d.%d",
5787		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5788		if (XS_NOERR(xs)) {
5789			XS_SETERR(xs, HBA_ARQFAIL);
5790		}
5791		return;
5792
5793	case RQCS_WIDE_FAILED:
5794		isp_prt(isp, ISP_LOGERR,
5795		    "Wide Negotiation failed for %d.%d.%d",
5796		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
5797		if (IS_SCSI(isp)) {
5798			sdparam *sdp = isp->isp_param;
5799			sdp += XS_CHANNEL(xs);
5800			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
5801			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
5802			isp->isp_update |= (1 << XS_CHANNEL(xs));
5803		}
5804		if (XS_NOERR(xs)) {
5805			XS_SETERR(xs, HBA_NOERROR);
5806		}
5807		return;
5808
5809	case RQCS_SYNCXFER_FAILED:
5810		isp_prt(isp, ISP_LOGERR,
5811		    "SDTR Message failed for target %d.%d.%d",
5812		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
5813		if (IS_SCSI(isp)) {
5814			sdparam *sdp = isp->isp_param;
5815			sdp += XS_CHANNEL(xs);
5816			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
5817			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
5818			isp->isp_update |= (1 << XS_CHANNEL(xs));
5819		}
5820		break;
5821
5822	case RQCS_LVD_BUSERR:
5823		isp_prt(isp, ISP_LOGERR,
5824		    "Bad LVD condition while talking to %d.%d.%d",
5825		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
5826		break;
5827
5828	case RQCS_PORT_UNAVAILABLE:
5829		/*
5830		 * No such port on the loop. Moral equivalent of SELTIMEO
5831		 */
5832	case RQCS_PORT_LOGGED_OUT:
5833	{
5834		const char *reason;
5835		uint8_t sts = sp->req_completion_status & 0xff;
5836
5837		/*
5838		 * It was there (maybe)- treat as a selection timeout.
5839		 */
5840		if (sts == RQCS_PORT_UNAVAILABLE) {
5841			reason = "unavailable";
5842		} else {
5843			reason = "logout";
5844		}
5845
5846		isp_prt(isp, ISP_LOGINFO, "port %s for target %d",
5847		    reason, XS_TGT(xs));
5848
5849		/*
5850		 * If we're on a local loop, force a LIP (which is overkill)
5851		 * to force a re-login of this unit. If we're on fabric,
5852		 * then we'll have to log in again as a matter of course.
5853		 */
5854		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
5855		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
5856			mbreg_t mbs;
5857			MEMZERO(&mbs, sizeof (mbs));
5858			mbs.param[0] = MBOX_INIT_LIP;
5859			if (FCPARAM(isp)->isp_2klogin) {
5860				mbs.ibits = (1 << 10);
5861			}
5862			mbs.logval = MBLOGALL;
5863			isp_mboxcmd_qnw(isp, &mbs, 1);
5864		}
5865		if (XS_NOERR(xs)) {
5866			XS_SETERR(xs, HBA_SELTIMEOUT);
5867		}
5868		return;
5869	}
5870	case RQCS_PORT_CHANGED:
5871		isp_prt(isp, ISP_LOGWARN,
5872		    "port changed for target %d", XS_TGT(xs));
5873		if (XS_NOERR(xs)) {
5874			XS_SETERR(xs, HBA_SELTIMEOUT);
5875		}
5876		return;
5877
5878	case RQCS_PORT_BUSY:
5879		isp_prt(isp, ISP_LOGWARN,
5880		    "port busy for target %d", XS_TGT(xs));
5881		if (XS_NOERR(xs)) {
5882			XS_SETERR(xs, HBA_TGTBSY);
5883		}
5884		return;
5885
5886	default:
5887		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
5888		    sp->req_completion_status);
5889		break;
5890	}
5891	if (XS_NOERR(xs)) {
5892		XS_SETERR(xs, HBA_BOTCH);
5893	}
5894}
5895
5896static void
5897isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
5898    XS_T *xs, long *rp)
5899{
5900	switch (sp->req_completion_status) {
5901	case RQCS_COMPLETE:
5902		if (XS_NOERR(xs)) {
5903			XS_SETERR(xs, HBA_NOERROR);
5904		}
5905		return;
5906
5907	case RQCS_DMA_ERROR:
5908		isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
5909		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5910		break;
5911
5912	case RQCS_TRANSPORT_ERROR:
5913		isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d",
5914		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5915		break;
5916
5917	case RQCS_RESET_OCCURRED:
5918		isp_prt(isp, ISP_LOGWARN,
5919		    "bus reset destroyed command for %d.%d.%d",
5920		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5921		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
5922		if (XS_NOERR(xs)) {
5923			XS_SETERR(xs, HBA_BUSRESET);
5924		}
5925		return;
5926
5927	case RQCS_ABORTED:
5928		isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
5929		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5930		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
5931		if (XS_NOERR(xs)) {
5932			XS_SETERR(xs, HBA_ABORTED);
5933		}
5934		return;
5935
5936	case RQCS_TIMEOUT:
5937		isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
5938		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5939		if (XS_NOERR(xs)) {
5940			XS_SETERR(xs, HBA_CMDTIMEOUT);
5941		}
5942		return;
5943
5944	case RQCS_DATA_OVERRUN:
5945		XS_RESID(xs) = sp->req_resid;
5946		isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d",
5947		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5948		if (XS_NOERR(xs)) {
5949			XS_SETERR(xs, HBA_DATAOVR);
5950		}
5951		return;
5952
5953	case RQCS_24XX_DRE:	/* data reassembly error */
5954		isp_prt(isp, ISP_LOGERR, "data reassembly error for target %d",
5955		    XS_TGT(xs));
5956		if (XS_NOERR(xs)) {
5957			XS_SETERR(xs, HBA_ABORTED);
5958		}
5959		*rp = XS_XFRLEN(xs);
5960		return;
5961
5962	case RQCS_24XX_TABORT:	/* aborted by target */
5963		isp_prt(isp, ISP_LOGERR, "target %d sent ABTS",
5964		    XS_TGT(xs));
5965		if (XS_NOERR(xs)) {
5966			XS_SETERR(xs, HBA_ABORTED);
5967		}
5968		return;
5969
5970	case RQCS_DATA_UNDERRUN:
5971
5972		XS_RESID(xs) = sp->req_resid;
5973		if (XS_NOERR(xs)) {
5974			XS_SETERR(xs, HBA_NOERROR);
5975		}
5976		return;
5977
5978	case RQCS_PORT_UNAVAILABLE:
5979		/*
5980		 * No such port on the loop. Moral equivalent of SELTIMEO
5981		 */
5982	case RQCS_PORT_LOGGED_OUT:
5983	{
5984		const char *reason;
5985		uint8_t sts = sp->req_completion_status & 0xff;
5986
5987		/*
5988		 * It was there (maybe)- treat as a selection timeout.
5989		 */
5990		if (sts == RQCS_PORT_UNAVAILABLE) {
5991			reason = "unavailable";
5992		} else {
5993			reason = "logout";
5994		}
5995
5996		isp_prt(isp, ISP_LOGINFO, "port %s for target %d",
5997		    reason, XS_TGT(xs));
5998
5999		/*
6000		 * If we're on a local loop, force a LIP (which is overkill)
6001		 * to force a re-login of this unit. If we're on fabric,
6002		 * then we'll have to log in again as a matter of course.
6003		 */
6004		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
6005		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
6006			mbreg_t mbs;
6007			MEMZERO(&mbs, sizeof (mbs));
6008			mbs.param[0] = MBOX_INIT_LIP;
6009			if (FCPARAM(isp)->isp_2klogin) {
6010				mbs.ibits = (1 << 10);
6011			}
6012			mbs.logval = MBLOGALL;
6013			isp_mboxcmd_qnw(isp, &mbs, 1);
6014		}
6015		if (XS_NOERR(xs)) {
6016			XS_SETERR(xs, HBA_SELTIMEOUT);
6017		}
6018		return;
6019	}
6020	case RQCS_PORT_CHANGED:
6021		isp_prt(isp, ISP_LOGWARN,
6022		    "port changed for target %d", XS_TGT(xs));
6023		if (XS_NOERR(xs)) {
6024			XS_SETERR(xs, HBA_SELTIMEOUT);
6025		}
6026		return;
6027
6028
6029	case RQCS_24XX_ENOMEM:	/* f/w resource unavailable */
6030		isp_prt(isp, ISP_LOGWARN,
6031		    "f/w resource unavailable for target %d", XS_TGT(xs));
6032		if (XS_NOERR(xs)) {
6033			*XS_STSP(xs) = SCSI_BUSY;
6034			XS_SETERR(xs, HBA_TGTBSY);
6035		}
6036		return;
6037
6038	case RQCS_24XX_TMO:	/* task management overrun */
6039		isp_prt(isp, ISP_LOGWARN,
6040		    "command for target %d overlapped task management",
6041		    XS_TGT(xs));
6042		if (XS_NOERR(xs)) {
6043			*XS_STSP(xs) = SCSI_BUSY;
6044			XS_SETERR(xs, HBA_TGTBSY);
6045		}
6046		return;
6047
6048	default:
6049		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
6050		    sp->req_completion_status);
6051		break;
6052	}
6053	if (XS_NOERR(xs)) {
6054		XS_SETERR(xs, HBA_BOTCH);
6055	}
6056}
6057
6058static void
6059isp_fastpost_complete(ispsoftc_t *isp, uint16_t fph)
6060{
6061	XS_T *xs;
6062
6063	if (fph == 0) {
6064		return;
6065	}
6066	xs = isp_find_xs(isp, fph);
6067	if (xs == NULL) {
6068		isp_prt(isp, ISP_LOGWARN,
6069		    "Command for fast post handle 0x%x not found", fph);
6070		return;
6071	}
6072	isp_destroy_handle(isp, fph);
6073
6074	/*
6075	 * Since we don't have a result queue entry item,
6076	 * we must believe that SCSI status is zero and
6077	 * that all data transferred.
6078	 */
6079	XS_SET_STATE_STAT(isp, xs, NULL);
6080	XS_RESID(xs) = 0;
6081	*XS_STSP(xs) = SCSI_GOOD;
6082	if (XS_XFRLEN(xs)) {
6083		ISP_DMAFREE(isp, xs, fph);
6084	}
6085	if (isp->isp_nactive)
6086		isp->isp_nactive--;
6087	isp->isp_fphccmplt++;
6088	isp_done(xs);
6089}
6090
6091static int
6092isp_mbox_continue(ispsoftc_t *isp)
6093{
6094	mbreg_t mbs;
6095	uint16_t *ptr;
6096	uint32_t offset;
6097
6098	switch (isp->isp_lastmbxcmd) {
6099	case MBOX_WRITE_RAM_WORD:
6100	case MBOX_READ_RAM_WORD:
6101	case MBOX_WRITE_RAM_WORD_EXTENDED:
6102	case MBOX_READ_RAM_WORD_EXTENDED:
6103		break;
6104	default:
6105		return (1);
6106	}
6107	if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
6108		isp->isp_mbxwrk0 = 0;
6109		return (-1);
6110	}
6111
6112	/*
6113	 * Clear the previous interrupt.
6114	 */
6115	if (IS_24XX(isp)) {
6116		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
6117	} else {
6118		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
6119		ISP_WRITE(isp, BIU_SEMA, 0);
6120	}
6121
6122	/*
6123	 * Continue with next word.
6124	 */
6125	MEMZERO(&mbs, sizeof (mbs));
6126	ptr = isp->isp_mbxworkp;
6127	switch (isp->isp_lastmbxcmd) {
6128	case MBOX_WRITE_RAM_WORD:
6129		mbs.param[1] = isp->isp_mbxwrk1++;;
6130		mbs.param[2] = *ptr++;;
6131		break;
6132	case MBOX_READ_RAM_WORD:
6133		*ptr++ = isp->isp_mboxtmp[2];
6134		mbs.param[1] = isp->isp_mbxwrk1++;
6135		break;
6136	case MBOX_WRITE_RAM_WORD_EXTENDED:
6137		offset = isp->isp_mbxwrk1;
6138		offset |= isp->isp_mbxwrk8 << 16;
6139
6140		mbs.param[2] = *ptr++;;
6141		mbs.param[1] = offset;
6142		mbs.param[8] = offset >> 16;
6143		isp->isp_mbxwrk1 = ++offset;
6144		isp->isp_mbxwrk8 = offset >> 16;
6145		break;
6146	case MBOX_READ_RAM_WORD_EXTENDED:
6147		offset = isp->isp_mbxwrk1;
6148		offset |= isp->isp_mbxwrk8 << 16;
6149
6150		*ptr++ = isp->isp_mboxtmp[2];
6151		mbs.param[1] = offset;
6152		mbs.param[8] = offset >> 16;
6153		isp->isp_mbxwrk1 = ++offset;
6154		isp->isp_mbxwrk8 = offset >> 16;
6155		break;
6156	}
6157	isp->isp_mbxworkp = ptr;
6158	isp->isp_mbxwrk0--;
6159	mbs.param[0] = isp->isp_lastmbxcmd;
6160	mbs.logval = MBLOGALL;
6161	isp_mboxcmd_qnw(isp, &mbs, 0);
6162	return (0);
6163}
6164
6165#define	HIWRD(x)			((x) >> 16)
6166#define	LOWRD(x)			((x)  & 0xffff)
6167#define	ISPOPMAP(a, b)			(((a) << 16) | (b))
6168static const uint32_t mbpscsi[] = {
6169	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
6170	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
6171	ISPOPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
6172	ISPOPMAP(0x1f, 0x01),	/* 0x03: MBOX_DUMP_RAM */
6173	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
6174	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
6175	ISPOPMAP(0x3f, 0x3f),	/* 0x06: MBOX_MAILBOX_REG_TEST */
6176	ISPOPMAP(0x07, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
6177	ISPOPMAP(0x01, 0x0f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
6178	ISPOPMAP(0x00, 0x00),	/* 0x09: */
6179	ISPOPMAP(0x00, 0x00),	/* 0x0a: */
6180	ISPOPMAP(0x00, 0x00),	/* 0x0b: */
6181	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
6182	ISPOPMAP(0x00, 0x00),	/* 0x0d: */
6183	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
6184	ISPOPMAP(0x00, 0x00),	/* 0x0f: */
6185	ISPOPMAP(0x1f, 0x1f),	/* 0x10: MBOX_INIT_REQ_QUEUE */
6186	ISPOPMAP(0x3f, 0x3f),	/* 0x11: MBOX_INIT_RES_QUEUE */
6187	ISPOPMAP(0x0f, 0x0f),	/* 0x12: MBOX_EXECUTE_IOCB */
6188	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
6189	ISPOPMAP(0x01, 0x3f),	/* 0x14: MBOX_STOP_FIRMWARE */
6190	ISPOPMAP(0x0f, 0x0f),	/* 0x15: MBOX_ABORT */
6191	ISPOPMAP(0x03, 0x03),	/* 0x16: MBOX_ABORT_DEVICE */
6192	ISPOPMAP(0x07, 0x07),	/* 0x17: MBOX_ABORT_TARGET */
6193	ISPOPMAP(0x07, 0x07),	/* 0x18: MBOX_BUS_RESET */
6194	ISPOPMAP(0x03, 0x07),	/* 0x19: MBOX_STOP_QUEUE */
6195	ISPOPMAP(0x03, 0x07),	/* 0x1a: MBOX_START_QUEUE */
6196	ISPOPMAP(0x03, 0x07),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6197	ISPOPMAP(0x03, 0x07),	/* 0x1c: MBOX_ABORT_QUEUE */
6198	ISPOPMAP(0x03, 0x4f),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6199	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
6200	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6201	ISPOPMAP(0x01, 0x07),	/* 0x20: MBOX_GET_INIT_SCSI_ID */
6202	ISPOPMAP(0x01, 0x07),	/* 0x21: MBOX_GET_SELECT_TIMEOUT */
6203	ISPOPMAP(0x01, 0xc7),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
6204	ISPOPMAP(0x01, 0x07),	/* 0x23: MBOX_GET_TAG_AGE_LIMIT */
6205	ISPOPMAP(0x01, 0x03),	/* 0x24: MBOX_GET_CLOCK_RATE */
6206	ISPOPMAP(0x01, 0x07),	/* 0x25: MBOX_GET_ACT_NEG_STATE */
6207	ISPOPMAP(0x01, 0x07),	/* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
6208	ISPOPMAP(0x01, 0x07),	/* 0x27: MBOX_GET_PCI_PARAMS */
6209	ISPOPMAP(0x03, 0x4f),	/* 0x28: MBOX_GET_TARGET_PARAMS */
6210	ISPOPMAP(0x03, 0x0f),	/* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
6211	ISPOPMAP(0x01, 0x07),	/* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
6212	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
6213	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
6214	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
6215	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
6216	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
6217	ISPOPMAP(0x03, 0x03),	/* 0x30: MBOX_SET_INIT_SCSI_ID */
6218	ISPOPMAP(0x07, 0x07),	/* 0x31: MBOX_SET_SELECT_TIMEOUT */
6219	ISPOPMAP(0xc7, 0xc7),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
6220	ISPOPMAP(0x07, 0x07),	/* 0x33: MBOX_SET_TAG_AGE_LIMIT */
6221	ISPOPMAP(0x03, 0x03),	/* 0x34: MBOX_SET_CLOCK_RATE */
6222	ISPOPMAP(0x07, 0x07),	/* 0x35: MBOX_SET_ACT_NEG_STATE */
6223	ISPOPMAP(0x07, 0x07),	/* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
6224	ISPOPMAP(0x07, 0x07),	/* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
6225	ISPOPMAP(0x4f, 0x4f),	/* 0x38: MBOX_SET_TARGET_PARAMS */
6226	ISPOPMAP(0x0f, 0x0f),	/* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
6227	ISPOPMAP(0x07, 0x07),	/* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
6228	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
6229	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
6230	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
6231	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
6232	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
6233	ISPOPMAP(0x01, 0x03),	/* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
6234	ISPOPMAP(0x3f, 0x01),	/* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
6235	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_EXEC_BIOS_IOCB */
6236	ISPOPMAP(0x00, 0x00),	/* 0x43: */
6237	ISPOPMAP(0x00, 0x00),	/* 0x44: */
6238	ISPOPMAP(0x03, 0x03),	/* 0x45: SET SYSTEM PARAMETER */
6239	ISPOPMAP(0x01, 0x03),	/* 0x46: GET SYSTEM PARAMETER */
6240	ISPOPMAP(0x00, 0x00),	/* 0x47: */
6241	ISPOPMAP(0x01, 0xcf),	/* 0x48: GET SCAM CONFIGURATION */
6242	ISPOPMAP(0xcf, 0xcf),	/* 0x49: SET SCAM CONFIGURATION */
6243	ISPOPMAP(0x03, 0x03),	/* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
6244	ISPOPMAP(0x01, 0x03),	/* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
6245	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
6246	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
6247	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
6248	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
6249	ISPOPMAP(0xdf, 0xdf),	/* 0x50: LOAD RAM A64 */
6250	ISPOPMAP(0xdf, 0xdf),	/* 0x51: DUMP RAM A64 */
6251	ISPOPMAP(0xdf, 0xff),	/* 0x52: INITIALIZE REQUEST QUEUE A64 */
6252	ISPOPMAP(0xef, 0xff),	/* 0x53: INITIALIZE RESPONSE QUEUE A64 */
6253	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUCUTE COMMAND IOCB A64 */
6254	ISPOPMAP(0x07, 0x01),	/* 0x55: ENABLE TARGET MODE */
6255	ISPOPMAP(0x03, 0x0f),	/* 0x56: GET TARGET STATUS */
6256	ISPOPMAP(0x00, 0x00),	/* 0x57: */
6257	ISPOPMAP(0x00, 0x00),	/* 0x58: */
6258	ISPOPMAP(0x00, 0x00),	/* 0x59: */
6259	ISPOPMAP(0x03, 0x03),	/* 0x5a: SET DATA OVERRUN RECOVERY MODE */
6260	ISPOPMAP(0x01, 0x03),	/* 0x5b: GET DATA OVERRUN RECOVERY MODE */
6261	ISPOPMAP(0x0f, 0x0f),	/* 0x5c: SET HOST DATA */
6262	ISPOPMAP(0x01, 0x01)	/* 0x5d: GET NOST DATA */
6263};
6264
6265static const char *scsi_mbcmd_names[] = {
6266	"NO-OP",
6267	"LOAD RAM",
6268	"EXEC FIRMWARE",
6269	"DUMP RAM",
6270	"WRITE RAM WORD",
6271	"READ RAM WORD",
6272	"MAILBOX REG TEST",
6273	"VERIFY CHECKSUM",
6274	"ABOUT FIRMWARE",
6275	NULL,
6276	NULL,
6277	NULL,
6278	NULL,
6279	NULL,
6280	"CHECK FIRMWARE",
6281	NULL,
6282	"INIT REQUEST QUEUE",
6283	"INIT RESULT QUEUE",
6284	"EXECUTE IOCB",
6285	"WAKE UP",
6286	"STOP FIRMWARE",
6287	"ABORT",
6288	"ABORT DEVICE",
6289	"ABORT TARGET",
6290	"BUS RESET",
6291	"STOP QUEUE",
6292	"START QUEUE",
6293	"SINGLE STEP QUEUE",
6294	"ABORT QUEUE",
6295	"GET DEV QUEUE STATUS",
6296	NULL,
6297	"GET FIRMWARE STATUS",
6298	"GET INIT SCSI ID",
6299	"GET SELECT TIMEOUT",
6300	"GET RETRY COUNT",
6301	"GET TAG AGE LIMIT",
6302	"GET CLOCK RATE",
6303	"GET ACT NEG STATE",
6304	"GET ASYNC DATA SETUP TIME",
6305	"GET PCI PARAMS",
6306	"GET TARGET PARAMS",
6307	"GET DEV QUEUE PARAMS",
6308	"GET RESET DELAY PARAMS",
6309	NULL,
6310	NULL,
6311	NULL,
6312	NULL,
6313	NULL,
6314	"SET INIT SCSI ID",
6315	"SET SELECT TIMEOUT",
6316	"SET RETRY COUNT",
6317	"SET TAG AGE LIMIT",
6318	"SET CLOCK RATE",
6319	"SET ACT NEG STATE",
6320	"SET ASYNC DATA SETUP TIME",
6321	"SET PCI CONTROL PARAMS",
6322	"SET TARGET PARAMS",
6323	"SET DEV QUEUE PARAMS",
6324	"SET RESET DELAY PARAMS",
6325	NULL,
6326	NULL,
6327	NULL,
6328	NULL,
6329	NULL,
6330	"RETURN BIOS BLOCK ADDR",
6331	"WRITE FOUR RAM WORDS",
6332	"EXEC BIOS IOCB",
6333	NULL,
6334	NULL,
6335	"SET SYSTEM PARAMETER",
6336	"GET SYSTEM PARAMETER",
6337	NULL,
6338	"GET SCAM CONFIGURATION",
6339	"SET SCAM CONFIGURATION",
6340	"SET FIRMWARE FEATURES",
6341	"GET FIRMWARE FEATURES",
6342	NULL,
6343	NULL,
6344	NULL,
6345	NULL,
6346	"LOAD RAM A64",
6347	"DUMP RAM A64",
6348	"INITIALIZE REQUEST QUEUE A64",
6349	"INITIALIZE RESPONSE QUEUE A64",
6350	"EXECUTE IOCB A64",
6351	"ENABLE TARGET MODE",
6352	"GET TARGET MODE STATE",
6353	NULL,
6354	NULL,
6355	NULL,
6356	"SET DATA OVERRUN RECOVERY MODE",
6357	"GET DATA OVERRUN RECOVERY MODE",
6358	"SET HOST DATA",
6359	"GET NOST DATA",
6360};
6361
6362static const uint32_t mbpfc[] = {
6363	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
6364	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
6365	ISPOPMAP(0x0f, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
6366	ISPOPMAP(0xdf, 0x01),	/* 0x03: MBOX_DUMP_RAM */
6367	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
6368	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
6369	ISPOPMAP(0xff, 0xff),	/* 0x06: MBOX_MAILBOX_REG_TEST */
6370	ISPOPMAP(0x03, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
6371	ISPOPMAP(0x01, 0x4f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
6372	ISPOPMAP(0xdf, 0x01),	/* 0x09: MBOX_LOAD_RISC_RAM_2100 */
6373	ISPOPMAP(0xdf, 0x01),	/* 0x0a: DUMP RAM */
6374	ISPOPMAP(0x1ff, 0x01),	/* 0x0b: MBOX_LOAD_RISC_RAM */
6375	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
6376	ISPOPMAP(0x10f, 0x01),	/* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
6377	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
6378	ISPOPMAP(0x10f, 0x05),	/* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
6379	ISPOPMAP(0x1f, 0x11),	/* 0x10: MBOX_INIT_REQ_QUEUE */
6380	ISPOPMAP(0x2f, 0x21),	/* 0x11: MBOX_INIT_RES_QUEUE */
6381	ISPOPMAP(0x0f, 0x01),	/* 0x12: MBOX_EXECUTE_IOCB */
6382	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
6383	ISPOPMAP(0x01, 0xff),	/* 0x14: MBOX_STOP_FIRMWARE */
6384	ISPOPMAP(0x4f, 0x01),	/* 0x15: MBOX_ABORT */
6385	ISPOPMAP(0x07, 0x01),	/* 0x16: MBOX_ABORT_DEVICE */
6386	ISPOPMAP(0x07, 0x01),	/* 0x17: MBOX_ABORT_TARGET */
6387	ISPOPMAP(0x03, 0x03),	/* 0x18: MBOX_BUS_RESET */
6388	ISPOPMAP(0x07, 0x05),	/* 0x19: MBOX_STOP_QUEUE */
6389	ISPOPMAP(0x07, 0x05),	/* 0x1a: MBOX_START_QUEUE */
6390	ISPOPMAP(0x07, 0x05),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6391	ISPOPMAP(0x07, 0x05),	/* 0x1c: MBOX_ABORT_QUEUE */
6392	ISPOPMAP(0x07, 0x03),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6393	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
6394	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6395	ISPOPMAP(0x01, 0x4f),	/* 0x20: MBOX_GET_LOOP_ID */
6396	ISPOPMAP(0x00, 0x00),	/* 0x21: */
6397	ISPOPMAP(0x01, 0x07),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
6398	ISPOPMAP(0x00, 0x00),	/* 0x23: */
6399	ISPOPMAP(0x00, 0x00),	/* 0x24: */
6400	ISPOPMAP(0x00, 0x00),	/* 0x25: */
6401	ISPOPMAP(0x00, 0x00),	/* 0x26: */
6402	ISPOPMAP(0x00, 0x00),	/* 0x27: */
6403	ISPOPMAP(0x01, 0x03),	/* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
6404	ISPOPMAP(0x03, 0x07),	/* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
6405	ISPOPMAP(0x00, 0x00),	/* 0x2a: */
6406	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
6407	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
6408	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
6409	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
6410	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
6411	ISPOPMAP(0x00, 0x00),	/* 0x30: */
6412	ISPOPMAP(0x00, 0x00),	/* 0x31: */
6413	ISPOPMAP(0x07, 0x07),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
6414	ISPOPMAP(0x00, 0x00),	/* 0x33: */
6415	ISPOPMAP(0x00, 0x00),	/* 0x34: */
6416	ISPOPMAP(0x00, 0x00),	/* 0x35: */
6417	ISPOPMAP(0x00, 0x00),	/* 0x36: */
6418	ISPOPMAP(0x00, 0x00),	/* 0x37: */
6419	ISPOPMAP(0x0f, 0x01),	/* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
6420	ISPOPMAP(0x0f, 0x07),	/* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
6421	ISPOPMAP(0x00, 0x00),	/* 0x3a: */
6422	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
6423	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
6424	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
6425	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
6426	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
6427	ISPOPMAP(0x03, 0x01),	/* 0x40: MBOX_LOOP_PORT_BYPASS */
6428	ISPOPMAP(0x03, 0x01),	/* 0x41: MBOX_LOOP_PORT_ENABLE */
6429	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_GET_RESOURCE_COUNT */
6430	ISPOPMAP(0x01, 0x01),	/* 0x43: MBOX_REQUEST_OFFLINE_MODE */
6431	ISPOPMAP(0x00, 0x00),	/* 0x44: */
6432	ISPOPMAP(0x00, 0x00),	/* 0x45: */
6433	ISPOPMAP(0x00, 0x00),	/* 0x46: */
6434	ISPOPMAP(0xcf, 0x03),	/* 0x47: GET PORT_DATABASE ENHANCED */
6435	ISPOPMAP(0x00, 0x00),	/* 0x48: */
6436	ISPOPMAP(0x00, 0x00),	/* 0x49: */
6437	ISPOPMAP(0x00, 0x00),	/* 0x4a: */
6438	ISPOPMAP(0x00, 0x00),	/* 0x4b: */
6439	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
6440	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
6441	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
6442	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
6443	ISPOPMAP(0x00, 0x00),	/* 0x50: */
6444	ISPOPMAP(0x00, 0x00),	/* 0x51: */
6445	ISPOPMAP(0x00, 0x00),	/* 0x52: */
6446	ISPOPMAP(0x00, 0x00),	/* 0x53: */
6447	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
6448	ISPOPMAP(0x00, 0x00),	/* 0x55: */
6449	ISPOPMAP(0x00, 0x00),	/* 0x56: */
6450	ISPOPMAP(0x00, 0x00),	/* 0x57: */
6451	ISPOPMAP(0x00, 0x00),	/* 0x58: */
6452	ISPOPMAP(0x00, 0x00),	/* 0x59: */
6453	ISPOPMAP(0x00, 0x00),	/* 0x5a: */
6454	ISPOPMAP(0x03, 0x01),	/* 0x5b: MBOX_DRIVER_HEARTBEAT */
6455	ISPOPMAP(0xcf, 0x01),	/* 0x5c: MBOX_FW_HEARTBEAT */
6456	ISPOPMAP(0x07, 0x03),	/* 0x5d: MBOX_GET_SET_DATA_RATE */
6457	ISPOPMAP(0x00, 0x00),	/* 0x5e: */
6458	ISPOPMAP(0x00, 0x00),	/* 0x5f: */
6459	ISPOPMAP(0xcd, 0x01),	/* 0x60: MBOX_INIT_FIRMWARE */
6460	ISPOPMAP(0x00, 0x00),	/* 0x61: */
6461	ISPOPMAP(0x01, 0x01),	/* 0x62: MBOX_INIT_LIP */
6462	ISPOPMAP(0xcd, 0x03),	/* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
6463	ISPOPMAP(0xcf, 0x01),	/* 0x64: MBOX_GET_PORT_DB */
6464	ISPOPMAP(0x07, 0x01),	/* 0x65: MBOX_CLEAR_ACA */
6465	ISPOPMAP(0x07, 0x01),	/* 0x66: MBOX_TARGET_RESET */
6466	ISPOPMAP(0x07, 0x01),	/* 0x67: MBOX_CLEAR_TASK_SET */
6467	ISPOPMAP(0x07, 0x01),	/* 0x68: MBOX_ABORT_TASK_SET */
6468	ISPOPMAP(0x01, 0x07),	/* 0x69: MBOX_GET_FW_STATE */
6469	ISPOPMAP(0x03, 0xcf),	/* 0x6a: MBOX_GET_PORT_NAME */
6470	ISPOPMAP(0xcf, 0x01),	/* 0x6b: MBOX_GET_LINK_STATUS */
6471	ISPOPMAP(0x0f, 0x01),	/* 0x6c: MBOX_INIT_LIP_RESET */
6472	ISPOPMAP(0x00, 0x00),	/* 0x6d: */
6473	ISPOPMAP(0xcf, 0x03),	/* 0x6e: MBOX_SEND_SNS */
6474	ISPOPMAP(0x0f, 0x07),	/* 0x6f: MBOX_FABRIC_LOGIN */
6475	ISPOPMAP(0x03, 0x01),	/* 0x70: MBOX_SEND_CHANGE_REQUEST */
6476	ISPOPMAP(0x03, 0x03),	/* 0x71: MBOX_FABRIC_LOGOUT */
6477	ISPOPMAP(0x0f, 0x0f),	/* 0x72: MBOX_INIT_LIP_LOGIN */
6478	ISPOPMAP(0x00, 0x00),	/* 0x73: */
6479	ISPOPMAP(0x07, 0x01),	/* 0x74: LOGIN LOOP PORT */
6480	ISPOPMAP(0xcf, 0x03),	/* 0x75: GET PORT/NODE NAME LIST */
6481	ISPOPMAP(0x4f, 0x01),	/* 0x76: SET VENDOR ID */
6482	ISPOPMAP(0xcd, 0x01),	/* 0x77: INITIALIZE IP MAILBOX */
6483	ISPOPMAP(0x00, 0x00),	/* 0x78: */
6484	ISPOPMAP(0x00, 0x00),	/* 0x79: */
6485	ISPOPMAP(0x00, 0x00),	/* 0x7a: */
6486	ISPOPMAP(0x00, 0x00),	/* 0x7b: */
6487	ISPOPMAP(0x4f, 0x03),	/* 0x7c: Get ID List */
6488	ISPOPMAP(0xcf, 0x01),	/* 0x7d: SEND LFA */
6489	ISPOPMAP(0x0f, 0x01)	/* 0x7e: LUN RESET */
6490};
6491/*
6492 * Footnotes
6493 *
6494 * (1): this sets bits 21..16 in mailbox register #8, which we nominally
6495 *	do not access at this time in the core driver. The caller is
6496 *	responsible for setting this register first (Gross!). The assumption
6497 *	is that we won't overflow.
6498 */
6499
6500static const char *fc_mbcmd_names[] = {
6501	"NO-OP",
6502	"LOAD RAM",
6503	"EXEC FIRMWARE",
6504	"DUMP RAM",
6505	"WRITE RAM WORD",
6506	"READ RAM WORD",
6507	"MAILBOX REG TEST",
6508	"VERIFY CHECKSUM",
6509	"ABOUT FIRMWARE",
6510	"LOAD RAM",
6511	"DUMP RAM",
6512	"WRITE RAM WORD EXTENDED",
6513	NULL,
6514	"READ RAM WORD EXTENDED",
6515	"CHECK FIRMWARE",
6516	NULL,
6517	"INIT REQUEST QUEUE",
6518	"INIT RESULT QUEUE",
6519	"EXECUTE IOCB",
6520	"WAKE UP",
6521	"STOP FIRMWARE",
6522	"ABORT",
6523	"ABORT DEVICE",
6524	"ABORT TARGET",
6525	"BUS RESET",
6526	"STOP QUEUE",
6527	"START QUEUE",
6528	"SINGLE STEP QUEUE",
6529	"ABORT QUEUE",
6530	"GET DEV QUEUE STATUS",
6531	NULL,
6532	"GET FIRMWARE STATUS",
6533	"GET LOOP ID",
6534	NULL,
6535	"GET RETRY COUNT",
6536	NULL,
6537	NULL,
6538	NULL,
6539	NULL,
6540	NULL,
6541	"GET FIRMWARE OPTIONS",
6542	"GET PORT QUEUE PARAMS",
6543	NULL,
6544	NULL,
6545	NULL,
6546	NULL,
6547	NULL,
6548	NULL,
6549	NULL,
6550	NULL,
6551	"SET RETRY COUNT",
6552	NULL,
6553	NULL,
6554	NULL,
6555	NULL,
6556	NULL,
6557	"SET FIRMWARE OPTIONS",
6558	"SET PORT QUEUE PARAMS",
6559	NULL,
6560	NULL,
6561	NULL,
6562	NULL,
6563	NULL,
6564	NULL,
6565	"LOOP PORT BYPASS",
6566	"LOOP PORT ENABLE",
6567	"GET RESOURCE COUNT",
6568	"REQUEST NON PARTICIPATING MODE",
6569	NULL,
6570	NULL,
6571	NULL,
6572	"GET PORT DATABASE ENHANCED",
6573	NULL,
6574	NULL,
6575	NULL,
6576	NULL,
6577	NULL,
6578	NULL,
6579	NULL,
6580	NULL,
6581	NULL,
6582	NULL,
6583	NULL,
6584	NULL,
6585	"EXECUTE IOCB A64",
6586	NULL,
6587	NULL,
6588	NULL,
6589	NULL,
6590	NULL,
6591	NULL,
6592	"DRIVER HEARTBEAT",
6593	NULL,
6594	"GET/SET DATA RATE",
6595	NULL,
6596	NULL,
6597	"INIT FIRMWARE",
6598	NULL,
6599	"INIT LIP",
6600	"GET FC-AL POSITION MAP",
6601	"GET PORT DATABASE",
6602	"CLEAR ACA",
6603	"TARGET RESET",
6604	"CLEAR TASK SET",
6605	"ABORT TASK SET",
6606	"GET FW STATE",
6607	"GET PORT NAME",
6608	"GET LINK STATUS",
6609	"INIT LIP RESET",
6610	NULL,
6611	"SEND SNS",
6612	"FABRIC LOGIN",
6613	"SEND CHANGE REQUEST",
6614	"FABRIC LOGOUT",
6615	"INIT LIP LOGIN",
6616	NULL,
6617	"LOGIN LOOP PORT",
6618	"GET PORT/NODE NAME LIST",
6619	"SET VENDOR ID",
6620	"INITIALIZE IP MAILBOX",
6621	NULL,
6622	NULL,
6623	NULL,
6624	NULL,
6625	"Get ID List",
6626	"SEND LFA",
6627	"Lun RESET"
6628};
6629
6630static void
6631isp_mboxcmd_qnw(ispsoftc_t *isp, mbreg_t *mbp, int nodelay)
6632{
6633	unsigned int ibits, obits, box, opcode;
6634	const uint32_t *mcp;
6635
6636	if (IS_FC(isp)) {
6637		mcp = mbpfc;
6638	} else {
6639		mcp = mbpscsi;
6640	}
6641	opcode = mbp->param[0];
6642	ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
6643	obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
6644	ibits |= mbp->ibits;
6645	obits |= mbp->obits;
6646	for (box = 0; box < MAX_MAILBOX(isp); box++) {
6647		if (ibits & (1 << box)) {
6648			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
6649		}
6650		if (nodelay == 0) {
6651			isp->isp_mboxtmp[box] = mbp->param[box] = 0;
6652		}
6653	}
6654	if (nodelay == 0) {
6655		isp->isp_lastmbxcmd = opcode;
6656		isp->isp_obits = obits;
6657		isp->isp_mboxbsy = 1;
6658	}
6659	if (IS_24XX(isp)) {
6660		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
6661	} else {
6662		ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
6663	}
6664	/*
6665	 * Oddly enough, if we're not delaying for an answer,
6666	 * delay a bit to give the f/w a chance to pick up the
6667	 * command.
6668	 */
6669	if (nodelay) {
6670		USEC_DELAY(1000);
6671	}
6672}
6673
6674static void
6675isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
6676{
6677	const char *cname, *xname;
6678	char tname[16], mname[16];
6679	unsigned int lim, ibits, obits, box, opcode;
6680	const uint32_t *mcp;
6681
6682	if (IS_FC(isp)) {
6683		mcp = mbpfc;
6684		lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
6685	} else {
6686		mcp = mbpscsi;
6687		lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
6688	}
6689
6690	if ((opcode = mbp->param[0]) >= lim) {
6691		mbp->param[0] = MBOX_INVALID_COMMAND;
6692		isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
6693		return;
6694	}
6695
6696	ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
6697	obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
6698
6699	/*
6700	 * Pick up any additional bits that the caller might have set.
6701	 */
6702	ibits |= mbp->ibits;
6703	obits |= mbp->obits;
6704
6705	if (ibits == 0 && obits == 0) {
6706		mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
6707		isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
6708		return;
6709	}
6710
6711	/*
6712	 * Get exclusive usage of mailbox registers.
6713	 */
6714	if (MBOX_ACQUIRE(isp)) {
6715		mbp->param[0] = MBOX_REGS_BUSY;
6716		goto out;
6717	}
6718
6719	for (box = 0; box < MAX_MAILBOX(isp); box++) {
6720		if (ibits & (1 << box)) {
6721			isp_prt(isp, ISP_LOGDEBUG1, "IN mbox %d = 0x%04x", box,
6722			    mbp->param[box]);
6723			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
6724		}
6725		isp->isp_mboxtmp[box] = mbp->param[box] = 0;
6726	}
6727
6728	isp->isp_lastmbxcmd = opcode;
6729
6730	/*
6731	 * We assume that we can't overwrite a previous command.
6732	 */
6733	isp->isp_obits = obits;
6734	isp->isp_mboxbsy = 1;
6735
6736	/*
6737	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
6738	 */
6739	if (IS_24XX(isp)) {
6740		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
6741	} else {
6742		ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
6743	}
6744
6745	/*
6746	 * While we haven't finished the command, spin our wheels here.
6747	 */
6748	MBOX_WAIT_COMPLETE(isp, mbp);
6749
6750	/*
6751	 * Did the command time out?
6752	 */
6753	if (mbp->param[0] == MBOX_TIMEOUT) {
6754		MBOX_RELEASE(isp);
6755		goto out;
6756	}
6757
6758	/*
6759	 * Copy back output registers.
6760	 */
6761	for (box = 0; box < MAX_MAILBOX(isp); box++) {
6762		if (obits & (1 << box)) {
6763			mbp->param[box] = isp->isp_mboxtmp[box];
6764			isp_prt(isp, ISP_LOGDEBUG1, "OUT mbox %d = 0x%04x", box,
6765			    mbp->param[box]);
6766		}
6767	}
6768
6769	MBOX_RELEASE(isp);
6770 out:
6771	isp->isp_mboxbsy = 0;
6772	if (mbp->logval == 0 || opcode == MBOX_EXEC_FIRMWARE) {
6773		return;
6774	}
6775	cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
6776	if (cname == NULL) {
6777		cname = tname;
6778		SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
6779	}
6780
6781	/*
6782	 * Just to be chatty here...
6783	 */
6784	xname = NULL;
6785	switch (mbp->param[0]) {
6786	case MBOX_COMMAND_COMPLETE:
6787		break;
6788	case MBOX_INVALID_COMMAND:
6789		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_COMPLETE)) {
6790			xname = "INVALID COMMAND";
6791		}
6792		break;
6793	case MBOX_HOST_INTERFACE_ERROR:
6794		if (mbp->logval & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR)) {
6795			xname = "HOST INTERFACE ERROR";
6796		}
6797		break;
6798	case MBOX_TEST_FAILED:
6799		if (mbp->logval & MBLOGMASK(MBOX_TEST_FAILED)) {
6800			xname = "TEST FAILED";
6801		}
6802		break;
6803	case MBOX_COMMAND_ERROR:
6804		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_ERROR)) {
6805			xname = "COMMAND ERROR";
6806		}
6807		break;
6808	case MBOX_COMMAND_PARAM_ERROR:
6809		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR)) {
6810			xname = "COMMAND PARAMETER ERROR";
6811		}
6812		break;
6813	case MBOX_LOOP_ID_USED:
6814		if (mbp->logval & MBLOGMASK(MBOX_LOOP_ID_USED)) {
6815			xname = "LOOP ID ALREADY IN USE";
6816		}
6817		break;
6818	case MBOX_PORT_ID_USED:
6819		if (mbp->logval & MBLOGMASK(MBOX_PORT_ID_USED)) {
6820			xname = "PORT ID ALREADY IN USE";
6821		}
6822		break;
6823	case MBOX_ALL_IDS_USED:
6824		if (mbp->logval & MBLOGMASK(MBOX_ALL_IDS_USED)) {
6825			xname = "ALL LOOP IDS IN USE";
6826		}
6827		break;
6828	case MBOX_REGS_BUSY:
6829		xname = "REGISTERS BUSY";
6830		break;
6831	case MBOX_TIMEOUT:
6832		xname = "TIMEOUT";
6833		break;
6834	default:
6835		SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
6836		xname = mname;
6837		break;
6838	}
6839	if (xname) {
6840		isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
6841		    cname, xname);
6842	}
6843}
6844
6845static void
6846isp_fw_state(ispsoftc_t *isp)
6847{
6848	if (IS_FC(isp)) {
6849		mbreg_t mbs;
6850		fcparam *fcp = isp->isp_param;
6851
6852		MEMZERO(&mbs, sizeof (mbs));
6853		mbs.param[0] = MBOX_GET_FW_STATE;
6854		mbs.logval = MBLOGALL;
6855		isp_mboxcmd(isp, &mbs);
6856		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
6857			fcp->isp_fwstate = mbs.param[1];
6858		}
6859	}
6860}
6861
6862static void
6863isp_update(ispsoftc_t *isp)
6864{
6865	int bus, upmask;
6866
6867	for (bus = 0, upmask = isp->isp_update; upmask != 0; bus++) {
6868		if (upmask & (1 << bus)) {
6869			isp_update_bus(isp, bus);
6870		}
6871		upmask &= ~(1 << bus);
6872	}
6873}
6874
6875static void
6876isp_update_bus(ispsoftc_t *isp, int bus)
6877{
6878	int tgt;
6879	mbreg_t mbs;
6880	sdparam *sdp;
6881
6882	isp->isp_update &= ~(1 << bus);
6883	if (IS_FC(isp)) {
6884		/*
6885		 * There are no 'per-bus' settings for Fibre Channel.
6886		 */
6887		return;
6888	}
6889	sdp = isp->isp_param;
6890	sdp += bus;
6891
6892	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
6893		uint16_t flags, period, offset;
6894		int get;
6895
6896		if (sdp->isp_devparam[tgt].dev_enable == 0) {
6897			sdp->isp_devparam[tgt].dev_update = 0;
6898			sdp->isp_devparam[tgt].dev_refresh = 0;
6899			isp_prt(isp, ISP_LOGDEBUG0,
6900	 		    "skipping target %d bus %d update", tgt, bus);
6901			continue;
6902		}
6903		/*
6904		 * If the goal is to update the status of the device,
6905		 * take what's in goal_flags and try and set the device
6906		 * toward that. Otherwise, if we're just refreshing the
6907		 * current device state, get the current parameters.
6908		 */
6909
6910		MEMZERO(&mbs, sizeof (mbs));
6911
6912		/*
6913		 * Refresh overrides set
6914		 */
6915		if (sdp->isp_devparam[tgt].dev_refresh) {
6916			mbs.param[0] = MBOX_GET_TARGET_PARAMS;
6917			get = 1;
6918		} else if (sdp->isp_devparam[tgt].dev_update) {
6919			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
6920
6921			/*
6922			 * Make sure goal_flags has "Renegotiate on Error"
6923			 * on and "Freeze Queue on Error" off.
6924			 */
6925			sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
6926			sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
6927			mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
6928
6929			/*
6930			 * Insist that PARITY must be enabled
6931			 * if SYNC or WIDE is enabled.
6932			 */
6933			if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
6934				mbs.param[2] |= DPARM_PARITY;
6935			}
6936
6937			if (mbs.param[2] & DPARM_SYNC) {
6938				mbs.param[3] =
6939				    (sdp->isp_devparam[tgt].goal_offset << 8) |
6940				    (sdp->isp_devparam[tgt].goal_period);
6941			}
6942			/*
6943			 * A command completion later that has
6944			 * RQSTF_NEGOTIATION set can cause
6945			 * the dev_refresh/announce cycle also.
6946			 *
6947			 * Note: It is really important to update our current
6948			 * flags with at least the state of TAG capabilities-
6949			 * otherwise we might try and send a tagged command
6950			 * when we have it all turned off. So change it here
6951			 * to say that current already matches goal.
6952			 */
6953			sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
6954			sdp->isp_devparam[tgt].actv_flags |=
6955			    (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
6956			isp_prt(isp, ISP_LOGDEBUG0,
6957			    "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
6958			    bus, tgt, mbs.param[2], mbs.param[3] >> 8,
6959			    mbs.param[3] & 0xff);
6960			get = 0;
6961		} else {
6962			continue;
6963		}
6964		mbs.param[1] = (bus << 15) | (tgt << 8);
6965		mbs.logval = MBLOGALL;
6966		isp_mboxcmd(isp, &mbs);
6967		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
6968			continue;
6969		}
6970		if (get == 0) {
6971			isp->isp_sendmarker |= (1 << bus);
6972			sdp->isp_devparam[tgt].dev_update = 0;
6973			sdp->isp_devparam[tgt].dev_refresh = 1;
6974		} else {
6975			sdp->isp_devparam[tgt].dev_refresh = 0;
6976			flags = mbs.param[2];
6977			period = mbs.param[3] & 0xff;
6978			offset = mbs.param[3] >> 8;
6979			sdp->isp_devparam[tgt].actv_flags = flags;
6980			sdp->isp_devparam[tgt].actv_period = period;
6981			sdp->isp_devparam[tgt].actv_offset = offset;
6982			get = (bus << 16) | tgt;
6983			(void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get);
6984		}
6985	}
6986
6987	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
6988		if (sdp->isp_devparam[tgt].dev_update ||
6989		    sdp->isp_devparam[tgt].dev_refresh) {
6990			isp->isp_update |= (1 << bus);
6991			break;
6992		}
6993	}
6994}
6995
6996#ifndef	DEFAULT_EXEC_THROTTLE
6997#define	DEFAULT_EXEC_THROTTLE(isp)	ISP_EXEC_THROTTLE
6998#endif
6999
7000static void
7001isp_setdfltparm(ispsoftc_t *isp, int channel)
7002{
7003	int tgt;
7004	sdparam *sdp;
7005
7006	sdp = (sdparam *) isp->isp_param;
7007	sdp += channel;
7008
7009	/*
7010	 * Been there, done that, got the T-shirt...
7011	 */
7012	if (sdp->isp_gotdparms) {
7013		return;
7014	}
7015	sdp->isp_gotdparms = 1;
7016	sdp->isp_bad_nvram = 0;
7017	/*
7018	 * Establish some default parameters.
7019	 */
7020	sdp->isp_cmd_dma_burst_enable = 0;
7021	sdp->isp_data_dma_burst_enabl = 1;
7022	sdp->isp_fifo_threshold = 0;
7023	sdp->isp_initiator_id = DEFAULT_IID(isp);
7024	if (isp->isp_type >= ISP_HA_SCSI_1040) {
7025		sdp->isp_async_data_setup = 9;
7026	} else {
7027		sdp->isp_async_data_setup = 6;
7028	}
7029	sdp->isp_selection_timeout = 250;
7030	sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
7031	sdp->isp_tag_aging = 8;
7032	sdp->isp_bus_reset_delay = 5;
7033	/*
7034	 * Don't retry selection, busy or queue full automatically- reflect
7035	 * these back to us.
7036	 */
7037	sdp->isp_retry_count = 0;
7038	sdp->isp_retry_delay = 0;
7039
7040	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7041		sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
7042		sdp->isp_devparam[tgt].dev_enable = 1;
7043	}
7044
7045	/*
7046	 * If we've not been told to avoid reading NVRAM, try and read it.
7047	 * If we're successful reading it, we can then return because NVRAM
7048	 * will tell us what the desired settings are. Otherwise, we establish
7049	 * some reasonable 'fake' nvram and goal defaults.
7050	 */
7051
7052	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7053		if (isp_read_nvram(isp) == 0) {
7054			return;
7055		}
7056		sdp->isp_bad_nvram = 1;
7057	}
7058
7059	/*
7060	 * Now try and see whether we have specific values for them.
7061	 */
7062	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7063		mbreg_t mbs;
7064
7065		MEMZERO(&mbs, sizeof (mbs));
7066		mbs.param[0] = MBOX_GET_ACT_NEG_STATE;
7067		mbs.logval = MBLOGNONE;
7068		isp_mboxcmd(isp, &mbs);
7069		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7070			sdp->isp_req_ack_active_neg = 1;
7071			sdp->isp_data_line_active_neg = 1;
7072		} else {
7073			sdp->isp_req_ack_active_neg =
7074			    (mbs.param[1+channel] >> 4) & 0x1;
7075			sdp->isp_data_line_active_neg =
7076			    (mbs.param[1+channel] >> 5) & 0x1;
7077		}
7078	}
7079
7080	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc3,
7081	    0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
7082	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
7083	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
7084	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc3,
7085	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
7086	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
7087	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
7088
7089	/*
7090	 * The trick here is to establish a default for the default (honk!)
7091	 * state (goal_flags). Then try and get the current status from
7092	 * the card to fill in the current state. We don't, in fact, set
7093	 * the default to the SAFE default state- that's not the goal state.
7094	 */
7095	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7096		uint8_t off, per;
7097		sdp->isp_devparam[tgt].actv_offset = 0;
7098		sdp->isp_devparam[tgt].actv_period = 0;
7099		sdp->isp_devparam[tgt].actv_flags = 0;
7100
7101		sdp->isp_devparam[tgt].goal_flags =
7102		    sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
7103
7104		/*
7105		 * We default to Wide/Fast for versions less than a 1040
7106		 * (unless it's SBus).
7107		 */
7108		if (IS_ULTRA3(isp)) {
7109			off = ISP_80M_SYNCPARMS >> 8;
7110			per = ISP_80M_SYNCPARMS & 0xff;
7111		} else if (IS_ULTRA2(isp)) {
7112			off = ISP_40M_SYNCPARMS >> 8;
7113			per = ISP_40M_SYNCPARMS & 0xff;
7114		} else if (IS_1240(isp)) {
7115			off = ISP_20M_SYNCPARMS >> 8;
7116			per = ISP_20M_SYNCPARMS & 0xff;
7117		} else if ((isp->isp_bustype == ISP_BT_SBUS &&
7118		    isp->isp_type < ISP_HA_SCSI_1020A) ||
7119		    (isp->isp_bustype == ISP_BT_PCI &&
7120		    isp->isp_type < ISP_HA_SCSI_1040) ||
7121		    (isp->isp_clock && isp->isp_clock < 60) ||
7122		    (sdp->isp_ultramode == 0)) {
7123			off = ISP_10M_SYNCPARMS >> 8;
7124			per = ISP_10M_SYNCPARMS & 0xff;
7125		} else {
7126			off = ISP_20M_SYNCPARMS_1040 >> 8;
7127			per = ISP_20M_SYNCPARMS_1040 & 0xff;
7128		}
7129		sdp->isp_devparam[tgt].goal_offset =
7130		    sdp->isp_devparam[tgt].nvrm_offset = off;
7131		sdp->isp_devparam[tgt].goal_period =
7132		    sdp->isp_devparam[tgt].nvrm_period = per;
7133
7134		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc3,
7135		    channel, tgt, sdp->isp_devparam[tgt].nvrm_flags,
7136		    sdp->isp_devparam[tgt].nvrm_offset,
7137		    sdp->isp_devparam[tgt].nvrm_period);
7138	}
7139}
7140
7141#ifndef	DEFAULT_FRAMESIZE
7142#define	DEFAULT_FRAMESIZE(isp)		ICB_DFLT_FRMLEN
7143#endif
7144static void
7145isp_setdfltfcparm(ispsoftc_t *isp)
7146{
7147	fcparam *fcp = FCPARAM(isp);
7148
7149	if (fcp->isp_gotdparms) {
7150		return;
7151	}
7152	fcp->isp_gotdparms = 1;
7153	fcp->isp_bad_nvram = 0;
7154	fcp->isp_maxfrmlen = DEFAULT_FRAMESIZE(isp);
7155	fcp->isp_maxalloc = ICB_DFLT_ALLOC;
7156	fcp->isp_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
7157	fcp->isp_retry_delay = ICB_DFLT_RDELAY;
7158	fcp->isp_retry_count = ICB_DFLT_RCOUNT;
7159	/* Platform specific.... */
7160	fcp->isp_loopid = DEFAULT_LOOPID(isp);
7161	fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp);
7162	fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp);
7163	fcp->isp_fwoptions = 0;
7164	fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
7165	fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
7166	fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
7167	fcp->isp_fwoptions |= ICBOPT_FAST_POST;
7168	if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
7169		fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
7170	}
7171
7172	/*
7173	 * Make sure this is turned off now until we get
7174	 * extended options from NVRAM
7175	 */
7176	fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
7177
7178	/*
7179	 * Now try and read NVRAM unless told to not do so.
7180	 * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
7181	 */
7182	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7183		int i, j = 0;
7184		/*
7185		 * Give a couple of tries at reading NVRAM.
7186		 */
7187		for (i = 0; i < 2; i++) {
7188			j = isp_read_nvram(isp);
7189			if (j == 0) {
7190				break;
7191			}
7192		}
7193		if (j) {
7194			fcp->isp_bad_nvram = 1;
7195			isp->isp_confopts |= ISP_CFG_NONVRAM;
7196			isp->isp_confopts |= ISP_CFG_OWNWWPN;
7197			isp->isp_confopts |= ISP_CFG_OWNWWNN;
7198		}
7199	} else {
7200		isp->isp_confopts |= ISP_CFG_OWNWWPN|ISP_CFG_OWNWWNN;
7201	}
7202
7203	/*
7204	 * Set node && port to override platform set defaults
7205	 * unless the nvram read failed (or none was done),
7206	 * or the platform code wants to use what had been
7207	 * set in the defaults.
7208	 */
7209	if (isp->isp_confopts & ISP_CFG_OWNWWNN) {
7210		isp_prt(isp, ISP_LOGCONFIG, "Using Node WWN 0x%08x%08x",
7211		    (uint32_t) (DEFAULT_NODEWWN(isp) >> 32),
7212		    (uint32_t) (DEFAULT_NODEWWN(isp) & 0xffffffff));
7213		ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
7214	} else {
7215		/*
7216		 * We always start out with values derived
7217		 * from NVRAM or our platform default.
7218		 */
7219		ISP_NODEWWN(isp) = fcp->isp_wwnn_nvram;
7220		if (fcp->isp_wwnn_nvram == 0) {
7221			isp_prt(isp, ISP_LOGCONFIG,
7222			    "bad WWNN- using default");
7223			ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
7224		}
7225	}
7226	if (isp->isp_confopts & ISP_CFG_OWNWWPN) {
7227		isp_prt(isp, ISP_LOGCONFIG, "Using Port WWN 0x%08x%08x",
7228		    (uint32_t) (DEFAULT_PORTWWN(isp) >> 32),
7229		    (uint32_t) (DEFAULT_PORTWWN(isp) & 0xffffffff));
7230		ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
7231	} else {
7232		/*
7233		 * We always start out with values derived
7234		 * from NVRAM or our platform default.
7235		 */
7236		ISP_PORTWWN(isp) = fcp->isp_wwpn_nvram;
7237		if (fcp->isp_wwpn_nvram == 0) {
7238			isp_prt(isp, ISP_LOGCONFIG,
7239			    "bad WWPN- using default");
7240			ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
7241		}
7242	}
7243}
7244
7245/*
7246 * Re-initialize the ISP and complete all orphaned commands
7247 * with a 'botched' notice. The reset/init routines should
7248 * not disturb an already active list of commands.
7249 */
7250
7251void
7252isp_reinit(ispsoftc_t *isp)
7253{
7254	XS_T *xs;
7255	uint32_t tmp;
7256
7257	if (IS_FC(isp)) {
7258		ISP_MARK_PORTDB(isp, 0);
7259	}
7260	isp_reset(isp);
7261	if (isp->isp_state != ISP_RESETSTATE) {
7262		isp_prt(isp, ISP_LOGERR, "isp_reinit cannot reset card");
7263	} else if (isp->isp_role != ISP_ROLE_NONE) {
7264		isp_init(isp);
7265		if (isp->isp_state == ISP_INITSTATE) {
7266			isp->isp_state = ISP_RUNSTATE;
7267		}
7268		if (isp->isp_state != ISP_RUNSTATE) {
7269			isp_prt(isp, ISP_LOGERR,
7270			    "isp_reinit cannot restart card");
7271			ISP_DISABLE_INTS(isp);
7272		}
7273	} else {
7274		ISP_DISABLE_INTS(isp);
7275		if (IS_FC(isp)) {
7276			/*
7277			 * If we're in ISP_ROLE_NONE, turn off the lasers.
7278			 */
7279			if (!IS_24XX(isp)) {
7280				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
7281				ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
7282				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
7283				ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
7284				ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
7285			}
7286		}
7287 	}
7288	isp->isp_nactive = 0;
7289
7290	for (tmp = 0; tmp < isp->isp_maxcmds; tmp++) {
7291		uint32_t handle;
7292
7293		xs = isp->isp_xflist[tmp];
7294		if (xs == NULL) {
7295			continue;
7296		}
7297		handle = isp_find_handle(isp, xs);
7298		if (handle == 0) {
7299			continue;
7300		}
7301		isp_destroy_handle(isp, handle);
7302		if (XS_XFRLEN(xs)) {
7303			ISP_DMAFREE(isp, xs, handle);
7304			XS_RESID(xs) = XS_XFRLEN(xs);
7305		} else {
7306			XS_RESID(xs) = 0;
7307		}
7308		XS_SETERR(xs, HBA_BUSRESET);
7309		isp_done(xs);
7310	}
7311#ifdef	ISP_TARGET_MODE
7312	MEMZERO(isp->isp_tgtlist, isp->isp_maxcmds * sizeof (void **));
7313#endif
7314}
7315
7316/*
7317 * NVRAM Routines
7318 */
7319static int
7320isp_read_nvram(ispsoftc_t *isp)
7321{
7322	int i, amt, retval;
7323	uint8_t csum, minversion;
7324	union {
7325		uint8_t _x[ISP2100_NVRAM_SIZE];
7326		uint16_t _s[ISP2100_NVRAM_SIZE>>1];
7327	} _n;
7328#define	nvram_data	_n._x
7329#define	nvram_words	_n._s
7330
7331	if (IS_24XX(isp)) {
7332		return (isp_read_nvram_2400(isp));
7333	} else if (IS_FC(isp)) {
7334		amt = ISP2100_NVRAM_SIZE;
7335		minversion = 1;
7336	} else if (IS_ULTRA2(isp)) {
7337		amt = ISP1080_NVRAM_SIZE;
7338		minversion = 0;
7339	} else {
7340		amt = ISP_NVRAM_SIZE;
7341		minversion = 2;
7342	}
7343
7344	for (i = 0; i < amt>>1; i++) {
7345		isp_rdnvram_word(isp, i, &nvram_words[i]);
7346	}
7347
7348	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7349	    nvram_data[2] != 'P') {
7350		if (isp->isp_bustype != ISP_BT_SBUS) {
7351			isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
7352			isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x",
7353			    nvram_data[0], nvram_data[1], nvram_data[2]);
7354		}
7355		retval = -1;
7356		goto out;
7357	}
7358
7359	for (csum = 0, i = 0; i < amt; i++) {
7360		csum += nvram_data[i];
7361	}
7362	if (csum != 0) {
7363		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7364		retval = -1;
7365		goto out;
7366	}
7367
7368	if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
7369		isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
7370		    ISP_NVRAM_VERSION(nvram_data));
7371		retval = -1;
7372		goto out;
7373	}
7374
7375	if (IS_ULTRA3(isp)) {
7376		isp_parse_nvram_12160(isp, 0, nvram_data);
7377		if (IS_12160(isp))
7378			isp_parse_nvram_12160(isp, 1, nvram_data);
7379	} else if (IS_1080(isp)) {
7380		isp_parse_nvram_1080(isp, 0, nvram_data);
7381	} else if (IS_1280(isp) || IS_1240(isp)) {
7382		isp_parse_nvram_1080(isp, 0, nvram_data);
7383		isp_parse_nvram_1080(isp, 1, nvram_data);
7384	} else if (IS_SCSI(isp)) {
7385		isp_parse_nvram_1020(isp, nvram_data);
7386	} else {
7387		isp_parse_nvram_2100(isp, nvram_data);
7388	}
7389	retval = 0;
7390out:
7391	return (retval);
7392#undef	nvram_data
7393#undef	nvram_words
7394}
7395
7396static int
7397isp_read_nvram_2400(ispsoftc_t *isp)
7398{
7399	uint8_t *nvram_data = FCPARAM(isp)->isp_scratch;
7400	int retval = 0;
7401	uint32_t addr, csum, lwrds, *dptr;
7402
7403	if (isp->isp_port) {
7404		addr = ISP2400_NVRAM_PORT1_ADDR;
7405	} else {
7406		addr = ISP2400_NVRAM_PORT0_ADDR;
7407	}
7408
7409	dptr = (uint32_t *) nvram_data;
7410	for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7411		isp_rd_2400_nvram(isp, addr++, dptr++);
7412	}
7413	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7414	    nvram_data[2] != 'P') {
7415		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
7416		retval = -1;
7417		goto out;
7418	}
7419	dptr = (uint32_t *) nvram_data;
7420	for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7421		csum += dptr[lwrds];
7422	}
7423	if (csum != 0) {
7424		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7425		retval = -1;
7426		goto out;
7427	}
7428	isp_parse_nvram_2400(isp, nvram_data);
7429out:
7430	return (retval);
7431}
7432
7433static void
7434isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
7435{
7436	int i, cbits;
7437	uint16_t bit, rqst, junk;
7438
7439	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7440	USEC_DELAY(10);
7441	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7442	USEC_DELAY(10);
7443
7444	if (IS_FC(isp)) {
7445		wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
7446		if (IS_2312(isp) && isp->isp_port) {
7447			wo += 128;
7448		}
7449		rqst = (ISP_NVRAM_READ << 8) | wo;
7450		cbits = 10;
7451	} else if (IS_ULTRA2(isp)) {
7452		wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
7453		rqst = (ISP_NVRAM_READ << 8) | wo;
7454		cbits = 10;
7455	} else {
7456		wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
7457		rqst = (ISP_NVRAM_READ << 6) | wo;
7458		cbits = 8;
7459	}
7460
7461	/*
7462	 * Clock the word select request out...
7463	 */
7464	for (i = cbits; i >= 0; i--) {
7465		if ((rqst >> i) & 1) {
7466			bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
7467		} else {
7468			bit = BIU_NVRAM_SELECT;
7469		}
7470		ISP_WRITE(isp, BIU_NVRAM, bit);
7471		USEC_DELAY(10);
7472		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7473		ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
7474		USEC_DELAY(10);
7475		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7476		ISP_WRITE(isp, BIU_NVRAM, bit);
7477		USEC_DELAY(10);
7478		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7479	}
7480	/*
7481	 * Now read the result back in (bits come back in MSB format).
7482	 */
7483	*rp = 0;
7484	for (i = 0; i < 16; i++) {
7485		uint16_t rv;
7486		*rp <<= 1;
7487		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7488		USEC_DELAY(10);
7489		rv = ISP_READ(isp, BIU_NVRAM);
7490		if (rv & BIU_NVRAM_DATAIN) {
7491			*rp |= 1;
7492		}
7493		USEC_DELAY(10);
7494		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7495		USEC_DELAY(10);
7496		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7497	}
7498	ISP_WRITE(isp, BIU_NVRAM, 0);
7499	USEC_DELAY(10);
7500	junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7501	ISP_SWIZZLE_NVRAM_WORD(isp, rp);
7502}
7503
7504static void
7505isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
7506{
7507	int loops = 0;
7508	const uint32_t base = 0x7ffe0000;
7509	uint32_t tmp = 0;
7510
7511	ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
7512	for (loops = 0; loops < 5000; loops++) {
7513		USEC_DELAY(10);
7514		tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
7515		if ((tmp & (1U << 31)) != 0) {
7516			break;
7517		}
7518	}
7519	if (tmp & (1U << 31)) {
7520		tmp = ISP_READ(isp, BIU2400_FLASH_DATA);
7521		*rp = tmp;
7522	} else {
7523		*rp = 0xffffffff;
7524	}
7525}
7526
7527static void
7528isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data)
7529{
7530	sdparam *sdp = (sdparam *) isp->isp_param;
7531	int tgt;
7532
7533	sdp->isp_fifo_threshold =
7534		ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
7535		(ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
7536
7537	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
7538		sdp->isp_initiator_id =
7539			ISP_NVRAM_INITIATOR_ID(nvram_data);
7540
7541	sdp->isp_bus_reset_delay =
7542		ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
7543
7544	sdp->isp_retry_count =
7545		ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
7546
7547	sdp->isp_retry_delay =
7548		ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
7549
7550	sdp->isp_async_data_setup =
7551		ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
7552
7553	if (isp->isp_type >= ISP_HA_SCSI_1040) {
7554		if (sdp->isp_async_data_setup < 9) {
7555			sdp->isp_async_data_setup = 9;
7556		}
7557	} else {
7558		if (sdp->isp_async_data_setup != 6) {
7559			sdp->isp_async_data_setup = 6;
7560		}
7561	}
7562
7563	sdp->isp_req_ack_active_neg =
7564		ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
7565
7566	sdp->isp_data_line_active_neg =
7567		ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
7568
7569	sdp->isp_data_dma_burst_enabl =
7570		ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
7571
7572	sdp->isp_cmd_dma_burst_enable =
7573		ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
7574
7575	sdp->isp_tag_aging =
7576		ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
7577
7578	sdp->isp_selection_timeout =
7579		ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
7580
7581	sdp->isp_max_queue_depth =
7582		ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
7583
7584	sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
7585
7586	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
7587	    0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
7588	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
7589	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
7590	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
7591	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
7592	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
7593	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
7594
7595	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7596		sdp->isp_devparam[tgt].dev_enable =
7597			ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
7598		sdp->isp_devparam[tgt].exc_throttle =
7599			ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
7600		sdp->isp_devparam[tgt].nvrm_offset =
7601			ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
7602		sdp->isp_devparam[tgt].nvrm_period =
7603			ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
7604		/*
7605		 * We probably shouldn't lie about this, but it
7606		 * it makes it much safer if we limit NVRAM values
7607		 * to sanity.
7608		 */
7609		if (isp->isp_type < ISP_HA_SCSI_1040) {
7610			/*
7611			 * If we're not ultra, we can't possibly
7612			 * be a shorter period than this.
7613			 */
7614			if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
7615				sdp->isp_devparam[tgt].nvrm_period = 0x19;
7616			}
7617			if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
7618				sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
7619			}
7620		} else {
7621			if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
7622				sdp->isp_devparam[tgt].nvrm_offset = 0x8;
7623			}
7624		}
7625		sdp->isp_devparam[tgt].nvrm_flags = 0;
7626		if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
7627			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
7628		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
7629		if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
7630			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
7631		if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
7632			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
7633		if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
7634			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
7635		if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
7636			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
7637		if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
7638			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
7639		sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
7640		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
7641		    0, tgt, sdp->isp_devparam[tgt].nvrm_flags,
7642		    sdp->isp_devparam[tgt].nvrm_offset,
7643		    sdp->isp_devparam[tgt].nvrm_period);
7644		sdp->isp_devparam[tgt].goal_offset =
7645		    sdp->isp_devparam[tgt].nvrm_offset;
7646		sdp->isp_devparam[tgt].goal_period =
7647		    sdp->isp_devparam[tgt].nvrm_period;
7648		sdp->isp_devparam[tgt].goal_flags =
7649		    sdp->isp_devparam[tgt].nvrm_flags;
7650	}
7651}
7652
7653static void
7654isp_parse_nvram_1080(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
7655{
7656	sdparam *sdp = (sdparam *) isp->isp_param;
7657	int tgt;
7658
7659	sdp += bus;
7660
7661	sdp->isp_fifo_threshold =
7662	    ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
7663
7664	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
7665		sdp->isp_initiator_id =
7666		    ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
7667
7668	sdp->isp_bus_reset_delay =
7669	    ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
7670
7671	sdp->isp_retry_count =
7672	    ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
7673
7674	sdp->isp_retry_delay =
7675	    ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
7676
7677	sdp->isp_async_data_setup =
7678	    ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
7679
7680	sdp->isp_req_ack_active_neg =
7681	    ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
7682
7683	sdp->isp_data_line_active_neg =
7684	    ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
7685
7686	sdp->isp_data_dma_burst_enabl =
7687	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
7688
7689	sdp->isp_cmd_dma_burst_enable =
7690	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
7691
7692	sdp->isp_selection_timeout =
7693	    ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
7694
7695	sdp->isp_max_queue_depth =
7696	     ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
7697
7698	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
7699	    bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
7700	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
7701	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
7702	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
7703	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
7704	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
7705	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
7706
7707
7708	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7709		sdp->isp_devparam[tgt].dev_enable =
7710		    ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
7711		sdp->isp_devparam[tgt].exc_throttle =
7712			ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
7713		sdp->isp_devparam[tgt].nvrm_offset =
7714			ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
7715		sdp->isp_devparam[tgt].nvrm_period =
7716			ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
7717		sdp->isp_devparam[tgt].nvrm_flags = 0;
7718		if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
7719			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
7720		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
7721		if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
7722			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
7723		if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
7724			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
7725		if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
7726			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
7727		if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
7728			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
7729		if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
7730			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
7731		sdp->isp_devparam[tgt].actv_flags = 0;
7732		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
7733		    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
7734		    sdp->isp_devparam[tgt].nvrm_offset,
7735		    sdp->isp_devparam[tgt].nvrm_period);
7736		sdp->isp_devparam[tgt].goal_offset =
7737		    sdp->isp_devparam[tgt].nvrm_offset;
7738		sdp->isp_devparam[tgt].goal_period =
7739		    sdp->isp_devparam[tgt].nvrm_period;
7740		sdp->isp_devparam[tgt].goal_flags =
7741		    sdp->isp_devparam[tgt].nvrm_flags;
7742	}
7743}
7744
7745static void
7746isp_parse_nvram_12160(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
7747{
7748	sdparam *sdp = (sdparam *) isp->isp_param;
7749	int tgt;
7750
7751	sdp += bus;
7752
7753	sdp->isp_fifo_threshold =
7754	    ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
7755
7756	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
7757		sdp->isp_initiator_id =
7758		    ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
7759
7760	sdp->isp_bus_reset_delay =
7761	    ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
7762
7763	sdp->isp_retry_count =
7764	    ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
7765
7766	sdp->isp_retry_delay =
7767	    ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
7768
7769	sdp->isp_async_data_setup =
7770	    ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
7771
7772	sdp->isp_req_ack_active_neg =
7773	    ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
7774
7775	sdp->isp_data_line_active_neg =
7776	    ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
7777
7778	sdp->isp_data_dma_burst_enabl =
7779	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
7780
7781	sdp->isp_cmd_dma_burst_enable =
7782	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
7783
7784	sdp->isp_selection_timeout =
7785	    ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
7786
7787	sdp->isp_max_queue_depth =
7788	     ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
7789
7790	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
7791	    bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
7792	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
7793	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
7794	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
7795	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
7796	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
7797	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
7798
7799	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7800		sdp->isp_devparam[tgt].dev_enable =
7801		    ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
7802		sdp->isp_devparam[tgt].exc_throttle =
7803			ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
7804		sdp->isp_devparam[tgt].nvrm_offset =
7805			ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
7806		sdp->isp_devparam[tgt].nvrm_period =
7807			ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
7808		sdp->isp_devparam[tgt].nvrm_flags = 0;
7809		if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
7810			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
7811		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
7812		if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
7813			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
7814		if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
7815			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
7816		if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
7817			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
7818		if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
7819			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
7820		if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
7821			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
7822		sdp->isp_devparam[tgt].actv_flags = 0;
7823		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
7824		    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
7825		    sdp->isp_devparam[tgt].nvrm_offset,
7826		    sdp->isp_devparam[tgt].nvrm_period);
7827		sdp->isp_devparam[tgt].goal_offset =
7828		    sdp->isp_devparam[tgt].nvrm_offset;
7829		sdp->isp_devparam[tgt].goal_period =
7830		    sdp->isp_devparam[tgt].nvrm_period;
7831		sdp->isp_devparam[tgt].goal_flags =
7832		    sdp->isp_devparam[tgt].nvrm_flags;
7833	}
7834}
7835
7836static void
7837isp_fix_nvram_wwns(ispsoftc_t *isp)
7838{
7839	fcparam *fcp = FCPARAM(isp);
7840
7841	/*
7842	 * Make sure we have both Node and Port as non-zero values.
7843	 */
7844	if (fcp->isp_wwnn_nvram != 0 && fcp->isp_wwpn_nvram == 0) {
7845		fcp->isp_wwpn_nvram = fcp->isp_wwnn_nvram;
7846	} else if (fcp->isp_wwnn_nvram == 0 && fcp->isp_wwpn_nvram != 0) {
7847		fcp->isp_wwnn_nvram = fcp->isp_wwpn_nvram;
7848	}
7849
7850	/*
7851	 * Make the Node and Port values sane if they're NAA == 2.
7852	 * This means to clear bits 48..56 for the Node WWN and
7853	 * make sure that there's some non-zero value in 48..56
7854	 * for the Port WWN.
7855	 */
7856	if (fcp->isp_wwnn_nvram && fcp->isp_wwpn_nvram) {
7857		if ((fcp->isp_wwnn_nvram & (((uint64_t) 0xfff) << 48)) != 0 &&
7858		    (fcp->isp_wwnn_nvram >> 60) == 2) {
7859			fcp->isp_wwnn_nvram &= ~((uint64_t) 0xfff << 48);
7860		}
7861		if ((fcp->isp_wwpn_nvram & (((uint64_t) 0xfff) << 48)) == 0 &&
7862		    (fcp->isp_wwpn_nvram >> 60) == 2) {
7863			fcp->isp_wwpn_nvram |= ((uint64_t) 1 << 56);
7864		}
7865	}
7866}
7867
7868static void
7869isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
7870{
7871	fcparam *fcp = FCPARAM(isp);
7872	uint64_t wwn;
7873
7874	/*
7875	 * There is NVRAM storage for both Port and Node entities-
7876	 * but the Node entity appears to be unused on all the cards
7877	 * I can find. However, we should account for this being set
7878	 * at some point in the future.
7879	 *
7880	 * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
7881	 * bits 48..60. In the case of the 2202, it appears that they do
7882	 * use bit 48 to distinguish between the two instances on the card.
7883	 * The 2204, which I've never seen, *probably* extends this method.
7884	 */
7885	wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
7886	if (wwn) {
7887		isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
7888		    (uint32_t) (wwn >> 32), (uint32_t) (wwn & 0xffffffff));
7889		if ((wwn >> 60) == 0) {
7890			wwn |= (((uint64_t) 2)<< 60);
7891		}
7892	}
7893	fcp->isp_wwpn_nvram = wwn;
7894	if (IS_2200(isp) || IS_23XX(isp)) {
7895		wwn = ISP2100_NVRAM_NODE_NAME(nvram_data);
7896		if (wwn) {
7897			isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
7898			    (uint32_t) (wwn >> 32),
7899			    (uint32_t) (wwn & 0xffffffff));
7900			if ((wwn >> 60) == 0) {
7901				wwn |= (((uint64_t) 2)<< 60);
7902			}
7903		}
7904	} else {
7905		wwn &= ~((uint64_t) 0xfff << 48);
7906	}
7907	fcp->isp_wwnn_nvram = wwn;
7908
7909	isp_fix_nvram_wwns(isp);
7910
7911	fcp->isp_maxalloc = ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
7912	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
7913		fcp->isp_maxfrmlen = ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
7914	}
7915	fcp->isp_retry_delay = ISP2100_NVRAM_RETRY_DELAY(nvram_data);
7916	fcp->isp_retry_count = ISP2100_NVRAM_RETRY_COUNT(nvram_data);
7917	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
7918		fcp->isp_loopid = ISP2100_NVRAM_HARDLOOPID(nvram_data);
7919	}
7920	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
7921		fcp->isp_execthrottle =
7922			ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
7923	}
7924	fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
7925	isp_prt(isp, ISP_LOGDEBUG0,
7926	    "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d",
7927	    (uint32_t) (fcp->isp_wwnn_nvram >> 32), (uint32_t) fcp->isp_wwnn_nvram,
7928	    (uint32_t) (fcp->isp_wwpn_nvram >> 32), (uint32_t) fcp->isp_wwpn_nvram,
7929	    ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data),
7930	    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data));
7931	isp_prt(isp, ISP_LOGDEBUG0,
7932	    "execthrottle %d fwoptions 0x%x hardloop %d tov %d",
7933	    ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
7934	    ISP2100_NVRAM_OPTIONS(nvram_data),
7935	    ISP2100_NVRAM_HARDLOOPID(nvram_data),
7936	    ISP2100_NVRAM_TOV(nvram_data));
7937	fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data);
7938	fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data);
7939	isp_prt(isp, ISP_LOGDEBUG0,
7940	    "xfwoptions 0x%x zfw options 0x%x",
7941	    ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data));
7942}
7943
7944static void
7945isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
7946{
7947	fcparam *fcp = FCPARAM(isp);
7948	uint64_t wwn;
7949
7950	isp_prt(isp, ISP_LOGDEBUG0,
7951	    "NVRAM 0x%08x%08x 0x%08x%08x exchg_cnt %d maxframelen %d",
7952	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
7953	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
7954	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
7955	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
7956	    ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data),
7957	    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
7958	isp_prt(isp, ISP_LOGDEBUG0,
7959	    "NVRAM execthr %d loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
7960	    ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data),
7961	    ISP2400_NVRAM_HARDLOOPID(nvram_data),
7962	    ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
7963	    ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
7964	    ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
7965
7966	wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
7967	if (wwn) {
7968		if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
7969			wwn = 0;
7970		}
7971	}
7972	fcp->isp_wwpn_nvram = wwn;
7973
7974	wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
7975	if (wwn) {
7976		if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
7977			wwn = 0;
7978		}
7979	}
7980	fcp->isp_wwnn_nvram = wwn;
7981
7982	isp_fix_nvram_wwns(isp);
7983
7984	if (ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data)) {
7985		fcp->isp_maxalloc = ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data);
7986	}
7987	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
7988		fcp->isp_maxfrmlen = ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
7989	}
7990	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
7991		fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
7992	}
7993	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
7994		fcp->isp_execthrottle =
7995			ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data);
7996	}
7997	fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
7998	fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
7999	fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
8000}
8001
8002#ifdef	ISP_FW_CRASH_DUMP
8003static void isp2200_fw_dump(ispsoftc_t *);
8004static void isp2300_fw_dump(ispsoftc_t *);
8005
8006static void
8007isp2200_fw_dump(ispsoftc_t *isp)
8008{
8009	int i, j;
8010	mbreg_t mbs;
8011	uint16_t *ptr;
8012
8013	MEMZERO(&mbs, sizeof (mbs));
8014	ptr = FCPARAM(isp)->isp_dump_data;
8015	if (ptr == NULL) {
8016		isp_prt(isp, ISP_LOGERR,
8017		   "No place to dump RISC registers and SRAM");
8018		return;
8019	}
8020	if (*ptr++) {
8021		isp_prt(isp, ISP_LOGERR,
8022		   "dump area for RISC registers and SRAM already used");
8023		return;
8024	}
8025	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
8026	for (i = 0; i < 100; i++) {
8027		USEC_DELAY(100);
8028		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
8029			break;
8030		}
8031	}
8032	if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
8033		/*
8034		 * PBIU Registers
8035		 */
8036		for (i = 0; i < 8; i++) {
8037			*ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
8038		}
8039
8040		/*
8041		 * Mailbox Registers
8042		 */
8043		for (i = 0; i < 8; i++) {
8044			*ptr++ = ISP_READ(isp, MBOX_BLOCK + (i << 1));
8045		}
8046
8047		/*
8048		 * DMA Registers
8049		 */
8050		for (i = 0; i < 48; i++) {
8051			*ptr++ = ISP_READ(isp, DMA_BLOCK + 0x20 + (i << 1));
8052		}
8053
8054		/*
8055		 * RISC H/W Registers
8056		 */
8057		ISP_WRITE(isp, BIU2100_CSR, 0);
8058		for (i = 0; i < 16; i++) {
8059			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
8060		}
8061
8062		/*
8063		 * RISC GP Registers
8064		 */
8065		for (j = 0; j < 8; j++) {
8066			ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 8));
8067			for (i = 0; i < 16; i++) {
8068				*ptr++ =
8069				    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8070			}
8071		}
8072
8073		/*
8074		 * Frame Buffer Hardware Registers
8075		 */
8076		ISP_WRITE(isp, BIU2100_CSR, 0x10);
8077		for (i = 0; i < 16; i++) {
8078			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8079		}
8080
8081		/*
8082		 * Fibre Protocol Module 0 Hardware Registers
8083		 */
8084		ISP_WRITE(isp, BIU2100_CSR, 0x20);
8085		for (i = 0; i < 64; i++) {
8086			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8087		}
8088
8089		/*
8090		 * Fibre Protocol Module 1 Hardware Registers
8091		 */
8092		ISP_WRITE(isp, BIU2100_CSR, 0x30);
8093		for (i = 0; i < 64; i++) {
8094			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8095		}
8096	} else {
8097		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
8098		return;
8099	}
8100	isp_prt(isp, ISP_LOGALL,
8101	   "isp_fw_dump: RISC registers dumped successfully");
8102	ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
8103	for (i = 0; i < 100; i++) {
8104		USEC_DELAY(100);
8105		if (ISP_READ(isp, OUTMAILBOX0) == 0) {
8106			break;
8107		}
8108	}
8109	if (ISP_READ(isp, OUTMAILBOX0) != 0) {
8110		isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
8111		return;
8112	}
8113	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
8114	for (i = 0; i < 100; i++) {
8115		USEC_DELAY(100);
8116		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
8117			break;
8118		}
8119	}
8120	if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
8121		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause After Reset");
8122		return;
8123	}
8124	ISP_WRITE(isp, RISC_EMB, 0xf2);
8125	ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
8126	for (i = 0; i < 100; i++) {
8127		USEC_DELAY(100);
8128		if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
8129			break;
8130		}
8131	}
8132	ISP_ENABLE_INTS(isp);
8133	mbs.param[0] = MBOX_READ_RAM_WORD;
8134	mbs.param[1] = 0x1000;
8135	isp->isp_mbxworkp = (void *) ptr;
8136	isp->isp_mbxwrk0 = 0xefff;	/* continuation count */
8137	isp->isp_mbxwrk1 = 0x1001;	/* next SRAM address */
8138	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
8139	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
8140		isp_prt(isp, ISP_LOGWARN,
8141		    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
8142		return;
8143	}
8144	ptr = isp->isp_mbxworkp;	/* finish fetch of final word */
8145	*ptr++ = isp->isp_mboxtmp[2];
8146	isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped successfully");
8147	FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
8148	(void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
8149}
8150
8151static void
8152isp2300_fw_dump(ispsoftc_t *isp)
8153{
8154	int i, j;
8155	mbreg_t mbs;
8156	uint16_t *ptr;
8157
8158	MEMZERO(&mbs, sizeof (mbs));
8159	ptr = FCPARAM(isp)->isp_dump_data;
8160	if (ptr == NULL) {
8161		isp_prt(isp, ISP_LOGERR,
8162		   "No place to dump RISC registers and SRAM");
8163		return;
8164	}
8165	if (*ptr++) {
8166		isp_prt(isp, ISP_LOGERR,
8167		   "dump area for RISC registers and SRAM already used");
8168		return;
8169	}
8170	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
8171	for (i = 0; i < 100; i++) {
8172		USEC_DELAY(100);
8173		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
8174			break;
8175		}
8176	}
8177	if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
8178		/*
8179		 * PBIU registers
8180		 */
8181		for (i = 0; i < 8; i++) {
8182			*ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
8183		}
8184
8185		/*
8186		 * ReqQ-RspQ-Risc2Host Status registers
8187		 */
8188		for (i = 0; i < 8; i++) {
8189			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x10 + (i << 1));
8190		}
8191
8192		/*
8193		 * Mailbox Registers
8194		 */
8195		for (i = 0; i < 32; i++) {
8196			*ptr++ =
8197			    ISP_READ(isp, PCI_MBOX_REGS2300_OFF + (i << 1));
8198		}
8199
8200		/*
8201		 * Auto Request Response DMA registers
8202		 */
8203		ISP_WRITE(isp, BIU2100_CSR, 0x40);
8204		for (i = 0; i < 32; i++) {
8205			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8206		}
8207
8208		/*
8209		 * DMA registers
8210		 */
8211		ISP_WRITE(isp, BIU2100_CSR, 0x50);
8212		for (i = 0; i < 48; i++) {
8213			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8214		}
8215
8216		/*
8217		 * RISC hardware registers
8218		 */
8219		ISP_WRITE(isp, BIU2100_CSR, 0);
8220		for (i = 0; i < 16; i++) {
8221			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
8222		}
8223
8224		/*
8225		 * RISC GP? registers
8226		 */
8227		for (j = 0; j < 8; j++) {
8228			ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 9));
8229			for (i = 0; i < 16; i++) {
8230				*ptr++ =
8231				    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8232			}
8233		}
8234
8235		/*
8236		 * frame buffer hardware registers
8237		 */
8238		ISP_WRITE(isp, BIU2100_CSR, 0x10);
8239		for (i = 0; i < 64; i++) {
8240			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8241		}
8242
8243		/*
8244		 * FPM B0 hardware registers
8245		 */
8246		ISP_WRITE(isp, BIU2100_CSR, 0x20);
8247		for (i = 0; i < 64; i++) {
8248			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8249		}
8250
8251		/*
8252		 * FPM B1 hardware registers
8253		 */
8254		ISP_WRITE(isp, BIU2100_CSR, 0x30);
8255		for (i = 0; i < 64; i++) {
8256			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8257		}
8258	} else {
8259		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
8260		return;
8261	}
8262	isp_prt(isp, ISP_LOGALL,
8263	   "isp_fw_dump: RISC registers dumped successfully");
8264	ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
8265	for (i = 0; i < 100; i++) {
8266		USEC_DELAY(100);
8267		if (ISP_READ(isp, OUTMAILBOX0) == 0) {
8268			break;
8269		}
8270	}
8271	if (ISP_READ(isp, OUTMAILBOX0) != 0) {
8272		isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
8273		return;
8274	}
8275	ISP_ENABLE_INTS(isp);
8276	MEMZERO(&mbs, sizeof (mbs));
8277	mbs.param[0] = MBOX_READ_RAM_WORD;
8278	mbs.param[1] = 0x800;
8279	isp->isp_mbxworkp = (void *) ptr;
8280	isp->isp_mbxwrk0 = 0xf7ff;	/* continuation count */
8281	isp->isp_mbxwrk1 = 0x801;	/* next SRAM address */
8282	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
8283	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
8284		isp_prt(isp, ISP_LOGWARN,
8285		    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
8286		return;
8287	}
8288	ptr = isp->isp_mbxworkp;	/* finish fetch of final word */
8289	*ptr++ = isp->isp_mboxtmp[2];
8290	MEMZERO(&mbs, sizeof (mbs));
8291	mbs.param[0] = MBOX_READ_RAM_WORD_EXTENDED;
8292	mbs.param[8] = 1;
8293	isp->isp_mbxworkp = (void *) ptr;
8294	isp->isp_mbxwrk0 = 0xffff;	/* continuation count */
8295	isp->isp_mbxwrk1 = 0x1;		/* next SRAM address */
8296	isp->isp_mbxwrk8 = 0x1;
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", 0x10000 + isp->isp_mbxwrk1);
8301		return;
8302	}
8303	ptr = isp->isp_mbxworkp;	/* finish final word */
8304	*ptr++ = mbs.param[2];
8305	isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped successfully");
8306	FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
8307	(void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
8308}
8309
8310void
8311isp_fw_dump(ispsoftc_t *isp)
8312{
8313	if (IS_2200(isp))
8314		isp2200_fw_dump(isp);
8315	else if (IS_23XX(isp))
8316		isp2300_fw_dump(isp);
8317	else if (IS_24XX(isp))
8318		isp_prt(isp, ISP_LOGERR, "24XX dump method undefined");
8319
8320}
8321#endif
8322