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