isp.c revision 103819
1/* $FreeBSD: head/sys/dev/isp/isp.c 103819 2002-09-23 04:59:42Z mjacob $ */
2/*
3 * Machine and OS Independent (well, as best as possible)
4 * code for the Qlogic ISP SCSI adapters.
5 *
6 * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob
7 * Feral Software
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice immediately at the beginning of the file, without modification,
15 *    this list of conditions, and the following disclaimer.
16 * 2. The name of the author may not be used to endorse or promote products
17 *    derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
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
42#ifdef	__NetBSD__
43#include <dev/ic/isp_netbsd.h>
44#endif
45#ifdef	__FreeBSD__
46#include <dev/isp/isp_freebsd.h>
47#endif
48#ifdef	__OpenBSD__
49#include <dev/ic/isp_openbsd.h>
50#endif
51#ifdef	__linux__
52#include "isp_linux.h"
53#endif
54#ifdef	__svr4__
55#include "isp_solaris.h"
56#endif
57
58/*
59 * General defines
60 */
61
62#define	MBOX_DELAY_COUNT	1000000 / 100
63
64/*
65 * Local static data
66 */
67static const char portshift[] =
68    "Target %d Loop ID 0x%x (Port 0x%x) => Loop 0x%x (Port 0x%x)";
69static const char portdup[] =
70    "Target %d duplicates Target %d- killing off both";
71static const char retained[] =
72    "Retaining Loop ID 0x%x for Target %d (Port 0x%x)";
73static const char lretained[] =
74    "Retained login of Target %d (Loop ID 0x%x) Port 0x%x";
75static const char plogout[] =
76    "Logging out Target %d at Loop ID 0x%x (Port 0x%x)";
77static const char plogierr[] =
78    "Command Error in PLOGI for Port 0x%x (0x%x)";
79static const char nopdb[] =
80    "Could not get PDB for Device @ Port 0x%x";
81static const char pdbmfail1[] =
82    "PDB Loop ID info for Device @ Port 0x%x does not match up (0x%x)";
83static const char pdbmfail2[] =
84    "PDB Port info for Device @ Port 0x%x does not match up (0x%x)";
85static const char ldumped[] =
86    "Target %d (Loop ID 0x%x) Port 0x%x dumped after login info mismatch";
87static const char notresp[] =
88  "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
89static const char xact1[] =
90    "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
91static const char xact2[] =
92    "HBA attempted queued transaction to target routine %d on target %d bus %d";
93static const char xact3[] =
94    "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
95static const char pskip[] =
96    "SCSI phase skipped for target %d.%d.%d";
97static const char topology[] =
98    "Loop ID %d, AL_PA 0x%x, Port ID 0x%x, Loop State 0x%x, Topology '%s'";
99static const char swrej[] =
100    "Fabric Nameserver rejected %s (Reason=0x%x Expl=0x%x) for Port ID 0x%x";
101static const char finmsg[] =
102    "(%d.%d.%d): FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x";
103static const char sc0[] =
104    "%s CHAN %d FTHRSH %d IID %d RESETD %d RETRYC %d RETRYD %d ASD 0x%x";
105static const char sc1[] =
106    "%s RAAN 0x%x DLAN 0x%x DDMAB 0x%x CDMAB 0x%x SELTIME %d MQD %d";
107static const char sc2[] = "%s CHAN %d TGT %d FLAGS 0x%x 0x%x/0x%x";
108static const char sc3[] = "Generated";
109static const char sc4[] = "NVRAM";
110static const char bun[] =
111    "bad underrun for %d.%d (count %d, resid %d, status %s)";
112
113/*
114 * Local function prototypes.
115 */
116static int isp_parse_async(struct ispsoftc *, u_int16_t);
117static int isp_handle_other_response(struct ispsoftc *, int, isphdr_t *,
118    u_int16_t *);
119static void
120isp_parse_status(struct ispsoftc *, ispstatusreq_t *, XS_T *);
121static void isp_fastpost_complete(struct ispsoftc *, u_int16_t);
122static int isp_mbox_continue(struct ispsoftc *);
123static void isp_scsi_init(struct ispsoftc *);
124static void isp_scsi_channel_init(struct ispsoftc *, int);
125static void isp_fibre_init(struct ispsoftc *);
126static void isp_mark_getpdb_all(struct ispsoftc *);
127static int isp_getmap(struct ispsoftc *, fcpos_map_t *);
128static int isp_getpdb(struct ispsoftc *, int, isp_pdb_t *);
129static u_int64_t isp_get_portname(struct ispsoftc *, int, int);
130static int isp_fclink_test(struct ispsoftc *, int);
131static char *isp2100_fw_statename(int);
132static int isp_pdb_sync(struct ispsoftc *);
133static int isp_scan_loop(struct ispsoftc *);
134static int isp_fabric_mbox_cmd(struct ispsoftc *, mbreg_t *);
135static int isp_scan_fabric(struct ispsoftc *, int);
136static void isp_register_fc4_type(struct ispsoftc *);
137static void isp_fw_state(struct ispsoftc *);
138static void isp_mboxcmd_qnw(struct ispsoftc *, mbreg_t *, int);
139static void isp_mboxcmd(struct ispsoftc *, mbreg_t *, int);
140
141static void isp_update(struct ispsoftc *);
142static void isp_update_bus(struct ispsoftc *, int);
143static void isp_setdfltparm(struct ispsoftc *, int);
144static int isp_read_nvram(struct ispsoftc *);
145static void isp_rdnvram_word(struct ispsoftc *, int, u_int16_t *);
146static void isp_parse_nvram_1020(struct ispsoftc *, u_int8_t *);
147static void isp_parse_nvram_1080(struct ispsoftc *, int, u_int8_t *);
148static void isp_parse_nvram_12160(struct ispsoftc *, int, u_int8_t *);
149static void isp_parse_nvram_2100(struct ispsoftc *, u_int8_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(struct ispsoftc *isp)
161{
162	mbreg_t mbs;
163	u_int16_t code_org;
164	int loops, i, dodnld = 1;
165	char *btype = "????";
166
167	isp->isp_state = ISP_NILSTATE;
168
169	/*
170	 * Basic types (SCSI, FibreChannel and PCI or SBus)
171	 * have been set in the MD code. We figure out more
172	 * here. Possibly more refined types based upon PCI
173	 * identification. Chip revision has been gathered.
174	 *
175	 * After we've fired this chip up, zero out the conf1 register
176	 * for SCSI adapters and do other settings for the 2100.
177	 */
178
179	/*
180	 * Get the current running firmware revision out of the
181	 * chip before we hit it over the head (if this is our
182	 * first time through). Note that we store this as the
183	 * 'ROM' firmware revision- which it may not be. In any
184	 * case, we don't really use this yet, but we may in
185	 * the future.
186	 */
187	if (isp->isp_touched == 0) {
188		/*
189		 * First see whether or not we're sitting in the ISP PROM.
190		 * If we've just been reset, we'll have the string "ISP   "
191		 * spread through outgoing mailbox registers 1-3. We do
192		 * this for PCI cards because otherwise we really don't
193		 * know what state the card is in and we could hang if
194		 * we try this command otherwise.
195		 *
196		 * For SBus cards, we just do this because they almost
197		 * certainly will be running firmware by now.
198		 */
199		if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 ||
200		    ISP_READ(isp, OUTMAILBOX2) != 0x5020 ||
201		    ISP_READ(isp, OUTMAILBOX3) != 0x2020) {
202			/*
203			 * Just in case it was paused...
204			 */
205			ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
206			mbs.param[0] = MBOX_ABOUT_FIRMWARE;
207			isp_mboxcmd(isp, &mbs, MBLOGNONE);
208			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
209				isp->isp_romfw_rev[0] = mbs.param[1];
210				isp->isp_romfw_rev[1] = mbs.param[2];
211				isp->isp_romfw_rev[2] = mbs.param[3];
212			}
213		}
214		isp->isp_touched = 1;
215	}
216
217	DISABLE_INTS(isp);
218
219	/*
220	 * Set up default request/response queue in-pointer/out-pointer
221	 * register indices.
222	 */
223	if (IS_23XX(isp)) {
224		isp->isp_rqstinrp = BIU_REQINP;
225		isp->isp_rqstoutrp = BIU_REQOUTP;
226		isp->isp_respinrp = BIU_RSPINP;
227		isp->isp_respoutrp = BIU_RSPOUTP;
228	} else {
229		isp->isp_rqstinrp = INMAILBOX4;
230		isp->isp_rqstoutrp = OUTMAILBOX4;
231		isp->isp_respinrp = OUTMAILBOX5;
232		isp->isp_respoutrp = INMAILBOX5;
233	}
234
235	/*
236	 * Put the board into PAUSE mode (so we can read the SXP registers
237	 * or write FPM/FBM registers).
238	 */
239	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
240
241	if (IS_FC(isp)) {
242		switch (isp->isp_type) {
243		case ISP_HA_FC_2100:
244			btype = "2100";
245			break;
246		case ISP_HA_FC_2200:
247			btype = "2200";
248			break;
249		case ISP_HA_FC_2300:
250			btype = "2300";
251			break;
252		case ISP_HA_FC_2312:
253			btype = "2312";
254			break;
255		default:
256			break;
257		}
258		/*
259		 * While we're paused, reset the FPM module and FBM fifos.
260		 */
261		ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
262		ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
263		ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
264		ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
265		ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
266	} else if (IS_1240(isp)) {
267		sdparam *sdp = isp->isp_param;
268		btype = "1240";
269		isp->isp_clock = 60;
270		sdp->isp_ultramode = 1;
271		sdp++;
272		sdp->isp_ultramode = 1;
273		/*
274		 * XXX: Should probably do some bus sensing.
275		 */
276	} else if (IS_ULTRA2(isp)) {
277		static const char m[] = "bus %d is in %s Mode";
278		u_int16_t l;
279		sdparam *sdp = isp->isp_param;
280
281		isp->isp_clock = 100;
282
283		if (IS_1280(isp))
284			btype = "1280";
285		else if (IS_1080(isp))
286			btype = "1080";
287		else if (IS_12160(isp))
288			btype = "12160";
289		else
290			btype = "<UNKLVD>";
291
292		l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
293		switch (l) {
294		case ISP1080_LVD_MODE:
295			sdp->isp_lvdmode = 1;
296			isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD");
297			break;
298		case ISP1080_HVD_MODE:
299			sdp->isp_diffmode = 1;
300			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential");
301			break;
302		case ISP1080_SE_MODE:
303			sdp->isp_ultramode = 1;
304			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended");
305			break;
306		default:
307			isp_prt(isp, ISP_LOGERR,
308			    "unknown mode on bus %d (0x%x)", 0, l);
309			break;
310		}
311
312		if (IS_DUALBUS(isp)) {
313			sdp++;
314			l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
315			l &= ISP1080_MODE_MASK;
316			switch(l) {
317			case ISP1080_LVD_MODE:
318				sdp->isp_lvdmode = 1;
319				isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
320				break;
321			case ISP1080_HVD_MODE:
322				sdp->isp_diffmode = 1;
323				isp_prt(isp, ISP_LOGCONFIG,
324				    m, 1, "Differential");
325				break;
326			case ISP1080_SE_MODE:
327				sdp->isp_ultramode = 1;
328				isp_prt(isp, ISP_LOGCONFIG,
329				    m, 1, "Single-Ended");
330				break;
331			default:
332				isp_prt(isp, ISP_LOGERR,
333				    "unknown mode on bus %d (0x%x)", 1, l);
334				break;
335			}
336		}
337	} else {
338		sdparam *sdp = isp->isp_param;
339		i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
340		switch (i) {
341		default:
342			isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
343			/* FALLTHROUGH */
344		case 1:
345			btype = "1020";
346			isp->isp_type = ISP_HA_SCSI_1020;
347			isp->isp_clock = 40;
348			break;
349		case 2:
350			/*
351			 * Some 1020A chips are Ultra Capable, but don't
352			 * run the clock rate up for that unless told to
353			 * do so by the Ultra Capable bits being set.
354			 */
355			btype = "1020A";
356			isp->isp_type = ISP_HA_SCSI_1020A;
357			isp->isp_clock = 40;
358			break;
359		case 3:
360			btype = "1040";
361			isp->isp_type = ISP_HA_SCSI_1040;
362			isp->isp_clock = 60;
363			break;
364		case 4:
365			btype = "1040A";
366			isp->isp_type = ISP_HA_SCSI_1040A;
367			isp->isp_clock = 60;
368			break;
369		case 5:
370			btype = "1040B";
371			isp->isp_type = ISP_HA_SCSI_1040B;
372			isp->isp_clock = 60;
373			break;
374		case 6:
375			btype = "1040C";
376			isp->isp_type = ISP_HA_SCSI_1040C;
377			isp->isp_clock = 60;
378                        break;
379		}
380		/*
381		 * Now, while we're at it, gather info about ultra
382		 * and/or differential mode.
383		 */
384		if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
385			isp_prt(isp, ISP_LOGCONFIG, "Differential Mode");
386			sdp->isp_diffmode = 1;
387		} else {
388			sdp->isp_diffmode = 0;
389		}
390		i = ISP_READ(isp, RISC_PSR);
391		if (isp->isp_bustype == ISP_BT_SBUS) {
392			i &= RISC_PSR_SBUS_ULTRA;
393		} else {
394			i &= RISC_PSR_PCI_ULTRA;
395		}
396		if (i != 0) {
397			isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable");
398			sdp->isp_ultramode = 1;
399			/*
400			 * If we're in Ultra Mode, we have to be 60Mhz clock-
401			 * even for the SBus version.
402			 */
403			isp->isp_clock = 60;
404		} else {
405			sdp->isp_ultramode = 0;
406			/*
407			 * Clock is known. Gronk.
408			 */
409		}
410
411		/*
412		 * Machine dependent clock (if set) overrides
413		 * our generic determinations.
414		 */
415		if (isp->isp_mdvec->dv_clock) {
416			if (isp->isp_mdvec->dv_clock < isp->isp_clock) {
417				isp->isp_clock = isp->isp_mdvec->dv_clock;
418			}
419		}
420
421	}
422
423	/*
424	 * Clear instrumentation
425	 */
426	isp->isp_intcnt = isp->isp_intbogus = 0;
427
428	/*
429	 * Do MD specific pre initialization
430	 */
431	ISP_RESET0(isp);
432
433again:
434
435	/*
436	 * Hit the chip over the head with hammer,
437	 * and give the ISP a chance to recover.
438	 */
439
440	if (IS_SCSI(isp)) {
441		ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
442		/*
443		 * A slight delay...
444		 */
445		USEC_DELAY(100);
446
447		/*
448		 * Clear data && control DMA engines.
449		 */
450		ISP_WRITE(isp, CDMA_CONTROL,
451		    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
452		ISP_WRITE(isp, DDMA_CONTROL,
453		    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
454
455
456	} else {
457		ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
458		/*
459		 * A slight delay...
460		 */
461		USEC_DELAY(100);
462
463		/*
464		 * Clear data && control DMA engines.
465		 */
466		ISP_WRITE(isp, CDMA2100_CONTROL,
467			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
468		ISP_WRITE(isp, TDMA2100_CONTROL,
469			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
470		ISP_WRITE(isp, RDMA2100_CONTROL,
471			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
472	}
473
474	/*
475	 * Wait for ISP to be ready to go...
476	 */
477	loops = MBOX_DELAY_COUNT;
478	for (;;) {
479		if (IS_SCSI(isp)) {
480			if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET))
481				break;
482		} else {
483			if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
484				break;
485		}
486		USEC_DELAY(100);
487		if (--loops < 0) {
488			ISP_DUMPREGS(isp, "chip reset timed out");
489			return;
490		}
491	}
492
493	/*
494	 * After we've fired this chip up, zero out the conf1 register
495	 * for SCSI adapters and other settings for the 2100.
496	 */
497
498	if (IS_SCSI(isp)) {
499		ISP_WRITE(isp, BIU_CONF1, 0);
500	} else {
501		ISP_WRITE(isp, BIU2100_CSR, 0);
502	}
503
504	/*
505	 * Reset RISC Processor
506	 */
507	ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
508	USEC_DELAY(100);
509	/* Clear semaphore register (just to be sure) */
510	ISP_WRITE(isp, BIU_SEMA, 0);
511
512	/*
513	 * Establish some initial burst rate stuff.
514	 * (only for the 1XX0 boards). This really should
515	 * be done later after fetching from NVRAM.
516	 */
517	if (IS_SCSI(isp)) {
518		u_int16_t tmp = isp->isp_mdvec->dv_conf1;
519		/*
520		 * Busted FIFO. Turn off all but burst enables.
521		 */
522		if (isp->isp_type == ISP_HA_SCSI_1040A) {
523			tmp &= BIU_BURST_ENABLE;
524		}
525		ISP_SETBITS(isp, BIU_CONF1, tmp);
526		if (tmp & BIU_BURST_ENABLE) {
527			ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
528			ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
529		}
530#ifdef	PTI_CARDS
531		if (((sdparam *) isp->isp_param)->isp_ultramode) {
532			while (ISP_READ(isp, RISC_MTR) != 0x1313) {
533				ISP_WRITE(isp, RISC_MTR, 0x1313);
534				ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
535			}
536		} else {
537			ISP_WRITE(isp, RISC_MTR, 0x1212);
538		}
539		/*
540		 * PTI specific register
541		 */
542		ISP_WRITE(isp, RISC_EMB, DUAL_BANK)
543#else
544		ISP_WRITE(isp, RISC_MTR, 0x1212);
545#endif
546	} else {
547		ISP_WRITE(isp, RISC_MTR2100, 0x1212);
548		if (IS_2200(isp) || IS_23XX(isp)) {
549			ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
550		}
551	}
552
553	ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); /* release paused processor */
554
555	/*
556	 * Do MD specific post initialization
557	 */
558	ISP_RESET1(isp);
559
560	/*
561	 * Wait for everything to finish firing up.
562	 *
563	 * Avoid doing this on the 2312 because you can generate a PCI
564	 * parity error (chip breakage).
565	 */
566	if (IS_23XX(isp)) {
567		USEC_DELAY(5);
568	} else {
569		loops = MBOX_DELAY_COUNT;
570		while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
571			USEC_DELAY(100);
572			if (--loops < 0) {
573				isp_prt(isp, ISP_LOGERR,
574				    "MBOX_BUSY never cleared on reset");
575				return;
576			}
577		}
578	}
579
580	/*
581	 * Up until this point we've done everything by just reading or
582	 * setting registers. From this point on we rely on at least *some*
583	 * kind of firmware running in the card.
584	 */
585
586	/*
587	 * Do some sanity checking.
588	 */
589	mbs.param[0] = MBOX_NO_OP;
590	isp_mboxcmd(isp, &mbs, MBLOGALL);
591	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
592		return;
593	}
594
595	if (IS_SCSI(isp)) {
596		mbs.param[0] = MBOX_MAILBOX_REG_TEST;
597		mbs.param[1] = 0xdead;
598		mbs.param[2] = 0xbeef;
599		mbs.param[3] = 0xffff;
600		mbs.param[4] = 0x1111;
601		mbs.param[5] = 0xa5a5;
602		isp_mboxcmd(isp, &mbs, MBLOGALL);
603		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
604			return;
605		}
606		if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
607		    mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
608		    mbs.param[5] != 0xa5a5) {
609			isp_prt(isp, ISP_LOGERR,
610			    "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)",
611			    mbs.param[1], mbs.param[2], mbs.param[3],
612			    mbs.param[4], mbs.param[5]);
613			return;
614		}
615
616	}
617
618	/*
619	 * Download new Firmware, unless requested not to do so.
620	 * This is made slightly trickier in some cases where the
621	 * firmware of the ROM revision is newer than the revision
622	 * compiled into the driver. So, where we used to compare
623	 * versions of our f/w and the ROM f/w, now we just see
624	 * whether we have f/w at all and whether a config flag
625	 * has disabled our download.
626	 */
627	if ((isp->isp_mdvec->dv_ispfw == NULL) ||
628	    (isp->isp_confopts & ISP_CFG_NORELOAD)) {
629		dodnld = 0;
630	}
631
632	if (IS_23XX(isp))
633		code_org = ISP_CODE_ORG_2300;
634	else
635		code_org = ISP_CODE_ORG;
636
637	if (dodnld) {
638		isp->isp_mbxworkp = (void *) &isp->isp_mdvec->dv_ispfw[1];
639		isp->isp_mbxwrk0 = isp->isp_mdvec->dv_ispfw[3] - 1;
640		isp->isp_mbxwrk1 = code_org + 1;
641		mbs.param[0] = MBOX_WRITE_RAM_WORD;
642		mbs.param[1] = code_org;
643		mbs.param[2] = isp->isp_mdvec->dv_ispfw[0];
644		isp_mboxcmd(isp, &mbs, MBLOGNONE);
645		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
646			isp_prt(isp, ISP_LOGERR,
647			    "F/W download failed at word %d",
648			    isp->isp_mbxwrk1 - code_org);
649			dodnld = 0;
650			goto again;
651		}
652		/*
653		 * Verify that it downloaded correctly.
654		 */
655		mbs.param[0] = MBOX_VERIFY_CHECKSUM;
656		mbs.param[1] = code_org;
657		isp_mboxcmd(isp, &mbs, MBLOGNONE);
658		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
659			isp_prt(isp, ISP_LOGERR, "Ram Checksum Failure");
660			return;
661		}
662		isp->isp_loaded_fw = 1;
663	} else {
664		isp->isp_loaded_fw = 0;
665		isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
666	}
667
668	/*
669	 * Now start it rolling.
670	 *
671	 * If we didn't actually download f/w,
672	 * we still need to (re)start it.
673	 */
674
675
676	mbs.param[0] = MBOX_EXEC_FIRMWARE;
677	mbs.param[1] = code_org;
678	isp_mboxcmd(isp, &mbs, MBLOGNONE);
679	/*
680	 * Give it a chance to start.
681	 */
682	USEC_DELAY(500);
683
684	if (IS_SCSI(isp)) {
685		/*
686		 * Set CLOCK RATE, but only if asked to.
687		 */
688		if (isp->isp_clock) {
689			mbs.param[0] = MBOX_SET_CLOCK_RATE;
690			mbs.param[1] = isp->isp_clock;
691			isp_mboxcmd(isp, &mbs, MBLOGALL);
692			/* we will try not to care if this fails */
693		}
694	}
695
696	mbs.param[0] = MBOX_ABOUT_FIRMWARE;
697	isp_mboxcmd(isp, &mbs, MBLOGALL);
698	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
699		return;
700	}
701
702	/*
703	 * The SBus firmware that we are using apparently does not return
704	 * major, minor, micro revisions in the mailbox registers, which
705	 * is really, really, annoying.
706	 */
707	if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {
708		if (dodnld) {
709#ifdef	ISP_TARGET_MODE
710			isp->isp_fwrev[0] = 7;
711			isp->isp_fwrev[1] = 55;
712#else
713			isp->isp_fwrev[0] = 1;
714			isp->isp_fwrev[1] = 37;
715#endif
716			isp->isp_fwrev[2] = 0;
717		}
718	} else {
719		isp->isp_fwrev[0] = mbs.param[1];
720		isp->isp_fwrev[1] = mbs.param[2];
721		isp->isp_fwrev[2] = mbs.param[3];
722	}
723	isp_prt(isp, ISP_LOGCONFIG,
724	    "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
725	    btype, isp->isp_revision, dodnld? "loaded" : "resident",
726	    isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
727
728	if (IS_FC(isp)) {
729		/*
730		 * We do not believe firmware attributes for 2100 code less
731		 * than 1.17.0, unless it's the firmware we specifically
732		 * are loading.
733		 *
734		 * Note that all 22XX and 23XX f/w is greater than 1.X.0.
735		 */
736		if (!(ISP_FW_NEWER_THAN(isp, 1, 17, 0))) {
737#ifdef	USE_SMALLER_2100_FIRMWARE
738			FCPARAM(isp)->isp_fwattr = ISP_FW_ATTR_SCCLUN;
739#else
740			FCPARAM(isp)->isp_fwattr = 0;
741#endif
742		} else {
743			FCPARAM(isp)->isp_fwattr = mbs.param[6];
744			isp_prt(isp, ISP_LOGDEBUG0,
745			    "Firmware Attributes = 0x%x", mbs.param[6]);
746		}
747		if (ISP_READ(isp, BIU2100_CSR) & BIU2100_PCI64) {
748			isp_prt(isp, ISP_LOGCONFIG,
749			    "Installed in 64-Bit PCI slot");
750		}
751	}
752
753	if (isp->isp_romfw_rev[0] || isp->isp_romfw_rev[1] ||
754	    isp->isp_romfw_rev[2]) {
755		isp_prt(isp, ISP_LOGCONFIG, "Last F/W revision was %d.%d.%d",
756		    isp->isp_romfw_rev[0], isp->isp_romfw_rev[1],
757		    isp->isp_romfw_rev[2]);
758	}
759
760	mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
761	isp_mboxcmd(isp, &mbs, MBLOGALL);
762	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
763		return;
764	}
765	isp->isp_maxcmds = mbs.param[2];
766	isp_prt(isp, ISP_LOGINFO,
767	    "%d max I/O commands supported", mbs.param[2]);
768	isp_fw_state(isp);
769
770	/*
771	 * Set up DMA for the request and result mailboxes.
772	 */
773	if (ISP_MBOXDMASETUP(isp) != 0) {
774		isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
775		return;
776	}
777	isp->isp_state = ISP_RESETSTATE;
778
779	/*
780	 * Okay- now that we have new firmware running, we now (re)set our
781	 * notion of how many luns we support. This is somewhat tricky because
782	 * if we haven't loaded firmware, we sometimes do not have an easy way
783	 * of knowing how many luns we support.
784	 *
785	 * Expanded lun firmware gives you 32 luns for SCSI cards and
786	 * 16384 luns for Fibre Channel cards.
787	 *
788	 * It turns out that even for QLogic 2100s with ROM 1.10 and above
789	 * we do get a firmware attributes word returned in mailbox register 6.
790	 *
791	 * Because the lun is in a a different position in the Request Queue
792	 * Entry structure for Fibre Channel with expanded lun firmware, we
793	 * can only support one lun (lun zero) when we don't know what kind
794	 * of firmware we're running.
795	 *
796	 * Note that we only do this once (the first time thru isp_reset)
797	 * because we may be called again after firmware has been loaded once
798	 * and released.
799	 */
800	if (IS_SCSI(isp)) {
801		if (dodnld) {
802			if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) {
803				isp->isp_maxluns = 32;
804			} else {
805				isp->isp_maxluns = 8;
806			}
807		} else {
808			isp->isp_maxluns = 8;
809		}
810	} else {
811		if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
812			isp->isp_maxluns = 16384;
813		} else {
814			isp->isp_maxluns = 16;
815		}
816	}
817}
818
819/*
820 * Initialize Parameters of Hardware to a known state.
821 *
822 * Locks are held before coming here.
823 */
824
825void
826isp_init(struct ispsoftc *isp)
827{
828	/*
829	 * Must do this first to get defaults established.
830	 */
831	isp_setdfltparm(isp, 0);
832	if (IS_DUALBUS(isp)) {
833		isp_setdfltparm(isp, 1);
834	}
835	if (IS_FC(isp)) {
836		isp_fibre_init(isp);
837	} else {
838		isp_scsi_init(isp);
839	}
840}
841
842static void
843isp_scsi_init(struct ispsoftc *isp)
844{
845	sdparam *sdp_chan0, *sdp_chan1;
846	mbreg_t mbs;
847
848	sdp_chan0 = isp->isp_param;
849	sdp_chan1 = sdp_chan0;
850	if (IS_DUALBUS(isp)) {
851		sdp_chan1++;
852	}
853
854	/*
855	 * If we have no role (neither target nor initiator), return.
856	 */
857	if (isp->isp_role == ISP_ROLE_NONE) {
858		return;
859	}
860
861	/* First do overall per-card settings. */
862
863	/*
864	 * If we have fast memory timing enabled, turn it on.
865	 */
866	if (sdp_chan0->isp_fast_mttr) {
867		ISP_WRITE(isp, RISC_MTR, 0x1313);
868	}
869
870	/*
871	 * Set Retry Delay and Count.
872	 * You set both channels at the same time.
873	 */
874	mbs.param[0] = MBOX_SET_RETRY_COUNT;
875	mbs.param[1] = sdp_chan0->isp_retry_count;
876	mbs.param[2] = sdp_chan0->isp_retry_delay;
877	mbs.param[6] = sdp_chan1->isp_retry_count;
878	mbs.param[7] = sdp_chan1->isp_retry_delay;
879
880	isp_mboxcmd(isp, &mbs, MBLOGALL);
881	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
882		return;
883	}
884
885	/*
886	 * Set ASYNC DATA SETUP time. This is very important.
887	 */
888	mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
889	mbs.param[1] = sdp_chan0->isp_async_data_setup;
890	mbs.param[2] = sdp_chan1->isp_async_data_setup;
891	isp_mboxcmd(isp, &mbs, MBLOGALL);
892	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
893		return;
894	}
895
896	/*
897	 * Set ACTIVE Negation State.
898	 */
899	mbs.param[0] = MBOX_SET_ACT_NEG_STATE;
900	mbs.param[1] =
901	    (sdp_chan0->isp_req_ack_active_neg << 4) |
902	    (sdp_chan0->isp_data_line_active_neg << 5);
903	mbs.param[2] =
904	    (sdp_chan1->isp_req_ack_active_neg << 4) |
905	    (sdp_chan1->isp_data_line_active_neg << 5);
906
907	isp_mboxcmd(isp, &mbs, MBLOGNONE);
908	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
909		isp_prt(isp, ISP_LOGERR,
910		    "failed to set active negation state (%d,%d), (%d,%d)",
911		    sdp_chan0->isp_req_ack_active_neg,
912		    sdp_chan0->isp_data_line_active_neg,
913		    sdp_chan1->isp_req_ack_active_neg,
914		    sdp_chan1->isp_data_line_active_neg);
915		/*
916		 * But don't return.
917		 */
918	}
919
920	/*
921	 * Set the Tag Aging limit
922	 */
923	mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT;
924	mbs.param[1] = sdp_chan0->isp_tag_aging;
925	mbs.param[2] = sdp_chan1->isp_tag_aging;
926	isp_mboxcmd(isp, &mbs, MBLOGALL);
927	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
928		isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
929		    sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
930		return;
931	}
932
933	/*
934	 * Set selection timeout.
935	 */
936	mbs.param[0] = MBOX_SET_SELECT_TIMEOUT;
937	mbs.param[1] = sdp_chan0->isp_selection_timeout;
938	mbs.param[2] = sdp_chan1->isp_selection_timeout;
939	isp_mboxcmd(isp, &mbs, MBLOGALL);
940	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
941		return;
942	}
943
944	/* now do per-channel settings */
945	isp_scsi_channel_init(isp, 0);
946	if (IS_DUALBUS(isp))
947		isp_scsi_channel_init(isp, 1);
948
949	/*
950	 * Now enable request/response queues
951	 */
952
953	if (IS_ULTRA2(isp) || IS_1240(isp)) {
954		mbs.param[0] = MBOX_INIT_RES_QUEUE_A64;
955		mbs.param[1] = RESULT_QUEUE_LEN(isp);
956		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
957		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
958		mbs.param[4] = 0;
959		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
960		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
961		isp_mboxcmd(isp, &mbs, MBLOGALL);
962		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
963			return;
964		}
965		isp->isp_residx = mbs.param[5];
966
967		mbs.param[0] = MBOX_INIT_REQ_QUEUE_A64;
968		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
969		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
970		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
971		mbs.param[5] = 0;
972		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
973		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
974		isp_mboxcmd(isp, &mbs, MBLOGALL);
975		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
976			return;
977		}
978		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
979	} else {
980		mbs.param[0] = MBOX_INIT_RES_QUEUE;
981		mbs.param[1] = RESULT_QUEUE_LEN(isp);
982		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
983		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
984		mbs.param[4] = 0;
985		isp_mboxcmd(isp, &mbs, MBLOGALL);
986		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
987			return;
988		}
989		isp->isp_residx = mbs.param[5];
990
991		mbs.param[0] = MBOX_INIT_REQ_QUEUE;
992		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
993		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
994		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
995		mbs.param[5] = 0;
996		isp_mboxcmd(isp, &mbs, MBLOGALL);
997		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
998			return;
999		}
1000		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
1001	}
1002
1003	/*
1004	 * Turn on Fast Posting, LVD transitions
1005	 *
1006	 * Ultra2 F/W always has had fast posting (and LVD transitions)
1007	 *
1008	 * Ultra and older (i.e., SBus) cards may not. It's just safer
1009	 * to assume not for them.
1010	 */
1011
1012	mbs.param[0] = MBOX_SET_FW_FEATURES;
1013	mbs.param[1] = 0;
1014	if (IS_ULTRA2(isp))
1015		mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
1016#ifndef	ISP_NO_RIO
1017	if (IS_ULTRA2(isp) || IS_1240(isp))
1018		mbs.param[1] |= FW_FEATURE_RIO_16BIT;
1019#else
1020#ifndef	ISP_NO_FASTPOST
1021	if (IS_ULTRA2(isp) || IS_1240(isp))
1022		mbs.param[1] |= FW_FEATURE_FAST_POST;
1023#endif
1024#endif
1025	if (mbs.param[1] != 0) {
1026		u_int16_t sfeat = mbs.param[1];
1027		isp_mboxcmd(isp, &mbs, MBLOGALL);
1028		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1029			isp_prt(isp, ISP_LOGINFO,
1030			    "Enabled FW features (0x%x)", sfeat);
1031		}
1032	}
1033
1034	/*
1035	 * Let the outer layers decide whether to issue a SCSI bus reset.
1036	 */
1037	isp->isp_state = ISP_INITSTATE;
1038}
1039
1040static void
1041isp_scsi_channel_init(struct ispsoftc *isp, int channel)
1042{
1043	sdparam *sdp;
1044	mbreg_t mbs;
1045	int tgt;
1046
1047	sdp = isp->isp_param;
1048	sdp += channel;
1049
1050	/*
1051	 * Set (possibly new) Initiator ID.
1052	 */
1053	mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
1054	mbs.param[1] = (channel << 7) | sdp->isp_initiator_id;
1055	isp_mboxcmd(isp, &mbs, MBLOGALL);
1056	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1057		return;
1058	}
1059	isp_prt(isp, ISP_LOGINFO, "Initiator ID is %d on Channel %d",
1060	    sdp->isp_initiator_id, channel);
1061
1062
1063	/*
1064	 * Set current per-target parameters to an initial safe minimum.
1065	 */
1066	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1067		int lun;
1068		u_int16_t sdf;
1069
1070		if (sdp->isp_devparam[tgt].dev_enable == 0) {
1071			continue;
1072		}
1073#ifndef	ISP_TARGET_MODE
1074		sdf = sdp->isp_devparam[tgt].goal_flags;
1075		sdf &= DPARM_SAFE_DFLT;
1076		/*
1077		 * It is not quite clear when this changed over so that
1078		 * we could force narrow and async for 1000/1020 cards,
1079		 * but assume that this is only the case for loaded
1080		 * firmware.
1081		 */
1082		if (isp->isp_loaded_fw) {
1083			sdf |= DPARM_NARROW | DPARM_ASYNC;
1084		}
1085#else
1086		/*
1087		 * The !$*!)$!$)* f/w uses the same index into some
1088		 * internal table to decide how to respond to negotiations,
1089		 * so if we've said "let's be safe" for ID X, and ID X
1090		 * selects *us*, the negotiations will back to 'safe'
1091		 * (as in narrow/async). What the f/w *should* do is
1092		 * use the initiator id settings to decide how to respond.
1093		 */
1094		sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT;
1095#endif
1096		mbs.param[0] = MBOX_SET_TARGET_PARAMS;
1097		mbs.param[1] = (channel << 15) | (tgt << 8);
1098		mbs.param[2] = sdf;
1099		if ((sdf & DPARM_SYNC) == 0) {
1100			mbs.param[3] = 0;
1101		} else {
1102			mbs.param[3] =
1103			    (sdp->isp_devparam[tgt].goal_offset << 8) |
1104			    (sdp->isp_devparam[tgt].goal_period);
1105		}
1106		isp_prt(isp, ISP_LOGDEBUG0,
1107		    "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
1108		    channel, tgt, mbs.param[2], mbs.param[3] >> 8,
1109		    mbs.param[3] & 0xff);
1110		isp_mboxcmd(isp, &mbs, MBLOGNONE);
1111		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1112			sdf = DPARM_SAFE_DFLT;
1113			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
1114			mbs.param[1] = (tgt << 8) | (channel << 15);
1115			mbs.param[2] = sdf;
1116			mbs.param[3] = 0;
1117			isp_mboxcmd(isp, &mbs, MBLOGALL);
1118			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1119				continue;
1120			}
1121		}
1122
1123		/*
1124		 * We don't update any information directly from the f/w
1125		 * because we need to run at least one command to cause a
1126		 * new state to be latched up. So, we just assume that we
1127		 * converge to the values we just had set.
1128		 *
1129		 * Ensure that we don't believe tagged queuing is enabled yet.
1130		 * It turns out that sometimes the ISP just ignores our
1131		 * attempts to set parameters for devices that it hasn't
1132		 * seen yet.
1133		 */
1134		sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING;
1135		for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
1136			mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
1137			mbs.param[1] = (channel << 15) | (tgt << 8) | lun;
1138			mbs.param[2] = sdp->isp_max_queue_depth;
1139			mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
1140			isp_mboxcmd(isp, &mbs, MBLOGALL);
1141			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1142				break;
1143			}
1144		}
1145	}
1146	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1147		if (sdp->isp_devparam[tgt].dev_refresh) {
1148			isp->isp_sendmarker |= (1 << channel);
1149			isp->isp_update |= (1 << channel);
1150			break;
1151		}
1152	}
1153}
1154
1155/*
1156 * Fibre Channel specific initialization.
1157 *
1158 * Locks are held before coming here.
1159 */
1160static void
1161isp_fibre_init(struct ispsoftc *isp)
1162{
1163	fcparam *fcp;
1164	isp_icb_t local, *icbp = &local;
1165	mbreg_t mbs;
1166	int loopid;
1167	u_int64_t nwwn, pwwn;
1168
1169	fcp = isp->isp_param;
1170
1171	/*
1172	 * Do this *before* initializing the firmware.
1173	 */
1174	isp_mark_getpdb_all(isp);
1175	fcp->isp_fwstate = FW_CONFIG_WAIT;
1176	fcp->isp_loopstate = LOOP_NIL;
1177
1178	/*
1179	 * If we have no role (neither target nor initiator), return.
1180	 */
1181	if (isp->isp_role == ISP_ROLE_NONE) {
1182		return;
1183	}
1184
1185	loopid = fcp->isp_loopid;
1186	MEMZERO(icbp, sizeof (*icbp));
1187	icbp->icb_version = ICB_VERSION1;
1188
1189	/*
1190	 * Firmware Options are either retrieved from NVRAM or
1191	 * are patched elsewhere. We check them for sanity here
1192	 * and make changes based on board revision, but otherwise
1193	 * let others decide policy.
1194	 */
1195
1196	/*
1197	 * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
1198	 */
1199	if ((isp->isp_type == ISP_HA_FC_2100) && isp->isp_revision < 5) {
1200		fcp->isp_fwoptions &= ~ICBOPT_FAIRNESS;
1201	}
1202
1203	/*
1204	 * We have to use FULL LOGIN even though it resets the loop too much
1205	 * because otherwise port database entries don't get updated after
1206	 * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
1207	 */
1208	if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
1209		fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
1210	}
1211
1212	/*
1213	 * Insist on Port Database Update Async notifications
1214	 */
1215	fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
1216
1217	/*
1218	 * Make sure that target role reflects into fwoptions.
1219	 */
1220	if (isp->isp_role & ISP_ROLE_TARGET) {
1221		fcp->isp_fwoptions |= ICBOPT_TGT_ENABLE;
1222	} else {
1223		fcp->isp_fwoptions &= ~ICBOPT_TGT_ENABLE;
1224	}
1225
1226	/*
1227	 * Propagate all of this into the ICB structure.
1228	 */
1229	icbp->icb_fwoptions = fcp->isp_fwoptions;
1230	icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
1231	if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
1232	    icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
1233		isp_prt(isp, ISP_LOGERR,
1234		    "bad frame length (%d) from NVRAM- using %d",
1235		    fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN);
1236		icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
1237	}
1238	icbp->icb_maxalloc = fcp->isp_maxalloc;
1239	if (icbp->icb_maxalloc < 1) {
1240		isp_prt(isp, ISP_LOGERR,
1241		    "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
1242		icbp->icb_maxalloc = 16;
1243	}
1244	icbp->icb_execthrottle = fcp->isp_execthrottle;
1245	if (icbp->icb_execthrottle < 1) {
1246		isp_prt(isp, ISP_LOGERR,
1247		    "bad execution throttle of %d- using 16",
1248		    fcp->isp_execthrottle);
1249		icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
1250	}
1251	icbp->icb_retry_delay = fcp->isp_retry_delay;
1252	icbp->icb_retry_count = fcp->isp_retry_count;
1253	icbp->icb_hardaddr = loopid;
1254	/*
1255	 * Right now we just set extended options to prefer point-to-point
1256	 * over loop based upon some soft config options.
1257	 *
1258	 * NB: for the 2300, ICBOPT_EXTENDED is required.
1259	 */
1260	if (IS_2200(isp) || IS_23XX(isp)) {
1261		icbp->icb_fwoptions |= ICBOPT_EXTENDED;
1262		/*
1263		 * Prefer or force Point-To-Point instead Loop?
1264		 */
1265		switch(isp->isp_confopts & ISP_CFG_PORT_PREF) {
1266		case ISP_CFG_NPORT:
1267			icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP;
1268			break;
1269		case ISP_CFG_NPORT_ONLY:
1270			icbp->icb_xfwoptions |= ICBXOPT_PTP_ONLY;
1271			break;
1272		case ISP_CFG_LPORT_ONLY:
1273			icbp->icb_xfwoptions |= ICBXOPT_LOOP_ONLY;
1274			break;
1275		default:
1276			icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
1277			break;
1278		}
1279		if (IS_23XX(isp)) {
1280			/*
1281			 * QLogic recommends that FAST Posting be turned
1282			 * off for 23XX cards and instead allow the HBA
1283			 * to write response queue entries and interrupt
1284			 * after a delay (ZIO).
1285			 *
1286			 * If we set ZIO, it will disable fast posting,
1287			 * so we don't need to clear it in fwoptions.
1288			 */
1289			icbp->icb_xfwoptions |= ICBXOPT_ZIO;
1290
1291			if (isp->isp_confopts & ISP_CFG_ONEGB) {
1292				icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
1293			} else if (isp->isp_confopts & ISP_CFG_TWOGB) {
1294				icbp->icb_zfwoptions |= ICBZOPT_RATE_TWOGB;
1295			} else {
1296				icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
1297			}
1298		}
1299	}
1300
1301#ifndef	ISP_NO_RIO_FC
1302	/*
1303	 * RIO seems to be enabled in 2100s for fw >= 1.17.0.
1304	 *
1305	 * I've had some questionable problems with RIO on 2200.
1306	 * More specifically, on a 2204 I had problems with RIO
1307	 * on a Linux system where I was dropping commands right
1308	 * and left. It's not clear to me what the actual problem
1309	 * was.
1310	 *
1311	 * 23XX Cards do not support RIO. Instead they support ZIO.
1312	 */
1313#if	0
1314	if (!IS_23XX(isp) && ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
1315		icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
1316		icbp->icb_racctimer = 4;
1317		icbp->icb_idelaytimer = 8;
1318	}
1319#endif
1320#endif
1321
1322	/*
1323	 * For 22XX > 2.1.26 && 23XX, set someoptions.
1324	 * XXX: Probably okay for newer 2100 f/w too.
1325	 */
1326	if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
1327		/*
1328		 * Turn on LIP F8 async event (1)
1329		 * Turn on generate AE 8013 on all LIP Resets (2)
1330		 * Disable LIP F7 switching (8)
1331		 */
1332		mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS;
1333		mbs.param[1] = 0xb;
1334		mbs.param[2] = 0;
1335		mbs.param[3] = 0;
1336		isp_mboxcmd(isp, &mbs, MBLOGALL);
1337	}
1338	icbp->icb_logintime = 30;	/* 30 second login timeout */
1339
1340	if (IS_23XX(isp)) {
1341		ISP_WRITE(isp, isp->isp_rqstinrp, 0);
1342        	ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
1343        	ISP_WRITE(isp, isp->isp_respinrp, 0);
1344		ISP_WRITE(isp, isp->isp_respoutrp, 0);
1345	}
1346
1347	nwwn = ISP_NODEWWN(isp);
1348	pwwn = ISP_PORTWWN(isp);
1349	if (nwwn && pwwn) {
1350		icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
1351		MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn);
1352		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
1353		isp_prt(isp, ISP_LOGDEBUG1,
1354		    "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
1355		    ((u_int32_t) (nwwn >> 32)),
1356		    ((u_int32_t) (nwwn & 0xffffffff)),
1357		    ((u_int32_t) (pwwn >> 32)),
1358		    ((u_int32_t) (pwwn & 0xffffffff)));
1359	} else {
1360		isp_prt(isp, ISP_LOGDEBUG1, "Not using any WWNs");
1361		icbp->icb_fwoptions &= ~(ICBOPT_BOTH_WWNS|ICBOPT_FULL_LOGIN);
1362	}
1363	icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
1364	icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
1365	icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
1366	icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
1367	icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
1368	icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
1369	icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
1370	icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
1371	icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
1372	icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
1373	isp_prt(isp, ISP_LOGDEBUG0,
1374	    "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
1375	    icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
1376
1377	FC_SCRATCH_ACQUIRE(isp);
1378	isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
1379
1380	/*
1381	 * Init the firmware
1382	 */
1383	mbs.param[0] = MBOX_INIT_FIRMWARE;
1384	mbs.param[1] = 0;
1385	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1386	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1387	mbs.param[4] = 0;
1388	mbs.param[5] = 0;
1389	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1390	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1391	isp_mboxcmd(isp, &mbs, MBLOGALL);
1392	FC_SCRATCH_RELEASE(isp);
1393	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1394		return;
1395	}
1396	isp->isp_reqidx = isp->isp_reqodx = 0;
1397	isp->isp_residx = 0;
1398	isp->isp_sendmarker = 1;
1399
1400	/*
1401	 * Whatever happens, we're now committed to being here.
1402	 */
1403	isp->isp_state = ISP_INITSTATE;
1404}
1405
1406/*
1407 * Fibre Channel Support- get the port database for the id.
1408 *
1409 * Locks are held before coming here. Return 0 if success,
1410 * else failure.
1411 */
1412
1413static int
1414isp_getmap(struct ispsoftc *isp, fcpos_map_t *map)
1415{
1416	fcparam *fcp = (fcparam *) isp->isp_param;
1417	mbreg_t mbs;
1418
1419	mbs.param[0] = MBOX_GET_FC_AL_POSITION_MAP;
1420	mbs.param[1] = 0;
1421	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1422	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1423	/*
1424	 * Unneeded. For the 2100, except for initializing f/w, registers
1425	 * 4/5 have to not be written to.
1426	 *	mbs.param[4] = 0;
1427	 *	mbs.param[5] = 0;
1428	 *
1429	 */
1430	mbs.param[6] = 0;
1431	mbs.param[7] = 0;
1432	FC_SCRATCH_ACQUIRE(isp);
1433	isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
1434	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1435		MEMCPY(map, fcp->isp_scratch, sizeof (fcpos_map_t));
1436		map->fwmap = mbs.param[1] != 0;
1437		FC_SCRATCH_RELEASE(isp);
1438		return (0);
1439	}
1440	FC_SCRATCH_RELEASE(isp);
1441	return (-1);
1442}
1443
1444static void
1445isp_mark_getpdb_all(struct ispsoftc *isp)
1446{
1447	fcparam *fcp = (fcparam *) isp->isp_param;
1448	int i;
1449	for (i = 0; i < MAX_FC_TARG; i++) {
1450		fcp->portdb[i].valid = fcp->portdb[i].fabric_dev = 0;
1451	}
1452}
1453
1454static int
1455isp_getpdb(struct ispsoftc *isp, int id, isp_pdb_t *pdbp)
1456{
1457	fcparam *fcp = (fcparam *) isp->isp_param;
1458	mbreg_t mbs;
1459
1460	mbs.param[0] = MBOX_GET_PORT_DB;
1461	mbs.param[1] = id << 8;
1462	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1463	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1464	/*
1465	 * Unneeded. For the 2100, except for initializing f/w, registers
1466	 * 4/5 have to not be written to.
1467	 *	mbs.param[4] = 0;
1468	 *	mbs.param[5] = 0;
1469	 *
1470	 */
1471	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1472	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1473	FC_SCRATCH_ACQUIRE(isp);
1474	isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
1475	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1476		isp_get_pdb(isp, (isp_pdb_t *)fcp->isp_scratch, pdbp);
1477		FC_SCRATCH_RELEASE(isp);
1478		return (0);
1479	}
1480	FC_SCRATCH_RELEASE(isp);
1481	return (-1);
1482}
1483
1484static u_int64_t
1485isp_get_portname(struct ispsoftc *isp, int loopid, int nodename)
1486{
1487	u_int64_t wwn = 0;
1488	mbreg_t mbs;
1489
1490	mbs.param[0] = MBOX_GET_PORT_NAME;
1491	mbs.param[1] = loopid << 8;
1492	if (nodename)
1493		mbs.param[1] |= 1;
1494	isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
1495	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1496		wwn =
1497		    (((u_int64_t)(mbs.param[2] & 0xff)) << 56) |
1498		    (((u_int64_t)(mbs.param[2] >> 8))	<< 48) |
1499		    (((u_int64_t)(mbs.param[3] & 0xff))	<< 40) |
1500		    (((u_int64_t)(mbs.param[3] >> 8))	<< 32) |
1501		    (((u_int64_t)(mbs.param[6] & 0xff))	<< 24) |
1502		    (((u_int64_t)(mbs.param[6] >> 8))	<< 16) |
1503		    (((u_int64_t)(mbs.param[7] & 0xff))	<<  8) |
1504		    (((u_int64_t)(mbs.param[7] >> 8)));
1505	}
1506	return (wwn);
1507}
1508
1509/*
1510 * Make sure we have good FC link and know our Loop ID.
1511 */
1512
1513static int
1514isp_fclink_test(struct ispsoftc *isp, int usdelay)
1515{
1516	static char *toponames[] = {
1517		"Private Loop",
1518		"FL Port",
1519		"N-Port to N-Port",
1520		"F Port",
1521		"F Port (no FLOGI_ACC response)"
1522	};
1523	mbreg_t mbs;
1524	int count, check_for_fabric;
1525	u_int8_t lwfs;
1526	fcparam *fcp;
1527	struct lportdb *lp;
1528	isp_pdb_t pdb;
1529
1530	fcp = isp->isp_param;
1531
1532	/*
1533	 * XXX: Here is where we would start a 'loop dead' timeout
1534	 */
1535
1536	/*
1537	 * Wait up to N microseconds for F/W to go to a ready state.
1538	 */
1539	lwfs = FW_CONFIG_WAIT;
1540	count = 0;
1541	while (count < usdelay) {
1542		u_int64_t enano;
1543		u_int32_t wrk;
1544		NANOTIME_T hra, hrb;
1545
1546		GET_NANOTIME(&hra);
1547		isp_fw_state(isp);
1548		if (lwfs != fcp->isp_fwstate) {
1549			isp_prt(isp, ISP_LOGINFO, "Firmware State <%s->%s>",
1550			    isp2100_fw_statename((int)lwfs),
1551			    isp2100_fw_statename((int)fcp->isp_fwstate));
1552			lwfs = fcp->isp_fwstate;
1553		}
1554		if (fcp->isp_fwstate == FW_READY) {
1555			break;
1556		}
1557		GET_NANOTIME(&hrb);
1558
1559		/*
1560		 * Get the elapsed time in nanoseconds.
1561		 * Always guaranteed to be non-zero.
1562		 */
1563		enano = NANOTIME_SUB(&hrb, &hra);
1564
1565		isp_prt(isp, ISP_LOGDEBUG1,
1566		    "usec%d: 0x%lx->0x%lx enano 0x%x%08x",
1567		    count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb),
1568		    (u_int32_t)(enano >> 32), (u_int32_t)(enano & 0xffffffff));
1569
1570		/*
1571		 * If the elapsed time is less than 1 millisecond,
1572		 * delay a period of time up to that millisecond of
1573		 * waiting.
1574		 *
1575		 * This peculiar code is an attempt to try and avoid
1576		 * invoking u_int64_t math support functions for some
1577		 * platforms where linkage is a problem.
1578		 */
1579		if (enano < (1000 * 1000)) {
1580			count += 1000;
1581			enano = (1000 * 1000) - enano;
1582			while (enano > (u_int64_t) 4000000000U) {
1583				USEC_SLEEP(isp, 4000000);
1584				enano -= (u_int64_t) 4000000000U;
1585			}
1586			wrk = enano;
1587			wrk /= 1000;
1588			USEC_SLEEP(isp, wrk);
1589		} else {
1590			while (enano > (u_int64_t) 4000000000U) {
1591				count += 4000000;
1592				enano -= (u_int64_t) 4000000000U;
1593			}
1594			wrk = enano;
1595			count += (wrk / 1000);
1596		}
1597	}
1598
1599	/*
1600	 * If we haven't gone to 'ready' state, return.
1601	 */
1602	if (fcp->isp_fwstate != FW_READY) {
1603		return (-1);
1604	}
1605
1606	/*
1607	 * Get our Loop ID (if possible). We really need to have it.
1608	 */
1609	mbs.param[0] = MBOX_GET_LOOP_ID;
1610	isp_mboxcmd(isp, &mbs, MBLOGALL);
1611	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1612		return (-1);
1613	}
1614	fcp->isp_loopid = mbs.param[1];
1615	if (IS_2200(isp) || IS_23XX(isp)) {
1616		int topo = (int) mbs.param[6];
1617		if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
1618			topo = TOPO_PTP_STUB;
1619		fcp->isp_topo = topo;
1620	} else {
1621		fcp->isp_topo = TOPO_NL_PORT;
1622	}
1623	fcp->isp_portid = fcp->isp_alpa = mbs.param[2] & 0xff;
1624
1625	/*
1626	 * Check to see if we're on a fabric by trying to see if we
1627	 * can talk to the fabric name server. This can be a bit
1628	 * tricky because if we're a 2100, we should check always
1629	 * (in case we're connected to an server doing aliasing).
1630	 */
1631	fcp->isp_onfabric = 0;
1632
1633	if (IS_2100(isp)) {
1634		/*
1635		 * Don't bother with fabric if we are using really old
1636		 * 2100 firmware. It's just not worth it.
1637		 */
1638		if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) {
1639			check_for_fabric = 1;
1640		} else {
1641			check_for_fabric = 0;
1642		}
1643	} else if (fcp->isp_topo == TOPO_FL_PORT ||
1644	    fcp->isp_topo == TOPO_F_PORT) {
1645		check_for_fabric = 1;
1646	} else
1647		check_for_fabric = 0;
1648
1649	if (check_for_fabric && isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
1650		int loopid = FL_PORT_ID;
1651		if (IS_2100(isp)) {
1652			fcp->isp_topo = TOPO_FL_PORT;
1653		}
1654
1655		if (BITS2WORD(pdb.pdb_portid_bits) == 0) {
1656			/*
1657			 * Crock.
1658			 */
1659			fcp->isp_topo = TOPO_NL_PORT;
1660			goto not_on_fabric;
1661		}
1662		fcp->isp_portid = mbs.param[2] | ((int) mbs.param[3] << 16);
1663
1664		/*
1665		 * Save the Fabric controller's port database entry.
1666		 */
1667		lp = &fcp->portdb[loopid];
1668		lp->node_wwn =
1669		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
1670		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
1671		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
1672		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
1673		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
1674		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
1675		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
1676		    (((u_int64_t)pdb.pdb_nodename[7]));
1677		lp->port_wwn =
1678		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
1679		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
1680		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
1681		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
1682		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
1683		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
1684		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
1685		    (((u_int64_t)pdb.pdb_portname[7]));
1686		lp->roles =
1687		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
1688		lp->portid = BITS2WORD(pdb.pdb_portid_bits);
1689		lp->loopid = pdb.pdb_loopid;
1690		lp->loggedin = lp->valid = 1;
1691		fcp->isp_onfabric = 1;
1692		(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
1693		isp_register_fc4_type(isp);
1694	} else {
1695not_on_fabric:
1696		fcp->isp_onfabric = 0;
1697		fcp->portdb[FL_PORT_ID].valid = 0;
1698	}
1699
1700	fcp->isp_gbspeed = 1;
1701	if (IS_23XX(isp)) {
1702		mbs.param[0] = MBOX_GET_SET_DATA_RATE;
1703		mbs.param[1] = MBGSD_GET_RATE;
1704		/* mbs.param[2] undefined if we're just getting rate */
1705		isp_mboxcmd(isp, &mbs, MBLOGALL);
1706		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1707			if (mbs.param[1] == MBGSD_TWOGB) {
1708				isp_prt(isp, ISP_LOGINFO, "2Gb link speed/s");
1709				fcp->isp_gbspeed = 2;
1710			}
1711		}
1712	}
1713
1714	isp_prt(isp, ISP_LOGCONFIG, topology, fcp->isp_loopid, fcp->isp_alpa,
1715	    fcp->isp_portid, fcp->isp_loopstate, toponames[fcp->isp_topo]);
1716
1717	/*
1718	 * Announce ourselves, too. This involves synthesizing an entry.
1719	 */
1720	if (fcp->isp_iid_set == 0) {
1721		fcp->isp_iid_set = 1;
1722		fcp->isp_iid = fcp->isp_loopid;
1723		lp = &fcp->portdb[fcp->isp_iid];
1724	} else {
1725		lp = &fcp->portdb[fcp->isp_iid];
1726		if (fcp->isp_portid != lp->portid ||
1727		    fcp->isp_loopid != lp->loopid ||
1728		    fcp->isp_nodewwn != ISP_NODEWWN(isp) ||
1729		    fcp->isp_portwwn != ISP_PORTWWN(isp)) {
1730			lp->valid = 0;
1731			count = fcp->isp_iid;
1732			(void) isp_async(isp, ISPASYNC_PROMENADE, &count);
1733		}
1734	}
1735	lp->loopid = fcp->isp_loopid;
1736	lp->portid = fcp->isp_portid;
1737	lp->node_wwn = ISP_NODEWWN(isp);
1738	lp->port_wwn = ISP_PORTWWN(isp);
1739	switch (isp->isp_role) {
1740	case ISP_ROLE_NONE:
1741		lp->roles = 0;
1742		break;
1743	case ISP_ROLE_TARGET:
1744		lp->roles = SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT;
1745		break;
1746	case ISP_ROLE_INITIATOR:
1747		lp->roles = SVC3_INI_ROLE >> SVC3_ROLE_SHIFT;
1748		break;
1749	case ISP_ROLE_BOTH:
1750		lp->roles = (SVC3_INI_ROLE|SVC3_TGT_ROLE) >> SVC3_ROLE_SHIFT;
1751		break;
1752	}
1753	lp->loggedin = lp->valid = 1;
1754	count = fcp->isp_iid;
1755	(void) isp_async(isp, ISPASYNC_PROMENADE, &count);
1756	return (0);
1757}
1758
1759static char *
1760isp2100_fw_statename(int state)
1761{
1762	switch(state) {
1763	case FW_CONFIG_WAIT:	return "Config Wait";
1764	case FW_WAIT_AL_PA:	return "Waiting for AL_PA";
1765	case FW_WAIT_LOGIN:	return "Wait Login";
1766	case FW_READY:		return "Ready";
1767	case FW_LOSS_OF_SYNC:	return "Loss Of Sync";
1768	case FW_ERROR:		return "Error";
1769	case FW_REINIT:		return "Re-Init";
1770	case FW_NON_PART:	return "Nonparticipating";
1771	default:		return "?????";
1772	}
1773}
1774
1775/*
1776 * Synchronize our soft copy of the port database with what the f/w thinks
1777 * (with a view toward possibly for a specific target....)
1778 */
1779
1780static int
1781isp_pdb_sync(struct ispsoftc *isp)
1782{
1783	struct lportdb *lp;
1784	fcparam *fcp = isp->isp_param;
1785	isp_pdb_t pdb;
1786	int loopid, base, lim;
1787
1788	/*
1789	 * Make sure we're okay for doing this right now.
1790	 */
1791	if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
1792	    fcp->isp_loopstate != LOOP_FSCAN_DONE &&
1793	    fcp->isp_loopstate != LOOP_LSCAN_DONE) {
1794		return (-1);
1795	}
1796
1797	if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT ||
1798	    fcp->isp_topo == TOPO_N_PORT) {
1799		if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
1800			if (isp_scan_loop(isp) != 0) {
1801				return (-1);
1802			}
1803		}
1804	}
1805	fcp->isp_loopstate = LOOP_SYNCING_PDB;
1806
1807	/*
1808	 * If we get this far, we've settled our differences with the f/w
1809	 * (for local loop device) and we can say that the loop state is ready.
1810	 */
1811
1812	if (fcp->isp_topo == TOPO_NL_PORT) {
1813		fcp->loop_seen_once = 1;
1814		fcp->isp_loopstate = LOOP_READY;
1815		return (0);
1816	}
1817
1818	/*
1819	 * Find all Fabric Entities that didn't make it from one scan to the
1820	 * next and let the world know they went away. Scan the whole database.
1821	 */
1822	for (lp = &fcp->portdb[0]; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
1823		if (lp->was_fabric_dev && lp->fabric_dev == 0) {
1824			loopid = lp - fcp->portdb;
1825			lp->valid = 0;	/* should already be set */
1826			(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
1827			MEMZERO((void *) lp, sizeof (*lp));
1828			continue;
1829		}
1830		lp->was_fabric_dev = lp->fabric_dev;
1831	}
1832
1833	if (fcp->isp_topo == TOPO_FL_PORT)
1834		base = FC_SNS_ID+1;
1835	else
1836		base = 0;
1837
1838	if (fcp->isp_topo == TOPO_N_PORT)
1839		lim = 1;
1840	else
1841		lim = MAX_FC_TARG;
1842
1843	/*
1844	 * Now log in any fabric devices that the outer layer has
1845	 * left for us to see. This seems the most sane policy
1846	 * for the moment.
1847	 */
1848	for (lp = &fcp->portdb[base]; lp < &fcp->portdb[lim]; lp++) {
1849		u_int32_t portid;
1850		mbreg_t mbs;
1851
1852		loopid = lp - fcp->portdb;
1853		if (loopid >= FL_PORT_ID && loopid <= FC_SNS_ID) {
1854			continue;
1855		}
1856
1857		/*
1858		 * Anything here?
1859		 */
1860		if (lp->port_wwn == 0) {
1861			continue;
1862		}
1863
1864		/*
1865		 * Don't try to log into yourself.
1866		 */
1867		if ((portid = lp->portid) == fcp->isp_portid) {
1868			continue;
1869		}
1870
1871
1872		/*
1873		 * If we'd been logged in- see if we still are and we haven't
1874		 * changed. If so, no need to log ourselves out, etc..
1875		 *
1876		 * Unfortunately, our charming Qlogic f/w has decided to
1877		 * return a valid port database entry for a fabric device
1878		 * that has, in fact, gone away. And it hangs trying to
1879		 * log it out.
1880		 */
1881		if (lp->loggedin && lp->force_logout == 0 &&
1882		    isp_getpdb(isp, lp->loopid, &pdb) == 0) {
1883			int nrole;
1884			u_int64_t nwwnn, nwwpn;
1885			nwwnn =
1886			    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
1887			    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
1888			    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
1889			    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
1890			    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
1891			    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
1892			    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
1893			    (((u_int64_t)pdb.pdb_nodename[7]));
1894			nwwpn =
1895			    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
1896			    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
1897			    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
1898			    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
1899			    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
1900			    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
1901			    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
1902			    (((u_int64_t)pdb.pdb_portname[7]));
1903			nrole = (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >>
1904			    SVC3_ROLE_SHIFT;
1905			if (pdb.pdb_loopid == lp->loopid && lp->portid ==
1906			    (u_int32_t) BITS2WORD(pdb.pdb_portid_bits) &&
1907			    nwwnn == lp->node_wwn && nwwpn == lp->port_wwn &&
1908			    lp->roles == nrole && lp->force_logout == 0) {
1909				lp->loggedin = lp->valid = 1;
1910				isp_prt(isp, ISP_LOGCONFIG, lretained,
1911				    (int) (lp - fcp->portdb),
1912				    (int) lp->loopid, lp->portid);
1913				continue;
1914			}
1915		}
1916
1917		if (fcp->isp_fwstate != FW_READY ||
1918		    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
1919			return (-1);
1920		}
1921
1922		/*
1923		 * Force a logout if we were logged in.
1924		 */
1925		if (lp->loggedin) {
1926			if (lp->force_logout ||
1927			    isp_getpdb(isp, lp->loopid, &pdb) == 0) {
1928				mbs.param[0] = MBOX_FABRIC_LOGOUT;
1929				mbs.param[1] = lp->loopid << 8;
1930				mbs.param[2] = 0;
1931				mbs.param[3] = 0;
1932				isp_mboxcmd(isp, &mbs, MBLOGNONE);
1933				isp_prt(isp, ISP_LOGINFO, plogout,
1934				    (int) (lp - fcp->portdb), lp->loopid,
1935				    lp->portid);
1936			}
1937			lp->force_logout = lp->loggedin = 0;
1938			if (fcp->isp_fwstate != FW_READY ||
1939			    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
1940				return (-1);
1941			}
1942		}
1943
1944		/*
1945		 * And log in....
1946		 */
1947		loopid = lp - fcp->portdb;
1948		lp->loopid = FL_PORT_ID;
1949		do {
1950			mbs.param[0] = MBOX_FABRIC_LOGIN;
1951			mbs.param[1] = loopid << 8;
1952			mbs.param[2] = portid >> 16;
1953			mbs.param[3] = portid & 0xffff;
1954			isp_mboxcmd(isp, &mbs, MBLOGALL & ~(MBOX_LOOP_ID_USED |
1955			    MBOX_PORT_ID_USED | MBOX_COMMAND_ERROR));
1956			if (fcp->isp_fwstate != FW_READY ||
1957			    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
1958				return (-1);
1959			}
1960			switch (mbs.param[0]) {
1961			case MBOX_LOOP_ID_USED:
1962				/*
1963				 * Try the next available loop id.
1964				 */
1965				loopid++;
1966				break;
1967			case MBOX_PORT_ID_USED:
1968				/*
1969				 * This port is already logged in.
1970				 * Snaffle the loop id it's using if it's
1971				 * nonzero, otherwise we're hosed.
1972				 */
1973				if (mbs.param[1] != 0) {
1974					loopid = mbs.param[1];
1975					isp_prt(isp, ISP_LOGINFO, retained,
1976					    loopid, (int) (lp - fcp->portdb),
1977					    lp->portid);
1978				} else {
1979					loopid = MAX_FC_TARG;
1980					break;
1981				}
1982				/* FALLTHROUGH */
1983			case MBOX_COMMAND_COMPLETE:
1984				lp->loggedin = 1;
1985				lp->loopid = loopid;
1986				break;
1987			case MBOX_COMMAND_ERROR:
1988				isp_prt(isp, ISP_LOGINFO, plogierr,
1989				    portid, mbs.param[1]);
1990				/* FALLTHROUGH */
1991			case MBOX_ALL_IDS_USED: /* We're outta IDs */
1992			default:
1993				loopid = MAX_FC_TARG;
1994				break;
1995			}
1996		} while (lp->loopid == FL_PORT_ID && loopid < MAX_FC_TARG);
1997
1998		/*
1999		 * If we get here and we haven't set a Loop ID,
2000		 * we failed to log into this device.
2001		 */
2002
2003		if (lp->loopid == FL_PORT_ID) {
2004			lp->loopid = 0;
2005			continue;
2006		}
2007
2008		/*
2009		 * Make sure we can get the approriate port information.
2010		 */
2011		if (isp_getpdb(isp, lp->loopid, &pdb) != 0) {
2012			isp_prt(isp, ISP_LOGWARN, nopdb, lp->portid);
2013			goto dump_em;
2014		}
2015
2016		if (fcp->isp_fwstate != FW_READY ||
2017		    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
2018			return (-1);
2019		}
2020
2021		if (pdb.pdb_loopid != lp->loopid) {
2022			isp_prt(isp, ISP_LOGWARN, pdbmfail1,
2023			    lp->portid, pdb.pdb_loopid);
2024			goto dump_em;
2025		}
2026
2027		if (lp->portid != (u_int32_t) BITS2WORD(pdb.pdb_portid_bits)) {
2028			isp_prt(isp, ISP_LOGWARN, pdbmfail2,
2029			    lp->portid, BITS2WORD(pdb.pdb_portid_bits));
2030			goto dump_em;
2031		}
2032
2033		lp->roles =
2034		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
2035		lp->node_wwn =
2036		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
2037		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
2038		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
2039		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
2040		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
2041		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
2042		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
2043		    (((u_int64_t)pdb.pdb_nodename[7]));
2044		lp->port_wwn =
2045		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
2046		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
2047		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
2048		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
2049		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
2050		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
2051		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
2052		    (((u_int64_t)pdb.pdb_portname[7]));
2053		/*
2054		 * Check to make sure this all makes sense.
2055		 */
2056		if (lp->node_wwn && lp->port_wwn) {
2057			lp->valid = 1;
2058			loopid = lp - fcp->portdb;
2059			(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
2060			continue;
2061		}
2062dump_em:
2063		lp->valid = 0;
2064		isp_prt(isp, ISP_LOGINFO,
2065		    ldumped, loopid, lp->loopid, lp->portid);
2066		mbs.param[0] = MBOX_FABRIC_LOGOUT;
2067		mbs.param[1] = lp->loopid << 8;
2068		mbs.param[2] = 0;
2069		mbs.param[3] = 0;
2070		isp_mboxcmd(isp, &mbs, MBLOGNONE);
2071		if (fcp->isp_fwstate != FW_READY ||
2072		    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
2073			return (-1);
2074		}
2075	}
2076	/*
2077	 * If we get here, we've for sure seen not only a valid loop
2078	 * but know what is or isn't on it, so mark this for usage
2079	 * in isp_start.
2080	 */
2081	fcp->loop_seen_once = 1;
2082	fcp->isp_loopstate = LOOP_READY;
2083	return (0);
2084}
2085
2086static int
2087isp_scan_loop(struct ispsoftc *isp)
2088{
2089	struct lportdb *lp;
2090	fcparam *fcp = isp->isp_param;
2091	isp_pdb_t pdb;
2092	int loopid, lim, hival;
2093
2094	switch (fcp->isp_topo) {
2095	case TOPO_NL_PORT:
2096		hival = FL_PORT_ID;
2097		break;
2098	case TOPO_N_PORT:
2099		hival = 2;
2100		break;
2101	case TOPO_FL_PORT:
2102		hival = FC_PORT_ID;
2103		break;
2104	default:
2105		fcp->isp_loopstate = LOOP_LSCAN_DONE;
2106		return (0);
2107	}
2108	fcp->isp_loopstate = LOOP_SCANNING_LOOP;
2109
2110	/*
2111	 * make sure the temp port database is clean...
2112	 */
2113	MEMZERO((void *)fcp->tport, sizeof (fcp->tport));
2114
2115	/*
2116	 * Run through the local loop ports and get port database info
2117	 * for each loop ID.
2118	 *
2119	 * There's a somewhat unexplained situation where the f/w passes back
2120	 * the wrong database entity- if that happens, just restart (up to
2121	 * FL_PORT_ID times).
2122	 */
2123	for (lim = loopid = 0; loopid < hival; loopid++) {
2124		lp = &fcp->tport[loopid];
2125
2126		/*
2127		 * Don't even try for ourselves...
2128	 	 */
2129		if (loopid == fcp->isp_loopid)
2130			continue;
2131
2132		lp->node_wwn = isp_get_portname(isp, loopid, 1);
2133		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
2134			return (-1);
2135		if (lp->node_wwn == 0)
2136			continue;
2137		lp->port_wwn = isp_get_portname(isp, loopid, 0);
2138		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
2139			return (-1);
2140		if (lp->port_wwn == 0) {
2141			lp->node_wwn = 0;
2142			continue;
2143		}
2144
2145		/*
2146		 * Get an entry....
2147		 */
2148		if (isp_getpdb(isp, loopid, &pdb) != 0) {
2149			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
2150				return (-1);
2151			continue;
2152		}
2153		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2154			return (-1);
2155		}
2156
2157		/*
2158		 * If the returned database element doesn't match what we
2159		 * asked for, restart the process entirely (up to a point...).
2160		 */
2161		if (pdb.pdb_loopid != loopid) {
2162			loopid = 0;
2163			if (lim++ < hival) {
2164				continue;
2165			}
2166			isp_prt(isp, ISP_LOGWARN,
2167			    "giving up on synchronizing the port database");
2168			return (-1);
2169		}
2170
2171		/*
2172		 * Save the pertinent info locally.
2173		 */
2174		lp->node_wwn =
2175		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
2176		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
2177		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
2178		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
2179		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
2180		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
2181		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
2182		    (((u_int64_t)pdb.pdb_nodename[7]));
2183		lp->port_wwn =
2184		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
2185		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
2186		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
2187		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
2188		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
2189		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
2190		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
2191		    (((u_int64_t)pdb.pdb_portname[7]));
2192		lp->roles =
2193		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
2194		lp->portid = BITS2WORD(pdb.pdb_portid_bits);
2195		lp->loopid = pdb.pdb_loopid;
2196	}
2197
2198	/*
2199	 * Mark all of the permanent local loop database entries as invalid
2200	 * (except our own entry).
2201	 */
2202	for (loopid = 0; loopid < hival; loopid++) {
2203		if (loopid == fcp->isp_iid) {
2204			fcp->portdb[loopid].valid = 1;
2205			fcp->portdb[loopid].loopid = fcp->isp_loopid;
2206			continue;
2207		}
2208		fcp->portdb[loopid].valid = 0;
2209	}
2210
2211	/*
2212	 * Now merge our local copy of the port database into our saved copy.
2213	 * Notify the outer layers of new devices arriving.
2214	 */
2215	for (loopid = 0; loopid < hival; loopid++) {
2216		int i;
2217
2218		/*
2219		 * If we don't have a non-zero Port WWN, we're not here.
2220		 */
2221		if (fcp->tport[loopid].port_wwn == 0) {
2222			continue;
2223		}
2224
2225		/*
2226		 * Skip ourselves.
2227		 */
2228		if (loopid == fcp->isp_iid) {
2229			continue;
2230		}
2231
2232		/*
2233		 * For the purposes of deciding whether this is the
2234		 * 'same' device or not, we only search for an identical
2235		 * Port WWN. Node WWNs may or may not be the same as
2236		 * the Port WWN, and there may be multiple different
2237		 * Port WWNs with the same Node WWN. It would be chaos
2238		 * to have multiple identical Port WWNs, so we don't
2239		 * allow that.
2240		 */
2241
2242		for (i = 0; i < hival; i++) {
2243			int j;
2244			if (fcp->portdb[i].port_wwn == 0)
2245				continue;
2246			if (fcp->portdb[i].port_wwn !=
2247			    fcp->tport[loopid].port_wwn)
2248				continue;
2249			/*
2250			 * We found this WWN elsewhere- it's changed
2251			 * loopids then. We don't change it's actual
2252			 * position in our cached port database- we
2253			 * just change the actual loop ID we'd use.
2254			 */
2255			if (fcp->portdb[i].loopid != loopid) {
2256				isp_prt(isp, ISP_LOGINFO, portshift, i,
2257				    fcp->portdb[i].loopid,
2258				    fcp->portdb[i].portid, loopid,
2259				    fcp->tport[loopid].portid);
2260			}
2261			fcp->portdb[i].portid = fcp->tport[loopid].portid;
2262			fcp->portdb[i].loopid = loopid;
2263			fcp->portdb[i].valid = 1;
2264			fcp->portdb[i].roles = fcp->tport[loopid].roles;
2265
2266			/*
2267			 * Now make sure this Port WWN doesn't exist elsewhere
2268			 * in the port database.
2269			 */
2270			for (j = i+1; j < hival; j++) {
2271				if (fcp->portdb[i].port_wwn !=
2272				    fcp->portdb[j].port_wwn) {
2273					continue;
2274				}
2275				isp_prt(isp, ISP_LOGWARN, portdup, j, i);
2276				/*
2277				 * Invalidate the 'old' *and* 'new' ones.
2278				 * This is really harsh and not quite right,
2279				 * but if this happens, we really don't know
2280				 * who is what at this point.
2281				 */
2282				fcp->portdb[i].valid = 0;
2283				fcp->portdb[j].valid = 0;
2284			}
2285			break;
2286		}
2287
2288		/*
2289		 * If we didn't traverse the entire port database,
2290		 * then we found (and remapped) an existing entry.
2291		 * No need to notify anyone- go for the next one.
2292		 */
2293		if (i < hival) {
2294			isp_prt(isp, ISP_LOGINFO, retained,
2295			    fcp->portdb[i].loopid, i, fcp->portdb[i].portid);
2296			continue;
2297		}
2298
2299		/*
2300		 * We've not found this Port WWN anywhere. It's a new entry.
2301		 * See if we can leave it where it is (with target == loopid).
2302		 */
2303		if (fcp->portdb[loopid].port_wwn != 0) {
2304			for (lim = 0; lim < hival; lim++) {
2305				if (fcp->portdb[lim].port_wwn == 0)
2306					break;
2307			}
2308			/* "Cannot Happen" */
2309			if (lim == hival) {
2310				isp_prt(isp, ISP_LOGWARN, "Remap Overflow");
2311				continue;
2312			}
2313			i = lim;
2314		} else {
2315			i = loopid;
2316		}
2317
2318		/*
2319		 * NB:	The actual loopid we use here is loopid- we may
2320		 *	in fact be at a completely different index (target).
2321		 */
2322		fcp->portdb[i].loopid = loopid;
2323		fcp->portdb[i].port_wwn = fcp->tport[loopid].port_wwn;
2324		fcp->portdb[i].node_wwn = fcp->tport[loopid].node_wwn;
2325		fcp->portdb[i].roles = fcp->tport[loopid].roles;
2326		fcp->portdb[i].portid = fcp->tport[loopid].portid;
2327		fcp->portdb[i].valid = 1;
2328
2329		/*
2330		 * Tell the outside world we've arrived.
2331		 */
2332		(void) isp_async(isp, ISPASYNC_PROMENADE, &i);
2333	}
2334
2335	/*
2336	 * Now find all previously used targets that are now invalid and
2337	 * notify the outer layers that they're gone.
2338	 */
2339	for (lp = &fcp->portdb[0]; lp < &fcp->portdb[hival]; lp++) {
2340		if (lp->valid || lp->port_wwn == 0) {
2341			continue;
2342		}
2343
2344		/*
2345		 * Tell the outside world we've gone
2346		 * away and erase our pdb entry.
2347		 *
2348		 */
2349		loopid = lp - fcp->portdb;
2350		(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
2351		MEMZERO((void *) lp, sizeof (*lp));
2352	}
2353	fcp->isp_loopstate = LOOP_LSCAN_DONE;
2354	return (0);
2355}
2356
2357
2358static int
2359isp_fabric_mbox_cmd(struct ispsoftc *isp, mbreg_t *mbp)
2360{
2361	isp_mboxcmd(isp, mbp, MBLOGNONE);
2362	if (mbp->param[0] != MBOX_COMMAND_COMPLETE) {
2363		if (FCPARAM(isp)->isp_loopstate == LOOP_SCANNING_FABRIC) {
2364			FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
2365		}
2366		if (mbp->param[0] == MBOX_COMMAND_ERROR) {
2367			char tbuf[16];
2368			char *m;
2369			switch (mbp->param[1]) {
2370			case 1:
2371				m = "No Loop";
2372				break;
2373			case 2:
2374				m = "Failed to allocate IOCB buffer";
2375				break;
2376			case 3:
2377				m = "Failed to allocate XCB buffer";
2378				break;
2379			case 4:
2380				m = "timeout or transmit failed";
2381				break;
2382			case 5:
2383				m = "no fabric loop";
2384				break;
2385			case 6:
2386				m = "remote device not a target";
2387				break;
2388			default:
2389				SNPRINTF(tbuf, sizeof tbuf, "%x",
2390				    mbp->param[1]);
2391				m = tbuf;
2392				break;
2393			}
2394			isp_prt(isp, ISP_LOGERR, "SNS Failed- %s", m);
2395		}
2396		return (-1);
2397	}
2398
2399	if (FCPARAM(isp)->isp_fwstate != FW_READY ||
2400	    FCPARAM(isp)->isp_loopstate < LOOP_SCANNING_FABRIC) {
2401		return (-1);
2402	}
2403	return(0);
2404}
2405
2406#ifdef	ISP_USE_GA_NXT
2407static int
2408isp_scan_fabric(struct ispsoftc *isp, int ftype)
2409{
2410	fcparam *fcp = isp->isp_param;
2411	u_int32_t portid, first_portid, last_portid;
2412	int hicap, last_port_same;
2413
2414	if (fcp->isp_onfabric == 0) {
2415		fcp->isp_loopstate = LOOP_FSCAN_DONE;
2416		return (0);
2417	}
2418
2419	FC_SCRATCH_ACQUIRE(isp);
2420
2421	/*
2422	 * Since Port IDs are 24 bits, we can check against having seen
2423	 * anything yet with this value.
2424	 */
2425	last_port_same = 0;
2426	last_portid = 0xffffffff;	/* not a port */
2427	first_portid = portid = fcp->isp_portid;
2428	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
2429
2430	for (hicap = 0; hicap < GA_NXT_MAX; hicap++) {
2431		mbreg_t mbs;
2432		sns_screq_t *rq;
2433		sns_ga_nxt_rsp_t *rs0, *rs1;
2434		struct lportdb lcl;
2435		u_int8_t sc[SNS_GA_NXT_RESP_SIZE];
2436
2437		rq = (sns_screq_t *)sc;
2438		MEMZERO((void *) rq, SNS_GA_NXT_REQ_SIZE);
2439		rq->snscb_rblen = SNS_GA_NXT_RESP_SIZE >> 1;
2440		rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+0x100);
2441		rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+0x100);
2442		rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+0x100);
2443		rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+0x100);
2444		rq->snscb_sblen = 6;
2445		rq->snscb_data[0] = SNS_GA_NXT;
2446		rq->snscb_data[4] = portid & 0xffff;
2447		rq->snscb_data[5] = (portid >> 16) & 0xff;
2448		isp_put_sns_request(isp, rq, (sns_screq_t *) fcp->isp_scratch);
2449		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GA_NXT_REQ_SIZE);
2450		mbs.param[0] = MBOX_SEND_SNS;
2451		mbs.param[1] = SNS_GA_NXT_REQ_SIZE >> 1;
2452		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2453		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2454		/*
2455		 * Leave 4 and 5 alone
2456		 */
2457		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2458		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2459		if (isp_fabric_mbox_cmd(isp, &mbs)) {
2460			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
2461				fcp->isp_loopstate = LOOP_PDB_RCVD;
2462			}
2463			FC_SCRATCH_RELEASE(isp);
2464			return (-1);
2465		}
2466		MEMORYBARRIER(isp, SYNC_SFORCPU, 0x100, SNS_GA_NXT_RESP_SIZE);
2467		rs1 = (sns_ga_nxt_rsp_t *) sc;
2468		rs0 = (sns_ga_nxt_rsp_t *) ((u_int8_t *)fcp->isp_scratch+0x100);
2469		isp_get_ga_nxt_response(isp, rs0, rs1);
2470		if (rs1->snscb_cthdr.ct_response != FS_ACC) {
2471			int level;
2472			if (rs1->snscb_cthdr.ct_reason == 9 &&
2473			    rs1->snscb_cthdr.ct_explanation == 7)
2474				level = ISP_LOGDEBUG0;
2475			else
2476				level = ISP_LOGWARN;
2477			isp_prt(isp, level, swrej, "GA_NXT",
2478			    rs1->snscb_cthdr.ct_reason,
2479			    rs1->snscb_cthdr.ct_explanation, portid);
2480			FC_SCRATCH_RELEASE(isp);
2481			fcp->isp_loopstate = LOOP_FSCAN_DONE;
2482			return (0);
2483		}
2484		portid =
2485		    (((u_int32_t) rs1->snscb_port_id[0]) << 16) |
2486		    (((u_int32_t) rs1->snscb_port_id[1]) << 8) |
2487		    (((u_int32_t) rs1->snscb_port_id[2]));
2488
2489		/*
2490		 * XXX: We should check to make sure that this entry
2491		 * XXX: supports the type(s) we are interested in.
2492		 */
2493		/*
2494		 * Okay, we now have information about a fabric object.
2495		 * If it is the type we're interested in, tell the outer layers
2496		 * about it. The outer layer needs to  know: Port ID, WWNN,
2497		 * WWPN, FC4 type, and port type.
2498		 *
2499		 * The lportdb structure is adequate for this.
2500		 */
2501		MEMZERO(&lcl, sizeof (lcl));
2502		lcl.port_type = rs1->snscb_port_type;
2503		lcl.fc4_type = ftype;
2504		lcl.portid = portid;
2505		lcl.node_wwn =
2506		    (((u_int64_t)rs1->snscb_nodename[0]) << 56) |
2507		    (((u_int64_t)rs1->snscb_nodename[1]) << 48) |
2508		    (((u_int64_t)rs1->snscb_nodename[2]) << 40) |
2509		    (((u_int64_t)rs1->snscb_nodename[3]) << 32) |
2510		    (((u_int64_t)rs1->snscb_nodename[4]) << 24) |
2511		    (((u_int64_t)rs1->snscb_nodename[5]) << 16) |
2512		    (((u_int64_t)rs1->snscb_nodename[6]) <<  8) |
2513		    (((u_int64_t)rs1->snscb_nodename[7]));
2514		lcl.port_wwn =
2515		    (((u_int64_t)rs1->snscb_portname[0]) << 56) |
2516		    (((u_int64_t)rs1->snscb_portname[1]) << 48) |
2517		    (((u_int64_t)rs1->snscb_portname[2]) << 40) |
2518		    (((u_int64_t)rs1->snscb_portname[3]) << 32) |
2519		    (((u_int64_t)rs1->snscb_portname[4]) << 24) |
2520		    (((u_int64_t)rs1->snscb_portname[5]) << 16) |
2521		    (((u_int64_t)rs1->snscb_portname[6]) <<  8) |
2522		    (((u_int64_t)rs1->snscb_portname[7]));
2523
2524		/*
2525		 * Does this fabric object support the type we want?
2526		 * If not, skip it.
2527		 */
2528		if (rs1->snscb_fc4_types[ftype >> 5] & (1 << (ftype & 0x1f))) {
2529			if (first_portid == portid) {
2530				lcl.last_fabric_dev = 1;
2531			} else {
2532				lcl.last_fabric_dev = 0;
2533			}
2534			(void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
2535		} else {
2536			isp_prt(isp, ISP_LOGDEBUG0,
2537			    "PortID 0x%x doesn't support FC4 type 0x%x",
2538			    portid, ftype);
2539		}
2540		if (first_portid == portid) {
2541			fcp->isp_loopstate = LOOP_FSCAN_DONE;
2542			FC_SCRATCH_RELEASE(isp);
2543			return (0);
2544		}
2545		if (portid == last_portid) {
2546			if (last_port_same++ > 20) {
2547				isp_prt(isp, ISP_LOGWARN,
2548				    "tangled fabric database detected");
2549				break;
2550			}
2551		} else {
2552			last_port_same = 0 ;
2553			last_portid = portid;
2554		}
2555	}
2556	FC_SCRATCH_RELEASE(isp);
2557	if (hicap >= GA_NXT_MAX) {
2558		isp_prt(isp, ISP_LOGWARN, "fabric too big (> %d)", GA_NXT_MAX);
2559	}
2560	fcp->isp_loopstate = LOOP_FSCAN_DONE;
2561	return (0);
2562}
2563#else
2564#define	GIDLEN	((ISP2100_SCRLEN >> 1) + 16)
2565#define	NGENT	((GIDLEN - 16) >> 2)
2566
2567#define	IGPOFF	(ISP2100_SCRLEN - GIDLEN)
2568#define	GXOFF	(256)
2569
2570static int
2571isp_scan_fabric(struct ispsoftc *isp, int ftype)
2572{
2573	fcparam *fcp = FCPARAM(isp);
2574	mbreg_t mbs;
2575	int i;
2576	sns_gid_ft_req_t *rq;
2577	sns_gid_ft_rsp_t *rs0, *rs1;
2578
2579	if (fcp->isp_onfabric == 0) {
2580		fcp->isp_loopstate = LOOP_FSCAN_DONE;
2581		return (0);
2582	}
2583
2584	FC_SCRATCH_ACQUIRE(isp);
2585	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
2586
2587	rq = (sns_gid_ft_req_t *)fcp->tport;
2588	MEMZERO((void *) rq, SNS_GID_FT_REQ_SIZE);
2589	rq->snscb_rblen = GIDLEN >> 1;
2590	rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+IGPOFF);
2591	rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+IGPOFF);
2592	rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+IGPOFF);
2593	rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+IGPOFF);
2594	rq->snscb_sblen = 6;
2595	rq->snscb_cmd = SNS_GID_FT;
2596	rq->snscb_mword_div_2 = NGENT;
2597	rq->snscb_fc4_type = ftype;
2598	isp_put_gid_ft_request(isp, rq, (sns_gid_ft_req_t *) fcp->isp_scratch);
2599	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE);
2600	mbs.param[0] = MBOX_SEND_SNS;
2601	mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
2602	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2603	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2604
2605	/*
2606	 * Leave 4 and 5 alone
2607	 */
2608	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2609	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2610	if (isp_fabric_mbox_cmd(isp, &mbs)) {
2611		if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
2612			fcp->isp_loopstate = LOOP_PDB_RCVD;
2613		}
2614		FC_SCRATCH_RELEASE(isp);
2615		return (-1);
2616	}
2617	if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2618		FC_SCRATCH_RELEASE(isp);
2619		return (-1);
2620	}
2621	MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN);
2622	rs1 = (sns_gid_ft_rsp_t *) fcp->tport;
2623	rs0 = (sns_gid_ft_rsp_t *) ((u_int8_t *)fcp->isp_scratch+IGPOFF);
2624	isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
2625	if (rs1->snscb_cthdr.ct_response != FS_ACC) {
2626		int level;
2627		if (rs1->snscb_cthdr.ct_reason == 9 &&
2628		    rs1->snscb_cthdr.ct_explanation == 7)
2629			level = ISP_LOGDEBUG0;
2630		else
2631			level = ISP_LOGWARN;
2632		isp_prt(isp, level, swrej, "GID_FT",
2633		    rs1->snscb_cthdr.ct_reason,
2634		    rs1->snscb_cthdr.ct_explanation, 0);
2635		FC_SCRATCH_RELEASE(isp);
2636		fcp->isp_loopstate = LOOP_FSCAN_DONE;
2637		return (0);
2638	}
2639
2640	/*
2641	 * Okay, we now have a list of Port IDs for this class of device.
2642	 * Go through the list and for each one get the WWPN/WWNN for it
2643	 * and tell the outer layers about it. The outer layer needs to
2644	 * know: Port ID, WWNN, WWPN, FC4 type, and (possibly) port type.
2645	 *
2646	 * The lportdb structure is adequate for this.
2647	 */
2648	i = -1;
2649	do {
2650		sns_gxn_id_req_t grqbuf, *gq = &grqbuf;
2651		sns_gxn_id_rsp_t *gs0, grsbuf, *gs1 = &grsbuf;
2652		struct lportdb lcl;
2653#if	0
2654		sns_gff_id_rsp_t *fs0, ffsbuf, *fs1 = &ffsbuf;
2655#endif
2656
2657		i++;
2658		MEMZERO(&lcl, sizeof (lcl));
2659		lcl.fc4_type = ftype;
2660		lcl.portid =
2661		    (((u_int32_t) rs1->snscb_ports[i].portid[0]) << 16) |
2662		    (((u_int32_t) rs1->snscb_ports[i].portid[1]) << 8) |
2663		    (((u_int32_t) rs1->snscb_ports[i].portid[2]));
2664
2665		MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
2666		gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
2667		gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
2668		gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
2669		gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
2670		gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
2671		gq->snscb_sblen = 6;
2672		gq->snscb_cmd = SNS_GPN_ID;
2673		gq->snscb_portid = lcl.portid;
2674		isp_put_gxn_id_request(isp, gq,
2675		    (sns_gxn_id_req_t *) fcp->isp_scratch);
2676		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
2677		mbs.param[0] = MBOX_SEND_SNS;
2678		mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
2679		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2680		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2681		/*
2682		 * Leave 4 and 5 alone
2683		 */
2684		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2685		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2686		if (isp_fabric_mbox_cmd(isp, &mbs)) {
2687			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
2688				fcp->isp_loopstate = LOOP_PDB_RCVD;
2689			}
2690			FC_SCRATCH_RELEASE(isp);
2691			return (-1);
2692		}
2693		if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2694			FC_SCRATCH_RELEASE(isp);
2695			return (-1);
2696		}
2697		MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
2698		gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
2699		isp_get_gxn_id_response(isp, gs0, gs1);
2700		if (gs1->snscb_cthdr.ct_response != FS_ACC) {
2701			isp_prt(isp, ISP_LOGWARN, swrej, "GPN_ID",
2702			    gs1->snscb_cthdr.ct_reason,
2703			    gs1->snscb_cthdr.ct_explanation, lcl.portid);
2704			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2705				FC_SCRATCH_RELEASE(isp);
2706				return (-1);
2707			}
2708			continue;
2709		}
2710		lcl.port_wwn =
2711		    (((u_int64_t)gs1->snscb_wwn[0]) << 56) |
2712		    (((u_int64_t)gs1->snscb_wwn[1]) << 48) |
2713		    (((u_int64_t)gs1->snscb_wwn[2]) << 40) |
2714		    (((u_int64_t)gs1->snscb_wwn[3]) << 32) |
2715		    (((u_int64_t)gs1->snscb_wwn[4]) << 24) |
2716		    (((u_int64_t)gs1->snscb_wwn[5]) << 16) |
2717		    (((u_int64_t)gs1->snscb_wwn[6]) <<  8) |
2718		    (((u_int64_t)gs1->snscb_wwn[7]));
2719
2720		MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
2721		gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
2722		gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
2723		gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
2724		gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
2725		gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
2726		gq->snscb_sblen = 6;
2727		gq->snscb_cmd = SNS_GNN_ID;
2728		gq->snscb_portid = lcl.portid;
2729		isp_put_gxn_id_request(isp, gq,
2730		    (sns_gxn_id_req_t *) fcp->isp_scratch);
2731		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
2732		mbs.param[0] = MBOX_SEND_SNS;
2733		mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
2734		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2735		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2736		/*
2737		 * Leave 4 and 5 alone
2738		 */
2739		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2740		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2741		if (isp_fabric_mbox_cmd(isp, &mbs)) {
2742			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
2743				fcp->isp_loopstate = LOOP_PDB_RCVD;
2744			}
2745			FC_SCRATCH_RELEASE(isp);
2746			return (-1);
2747		}
2748		if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2749			FC_SCRATCH_RELEASE(isp);
2750			return (-1);
2751		}
2752		MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
2753		gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
2754		isp_get_gxn_id_response(isp, gs0, gs1);
2755		if (gs1->snscb_cthdr.ct_response != FS_ACC) {
2756			isp_prt(isp, ISP_LOGWARN, swrej, "GNN_ID",
2757			    gs1->snscb_cthdr.ct_reason,
2758			    gs1->snscb_cthdr.ct_explanation, lcl.portid);
2759			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2760				FC_SCRATCH_RELEASE(isp);
2761				return (-1);
2762			}
2763			continue;
2764		}
2765		lcl.node_wwn =
2766		    (((u_int64_t)gs1->snscb_wwn[0]) << 56) |
2767		    (((u_int64_t)gs1->snscb_wwn[1]) << 48) |
2768		    (((u_int64_t)gs1->snscb_wwn[2]) << 40) |
2769		    (((u_int64_t)gs1->snscb_wwn[3]) << 32) |
2770		    (((u_int64_t)gs1->snscb_wwn[4]) << 24) |
2771		    (((u_int64_t)gs1->snscb_wwn[5]) << 16) |
2772		    (((u_int64_t)gs1->snscb_wwn[6]) <<  8) |
2773		    (((u_int64_t)gs1->snscb_wwn[7]));
2774
2775		/*
2776		 * The QLogic f/w is bouncing this with a parameter error.
2777		 */
2778#if	0
2779		/*
2780		 * Try and get FC4 Features (FC-GS-3 only).
2781		 * We can use the sns_gxn_id_req_t for this request.
2782		 */
2783		MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
2784		gq->snscb_rblen = SNS_GFF_ID_RESP_SIZE >> 1;
2785		gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
2786		gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
2787		gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
2788		gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
2789		gq->snscb_sblen = 6;
2790		gq->snscb_cmd = SNS_GFF_ID;
2791		gq->snscb_portid = lcl.portid;
2792		isp_put_gxn_id_request(isp, gq,
2793		    (sns_gxn_id_req_t *) fcp->isp_scratch);
2794		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
2795		mbs.param[0] = MBOX_SEND_SNS;
2796		mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
2797		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2798		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2799		/*
2800		 * Leave 4 and 5 alone
2801		 */
2802		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2803		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2804		if (isp_fabric_mbox_cmd(isp, &mbs)) {
2805			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
2806				fcp->isp_loopstate = LOOP_PDB_RCVD;
2807			}
2808			FC_SCRATCH_RELEASE(isp);
2809			return (-1);
2810		}
2811		if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2812			FC_SCRATCH_RELEASE(isp);
2813			return (-1);
2814		}
2815		MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GFF_ID_RESP_SIZE);
2816		fs0 = (sns_gff_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
2817		isp_get_gff_id_response(isp, fs0, fs1);
2818		if (fs1->snscb_cthdr.ct_response != FS_ACC) {
2819			isp_prt(isp, /* ISP_LOGDEBUG0 */ ISP_LOGWARN,
2820			    swrej, "GFF_ID",
2821			    fs1->snscb_cthdr.ct_reason,
2822			    fs1->snscb_cthdr.ct_explanation, lcl.portid);
2823			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
2824				FC_SCRATCH_RELEASE(isp);
2825				return (-1);
2826			}
2827		} else {
2828			int index = (ftype >> 3);
2829			int bshft = (ftype & 0x7) * 4;
2830			int fc4_fval =
2831			    (fs1->snscb_fc4_features[index] >> bshft) & 0xf;
2832			if (fc4_fval & 0x1) {
2833				lcl.roles |=
2834				    (SVC3_INI_ROLE >> SVC3_ROLE_SHIFT);
2835			}
2836			if (fc4_fval & 0x2) {
2837				lcl.roles |=
2838				    (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT);
2839			}
2840		}
2841#endif
2842
2843		/*
2844		 * If we really want to know what kind of port type this is,
2845		 * we have to run another CT command. Otherwise, we'll leave
2846		 * it as undefined.
2847		 *
2848		lcl.port_type = 0;
2849		 */
2850		if (rs1->snscb_ports[i].control & 0x80) {
2851			lcl.last_fabric_dev = 1;
2852		} else {
2853			lcl.last_fabric_dev = 0;
2854		}
2855		(void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
2856
2857	} while ((rs1->snscb_ports[i].control & 0x80) == 0 && i < NGENT-1);
2858
2859	/*
2860	 * If we're not at the last entry, our list isn't big enough.
2861	 */
2862	if ((rs1->snscb_ports[i].control & 0x80) == 0) {
2863		isp_prt(isp, ISP_LOGWARN, "fabric too big for scratch area");
2864	}
2865
2866	FC_SCRATCH_RELEASE(isp);
2867	fcp->isp_loopstate = LOOP_FSCAN_DONE;
2868	return (0);
2869}
2870#endif
2871
2872static void
2873isp_register_fc4_type(struct ispsoftc *isp)
2874{
2875	fcparam *fcp = isp->isp_param;
2876	u_int8_t local[SNS_RFT_ID_REQ_SIZE];
2877	sns_screq_t *reqp = (sns_screq_t *) local;
2878	mbreg_t mbs;
2879
2880	MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
2881	reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
2882	reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
2883	reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
2884	reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
2885	reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
2886	reqp->snscb_sblen = 22;
2887	reqp->snscb_data[0] = SNS_RFT_ID;
2888	reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
2889	reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
2890	reqp->snscb_data[6] = (1 << FC4_SCSI);
2891#if	0
2892	reqp->snscb_data[6] |= (1 << FC4_IP);	/* ISO/IEC 8802-2 LLC/SNAP */
2893#endif
2894	FC_SCRATCH_ACQUIRE(isp);
2895	isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
2896	mbs.param[0] = MBOX_SEND_SNS;
2897	mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
2898	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2899	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2900	/*
2901	 * Leave 4 and 5 alone
2902	 */
2903	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2904	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2905	isp_mboxcmd(isp, &mbs, MBLOGALL);
2906	FC_SCRATCH_RELEASE(isp);
2907	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
2908		isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 types succeeded");
2909	}
2910}
2911
2912/*
2913 * Start a command. Locking is assumed done in the caller.
2914 */
2915
2916int
2917isp_start(XS_T *xs)
2918{
2919	struct ispsoftc *isp;
2920	u_int16_t nxti, optr, handle;
2921	u_int8_t local[QENTRY_LEN];
2922	ispreq_t *reqp, *qep;
2923	int target, i;
2924
2925	XS_INITERR(xs);
2926	isp = XS_ISP(xs);
2927
2928	/*
2929	 * Check to make sure we're supporting initiator role.
2930	 */
2931	if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
2932		XS_SETERR(xs, HBA_SELTIMEOUT);
2933		return (CMD_COMPLETE);
2934	}
2935
2936	/*
2937	 * Now make sure we're running.
2938	 */
2939
2940	if (isp->isp_state != ISP_RUNSTATE) {
2941		isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
2942		XS_SETERR(xs, HBA_BOTCH);
2943		return (CMD_COMPLETE);
2944	}
2945
2946	/*
2947	 * Check command CDB length, etc.. We really are limited to 16 bytes
2948	 * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
2949	 * but probably only if we're running fairly new firmware (we'll
2950	 * let the old f/w choke on an extended command queue entry).
2951	 */
2952
2953	if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
2954		isp_prt(isp, ISP_LOGERR,
2955		    "unsupported cdb length (%d, CDB[0]=0x%x)",
2956		    XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
2957		XS_SETERR(xs, HBA_BOTCH);
2958		return (CMD_COMPLETE);
2959	}
2960
2961	/*
2962	 * Check to see whether we have good firmware state still or
2963	 * need to refresh our port database for this target.
2964	 */
2965	target = XS_TGT(xs);
2966	if (IS_FC(isp)) {
2967		fcparam *fcp = isp->isp_param;
2968		struct lportdb *lp;
2969#ifdef	HANDLE_LOOPSTATE_IN_OUTER_LAYERS
2970		if (fcp->isp_fwstate != FW_READY ||
2971		    fcp->isp_loopstate != LOOP_READY) {
2972			return (CMD_RQLATER);
2973		}
2974
2975		/*
2976		 * If we're not on a Fabric, we can't have a target
2977		 * above FL_PORT_ID-1.
2978		 *
2979		 * If we're on a fabric and *not* connected as an F-port,
2980		 * we can't have a target less than FC_SNS_ID+1. This
2981		 * keeps us from having to sort out the difference between
2982		 * local public loop devices and those which we might get
2983		 * from a switch's database.
2984		 */
2985		if (fcp->isp_onfabric == 0) {
2986			if (target >= FL_PORT_ID) {
2987				XS_SETERR(xs, HBA_SELTIMEOUT);
2988				return (CMD_COMPLETE);
2989			}
2990		} else {
2991			if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
2992				XS_SETERR(xs, HBA_SELTIMEOUT);
2993				return (CMD_COMPLETE);
2994			}
2995			/*
2996			 * We used to exclude having local loop ports
2997			 * at the same time that we have fabric ports.
2998			 * That is, we used to exclude having ports
2999			 * at < FL_PORT_ID if we're FL-port.
3000			 *
3001			 * That's wrong. The only thing that could be
3002			 * dicey is if the switch you're connected to
3003			 * has these local loop ports appear on the
3004			 * fabric and we somehow attach them twice.
3005			 */
3006		}
3007#else
3008		/*
3009		 * Check for f/w being in ready state. If the f/w
3010		 * isn't in ready state, then we don't know our
3011		 * loop ID and the f/w hasn't completed logging
3012		 * into all targets on the loop. If this is the
3013		 * case, then bounce the command. We pretend this is
3014		 * a SELECTION TIMEOUT error if we've never gone to
3015		 * FW_READY state at all- in this case we may not
3016		 * be hooked to a loop at all and we shouldn't hang
3017		 * the machine for this. Otherwise, defer this command
3018		 * until later.
3019		 */
3020		if (fcp->isp_fwstate != FW_READY) {
3021			/*
3022			 * Give ourselves at most a 250ms delay.
3023			 */
3024			if (isp_fclink_test(isp, 250000)) {
3025				XS_SETERR(xs, HBA_SELTIMEOUT);
3026				if (fcp->loop_seen_once) {
3027					return (CMD_RQLATER);
3028				} else {
3029					return (CMD_COMPLETE);
3030				}
3031			}
3032		}
3033
3034		/*
3035		 * If we're not on a Fabric, we can't have a target
3036		 * above FL_PORT_ID-1.
3037		 *
3038		 * If we're on a fabric and *not* connected as an F-port,
3039		 * we can't have a target less than FC_SNS_ID+1. This
3040		 * keeps us from having to sort out the difference between
3041		 * local public loop devices and those which we might get
3042		 * from a switch's database.
3043		 */
3044		if (fcp->isp_onfabric == 0) {
3045			if (target >= FL_PORT_ID) {
3046				XS_SETERR(xs, HBA_SELTIMEOUT);
3047				return (CMD_COMPLETE);
3048			}
3049		} else {
3050			if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
3051				XS_SETERR(xs, HBA_SELTIMEOUT);
3052				return (CMD_COMPLETE);
3053			}
3054			if (fcp->isp_topo != TOPO_F_PORT &&
3055			    target < FL_PORT_ID) {
3056				XS_SETERR(xs, HBA_SELTIMEOUT);
3057				return (CMD_COMPLETE);
3058			}
3059		}
3060
3061		/*
3062		 * If our loop state is such that we haven't yet received
3063		 * a "Port Database Changed" notification (after a LIP or
3064		 * a Loop Reset or firmware initialization), then defer
3065		 * sending commands for a little while, but only if we've
3066		 * seen a valid loop at one point (otherwise we can get
3067		 * stuck at initialization time).
3068		 */
3069		if (fcp->isp_loopstate < LOOP_PDB_RCVD) {
3070			XS_SETERR(xs, HBA_SELTIMEOUT);
3071			if (fcp->loop_seen_once) {
3072				return (CMD_RQLATER);
3073			} else {
3074				return (CMD_COMPLETE);
3075			}
3076		}
3077
3078		/*
3079		 * If we're in the middle of loop or fabric scanning
3080		 * or merging the port databases, retry this command later.
3081		 */
3082		if (fcp->isp_loopstate == LOOP_SCANNING_FABRIC ||
3083		    fcp->isp_loopstate == LOOP_SCANNING_LOOP ||
3084		    fcp->isp_loopstate == LOOP_SYNCING_PDB) {
3085			return (CMD_RQLATER);
3086		}
3087
3088		/*
3089		 * If our loop state is now such that we've just now
3090		 * received a Port Database Change notification, then
3091		 * we have to go off and (re)scan the fabric. We back
3092		 * out and try again later if this doesn't work.
3093		 */
3094		if (fcp->isp_loopstate == LOOP_PDB_RCVD && fcp->isp_onfabric) {
3095			if (isp_scan_fabric(isp, FC4_SCSI)) {
3096				return (CMD_RQLATER);
3097			}
3098			if (fcp->isp_fwstate != FW_READY ||
3099			    fcp->isp_loopstate < LOOP_FSCAN_DONE) {
3100				return (CMD_RQLATER);
3101			}
3102		}
3103
3104		/*
3105		 * If our loop state is now such that we've just now
3106		 * received a Port Database Change notification, then
3107		 * we have to go off and (re)synchronize our port
3108		 * database.
3109		 */
3110		if (fcp->isp_loopstate < LOOP_READY) {
3111			if (isp_pdb_sync(isp)) {
3112				return (CMD_RQLATER);
3113			}
3114			if (fcp->isp_fwstate != FW_READY ||
3115			    fcp->isp_loopstate != LOOP_READY) {
3116				return (CMD_RQLATER);
3117			}
3118		}
3119
3120		/*
3121		 * XXX: Here's were we would cancel any loop_dead flag
3122		 * XXX: also cancel in dead_loop timeout that's running
3123		 */
3124#endif
3125
3126		/*
3127		 * Now check whether we should even think about pursuing this.
3128		 */
3129		lp = &fcp->portdb[target];
3130		if (lp->valid == 0) {
3131			XS_SETERR(xs, HBA_SELTIMEOUT);
3132			return (CMD_COMPLETE);
3133		}
3134		if ((lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) == 0) {
3135			isp_prt(isp, ISP_LOGDEBUG2,
3136			    "Target %d does not have target service", target);
3137			XS_SETERR(xs, HBA_SELTIMEOUT);
3138			return (CMD_COMPLETE);
3139		}
3140		/*
3141		 * Now turn target into what the actual Loop ID is.
3142		 */
3143		target = lp->loopid;
3144	}
3145
3146	/*
3147	 * Next check to see if any HBA or Device
3148	 * parameters need to be updated.
3149	 */
3150	if (isp->isp_update != 0) {
3151		isp_update(isp);
3152	}
3153
3154	if (isp_getrqentry(isp, &nxti, &optr, (void **)&qep)) {
3155		isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
3156		XS_SETERR(xs, HBA_BOTCH);
3157		return (CMD_EAGAIN);
3158	}
3159
3160	/*
3161	 * Now see if we need to synchronize the ISP with respect to anything.
3162	 * We do dual duty here (cough) for synchronizing for busses other
3163	 * than which we got here to send a command to.
3164	 */
3165	reqp = (ispreq_t *) local;
3166	if (isp->isp_sendmarker) {
3167		u_int8_t n = (IS_DUALBUS(isp)? 2: 1);
3168		/*
3169		 * Check ports to send markers for...
3170		 */
3171		for (i = 0; i < n; i++) {
3172			if ((isp->isp_sendmarker & (1 << i)) == 0) {
3173				continue;
3174			}
3175			MEMZERO((void *) reqp, QENTRY_LEN);
3176			reqp->req_header.rqs_entry_count = 1;
3177			reqp->req_header.rqs_entry_type = RQSTYPE_MARKER;
3178			reqp->req_modifier = SYNC_ALL;
3179			reqp->req_target = i << 7;	/* insert bus number */
3180			isp_put_request(isp, reqp, qep);
3181			ISP_ADD_REQUEST(isp, nxti);
3182			isp->isp_sendmarker &= ~(1 << i);
3183			if (isp_getrqentry(isp, &nxti, &optr, (void **) &qep)) {
3184				isp_prt(isp, ISP_LOGDEBUG0,
3185				    "Request Queue Overflow+");
3186				XS_SETERR(xs, HBA_BOTCH);
3187				return (CMD_EAGAIN);
3188			}
3189		}
3190	}
3191
3192	MEMZERO((void *)reqp, QENTRY_LEN);
3193	reqp->req_header.rqs_entry_count = 1;
3194	if (IS_FC(isp)) {
3195		reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
3196	} else {
3197		if (XS_CDBLEN(xs) > 12)
3198			reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
3199		else
3200			reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
3201	}
3202	/* reqp->req_header.rqs_flags = 0; */
3203	/* reqp->req_header.rqs_seqno = 0; */
3204	if (IS_FC(isp)) {
3205		/*
3206		 * See comment in isp_intr
3207		 */
3208		/* XS_RESID(xs) = 0; */
3209
3210		/*
3211		 * Fibre Channel always requires some kind of tag.
3212		 * The Qlogic drivers seem be happy not to use a tag,
3213		 * but this breaks for some devices (IBM drives).
3214		 */
3215		if (XS_TAG_P(xs)) {
3216			((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
3217		} else {
3218			/*
3219			 * If we don't know what tag to use, use HEAD OF QUEUE
3220			 * for Request Sense or Simple.
3221			 */
3222			if (XS_CDBP(xs)[0] == 0x3)	/* REQUEST SENSE */
3223				((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
3224			else
3225				((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
3226		}
3227	} else {
3228		sdparam *sdp = (sdparam *)isp->isp_param;
3229		sdp += XS_CHANNEL(xs);
3230		if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) &&
3231		    XS_TAG_P(xs)) {
3232			reqp->req_flags = XS_TAG_TYPE(xs);
3233		}
3234	}
3235	reqp->req_target = target | (XS_CHANNEL(xs) << 7);
3236	if (IS_SCSI(isp)) {
3237		reqp->req_lun_trn = XS_LUN(xs);
3238		reqp->req_cdblen = XS_CDBLEN(xs);
3239	} else {
3240		if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)
3241			((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
3242		else
3243			((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
3244	}
3245	MEMCPY(reqp->req_cdb, XS_CDBP(xs), XS_CDBLEN(xs));
3246
3247	reqp->req_time = XS_TIME(xs) / 1000;
3248	if (reqp->req_time == 0 && XS_TIME(xs)) {
3249		reqp->req_time = 1;
3250	}
3251
3252	if (isp_save_xs(isp, xs, &handle)) {
3253		isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
3254		XS_SETERR(xs, HBA_BOTCH);
3255		return (CMD_EAGAIN);
3256	}
3257	reqp->req_handle = handle;
3258
3259	/*
3260	 * Set up DMA and/or do any bus swizzling of the request entry
3261	 * so that the Qlogic F/W understands what is being asked of it.
3262	 */
3263	i = ISP_DMASETUP(isp, xs, reqp, &nxti, optr);
3264	if (i != CMD_QUEUED) {
3265		isp_destroy_handle(isp, handle);
3266		/*
3267		 * dmasetup sets actual error in packet, and
3268		 * return what we were given to return.
3269		 */
3270		return (i);
3271	}
3272	XS_SETERR(xs, HBA_NOERROR);
3273	isp_prt(isp, ISP_LOGDEBUG2,
3274	    "START cmd for %d.%d.%d cmd 0x%x datalen %ld",
3275	    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0],
3276	    (long) XS_XFRLEN(xs));
3277	ISP_ADD_REQUEST(isp, nxti);
3278	isp->isp_nactive++;
3279	return (CMD_QUEUED);
3280}
3281
3282/*
3283 * isp control
3284 * Locks (ints blocked) assumed held.
3285 */
3286
3287int
3288isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
3289{
3290	XS_T *xs;
3291	mbreg_t mbs;
3292	int bus, tgt;
3293	u_int16_t handle;
3294
3295	switch (ctl) {
3296	default:
3297		isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
3298		break;
3299
3300	case ISPCTL_RESET_BUS:
3301		/*
3302		 * Issue a bus reset.
3303		 */
3304		mbs.param[0] = MBOX_BUS_RESET;
3305		mbs.param[2] = 0;
3306		if (IS_SCSI(isp)) {
3307			mbs.param[1] =
3308			    ((sdparam *) isp->isp_param)->isp_bus_reset_delay;
3309			if (mbs.param[1] < 2)
3310				mbs.param[1] = 2;
3311			bus = *((int *) arg);
3312			if (IS_DUALBUS(isp))
3313				mbs.param[2] = bus;
3314		} else {
3315			mbs.param[1] = 10;
3316			bus = 0;
3317		}
3318		isp->isp_sendmarker |= (1 << bus);
3319		isp_mboxcmd(isp, &mbs, MBLOGALL);
3320		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3321			break;
3322		}
3323		isp_prt(isp, ISP_LOGINFO,
3324		    "driver initiated bus reset of bus %d", bus);
3325		return (0);
3326
3327	case ISPCTL_RESET_DEV:
3328		tgt = (*((int *) arg)) & 0xffff;
3329		bus = (*((int *) arg)) >> 16;
3330		mbs.param[0] = MBOX_ABORT_TARGET;
3331		mbs.param[1] = (tgt << 8) | (bus << 15);
3332		mbs.param[2] = 3;	/* 'delay', in seconds */
3333		isp_mboxcmd(isp, &mbs, MBLOGALL);
3334		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3335			break;
3336		}
3337		isp_prt(isp, ISP_LOGINFO,
3338		    "Target %d on Bus %d Reset Succeeded", tgt, bus);
3339		isp->isp_sendmarker |= (1 << bus);
3340		return (0);
3341
3342	case ISPCTL_ABORT_CMD:
3343		xs = (XS_T *) arg;
3344		tgt = XS_TGT(xs);
3345		handle = isp_find_handle(isp, xs);
3346		if (handle == 0) {
3347			isp_prt(isp, ISP_LOGWARN,
3348			    "cannot find handle for command to abort");
3349			break;
3350		}
3351		bus = XS_CHANNEL(xs);
3352		mbs.param[0] = MBOX_ABORT;
3353		if (IS_FC(isp)) {
3354			if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)  {
3355				mbs.param[1] = tgt << 8;
3356				mbs.param[4] = 0;
3357				mbs.param[5] = 0;
3358				mbs.param[6] = XS_LUN(xs);
3359			} else {
3360				mbs.param[1] = tgt << 8 | XS_LUN(xs);
3361			}
3362		} else {
3363			mbs.param[1] =
3364			    (bus << 15) | (XS_TGT(xs) << 8) | XS_LUN(xs);
3365		}
3366		mbs.param[3] = 0;
3367		mbs.param[2] = handle;
3368		isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_ERROR);
3369		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
3370			return (0);
3371		}
3372		/*
3373		 * XXX: Look for command in the REQUEST QUEUE. That is,
3374		 * XXX: It hasen't been picked up by firmware yet.
3375		 */
3376		break;
3377
3378	case ISPCTL_UPDATE_PARAMS:
3379
3380		isp_update(isp);
3381		return (0);
3382
3383	case ISPCTL_FCLINK_TEST:
3384
3385		if (IS_FC(isp)) {
3386			int usdelay = (arg)? *((int *) arg) : 250000;
3387			return (isp_fclink_test(isp, usdelay));
3388		}
3389		break;
3390
3391	case ISPCTL_SCAN_FABRIC:
3392
3393		if (IS_FC(isp)) {
3394			int ftype = (arg)? *((int *) arg) : FC4_SCSI;
3395			return (isp_scan_fabric(isp, ftype));
3396		}
3397		break;
3398
3399	case ISPCTL_SCAN_LOOP:
3400
3401		if (IS_FC(isp)) {
3402			return (isp_scan_loop(isp));
3403		}
3404		break;
3405
3406	case ISPCTL_PDB_SYNC:
3407
3408		if (IS_FC(isp)) {
3409			return (isp_pdb_sync(isp));
3410		}
3411		break;
3412
3413	case ISPCTL_SEND_LIP:
3414
3415		if (IS_FC(isp)) {
3416			mbs.param[0] = MBOX_INIT_LIP;
3417			isp_mboxcmd(isp, &mbs, MBLOGALL);
3418			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
3419				return (0);
3420			}
3421		}
3422		break;
3423
3424	case ISPCTL_GET_POSMAP:
3425
3426		if (IS_FC(isp) && arg) {
3427			return (isp_getmap(isp, arg));
3428		}
3429		break;
3430
3431	case ISPCTL_RUN_MBOXCMD:
3432
3433		isp_mboxcmd(isp, arg, MBLOGALL);
3434		return(0);
3435
3436#ifdef	ISP_TARGET_MODE
3437	case ISPCTL_TOGGLE_TMODE:
3438	{
3439
3440		/*
3441		 * We don't check/set against role here- that's the
3442		 * responsibility for the outer layer to coordinate.
3443		 */
3444		if (IS_SCSI(isp)) {
3445			int param = *(int *)arg;
3446			mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
3447			mbs.param[1] = param & 0xffff;
3448			mbs.param[2] = param >> 16;
3449			isp_mboxcmd(isp, &mbs, MBLOGALL);
3450			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3451				break;
3452			}
3453		}
3454		return (0);
3455	}
3456#endif
3457	}
3458	return (-1);
3459}
3460
3461/*
3462 * Interrupt Service Routine(s).
3463 *
3464 * External (OS) framework has done the appropriate locking,
3465 * and the locking will be held throughout this function.
3466 */
3467
3468/*
3469 * Limit our stack depth by sticking with the max likely number
3470 * of completions on a request queue at any one time.
3471 */
3472#ifndef	MAX_REQUESTQ_COMPLETIONS
3473#define	MAX_REQUESTQ_COMPLETIONS	64
3474#endif
3475
3476void
3477isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
3478{
3479	XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
3480	u_int16_t iptr, optr, junk;
3481	int i, nlooked = 0, ndone = 0;
3482
3483again:
3484	/*
3485	 * Is this a mailbox related interrupt?
3486	 * The mailbox semaphore will be nonzero if so.
3487	 */
3488	if (sema) {
3489		if (mbox & 0x4000) {
3490			isp->isp_intmboxc++;
3491			if (isp->isp_mboxbsy) {
3492				int i = 0, obits = isp->isp_obits;
3493				isp->isp_mboxtmp[i++] = mbox;
3494				for (i = 1; i < MAX_MAILBOX; i++) {
3495					if ((obits & (1 << i)) == 0) {
3496						continue;
3497					}
3498					isp->isp_mboxtmp[i] =
3499					    ISP_READ(isp, MBOX_OFF(i));
3500				}
3501				if (isp->isp_mbxwrk0) {
3502					if (isp_mbox_continue(isp) == 0) {
3503						return;
3504					}
3505				}
3506				MBOX_NOTIFY_COMPLETE(isp);
3507			} else {
3508				isp_prt(isp, ISP_LOGWARN,
3509				    "Mbox Command Async (0x%x) with no waiters",
3510				    mbox);
3511			}
3512		} else if (isp_parse_async(isp, mbox) < 0) {
3513			return;
3514		}
3515		if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) ||
3516		    isp->isp_state != ISP_RUNSTATE) {
3517			ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3518			ISP_WRITE(isp, BIU_SEMA, 0);
3519			return;
3520		}
3521	}
3522
3523	/*
3524	 * We can't be getting this now.
3525	 */
3526	if (isp->isp_state != ISP_RUNSTATE) {
3527		isp_prt(isp, ISP_LOGWARN,
3528		    "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
3529		/*
3530		 * Thank you very much!  *Burrrp*!
3531		 */
3532		WRITE_RESPONSE_QUEUE_OUT_POINTER(isp,
3533		    READ_RESPONSE_QUEUE_IN_POINTER(isp));
3534
3535		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3536		ISP_WRITE(isp, BIU_SEMA, 0);
3537		return;
3538	}
3539
3540	/*
3541	 * Get the current Response Queue Out Pointer.
3542	 *
3543	 * If we're a 2300, we can ask what hardware what it thinks.
3544	 */
3545	if (IS_23XX(isp)) {
3546		optr = ISP_READ(isp, isp->isp_respoutrp);
3547		/*
3548		 * Debug: to be taken out eventually
3549		 */
3550		if (isp->isp_residx != optr) {
3551			isp_prt(isp, ISP_LOGWARN, "optr %x soft optr %x",
3552			    optr, isp->isp_residx);
3553		}
3554	} else {
3555		optr = isp->isp_residx;
3556	}
3557
3558	/*
3559	 * You *must* read the Response Queue In Pointer
3560	 * prior to clearing the RISC interrupt.
3561	 *
3562	 * Debounce the 2300 if revision less than 2.
3563	 */
3564	if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
3565		i = 0;
3566		do {
3567			iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
3568			junk = READ_RESPONSE_QUEUE_IN_POINTER(isp);
3569		} while (junk != iptr && ++i < 1000);
3570
3571		if (iptr != junk) {
3572			ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3573			isp_prt(isp, ISP_LOGWARN,
3574			    "Response Queue Out Pointer Unstable (%x, %x)",
3575			    iptr, junk);
3576			return;
3577		}
3578	} else {
3579		iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
3580	}
3581	isp->isp_resodx = iptr;
3582
3583
3584	if (optr == iptr && sema == 0) {
3585		/*
3586		 * There are a lot of these- reasons unknown- mostly on
3587		 * faster Alpha machines.
3588		 *
3589		 * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
3590		 * make sure the old interrupt went away (to avoid 'ringing'
3591		 * effects), but that didn't stop this from occurring.
3592		 */
3593		if (IS_23XX(isp)) {
3594			USEC_DELAY(100);
3595			iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
3596			junk = ISP_READ(isp, BIU_R2HSTSLO);
3597		} else {
3598			junk = ISP_READ(isp, BIU_ISR);
3599		}
3600		if (optr == iptr) {
3601			if (IS_23XX(isp)) {
3602				;
3603			} else {
3604				sema = ISP_READ(isp, BIU_SEMA);
3605				mbox = ISP_READ(isp, OUTMAILBOX0);
3606				if ((sema & 0x3) && (mbox & 0x8000)) {
3607					goto again;
3608				}
3609			}
3610			isp->isp_intbogus++;
3611			isp_prt(isp, ISP_LOGDEBUG1,
3612			    "bogus intr- isr %x (%x) iptr %x optr %x",
3613			    isr, junk, iptr, optr);
3614		}
3615	}
3616	isp->isp_resodx = iptr;
3617	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3618	ISP_WRITE(isp, BIU_SEMA, 0);
3619
3620	if (isp->isp_rspbsy) {
3621		return;
3622	}
3623	isp->isp_rspbsy = 1;
3624
3625	while (optr != iptr) {
3626		ispstatusreq_t local, *sp = &local;
3627		isphdr_t *hp;
3628		int type;
3629		u_int16_t oop;
3630		int buddaboom = 0;
3631
3632		hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
3633		oop = optr;
3634		optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
3635		nlooked++;
3636		/*
3637		 * Synchronize our view of this response queue entry.
3638		 */
3639		MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN);
3640
3641		type = isp_get_response_type(isp, hp);
3642
3643		if (type == RQSTYPE_RESPONSE) {
3644			isp_get_response(isp, (ispstatusreq_t *) hp, sp);
3645		} else if (type == RQSTYPE_RIO2) {
3646			isp_rio2_t rio;
3647			isp_get_rio2(isp, (isp_rio2_t *) hp, &rio);
3648			for (i = 0; i < rio.req_header.rqs_seqno; i++) {
3649				isp_fastpost_complete(isp, rio.req_handles[i]);
3650			}
3651			if (isp->isp_fpcchiwater < rio.req_header.rqs_seqno)
3652				isp->isp_fpcchiwater = rio.req_header.rqs_seqno;
3653			MEMZERO(hp, QENTRY_LEN);	/* PERF */
3654			continue;
3655		} else {
3656			/*
3657			 * Somebody reachable via isp_handle_other_response
3658			 * may have updated the response queue pointers for
3659			 * us, so we reload our goal index.
3660			 */
3661			if (isp_handle_other_response(isp, type, hp, &optr)) {
3662				iptr = isp->isp_resodx;
3663				MEMZERO(hp, QENTRY_LEN);	/* PERF */
3664				continue;
3665			}
3666
3667			/*
3668			 * After this point, we'll just look at the header as
3669			 * we don't know how to deal with the rest of the
3670			 * response.
3671			 */
3672			isp_get_response(isp, (ispstatusreq_t *) hp, sp);
3673
3674			/*
3675			 * It really has to be a bounced request just copied
3676			 * from the request queue to the response queue. If
3677			 * not, something bad has happened.
3678			 */
3679			if (sp->req_header.rqs_entry_type != RQSTYPE_REQUEST) {
3680				isp_prt(isp, ISP_LOGERR, notresp,
3681				    sp->req_header.rqs_entry_type, oop, optr,
3682				    nlooked);
3683				if (isp->isp_dblev & ISP_LOGDEBUG0) {
3684					isp_print_bytes(isp, "Queue Entry",
3685					    QENTRY_LEN, sp);
3686				}
3687				MEMZERO(hp, QENTRY_LEN);	/* PERF */
3688				continue;
3689			}
3690			buddaboom = 1;
3691		}
3692
3693		if (sp->req_header.rqs_flags & 0xf) {
3694#define	_RQS_OFLAGS	\
3695	~(RQSFLAG_CONTINUATION|RQSFLAG_FULL|RQSFLAG_BADHEADER|RQSFLAG_BADPACKET)
3696			if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
3697				isp_prt(isp, ISP_LOGWARN,
3698				    "continuation segment");
3699				WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
3700				continue;
3701			}
3702			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
3703				isp_prt(isp, ISP_LOGDEBUG1,
3704				    "internal queues full");
3705				/*
3706				 * We'll synthesize a QUEUE FULL message below.
3707				 */
3708			}
3709			if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
3710				isp_prt(isp, ISP_LOGERR,  "bad header flag");
3711				buddaboom++;
3712			}
3713			if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
3714				isp_prt(isp, ISP_LOGERR, "bad request packet");
3715				buddaboom++;
3716			}
3717			if (sp->req_header.rqs_flags & _RQS_OFLAGS) {
3718				isp_prt(isp, ISP_LOGERR,
3719				    "unknown flags (0x%x) in response",
3720				    sp->req_header.rqs_flags);
3721				buddaboom++;
3722			}
3723#undef	_RQS_OFLAGS
3724		}
3725		if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) {
3726			MEMZERO(hp, QENTRY_LEN);	/* PERF */
3727			isp_prt(isp, ISP_LOGERR,
3728			    "bad request handle %d (type 0x%x, flags 0x%x)",
3729			    sp->req_handle, sp->req_header.rqs_entry_type,
3730			    sp->req_header.rqs_flags);
3731			WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
3732			continue;
3733		}
3734		xs = isp_find_xs(isp, sp->req_handle);
3735		if (xs == NULL) {
3736			u_int8_t ts = sp->req_completion_status & 0xff;
3737			MEMZERO(hp, QENTRY_LEN);	/* PERF */
3738			/*
3739			 * Only whine if this isn't the expected fallout of
3740			 * aborting the command.
3741			 */
3742			if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) {
3743				isp_prt(isp, ISP_LOGERR,
3744				    "cannot find handle 0x%x (type 0x%x)",
3745				    sp->req_handle,
3746				    sp->req_header.rqs_entry_type);
3747			} else if (ts != RQCS_ABORTED) {
3748				isp_prt(isp, ISP_LOGERR,
3749				    "cannot find handle 0x%x (status 0x%x)",
3750				    sp->req_handle, ts);
3751			}
3752			WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
3753			continue;
3754		}
3755		isp_destroy_handle(isp, sp->req_handle);
3756		if (sp->req_status_flags & RQSTF_BUS_RESET) {
3757			XS_SETERR(xs, HBA_BUSRESET);
3758			isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
3759		}
3760		if (buddaboom) {
3761			XS_SETERR(xs, HBA_BOTCH);
3762		}
3763
3764		if (IS_FC(isp) && (sp->req_scsi_status & RQCS_SV)) {
3765			/*
3766			 * Fibre Channel F/W doesn't say we got status
3767			 * if there's Sense Data instead. I guess they
3768			 * think it goes w/o saying.
3769			 */
3770			sp->req_state_flags |= RQSF_GOT_STATUS;
3771		}
3772		if (sp->req_state_flags & RQSF_GOT_STATUS) {
3773			*XS_STSP(xs) = sp->req_scsi_status & 0xff;
3774		}
3775
3776		switch (sp->req_header.rqs_entry_type) {
3777		case RQSTYPE_RESPONSE:
3778			XS_SET_STATE_STAT(isp, xs, sp);
3779			isp_parse_status(isp, sp, xs);
3780			if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) &&
3781			    (*XS_STSP(xs) == SCSI_BUSY)) {
3782				XS_SETERR(xs, HBA_TGTBSY);
3783			}
3784			if (IS_SCSI(isp)) {
3785				XS_RESID(xs) = sp->req_resid;
3786				if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
3787				    (*XS_STSP(xs) == SCSI_CHECK) &&
3788				    (sp->req_state_flags & RQSF_GOT_SENSE)) {
3789					XS_SAVE_SENSE(xs, sp);
3790				}
3791				/*
3792				 * A new synchronous rate was negotiated for
3793				 * this target. Mark state such that we'll go
3794				 * look up that which has changed later.
3795				 */
3796				if (sp->req_status_flags & RQSTF_NEGOTIATION) {
3797					int t = XS_TGT(xs);
3798					sdparam *sdp = isp->isp_param;
3799					sdp += XS_CHANNEL(xs);
3800					sdp->isp_devparam[t].dev_refresh = 1;
3801					isp->isp_update |=
3802					    (1 << XS_CHANNEL(xs));
3803				}
3804			} else {
3805				if (sp->req_status_flags & RQSF_XFER_COMPLETE) {
3806					XS_RESID(xs) = 0;
3807				} else if (sp->req_scsi_status & RQCS_RESID) {
3808					XS_RESID(xs) = sp->req_resid;
3809				} else {
3810					XS_RESID(xs) = 0;
3811				}
3812				if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
3813				    (*XS_STSP(xs) == SCSI_CHECK) &&
3814				    (sp->req_scsi_status & RQCS_SV)) {
3815					XS_SAVE_SENSE(xs, sp);
3816					/* solely for the benefit of debug */
3817					sp->req_state_flags |= RQSF_GOT_SENSE;
3818				}
3819			}
3820			isp_prt(isp, ISP_LOGDEBUG2,
3821			   "asked for %ld got resid %ld", (long) XS_XFRLEN(xs),
3822			   (long) sp->req_resid);
3823			break;
3824		case RQSTYPE_REQUEST:
3825			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
3826				/*
3827				 * Force Queue Full status.
3828				 */
3829				*XS_STSP(xs) = SCSI_QFULL;
3830				XS_SETERR(xs, HBA_NOERROR);
3831			} else if (XS_NOERR(xs)) {
3832				/*
3833				 * ????
3834				 */
3835				isp_prt(isp, ISP_LOGDEBUG0,
3836				    "Request Queue Entry bounced back");
3837				XS_SETERR(xs, HBA_BOTCH);
3838			}
3839			XS_RESID(xs) = XS_XFRLEN(xs);
3840			break;
3841		default:
3842			isp_prt(isp, ISP_LOGWARN,
3843			    "unhandled response queue type 0x%x",
3844			    sp->req_header.rqs_entry_type);
3845			if (XS_NOERR(xs)) {
3846				XS_SETERR(xs, HBA_BOTCH);
3847			}
3848			break;
3849		}
3850
3851		/*
3852		 * Free any dma resources. As a side effect, this may
3853		 * also do any cache flushing necessary for data coherence.			 */
3854		if (XS_XFRLEN(xs)) {
3855			ISP_DMAFREE(isp, xs, sp->req_handle);
3856		}
3857
3858		if (((isp->isp_dblev & (ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
3859		    ((isp->isp_dblev & ISP_LOGDEBUG1) && ((!XS_NOERR(xs)) ||
3860		    (*XS_STSP(xs) != SCSI_GOOD)))) {
3861			char skey;
3862			if (sp->req_state_flags & RQSF_GOT_SENSE) {
3863				skey = XS_SNSKEY(xs) & 0xf;
3864				if (skey < 10)
3865					skey += '0';
3866				else
3867					skey += 'a' - 10;
3868			} else if (*XS_STSP(xs) == SCSI_CHECK) {
3869				skey = '?';
3870			} else {
3871				skey = '.';
3872			}
3873			isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs),
3874			    XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), XS_RESID(xs),
3875			    *XS_STSP(xs), skey, XS_ERR(xs));
3876		}
3877
3878		if (isp->isp_nactive > 0)
3879		    isp->isp_nactive--;
3880		complist[ndone++] = xs;	/* defer completion call until later */
3881		MEMZERO(hp, QENTRY_LEN);	/* PERF */
3882		if (ndone == MAX_REQUESTQ_COMPLETIONS) {
3883			break;
3884		}
3885	}
3886
3887	/*
3888	 * If we looked at any commands, then it's valid to find out
3889	 * what the outpointer is. It also is a trigger to update the
3890	 * ISP's notion of what we've seen so far.
3891	 */
3892	if (nlooked) {
3893		WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
3894		/*
3895		 * While we're at it, read the requst queue out pointer.
3896		 */
3897		isp->isp_reqodx = READ_REQUEST_QUEUE_OUT_POINTER(isp);
3898		if (isp->isp_rscchiwater < ndone)
3899			isp->isp_rscchiwater = ndone;
3900	}
3901
3902	isp->isp_residx = optr;
3903	isp->isp_rspbsy = 0;
3904	for (i = 0; i < ndone; i++) {
3905		xs = complist[i];
3906		if (xs) {
3907			isp->isp_rsltccmplt++;
3908			isp_done(xs);
3909		}
3910	}
3911}
3912
3913/*
3914 * Support routines.
3915 */
3916
3917static int
3918isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
3919{
3920	int rval = 0;
3921	int bus;
3922
3923	if (IS_DUALBUS(isp)) {
3924		bus = ISP_READ(isp, OUTMAILBOX6);
3925	} else {
3926		bus = 0;
3927	}
3928	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
3929
3930	switch (mbox) {
3931	case ASYNC_BUS_RESET:
3932		isp->isp_sendmarker |= (1 << bus);
3933#ifdef	ISP_TARGET_MODE
3934		if (isp_target_async(isp, bus, mbox))
3935			rval = -1;
3936#endif
3937		isp_async(isp, ISPASYNC_BUS_RESET, &bus);
3938		break;
3939	case ASYNC_SYSTEM_ERROR:
3940#ifdef	ISP_FW_CRASH_DUMP
3941		/*
3942		 * If we have crash dumps enabled, it's up to the handler
3943		 * for isp_async to reinit stuff and restart the firmware
3944		 * after performing the crash dump. The reason we do things
3945		 * this way is that we may need to activate a kernel thread
3946		 * to do all the crash dump goop.
3947		 */
3948		isp_async(isp, ISPASYNC_FW_CRASH, NULL);
3949#else
3950		isp_async(isp, ISPASYNC_FW_CRASH, NULL);
3951		isp_reinit(isp);
3952		isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
3953#endif
3954		rval = -1;
3955		break;
3956
3957	case ASYNC_RQS_XFER_ERR:
3958		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
3959		break;
3960
3961	case ASYNC_RSP_XFER_ERR:
3962		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
3963		break;
3964
3965	case ASYNC_QWAKEUP:
3966		/*
3967		 * We've just been notified that the Queue has woken up.
3968		 * We don't need to be chatty about this- just unlatch things
3969		 * and move on.
3970		 */
3971		mbox = READ_REQUEST_QUEUE_OUT_POINTER(isp);
3972		break;
3973
3974	case ASYNC_TIMEOUT_RESET:
3975		isp_prt(isp, ISP_LOGWARN,
3976		    "timeout initiated SCSI bus reset of bus %d", bus);
3977		isp->isp_sendmarker |= (1 << bus);
3978#ifdef	ISP_TARGET_MODE
3979		if (isp_target_async(isp, bus, mbox))
3980			rval = -1;
3981#endif
3982		break;
3983
3984	case ASYNC_DEVICE_RESET:
3985		isp_prt(isp, ISP_LOGINFO, "device reset on bus %d", bus);
3986		isp->isp_sendmarker |= (1 << bus);
3987#ifdef	ISP_TARGET_MODE
3988		if (isp_target_async(isp, bus, mbox))
3989			rval = -1;
3990#endif
3991		break;
3992
3993	case ASYNC_EXTMSG_UNDERRUN:
3994		isp_prt(isp, ISP_LOGWARN, "extended message underrun");
3995		break;
3996
3997	case ASYNC_SCAM_INT:
3998		isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
3999		break;
4000
4001	case ASYNC_HUNG_SCSI:
4002		isp_prt(isp, ISP_LOGERR,
4003		    "stalled SCSI Bus after DATA Overrun");
4004		/* XXX: Need to issue SCSI reset at this point */
4005		break;
4006
4007	case ASYNC_KILLED_BUS:
4008		isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
4009		break;
4010
4011	case ASYNC_BUS_TRANSIT:
4012		mbox = ISP_READ(isp, OUTMAILBOX2);
4013		switch (mbox & 0x1c00) {
4014		case SXP_PINS_LVD_MODE:
4015			isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
4016			SDPARAM(isp)->isp_diffmode = 0;
4017			SDPARAM(isp)->isp_ultramode = 0;
4018			SDPARAM(isp)->isp_lvdmode = 1;
4019			break;
4020		case SXP_PINS_HVD_MODE:
4021			isp_prt(isp, ISP_LOGINFO,
4022			    "Transition to Differential mode");
4023			SDPARAM(isp)->isp_diffmode = 1;
4024			SDPARAM(isp)->isp_ultramode = 0;
4025			SDPARAM(isp)->isp_lvdmode = 0;
4026			break;
4027		case SXP_PINS_SE_MODE:
4028			isp_prt(isp, ISP_LOGINFO,
4029			    "Transition to Single Ended mode");
4030			SDPARAM(isp)->isp_diffmode = 0;
4031			SDPARAM(isp)->isp_ultramode = 1;
4032			SDPARAM(isp)->isp_lvdmode = 0;
4033			break;
4034		default:
4035			isp_prt(isp, ISP_LOGWARN,
4036			    "Transition to Unknown Mode 0x%x", mbox);
4037			break;
4038		}
4039		/*
4040		 * XXX: Set up to renegotiate again!
4041		 */
4042		/* Can only be for a 1080... */
4043		isp->isp_sendmarker |= (1 << bus);
4044		break;
4045
4046	/*
4047	 * We can use bus, which will always be zero for FC cards,
4048	 * as a mailbox pattern accumulator to be checked below.
4049	 */
4050	case ASYNC_RIO5:
4051		bus = 0x1ce;	/* outgoing mailbox regs 1-3, 6-7 */
4052		break;
4053
4054	case ASYNC_RIO4:
4055		bus = 0x14e;	/* outgoing mailbox regs 1-3, 6 */
4056		break;
4057
4058	case ASYNC_RIO3:
4059		bus = 0x10e;	/* outgoing mailbox regs 1-3 */
4060		break;
4061
4062	case ASYNC_RIO2:
4063		bus = 0x106;	/* outgoing mailbox regs 1-2 */
4064		break;
4065
4066	case ASYNC_RIO1:
4067	case ASYNC_CMD_CMPLT:
4068		bus = 0x102;	/* outgoing mailbox regs 1 */
4069		break;
4070
4071	case ASYNC_RIO_RESP:
4072		return (rval);
4073
4074	case ASYNC_CTIO_DONE:
4075	{
4076#ifdef	ISP_TARGET_MODE
4077		int handle =
4078		    (ISP_READ(isp, OUTMAILBOX2) << 16) |
4079		    (ISP_READ(isp, OUTMAILBOX1));
4080		if (isp_target_async(isp, handle, mbox))
4081			rval = -1;
4082#else
4083		isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
4084#endif
4085		isp->isp_fphccmplt++;	/* count it as a fast posting intr */
4086		break;
4087	}
4088	case ASYNC_LIP_F8:
4089	case ASYNC_LIP_OCCURRED:
4090		FCPARAM(isp)->isp_lipseq =
4091		    ISP_READ(isp, OUTMAILBOX1);
4092		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4093		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
4094		isp->isp_sendmarker = 1;
4095		isp_mark_getpdb_all(isp);
4096		isp_async(isp, ISPASYNC_LIP, NULL);
4097#ifdef	ISP_TARGET_MODE
4098		if (isp_target_async(isp, bus, mbox))
4099			rval = -1;
4100#endif
4101		/*
4102		 * We've had problems with data corruption occuring on
4103		 * commands that complete (with no apparent error) after
4104		 * we receive a LIP. This has been observed mostly on
4105		 * Local Loop topologies. To be safe, let's just mark
4106		 * all active commands as dead.
4107		 */
4108		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
4109		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
4110			int i, j;
4111			for (i = j = 0; i < isp->isp_maxcmds; i++) {
4112				XS_T *xs;
4113				xs = isp->isp_xflist[i];
4114				if (xs != NULL) {
4115					j++;
4116					XS_SETERR(xs, HBA_BUSRESET);
4117				}
4118			}
4119			if (j) {
4120				isp_prt(isp, ISP_LOGERR,
4121				    "LIP destroyed %d active commands", j);
4122			}
4123		}
4124		break;
4125
4126	case ASYNC_LOOP_UP:
4127		isp->isp_sendmarker = 1;
4128		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4129		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
4130		isp_mark_getpdb_all(isp);
4131		isp_async(isp, ISPASYNC_LOOP_UP, NULL);
4132#ifdef	ISP_TARGET_MODE
4133		if (isp_target_async(isp, bus, mbox))
4134			rval = -1;
4135#endif
4136		break;
4137
4138	case ASYNC_LOOP_DOWN:
4139		isp->isp_sendmarker = 1;
4140		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4141		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
4142		isp_mark_getpdb_all(isp);
4143		isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
4144#ifdef	ISP_TARGET_MODE
4145		if (isp_target_async(isp, bus, mbox))
4146			rval = -1;
4147#endif
4148		break;
4149
4150	case ASYNC_LOOP_RESET:
4151		isp->isp_sendmarker = 1;
4152		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4153		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
4154		isp_mark_getpdb_all(isp);
4155		isp_async(isp, ISPASYNC_LOOP_RESET, NULL);
4156#ifdef	ISP_TARGET_MODE
4157		if (isp_target_async(isp, bus, mbox))
4158			rval = -1;
4159#endif
4160		break;
4161
4162	case ASYNC_PDB_CHANGED:
4163		isp->isp_sendmarker = 1;
4164		FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
4165		isp_mark_getpdb_all(isp);
4166		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_PDB);
4167		break;
4168
4169	case ASYNC_CHANGE_NOTIFY:
4170		/*
4171		 * Not correct, but it will force us to rescan the loop.
4172		 */
4173		FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
4174		isp_mark_getpdb_all(isp);
4175		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_SNS);
4176		break;
4177
4178	case ASYNC_PTPMODE:
4179		if (FCPARAM(isp)->isp_onfabric)
4180			FCPARAM(isp)->isp_topo = TOPO_F_PORT;
4181		else
4182			FCPARAM(isp)->isp_topo = TOPO_N_PORT;
4183		isp_mark_getpdb_all(isp);
4184		isp->isp_sendmarker = 1;
4185		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4186		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
4187		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
4188#ifdef	ISP_TARGET_MODE
4189		if (isp_target_async(isp, bus, mbox))
4190			rval = -1;
4191#endif
4192		isp_prt(isp, ISP_LOGINFO, "Point-to-Point mode");
4193		break;
4194
4195	case ASYNC_CONNMODE:
4196		mbox = ISP_READ(isp, OUTMAILBOX1);
4197		isp_mark_getpdb_all(isp);
4198		switch (mbox) {
4199		case ISP_CONN_LOOP:
4200			isp_prt(isp, ISP_LOGINFO,
4201			    "Point-to-Point -> Loop mode");
4202			break;
4203		case ISP_CONN_PTP:
4204			isp_prt(isp, ISP_LOGINFO,
4205			    "Loop -> Point-to-Point mode");
4206			break;
4207		case ISP_CONN_BADLIP:
4208			isp_prt(isp, ISP_LOGWARN,
4209			    "Point-to-Point -> Loop mode (BAD LIP)");
4210			break;
4211		case ISP_CONN_FATAL:
4212			isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
4213			isp_async(isp, ISPASYNC_FW_CRASH, NULL);
4214			isp_reinit(isp);
4215			isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
4216			return (-1);
4217		case ISP_CONN_LOOPBACK:
4218			isp_prt(isp, ISP_LOGWARN,
4219			    "Looped Back in Point-to-Point mode");
4220			break;
4221		default:
4222			isp_prt(isp, ISP_LOGWARN,
4223			    "Unknown connection mode (0x%x)", mbox);
4224			break;
4225		}
4226		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
4227		isp->isp_sendmarker = 1;
4228		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
4229		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
4230		break;
4231
4232	default:
4233		isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
4234		break;
4235	}
4236
4237	if (bus & 0x100) {
4238		int i, nh;
4239		u_int16_t handles[5];
4240
4241		for (nh = 0, i = 1; i < MAX_MAILBOX; i++) {
4242			if ((bus & (1 << i)) == 0) {
4243				continue;
4244			}
4245			handles[nh++] = ISP_READ(isp, MBOX_OFF(i));
4246		}
4247		for (i = 0; i < nh; i++) {
4248			isp_fastpost_complete(isp, handles[i]);
4249			isp_prt(isp,  ISP_LOGDEBUG3,
4250			    "fast post completion of %u", handles[i]);
4251		}
4252		if (isp->isp_fpcchiwater < nh)
4253			isp->isp_fpcchiwater = nh;
4254	} else {
4255		isp->isp_intoasync++;
4256	}
4257	return (rval);
4258}
4259
4260/*
4261 * Handle other response entries. A pointer to the request queue output
4262 * index is here in case we want to eat several entries at once, although
4263 * this is not used currently.
4264 */
4265
4266static int
4267isp_handle_other_response(struct ispsoftc *isp, int type,
4268    isphdr_t *hp, u_int16_t *optrp)
4269{
4270	switch (type) {
4271	case RQSTYPE_STATUS_CONT:
4272		isp_prt(isp, ISP_LOGINFO, "Ignored Continuation Response");
4273		return (1);
4274	case RQSTYPE_ATIO:
4275	case RQSTYPE_CTIO:
4276	case RQSTYPE_ENABLE_LUN:
4277	case RQSTYPE_MODIFY_LUN:
4278	case RQSTYPE_NOTIFY:
4279	case RQSTYPE_NOTIFY_ACK:
4280	case RQSTYPE_CTIO1:
4281	case RQSTYPE_ATIO2:
4282	case RQSTYPE_CTIO2:
4283	case RQSTYPE_CTIO3:
4284		isp->isp_rsltccmplt++;	/* count as a response completion */
4285#ifdef	ISP_TARGET_MODE
4286		if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
4287			return (1);
4288		}
4289#else
4290		optrp = optrp;
4291		/* FALLTHROUGH */
4292#endif
4293	case RQSTYPE_REQUEST:
4294	default:
4295		if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) {
4296			return (1);
4297		}
4298		isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
4299		    isp_get_response_type(isp, hp));
4300		return (0);
4301	}
4302}
4303
4304static void
4305isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
4306{
4307	switch (sp->req_completion_status & 0xff) {
4308	case RQCS_COMPLETE:
4309		if (XS_NOERR(xs)) {
4310			XS_SETERR(xs, HBA_NOERROR);
4311		}
4312		return;
4313
4314	case RQCS_INCOMPLETE:
4315		if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
4316			isp_prt(isp, ISP_LOGDEBUG1,
4317			    "Selection Timeout for %d.%d.%d",
4318			    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4319			if (XS_NOERR(xs)) {
4320				XS_SETERR(xs, HBA_SELTIMEOUT);
4321			}
4322			return;
4323		}
4324		isp_prt(isp, ISP_LOGERR,
4325		    "command incomplete for %d.%d.%d, state 0x%x",
4326		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
4327		    sp->req_state_flags);
4328		break;
4329
4330	case RQCS_DMA_ERROR:
4331		isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
4332		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4333		break;
4334
4335	case RQCS_TRANSPORT_ERROR:
4336	{
4337		char buf[172];
4338		SNPRINTF(buf, sizeof (buf), "states=>");
4339		if (sp->req_state_flags & RQSF_GOT_BUS) {
4340			SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
4341		}
4342		if (sp->req_state_flags & RQSF_GOT_TARGET) {
4343			SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
4344		}
4345		if (sp->req_state_flags & RQSF_SENT_CDB) {
4346			SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
4347		}
4348		if (sp->req_state_flags & RQSF_XFRD_DATA) {
4349			SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
4350		}
4351		if (sp->req_state_flags & RQSF_GOT_STATUS) {
4352			SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
4353		}
4354		if (sp->req_state_flags & RQSF_GOT_SENSE) {
4355			SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
4356		}
4357		if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
4358			SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
4359		}
4360		SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
4361		if (sp->req_status_flags & RQSTF_DISCONNECT) {
4362			SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
4363		}
4364		if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
4365			SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
4366		}
4367		if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
4368			SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
4369		}
4370		if (sp->req_status_flags & RQSTF_BUS_RESET) {
4371			SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
4372		}
4373		if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
4374			SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
4375		}
4376		if (sp->req_status_flags & RQSTF_ABORTED) {
4377			SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
4378		}
4379		if (sp->req_status_flags & RQSTF_TIMEOUT) {
4380			SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
4381		}
4382		if (sp->req_status_flags & RQSTF_NEGOTIATION) {
4383			SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
4384		}
4385		isp_prt(isp, ISP_LOGERR, "%s", buf);
4386		isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
4387		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf);
4388		break;
4389	}
4390	case RQCS_RESET_OCCURRED:
4391		isp_prt(isp, ISP_LOGWARN,
4392		    "bus reset destroyed command for %d.%d.%d",
4393		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4394		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
4395		if (XS_NOERR(xs)) {
4396			XS_SETERR(xs, HBA_BUSRESET);
4397		}
4398		return;
4399
4400	case RQCS_ABORTED:
4401		isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
4402		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4403		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
4404		if (XS_NOERR(xs)) {
4405			XS_SETERR(xs, HBA_ABORTED);
4406		}
4407		return;
4408
4409	case RQCS_TIMEOUT:
4410		isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
4411		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4412		/*
4413	 	 * Check to see if we logged out the device.
4414		 */
4415		if (IS_FC(isp)) {
4416			if ((sp->req_completion_status & RQSTF_LOGOUT) &&
4417			    FCPARAM(isp)->portdb[XS_TGT(xs)].valid &&
4418			    FCPARAM(isp)->portdb[XS_TGT(xs)].fabric_dev) {
4419				FCPARAM(isp)->portdb[XS_TGT(xs)].relogin = 1;
4420			}
4421		}
4422		if (XS_NOERR(xs)) {
4423			XS_SETERR(xs, HBA_CMDTIMEOUT);
4424		}
4425		return;
4426
4427	case RQCS_DATA_OVERRUN:
4428		XS_RESID(xs) = sp->req_resid;
4429		isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d",
4430		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4431		if (XS_NOERR(xs)) {
4432			XS_SETERR(xs, HBA_DATAOVR);
4433		}
4434		return;
4435
4436	case RQCS_COMMAND_OVERRUN:
4437		isp_prt(isp, ISP_LOGERR,
4438		    "command overrun for command on %d.%d.%d",
4439		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4440		break;
4441
4442	case RQCS_STATUS_OVERRUN:
4443		isp_prt(isp, ISP_LOGERR,
4444		    "status overrun for command on %d.%d.%d",
4445		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4446		break;
4447
4448	case RQCS_BAD_MESSAGE:
4449		isp_prt(isp, ISP_LOGERR,
4450		    "msg not COMMAND COMPLETE after status %d.%d.%d",
4451		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4452		break;
4453
4454	case RQCS_NO_MESSAGE_OUT:
4455		isp_prt(isp, ISP_LOGERR,
4456		    "No MESSAGE OUT phase after selection on %d.%d.%d",
4457		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4458		break;
4459
4460	case RQCS_EXT_ID_FAILED:
4461		isp_prt(isp, ISP_LOGERR, "EXTENDED IDENTIFY failed %d.%d.%d",
4462		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4463		break;
4464
4465	case RQCS_IDE_MSG_FAILED:
4466		isp_prt(isp, ISP_LOGERR,
4467		    "INITIATOR DETECTED ERROR rejected by %d.%d.%d",
4468		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4469		break;
4470
4471	case RQCS_ABORT_MSG_FAILED:
4472		isp_prt(isp, ISP_LOGERR, "ABORT OPERATION rejected by %d.%d.%d",
4473		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4474		break;
4475
4476	case RQCS_REJECT_MSG_FAILED:
4477		isp_prt(isp, ISP_LOGERR, "MESSAGE REJECT rejected by %d.%d.%d",
4478		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4479		break;
4480
4481	case RQCS_NOP_MSG_FAILED:
4482		isp_prt(isp, ISP_LOGERR, "NOP rejected by %d.%d.%d",
4483		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4484		break;
4485
4486	case RQCS_PARITY_ERROR_MSG_FAILED:
4487		isp_prt(isp, ISP_LOGERR,
4488		    "MESSAGE PARITY ERROR rejected by %d.%d.%d",
4489		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4490		break;
4491
4492	case RQCS_DEVICE_RESET_MSG_FAILED:
4493		isp_prt(isp, ISP_LOGWARN,
4494		    "BUS DEVICE RESET rejected by %d.%d.%d",
4495		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4496		break;
4497
4498	case RQCS_ID_MSG_FAILED:
4499		isp_prt(isp, ISP_LOGERR, "IDENTIFY rejected by %d.%d.%d",
4500		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4501		break;
4502
4503	case RQCS_UNEXP_BUS_FREE:
4504		isp_prt(isp, ISP_LOGERR, "%d.%d.%d had an unexpected bus free",
4505		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4506		break;
4507
4508	case RQCS_DATA_UNDERRUN:
4509	{
4510		if (IS_FC(isp)) {
4511			int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
4512			if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
4513				isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
4514				    XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
4515				    (ru_marked)? "marked" : "not marked");
4516				if (XS_NOERR(xs)) {
4517					XS_SETERR(xs, HBA_BOTCH);
4518				}
4519				return;
4520			}
4521		}
4522		XS_RESID(xs) = sp->req_resid;
4523		if (XS_NOERR(xs)) {
4524			XS_SETERR(xs, HBA_NOERROR);
4525		}
4526		return;
4527	}
4528
4529	case RQCS_XACT_ERR1:
4530		isp_prt(isp, ISP_LOGERR, xact1, XS_CHANNEL(xs),
4531		    XS_TGT(xs), XS_LUN(xs));
4532		break;
4533
4534	case RQCS_XACT_ERR2:
4535		isp_prt(isp, ISP_LOGERR, xact2,
4536		    XS_LUN(xs), XS_TGT(xs), XS_CHANNEL(xs));
4537		break;
4538
4539	case RQCS_XACT_ERR3:
4540		isp_prt(isp, ISP_LOGERR, xact3,
4541		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4542		break;
4543
4544	case RQCS_BAD_ENTRY:
4545		isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
4546		break;
4547
4548	case RQCS_QUEUE_FULL:
4549		isp_prt(isp, ISP_LOGDEBUG0,
4550		    "internal queues full for %d.%d.%d status 0x%x",
4551		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), *XS_STSP(xs));
4552
4553		/*
4554		 * If QFULL or some other status byte is set, then this
4555		 * isn't an error, per se.
4556		 *
4557		 * Unfortunately, some QLogic f/w writers have, in
4558		 * some cases, ommitted to *set* status to QFULL.
4559		 *
4560
4561		if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
4562			XS_SETERR(xs, HBA_NOERROR);
4563			return;
4564		}
4565
4566		 *
4567		 *
4568		 */
4569
4570		*XS_STSP(xs) = SCSI_QFULL;
4571		XS_SETERR(xs, HBA_NOERROR);
4572		return;
4573
4574	case RQCS_PHASE_SKIPPED:
4575		isp_prt(isp, ISP_LOGERR, pskip, XS_CHANNEL(xs),
4576		    XS_TGT(xs), XS_LUN(xs));
4577		break;
4578
4579	case RQCS_ARQS_FAILED:
4580		isp_prt(isp, ISP_LOGERR,
4581		    "Auto Request Sense failed for %d.%d.%d",
4582		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
4583		if (XS_NOERR(xs)) {
4584			XS_SETERR(xs, HBA_ARQFAIL);
4585		}
4586		return;
4587
4588	case RQCS_WIDE_FAILED:
4589		isp_prt(isp, ISP_LOGERR,
4590		    "Wide Negotiation failed for %d.%d.%d",
4591		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
4592		if (IS_SCSI(isp)) {
4593			sdparam *sdp = isp->isp_param;
4594			sdp += XS_CHANNEL(xs);
4595			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
4596			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
4597			isp->isp_update |= (1 << XS_CHANNEL(xs));
4598		}
4599		if (XS_NOERR(xs)) {
4600			XS_SETERR(xs, HBA_NOERROR);
4601		}
4602		return;
4603
4604	case RQCS_SYNCXFER_FAILED:
4605		isp_prt(isp, ISP_LOGERR,
4606		    "SDTR Message failed for target %d.%d.%d",
4607		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
4608		if (IS_SCSI(isp)) {
4609			sdparam *sdp = isp->isp_param;
4610			sdp += XS_CHANNEL(xs);
4611			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
4612			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
4613			isp->isp_update |= (1 << XS_CHANNEL(xs));
4614		}
4615		break;
4616
4617	case RQCS_LVD_BUSERR:
4618		isp_prt(isp, ISP_LOGERR,
4619		    "Bad LVD condition while talking to %d.%d.%d",
4620		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
4621		break;
4622
4623	case RQCS_PORT_UNAVAILABLE:
4624		/*
4625		 * No such port on the loop. Moral equivalent of SELTIMEO
4626		 */
4627	case RQCS_PORT_LOGGED_OUT:
4628		/*
4629		 * It was there (maybe)- treat as a selection timeout.
4630		 */
4631		if ((sp->req_completion_status & 0xff) == RQCS_PORT_UNAVAILABLE)
4632			isp_prt(isp, ISP_LOGINFO,
4633			    "port unavailable for target %d", XS_TGT(xs));
4634		else
4635			isp_prt(isp, ISP_LOGINFO,
4636			    "port logout for target %d", XS_TGT(xs));
4637		/*
4638		 * If we're on a local loop, force a LIP (which is overkill)
4639		 * to force a re-login of this unit. If we're on fabric,
4640		 * then we'll have to relogin as a matter of course.
4641		 */
4642		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
4643		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
4644			mbreg_t mbs;
4645			mbs.param[0] = MBOX_INIT_LIP;
4646			isp_mboxcmd_qnw(isp, &mbs, 1);
4647		}
4648
4649		/*
4650		 * Probably overkill.
4651		 */
4652		isp->isp_sendmarker = 1;
4653		FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
4654		isp_mark_getpdb_all(isp);
4655		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
4656		if (XS_NOERR(xs)) {
4657			XS_SETERR(xs, HBA_SELTIMEOUT);
4658		}
4659		return;
4660
4661	case RQCS_PORT_CHANGED:
4662		isp_prt(isp, ISP_LOGWARN,
4663		    "port changed for target %d", XS_TGT(xs));
4664		if (XS_NOERR(xs)) {
4665			XS_SETERR(xs, HBA_SELTIMEOUT);
4666		}
4667		return;
4668
4669	case RQCS_PORT_BUSY:
4670		isp_prt(isp, ISP_LOGWARN,
4671		    "port busy for target %d", XS_TGT(xs));
4672		if (XS_NOERR(xs)) {
4673			XS_SETERR(xs, HBA_TGTBSY);
4674		}
4675		return;
4676
4677	default:
4678		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
4679		    sp->req_completion_status);
4680		break;
4681	}
4682	if (XS_NOERR(xs)) {
4683		XS_SETERR(xs, HBA_BOTCH);
4684	}
4685}
4686
4687static void
4688isp_fastpost_complete(struct ispsoftc *isp, u_int16_t fph)
4689{
4690	XS_T *xs;
4691
4692	if (fph == 0) {
4693		return;
4694	}
4695	xs = isp_find_xs(isp, fph);
4696	if (xs == NULL) {
4697		isp_prt(isp, ISP_LOGWARN,
4698		    "Command for fast post handle 0x%x not found", fph);
4699		return;
4700	}
4701	isp_destroy_handle(isp, fph);
4702
4703	/*
4704	 * Since we don't have a result queue entry item,
4705	 * we must believe that SCSI status is zero and
4706	 * that all data transferred.
4707	 */
4708	XS_SET_STATE_STAT(isp, xs, NULL);
4709	XS_RESID(xs) = 0;
4710	*XS_STSP(xs) = SCSI_GOOD;
4711	if (XS_XFRLEN(xs)) {
4712		ISP_DMAFREE(isp, xs, fph);
4713	}
4714	if (isp->isp_nactive)
4715		isp->isp_nactive--;
4716	isp->isp_fphccmplt++;
4717	isp_done(xs);
4718}
4719
4720static int
4721isp_mbox_continue(struct ispsoftc *isp)
4722{
4723	mbreg_t mbs;
4724	u_int16_t *ptr;
4725
4726	switch (isp->isp_lastmbxcmd) {
4727	case MBOX_WRITE_RAM_WORD:
4728	case MBOX_READ_RAM_WORD:
4729	case MBOX_READ_RAM_WORD_EXTENDED:
4730		break;
4731	default:
4732		return (1);
4733	}
4734	if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
4735		isp->isp_mbxwrk0 = 0;
4736		return (-1);
4737	}
4738
4739
4740	/*
4741	 * Clear the previous interrupt.
4742	 */
4743	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
4744	ISP_WRITE(isp, BIU_SEMA, 0);
4745
4746	/*
4747	 * Continue with next word.
4748	 */
4749	ptr = isp->isp_mbxworkp;
4750	switch (isp->isp_lastmbxcmd) {
4751	case MBOX_WRITE_RAM_WORD:
4752		mbs.param[2] = *ptr++;
4753		mbs.param[1] = isp->isp_mbxwrk1++;
4754		break;
4755	case MBOX_READ_RAM_WORD:
4756	case MBOX_READ_RAM_WORD_EXTENDED:
4757		*ptr++ = isp->isp_mboxtmp[2];
4758		mbs.param[1] = isp->isp_mbxwrk1++;
4759		break;
4760	}
4761	isp->isp_mbxworkp = ptr;
4762	mbs.param[0] = isp->isp_lastmbxcmd;
4763	isp->isp_mbxwrk0 -= 1;
4764	isp_mboxcmd_qnw(isp, &mbs, 0);
4765	return (0);
4766}
4767
4768
4769#define	HIBYT(x)			((x) >> 0x8)
4770#define	LOBYT(x)			((x)  & 0xff)
4771#define	ISPOPMAP(a, b)			(((a) << 8) | (b))
4772static u_int16_t mbpscsi[] = {
4773	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
4774	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
4775	ISPOPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
4776	ISPOPMAP(0x1f, 0x01),	/* 0x03: MBOX_DUMP_RAM */
4777	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
4778	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
4779	ISPOPMAP(0x3f, 0x3f),	/* 0x06: MBOX_MAILBOX_REG_TEST */
4780	ISPOPMAP(0x03, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
4781	ISPOPMAP(0x01, 0x0f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
4782	ISPOPMAP(0x00, 0x00),	/* 0x09: */
4783	ISPOPMAP(0x00, 0x00),	/* 0x0a: */
4784	ISPOPMAP(0x00, 0x00),	/* 0x0b: */
4785	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
4786	ISPOPMAP(0x00, 0x00),	/* 0x0d: */
4787	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
4788	ISPOPMAP(0x00, 0x00),	/* 0x0f: */
4789	ISPOPMAP(0x1f, 0x1f),	/* 0x10: MBOX_INIT_REQ_QUEUE */
4790	ISPOPMAP(0x3f, 0x3f),	/* 0x11: MBOX_INIT_RES_QUEUE */
4791	ISPOPMAP(0x0f, 0x0f),	/* 0x12: MBOX_EXECUTE_IOCB */
4792	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
4793	ISPOPMAP(0x01, 0x3f),	/* 0x14: MBOX_STOP_FIRMWARE */
4794	ISPOPMAP(0x0f, 0x0f),	/* 0x15: MBOX_ABORT */
4795	ISPOPMAP(0x03, 0x03),	/* 0x16: MBOX_ABORT_DEVICE */
4796	ISPOPMAP(0x07, 0x07),	/* 0x17: MBOX_ABORT_TARGET */
4797	ISPOPMAP(0x07, 0x07),	/* 0x18: MBOX_BUS_RESET */
4798	ISPOPMAP(0x03, 0x07),	/* 0x19: MBOX_STOP_QUEUE */
4799	ISPOPMAP(0x03, 0x07),	/* 0x1a: MBOX_START_QUEUE */
4800	ISPOPMAP(0x03, 0x07),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
4801	ISPOPMAP(0x03, 0x07),	/* 0x1c: MBOX_ABORT_QUEUE */
4802	ISPOPMAP(0x03, 0x4f),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
4803	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
4804	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
4805	ISPOPMAP(0x01, 0x07),	/* 0x20: MBOX_GET_INIT_SCSI_ID */
4806	ISPOPMAP(0x01, 0x07),	/* 0x21: MBOX_GET_SELECT_TIMEOUT */
4807	ISPOPMAP(0x01, 0xc7),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
4808	ISPOPMAP(0x01, 0x07),	/* 0x23: MBOX_GET_TAG_AGE_LIMIT */
4809	ISPOPMAP(0x01, 0x03),	/* 0x24: MBOX_GET_CLOCK_RATE */
4810	ISPOPMAP(0x01, 0x07),	/* 0x25: MBOX_GET_ACT_NEG_STATE */
4811	ISPOPMAP(0x01, 0x07),	/* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
4812	ISPOPMAP(0x01, 0x07),	/* 0x27: MBOX_GET_PCI_PARAMS */
4813	ISPOPMAP(0x03, 0x4f),	/* 0x28: MBOX_GET_TARGET_PARAMS */
4814	ISPOPMAP(0x03, 0x0f),	/* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
4815	ISPOPMAP(0x01, 0x07),	/* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
4816	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
4817	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
4818	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
4819	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
4820	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
4821	ISPOPMAP(0x03, 0x03),	/* 0x30: MBOX_SET_INIT_SCSI_ID */
4822	ISPOPMAP(0x07, 0x07),	/* 0x31: MBOX_SET_SELECT_TIMEOUT */
4823	ISPOPMAP(0xc7, 0xc7),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
4824	ISPOPMAP(0x07, 0x07),	/* 0x33: MBOX_SET_TAG_AGE_LIMIT */
4825	ISPOPMAP(0x03, 0x03),	/* 0x34: MBOX_SET_CLOCK_RATE */
4826	ISPOPMAP(0x07, 0x07),	/* 0x35: MBOX_SET_ACT_NEG_STATE */
4827	ISPOPMAP(0x07, 0x07),	/* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
4828	ISPOPMAP(0x07, 0x07),	/* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
4829	ISPOPMAP(0x4f, 0x4f),	/* 0x38: MBOX_SET_TARGET_PARAMS */
4830	ISPOPMAP(0x0f, 0x0f),	/* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
4831	ISPOPMAP(0x07, 0x07),	/* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
4832	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
4833	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
4834	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
4835	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
4836	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
4837	ISPOPMAP(0x01, 0x03),	/* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
4838	ISPOPMAP(0x3f, 0x01),	/* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
4839	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_EXEC_BIOS_IOCB */
4840	ISPOPMAP(0x00, 0x00),	/* 0x43: */
4841	ISPOPMAP(0x00, 0x00),	/* 0x44: */
4842	ISPOPMAP(0x03, 0x03),	/* 0x45: SET SYSTEM PARAMETER */
4843	ISPOPMAP(0x01, 0x03),	/* 0x46: GET SYSTEM PARAMETER */
4844	ISPOPMAP(0x00, 0x00),	/* 0x47: */
4845	ISPOPMAP(0x01, 0xcf),	/* 0x48: GET SCAM CONFIGURATION */
4846	ISPOPMAP(0xcf, 0xcf),	/* 0x49: SET SCAM CONFIGURATION */
4847	ISPOPMAP(0x03, 0x03),	/* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
4848	ISPOPMAP(0x01, 0x03),	/* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
4849	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
4850	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
4851	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
4852	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
4853	ISPOPMAP(0xdf, 0xdf),	/* 0x50: LOAD RAM A64 */
4854	ISPOPMAP(0xdf, 0xdf),	/* 0x51: DUMP RAM A64 */
4855	ISPOPMAP(0xdf, 0xff),	/* 0x52: INITIALIZE REQUEST QUEUE A64 */
4856	ISPOPMAP(0xef, 0xff),	/* 0x53: INITIALIZE RESPONSE QUEUE A64 */
4857	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
4858	ISPOPMAP(0x07, 0x01),	/* 0x55: ENABLE TARGET MODE */
4859	ISPOPMAP(0x03, 0x0f),	/* 0x56: GET TARGET STATUS */
4860	ISPOPMAP(0x00, 0x00),	/* 0x57: */
4861	ISPOPMAP(0x00, 0x00),	/* 0x58: */
4862	ISPOPMAP(0x00, 0x00),	/* 0x59: */
4863	ISPOPMAP(0x03, 0x03),	/* 0x5a: SET DATA OVERRUN RECOVERY MODE */
4864	ISPOPMAP(0x01, 0x03),	/* 0x5b: GET DATA OVERRUN RECOVERY MODE */
4865	ISPOPMAP(0x0f, 0x0f),	/* 0x5c: SET HOST DATA */
4866	ISPOPMAP(0x01, 0x01)	/* 0x5d: GET NOST DATA */
4867};
4868
4869#ifndef	ISP_STRIPPED
4870static char *scsi_mbcmd_names[] = {
4871	"NO-OP",
4872	"LOAD RAM",
4873	"EXEC FIRMWARE",
4874	"DUMP RAM",
4875	"WRITE RAM WORD",
4876	"READ RAM WORD",
4877	"MAILBOX REG TEST",
4878	"VERIFY CHECKSUM",
4879	"ABOUT FIRMWARE",
4880	NULL,
4881	NULL,
4882	NULL,
4883	NULL,
4884	NULL,
4885	"CHECK FIRMWARE",
4886	NULL,
4887	"INIT REQUEST QUEUE",
4888	"INIT RESULT QUEUE",
4889	"EXECUTE IOCB",
4890	"WAKE UP",
4891	"STOP FIRMWARE",
4892	"ABORT",
4893	"ABORT DEVICE",
4894	"ABORT TARGET",
4895	"BUS RESET",
4896	"STOP QUEUE",
4897	"START QUEUE",
4898	"SINGLE STEP QUEUE",
4899	"ABORT QUEUE",
4900	"GET DEV QUEUE STATUS",
4901	NULL,
4902	"GET FIRMWARE STATUS",
4903	"GET INIT SCSI ID",
4904	"GET SELECT TIMEOUT",
4905	"GET RETRY COUNT",
4906	"GET TAG AGE LIMIT",
4907	"GET CLOCK RATE",
4908	"GET ACT NEG STATE",
4909	"GET ASYNC DATA SETUP TIME",
4910	"GET PCI PARAMS",
4911	"GET TARGET PARAMS",
4912	"GET DEV QUEUE PARAMS",
4913	"GET RESET DELAY PARAMS",
4914	NULL,
4915	NULL,
4916	NULL,
4917	NULL,
4918	NULL,
4919	"SET INIT SCSI ID",
4920	"SET SELECT TIMEOUT",
4921	"SET RETRY COUNT",
4922	"SET TAG AGE LIMIT",
4923	"SET CLOCK RATE",
4924	"SET ACT NEG STATE",
4925	"SET ASYNC DATA SETUP TIME",
4926	"SET PCI CONTROL PARAMS",
4927	"SET TARGET PARAMS",
4928	"SET DEV QUEUE PARAMS",
4929	"SET RESET DELAY PARAMS",
4930	NULL,
4931	NULL,
4932	NULL,
4933	NULL,
4934	NULL,
4935	"RETURN BIOS BLOCK ADDR",
4936	"WRITE FOUR RAM WORDS",
4937	"EXEC BIOS IOCB",
4938	NULL,
4939	NULL,
4940	"SET SYSTEM PARAMETER",
4941	"GET SYSTEM PARAMETER",
4942	NULL,
4943	"GET SCAM CONFIGURATION",
4944	"SET SCAM CONFIGURATION",
4945	"SET FIRMWARE FEATURES",
4946	"GET FIRMWARE FEATURES",
4947	NULL,
4948	NULL,
4949	NULL,
4950	NULL,
4951	"LOAD RAM A64",
4952	"DUMP RAM A64",
4953	"INITIALIZE REQUEST QUEUE A64",
4954	"INITIALIZE RESPONSE QUEUE A64",
4955	"EXECUTE IOCB A64",
4956	"ENABLE TARGET MODE",
4957	"GET TARGET MODE STATE",
4958	NULL,
4959	NULL,
4960	NULL,
4961	"SET DATA OVERRUN RECOVERY MODE",
4962	"GET DATA OVERRUN RECOVERY MODE",
4963	"SET HOST DATA",
4964	"GET NOST DATA",
4965};
4966#endif
4967
4968static u_int16_t mbpfc[] = {
4969	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
4970	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
4971	ISPOPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
4972	ISPOPMAP(0xdf, 0x01),	/* 0x03: MBOX_DUMP_RAM */
4973	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
4974	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
4975	ISPOPMAP(0xff, 0xff),	/* 0x06: MBOX_MAILBOX_REG_TEST */
4976	ISPOPMAP(0x03, 0x05),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
4977	ISPOPMAP(0x01, 0x4f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
4978	ISPOPMAP(0xdf, 0x01),	/* 0x09: LOAD RAM */
4979	ISPOPMAP(0xdf, 0x01),	/* 0x0a: DUMP RAM */
4980	ISPOPMAP(0x00, 0x00),	/* 0x0b: */
4981	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
4982	ISPOPMAP(0x00, 0x00),	/* 0x0d: */
4983	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
4984	ISPOPMAP(0x03, 0x07),	/* 0x0f: MBOX_READ_RAM_WORD_EXTENDED(1) */
4985	ISPOPMAP(0x1f, 0x11),	/* 0x10: MBOX_INIT_REQ_QUEUE */
4986	ISPOPMAP(0x2f, 0x21),	/* 0x11: MBOX_INIT_RES_QUEUE */
4987	ISPOPMAP(0x0f, 0x01),	/* 0x12: MBOX_EXECUTE_IOCB */
4988	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
4989	ISPOPMAP(0x01, 0xff),	/* 0x14: MBOX_STOP_FIRMWARE */
4990	ISPOPMAP(0x4f, 0x01),	/* 0x15: MBOX_ABORT */
4991	ISPOPMAP(0x07, 0x01),	/* 0x16: MBOX_ABORT_DEVICE */
4992	ISPOPMAP(0x07, 0x01),	/* 0x17: MBOX_ABORT_TARGET */
4993	ISPOPMAP(0x03, 0x03),	/* 0x18: MBOX_BUS_RESET */
4994	ISPOPMAP(0x07, 0x05),	/* 0x19: MBOX_STOP_QUEUE */
4995	ISPOPMAP(0x07, 0x05),	/* 0x1a: MBOX_START_QUEUE */
4996	ISPOPMAP(0x07, 0x05),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
4997	ISPOPMAP(0x07, 0x05),	/* 0x1c: MBOX_ABORT_QUEUE */
4998	ISPOPMAP(0x07, 0x03),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
4999	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
5000	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
5001	ISPOPMAP(0x01, 0x4f),	/* 0x20: MBOX_GET_LOOP_ID */
5002	ISPOPMAP(0x00, 0x00),	/* 0x21: */
5003	ISPOPMAP(0x01, 0x07),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
5004	ISPOPMAP(0x00, 0x00),	/* 0x23: */
5005	ISPOPMAP(0x00, 0x00),	/* 0x24: */
5006	ISPOPMAP(0x00, 0x00),	/* 0x25: */
5007	ISPOPMAP(0x00, 0x00),	/* 0x26: */
5008	ISPOPMAP(0x00, 0x00),	/* 0x27: */
5009	ISPOPMAP(0x01, 0x03),	/* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
5010	ISPOPMAP(0x03, 0x07),	/* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
5011	ISPOPMAP(0x00, 0x00),	/* 0x2a: */
5012	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
5013	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
5014	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
5015	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
5016	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
5017	ISPOPMAP(0x00, 0x00),	/* 0x30: */
5018	ISPOPMAP(0x00, 0x00),	/* 0x31: */
5019	ISPOPMAP(0x07, 0x07),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
5020	ISPOPMAP(0x00, 0x00),	/* 0x33: */
5021	ISPOPMAP(0x00, 0x00),	/* 0x34: */
5022	ISPOPMAP(0x00, 0x00),	/* 0x35: */
5023	ISPOPMAP(0x00, 0x00),	/* 0x36: */
5024	ISPOPMAP(0x00, 0x00),	/* 0x37: */
5025	ISPOPMAP(0x0f, 0x01),	/* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
5026	ISPOPMAP(0x0f, 0x07),	/* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
5027	ISPOPMAP(0x00, 0x00),	/* 0x3a: */
5028	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
5029	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
5030	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
5031	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
5032	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
5033	ISPOPMAP(0x03, 0x01),	/* 0x40: MBOX_LOOP_PORT_BYPASS */
5034	ISPOPMAP(0x03, 0x01),	/* 0x41: MBOX_LOOP_PORT_ENABLE */
5035	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_GET_RESOURCE_COUNTS */
5036	ISPOPMAP(0x01, 0x01),	/* 0x43: MBOX_REQUEST_NON_PARTICIPATING_MODE */
5037	ISPOPMAP(0x00, 0x00),	/* 0x44: */
5038	ISPOPMAP(0x00, 0x00),	/* 0x45: */
5039	ISPOPMAP(0x00, 0x00),	/* 0x46: */
5040	ISPOPMAP(0xcf, 0x03),	/* 0x47: GET PORT_DATABASE ENHANCED */
5041	ISPOPMAP(0x00, 0x00),	/* 0x48: */
5042	ISPOPMAP(0x00, 0x00),	/* 0x49: */
5043	ISPOPMAP(0x00, 0x00),	/* 0x4a: */
5044	ISPOPMAP(0x00, 0x00),	/* 0x4b: */
5045	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
5046	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
5047	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
5048	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
5049	ISPOPMAP(0x00, 0x00),	/* 0x50: */
5050	ISPOPMAP(0x00, 0x00),	/* 0x51: */
5051	ISPOPMAP(0x00, 0x00),	/* 0x52: */
5052	ISPOPMAP(0x00, 0x00),	/* 0x53: */
5053	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
5054	ISPOPMAP(0x00, 0x00),	/* 0x55: */
5055	ISPOPMAP(0x00, 0x00),	/* 0x56: */
5056	ISPOPMAP(0x00, 0x00),	/* 0x57: */
5057	ISPOPMAP(0x00, 0x00),	/* 0x58: */
5058	ISPOPMAP(0x00, 0x00),	/* 0x59: */
5059	ISPOPMAP(0x00, 0x00),	/* 0x5a: */
5060	ISPOPMAP(0x03, 0x01),	/* 0x5b: MBOX_DRIVER_HEARTBEAT */
5061	ISPOPMAP(0xcf, 0x01),	/* 0x5c: MBOX_FW_HEARTBEAT */
5062	ISPOPMAP(0x07, 0x03),	/* 0x5d: MBOX_GET_SET_DATA_RATE */
5063	ISPOPMAP(0x00, 0x00),	/* 0x5e: */
5064	ISPOPMAP(0x00, 0x00),	/* 0x5f: */
5065	ISPOPMAP(0xfd, 0x31),	/* 0x60: MBOX_INIT_FIRMWARE */
5066	ISPOPMAP(0x00, 0x00),	/* 0x61: */
5067	ISPOPMAP(0x01, 0x01),	/* 0x62: MBOX_INIT_LIP */
5068	ISPOPMAP(0xcd, 0x03),	/* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
5069	ISPOPMAP(0xcf, 0x01),	/* 0x64: MBOX_GET_PORT_DB */
5070	ISPOPMAP(0x07, 0x01),	/* 0x65: MBOX_CLEAR_ACA */
5071	ISPOPMAP(0x07, 0x01),	/* 0x66: MBOX_TARGET_RESET */
5072	ISPOPMAP(0x07, 0x01),	/* 0x67: MBOX_CLEAR_TASK_SET */
5073	ISPOPMAP(0x07, 0x01),	/* 0x68: MBOX_ABORT_TASK_SET */
5074	ISPOPMAP(0x01, 0x07),	/* 0x69: MBOX_GET_FW_STATE */
5075	ISPOPMAP(0x03, 0xcf),	/* 0x6a: MBOX_GET_PORT_NAME */
5076	ISPOPMAP(0xcf, 0x01),	/* 0x6b: MBOX_GET_LINK_STATUS */
5077	ISPOPMAP(0x0f, 0x01),	/* 0x6c: MBOX_INIT_LIP_RESET */
5078	ISPOPMAP(0x00, 0x00),	/* 0x6d: */
5079	ISPOPMAP(0xcf, 0x03),	/* 0x6e: MBOX_SEND_SNS */
5080	ISPOPMAP(0x0f, 0x07),	/* 0x6f: MBOX_FABRIC_LOGIN */
5081	ISPOPMAP(0x03, 0x01),	/* 0x70: MBOX_SEND_CHANGE_REQUEST */
5082	ISPOPMAP(0x03, 0x03),	/* 0x71: MBOX_FABRIC_LOGOUT */
5083	ISPOPMAP(0x0f, 0x0f),	/* 0x72: MBOX_INIT_LIP_LOGIN */
5084	ISPOPMAP(0x00, 0x00),	/* 0x73: */
5085	ISPOPMAP(0x07, 0x01),	/* 0x74: LOGIN LOOP PORT */
5086	ISPOPMAP(0xcf, 0x03),	/* 0x75: GET PORT/NODE NAME LIST */
5087	ISPOPMAP(0x4f, 0x01),	/* 0x76: SET VENDOR ID */
5088	ISPOPMAP(0xcd, 0x01),	/* 0x77: INITIALIZE IP MAILBOX */
5089	ISPOPMAP(0x00, 0x00),	/* 0x78: */
5090	ISPOPMAP(0x00, 0x00),	/* 0x79: */
5091	ISPOPMAP(0x00, 0x00),	/* 0x7a: */
5092	ISPOPMAP(0x00, 0x00),	/* 0x7b: */
5093	ISPOPMAP(0x4f, 0x03),	/* 0x7c: Get ID List */
5094	ISPOPMAP(0xcf, 0x01),	/* 0x7d: SEND LFA */
5095	ISPOPMAP(0x07, 0x01)	/* 0x7e: Lun RESET */
5096};
5097/*
5098 * Footnotes
5099 *
5100 * (1): this sets bits 21..16 in mailbox register #8, which we nominally
5101 *	do not access at this time in the core driver. The caller is
5102 *	responsible for setting this register first (Gross!).
5103 */
5104
5105#ifndef	ISP_STRIPPED
5106static char *fc_mbcmd_names[] = {
5107	"NO-OP",
5108	"LOAD RAM",
5109	"EXEC FIRMWARE",
5110	"DUMP RAM",
5111	"WRITE RAM WORD",
5112	"READ RAM WORD",
5113	"MAILBOX REG TEST",
5114	"VERIFY CHECKSUM",
5115	"ABOUT FIRMWARE",
5116	"LOAD RAM",
5117	"DUMP RAM",
5118	NULL,
5119	NULL,
5120	"READ RAM WORD EXTENDED",
5121	"CHECK FIRMWARE",
5122	NULL,
5123	"INIT REQUEST QUEUE",
5124	"INIT RESULT QUEUE",
5125	"EXECUTE IOCB",
5126	"WAKE UP",
5127	"STOP FIRMWARE",
5128	"ABORT",
5129	"ABORT DEVICE",
5130	"ABORT TARGET",
5131	"BUS RESET",
5132	"STOP QUEUE",
5133	"START QUEUE",
5134	"SINGLE STEP QUEUE",
5135	"ABORT QUEUE",
5136	"GET DEV QUEUE STATUS",
5137	NULL,
5138	"GET FIRMWARE STATUS",
5139	"GET LOOP ID",
5140	NULL,
5141	"GET RETRY COUNT",
5142	NULL,
5143	NULL,
5144	NULL,
5145	NULL,
5146	NULL,
5147	"GET FIRMWARE OPTIONS",
5148	"GET PORT QUEUE PARAMS",
5149	NULL,
5150	NULL,
5151	NULL,
5152	NULL,
5153	NULL,
5154	NULL,
5155	NULL,
5156	NULL,
5157	"SET RETRY COUNT",
5158	NULL,
5159	NULL,
5160	NULL,
5161	NULL,
5162	NULL,
5163	"SET FIRMWARE OPTIONS",
5164	"SET PORT QUEUE PARAMS",
5165	NULL,
5166	NULL,
5167	NULL,
5168	NULL,
5169	NULL,
5170	NULL,
5171	"LOOP PORT BYPASS",
5172	"LOOP PORT ENABLE",
5173	"GET RESOURCE COUNTS",
5174	"REQUEST NON PARTICIPATING MODE",
5175	NULL,
5176	NULL,
5177	NULL,
5178	"GET PORT DATABASE,, ENHANCED",
5179	NULL,
5180	NULL,
5181	NULL,
5182	NULL,
5183	NULL,
5184	NULL,
5185	NULL,
5186	NULL,
5187	NULL,
5188	NULL,
5189	NULL,
5190	NULL,
5191	"EXECUTE IOCB A64",
5192	NULL,
5193	NULL,
5194	NULL,
5195	NULL,
5196	NULL,
5197	NULL,
5198	NULL,
5199	NULL,
5200	"GET/SET DATA RATE",
5201	NULL,
5202	NULL,
5203	"INIT FIRMWARE",
5204	NULL,
5205	"INIT LIP",
5206	"GET FC-AL POSITION MAP",
5207	"GET PORT DATABASE",
5208	"CLEAR ACA",
5209	"TARGET RESET",
5210	"CLEAR TASK SET",
5211	"ABORT TASK SET",
5212	"GET FW STATE",
5213	"GET PORT NAME",
5214	"GET LINK STATUS",
5215	"INIT LIP RESET",
5216	NULL,
5217	"SEND SNS",
5218	"FABRIC LOGIN",
5219	"SEND CHANGE REQUEST",
5220	"FABRIC LOGOUT",
5221	"INIT LIP LOGIN",
5222	NULL,
5223	"LOGIN LOOP PORT",
5224	"GET PORT/NODE NAME LIST",
5225	"SET VENDOR ID",
5226	"INITIALIZE IP MAILBOX",
5227	NULL,
5228	NULL,
5229	NULL,
5230	NULL,
5231	"Get ID List",
5232	"SEND LFA",
5233	"Lun RESET"
5234};
5235#endif
5236
5237static void
5238isp_mboxcmd_qnw(struct ispsoftc *isp, mbreg_t *mbp, int nodelay)
5239{
5240	unsigned int lim, ibits, obits, box, opcode;
5241	u_int16_t *mcp;
5242
5243	if (IS_FC(isp)) {
5244		mcp = mbpfc;
5245		lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
5246	} else {
5247		mcp = mbpscsi;
5248		lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
5249	}
5250	opcode = mbp->param[0];
5251	ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
5252	obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
5253	for (box = 0; box < MAX_MAILBOX; box++) {
5254		if (ibits & (1 << box)) {
5255			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
5256		}
5257		if (nodelay == 0) {
5258			isp->isp_mboxtmp[box] = mbp->param[box] = 0;
5259		}
5260	}
5261	if (nodelay == 0) {
5262		isp->isp_lastmbxcmd = opcode;
5263		isp->isp_obits = obits;
5264		isp->isp_mboxbsy = 1;
5265	}
5266	ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
5267	/*
5268	 * Oddly enough, if we're not delaying for an answer,
5269	 * delay a bit to give the f/w a chance to pick up the
5270	 * command.
5271	 */
5272	if (nodelay) {
5273		USEC_DELAY(1000);
5274	}
5275}
5276
5277static void
5278isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
5279{
5280	char *cname, *xname, tname[16], mname[16];
5281	unsigned int lim, ibits, obits, box, opcode;
5282	u_int16_t *mcp;
5283
5284	if (IS_FC(isp)) {
5285		mcp = mbpfc;
5286		lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
5287	} else {
5288		mcp = mbpscsi;
5289		lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
5290	}
5291
5292	if ((opcode = mbp->param[0]) >= lim) {
5293		mbp->param[0] = MBOX_INVALID_COMMAND;
5294		isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
5295		return;
5296	}
5297
5298	ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
5299	obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
5300
5301	if (ibits == 0 && obits == 0) {
5302		mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
5303		isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
5304		return;
5305	}
5306
5307	/*
5308	 * Get exclusive usage of mailbox registers.
5309	 */
5310	MBOX_ACQUIRE(isp);
5311
5312	for (box = 0; box < MAX_MAILBOX; box++) {
5313		if (ibits & (1 << box)) {
5314			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
5315		}
5316		isp->isp_mboxtmp[box] = mbp->param[box] = 0;
5317	}
5318
5319	isp->isp_lastmbxcmd = opcode;
5320
5321	/*
5322	 * We assume that we can't overwrite a previous command.
5323	 */
5324	isp->isp_obits = obits;
5325	isp->isp_mboxbsy = 1;
5326
5327	/*
5328	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
5329	 */
5330	ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
5331
5332	/*
5333	 * While we haven't finished the command, spin our wheels here.
5334	 */
5335	MBOX_WAIT_COMPLETE(isp);
5336
5337	if (isp->isp_mboxbsy) {
5338		/*
5339		 * Command timed out.
5340		 */
5341		isp->isp_mboxbsy = 0;
5342		MBOX_RELEASE(isp);
5343		return;
5344	}
5345
5346	/*
5347	 * Copy back output registers.
5348	 */
5349	for (box = 0; box < MAX_MAILBOX; box++) {
5350		if (obits & (1 << box)) {
5351			mbp->param[box] = isp->isp_mboxtmp[box];
5352		}
5353	}
5354
5355	MBOX_RELEASE(isp);
5356
5357	if (logmask == 0 || opcode == MBOX_EXEC_FIRMWARE) {
5358		return;
5359	}
5360#ifdef	ISP_STRIPPED
5361	cname = NULL;
5362#else
5363	cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
5364#endif
5365	if (cname == NULL) {
5366		cname = tname;
5367		SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
5368	}
5369
5370	/*
5371	 * Just to be chatty here...
5372	 */
5373	xname = NULL;
5374	switch (mbp->param[0]) {
5375	case MBOX_COMMAND_COMPLETE:
5376		break;
5377	case MBOX_INVALID_COMMAND:
5378		if (logmask & MBLOGMASK(MBOX_COMMAND_COMPLETE))
5379			xname = "INVALID COMMAND";
5380		break;
5381	case MBOX_HOST_INTERFACE_ERROR:
5382		if (logmask & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR))
5383			xname = "HOST INTERFACE ERROR";
5384		break;
5385	case MBOX_TEST_FAILED:
5386		if (logmask & MBLOGMASK(MBOX_TEST_FAILED))
5387			xname = "TEST FAILED";
5388		break;
5389	case MBOX_COMMAND_ERROR:
5390		if (logmask & MBLOGMASK(MBOX_COMMAND_ERROR))
5391			xname = "COMMAND ERROR";
5392		break;
5393	case MBOX_COMMAND_PARAM_ERROR:
5394		if (logmask & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR))
5395			xname = "COMMAND PARAMETER ERROR";
5396		break;
5397	case MBOX_LOOP_ID_USED:
5398		if (logmask & MBLOGMASK(MBOX_LOOP_ID_USED))
5399			xname = "LOOP ID ALREADY IN USE";
5400		break;
5401	case MBOX_PORT_ID_USED:
5402		if (logmask & MBLOGMASK(MBOX_PORT_ID_USED))
5403			xname = "PORT ID ALREADY IN USE";
5404		break;
5405	case MBOX_ALL_IDS_USED:
5406		if (logmask & MBLOGMASK(MBOX_ALL_IDS_USED))
5407			xname = "ALL LOOP IDS IN USE";
5408		break;
5409	case 0:		/* special case */
5410		xname = "TIMEOUT";
5411		break;
5412	default:
5413		SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
5414		xname = mname;
5415		break;
5416	}
5417	if (xname)
5418		isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
5419		    cname, xname);
5420}
5421
5422static void
5423isp_fw_state(struct ispsoftc *isp)
5424{
5425	if (IS_FC(isp)) {
5426		mbreg_t mbs;
5427		fcparam *fcp = isp->isp_param;
5428
5429		mbs.param[0] = MBOX_GET_FW_STATE;
5430		isp_mboxcmd(isp, &mbs, MBLOGALL);
5431		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
5432			fcp->isp_fwstate = mbs.param[1];
5433		}
5434	}
5435}
5436
5437static void
5438isp_update(struct ispsoftc *isp)
5439{
5440	int bus, upmask;
5441
5442	for (bus = 0, upmask = isp->isp_update; upmask != 0; bus++) {
5443		if (upmask & (1 << bus)) {
5444			isp_update_bus(isp, bus);
5445		}
5446		upmask &= ~(1 << bus);
5447	}
5448}
5449
5450static void
5451isp_update_bus(struct ispsoftc *isp, int bus)
5452{
5453	int tgt;
5454	mbreg_t mbs;
5455	sdparam *sdp;
5456
5457	isp->isp_update &= ~(1 << bus);
5458	if (IS_FC(isp)) {
5459		/*
5460		 * There are no 'per-bus' settings for Fibre Channel.
5461		 */
5462		return;
5463	}
5464	sdp = isp->isp_param;
5465	sdp += bus;
5466
5467	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
5468		u_int16_t flags, period, offset;
5469		int get;
5470
5471		if (sdp->isp_devparam[tgt].dev_enable == 0) {
5472			sdp->isp_devparam[tgt].dev_update = 0;
5473			sdp->isp_devparam[tgt].dev_refresh = 0;
5474			isp_prt(isp, ISP_LOGDEBUG0,
5475	 		    "skipping target %d bus %d update", tgt, bus);
5476			continue;
5477		}
5478		/*
5479		 * If the goal is to update the status of the device,
5480		 * take what's in goal_flags and try and set the device
5481		 * toward that. Otherwise, if we're just refreshing the
5482		 * current device state, get the current parameters.
5483		 */
5484
5485		/*
5486		 * Refresh overrides set
5487		 */
5488		if (sdp->isp_devparam[tgt].dev_refresh) {
5489			mbs.param[0] = MBOX_GET_TARGET_PARAMS;
5490			sdp->isp_devparam[tgt].dev_refresh = 0;
5491			get = 1;
5492		} else if (sdp->isp_devparam[tgt].dev_update) {
5493			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
5494			/*
5495			 * Make sure goal_flags has "Renegotiate on Error"
5496			 * on and "Freeze Queue on Error" off.
5497			 */
5498			sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
5499			sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
5500
5501			mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
5502
5503			/*
5504			 * Insist that PARITY must be enabled
5505			 * if SYNC or WIDE is enabled.
5506			 */
5507			if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
5508				mbs.param[2] |= DPARM_PARITY;
5509			}
5510
5511			if ((mbs.param[2] & DPARM_SYNC) == 0) {
5512				mbs.param[3] = 0;
5513			} else {
5514				mbs.param[3] =
5515				    (sdp->isp_devparam[tgt].goal_offset << 8) |
5516				    (sdp->isp_devparam[tgt].goal_period);
5517			}
5518			/*
5519			 * A command completion later that has
5520			 * RQSTF_NEGOTIATION set can cause
5521			 * the dev_refresh/announce cycle also.
5522			 *
5523			 * Note: It is really important to update our current
5524			 * flags with at least the state of TAG capabilities-
5525			 * otherwise we might try and send a tagged command
5526			 * when we have it all turned off. So change it here
5527			 * to say that current already matches goal.
5528			 */
5529			sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
5530			sdp->isp_devparam[tgt].actv_flags |=
5531			    (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
5532			isp_prt(isp, ISP_LOGDEBUG0,
5533			    "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
5534			    bus, tgt, mbs.param[2], mbs.param[3] >> 8,
5535			    mbs.param[3] & 0xff);
5536			sdp->isp_devparam[tgt].dev_update = 0;
5537			sdp->isp_devparam[tgt].dev_refresh = 1;
5538			get = 0;
5539		} else {
5540			continue;
5541		}
5542		mbs.param[1] = (bus << 15) | (tgt << 8);
5543		isp_mboxcmd(isp, &mbs, MBLOGALL);
5544		if (get == 0) {
5545			isp->isp_sendmarker |= (1 << bus);
5546			continue;
5547		}
5548		flags = mbs.param[2];
5549		period = mbs.param[3] & 0xff;
5550		offset = mbs.param[3] >> 8;
5551		sdp->isp_devparam[tgt].actv_flags = flags;
5552		sdp->isp_devparam[tgt].actv_period = period;
5553		sdp->isp_devparam[tgt].actv_offset = offset;
5554		get = (bus << 16) | tgt;
5555		(void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get);
5556	}
5557
5558	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
5559		if (sdp->isp_devparam[tgt].dev_update ||
5560		    sdp->isp_devparam[tgt].dev_refresh) {
5561			isp->isp_update |= (1 << bus);
5562			break;
5563		}
5564	}
5565}
5566
5567#ifndef	DEFAULT_FRAMESIZE
5568#define	DEFAULT_FRAMESIZE(isp)		ICB_DFLT_FRMLEN
5569#endif
5570#ifndef	DEFAULT_EXEC_THROTTLE
5571#define	DEFAULT_EXEC_THROTTLE(isp)	ISP_EXEC_THROTTLE
5572#endif
5573
5574static void
5575isp_setdfltparm(struct ispsoftc *isp, int channel)
5576{
5577	int tgt;
5578	mbreg_t mbs;
5579	sdparam *sdp;
5580
5581	if (IS_FC(isp)) {
5582		fcparam *fcp = (fcparam *) isp->isp_param;
5583		int nvfail;
5584
5585		fcp += channel;
5586		if (fcp->isp_gotdparms) {
5587			return;
5588		}
5589		fcp->isp_gotdparms = 1;
5590		fcp->isp_maxfrmlen = DEFAULT_FRAMESIZE(isp);
5591		fcp->isp_maxalloc = ICB_DFLT_ALLOC;
5592		fcp->isp_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
5593		fcp->isp_retry_delay = ICB_DFLT_RDELAY;
5594		fcp->isp_retry_count = ICB_DFLT_RCOUNT;
5595		/* Platform specific.... */
5596		fcp->isp_loopid = DEFAULT_LOOPID(isp);
5597		fcp->isp_nodewwn = DEFAULT_NODEWWN(isp);
5598		fcp->isp_portwwn = DEFAULT_PORTWWN(isp);
5599		fcp->isp_fwoptions = 0;
5600		fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
5601		fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
5602		fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
5603#ifndef	ISP_NO_FASTPOST_FC
5604		fcp->isp_fwoptions |= ICBOPT_FAST_POST;
5605#endif
5606		if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
5607			fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
5608
5609		/*
5610		 * Make sure this is turned off now until we get
5611		 * extended options from NVRAM
5612		 */
5613		fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
5614
5615		/*
5616		 * Now try and read NVRAM unless told to not do so.
5617		 * This will set fcparam's isp_nodewwn && isp_portwwn.
5618		 */
5619		if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
5620		    	nvfail = isp_read_nvram(isp);
5621			if (nvfail)
5622				isp->isp_confopts |= ISP_CFG_NONVRAM;
5623		} else {
5624			nvfail = 1;
5625		}
5626		/*
5627		 * Set node && port to override platform set defaults
5628		 * unless the nvram read failed (or none was done),
5629		 * or the platform code wants to use what had been
5630		 * set in the defaults.
5631		 */
5632		if (nvfail) {
5633			isp->isp_confopts |= ISP_CFG_OWNWWPN|ISP_CFG_OWNWWNN;
5634		}
5635		if (isp->isp_confopts & ISP_CFG_OWNWWNN) {
5636			isp_prt(isp, ISP_LOGCONFIG, "Using Node WWN 0x%08x%08x",
5637			    (u_int32_t) (DEFAULT_NODEWWN(isp) >> 32),
5638			    (u_int32_t) (DEFAULT_NODEWWN(isp) & 0xffffffff));
5639			ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
5640		} else {
5641			/*
5642			 * We always start out with values derived
5643			 * from NVRAM or our platform default.
5644			 */
5645			ISP_NODEWWN(isp) = fcp->isp_nodewwn;
5646		}
5647		if (isp->isp_confopts & ISP_CFG_OWNWWPN) {
5648			isp_prt(isp, ISP_LOGCONFIG, "Using Port WWN 0x%08x%08x",
5649			    (u_int32_t) (DEFAULT_PORTWWN(isp) >> 32),
5650			    (u_int32_t) (DEFAULT_PORTWWN(isp) & 0xffffffff));
5651			ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
5652		} else {
5653			/*
5654			 * We always start out with values derived
5655			 * from NVRAM or our platform default.
5656			 */
5657			ISP_PORTWWN(isp) = fcp->isp_portwwn;
5658		}
5659		return;
5660	}
5661
5662	sdp = (sdparam *) isp->isp_param;
5663	sdp += channel;
5664
5665	/*
5666	 * Been there, done that, got the T-shirt...
5667	 */
5668	if (sdp->isp_gotdparms) {
5669		return;
5670	}
5671	sdp->isp_gotdparms = 1;
5672
5673	/*
5674	 * Establish some default parameters.
5675	 */
5676	sdp->isp_cmd_dma_burst_enable = 0;
5677	sdp->isp_data_dma_burst_enabl = 1;
5678	sdp->isp_fifo_threshold = 0;
5679	sdp->isp_initiator_id = DEFAULT_IID(isp);
5680	if (isp->isp_type >= ISP_HA_SCSI_1040) {
5681		sdp->isp_async_data_setup = 9;
5682	} else {
5683		sdp->isp_async_data_setup = 6;
5684	}
5685	sdp->isp_selection_timeout = 250;
5686	sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
5687	sdp->isp_tag_aging = 8;
5688	sdp->isp_bus_reset_delay = 5;
5689	/*
5690	 * Don't retry selection, busy or queue full automatically- reflect
5691	 * these back to us.
5692	 */
5693	sdp->isp_retry_count = 0;
5694	sdp->isp_retry_delay = 0;
5695
5696	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
5697		sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
5698		sdp->isp_devparam[tgt].dev_enable = 1;
5699	}
5700
5701	/*
5702	 * If we've not been told to avoid reading NVRAM, try and read it.
5703	 * If we're successful reading it, we can then return because NVRAM
5704	 * will tell us what the desired settings are. Otherwise, we establish
5705	 * some reasonable 'fake' nvram and goal defaults.
5706	 */
5707
5708	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
5709		if (isp_read_nvram(isp) == 0) {
5710			return;
5711		}
5712	}
5713
5714	/*
5715	 * Now try and see whether we have specific values for them.
5716	 */
5717	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
5718		mbs.param[0] = MBOX_GET_ACT_NEG_STATE;
5719		isp_mboxcmd(isp, &mbs, MBLOGNONE);
5720		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
5721			sdp->isp_req_ack_active_neg = 1;
5722			sdp->isp_data_line_active_neg = 1;
5723		} else {
5724			sdp->isp_req_ack_active_neg =
5725			    (mbs.param[1+channel] >> 4) & 0x1;
5726			sdp->isp_data_line_active_neg =
5727			    (mbs.param[1+channel] >> 5) & 0x1;
5728		}
5729	}
5730
5731	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc3,
5732	    0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
5733	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
5734	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
5735	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc3,
5736	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
5737	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
5738	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
5739
5740	/*
5741	 * The trick here is to establish a default for the default (honk!)
5742	 * state (goal_flags). Then try and get the current status from
5743	 * the card to fill in the current state. We don't, in fact, set
5744	 * the default to the SAFE default state- that's not the goal state.
5745	 */
5746	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
5747		u_int8_t off, per;
5748		sdp->isp_devparam[tgt].actv_offset = 0;
5749		sdp->isp_devparam[tgt].actv_period = 0;
5750		sdp->isp_devparam[tgt].actv_flags = 0;
5751
5752		sdp->isp_devparam[tgt].goal_flags =
5753		    sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
5754
5755		/*
5756		 * We default to Wide/Fast for versions less than a 1040
5757		 * (unless it's SBus).
5758		 */
5759		if (IS_ULTRA3(isp)) {
5760			off = ISP_80M_SYNCPARMS >> 8;
5761			per = ISP_80M_SYNCPARMS & 0xff;
5762		} else if (IS_ULTRA2(isp)) {
5763			off = ISP_40M_SYNCPARMS >> 8;
5764			per = ISP_40M_SYNCPARMS & 0xff;
5765		} else if (IS_1240(isp)) {
5766			off = ISP_20M_SYNCPARMS >> 8;
5767			per = ISP_20M_SYNCPARMS & 0xff;
5768		} else if ((isp->isp_bustype == ISP_BT_SBUS &&
5769		    isp->isp_type < ISP_HA_SCSI_1020A) ||
5770		    (isp->isp_bustype == ISP_BT_PCI &&
5771		    isp->isp_type < ISP_HA_SCSI_1040) ||
5772		    (isp->isp_clock && isp->isp_clock < 60) ||
5773		    (sdp->isp_ultramode == 0)) {
5774			off = ISP_10M_SYNCPARMS >> 8;
5775			per = ISP_10M_SYNCPARMS & 0xff;
5776		} else {
5777			off = ISP_20M_SYNCPARMS_1040 >> 8;
5778			per = ISP_20M_SYNCPARMS_1040 & 0xff;
5779		}
5780		sdp->isp_devparam[tgt].goal_offset =
5781		    sdp->isp_devparam[tgt].nvrm_offset = off;
5782		sdp->isp_devparam[tgt].goal_period =
5783		    sdp->isp_devparam[tgt].nvrm_period = per;
5784
5785		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc3,
5786		    channel, tgt, sdp->isp_devparam[tgt].nvrm_flags,
5787		    sdp->isp_devparam[tgt].nvrm_offset,
5788		    sdp->isp_devparam[tgt].nvrm_period);
5789	}
5790}
5791
5792/*
5793 * Re-initialize the ISP and complete all orphaned commands
5794 * with a 'botched' notice. The reset/init routines should
5795 * not disturb an already active list of commands.
5796 *
5797 * Locks held prior to coming here.
5798 */
5799
5800void
5801isp_reinit(struct ispsoftc *isp)
5802{
5803	XS_T *xs;
5804	u_int16_t handle;
5805
5806	isp_reset(isp);
5807	if (isp->isp_state != ISP_RESETSTATE) {
5808		isp_prt(isp, ISP_LOGERR, "isp_reinit cannot reset card");
5809	} else if (isp->isp_role != ISP_ROLE_NONE) {
5810		isp_init(isp);
5811		if (isp->isp_state == ISP_INITSTATE) {
5812			isp->isp_state = ISP_RUNSTATE;
5813		}
5814		if (isp->isp_state != ISP_RUNSTATE) {
5815			isp_prt(isp, ISP_LOGERR,
5816			    "isp_reinit cannot restart card");
5817		}
5818	}
5819	isp->isp_nactive = 0;
5820
5821	for (handle = 1; (int) handle <= isp->isp_maxcmds; handle++) {
5822		xs = isp_find_xs(isp, handle);
5823		if (xs == NULL) {
5824			continue;
5825		}
5826		isp_destroy_handle(isp, handle);
5827		if (XS_XFRLEN(xs)) {
5828			ISP_DMAFREE(isp, xs, handle);
5829			XS_RESID(xs) = XS_XFRLEN(xs);
5830		} else {
5831			XS_RESID(xs) = 0;
5832		}
5833		XS_SETERR(xs, HBA_BUSRESET);
5834		isp_done(xs);
5835	}
5836}
5837
5838/*
5839 * NVRAM Routines
5840 */
5841static int
5842isp_read_nvram(struct ispsoftc *isp)
5843{
5844	int i, amt;
5845	u_int8_t csum, minversion;
5846	union {
5847		u_int8_t _x[ISP2100_NVRAM_SIZE];
5848		u_int16_t _s[ISP2100_NVRAM_SIZE>>1];
5849	} _n;
5850#define	nvram_data	_n._x
5851#define	nvram_words	_n._s
5852
5853	if (IS_FC(isp)) {
5854		amt = ISP2100_NVRAM_SIZE;
5855		minversion = 1;
5856	} else if (IS_ULTRA2(isp)) {
5857		amt = ISP1080_NVRAM_SIZE;
5858		minversion = 0;
5859	} else {
5860		amt = ISP_NVRAM_SIZE;
5861		minversion = 2;
5862	}
5863
5864	/*
5865	 * Just read the first two words first to see if we have a valid
5866	 * NVRAM to continue reading the rest with.
5867	 */
5868	for (i = 0; i < 2; i++) {
5869		isp_rdnvram_word(isp, i, &nvram_words[i]);
5870	}
5871	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
5872	    nvram_data[2] != 'P') {
5873		if (isp->isp_bustype != ISP_BT_SBUS) {
5874			isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
5875			isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x",
5876			    nvram_data[0], nvram_data[1], nvram_data[2]);
5877		}
5878		return (-1);
5879	}
5880	for (i = 2; i < amt>>1; i++) {
5881		isp_rdnvram_word(isp, i, &nvram_words[i]);
5882	}
5883	for (csum = 0, i = 0; i < amt; i++) {
5884		csum += nvram_data[i];
5885	}
5886	if (csum != 0) {
5887		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
5888		return (-1);
5889	}
5890	if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
5891		isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
5892		    ISP_NVRAM_VERSION(nvram_data));
5893		return (-1);
5894	}
5895
5896	if (IS_ULTRA3(isp)) {
5897		isp_parse_nvram_12160(isp, 0, nvram_data);
5898		isp_parse_nvram_12160(isp, 1, nvram_data);
5899	} else if (IS_1080(isp)) {
5900		isp_parse_nvram_1080(isp, 0, nvram_data);
5901	} else if (IS_1280(isp) || IS_1240(isp)) {
5902		isp_parse_nvram_1080(isp, 0, nvram_data);
5903		isp_parse_nvram_1080(isp, 1, nvram_data);
5904	} else if (IS_SCSI(isp)) {
5905		isp_parse_nvram_1020(isp, nvram_data);
5906	} else {
5907		isp_parse_nvram_2100(isp, nvram_data);
5908	}
5909	return (0);
5910#undef	nvram_data
5911#undef	nvram_words
5912}
5913
5914static void
5915isp_rdnvram_word(struct ispsoftc *isp, int wo, u_int16_t *rp)
5916{
5917	int i, cbits;
5918	u_int16_t bit, rqst;
5919
5920	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
5921	USEC_DELAY(2);
5922	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
5923	USEC_DELAY(2);
5924
5925	if (IS_FC(isp)) {
5926		wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
5927		if (IS_2312(isp) && isp->isp_port) {
5928			wo += 128;
5929		}
5930		rqst = (ISP_NVRAM_READ << 8) | wo;
5931		cbits = 10;
5932	} else if (IS_ULTRA2(isp)) {
5933		wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
5934		rqst = (ISP_NVRAM_READ << 8) | wo;
5935		cbits = 10;
5936	} else {
5937		wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
5938		rqst = (ISP_NVRAM_READ << 6) | wo;
5939		cbits = 8;
5940	}
5941
5942	/*
5943	 * Clock the word select request out...
5944	 */
5945	for (i = cbits; i >= 0; i--) {
5946		if ((rqst >> i) & 1) {
5947			bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
5948		} else {
5949			bit = BIU_NVRAM_SELECT;
5950		}
5951		ISP_WRITE(isp, BIU_NVRAM, bit);
5952		USEC_DELAY(2);
5953		ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
5954		USEC_DELAY(2);
5955		ISP_WRITE(isp, BIU_NVRAM, bit);
5956		USEC_DELAY(2);
5957	}
5958	/*
5959	 * Now read the result back in (bits come back in MSB format).
5960	 */
5961	*rp = 0;
5962	for (i = 0; i < 16; i++) {
5963		u_int16_t rv;
5964		*rp <<= 1;
5965		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
5966		USEC_DELAY(2);
5967		rv = ISP_READ(isp, BIU_NVRAM);
5968		if (rv & BIU_NVRAM_DATAIN) {
5969			*rp |= 1;
5970		}
5971		USEC_DELAY(2);
5972		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
5973		USEC_DELAY(2);
5974	}
5975	ISP_WRITE(isp, BIU_NVRAM, 0);
5976	USEC_DELAY(2);
5977	ISP_SWIZZLE_NVRAM_WORD(isp, rp);
5978}
5979
5980static void
5981isp_parse_nvram_1020(struct ispsoftc *isp, u_int8_t *nvram_data)
5982{
5983	sdparam *sdp = (sdparam *) isp->isp_param;
5984	int tgt;
5985
5986	sdp->isp_fifo_threshold =
5987		ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
5988		(ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
5989
5990	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
5991		sdp->isp_initiator_id =
5992			ISP_NVRAM_INITIATOR_ID(nvram_data);
5993
5994	sdp->isp_bus_reset_delay =
5995		ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
5996
5997	sdp->isp_retry_count =
5998		ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
5999
6000	sdp->isp_retry_delay =
6001		ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
6002
6003	sdp->isp_async_data_setup =
6004		ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
6005
6006	if (isp->isp_type >= ISP_HA_SCSI_1040) {
6007		if (sdp->isp_async_data_setup < 9) {
6008			sdp->isp_async_data_setup = 9;
6009		}
6010	} else {
6011		if (sdp->isp_async_data_setup != 6) {
6012			sdp->isp_async_data_setup = 6;
6013		}
6014	}
6015
6016	sdp->isp_req_ack_active_neg =
6017		ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
6018
6019	sdp->isp_data_line_active_neg =
6020		ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
6021
6022	sdp->isp_data_dma_burst_enabl =
6023		ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
6024
6025	sdp->isp_cmd_dma_burst_enable =
6026		ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
6027
6028	sdp->isp_tag_aging =
6029		ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
6030
6031	sdp->isp_selection_timeout =
6032		ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
6033
6034	sdp->isp_max_queue_depth =
6035		ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
6036
6037	sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
6038
6039	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
6040	    0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
6041	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
6042	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
6043	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
6044	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
6045	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
6046	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
6047
6048	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
6049		sdp->isp_devparam[tgt].dev_enable =
6050			ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
6051		sdp->isp_devparam[tgt].exc_throttle =
6052			ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
6053		sdp->isp_devparam[tgt].nvrm_offset =
6054			ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
6055		sdp->isp_devparam[tgt].nvrm_period =
6056			ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
6057		/*
6058		 * We probably shouldn't lie about this, but it
6059		 * it makes it much safer if we limit NVRAM values
6060		 * to sanity.
6061		 */
6062		if (isp->isp_type < ISP_HA_SCSI_1040) {
6063			/*
6064			 * If we're not ultra, we can't possibly
6065			 * be a shorter period than this.
6066			 */
6067			if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
6068				sdp->isp_devparam[tgt].nvrm_period = 0x19;
6069			}
6070			if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
6071				sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
6072			}
6073		} else {
6074			if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
6075				sdp->isp_devparam[tgt].nvrm_offset = 0x8;
6076			}
6077		}
6078		sdp->isp_devparam[tgt].nvrm_flags = 0;
6079		if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
6080			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
6081		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
6082		if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
6083			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
6084		if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
6085			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
6086		if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
6087			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
6088		if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
6089			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
6090		if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
6091			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
6092		sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
6093		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
6094		    0, tgt, sdp->isp_devparam[tgt].nvrm_flags,
6095		    sdp->isp_devparam[tgt].nvrm_offset,
6096		    sdp->isp_devparam[tgt].nvrm_period);
6097		sdp->isp_devparam[tgt].goal_offset =
6098		    sdp->isp_devparam[tgt].nvrm_offset;
6099		sdp->isp_devparam[tgt].goal_period =
6100		    sdp->isp_devparam[tgt].nvrm_period;
6101		sdp->isp_devparam[tgt].goal_flags =
6102		    sdp->isp_devparam[tgt].nvrm_flags;
6103	}
6104}
6105
6106static void
6107isp_parse_nvram_1080(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
6108{
6109	sdparam *sdp = (sdparam *) isp->isp_param;
6110	int tgt;
6111
6112	sdp += bus;
6113
6114	sdp->isp_fifo_threshold =
6115	    ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
6116
6117	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
6118		sdp->isp_initiator_id =
6119		    ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
6120
6121	sdp->isp_bus_reset_delay =
6122	    ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
6123
6124	sdp->isp_retry_count =
6125	    ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
6126
6127	sdp->isp_retry_delay =
6128	    ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
6129
6130	sdp->isp_async_data_setup =
6131	    ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
6132
6133	sdp->isp_req_ack_active_neg =
6134	    ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
6135
6136	sdp->isp_data_line_active_neg =
6137	    ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
6138
6139	sdp->isp_data_dma_burst_enabl =
6140	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
6141
6142	sdp->isp_cmd_dma_burst_enable =
6143	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
6144
6145	sdp->isp_selection_timeout =
6146	    ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
6147
6148	sdp->isp_max_queue_depth =
6149	     ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
6150
6151	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
6152	    bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
6153	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
6154	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
6155	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
6156	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
6157	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
6158	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
6159
6160
6161	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
6162		sdp->isp_devparam[tgt].dev_enable =
6163		    ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
6164		sdp->isp_devparam[tgt].exc_throttle =
6165			ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
6166		sdp->isp_devparam[tgt].nvrm_offset =
6167			ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
6168		sdp->isp_devparam[tgt].nvrm_period =
6169			ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
6170		sdp->isp_devparam[tgt].nvrm_flags = 0;
6171		if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
6172			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
6173		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
6174		if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
6175			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
6176		if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
6177			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
6178		if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
6179			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
6180		if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
6181			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
6182		if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
6183			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
6184		sdp->isp_devparam[tgt].actv_flags = 0;
6185		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
6186		    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
6187		    sdp->isp_devparam[tgt].nvrm_offset,
6188		    sdp->isp_devparam[tgt].nvrm_period);
6189		sdp->isp_devparam[tgt].goal_offset =
6190		    sdp->isp_devparam[tgt].nvrm_offset;
6191		sdp->isp_devparam[tgt].goal_period =
6192		    sdp->isp_devparam[tgt].nvrm_period;
6193		sdp->isp_devparam[tgt].goal_flags =
6194		    sdp->isp_devparam[tgt].nvrm_flags;
6195	}
6196}
6197
6198static void
6199isp_parse_nvram_12160(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
6200{
6201	sdparam *sdp = (sdparam *) isp->isp_param;
6202	int tgt;
6203
6204	sdp += bus;
6205
6206	sdp->isp_fifo_threshold =
6207	    ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
6208
6209	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
6210		sdp->isp_initiator_id =
6211		    ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
6212
6213	sdp->isp_bus_reset_delay =
6214	    ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
6215
6216	sdp->isp_retry_count =
6217	    ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
6218
6219	sdp->isp_retry_delay =
6220	    ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
6221
6222	sdp->isp_async_data_setup =
6223	    ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
6224
6225	sdp->isp_req_ack_active_neg =
6226	    ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
6227
6228	sdp->isp_data_line_active_neg =
6229	    ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
6230
6231	sdp->isp_data_dma_burst_enabl =
6232	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
6233
6234	sdp->isp_cmd_dma_burst_enable =
6235	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
6236
6237	sdp->isp_selection_timeout =
6238	    ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
6239
6240	sdp->isp_max_queue_depth =
6241	     ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
6242
6243	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
6244	    bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
6245	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
6246	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
6247	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
6248	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
6249	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
6250	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
6251
6252	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
6253		sdp->isp_devparam[tgt].dev_enable =
6254		    ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
6255		sdp->isp_devparam[tgt].exc_throttle =
6256			ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
6257		sdp->isp_devparam[tgt].nvrm_offset =
6258			ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
6259		sdp->isp_devparam[tgt].nvrm_period =
6260			ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
6261		sdp->isp_devparam[tgt].nvrm_flags = 0;
6262		if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
6263			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
6264		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
6265		if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
6266			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
6267		if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
6268			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
6269		if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
6270			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
6271		if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
6272			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
6273		if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
6274			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
6275		sdp->isp_devparam[tgt].actv_flags = 0;
6276		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
6277		    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
6278		    sdp->isp_devparam[tgt].nvrm_offset,
6279		    sdp->isp_devparam[tgt].nvrm_period);
6280		sdp->isp_devparam[tgt].goal_offset =
6281		    sdp->isp_devparam[tgt].nvrm_offset;
6282		sdp->isp_devparam[tgt].goal_period =
6283		    sdp->isp_devparam[tgt].nvrm_period;
6284		sdp->isp_devparam[tgt].goal_flags =
6285		    sdp->isp_devparam[tgt].nvrm_flags;
6286	}
6287}
6288
6289static void
6290isp_parse_nvram_2100(struct ispsoftc *isp, u_int8_t *nvram_data)
6291{
6292	fcparam *fcp = (fcparam *) isp->isp_param;
6293	u_int64_t wwn;
6294
6295	/*
6296	 * There is NVRAM storage for both Port and Node entities-
6297	 * but the Node entity appears to be unused on all the cards
6298	 * I can find. However, we should account for this being set
6299	 * at some point in the future.
6300	 *
6301	 * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
6302	 * bits 48..60. In the case of the 2202, it appears that they do
6303	 * use bit 48 to distinguish between the two instances on the card.
6304	 * The 2204, which I've never seen, *probably* extends this method.
6305	 */
6306	wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
6307	if (wwn) {
6308		isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
6309		    (u_int32_t) (wwn >> 32), (u_int32_t) (wwn & 0xffffffff));
6310		if ((wwn >> 60) == 0) {
6311			wwn |= (((u_int64_t) 2)<< 60);
6312		}
6313	}
6314	fcp->isp_portwwn = wwn;
6315	if (IS_2200(isp) || IS_23XX(isp)) {
6316		wwn = ISP2200_NVRAM_NODE_NAME(nvram_data);
6317		if (wwn) {
6318			isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
6319			    (u_int32_t) (wwn >> 32),
6320			    (u_int32_t) (wwn & 0xffffffff));
6321			if ((wwn >> 60) == 0) {
6322				wwn |= (((u_int64_t) 2)<< 60);
6323			}
6324		}
6325	} else {
6326		wwn &= ~((u_int64_t) 0xfff << 48);
6327	}
6328	fcp->isp_nodewwn = wwn;
6329
6330	/*
6331	 * Make sure we have both Node and Port as non-zero values.
6332	 */
6333	if (fcp->isp_nodewwn != 0 && fcp->isp_portwwn == 0) {
6334		fcp->isp_portwwn = fcp->isp_nodewwn;
6335	} else if (fcp->isp_nodewwn == 0 && fcp->isp_portwwn != 0) {
6336		fcp->isp_nodewwn = fcp->isp_portwwn;
6337	}
6338
6339	/*
6340	 * Make the Node and Port values sane if they're NAA == 2.
6341	 * This means to clear bits 48..56 for the Node WWN and
6342	 * make sure that there's some non-zero value in 48..56
6343	 * for the Port WWN.
6344	 */
6345	if (fcp->isp_nodewwn && fcp->isp_portwwn) {
6346		if ((fcp->isp_nodewwn & (((u_int64_t) 0xfff) << 48)) != 0 &&
6347		    (fcp->isp_nodewwn >> 60) == 2) {
6348			fcp->isp_nodewwn &= ~((u_int64_t) 0xfff << 48);
6349		}
6350		if ((fcp->isp_portwwn & (((u_int64_t) 0xfff) << 48)) == 0 &&
6351		    (fcp->isp_portwwn >> 60) == 2) {
6352			fcp->isp_portwwn |= ((u_int64_t) 1 << 56);
6353		}
6354	}
6355
6356	isp_prt(isp, ISP_LOGDEBUG0,
6357	    "NVRAM: maxfrmlen %d execthrottle %d fwoptions 0x%x loopid %x",
6358	    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data),
6359	    ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
6360	    ISP2100_NVRAM_OPTIONS(nvram_data),
6361	    ISP2100_NVRAM_HARDLOOPID(nvram_data));
6362
6363	fcp->isp_maxalloc =
6364		ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
6365	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0)
6366		fcp->isp_maxfrmlen =
6367			ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
6368	fcp->isp_retry_delay =
6369		ISP2100_NVRAM_RETRY_DELAY(nvram_data);
6370	fcp->isp_retry_count =
6371		ISP2100_NVRAM_RETRY_COUNT(nvram_data);
6372	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
6373		fcp->isp_loopid =
6374			ISP2100_NVRAM_HARDLOOPID(nvram_data);
6375	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0)
6376		fcp->isp_execthrottle =
6377			ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
6378	fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
6379}
6380
6381#ifdef	ISP_FW_CRASH_DUMP
6382static void isp2200_fw_dump(struct ispsoftc *);
6383static void isp2300_fw_dump(struct ispsoftc *);
6384
6385static void
6386isp2200_fw_dump(struct ispsoftc *isp)
6387{
6388	int i, j;
6389	mbreg_t mbs;
6390	u_int16_t *ptr;
6391
6392	ptr = FCPARAM(isp)->isp_dump_data;
6393	if (ptr == NULL) {
6394		isp_prt(isp, ISP_LOGERR,
6395		   "No place to dump RISC registers and SRAM");
6396		return;
6397	}
6398	if (*ptr++) {
6399		isp_prt(isp, ISP_LOGERR,
6400		   "dump area for RISC registers and SRAM already used");
6401		return;
6402	}
6403	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
6404	for (i = 0; i < 100; i++) {
6405		USEC_DELAY(100);
6406		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
6407			break;
6408		}
6409	}
6410	if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
6411		/*
6412		 * PBIU Registers
6413		 */
6414		for (i = 0; i < 8; i++) {
6415			*ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
6416		}
6417
6418		/*
6419		 * Mailbox Registers
6420		 */
6421		for (i = 0; i < 8; i++) {
6422			*ptr++ = ISP_READ(isp, MBOX_BLOCK + (i << 1));
6423		}
6424
6425		/*
6426		 * DMA Registers
6427		 */
6428		for (i = 0; i < 48; i++) {
6429			*ptr++ = ISP_READ(isp, DMA_BLOCK + 0x20 + (i << 1));
6430		}
6431
6432		/*
6433		 * RISC H/W Registers
6434		 */
6435		ISP_WRITE(isp, BIU2100_CSR, 0);
6436		for (i = 0; i < 16; i++) {
6437			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
6438		}
6439
6440		/*
6441		 * RISC GP Registers
6442		 */
6443		for (j = 0; j < 8; j++) {
6444			ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 8));
6445			for (i = 0; i < 16; i++) {
6446				*ptr++ =
6447				    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6448			}
6449		}
6450
6451		/*
6452		 * Frame Buffer Hardware Registers
6453		 */
6454		ISP_WRITE(isp, BIU2100_CSR, 0x10);
6455		for (i = 0; i < 16; i++) {
6456			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6457		}
6458
6459		/*
6460		 * Fibre Protocol Module 0 Hardware Registers
6461		 */
6462		ISP_WRITE(isp, BIU2100_CSR, 0x20);
6463		for (i = 0; i < 64; i++) {
6464			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6465		}
6466
6467		/*
6468		 * Fibre Protocol Module 1 Hardware Registers
6469		 */
6470		ISP_WRITE(isp, BIU2100_CSR, 0x30);
6471		for (i = 0; i < 64; i++) {
6472			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6473		}
6474	} else {
6475		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
6476		return;
6477	}
6478	isp_prt(isp, ISP_LOGALL,
6479	   "isp_fw_dump: RISC registers dumped successfully");
6480	ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
6481	for (i = 0; i < 100; i++) {
6482		USEC_DELAY(100);
6483		if (ISP_READ(isp, OUTMAILBOX0) == 0) {
6484			break;
6485		}
6486	}
6487	if (ISP_READ(isp, OUTMAILBOX0) != 0) {
6488		isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
6489		return;
6490	}
6491	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
6492	for (i = 0; i < 100; i++) {
6493		USEC_DELAY(100);
6494		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
6495			break;
6496		}
6497	}
6498	if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
6499		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause After Reset");
6500		return;
6501	}
6502	ISP_WRITE(isp, RISC_EMB, 0xf2);
6503	ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
6504	for (i = 0; i < 100; i++) {
6505		USEC_DELAY(100);
6506		if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
6507			break;
6508		}
6509	}
6510	ENABLE_INTS(isp);
6511	mbs.param[0] = MBOX_READ_RAM_WORD;
6512	mbs.param[1] = 0x1000;
6513	isp->isp_mbxworkp = (void *) ptr;
6514	isp->isp_mbxwrk0 = 0xefff;	/* continuation count */
6515	isp->isp_mbxwrk1 = 0x1001;	/* next SRAM address */
6516	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
6517	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
6518		isp_prt(isp, ISP_LOGWARN,
6519		    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
6520		return;
6521	}
6522	ptr = isp->isp_mbxworkp;	/* finish fetch of final word */
6523	*ptr++ = isp->isp_mboxtmp[2];
6524	isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped succesfully");
6525	FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
6526	(void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
6527}
6528
6529static void
6530isp2300_fw_dump(struct ispsoftc *isp)
6531{
6532	int i, j;
6533	mbreg_t mbs;
6534	u_int16_t *ptr;
6535
6536	ptr = FCPARAM(isp)->isp_dump_data;
6537	if (ptr == NULL) {
6538		isp_prt(isp, ISP_LOGERR,
6539		   "No place to dump RISC registers and SRAM");
6540		return;
6541	}
6542	if (*ptr++) {
6543		isp_prt(isp, ISP_LOGERR,
6544		   "dump area for RISC registers and SRAM already used");
6545		return;
6546	}
6547	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
6548	for (i = 0; i < 100; i++) {
6549		USEC_DELAY(100);
6550		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
6551			break;
6552		}
6553	}
6554	if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
6555		/*
6556		 * PBIU registers
6557		 */
6558		for (i = 0; i < 8; i++) {
6559			*ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
6560		}
6561
6562		/*
6563		 * ReqQ-RspQ-Risc2Host Status registers
6564		 */
6565		for (i = 0; i < 8; i++) {
6566			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x10 + (i << 1));
6567		}
6568
6569		/*
6570		 * Mailbox Registers
6571		 */
6572		for (i = 0; i < 32; i++) {
6573			*ptr++ =
6574			    ISP_READ(isp, PCI_MBOX_REGS2300_OFF + (i << 1));
6575		}
6576
6577		/*
6578		 * Auto Request Response DMA registers
6579		 */
6580		ISP_WRITE(isp, BIU2100_CSR, 0x40);
6581		for (i = 0; i < 32; i++) {
6582			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6583		}
6584
6585		/*
6586		 * DMA registers
6587		 */
6588		ISP_WRITE(isp, BIU2100_CSR, 0x50);
6589		for (i = 0; i < 48; i++) {
6590			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6591		}
6592
6593		/*
6594		 * RISC hardware registers
6595		 */
6596		ISP_WRITE(isp, BIU2100_CSR, 0);
6597		for (i = 0; i < 16; i++) {
6598			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
6599		}
6600
6601		/*
6602		 * RISC GP? registers
6603		 */
6604		for (j = 0; j < 8; j++) {
6605			ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 9));
6606			for (i = 0; i < 16; i++) {
6607				*ptr++ =
6608				    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6609			}
6610		}
6611
6612		/*
6613		 * frame buffer hardware registers
6614		 */
6615		ISP_WRITE(isp, BIU2100_CSR, 0x10);
6616		for (i = 0; i < 64; i++) {
6617			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6618		}
6619
6620		/*
6621		 * FPM B0 hardware registers
6622		 */
6623		ISP_WRITE(isp, BIU2100_CSR, 0x20);
6624		for (i = 0; i < 64; i++) {
6625			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6626		}
6627
6628		/*
6629		 * FPM B1 hardware registers
6630		 */
6631		ISP_WRITE(isp, BIU2100_CSR, 0x30);
6632		for (i = 0; i < 64; i++) {
6633			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
6634		}
6635	} else {
6636		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
6637		return;
6638	}
6639	isp_prt(isp, ISP_LOGALL,
6640	   "isp_fw_dump: RISC registers dumped successfully");
6641	ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
6642	for (i = 0; i < 100; i++) {
6643		USEC_DELAY(100);
6644		if (ISP_READ(isp, OUTMAILBOX0) == 0) {
6645			break;
6646		}
6647	}
6648	if (ISP_READ(isp, OUTMAILBOX0) != 0) {
6649		isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
6650		return;
6651	}
6652	ENABLE_INTS(isp);
6653	mbs.param[0] = MBOX_READ_RAM_WORD;
6654	mbs.param[1] = 0x800;
6655	isp->isp_mbxworkp = (void *) ptr;
6656	isp->isp_mbxwrk0 = 0xf7ff;	/* continuation count */
6657	isp->isp_mbxwrk1 = 0x801;	/* next SRAM address */
6658	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
6659	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
6660		isp_prt(isp, ISP_LOGWARN,
6661		    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
6662		return;
6663	}
6664	ptr = isp->isp_mbxworkp;	/* finish fetch of final word */
6665	*ptr++ = isp->isp_mboxtmp[2];
6666
6667	/*
6668	 * We don't have access to mailbox registers 8.. onward
6669	 * in our 'common' device model- so we have to set it
6670	 * here and hope it stays the same!
6671	 */
6672	ISP_WRITE(isp, PCI_MBOX_REGS2300_OFF + (8 << 1), 0x1);
6673
6674	mbs.param[0] = MBOX_READ_RAM_WORD_EXTENDED;
6675	mbs.param[1] = 0;
6676	isp->isp_mbxworkp = (void *) ptr;
6677	isp->isp_mbxwrk0 = 0xffff;	/* continuation count */
6678	isp->isp_mbxwrk1 = 0x1;		/* next SRAM address */
6679	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
6680	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
6681		isp_prt(isp, ISP_LOGWARN,
6682		    "RAM DUMP FAILED @ WORD %x", 0x10000 + isp->isp_mbxwrk1);
6683		return;
6684	}
6685	ptr = isp->isp_mbxworkp;	/* finish final word */
6686	*ptr++ = mbs.param[2];
6687	isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped succesfully");
6688	FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
6689	(void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
6690}
6691
6692void
6693isp_fw_dump(struct ispsoftc *isp)
6694{
6695	if (IS_2200(isp))
6696		isp2200_fw_dump(isp);
6697	else if (IS_23XX(isp))
6698		isp2300_fw_dump(isp);
6699}
6700#endif
6701