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