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