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