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