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