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