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