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