xref: /freebsd/sys/dev/isp/isp.c (revision 94942af266ac119ede0ca836f9aa5a5ac0582938)
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 		/*
5125 		 * It's up to the handler for isp_async to reinit stuff and
5126 		 * restart the firmware
5127 		 */
5128 		isp_async(isp, ISPASYNC_FW_CRASH, NULL);
5129 		rval = -1;
5130 		break;
5131 
5132 	case ASYNC_RQS_XFER_ERR:
5133 		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
5134 		break;
5135 
5136 	case ASYNC_RSP_XFER_ERR:
5137 		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
5138 		break;
5139 
5140 	case ASYNC_QWAKEUP:
5141 		/*
5142 		 * We've just been notified that the Queue has woken up.
5143 		 * We don't need to be chatty about this- just unlatch things
5144 		 * and move on.
5145 		 */
5146 		mbox = ISP_READ(isp, isp->isp_rqstoutrp);
5147 		break;
5148 
5149 	case ASYNC_TIMEOUT_RESET:
5150 		isp_prt(isp, ISP_LOGWARN,
5151 		    "timeout initiated SCSI bus reset of bus %d", bus);
5152 		isp->isp_sendmarker |= (1 << bus);
5153 #ifdef	ISP_TARGET_MODE
5154 		if (isp_target_async(isp, bus, mbox)) {
5155 			rval = -1;
5156 		}
5157 #endif
5158 		break;
5159 
5160 	case ASYNC_DEVICE_RESET:
5161 		isp_prt(isp, ISP_LOGINFO, "device reset on bus %d", bus);
5162 		isp->isp_sendmarker |= (1 << bus);
5163 #ifdef	ISP_TARGET_MODE
5164 		if (isp_target_async(isp, bus, mbox)) {
5165 			rval = -1;
5166 		}
5167 #endif
5168 		break;
5169 
5170 	case ASYNC_EXTMSG_UNDERRUN:
5171 		isp_prt(isp, ISP_LOGWARN, "extended message underrun");
5172 		break;
5173 
5174 	case ASYNC_SCAM_INT:
5175 		isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
5176 		break;
5177 
5178 	case ASYNC_HUNG_SCSI:
5179 		isp_prt(isp, ISP_LOGERR,
5180 		    "stalled SCSI Bus after DATA Overrun");
5181 		/* XXX: Need to issue SCSI reset at this point */
5182 		break;
5183 
5184 	case ASYNC_KILLED_BUS:
5185 		isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
5186 		break;
5187 
5188 	case ASYNC_BUS_TRANSIT:
5189 		mbox = ISP_READ(isp, OUTMAILBOX2);
5190 		switch (mbox & 0x1c00) {
5191 		case SXP_PINS_LVD_MODE:
5192 			isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
5193 			SDPARAM(isp)->isp_diffmode = 0;
5194 			SDPARAM(isp)->isp_ultramode = 0;
5195 			SDPARAM(isp)->isp_lvdmode = 1;
5196 			break;
5197 		case SXP_PINS_HVD_MODE:
5198 			isp_prt(isp, ISP_LOGINFO,
5199 			    "Transition to Differential mode");
5200 			SDPARAM(isp)->isp_diffmode = 1;
5201 			SDPARAM(isp)->isp_ultramode = 0;
5202 			SDPARAM(isp)->isp_lvdmode = 0;
5203 			break;
5204 		case SXP_PINS_SE_MODE:
5205 			isp_prt(isp, ISP_LOGINFO,
5206 			    "Transition to Single Ended mode");
5207 			SDPARAM(isp)->isp_diffmode = 0;
5208 			SDPARAM(isp)->isp_ultramode = 1;
5209 			SDPARAM(isp)->isp_lvdmode = 0;
5210 			break;
5211 		default:
5212 			isp_prt(isp, ISP_LOGWARN,
5213 			    "Transition to Unknown Mode 0x%x", mbox);
5214 			break;
5215 		}
5216 		/*
5217 		 * XXX: Set up to renegotiate again!
5218 		 */
5219 		/* Can only be for a 1080... */
5220 		isp->isp_sendmarker |= (1 << bus);
5221 		break;
5222 
5223 	/*
5224 	 * We can use bus, which will always be zero for FC cards,
5225 	 * as a mailbox pattern accumulator to be checked below.
5226 	 */
5227 	case ASYNC_RIO5:
5228 		bus = 0x1ce;	/* outgoing mailbox regs 1-3, 6-7 */
5229 		break;
5230 
5231 	case ASYNC_RIO4:
5232 		bus = 0x14e;	/* outgoing mailbox regs 1-3, 6 */
5233 		break;
5234 
5235 	case ASYNC_RIO3:
5236 		bus = 0x10e;	/* outgoing mailbox regs 1-3 */
5237 		break;
5238 
5239 	case ASYNC_RIO2:
5240 		bus = 0x106;	/* outgoing mailbox regs 1-2 */
5241 		break;
5242 
5243 	case ASYNC_RIO1:
5244 	case ASYNC_CMD_CMPLT:
5245 		bus = 0x102;	/* outgoing mailbox regs 1 */
5246 		break;
5247 
5248 	case ASYNC_RIO_RESP:
5249 		return (rval);
5250 
5251 	case ASYNC_CTIO_DONE:
5252 	{
5253 #ifdef	ISP_TARGET_MODE
5254 		int handle =
5255 		    (ISP_READ(isp, OUTMAILBOX2) << 16) |
5256 		    (ISP_READ(isp, OUTMAILBOX1));
5257 		if (isp_target_async(isp, handle, mbox)) {
5258 			rval = -1;
5259 		} else {
5260 			/* count it as a fast posting intr */
5261 			isp->isp_fphccmplt++;
5262 		}
5263 #else
5264 		isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
5265 		isp->isp_fphccmplt++;	/* count it as a fast posting intr */
5266 #endif
5267 		break;
5268 	}
5269 	case ASYNC_LIP_ERROR:
5270 	case ASYNC_LIP_F8:
5271 	case ASYNC_LIP_OCCURRED:
5272 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
5273 		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
5274 		isp->isp_sendmarker = 1;
5275 		ISP_MARK_PORTDB(isp, 1);
5276 		isp_async(isp, ISPASYNC_LIP, NULL);
5277 #ifdef	ISP_TARGET_MODE
5278 		if (isp_target_async(isp, bus, mbox)) {
5279 			rval = -1;
5280 		}
5281 #endif
5282 		/*
5283 		 * We've had problems with data corruption occuring on
5284 		 * commands that complete (with no apparent error) after
5285 		 * we receive a LIP. This has been observed mostly on
5286 		 * Local Loop topologies. To be safe, let's just mark
5287 		 * all active commands as dead.
5288 		 */
5289 		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
5290 		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
5291 			int i, j;
5292 			for (i = j = 0; i < isp->isp_maxcmds; i++) {
5293 				XS_T *xs;
5294 				xs = isp->isp_xflist[i];
5295 				if (xs != NULL) {
5296 					j++;
5297 					XS_SETERR(xs, HBA_BUSRESET);
5298 				}
5299 			}
5300 			if (j) {
5301 				isp_prt(isp, ISP_LOGERR,
5302 				    "LIP destroyed %d active commands", j);
5303 			}
5304 		}
5305 		break;
5306 
5307 	case ASYNC_LOOP_UP:
5308 		isp->isp_sendmarker = 1;
5309 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
5310 		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
5311 		ISP_MARK_PORTDB(isp, 1);
5312 		isp_async(isp, ISPASYNC_LOOP_UP, NULL);
5313 #ifdef	ISP_TARGET_MODE
5314 		if (isp_target_async(isp, bus, mbox)) {
5315 			rval = -1;
5316 		}
5317 #endif
5318 		break;
5319 
5320 	case ASYNC_LOOP_DOWN:
5321 		isp->isp_sendmarker = 1;
5322 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
5323 		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
5324 		ISP_MARK_PORTDB(isp, 1);
5325 		isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
5326 #ifdef	ISP_TARGET_MODE
5327 		if (isp_target_async(isp, bus, mbox)) {
5328 			rval = -1;
5329 		}
5330 #endif
5331 		break;
5332 
5333 	case ASYNC_LOOP_RESET:
5334 		isp->isp_sendmarker = 1;
5335 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
5336 		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
5337 		ISP_MARK_PORTDB(isp, 1);
5338 		isp_async(isp, ISPASYNC_LOOP_RESET, NULL);
5339 #ifdef	ISP_TARGET_MODE
5340 		if (isp_target_async(isp, bus, mbox)) {
5341 			rval = -1;
5342 		}
5343 #endif
5344 		break;
5345 
5346 	case ASYNC_PDB_CHANGED:
5347 		isp->isp_sendmarker = 1;
5348 		FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
5349 		ISP_MARK_PORTDB(isp, 1);
5350 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_PDB);
5351 		break;
5352 
5353 	case ASYNC_CHANGE_NOTIFY:
5354 	    	if (FCPARAM(isp)->isp_topo == TOPO_F_PORT) {
5355 			FCPARAM(isp)->isp_loopstate = LOOP_LSCAN_DONE;
5356 		} else {
5357 			FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
5358 		}
5359 		ISP_MARK_PORTDB(isp, 1);
5360 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_SNS);
5361 		break;
5362 
5363 	case ASYNC_PTPMODE:
5364 		ISP_MARK_PORTDB(isp, 1);
5365 		isp->isp_sendmarker = 1;
5366 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
5367 		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
5368 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
5369 #ifdef	ISP_TARGET_MODE
5370 		if (isp_target_async(isp, bus, mbox)) {
5371 			rval = -1;
5372 		}
5373 #endif
5374 		isp_prt(isp, ISP_LOGINFO, "Point-to-Point mode");
5375 		break;
5376 
5377 	case ASYNC_CONNMODE:
5378 		mbox = ISP_READ(isp, OUTMAILBOX1);
5379 		ISP_MARK_PORTDB(isp, 1);
5380 		switch (mbox) {
5381 		case ISP_CONN_LOOP:
5382 			isp_prt(isp, ISP_LOGINFO,
5383 			    "Point-to-Point -> Loop mode");
5384 			break;
5385 		case ISP_CONN_PTP:
5386 			isp_prt(isp, ISP_LOGINFO,
5387 			    "Loop -> Point-to-Point mode");
5388 			break;
5389 		case ISP_CONN_BADLIP:
5390 			isp_prt(isp, ISP_LOGWARN,
5391 			    "Point-to-Point -> Loop mode (BAD LIP)");
5392 			break;
5393 		case ISP_CONN_FATAL:
5394 			isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
5395 			isp_async(isp, ISPASYNC_FW_CRASH, NULL);
5396 			return (-1);
5397 		case ISP_CONN_LOOPBACK:
5398 			isp_prt(isp, ISP_LOGWARN,
5399 			    "Looped Back in Point-to-Point mode");
5400 			break;
5401 		default:
5402 			isp_prt(isp, ISP_LOGWARN,
5403 			    "Unknown connection mode (0x%x)", mbox);
5404 			break;
5405 		}
5406 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
5407 		isp->isp_sendmarker = 1;
5408 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
5409 		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
5410 		break;
5411 
5412 	case ASYNC_RJT_SENT:	/* same as ASYNC_QFULL_SENT */
5413 		if (IS_24XX(isp)) {
5414 			isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
5415 			break;
5416 		} else if (IS_2200(isp)) {
5417 			isp_prt(isp, ISP_LOGTDEBUG0, "QFULL sent");
5418 			break;
5419 		}
5420 		/* FALLTHROUGH */
5421 	default:
5422 		isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
5423 		break;
5424 	}
5425 
5426 	if (bus & 0x100) {
5427 		int i, nh;
5428 		uint16_t handles[16];
5429 
5430 		for (nh = 0, i = 1; i < MAX_MAILBOX(isp); i++) {
5431 			if ((bus & (1 << i)) == 0) {
5432 				continue;
5433 			}
5434 			handles[nh++] = ISP_READ(isp, MBOX_OFF(i));
5435 		}
5436 		for (i = 0; i < nh; i++) {
5437 			isp_fastpost_complete(isp, handles[i]);
5438 			isp_prt(isp,  ISP_LOGDEBUG3,
5439 			    "fast post completion of %u", handles[i]);
5440 		}
5441 		if (isp->isp_fpcchiwater < nh) {
5442 			isp->isp_fpcchiwater = nh;
5443 		}
5444 	} else {
5445 		isp->isp_intoasync++;
5446 	}
5447 	return (rval);
5448 }
5449 
5450 /*
5451  * Handle other response entries. A pointer to the request queue output
5452  * index is here in case we want to eat several entries at once, although
5453  * this is not used currently.
5454  */
5455 
5456 static int
5457 isp_handle_other_response(ispsoftc_t *isp, int type,
5458     isphdr_t *hp, uint32_t *optrp)
5459 {
5460 	switch (type) {
5461 	case RQSTYPE_STATUS_CONT:
5462 		isp_prt(isp, ISP_LOGDEBUG0, "Ignored Continuation Response");
5463 		return (1);
5464 	case RQSTYPE_MARKER:
5465 		isp_prt(isp, ISP_LOGDEBUG0, "Marker Response");
5466 		return (1);
5467 	case RQSTYPE_ATIO:
5468 	case RQSTYPE_CTIO:
5469 	case RQSTYPE_ENABLE_LUN:
5470 	case RQSTYPE_MODIFY_LUN:
5471 	case RQSTYPE_NOTIFY:
5472 	case RQSTYPE_NOTIFY_ACK:
5473 	case RQSTYPE_CTIO1:
5474 	case RQSTYPE_ATIO2:
5475 	case RQSTYPE_CTIO2:
5476 	case RQSTYPE_CTIO3:
5477 	case RQSTYPE_CTIO7:
5478 	case RQSTYPE_ABTS_RCVD:
5479 	case RQSTYPE_ABTS_RSP:
5480 		isp->isp_rsltccmplt++;	/* count as a response completion */
5481 #ifdef	ISP_TARGET_MODE
5482 		if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
5483 			return (1);
5484 		}
5485 #endif
5486 		/* FALLTHROUGH */
5487 	case RQSTYPE_REQUEST:
5488 	default:
5489 		USEC_DELAY(100);
5490 		if (type != isp_get_response_type(isp, hp)) {
5491 			/*
5492 			 * This is questionable- we're just papering over
5493 			 * something we've seen on SMP linux in target
5494 			 * mode- we don't really know what's happening
5495 			 * here that causes us to think we've gotten
5496 			 * an entry, but that either the entry isn't
5497 			 * filled out yet or our CPU read data is stale.
5498 			 */
5499 			isp_prt(isp, ISP_LOGINFO,
5500 				"unstable type in response queue");
5501 			return (-1);
5502 		}
5503 		isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
5504 		    isp_get_response_type(isp, hp));
5505 		if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) {
5506 			return (1);
5507 		}
5508 		return (0);
5509 	}
5510 }
5511 
5512 static void
5513 isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
5514 {
5515 	switch (sp->req_completion_status & 0xff) {
5516 	case RQCS_COMPLETE:
5517 		if (XS_NOERR(xs)) {
5518 			XS_SETERR(xs, HBA_NOERROR);
5519 		}
5520 		return;
5521 
5522 	case RQCS_INCOMPLETE:
5523 		if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
5524 			isp_prt(isp, ISP_LOGDEBUG1,
5525 			    "Selection Timeout for %d.%d.%d",
5526 			    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5527 			if (XS_NOERR(xs)) {
5528 				XS_SETERR(xs, HBA_SELTIMEOUT);
5529 				*rp = XS_XFRLEN(xs);
5530 			}
5531 			return;
5532 		}
5533 		isp_prt(isp, ISP_LOGERR,
5534 		    "command incomplete for %d.%d.%d, state 0x%x",
5535 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
5536 		    sp->req_state_flags);
5537 		break;
5538 
5539 	case RQCS_DMA_ERROR:
5540 		isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
5541 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5542 		*rp = XS_XFRLEN(xs);
5543 		break;
5544 
5545 	case RQCS_TRANSPORT_ERROR:
5546 	{
5547 		char buf[172];
5548 		SNPRINTF(buf, sizeof (buf), "states=>");
5549 		if (sp->req_state_flags & RQSF_GOT_BUS) {
5550 			SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
5551 		}
5552 		if (sp->req_state_flags & RQSF_GOT_TARGET) {
5553 			SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
5554 		}
5555 		if (sp->req_state_flags & RQSF_SENT_CDB) {
5556 			SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
5557 		}
5558 		if (sp->req_state_flags & RQSF_XFRD_DATA) {
5559 			SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
5560 		}
5561 		if (sp->req_state_flags & RQSF_GOT_STATUS) {
5562 			SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
5563 		}
5564 		if (sp->req_state_flags & RQSF_GOT_SENSE) {
5565 			SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
5566 		}
5567 		if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
5568 			SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
5569 		}
5570 		SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
5571 		if (sp->req_status_flags & RQSTF_DISCONNECT) {
5572 			SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
5573 		}
5574 		if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
5575 			SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
5576 		}
5577 		if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
5578 			SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
5579 		}
5580 		if (sp->req_status_flags & RQSTF_BUS_RESET) {
5581 			SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
5582 		}
5583 		if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
5584 			SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
5585 		}
5586 		if (sp->req_status_flags & RQSTF_ABORTED) {
5587 			SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
5588 		}
5589 		if (sp->req_status_flags & RQSTF_TIMEOUT) {
5590 			SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
5591 		}
5592 		if (sp->req_status_flags & RQSTF_NEGOTIATION) {
5593 			SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
5594 		}
5595 		isp_prt(isp, ISP_LOGERR, "%s", buf);
5596 		isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
5597 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf);
5598 		*rp = XS_XFRLEN(xs);
5599 		break;
5600 	}
5601 	case RQCS_RESET_OCCURRED:
5602 		isp_prt(isp, ISP_LOGWARN,
5603 		    "bus reset destroyed command for %d.%d.%d",
5604 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5605 		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
5606 		if (XS_NOERR(xs)) {
5607 			XS_SETERR(xs, HBA_BUSRESET);
5608 		}
5609 		*rp = XS_XFRLEN(xs);
5610 		return;
5611 
5612 	case RQCS_ABORTED:
5613 		isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
5614 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5615 		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
5616 		if (XS_NOERR(xs)) {
5617 			XS_SETERR(xs, HBA_ABORTED);
5618 		}
5619 		return;
5620 
5621 	case RQCS_TIMEOUT:
5622 		isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
5623 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5624 		/*
5625 	 	 * XXX: Check to see if we logged out of the device.
5626 		 */
5627 		if (XS_NOERR(xs)) {
5628 			XS_SETERR(xs, HBA_CMDTIMEOUT);
5629 		}
5630 		return;
5631 
5632 	case RQCS_DATA_OVERRUN:
5633 		XS_RESID(xs) = sp->req_resid;
5634 		isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d",
5635 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5636 		if (XS_NOERR(xs)) {
5637 			XS_SETERR(xs, HBA_DATAOVR);
5638 		}
5639 		return;
5640 
5641 	case RQCS_COMMAND_OVERRUN:
5642 		isp_prt(isp, ISP_LOGERR,
5643 		    "command overrun for command on %d.%d.%d",
5644 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5645 		break;
5646 
5647 	case RQCS_STATUS_OVERRUN:
5648 		isp_prt(isp, ISP_LOGERR,
5649 		    "status overrun for command on %d.%d.%d",
5650 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5651 		break;
5652 
5653 	case RQCS_BAD_MESSAGE:
5654 		isp_prt(isp, ISP_LOGERR,
5655 		    "msg not COMMAND COMPLETE after status %d.%d.%d",
5656 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5657 		break;
5658 
5659 	case RQCS_NO_MESSAGE_OUT:
5660 		isp_prt(isp, ISP_LOGERR,
5661 		    "No MESSAGE OUT phase after selection on %d.%d.%d",
5662 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5663 		break;
5664 
5665 	case RQCS_EXT_ID_FAILED:
5666 		isp_prt(isp, ISP_LOGERR, "EXTENDED IDENTIFY failed %d.%d.%d",
5667 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5668 		break;
5669 
5670 	case RQCS_IDE_MSG_FAILED:
5671 		isp_prt(isp, ISP_LOGERR,
5672 		    "INITIATOR DETECTED ERROR rejected by %d.%d.%d",
5673 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5674 		break;
5675 
5676 	case RQCS_ABORT_MSG_FAILED:
5677 		isp_prt(isp, ISP_LOGERR, "ABORT OPERATION rejected by %d.%d.%d",
5678 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5679 		break;
5680 
5681 	case RQCS_REJECT_MSG_FAILED:
5682 		isp_prt(isp, ISP_LOGERR, "MESSAGE REJECT rejected by %d.%d.%d",
5683 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5684 		break;
5685 
5686 	case RQCS_NOP_MSG_FAILED:
5687 		isp_prt(isp, ISP_LOGERR, "NOP rejected by %d.%d.%d",
5688 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5689 		break;
5690 
5691 	case RQCS_PARITY_ERROR_MSG_FAILED:
5692 		isp_prt(isp, ISP_LOGERR,
5693 		    "MESSAGE PARITY ERROR rejected by %d.%d.%d",
5694 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5695 		break;
5696 
5697 	case RQCS_DEVICE_RESET_MSG_FAILED:
5698 		isp_prt(isp, ISP_LOGWARN,
5699 		    "BUS DEVICE RESET rejected by %d.%d.%d",
5700 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5701 		break;
5702 
5703 	case RQCS_ID_MSG_FAILED:
5704 		isp_prt(isp, ISP_LOGERR, "IDENTIFY rejected by %d.%d.%d",
5705 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5706 		break;
5707 
5708 	case RQCS_UNEXP_BUS_FREE:
5709 		isp_prt(isp, ISP_LOGERR, "%d.%d.%d had an unexpected bus free",
5710 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5711 		break;
5712 
5713 	case RQCS_DATA_UNDERRUN:
5714 	{
5715 		if (IS_FC(isp)) {
5716 			int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
5717 			if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
5718 				isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
5719 				    XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
5720 				    (ru_marked)? "marked" : "not marked");
5721 				if (XS_NOERR(xs)) {
5722 					XS_SETERR(xs, HBA_BOTCH);
5723 				}
5724 				return;
5725 			}
5726 		}
5727 		XS_RESID(xs) = sp->req_resid;
5728 		if (XS_NOERR(xs)) {
5729 			XS_SETERR(xs, HBA_NOERROR);
5730 		}
5731 		return;
5732 	}
5733 
5734 	case RQCS_XACT_ERR1:
5735 		isp_prt(isp, ISP_LOGERR, xact1, XS_CHANNEL(xs),
5736 		    XS_TGT(xs), XS_LUN(xs));
5737 		break;
5738 
5739 	case RQCS_XACT_ERR2:
5740 		isp_prt(isp, ISP_LOGERR, xact2,
5741 		    XS_LUN(xs), XS_TGT(xs), XS_CHANNEL(xs));
5742 		break;
5743 
5744 	case RQCS_XACT_ERR3:
5745 		isp_prt(isp, ISP_LOGERR, xact3,
5746 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5747 		break;
5748 
5749 	case RQCS_BAD_ENTRY:
5750 		isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
5751 		break;
5752 
5753 	case RQCS_QUEUE_FULL:
5754 		isp_prt(isp, ISP_LOGDEBUG0,
5755 		    "internal queues full for %d.%d.%d status 0x%x",
5756 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), *XS_STSP(xs));
5757 
5758 		/*
5759 		 * If QFULL or some other status byte is set, then this
5760 		 * isn't an error, per se.
5761 		 *
5762 		 * Unfortunately, some QLogic f/w writers have, in
5763 		 * some cases, ommitted to *set* status to QFULL.
5764 		 *
5765 
5766 		if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
5767 			XS_SETERR(xs, HBA_NOERROR);
5768 			return;
5769 		}
5770 
5771 		 *
5772 		 *
5773 		 */
5774 
5775 		*XS_STSP(xs) = SCSI_QFULL;
5776 		XS_SETERR(xs, HBA_NOERROR);
5777 		return;
5778 
5779 	case RQCS_PHASE_SKIPPED:
5780 		isp_prt(isp, ISP_LOGERR, pskip, XS_CHANNEL(xs),
5781 		    XS_TGT(xs), XS_LUN(xs));
5782 		break;
5783 
5784 	case RQCS_ARQS_FAILED:
5785 		isp_prt(isp, ISP_LOGERR,
5786 		    "Auto Request Sense failed for %d.%d.%d",
5787 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5788 		if (XS_NOERR(xs)) {
5789 			XS_SETERR(xs, HBA_ARQFAIL);
5790 		}
5791 		return;
5792 
5793 	case RQCS_WIDE_FAILED:
5794 		isp_prt(isp, ISP_LOGERR,
5795 		    "Wide Negotiation failed for %d.%d.%d",
5796 		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
5797 		if (IS_SCSI(isp)) {
5798 			sdparam *sdp = isp->isp_param;
5799 			sdp += XS_CHANNEL(xs);
5800 			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
5801 			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
5802 			isp->isp_update |= (1 << XS_CHANNEL(xs));
5803 		}
5804 		if (XS_NOERR(xs)) {
5805 			XS_SETERR(xs, HBA_NOERROR);
5806 		}
5807 		return;
5808 
5809 	case RQCS_SYNCXFER_FAILED:
5810 		isp_prt(isp, ISP_LOGERR,
5811 		    "SDTR Message failed for target %d.%d.%d",
5812 		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
5813 		if (IS_SCSI(isp)) {
5814 			sdparam *sdp = isp->isp_param;
5815 			sdp += XS_CHANNEL(xs);
5816 			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
5817 			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
5818 			isp->isp_update |= (1 << XS_CHANNEL(xs));
5819 		}
5820 		break;
5821 
5822 	case RQCS_LVD_BUSERR:
5823 		isp_prt(isp, ISP_LOGERR,
5824 		    "Bad LVD condition while talking to %d.%d.%d",
5825 		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
5826 		break;
5827 
5828 	case RQCS_PORT_UNAVAILABLE:
5829 		/*
5830 		 * No such port on the loop. Moral equivalent of SELTIMEO
5831 		 */
5832 	case RQCS_PORT_LOGGED_OUT:
5833 	{
5834 		const char *reason;
5835 		uint8_t sts = sp->req_completion_status & 0xff;
5836 
5837 		/*
5838 		 * It was there (maybe)- treat as a selection timeout.
5839 		 */
5840 		if (sts == RQCS_PORT_UNAVAILABLE) {
5841 			reason = "unavailable";
5842 		} else {
5843 			reason = "logout";
5844 		}
5845 
5846 		isp_prt(isp, ISP_LOGINFO, "port %s for target %d",
5847 		    reason, XS_TGT(xs));
5848 
5849 		/*
5850 		 * If we're on a local loop, force a LIP (which is overkill)
5851 		 * to force a re-login of this unit. If we're on fabric,
5852 		 * then we'll have to log in again as a matter of course.
5853 		 */
5854 		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
5855 		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
5856 			mbreg_t mbs;
5857 			MEMZERO(&mbs, sizeof (mbs));
5858 			mbs.param[0] = MBOX_INIT_LIP;
5859 			if (FCPARAM(isp)->isp_2klogin) {
5860 				mbs.ibits = (1 << 10);
5861 			}
5862 			mbs.logval = MBLOGALL;
5863 			isp_mboxcmd_qnw(isp, &mbs, 1);
5864 		}
5865 		if (XS_NOERR(xs)) {
5866 			XS_SETERR(xs, HBA_SELTIMEOUT);
5867 		}
5868 		return;
5869 	}
5870 	case RQCS_PORT_CHANGED:
5871 		isp_prt(isp, ISP_LOGWARN,
5872 		    "port changed for target %d", XS_TGT(xs));
5873 		if (XS_NOERR(xs)) {
5874 			XS_SETERR(xs, HBA_SELTIMEOUT);
5875 		}
5876 		return;
5877 
5878 	case RQCS_PORT_BUSY:
5879 		isp_prt(isp, ISP_LOGWARN,
5880 		    "port busy for target %d", XS_TGT(xs));
5881 		if (XS_NOERR(xs)) {
5882 			XS_SETERR(xs, HBA_TGTBSY);
5883 		}
5884 		return;
5885 
5886 	default:
5887 		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
5888 		    sp->req_completion_status);
5889 		break;
5890 	}
5891 	if (XS_NOERR(xs)) {
5892 		XS_SETERR(xs, HBA_BOTCH);
5893 	}
5894 }
5895 
5896 static void
5897 isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
5898     XS_T *xs, long *rp)
5899 {
5900 	switch (sp->req_completion_status) {
5901 	case RQCS_COMPLETE:
5902 		if (XS_NOERR(xs)) {
5903 			XS_SETERR(xs, HBA_NOERROR);
5904 		}
5905 		return;
5906 
5907 	case RQCS_DMA_ERROR:
5908 		isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
5909 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5910 		break;
5911 
5912 	case RQCS_TRANSPORT_ERROR:
5913 		isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d",
5914 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5915 		break;
5916 
5917 	case RQCS_RESET_OCCURRED:
5918 		isp_prt(isp, ISP_LOGWARN,
5919 		    "bus reset destroyed command for %d.%d.%d",
5920 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5921 		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
5922 		if (XS_NOERR(xs)) {
5923 			XS_SETERR(xs, HBA_BUSRESET);
5924 		}
5925 		return;
5926 
5927 	case RQCS_ABORTED:
5928 		isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
5929 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5930 		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
5931 		if (XS_NOERR(xs)) {
5932 			XS_SETERR(xs, HBA_ABORTED);
5933 		}
5934 		return;
5935 
5936 	case RQCS_TIMEOUT:
5937 		isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
5938 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5939 		if (XS_NOERR(xs)) {
5940 			XS_SETERR(xs, HBA_CMDTIMEOUT);
5941 		}
5942 		return;
5943 
5944 	case RQCS_DATA_OVERRUN:
5945 		XS_RESID(xs) = sp->req_resid;
5946 		isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d",
5947 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
5948 		if (XS_NOERR(xs)) {
5949 			XS_SETERR(xs, HBA_DATAOVR);
5950 		}
5951 		return;
5952 
5953 	case RQCS_24XX_DRE:	/* data reassembly error */
5954 		isp_prt(isp, ISP_LOGERR, "data reassembly error for target %d",
5955 		    XS_TGT(xs));
5956 		if (XS_NOERR(xs)) {
5957 			XS_SETERR(xs, HBA_ABORTED);
5958 		}
5959 		*rp = XS_XFRLEN(xs);
5960 		return;
5961 
5962 	case RQCS_24XX_TABORT:	/* aborted by target */
5963 		isp_prt(isp, ISP_LOGERR, "target %d sent ABTS",
5964 		    XS_TGT(xs));
5965 		if (XS_NOERR(xs)) {
5966 			XS_SETERR(xs, HBA_ABORTED);
5967 		}
5968 		return;
5969 
5970 	case RQCS_DATA_UNDERRUN:
5971 
5972 		XS_RESID(xs) = sp->req_resid;
5973 		if (XS_NOERR(xs)) {
5974 			XS_SETERR(xs, HBA_NOERROR);
5975 		}
5976 		return;
5977 
5978 	case RQCS_PORT_UNAVAILABLE:
5979 		/*
5980 		 * No such port on the loop. Moral equivalent of SELTIMEO
5981 		 */
5982 	case RQCS_PORT_LOGGED_OUT:
5983 	{
5984 		const char *reason;
5985 		uint8_t sts = sp->req_completion_status & 0xff;
5986 
5987 		/*
5988 		 * It was there (maybe)- treat as a selection timeout.
5989 		 */
5990 		if (sts == RQCS_PORT_UNAVAILABLE) {
5991 			reason = "unavailable";
5992 		} else {
5993 			reason = "logout";
5994 		}
5995 
5996 		isp_prt(isp, ISP_LOGINFO, "port %s for target %d",
5997 		    reason, XS_TGT(xs));
5998 
5999 		/*
6000 		 * If we're on a local loop, force a LIP (which is overkill)
6001 		 * to force a re-login of this unit. If we're on fabric,
6002 		 * then we'll have to log in again as a matter of course.
6003 		 */
6004 		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
6005 		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
6006 			mbreg_t mbs;
6007 			MEMZERO(&mbs, sizeof (mbs));
6008 			mbs.param[0] = MBOX_INIT_LIP;
6009 			if (FCPARAM(isp)->isp_2klogin) {
6010 				mbs.ibits = (1 << 10);
6011 			}
6012 			mbs.logval = MBLOGALL;
6013 			isp_mboxcmd_qnw(isp, &mbs, 1);
6014 		}
6015 		if (XS_NOERR(xs)) {
6016 			XS_SETERR(xs, HBA_SELTIMEOUT);
6017 		}
6018 		return;
6019 	}
6020 	case RQCS_PORT_CHANGED:
6021 		isp_prt(isp, ISP_LOGWARN,
6022 		    "port changed for target %d", XS_TGT(xs));
6023 		if (XS_NOERR(xs)) {
6024 			XS_SETERR(xs, HBA_SELTIMEOUT);
6025 		}
6026 		return;
6027 
6028 
6029 	case RQCS_24XX_ENOMEM:	/* f/w resource unavailable */
6030 		isp_prt(isp, ISP_LOGWARN,
6031 		    "f/w resource unavailable for target %d", XS_TGT(xs));
6032 		if (XS_NOERR(xs)) {
6033 			*XS_STSP(xs) = SCSI_BUSY;
6034 			XS_SETERR(xs, HBA_TGTBSY);
6035 		}
6036 		return;
6037 
6038 	case RQCS_24XX_TMO:	/* task management overrun */
6039 		isp_prt(isp, ISP_LOGWARN,
6040 		    "command for target %d overlapped task management",
6041 		    XS_TGT(xs));
6042 		if (XS_NOERR(xs)) {
6043 			*XS_STSP(xs) = SCSI_BUSY;
6044 			XS_SETERR(xs, HBA_TGTBSY);
6045 		}
6046 		return;
6047 
6048 	default:
6049 		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
6050 		    sp->req_completion_status);
6051 		break;
6052 	}
6053 	if (XS_NOERR(xs)) {
6054 		XS_SETERR(xs, HBA_BOTCH);
6055 	}
6056 }
6057 
6058 static void
6059 isp_fastpost_complete(ispsoftc_t *isp, uint16_t fph)
6060 {
6061 	XS_T *xs;
6062 
6063 	if (fph == 0) {
6064 		return;
6065 	}
6066 	xs = isp_find_xs(isp, fph);
6067 	if (xs == NULL) {
6068 		isp_prt(isp, ISP_LOGWARN,
6069 		    "Command for fast post handle 0x%x not found", fph);
6070 		return;
6071 	}
6072 	isp_destroy_handle(isp, fph);
6073 
6074 	/*
6075 	 * Since we don't have a result queue entry item,
6076 	 * we must believe that SCSI status is zero and
6077 	 * that all data transferred.
6078 	 */
6079 	XS_SET_STATE_STAT(isp, xs, NULL);
6080 	XS_RESID(xs) = 0;
6081 	*XS_STSP(xs) = SCSI_GOOD;
6082 	if (XS_XFRLEN(xs)) {
6083 		ISP_DMAFREE(isp, xs, fph);
6084 	}
6085 	if (isp->isp_nactive)
6086 		isp->isp_nactive--;
6087 	isp->isp_fphccmplt++;
6088 	isp_done(xs);
6089 }
6090 
6091 static int
6092 isp_mbox_continue(ispsoftc_t *isp)
6093 {
6094 	mbreg_t mbs;
6095 	uint16_t *ptr;
6096 	uint32_t offset;
6097 
6098 	switch (isp->isp_lastmbxcmd) {
6099 	case MBOX_WRITE_RAM_WORD:
6100 	case MBOX_READ_RAM_WORD:
6101 	case MBOX_WRITE_RAM_WORD_EXTENDED:
6102 	case MBOX_READ_RAM_WORD_EXTENDED:
6103 		break;
6104 	default:
6105 		return (1);
6106 	}
6107 	if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
6108 		isp->isp_mbxwrk0 = 0;
6109 		return (-1);
6110 	}
6111 
6112 	/*
6113 	 * Clear the previous interrupt.
6114 	 */
6115 	if (IS_24XX(isp)) {
6116 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
6117 	} else {
6118 		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
6119 		ISP_WRITE(isp, BIU_SEMA, 0);
6120 	}
6121 
6122 	/*
6123 	 * Continue with next word.
6124 	 */
6125 	MEMZERO(&mbs, sizeof (mbs));
6126 	ptr = isp->isp_mbxworkp;
6127 	switch (isp->isp_lastmbxcmd) {
6128 	case MBOX_WRITE_RAM_WORD:
6129 		mbs.param[1] = isp->isp_mbxwrk1++;;
6130 		mbs.param[2] = *ptr++;;
6131 		break;
6132 	case MBOX_READ_RAM_WORD:
6133 		*ptr++ = isp->isp_mboxtmp[2];
6134 		mbs.param[1] = isp->isp_mbxwrk1++;
6135 		break;
6136 	case MBOX_WRITE_RAM_WORD_EXTENDED:
6137 		offset = isp->isp_mbxwrk1;
6138 		offset |= isp->isp_mbxwrk8 << 16;
6139 
6140 		mbs.param[2] = *ptr++;;
6141 		mbs.param[1] = offset;
6142 		mbs.param[8] = offset >> 16;
6143 		isp->isp_mbxwrk1 = ++offset;
6144 		isp->isp_mbxwrk8 = offset >> 16;
6145 		break;
6146 	case MBOX_READ_RAM_WORD_EXTENDED:
6147 		offset = isp->isp_mbxwrk1;
6148 		offset |= isp->isp_mbxwrk8 << 16;
6149 
6150 		*ptr++ = isp->isp_mboxtmp[2];
6151 		mbs.param[1] = offset;
6152 		mbs.param[8] = offset >> 16;
6153 		isp->isp_mbxwrk1 = ++offset;
6154 		isp->isp_mbxwrk8 = offset >> 16;
6155 		break;
6156 	}
6157 	isp->isp_mbxworkp = ptr;
6158 	isp->isp_mbxwrk0--;
6159 	mbs.param[0] = isp->isp_lastmbxcmd;
6160 	mbs.logval = MBLOGALL;
6161 	isp_mboxcmd_qnw(isp, &mbs, 0);
6162 	return (0);
6163 }
6164 
6165 #define	HIWRD(x)			((x) >> 16)
6166 #define	LOWRD(x)			((x)  & 0xffff)
6167 #define	ISPOPMAP(a, b)			(((a) << 16) | (b))
6168 static const uint32_t mbpscsi[] = {
6169 	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
6170 	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
6171 	ISPOPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
6172 	ISPOPMAP(0x1f, 0x01),	/* 0x03: MBOX_DUMP_RAM */
6173 	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
6174 	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
6175 	ISPOPMAP(0x3f, 0x3f),	/* 0x06: MBOX_MAILBOX_REG_TEST */
6176 	ISPOPMAP(0x07, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
6177 	ISPOPMAP(0x01, 0x0f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
6178 	ISPOPMAP(0x00, 0x00),	/* 0x09: */
6179 	ISPOPMAP(0x00, 0x00),	/* 0x0a: */
6180 	ISPOPMAP(0x00, 0x00),	/* 0x0b: */
6181 	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
6182 	ISPOPMAP(0x00, 0x00),	/* 0x0d: */
6183 	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
6184 	ISPOPMAP(0x00, 0x00),	/* 0x0f: */
6185 	ISPOPMAP(0x1f, 0x1f),	/* 0x10: MBOX_INIT_REQ_QUEUE */
6186 	ISPOPMAP(0x3f, 0x3f),	/* 0x11: MBOX_INIT_RES_QUEUE */
6187 	ISPOPMAP(0x0f, 0x0f),	/* 0x12: MBOX_EXECUTE_IOCB */
6188 	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
6189 	ISPOPMAP(0x01, 0x3f),	/* 0x14: MBOX_STOP_FIRMWARE */
6190 	ISPOPMAP(0x0f, 0x0f),	/* 0x15: MBOX_ABORT */
6191 	ISPOPMAP(0x03, 0x03),	/* 0x16: MBOX_ABORT_DEVICE */
6192 	ISPOPMAP(0x07, 0x07),	/* 0x17: MBOX_ABORT_TARGET */
6193 	ISPOPMAP(0x07, 0x07),	/* 0x18: MBOX_BUS_RESET */
6194 	ISPOPMAP(0x03, 0x07),	/* 0x19: MBOX_STOP_QUEUE */
6195 	ISPOPMAP(0x03, 0x07),	/* 0x1a: MBOX_START_QUEUE */
6196 	ISPOPMAP(0x03, 0x07),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6197 	ISPOPMAP(0x03, 0x07),	/* 0x1c: MBOX_ABORT_QUEUE */
6198 	ISPOPMAP(0x03, 0x4f),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6199 	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
6200 	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6201 	ISPOPMAP(0x01, 0x07),	/* 0x20: MBOX_GET_INIT_SCSI_ID */
6202 	ISPOPMAP(0x01, 0x07),	/* 0x21: MBOX_GET_SELECT_TIMEOUT */
6203 	ISPOPMAP(0x01, 0xc7),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
6204 	ISPOPMAP(0x01, 0x07),	/* 0x23: MBOX_GET_TAG_AGE_LIMIT */
6205 	ISPOPMAP(0x01, 0x03),	/* 0x24: MBOX_GET_CLOCK_RATE */
6206 	ISPOPMAP(0x01, 0x07),	/* 0x25: MBOX_GET_ACT_NEG_STATE */
6207 	ISPOPMAP(0x01, 0x07),	/* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
6208 	ISPOPMAP(0x01, 0x07),	/* 0x27: MBOX_GET_PCI_PARAMS */
6209 	ISPOPMAP(0x03, 0x4f),	/* 0x28: MBOX_GET_TARGET_PARAMS */
6210 	ISPOPMAP(0x03, 0x0f),	/* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
6211 	ISPOPMAP(0x01, 0x07),	/* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
6212 	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
6213 	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
6214 	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
6215 	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
6216 	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
6217 	ISPOPMAP(0x03, 0x03),	/* 0x30: MBOX_SET_INIT_SCSI_ID */
6218 	ISPOPMAP(0x07, 0x07),	/* 0x31: MBOX_SET_SELECT_TIMEOUT */
6219 	ISPOPMAP(0xc7, 0xc7),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
6220 	ISPOPMAP(0x07, 0x07),	/* 0x33: MBOX_SET_TAG_AGE_LIMIT */
6221 	ISPOPMAP(0x03, 0x03),	/* 0x34: MBOX_SET_CLOCK_RATE */
6222 	ISPOPMAP(0x07, 0x07),	/* 0x35: MBOX_SET_ACT_NEG_STATE */
6223 	ISPOPMAP(0x07, 0x07),	/* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
6224 	ISPOPMAP(0x07, 0x07),	/* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
6225 	ISPOPMAP(0x4f, 0x4f),	/* 0x38: MBOX_SET_TARGET_PARAMS */
6226 	ISPOPMAP(0x0f, 0x0f),	/* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
6227 	ISPOPMAP(0x07, 0x07),	/* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
6228 	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
6229 	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
6230 	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
6231 	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
6232 	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
6233 	ISPOPMAP(0x01, 0x03),	/* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
6234 	ISPOPMAP(0x3f, 0x01),	/* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
6235 	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_EXEC_BIOS_IOCB */
6236 	ISPOPMAP(0x00, 0x00),	/* 0x43: */
6237 	ISPOPMAP(0x00, 0x00),	/* 0x44: */
6238 	ISPOPMAP(0x03, 0x03),	/* 0x45: SET SYSTEM PARAMETER */
6239 	ISPOPMAP(0x01, 0x03),	/* 0x46: GET SYSTEM PARAMETER */
6240 	ISPOPMAP(0x00, 0x00),	/* 0x47: */
6241 	ISPOPMAP(0x01, 0xcf),	/* 0x48: GET SCAM CONFIGURATION */
6242 	ISPOPMAP(0xcf, 0xcf),	/* 0x49: SET SCAM CONFIGURATION */
6243 	ISPOPMAP(0x03, 0x03),	/* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
6244 	ISPOPMAP(0x01, 0x03),	/* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
6245 	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
6246 	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
6247 	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
6248 	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
6249 	ISPOPMAP(0xdf, 0xdf),	/* 0x50: LOAD RAM A64 */
6250 	ISPOPMAP(0xdf, 0xdf),	/* 0x51: DUMP RAM A64 */
6251 	ISPOPMAP(0xdf, 0xff),	/* 0x52: INITIALIZE REQUEST QUEUE A64 */
6252 	ISPOPMAP(0xef, 0xff),	/* 0x53: INITIALIZE RESPONSE QUEUE A64 */
6253 	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUCUTE COMMAND IOCB A64 */
6254 	ISPOPMAP(0x07, 0x01),	/* 0x55: ENABLE TARGET MODE */
6255 	ISPOPMAP(0x03, 0x0f),	/* 0x56: GET TARGET STATUS */
6256 	ISPOPMAP(0x00, 0x00),	/* 0x57: */
6257 	ISPOPMAP(0x00, 0x00),	/* 0x58: */
6258 	ISPOPMAP(0x00, 0x00),	/* 0x59: */
6259 	ISPOPMAP(0x03, 0x03),	/* 0x5a: SET DATA OVERRUN RECOVERY MODE */
6260 	ISPOPMAP(0x01, 0x03),	/* 0x5b: GET DATA OVERRUN RECOVERY MODE */
6261 	ISPOPMAP(0x0f, 0x0f),	/* 0x5c: SET HOST DATA */
6262 	ISPOPMAP(0x01, 0x01)	/* 0x5d: GET NOST DATA */
6263 };
6264 
6265 static const char *scsi_mbcmd_names[] = {
6266 	"NO-OP",
6267 	"LOAD RAM",
6268 	"EXEC FIRMWARE",
6269 	"DUMP RAM",
6270 	"WRITE RAM WORD",
6271 	"READ RAM WORD",
6272 	"MAILBOX REG TEST",
6273 	"VERIFY CHECKSUM",
6274 	"ABOUT FIRMWARE",
6275 	NULL,
6276 	NULL,
6277 	NULL,
6278 	NULL,
6279 	NULL,
6280 	"CHECK FIRMWARE",
6281 	NULL,
6282 	"INIT REQUEST QUEUE",
6283 	"INIT RESULT QUEUE",
6284 	"EXECUTE IOCB",
6285 	"WAKE UP",
6286 	"STOP FIRMWARE",
6287 	"ABORT",
6288 	"ABORT DEVICE",
6289 	"ABORT TARGET",
6290 	"BUS RESET",
6291 	"STOP QUEUE",
6292 	"START QUEUE",
6293 	"SINGLE STEP QUEUE",
6294 	"ABORT QUEUE",
6295 	"GET DEV QUEUE STATUS",
6296 	NULL,
6297 	"GET FIRMWARE STATUS",
6298 	"GET INIT SCSI ID",
6299 	"GET SELECT TIMEOUT",
6300 	"GET RETRY COUNT",
6301 	"GET TAG AGE LIMIT",
6302 	"GET CLOCK RATE",
6303 	"GET ACT NEG STATE",
6304 	"GET ASYNC DATA SETUP TIME",
6305 	"GET PCI PARAMS",
6306 	"GET TARGET PARAMS",
6307 	"GET DEV QUEUE PARAMS",
6308 	"GET RESET DELAY PARAMS",
6309 	NULL,
6310 	NULL,
6311 	NULL,
6312 	NULL,
6313 	NULL,
6314 	"SET INIT SCSI ID",
6315 	"SET SELECT TIMEOUT",
6316 	"SET RETRY COUNT",
6317 	"SET TAG AGE LIMIT",
6318 	"SET CLOCK RATE",
6319 	"SET ACT NEG STATE",
6320 	"SET ASYNC DATA SETUP TIME",
6321 	"SET PCI CONTROL PARAMS",
6322 	"SET TARGET PARAMS",
6323 	"SET DEV QUEUE PARAMS",
6324 	"SET RESET DELAY PARAMS",
6325 	NULL,
6326 	NULL,
6327 	NULL,
6328 	NULL,
6329 	NULL,
6330 	"RETURN BIOS BLOCK ADDR",
6331 	"WRITE FOUR RAM WORDS",
6332 	"EXEC BIOS IOCB",
6333 	NULL,
6334 	NULL,
6335 	"SET SYSTEM PARAMETER",
6336 	"GET SYSTEM PARAMETER",
6337 	NULL,
6338 	"GET SCAM CONFIGURATION",
6339 	"SET SCAM CONFIGURATION",
6340 	"SET FIRMWARE FEATURES",
6341 	"GET FIRMWARE FEATURES",
6342 	NULL,
6343 	NULL,
6344 	NULL,
6345 	NULL,
6346 	"LOAD RAM A64",
6347 	"DUMP RAM A64",
6348 	"INITIALIZE REQUEST QUEUE A64",
6349 	"INITIALIZE RESPONSE QUEUE A64",
6350 	"EXECUTE IOCB A64",
6351 	"ENABLE TARGET MODE",
6352 	"GET TARGET MODE STATE",
6353 	NULL,
6354 	NULL,
6355 	NULL,
6356 	"SET DATA OVERRUN RECOVERY MODE",
6357 	"GET DATA OVERRUN RECOVERY MODE",
6358 	"SET HOST DATA",
6359 	"GET NOST DATA",
6360 };
6361 
6362 static const uint32_t mbpfc[] = {
6363 	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
6364 	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
6365 	ISPOPMAP(0x0f, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
6366 	ISPOPMAP(0xdf, 0x01),	/* 0x03: MBOX_DUMP_RAM */
6367 	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
6368 	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
6369 	ISPOPMAP(0xff, 0xff),	/* 0x06: MBOX_MAILBOX_REG_TEST */
6370 	ISPOPMAP(0x03, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
6371 	ISPOPMAP(0x01, 0x4f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
6372 	ISPOPMAP(0xdf, 0x01),	/* 0x09: MBOX_LOAD_RISC_RAM_2100 */
6373 	ISPOPMAP(0xdf, 0x01),	/* 0x0a: DUMP RAM */
6374 	ISPOPMAP(0x1ff, 0x01),	/* 0x0b: MBOX_LOAD_RISC_RAM */
6375 	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
6376 	ISPOPMAP(0x10f, 0x01),	/* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
6377 	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
6378 	ISPOPMAP(0x10f, 0x05),	/* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
6379 	ISPOPMAP(0x1f, 0x11),	/* 0x10: MBOX_INIT_REQ_QUEUE */
6380 	ISPOPMAP(0x2f, 0x21),	/* 0x11: MBOX_INIT_RES_QUEUE */
6381 	ISPOPMAP(0x0f, 0x01),	/* 0x12: MBOX_EXECUTE_IOCB */
6382 	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
6383 	ISPOPMAP(0x01, 0xff),	/* 0x14: MBOX_STOP_FIRMWARE */
6384 	ISPOPMAP(0x4f, 0x01),	/* 0x15: MBOX_ABORT */
6385 	ISPOPMAP(0x07, 0x01),	/* 0x16: MBOX_ABORT_DEVICE */
6386 	ISPOPMAP(0x07, 0x01),	/* 0x17: MBOX_ABORT_TARGET */
6387 	ISPOPMAP(0x03, 0x03),	/* 0x18: MBOX_BUS_RESET */
6388 	ISPOPMAP(0x07, 0x05),	/* 0x19: MBOX_STOP_QUEUE */
6389 	ISPOPMAP(0x07, 0x05),	/* 0x1a: MBOX_START_QUEUE */
6390 	ISPOPMAP(0x07, 0x05),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6391 	ISPOPMAP(0x07, 0x05),	/* 0x1c: MBOX_ABORT_QUEUE */
6392 	ISPOPMAP(0x07, 0x03),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6393 	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
6394 	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6395 	ISPOPMAP(0x01, 0x4f),	/* 0x20: MBOX_GET_LOOP_ID */
6396 	ISPOPMAP(0x00, 0x00),	/* 0x21: */
6397 	ISPOPMAP(0x01, 0x07),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
6398 	ISPOPMAP(0x00, 0x00),	/* 0x23: */
6399 	ISPOPMAP(0x00, 0x00),	/* 0x24: */
6400 	ISPOPMAP(0x00, 0x00),	/* 0x25: */
6401 	ISPOPMAP(0x00, 0x00),	/* 0x26: */
6402 	ISPOPMAP(0x00, 0x00),	/* 0x27: */
6403 	ISPOPMAP(0x01, 0x03),	/* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
6404 	ISPOPMAP(0x03, 0x07),	/* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
6405 	ISPOPMAP(0x00, 0x00),	/* 0x2a: */
6406 	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
6407 	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
6408 	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
6409 	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
6410 	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
6411 	ISPOPMAP(0x00, 0x00),	/* 0x30: */
6412 	ISPOPMAP(0x00, 0x00),	/* 0x31: */
6413 	ISPOPMAP(0x07, 0x07),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
6414 	ISPOPMAP(0x00, 0x00),	/* 0x33: */
6415 	ISPOPMAP(0x00, 0x00),	/* 0x34: */
6416 	ISPOPMAP(0x00, 0x00),	/* 0x35: */
6417 	ISPOPMAP(0x00, 0x00),	/* 0x36: */
6418 	ISPOPMAP(0x00, 0x00),	/* 0x37: */
6419 	ISPOPMAP(0x0f, 0x01),	/* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
6420 	ISPOPMAP(0x0f, 0x07),	/* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
6421 	ISPOPMAP(0x00, 0x00),	/* 0x3a: */
6422 	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
6423 	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
6424 	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
6425 	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
6426 	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
6427 	ISPOPMAP(0x03, 0x01),	/* 0x40: MBOX_LOOP_PORT_BYPASS */
6428 	ISPOPMAP(0x03, 0x01),	/* 0x41: MBOX_LOOP_PORT_ENABLE */
6429 	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_GET_RESOURCE_COUNT */
6430 	ISPOPMAP(0x01, 0x01),	/* 0x43: MBOX_REQUEST_OFFLINE_MODE */
6431 	ISPOPMAP(0x00, 0x00),	/* 0x44: */
6432 	ISPOPMAP(0x00, 0x00),	/* 0x45: */
6433 	ISPOPMAP(0x00, 0x00),	/* 0x46: */
6434 	ISPOPMAP(0xcf, 0x03),	/* 0x47: GET PORT_DATABASE ENHANCED */
6435 	ISPOPMAP(0x00, 0x00),	/* 0x48: */
6436 	ISPOPMAP(0x00, 0x00),	/* 0x49: */
6437 	ISPOPMAP(0x00, 0x00),	/* 0x4a: */
6438 	ISPOPMAP(0x00, 0x00),	/* 0x4b: */
6439 	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
6440 	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
6441 	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
6442 	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
6443 	ISPOPMAP(0x00, 0x00),	/* 0x50: */
6444 	ISPOPMAP(0x00, 0x00),	/* 0x51: */
6445 	ISPOPMAP(0x00, 0x00),	/* 0x52: */
6446 	ISPOPMAP(0x00, 0x00),	/* 0x53: */
6447 	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
6448 	ISPOPMAP(0x00, 0x00),	/* 0x55: */
6449 	ISPOPMAP(0x00, 0x00),	/* 0x56: */
6450 	ISPOPMAP(0x00, 0x00),	/* 0x57: */
6451 	ISPOPMAP(0x00, 0x00),	/* 0x58: */
6452 	ISPOPMAP(0x00, 0x00),	/* 0x59: */
6453 	ISPOPMAP(0x00, 0x00),	/* 0x5a: */
6454 	ISPOPMAP(0x03, 0x01),	/* 0x5b: MBOX_DRIVER_HEARTBEAT */
6455 	ISPOPMAP(0xcf, 0x01),	/* 0x5c: MBOX_FW_HEARTBEAT */
6456 	ISPOPMAP(0x07, 0x03),	/* 0x5d: MBOX_GET_SET_DATA_RATE */
6457 	ISPOPMAP(0x00, 0x00),	/* 0x5e: */
6458 	ISPOPMAP(0x00, 0x00),	/* 0x5f: */
6459 	ISPOPMAP(0xcd, 0x01),	/* 0x60: MBOX_INIT_FIRMWARE */
6460 	ISPOPMAP(0x00, 0x00),	/* 0x61: */
6461 	ISPOPMAP(0x01, 0x01),	/* 0x62: MBOX_INIT_LIP */
6462 	ISPOPMAP(0xcd, 0x03),	/* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
6463 	ISPOPMAP(0xcf, 0x01),	/* 0x64: MBOX_GET_PORT_DB */
6464 	ISPOPMAP(0x07, 0x01),	/* 0x65: MBOX_CLEAR_ACA */
6465 	ISPOPMAP(0x07, 0x01),	/* 0x66: MBOX_TARGET_RESET */
6466 	ISPOPMAP(0x07, 0x01),	/* 0x67: MBOX_CLEAR_TASK_SET */
6467 	ISPOPMAP(0x07, 0x01),	/* 0x68: MBOX_ABORT_TASK_SET */
6468 	ISPOPMAP(0x01, 0x07),	/* 0x69: MBOX_GET_FW_STATE */
6469 	ISPOPMAP(0x03, 0xcf),	/* 0x6a: MBOX_GET_PORT_NAME */
6470 	ISPOPMAP(0xcf, 0x01),	/* 0x6b: MBOX_GET_LINK_STATUS */
6471 	ISPOPMAP(0x0f, 0x01),	/* 0x6c: MBOX_INIT_LIP_RESET */
6472 	ISPOPMAP(0x00, 0x00),	/* 0x6d: */
6473 	ISPOPMAP(0xcf, 0x03),	/* 0x6e: MBOX_SEND_SNS */
6474 	ISPOPMAP(0x0f, 0x07),	/* 0x6f: MBOX_FABRIC_LOGIN */
6475 	ISPOPMAP(0x03, 0x01),	/* 0x70: MBOX_SEND_CHANGE_REQUEST */
6476 	ISPOPMAP(0x03, 0x03),	/* 0x71: MBOX_FABRIC_LOGOUT */
6477 	ISPOPMAP(0x0f, 0x0f),	/* 0x72: MBOX_INIT_LIP_LOGIN */
6478 	ISPOPMAP(0x00, 0x00),	/* 0x73: */
6479 	ISPOPMAP(0x07, 0x01),	/* 0x74: LOGIN LOOP PORT */
6480 	ISPOPMAP(0xcf, 0x03),	/* 0x75: GET PORT/NODE NAME LIST */
6481 	ISPOPMAP(0x4f, 0x01),	/* 0x76: SET VENDOR ID */
6482 	ISPOPMAP(0xcd, 0x01),	/* 0x77: INITIALIZE IP MAILBOX */
6483 	ISPOPMAP(0x00, 0x00),	/* 0x78: */
6484 	ISPOPMAP(0x00, 0x00),	/* 0x79: */
6485 	ISPOPMAP(0x00, 0x00),	/* 0x7a: */
6486 	ISPOPMAP(0x00, 0x00),	/* 0x7b: */
6487 	ISPOPMAP(0x4f, 0x03),	/* 0x7c: Get ID List */
6488 	ISPOPMAP(0xcf, 0x01),	/* 0x7d: SEND LFA */
6489 	ISPOPMAP(0x0f, 0x01)	/* 0x7e: LUN RESET */
6490 };
6491 /*
6492  * Footnotes
6493  *
6494  * (1): this sets bits 21..16 in mailbox register #8, which we nominally
6495  *	do not access at this time in the core driver. The caller is
6496  *	responsible for setting this register first (Gross!). The assumption
6497  *	is that we won't overflow.
6498  */
6499 
6500 static const char *fc_mbcmd_names[] = {
6501 	"NO-OP",
6502 	"LOAD RAM",
6503 	"EXEC FIRMWARE",
6504 	"DUMP RAM",
6505 	"WRITE RAM WORD",
6506 	"READ RAM WORD",
6507 	"MAILBOX REG TEST",
6508 	"VERIFY CHECKSUM",
6509 	"ABOUT FIRMWARE",
6510 	"LOAD RAM",
6511 	"DUMP RAM",
6512 	"WRITE RAM WORD EXTENDED",
6513 	NULL,
6514 	"READ RAM WORD EXTENDED",
6515 	"CHECK FIRMWARE",
6516 	NULL,
6517 	"INIT REQUEST QUEUE",
6518 	"INIT RESULT QUEUE",
6519 	"EXECUTE IOCB",
6520 	"WAKE UP",
6521 	"STOP FIRMWARE",
6522 	"ABORT",
6523 	"ABORT DEVICE",
6524 	"ABORT TARGET",
6525 	"BUS RESET",
6526 	"STOP QUEUE",
6527 	"START QUEUE",
6528 	"SINGLE STEP QUEUE",
6529 	"ABORT QUEUE",
6530 	"GET DEV QUEUE STATUS",
6531 	NULL,
6532 	"GET FIRMWARE STATUS",
6533 	"GET LOOP ID",
6534 	NULL,
6535 	"GET RETRY COUNT",
6536 	NULL,
6537 	NULL,
6538 	NULL,
6539 	NULL,
6540 	NULL,
6541 	"GET FIRMWARE OPTIONS",
6542 	"GET PORT QUEUE PARAMS",
6543 	NULL,
6544 	NULL,
6545 	NULL,
6546 	NULL,
6547 	NULL,
6548 	NULL,
6549 	NULL,
6550 	NULL,
6551 	"SET RETRY COUNT",
6552 	NULL,
6553 	NULL,
6554 	NULL,
6555 	NULL,
6556 	NULL,
6557 	"SET FIRMWARE OPTIONS",
6558 	"SET PORT QUEUE PARAMS",
6559 	NULL,
6560 	NULL,
6561 	NULL,
6562 	NULL,
6563 	NULL,
6564 	NULL,
6565 	"LOOP PORT BYPASS",
6566 	"LOOP PORT ENABLE",
6567 	"GET RESOURCE COUNT",
6568 	"REQUEST NON PARTICIPATING MODE",
6569 	NULL,
6570 	NULL,
6571 	NULL,
6572 	"GET PORT DATABASE ENHANCED",
6573 	NULL,
6574 	NULL,
6575 	NULL,
6576 	NULL,
6577 	NULL,
6578 	NULL,
6579 	NULL,
6580 	NULL,
6581 	NULL,
6582 	NULL,
6583 	NULL,
6584 	NULL,
6585 	"EXECUTE IOCB A64",
6586 	NULL,
6587 	NULL,
6588 	NULL,
6589 	NULL,
6590 	NULL,
6591 	NULL,
6592 	"DRIVER HEARTBEAT",
6593 	NULL,
6594 	"GET/SET DATA RATE",
6595 	NULL,
6596 	NULL,
6597 	"INIT FIRMWARE",
6598 	NULL,
6599 	"INIT LIP",
6600 	"GET FC-AL POSITION MAP",
6601 	"GET PORT DATABASE",
6602 	"CLEAR ACA",
6603 	"TARGET RESET",
6604 	"CLEAR TASK SET",
6605 	"ABORT TASK SET",
6606 	"GET FW STATE",
6607 	"GET PORT NAME",
6608 	"GET LINK STATUS",
6609 	"INIT LIP RESET",
6610 	NULL,
6611 	"SEND SNS",
6612 	"FABRIC LOGIN",
6613 	"SEND CHANGE REQUEST",
6614 	"FABRIC LOGOUT",
6615 	"INIT LIP LOGIN",
6616 	NULL,
6617 	"LOGIN LOOP PORT",
6618 	"GET PORT/NODE NAME LIST",
6619 	"SET VENDOR ID",
6620 	"INITIALIZE IP MAILBOX",
6621 	NULL,
6622 	NULL,
6623 	NULL,
6624 	NULL,
6625 	"Get ID List",
6626 	"SEND LFA",
6627 	"Lun RESET"
6628 };
6629 
6630 static void
6631 isp_mboxcmd_qnw(ispsoftc_t *isp, mbreg_t *mbp, int nodelay)
6632 {
6633 	unsigned int ibits, obits, box, opcode;
6634 	const uint32_t *mcp;
6635 
6636 	if (IS_FC(isp)) {
6637 		mcp = mbpfc;
6638 	} else {
6639 		mcp = mbpscsi;
6640 	}
6641 	opcode = mbp->param[0];
6642 	ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
6643 	obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
6644 	ibits |= mbp->ibits;
6645 	obits |= mbp->obits;
6646 	for (box = 0; box < MAX_MAILBOX(isp); box++) {
6647 		if (ibits & (1 << box)) {
6648 			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
6649 		}
6650 		if (nodelay == 0) {
6651 			isp->isp_mboxtmp[box] = mbp->param[box] = 0;
6652 		}
6653 	}
6654 	if (nodelay == 0) {
6655 		isp->isp_lastmbxcmd = opcode;
6656 		isp->isp_obits = obits;
6657 		isp->isp_mboxbsy = 1;
6658 	}
6659 	if (IS_24XX(isp)) {
6660 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
6661 	} else {
6662 		ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
6663 	}
6664 	/*
6665 	 * Oddly enough, if we're not delaying for an answer,
6666 	 * delay a bit to give the f/w a chance to pick up the
6667 	 * command.
6668 	 */
6669 	if (nodelay) {
6670 		USEC_DELAY(1000);
6671 	}
6672 }
6673 
6674 static void
6675 isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
6676 {
6677 	const char *cname, *xname;
6678 	char tname[16], mname[16];
6679 	unsigned int lim, ibits, obits, box, opcode;
6680 	const uint32_t *mcp;
6681 
6682 	if (IS_FC(isp)) {
6683 		mcp = mbpfc;
6684 		lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
6685 	} else {
6686 		mcp = mbpscsi;
6687 		lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
6688 	}
6689 
6690 	if ((opcode = mbp->param[0]) >= lim) {
6691 		mbp->param[0] = MBOX_INVALID_COMMAND;
6692 		isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
6693 		return;
6694 	}
6695 
6696 	ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
6697 	obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
6698 
6699 	/*
6700 	 * Pick up any additional bits that the caller might have set.
6701 	 */
6702 	ibits |= mbp->ibits;
6703 	obits |= mbp->obits;
6704 
6705 	if (ibits == 0 && obits == 0) {
6706 		mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
6707 		isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
6708 		return;
6709 	}
6710 
6711 	/*
6712 	 * Get exclusive usage of mailbox registers.
6713 	 */
6714 	if (MBOX_ACQUIRE(isp)) {
6715 		mbp->param[0] = MBOX_REGS_BUSY;
6716 		goto out;
6717 	}
6718 
6719 	for (box = 0; box < MAX_MAILBOX(isp); box++) {
6720 		if (ibits & (1 << box)) {
6721 			isp_prt(isp, ISP_LOGDEBUG1, "IN mbox %d = 0x%04x", box,
6722 			    mbp->param[box]);
6723 			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
6724 		}
6725 		isp->isp_mboxtmp[box] = mbp->param[box] = 0;
6726 	}
6727 
6728 	isp->isp_lastmbxcmd = opcode;
6729 
6730 	/*
6731 	 * We assume that we can't overwrite a previous command.
6732 	 */
6733 	isp->isp_obits = obits;
6734 	isp->isp_mboxbsy = 1;
6735 
6736 	/*
6737 	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
6738 	 */
6739 	if (IS_24XX(isp)) {
6740 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
6741 	} else {
6742 		ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
6743 	}
6744 
6745 	/*
6746 	 * While we haven't finished the command, spin our wheels here.
6747 	 */
6748 	MBOX_WAIT_COMPLETE(isp, mbp);
6749 
6750 	/*
6751 	 * Did the command time out?
6752 	 */
6753 	if (mbp->param[0] == MBOX_TIMEOUT) {
6754 		MBOX_RELEASE(isp);
6755 		goto out;
6756 	}
6757 
6758 	/*
6759 	 * Copy back output registers.
6760 	 */
6761 	for (box = 0; box < MAX_MAILBOX(isp); box++) {
6762 		if (obits & (1 << box)) {
6763 			mbp->param[box] = isp->isp_mboxtmp[box];
6764 			isp_prt(isp, ISP_LOGDEBUG1, "OUT mbox %d = 0x%04x", box,
6765 			    mbp->param[box]);
6766 		}
6767 	}
6768 
6769 	MBOX_RELEASE(isp);
6770  out:
6771 	isp->isp_mboxbsy = 0;
6772 	if (mbp->logval == 0 || opcode == MBOX_EXEC_FIRMWARE) {
6773 		return;
6774 	}
6775 	cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
6776 	if (cname == NULL) {
6777 		cname = tname;
6778 		SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
6779 	}
6780 
6781 	/*
6782 	 * Just to be chatty here...
6783 	 */
6784 	xname = NULL;
6785 	switch (mbp->param[0]) {
6786 	case MBOX_COMMAND_COMPLETE:
6787 		break;
6788 	case MBOX_INVALID_COMMAND:
6789 		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_COMPLETE)) {
6790 			xname = "INVALID COMMAND";
6791 		}
6792 		break;
6793 	case MBOX_HOST_INTERFACE_ERROR:
6794 		if (mbp->logval & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR)) {
6795 			xname = "HOST INTERFACE ERROR";
6796 		}
6797 		break;
6798 	case MBOX_TEST_FAILED:
6799 		if (mbp->logval & MBLOGMASK(MBOX_TEST_FAILED)) {
6800 			xname = "TEST FAILED";
6801 		}
6802 		break;
6803 	case MBOX_COMMAND_ERROR:
6804 		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_ERROR)) {
6805 			xname = "COMMAND ERROR";
6806 		}
6807 		break;
6808 	case MBOX_COMMAND_PARAM_ERROR:
6809 		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR)) {
6810 			xname = "COMMAND PARAMETER ERROR";
6811 		}
6812 		break;
6813 	case MBOX_LOOP_ID_USED:
6814 		if (mbp->logval & MBLOGMASK(MBOX_LOOP_ID_USED)) {
6815 			xname = "LOOP ID ALREADY IN USE";
6816 		}
6817 		break;
6818 	case MBOX_PORT_ID_USED:
6819 		if (mbp->logval & MBLOGMASK(MBOX_PORT_ID_USED)) {
6820 			xname = "PORT ID ALREADY IN USE";
6821 		}
6822 		break;
6823 	case MBOX_ALL_IDS_USED:
6824 		if (mbp->logval & MBLOGMASK(MBOX_ALL_IDS_USED)) {
6825 			xname = "ALL LOOP IDS IN USE";
6826 		}
6827 		break;
6828 	case MBOX_REGS_BUSY:
6829 		xname = "REGISTERS BUSY";
6830 		break;
6831 	case MBOX_TIMEOUT:
6832 		xname = "TIMEOUT";
6833 		break;
6834 	default:
6835 		SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
6836 		xname = mname;
6837 		break;
6838 	}
6839 	if (xname) {
6840 		isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
6841 		    cname, xname);
6842 	}
6843 }
6844 
6845 static void
6846 isp_fw_state(ispsoftc_t *isp)
6847 {
6848 	if (IS_FC(isp)) {
6849 		mbreg_t mbs;
6850 		fcparam *fcp = isp->isp_param;
6851 
6852 		MEMZERO(&mbs, sizeof (mbs));
6853 		mbs.param[0] = MBOX_GET_FW_STATE;
6854 		mbs.logval = MBLOGALL;
6855 		isp_mboxcmd(isp, &mbs);
6856 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
6857 			fcp->isp_fwstate = mbs.param[1];
6858 		}
6859 	}
6860 }
6861 
6862 static void
6863 isp_update(ispsoftc_t *isp)
6864 {
6865 	int bus, upmask;
6866 
6867 	for (bus = 0, upmask = isp->isp_update; upmask != 0; bus++) {
6868 		if (upmask & (1 << bus)) {
6869 			isp_update_bus(isp, bus);
6870 		}
6871 		upmask &= ~(1 << bus);
6872 	}
6873 }
6874 
6875 static void
6876 isp_update_bus(ispsoftc_t *isp, int bus)
6877 {
6878 	int tgt;
6879 	mbreg_t mbs;
6880 	sdparam *sdp;
6881 
6882 	isp->isp_update &= ~(1 << bus);
6883 	if (IS_FC(isp)) {
6884 		/*
6885 		 * There are no 'per-bus' settings for Fibre Channel.
6886 		 */
6887 		return;
6888 	}
6889 	sdp = isp->isp_param;
6890 	sdp += bus;
6891 
6892 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
6893 		uint16_t flags, period, offset;
6894 		int get;
6895 
6896 		if (sdp->isp_devparam[tgt].dev_enable == 0) {
6897 			sdp->isp_devparam[tgt].dev_update = 0;
6898 			sdp->isp_devparam[tgt].dev_refresh = 0;
6899 			isp_prt(isp, ISP_LOGDEBUG0,
6900 	 		    "skipping target %d bus %d update", tgt, bus);
6901 			continue;
6902 		}
6903 		/*
6904 		 * If the goal is to update the status of the device,
6905 		 * take what's in goal_flags and try and set the device
6906 		 * toward that. Otherwise, if we're just refreshing the
6907 		 * current device state, get the current parameters.
6908 		 */
6909 
6910 		MEMZERO(&mbs, sizeof (mbs));
6911 
6912 		/*
6913 		 * Refresh overrides set
6914 		 */
6915 		if (sdp->isp_devparam[tgt].dev_refresh) {
6916 			mbs.param[0] = MBOX_GET_TARGET_PARAMS;
6917 			get = 1;
6918 		} else if (sdp->isp_devparam[tgt].dev_update) {
6919 			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
6920 
6921 			/*
6922 			 * Make sure goal_flags has "Renegotiate on Error"
6923 			 * on and "Freeze Queue on Error" off.
6924 			 */
6925 			sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
6926 			sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
6927 			mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
6928 
6929 			/*
6930 			 * Insist that PARITY must be enabled
6931 			 * if SYNC or WIDE is enabled.
6932 			 */
6933 			if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
6934 				mbs.param[2] |= DPARM_PARITY;
6935 			}
6936 
6937 			if (mbs.param[2] & DPARM_SYNC) {
6938 				mbs.param[3] =
6939 				    (sdp->isp_devparam[tgt].goal_offset << 8) |
6940 				    (sdp->isp_devparam[tgt].goal_period);
6941 			}
6942 			/*
6943 			 * A command completion later that has
6944 			 * RQSTF_NEGOTIATION set can cause
6945 			 * the dev_refresh/announce cycle also.
6946 			 *
6947 			 * Note: It is really important to update our current
6948 			 * flags with at least the state of TAG capabilities-
6949 			 * otherwise we might try and send a tagged command
6950 			 * when we have it all turned off. So change it here
6951 			 * to say that current already matches goal.
6952 			 */
6953 			sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
6954 			sdp->isp_devparam[tgt].actv_flags |=
6955 			    (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
6956 			isp_prt(isp, ISP_LOGDEBUG0,
6957 			    "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
6958 			    bus, tgt, mbs.param[2], mbs.param[3] >> 8,
6959 			    mbs.param[3] & 0xff);
6960 			get = 0;
6961 		} else {
6962 			continue;
6963 		}
6964 		mbs.param[1] = (bus << 15) | (tgt << 8);
6965 		mbs.logval = MBLOGALL;
6966 		isp_mboxcmd(isp, &mbs);
6967 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
6968 			continue;
6969 		}
6970 		if (get == 0) {
6971 			isp->isp_sendmarker |= (1 << bus);
6972 			sdp->isp_devparam[tgt].dev_update = 0;
6973 			sdp->isp_devparam[tgt].dev_refresh = 1;
6974 		} else {
6975 			sdp->isp_devparam[tgt].dev_refresh = 0;
6976 			flags = mbs.param[2];
6977 			period = mbs.param[3] & 0xff;
6978 			offset = mbs.param[3] >> 8;
6979 			sdp->isp_devparam[tgt].actv_flags = flags;
6980 			sdp->isp_devparam[tgt].actv_period = period;
6981 			sdp->isp_devparam[tgt].actv_offset = offset;
6982 			get = (bus << 16) | tgt;
6983 			(void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get);
6984 		}
6985 	}
6986 
6987 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
6988 		if (sdp->isp_devparam[tgt].dev_update ||
6989 		    sdp->isp_devparam[tgt].dev_refresh) {
6990 			isp->isp_update |= (1 << bus);
6991 			break;
6992 		}
6993 	}
6994 }
6995 
6996 #ifndef	DEFAULT_EXEC_THROTTLE
6997 #define	DEFAULT_EXEC_THROTTLE(isp)	ISP_EXEC_THROTTLE
6998 #endif
6999 
7000 static void
7001 isp_setdfltparm(ispsoftc_t *isp, int channel)
7002 {
7003 	int tgt;
7004 	sdparam *sdp;
7005 
7006 	sdp = (sdparam *) isp->isp_param;
7007 	sdp += channel;
7008 
7009 	/*
7010 	 * Been there, done that, got the T-shirt...
7011 	 */
7012 	if (sdp->isp_gotdparms) {
7013 		return;
7014 	}
7015 	sdp->isp_gotdparms = 1;
7016 	sdp->isp_bad_nvram = 0;
7017 	/*
7018 	 * Establish some default parameters.
7019 	 */
7020 	sdp->isp_cmd_dma_burst_enable = 0;
7021 	sdp->isp_data_dma_burst_enabl = 1;
7022 	sdp->isp_fifo_threshold = 0;
7023 	sdp->isp_initiator_id = DEFAULT_IID(isp);
7024 	if (isp->isp_type >= ISP_HA_SCSI_1040) {
7025 		sdp->isp_async_data_setup = 9;
7026 	} else {
7027 		sdp->isp_async_data_setup = 6;
7028 	}
7029 	sdp->isp_selection_timeout = 250;
7030 	sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
7031 	sdp->isp_tag_aging = 8;
7032 	sdp->isp_bus_reset_delay = 5;
7033 	/*
7034 	 * Don't retry selection, busy or queue full automatically- reflect
7035 	 * these back to us.
7036 	 */
7037 	sdp->isp_retry_count = 0;
7038 	sdp->isp_retry_delay = 0;
7039 
7040 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7041 		sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
7042 		sdp->isp_devparam[tgt].dev_enable = 1;
7043 	}
7044 
7045 	/*
7046 	 * If we've not been told to avoid reading NVRAM, try and read it.
7047 	 * If we're successful reading it, we can then return because NVRAM
7048 	 * will tell us what the desired settings are. Otherwise, we establish
7049 	 * some reasonable 'fake' nvram and goal defaults.
7050 	 */
7051 
7052 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7053 		if (isp_read_nvram(isp) == 0) {
7054 			return;
7055 		}
7056 		sdp->isp_bad_nvram = 1;
7057 	}
7058 
7059 	/*
7060 	 * Now try and see whether we have specific values for them.
7061 	 */
7062 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7063 		mbreg_t mbs;
7064 
7065 		MEMZERO(&mbs, sizeof (mbs));
7066 		mbs.param[0] = MBOX_GET_ACT_NEG_STATE;
7067 		mbs.logval = MBLOGNONE;
7068 		isp_mboxcmd(isp, &mbs);
7069 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7070 			sdp->isp_req_ack_active_neg = 1;
7071 			sdp->isp_data_line_active_neg = 1;
7072 		} else {
7073 			sdp->isp_req_ack_active_neg =
7074 			    (mbs.param[1+channel] >> 4) & 0x1;
7075 			sdp->isp_data_line_active_neg =
7076 			    (mbs.param[1+channel] >> 5) & 0x1;
7077 		}
7078 	}
7079 
7080 	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc3,
7081 	    0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
7082 	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
7083 	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
7084 	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc3,
7085 	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
7086 	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
7087 	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
7088 
7089 	/*
7090 	 * The trick here is to establish a default for the default (honk!)
7091 	 * state (goal_flags). Then try and get the current status from
7092 	 * the card to fill in the current state. We don't, in fact, set
7093 	 * the default to the SAFE default state- that's not the goal state.
7094 	 */
7095 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7096 		uint8_t off, per;
7097 		sdp->isp_devparam[tgt].actv_offset = 0;
7098 		sdp->isp_devparam[tgt].actv_period = 0;
7099 		sdp->isp_devparam[tgt].actv_flags = 0;
7100 
7101 		sdp->isp_devparam[tgt].goal_flags =
7102 		    sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
7103 
7104 		/*
7105 		 * We default to Wide/Fast for versions less than a 1040
7106 		 * (unless it's SBus).
7107 		 */
7108 		if (IS_ULTRA3(isp)) {
7109 			off = ISP_80M_SYNCPARMS >> 8;
7110 			per = ISP_80M_SYNCPARMS & 0xff;
7111 		} else if (IS_ULTRA2(isp)) {
7112 			off = ISP_40M_SYNCPARMS >> 8;
7113 			per = ISP_40M_SYNCPARMS & 0xff;
7114 		} else if (IS_1240(isp)) {
7115 			off = ISP_20M_SYNCPARMS >> 8;
7116 			per = ISP_20M_SYNCPARMS & 0xff;
7117 		} else if ((isp->isp_bustype == ISP_BT_SBUS &&
7118 		    isp->isp_type < ISP_HA_SCSI_1020A) ||
7119 		    (isp->isp_bustype == ISP_BT_PCI &&
7120 		    isp->isp_type < ISP_HA_SCSI_1040) ||
7121 		    (isp->isp_clock && isp->isp_clock < 60) ||
7122 		    (sdp->isp_ultramode == 0)) {
7123 			off = ISP_10M_SYNCPARMS >> 8;
7124 			per = ISP_10M_SYNCPARMS & 0xff;
7125 		} else {
7126 			off = ISP_20M_SYNCPARMS_1040 >> 8;
7127 			per = ISP_20M_SYNCPARMS_1040 & 0xff;
7128 		}
7129 		sdp->isp_devparam[tgt].goal_offset =
7130 		    sdp->isp_devparam[tgt].nvrm_offset = off;
7131 		sdp->isp_devparam[tgt].goal_period =
7132 		    sdp->isp_devparam[tgt].nvrm_period = per;
7133 
7134 		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc3,
7135 		    channel, tgt, sdp->isp_devparam[tgt].nvrm_flags,
7136 		    sdp->isp_devparam[tgt].nvrm_offset,
7137 		    sdp->isp_devparam[tgt].nvrm_period);
7138 	}
7139 }
7140 
7141 #ifndef	DEFAULT_FRAMESIZE
7142 #define	DEFAULT_FRAMESIZE(isp)		ICB_DFLT_FRMLEN
7143 #endif
7144 static void
7145 isp_setdfltfcparm(ispsoftc_t *isp)
7146 {
7147 	fcparam *fcp = FCPARAM(isp);
7148 
7149 	if (fcp->isp_gotdparms) {
7150 		return;
7151 	}
7152 	fcp->isp_gotdparms = 1;
7153 	fcp->isp_bad_nvram = 0;
7154 	fcp->isp_maxfrmlen = DEFAULT_FRAMESIZE(isp);
7155 	fcp->isp_maxalloc = ICB_DFLT_ALLOC;
7156 	fcp->isp_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
7157 	fcp->isp_retry_delay = ICB_DFLT_RDELAY;
7158 	fcp->isp_retry_count = ICB_DFLT_RCOUNT;
7159 	/* Platform specific.... */
7160 	fcp->isp_loopid = DEFAULT_LOOPID(isp);
7161 	fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp);
7162 	fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp);
7163 	fcp->isp_fwoptions = 0;
7164 	fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
7165 	fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
7166 	fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
7167 	fcp->isp_fwoptions |= ICBOPT_FAST_POST;
7168 	if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
7169 		fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
7170 	}
7171 
7172 	/*
7173 	 * Make sure this is turned off now until we get
7174 	 * extended options from NVRAM
7175 	 */
7176 	fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
7177 
7178 	/*
7179 	 * Now try and read NVRAM unless told to not do so.
7180 	 * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
7181 	 */
7182 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7183 		int i, j = 0;
7184 		/*
7185 		 * Give a couple of tries at reading NVRAM.
7186 		 */
7187 		for (i = 0; i < 2; i++) {
7188 			j = isp_read_nvram(isp);
7189 			if (j == 0) {
7190 				break;
7191 			}
7192 		}
7193 		if (j) {
7194 			fcp->isp_bad_nvram = 1;
7195 			isp->isp_confopts |= ISP_CFG_NONVRAM;
7196 			isp->isp_confopts |= ISP_CFG_OWNWWPN;
7197 			isp->isp_confopts |= ISP_CFG_OWNWWNN;
7198 		}
7199 	} else {
7200 		isp->isp_confopts |= ISP_CFG_OWNWWPN|ISP_CFG_OWNWWNN;
7201 	}
7202 
7203 	/*
7204 	 * Set node && port to override platform set defaults
7205 	 * unless the nvram read failed (or none was done),
7206 	 * or the platform code wants to use what had been
7207 	 * set in the defaults.
7208 	 */
7209 	if (isp->isp_confopts & ISP_CFG_OWNWWNN) {
7210 		isp_prt(isp, ISP_LOGCONFIG, "Using Node WWN 0x%08x%08x",
7211 		    (uint32_t) (DEFAULT_NODEWWN(isp) >> 32),
7212 		    (uint32_t) (DEFAULT_NODEWWN(isp) & 0xffffffff));
7213 		ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
7214 	} else {
7215 		/*
7216 		 * We always start out with values derived
7217 		 * from NVRAM or our platform default.
7218 		 */
7219 		ISP_NODEWWN(isp) = fcp->isp_wwnn_nvram;
7220 		if (fcp->isp_wwnn_nvram == 0) {
7221 			isp_prt(isp, ISP_LOGCONFIG,
7222 			    "bad WWNN- using default");
7223 			ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
7224 		}
7225 	}
7226 	if (isp->isp_confopts & ISP_CFG_OWNWWPN) {
7227 		isp_prt(isp, ISP_LOGCONFIG, "Using Port WWN 0x%08x%08x",
7228 		    (uint32_t) (DEFAULT_PORTWWN(isp) >> 32),
7229 		    (uint32_t) (DEFAULT_PORTWWN(isp) & 0xffffffff));
7230 		ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
7231 	} else {
7232 		/*
7233 		 * We always start out with values derived
7234 		 * from NVRAM or our platform default.
7235 		 */
7236 		ISP_PORTWWN(isp) = fcp->isp_wwpn_nvram;
7237 		if (fcp->isp_wwpn_nvram == 0) {
7238 			isp_prt(isp, ISP_LOGCONFIG,
7239 			    "bad WWPN- using default");
7240 			ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
7241 		}
7242 	}
7243 }
7244 
7245 /*
7246  * Re-initialize the ISP and complete all orphaned commands
7247  * with a 'botched' notice. The reset/init routines should
7248  * not disturb an already active list of commands.
7249  */
7250 
7251 void
7252 isp_reinit(ispsoftc_t *isp)
7253 {
7254 	XS_T *xs;
7255 	uint32_t tmp;
7256 
7257 	if (IS_FC(isp)) {
7258 		ISP_MARK_PORTDB(isp, 0);
7259 	}
7260 	isp_reset(isp);
7261 	if (isp->isp_state != ISP_RESETSTATE) {
7262 		isp_prt(isp, ISP_LOGERR, "isp_reinit cannot reset card");
7263 	} else if (isp->isp_role != ISP_ROLE_NONE) {
7264 		isp_init(isp);
7265 		if (isp->isp_state == ISP_INITSTATE) {
7266 			isp->isp_state = ISP_RUNSTATE;
7267 		}
7268 		if (isp->isp_state != ISP_RUNSTATE) {
7269 			isp_prt(isp, ISP_LOGERR,
7270 			    "isp_reinit cannot restart card");
7271 			ISP_DISABLE_INTS(isp);
7272 		}
7273 	} else {
7274 		ISP_DISABLE_INTS(isp);
7275 		if (IS_FC(isp)) {
7276 			/*
7277 			 * If we're in ISP_ROLE_NONE, turn off the lasers.
7278 			 */
7279 			if (!IS_24XX(isp)) {
7280 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
7281 				ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
7282 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
7283 				ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
7284 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
7285 			}
7286 		}
7287  	}
7288 	isp->isp_nactive = 0;
7289 
7290 	for (tmp = 0; tmp < isp->isp_maxcmds; tmp++) {
7291 		uint32_t handle;
7292 
7293 		xs = isp->isp_xflist[tmp];
7294 		if (xs == NULL) {
7295 			continue;
7296 		}
7297 		handle = isp_find_handle(isp, xs);
7298 		if (handle == 0) {
7299 			continue;
7300 		}
7301 		isp_destroy_handle(isp, handle);
7302 		if (XS_XFRLEN(xs)) {
7303 			ISP_DMAFREE(isp, xs, handle);
7304 			XS_RESID(xs) = XS_XFRLEN(xs);
7305 		} else {
7306 			XS_RESID(xs) = 0;
7307 		}
7308 		XS_SETERR(xs, HBA_BUSRESET);
7309 		isp_done(xs);
7310 	}
7311 #ifdef	ISP_TARGET_MODE
7312 	MEMZERO(isp->isp_tgtlist, isp->isp_maxcmds * sizeof (void **));
7313 #endif
7314 }
7315 
7316 /*
7317  * NVRAM Routines
7318  */
7319 static int
7320 isp_read_nvram(ispsoftc_t *isp)
7321 {
7322 	int i, amt, retval;
7323 	uint8_t csum, minversion;
7324 	union {
7325 		uint8_t _x[ISP2100_NVRAM_SIZE];
7326 		uint16_t _s[ISP2100_NVRAM_SIZE>>1];
7327 	} _n;
7328 #define	nvram_data	_n._x
7329 #define	nvram_words	_n._s
7330 
7331 	if (IS_24XX(isp)) {
7332 		return (isp_read_nvram_2400(isp));
7333 	} else if (IS_FC(isp)) {
7334 		amt = ISP2100_NVRAM_SIZE;
7335 		minversion = 1;
7336 	} else if (IS_ULTRA2(isp)) {
7337 		amt = ISP1080_NVRAM_SIZE;
7338 		minversion = 0;
7339 	} else {
7340 		amt = ISP_NVRAM_SIZE;
7341 		minversion = 2;
7342 	}
7343 
7344 	for (i = 0; i < amt>>1; i++) {
7345 		isp_rdnvram_word(isp, i, &nvram_words[i]);
7346 	}
7347 
7348 	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7349 	    nvram_data[2] != 'P') {
7350 		if (isp->isp_bustype != ISP_BT_SBUS) {
7351 			isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
7352 			isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x",
7353 			    nvram_data[0], nvram_data[1], nvram_data[2]);
7354 		}
7355 		retval = -1;
7356 		goto out;
7357 	}
7358 
7359 	for (csum = 0, i = 0; i < amt; i++) {
7360 		csum += nvram_data[i];
7361 	}
7362 	if (csum != 0) {
7363 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7364 		retval = -1;
7365 		goto out;
7366 	}
7367 
7368 	if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
7369 		isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
7370 		    ISP_NVRAM_VERSION(nvram_data));
7371 		retval = -1;
7372 		goto out;
7373 	}
7374 
7375 	if (IS_ULTRA3(isp)) {
7376 		isp_parse_nvram_12160(isp, 0, nvram_data);
7377 		if (IS_12160(isp))
7378 			isp_parse_nvram_12160(isp, 1, nvram_data);
7379 	} else if (IS_1080(isp)) {
7380 		isp_parse_nvram_1080(isp, 0, nvram_data);
7381 	} else if (IS_1280(isp) || IS_1240(isp)) {
7382 		isp_parse_nvram_1080(isp, 0, nvram_data);
7383 		isp_parse_nvram_1080(isp, 1, nvram_data);
7384 	} else if (IS_SCSI(isp)) {
7385 		isp_parse_nvram_1020(isp, nvram_data);
7386 	} else {
7387 		isp_parse_nvram_2100(isp, nvram_data);
7388 	}
7389 	retval = 0;
7390 out:
7391 	return (retval);
7392 #undef	nvram_data
7393 #undef	nvram_words
7394 }
7395 
7396 static int
7397 isp_read_nvram_2400(ispsoftc_t *isp)
7398 {
7399 	uint8_t *nvram_data = FCPARAM(isp)->isp_scratch;
7400 	int retval = 0;
7401 	uint32_t addr, csum, lwrds, *dptr;
7402 
7403 	if (isp->isp_port) {
7404 		addr = ISP2400_NVRAM_PORT1_ADDR;
7405 	} else {
7406 		addr = ISP2400_NVRAM_PORT0_ADDR;
7407 	}
7408 
7409 	dptr = (uint32_t *) nvram_data;
7410 	for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7411 		isp_rd_2400_nvram(isp, addr++, dptr++);
7412 	}
7413 	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7414 	    nvram_data[2] != 'P') {
7415 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
7416 		retval = -1;
7417 		goto out;
7418 	}
7419 	dptr = (uint32_t *) nvram_data;
7420 	for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7421 		csum += dptr[lwrds];
7422 	}
7423 	if (csum != 0) {
7424 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7425 		retval = -1;
7426 		goto out;
7427 	}
7428 	isp_parse_nvram_2400(isp, nvram_data);
7429 out:
7430 	return (retval);
7431 }
7432 
7433 static void
7434 isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
7435 {
7436 	int i, cbits;
7437 	uint16_t bit, rqst, junk;
7438 
7439 	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7440 	USEC_DELAY(10);
7441 	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7442 	USEC_DELAY(10);
7443 
7444 	if (IS_FC(isp)) {
7445 		wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
7446 		if (IS_2312(isp) && isp->isp_port) {
7447 			wo += 128;
7448 		}
7449 		rqst = (ISP_NVRAM_READ << 8) | wo;
7450 		cbits = 10;
7451 	} else if (IS_ULTRA2(isp)) {
7452 		wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
7453 		rqst = (ISP_NVRAM_READ << 8) | wo;
7454 		cbits = 10;
7455 	} else {
7456 		wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
7457 		rqst = (ISP_NVRAM_READ << 6) | wo;
7458 		cbits = 8;
7459 	}
7460 
7461 	/*
7462 	 * Clock the word select request out...
7463 	 */
7464 	for (i = cbits; i >= 0; i--) {
7465 		if ((rqst >> i) & 1) {
7466 			bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
7467 		} else {
7468 			bit = BIU_NVRAM_SELECT;
7469 		}
7470 		ISP_WRITE(isp, BIU_NVRAM, bit);
7471 		USEC_DELAY(10);
7472 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7473 		ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
7474 		USEC_DELAY(10);
7475 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7476 		ISP_WRITE(isp, BIU_NVRAM, bit);
7477 		USEC_DELAY(10);
7478 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7479 	}
7480 	/*
7481 	 * Now read the result back in (bits come back in MSB format).
7482 	 */
7483 	*rp = 0;
7484 	for (i = 0; i < 16; i++) {
7485 		uint16_t rv;
7486 		*rp <<= 1;
7487 		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7488 		USEC_DELAY(10);
7489 		rv = ISP_READ(isp, BIU_NVRAM);
7490 		if (rv & BIU_NVRAM_DATAIN) {
7491 			*rp |= 1;
7492 		}
7493 		USEC_DELAY(10);
7494 		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7495 		USEC_DELAY(10);
7496 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7497 	}
7498 	ISP_WRITE(isp, BIU_NVRAM, 0);
7499 	USEC_DELAY(10);
7500 	junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7501 	ISP_SWIZZLE_NVRAM_WORD(isp, rp);
7502 }
7503 
7504 static void
7505 isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
7506 {
7507 	int loops = 0;
7508 	const uint32_t base = 0x7ffe0000;
7509 	uint32_t tmp = 0;
7510 
7511 	ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
7512 	for (loops = 0; loops < 5000; loops++) {
7513 		USEC_DELAY(10);
7514 		tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
7515 		if ((tmp & (1U << 31)) != 0) {
7516 			break;
7517 		}
7518 	}
7519 	if (tmp & (1U << 31)) {
7520 		tmp = ISP_READ(isp, BIU2400_FLASH_DATA);
7521 		*rp = tmp;
7522 	} else {
7523 		*rp = 0xffffffff;
7524 	}
7525 }
7526 
7527 static void
7528 isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data)
7529 {
7530 	sdparam *sdp = (sdparam *) isp->isp_param;
7531 	int tgt;
7532 
7533 	sdp->isp_fifo_threshold =
7534 		ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
7535 		(ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
7536 
7537 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
7538 		sdp->isp_initiator_id =
7539 			ISP_NVRAM_INITIATOR_ID(nvram_data);
7540 
7541 	sdp->isp_bus_reset_delay =
7542 		ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
7543 
7544 	sdp->isp_retry_count =
7545 		ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
7546 
7547 	sdp->isp_retry_delay =
7548 		ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
7549 
7550 	sdp->isp_async_data_setup =
7551 		ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
7552 
7553 	if (isp->isp_type >= ISP_HA_SCSI_1040) {
7554 		if (sdp->isp_async_data_setup < 9) {
7555 			sdp->isp_async_data_setup = 9;
7556 		}
7557 	} else {
7558 		if (sdp->isp_async_data_setup != 6) {
7559 			sdp->isp_async_data_setup = 6;
7560 		}
7561 	}
7562 
7563 	sdp->isp_req_ack_active_neg =
7564 		ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
7565 
7566 	sdp->isp_data_line_active_neg =
7567 		ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
7568 
7569 	sdp->isp_data_dma_burst_enabl =
7570 		ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
7571 
7572 	sdp->isp_cmd_dma_burst_enable =
7573 		ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
7574 
7575 	sdp->isp_tag_aging =
7576 		ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
7577 
7578 	sdp->isp_selection_timeout =
7579 		ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
7580 
7581 	sdp->isp_max_queue_depth =
7582 		ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
7583 
7584 	sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
7585 
7586 	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
7587 	    0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
7588 	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
7589 	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
7590 	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
7591 	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
7592 	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
7593 	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
7594 
7595 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7596 		sdp->isp_devparam[tgt].dev_enable =
7597 			ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
7598 		sdp->isp_devparam[tgt].exc_throttle =
7599 			ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
7600 		sdp->isp_devparam[tgt].nvrm_offset =
7601 			ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
7602 		sdp->isp_devparam[tgt].nvrm_period =
7603 			ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
7604 		/*
7605 		 * We probably shouldn't lie about this, but it
7606 		 * it makes it much safer if we limit NVRAM values
7607 		 * to sanity.
7608 		 */
7609 		if (isp->isp_type < ISP_HA_SCSI_1040) {
7610 			/*
7611 			 * If we're not ultra, we can't possibly
7612 			 * be a shorter period than this.
7613 			 */
7614 			if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
7615 				sdp->isp_devparam[tgt].nvrm_period = 0x19;
7616 			}
7617 			if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
7618 				sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
7619 			}
7620 		} else {
7621 			if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
7622 				sdp->isp_devparam[tgt].nvrm_offset = 0x8;
7623 			}
7624 		}
7625 		sdp->isp_devparam[tgt].nvrm_flags = 0;
7626 		if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
7627 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
7628 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
7629 		if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
7630 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
7631 		if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
7632 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
7633 		if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
7634 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
7635 		if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
7636 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
7637 		if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
7638 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
7639 		sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
7640 		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
7641 		    0, tgt, sdp->isp_devparam[tgt].nvrm_flags,
7642 		    sdp->isp_devparam[tgt].nvrm_offset,
7643 		    sdp->isp_devparam[tgt].nvrm_period);
7644 		sdp->isp_devparam[tgt].goal_offset =
7645 		    sdp->isp_devparam[tgt].nvrm_offset;
7646 		sdp->isp_devparam[tgt].goal_period =
7647 		    sdp->isp_devparam[tgt].nvrm_period;
7648 		sdp->isp_devparam[tgt].goal_flags =
7649 		    sdp->isp_devparam[tgt].nvrm_flags;
7650 	}
7651 }
7652 
7653 static void
7654 isp_parse_nvram_1080(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
7655 {
7656 	sdparam *sdp = (sdparam *) isp->isp_param;
7657 	int tgt;
7658 
7659 	sdp += bus;
7660 
7661 	sdp->isp_fifo_threshold =
7662 	    ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
7663 
7664 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
7665 		sdp->isp_initiator_id =
7666 		    ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
7667 
7668 	sdp->isp_bus_reset_delay =
7669 	    ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
7670 
7671 	sdp->isp_retry_count =
7672 	    ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
7673 
7674 	sdp->isp_retry_delay =
7675 	    ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
7676 
7677 	sdp->isp_async_data_setup =
7678 	    ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
7679 
7680 	sdp->isp_req_ack_active_neg =
7681 	    ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
7682 
7683 	sdp->isp_data_line_active_neg =
7684 	    ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
7685 
7686 	sdp->isp_data_dma_burst_enabl =
7687 	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
7688 
7689 	sdp->isp_cmd_dma_burst_enable =
7690 	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
7691 
7692 	sdp->isp_selection_timeout =
7693 	    ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
7694 
7695 	sdp->isp_max_queue_depth =
7696 	     ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
7697 
7698 	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
7699 	    bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
7700 	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
7701 	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
7702 	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
7703 	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
7704 	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
7705 	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
7706 
7707 
7708 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7709 		sdp->isp_devparam[tgt].dev_enable =
7710 		    ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
7711 		sdp->isp_devparam[tgt].exc_throttle =
7712 			ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
7713 		sdp->isp_devparam[tgt].nvrm_offset =
7714 			ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
7715 		sdp->isp_devparam[tgt].nvrm_period =
7716 			ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
7717 		sdp->isp_devparam[tgt].nvrm_flags = 0;
7718 		if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
7719 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
7720 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
7721 		if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
7722 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
7723 		if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
7724 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
7725 		if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
7726 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
7727 		if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
7728 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
7729 		if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
7730 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
7731 		sdp->isp_devparam[tgt].actv_flags = 0;
7732 		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
7733 		    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
7734 		    sdp->isp_devparam[tgt].nvrm_offset,
7735 		    sdp->isp_devparam[tgt].nvrm_period);
7736 		sdp->isp_devparam[tgt].goal_offset =
7737 		    sdp->isp_devparam[tgt].nvrm_offset;
7738 		sdp->isp_devparam[tgt].goal_period =
7739 		    sdp->isp_devparam[tgt].nvrm_period;
7740 		sdp->isp_devparam[tgt].goal_flags =
7741 		    sdp->isp_devparam[tgt].nvrm_flags;
7742 	}
7743 }
7744 
7745 static void
7746 isp_parse_nvram_12160(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
7747 {
7748 	sdparam *sdp = (sdparam *) isp->isp_param;
7749 	int tgt;
7750 
7751 	sdp += bus;
7752 
7753 	sdp->isp_fifo_threshold =
7754 	    ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
7755 
7756 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
7757 		sdp->isp_initiator_id =
7758 		    ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
7759 
7760 	sdp->isp_bus_reset_delay =
7761 	    ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
7762 
7763 	sdp->isp_retry_count =
7764 	    ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
7765 
7766 	sdp->isp_retry_delay =
7767 	    ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
7768 
7769 	sdp->isp_async_data_setup =
7770 	    ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
7771 
7772 	sdp->isp_req_ack_active_neg =
7773 	    ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
7774 
7775 	sdp->isp_data_line_active_neg =
7776 	    ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
7777 
7778 	sdp->isp_data_dma_burst_enabl =
7779 	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
7780 
7781 	sdp->isp_cmd_dma_burst_enable =
7782 	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
7783 
7784 	sdp->isp_selection_timeout =
7785 	    ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
7786 
7787 	sdp->isp_max_queue_depth =
7788 	     ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
7789 
7790 	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
7791 	    bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
7792 	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
7793 	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
7794 	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
7795 	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
7796 	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
7797 	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
7798 
7799 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7800 		sdp->isp_devparam[tgt].dev_enable =
7801 		    ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
7802 		sdp->isp_devparam[tgt].exc_throttle =
7803 			ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
7804 		sdp->isp_devparam[tgt].nvrm_offset =
7805 			ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
7806 		sdp->isp_devparam[tgt].nvrm_period =
7807 			ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
7808 		sdp->isp_devparam[tgt].nvrm_flags = 0;
7809 		if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
7810 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
7811 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
7812 		if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
7813 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
7814 		if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
7815 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
7816 		if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
7817 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
7818 		if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
7819 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
7820 		if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
7821 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
7822 		sdp->isp_devparam[tgt].actv_flags = 0;
7823 		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
7824 		    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
7825 		    sdp->isp_devparam[tgt].nvrm_offset,
7826 		    sdp->isp_devparam[tgt].nvrm_period);
7827 		sdp->isp_devparam[tgt].goal_offset =
7828 		    sdp->isp_devparam[tgt].nvrm_offset;
7829 		sdp->isp_devparam[tgt].goal_period =
7830 		    sdp->isp_devparam[tgt].nvrm_period;
7831 		sdp->isp_devparam[tgt].goal_flags =
7832 		    sdp->isp_devparam[tgt].nvrm_flags;
7833 	}
7834 }
7835 
7836 static void
7837 isp_fix_nvram_wwns(ispsoftc_t *isp)
7838 {
7839 	fcparam *fcp = FCPARAM(isp);
7840 
7841 	/*
7842 	 * Make sure we have both Node and Port as non-zero values.
7843 	 */
7844 	if (fcp->isp_wwnn_nvram != 0 && fcp->isp_wwpn_nvram == 0) {
7845 		fcp->isp_wwpn_nvram = fcp->isp_wwnn_nvram;
7846 	} else if (fcp->isp_wwnn_nvram == 0 && fcp->isp_wwpn_nvram != 0) {
7847 		fcp->isp_wwnn_nvram = fcp->isp_wwpn_nvram;
7848 	}
7849 
7850 	/*
7851 	 * Make the Node and Port values sane if they're NAA == 2.
7852 	 * This means to clear bits 48..56 for the Node WWN and
7853 	 * make sure that there's some non-zero value in 48..56
7854 	 * for the Port WWN.
7855 	 */
7856 	if (fcp->isp_wwnn_nvram && fcp->isp_wwpn_nvram) {
7857 		if ((fcp->isp_wwnn_nvram & (((uint64_t) 0xfff) << 48)) != 0 &&
7858 		    (fcp->isp_wwnn_nvram >> 60) == 2) {
7859 			fcp->isp_wwnn_nvram &= ~((uint64_t) 0xfff << 48);
7860 		}
7861 		if ((fcp->isp_wwpn_nvram & (((uint64_t) 0xfff) << 48)) == 0 &&
7862 		    (fcp->isp_wwpn_nvram >> 60) == 2) {
7863 			fcp->isp_wwpn_nvram |= ((uint64_t) 1 << 56);
7864 		}
7865 	}
7866 }
7867 
7868 static void
7869 isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
7870 {
7871 	fcparam *fcp = FCPARAM(isp);
7872 	uint64_t wwn;
7873 
7874 	/*
7875 	 * There is NVRAM storage for both Port and Node entities-
7876 	 * but the Node entity appears to be unused on all the cards
7877 	 * I can find. However, we should account for this being set
7878 	 * at some point in the future.
7879 	 *
7880 	 * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
7881 	 * bits 48..60. In the case of the 2202, it appears that they do
7882 	 * use bit 48 to distinguish between the two instances on the card.
7883 	 * The 2204, which I've never seen, *probably* extends this method.
7884 	 */
7885 	wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
7886 	if (wwn) {
7887 		isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
7888 		    (uint32_t) (wwn >> 32), (uint32_t) (wwn & 0xffffffff));
7889 		if ((wwn >> 60) == 0) {
7890 			wwn |= (((uint64_t) 2)<< 60);
7891 		}
7892 	}
7893 	fcp->isp_wwpn_nvram = wwn;
7894 	if (IS_2200(isp) || IS_23XX(isp)) {
7895 		wwn = ISP2100_NVRAM_NODE_NAME(nvram_data);
7896 		if (wwn) {
7897 			isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
7898 			    (uint32_t) (wwn >> 32),
7899 			    (uint32_t) (wwn & 0xffffffff));
7900 			if ((wwn >> 60) == 0) {
7901 				wwn |= (((uint64_t) 2)<< 60);
7902 			}
7903 		}
7904 	} else {
7905 		wwn &= ~((uint64_t) 0xfff << 48);
7906 	}
7907 	fcp->isp_wwnn_nvram = wwn;
7908 
7909 	isp_fix_nvram_wwns(isp);
7910 
7911 	fcp->isp_maxalloc = ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
7912 	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
7913 		fcp->isp_maxfrmlen = ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
7914 	}
7915 	fcp->isp_retry_delay = ISP2100_NVRAM_RETRY_DELAY(nvram_data);
7916 	fcp->isp_retry_count = ISP2100_NVRAM_RETRY_COUNT(nvram_data);
7917 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
7918 		fcp->isp_loopid = ISP2100_NVRAM_HARDLOOPID(nvram_data);
7919 	}
7920 	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
7921 		fcp->isp_execthrottle =
7922 			ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
7923 	}
7924 	fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
7925 	isp_prt(isp, ISP_LOGDEBUG0,
7926 	    "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d",
7927 	    (uint32_t) (fcp->isp_wwnn_nvram >> 32), (uint32_t) fcp->isp_wwnn_nvram,
7928 	    (uint32_t) (fcp->isp_wwpn_nvram >> 32), (uint32_t) fcp->isp_wwpn_nvram,
7929 	    ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data),
7930 	    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data));
7931 	isp_prt(isp, ISP_LOGDEBUG0,
7932 	    "execthrottle %d fwoptions 0x%x hardloop %d tov %d",
7933 	    ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
7934 	    ISP2100_NVRAM_OPTIONS(nvram_data),
7935 	    ISP2100_NVRAM_HARDLOOPID(nvram_data),
7936 	    ISP2100_NVRAM_TOV(nvram_data));
7937 	fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data);
7938 	fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data);
7939 	isp_prt(isp, ISP_LOGDEBUG0,
7940 	    "xfwoptions 0x%x zfw options 0x%x",
7941 	    ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data));
7942 }
7943 
7944 static void
7945 isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
7946 {
7947 	fcparam *fcp = FCPARAM(isp);
7948 	uint64_t wwn;
7949 
7950 	isp_prt(isp, ISP_LOGDEBUG0,
7951 	    "NVRAM 0x%08x%08x 0x%08x%08x exchg_cnt %d maxframelen %d",
7952 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
7953 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
7954 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
7955 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
7956 	    ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data),
7957 	    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
7958 	isp_prt(isp, ISP_LOGDEBUG0,
7959 	    "NVRAM execthr %d loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
7960 	    ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data),
7961 	    ISP2400_NVRAM_HARDLOOPID(nvram_data),
7962 	    ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
7963 	    ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
7964 	    ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
7965 
7966 	wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
7967 	if (wwn) {
7968 		if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
7969 			wwn = 0;
7970 		}
7971 	}
7972 	fcp->isp_wwpn_nvram = wwn;
7973 
7974 	wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
7975 	if (wwn) {
7976 		if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
7977 			wwn = 0;
7978 		}
7979 	}
7980 	fcp->isp_wwnn_nvram = wwn;
7981 
7982 	isp_fix_nvram_wwns(isp);
7983 
7984 	if (ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data)) {
7985 		fcp->isp_maxalloc = ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data);
7986 	}
7987 	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
7988 		fcp->isp_maxfrmlen = ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
7989 	}
7990 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
7991 		fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
7992 	}
7993 	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
7994 		fcp->isp_execthrottle =
7995 			ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data);
7996 	}
7997 	fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
7998 	fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
7999 	fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
8000 }
8001 
8002 #ifdef	ISP_FW_CRASH_DUMP
8003 static void isp2200_fw_dump(ispsoftc_t *);
8004 static void isp2300_fw_dump(ispsoftc_t *);
8005 
8006 static void
8007 isp2200_fw_dump(ispsoftc_t *isp)
8008 {
8009 	int i, j;
8010 	mbreg_t mbs;
8011 	uint16_t *ptr;
8012 
8013 	MEMZERO(&mbs, sizeof (mbs));
8014 	ptr = FCPARAM(isp)->isp_dump_data;
8015 	if (ptr == NULL) {
8016 		isp_prt(isp, ISP_LOGERR,
8017 		   "No place to dump RISC registers and SRAM");
8018 		return;
8019 	}
8020 	if (*ptr++) {
8021 		isp_prt(isp, ISP_LOGERR,
8022 		   "dump area for RISC registers and SRAM already used");
8023 		return;
8024 	}
8025 	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
8026 	for (i = 0; i < 100; i++) {
8027 		USEC_DELAY(100);
8028 		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
8029 			break;
8030 		}
8031 	}
8032 	if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
8033 		/*
8034 		 * PBIU Registers
8035 		 */
8036 		for (i = 0; i < 8; i++) {
8037 			*ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
8038 		}
8039 
8040 		/*
8041 		 * Mailbox Registers
8042 		 */
8043 		for (i = 0; i < 8; i++) {
8044 			*ptr++ = ISP_READ(isp, MBOX_BLOCK + (i << 1));
8045 		}
8046 
8047 		/*
8048 		 * DMA Registers
8049 		 */
8050 		for (i = 0; i < 48; i++) {
8051 			*ptr++ = ISP_READ(isp, DMA_BLOCK + 0x20 + (i << 1));
8052 		}
8053 
8054 		/*
8055 		 * RISC H/W Registers
8056 		 */
8057 		ISP_WRITE(isp, BIU2100_CSR, 0);
8058 		for (i = 0; i < 16; i++) {
8059 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
8060 		}
8061 
8062 		/*
8063 		 * RISC GP Registers
8064 		 */
8065 		for (j = 0; j < 8; j++) {
8066 			ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 8));
8067 			for (i = 0; i < 16; i++) {
8068 				*ptr++ =
8069 				    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8070 			}
8071 		}
8072 
8073 		/*
8074 		 * Frame Buffer Hardware Registers
8075 		 */
8076 		ISP_WRITE(isp, BIU2100_CSR, 0x10);
8077 		for (i = 0; i < 16; i++) {
8078 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8079 		}
8080 
8081 		/*
8082 		 * Fibre Protocol Module 0 Hardware Registers
8083 		 */
8084 		ISP_WRITE(isp, BIU2100_CSR, 0x20);
8085 		for (i = 0; i < 64; i++) {
8086 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8087 		}
8088 
8089 		/*
8090 		 * Fibre Protocol Module 1 Hardware Registers
8091 		 */
8092 		ISP_WRITE(isp, BIU2100_CSR, 0x30);
8093 		for (i = 0; i < 64; i++) {
8094 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8095 		}
8096 	} else {
8097 		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
8098 		return;
8099 	}
8100 	isp_prt(isp, ISP_LOGALL,
8101 	   "isp_fw_dump: RISC registers dumped successfully");
8102 	ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
8103 	for (i = 0; i < 100; i++) {
8104 		USEC_DELAY(100);
8105 		if (ISP_READ(isp, OUTMAILBOX0) == 0) {
8106 			break;
8107 		}
8108 	}
8109 	if (ISP_READ(isp, OUTMAILBOX0) != 0) {
8110 		isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
8111 		return;
8112 	}
8113 	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
8114 	for (i = 0; i < 100; i++) {
8115 		USEC_DELAY(100);
8116 		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
8117 			break;
8118 		}
8119 	}
8120 	if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
8121 		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause After Reset");
8122 		return;
8123 	}
8124 	ISP_WRITE(isp, RISC_EMB, 0xf2);
8125 	ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
8126 	for (i = 0; i < 100; i++) {
8127 		USEC_DELAY(100);
8128 		if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
8129 			break;
8130 		}
8131 	}
8132 	ISP_ENABLE_INTS(isp);
8133 	mbs.param[0] = MBOX_READ_RAM_WORD;
8134 	mbs.param[1] = 0x1000;
8135 	isp->isp_mbxworkp = (void *) ptr;
8136 	isp->isp_mbxwrk0 = 0xefff;	/* continuation count */
8137 	isp->isp_mbxwrk1 = 0x1001;	/* next SRAM address */
8138 	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
8139 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
8140 		isp_prt(isp, ISP_LOGWARN,
8141 		    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
8142 		return;
8143 	}
8144 	ptr = isp->isp_mbxworkp;	/* finish fetch of final word */
8145 	*ptr++ = isp->isp_mboxtmp[2];
8146 	isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped successfully");
8147 	FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
8148 	(void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
8149 }
8150 
8151 static void
8152 isp2300_fw_dump(ispsoftc_t *isp)
8153 {
8154 	int i, j;
8155 	mbreg_t mbs;
8156 	uint16_t *ptr;
8157 
8158 	MEMZERO(&mbs, sizeof (mbs));
8159 	ptr = FCPARAM(isp)->isp_dump_data;
8160 	if (ptr == NULL) {
8161 		isp_prt(isp, ISP_LOGERR,
8162 		   "No place to dump RISC registers and SRAM");
8163 		return;
8164 	}
8165 	if (*ptr++) {
8166 		isp_prt(isp, ISP_LOGERR,
8167 		   "dump area for RISC registers and SRAM already used");
8168 		return;
8169 	}
8170 	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
8171 	for (i = 0; i < 100; i++) {
8172 		USEC_DELAY(100);
8173 		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
8174 			break;
8175 		}
8176 	}
8177 	if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
8178 		/*
8179 		 * PBIU registers
8180 		 */
8181 		for (i = 0; i < 8; i++) {
8182 			*ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
8183 		}
8184 
8185 		/*
8186 		 * ReqQ-RspQ-Risc2Host Status registers
8187 		 */
8188 		for (i = 0; i < 8; i++) {
8189 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x10 + (i << 1));
8190 		}
8191 
8192 		/*
8193 		 * Mailbox Registers
8194 		 */
8195 		for (i = 0; i < 32; i++) {
8196 			*ptr++ =
8197 			    ISP_READ(isp, PCI_MBOX_REGS2300_OFF + (i << 1));
8198 		}
8199 
8200 		/*
8201 		 * Auto Request Response DMA registers
8202 		 */
8203 		ISP_WRITE(isp, BIU2100_CSR, 0x40);
8204 		for (i = 0; i < 32; i++) {
8205 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8206 		}
8207 
8208 		/*
8209 		 * DMA registers
8210 		 */
8211 		ISP_WRITE(isp, BIU2100_CSR, 0x50);
8212 		for (i = 0; i < 48; i++) {
8213 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8214 		}
8215 
8216 		/*
8217 		 * RISC hardware registers
8218 		 */
8219 		ISP_WRITE(isp, BIU2100_CSR, 0);
8220 		for (i = 0; i < 16; i++) {
8221 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
8222 		}
8223 
8224 		/*
8225 		 * RISC GP? registers
8226 		 */
8227 		for (j = 0; j < 8; j++) {
8228 			ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 9));
8229 			for (i = 0; i < 16; i++) {
8230 				*ptr++ =
8231 				    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8232 			}
8233 		}
8234 
8235 		/*
8236 		 * frame buffer hardware registers
8237 		 */
8238 		ISP_WRITE(isp, BIU2100_CSR, 0x10);
8239 		for (i = 0; i < 64; i++) {
8240 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8241 		}
8242 
8243 		/*
8244 		 * FPM B0 hardware registers
8245 		 */
8246 		ISP_WRITE(isp, BIU2100_CSR, 0x20);
8247 		for (i = 0; i < 64; i++) {
8248 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8249 		}
8250 
8251 		/*
8252 		 * FPM B1 hardware registers
8253 		 */
8254 		ISP_WRITE(isp, BIU2100_CSR, 0x30);
8255 		for (i = 0; i < 64; i++) {
8256 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
8257 		}
8258 	} else {
8259 		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
8260 		return;
8261 	}
8262 	isp_prt(isp, ISP_LOGALL,
8263 	   "isp_fw_dump: RISC registers dumped successfully");
8264 	ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
8265 	for (i = 0; i < 100; i++) {
8266 		USEC_DELAY(100);
8267 		if (ISP_READ(isp, OUTMAILBOX0) == 0) {
8268 			break;
8269 		}
8270 	}
8271 	if (ISP_READ(isp, OUTMAILBOX0) != 0) {
8272 		isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
8273 		return;
8274 	}
8275 	ISP_ENABLE_INTS(isp);
8276 	MEMZERO(&mbs, sizeof (mbs));
8277 	mbs.param[0] = MBOX_READ_RAM_WORD;
8278 	mbs.param[1] = 0x800;
8279 	isp->isp_mbxworkp = (void *) ptr;
8280 	isp->isp_mbxwrk0 = 0xf7ff;	/* continuation count */
8281 	isp->isp_mbxwrk1 = 0x801;	/* next SRAM address */
8282 	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
8283 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
8284 		isp_prt(isp, ISP_LOGWARN,
8285 		    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
8286 		return;
8287 	}
8288 	ptr = isp->isp_mbxworkp;	/* finish fetch of final word */
8289 	*ptr++ = isp->isp_mboxtmp[2];
8290 	MEMZERO(&mbs, sizeof (mbs));
8291 	mbs.param[0] = MBOX_READ_RAM_WORD_EXTENDED;
8292 	mbs.param[8] = 1;
8293 	isp->isp_mbxworkp = (void *) ptr;
8294 	isp->isp_mbxwrk0 = 0xffff;	/* continuation count */
8295 	isp->isp_mbxwrk1 = 0x1;		/* next SRAM address */
8296 	isp->isp_mbxwrk8 = 0x1;
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", 0x10000 + isp->isp_mbxwrk1);
8301 		return;
8302 	}
8303 	ptr = isp->isp_mbxworkp;	/* finish final word */
8304 	*ptr++ = mbs.param[2];
8305 	isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped successfully");
8306 	FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
8307 	(void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
8308 }
8309 
8310 void
8311 isp_fw_dump(ispsoftc_t *isp)
8312 {
8313 	if (IS_2200(isp))
8314 		isp2200_fw_dump(isp);
8315 	else if (IS_23XX(isp))
8316 		isp2300_fw_dump(isp);
8317 	else if (IS_24XX(isp))
8318 		isp_prt(isp, ISP_LOGERR, "24XX dump method undefined");
8319 
8320 }
8321 #endif
8322