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