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