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