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