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