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