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