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