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