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