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