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