xref: /netbsd/sys/dev/ic/isp.c (revision 6550d01e)
1 /* $NetBSD: isp.c,v 1.121 2010/03/26 20:52:00 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.121 2010/03/26 20:52:00 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)));
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)));
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));
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));
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);
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);
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));
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);
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);
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);
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);
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);
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 != MBOX_LOOP_ID_USED) {
3941 			i = lim;
3942 			break;
3943 		} else if (r == MBOX_TIMEOUT) {
3944 			return (-1);
3945 		} else {
3946 			*ohp = handle;
3947 			handle = isp_nxt_handle(isp, chan, *ohp);
3948 		}
3949 	}
3950 
3951 	if (i == lim) {
3952 		isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed", chan, portid);
3953 		return (-1);
3954 	}
3955 
3956 	/*
3957 	 * If we successfully logged into it, get the PDB for it
3958 	 * so we can crosscheck that it is still what we think it
3959 	 * is and that we also have the role it plays
3960 	 */
3961 	r = isp_getpdb(isp, chan, handle, p, 0);
3962 	if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3963 		return (-1);
3964 	}
3965 	if (r != 0) {
3966 		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle);
3967 		return (-1);
3968 	}
3969 
3970 	if (p->handle != handle || p->portid != portid) {
3971 		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
3972 		    chan, portid, handle, p->portid, p->handle);
3973 		return (-1);
3974 	}
3975 	return (0);
3976 }
3977 
3978 static int
3979 isp_register_fc4_type(ispsoftc_t *isp, int chan)
3980 {
3981 	fcparam *fcp = FCPARAM(isp, chan);
3982 	uint8_t local[SNS_RFT_ID_REQ_SIZE];
3983 	sns_screq_t *reqp = (sns_screq_t *) local;
3984 	mbreg_t mbs;
3985 
3986 	ISP_MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
3987 	reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
3988 	reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
3989 	reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
3990 	reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
3991 	reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
3992 	reqp->snscb_sblen = 22;
3993 	reqp->snscb_data[0] = SNS_RFT_ID;
3994 	reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
3995 	reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
3996 	reqp->snscb_data[6] = (1 << FC4_SCSI);
3997 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
3998 		isp_prt(isp, ISP_LOGERR, sacq);
3999 		return (-1);
4000 	}
4001 	isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
4002 	MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 1000000);
4003 	mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
4004 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4005 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4006 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4007 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4008 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE);
4009 	isp_mboxcmd(isp, &mbs);
4010 	FC_SCRATCH_RELEASE(isp, chan);
4011 	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
4012 		return (0);
4013 	} else {
4014 		return (-1);
4015 	}
4016 }
4017 
4018 static int
4019 isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
4020 {
4021 	mbreg_t mbs;
4022 	fcparam *fcp = FCPARAM(isp, chan);
4023 	union {
4024 		isp_ct_pt_t plocal;
4025 		rft_id_t clocal;
4026 		uint8_t q[QENTRY_LEN];
4027 	} un;
4028 	isp_ct_pt_t *pt;
4029 	ct_hdr_t *ct;
4030 	rft_id_t *rp;
4031 	uint8_t *scp = fcp->isp_scratch;
4032 
4033 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4034 		isp_prt(isp, ISP_LOGERR, sacq);
4035 		return (-1);
4036 	}
4037 
4038 	/*
4039 	 * Build a Passthrough IOCB in memory.
4040 	 */
4041 	ISP_MEMZERO(un.q, QENTRY_LEN);
4042 	pt = &un.plocal;
4043 	pt->ctp_header.rqs_entry_count = 1;
4044 	pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
4045 	pt->ctp_handle = 0xffffffff;
4046 	pt->ctp_nphdl = fcp->isp_sns_hdl;
4047 	pt->ctp_cmd_cnt = 1;
4048 	pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
4049 	pt->ctp_time = 1;
4050 	pt->ctp_rsp_cnt = 1;
4051 	pt->ctp_rsp_bcnt = sizeof (ct_hdr_t);
4052 	pt->ctp_cmd_bcnt = sizeof (rft_id_t);
4053 	pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
4054 	pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
4055 	pt->ctp_dataseg[0].ds_count = sizeof (rft_id_t);
4056 	pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
4057 	pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
4058 	pt->ctp_dataseg[1].ds_count = sizeof (ct_hdr_t);
4059 	isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
4060 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
4061 		isp_print_bytes(isp, "IOCB CT Request", QENTRY_LEN, pt);
4062 	}
4063 
4064 	/*
4065 	 * Build the CT header and command in memory.
4066 	 *
4067 	 * Note that the CT header has to end up as Big Endian format in memory.
4068 	 */
4069 	ISP_MEMZERO(&un.clocal, sizeof (un.clocal));
4070 	ct = &un.clocal.rftid_hdr;
4071 	ct->ct_revision = CT_REVISION;
4072 	ct->ct_fcs_type = CT_FC_TYPE_FC;
4073 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
4074 	ct->ct_cmd_resp = SNS_RFT_ID;
4075 	ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
4076 	rp = &un.clocal;
4077 	rp->rftid_portid[0] = fcp->isp_portid >> 16;
4078 	rp->rftid_portid[1] = fcp->isp_portid >> 8;
4079 	rp->rftid_portid[2] = fcp->isp_portid;
4080 	rp->rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
4081 	isp_put_rft_id(isp, rp, (rft_id_t *) &scp[XTXOFF]);
4082 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
4083 		isp_print_bytes(isp, "CT Header", QENTRY_LEN, &scp[XTXOFF]);
4084 	}
4085 
4086 	ISP_MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
4087 
4088 	MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 1000000);
4089 	mbs.param[1] = QENTRY_LEN;
4090 	mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
4091 	mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
4092 	mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
4093 	mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
4094 	MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN);
4095 	isp_mboxcmd(isp, &mbs);
4096 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4097 		FC_SCRATCH_RELEASE(isp, chan);
4098 		return (-1);
4099 	}
4100 	MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN);
4101 	pt = &un.plocal;
4102 	isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
4103 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
4104 		isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
4105 	}
4106 	if (pt->ctp_status) {
4107 		FC_SCRATCH_RELEASE(isp, chan);
4108 		isp_prt(isp, ISP_LOGWARN,
4109 		    "Chan %d Register FC4 Type CT Passthrough returned 0x%x",
4110 		    chan, pt->ctp_status);
4111 		return (1);
4112 	}
4113 
4114 	isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct);
4115 	FC_SCRATCH_RELEASE(isp, chan);
4116 
4117 	if (ct->ct_cmd_resp == LS_RJT) {
4118 		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
4119 		    "Chan %d Register FC4 Type rejected", chan);
4120 		return (-1);
4121 	} else if (ct->ct_cmd_resp == LS_ACC) {
4122 		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
4123 		    "Chan %d Register FC4 Type accepted", chan);
4124 		return (0);
4125 	} else {
4126 		isp_prt(isp, ISP_LOGWARN,
4127 		    "Chan %d Register FC4 Type: 0x%x",
4128 		    chan, ct->ct_cmd_resp);
4129 		return (-1);
4130 	}
4131 }
4132 
4133 static uint16_t
4134 isp_nxt_handle(ispsoftc_t *isp, int chan, uint16_t handle)
4135 {
4136 	int i;
4137 	if (handle == NIL_HANDLE) {
4138 		if (FCPARAM(isp, chan)->isp_topo == TOPO_F_PORT) {
4139 			handle = 0;
4140 		} else {
4141 			handle = SNS_ID+1;
4142 		}
4143 	} else {
4144 		handle += 1;
4145 		if (handle >= FL_ID && handle <= SNS_ID) {
4146 			handle = SNS_ID+1;
4147 		}
4148 		if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
4149 			handle = NPH_FL_ID+1;
4150 		}
4151 		if (ISP_CAP_2KLOGIN(isp)) {
4152 			if (handle == NPH_MAX_2K) {
4153 				handle = 0;
4154 			}
4155 		} else {
4156 			if (handle == NPH_MAX) {
4157 				handle = 0;
4158 			}
4159 		}
4160 	}
4161 	if (handle == FCPARAM(isp, chan)->isp_loopid) {
4162 		return (isp_nxt_handle(isp, chan, handle));
4163 	}
4164 	for (i = 0; i < MAX_FC_TARG; i++) {
4165 		if (FCPARAM(isp, chan)->portdb[i].state ==
4166 		    FC_PORTDB_STATE_NIL) {
4167 			continue;
4168 		}
4169 		if (FCPARAM(isp, chan)->portdb[i].handle == handle) {
4170 			return (isp_nxt_handle(isp, chan, handle));
4171 		}
4172 	}
4173 	return (handle);
4174 }
4175 
4176 /*
4177  * Start a command. Locking is assumed done in the caller.
4178  */
4179 
4180 int
4181 isp_start(XS_T *xs)
4182 {
4183 	ispsoftc_t *isp;
4184 	uint32_t handle;
4185 	uint8_t local[QENTRY_LEN];
4186 	ispreq_t *reqp;
4187 	void *cdbp, *qep;
4188 	uint16_t *tptr;
4189 	int target, dmaresult, hdlidx = 0;
4190 
4191 	XS_INITERR(xs);
4192 	isp = XS_ISP(xs);
4193 
4194 	/*
4195 	 * Now make sure we're running.
4196 	 */
4197 
4198 	if (isp->isp_state != ISP_RUNSTATE) {
4199 		isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
4200 		XS_SETERR(xs, HBA_BOTCH);
4201 		return (CMD_COMPLETE);
4202 	}
4203 
4204 	/*
4205 	 * Check command CDB length, etc.. We really are limited to 16 bytes
4206 	 * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
4207 	 * but probably only if we're running fairly new firmware (we'll
4208 	 * let the old f/w choke on an extended command queue entry).
4209 	 */
4210 
4211 	if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
4212 		isp_prt(isp, ISP_LOGERR, "unsupported cdb length (%d, CDB[0]=0x%x)", XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
4213 		XS_SETERR(xs, HBA_BOTCH);
4214 		return (CMD_COMPLETE);
4215 	}
4216 
4217 	/*
4218 	 * Translate the target to device handle as appropriate, checking
4219 	 * for correct device state as well.
4220 	 */
4221 	target = XS_TGT(xs);
4222 	if (IS_FC(isp)) {
4223 		fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
4224 
4225 		if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
4226 			XS_SETERR(xs, HBA_SELTIMEOUT);
4227 			return (CMD_COMPLETE);
4228 		}
4229 
4230 		/*
4231 		 * Try again later.
4232 		 */
4233 		if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate != LOOP_READY) {
4234 			return (CMD_RQLATER);
4235 		}
4236 
4237 		if (XS_TGT(xs) >= MAX_FC_TARG) {
4238 			XS_SETERR(xs, HBA_SELTIMEOUT);
4239 			return (CMD_COMPLETE);
4240 		}
4241 
4242 		hdlidx = fcp->isp_dev_map[XS_TGT(xs)] - 1;
4243 		isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d- hdlidx value %d", XS_TGT(xs), hdlidx);
4244 		if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
4245 			XS_SETERR(xs, HBA_SELTIMEOUT);
4246 			return (CMD_COMPLETE);
4247 		}
4248 		if (fcp->portdb[hdlidx].state == FC_PORTDB_STATE_ZOMBIE) {
4249 			return (CMD_RQLATER);
4250 		}
4251 		if (fcp->portdb[hdlidx].state != FC_PORTDB_STATE_VALID) {
4252 			XS_SETERR(xs, HBA_SELTIMEOUT);
4253 			return (CMD_COMPLETE);
4254 		}
4255 		target = fcp->portdb[hdlidx].handle;
4256 		fcp->portdb[hdlidx].dirty = 1;
4257 	} else {
4258 		sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
4259 		if ((sdp->role & ISP_ROLE_INITIATOR) == 0) {
4260 			XS_SETERR(xs, HBA_SELTIMEOUT);
4261 			return (CMD_COMPLETE);
4262 		}
4263 		if (sdp->update) {
4264 			isp_spi_update(isp, XS_CHANNEL(xs));
4265 		}
4266 	}
4267 
4268  start_again:
4269 
4270 	qep = isp_getrqentry(isp);
4271 	if (qep == NULL) {
4272 		isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
4273 		XS_SETERR(xs, HBA_BOTCH);
4274 		return (CMD_EAGAIN);
4275 	}
4276 	XS_SETERR(xs, HBA_NOERROR);
4277 
4278 	/*
4279 	 * Now see if we need to synchronize the ISP with respect to anything.
4280 	 * We do dual duty here (cough) for synchronizing for busses other
4281 	 * than which we got here to send a command to.
4282 	 */
4283 	reqp = (ispreq_t *) local;
4284 	ISP_MEMZERO(local, QENTRY_LEN);
4285 	if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) {
4286 		if (IS_24XX(isp)) {
4287 			isp_marker_24xx_t *m = (isp_marker_24xx_t *) reqp;
4288 			m->mrk_header.rqs_entry_count = 1;
4289 			m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
4290 			m->mrk_modifier = SYNC_ALL;
4291 			isp_put_marker_24xx(isp, m, qep);
4292 		} else {
4293 			isp_marker_t *m = (isp_marker_t *) reqp;
4294 			m->mrk_header.rqs_entry_count = 1;
4295 			m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
4296 			m->mrk_target = (XS_CHANNEL(xs) << 7);	/* bus # */
4297 			m->mrk_modifier = SYNC_ALL;
4298 			isp_put_marker(isp, m, qep);
4299 		}
4300 		ISP_SYNC_REQUEST(isp);
4301 		ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 0);
4302 		goto start_again;
4303 	}
4304 
4305 	reqp->req_header.rqs_entry_count = 1;
4306 	if (IS_24XX(isp)) {
4307 		reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
4308 	} else if (IS_FC(isp)) {
4309 		reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
4310 	} else {
4311 		if (XS_CDBLEN(xs) > 12) {
4312 			reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
4313 		} else {
4314 			reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
4315 		}
4316 	}
4317 	/* reqp->req_header.rqs_flags = 0; */
4318 	/* reqp->req_header.rqs_seqno = 0; */
4319 	if (IS_24XX(isp)) {
4320 		int ttype;
4321 		if (XS_TAG_P(xs)) {
4322 			ttype = XS_TAG_TYPE(xs);
4323 		} else {
4324 			if (XS_CDBP(xs)[0] == 0x3) {
4325 				ttype = REQFLAG_HTAG;
4326 			} else {
4327 				ttype = REQFLAG_STAG;
4328 			}
4329 		}
4330 		if (ttype == REQFLAG_OTAG) {
4331 			ttype = FCP_CMND_TASK_ATTR_ORDERED;
4332 		} else if (ttype == REQFLAG_HTAG) {
4333 			ttype = FCP_CMND_TASK_ATTR_HEAD;
4334 		} else {
4335 			ttype = FCP_CMND_TASK_ATTR_SIMPLE;
4336 		}
4337 		((ispreqt7_t *)reqp)->req_task_attribute = ttype;
4338 	} else if (IS_FC(isp)) {
4339 		/*
4340 		 * See comment in isp_intr
4341 		 */
4342 		/* XS_SET_RESID(xs, 0); */
4343 
4344 		/*
4345 		 * Fibre Channel always requires some kind of tag.
4346 		 * The Qlogic drivers seem be happy not to use a tag,
4347 		 * but this breaks for some devices (IBM drives).
4348 		 */
4349 		if (XS_TAG_P(xs)) {
4350 			((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
4351 		} else {
4352 			/*
4353 			 * If we don't know what tag to use, use HEAD OF QUEUE
4354 			 * for Request Sense or Simple.
4355 			 */
4356 			if (XS_CDBP(xs)[0] == 0x3)	/* REQUEST SENSE */
4357 				((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
4358 			else
4359 				((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
4360 		}
4361 	} else {
4362 		sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
4363 		if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) && XS_TAG_P(xs)) {
4364 			reqp->req_flags = XS_TAG_TYPE(xs);
4365 		}
4366 	}
4367 	cdbp = reqp->req_cdb;
4368 	tptr = &reqp->req_time;
4369 
4370 	if (IS_SCSI(isp)) {
4371 		reqp->req_target = target | (XS_CHANNEL(xs) << 7);
4372 		reqp->req_lun_trn = XS_LUN(xs);
4373 		reqp->req_cdblen = XS_CDBLEN(xs);
4374 	} else if (IS_24XX(isp)) {
4375 		fcportdb_t *lp;
4376 
4377 		lp = &FCPARAM(isp, XS_CHANNEL(xs))->portdb[hdlidx];
4378 		((ispreqt7_t *)reqp)->req_nphdl = target;
4379 		((ispreqt7_t *)reqp)->req_tidlo = lp->portid;
4380 		((ispreqt7_t *)reqp)->req_tidhi = lp->portid >> 16;
4381 		((ispreqt7_t *)reqp)->req_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(xs));
4382 		if (XS_LUN(xs) > 256) {
4383 			((ispreqt7_t *)reqp)->req_lun[0] = XS_LUN(xs) >> 8;
4384 			((ispreqt7_t *)reqp)->req_lun[0] |= 0x40;
4385 		}
4386 		((ispreqt7_t *)reqp)->req_lun[1] = XS_LUN(xs);
4387 		cdbp = ((ispreqt7_t *)reqp)->req_cdb;
4388 		tptr = &((ispreqt7_t *)reqp)->req_time;
4389 	} else if (ISP_CAP_2KLOGIN(isp)) {
4390 		((ispreqt2e_t *)reqp)->req_target = target;
4391 		((ispreqt2e_t *)reqp)->req_scclun = XS_LUN(xs);
4392 	} else if (ISP_CAP_SCCFW(isp)) {
4393 		((ispreqt2_t *)reqp)->req_target = target;
4394 		((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
4395 	} else {
4396 		((ispreqt2_t *)reqp)->req_target = target;
4397 		((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
4398 	}
4399 	ISP_MEMCPY(cdbp, XS_CDBP(xs), XS_CDBLEN(xs));
4400 
4401 	*tptr = XS_TIME(xs) / 1000;
4402 	if (*tptr == 0 && XS_TIME(xs)) {
4403 		*tptr = 1;
4404 	}
4405 	if (IS_24XX(isp) && *tptr > 0x1999) {
4406 		*tptr = 0x1999;
4407 	}
4408 
4409 	if (isp_allocate_xs(isp, xs, &handle)) {
4410 		isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
4411 		XS_SETERR(xs, HBA_BOTCH);
4412 		return (CMD_EAGAIN);
4413 	}
4414 	/* Whew. Thankfully the same for type 7 requests */
4415 	reqp->req_handle = handle;
4416 
4417 	/*
4418 	 * Set up DMA and/or do any platform dependent swizzling of the request entry
4419 	 * so that the Qlogic F/W understands what is being asked of it.
4420 	 *
4421 	 * The callee is responsible for adding all requests at this point.
4422 	 */
4423 	dmaresult = ISP_DMASETUP(isp, xs, reqp);
4424 	if (dmaresult != CMD_QUEUED) {
4425 		isp_destroy_handle(isp, handle);
4426 		/*
4427 		 * dmasetup sets actual error in packet, and
4428 		 * return what we were given to return.
4429 		 */
4430 		return (dmaresult);
4431 	}
4432 	isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "START cmd cdb[0]=0x%x datalen %ld", XS_CDBP(xs)[0], (long) XS_XFRLEN(xs));
4433 	isp->isp_nactive++;
4434 	return (CMD_QUEUED);
4435 }
4436 
4437 /*
4438  * isp control
4439  * Locks (ints blocked) assumed held.
4440  */
4441 
4442 int
4443 isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
4444 {
4445 	XS_T *xs;
4446 	mbreg_t *mbr, mbs;
4447 	int chan, tgt;
4448 	uint32_t handle;
4449 	va_list ap;
4450 
4451 	switch (ctl) {
4452 	case ISPCTL_RESET_BUS:
4453 		/*
4454 		 * Issue a bus reset.
4455 		 */
4456 		if (IS_24XX(isp)) {
4457 			isp_prt(isp, ISP_LOGWARN, "RESET BUS NOT IMPLEMENTED");
4458 			break;
4459 		} else if (IS_FC(isp)) {
4460 			mbs.param[1] = 10;
4461 			chan = 0;
4462 		} else {
4463 			va_start(ap, ctl);
4464 			chan = va_arg(ap, int);
4465 			va_end(ap);
4466 			mbs.param[1] = SDPARAM(isp, chan)->isp_bus_reset_delay;
4467 			if (mbs.param[1] < 2) {
4468 				mbs.param[1] = 2;
4469 			}
4470 			mbs.param[2] = chan;
4471 		}
4472 		MBSINIT(&mbs, MBOX_BUS_RESET, MBLOGALL, 0);
4473 		ISP_SET_SENDMARKER(isp, chan, 1);
4474 		isp_mboxcmd(isp, &mbs);
4475 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4476 			break;
4477 		}
4478 		isp_prt(isp, ISP_LOGINFO,
4479 		    "driver initiated bus reset of bus %d", chan);
4480 		return (0);
4481 
4482 	case ISPCTL_RESET_DEV:
4483 		va_start(ap, ctl);
4484 		chan = va_arg(ap, int);
4485 		tgt = va_arg(ap, int);
4486 		va_end(ap);
4487 		if (IS_24XX(isp)) {
4488 			uint8_t local[QENTRY_LEN];
4489 			isp24xx_tmf_t *tmf;
4490 			isp24xx_statusreq_t *sp;
4491 			fcparam *fcp = FCPARAM(isp, chan);
4492 			fcportdb_t *lp;
4493 			int hdlidx;
4494 
4495 			hdlidx = fcp->isp_dev_map[tgt] - 1;
4496 			if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
4497 				isp_prt(isp, ISP_LOGWARN,
4498 				    "Chan %d bad handle %d trying to reset"
4499 				    "target %d", chan, hdlidx, tgt);
4500 				break;
4501 			}
4502 			lp = &fcp->portdb[hdlidx];
4503 			if (lp->state != FC_PORTDB_STATE_VALID) {
4504 				isp_prt(isp, ISP_LOGWARN,
4505 				    "Chan %d handle %d for abort of target %d "
4506 				    "no longer valid", chan,
4507 				    hdlidx, tgt);
4508 				break;
4509 			}
4510 
4511 			tmf = (isp24xx_tmf_t *) local;
4512 			ISP_MEMZERO(tmf, QENTRY_LEN);
4513 			tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
4514 			tmf->tmf_header.rqs_entry_count = 1;
4515 			tmf->tmf_nphdl = lp->handle;
4516 			tmf->tmf_delay = 2;
4517 			tmf->tmf_timeout = 2;
4518 			tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
4519 			tmf->tmf_tidlo = lp->portid;
4520 			tmf->tmf_tidhi = lp->portid >> 16;
4521 			tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
4522 			isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
4523 			MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
4524 			mbs.param[1] = QENTRY_LEN;
4525 			mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4526 			mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4527 			mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4528 			mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4529 
4530 			if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4531 				isp_prt(isp, ISP_LOGERR, sacq);
4532 				break;
4533 			}
4534 			isp_put_24xx_tmf(isp, tmf, fcp->isp_scratch);
4535 			MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN);
4536 			fcp->sendmarker = 1;
4537 			isp_mboxcmd(isp, &mbs);
4538 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4539 				FC_SCRATCH_RELEASE(isp, chan);
4540 				break;
4541 			}
4542 			MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
4543 			    QENTRY_LEN);
4544 			sp = (isp24xx_statusreq_t *) local;
4545 			isp_get_24xx_response(isp,
4546 			    &((isp24xx_statusreq_t *)fcp->isp_scratch)[1], sp);
4547 			FC_SCRATCH_RELEASE(isp, chan);
4548 			if (sp->req_completion_status == 0) {
4549 				return (0);
4550 			}
4551 			isp_prt(isp, ISP_LOGWARN,
4552 			    "Chan %d reset of target %d returned 0x%x",
4553 			    chan, tgt, sp->req_completion_status);
4554 			break;
4555 		} else if (IS_FC(isp)) {
4556 			if (ISP_CAP_2KLOGIN(isp)) {
4557 				mbs.param[1] = tgt;
4558 				mbs.ibits = (1 << 10);
4559 			} else {
4560 				mbs.param[1] = (tgt << 8);
4561 			}
4562 		} else {
4563 			mbs.param[1] = (chan << 15) | (tgt << 8);
4564 		}
4565 		MBSINIT(&mbs, MBOX_ABORT_TARGET, MBLOGALL, 0);
4566 		mbs.param[2] = 3;	/* 'delay', in seconds */
4567 		isp_mboxcmd(isp, &mbs);
4568 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4569 			break;
4570 		}
4571 		isp_prt(isp, ISP_LOGINFO,
4572 		    "Target %d on Bus %d Reset Succeeded", tgt, chan);
4573 		ISP_SET_SENDMARKER(isp, chan, 1);
4574 		return (0);
4575 
4576 	case ISPCTL_ABORT_CMD:
4577 		va_start(ap, ctl);
4578 		xs = va_arg(ap, XS_T *);
4579 		va_end(ap);
4580 
4581 		tgt = XS_TGT(xs);
4582 		chan = XS_CHANNEL(xs);
4583 
4584 		handle = isp_find_handle(isp, xs);
4585 		if (handle == 0) {
4586 			isp_prt(isp, ISP_LOGWARN,
4587 			    "cannot find handle for command to abort");
4588 			break;
4589 		}
4590 		if (IS_24XX(isp)) {
4591 			isp24xx_abrt_t local, *ab = &local, *ab2;
4592 			fcparam *fcp;
4593 			fcportdb_t *lp;
4594 			int hdlidx;
4595 
4596 			fcp = FCPARAM(isp, chan);
4597 			hdlidx = fcp->isp_dev_map[tgt] - 1;
4598 			if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
4599 				isp_prt(isp, ISP_LOGWARN,
4600 				    "Chan %d bad handle %d trying to abort"
4601 				    "target %d", chan, hdlidx, tgt);
4602 				break;
4603 			}
4604 			lp = &fcp->portdb[hdlidx];
4605 			if (lp->state != FC_PORTDB_STATE_VALID) {
4606 				isp_prt(isp, ISP_LOGWARN,
4607 				    "Chan %d handle %d for abort of target %d "
4608 				    "no longer valid", chan, hdlidx, tgt);
4609 				break;
4610 			}
4611 			isp_prt(isp, ISP_LOGALL,
4612 			    "Chan %d Abort Cmd for N-Port 0x%04x @ Port "
4613 			    "0x%06x %p", chan, lp->handle, lp->portid, xs);
4614 			ISP_MEMZERO(ab, QENTRY_LEN);
4615 			ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO;
4616 			ab->abrt_header.rqs_entry_count = 1;
4617 			ab->abrt_handle = lp->handle;
4618 			ab->abrt_cmd_handle = handle;
4619 			ab->abrt_tidlo = lp->portid;
4620 			ab->abrt_tidhi = lp->portid >> 16;
4621 			ab->abrt_vpidx = ISP_GET_VPIDX(isp, chan);
4622 
4623 			ISP_MEMZERO(&mbs, sizeof (mbs));
4624 			MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
4625 			mbs.param[1] = QENTRY_LEN;
4626 			mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4627 			mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4628 			mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4629 			mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4630 
4631 			if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4632 				isp_prt(isp, ISP_LOGERR, sacq);
4633 				break;
4634 			}
4635 			isp_put_24xx_abrt(isp, ab, fcp->isp_scratch);
4636 			ab2 = (isp24xx_abrt_t *)
4637 			    &((uint8_t *)fcp->isp_scratch)[QENTRY_LEN];
4638 			ab2->abrt_nphdl = 0xdeaf;
4639 			MEMORYBARRIER(isp, SYNC_SFORDEV, 0, 2 * QENTRY_LEN);
4640 			isp_mboxcmd(isp, &mbs);
4641 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4642 				FC_SCRATCH_RELEASE(isp, chan);
4643 				break;
4644 			}
4645 			MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
4646 			    QENTRY_LEN);
4647 			isp_get_24xx_abrt(isp, ab2, ab);
4648 			FC_SCRATCH_RELEASE(isp, chan);
4649 			if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY) {
4650 				return (0);
4651 			}
4652 			isp_prt(isp, ISP_LOGWARN,
4653 			    "Chan %d handle %d abort returned 0x%x", chan,
4654 			    hdlidx, ab->abrt_nphdl);
4655 			break;
4656 		} else if (IS_FC(isp)) {
4657 			if (ISP_CAP_SCCFW(isp)) {
4658 				if (ISP_CAP_2KLOGIN(isp)) {
4659 					mbs.param[1] = tgt;
4660 				} else {
4661 					mbs.param[1] = tgt << 8;
4662 				}
4663 				mbs.param[6] = XS_LUN(xs);
4664 			} else {
4665 				mbs.param[1] = tgt << 8 | XS_LUN(xs);
4666 			}
4667 		} else {
4668 			mbs.param[1] = (chan << 15) | (tgt << 8) | XS_LUN(xs);
4669 		}
4670 		MBSINIT(&mbs, MBOX_ABORT, MBLOGALL & ~MBOX_COMMAND_ERROR, 0);
4671 		mbs.param[2] = handle;
4672 		isp_mboxcmd(isp, &mbs);
4673 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4674 			break;
4675 		}
4676 		return (0);
4677 
4678 	case ISPCTL_UPDATE_PARAMS:
4679 
4680 		va_start(ap, ctl);
4681 		chan = va_arg(ap, int);
4682 		va_end(ap);
4683 		isp_spi_update(isp, chan);
4684 		return (0);
4685 
4686 	case ISPCTL_FCLINK_TEST:
4687 
4688 		if (IS_FC(isp)) {
4689 			int usdelay;
4690 			va_start(ap, ctl);
4691 			chan = va_arg(ap, int);
4692 			usdelay = va_arg(ap, int);
4693 			va_end(ap);
4694 			if (usdelay == 0) {
4695 				usdelay =  250000;
4696 			}
4697 			return (isp_fclink_test(isp, chan, usdelay));
4698 		}
4699 		break;
4700 
4701 	case ISPCTL_SCAN_FABRIC:
4702 
4703 		if (IS_FC(isp)) {
4704 			va_start(ap, ctl);
4705 			chan = va_arg(ap, int);
4706 			va_end(ap);
4707 			return (isp_scan_fabric(isp, chan));
4708 		}
4709 		break;
4710 
4711 	case ISPCTL_SCAN_LOOP:
4712 
4713 		if (IS_FC(isp)) {
4714 			va_start(ap, ctl);
4715 			chan = va_arg(ap, int);
4716 			va_end(ap);
4717 			return (isp_scan_loop(isp, chan));
4718 		}
4719 		break;
4720 
4721 	case ISPCTL_PDB_SYNC:
4722 
4723 		if (IS_FC(isp)) {
4724 			va_start(ap, ctl);
4725 			chan = va_arg(ap, int);
4726 			va_end(ap);
4727 			return (isp_pdb_sync(isp, chan));
4728 		}
4729 		break;
4730 
4731 	case ISPCTL_SEND_LIP:
4732 
4733 		if (IS_FC(isp) && !IS_24XX(isp)) {
4734 			MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
4735 			if (ISP_CAP_2KLOGIN(isp)) {
4736 				mbs.ibits = (1 << 10);
4737 			}
4738 			isp_mboxcmd(isp, &mbs);
4739 			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
4740 				return (0);
4741 			}
4742 		}
4743 		break;
4744 
4745 	case ISPCTL_GET_PDB:
4746 		if (IS_FC(isp)) {
4747 			isp_pdb_t *pdb;
4748 			va_start(ap, ctl);
4749 			chan = va_arg(ap, int);
4750 			tgt = va_arg(ap, int);
4751 			pdb = va_arg(ap, isp_pdb_t *);
4752 			va_end(ap);
4753 			return (isp_getpdb(isp, chan, tgt, pdb, 1));
4754 		}
4755 		break;
4756 
4757 	case ISPCTL_GET_NAMES:
4758 	{
4759 		uint64_t *wwnn, *wwnp;
4760 		va_start(ap, ctl);
4761 		chan = va_arg(ap, int);
4762 		tgt = va_arg(ap, int);
4763 		wwnn = va_arg(ap, uint64_t *);
4764 		wwnp = va_arg(ap, uint64_t *);
4765 		va_end(ap);
4766 		if (wwnn == NULL && wwnp == NULL) {
4767 			break;
4768 		}
4769 		if (wwnn) {
4770 			*wwnn = isp_get_wwn(isp, chan, tgt, 1);
4771 			if (*wwnn == INI_NONE) {
4772 				break;
4773 			}
4774 		}
4775 		if (wwnp) {
4776 			*wwnp = isp_get_wwn(isp, chan, tgt, 0);
4777 			if (*wwnp == INI_NONE) {
4778 				break;
4779 			}
4780 		}
4781 		return (0);
4782 	}
4783 	case ISPCTL_RUN_MBOXCMD:
4784 	{
4785 		va_start(ap, ctl);
4786 		mbr = va_arg(ap, mbreg_t *);
4787 		va_end(ap);
4788 		isp_mboxcmd(isp, mbr);
4789 		return (0);
4790 	}
4791 	case ISPCTL_PLOGX:
4792 	{
4793 		isp_plcmd_t *p;
4794 		int r;
4795 
4796 		va_start(ap, ctl);
4797 		p = va_arg(ap, isp_plcmd_t *);
4798 		va_end(ap);
4799 
4800 		if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) {
4801 			return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0));
4802 		}
4803 		do {
4804 			p->handle = isp_nxt_handle(isp, p->channel, p->handle);
4805 			r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0);
4806 			if ((r & 0xffff) == MBOX_PORT_ID_USED) {
4807 				p->handle = r >> 16;
4808 				r = 0;
4809 				break;
4810 			}
4811 		} while ((r & 0xffff) == MBOX_LOOP_ID_USED);
4812 		return (r);
4813 	}
4814 	default:
4815 		isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
4816 		break;
4817 
4818 	}
4819 	return (-1);
4820 }
4821 
4822 /*
4823  * Interrupt Service Routine(s).
4824  *
4825  * External (OS) framework has done the appropriate locking,
4826  * and the locking will be held throughout this function.
4827  */
4828 
4829 /*
4830  * Limit our stack depth by sticking with the max likely number
4831  * of completions on a request queue at any one time.
4832  */
4833 #ifndef	MAX_REQUESTQ_COMPLETIONS
4834 #define	MAX_REQUESTQ_COMPLETIONS	32
4835 #endif
4836 
4837 void
4838 isp_intr(ispsoftc_t *isp, uint32_t isr, uint16_t sema, uint16_t mbox)
4839 {
4840 	XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
4841 	uint32_t iptr, optr, junk;
4842 	int i, nlooked = 0, ndone = 0;
4843 
4844 again:
4845 	optr = isp->isp_residx;
4846 	/*
4847 	 * Is this a mailbox related interrupt?
4848 	 * The mailbox semaphore will be nonzero if so.
4849 	 */
4850 	if (sema) {
4851  fmbox:
4852 		if (mbox & MBOX_COMMAND_COMPLETE) {
4853 			isp->isp_intmboxc++;
4854 			if (isp->isp_mboxbsy) {
4855 				int obits = isp->isp_obits;
4856 				isp->isp_mboxtmp[0] = mbox;
4857 				for (i = 1; i < MAX_MAILBOX(isp); i++) {
4858 					if ((obits & (1 << i)) == 0) {
4859 						continue;
4860 					}
4861 					isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
4862 				}
4863 				if (isp->isp_mbxwrk0) {
4864 					if (isp_mbox_continue(isp) == 0) {
4865 						return;
4866 					}
4867 				}
4868 				MBOX_NOTIFY_COMPLETE(isp);
4869 			} else {
4870 				isp_prt(isp, ISP_LOGWARN, "mailbox cmd (0x%x) with no waiters", mbox);
4871 			}
4872 		} else {
4873 			i = IS_FC(isp)? isp_parse_async_fc(isp, mbox) : isp_parse_async(isp, mbox);
4874 			if (i < 0) {
4875 				return;
4876 			}
4877 		}
4878 		if ((IS_FC(isp) && mbox != ASYNC_RIOZIO_STALL) || isp->isp_state != ISP_RUNSTATE) {
4879 			goto out;
4880 		}
4881 	}
4882 
4883 	/*
4884 	 * We can't be getting this now.
4885 	 */
4886 	if (isp->isp_state != ISP_RUNSTATE) {
4887 		/*
4888 		 * This seems to happen to 23XX and 24XX cards- don't know why.
4889 		 */
4890 		 if (isp->isp_mboxbsy && isp->isp_lastmbxcmd == MBOX_ABOUT_FIRMWARE) {
4891 			goto fmbox;
4892 		}
4893 		isp_prt(isp, ISP_LOGINFO, "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
4894 		/*
4895 		 * Thank you very much!  *Burrrp*!
4896 		 */
4897 		ISP_WRITE(isp, isp->isp_respoutrp, ISP_READ(isp, isp->isp_respinrp));
4898 		if (IS_24XX(isp)) {
4899 			ISP_DISABLE_INTS(isp);
4900 		}
4901 		goto out;
4902 	}
4903 
4904 #ifdef	ISP_TARGET_MODE
4905 	/*
4906 	 * Check for ATIO Queue entries.
4907 	 */
4908 	if (IS_24XX(isp)) {
4909 		iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
4910 		optr = ISP_READ(isp, BIU2400_ATIO_RSPOUTP);
4911 
4912 		while (optr != iptr) {
4913 			uint8_t qe[QENTRY_LEN];
4914 			isphdr_t *hp;
4915 			uint32_t oop;
4916 			void *addr;
4917 
4918 			oop = optr;
4919 			MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN);
4920 			addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
4921 			isp_get_hdr(isp, addr, (isphdr_t *)qe);
4922 			hp = (isphdr_t *)qe;
4923 			switch (hp->rqs_entry_type) {
4924 			case RQSTYPE_NOTIFY:
4925 			case RQSTYPE_ATIO:
4926 				(void) isp_target_notify(isp, addr, &oop);
4927 				break;
4928 			default:
4929 				isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
4930 				break;
4931 			}
4932 			optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
4933 			ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
4934 		}
4935 		optr = isp->isp_residx;
4936 	}
4937 #endif
4938 
4939 	/*
4940 	 * Get the current Response Queue Out Pointer.
4941 	 *
4942 	 * If we're a 2300 or 2400, we can ask what hardware what it thinks.
4943 	 */
4944 	if (IS_23XX(isp) || IS_24XX(isp)) {
4945 		optr = ISP_READ(isp, isp->isp_respoutrp);
4946 		/*
4947 		 * Debug: to be taken out eventually
4948 		 */
4949 		if (isp->isp_residx != optr) {
4950 			isp_prt(isp, ISP_LOGINFO, "isp_intr: hard optr=%x, soft optr %x", optr, isp->isp_residx);
4951 			isp->isp_residx = optr;
4952 		}
4953 	} else {
4954 		optr = isp->isp_residx;
4955 	}
4956 
4957 	/*
4958 	 * You *must* read the Response Queue In Pointer
4959 	 * prior to clearing the RISC interrupt.
4960 	 *
4961 	 * Debounce the 2300 if revision less than 2.
4962 	 */
4963 	if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
4964 		i = 0;
4965 		do {
4966 			iptr = ISP_READ(isp, isp->isp_respinrp);
4967 			junk = ISP_READ(isp, isp->isp_respinrp);
4968 		} while (junk != iptr && ++i < 1000);
4969 
4970 		if (iptr != junk) {
4971 			isp_prt(isp, ISP_LOGWARN, "Response Queue Out Pointer Unstable (%x, %x)", iptr, junk);
4972 			goto out;
4973 		}
4974 	} else {
4975 		iptr = ISP_READ(isp, isp->isp_respinrp);
4976 	}
4977 	isp->isp_resodx = iptr;
4978 
4979 
4980 	if (optr == iptr && sema == 0) {
4981 		/*
4982 		 * There are a lot of these- reasons unknown- mostly on
4983 		 * faster Alpha machines.
4984 		 *
4985 		 * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
4986 		 * make sure the old interrupt went away (to avoid 'ringing'
4987 		 * effects), but that didn't stop this from occurring.
4988 		 */
4989 		if (IS_24XX(isp)) {
4990 			junk = 0;
4991 		} else if (IS_23XX(isp)) {
4992 			ISP_DELAY(100);
4993 			iptr = ISP_READ(isp, isp->isp_respinrp);
4994 			junk = ISP_READ(isp, BIU_R2HSTSLO);
4995 		} else {
4996 			junk = ISP_READ(isp, BIU_ISR);
4997 		}
4998 		if (optr == iptr) {
4999 			if (IS_23XX(isp) || IS_24XX(isp)) {
5000 				;
5001 			} else {
5002 				sema = ISP_READ(isp, BIU_SEMA);
5003 				mbox = ISP_READ(isp, OUTMAILBOX0);
5004 				if ((sema & 0x3) && (mbox & 0x8000)) {
5005 					goto again;
5006 				}
5007 			}
5008 			isp->isp_intbogus++;
5009 			isp_prt(isp, ISP_LOGDEBUG1, "bogus intr- isr %x (%x) iptr %x optr %x", isr, junk, iptr, optr);
5010 		}
5011 	}
5012 	isp->isp_resodx = iptr;
5013 
5014 	while (optr != iptr) {
5015 		uint8_t qe[QENTRY_LEN];
5016 		ispstatusreq_t *sp = (ispstatusreq_t *) qe;
5017 		isphdr_t *hp;
5018 		int buddaboom, etype, scsi_status, completion_status;
5019 		int req_status_flags, req_state_flags;
5020 		uint8_t *snsp, *resp;
5021 		uint32_t rlen, slen;
5022 		long resid;
5023 		uint16_t oop;
5024 
5025 		hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
5026 		oop = optr;
5027 		optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
5028 		nlooked++;
5029  read_again:
5030 		buddaboom = req_status_flags = req_state_flags = 0;
5031 		resid = 0L;
5032 
5033 		/*
5034 		 * Synchronize our view of this response queue entry.
5035 		 */
5036 		MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN);
5037 		isp_get_hdr(isp, hp, &sp->req_header);
5038 		etype = sp->req_header.rqs_entry_type;
5039 
5040 		if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) {
5041 			isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe;
5042 			isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp2);
5043 			if (isp->isp_dblev & ISP_LOGDEBUG1) {
5044 				isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp2);
5045 			}
5046 			scsi_status = sp2->req_scsi_status;
5047 			completion_status = sp2->req_completion_status;
5048 			req_state_flags = 0;
5049 			resid = sp2->req_resid;
5050 		} else if (etype == RQSTYPE_RESPONSE) {
5051 			isp_get_response(isp, (ispstatusreq_t *) hp, sp);
5052 			if (isp->isp_dblev & ISP_LOGDEBUG1) {
5053 				isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp);
5054 			}
5055 			scsi_status = sp->req_scsi_status;
5056 			completion_status = sp->req_completion_status;
5057 			req_status_flags = sp->req_status_flags;
5058 			req_state_flags = sp->req_state_flags;
5059 			resid = sp->req_resid;
5060 		} else if (etype == RQSTYPE_RIO1) {
5061 			isp_rio1_t *rio = (isp_rio1_t *) qe;
5062 			isp_get_rio1(isp, (isp_rio1_t *) hp, rio);
5063 			if (isp->isp_dblev & ISP_LOGDEBUG1) {
5064 				isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, rio);
5065 			}
5066 			for (i = 0; i < rio->req_header.rqs_seqno; i++) {
5067 				isp_fastpost_complete(isp, rio->req_handles[i]);
5068 			}
5069 			if (isp->isp_fpcchiwater < rio->req_header.rqs_seqno) {
5070 				isp->isp_fpcchiwater = rio->req_header.rqs_seqno;
5071 			}
5072 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5073 			continue;
5074 		} else if (etype == RQSTYPE_RIO2) {
5075 			isp_prt(isp, ISP_LOGERR, "dropping RIO2 response\n");
5076 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5077 			continue;
5078 		} else {
5079 			/*
5080 			 * Somebody reachable via isp_handle_other_response
5081 			 * may have updated the response queue pointers for
5082 			 * us, so we reload our goal index.
5083 			 */
5084 			int r;
5085 			uint32_t tsto = oop;
5086 			r = isp_handle_other_response(isp, etype, hp, &tsto);
5087 			if (r < 0) {
5088 				goto read_again;
5089 			}
5090 			/*
5091 			 * If somebody updated the output pointer, then reset
5092 			 * optr to be one more than the updated amount.
5093 			 */
5094 			while (tsto != oop) {
5095 				optr = ISP_NXT_QENTRY(tsto,
5096 				    RESULT_QUEUE_LEN(isp));
5097 			}
5098 			if (r > 0) {
5099 				ISP_WRITE(isp, isp->isp_respoutrp, optr);
5100 				ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5101 				continue;
5102 			}
5103 
5104 			/*
5105 			 * After this point, we'll just look at the header as
5106 			 * we don't know how to deal with the rest of the
5107 			 * response.
5108 			 */
5109 
5110 			/*
5111 			 * It really has to be a bounced request just copied
5112 			 * from the request queue to the response queue. If
5113 			 * not, something bad has happened.
5114 			 */
5115 			if (etype != RQSTYPE_REQUEST) {
5116 				isp_prt(isp, ISP_LOGERR, notresp,
5117 				    etype, oop, optr, nlooked);
5118 				isp_print_bytes(isp,
5119 				    "Request Queue Entry", QENTRY_LEN, sp);
5120 				ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5121 				continue;
5122 			}
5123 			buddaboom = 1;
5124 			scsi_status = sp->req_scsi_status;
5125 			completion_status = sp->req_completion_status;
5126 			req_status_flags = sp->req_status_flags;
5127 			req_state_flags = sp->req_state_flags;
5128 			resid = sp->req_resid;
5129 		}
5130 
5131 		if (sp->req_header.rqs_flags & RQSFLAG_MASK) {
5132 			if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
5133 				isp_print_bytes(isp, "unexpected continuation segment", QENTRY_LEN, sp);
5134 				ISP_WRITE(isp, isp->isp_respoutrp, optr);
5135 				continue;
5136 			}
5137 			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
5138 				isp_prt(isp, ISP_LOGDEBUG0, "internal queues full");
5139 				/*
5140 				 * We'll synthesize a QUEUE FULL message below.
5141 				 */
5142 			}
5143 			if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
5144 				isp_print_bytes(isp, "bad header flag", QENTRY_LEN, sp);
5145 				buddaboom++;
5146 			}
5147 			if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
5148 				isp_print_bytes(isp, "bad request packet", QENTRY_LEN, sp);
5149 				buddaboom++;
5150 			}
5151 			if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
5152 				isp_print_bytes(isp, "invalid entry count", QENTRY_LEN, sp);
5153 				buddaboom++;
5154 			}
5155 			if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
5156 				isp_print_bytes(isp, "invalid IOCB ordering", QENTRY_LEN, sp);
5157 				ISP_WRITE(isp, isp->isp_respoutrp, optr);
5158 				continue;
5159 			}
5160 		}
5161 
5162 		if (!ISP_VALID_HANDLE(isp, sp->req_handle)) {
5163 			isp_prt(isp, ISP_LOGERR, "bad request handle 0x%x (iocb type 0x%x)", sp->req_handle, etype);
5164 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5165 			ISP_WRITE(isp, isp->isp_respoutrp, optr);
5166 			continue;
5167 		}
5168 		xs = isp_find_xs(isp, sp->req_handle);
5169 		if (xs == NULL) {
5170 			uint8_t ts = completion_status & 0xff;
5171 			/*
5172 			 * Only whine if this isn't the expected fallout of
5173 			 * aborting the command or resetting the target.
5174 			 */
5175 			if (etype != RQSTYPE_RESPONSE) {
5176 				isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (type 0x%x)", sp->req_handle, etype);
5177 			} else if (ts != RQCS_ABORTED && ts != RQCS_RESET_OCCURRED) {
5178 				isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)", sp->req_handle, ts);
5179 			}
5180 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5181 			ISP_WRITE(isp, isp->isp_respoutrp, optr);
5182 			continue;
5183 		}
5184 		if (req_status_flags & RQSTF_BUS_RESET) {
5185 			XS_SETERR(xs, HBA_BUSRESET);
5186 			ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
5187 		}
5188 		if (buddaboom) {
5189 			XS_SETERR(xs, HBA_BOTCH);
5190 		}
5191 
5192 		resp = NULL;
5193 		rlen = 0;
5194 		snsp = NULL;
5195 		slen = 0;
5196 		if (IS_24XX(isp) && (scsi_status & (RQCS_RV|RQCS_SV)) != 0) {
5197 			resp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
5198 			rlen = ((isp24xx_statusreq_t *)sp)->req_response_len;
5199 		} else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) {
5200 			resp = sp->req_response;
5201 			rlen = sp->req_response_len;
5202 		}
5203 		if (IS_FC(isp) && (scsi_status & RQCS_SV) != 0) {
5204 			/*
5205 			 * Fibre Channel F/W doesn't say we got status
5206 			 * if there's Sense Data instead. I guess they
5207 			 * think it goes w/o saying.
5208 			 */
5209 			req_state_flags |= RQSF_GOT_STATUS|RQSF_GOT_SENSE;
5210 			if (IS_24XX(isp)) {
5211 				snsp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
5212 				snsp += rlen;
5213 				slen = ((isp24xx_statusreq_t *)sp)->req_sense_len;
5214 			} else {
5215 				snsp = sp->req_sense_data;
5216 				slen = sp->req_sense_len;
5217 			}
5218 		} else if (IS_SCSI(isp) && (req_state_flags & RQSF_GOT_SENSE)) {
5219 			snsp = sp->req_sense_data;
5220 			slen = sp->req_sense_len;
5221 		}
5222 		if (req_state_flags & RQSF_GOT_STATUS) {
5223 			*XS_STSP(xs) = scsi_status & 0xff;
5224 		}
5225 
5226 		switch (etype) {
5227 		case RQSTYPE_RESPONSE:
5228 			if (resp && rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
5229 				const char *ptr;
5230 				char lb[64];
5231 				const char *rnames[6] = {
5232 					"Task Management Function Done",
5233 					"Data Length Differs From Burst Length",
5234 					"Invalid FCP Cmnd",
5235 					"FCP DATA RO mismatch with FCP DATA_XFR_RDY RO",
5236 					"Task Management Function Rejected",
5237 					"Task Management Function Failed",
5238 				};
5239 				if (resp[FCP_RSPNS_CODE_OFFSET] > 5) {
5240 					ISP_SNPRINTF(lb, sizeof lb, "Unknown FCP Response Code 0x%x", resp[FCP_RSPNS_CODE_OFFSET]);
5241 					ptr = lb;
5242 				} else {
5243 					ptr = rnames[resp[FCP_RSPNS_CODE_OFFSET]];
5244 				}
5245 				isp_xs_prt(isp, xs, ISP_LOGWARN, "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x", rlen, ptr, XS_CDBP(xs)[0] & 0xff);
5246 				if (resp[FCP_RSPNS_CODE_OFFSET] != 0) {
5247 					XS_SETERR(xs, HBA_BOTCH);
5248 				}
5249 			}
5250 			if (IS_24XX(isp)) {
5251 				isp_parse_status_24xx(isp, (isp24xx_statusreq_t *)sp, xs, &resid);
5252 			} else {
5253 				isp_parse_status(isp, (void *)sp, xs, &resid);
5254 			}
5255 			if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) && (*XS_STSP(xs) == SCSI_BUSY)) {
5256 				XS_SETERR(xs, HBA_TGTBSY);
5257 			}
5258 			if (IS_SCSI(isp)) {
5259 				XS_SET_RESID(xs, resid);
5260 				/*
5261 				 * A new synchronous rate was negotiated for
5262 				 * this target. Mark state such that we'll go
5263 				 * look up that which has changed later.
5264 				 */
5265 				if (req_status_flags & RQSTF_NEGOTIATION) {
5266 					int t = XS_TGT(xs);
5267 					sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
5268 					sdp->isp_devparam[t].dev_refresh = 1;
5269 					sdp->update = 1;
5270 				}
5271 			} else {
5272 				if (req_status_flags & RQSF_XFER_COMPLETE) {
5273 					XS_SET_RESID(xs, 0);
5274 				} else if (scsi_status & RQCS_RESID) {
5275 					XS_SET_RESID(xs, resid);
5276 				} else {
5277 					XS_SET_RESID(xs, 0);
5278 				}
5279 			}
5280 			if (snsp && slen) {
5281 				XS_SAVE_SENSE(xs, snsp, slen);
5282 			} else if ((req_status_flags & RQSF_GOT_STATUS) && (scsi_status & 0xff) == SCSI_CHECK && IS_FC(isp)) {
5283 				isp_prt(isp, ISP_LOGWARN, "CHECK CONDITION w/o sense data for CDB=0x%x", XS_CDBP(xs)[0] & 0xff);
5284 				isp_print_bytes(isp, "CC with no Sense", QENTRY_LEN, qe);
5285 			}
5286 			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));
5287 			break;
5288 		case RQSTYPE_REQUEST:
5289 		case RQSTYPE_A64:
5290 		case RQSTYPE_T2RQS:
5291 		case RQSTYPE_T3RQS:
5292 		case RQSTYPE_T7RQS:
5293 			if (!IS_24XX(isp) && (sp->req_header.rqs_flags & RQSFLAG_FULL)) {
5294 				/*
5295 				 * Force Queue Full status.
5296 				 */
5297 				*XS_STSP(xs) = SCSI_QFULL;
5298 				XS_SETERR(xs, HBA_NOERROR);
5299 			} else if (XS_NOERR(xs)) {
5300 				XS_SETERR(xs, HBA_BOTCH);
5301 			}
5302 			XS_SET_RESID(xs, XS_XFRLEN(xs));
5303 			break;
5304 		default:
5305 			isp_print_bytes(isp, "Unhandled Response Type", QENTRY_LEN, qe);
5306 			if (XS_NOERR(xs)) {
5307 				XS_SETERR(xs, HBA_BOTCH);
5308 			}
5309 			break;
5310 		}
5311 
5312 		/*
5313 		 * Free any DMA resources. As a side effect, this may
5314 		 * also do any cache flushing necessary for data coherence.
5315 		 */
5316 		if (XS_XFRLEN(xs)) {
5317 			ISP_DMAFREE(isp, xs, sp->req_handle);
5318 		}
5319 		isp_destroy_handle(isp, sp->req_handle);
5320 
5321 		if (((isp->isp_dblev & (ISP_LOGDEBUG1|ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
5322 		    ((isp->isp_dblev & (ISP_LOGDEBUG0|ISP_LOG_CWARN) && ((!XS_NOERR(xs)) || (*XS_STSP(xs) != SCSI_GOOD))))) {
5323 			isp_prt_endcmd(isp, xs);
5324 		}
5325 		if (isp->isp_nactive > 0) {
5326 		    isp->isp_nactive--;
5327 		}
5328 		complist[ndone++] = xs;	/* defer completion call until later */
5329 		ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5330 		if (ndone == MAX_REQUESTQ_COMPLETIONS) {
5331 			break;
5332 		}
5333 	}
5334 
5335 	/*
5336 	 * If we looked at any commands, then it's valid to find out
5337 	 * what the outpointer is. It also is a trigger to update the
5338 	 * ISP's notion of what we've seen so far.
5339 	 */
5340 	if (nlooked) {
5341 		ISP_WRITE(isp, isp->isp_respoutrp, optr);
5342 		/*
5343 		 * While we're at it, read the requst queue out pointer.
5344 		 */
5345 		isp->isp_reqodx = ISP_READ(isp, isp->isp_rqstoutrp);
5346 		if (isp->isp_rscchiwater < ndone) {
5347 			isp->isp_rscchiwater = ndone;
5348 		}
5349 	}
5350 
5351 out:
5352 
5353 	if (IS_24XX(isp)) {
5354 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
5355 	} else {
5356 		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
5357 		ISP_WRITE(isp, BIU_SEMA, 0);
5358 	}
5359 
5360 	isp->isp_residx = optr;
5361 	for (i = 0; i < ndone; i++) {
5362 		xs = complist[i];
5363 		if (xs) {
5364 			isp->isp_rsltccmplt++;
5365 			isp_done(xs);
5366 		}
5367 	}
5368 }
5369 
5370 /*
5371  * Support routines.
5372  */
5373 
5374 static void
5375 isp_prt_endcmd(ispsoftc_t *isp, XS_T *xs)
5376 {
5377 	char cdbstr[16 * 5 + 1];
5378 	int i, lim;
5379 
5380 	lim = XS_CDBLEN(xs) > 16? 16 : XS_CDBLEN(xs);
5381 	ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "0x%02x ", XS_CDBP(xs)[0]);
5382 	for (i = 1; i < lim; i++) {
5383 		ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "%s0x%02x ", cdbstr, XS_CDBP(xs)[i]);
5384 	}
5385 	if (XS_SENSE_VALID(xs)) {
5386 		isp_xs_prt(isp, xs, ISP_LOGALL, "FIN dl%d resid %ld CDB=%s KEY/ASC/ASCQ=0x%02x/0x%02x/0x%02x",
5387 		    XS_XFRLEN(xs), (long) XS_GET_RESID(xs), cdbstr, XS_SNSKEY(xs), XS_SNSASC(xs), XS_SNSASCQ(xs));
5388 	} else {
5389 		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));
5390 	}
5391 }
5392 
5393 /*
5394  * Parse an ASYNC mailbox complete
5395  *
5396  * Return non-zero if the event has been acknowledged.
5397  */
5398 static int
5399 isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
5400 {
5401 	int acked = 0;
5402 	uint32_t h1 = 0, h2 = 0;
5403 	uint16_t chan = 0;
5404 
5405 	/*
5406 	 * Pick up the channel, but not if this is a ASYNC_RIO32_2,
5407 	 * where Mailboxes 6/7 have the second handle.
5408 	 */
5409 	if (mbox != ASYNC_RIO32_2) {
5410 		if (IS_DUALBUS(isp)) {
5411 			chan = ISP_READ(isp, OUTMAILBOX6);
5412 		}
5413 	}
5414 	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
5415 
5416 	switch (mbox) {
5417 	case ASYNC_BUS_RESET:
5418 		ISP_SET_SENDMARKER(isp, chan, 1);
5419 #ifdef	ISP_TARGET_MODE
5420 		if (isp_target_async(isp, chan, mbox)) {
5421 			acked = 1;
5422 		}
5423 #endif
5424 		isp_async(isp, ISPASYNC_BUS_RESET, chan);
5425 		break;
5426 	case ASYNC_SYSTEM_ERROR:
5427 		isp->isp_dead = 1;
5428 		isp->isp_state = ISP_CRASHED;
5429 		/*
5430 		 * Were we waiting for a mailbox command to complete?
5431 		 * If so, it's dead, so wake up the waiter.
5432 		 */
5433 		if (isp->isp_mboxbsy) {
5434 			isp->isp_obits = 1;
5435 			isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
5436 			MBOX_NOTIFY_COMPLETE(isp);
5437 		}
5438 		/*
5439 		 * It's up to the handler for isp_async to reinit stuff and
5440 		 * restart the firmware
5441 		 */
5442 		isp_async(isp, ISPASYNC_FW_CRASH);
5443 		acked = 1;
5444 		break;
5445 
5446 	case ASYNC_RQS_XFER_ERR:
5447 		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
5448 		break;
5449 
5450 	case ASYNC_RSP_XFER_ERR:
5451 		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
5452 		break;
5453 
5454 	case ASYNC_QWAKEUP:
5455 		/*
5456 		 * We've just been notified that the Queue has woken up.
5457 		 * We don't need to be chatty about this- just unlatch things
5458 		 * and move on.
5459 		 */
5460 		mbox = ISP_READ(isp, isp->isp_rqstoutrp);
5461 		break;
5462 
5463 	case ASYNC_TIMEOUT_RESET:
5464 		isp_prt(isp, ISP_LOGWARN, "timeout initiated SCSI bus reset of chan %d", chan);
5465 		ISP_SET_SENDMARKER(isp, chan, 1);
5466 #ifdef	ISP_TARGET_MODE
5467 		if (isp_target_async(isp, chan, mbox)) {
5468 			acked = 1;
5469 		}
5470 #endif
5471 		break;
5472 
5473 	case ASYNC_DEVICE_RESET:
5474 		isp_prt(isp, ISP_LOGINFO, "device reset on chan %d", chan);
5475 		ISP_SET_SENDMARKER(isp, chan, 1);
5476 #ifdef	ISP_TARGET_MODE
5477 		if (isp_target_async(isp, chan, mbox)) {
5478 			acked = 1;
5479 		}
5480 #endif
5481 		break;
5482 
5483 	case ASYNC_EXTMSG_UNDERRUN:
5484 		isp_prt(isp, ISP_LOGWARN, "extended message underrun");
5485 		break;
5486 
5487 	case ASYNC_SCAM_INT:
5488 		isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
5489 		break;
5490 
5491 	case ASYNC_HUNG_SCSI:
5492 		isp_prt(isp, ISP_LOGERR, "stalled SCSI Bus after DATA Overrun");
5493 		/* XXX: Need to issue SCSI reset at this point */
5494 		break;
5495 
5496 	case ASYNC_KILLED_BUS:
5497 		isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
5498 		break;
5499 
5500 	case ASYNC_BUS_TRANSIT:
5501 		mbox = ISP_READ(isp, OUTMAILBOX2);
5502 		switch (mbox & SXP_PINS_MODE_MASK) {
5503 		case SXP_PINS_LVD_MODE:
5504 			isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
5505 			SDPARAM(isp, chan)->isp_diffmode = 0;
5506 			SDPARAM(isp, chan)->isp_ultramode = 0;
5507 			SDPARAM(isp, chan)->isp_lvdmode = 1;
5508 			break;
5509 		case SXP_PINS_HVD_MODE:
5510 			isp_prt(isp, ISP_LOGINFO,
5511 			    "Transition to Differential mode");
5512 			SDPARAM(isp, chan)->isp_diffmode = 1;
5513 			SDPARAM(isp, chan)->isp_ultramode = 0;
5514 			SDPARAM(isp, chan)->isp_lvdmode = 0;
5515 			break;
5516 		case SXP_PINS_SE_MODE:
5517 			isp_prt(isp, ISP_LOGINFO,
5518 			    "Transition to Single Ended mode");
5519 			SDPARAM(isp, chan)->isp_diffmode = 0;
5520 			SDPARAM(isp, chan)->isp_ultramode = 1;
5521 			SDPARAM(isp, chan)->isp_lvdmode = 0;
5522 			break;
5523 		default:
5524 			isp_prt(isp, ISP_LOGWARN,
5525 			    "Transition to Unknown Mode 0x%x", mbox);
5526 			break;
5527 		}
5528 		/*
5529 		 * XXX: Set up to renegotiate again!
5530 		 */
5531 		/* Can only be for a 1080... */
5532 		ISP_SET_SENDMARKER(isp, chan, 1);
5533 		break;
5534 
5535 	case ASYNC_CMD_CMPLT:
5536 	case ASYNC_RIO32_1:
5537 		if (!IS_ULTRA3(isp)) {
5538 			isp_prt(isp, ISP_LOGERR, "unexpected fast posting completion");
5539 			break;
5540 		}
5541 		/* FALLTHROUGH */
5542 		h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1);
5543 		break;
5544 
5545 	case ASYNC_RIO32_2:
5546 		h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1);
5547 		h2 = (ISP_READ(isp, OUTMAILBOX7) << 16) | ISP_READ(isp, OUTMAILBOX6);
5548 		break;
5549 
5550 	case ASYNC_RIO16_5:
5551 	case ASYNC_RIO16_4:
5552 	case ASYNC_RIO16_3:
5553 	case ASYNC_RIO16_2:
5554 	case ASYNC_RIO16_1:
5555 		isp_prt(isp, ISP_LOGERR, "unexpected 16 bit RIO handle");
5556 		break;
5557 	default:
5558 		isp_prt(isp, ISP_LOGWARN, "%s: unhandled async code 0x%x", __func__, mbox);
5559 		break;
5560 	}
5561 
5562 	if (h1 || h2) {
5563 		isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h1);
5564 		isp_fastpost_complete(isp, h1);
5565 		if (h2) {
5566 			isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h2);
5567 			isp_fastpost_complete(isp, h2);
5568 			if (isp->isp_fpcchiwater < 2) {
5569 				isp->isp_fpcchiwater = 2;
5570 			}
5571 		} else {
5572 			if (isp->isp_fpcchiwater < 1) {
5573 				isp->isp_fpcchiwater = 1;
5574 			}
5575 		}
5576 	} else {
5577 		isp->isp_intoasync++;
5578 	}
5579 	return (acked);
5580 }
5581 
5582 #define	GET_24XX_BUS(isp, chan, msg)										\
5583 	if (IS_24XX(isp)) {											\
5584 		chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;							\
5585 		if (chan >= isp->isp_nchan) {									\
5586 			isp_prt(isp, ISP_LOGERR, "bogus channel %u for %s at line %d",	chan, msg, __LINE__);	\
5587 			break;											\
5588 		}												\
5589 	}
5590 
5591 
5592 static int
5593 isp_parse_async_fc(ispsoftc_t *isp, uint16_t mbox)
5594 {
5595 	int acked = 0;
5596 	uint16_t chan;
5597 
5598 	if (IS_DUALBUS(isp)) {
5599 		chan = ISP_READ(isp, OUTMAILBOX6);
5600 	} else {
5601 		chan = 0;
5602 	}
5603 	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
5604 
5605 	switch (mbox) {
5606 	case ASYNC_SYSTEM_ERROR:
5607 		isp->isp_dead = 1;
5608 		isp->isp_state = ISP_CRASHED;
5609 		FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
5610 		FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
5611 		/*
5612 		 * Were we waiting for a mailbox command to complete?
5613 		 * If so, it's dead, so wake up the waiter.
5614 		 */
5615 		if (isp->isp_mboxbsy) {
5616 			isp->isp_obits = 1;
5617 			isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
5618 			MBOX_NOTIFY_COMPLETE(isp);
5619 		}
5620 		/*
5621 		 * It's up to the handler for isp_async to reinit stuff and
5622 		 * restart the firmware
5623 		 */
5624 		isp_async(isp, ISPASYNC_FW_CRASH);
5625 		acked = 1;
5626 		break;
5627 
5628 	case ASYNC_RQS_XFER_ERR:
5629 		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
5630 		break;
5631 
5632 	case ASYNC_RSP_XFER_ERR:
5633 		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
5634 		break;
5635 
5636 	case ASYNC_QWAKEUP:
5637 #ifdef	ISP_TARGET_MODE
5638 		if (IS_24XX(isp)) {
5639 			isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
5640 			break;
5641 		}
5642 #endif
5643 		isp_prt(isp, ISP_LOGERR, "%s: unexpected ASYNC_QWAKEUP code", __func__);
5644 		break;
5645 
5646 	case ASYNC_CMD_CMPLT:
5647 		isp_fastpost_complete(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1));
5648 		if (isp->isp_fpcchiwater < 1) {
5649 			isp->isp_fpcchiwater = 1;
5650 		}
5651 		break;
5652 
5653 	case ASYNC_RIOZIO_STALL:
5654 		break;
5655 
5656 	case ASYNC_CTIO_DONE:
5657 #ifdef	ISP_TARGET_MODE
5658 		if (isp_target_async(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1), mbox)) {
5659 			acked = 1;
5660 		} else {
5661 			isp->isp_fphccmplt++;
5662 		}
5663 #else
5664 		isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC CTIO done");
5665 #endif
5666 		break;
5667 	case ASYNC_LIP_ERROR:
5668 	case ASYNC_LIP_F8:
5669 	case ASYNC_LIP_OCCURRED:
5670 	case ASYNC_PTPMODE:
5671 		/*
5672 		 * These are broadcast events that have to be sent across
5673 		 * all active channels.
5674 		 */
5675 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5676 			fcparam *fcp = FCPARAM(isp, chan);
5677 			int topo = fcp->isp_topo;
5678 
5679 			if (fcp->role == ISP_ROLE_NONE) {
5680 				continue;
5681 			}
5682 
5683 			fcp->isp_fwstate = FW_CONFIG_WAIT;
5684 			fcp->isp_loopstate = LOOP_LIP_RCVD;
5685 			ISP_SET_SENDMARKER(isp, chan, 1);
5686 			ISP_MARK_PORTDB(isp, chan, 1);
5687 			isp_async(isp, ISPASYNC_LIP, chan);
5688 #ifdef	ISP_TARGET_MODE
5689 			if (isp_target_async(isp, chan, mbox)) {
5690 				acked = 1;
5691 			}
5692 #endif
5693 			/*
5694 			 * We've had problems with data corruption occuring on
5695 			 * commands that complete (with no apparent error) after
5696 			 * we receive a LIP. This has been observed mostly on
5697 			 * Local Loop topologies. To be safe, let's just mark
5698 			 * all active initiator commands as dead.
5699 			 */
5700 			if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
5701 				int i, j;
5702 				for (i = j = 0; i < isp->isp_maxcmds; i++) {
5703 					XS_T *xs;
5704 					isp_hdl_t *hdp;
5705 
5706 					hdp = &isp->isp_xflist[i];
5707 					if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) {
5708 						continue;
5709 					}
5710 					xs = hdp->cmd;
5711 					if (XS_CHANNEL(xs) != chan) {
5712 						continue;
5713 					}
5714 					j++;
5715 					XS_SETERR(xs, HBA_BUSRESET);
5716 				}
5717 				if (j) {
5718 					isp_prt(isp, ISP_LOGERR, lipd, chan, j);
5719 				}
5720 			}
5721 		}
5722 		break;
5723 
5724 	case ASYNC_LOOP_UP:
5725 		/*
5726 		 * This is a broadcast event that has to be sent across
5727 		 * all active channels.
5728 		 */
5729 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5730 			fcparam *fcp = FCPARAM(isp, chan);
5731 
5732 			if (fcp->role == ISP_ROLE_NONE) {
5733 				continue;
5734 			}
5735 
5736 			ISP_SET_SENDMARKER(isp, chan, 1);
5737 
5738 			fcp->isp_fwstate = FW_CONFIG_WAIT;
5739 			fcp->isp_loopstate = LOOP_LIP_RCVD;
5740 			ISP_MARK_PORTDB(isp, chan, 1);
5741 			isp_async(isp, ISPASYNC_LOOP_UP, chan);
5742 #ifdef	ISP_TARGET_MODE
5743 			if (isp_target_async(isp, chan, mbox)) {
5744 				acked = 1;
5745 			}
5746 #endif
5747 		}
5748 		break;
5749 
5750 	case ASYNC_LOOP_DOWN:
5751 		/*
5752 		 * This is a broadcast event that has to be sent across
5753 		 * all active channels.
5754 		 */
5755 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5756 			fcparam *fcp = FCPARAM(isp, chan);
5757 
5758 			if (fcp->role == ISP_ROLE_NONE) {
5759 				continue;
5760 			}
5761 
5762 			ISP_SET_SENDMARKER(isp, chan, 1);
5763 			fcp->isp_fwstate = FW_CONFIG_WAIT;
5764 			fcp->isp_loopstate = LOOP_NIL;
5765 			ISP_MARK_PORTDB(isp, chan, 1);
5766 			isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
5767 #ifdef	ISP_TARGET_MODE
5768 			if (isp_target_async(isp, chan, mbox)) {
5769 				acked = 1;
5770 			}
5771 #endif
5772 		}
5773 		break;
5774 
5775 	case ASYNC_LOOP_RESET:
5776 		/*
5777 		 * This is a broadcast event that has to be sent across
5778 		 * all active channels.
5779 		 */
5780 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5781 			fcparam *fcp = FCPARAM(isp, chan);
5782 
5783 			if (fcp->role == ISP_ROLE_NONE) {
5784 				continue;
5785 			}
5786 
5787 			ISP_SET_SENDMARKER(isp, chan, 1);
5788 			fcp->isp_fwstate = FW_CONFIG_WAIT;
5789 			fcp->isp_loopstate = LOOP_NIL;
5790 			ISP_MARK_PORTDB(isp, chan, 1);
5791 			isp_async(isp, ISPASYNC_LOOP_RESET, chan);
5792 #ifdef	ISP_TARGET_MODE
5793 			if (isp_target_async(isp, chan, mbox)) {
5794 				acked = 1;
5795 			}
5796 #endif
5797 		}
5798 		break;
5799 
5800 	case ASYNC_PDB_CHANGED:
5801 	{
5802 		int nphdl, nlstate, reason;
5803 		/*
5804 		 * We *should* get a channel out of the 24XX, but we don't seem
5805 		 * to get more than a PDB CHANGED on channel 0, so turn it into
5806 		 * a broadcast event.
5807 		 */
5808 		if (IS_24XX(isp)) {
5809 			nphdl = ISP_READ(isp, OUTMAILBOX1);
5810 			nlstate = ISP_READ(isp, OUTMAILBOX2);
5811 			reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
5812 		} else {
5813 			nphdl = NIL_HANDLE;
5814 			nlstate = reason = 0;
5815 		}
5816 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5817 			fcparam *fcp = FCPARAM(isp, chan);
5818 
5819 			if (fcp->role == ISP_ROLE_NONE) {
5820 				continue;
5821 			}
5822 			ISP_SET_SENDMARKER(isp, chan, 1);
5823 			fcp->isp_loopstate = LOOP_PDB_RCVD;
5824 			ISP_MARK_PORTDB(isp, chan, 1);
5825 			isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
5826 		}
5827 		break;
5828 	}
5829 	case ASYNC_CHANGE_NOTIFY:
5830 	{
5831 		int lochan, hichan;
5832 
5833 		if (ISP_FW_NEWER_THAN(isp, 4, 0, 25) && ISP_CAP_MULTI_ID(isp)) {
5834 			GET_24XX_BUS(isp, chan, "ASYNC_CHANGE_NOTIFY");
5835 			lochan = chan;
5836 			hichan = chan + 1;
5837 		} else {
5838 			lochan = 0;
5839 			hichan = isp->isp_nchan;
5840 		}
5841 		for (chan = lochan; chan < hichan; chan++) {
5842 			fcparam *fcp = FCPARAM(isp, chan);
5843 
5844 			if (fcp->role == ISP_ROLE_NONE) {
5845 				continue;
5846 			}
5847 
5848 			if (fcp->isp_topo == TOPO_F_PORT) {
5849 				fcp->isp_loopstate = LOOP_LSCAN_DONE;
5850 			} else {
5851 				fcp->isp_loopstate = LOOP_PDB_RCVD;
5852 			}
5853 			ISP_MARK_PORTDB(isp, chan, 1);
5854 			isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_SNS);
5855 		}
5856 		break;
5857 	}
5858 
5859 	case ASYNC_CONNMODE:
5860 		/*
5861 		 * This only applies to 2100 amd 2200 cards
5862 		 */
5863 		if (!IS_2200(isp) && !IS_2100(isp)) {
5864 			isp_prt(isp, ISP_LOGWARN, "bad card for ASYNC_CONNMODE event");
5865 			break;
5866 		}
5867 		chan = 0;
5868 		mbox = ISP_READ(isp, OUTMAILBOX1);
5869 		ISP_MARK_PORTDB(isp, chan, 1);
5870 		switch (mbox) {
5871 		case ISP_CONN_LOOP:
5872 			isp_prt(isp, ISP_LOGINFO,
5873 			    "Point-to-Point -> Loop mode");
5874 			break;
5875 		case ISP_CONN_PTP:
5876 			isp_prt(isp, ISP_LOGINFO,
5877 			    "Loop -> Point-to-Point mode");
5878 			break;
5879 		case ISP_CONN_BADLIP:
5880 			isp_prt(isp, ISP_LOGWARN,
5881 			    "Point-to-Point -> Loop mode (BAD LIP)");
5882 			break;
5883 		case ISP_CONN_FATAL:
5884 			isp->isp_dead = 1;
5885 			isp->isp_state = ISP_CRASHED;
5886 			isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
5887 			isp_async(isp, ISPASYNC_FW_CRASH);
5888 			return (-1);
5889 		case ISP_CONN_LOOPBACK:
5890 			isp_prt(isp, ISP_LOGWARN,
5891 			    "Looped Back in Point-to-Point mode");
5892 			break;
5893 		default:
5894 			isp_prt(isp, ISP_LOGWARN,
5895 			    "Unknown connection mode (0x%x)", mbox);
5896 			break;
5897 		}
5898 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_OTHER);
5899 		FCPARAM(isp, chan)->sendmarker = 1;
5900 		FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
5901 		FCPARAM(isp, chan)->isp_loopstate = LOOP_LIP_RCVD;
5902 		break;
5903 
5904 	case ASYNC_RCV_ERR:
5905 		if (IS_24XX(isp)) {
5906 			isp_prt(isp, ISP_LOGWARN, "Receive Error");
5907 		} else {
5908 			isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC_RCV_ERR");
5909 		}
5910 		break;
5911 	case ASYNC_RJT_SENT:	/* same as ASYNC_QFULL_SENT */
5912 		if (IS_24XX(isp)) {
5913 			isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
5914 			break;
5915 		} else if (IS_2200(isp)) {
5916 			isp_prt(isp, ISP_LOGTDEBUG0, "QFULL sent");
5917 			break;
5918 		}
5919 		/* FALLTHROUGH */
5920 	default:
5921 		isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
5922 		break;
5923 	}
5924 	if (mbox != ASYNC_CTIO_DONE && mbox != ASYNC_CMD_CMPLT) {
5925 		isp->isp_intoasync++;
5926 	}
5927 	return (acked);
5928 }
5929 
5930 /*
5931  * Handle other response entries. A pointer to the request queue output
5932  * index is here in case we want to eat several entries at once, although
5933  * this is not used currently.
5934  */
5935 
5936 static int
5937 isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *optrp)
5938 {
5939 	switch (type) {
5940 	case RQSTYPE_STATUS_CONT:
5941 		isp_prt(isp, ISP_LOGDEBUG0, "Ignored Continuation Response");
5942 		return (1);
5943 	case RQSTYPE_MARKER:
5944 		isp_prt(isp, ISP_LOGDEBUG0, "Marker Response");
5945 		return (1);
5946 	case RQSTYPE_ATIO:
5947 	case RQSTYPE_CTIO:
5948 	case RQSTYPE_ENABLE_LUN:
5949 	case RQSTYPE_MODIFY_LUN:
5950 	case RQSTYPE_NOTIFY:
5951 	case RQSTYPE_NOTIFY_ACK:
5952 	case RQSTYPE_CTIO1:
5953 	case RQSTYPE_ATIO2:
5954 	case RQSTYPE_CTIO2:
5955 	case RQSTYPE_CTIO3:
5956 	case RQSTYPE_CTIO7:
5957 	case RQSTYPE_ABTS_RCVD:
5958 	case RQSTYPE_ABTS_RSP:
5959 		isp->isp_rsltccmplt++;	/* count as a response completion */
5960 #ifdef	ISP_TARGET_MODE
5961 		if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
5962 			return (1);
5963 		}
5964 #endif
5965 		/* FALLTHROUGH */
5966 	case RQSTYPE_RPT_ID_ACQ:
5967 		if (IS_24XX(isp)) {
5968 			isp_ridacq_t rid;
5969 			isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
5970 			if (rid.ridacq_format == 0) {
5971 			}
5972 			return (1);
5973 		}
5974 		/* FALLTHROUGH */
5975 	case RQSTYPE_REQUEST:
5976 	default:
5977 		ISP_DELAY(100);
5978 		if (type != isp_get_response_type(isp, hp)) {
5979 			/*
5980 			 * This is questionable- we're just papering over
5981 			 * something we've seen on SMP linux in target
5982 			 * mode- we don't really know what's happening
5983 			 * here that causes us to think we've gotten
5984 			 * an entry, but that either the entry isn't
5985 			 * filled out yet or our CPU read data is stale.
5986 			 */
5987 			isp_prt(isp, ISP_LOGINFO,
5988 				"unstable type in response queue");
5989 			return (-1);
5990 		}
5991 		isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
5992 		    isp_get_response_type(isp, hp));
5993 		return (0);
5994 	}
5995 }
5996 
5997 static void
5998 isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
5999 {
6000 	switch (sp->req_completion_status & 0xff) {
6001 	case RQCS_COMPLETE:
6002 		if (XS_NOERR(xs)) {
6003 			XS_SETERR(xs, HBA_NOERROR);
6004 		}
6005 		return;
6006 
6007 	case RQCS_INCOMPLETE:
6008 		if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
6009 			isp_xs_prt(isp, xs, ISP_LOGDEBUG1, "Selection Timeout");
6010 			if (XS_NOERR(xs)) {
6011 				XS_SETERR(xs, HBA_SELTIMEOUT);
6012 				*rp = XS_XFRLEN(xs);
6013 			}
6014 			return;
6015 		}
6016 		isp_xs_prt(isp, xs, ISP_LOGERR, "Command Incomplete, state 0x%x", sp->req_state_flags);
6017 		break;
6018 
6019 	case RQCS_DMA_ERROR:
6020 		isp_xs_prt(isp, xs, ISP_LOGERR, "DMA Error");
6021 		*rp = XS_XFRLEN(xs);
6022 		break;
6023 
6024 	case RQCS_TRANSPORT_ERROR:
6025 	{
6026 		char buf[172];
6027 		ISP_SNPRINTF(buf, sizeof (buf), "states=>");
6028 		if (sp->req_state_flags & RQSF_GOT_BUS) {
6029 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
6030 		}
6031 		if (sp->req_state_flags & RQSF_GOT_TARGET) {
6032 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
6033 		}
6034 		if (sp->req_state_flags & RQSF_SENT_CDB) {
6035 			ISP_SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
6036 		}
6037 		if (sp->req_state_flags & RQSF_XFRD_DATA) {
6038 			ISP_SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
6039 		}
6040 		if (sp->req_state_flags & RQSF_GOT_STATUS) {
6041 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
6042 		}
6043 		if (sp->req_state_flags & RQSF_GOT_SENSE) {
6044 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
6045 		}
6046 		if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
6047 			ISP_SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
6048 		}
6049 		ISP_SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
6050 		if (sp->req_status_flags & RQSTF_DISCONNECT) {
6051 			ISP_SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
6052 		}
6053 		if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
6054 			ISP_SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
6055 		}
6056 		if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
6057 			ISP_SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
6058 		}
6059 		if (sp->req_status_flags & RQSTF_BUS_RESET) {
6060 			ISP_SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
6061 		}
6062 		if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
6063 			ISP_SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
6064 		}
6065 		if (sp->req_status_flags & RQSTF_ABORTED) {
6066 			ISP_SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
6067 		}
6068 		if (sp->req_status_flags & RQSTF_TIMEOUT) {
6069 			ISP_SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
6070 		}
6071 		if (sp->req_status_flags & RQSTF_NEGOTIATION) {
6072 			ISP_SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
6073 		}
6074 		isp_xs_prt(isp, xs,  ISP_LOGERR, "Transport Error: %s", buf);
6075 		*rp = XS_XFRLEN(xs);
6076 		break;
6077 	}
6078 	case RQCS_RESET_OCCURRED:
6079 	{
6080 		int chan;
6081 		isp_xs_prt(isp, xs, ISP_LOGWARN, "Bus Reset destroyed command");
6082 		for (chan = 0; chan < isp->isp_nchan; chan++) {
6083 			FCPARAM(isp, chan)->sendmarker = 1;
6084 		}
6085 		if (XS_NOERR(xs)) {
6086 			XS_SETERR(xs, HBA_BUSRESET);
6087 		}
6088 		*rp = XS_XFRLEN(xs);
6089 		return;
6090 	}
6091 	case RQCS_ABORTED:
6092 		isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
6093 		ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
6094 		if (XS_NOERR(xs)) {
6095 			XS_SETERR(xs, HBA_ABORTED);
6096 		}
6097 		return;
6098 
6099 	case RQCS_TIMEOUT:
6100 		isp_xs_prt(isp, xs, ISP_LOGWARN, "Command timed out");
6101 		/*
6102 	 	 * XXX: Check to see if we logged out of the device.
6103 		 */
6104 		if (XS_NOERR(xs)) {
6105 			XS_SETERR(xs, HBA_CMDTIMEOUT);
6106 		}
6107 		return;
6108 
6109 	case RQCS_DATA_OVERRUN:
6110 		XS_SET_RESID(xs, sp->req_resid);
6111 		isp_xs_prt(isp, xs, ISP_LOGERR, "data overrun (%ld)", (long) XS_GET_RESID(xs));
6112 		if (XS_NOERR(xs)) {
6113 			XS_SETERR(xs, HBA_DATAOVR);
6114 		}
6115 		return;
6116 
6117 	case RQCS_COMMAND_OVERRUN:
6118 		isp_xs_prt(isp, xs, ISP_LOGERR, "command overrun");
6119 		break;
6120 
6121 	case RQCS_STATUS_OVERRUN:
6122 		isp_xs_prt(isp, xs, ISP_LOGERR, "status overrun");
6123 		break;
6124 
6125 	case RQCS_BAD_MESSAGE:
6126 		isp_xs_prt(isp, xs, ISP_LOGERR, "msg not COMMAND COMPLETE after status");
6127 		break;
6128 
6129 	case RQCS_NO_MESSAGE_OUT:
6130 		isp_xs_prt(isp, xs, ISP_LOGERR, "No MESSAGE OUT phase after selection");
6131 		break;
6132 
6133 	case RQCS_EXT_ID_FAILED:
6134 		isp_xs_prt(isp, xs, ISP_LOGERR, "EXTENDED IDENTIFY failed");
6135 		break;
6136 
6137 	case RQCS_IDE_MSG_FAILED:
6138 		isp_xs_prt(isp, xs, ISP_LOGERR, "INITIATOR DETECTED ERROR rejected");
6139 		break;
6140 
6141 	case RQCS_ABORT_MSG_FAILED:
6142 		isp_xs_prt(isp, xs, ISP_LOGERR, "ABORT OPERATION rejected");
6143 		break;
6144 
6145 	case RQCS_REJECT_MSG_FAILED:
6146 		isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE REJECT rejected");
6147 		break;
6148 
6149 	case RQCS_NOP_MSG_FAILED:
6150 		isp_xs_prt(isp, xs, ISP_LOGERR, "NOP rejected");
6151 		break;
6152 
6153 	case RQCS_PARITY_ERROR_MSG_FAILED:
6154 		isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE PARITY ERROR rejected");
6155 		break;
6156 
6157 	case RQCS_DEVICE_RESET_MSG_FAILED:
6158 		isp_xs_prt(isp, xs, ISP_LOGWARN, "BUS DEVICE RESET rejected");
6159 		break;
6160 
6161 	case RQCS_ID_MSG_FAILED:
6162 		isp_xs_prt(isp, xs, ISP_LOGERR, "IDENTIFY rejected");
6163 		break;
6164 
6165 	case RQCS_UNEXP_BUS_FREE:
6166 		isp_xs_prt(isp, xs, ISP_LOGERR, "Unexpected Bus Free");
6167 		break;
6168 
6169 	case RQCS_DATA_UNDERRUN:
6170 	{
6171 		if (IS_FC(isp)) {
6172 			int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
6173 			if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
6174 				isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
6175 				if (XS_NOERR(xs)) {
6176 					XS_SETERR(xs, HBA_BOTCH);
6177 				}
6178 				return;
6179 			}
6180 		}
6181 		XS_SET_RESID(xs, sp->req_resid);
6182 		if (XS_NOERR(xs)) {
6183 			XS_SETERR(xs, HBA_NOERROR);
6184 		}
6185 		return;
6186 	}
6187 
6188 	case RQCS_XACT_ERR1:
6189 		isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued transaction with disconnect not set");
6190 		break;
6191 
6192 	case RQCS_XACT_ERR2:
6193 		isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued transaction to target routine %d", XS_LUN(xs));
6194 		break;
6195 
6196 	case RQCS_XACT_ERR3:
6197 		isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued cmd when queueing disabled");
6198 		break;
6199 
6200 	case RQCS_BAD_ENTRY:
6201 		isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
6202 		break;
6203 
6204 	case RQCS_QUEUE_FULL:
6205 		isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "internal queues full status 0x%x", *XS_STSP(xs));
6206 
6207 		/*
6208 		 * If QFULL or some other status byte is set, then this
6209 		 * isn't an error, per se.
6210 		 *
6211 		 * Unfortunately, some QLogic f/w writers have, in
6212 		 * some cases, ommitted to *set* status to QFULL.
6213 		 *
6214 
6215 		if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
6216 			XS_SETERR(xs, HBA_NOERROR);
6217 			return;
6218 		}
6219 
6220 		 *
6221 		 *
6222 		 */
6223 
6224 		*XS_STSP(xs) = SCSI_QFULL;
6225 		XS_SETERR(xs, HBA_NOERROR);
6226 		return;
6227 
6228 	case RQCS_PHASE_SKIPPED:
6229 		isp_xs_prt(isp, xs, ISP_LOGERR, "SCSI phase skipped");
6230 		break;
6231 
6232 	case RQCS_ARQS_FAILED:
6233 		isp_xs_prt(isp, xs, ISP_LOGERR, "Auto Request Sense Failed");
6234 		if (XS_NOERR(xs)) {
6235 			XS_SETERR(xs, HBA_ARQFAIL);
6236 		}
6237 		return;
6238 
6239 	case RQCS_WIDE_FAILED:
6240 		isp_xs_prt(isp, xs, ISP_LOGERR, "Wide Negotiation Failed");
6241 		if (IS_SCSI(isp)) {
6242 			sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
6243 			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
6244 			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
6245 			sdp->update = 1;
6246 		}
6247 		if (XS_NOERR(xs)) {
6248 			XS_SETERR(xs, HBA_NOERROR);
6249 		}
6250 		return;
6251 
6252 	case RQCS_SYNCXFER_FAILED:
6253 		isp_xs_prt(isp, xs, ISP_LOGERR, "SDTR Message Failed");
6254 		if (IS_SCSI(isp)) {
6255 			sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
6256 			sdp += XS_CHANNEL(xs);
6257 			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
6258 			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
6259 			sdp->update = 1;
6260 		}
6261 		break;
6262 
6263 	case RQCS_LVD_BUSERR:
6264 		isp_xs_prt(isp, xs, ISP_LOGERR, "Bad LVD condition");
6265 		break;
6266 
6267 	case RQCS_PORT_UNAVAILABLE:
6268 		/*
6269 		 * No such port on the loop. Moral equivalent of SELTIMEO
6270 		 */
6271 	case RQCS_PORT_LOGGED_OUT:
6272 	{
6273 		const char *reason;
6274 		uint8_t sts = sp->req_completion_status & 0xff;
6275 
6276 		/*
6277 		 * It was there (maybe)- treat as a selection timeout.
6278 		 */
6279 		if (sts == RQCS_PORT_UNAVAILABLE) {
6280 			reason = "unavailable";
6281 		} else {
6282 			reason = "logout";
6283 		}
6284 
6285 		isp_prt(isp, ISP_LOGINFO, "port %s for target %d",
6286 		    reason, XS_TGT(xs));
6287 
6288 		/*
6289 		 * If we're on a local loop, force a LIP (which is overkill)
6290 		 * to force a re-login of this unit. If we're on fabric,
6291 		 * then we'll have to log in again as a matter of course.
6292 		 */
6293 		if (FCPARAM(isp, 0)->isp_topo == TOPO_NL_PORT ||
6294 		    FCPARAM(isp, 0)->isp_topo == TOPO_FL_PORT) {
6295 			mbreg_t mbs;
6296 			MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
6297 			if (ISP_CAP_2KLOGIN(isp)) {
6298 				mbs.ibits = (1 << 10);
6299 			}
6300 			isp_mboxcmd_qnw(isp, &mbs, 1);
6301 		}
6302 		if (XS_NOERR(xs)) {
6303 			XS_SETERR(xs, HBA_SELTIMEOUT);
6304 		}
6305 		return;
6306 	}
6307 	case RQCS_PORT_CHANGED:
6308 		isp_prt(isp, ISP_LOGWARN,
6309 		    "port changed for target %d", XS_TGT(xs));
6310 		if (XS_NOERR(xs)) {
6311 			XS_SETERR(xs, HBA_SELTIMEOUT);
6312 		}
6313 		return;
6314 
6315 	case RQCS_PORT_BUSY:
6316 		isp_prt(isp, ISP_LOGWARN,
6317 		    "port busy for target %d", XS_TGT(xs));
6318 		if (XS_NOERR(xs)) {
6319 			XS_SETERR(xs, HBA_TGTBSY);
6320 		}
6321 		return;
6322 
6323 	default:
6324 		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
6325 		    sp->req_completion_status);
6326 		break;
6327 	}
6328 	if (XS_NOERR(xs)) {
6329 		XS_SETERR(xs, HBA_BOTCH);
6330 	}
6331 }
6332 
6333 static void
6334 isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs, long *rp)
6335 {
6336 	int ru_marked, sv_marked;
6337 	int chan = XS_CHANNEL(xs);
6338 
6339 	switch (sp->req_completion_status) {
6340 	case RQCS_COMPLETE:
6341 		if (XS_NOERR(xs)) {
6342 			XS_SETERR(xs, HBA_NOERROR);
6343 		}
6344 		return;
6345 
6346 	case RQCS_DMA_ERROR:
6347 		isp_xs_prt(isp, xs, ISP_LOGERR, "DMA error");
6348 		break;
6349 
6350 	case RQCS_TRANSPORT_ERROR:
6351 		isp_xs_prt(isp, xs,  ISP_LOGERR, "Transport Error");
6352 		break;
6353 
6354 	case RQCS_RESET_OCCURRED:
6355 		isp_xs_prt(isp, xs, ISP_LOGWARN, "reset destroyed command");
6356 		FCPARAM(isp, chan)->sendmarker = 1;
6357 		if (XS_NOERR(xs)) {
6358 			XS_SETERR(xs, HBA_BUSRESET);
6359 		}
6360 		return;
6361 
6362 	case RQCS_ABORTED:
6363 		isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
6364 		FCPARAM(isp, chan)->sendmarker = 1;
6365 		if (XS_NOERR(xs)) {
6366 			XS_SETERR(xs, HBA_ABORTED);
6367 		}
6368 		return;
6369 
6370 	case RQCS_TIMEOUT:
6371 		isp_xs_prt(isp, xs, ISP_LOGWARN, "Command Timed Out");
6372 		if (XS_NOERR(xs)) {
6373 			XS_SETERR(xs, HBA_CMDTIMEOUT);
6374 		}
6375 		return;
6376 
6377 	case RQCS_DATA_OVERRUN:
6378 		XS_SET_RESID(xs, sp->req_resid);
6379 		isp_xs_prt(isp, xs, ISP_LOGERR, "Data Overrun");
6380 		if (XS_NOERR(xs)) {
6381 			XS_SETERR(xs, HBA_DATAOVR);
6382 		}
6383 		return;
6384 
6385 	case RQCS_24XX_DRE:	/* data reassembly error */
6386 		isp_prt(isp, ISP_LOGERR,
6387 		    "Chan %d data reassembly error for target %d",
6388 		    chan, XS_TGT(xs));
6389 		if (XS_NOERR(xs)) {
6390 			XS_SETERR(xs, HBA_ABORTED);
6391 		}
6392 		*rp = XS_XFRLEN(xs);
6393 		return;
6394 
6395 	case RQCS_24XX_TABORT:	/* aborted by target */
6396 		isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS",
6397 		    chan, XS_TGT(xs));
6398 		if (XS_NOERR(xs)) {
6399 			XS_SETERR(xs, HBA_ABORTED);
6400 		}
6401 		return;
6402 
6403 	case RQCS_DATA_UNDERRUN:
6404 		ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
6405 		/*
6406 		 * We can get an underrun w/o things being marked
6407 		 * if we got a non-zero status.
6408 		 */
6409 		sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
6410 		if ((ru_marked == 0 && sv_marked == 0) ||
6411 		    (sp->req_resid > XS_XFRLEN(xs))) {
6412 			isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
6413 			if (XS_NOERR(xs)) {
6414 				XS_SETERR(xs, HBA_BOTCH);
6415 			}
6416 			return;
6417 		}
6418 		XS_SET_RESID(xs, sp->req_resid);
6419 		isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "Data Underrun (%d) for command 0x%x", sp->req_resid, XS_CDBP(xs)[0] & 0xff);
6420 		if (XS_NOERR(xs)) {
6421 			XS_SETERR(xs, HBA_NOERROR);
6422 		}
6423 		return;
6424 
6425 	case RQCS_PORT_UNAVAILABLE:
6426 		/*
6427 		 * No such port on the loop. Moral equivalent of SELTIMEO
6428 		 */
6429 	case RQCS_PORT_LOGGED_OUT:
6430 	{
6431 		const char *reason;
6432 		uint8_t sts = sp->req_completion_status & 0xff;
6433 
6434 		/*
6435 		 * It was there (maybe)- treat as a selection timeout.
6436 		 */
6437 		if (sts == RQCS_PORT_UNAVAILABLE) {
6438 			reason = "unavailable";
6439 		} else {
6440 			reason = "logout";
6441 		}
6442 
6443 		isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d",
6444 		    chan, reason, XS_TGT(xs));
6445 
6446 		/*
6447 		 * There is no MBOX_INIT_LIP for the 24XX.
6448 		 */
6449 		if (XS_NOERR(xs)) {
6450 			XS_SETERR(xs, HBA_SELTIMEOUT);
6451 		}
6452 		return;
6453 	}
6454 	case RQCS_PORT_CHANGED:
6455 		isp_prt(isp, ISP_LOGWARN,
6456 		    "port changed for target %d chan %d", XS_TGT(xs), chan);
6457 		if (XS_NOERR(xs)) {
6458 			XS_SETERR(xs, HBA_SELTIMEOUT);
6459 		}
6460 		return;
6461 
6462 
6463 	case RQCS_24XX_ENOMEM:	/* f/w resource unavailable */
6464 		isp_prt(isp, ISP_LOGWARN,
6465 		    "f/w resource unavailable for target %d chan %d",
6466 		    XS_TGT(xs), chan);
6467 		if (XS_NOERR(xs)) {
6468 			*XS_STSP(xs) = SCSI_BUSY;
6469 			XS_SETERR(xs, HBA_TGTBSY);
6470 		}
6471 		return;
6472 
6473 	case RQCS_24XX_TMO:	/* task management overrun */
6474 		isp_prt(isp, ISP_LOGWARN,
6475 		    "command for target %d overlapped task management for "
6476 		    "chan %d", XS_TGT(xs), chan);
6477 		if (XS_NOERR(xs)) {
6478 			*XS_STSP(xs) = SCSI_BUSY;
6479 			XS_SETERR(xs, HBA_TGTBSY);
6480 		}
6481 		return;
6482 
6483 	default:
6484 		isp_prt(isp, ISP_LOGERR,
6485 		    "Unknown Completion Status 0x%x on chan %d",
6486 		    sp->req_completion_status, chan);
6487 		break;
6488 	}
6489 	if (XS_NOERR(xs)) {
6490 		XS_SETERR(xs, HBA_BOTCH);
6491 	}
6492 }
6493 
6494 static void
6495 isp_fastpost_complete(ispsoftc_t *isp, uint32_t fph)
6496 {
6497 	XS_T *xs;
6498 
6499 	if (fph == 0) {
6500 		return;
6501 	}
6502 	xs = isp_find_xs(isp, fph);
6503 	if (xs == NULL) {
6504 		isp_prt(isp, ISP_LOGWARN,
6505 		    "Command for fast post handle 0x%x not found", fph);
6506 		return;
6507 	}
6508 	isp_destroy_handle(isp, fph);
6509 
6510 	/*
6511 	 * Since we don't have a result queue entry item,
6512 	 * we must believe that SCSI status is zero and
6513 	 * that all data transferred.
6514 	 */
6515 	XS_SET_RESID(xs, 0);
6516 	*XS_STSP(xs) = SCSI_GOOD;
6517 	if (XS_XFRLEN(xs)) {
6518 		ISP_DMAFREE(isp, xs, fph);
6519 	}
6520 	if (isp->isp_nactive) {
6521 		isp->isp_nactive--;
6522 	}
6523 	isp->isp_fphccmplt++;
6524 	isp_done(xs);
6525 }
6526 
6527 static int
6528 isp_mbox_continue(ispsoftc_t *isp)
6529 {
6530 	mbreg_t mbs;
6531 	uint16_t *ptr;
6532 	uint32_t offset;
6533 
6534 	switch (isp->isp_lastmbxcmd) {
6535 	case MBOX_WRITE_RAM_WORD:
6536 	case MBOX_READ_RAM_WORD:
6537 	case MBOX_WRITE_RAM_WORD_EXTENDED:
6538 	case MBOX_READ_RAM_WORD_EXTENDED:
6539 		break;
6540 	default:
6541 		return (1);
6542 	}
6543 	if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
6544 		isp->isp_mbxwrk0 = 0;
6545 		return (-1);
6546 	}
6547 
6548 	/*
6549 	 * Clear the previous interrupt.
6550 	 */
6551 	if (IS_24XX(isp)) {
6552 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
6553 	} else {
6554 		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
6555 		ISP_WRITE(isp, BIU_SEMA, 0);
6556 	}
6557 
6558 	/*
6559 	 * Continue with next word.
6560 	 */
6561 	ISP_MEMZERO(&mbs, sizeof (mbs));
6562 	ptr = isp->isp_mbxworkp;
6563 	switch (isp->isp_lastmbxcmd) {
6564 	case MBOX_WRITE_RAM_WORD:
6565 		mbs.param[1] = isp->isp_mbxwrk1++;
6566 		mbs.param[2] = *ptr++;
6567 		break;
6568 	case MBOX_READ_RAM_WORD:
6569 		*ptr++ = isp->isp_mboxtmp[2];
6570 		mbs.param[1] = isp->isp_mbxwrk1++;
6571 		break;
6572 	case MBOX_WRITE_RAM_WORD_EXTENDED:
6573 		offset = isp->isp_mbxwrk1;
6574 		offset |= isp->isp_mbxwrk8 << 16;
6575 
6576 		mbs.param[2] = *ptr++;
6577 		mbs.param[1] = offset;
6578 		mbs.param[8] = offset >> 16;
6579 		isp->isp_mbxwrk1 = ++offset;
6580 		isp->isp_mbxwrk8 = offset >> 16;
6581 		break;
6582 	case MBOX_READ_RAM_WORD_EXTENDED:
6583 		offset = isp->isp_mbxwrk1;
6584 		offset |= isp->isp_mbxwrk8 << 16;
6585 
6586 		*ptr++ = isp->isp_mboxtmp[2];
6587 		mbs.param[1] = offset;
6588 		mbs.param[8] = offset >> 16;
6589 		isp->isp_mbxwrk1 = ++offset;
6590 		isp->isp_mbxwrk8 = offset >> 16;
6591 		break;
6592 	}
6593 	isp->isp_mbxworkp = ptr;
6594 	isp->isp_mbxwrk0--;
6595 	mbs.param[0] = isp->isp_lastmbxcmd;
6596 	mbs.logval = MBLOGALL;
6597 	isp_mboxcmd_qnw(isp, &mbs, 0);
6598 	return (0);
6599 }
6600 
6601 #define	HIWRD(x)			((x) >> 16)
6602 #define	LOWRD(x)			((x)  & 0xffff)
6603 #define	ISPOPMAP(a, b)			(((a) << 16) | (b))
6604 static const uint32_t mbpscsi[] = {
6605 	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
6606 	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
6607 	ISPOPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
6608 	ISPOPMAP(0x1f, 0x01),	/* 0x03: MBOX_DUMP_RAM */
6609 	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
6610 	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
6611 	ISPOPMAP(0x3f, 0x3f),	/* 0x06: MBOX_MAILBOX_REG_TEST */
6612 	ISPOPMAP(0x07, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
6613 	ISPOPMAP(0x01, 0x0f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
6614 	ISPOPMAP(0x00, 0x00),	/* 0x09: */
6615 	ISPOPMAP(0x00, 0x00),	/* 0x0a: */
6616 	ISPOPMAP(0x00, 0x00),	/* 0x0b: */
6617 	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
6618 	ISPOPMAP(0x00, 0x00),	/* 0x0d: */
6619 	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
6620 	ISPOPMAP(0x00, 0x00),	/* 0x0f: */
6621 	ISPOPMAP(0x1f, 0x1f),	/* 0x10: MBOX_INIT_REQ_QUEUE */
6622 	ISPOPMAP(0x3f, 0x3f),	/* 0x11: MBOX_INIT_RES_QUEUE */
6623 	ISPOPMAP(0x0f, 0x0f),	/* 0x12: MBOX_EXECUTE_IOCB */
6624 	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
6625 	ISPOPMAP(0x01, 0x3f),	/* 0x14: MBOX_STOP_FIRMWARE */
6626 	ISPOPMAP(0x0f, 0x0f),	/* 0x15: MBOX_ABORT */
6627 	ISPOPMAP(0x03, 0x03),	/* 0x16: MBOX_ABORT_DEVICE */
6628 	ISPOPMAP(0x07, 0x07),	/* 0x17: MBOX_ABORT_TARGET */
6629 	ISPOPMAP(0x07, 0x07),	/* 0x18: MBOX_BUS_RESET */
6630 	ISPOPMAP(0x03, 0x07),	/* 0x19: MBOX_STOP_QUEUE */
6631 	ISPOPMAP(0x03, 0x07),	/* 0x1a: MBOX_START_QUEUE */
6632 	ISPOPMAP(0x03, 0x07),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6633 	ISPOPMAP(0x03, 0x07),	/* 0x1c: MBOX_ABORT_QUEUE */
6634 	ISPOPMAP(0x03, 0x4f),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6635 	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
6636 	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6637 	ISPOPMAP(0x01, 0x07),	/* 0x20: MBOX_GET_INIT_SCSI_ID */
6638 	ISPOPMAP(0x01, 0x07),	/* 0x21: MBOX_GET_SELECT_TIMEOUT */
6639 	ISPOPMAP(0x01, 0xc7),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
6640 	ISPOPMAP(0x01, 0x07),	/* 0x23: MBOX_GET_TAG_AGE_LIMIT */
6641 	ISPOPMAP(0x01, 0x03),	/* 0x24: MBOX_GET_CLOCK_RATE */
6642 	ISPOPMAP(0x01, 0x07),	/* 0x25: MBOX_GET_ACT_NEG_STATE */
6643 	ISPOPMAP(0x01, 0x07),	/* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
6644 	ISPOPMAP(0x01, 0x07),	/* 0x27: MBOX_GET_PCI_PARAMS */
6645 	ISPOPMAP(0x03, 0x4f),	/* 0x28: MBOX_GET_TARGET_PARAMS */
6646 	ISPOPMAP(0x03, 0x0f),	/* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
6647 	ISPOPMAP(0x01, 0x07),	/* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
6648 	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
6649 	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
6650 	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
6651 	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
6652 	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
6653 	ISPOPMAP(0x03, 0x03),	/* 0x30: MBOX_SET_INIT_SCSI_ID */
6654 	ISPOPMAP(0x07, 0x07),	/* 0x31: MBOX_SET_SELECT_TIMEOUT */
6655 	ISPOPMAP(0xc7, 0xc7),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
6656 	ISPOPMAP(0x07, 0x07),	/* 0x33: MBOX_SET_TAG_AGE_LIMIT */
6657 	ISPOPMAP(0x03, 0x03),	/* 0x34: MBOX_SET_CLOCK_RATE */
6658 	ISPOPMAP(0x07, 0x07),	/* 0x35: MBOX_SET_ACT_NEG_STATE */
6659 	ISPOPMAP(0x07, 0x07),	/* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
6660 	ISPOPMAP(0x07, 0x07),	/* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
6661 	ISPOPMAP(0x4f, 0x4f),	/* 0x38: MBOX_SET_TARGET_PARAMS */
6662 	ISPOPMAP(0x0f, 0x0f),	/* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
6663 	ISPOPMAP(0x07, 0x07),	/* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
6664 	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
6665 	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
6666 	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
6667 	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
6668 	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
6669 	ISPOPMAP(0x01, 0x03),	/* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
6670 	ISPOPMAP(0x3f, 0x01),	/* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
6671 	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_EXEC_BIOS_IOCB */
6672 	ISPOPMAP(0x00, 0x00),	/* 0x43: */
6673 	ISPOPMAP(0x00, 0x00),	/* 0x44: */
6674 	ISPOPMAP(0x03, 0x03),	/* 0x45: SET SYSTEM PARAMETER */
6675 	ISPOPMAP(0x01, 0x03),	/* 0x46: GET SYSTEM PARAMETER */
6676 	ISPOPMAP(0x00, 0x00),	/* 0x47: */
6677 	ISPOPMAP(0x01, 0xcf),	/* 0x48: GET SCAM CONFIGURATION */
6678 	ISPOPMAP(0xcf, 0xcf),	/* 0x49: SET SCAM CONFIGURATION */
6679 	ISPOPMAP(0x03, 0x03),	/* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
6680 	ISPOPMAP(0x01, 0x03),	/* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
6681 	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
6682 	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
6683 	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
6684 	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
6685 	ISPOPMAP(0xdf, 0xdf),	/* 0x50: LOAD RAM A64 */
6686 	ISPOPMAP(0xdf, 0xdf),	/* 0x51: DUMP RAM A64 */
6687 	ISPOPMAP(0xdf, 0xff),	/* 0x52: INITIALIZE REQUEST QUEUE A64 */
6688 	ISPOPMAP(0xef, 0xff),	/* 0x53: INITIALIZE RESPONSE QUEUE A64 */
6689 	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUCUTE COMMAND IOCB A64 */
6690 	ISPOPMAP(0x07, 0x01),	/* 0x55: ENABLE TARGET MODE */
6691 	ISPOPMAP(0x03, 0x0f),	/* 0x56: GET TARGET STATUS */
6692 	ISPOPMAP(0x00, 0x00),	/* 0x57: */
6693 	ISPOPMAP(0x00, 0x00),	/* 0x58: */
6694 	ISPOPMAP(0x00, 0x00),	/* 0x59: */
6695 	ISPOPMAP(0x03, 0x03),	/* 0x5a: SET DATA OVERRUN RECOVERY MODE */
6696 	ISPOPMAP(0x01, 0x03),	/* 0x5b: GET DATA OVERRUN RECOVERY MODE */
6697 	ISPOPMAP(0x0f, 0x0f),	/* 0x5c: SET HOST DATA */
6698 	ISPOPMAP(0x01, 0x01)	/* 0x5d: GET NOST DATA */
6699 };
6700 
6701 static const char *scsi_mbcmd_names[] = {
6702 	"NO-OP",
6703 	"LOAD RAM",
6704 	"EXEC FIRMWARE",
6705 	"DUMP RAM",
6706 	"WRITE RAM WORD",
6707 	"READ RAM WORD",
6708 	"MAILBOX REG TEST",
6709 	"VERIFY CHECKSUM",
6710 	"ABOUT FIRMWARE",
6711 	NULL,
6712 	NULL,
6713 	NULL,
6714 	NULL,
6715 	NULL,
6716 	"CHECK FIRMWARE",
6717 	NULL,
6718 	"INIT REQUEST QUEUE",
6719 	"INIT RESULT QUEUE",
6720 	"EXECUTE IOCB",
6721 	"WAKE UP",
6722 	"STOP FIRMWARE",
6723 	"ABORT",
6724 	"ABORT DEVICE",
6725 	"ABORT TARGET",
6726 	"BUS RESET",
6727 	"STOP QUEUE",
6728 	"START QUEUE",
6729 	"SINGLE STEP QUEUE",
6730 	"ABORT QUEUE",
6731 	"GET DEV QUEUE STATUS",
6732 	NULL,
6733 	"GET FIRMWARE STATUS",
6734 	"GET INIT SCSI ID",
6735 	"GET SELECT TIMEOUT",
6736 	"GET RETRY COUNT",
6737 	"GET TAG AGE LIMIT",
6738 	"GET CLOCK RATE",
6739 	"GET ACT NEG STATE",
6740 	"GET ASYNC DATA SETUP TIME",
6741 	"GET PCI PARAMS",
6742 	"GET TARGET PARAMS",
6743 	"GET DEV QUEUE PARAMS",
6744 	"GET RESET DELAY PARAMS",
6745 	NULL,
6746 	NULL,
6747 	NULL,
6748 	NULL,
6749 	NULL,
6750 	"SET INIT SCSI ID",
6751 	"SET SELECT TIMEOUT",
6752 	"SET RETRY COUNT",
6753 	"SET TAG AGE LIMIT",
6754 	"SET CLOCK RATE",
6755 	"SET ACT NEG STATE",
6756 	"SET ASYNC DATA SETUP TIME",
6757 	"SET PCI CONTROL PARAMS",
6758 	"SET TARGET PARAMS",
6759 	"SET DEV QUEUE PARAMS",
6760 	"SET RESET DELAY PARAMS",
6761 	NULL,
6762 	NULL,
6763 	NULL,
6764 	NULL,
6765 	NULL,
6766 	"RETURN BIOS BLOCK ADDR",
6767 	"WRITE FOUR RAM WORDS",
6768 	"EXEC BIOS IOCB",
6769 	NULL,
6770 	NULL,
6771 	"SET SYSTEM PARAMETER",
6772 	"GET SYSTEM PARAMETER",
6773 	NULL,
6774 	"GET SCAM CONFIGURATION",
6775 	"SET SCAM CONFIGURATION",
6776 	"SET FIRMWARE FEATURES",
6777 	"GET FIRMWARE FEATURES",
6778 	NULL,
6779 	NULL,
6780 	NULL,
6781 	NULL,
6782 	"LOAD RAM A64",
6783 	"DUMP RAM A64",
6784 	"INITIALIZE REQUEST QUEUE A64",
6785 	"INITIALIZE RESPONSE QUEUE A64",
6786 	"EXECUTE IOCB A64",
6787 	"ENABLE TARGET MODE",
6788 	"GET TARGET MODE STATE",
6789 	NULL,
6790 	NULL,
6791 	NULL,
6792 	"SET DATA OVERRUN RECOVERY MODE",
6793 	"GET DATA OVERRUN RECOVERY MODE",
6794 	"SET HOST DATA",
6795 	"GET NOST DATA",
6796 };
6797 
6798 static const uint32_t mbpfc[] = {
6799 	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
6800 	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
6801 	ISPOPMAP(0x0f, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
6802 	ISPOPMAP(0xdf, 0x01),	/* 0x03: MBOX_DUMP_RAM */
6803 	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
6804 	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
6805 	ISPOPMAP(0xff, 0xff),	/* 0x06: MBOX_MAILBOX_REG_TEST */
6806 	ISPOPMAP(0x07, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
6807 	ISPOPMAP(0x01, 0x4f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
6808 	ISPOPMAP(0xdf, 0x01),	/* 0x09: MBOX_LOAD_RISC_RAM_2100 */
6809 	ISPOPMAP(0xdf, 0x01),	/* 0x0a: DUMP RAM */
6810 	ISPOPMAP(0x1ff, 0x01),	/* 0x0b: MBOX_LOAD_RISC_RAM */
6811 	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
6812 	ISPOPMAP(0x10f, 0x01),	/* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
6813 	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
6814 	ISPOPMAP(0x10f, 0x05),	/* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
6815 	ISPOPMAP(0x1f, 0x11),	/* 0x10: MBOX_INIT_REQ_QUEUE */
6816 	ISPOPMAP(0x2f, 0x21),	/* 0x11: MBOX_INIT_RES_QUEUE */
6817 	ISPOPMAP(0x0f, 0x01),	/* 0x12: MBOX_EXECUTE_IOCB */
6818 	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
6819 	ISPOPMAP(0x01, 0xff),	/* 0x14: MBOX_STOP_FIRMWARE */
6820 	ISPOPMAP(0x4f, 0x01),	/* 0x15: MBOX_ABORT */
6821 	ISPOPMAP(0x07, 0x01),	/* 0x16: MBOX_ABORT_DEVICE */
6822 	ISPOPMAP(0x07, 0x01),	/* 0x17: MBOX_ABORT_TARGET */
6823 	ISPOPMAP(0x03, 0x03),	/* 0x18: MBOX_BUS_RESET */
6824 	ISPOPMAP(0x07, 0x05),	/* 0x19: MBOX_STOP_QUEUE */
6825 	ISPOPMAP(0x07, 0x05),	/* 0x1a: MBOX_START_QUEUE */
6826 	ISPOPMAP(0x07, 0x05),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6827 	ISPOPMAP(0x07, 0x05),	/* 0x1c: MBOX_ABORT_QUEUE */
6828 	ISPOPMAP(0x07, 0x03),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6829 	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
6830 	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6831 	ISPOPMAP(0x01, 0x4f),	/* 0x20: MBOX_GET_LOOP_ID */
6832 	ISPOPMAP(0x00, 0x00),	/* 0x21: */
6833 	ISPOPMAP(0x01, 0x07),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
6834 	ISPOPMAP(0x00, 0x00),	/* 0x23: */
6835 	ISPOPMAP(0x00, 0x00),	/* 0x24: */
6836 	ISPOPMAP(0x00, 0x00),	/* 0x25: */
6837 	ISPOPMAP(0x00, 0x00),	/* 0x26: */
6838 	ISPOPMAP(0x00, 0x00),	/* 0x27: */
6839 	ISPOPMAP(0x01, 0x03),	/* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
6840 	ISPOPMAP(0x03, 0x07),	/* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
6841 	ISPOPMAP(0x00, 0x00),	/* 0x2a: */
6842 	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
6843 	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
6844 	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
6845 	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
6846 	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
6847 	ISPOPMAP(0x00, 0x00),	/* 0x30: */
6848 	ISPOPMAP(0x00, 0x00),	/* 0x31: */
6849 	ISPOPMAP(0x07, 0x07),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
6850 	ISPOPMAP(0x00, 0x00),	/* 0x33: */
6851 	ISPOPMAP(0x00, 0x00),	/* 0x34: */
6852 	ISPOPMAP(0x00, 0x00),	/* 0x35: */
6853 	ISPOPMAP(0x00, 0x00),	/* 0x36: */
6854 	ISPOPMAP(0x00, 0x00),	/* 0x37: */
6855 	ISPOPMAP(0x0f, 0x01),	/* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
6856 	ISPOPMAP(0x0f, 0x07),	/* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
6857 	ISPOPMAP(0x00, 0x00),	/* 0x3a: */
6858 	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
6859 	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
6860 	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
6861 	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
6862 	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
6863 	ISPOPMAP(0x03, 0x01),	/* 0x40: MBOX_LOOP_PORT_BYPASS */
6864 	ISPOPMAP(0x03, 0x01),	/* 0x41: MBOX_LOOP_PORT_ENABLE */
6865 	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_GET_RESOURCE_COUNT */
6866 	ISPOPMAP(0x01, 0x01),	/* 0x43: MBOX_REQUEST_OFFLINE_MODE */
6867 	ISPOPMAP(0x00, 0x00),	/* 0x44: */
6868 	ISPOPMAP(0x00, 0x00),	/* 0x45: */
6869 	ISPOPMAP(0x00, 0x00),	/* 0x46: */
6870 	ISPOPMAP(0xcf, 0x03),	/* 0x47: GET PORT_DATABASE ENHANCED */
6871 	ISPOPMAP(0xcd, 0x01),	/* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */
6872 	ISPOPMAP(0xcd, 0x01),	/* 0x49: MBOX_GET_VP_DATABASE */
6873 	ISPOPMAP(0x2cd, 0x01),	/* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */
6874 	ISPOPMAP(0x00, 0x00),	/* 0x4b: */
6875 	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
6876 	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
6877 	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
6878 	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
6879 	ISPOPMAP(0x00, 0x00),	/* 0x50: */
6880 	ISPOPMAP(0x00, 0x00),	/* 0x51: */
6881 	ISPOPMAP(0x00, 0x00),	/* 0x52: */
6882 	ISPOPMAP(0x00, 0x00),	/* 0x53: */
6883 	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
6884 	ISPOPMAP(0x00, 0x00),	/* 0x55: */
6885 	ISPOPMAP(0x00, 0x00),	/* 0x56: */
6886 	ISPOPMAP(0x00, 0x00),	/* 0x57: */
6887 	ISPOPMAP(0x00, 0x00),	/* 0x58: */
6888 	ISPOPMAP(0x00, 0x00),	/* 0x59: */
6889 	ISPOPMAP(0x00, 0x00),	/* 0x5a: */
6890 	ISPOPMAP(0x03, 0x01),	/* 0x5b: MBOX_DRIVER_HEARTBEAT */
6891 	ISPOPMAP(0xcf, 0x01),	/* 0x5c: MBOX_FW_HEARTBEAT */
6892 	ISPOPMAP(0x07, 0x03),	/* 0x5d: MBOX_GET_SET_DATA_RATE */
6893 	ISPOPMAP(0x00, 0x00),	/* 0x5e: */
6894 	ISPOPMAP(0x00, 0x00),	/* 0x5f: */
6895 	ISPOPMAP(0xcd, 0x01),	/* 0x60: MBOX_INIT_FIRMWARE */
6896 	ISPOPMAP(0x00, 0x00),	/* 0x61: */
6897 	ISPOPMAP(0x01, 0x01),	/* 0x62: MBOX_INIT_LIP */
6898 	ISPOPMAP(0xcd, 0x03),	/* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
6899 	ISPOPMAP(0xcf, 0x01),	/* 0x64: MBOX_GET_PORT_DB */
6900 	ISPOPMAP(0x07, 0x01),	/* 0x65: MBOX_CLEAR_ACA */
6901 	ISPOPMAP(0x07, 0x01),	/* 0x66: MBOX_TARGET_RESET */
6902 	ISPOPMAP(0x07, 0x01),	/* 0x67: MBOX_CLEAR_TASK_SET */
6903 	ISPOPMAP(0x07, 0x01),	/* 0x68: MBOX_ABORT_TASK_SET */
6904 	ISPOPMAP(0x01, 0x07),	/* 0x69: MBOX_GET_FW_STATE */
6905 	ISPOPMAP(0x03, 0xcf),	/* 0x6a: MBOX_GET_PORT_NAME */
6906 	ISPOPMAP(0xcf, 0x01),	/* 0x6b: MBOX_GET_LINK_STATUS */
6907 	ISPOPMAP(0x0f, 0x01),	/* 0x6c: MBOX_INIT_LIP_RESET */
6908 	ISPOPMAP(0x00, 0x00),	/* 0x6d: */
6909 	ISPOPMAP(0xcf, 0x03),	/* 0x6e: MBOX_SEND_SNS */
6910 	ISPOPMAP(0x0f, 0x07),	/* 0x6f: MBOX_FABRIC_LOGIN */
6911 	ISPOPMAP(0x03, 0x01),	/* 0x70: MBOX_SEND_CHANGE_REQUEST */
6912 	ISPOPMAP(0x03, 0x03),	/* 0x71: MBOX_FABRIC_LOGOUT */
6913 	ISPOPMAP(0x0f, 0x0f),	/* 0x72: MBOX_INIT_LIP_LOGIN */
6914 	ISPOPMAP(0x00, 0x00),	/* 0x73: */
6915 	ISPOPMAP(0x07, 0x01),	/* 0x74: LOGIN LOOP PORT */
6916 	ISPOPMAP(0xcf, 0x03),	/* 0x75: GET PORT/NODE NAME LIST */
6917 	ISPOPMAP(0x4f, 0x01),	/* 0x76: SET VENDOR ID */
6918 	ISPOPMAP(0xcd, 0x01),	/* 0x77: INITIALIZE IP MAILBOX */
6919 	ISPOPMAP(0x00, 0x00),	/* 0x78: */
6920 	ISPOPMAP(0x00, 0x00),	/* 0x79: */
6921 	ISPOPMAP(0x00, 0x00),	/* 0x7a: */
6922 	ISPOPMAP(0x00, 0x00),	/* 0x7b: */
6923 	ISPOPMAP(0x4f, 0x03),	/* 0x7c: Get ID List */
6924 	ISPOPMAP(0xcf, 0x01),	/* 0x7d: SEND LFA */
6925 	ISPOPMAP(0x0f, 0x01)	/* 0x7e: LUN RESET */
6926 };
6927 /*
6928  * Footnotes
6929  *
6930  * (1): this sets bits 21..16 in mailbox register #8, which we nominally
6931  *	do not access at this time in the core driver. The caller is
6932  *	responsible for setting this register first (Gross!). The assumption
6933  *	is that we won't overflow.
6934  */
6935 
6936 static const char *fc_mbcmd_names[] = {
6937 	"NO-OP",
6938 	"LOAD RAM",
6939 	"EXEC FIRMWARE",
6940 	"DUMP RAM",
6941 	"WRITE RAM WORD",
6942 	"READ RAM WORD",
6943 	"MAILBOX REG TEST",
6944 	"VERIFY CHECKSUM",
6945 	"ABOUT FIRMWARE",
6946 	"LOAD RAM",
6947 	"DUMP RAM",
6948 	"WRITE RAM WORD EXTENDED",
6949 	NULL,
6950 	"READ RAM WORD EXTENDED",
6951 	"CHECK FIRMWARE",
6952 	NULL,
6953 	"INIT REQUEST QUEUE",
6954 	"INIT RESULT QUEUE",
6955 	"EXECUTE IOCB",
6956 	"WAKE UP",
6957 	"STOP FIRMWARE",
6958 	"ABORT",
6959 	"ABORT DEVICE",
6960 	"ABORT TARGET",
6961 	"BUS RESET",
6962 	"STOP QUEUE",
6963 	"START QUEUE",
6964 	"SINGLE STEP QUEUE",
6965 	"ABORT QUEUE",
6966 	"GET DEV QUEUE STATUS",
6967 	NULL,
6968 	"GET FIRMWARE STATUS",
6969 	"GET LOOP ID",
6970 	NULL,
6971 	"GET RETRY COUNT",
6972 	NULL,
6973 	NULL,
6974 	NULL,
6975 	NULL,
6976 	NULL,
6977 	"GET FIRMWARE OPTIONS",
6978 	"GET PORT QUEUE PARAMS",
6979 	NULL,
6980 	NULL,
6981 	NULL,
6982 	NULL,
6983 	NULL,
6984 	NULL,
6985 	NULL,
6986 	NULL,
6987 	"SET RETRY COUNT",
6988 	NULL,
6989 	NULL,
6990 	NULL,
6991 	NULL,
6992 	NULL,
6993 	"SET FIRMWARE OPTIONS",
6994 	"SET PORT QUEUE PARAMS",
6995 	NULL,
6996 	NULL,
6997 	NULL,
6998 	NULL,
6999 	NULL,
7000 	NULL,
7001 	"LOOP PORT BYPASS",
7002 	"LOOP PORT ENABLE",
7003 	"GET RESOURCE COUNT",
7004 	"REQUEST NON PARTICIPATING MODE",
7005 	NULL,
7006 	NULL,
7007 	NULL,
7008 	"GET PORT DATABASE ENHANCED",
7009 	"INIT FIRMWARE MULTI ID",
7010 	"GET VP DATABASE",
7011 	"GET VP DATABASE ENTRY",
7012 	NULL,
7013 	NULL,
7014 	NULL,
7015 	NULL,
7016 	NULL,
7017 	NULL,
7018 	NULL,
7019 	NULL,
7020 	NULL,
7021 	"EXECUTE IOCB A64",
7022 	NULL,
7023 	NULL,
7024 	NULL,
7025 	NULL,
7026 	NULL,
7027 	NULL,
7028 	"DRIVER HEARTBEAT",
7029 	NULL,
7030 	"GET/SET DATA RATE",
7031 	NULL,
7032 	NULL,
7033 	"INIT FIRMWARE",
7034 	NULL,
7035 	"INIT LIP",
7036 	"GET FC-AL POSITION MAP",
7037 	"GET PORT DATABASE",
7038 	"CLEAR ACA",
7039 	"TARGET RESET",
7040 	"CLEAR TASK SET",
7041 	"ABORT TASK SET",
7042 	"GET FW STATE",
7043 	"GET PORT NAME",
7044 	"GET LINK STATUS",
7045 	"INIT LIP RESET",
7046 	NULL,
7047 	"SEND SNS",
7048 	"FABRIC LOGIN",
7049 	"SEND CHANGE REQUEST",
7050 	"FABRIC LOGOUT",
7051 	"INIT LIP LOGIN",
7052 	NULL,
7053 	"LOGIN LOOP PORT",
7054 	"GET PORT/NODE NAME LIST",
7055 	"SET VENDOR ID",
7056 	"INITIALIZE IP MAILBOX",
7057 	NULL,
7058 	NULL,
7059 	NULL,
7060 	NULL,
7061 	"Get ID List",
7062 	"SEND LFA",
7063 	"Lun RESET"
7064 };
7065 
7066 static void
7067 isp_mboxcmd_qnw(ispsoftc_t *isp, mbreg_t *mbp, int nodelay)
7068 {
7069 	unsigned int ibits, obits, box, opcode;
7070 	const uint32_t *mcp;
7071 
7072 	if (IS_FC(isp)) {
7073 		mcp = mbpfc;
7074 	} else {
7075 		mcp = mbpscsi;
7076 	}
7077 	opcode = mbp->param[0];
7078 	ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7079 	obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7080 	ibits |= mbp->ibits;
7081 	obits |= mbp->obits;
7082 	for (box = 0; box < MAX_MAILBOX(isp); box++) {
7083 		if (ibits & (1 << box)) {
7084 			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
7085 		}
7086 		if (nodelay == 0) {
7087 			isp->isp_mboxtmp[box] = mbp->param[box] = 0;
7088 		}
7089 	}
7090 	if (nodelay == 0) {
7091 		isp->isp_lastmbxcmd = opcode;
7092 		isp->isp_obits = obits;
7093 		isp->isp_mboxbsy = 1;
7094 	}
7095 	if (IS_24XX(isp)) {
7096 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
7097 	} else {
7098 		ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
7099 	}
7100 	/*
7101 	 * Oddly enough, if we're not delaying for an answer,
7102 	 * delay a bit to give the f/w a chance to pick up the
7103 	 * command.
7104 	 */
7105 	if (nodelay) {
7106 		ISP_DELAY(1000);
7107 	}
7108 }
7109 
7110 static void
7111 isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
7112 {
7113 	const char *cname, *xname;
7114 	char tname[16], mname[16];
7115 	unsigned int lim, ibits, obits, box, opcode;
7116 	const uint32_t *mcp;
7117 
7118 	if (IS_FC(isp)) {
7119 		mcp = mbpfc;
7120 		lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
7121 	} else {
7122 		mcp = mbpscsi;
7123 		lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
7124 	}
7125 
7126 	if ((opcode = mbp->param[0]) >= lim) {
7127 		mbp->param[0] = MBOX_INVALID_COMMAND;
7128 		isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
7129 		return;
7130 	}
7131 
7132 	ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7133 	obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7134 
7135 	/*
7136 	 * Pick up any additional bits that the caller might have set.
7137 	 */
7138 	ibits |= mbp->ibits;
7139 	obits |= mbp->obits;
7140 
7141 	if (ibits == 0 && obits == 0) {
7142 		mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
7143 		isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
7144 		return;
7145 	}
7146 
7147 	/*
7148 	 * Get exclusive usage of mailbox registers.
7149 	 */
7150 	if (MBOX_ACQUIRE(isp)) {
7151 		mbp->param[0] = MBOX_REGS_BUSY;
7152 		goto out;
7153 	}
7154 
7155 	for (box = 0; box < MAX_MAILBOX(isp); box++) {
7156 		if (ibits & (1 << box)) {
7157 			isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box,
7158 			    mbp->param[box]);
7159 			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
7160 		}
7161 		isp->isp_mboxtmp[box] = mbp->param[box] = 0;
7162 	}
7163 
7164 	isp->isp_lastmbxcmd = opcode;
7165 
7166 	/*
7167 	 * We assume that we can't overwrite a previous command.
7168 	 */
7169 	isp->isp_obits = obits;
7170 	isp->isp_mboxbsy = 1;
7171 
7172 	/*
7173 	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
7174 	 */
7175 	if (IS_24XX(isp)) {
7176 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
7177 	} else {
7178 		ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
7179 	}
7180 
7181 	/*
7182 	 * While we haven't finished the command, spin our wheels here.
7183 	 */
7184 	MBOX_WAIT_COMPLETE(isp, mbp);
7185 
7186 	/*
7187 	 * Did the command time out?
7188 	 */
7189 	if (mbp->param[0] == MBOX_TIMEOUT) {
7190 		isp->isp_mboxbsy = 0;
7191 		MBOX_RELEASE(isp);
7192 		goto out;
7193 	}
7194 
7195 	/*
7196 	 * Copy back output registers.
7197 	 */
7198 	for (box = 0; box < MAX_MAILBOX(isp); box++) {
7199 		if (obits & (1 << box)) {
7200 			mbp->param[box] = isp->isp_mboxtmp[box];
7201 			isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box,
7202 			    mbp->param[box]);
7203 		}
7204 	}
7205 
7206 	isp->isp_mboxbsy = 0;
7207 	MBOX_RELEASE(isp);
7208  out:
7209 	if (mbp->logval == 0 || opcode == MBOX_EXEC_FIRMWARE) {
7210 		return;
7211 	}
7212 	cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
7213 	if (cname == NULL) {
7214 		cname = tname;
7215 		ISP_SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
7216 	}
7217 
7218 	/*
7219 	 * Just to be chatty here...
7220 	 */
7221 	xname = NULL;
7222 	switch (mbp->param[0]) {
7223 	case MBOX_COMMAND_COMPLETE:
7224 		break;
7225 	case MBOX_INVALID_COMMAND:
7226 		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_COMPLETE)) {
7227 			xname = "INVALID COMMAND";
7228 		}
7229 		break;
7230 	case MBOX_HOST_INTERFACE_ERROR:
7231 		if (mbp->logval & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR)) {
7232 			xname = "HOST INTERFACE ERROR";
7233 		}
7234 		break;
7235 	case MBOX_TEST_FAILED:
7236 		if (mbp->logval & MBLOGMASK(MBOX_TEST_FAILED)) {
7237 			xname = "TEST FAILED";
7238 		}
7239 		break;
7240 	case MBOX_COMMAND_ERROR:
7241 		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_ERROR)) {
7242 			xname = "COMMAND ERROR";
7243 		}
7244 		break;
7245 	case MBOX_COMMAND_PARAM_ERROR:
7246 		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR)) {
7247 			xname = "COMMAND PARAMETER ERROR";
7248 		}
7249 		break;
7250 	case MBOX_LOOP_ID_USED:
7251 		if (mbp->logval & MBLOGMASK(MBOX_LOOP_ID_USED)) {
7252 			xname = "LOOP ID ALREADY IN USE";
7253 		}
7254 		break;
7255 	case MBOX_PORT_ID_USED:
7256 		if (mbp->logval & MBLOGMASK(MBOX_PORT_ID_USED)) {
7257 			xname = "PORT ID ALREADY IN USE";
7258 		}
7259 		break;
7260 	case MBOX_ALL_IDS_USED:
7261 		if (mbp->logval & MBLOGMASK(MBOX_ALL_IDS_USED)) {
7262 			xname = "ALL LOOP IDS IN USE";
7263 		}
7264 		break;
7265 	case MBOX_REGS_BUSY:
7266 		xname = "REGISTERS BUSY";
7267 		break;
7268 	case MBOX_TIMEOUT:
7269 		xname = "TIMEOUT";
7270 		break;
7271 	default:
7272 		ISP_SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
7273 		xname = mname;
7274 		break;
7275 	}
7276 	if (xname) {
7277 		isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
7278 		    cname, xname);
7279 	}
7280 }
7281 
7282 static void
7283 isp_fw_state(ispsoftc_t *isp, int chan)
7284 {
7285 	if (IS_FC(isp)) {
7286 		mbreg_t mbs;
7287 		fcparam *fcp = FCPARAM(isp, chan);
7288 
7289 		MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0);
7290 		isp_mboxcmd(isp, &mbs);
7291 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
7292 			fcp->isp_fwstate = mbs.param[1];
7293 		}
7294 	}
7295 }
7296 
7297 static void
7298 isp_spi_update(ispsoftc_t *isp, int chan)
7299 {
7300 	int tgt;
7301 	mbreg_t mbs;
7302 	sdparam *sdp;
7303 
7304 	if (IS_FC(isp)) {
7305 		/*
7306 		 * There are no 'per-bus' settings for Fibre Channel.
7307 		 */
7308 		return;
7309 	}
7310 	sdp = SDPARAM(isp, chan);
7311 	sdp->update = 0;
7312 
7313 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7314 		uint16_t flags, period, offset;
7315 		int get;
7316 
7317 		if (sdp->isp_devparam[tgt].dev_enable == 0) {
7318 			sdp->isp_devparam[tgt].dev_update = 0;
7319 			sdp->isp_devparam[tgt].dev_refresh = 0;
7320 			isp_prt(isp, ISP_LOGDEBUG0, "skipping target %d bus %d update", tgt, chan);
7321 			continue;
7322 		}
7323 		/*
7324 		 * If the goal is to update the status of the device,
7325 		 * take what's in goal_flags and try and set the device
7326 		 * toward that. Otherwise, if we're just refreshing the
7327 		 * current device state, get the current parameters.
7328 		 */
7329 
7330 		MBSINIT(&mbs, 0, MBLOGALL, 0);
7331 
7332 		/*
7333 		 * Refresh overrides set
7334 		 */
7335 		if (sdp->isp_devparam[tgt].dev_refresh) {
7336 			mbs.param[0] = MBOX_GET_TARGET_PARAMS;
7337 			get = 1;
7338 		} else if (sdp->isp_devparam[tgt].dev_update) {
7339 			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
7340 
7341 			/*
7342 			 * Make sure goal_flags has "Renegotiate on Error"
7343 			 * on and "Freeze Queue on Error" off.
7344 			 */
7345 			sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
7346 			sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
7347 			mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
7348 
7349 			/*
7350 			 * Insist that PARITY must be enabled
7351 			 * if SYNC or WIDE is enabled.
7352 			 */
7353 			if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
7354 				mbs.param[2] |= DPARM_PARITY;
7355 			}
7356 
7357 			if (mbs.param[2] & DPARM_SYNC) {
7358 				mbs.param[3] =
7359 				    (sdp->isp_devparam[tgt].goal_offset << 8) |
7360 				    (sdp->isp_devparam[tgt].goal_period);
7361 			}
7362 			/*
7363 			 * A command completion later that has
7364 			 * RQSTF_NEGOTIATION set can cause
7365 			 * the dev_refresh/announce cycle also.
7366 			 *
7367 			 * Note: It is really important to update our current
7368 			 * flags with at least the state of TAG capabilities-
7369 			 * otherwise we might try and send a tagged command
7370 			 * when we have it all turned off. So change it here
7371 			 * to say that current already matches goal.
7372 			 */
7373 			sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
7374 			sdp->isp_devparam[tgt].actv_flags |=
7375 			    (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
7376 			isp_prt(isp, ISP_LOGDEBUG0, "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
7377 			    chan, tgt, mbs.param[2], mbs.param[3] >> 8, mbs.param[3] & 0xff);
7378 			get = 0;
7379 		} else {
7380 			continue;
7381 		}
7382 		mbs.param[1] = (chan << 15) | (tgt << 8);
7383 		isp_mboxcmd(isp, &mbs);
7384 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7385 			continue;
7386 		}
7387 		if (get == 0) {
7388 			sdp->sendmarker = 1;
7389 			sdp->isp_devparam[tgt].dev_update = 0;
7390 			sdp->isp_devparam[tgt].dev_refresh = 1;
7391 		} else {
7392 			sdp->isp_devparam[tgt].dev_refresh = 0;
7393 			flags = mbs.param[2];
7394 			period = mbs.param[3] & 0xff;
7395 			offset = mbs.param[3] >> 8;
7396 			sdp->isp_devparam[tgt].actv_flags = flags;
7397 			sdp->isp_devparam[tgt].actv_period = period;
7398 			sdp->isp_devparam[tgt].actv_offset = offset;
7399 			isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, chan, tgt);
7400 		}
7401 	}
7402 
7403 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7404 		if (sdp->isp_devparam[tgt].dev_update ||
7405 		    sdp->isp_devparam[tgt].dev_refresh) {
7406 			sdp->update = 1;
7407 			break;
7408 		}
7409 	}
7410 }
7411 
7412 static void
7413 isp_setdfltsdparm(ispsoftc_t *isp)
7414 {
7415 	int tgt;
7416 	sdparam *sdp, *sdp1;
7417 
7418 	sdp = SDPARAM(isp, 0);
7419 	sdp->role = GET_DEFAULT_ROLE(isp, 0);
7420 	if (IS_DUALBUS(isp)) {
7421 		sdp1 = sdp + 1;
7422 		sdp1->role = GET_DEFAULT_ROLE(isp, 1);
7423 	} else {
7424 		sdp1 = NULL;
7425 	}
7426 
7427 	/*
7428 	 * Establish some default parameters.
7429 	 */
7430 	sdp->isp_cmd_dma_burst_enable = 0;
7431 	sdp->isp_data_dma_burst_enabl = 1;
7432 	sdp->isp_fifo_threshold = 0;
7433 	sdp->isp_initiator_id = DEFAULT_IID(isp, 0);
7434 	if (isp->isp_type >= ISP_HA_SCSI_1040) {
7435 		sdp->isp_async_data_setup = 9;
7436 	} else {
7437 		sdp->isp_async_data_setup = 6;
7438 	}
7439 	sdp->isp_selection_timeout = 250;
7440 	sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
7441 	sdp->isp_tag_aging = 8;
7442 	sdp->isp_bus_reset_delay = 5;
7443 	/*
7444 	 * Don't retry selection, busy or queue full automatically- reflect
7445 	 * these back to us.
7446 	 */
7447 	sdp->isp_retry_count = 0;
7448 	sdp->isp_retry_delay = 0;
7449 
7450 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7451 		sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
7452 		sdp->isp_devparam[tgt].dev_enable = 1;
7453 	}
7454 
7455 	/*
7456 	 * The trick here is to establish a default for the default (honk!)
7457 	 * state (goal_flags). Then try and get the current status from
7458 	 * the card to fill in the current state. We don't, in fact, set
7459 	 * the default to the SAFE default state- that's not the goal state.
7460 	 */
7461 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7462 		uint8_t off, per;
7463 		sdp->isp_devparam[tgt].actv_offset = 0;
7464 		sdp->isp_devparam[tgt].actv_period = 0;
7465 		sdp->isp_devparam[tgt].actv_flags = 0;
7466 
7467 		sdp->isp_devparam[tgt].goal_flags =
7468 		    sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
7469 
7470 		/*
7471 		 * We default to Wide/Fast for versions less than a 1040
7472 		 * (unless it's SBus).
7473 		 */
7474 		if (IS_ULTRA3(isp)) {
7475 			off = ISP_80M_SYNCPARMS >> 8;
7476 			per = ISP_80M_SYNCPARMS & 0xff;
7477 		} else if (IS_ULTRA2(isp)) {
7478 			off = ISP_40M_SYNCPARMS >> 8;
7479 			per = ISP_40M_SYNCPARMS & 0xff;
7480 		} else if (IS_1240(isp)) {
7481 			off = ISP_20M_SYNCPARMS >> 8;
7482 			per = ISP_20M_SYNCPARMS & 0xff;
7483 		} else if ((isp->isp_bustype == ISP_BT_SBUS &&
7484 		    isp->isp_type < ISP_HA_SCSI_1020A) ||
7485 		    (isp->isp_bustype == ISP_BT_PCI &&
7486 		    isp->isp_type < ISP_HA_SCSI_1040) ||
7487 		    (isp->isp_clock && isp->isp_clock < 60) ||
7488 		    (sdp->isp_ultramode == 0)) {
7489 			off = ISP_10M_SYNCPARMS >> 8;
7490 			per = ISP_10M_SYNCPARMS & 0xff;
7491 		} else {
7492 			off = ISP_20M_SYNCPARMS_1040 >> 8;
7493 			per = ISP_20M_SYNCPARMS_1040 & 0xff;
7494 		}
7495 		sdp->isp_devparam[tgt].goal_offset =
7496 		    sdp->isp_devparam[tgt].nvrm_offset = off;
7497 		sdp->isp_devparam[tgt].goal_period =
7498 		    sdp->isp_devparam[tgt].nvrm_period = per;
7499 
7500 	}
7501 
7502 	/*
7503 	 * If we're a dual bus card, just copy the data over
7504 	 */
7505 	if (sdp1) {
7506 		*sdp1 = *sdp;
7507 		sdp1->isp_initiator_id = DEFAULT_IID(isp, 1);
7508 	}
7509 
7510 	/*
7511 	 * If we've not been told to avoid reading NVRAM, try and read it.
7512 	 * If we're successful reading it, we can then return because NVRAM
7513 	 * will tell us what the desired settings are. Otherwise, we establish
7514 	 * some reasonable 'fake' nvram and goal defaults.
7515 	 */
7516 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7517 		mbreg_t mbs;
7518 
7519 		if (isp_read_nvram(isp, 0) == 0) {
7520 			if (IS_DUALBUS(isp)) {
7521 				if (isp_read_nvram(isp, 1) == 0) {
7522 					return;
7523 				}
7524 			}
7525 		}
7526 		MBSINIT(&mbs, MBOX_GET_ACT_NEG_STATE, MBLOGNONE, 0);
7527 		isp_mboxcmd(isp, &mbs);
7528 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7529 			sdp->isp_req_ack_active_neg = 1;
7530 			sdp->isp_data_line_active_neg = 1;
7531 			if (sdp1) {
7532 				sdp1->isp_req_ack_active_neg = 1;
7533 				sdp1->isp_data_line_active_neg = 1;
7534 			}
7535 		} else {
7536 			sdp->isp_req_ack_active_neg =
7537 			    (mbs.param[1] >> 4) & 0x1;
7538 			sdp->isp_data_line_active_neg =
7539 			    (mbs.param[1] >> 5) & 0x1;
7540 			if (sdp1) {
7541 				sdp1->isp_req_ack_active_neg =
7542 				    (mbs.param[2] >> 4) & 0x1;
7543 				sdp1->isp_data_line_active_neg =
7544 				    (mbs.param[2] >> 5) & 0x1;
7545 			}
7546 		}
7547 	}
7548 
7549 }
7550 
7551 static void
7552 isp_setdfltfcparm(ispsoftc_t *isp, int chan)
7553 {
7554 	fcparam *fcp = FCPARAM(isp, chan);
7555 
7556 	/*
7557 	 * Establish some default parameters.
7558 	 */
7559 	fcp->role = GET_DEFAULT_ROLE(isp, chan);
7560 	fcp->isp_maxalloc = ICB_DFLT_ALLOC;
7561 	fcp->isp_retry_delay = ICB_DFLT_RDELAY;
7562 	fcp->isp_retry_count = ICB_DFLT_RCOUNT;
7563 	fcp->isp_loopid = DEFAULT_LOOPID(isp, chan);
7564 	fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan);
7565 	fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan);
7566 	fcp->isp_fwoptions = 0;
7567 	fcp->isp_lasthdl = NIL_HANDLE;
7568 
7569 	if (IS_24XX(isp)) {
7570 		fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS;
7571 		fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS;
7572 		if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
7573 			fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX;
7574 		}
7575 		fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS;
7576 	} else {
7577 		fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
7578 		fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
7579 		fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
7580 		if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
7581 			fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
7582 		}
7583 		/*
7584 		 * Make sure this is turned off now until we get
7585 		 * extended options from NVRAM
7586 		 */
7587 		fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
7588 	}
7589 
7590 
7591 	/*
7592 	 * Now try and read NVRAM unless told to not do so.
7593 	 * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
7594 	 */
7595 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7596 		int i, j = 0;
7597 		/*
7598 		 * Give a couple of tries at reading NVRAM.
7599 		 */
7600 		for (i = 0; i < 2; i++) {
7601 			j = isp_read_nvram(isp, chan);
7602 			if (j == 0) {
7603 				break;
7604 			}
7605 		}
7606 		if (j) {
7607 			isp->isp_confopts |= ISP_CFG_NONVRAM;
7608 		}
7609 	}
7610 
7611 	fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan);
7612 	fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan);
7613 	isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s",
7614 	    chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn),
7615 	    (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn),
7616 	    isp_class3_roles[fcp->role]);
7617 }
7618 
7619 /*
7620  * Re-initialize the ISP and complete all orphaned commands
7621  * with a 'botched' notice. The reset/init routines should
7622  * not disturb an already active list of commands.
7623  */
7624 
7625 void
7626 isp_reinit(ispsoftc_t *isp, int do_load_defaults)
7627 {
7628 	int i;
7629 
7630 	isp_reset(isp, do_load_defaults);
7631 
7632 	if (isp->isp_state != ISP_RESETSTATE) {
7633 		isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
7634 		ISP_DISABLE_INTS(isp);
7635 		goto cleanup;
7636 	}
7637 
7638 	isp_init(isp);
7639 
7640 	if (isp->isp_state == ISP_INITSTATE) {
7641 		isp->isp_state = ISP_RUNSTATE;
7642 	}
7643 
7644 	if (isp->isp_state != ISP_RUNSTATE) {
7645 #ifndef	ISP_TARGET_MODE
7646 		isp_prt(isp, ISP_LOGWARN, "%s: not at runstate", __func__);
7647 #endif
7648 		ISP_DISABLE_INTS(isp);
7649 		if (IS_FC(isp)) {
7650 			/*
7651 			 * If we're in ISP_ROLE_NONE, turn off the lasers.
7652 			 */
7653 			if (!IS_24XX(isp)) {
7654 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
7655 				ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
7656 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
7657 				ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
7658 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
7659 			}
7660 		}
7661  	}
7662 
7663  cleanup:
7664 
7665 	isp->isp_nactive = 0;
7666 
7667 	isp_clear_commands(isp);
7668 	if (IS_FC(isp)) {
7669 		for (i = 0; i < isp->isp_nchan; i++) {
7670 			ISP_MARK_PORTDB(isp, i, -1);
7671 		}
7672 	}
7673 }
7674 
7675 /*
7676  * NVRAM Routines
7677  */
7678 static int
7679 isp_read_nvram(ispsoftc_t *isp, int bus)
7680 {
7681 	int i, amt, retval;
7682 	uint8_t csum, minversion;
7683 	union {
7684 		uint8_t _x[ISP2400_NVRAM_SIZE];
7685 		uint16_t _s[ISP2400_NVRAM_SIZE>>1];
7686 	} _n;
7687 #define	nvram_data	_n._x
7688 #define	nvram_words	_n._s
7689 
7690 	if (IS_24XX(isp)) {
7691 		return (isp_read_nvram_2400(isp, nvram_data));
7692 	} else if (IS_FC(isp)) {
7693 		amt = ISP2100_NVRAM_SIZE;
7694 		minversion = 1;
7695 	} else if (IS_ULTRA2(isp)) {
7696 		amt = ISP1080_NVRAM_SIZE;
7697 		minversion = 0;
7698 	} else {
7699 		amt = ISP_NVRAM_SIZE;
7700 		minversion = 2;
7701 	}
7702 
7703 	for (i = 0; i < amt>>1; i++) {
7704 		isp_rdnvram_word(isp, i, &nvram_words[i]);
7705 	}
7706 
7707 	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7708 	    nvram_data[2] != 'P') {
7709 		if (isp->isp_bustype != ISP_BT_SBUS) {
7710 			isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
7711 			isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x", nvram_data[0], nvram_data[1], nvram_data[2]);
7712 		}
7713 		retval = -1;
7714 		goto out;
7715 	}
7716 
7717 	for (csum = 0, i = 0; i < amt; i++) {
7718 		csum += nvram_data[i];
7719 	}
7720 	if (csum != 0) {
7721 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7722 		retval = -1;
7723 		goto out;
7724 	}
7725 
7726 	if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
7727 		isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
7728 		    ISP_NVRAM_VERSION(nvram_data));
7729 		retval = -1;
7730 		goto out;
7731 	}
7732 
7733 	if (IS_ULTRA3(isp)) {
7734 		isp_parse_nvram_12160(isp, bus, nvram_data);
7735 	} else if (IS_1080(isp)) {
7736 		isp_parse_nvram_1080(isp, bus, nvram_data);
7737 	} else if (IS_1280(isp) || IS_1240(isp)) {
7738 		isp_parse_nvram_1080(isp, bus, nvram_data);
7739 	} else if (IS_SCSI(isp)) {
7740 		isp_parse_nvram_1020(isp, nvram_data);
7741 	} else {
7742 		isp_parse_nvram_2100(isp, nvram_data);
7743 	}
7744 	retval = 0;
7745 out:
7746 	return (retval);
7747 #undef	nvram_data
7748 #undef	nvram_words
7749 }
7750 
7751 static int
7752 isp_read_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
7753 {
7754 	int retval = 0;
7755 	uint32_t addr, csum, lwrds, *dptr;
7756 
7757 	if (isp->isp_port) {
7758 		addr = ISP2400_NVRAM_PORT1_ADDR;
7759 	} else {
7760 		addr = ISP2400_NVRAM_PORT0_ADDR;
7761 	}
7762 
7763 	dptr = (uint32_t *) nvram_data;
7764 	for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7765 		isp_rd_2400_nvram(isp, addr++, dptr++);
7766 	}
7767 	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7768 	    nvram_data[2] != 'P') {
7769 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
7770 		    nvram_data[0], nvram_data[1], nvram_data[2]);
7771 		retval = -1;
7772 		goto out;
7773 	}
7774 	dptr = (uint32_t *) nvram_data;
7775 	for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7776 		uint32_t tmp;
7777 		ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
7778 		csum += tmp;
7779 	}
7780 	if (csum != 0) {
7781 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7782 		retval = -1;
7783 		goto out;
7784 	}
7785 	isp_parse_nvram_2400(isp, nvram_data);
7786 out:
7787 	return (retval);
7788 }
7789 
7790 static void
7791 isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
7792 {
7793 	int i, cbits;
7794 	uint16_t bit, rqst, junk;
7795 
7796 	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7797 	ISP_DELAY(10);
7798 	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7799 	ISP_DELAY(10);
7800 
7801 	if (IS_FC(isp)) {
7802 		wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
7803 		if (IS_2312(isp) && isp->isp_port) {
7804 			wo += 128;
7805 		}
7806 		rqst = (ISP_NVRAM_READ << 8) | wo;
7807 		cbits = 10;
7808 	} else if (IS_ULTRA2(isp)) {
7809 		wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
7810 		rqst = (ISP_NVRAM_READ << 8) | wo;
7811 		cbits = 10;
7812 	} else {
7813 		wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
7814 		rqst = (ISP_NVRAM_READ << 6) | wo;
7815 		cbits = 8;
7816 	}
7817 
7818 	/*
7819 	 * Clock the word select request out...
7820 	 */
7821 	for (i = cbits; i >= 0; i--) {
7822 		if ((rqst >> i) & 1) {
7823 			bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
7824 		} else {
7825 			bit = BIU_NVRAM_SELECT;
7826 		}
7827 		ISP_WRITE(isp, BIU_NVRAM, bit);
7828 		ISP_DELAY(10);
7829 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7830 		ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
7831 		ISP_DELAY(10);
7832 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7833 		ISP_WRITE(isp, BIU_NVRAM, bit);
7834 		ISP_DELAY(10);
7835 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7836 	}
7837 	/*
7838 	 * Now read the result back in (bits come back in MSB format).
7839 	 */
7840 	*rp = 0;
7841 	for (i = 0; i < 16; i++) {
7842 		uint16_t rv;
7843 		*rp <<= 1;
7844 		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7845 		ISP_DELAY(10);
7846 		rv = ISP_READ(isp, BIU_NVRAM);
7847 		if (rv & BIU_NVRAM_DATAIN) {
7848 			*rp |= 1;
7849 		}
7850 		ISP_DELAY(10);
7851 		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7852 		ISP_DELAY(10);
7853 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7854 	}
7855 	ISP_WRITE(isp, BIU_NVRAM, 0);
7856 	ISP_DELAY(10);
7857 	junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7858 	ISP_SWIZZLE_NVRAM_WORD(isp, rp);
7859 }
7860 
7861 static void
7862 isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
7863 {
7864 	int loops = 0;
7865 	uint32_t base = 0x7ffe0000;
7866 	uint32_t tmp = 0;
7867 
7868 	if (IS_25XX(isp)) {
7869 		base = 0x7ff00000 | 0x48000;
7870 	}
7871 	ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
7872 	for (loops = 0; loops < 5000; loops++) {
7873 		ISP_DELAY(10);
7874 		tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
7875 		if ((tmp & (1U << 31)) != 0) {
7876 			break;
7877 		}
7878 	}
7879 	if (tmp & (1U << 31)) {
7880 		*rp = ISP_READ(isp, BIU2400_FLASH_DATA);
7881 		ISP_SWIZZLE_NVRAM_LONG(isp, rp);
7882 	} else {
7883 		*rp = 0xffffffff;
7884 	}
7885 }
7886 
7887 static void
7888 isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data)
7889 {
7890 	sdparam *sdp = SDPARAM(isp, 0);
7891 	int tgt;
7892 
7893 	sdp->isp_fifo_threshold =
7894 		ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
7895 		(ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
7896 
7897 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
7898 		sdp->isp_initiator_id =
7899 			ISP_NVRAM_INITIATOR_ID(nvram_data);
7900 
7901 	sdp->isp_bus_reset_delay =
7902 		ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
7903 
7904 	sdp->isp_retry_count =
7905 		ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
7906 
7907 	sdp->isp_retry_delay =
7908 		ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
7909 
7910 	sdp->isp_async_data_setup =
7911 		ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
7912 
7913 	if (isp->isp_type >= ISP_HA_SCSI_1040) {
7914 		if (sdp->isp_async_data_setup < 9) {
7915 			sdp->isp_async_data_setup = 9;
7916 		}
7917 	} else {
7918 		if (sdp->isp_async_data_setup != 6) {
7919 			sdp->isp_async_data_setup = 6;
7920 		}
7921 	}
7922 
7923 	sdp->isp_req_ack_active_neg =
7924 		ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
7925 
7926 	sdp->isp_data_line_active_neg =
7927 		ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
7928 
7929 	sdp->isp_data_dma_burst_enabl =
7930 		ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
7931 
7932 	sdp->isp_cmd_dma_burst_enable =
7933 		ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
7934 
7935 	sdp->isp_tag_aging =
7936 		ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
7937 
7938 	sdp->isp_selection_timeout =
7939 		ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
7940 
7941 	sdp->isp_max_queue_depth =
7942 		ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
7943 
7944 	sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
7945 
7946 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7947 		sdp->isp_devparam[tgt].dev_enable =
7948 			ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
7949 		sdp->isp_devparam[tgt].exc_throttle =
7950 			ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
7951 		sdp->isp_devparam[tgt].nvrm_offset =
7952 			ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
7953 		sdp->isp_devparam[tgt].nvrm_period =
7954 			ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
7955 		/*
7956 		 * We probably shouldn't lie about this, but it
7957 		 * it makes it much safer if we limit NVRAM values
7958 		 * to sanity.
7959 		 */
7960 		if (isp->isp_type < ISP_HA_SCSI_1040) {
7961 			/*
7962 			 * If we're not ultra, we can't possibly
7963 			 * be a shorter period than this.
7964 			 */
7965 			if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
7966 				sdp->isp_devparam[tgt].nvrm_period = 0x19;
7967 			}
7968 			if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
7969 				sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
7970 			}
7971 		} else {
7972 			if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
7973 				sdp->isp_devparam[tgt].nvrm_offset = 0x8;
7974 			}
7975 		}
7976 		sdp->isp_devparam[tgt].nvrm_flags = 0;
7977 		if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
7978 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
7979 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
7980 		if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
7981 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
7982 		if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
7983 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
7984 		if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
7985 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
7986 		if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
7987 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
7988 		if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
7989 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
7990 		sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
7991 		sdp->isp_devparam[tgt].goal_offset =
7992 		    sdp->isp_devparam[tgt].nvrm_offset;
7993 		sdp->isp_devparam[tgt].goal_period =
7994 		    sdp->isp_devparam[tgt].nvrm_period;
7995 		sdp->isp_devparam[tgt].goal_flags =
7996 		    sdp->isp_devparam[tgt].nvrm_flags;
7997 	}
7998 }
7999 
8000 static void
8001 isp_parse_nvram_1080(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
8002 {
8003 	sdparam *sdp = SDPARAM(isp, bus);
8004 	int tgt;
8005 
8006 	sdp->isp_fifo_threshold =
8007 	    ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
8008 
8009 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
8010 		sdp->isp_initiator_id =
8011 		    ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
8012 
8013 	sdp->isp_bus_reset_delay =
8014 	    ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
8015 
8016 	sdp->isp_retry_count =
8017 	    ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
8018 
8019 	sdp->isp_retry_delay =
8020 	    ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
8021 
8022 	sdp->isp_async_data_setup =
8023 	    ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
8024 
8025 	sdp->isp_req_ack_active_neg =
8026 	    ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
8027 
8028 	sdp->isp_data_line_active_neg =
8029 	    ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
8030 
8031 	sdp->isp_data_dma_burst_enabl =
8032 	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
8033 
8034 	sdp->isp_cmd_dma_burst_enable =
8035 	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
8036 
8037 	sdp->isp_selection_timeout =
8038 	    ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
8039 
8040 	sdp->isp_max_queue_depth =
8041 	     ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
8042 
8043 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
8044 		sdp->isp_devparam[tgt].dev_enable =
8045 		    ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
8046 		sdp->isp_devparam[tgt].exc_throttle =
8047 			ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
8048 		sdp->isp_devparam[tgt].nvrm_offset =
8049 			ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
8050 		sdp->isp_devparam[tgt].nvrm_period =
8051 			ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
8052 		sdp->isp_devparam[tgt].nvrm_flags = 0;
8053 		if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
8054 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8055 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8056 		if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
8057 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8058 		if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
8059 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8060 		if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
8061 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8062 		if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
8063 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8064 		if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
8065 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8066 		sdp->isp_devparam[tgt].actv_flags = 0;
8067 		sdp->isp_devparam[tgt].goal_offset =
8068 		    sdp->isp_devparam[tgt].nvrm_offset;
8069 		sdp->isp_devparam[tgt].goal_period =
8070 		    sdp->isp_devparam[tgt].nvrm_period;
8071 		sdp->isp_devparam[tgt].goal_flags =
8072 		    sdp->isp_devparam[tgt].nvrm_flags;
8073 	}
8074 }
8075 
8076 static void
8077 isp_parse_nvram_12160(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
8078 {
8079 	sdparam *sdp = SDPARAM(isp, bus);
8080 	int tgt;
8081 
8082 	sdp->isp_fifo_threshold =
8083 	    ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
8084 
8085 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
8086 		sdp->isp_initiator_id =
8087 		    ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
8088 
8089 	sdp->isp_bus_reset_delay =
8090 	    ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
8091 
8092 	sdp->isp_retry_count =
8093 	    ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
8094 
8095 	sdp->isp_retry_delay =
8096 	    ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
8097 
8098 	sdp->isp_async_data_setup =
8099 	    ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
8100 
8101 	sdp->isp_req_ack_active_neg =
8102 	    ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
8103 
8104 	sdp->isp_data_line_active_neg =
8105 	    ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
8106 
8107 	sdp->isp_data_dma_burst_enabl =
8108 	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
8109 
8110 	sdp->isp_cmd_dma_burst_enable =
8111 	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
8112 
8113 	sdp->isp_selection_timeout =
8114 	    ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
8115 
8116 	sdp->isp_max_queue_depth =
8117 	     ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
8118 
8119 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
8120 		sdp->isp_devparam[tgt].dev_enable =
8121 		    ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
8122 		sdp->isp_devparam[tgt].exc_throttle =
8123 			ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
8124 		sdp->isp_devparam[tgt].nvrm_offset =
8125 			ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
8126 		sdp->isp_devparam[tgt].nvrm_period =
8127 			ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
8128 		sdp->isp_devparam[tgt].nvrm_flags = 0;
8129 		if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
8130 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8131 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8132 		if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
8133 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8134 		if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
8135 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8136 		if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
8137 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8138 		if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
8139 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8140 		if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
8141 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8142 		sdp->isp_devparam[tgt].actv_flags = 0;
8143 		sdp->isp_devparam[tgt].goal_offset =
8144 		    sdp->isp_devparam[tgt].nvrm_offset;
8145 		sdp->isp_devparam[tgt].goal_period =
8146 		    sdp->isp_devparam[tgt].nvrm_period;
8147 		sdp->isp_devparam[tgt].goal_flags =
8148 		    sdp->isp_devparam[tgt].nvrm_flags;
8149 	}
8150 }
8151 
8152 static void
8153 isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
8154 {
8155 	fcparam *fcp = FCPARAM(isp, 0);
8156 	uint64_t wwn;
8157 
8158 	/*
8159 	 * There is NVRAM storage for both Port and Node entities-
8160 	 * but the Node entity appears to be unused on all the cards
8161 	 * I can find. However, we should account for this being set
8162 	 * at some point in the future.
8163 	 *
8164 	 * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
8165 	 * bits 48..60. In the case of the 2202, it appears that they do
8166 	 * use bit 48 to distinguish between the two instances on the card.
8167 	 * The 2204, which I've never seen, *probably* extends this method.
8168 	 */
8169 	wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
8170 	if (wwn) {
8171 		isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
8172 		    (uint32_t) (wwn >> 32), (uint32_t) (wwn));
8173 		if ((wwn >> 60) == 0) {
8174 			wwn |= (((uint64_t) 2)<< 60);
8175 		}
8176 	}
8177 	fcp->isp_wwpn_nvram = wwn;
8178 	if (IS_2200(isp) || IS_23XX(isp)) {
8179 		wwn = ISP2100_NVRAM_NODE_NAME(nvram_data);
8180 		if (wwn) {
8181 			isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
8182 			    (uint32_t) (wwn >> 32),
8183 			    (uint32_t) (wwn));
8184 			if ((wwn >> 60) == 0) {
8185 				wwn |= (((uint64_t) 2)<< 60);
8186 			}
8187 		} else {
8188 			wwn = fcp->isp_wwpn_nvram & ~((uint64_t) 0xfff << 48);
8189 		}
8190 	} else {
8191 		wwn &= ~((uint64_t) 0xfff << 48);
8192 	}
8193 	fcp->isp_wwnn_nvram = wwn;
8194 
8195 	fcp->isp_maxalloc = ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
8196 	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
8197 		DEFAULT_FRAMESIZE(isp) =
8198 		    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
8199 	}
8200 	fcp->isp_retry_delay = ISP2100_NVRAM_RETRY_DELAY(nvram_data);
8201 	fcp->isp_retry_count = ISP2100_NVRAM_RETRY_COUNT(nvram_data);
8202 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
8203 		fcp->isp_loopid = ISP2100_NVRAM_HARDLOOPID(nvram_data);
8204 	}
8205 	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
8206 		DEFAULT_EXEC_THROTTLE(isp) =
8207 			ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
8208 	}
8209 	fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
8210 	isp_prt(isp, ISP_LOGDEBUG0,
8211 	    "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d",
8212 	    (uint32_t) (fcp->isp_wwnn_nvram >> 32),
8213 	    (uint32_t) fcp->isp_wwnn_nvram,
8214 	    (uint32_t) (fcp->isp_wwpn_nvram >> 32),
8215 	    (uint32_t) fcp->isp_wwpn_nvram,
8216 	    ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data),
8217 	    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data));
8218 	isp_prt(isp, ISP_LOGDEBUG0,
8219 	    "execthrottle %d fwoptions 0x%x hardloop %d tov %d",
8220 	    ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
8221 	    ISP2100_NVRAM_OPTIONS(nvram_data),
8222 	    ISP2100_NVRAM_HARDLOOPID(nvram_data),
8223 	    ISP2100_NVRAM_TOV(nvram_data));
8224 	fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data);
8225 	fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data);
8226 	isp_prt(isp, ISP_LOGDEBUG0, "xfwoptions 0x%x zfw options 0x%x",
8227 	    ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data));
8228 }
8229 
8230 static void
8231 isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
8232 {
8233 	fcparam *fcp = FCPARAM(isp, 0);
8234 	uint64_t wwn;
8235 
8236 	isp_prt(isp, ISP_LOGDEBUG0,
8237 	    "NVRAM 0x%08x%08x 0x%08x%08x exchg_cnt %d maxframelen %d",
8238 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
8239 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
8240 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
8241 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
8242 	    ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data),
8243 	    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
8244 	isp_prt(isp, ISP_LOGDEBUG0,
8245 	    "NVRAM execthr %d loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
8246 	    ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data),
8247 	    ISP2400_NVRAM_HARDLOOPID(nvram_data),
8248 	    ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
8249 	    ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
8250 	    ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
8251 
8252 	wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
8253 	fcp->isp_wwpn_nvram = wwn;
8254 
8255 	wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
8256 	if (wwn) {
8257 		if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
8258 			wwn = 0;
8259 		}
8260 	}
8261 	if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) {
8262 		wwn = fcp->isp_wwpn_nvram;
8263 		wwn &= ~((uint64_t) 0xfff << 48);
8264 	}
8265 	fcp->isp_wwnn_nvram = wwn;
8266 
8267 	if (ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data)) {
8268 		fcp->isp_maxalloc = ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data);
8269 	}
8270 	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
8271 		DEFAULT_FRAMESIZE(isp) =
8272 		    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
8273 	}
8274 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
8275 		fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
8276 	}
8277 	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
8278 		DEFAULT_EXEC_THROTTLE(isp) =
8279 			ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data);
8280 	}
8281 	fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
8282 	fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
8283 	fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
8284 }
8285