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