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