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