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