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