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