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