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