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