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