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