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