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