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