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