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