summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2009-06-24 11:00:54 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2009-06-24 11:00:54 +0000
commit2e55d12d2d0d0545e0de51990092ce1d4ac716ee (patch)
treeb8711a0f5b0877f19619922d8b5b7a83c1e7f4ab /sys/dev
parentf0c12908cc29344c55624d46d4cfc2c342235446 (diff)
Major update to isp driver, mostly from mjacob via FreeBSD.
Everything that worked before should still work so in it goes. Newer boards (2300, 2400) may now work but are still a work in progress. Thanks to many testers but especially kettenis@ for finding a show stopper bug and stomping it. ok deraadt@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/isp.c5707
-rw-r--r--sys/dev/ic/isp_library.c2681
-rw-r--r--sys/dev/ic/isp_library.h215
-rw-r--r--sys/dev/ic/isp_openbsd.c496
-rw-r--r--sys/dev/ic/isp_openbsd.h223
-rw-r--r--sys/dev/ic/isp_stds.h12
-rw-r--r--sys/dev/ic/isp_target.c1036
-rw-r--r--sys/dev/ic/isp_target.h146
-rw-r--r--sys/dev/ic/isp_tpublic.h124
-rw-r--r--sys/dev/ic/ispmbox.h67
-rw-r--r--sys/dev/ic/ispreg.h52
-rw-r--r--sys/dev/ic/ispvar.h326
-rw-r--r--sys/dev/pci/isp_pci.c767
-rw-r--r--sys/dev/sbus/isp_sbus.c105
14 files changed, 7988 insertions, 3969 deletions
diff --git a/sys/dev/ic/isp.c b/sys/dev/ic/isp.c
index 8ccfe47c05f..2d0f10fdd18 100644
--- a/sys/dev/ic/isp.c
+++ b/sys/dev/ic/isp.c
@@ -1,33 +1,35 @@
-/* $OpenBSD: isp.c,v 1.45 2009/06/03 05:11:09 krw Exp $ */
+/* $OpenBSD: isp.c,v 1.46 2009/06/24 11:00:53 krw Exp $ */
/* $FreeBSD: src/sys/dev/isp/isp.c,v 1.150 2008/12/15 21:42:38 marius Exp $*/
+/*-
+ * Copyright (c) 1997-2007 by Matthew Jacob
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
/*
* Machine and OS Independent (well, as best as possible)
- * code for the QLogic ISP SCSI adapters.
- *
- * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob
- * Feral Software
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * code for the Qlogic ISP SCSI and FC-SCSI adapters.
*/
/*
@@ -39,11 +41,14 @@
/*
* Include header file appropriate for platform we're building on.
*/
-
#ifdef __NetBSD__
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
#include <dev/ic/isp_netbsd.h>
#endif
#ifdef __FreeBSD__
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/isp/isp.c,v 1.149 2007/07/10 07:55:04 mjacob Exp $");
#include <dev/isp/isp_freebsd.h>
#endif
#ifdef __OpenBSD__
@@ -61,30 +66,16 @@
*/
#define MBOX_DELAY_COUNT 1000000 / 100
+#define ISP_MARK_PORTDB(a, b) \
+ isp_prt(isp, ISP_LOGSANCFG, "line %d: markportdb", __LINE__); \
+ isp_mark_portdb(a, b)
/*
* Local static data
*/
-static const char portshift[] =
- "Target %d Loop ID 0x%x (Port 0x%x) => Loop 0x%x (Port 0x%x)";
-static const char portdup[] =
- "Target %d duplicates Target %d- killing off both";
-static const char retained[] =
- "Retaining Loop ID 0x%x for Target %d (Port 0x%x)";
-static const char lretained[] =
- "Retained login of Target %d (Loop ID 0x%x) Port 0x%x";
-static const char plogout[] =
- "Logging out Target %d at Loop ID 0x%x (Port 0x%x)";
-static const char plogierr[] =
- "Command Error in PLOGI for Port 0x%x (0x%x)";
-static const char nopdb[] =
- "Could not get PDB for Device @ Port 0x%x";
-static const char pdbmfail1[] =
- "PDB Loop ID info for Device @ Port 0x%x does not match up (0x%x)";
-static const char pdbmfail2[] =
- "PDB Port info for Device @ Port 0x%x does not match up (0x%x)";
-static const char ldumped[] =
- "Target %d (Loop ID 0x%x) Port 0x%x dumped after login info mismatch";
+static const char fconf[] =
+ "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)";
static const char notresp[] =
"Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
static const char xact1[] =
@@ -96,11 +87,11 @@ static const char xact3[] =
static const char pskip[] =
"SCSI phase skipped for target %d.%d.%d";
static const char topology[] =
- "Loop ID %d, AL_PA 0x%x, Port ID 0x%x, Loop State 0x%x, Topology '%s'";
-static const char swrej[] =
- "Fabric Nameserver rejected %s (Reason=0x%x Expl=0x%x) for Port ID 0x%x";
+ "HBA PortID 0x%06x N-Port Handle %d, Connection Topology '%s'";
+static const char ourwwn[] =
+ "HBA WWNN 0x%08x%08x HBA WWPN 0x%08x%08x";
static const char finmsg[] =
- "(%d.%d.%d): FIN dl%d resid %lu STS 0x%x SKEY %c XS_ERR=0x%x";
+ "%d.%d.%d: FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x";
static const char sc0[] =
"%s CHAN %d FTHRSH %d IID %d RESETD %d RETRYC %d RETRYD %d ASD 0x%x";
static const char sc1[] =
@@ -114,40 +105,54 @@ static const char bun[] =
/*
* Local function prototypes.
*/
-static int isp_parse_async(struct ispsoftc *, u_int16_t);
-static int isp_handle_other_response(struct ispsoftc *, int, isphdr_t *,
- u_int16_t *);
-static void
-isp_parse_status(struct ispsoftc *, ispstatusreq_t *, XS_T *);
-static void isp_fastpost_complete(struct ispsoftc *, u_int16_t);
-static int isp_mbox_continue(struct ispsoftc *);
-static void isp_scsi_init(struct ispsoftc *);
-static void isp_scsi_channel_init(struct ispsoftc *, int);
-static void isp_fibre_init(struct ispsoftc *);
-static void isp_mark_getpdb_all(struct ispsoftc *);
-static int isp_getmap(struct ispsoftc *, fcpos_map_t *);
-static int isp_getpdb(struct ispsoftc *, int, isp_pdb_t *);
-static u_int64_t isp_get_portname(struct ispsoftc *, int, int);
-static int isp_fclink_test(struct ispsoftc *, int);
-static char *isp2100_fw_statename(int);
-static int isp_pdb_sync(struct ispsoftc *);
-static int isp_scan_loop(struct ispsoftc *);
-static int isp_fabric_mbox_cmd(struct ispsoftc *, mbreg_t *);
-static int isp_scan_fabric(struct ispsoftc *, int);
-static void isp_register_fc4_type(struct ispsoftc *);
-static void isp_fw_state(struct ispsoftc *);
-static void isp_mboxcmd_qnw(struct ispsoftc *, mbreg_t *, int);
-static void isp_mboxcmd(struct ispsoftc *, mbreg_t *, int);
-
-static void isp_update(struct ispsoftc *);
-static void isp_update_bus(struct ispsoftc *, int);
-static void isp_setdfltparm(struct ispsoftc *, int);
-static int isp_read_nvram(struct ispsoftc *);
-static void isp_rdnvram_word(struct ispsoftc *, int, u_int16_t *);
-static void isp_parse_nvram_1020(struct ispsoftc *, u_int8_t *);
-static void isp_parse_nvram_1080(struct ispsoftc *, int, u_int8_t *);
-static void isp_parse_nvram_12160(struct ispsoftc *, int, u_int8_t *);
-static void isp_parse_nvram_2100(struct ispsoftc *, u_int8_t *);
+int isp_parse_async(struct ispsoftc *, u_int16_t);
+int isp_handle_other_response(struct ispsoftc *, int, isphdr_t *,
+ u_int32_t *);
+void
+isp_parse_status(struct ispsoftc *, ispstatusreq_t *, XS_T *, long *);
+void
+isp_parse_status_24xx(struct ispsoftc *, isp24xx_statusreq_t *, XS_T *, long *);
+void isp_fastpost_complete(struct ispsoftc *, u_int16_t);
+int isp_mbox_continue(struct ispsoftc *);
+void isp_scsi_init(struct ispsoftc *);
+void isp_scsi_channel_init(struct ispsoftc *, int);
+void isp_fibre_init(struct ispsoftc *);
+void isp_fibre_init_2400(struct ispsoftc *);
+void isp_mark_portdb(struct ispsoftc *, int);
+int isp_plogx(struct ispsoftc *, u_int16_t, u_int32_t, int, int);
+int isp_port_login(struct ispsoftc *, u_int16_t, u_int32_t);
+int isp_port_logout(struct ispsoftc *, u_int16_t, u_int32_t);
+int isp_getpdb(struct ispsoftc *, u_int16_t, isp_pdb_t *, int);
+u_int64_t isp_get_portname(struct ispsoftc *, int, int);
+int isp_fclink_test(struct ispsoftc *, int);
+const char *ispfc_fw_statename(int);
+int isp_pdb_sync(struct ispsoftc *);
+int isp_scan_loop(struct ispsoftc *);
+int isp_gid_ft_sns(struct ispsoftc *);
+int isp_gid_ft_ct_passthru(struct ispsoftc *);
+int isp_scan_fabric(struct ispsoftc *);
+int isp_login_device(struct ispsoftc *, u_int32_t, isp_pdb_t *, u_int16_t *);
+int isp_register_fc4_type(struct ispsoftc *);
+int isp_register_fc4_type_24xx(struct ispsoftc *);
+u_int16_t isp_nxt_handle(struct ispsoftc *, u_int16_t);
+void isp_fw_state(struct ispsoftc *);
+void isp_mboxcmd_qnw(struct ispsoftc *, mbreg_t *, int);
+void isp_mboxcmd(struct ispsoftc *, mbreg_t *);
+
+void isp_update(struct ispsoftc *);
+void isp_update_bus(struct ispsoftc *, int);
+void isp_setdfltparm(struct ispsoftc *, int);
+void isp_setdfltfcparm(struct ispsoftc *);
+int isp_read_nvram(struct ispsoftc *);
+int isp_read_nvram_2400(struct ispsoftc *);
+void isp_rdnvram_word(struct ispsoftc *, int, u_int16_t *);
+void isp_rd_2400_nvram(struct ispsoftc *, u_int32_t, u_int32_t *);
+void isp_parse_nvram_1020(struct ispsoftc *, u_int8_t *);
+void isp_parse_nvram_1080(struct ispsoftc *, int, u_int8_t *);
+void isp_parse_nvram_12160(struct ispsoftc *, int, u_int8_t *);
+void isp_fix_nvram_wwns(struct ispsoftc *);
+void isp_parse_nvram_2100(struct ispsoftc *, u_int8_t *);
+void isp_parse_nvram_2400(struct ispsoftc *, u_int8_t *);
/*
* Reset Hardware.
@@ -161,9 +166,10 @@ void
isp_reset(struct ispsoftc *isp)
{
mbreg_t mbs;
- u_int16_t code_org;
+ u_int32_t code_org, val;
int loops, i, dodnld = 1;
- char *btype = "????";
+ static const char *btype = "????";
+ static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
isp->isp_state = ISP_NILSTATE;
@@ -203,10 +209,16 @@ isp_reset(struct ispsoftc *isp)
/*
* Just in case it was paused...
*/
- ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
+ if (IS_24XX(isp)) {
+ ISP_WRITE(isp, BIU2400_HCCR,
+ HCCR_2400_CMD_RELEASE);
+ } else {
+ ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
+ }
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_ABOUT_FIRMWARE;
- isp_mboxcmd(isp, &mbs, MBLOGNONE);
+ mbs.logval = MBLOGNONE;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
isp->isp_romfw_rev[0] = mbs.param[1];
isp->isp_romfw_rev[1] = mbs.param[2];
@@ -216,13 +228,47 @@ isp_reset(struct ispsoftc *isp)
isp->isp_touched = 1;
}
- DISABLE_INTS(isp);
+ ISP_DISABLE_INTS(isp);
+
+ /*
+ * Pick an initial maxcmds value which will be used
+ * to allocate xflist pointer space. It may be changed
+ * later by the firmware.
+ */
+ if (IS_24XX(isp)) {
+ isp->isp_maxcmds = 4096;
+ } else if (IS_2322(isp)) {
+ isp->isp_maxcmds = 2048;
+ } else if (IS_23XX(isp) || IS_2200(isp)) {
+ isp->isp_maxcmds = 1024;
+ } else {
+ isp->isp_maxcmds = 512;
+ }
+
+ /*
+ * Set up DMA for the request and result queues.
+ *
+ * We do this now so we can use the request queue
+ * for a dma
+ */
+ if (ISP_MBOXDMASETUP(isp) != 0) {
+ isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
+ return;
+ }
+
/*
* Set up default request/response queue in-pointer/out-pointer
* register indices.
*/
- if (IS_23XX(isp)) {
+ if (IS_24XX(isp)) {
+ isp->isp_rqstinrp = BIU2400_REQINP;
+ isp->isp_rqstoutrp = BIU2400_REQOUTP;
+ isp->isp_respinrp = BIU2400_RSPINP;
+ isp->isp_respoutrp = BIU2400_RSPOUTP;
+ isp->isp_atioinrp = BIU2400_ATIO_RSPINP;
+ isp->isp_atiooutrp = BIU2400_ATIO_REQINP;
+ } else if (IS_23XX(isp)) {
isp->isp_rqstinrp = BIU_REQINP;
isp->isp_rqstoutrp = BIU_REQOUTP;
isp->isp_respinrp = BIU_RSPINP;
@@ -238,7 +284,13 @@ isp_reset(struct ispsoftc *isp)
* Put the board into PAUSE mode (so we can read the SXP registers
* or write FPM/FBM registers).
*/
- ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
+ if (IS_24XX(isp)) {
+ ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT);
+ ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
+ ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
+ } else {
+ ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
+ }
if (IS_FC(isp)) {
switch (isp->isp_type) {
@@ -254,17 +306,27 @@ isp_reset(struct ispsoftc *isp)
case ISP_HA_FC_2312:
btype = "2312";
break;
+ case ISP_HA_FC_2322:
+ btype = "2322";
+ break;
+ case ISP_HA_FC_2400:
+ btype = "2422";
+ break;
default:
break;
}
- /*
- * While we're paused, reset the FPM module and FBM fifos.
- */
- ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
- ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
- ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
- ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
- ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
+
+ if (!IS_24XX(isp)) {
+ /*
+ * While we're paused, reset the FPM module and FBM
+ * fifos.
+ */
+ ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
+ ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
+ ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
+ ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
+ ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
+ }
} else if (IS_1240(isp)) {
sdparam *sdp = isp->isp_param;
btype = "1240";
@@ -447,8 +509,6 @@ isp_reset(struct ispsoftc *isp)
*/
ISP_RESET0(isp);
-again:
-
/*
* Hit the chip over the head with hammer,
* and give the ISP a chance to recover.
@@ -470,6 +530,44 @@ again:
DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
+ } else if (IS_24XX(isp)) {
+ /*
+ * Stop DMA and wait for it to stop.
+ */
+ ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
+ for (val = loops = 0; loops < 30000; loops++) {
+ USEC_DELAY(10);
+ val = ISP_READ(isp, BIU2400_CSR);
+ if ((val & BIU2400_DMA_ACTIVE) == 0) {
+ break;
+ }
+ }
+ if (val & BIU2400_DMA_ACTIVE) {
+ ISP_RESET0(isp);
+ isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
+ return;
+ }
+ /*
+ * Hold it in SOFT_RESET and STOP state for 100us.
+ */
+ ISP_WRITE(isp, BIU2400_CSR,
+ BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
+ USEC_DELAY(100);
+ for (loops = 0; loops < 10000; loops++) {
+ USEC_DELAY(5);
+ val = ISP_READ(isp, OUTMAILBOX0);
+ }
+ for (val = loops = 0; loops < 500000; loops ++) {
+ val = ISP_READ(isp, BIU2400_CSR);
+ if ((val & BIU2400_SOFT_RESET) == 0) {
+ break;
+ }
+ }
+ if (val & BIU2400_SOFT_RESET) {
+ ISP_RESET0(isp);
+ isp_prt(isp, ISP_LOGERR, "Failed to come out of reset");
+ return;
+ }
} else {
ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
/*
@@ -494,8 +592,13 @@ again:
loops = MBOX_DELAY_COUNT;
for (;;) {
if (IS_SCSI(isp)) {
- if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET))
+ if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET)) {
break;
+ }
+ } else if (IS_24XX(isp)) {
+ if (ISP_READ(isp, OUTMAILBOX0) == 0) {
+ break;
+ }
} else {
if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
break;
@@ -503,6 +606,7 @@ again:
USEC_DELAY(100);
if (--loops < 0) {
ISP_DUMPREGS(isp, "chip reset timed out");
+ ISP_RESET0(isp);
return;
}
}
@@ -514,24 +618,41 @@ again:
if (IS_SCSI(isp)) {
ISP_WRITE(isp, BIU_CONF1, 0);
- } else {
+ } else if (!IS_24XX(isp)) {
ISP_WRITE(isp, BIU2100_CSR, 0);
}
/*
* Reset RISC Processor
*/
- ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
- USEC_DELAY(100);
- /* Clear semaphore register (just to be sure) */
- ISP_WRITE(isp, BIU_SEMA, 0);
+ if (IS_24XX(isp)) {
+ ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
+ ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE);
+ ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
+ } else {
+ ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
+ USEC_DELAY(100);
+ ISP_WRITE(isp, BIU_SEMA, 0);
+ }
+
/*
- * Establish some initial burst rate stuff.
- * (only for the 1XX0 boards). This really should
- * be done later after fetching from NVRAM.
+ * Post-RISC Reset stuff.
*/
- if (IS_SCSI(isp)) {
+ if (IS_24XX(isp)) {
+ for (val = loops = 0; loops < 5000000; loops++) {
+ USEC_DELAY(5);
+ val = ISP_READ(isp, OUTMAILBOX0);
+ if (val == 0) {
+ break;
+ }
+ }
+ if (val != 0) {
+ ISP_RESET0(isp);
+ isp_prt(isp, ISP_LOGERR, "reset didn't clear");
+ return;
+ }
+ } else if (IS_SCSI(isp)) {
u_int16_t tmp = isp->isp_mdvec->dv_conf1;
/*
* Busted FIFO. Turn off all but burst enables.
@@ -544,30 +665,36 @@ again:
ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
}
-#ifdef PTI_CARDS
- if (((sdparam *) isp->isp_param)->isp_ultramode) {
- while (ISP_READ(isp, RISC_MTR) != 0x1313) {
- ISP_WRITE(isp, RISC_MTR, 0x1313);
- ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
+ if (SDPARAM(isp)->isp_ptisp) {
+ if (SDPARAM(isp)->isp_ultramode) {
+ while (ISP_READ(isp, RISC_MTR) != 0x1313) {
+ ISP_WRITE(isp, RISC_MTR, 0x1313);
+ ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
+ }
+ } else {
+ ISP_WRITE(isp, RISC_MTR, 0x1212);
}
+ /*
+ * PTI specific register
+ */
+ ISP_WRITE(isp, RISC_EMB, DUAL_BANK);
} else {
ISP_WRITE(isp, RISC_MTR, 0x1212);
}
- /*
- * PTI specific register
- */
- ISP_WRITE(isp, RISC_EMB, DUAL_BANK)
-#else
- ISP_WRITE(isp, RISC_MTR, 0x1212);
-#endif
+ ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
} else {
ISP_WRITE(isp, RISC_MTR2100, 0x1212);
if (IS_2200(isp) || IS_23XX(isp)) {
ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
}
+ ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
}
- ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); /* release paused processor */
+ ISP_WRITE(isp, isp->isp_rqstinrp, 0);
+ ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
+ ISP_WRITE(isp, isp->isp_respinrp, 0);
+ ISP_WRITE(isp, isp->isp_respoutrp, 0);
+
/*
* Do MD specific post initialization
@@ -580,13 +707,14 @@ again:
* Avoid doing this on the 2312 because you can generate a PCI
* parity error (chip breakage).
*/
- if (IS_23XX(isp)) {
- USEC_DELAY(5);
+ if (IS_2312(isp)) {
+ USEC_DELAY(100);
} else {
loops = MBOX_DELAY_COUNT;
while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
USEC_DELAY(100);
if (--loops < 0) {
+ ISP_RESET0(isp);
isp_prt(isp, ISP_LOGERR,
"MBOX_BUSY never cleared on reset");
return;
@@ -605,12 +733,14 @@ again:
*/
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_NO_OP;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ ISP_RESET0(isp);
return;
}
- if (IS_SCSI(isp)) {
+ if (IS_SCSI(isp) || IS_24XX(isp)) {
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_MAILBOX_REG_TEST;
mbs.param[1] = 0xdead;
@@ -618,13 +748,18 @@ again:
mbs.param[3] = 0xffff;
mbs.param[4] = 0x1111;
mbs.param[5] = 0xa5a5;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.param[6] = 0x0000;
+ mbs.param[7] = 0x0000;
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ ISP_RESET0(isp);
return;
}
if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
mbs.param[5] != 0xa5a5) {
+ ISP_RESET0(isp);
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],
@@ -648,26 +783,193 @@ again:
dodnld = 0;
}
- if (IS_23XX(isp))
+ if (IS_24XX(isp)) {
+ code_org = ISP_CODE_ORG_2400;
+ } else if (IS_23XX(isp)) {
code_org = ISP_CODE_ORG_2300;
- else
+ } else {
code_org = ISP_CODE_ORG;
+ }
+
+ if (dodnld && IS_24XX(isp)) {
+ const u_int32_t *ptr = isp->isp_mdvec->dv_ispfw;
+
+ /*
+ * NB: Whatever you do do, do *not* issue the VERIFY FIRMWARE
+ * NB: command to the 2400 while loading new firmware. This
+ * NB: causes the new f/w to start and immediately crash back
+ * NB: to the ROM.
+ */
+
+ /*
+ * Keep loading until we run out of f/w.
+ */
+ code_org = ptr[2]; /* 1st load address is our start addr */
+
+ for (;;) {
+ u_int32_t la, wi, wl;
+
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "load 0x%x words of code at load address 0x%x",
+ ptr[3], ptr[2]);
+
+ wi = 0;
+ la = ptr[2];
+ wl = ptr[3];
+
+ while (wi < ptr[3]) {
+ u_int32_t *cp;
+ u_int32_t nw;
+
+ nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 2;
+ if (nw > wl) {
+ nw = wl;
+ }
+ cp = isp->isp_rquest;
+ for (i = 0; i < nw; i++) {
+ ISP_IOXPUT_32(isp, ptr[wi++], &cp[i]);
+ wl--;
+ }
+ MEMORYBARRIER(isp, SYNC_REQUEST,
+ 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_LOAD_RISC_RAM;
+ mbs.param[1] = la;
+ mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
+ mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
+ mbs.param[4] = nw >> 16;
+ mbs.param[5] = nw;
+ mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
+ mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
+ mbs.param[8] = la >> 16;
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ isp_prt(isp, ISP_LOGERR,
+ "F/W Risc Ram Load Failed");
+ ISP_RESET0(isp);
+ return;
+ }
+ la += nw;
+ }
+
+ if (ptr[1] == 0) {
+ break;
+ }
+ ptr += ptr[3];
+ }
+ isp->isp_loaded_fw = 1;
+ } else if (dodnld && IS_23XX(isp)) {
+ const u_int16_t *ptr = isp->isp_mdvec->dv_ispfw;
+ u_int16_t wi, wl, segno;
+ u_int32_t la;
+
+ la = code_org;
+ segno = 0;
+
+ for (;;) {
+ u_int32_t nxtaddr;
+
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "load 0x%x words of code at load address 0x%x",
+ ptr[3], la);
+
+ wi = 0;
+ wl = ptr[3];
+
+ while (wi < ptr[3]) {
+ u_int16_t *cp;
+ u_int32_t nw;
+
+ nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 1;
+ if (nw > wl) {
+ nw = wl;
+ }
+ if (nw > (1 << 15)) {
+ nw = 1 << 15;
+ }
+ cp = isp->isp_rquest;
+ for (i = 0; i < nw; i++) {
+ ISP_IOXPUT_16(isp, ptr[wi++], &cp[i]);
+ wl--;
+ }
+ MEMORYBARRIER(isp, SYNC_REQUEST,
+ 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_LOAD_RISC_RAM;
+ mbs.param[1] = la;
+ mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
+ mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
+ mbs.param[4] = nw;
+ mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
+ mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
+ mbs.param[8] = la >> 16;
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ isp_prt(isp, ISP_LOGERR,
+ "F/W Risc Ram Load Failed");
+ ISP_RESET0(isp);
+ return;
+ }
+ la += nw;
+ }
+
+ if (!IS_2322(isp)) {
+ /*
+ * Verify that it downloaded correctly.
+ */
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_VERIFY_CHECKSUM;
+ mbs.param[1] = code_org;
+ mbs.logval = MBLOGNONE;
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ isp_prt(isp, ISP_LOGERR, dcrc);
+ ISP_RESET0(isp);
+ return;
+ }
+ break;
+ }
+
+ if (++segno == 3) {
+ break;
+ }
+
+ /*
+ * If we're a 2322, the firmware actually comes in
+ * three chunks. We loaded the first at the code_org
+ * address. The other two chunks, which follow right
+ * after each other in memory here, get loaded at
+ * addresses specfied at offset 0x9..0xB.
+ */
- if (dodnld) {
- isp->isp_mbxworkp = (void *) &isp->isp_mdvec->dv_ispfw[1];
- isp->isp_mbxwrk0 = isp->isp_mdvec->dv_ispfw[3] - 1;
+ nxtaddr = ptr[3];
+ ptr = &ptr[nxtaddr];
+ la = ptr[5] | ((ptr[4] & 0x3f) << 16);
+ }
+ isp->isp_loaded_fw = 1;
+ } else if (dodnld) {
+ union {
+ const u_int16_t *cp;
+ u_int16_t *np;
+ } u;
+ u.cp = isp->isp_mdvec->dv_ispfw;
+ isp->isp_mbxworkp = &u.np[1];
+ isp->isp_mbxwrk0 = u.np[3] - 1;
isp->isp_mbxwrk1 = code_org + 1;
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_WRITE_RAM_WORD;
mbs.param[1] = code_org;
- mbs.param[2] = isp->isp_mdvec->dv_ispfw[0];
- isp_mboxcmd(isp, &mbs, MBLOGNONE);
+ mbs.param[2] = u.np[0];
+ mbs.logval = MBLOGNONE;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGERR,
"F/W download failed at word %d",
isp->isp_mbxwrk1 - code_org);
- dodnld = 0;
- goto again;
+ ISP_RESET0(isp);
+ return;
}
/*
* Verify that it downloaded correctly.
@@ -675,9 +977,11 @@ again:
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_VERIFY_CHECKSUM;
mbs.param[1] = code_org;
- isp_mboxcmd(isp, &mbs, MBLOGNONE);
+ mbs.logval = MBLOGNONE;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_prt(isp, ISP_LOGERR, "Ram Checksum Failure");
+ isp_prt(isp, ISP_LOGERR, dcrc);
+ ISP_RESET0(isp);
return;
}
isp->isp_loaded_fw = 1;
@@ -695,13 +999,40 @@ again:
MEMZERO(&mbs, sizeof (mbs));
+ mbs.timeout = 1000000;
mbs.param[0] = MBOX_EXEC_FIRMWARE;
- mbs.param[1] = code_org;
- isp_mboxcmd(isp, &mbs, MBLOGNONE);
+ if (IS_24XX(isp)) {
+ mbs.param[1] = code_org >> 16;
+ mbs.param[2] = code_org;
+ if (isp->isp_loaded_fw) {
+ mbs.param[3] = 0;
+ } else {
+ mbs.param[3] = 1;
+ }
+ } else if (IS_2322(isp)) {
+ mbs.param[1] = code_org;
+ if (isp->isp_loaded_fw) {
+ mbs.param[2] = 0;
+ } else {
+ mbs.param[2] = 1;
+ }
+ } else {
+ mbs.param[1] = code_org;
+ }
+
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
+ if (IS_2322(isp) || IS_24XX(isp)) {
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ ISP_RESET0(isp);
+ return;
+ }
+ }
+
/*
- * Give it a chance to start.
+ * Give it a chance to finish starting up.
*/
- USEC_DELAY(500);
+ USEC_DELAY(250000);
if (IS_SCSI(isp)) {
/*
@@ -711,15 +1042,24 @@ again:
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_SET_CLOCK_RATE;
mbs.param[1] = isp->isp_clock;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGNONE;
+ isp_mboxcmd(isp, &mbs);
/* we will try not to care if this fails */
}
}
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_ABOUT_FIRMWARE;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ ISP_RESET0(isp);
+ return;
+ }
+
+ if (IS_24XX(isp) && mbs.param[1] == 0xdead) {
+ isp_prt(isp, ISP_LOGERR, "f/w didn't *really* start");
+ ISP_RESET0(isp);
return;
}
@@ -744,7 +1084,8 @@ again:
isp->isp_fwrev[1] = mbs.param[2];
isp->isp_fwrev[2] = mbs.param[3];
}
- isp_prt(isp, ISP_LOGCONFIG,
+
+ isp_prt(isp, ISP_LOGALL,
"Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
btype, isp->isp_revision, dodnld? "loaded" : "resident",
isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
@@ -755,9 +1096,9 @@ again:
* than 1.17.0, unless it's the firmware we specifically
* are loading.
*
- * Note that all 22XX and 23XX f/w is greater than 1.X.0.
+ * Note that all 22XX and later f/w is greater than 1.X.0.
*/
- if (!(ISP_FW_NEWER_THAN(isp, 1, 17, 0))) {
+ if ((ISP_FW_OLDER_THAN(isp, 1, 17, 1))) {
#ifdef USE_SMALLER_2100_FIRMWARE
FCPARAM(isp)->isp_fwattr = ISP_FW_ATTR_SCCLUN;
#else
@@ -768,9 +1109,27 @@ again:
isp_prt(isp, ISP_LOGDEBUG0,
"Firmware Attributes = 0x%x", mbs.param[6]);
}
- if (ISP_READ(isp, BIU2100_CSR) & BIU2100_PCI64) {
- isp_prt(isp, ISP_LOGCONFIG,
- "Installed in 64-Bit PCI slot");
+ FCPARAM(isp)->isp_2klogin = 0;
+ FCPARAM(isp)->isp_sccfw = 0;
+ FCPARAM(isp)->isp_tmode = 0;
+ if (IS_24XX(isp)) {
+ FCPARAM(isp)->isp_2klogin = 1;
+ FCPARAM(isp)->isp_sccfw = 1;
+ FCPARAM(isp)->isp_tmode = 1;
+ } else {
+ if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
+ FCPARAM(isp)->isp_sccfw = 1;
+ }
+ if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_2KLOGINS) {
+ FCPARAM(isp)->isp_2klogin = 1;
+ FCPARAM(isp)->isp_sccfw = 1;
+ }
+ if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_TMODE) {
+ FCPARAM(isp)->isp_tmode = 1;
+ }
+ }
+ if (FCPARAM(isp)->isp_2klogin) {
+ isp_prt(isp, ISP_LOGCONFIG, "2K Logins Supported");
}
}
@@ -781,24 +1140,23 @@ again:
isp->isp_romfw_rev[2]);
}
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- return;
+ if (!IS_24XX(isp)) {
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ ISP_RESET0(isp);
+ return;
+ }
+ if (isp->isp_maxcmds >= mbs.param[2]) {
+ isp->isp_maxcmds = mbs.param[2];
+ }
}
- isp->isp_maxcmds = mbs.param[2];
- isp_prt(isp, ISP_LOGINFO,
- "%d max I/O commands supported", mbs.param[2]);
+ isp_prt(isp, ISP_LOGCONFIG,
+ "%d max I/O command limit set", isp->isp_maxcmds);
isp_fw_state(isp);
- /*
- * Set up DMA for the request and result mailboxes.
- */
- if (ISP_MBOXDMASETUP(isp) != 0) {
- isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
- return;
- }
isp->isp_state = ISP_RESETSTATE;
/*
@@ -829,12 +1187,24 @@ again:
isp->isp_maxluns = 8;
}
} else {
- if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
+ if (FCPARAM(isp)->isp_sccfw) {
isp->isp_maxluns = 16384;
} else {
isp->isp_maxluns = 16;
}
}
+ /*
+ * Must do this first to get defaults established.
+ */
+ if (IS_SCSI(isp)) {
+ isp_setdfltparm(isp, 0);
+ if (IS_DUALBUS(isp)) {
+ isp_setdfltparm(isp, 1);
+ }
+ } else {
+ isp_setdfltfcparm(isp);
+ }
+
}
/*
@@ -846,21 +1216,27 @@ again:
void
isp_init(struct ispsoftc *isp)
{
- /*
- * Must do this first to get defaults established.
- */
- isp_setdfltparm(isp, 0);
- if (IS_DUALBUS(isp)) {
- isp_setdfltparm(isp, 1);
- }
if (IS_FC(isp)) {
- isp_fibre_init(isp);
+ /*
+ * Do this *before* initializing the firmware.
+ */
+ ISP_MARK_PORTDB(isp, 0);
+ FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
+ FCPARAM(isp)->isp_loopstate = LOOP_NIL;
+
+ if (isp->isp_role != ISP_ROLE_NONE) {
+ if (IS_24XX(isp)) {
+ isp_fibre_init_2400(isp);
+ } else {
+ isp_fibre_init(isp);
+ }
+ }
} else {
isp_scsi_init(isp);
}
}
-static void
+void
isp_scsi_init(struct ispsoftc *isp)
{
sdparam *sdp_chan0, *sdp_chan1;
@@ -898,8 +1274,8 @@ isp_scsi_init(struct ispsoftc *isp)
mbs.param[2] = sdp_chan0->isp_retry_delay;
mbs.param[6] = sdp_chan1->isp_retry_count;
mbs.param[7] = sdp_chan1->isp_retry_delay;
-
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
}
@@ -911,7 +1287,8 @@ isp_scsi_init(struct ispsoftc *isp)
mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
mbs.param[1] = sdp_chan0->isp_async_data_setup;
mbs.param[2] = sdp_chan1->isp_async_data_setup;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
}
@@ -927,8 +1304,8 @@ isp_scsi_init(struct ispsoftc *isp)
mbs.param[2] =
(sdp_chan1->isp_req_ack_active_neg << 4) |
(sdp_chan1->isp_data_line_active_neg << 5);
-
- isp_mboxcmd(isp, &mbs, MBLOGNONE);
+ mbs.logval = MBLOGNONE;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGERR,
"failed to set active negation state (%d,%d), (%d,%d)",
@@ -948,7 +1325,8 @@ isp_scsi_init(struct ispsoftc *isp)
mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT;
mbs.param[1] = sdp_chan0->isp_tag_aging;
mbs.param[2] = sdp_chan1->isp_tag_aging;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
@@ -962,7 +1340,8 @@ isp_scsi_init(struct ispsoftc *isp)
mbs.param[0] = MBOX_SET_SELECT_TIMEOUT;
mbs.param[1] = sdp_chan0->isp_selection_timeout;
mbs.param[2] = sdp_chan1->isp_selection_timeout;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
}
@@ -985,7 +1364,8 @@ isp_scsi_init(struct ispsoftc *isp)
mbs.param[4] = 0;
mbs.param[6] = DMA_WD3(isp->isp_result_dma);
mbs.param[7] = DMA_WD2(isp->isp_result_dma);
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
}
@@ -999,7 +1379,8 @@ isp_scsi_init(struct ispsoftc *isp)
mbs.param[5] = 0;
mbs.param[6] = DMA_WD3(isp->isp_result_dma);
mbs.param[7] = DMA_WD2(isp->isp_result_dma);
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
}
@@ -1011,7 +1392,8 @@ isp_scsi_init(struct ispsoftc *isp)
mbs.param[2] = DMA_WD1(isp->isp_result_dma);
mbs.param[3] = DMA_WD0(isp->isp_result_dma);
mbs.param[4] = 0;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
}
@@ -1023,7 +1405,8 @@ isp_scsi_init(struct ispsoftc *isp)
mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
mbs.param[5] = 0;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
}
@@ -1048,14 +1431,13 @@ isp_scsi_init(struct ispsoftc *isp)
if (IS_ULTRA2(isp) || IS_1240(isp))
mbs.param[1] |= FW_FEATURE_RIO_16BIT;
#else
-#ifndef ISP_NO_FASTPOST
if (IS_ULTRA2(isp) || IS_1240(isp))
mbs.param[1] |= FW_FEATURE_FAST_POST;
#endif
-#endif
if (mbs.param[1] != 0) {
u_int16_t sfeat = mbs.param[1];
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGINFO,
"Enabled FW features (0x%x)", sfeat);
@@ -1068,7 +1450,7 @@ isp_scsi_init(struct ispsoftc *isp)
isp->isp_state = ISP_INITSTATE;
}
-static void
+void
isp_scsi_channel_init(struct ispsoftc *isp, int channel)
{
sdparam *sdp;
@@ -1084,7 +1466,8 @@ isp_scsi_channel_init(struct ispsoftc *isp, int channel)
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
mbs.param[1] = (channel << 7) | sdp->isp_initiator_id;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
}
@@ -1140,7 +1523,8 @@ isp_scsi_channel_init(struct ispsoftc *isp, int channel)
"Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
channel, tgt, mbs.param[2], mbs.param[3] >> 8,
mbs.param[3] & 0xff);
- isp_mboxcmd(isp, &mbs, MBLOGNONE);
+ mbs.logval = MBLOGNONE;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
sdf = DPARM_SAFE_DFLT;
MEMZERO(&mbs, sizeof (mbs));
@@ -1148,7 +1532,8 @@ isp_scsi_channel_init(struct ispsoftc *isp, int channel)
mbs.param[1] = (tgt << 8) | (channel << 15);
mbs.param[2] = sdf;
mbs.param[3] = 0;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
continue;
}
@@ -1172,7 +1557,8 @@ isp_scsi_channel_init(struct ispsoftc *isp, int channel)
mbs.param[1] = (channel << 15) | (tgt << 8) | lun;
mbs.param[2] = sdp->isp_max_queue_depth;
mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
break;
}
@@ -1189,37 +1575,21 @@ isp_scsi_channel_init(struct ispsoftc *isp, int channel)
/*
* Fibre Channel specific initialization.
- *
- * Locks are held before coming here.
*/
-static void
+void
isp_fibre_init(struct ispsoftc *isp)
{
fcparam *fcp;
isp_icb_t local, *icbp = &local;
mbreg_t mbs;
- int loopid;
+ int ownloopid;
u_int64_t nwwn, pwwn;
fcp = isp->isp_param;
- /*
- * Do this *before* initializing the firmware.
- */
- isp_mark_getpdb_all(isp);
- fcp->isp_fwstate = FW_CONFIG_WAIT;
- fcp->isp_loopstate = LOOP_NIL;
-
- /*
- * If we have no role (neither target nor initiator), return.
- */
- if (isp->isp_role == ISP_ROLE_NONE) {
- return;
- }
-
- loopid = fcp->isp_loopid;
MEMZERO(icbp, sizeof (*icbp));
icbp->icb_version = ICB_VERSION1;
+ icbp->icb_fwoptions = fcp->isp_fwoptions;
/*
* Firmware Options are either retrieved from NVRAM or
@@ -1231,8 +1601,8 @@ isp_fibre_init(struct ispsoftc *isp)
/*
* If this is a 2100 < revision 5, we have to turn off FAIRNESS.
*/
- if ((isp->isp_type == ISP_HA_FC_2100) && isp->isp_revision < 5) {
- fcp->isp_fwoptions &= ~ICBOPT_FAIRNESS;
+ if (IS_2100(isp) && isp->isp_revision < 5) {
+ icbp->icb_fwoptions &= ~ICBOPT_FAIRNESS;
}
/*
@@ -1241,27 +1611,29 @@ isp_fibre_init(struct ispsoftc *isp)
* a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
*/
if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
- fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
+ icbp->icb_fwoptions |= ICBOPT_FULL_LOGIN;
}
/*
* Insist on Port Database Update Async notifications
*/
- fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
+ icbp->icb_fwoptions |= ICBOPT_PDBCHANGE_AE;
/*
* Make sure that target role reflects into fwoptions.
*/
if (isp->isp_role & ISP_ROLE_TARGET) {
- fcp->isp_fwoptions |= ICBOPT_TGT_ENABLE;
+ icbp->icb_fwoptions |= ICBOPT_TGT_ENABLE;
} else {
- fcp->isp_fwoptions &= ~ICBOPT_TGT_ENABLE;
+ icbp->icb_fwoptions &= ~ICBOPT_TGT_ENABLE;
+ }
+
+ if (isp->isp_role & ISP_ROLE_INITIATOR) {
+ icbp->icb_fwoptions &= ~ICBOPT_INI_DISABLE;
+ } else {
+ icbp->icb_fwoptions |= ICBOPT_INI_DISABLE;
}
- /*
- * Propagate all of this into the ICB structure.
- */
- icbp->icb_fwoptions = fcp->isp_fwoptions;
icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
@@ -1285,7 +1657,21 @@ isp_fibre_init(struct ispsoftc *isp)
}
icbp->icb_retry_delay = fcp->isp_retry_delay;
icbp->icb_retry_count = fcp->isp_retry_count;
- icbp->icb_hardaddr = loopid;
+ icbp->icb_hardaddr = fcp->isp_loopid;
+ ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
+ if (icbp->icb_hardaddr > 125) {
+ icbp->icb_hardaddr = 0;
+ ownloopid = 0;
+ }
+
+ /*
+ * Our life seems so much better with 2200s and later with
+ * the latest f/w if we set Hard Address.
+ */
+ if (ownloopid || ISP_FW_NEWER_THAN(isp, 2, 2, 5)) {
+ icbp->icb_fwoptions |= ICBOPT_HARD_ADDRESS;
+ }
+
/*
* Right now we just set extended options to prefer point-to-point
* over loop based upon some soft config options.
@@ -1311,26 +1697,21 @@ isp_fibre_init(struct ispsoftc *isp)
icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
break;
}
- if (IS_23XX(isp)) {
+ if (IS_2200(isp)) {
+ icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
+ } else {
/*
* QLogic recommends that FAST Posting be turned
* off for 23XX cards and instead allow the HBA
* to write response queue entries and interrupt
* after a delay (ZIO).
- *
- * If we set ZIO, it will disable fast posting,
- * so we don't need to clear it in fwoptions.
- */
- icbp->icb_xfwoptions |= ICBXOPT_ZIO;
-#if 0
- /*
- * Values, in 100us increments. The default
- * is 2 (200us) if a value 0 (default) is
- * selected.
*/
- icbp->icb_idelaytimer = 2;
-#endif
-
+ icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
+ if ((fcp->isp_xfwoptions & ICBXOPT_TIMER_MASK) ==
+ ICBXOPT_ZIO) {
+ icbp->icb_xfwoptions |= ICBXOPT_ZIO;
+ icbp->icb_idelaytimer = 10;
+ }
if (isp->isp_confopts & ISP_CFG_ONEGB) {
icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
} else if (isp->isp_confopts & ISP_CFG_TWOGB) {
@@ -1338,32 +1719,15 @@ isp_fibre_init(struct ispsoftc *isp)
} else {
icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
}
+ if (fcp->isp_zfwoptions & ICBZOPT_50_OHM) {
+ icbp->icb_zfwoptions |= ICBZOPT_50_OHM;
+ }
}
}
-#ifndef ISP_NO_RIO_FC
- /*
- * RIO seems to be enabled in 2100s for fw >= 1.17.0.
- *
- * I've had some questionable problems with RIO on 2200.
- * More specifically, on a 2204 I had problems with RIO
- * on a Linux system where I was dropping commands right
- * and left. It's not clear to me what the actual problem
- * was.
- *
- * 23XX Cards do not support RIO. Instead they support ZIO.
- */
-#if 0
- if (!IS_23XX(isp) && ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
- icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
- icbp->icb_racctimer = 4;
- icbp->icb_idelaytimer = 8;
- }
-#endif
-#endif
/*
- * For 22XX > 2.1.26 && 23XX, set someoptions.
+ * For 22XX > 2.1.26 && 23XX, set some options.
* XXX: Probably okay for newer 2100 f/w too.
*/
if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
@@ -1377,16 +1741,14 @@ isp_fibre_init(struct ispsoftc *isp)
mbs.param[1] = 0xb;
mbs.param[2] = 0;
mbs.param[3] = 0;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
- }
- icbp->icb_logintime = 30; /* 30 second login timeout */
-
- if (IS_23XX(isp)) {
- ISP_WRITE(isp, isp->isp_rqstinrp, 0);
- ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
- ISP_WRITE(isp, isp->isp_respinrp, 0);
- ISP_WRITE(isp, isp->isp_respoutrp, 0);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ return;
+ }
}
+ icbp->icb_logintime = ICB_LOGIN_TOV;
+ icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV;
nwwn = ISP_NODEWWN(isp);
pwwn = ISP_PORTWWN(isp);
@@ -1400,12 +1762,25 @@ isp_fibre_init(struct ispsoftc *isp)
((u_int32_t) (nwwn & 0xffffffff)),
((u_int32_t) (pwwn >> 32)),
((u_int32_t) (pwwn & 0xffffffff)));
+ } else if (pwwn) {
+ icbp->icb_fwoptions &= ~ICBOPT_BOTH_WWNS;
+ MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "Setting ICB Port 0x%08x%08x",
+ ((u_int32_t) (pwwn >> 32)),
+ ((u_int32_t) (pwwn & 0xffffffff)));
} else {
- isp_prt(isp, ISP_LOGDEBUG1, "Not using any WWNs");
- icbp->icb_fwoptions &= ~(ICBOPT_BOTH_WWNS|ICBOPT_FULL_LOGIN);
+ isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
+ return;
}
icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
+ if (icbp->icb_rqstqlen < 1) {
+ isp_prt(isp, ISP_LOGERR, "bad request queue length");
+ }
icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
+ if (icbp->icb_rsltqlen < 1) {
+ isp_prt(isp, ISP_LOGERR, "bad result queue length");
+ }
icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
@@ -1414,6 +1789,7 @@ isp_fibre_init(struct ispsoftc *isp)
icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
+
isp_prt(isp, ISP_LOGDEBUG0,
"isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
@@ -1430,17 +1806,21 @@ isp_fibre_init(struct ispsoftc *isp)
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
+ mbs.logval = MBLOGALL;
+ mbs.timeout = 30 * 1000000;
isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %p (%08x%08x)",
- fcp->isp_scratch, (uint32_t) ((uint64_t)fcp->isp_scdma >> 32),
- (uint32_t) fcp->isp_scdma);
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ fcp->isp_scratch, (u_int32_t) ((u_int64_t)fcp->isp_scdma >> 32),
+ (u_int32_t) fcp->isp_scdma);
+ MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp));
+ isp_mboxcmd(isp, &mbs);
FC_SCRATCH_RELEASE(isp);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ isp_print_bytes(isp, "isp_fibre_init", sizeof (*icbp), icbp);
return;
}
- isp->isp_reqidx = isp->isp_reqodx = 0;
+ isp->isp_reqidx = 0;
+ isp->isp_reqodx = 0;
isp->isp_residx = 0;
- isp->isp_sendmarker = 1;
/*
* Whatever happens, we're now committed to being here.
@@ -1448,84 +1828,615 @@ isp_fibre_init(struct ispsoftc *isp)
isp->isp_state = ISP_INITSTATE;
}
-/*
- * Fibre Channel Support- get the port database for the id.
- *
- * Locks are held before coming here. Return 0 if success,
- * else failure.
- */
-
-static int
-isp_getmap(struct ispsoftc *isp, fcpos_map_t *map)
+void
+isp_fibre_init_2400(struct ispsoftc *isp)
{
- fcparam *fcp = (fcparam *) isp->isp_param;
+ fcparam *fcp;
+ isp_icb_2400_t local, *icbp = &local;
mbreg_t mbs;
+ int ownloopid;
+ u_int64_t nwwn, pwwn;
+
+ fcp = isp->isp_param;
+
+ /*
+ * Turn on LIP F8 async event (1)
+ */
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS;
+ mbs.param[1] = 1;
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ return;
+ }
+
+ /*
+ * XXX: This should be applied to icb- not fwoptions
+ */
+ if (isp->isp_role & ISP_ROLE_TARGET) {
+ fcp->isp_fwoptions |= ICB2400_OPT1_TGT_ENABLE;
+ } else {
+ fcp->isp_fwoptions &= ~ICB2400_OPT1_TGT_ENABLE;
+ }
+
+ if (isp->isp_role & ISP_ROLE_INITIATOR) {
+ fcp->isp_fwoptions &= ~ICB2400_OPT1_INI_DISABLE;
+ } else {
+ fcp->isp_fwoptions |= ICB2400_OPT1_INI_DISABLE;
+ }
+
+ MEMZERO(icbp, sizeof (*icbp));
+ icbp->icb_version = ICB_VERSION1;
+ icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
+ if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
+ icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
+ isp_prt(isp, ISP_LOGERR,
+ "bad frame length (%d) from NVRAM- using %d",
+ fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN);
+ icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
+ }
+
+ icbp->icb_execthrottle = fcp->isp_execthrottle;
+ if (icbp->icb_execthrottle < 1) {
+ isp_prt(isp, ISP_LOGERR,
+ "bad execution throttle of %d- using 16",
+ fcp->isp_execthrottle);
+ icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
+ }
+
+ if (isp->isp_role & ISP_ROLE_TARGET) {
+ /*
+ * Get current resource count
+ */
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_GET_RESOURCE_COUNT;
+ mbs.obits = 0x4cf;
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ return;
+ }
+ icbp->icb_xchgcnt = mbs.param[3];
+ }
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_GET_FC_AL_POSITION_MAP;
+ icbp->icb_fwoptions1 = fcp->isp_fwoptions;
+
+ icbp->icb_hardaddr = fcp->isp_loopid;
+ ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
+ if (icbp->icb_hardaddr > 125) {
+ icbp->icb_hardaddr = 0;
+ ownloopid = 0;
+ }
+ if (ownloopid) {
+ icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS;
+ }
+
+ icbp->icb_fwoptions2 = fcp->isp_xfwoptions;
+ switch(isp->isp_confopts & ISP_CFG_PORT_PREF) {
+ case ISP_CFG_NPORT:
+ icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
+ icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_2_LOOP;
+ break;
+ case ISP_CFG_NPORT_ONLY:
+ icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
+ icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY;
+ break;
+ case ISP_CFG_LPORT_ONLY:
+ icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
+ icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_ONLY;
+ break;
+ default:
+ icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
+ icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
+ break;
+ }
+
+ switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) {
+ case ICB2400_OPT2_ZIO:
+ case ICB2400_OPT2_ZIO1:
+ icbp->icb_idelaytimer = 0;
+ break;
+ case 0:
+ break;
+ default:
+ isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field",
+ icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
+ icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK;
+ break;
+ }
+
+ icbp->icb_fwoptions3 = fcp->isp_zfwoptions;
+ icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_AUTO;
+ if (isp->isp_confopts & ISP_CFG_ONEGB) {
+ icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_ONEGB;
+ } else if (isp->isp_confopts & ISP_CFG_TWOGB) {
+ icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_TWOGB;
+ } else if (isp->isp_confopts & ISP_CFG_FOURGB) {
+ icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_FOURGB;
+ } else {
+ icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
+ }
+
+ if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
+ icbp->icb_fwoptions3 |= ICB2400_OPT3_SOFTID;
+ }
+ icbp->icb_logintime = ICB_LOGIN_TOV;
+
+ nwwn = ISP_NODEWWN(isp);
+ pwwn = ISP_PORTWWN(isp);
+
+ if (nwwn && pwwn) {
+ icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS;
+ MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn);
+ MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
+ ((u_int32_t) (nwwn >> 32)),
+ ((u_int32_t) (nwwn & 0xffffffff)),
+ ((u_int32_t) (pwwn >> 32)),
+ ((u_int32_t) (pwwn & 0xffffffff)));
+ } else if (pwwn) {
+ icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS;
+ MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "Setting ICB Port 0x%08x%08x",
+ ((u_int32_t) (pwwn >> 32)),
+ ((u_int32_t) (pwwn & 0xffffffff)));
+ } else {
+ isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
+ return;
+ }
+ icbp->icb_retry_count = fcp->isp_retry_count;
+
+ icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
+ if (icbp->icb_rqstqlen < 8) {
+ isp_prt(isp, ISP_LOGERR, "bad request queue length %d",
+ icbp->icb_rqstqlen);
+ return;
+ }
+ icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
+ if (icbp->icb_rsltqlen < 8) {
+ isp_prt(isp, ISP_LOGERR, "bad result queue length %d",
+ icbp->icb_rsltqlen);
+ return;
+ }
+ icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
+ icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
+ icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
+ icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
+
+ icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
+ icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
+ icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
+ icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
+
+#ifdef ISP_TARGET_MODE
+ if (isp->isp_role & ISP_ROLE_TARGET) {
+ icbp->icb_atioqlen = RESULT_QUEUE_LEN(isp);
+ if (icbp->icb_atioqlen < 8) {
+ isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d",
+ icbp->icb_atioqlen);
+ return;
+ }
+ icbp->icb_atioqaddr[RQRSP_ADDR0015] =
+ DMA_WD0(isp->isp_atioq_dma);
+ icbp->icb_atioqaddr[RQRSP_ADDR1631] =
+ DMA_WD1(isp->isp_atioq_dma);
+ icbp->icb_atioqaddr[RQRSP_ADDR3247] =
+ DMA_WD2(isp->isp_atioq_dma);
+ icbp->icb_atioqaddr[RQRSP_ADDR4863] =
+ DMA_WD3(isp->isp_atioq_dma);
+ 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),
+ DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma));
+ }
+#endif
+
+ 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);
+
+ 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),
+ DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma),
+ DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
+ DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma));
+
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp, "isp_fibre_init_2400", sizeof (*icbp),
+ icbp);
+ }
+ FC_SCRATCH_ACQUIRE(isp);
+ isp_put_icb_2400(isp, icbp, fcp->isp_scratch);
+
+
+ /*
+ * Init the firmware
+ */
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_INIT_FIRMWARE;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
- FC_SCRATCH_ACQUIRE(isp);
- isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
- if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
- MEMCPY(map, fcp->isp_scratch, sizeof (fcpos_map_t));
- map->fwmap = mbs.param[1] != 0;
- FC_SCRATCH_RELEASE(isp);
- return (0);
- }
+ mbs.param[6] = DMA_WD3(fcp->isp_scdma);
+ mbs.param[7] = DMA_WD2(fcp->isp_scdma);
+ mbs.logval = MBLOGALL;
+ mbs.timeout = 30 * 1000000;
+ 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));
+ MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp));
+ isp_mboxcmd(isp, &mbs);
FC_SCRATCH_RELEASE(isp);
- return (-1);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ return;
+ }
+ isp->isp_reqidx = 0;
+ isp->isp_reqodx = 0;
+ isp->isp_residx = 0;
+
+ /*
+ * Whatever happens, we're now committed to being here.
+ */
+ isp->isp_state = ISP_INITSTATE;
}
-static void
-isp_mark_getpdb_all(struct ispsoftc *isp)
+void
+isp_mark_portdb(struct ispsoftc *isp, int onprobation)
{
fcparam *fcp = (fcparam *) isp->isp_param;
int i;
+
for (i = 0; i < MAX_FC_TARG; i++) {
- fcp->portdb[i].valid = fcp->portdb[i].fabric_dev = 0;
+ if (onprobation == 0) {
+ MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
+ } else {
+ switch (fcp->portdb[i].state) {
+ case FC_PORTDB_STATE_CHANGED:
+ case FC_PORTDB_STATE_PENDING_VALID:
+ case FC_PORTDB_STATE_VALID:
+ case FC_PORTDB_STATE_PROBATIONAL:
+ fcp->portdb[i].state =
+ FC_PORTDB_STATE_PROBATIONAL;
+ break;
+ case FC_PORTDB_STATE_ZOMBIE:
+ break;
+ case FC_PORTDB_STATE_NIL:
+ default:
+ MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
+ fcp->portdb[i].state =
+ FC_PORTDB_STATE_NIL;
+ break;
+ }
+ }
+ }
+}
+
+/*
+ * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards
+ * or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
+ */
+int
+isp_plogx(struct ispsoftc *isp, u_int16_t handle, u_int32_t portid, int flags, int gs)
+{
+ mbreg_t mbs;
+ u_int8_t q[QENTRY_LEN];
+ isp_plogx_t *plp;
+ u_int8_t *scp;
+ u_int32_t sst, parm1;
+ int rval;
+
+ if (!IS_24XX(isp)) {
+ int action = flags & PLOGX_FLG_CMD_MASK;
+ if (action == PLOGX_FLG_CMD_PLOGI) {
+ return (isp_port_login(isp, handle, portid));
+ } else if (action == PLOGX_FLG_CMD_LOGO) {
+ return (isp_port_logout(isp, handle, portid));
+ } else {
+ return (MBOX_INVALID_COMMAND);
+ }
+ }
+
+ MEMZERO(q, QENTRY_LEN);
+ plp = (isp_plogx_t *) q;
+ plp->plogx_header.rqs_entry_count = 1;
+ plp->plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
+ plp->plogx_handle = 0xffffffff;
+ plp->plogx_nphdl = handle;
+ plp->plogx_portlo = portid;
+ plp->plogx_rspsz_porthi = (portid >> 16) & 0xff;
+ plp->plogx_flags = flags;
+
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, plp);
+ }
+
+ if (gs == 0) {
+ FC_SCRATCH_ACQUIRE(isp);
+ }
+ scp = FCPARAM(isp)->isp_scratch;
+ isp_put_plogx(isp, plp, (isp_plogx_t *) scp);
+
+
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
+ mbs.param[1] = QENTRY_LEN;
+ mbs.param[2] = DMA_WD1(FCPARAM(isp)->isp_scdma);
+ mbs.param[3] = DMA_WD0(FCPARAM(isp)->isp_scdma);
+ mbs.param[6] = DMA_WD3(FCPARAM(isp)->isp_scdma);
+ mbs.param[7] = DMA_WD2(FCPARAM(isp)->isp_scdma);
+ mbs.timeout = 500000;
+ mbs.logval = MBLOGALL;
+ MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN);
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ rval = mbs.param[0];
+ goto out;
+ }
+ MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN);
+ scp += QENTRY_LEN;
+ isp_get_plogx(isp, (isp_plogx_t *) scp, plp);
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, plp);
+ }
+
+ if (plp->plogx_status == PLOGX_STATUS_OK) {
+ rval = 0;
+ goto out;
+ } else if (plp->plogx_status != PLOGX_STATUS_IOCBERR) {
+ isp_prt(isp, ISP_LOGWARN, "status 0x%x on port login IOCB",
+ plp->plogx_status);
+ rval = -1;
+ goto out;
+ }
+
+ sst = plp->plogx_ioparm[0].lo16 | (plp->plogx_ioparm[0].hi16 << 16);
+ parm1 = plp->plogx_ioparm[1].lo16 | (plp->plogx_ioparm[1].hi16 << 16);
+
+ rval = -1;
+
+ switch (sst) {
+ case PLOGX_IOCBERR_NOLINK:
+ isp_prt(isp, ISP_LOGERR, "PLOGX failed- no link");
+ break;
+ case PLOGX_IOCBERR_NOIOCB:
+ isp_prt(isp, ISP_LOGERR, "PLOGX failed- no IOCB buffer");
+ break;
+ case PLOGX_IOCBERR_NOXGHG:
+ isp_prt(isp, ISP_LOGERR,
+ "PLOGX failed- no Exchange Control Block");
+ break;
+ case PLOGX_IOCBERR_FAILED:
+ isp_prt(isp, ISP_LOGERR,
+ "PLOGX(0x%x) of Port 0x%06x failed: reason 0x%x (last LOGIN"
+ " state 0x%x)", flags, portid, parm1 & 0xff,
+ (parm1 >> 8) & 0xff);
+ break;
+ case PLOGX_IOCBERR_NOFABRIC:
+ isp_prt(isp, ISP_LOGERR, "PLOGX failed- no fabric");
+ break;
+ case PLOGX_IOCBERR_NOTREADY:
+ isp_prt(isp, ISP_LOGERR, "PLOGX failed- f/w not ready");
+ break;
+ case PLOGX_IOCBERR_NOLOGIN:
+ isp_prt(isp, ISP_LOGERR,
+ "PLOGX failed- not logged in (last LOGIN state 0x%x)",
+ parm1);
+ rval = MBOX_NOT_LOGGED_IN;
+ break;
+ case PLOGX_IOCBERR_REJECT:
+ isp_prt(isp, ISP_LOGERR, "PLOGX failed: LS_RJT = 0x%x", parm1);
+ break;
+ case PLOGX_IOCBERR_NOPCB:
+ isp_prt(isp, ISP_LOGERR, "PLOGX failed- no PCB allocated");
+ break;
+ case PLOGX_IOCBERR_EINVAL:
+ isp_prt(isp, ISP_LOGERR,
+ "PLOGX failed: invalid parameter at offset 0x%x", parm1);
+ break;
+ case PLOGX_IOCBERR_PORTUSED:
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "portid 0x%x already logged in with N-port handle 0x%x",
+ portid, parm1);
+ rval = MBOX_PORT_ID_USED | (handle << 16);
+ break;
+ case PLOGX_IOCBERR_HNDLUSED:
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "N-port handle 0x%x already used for portid 0x%x",
+ handle, parm1);
+ rval = MBOX_LOOP_ID_USED;
+ break;
+ case PLOGX_IOCBERR_NOHANDLE:
+ isp_prt(isp, ISP_LOGERR, "PLOGX failed- no handle allocated");
+ break;
+ case PLOGX_IOCBERR_NOFLOGI:
+ isp_prt(isp, ISP_LOGERR, "PLOGX failed- no FLOGI_ACC");
+ break;
+ default:
+ isp_prt(isp, ISP_LOGERR, "status %x from %x", plp->plogx_status,
+ flags);
+ rval = -1;
+ break;
}
+out:
+ if (gs == 0) {
+ FC_SCRATCH_RELEASE(isp);
+ }
+ return (rval);
}
-static int
-isp_getpdb(struct ispsoftc *isp, int id, isp_pdb_t *pdbp)
+int
+isp_port_login(struct ispsoftc *isp, u_int16_t handle, u_int32_t portid)
+{
+ mbreg_t mbs;
+
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_FABRIC_LOGIN;
+ if (FCPARAM(isp)->isp_2klogin) {
+ mbs.param[1] = handle;
+ mbs.ibits = (1 << 10);
+ } else {
+ mbs.param[1] = handle << 8;
+ }
+ mbs.param[2] = portid >> 16;
+ mbs.param[3] = portid;
+ mbs.logval = MBLOGNONE;
+ mbs.timeout = 500000;
+ isp_mboxcmd(isp, &mbs);
+
+ switch (mbs.param[0]) {
+ case MBOX_PORT_ID_USED:
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "isp_plogi_old: portid 0x%06x already logged in as %u",
+ portid, mbs.param[1]);
+ return (MBOX_PORT_ID_USED | (mbs.param[1] << 16));
+
+ case MBOX_LOOP_ID_USED:
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "isp_plogi_old: handle %u in use for port id 0x%02xXXXX",
+ handle, mbs.param[1] & 0xff);
+ return (MBOX_LOOP_ID_USED);
+
+ case MBOX_COMMAND_COMPLETE:
+ return (0);
+
+ case MBOX_COMMAND_ERROR:
+ isp_prt(isp, ISP_LOGINFO,
+ "isp_plogi_old: error 0x%x in PLOGI to port 0x%06x",
+ mbs.param[1], portid);
+ return (MBOX_COMMAND_ERROR);
+
+ case MBOX_ALL_IDS_USED:
+ isp_prt(isp, ISP_LOGINFO,
+ "isp_plogi_old: all IDs used for fabric login");
+ return (MBOX_ALL_IDS_USED);
+
+ default:
+ isp_prt(isp, ISP_LOGINFO,
+ "isp_plogi_old: error 0x%x on port login of 0x%06x@0x%0x",
+ mbs.param[0], portid, handle);
+ return (mbs.param[0]);
+ }
+}
+
+int
+isp_port_logout(struct ispsoftc *isp, u_int16_t handle, u_int32_t portid)
+{
+ mbreg_t mbs;
+
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_FABRIC_LOGOUT;
+ if (FCPARAM(isp)->isp_2klogin) {
+ mbs.param[1] = handle;
+ mbs.ibits = (1 << 10);
+ } else {
+ mbs.param[1] = handle << 8;
+ }
+ mbs.logval = MBLOGNONE;
+ mbs.timeout = 100000;
+ isp_mboxcmd(isp, &mbs);
+ return (mbs.param[0] == MBOX_COMMAND_COMPLETE? 0 : mbs.param[0]);
+}
+
+int
+isp_getpdb(struct ispsoftc *isp, u_int16_t id, isp_pdb_t *pdb, int dolock)
{
fcparam *fcp = (fcparam *) isp->isp_param;
mbreg_t mbs;
+ union {
+ isp_pdb_21xx_t fred;
+ isp_pdb_24xx_t bill;
+ } un;
- MEMZERO(&mbs, sizeof (mbs));
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_GET_PORT_DB;
- mbs.param[1] = id << 8;
+ if (IS_24XX(isp)) {
+ mbs.ibits = 0x3ff;
+ mbs.param[1] = id;
+ } else if (FCPARAM(isp)->isp_2klogin) {
+ mbs.param[1] = id;
+ mbs.ibits = (1 << 10);
+ } else {
+ mbs.param[1] = id << 8;
+ }
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
- FC_SCRATCH_ACQUIRE(isp);
- isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
- if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
- isp_get_pdb(isp, (isp_pdb_t *)fcp->isp_scratch, pdbp);
+ mbs.timeout = 250000;
+ mbs.logval = MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR;
+ if (dolock) {
+ FC_SCRATCH_ACQUIRE(isp);
+ }
+ MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (un));
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ if (dolock) {
+ FC_SCRATCH_RELEASE(isp);
+ }
+ return (-1);
+ }
+ if (IS_24XX(isp)) {
+ isp_get_pdb_24xx(isp, fcp->isp_scratch, &un.bill);
+ pdb->handle = un.bill.pdb_handle;
+ pdb->s3_role = un.bill.pdb_prli_svc3;
+ pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
+ MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
+ MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
+ } else {
+ isp_get_pdb_21xx(isp, fcp->isp_scratch, &un.fred);
+ pdb->handle = un.fred.pdb_loopid;
+ pdb->s3_role = un.fred.pdb_prli_svc3;
+ pdb->portid = BITS2WORD(un.fred.pdb_portid_bits);
+ MEMCPY(pdb->portname, un.fred.pdb_portname, 8);
+ MEMCPY(pdb->nodename, un.fred.pdb_nodename, 8);
+ }
+ if (dolock) {
FC_SCRATCH_RELEASE(isp);
- return (0);
}
- FC_SCRATCH_RELEASE(isp);
- return (-1);
+ return (0);
}
-static u_int64_t
+u_int64_t
isp_get_portname(struct ispsoftc *isp, int loopid, int nodename)
{
- u_int64_t wwn = 0;
+ u_int64_t wwn = (u_int64_t) -1;
mbreg_t mbs;
- MEMZERO(&mbs, sizeof (mbs));
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_GET_PORT_NAME;
- mbs.param[1] = loopid << 8;
- if (nodename)
- mbs.param[1] |= 1;
- isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
- if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
+ if (FCPARAM(isp)->isp_2klogin || IS_24XX(isp)) {
+ mbs.param[1] = loopid;
+ mbs.ibits = (1 << 10);
+ if (nodename) {
+ mbs.param[10] = 1;
+ }
+ } else {
+ mbs.param[1] = loopid << 8;
+ if (nodename) {
+ mbs.param[1] |= 1;
+ }
+ }
+ mbs.logval = MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR;
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ return (wwn);
+ }
+ if (IS_24XX(isp)) {
wwn =
- (((u_int64_t)(mbs.param[2] & 0xff)) << 56) |
+ (((u_int64_t)(mbs.param[2] >> 8)) << 56) |
+ (((u_int64_t)(mbs.param[2] & 0xff)) << 48) |
+ (((u_int64_t)(mbs.param[3] >> 8)) << 40) |
+ (((u_int64_t)(mbs.param[3] & 0xff)) << 32) |
+ (((u_int64_t)(mbs.param[6] >> 8)) << 24) |
+ (((u_int64_t)(mbs.param[6] & 0xff)) << 16) |
+ (((u_int64_t)(mbs.param[7] >> 8)) << 8) |
+ (((u_int64_t)(mbs.param[7] & 0xff)));
+ } else {
+ wwn =
+ (((u_int64_t)(mbs.param[2] & 0xff)) << 56) |
(((u_int64_t)(mbs.param[2] >> 8)) << 48) |
(((u_int64_t)(mbs.param[3] & 0xff)) << 40) |
(((u_int64_t)(mbs.param[3] >> 8)) << 32) |
@@ -1538,13 +2449,13 @@ isp_get_portname(struct ispsoftc *isp, int loopid, int nodename)
}
/*
- * Make sure we have good FC link and know our Loop ID.
+ * Make sure we have good FC link.
*/
-static int
+int
isp_fclink_test(struct ispsoftc *isp, int usdelay)
{
- static char *toponames[] = {
+ static const char *toponames[] = {
"Private Loop",
"FL Port",
"N-Port to N-Port",
@@ -1554,15 +2465,15 @@ isp_fclink_test(struct ispsoftc *isp, int usdelay)
mbreg_t mbs;
int count, check_for_fabric;
u_int8_t lwfs;
+ int loopid;
fcparam *fcp;
- struct lportdb *lp;
+ fcportdb_t *lp;
isp_pdb_t pdb;
fcp = isp->isp_param;
- /*
- * XXX: Here is where we would start a 'loop dead' timeout
- */
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC Link Test Entry");
+ ISP_MARK_PORTDB(isp, 1);
/*
* Wait up to N microseconds for F/W to go to a ready state.
@@ -1577,12 +2488,14 @@ isp_fclink_test(struct ispsoftc *isp, int usdelay)
GET_NANOTIME(&hra);
isp_fw_state(isp);
if (lwfs != fcp->isp_fwstate) {
- isp_prt(isp, ISP_LOGINFO, "Firmware State <%s->%s>",
- isp2100_fw_statename((int)lwfs),
- isp2100_fw_statename((int)fcp->isp_fwstate));
+ isp_prt(isp, ISP_LOGCONFIG|ISP_LOGSANCFG,
+ "Firmware State <%s->%s>",
+ ispfc_fw_statename((int)lwfs),
+ ispfc_fw_statename((int)fcp->isp_fwstate));
lwfs = fcp->isp_fwstate;
}
- if (fcp->isp_fwstate == FW_READY) {
+ if (fcp->isp_fwstate == FW_READY &&
+ fcp->isp_loopstate >= LOOP_PDB_RCVD) {
break;
}
GET_NANOTIME(&hrb);
@@ -1631,36 +2544,38 @@ isp_fclink_test(struct ispsoftc *isp, int usdelay)
* If we haven't gone to 'ready' state, return.
*/
if (fcp->isp_fwstate != FW_READY) {
+ isp_prt(isp, ISP_LOGSANCFG,
+ "isp_fclink_test: not at FW_READY state");
return (-1);
}
/*
- * Get our Loop ID (if possible). We really need to have it.
+ * Get our Loop ID and Port ID.
*/
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_GET_LOOP_ID;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return (-1);
}
- fcp->isp_loopid = mbs.param[1];
- if (IS_2200(isp) || IS_23XX(isp)) {
+
+ if (FCPARAM(isp)->isp_2klogin) {
+ fcp->isp_loopid = mbs.param[1];
+ } else {
+ fcp->isp_loopid = mbs.param[1] & 0xff;
+ }
+
+ if (IS_2100(isp)) {
+ fcp->isp_topo = TOPO_NL_PORT;
+ } else {
int topo = (int) mbs.param[6];
- if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
+ if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB) {
topo = TOPO_PTP_STUB;
+ }
fcp->isp_topo = topo;
- } else {
- fcp->isp_topo = TOPO_NL_PORT;
}
- fcp->isp_portid = fcp->isp_alpa = mbs.param[2] & 0xff;
-
- /*
- * Check to see if we're on a fabric by trying to see if we
- * can talk to the fabric name server. This can be a bit
- * tricky because if we're a 2100, we should check always
- * (in case we're connected to a server doing aliasing).
- */
- fcp->isp_onfabric = 0;
+ fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16);
if (IS_2100(isp)) {
/*
@@ -1675,122 +2590,92 @@ isp_fclink_test(struct ispsoftc *isp, int usdelay)
} else if (fcp->isp_topo == TOPO_FL_PORT ||
fcp->isp_topo == TOPO_F_PORT) {
check_for_fabric = 1;
- } else
+ } else {
check_for_fabric = 0;
+ }
- if (check_for_fabric && isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
- int loopid = FL_PORT_ID;
+ if (IS_24XX(isp)) {
+ loopid = NPH_FL_ID;
+ } else {
+ loopid = FL_ID;
+ }
+
+ if (check_for_fabric && isp_getpdb(isp, loopid, &pdb, 1) == 0) {
+ int r;
if (IS_2100(isp)) {
fcp->isp_topo = TOPO_FL_PORT;
}
-
- if (BITS2WORD(pdb.pdb_portid_bits) == 0) {
+ if (pdb.portid == 0) {
/*
* Crock.
*/
fcp->isp_topo = TOPO_NL_PORT;
goto not_on_fabric;
}
- fcp->isp_portid = mbs.param[2] | ((int) mbs.param[3] << 16);
/*
* Save the Fabric controller's port database entry.
*/
- lp = &fcp->portdb[loopid];
- lp->node_wwn =
- (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
- (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
- (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
- (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
- (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
- (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
- (((u_int64_t)pdb.pdb_nodename[6]) << 8) |
- (((u_int64_t)pdb.pdb_nodename[7]));
- lp->port_wwn =
- (((u_int64_t)pdb.pdb_portname[0]) << 56) |
- (((u_int64_t)pdb.pdb_portname[1]) << 48) |
- (((u_int64_t)pdb.pdb_portname[2]) << 40) |
- (((u_int64_t)pdb.pdb_portname[3]) << 32) |
- (((u_int64_t)pdb.pdb_portname[4]) << 24) |
- (((u_int64_t)pdb.pdb_portname[5]) << 16) |
- (((u_int64_t)pdb.pdb_portname[6]) << 8) |
- (((u_int64_t)pdb.pdb_portname[7]));
- lp->roles =
- (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
- lp->portid = BITS2WORD(pdb.pdb_portid_bits);
- lp->loopid = pdb.pdb_loopid;
- lp->loggedin = lp->valid = 1;
- fcp->isp_onfabric = 1;
- (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
- isp_register_fc4_type(isp);
+ lp = &fcp->portdb[FL_ID];
+ lp->state = FC_PORTDB_STATE_PENDING_VALID;
+ MAKE_WWN_FROM_NODE_NAME(lp->node_wwn, pdb.nodename);
+ MAKE_WWN_FROM_NODE_NAME(lp->port_wwn, pdb.portname);
+ lp->roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
+ lp->portid = pdb.portid;
+ lp->handle = pdb.handle;
+ lp->new_portid = lp->portid;
+ lp->new_roles = lp->roles;
+ if (IS_24XX(isp)) {
+ r = isp_register_fc4_type_24xx(isp);
+ } else {
+ r = isp_register_fc4_type(isp);
+ }
+ if (r) {
+ isp_prt(isp, ISP_LOGSANCFG,
+ "isp_fclink_test: register fc4 type failed");
+ return (-1);
+ }
} else {
not_on_fabric:
- fcp->isp_onfabric = 0;
- fcp->portdb[FL_PORT_ID].valid = 0;
+ fcp->portdb[FL_ID].state = FC_PORTDB_STATE_NIL;
}
fcp->isp_gbspeed = 1;
- if (IS_23XX(isp)) {
- MEMZERO(&mbs, sizeof (mbs));
+ if (IS_23XX(isp) || IS_24XX(isp)) {
+ MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_GET_SET_DATA_RATE;
mbs.param[1] = MBGSD_GET_RATE;
/* mbs.param[2] undefined if we're just getting rate */
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ mbs.timeout = 3000000;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
- if (mbs.param[1] == MBGSD_TWOGB) {
+ if (mbs.param[1] == MBGSD_FOURGB) {
+ isp_prt(isp, ISP_LOGINFO, "4Gb link speed/s");
+ fcp->isp_gbspeed = 4;
+ } if (mbs.param[1] == MBGSD_TWOGB) {
isp_prt(isp, ISP_LOGINFO, "2Gb link speed/s");
fcp->isp_gbspeed = 2;
}
}
}
- isp_prt(isp, ISP_LOGCONFIG, topology, fcp->isp_loopid, fcp->isp_alpa,
- fcp->isp_portid, fcp->isp_loopstate, toponames[fcp->isp_topo]);
-
/*
- * Announce ourselves, too. This involves synthesizing an entry.
+ * Announce ourselves, too.
*/
- if (fcp->isp_iid_set == 0) {
- fcp->isp_iid_set = 1;
- fcp->isp_iid = fcp->isp_loopid;
- lp = &fcp->portdb[fcp->isp_iid];
- } else {
- lp = &fcp->portdb[fcp->isp_iid];
- if (fcp->isp_portid != lp->portid ||
- fcp->isp_loopid != lp->loopid ||
- fcp->isp_nodewwn != ISP_NODEWWN(isp) ||
- fcp->isp_portwwn != ISP_PORTWWN(isp)) {
- lp->valid = 0;
- count = fcp->isp_iid;
- (void) isp_async(isp, ISPASYNC_PROMENADE, &count);
- }
- }
- lp->loopid = fcp->isp_loopid;
- lp->portid = fcp->isp_portid;
- lp->node_wwn = ISP_NODEWWN(isp);
- lp->port_wwn = ISP_PORTWWN(isp);
- switch (isp->isp_role) {
- case ISP_ROLE_NONE:
- lp->roles = 0;
- break;
- case ISP_ROLE_TARGET:
- lp->roles = SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT;
- break;
- case ISP_ROLE_INITIATOR:
- lp->roles = SVC3_INI_ROLE >> SVC3_ROLE_SHIFT;
- break;
- case ISP_ROLE_BOTH:
- lp->roles = (SVC3_INI_ROLE|SVC3_TGT_ROLE) >> SVC3_ROLE_SHIFT;
- break;
- }
- lp->loggedin = lp->valid = 1;
- count = fcp->isp_iid;
- (void) isp_async(isp, ISPASYNC_PROMENADE, &count);
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGCONFIG, topology, fcp->isp_portid,
+ fcp->isp_loopid, toponames[fcp->isp_topo]);
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGCONFIG, ourwwn,
+ (u_int32_t) (ISP_NODEWWN(isp) >> 32),
+ (u_int32_t) ISP_NODEWWN(isp),
+ (u_int32_t) (ISP_PORTWWN(isp) >> 32),
+ (u_int32_t) ISP_PORTWWN(isp));
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC Link Test Complete");
return (0);
}
-static char *
-isp2100_fw_statename(int state)
+const char *
+ispfc_fw_statename(int state)
{
switch(state) {
case FW_CONFIG_WAIT: return "Config Wait";
@@ -1806,17 +2691,35 @@ isp2100_fw_statename(int state)
}
/*
- * Synchronize our soft copy of the port database with what the f/w thinks
- * (with a view toward possibly for a specific target....)
+ * Complete the synchronization of our Port Database.
+ *
+ * At this point, we've scanned the local loop (if any) and the fabric
+ * and performed fabric logins on all new devices.
+ *
+ * Our task here is to go through our port database and remove any entities
+ * that are still marked probational (issuing PLOGO for ones which we had
+ * PLOGI'd into) or are dead.
+ *
+ * Our task here is to also check policy to decide whether devices which
+ * have *changed* in some way should still be kept active. For example,
+ * if a device has just changed PortID, we can either elect to treat it
+ * as an old device or as a newly arrived device (and notify the outer
+ * layer appropriately).
+ *
+ * We also do initiator map target id assignment here for new initiator
+ * devices and refresh old ones ot make sure that they point to the corret
+ * entities.
*/
-
-static int
+int
isp_pdb_sync(struct ispsoftc *isp)
{
- struct lportdb *lp;
fcparam *fcp = isp->isp_param;
- isp_pdb_t pdb;
- int loopid, base, lim;
+ fcportdb_t *lp;
+ u_int16_t dbidx;
+
+ if (fcp->isp_loopstate == LOOP_READY) {
+ return (0);
+ }
/*
* Make sure we're okay for doing this right now.
@@ -1824,289 +2727,127 @@ isp_pdb_sync(struct ispsoftc *isp)
if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
fcp->isp_loopstate != LOOP_FSCAN_DONE &&
fcp->isp_loopstate != LOOP_LSCAN_DONE) {
+ isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d",
+ fcp->isp_loopstate);
return (-1);
}
- if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT ||
+ if (fcp->isp_topo == TOPO_FL_PORT ||
+ fcp->isp_topo == TOPO_NL_PORT ||
fcp->isp_topo == TOPO_N_PORT) {
if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
if (isp_scan_loop(isp) != 0) {
+ isp_prt(isp, ISP_LOGWARN,
+ "isp_pdb_sync: isp_scan_loop failed");
return (-1);
}
}
}
- fcp->isp_loopstate = LOOP_SYNCING_PDB;
-
- /*
- * If we get this far, we've settled our differences with the f/w
- * (for local loop device) and we can say that the loop state is ready.
- */
-
- if (fcp->isp_topo == TOPO_NL_PORT) {
- fcp->loop_seen_once = 1;
- fcp->isp_loopstate = LOOP_READY;
- return (0);
- }
- /*
- * Find all Fabric Entities that didn't make it from one scan to the
- * next and let the world know they went away. Scan the whole database.
- */
- for (lp = &fcp->portdb[0]; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
- if (lp->was_fabric_dev && lp->fabric_dev == 0) {
- loopid = lp - fcp->portdb;
- lp->valid = 0; /* should already be set */
- (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
- MEMZERO((void *) lp, sizeof (*lp));
- continue;
+ if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
+ if (fcp->isp_loopstate < LOOP_FSCAN_DONE) {
+ if (isp_scan_fabric(isp) != 0) {
+ isp_prt(isp, ISP_LOGWARN,
+ "isp_pdb_sync: isp_scan_fabric failed");
+ return (-1);
+ }
}
- lp->was_fabric_dev = lp->fabric_dev;
}
- if (fcp->isp_topo == TOPO_FL_PORT)
- base = FC_SNS_ID+1;
- else
- base = 0;
-
- if (fcp->isp_topo == TOPO_N_PORT)
- lim = 1;
- else
- lim = MAX_FC_TARG;
-
- /*
- * Now log in any fabric devices that the outer layer has
- * left for us to see. This seems the most sane policy
- * for the moment.
- */
- for (lp = &fcp->portdb[base]; lp < &fcp->portdb[lim]; lp++) {
- u_int32_t portid;
- mbreg_t mbs;
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Synchronizing PDBs");
- loopid = lp - fcp->portdb;
- if (loopid >= FL_PORT_ID && loopid <= FC_SNS_ID) {
- continue;
- }
+ fcp->isp_loopstate = LOOP_SYNCING_PDB;
- /*
- * Anything here?
- */
- if (lp->port_wwn == 0) {
- continue;
- }
+ for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
+ lp = &fcp->portdb[dbidx];
- /*
- * Don't try to log into yourself.
- */
- if ((portid = lp->portid) == fcp->isp_portid) {
+ if (lp->state == FC_PORTDB_STATE_NIL) {
continue;
}
-
- /*
- * If we'd been logged in- see if we still are and we haven't
- * changed. If so, no need to log ourselves out, etc..
- *
- * Unfortunately, our charming QLogic f/w has decided to
- * return a valid port database entry for a fabric device
- * that has, in fact, gone away. And it hangs trying to
- * log it out.
- */
- if (lp->loggedin && lp->force_logout == 0 &&
- isp_getpdb(isp, lp->loopid, &pdb) == 0) {
- int nrole;
- u_int64_t nwwnn, nwwpn;
- nwwnn =
- (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
- (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
- (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
- (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
- (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
- (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
- (((u_int64_t)pdb.pdb_nodename[6]) << 8) |
- (((u_int64_t)pdb.pdb_nodename[7]));
- nwwpn =
- (((u_int64_t)pdb.pdb_portname[0]) << 56) |
- (((u_int64_t)pdb.pdb_portname[1]) << 48) |
- (((u_int64_t)pdb.pdb_portname[2]) << 40) |
- (((u_int64_t)pdb.pdb_portname[3]) << 32) |
- (((u_int64_t)pdb.pdb_portname[4]) << 24) |
- (((u_int64_t)pdb.pdb_portname[5]) << 16) |
- (((u_int64_t)pdb.pdb_portname[6]) << 8) |
- (((u_int64_t)pdb.pdb_portname[7]));
- nrole = (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >>
- SVC3_ROLE_SHIFT;
- if (pdb.pdb_loopid == lp->loopid && lp->portid ==
- (u_int32_t) BITS2WORD(pdb.pdb_portid_bits) &&
- nwwnn == lp->node_wwn && nwwpn == lp->port_wwn &&
- lp->roles == nrole && lp->force_logout == 0) {
- lp->loggedin = lp->valid = 1;
- isp_prt(isp, ISP_LOGCONFIG, lretained,
- (int) (lp - fcp->portdb),
- (int) lp->loopid, lp->portid);
- continue;
+ if (lp->state == FC_PORTDB_STATE_VALID) {
+ if (dbidx != FL_ID) {
+ isp_prt(isp,
+ ISP_LOGERR, "portdb idx %d already valid",
+ dbidx);
}
+ continue;
}
- if (fcp->isp_fwstate != FW_READY ||
- fcp->isp_loopstate != LOOP_SYNCING_PDB) {
- return (-1);
- }
-
- /*
- * Force a logout if we were logged in.
- */
- if (lp->loggedin) {
- if (lp->force_logout ||
- isp_getpdb(isp, lp->loopid, &pdb) == 0) {
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_FABRIC_LOGOUT;
- mbs.param[1] = lp->loopid << 8;
- isp_mboxcmd(isp, &mbs, MBLOGNONE);
- isp_prt(isp, ISP_LOGINFO, plogout,
- (int) (lp - fcp->portdb), lp->loopid,
- lp->portid);
+ switch (lp->state) {
+ case FC_PORTDB_STATE_PROBATIONAL:
+ case FC_PORTDB_STATE_DEAD:
+ /*
+ * It's up to the outer layers to clear isp_ini_map.
+ */
+ lp->state = FC_PORTDB_STATE_NIL;
+ isp_async(isp, ISPASYNC_DEV_GONE, lp);
+ if (lp->autologin == 0) {
+ (void) isp_plogx(isp, lp->handle, lp->portid,
+ PLOGX_FLG_CMD_LOGO |
+ PLOGX_FLG_IMPLICIT |
+ PLOGX_FLG_FREE_NPHDL, 0);
+ } else {
+ lp->autologin = 0;
}
- lp->force_logout = lp->loggedin = 0;
- if (fcp->isp_fwstate != FW_READY ||
- fcp->isp_loopstate != LOOP_SYNCING_PDB) {
- return (-1);
+ lp->new_roles = 0;
+ lp->new_portid = 0;
+ /*
+ * Note that we might come out of this with our state
+ * set to FC_PORTDB_STATE_ZOMBIE.
+ */
+ break;
+ case FC_PORTDB_STATE_NEW:
+ /*
+ * It's up to the outer layers to assign a virtual
+ * target id in isp_ini_map (if any).
+ */
+ lp->portid = lp->new_portid;
+ lp->roles = lp->new_roles;
+ lp->state = FC_PORTDB_STATE_VALID;
+ isp_async(isp, ISPASYNC_DEV_ARRIVED, lp);
+ lp->new_roles = 0;
+ lp->new_portid = 0;
+ lp->reserved = 0;
+ lp->new_reserved = 0;
+ break;
+ case FC_PORTDB_STATE_CHANGED:
+/*
+ * XXXX FIX THIS
+ */
+ lp->state = FC_PORTDB_STATE_VALID;
+ isp_async(isp, ISPASYNC_DEV_CHANGED, lp);
+ lp->new_roles = 0;
+ lp->new_portid = 0;
+ lp->reserved = 0;
+ lp->new_reserved = 0;
+ break;
+ case FC_PORTDB_STATE_PENDING_VALID:
+ lp->portid = lp->new_portid;
+ lp->roles = lp->new_roles;
+ if (lp->ini_map_idx) {
+ int t = lp->ini_map_idx - 1;
+ fcp->isp_ini_map[t] = dbidx + 1;
}
- }
-
- /*
- * And log in....
- */
- loopid = lp - fcp->portdb;
- lp->loopid = FL_PORT_ID;
- do {
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_FABRIC_LOGIN;
- mbs.param[1] = loopid << 8;
- mbs.param[2] = portid >> 16;
- mbs.param[3] = portid & 0xffff;
- isp_mboxcmd(isp, &mbs, MBLOGALL & ~(MBOX_LOOP_ID_USED |
- MBOX_PORT_ID_USED | MBOX_COMMAND_ERROR));
- if (fcp->isp_fwstate != FW_READY ||
- fcp->isp_loopstate != LOOP_SYNCING_PDB) {
- return (-1);
+ lp->state = FC_PORTDB_STATE_VALID;
+ isp_async(isp, ISPASYNC_DEV_STAYED, lp);
+ if (dbidx != FL_ID) {
+ lp->new_roles = 0;
+ lp->new_portid = 0;
}
- switch (mbs.param[0]) {
- case MBOX_LOOP_ID_USED:
- /*
- * Try the next available loop id.
- */
- loopid++;
- break;
- case MBOX_PORT_ID_USED:
- /*
- * This port is already logged in.
- * Snaffle the loop id it's using if it's
- * nonzero, otherwise we're hosed.
- */
- if (mbs.param[1] != 0) {
- loopid = mbs.param[1];
- isp_prt(isp, ISP_LOGINFO, retained,
- loopid, (int) (lp - fcp->portdb),
- lp->portid);
- } else {
- loopid = MAX_FC_TARG;
- break;
- }
- /* FALLTHROUGH */
- case MBOX_COMMAND_COMPLETE:
- lp->loggedin = 1;
- lp->loopid = loopid;
- break;
- case MBOX_COMMAND_ERROR:
- isp_prt(isp, ISP_LOGINFO, plogierr,
- portid, mbs.param[1]);
- /* FALLTHROUGH */
- case MBOX_ALL_IDS_USED: /* We're outta IDs */
- default:
- loopid = MAX_FC_TARG;
- break;
- }
- } while (lp->loopid == FL_PORT_ID && loopid < MAX_FC_TARG);
-
- /*
- * If we get here and we haven't set a Loop ID,
- * we failed to log into this device.
- */
-
- if (lp->loopid == FL_PORT_ID) {
- lp->loopid = 0;
- continue;
- }
-
- /*
- * Make sure we can get the appropriate port information.
- */
- if (isp_getpdb(isp, lp->loopid, &pdb) != 0) {
- isp_prt(isp, ISP_LOGWARN, nopdb, lp->portid);
- goto dump_em;
- }
-
- if (fcp->isp_fwstate != FW_READY ||
- fcp->isp_loopstate != LOOP_SYNCING_PDB) {
- return (-1);
- }
-
- if (pdb.pdb_loopid != lp->loopid) {
- isp_prt(isp, ISP_LOGWARN, pdbmfail1,
- lp->portid, pdb.pdb_loopid);
- goto dump_em;
- }
-
- if (lp->portid != (u_int32_t) BITS2WORD(pdb.pdb_portid_bits)) {
- isp_prt(isp, ISP_LOGWARN, pdbmfail2,
- lp->portid, BITS2WORD(pdb.pdb_portid_bits));
- goto dump_em;
- }
-
- lp->roles =
- (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
- lp->node_wwn =
- (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
- (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
- (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
- (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
- (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
- (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
- (((u_int64_t)pdb.pdb_nodename[6]) << 8) |
- (((u_int64_t)pdb.pdb_nodename[7]));
- lp->port_wwn =
- (((u_int64_t)pdb.pdb_portname[0]) << 56) |
- (((u_int64_t)pdb.pdb_portname[1]) << 48) |
- (((u_int64_t)pdb.pdb_portname[2]) << 40) |
- (((u_int64_t)pdb.pdb_portname[3]) << 32) |
- (((u_int64_t)pdb.pdb_portname[4]) << 24) |
- (((u_int64_t)pdb.pdb_portname[5]) << 16) |
- (((u_int64_t)pdb.pdb_portname[6]) << 8) |
- (((u_int64_t)pdb.pdb_portname[7]));
- /*
- * Check to make sure this all makes sense.
- */
- if (lp->node_wwn && lp->port_wwn) {
- lp->valid = 1;
- loopid = lp - fcp->portdb;
- (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
- continue;
- }
-dump_em:
- lp->valid = 0;
- isp_prt(isp, ISP_LOGINFO,
- ldumped, loopid, lp->loopid, lp->portid);
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_FABRIC_LOGOUT;
- mbs.param[1] = lp->loopid << 8;
- mbs.param[2] = 0;
- mbs.param[3] = 0;
- isp_mboxcmd(isp, &mbs, MBLOGNONE);
- if (fcp->isp_fwstate != FW_READY ||
- fcp->isp_loopstate != LOOP_SYNCING_PDB) {
- return (-1);
+ lp->reserved = 0;
+ lp->new_reserved = 0;
+ break;
+ case FC_PORTDB_STATE_ZOMBIE:
+ break;
+ default:
+ isp_prt(isp, ISP_LOGWARN,
+ "isp_scan_loop: state %d for idx %d",
+ lp->state, dbidx);
+ isp_dump_portdb(isp);
}
}
+
/*
* If we get here, we've for sure seen not only a valid loop
* but know what is or isn't on it, so mark this for usage
@@ -2117,799 +2858,969 @@ dump_em:
return (0);
}
-static int
+/*
+ * Scan local loop for devices.
+ */
+int
isp_scan_loop(struct ispsoftc *isp)
{
- struct lportdb *lp;
+ fcportdb_t *lp, tmp;
fcparam *fcp = isp->isp_param;
+ int i;
isp_pdb_t pdb;
- int loopid, lim, hival;
+ u_int16_t handle, lim = 0;
+ if (fcp->isp_fwstate < FW_READY ||
+ fcp->isp_loopstate < LOOP_PDB_RCVD) {
+ return (-1);
+ }
+
+ if (fcp->isp_loopstate > LOOP_SCANNING_LOOP) {
+ return (0);
+ }
+
+ /*
+ * Check our connection topology.
+ *
+ * If we're a public or private loop, we scan 0..125 as handle values.
+ * The firmware has (typically) peformed a PLOGI for us.
+ *
+ * If we're a N-port connection, we treat this is a short loop (0..1).
+ *
+ * If we're in target mode, we can all possible handles to see who
+ * might have logged into us.
+ */
switch (fcp->isp_topo) {
case TOPO_NL_PORT:
- hival = FL_PORT_ID;
+ case TOPO_FL_PORT:
+ lim = LOCAL_LOOP_LIM;
break;
case TOPO_N_PORT:
- hival = 2;
- break;
- case TOPO_FL_PORT:
- hival = FC_PORT_ID;
+ lim = 2;
break;
default:
+ isp_prt(isp, ISP_LOGDEBUG0, "no loop topology to scan");
fcp->isp_loopstate = LOOP_LSCAN_DONE;
return (0);
}
+
fcp->isp_loopstate = LOOP_SCANNING_LOOP;
- /*
- * make sure the temp port database is clean...
- */
- MEMZERO((void *)fcp->tport, sizeof (fcp->tport));
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC scan loop 0..%d", lim-1);
+
/*
- * Run through the local loop ports and get port database info
- * for each loop ID.
- *
- * There's a somewhat unexplained situation where the f/w passes back
- * the wrong database entity- if that happens, just restart (up to
- * FL_PORT_ID times).
+ * Run through the list and get the port database info for each one.
*/
- for (lim = loopid = 0; loopid < hival; loopid++) {
- lp = &fcp->tport[loopid];
-
+ for (handle = 0; handle < lim; handle++) {
/*
- * Don't even try for ourselves...
+ * But don't even try for ourselves...
*/
- if (loopid == fcp->isp_loopid)
+ if (handle == fcp->isp_loopid) {
continue;
+ }
- lp->node_wwn = isp_get_portname(isp, loopid, 1);
- if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
- return (-1);
- if (lp->node_wwn == 0)
- continue;
- lp->port_wwn = isp_get_portname(isp, loopid, 0);
- if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
- return (-1);
- if (lp->port_wwn == 0) {
- lp->node_wwn = 0;
- continue;
+ /*
+ * In older cards with older f/w GET_PORT_DATABASE has been
+ * known to hang. This trick gets around that problem.
+ */
+ if (IS_2100(isp) || IS_2200(isp)) {
+ u_int64_t node_wwn = isp_get_portname(isp, handle, 1);
+ if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
+ return (-1);
+ }
+ if (node_wwn == 0) {
+ continue;
+ }
}
/*
- * Get an entry....
+ * Get the port database entity for this index.
*/
- if (isp_getpdb(isp, loopid, &pdb) != 0) {
- if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
+ if (isp_getpdb(isp, handle, &pdb, 1) != 0) {
+ if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
+ ISP_MARK_PORTDB(isp, 1);
return (-1);
+ }
continue;
}
+
if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
+ ISP_MARK_PORTDB(isp, 1);
return (-1);
}
/*
- * If the returned database element doesn't match what we
- * asked for, restart the process entirely (up to a point...).
+ * On *very* old 2100 firmware we would end up sometimes
+ * with the firmware returning the port database entry
+ * for something else. We used to restart this, but
+ * now we just punt.
*/
- if (pdb.pdb_loopid != loopid) {
- loopid = 0;
- if (lim++ < hival) {
- continue;
- }
+ if (IS_2100(isp) && pdb.handle != handle) {
isp_prt(isp, ISP_LOGWARN,
"giving up on synchronizing the port database");
+ ISP_MARK_PORTDB(isp, 1);
return (-1);
}
/*
* Save the pertinent info locally.
*/
- lp->node_wwn =
- (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
- (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
- (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
- (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
- (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
- (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
- (((u_int64_t)pdb.pdb_nodename[6]) << 8) |
- (((u_int64_t)pdb.pdb_nodename[7]));
- lp->port_wwn =
- (((u_int64_t)pdb.pdb_portname[0]) << 56) |
- (((u_int64_t)pdb.pdb_portname[1]) << 48) |
- (((u_int64_t)pdb.pdb_portname[2]) << 40) |
- (((u_int64_t)pdb.pdb_portname[3]) << 32) |
- (((u_int64_t)pdb.pdb_portname[4]) << 24) |
- (((u_int64_t)pdb.pdb_portname[5]) << 16) |
- (((u_int64_t)pdb.pdb_portname[6]) << 8) |
- (((u_int64_t)pdb.pdb_portname[7]));
- lp->roles =
- (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
- lp->portid = BITS2WORD(pdb.pdb_portid_bits);
- lp->loopid = pdb.pdb_loopid;
- }
-
- /*
- * Mark all of the permanent local loop database entries as invalid
- * (except our own entry).
- */
- for (loopid = 0; loopid < hival; loopid++) {
- if (loopid == fcp->isp_iid) {
- fcp->portdb[loopid].valid = 1;
- fcp->portdb[loopid].loopid = fcp->isp_loopid;
- continue;
- }
- fcp->portdb[loopid].valid = 0;
- }
-
- /*
- * Now merge our local copy of the port database into our saved copy.
- * Notify the outer layers of new devices arriving.
- */
- for (loopid = 0; loopid < hival; loopid++) {
- int i;
-
- /*
- * If we don't have a non-zero Port WWN, we're not here.
- */
- if (fcp->tport[loopid].port_wwn == 0) {
- continue;
- }
+ MAKE_WWN_FROM_NODE_NAME(tmp.node_wwn, pdb.nodename);
+ MAKE_WWN_FROM_NODE_NAME(tmp.port_wwn, pdb.portname);
+ tmp.roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
+ tmp.portid = pdb.portid;
+ tmp.handle = pdb.handle;
/*
- * Skip ourselves.
+ * Check to make sure it's still a valid entry. The 24XX seems
+ * to return a portid but not a WWPN/WWNN or role for devices
+ * which shift on a loop.
*/
- if (loopid == fcp->isp_iid) {
+ if (tmp.node_wwn == 0 || tmp.port_wwn == 0 || tmp.portid == 0) {
+ int a, b, c;
+ a = (tmp.node_wwn == 0);
+ b = (tmp.port_wwn == 0);
+ c = (tmp.portid == 0);
+ isp_prt(isp, ISP_LOGWARN,
+ "bad pdb (%1d%1d%1d) @ handle 0x%x", a, b, c,
+ handle);
+ isp_dump_portdb(isp);
continue;
}
/*
- * For the purposes of deciding whether this is the
- * 'same' device or not, we only search for an identical
- * Port WWN. Node WWNs may or may not be the same as
- * the Port WWN, and there may be multiple different
- * Port WWNs with the same Node WWN. It would be chaos
- * to have multiple identical Port WWNs, so we don't
- * allow that.
+ * Now search the entire port database
+ * for the same Port and Node WWN.
*/
-
- for (i = 0; i < hival; i++) {
- int j;
- if (fcp->portdb[i].port_wwn == 0)
+ for (i = 0; i < MAX_FC_TARG; i++) {
+ lp = &fcp->portdb[i];
+ if (lp->state == FC_PORTDB_STATE_NIL) {
continue;
- if (fcp->portdb[i].port_wwn !=
- fcp->tport[loopid].port_wwn)
+ }
+ if (lp->node_wwn != tmp.node_wwn) {
+ continue;
+ }
+ if (lp->port_wwn != tmp.port_wwn) {
continue;
+ }
+
/*
- * We found this WWN elsewhere- it's changed
- * loopids then. We don't change its actual
- * position in our cached port database- we
- * just change the actual loop ID we'd use.
+ * Okay- we've found a non-nil entry that matches.
+ * Check to make sure it's probational or a zombie.
*/
- if (fcp->portdb[i].loopid != loopid) {
- isp_prt(isp, ISP_LOGINFO, portshift, i,
- fcp->portdb[i].loopid,
- fcp->portdb[i].portid, loopid,
- fcp->tport[loopid].portid);
+ if (lp->state != FC_PORTDB_STATE_PROBATIONAL &&
+ lp->state != FC_PORTDB_STATE_ZOMBIE) {
+ isp_prt(isp, ISP_LOGERR,
+ "[%d] not probational/zombie (0x%x)",
+ i, lp->state);
+ isp_dump_portdb(isp);
+ ISP_MARK_PORTDB(isp, 1);
+ return (-1);
}
- fcp->portdb[i].portid = fcp->tport[loopid].portid;
- fcp->portdb[i].loopid = loopid;
- fcp->portdb[i].valid = 1;
- fcp->portdb[i].roles = fcp->tport[loopid].roles;
/*
- * Now make sure this Port WWN doesn't exist elsewhere
- * in the port database.
+ * Mark the device as something the f/w logs into
+ * automatically.
*/
- for (j = i+1; j < hival; j++) {
- if (fcp->portdb[i].port_wwn !=
- fcp->portdb[j].port_wwn) {
- continue;
- }
- isp_prt(isp, ISP_LOGWARN, portdup, j, i);
- /*
- * Invalidate the 'old' *and* 'new' ones.
- * This is really harsh and not quite right,
- * but if this happens, we really don't know
- * who is what at this point.
- */
- fcp->portdb[i].valid = 0;
- fcp->portdb[j].valid = 0;
+ lp->autologin = 1;
+
+ /*
+ * Check to make see if really still the same
+ * device. If it is, we mark it pending valid.
+ */
+ if (lp->portid == tmp.portid &&
+ lp->handle == tmp.handle &&
+ lp->roles == tmp.roles) {
+ lp->new_portid = tmp.portid;
+ lp->new_roles = tmp.roles;
+ lp->state = FC_PORTDB_STATE_PENDING_VALID;
+ isp_prt(isp, ISP_LOGSANCFG,
+ "Loop Port 0x%02x@0x%x Pending Valid",
+ tmp.portid, tmp.handle);
+ break;
}
+
+ /*
+ * We can wipe out the old handle value
+ * here because it's no longer valid.
+ */
+ lp->handle = tmp.handle;
+
+ /*
+ * Claim that this has changed and let somebody else
+ * decide what to do.
+ */
+ isp_prt(isp, ISP_LOGSANCFG,
+ "Loop Port 0x%02x@0x%x changed",
+ tmp.portid, tmp.handle);
+ lp->state = FC_PORTDB_STATE_CHANGED;
+ lp->new_portid = tmp.portid;
+ lp->new_roles = tmp.roles;
break;
}
/*
- * If we didn't traverse the entire port database,
- * then we found (and remapped) an existing entry.
- * No need to notify anyone- go for the next one.
+ * Did we find and update an old entry?
*/
- if (i < hival) {
- isp_prt(isp, ISP_LOGINFO, retained,
- fcp->portdb[i].loopid, i, fcp->portdb[i].portid);
+ if (i < MAX_FC_TARG) {
continue;
}
/*
- * We've not found this Port WWN anywhere. It's a new entry.
- * See if we can leave it where it is (with target == loopid).
+ * Ah. A new device entry. Find an empty slot
+ * for it and save info for later disposition.
*/
- if (fcp->portdb[loopid].port_wwn != 0) {
- for (lim = 0; lim < hival; lim++) {
- if (fcp->portdb[lim].port_wwn == 0)
- break;
- }
- /* "Cannot Happen" */
- if (lim == hival) {
- isp_prt(isp, ISP_LOGWARN, "Remap Overflow");
- continue;
+ for (i = 0; i < MAX_FC_TARG; i++) {
+ if (fcp->portdb[i].state == FC_PORTDB_STATE_NIL) {
+ break;
}
- i = lim;
- } else {
- i = loopid;
}
-
- /*
- * NB: The actual loopid we use here is loopid- we may
- * in fact be at a completely different index (target).
- */
- fcp->portdb[i].loopid = loopid;
- fcp->portdb[i].port_wwn = fcp->tport[loopid].port_wwn;
- fcp->portdb[i].node_wwn = fcp->tport[loopid].node_wwn;
- fcp->portdb[i].roles = fcp->tport[loopid].roles;
- fcp->portdb[i].portid = fcp->tport[loopid].portid;
- fcp->portdb[i].valid = 1;
-
- /*
- * Tell the outside world we've arrived.
- */
- (void) isp_async(isp, ISPASYNC_PROMENADE, &i);
- }
-
- /*
- * Now find all previously used targets that are now invalid and
- * notify the outer layers that they're gone.
- */
- for (lp = &fcp->portdb[0]; lp < &fcp->portdb[hival]; lp++) {
- if (lp->valid || lp->port_wwn == 0) {
+ if (i == MAX_FC_TARG) {
+ isp_prt(isp, ISP_LOGERR, "out of portdb entries");
continue;
}
+ lp = &fcp->portdb[i];
- /*
- * Tell the outside world we've gone
- * away and erase our pdb entry.
- *
- */
- loopid = lp - fcp->portdb;
- (void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
- MEMZERO((void *) lp, sizeof (*lp));
+ MEMZERO(lp, sizeof (fcportdb_t));
+ lp->autologin = 1;
+ lp->state = FC_PORTDB_STATE_NEW;
+ lp->new_portid = tmp.portid;
+ lp->new_roles = tmp.roles;
+ lp->handle = tmp.handle;
+ lp->port_wwn = tmp.port_wwn;
+ lp->node_wwn = tmp.node_wwn;
+ isp_prt(isp, ISP_LOGSANCFG,
+ "Loop Port 0x%02x@0x%x is New Entry",
+ tmp.portid, tmp.handle);
}
fcp->isp_loopstate = LOOP_LSCAN_DONE;
return (0);
}
+/*
+ * Scan the fabric for devices and add them to our port database.
+ *
+ * Use the GID_FT command to get all Port IDs for FC4 SCSI devices it knows.
+ *
+ * For 2100-23XX cards, we can use the SNS mailbox command to pass simple
+ * name server commands to the switch management server via the QLogic f/w.
+ *
+ * For the 24XX card, we have to use CT-Pass through run via the Execute IOCB
+ * mailbox command.
+ *
+ * The net result is to leave the list of Port IDs setting untranslated in
+ * offset IGPOFF of the FC scratch area, whereupon we'll canonicalize it to
+ * host order at OGPOFF.
+ */
+
+/*
+ * Take less than half of our scratch area to store Port IDs
+ */
+#define GIDLEN ((ISP2100_SCRLEN >> 1) - 16 - SNS_GID_FT_REQ_SIZE)
+#define NGENT ((GIDLEN - 16) >> 2)
+
+#define IGPOFF (2 * QENTRY_LEN)
+#define OGPOFF (ISP2100_SCRLEN >> 1)
+#define ZTXOFF (ISP2100_SCRLEN - (1 * QENTRY_LEN))
+#define CTXOFF (ISP2100_SCRLEN - (2 * QENTRY_LEN))
+#define XTXOFF (ISP2100_SCRLEN - (3 * QENTRY_LEN))
-static int
-isp_fabric_mbox_cmd(struct ispsoftc *isp, mbreg_t *mbp)
+int
+isp_gid_ft_sns(struct ispsoftc *isp)
{
- /* the caller sets up the mailbox */
- isp_mboxcmd(isp, mbp, MBLOGNONE);
- if (mbp->param[0] != MBOX_COMMAND_COMPLETE) {
- if (FCPARAM(isp)->isp_loopstate == LOOP_SCANNING_FABRIC) {
- FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
- }
- if (mbp->param[0] == MBOX_COMMAND_ERROR) {
- char tbuf[16];
- char *m;
- switch (mbp->param[1]) {
- case 1:
- m = "No Loop";
- break;
- case 2:
- m = "Failed to allocate IOCB buffer";
- break;
- case 3:
- m = "Failed to allocate XCB buffer";
- break;
- case 4:
- m = "timeout or transmit failed";
- break;
- case 5:
- m = "no fabric loop";
- break;
- case 6:
- m = "remote device not a target";
- break;
- default:
- SNPRINTF(tbuf, sizeof tbuf, "%x",
- mbp->param[1]);
- m = tbuf;
- break;
- }
- isp_prt(isp, ISP_LOGERR, "SNS Failed- %s", m);
- }
- return (-1);
- }
+ union {
+ sns_gid_ft_req_t _x;
+ u_int8_t _y[SNS_GID_FT_REQ_SIZE];
+ } un;
+ fcparam *fcp = FCPARAM(isp);
+ sns_gid_ft_req_t *rq = &un._x;
+ mbreg_t mbs;
- if (FCPARAM(isp)->isp_fwstate != FW_READY ||
- FCPARAM(isp)->isp_loopstate < LOOP_SCANNING_FABRIC) {
- return (-1);
+ isp_prt(isp, ISP_LOGDEBUG0, "scanning fabric (GID_FT) via SNS");
+
+ MEMZERO(rq, SNS_GID_FT_REQ_SIZE);
+ rq->snscb_rblen = GIDLEN >> 1;
+ rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + IGPOFF);
+ rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + IGPOFF);
+ rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + IGPOFF);
+ rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + IGPOFF);
+ rq->snscb_sblen = 6;
+ rq->snscb_cmd = SNS_GID_FT;
+ rq->snscb_mword_div_2 = NGENT;
+ rq->snscb_fc4_type = FC4_SCSI;
+
+ isp_put_gid_ft_request(isp, rq, fcp->isp_scratch);
+ MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE);
+
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_SEND_SNS;
+ mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
+ mbs.param[2] = DMA_WD1(fcp->isp_scdma);
+ mbs.param[3] = DMA_WD0(fcp->isp_scdma);
+ mbs.param[6] = DMA_WD3(fcp->isp_scdma);
+ mbs.param[7] = DMA_WD2(fcp->isp_scdma);
+ mbs.logval = MBLOGALL;
+ mbs.timeout = 10000000;
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ if (mbs.param[0] == MBOX_INVALID_COMMAND) {
+ return (1);
+ } else {
+ return (-1);
+ }
}
- return(0);
+ return (0);
}
-#ifdef ISP_USE_GA_NXT
-static int
-isp_scan_fabric(struct ispsoftc *isp, int ftype)
+int
+isp_gid_ft_ct_passthru(struct ispsoftc *isp)
{
- fcparam *fcp = isp->isp_param;
- u_int32_t portid, first_portid, last_portid;
- int hicap, last_port_same;
-
- if (fcp->isp_onfabric == 0) {
- fcp->isp_loopstate = LOOP_FSCAN_DONE;
- return (0);
+ mbreg_t mbs;
+ fcparam *fcp = FCPARAM(isp);
+ union {
+ isp_ct_pt_t plocal;
+ ct_hdr_t clocal;
+ u_int8_t q[QENTRY_LEN];
+ } un;
+ isp_ct_pt_t *pt;
+ ct_hdr_t *ct;
+ u_int32_t *rp;
+ u_int8_t *scp = fcp->isp_scratch;
+
+ isp_prt(isp, ISP_LOGDEBUG0, "scanning fabric (GID_FT) via CT");
+
+ if (!IS_24XX(isp)) {
+ return (1);
}
- FC_SCRATCH_ACQUIRE(isp);
-
/*
- * Since Port IDs are 24 bits, we can check against having seen
- * anything yet with this value.
+ * Build a Passthrough IOCB in memory.
*/
- last_port_same = 0;
- last_portid = 0xffffffff; /* not a port */
- first_portid = portid = fcp->isp_portid;
- fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
-
- for (hicap = 0; hicap < GA_NXT_MAX; hicap++) {
- mbreg_t mbs;
- sns_screq_t *rq;
- sns_ga_nxt_rsp_t *rs0, *rs1;
- struct lportdb lcl;
- u_int8_t sc[SNS_GA_NXT_RESP_SIZE];
-
- rq = (sns_screq_t *)sc;
- MEMZERO((void *) rq, SNS_GA_NXT_REQ_SIZE);
- rq->snscb_rblen = SNS_GA_NXT_RESP_SIZE >> 1;
- rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+0x100);
- rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+0x100);
- rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+0x100);
- rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+0x100);
- rq->snscb_sblen = 6;
- rq->snscb_data[0] = SNS_GA_NXT;
- rq->snscb_data[4] = portid & 0xffff;
- rq->snscb_data[5] = (portid >> 16) & 0xff;
- isp_put_sns_request(isp, rq, (sns_screq_t *) fcp->isp_scratch);
- MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GA_NXT_REQ_SIZE);
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SEND_SNS;
- mbs.param[1] = SNS_GA_NXT_REQ_SIZE >> 1;
- mbs.param[2] = DMA_WD1(fcp->isp_scdma);
- mbs.param[3] = DMA_WD0(fcp->isp_scdma);
- /*
- * Leave 4 and 5 alone
- */
- mbs.param[6] = DMA_WD3(fcp->isp_scdma);
- mbs.param[7] = DMA_WD2(fcp->isp_scdma);
- if (isp_fabric_mbox_cmd(isp, &mbs)) {
- if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
- fcp->isp_loopstate = LOOP_PDB_RCVD;
- }
- FC_SCRATCH_RELEASE(isp);
- return (-1);
- }
- MEMORYBARRIER(isp, SYNC_SFORCPU, 0x100, SNS_GA_NXT_RESP_SIZE);
- rs1 = (sns_ga_nxt_rsp_t *) sc;
- rs0 = (sns_ga_nxt_rsp_t *) ((u_int8_t *)fcp->isp_scratch+0x100);
- isp_get_ga_nxt_response(isp, rs0, rs1);
- if (rs1->snscb_cthdr.ct_response != FS_ACC) {
- int level;
- if (rs1->snscb_cthdr.ct_reason == 9 &&
- rs1->snscb_cthdr.ct_explanation == 7)
- level = ISP_LOGDEBUG0;
- else
- level = ISP_LOGWARN;
- isp_prt(isp, level, swrej, "GA_NXT",
- rs1->snscb_cthdr.ct_reason,
- rs1->snscb_cthdr.ct_explanation, portid);
- FC_SCRATCH_RELEASE(isp);
- fcp->isp_loopstate = LOOP_FSCAN_DONE;
- return (0);
- }
- portid =
- (((u_int32_t) rs1->snscb_port_id[0]) << 16) |
- (((u_int32_t) rs1->snscb_port_id[1]) << 8) |
- (((u_int32_t) rs1->snscb_port_id[2]));
+ pt = &un.plocal;
+ MEMZERO(un.q, QENTRY_LEN);
+ pt->ctp_header.rqs_entry_count = 1;
+ pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
+ pt->ctp_handle = 0xffffffff;
+ pt->ctp_nphdl = NPH_SNS_ID;
+ pt->ctp_cmd_cnt = 1;
+ pt->ctp_time = 30;
+ pt->ctp_rsp_cnt = 1;
+ pt->ctp_rsp_bcnt = GIDLEN;
+ pt->ctp_cmd_bcnt = sizeof (*ct) + sizeof (u_int32_t);
+ pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
+ pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
+ pt->ctp_dataseg[0].ds_count = sizeof (*ct) + sizeof (u_int32_t);
+ pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
+ pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
+ pt->ctp_dataseg[1].ds_count = GIDLEN;
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp, "ct IOCB", QENTRY_LEN, pt);
+ }
+ isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
- /*
- * XXX: We should check to make sure that this entry
- * XXX: supports the type(s) we are interested in.
- */
- /*
- * Okay, we now have information about a fabric object.
- * If it is the type we're interested in, tell the outer layers
- * about it. The outer layer needs to know: Port ID, WWNN,
- * WWPN, FC4 type, and port type.
- *
- * The lportdb structure is adequate for this.
- */
- MEMZERO(&lcl, sizeof (lcl));
- lcl.port_type = rs1->snscb_port_type;
- lcl.fc4_type = ftype;
- lcl.portid = portid;
- lcl.node_wwn =
- (((u_int64_t)rs1->snscb_nodename[0]) << 56) |
- (((u_int64_t)rs1->snscb_nodename[1]) << 48) |
- (((u_int64_t)rs1->snscb_nodename[2]) << 40) |
- (((u_int64_t)rs1->snscb_nodename[3]) << 32) |
- (((u_int64_t)rs1->snscb_nodename[4]) << 24) |
- (((u_int64_t)rs1->snscb_nodename[5]) << 16) |
- (((u_int64_t)rs1->snscb_nodename[6]) << 8) |
- (((u_int64_t)rs1->snscb_nodename[7]));
- lcl.port_wwn =
- (((u_int64_t)rs1->snscb_portname[0]) << 56) |
- (((u_int64_t)rs1->snscb_portname[1]) << 48) |
- (((u_int64_t)rs1->snscb_portname[2]) << 40) |
- (((u_int64_t)rs1->snscb_portname[3]) << 32) |
- (((u_int64_t)rs1->snscb_portname[4]) << 24) |
- (((u_int64_t)rs1->snscb_portname[5]) << 16) |
- (((u_int64_t)rs1->snscb_portname[6]) << 8) |
- (((u_int64_t)rs1->snscb_portname[7]));
+ /*
+ * Build the CT header and command in memory.
+ *
+ * Note that the CT header has to end up as Big Endian format in memory.
+ */
+ ct = &un.clocal;
+ MEMZERO(ct, sizeof (*ct));
+ ct->ct_revision = CT_REVISION;
+ ct->ct_fcs_type = CT_FC_TYPE_FC;
+ ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
+ ct->ct_cmd_resp = SNS_GID_FT;
+ ct->ct_bcnt_resid = (GIDLEN - 16) >> 2;
+
+ isp_put_ct_hdr(isp, ct, (ct_hdr_t *) &scp[XTXOFF]);
+ rp = (u_int32_t *) &scp[XTXOFF+sizeof (*ct)];
+ ISP_IOZPUT_32(isp, FC4_SCSI, rp);
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp, "CT HDR + payload after put",
+ sizeof (*ct) + sizeof (u_int32_t), &scp[XTXOFF]);
+ }
+ MEMZERO(&scp[ZTXOFF], QENTRY_LEN);
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
+ mbs.param[1] = QENTRY_LEN;
+ mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
+ mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
+ mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
+ mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
+ mbs.timeout = 500000;
+ mbs.logval = MBLOGALL;
+ MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN);
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ return (-1);
+ }
+ MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN);
+ pt = &un.plocal;
+ isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
+ }
- /*
- * Does this fabric object support the type we want?
- * If not, skip it.
- */
- if (rs1->snscb_fc4_types[ftype >> 5] & (1 << (ftype & 0x1f))) {
- if (first_portid == portid) {
- lcl.last_fabric_dev = 1;
- } else {
- lcl.last_fabric_dev = 0;
- }
- (void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
- } else {
- isp_prt(isp, ISP_LOGDEBUG0,
- "PortID 0x%x doesn't support FC4 type 0x%x",
- portid, ftype);
- }
- if (first_portid == portid) {
- fcp->isp_loopstate = LOOP_FSCAN_DONE;
- FC_SCRATCH_RELEASE(isp);
- return (0);
- }
- if (portid == last_portid) {
- if (last_port_same++ > 20) {
- isp_prt(isp, ISP_LOGWARN,
- "tangled fabric database detected");
- break;
- }
- } else {
- last_port_same = 0 ;
- last_portid = portid;
- }
+ if (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) {
+ isp_prt(isp, ISP_LOGWARN, "CT Passthrough returned 0x%x",
+ pt->ctp_status);
+ return (-1);
}
- FC_SCRATCH_RELEASE(isp);
- if (hicap >= GA_NXT_MAX) {
- isp_prt(isp, ISP_LOGWARN, "fabric too big (> %d)", GA_NXT_MAX);
+ MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN + 16);
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp, "CT response", GIDLEN+16, &scp[IGPOFF]);
}
- fcp->isp_loopstate = LOOP_FSCAN_DONE;
return (0);
}
-#else
-#define GIDLEN ((ISP2100_SCRLEN >> 1) + 16)
-#define NGENT ((GIDLEN - 16) >> 2)
-
-#define IGPOFF (ISP2100_SCRLEN - GIDLEN)
-#define GXOFF (256)
-static int
-isp_scan_fabric(struct ispsoftc *isp, int ftype)
+int
+isp_scan_fabric(struct ispsoftc *isp)
{
fcparam *fcp = FCPARAM(isp);
- mbreg_t mbs;
- int i;
- sns_gid_ft_req_t *rq;
+ u_int32_t portid;
+ u_int16_t handle, oldhandle;
+ int portidx, portlim, r;
sns_gid_ft_rsp_t *rs0, *rs1;
- if (fcp->isp_onfabric == 0) {
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC Scan Fabric");
+ if (fcp->isp_fwstate != FW_READY ||
+ fcp->isp_loopstate < LOOP_LSCAN_DONE) {
+ return (-1);
+ }
+ if (fcp->isp_loopstate > LOOP_SCANNING_FABRIC) {
+ return (0);
+ }
+ if (fcp->isp_topo != TOPO_FL_PORT && fcp->isp_topo != TOPO_F_PORT) {
fcp->isp_loopstate = LOOP_FSCAN_DONE;
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "FC Scan Fabric Done (no fabric)");
return (0);
}
FC_SCRATCH_ACQUIRE(isp);
fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
- rq = (sns_gid_ft_req_t *)fcp->tport;
- MEMZERO((void *) rq, SNS_GID_FT_REQ_SIZE);
- rq->snscb_rblen = GIDLEN >> 1;
- rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+IGPOFF);
- rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+IGPOFF);
- rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+IGPOFF);
- rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+IGPOFF);
- rq->snscb_sblen = 6;
- rq->snscb_cmd = SNS_GID_FT;
- rq->snscb_mword_div_2 = NGENT;
- rq->snscb_fc4_type = ftype;
- isp_put_gid_ft_request(isp, rq, (sns_gid_ft_req_t *) fcp->isp_scratch);
- MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE);
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SEND_SNS;
- mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
- mbs.param[2] = DMA_WD1(fcp->isp_scdma);
- mbs.param[3] = DMA_WD0(fcp->isp_scdma);
+ if (IS_24XX(isp)) {
+ r = isp_gid_ft_ct_passthru(isp);
+ } else {
+ r = isp_gid_ft_sns(isp);
+ }
- /*
- * Leave 4 and 5 alone
- */
- mbs.param[6] = DMA_WD3(fcp->isp_scdma);
- mbs.param[7] = DMA_WD2(fcp->isp_scdma);
- if (isp_fabric_mbox_cmd(isp, &mbs)) {
- if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
- fcp->isp_loopstate = LOOP_PDB_RCVD;
- }
+ if (r > 0) {
+ fcp->isp_loopstate = LOOP_FSCAN_DONE;
FC_SCRATCH_RELEASE(isp);
- return (-1);
+ return (0);
+ } else if (r < 0) {
+ fcp->isp_loopstate = LOOP_PDB_RCVD; /* try again */
+ FC_SCRATCH_RELEASE(isp);
+ return (0);
}
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
FC_SCRATCH_RELEASE(isp);
return (-1);
}
+
MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN);
- rs1 = (sns_gid_ft_rsp_t *) fcp->tport;
rs0 = (sns_gid_ft_rsp_t *) ((u_int8_t *)fcp->isp_scratch+IGPOFF);
+ rs1 = (sns_gid_ft_rsp_t *) ((u_int8_t *)fcp->isp_scratch+OGPOFF);
isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
- if (rs1->snscb_cthdr.ct_response != FS_ACC) {
+ if (rs1->snscb_cthdr.ct_cmd_resp != LS_ACC) {
int level;
if (rs1->snscb_cthdr.ct_reason == 9 &&
- rs1->snscb_cthdr.ct_explanation == 7)
- level = ISP_LOGDEBUG0;
- else
+ rs1->snscb_cthdr.ct_explanation == 7) {
+ level = ISP_LOGSANCFG|ISP_LOGDEBUG0;
+ } else {
level = ISP_LOGWARN;
- isp_prt(isp, level, swrej, "GID_FT",
- rs1->snscb_cthdr.ct_reason,
- rs1->snscb_cthdr.ct_explanation, 0);
+ }
+ isp_prt(isp, level, "Fabric Nameserver rejected GID_FT "
+ "(Reason=0x%x Expl=0x%x)", rs1->snscb_cthdr.ct_reason,
+ rs1->snscb_cthdr.ct_explanation);
FC_SCRATCH_RELEASE(isp);
fcp->isp_loopstate = LOOP_FSCAN_DONE;
return (0);
}
+
/*
- * Okay, we now have a list of Port IDs for this class of device.
- * Go through the list and for each one get the WWPN/WWNN for it
- * and tell the outer layers about it. The outer layer needs to
- * know: Port ID, WWNN, WWPN, FC4 type, and (possibly) port type.
+ * If we get this far, we certainly still have the fabric controller.
+ */
+ fcp->portdb[FL_ID].state = FC_PORTDB_STATE_PENDING_VALID;
+
+ /*
+ * Prime the handle we will start using.
+ */
+ oldhandle = NIL_HANDLE;
+
+ /*
+ * Okay, we now have a list of Port IDs for all FC4 SCSI devices
+ * that the Fabric Name server knows about. Go through the list
+ * and remove duplicate port ids.
+ */
+
+ portlim = 0;
+ portidx = 0;
+ for (portidx = 0; portidx < NGENT-1; portidx++) {
+ if (rs1->snscb_ports[portidx].control & 0x80) {
+ break;
+ }
+ }
+
+ /*
+ * If we're not at the last entry, our list wasn't big enough.
+ */
+ if ((rs1->snscb_ports[portidx].control & 0x80) == 0) {
+ isp_prt(isp, ISP_LOGWARN,
+ "fabric too big for scratch area: increase ISP2100_SCRLEN");
+ }
+ portlim = portidx + 1;
+ isp_prt(isp, ISP_LOGSANCFG,
+ "got %d ports back from name server", portlim);
+
+ for (portidx = 0; portidx < portlim; portidx++) {
+ int npidx;
+
+ portid =
+ ((rs1->snscb_ports[portidx].portid[0]) << 16) |
+ ((rs1->snscb_ports[portidx].portid[1]) << 8) |
+ ((rs1->snscb_ports[portidx].portid[2]));
+
+ for (npidx = portidx + 1; npidx < portlim; npidx++) {
+ u_int32_t new_portid =
+ ((rs1->snscb_ports[npidx].portid[0]) << 16) |
+ ((rs1->snscb_ports[npidx].portid[1]) << 8) |
+ ((rs1->snscb_ports[npidx].portid[2]));
+ if (new_portid == portid) {
+ break;
+ }
+ }
+
+ if (npidx < portlim) {
+ rs1->snscb_ports[npidx].portid[0] = 0;
+ rs1->snscb_ports[npidx].portid[1] = 0;
+ rs1->snscb_ports[npidx].portid[2] = 0;
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "removing duplicate PortID 0x%x entry from list",
+ portid);
+ }
+ }
+
+ /*
+ * Okay, we now have a list of Port IDs for all FC4 SCSI devices
+ * that the Fabric Name server knows about.
+ *
+ * For each entry on this list go through our port database looking
+ * for probational entries- if we find one, then an old entry is
+ * is maybe still this one. We get some information to find out.
*
- * The lportdb structure is adequate for this.
+ * Otherwise, it's a new fabric device, and we log into it
+ * (unconditionally). After searching the entire database
+ * again to make sure that we never ever ever ever have more
+ * than one entry that has the same PortID or the same
+ * WWNN/WWPN duple, we enter the device into our database.
*/
- i = -1;
- do {
- sns_gxn_id_req_t grqbuf, *gq = &grqbuf;
- sns_gxn_id_rsp_t *gs0, grsbuf, *gs1 = &grsbuf;
- struct lportdb lcl;
-#if 0
- sns_gff_id_rsp_t *fs0, ffsbuf, *fs1 = &ffsbuf;
-#endif
- i++;
- MEMZERO(&lcl, sizeof (lcl));
- lcl.fc4_type = ftype;
- lcl.portid =
- (((u_int32_t) rs1->snscb_ports[i].portid[0]) << 16) |
- (((u_int32_t) rs1->snscb_ports[i].portid[1]) << 8) |
- (((u_int32_t) rs1->snscb_ports[i].portid[2]));
-
- MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
- gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
- gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
- gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
- gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
- gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
- gq->snscb_sblen = 6;
- gq->snscb_cmd = SNS_GPN_ID;
- gq->snscb_portid = lcl.portid;
- isp_put_gxn_id_request(isp, gq,
- (sns_gxn_id_req_t *) fcp->isp_scratch);
- MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SEND_SNS;
- mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
- mbs.param[2] = DMA_WD1(fcp->isp_scdma);
- mbs.param[3] = DMA_WD0(fcp->isp_scdma);
+ for (portidx = 0; portidx < portlim; portidx++) {
+ fcportdb_t *lp;
+ isp_pdb_t pdb;
+ u_int64_t wwnn, wwpn;
+ int dbidx, nr;
+
+ portid =
+ ((rs1->snscb_ports[portidx].portid[0]) << 16) |
+ ((rs1->snscb_ports[portidx].portid[1]) << 8) |
+ ((rs1->snscb_ports[portidx].portid[2]));
+
+ if (portid == 0) {
+ isp_prt(isp, ISP_LOGSANCFG,
+ "skipping null PortID at idx %d", portidx);
+ continue;
+ }
+
/*
- * Leave 4 and 5 alone
+ * Skip ourselves...
*/
- mbs.param[6] = DMA_WD3(fcp->isp_scdma);
- mbs.param[7] = DMA_WD2(fcp->isp_scdma);
- if (isp_fabric_mbox_cmd(isp, &mbs)) {
- if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
- fcp->isp_loopstate = LOOP_PDB_RCVD;
- }
- FC_SCRATCH_RELEASE(isp);
- return (-1);
+ if (portid == fcp->isp_portid) {
+ isp_prt(isp, ISP_LOGSANCFG,
+ "skip ourselves @ PortID 0x%06x", portid);
+ continue;
}
- if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
- FC_SCRATCH_RELEASE(isp);
- return (-1);
+ isp_prt(isp, ISP_LOGSANCFG,
+ "Checking Fabric Port 0x%06x", portid);
+
+ /*
+ * We now search our Port Database for any
+ * probational entries with this PortID. We don't
+ * look for zombies here- only probational
+ * entries (we've already logged out of zombies).
+ */
+ for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
+ lp = &fcp->portdb[dbidx];
+
+ if (lp->state != FC_PORTDB_STATE_PROBATIONAL) {
+ continue;
+ }
+ if (lp->portid == portid) {
+ break;
+ }
}
- MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
- gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
- isp_get_gxn_id_response(isp, gs0, gs1);
- if (gs1->snscb_cthdr.ct_response != FS_ACC) {
- isp_prt(isp, ISP_LOGWARN, swrej, "GPN_ID",
- gs1->snscb_cthdr.ct_reason,
- gs1->snscb_cthdr.ct_explanation, lcl.portid);
+
+ /*
+ * We found a probational entry with this Port ID.
+ */
+ if (dbidx < MAX_FC_TARG) {
+ int handle_changed = 0;
+
+ lp = &fcp->portdb[dbidx];
+
+ /*
+ * See if we're still logged into it.
+ *
+ * If we aren't, mark it as a dead device and
+ * leave the new portid in the database entry
+ * for somebody further along to decide what to
+ * do (policy choice).
+ *
+ * If we are, check to see if it's the same
+ * device still (it should be). If for some
+ * reason it isn't, mark it as a changed device
+ * and leave the new portid and role in the
+ * database entry for somebody further along to
+ * decide what to do (policy choice).
+ *
+ */
+
+ r = isp_getpdb(isp, lp->handle, &pdb, 0);
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
FC_SCRATCH_RELEASE(isp);
+ ISP_MARK_PORTDB(isp, 1);
return (-1);
}
+ if (r != 0) {
+ lp->new_portid = portid;
+ lp->state = FC_PORTDB_STATE_DEAD;
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Fabric Port 0x%06x considered dead",
+ portid);
+ continue;
+ }
+
+
+ /*
+ * Check to make sure that handle, portid, WWPN and
+ * WWNN agree. If they don't, then the association
+ * between this PortID and the stated handle has been
+ * broken by the firmware.
+ */
+ MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
+ MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
+ if (pdb.handle != lp->handle ||
+ pdb.portid != portid ||
+ wwpn != lp->port_wwn ||
+ wwnn != lp->node_wwn) {
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ fconf, dbidx, pdb.handle, pdb.portid,
+ (u_int32_t) (wwnn >> 32), (u_int32_t) wwnn,
+ (u_int32_t) (wwpn >> 32), (u_int32_t) wwpn,
+ lp->handle, portid,
+ (u_int32_t) (lp->node_wwn >> 32),
+ (u_int32_t) lp->node_wwn,
+ (u_int32_t) (lp->port_wwn >> 32),
+ (u_int32_t) lp->port_wwn);
+ /*
+ * Try to re-login to this device using a
+ * new handle. If that fails, mark it dead.
+ *
+ * isp_login_device will check for handle and
+ * portid consistency after re-login.
+ *
+ */
+ if (isp_login_device(isp, portid, &pdb,
+ &oldhandle)) {
+ lp->new_portid = portid;
+ lp->state = FC_PORTDB_STATE_DEAD;
+ if (fcp->isp_loopstate !=
+ LOOP_SCANNING_FABRIC) {
+ FC_SCRATCH_RELEASE(isp);
+ ISP_MARK_PORTDB(isp, 1);
+ return (-1);
+ }
+ continue;
+ }
+ MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
+ MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
+ if (wwpn != lp->port_wwn ||
+ wwnn != lp->node_wwn) {
+ isp_prt(isp, ISP_LOGWARN, "changed WWN"
+ " after relogin");
+ lp->new_portid = portid;
+ lp->state = FC_PORTDB_STATE_DEAD;
+ continue;
+ }
+
+ lp->handle = pdb.handle;
+ handle_changed++;
+ }
+
+ nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
+
+ /*
+ * Check to see whether the portid and roles have
+ * stayed the same. If they have stayed the same,
+ * we believe that this is the same device and it
+ * hasn't become disconnected and reconnected, so
+ * mark it as pending valid.
+ *
+ * If they aren't the same, mark the device as a
+ * changed device and save the new port id and role
+ * and let somebody else decide.
+ */
+
+ lp->new_portid = portid;
+ lp->new_roles = nr;
+ if (pdb.portid != lp->portid || nr != lp->roles ||
+ handle_changed) {
+ isp_prt(isp, ISP_LOGSANCFG,
+ "Fabric Port 0x%06x changed", portid);
+ lp->state = FC_PORTDB_STATE_CHANGED;
+ } else {
+ isp_prt(isp, ISP_LOGSANCFG,
+ "Fabric Port 0x%06x Now Pending Valid",
+ portid);
+ lp->state = FC_PORTDB_STATE_PENDING_VALID;
+ }
continue;
}
- lcl.port_wwn =
- (((u_int64_t)gs1->snscb_wwn[0]) << 56) |
- (((u_int64_t)gs1->snscb_wwn[1]) << 48) |
- (((u_int64_t)gs1->snscb_wwn[2]) << 40) |
- (((u_int64_t)gs1->snscb_wwn[3]) << 32) |
- (((u_int64_t)gs1->snscb_wwn[4]) << 24) |
- (((u_int64_t)gs1->snscb_wwn[5]) << 16) |
- (((u_int64_t)gs1->snscb_wwn[6]) << 8) |
- (((u_int64_t)gs1->snscb_wwn[7]));
-
- MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
- gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
- gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
- gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
- gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
- gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
- gq->snscb_sblen = 6;
- gq->snscb_cmd = SNS_GNN_ID;
- gq->snscb_portid = lcl.portid;
- isp_put_gxn_id_request(isp, gq,
- (sns_gxn_id_req_t *) fcp->isp_scratch);
- MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SEND_SNS;
- mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
- mbs.param[2] = DMA_WD1(fcp->isp_scdma);
- mbs.param[3] = DMA_WD0(fcp->isp_scdma);
+
/*
- * Leave 4 and 5 alone
+ * Ah- a new entry. Search the database again for all non-NIL
+ * entries to make sure we never ever make a new database entry
+ * with the same port id. While we're at it, mark where the
+ * last free entry was.
*/
- mbs.param[6] = DMA_WD3(fcp->isp_scdma);
- mbs.param[7] = DMA_WD2(fcp->isp_scdma);
- if (isp_fabric_mbox_cmd(isp, &mbs)) {
- if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
- fcp->isp_loopstate = LOOP_PDB_RCVD;
+
+ dbidx = MAX_FC_TARG;
+ for (lp = fcp->portdb; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
+ if (lp >= &fcp->portdb[FL_ID] &&
+ lp <= &fcp->portdb[SNS_ID]) {
+ continue;
}
- FC_SCRATCH_RELEASE(isp);
- return (-1);
- }
- if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
- FC_SCRATCH_RELEASE(isp);
- return (-1);
- }
- MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
- gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
- isp_get_gxn_id_response(isp, gs0, gs1);
- if (gs1->snscb_cthdr.ct_response != FS_ACC) {
- isp_prt(isp, ISP_LOGWARN, swrej, "GNN_ID",
- gs1->snscb_cthdr.ct_reason,
- gs1->snscb_cthdr.ct_explanation, lcl.portid);
- if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
- FC_SCRATCH_RELEASE(isp);
- return (-1);
+ if (lp->state == FC_PORTDB_STATE_NIL) {
+ if (dbidx == MAX_FC_TARG) {
+ dbidx = lp - fcp->portdb;
+ }
+ continue;
+ }
+ if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
+ continue;
}
+ if (lp->portid == portid) {
+ break;
+ }
+ }
+
+ if (lp < &fcp->portdb[MAX_FC_TARG]) {
+ isp_prt(isp, ISP_LOGWARN,
+ "PortID 0x%06x already at %d handle %d state %d",
+ portid, dbidx, lp->handle, lp->state);
continue;
}
- lcl.node_wwn =
- (((u_int64_t)gs1->snscb_wwn[0]) << 56) |
- (((u_int64_t)gs1->snscb_wwn[1]) << 48) |
- (((u_int64_t)gs1->snscb_wwn[2]) << 40) |
- (((u_int64_t)gs1->snscb_wwn[3]) << 32) |
- (((u_int64_t)gs1->snscb_wwn[4]) << 24) |
- (((u_int64_t)gs1->snscb_wwn[5]) << 16) |
- (((u_int64_t)gs1->snscb_wwn[6]) << 8) |
- (((u_int64_t)gs1->snscb_wwn[7]));
/*
- * The QLogic f/w is bouncing this with a parameter error.
+ * We should have the index of the first free entry seen.
*/
-#if 0
+ if (dbidx == MAX_FC_TARG) {
+ isp_prt(isp, ISP_LOGERR,
+ "port database too small to login PortID 0x%06x"
+ "- increase MAX_FC_TARG", portid);
+ continue;
+ }
+
/*
- * Try and get FC4 Features (FC-GS-3 only).
- * We can use the sns_gxn_id_req_t for this request.
+ * Otherwise, point to our new home.
*/
- MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
- gq->snscb_rblen = SNS_GFF_ID_RESP_SIZE >> 1;
- gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
- gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
- gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
- gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
- gq->snscb_sblen = 6;
- gq->snscb_cmd = SNS_GFF_ID;
- gq->snscb_portid = lcl.portid;
- isp_put_gxn_id_request(isp, gq,
- (sns_gxn_id_req_t *) fcp->isp_scratch);
- MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SEND_SNS;
- mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
- mbs.param[2] = DMA_WD1(fcp->isp_scdma);
- mbs.param[3] = DMA_WD0(fcp->isp_scdma);
+ lp = &fcp->portdb[dbidx];
+
/*
- * Leave 4 and 5 alone
+ * Try to see if we are logged into this device,
+ * and maybe log into it.
+ *
+ * isp_login_device will check for handle and
+ * portid consistency after login.
*/
- mbs.param[6] = DMA_WD3(fcp->isp_scdma);
- mbs.param[7] = DMA_WD2(fcp->isp_scdma);
- if (isp_fabric_mbox_cmd(isp, &mbs)) {
- if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
- fcp->isp_loopstate = LOOP_PDB_RCVD;
- }
- FC_SCRATCH_RELEASE(isp);
- return (-1);
- }
- if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
- FC_SCRATCH_RELEASE(isp);
- return (-1);
- }
- MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GFF_ID_RESP_SIZE);
- fs0 = (sns_gff_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
- isp_get_gff_id_response(isp, fs0, fs1);
- if (fs1->snscb_cthdr.ct_response != FS_ACC) {
- isp_prt(isp, /* ISP_LOGDEBUG0 */ ISP_LOGWARN,
- swrej, "GFF_ID",
- fs1->snscb_cthdr.ct_reason,
- fs1->snscb_cthdr.ct_explanation, lcl.portid);
+ if (isp_login_device(isp, portid, &pdb, &oldhandle)) {
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
FC_SCRATCH_RELEASE(isp);
+ ISP_MARK_PORTDB(isp, 1);
return (-1);
}
- } else {
- int index = (ftype >> 3);
- int bshft = (ftype & 0x7) * 4;
- int fc4_fval =
- (fs1->snscb_fc4_features[index] >> bshft) & 0xf;
- if (fc4_fval & 0x1) {
- lcl.roles |=
- (SVC3_INI_ROLE >> SVC3_ROLE_SHIFT);
+ continue;
+ }
+
+ handle = pdb.handle;
+ MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
+ MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
+ nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
+
+ /*
+ * And go through the database *one* more time to make sure
+ * that we do not make more than one entry that has the same
+ * WWNN/WWPN duple
+ */
+ for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
+ if (dbidx >= FL_ID && dbidx <= SNS_ID) {
+ continue;
+ }
+ if (fcp->portdb[dbidx].state == FC_PORTDB_STATE_NIL) {
+ continue;
}
- if (fc4_fval & 0x2) {
- lcl.roles |=
- (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT);
+ if (fcp->portdb[dbidx].node_wwn == wwnn &&
+ fcp->portdb[dbidx].port_wwn == wwpn) {
+ break;
}
}
-#endif
+
+ if (dbidx == MAX_FC_TARG) {
+ MEMZERO(lp, sizeof (fcportdb_t));
+ lp->handle = handle;
+ lp->node_wwn = wwnn;
+ lp->port_wwn = wwpn;
+ lp->new_portid = portid;
+ lp->new_roles = nr;
+ lp->state = FC_PORTDB_STATE_NEW;
+ isp_prt(isp, ISP_LOGSANCFG,
+ "Fabric Port 0x%06x is New Entry", portid);
+ continue;
+ }
+
+ if (fcp->portdb[dbidx].state != FC_PORTDB_STATE_ZOMBIE) {
+ isp_prt(isp, ISP_LOGWARN,
+ "PortID 0x%x 0x%08x%08x/0x%08x%08x %ld already at "
+ "idx %d, state 0x%x", portid,
+ (u_int32_t) (wwnn >> 32), (u_int32_t) wwnn,
+ (u_int32_t) (wwpn >> 32), (u_int32_t) wwpn,
+ (long) (lp - fcp->portdb), dbidx,
+ fcp->portdb[dbidx].state);
+ continue;
+ }
/*
- * If we really want to know what kind of port type this is,
- * we have to run another CT command. Otherwise, we'll leave
- * it as undefined.
- *
- lcl.port_type = 0;
+ * We found a zombie entry that matches us.
+ * Revive it. We know that WWN and WWPN
+ * are the same. For fabric devices, we
+ * don't care that handle is different
+ * as we assign that. If role or portid
+ * are different, it maybe a changed device.
*/
- if (rs1->snscb_ports[i].control & 0x80) {
- lcl.last_fabric_dev = 1;
+ lp = &fcp->portdb[dbidx];
+ lp->handle = handle;
+ lp->new_portid = portid;
+ lp->new_roles = nr;
+ if (lp->portid != portid || lp->roles != nr) {
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Zombie Fabric Port 0x%06x Now Changed", portid);
+ lp->state = FC_PORTDB_STATE_CHANGED;
} else {
- lcl.last_fabric_dev = 0;
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Zombie Fabric Port 0x%06x Now Pending Valid",
+ portid);
+ lp->state = FC_PORTDB_STATE_PENDING_VALID;
}
- (void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
+ }
- } while ((rs1->snscb_ports[i].control & 0x80) == 0 && i < NGENT-1);
+ FC_SCRATCH_RELEASE(isp);
+ if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
+ ISP_MARK_PORTDB(isp, 1);
+ return (-1);
+ }
+ fcp->isp_loopstate = LOOP_FSCAN_DONE;
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC Scan Fabric Done");
+ return (0);
+}
+
+/*
+ * Find an unused handle and try and use to login to a port.
+ */
+int
+isp_login_device(struct ispsoftc *isp, u_int32_t portid, isp_pdb_t *p, u_int16_t *ohp)
+{
+ int lim, i, r;
+ u_int16_t handle;
+
+ if (FCPARAM(isp)->isp_2klogin) {
+ lim = NPH_MAX_2K;
+ } else {
+ lim = NPH_MAX;
+ }
+
+ handle = isp_nxt_handle(isp, *ohp);
+ for (i = 0; i < lim; i++) {
+ /*
+ * See if we're still logged into something with
+ * this handle and that something agrees with this
+ * port id.
+ */
+ r = isp_getpdb(isp, handle, p, 0);
+ if (r == 0 && p->portid != portid) {
+ (void) isp_plogx(isp, handle, portid,
+ PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT, 1);
+ } else if (r == 0) {
+ break;
+ }
+ if (FCPARAM(isp)->isp_loopstate != LOOP_SCANNING_FABRIC) {
+ return (-1);
+ }
+ /*
+ * Now try and log into the device
+ */
+ r = isp_plogx(isp, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
+ if (FCPARAM(isp)->isp_loopstate != LOOP_SCANNING_FABRIC) {
+ return (-1);
+ }
+ if (r == 0) {
+ *ohp = handle;
+ break;
+ } else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
+ handle = r >> 16;
+ break;
+ } else if (r != MBOX_LOOP_ID_USED) {
+ i = lim;
+ break;
+ } else {
+ *ohp = handle;
+ handle = isp_nxt_handle(isp, *ohp);
+ }
+ }
+
+ if (i == lim) {
+ isp_prt(isp, ISP_LOGWARN, "PLOGI 0x%06x failed", portid);
+ return (-1);
+ }
/*
- * If we're not at the last entry, our list isn't big enough.
+ * If we successfully logged into it, get the PDB for it
+ * so we can crosscheck that it is still what we think it
+ * is and that we also have the role it plays
*/
- if ((rs1->snscb_ports[i].control & 0x80) == 0) {
- isp_prt(isp, ISP_LOGWARN, "fabric too big for scratch area");
+ r = isp_getpdb(isp, handle, p, 0);
+ if (FCPARAM(isp)->isp_loopstate != LOOP_SCANNING_FABRIC) {
+ return (-1);
+ }
+ if (r != 0) {
+ isp_prt(isp, ISP_LOGERR, "new device 0x%06x@0x%x disappeared",
+ portid, handle);
+ return (-1);
}
- FC_SCRATCH_RELEASE(isp);
- fcp->isp_loopstate = LOOP_FSCAN_DONE;
+ if (p->handle != handle || p->portid != portid) {
+ isp_prt(isp, ISP_LOGERR,
+ "new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
+ portid, handle, p->portid, p->handle);
+ return (-1);
+ }
return (0);
}
-#endif
-static void
+int
isp_register_fc4_type(struct ispsoftc *isp)
{
fcparam *fcp = isp->isp_param;
@@ -2928,9 +3839,6 @@ isp_register_fc4_type(struct ispsoftc *isp)
reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
reqp->snscb_data[6] = (1 << FC4_SCSI);
-#if 0
- reqp->snscb_data[6] |= (1 << FC4_IP); /* ISO/IEC 8802-2 LLC/SNAP */
-#endif
FC_SCRATCH_ACQUIRE(isp);
isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
MEMZERO(&mbs, sizeof (mbs));
@@ -2938,18 +3846,167 @@ isp_register_fc4_type(struct ispsoftc *isp)
mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
mbs.param[2] = DMA_WD1(fcp->isp_scdma);
mbs.param[3] = DMA_WD0(fcp->isp_scdma);
- /*
- * Leave 4 and 5 alone
- */
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ mbs.timeout = 10000000;
+ MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE);
+ isp_mboxcmd(isp, &mbs);
FC_SCRATCH_RELEASE(isp);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
- isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 types succeeded");
+ return (0);
+ } else {
+ return (-1);
}
}
+int
+isp_register_fc4_type_24xx(struct ispsoftc *isp)
+{
+ mbreg_t mbs;
+ fcparam *fcp = FCPARAM(isp);
+ union {
+ isp_ct_pt_t plocal;
+ rft_id_t clocal;
+ u_int8_t q[QENTRY_LEN];
+ } un;
+ isp_ct_pt_t *pt;
+ ct_hdr_t *ct;
+ rft_id_t *rp;
+ u_int8_t *scp = fcp->isp_scratch;
+
+ FC_SCRATCH_ACQUIRE(isp);
+ /*
+ * Build a Passthrough IOCB in memory.
+ */
+ MEMZERO(un.q, QENTRY_LEN);
+ pt = &un.plocal;
+ pt->ctp_header.rqs_entry_count = 1;
+ pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
+ pt->ctp_handle = 0xffffffff;
+ pt->ctp_nphdl = NPH_SNS_ID;
+ pt->ctp_cmd_cnt = 1;
+ pt->ctp_time = 1;
+ pt->ctp_rsp_cnt = 1;
+ pt->ctp_rsp_bcnt = sizeof (ct_hdr_t);
+ pt->ctp_cmd_bcnt = sizeof (rft_id_t);
+ pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
+ pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
+ pt->ctp_dataseg[0].ds_count = sizeof (rft_id_t);
+ pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
+ pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
+ pt->ctp_dataseg[1].ds_count = sizeof (ct_hdr_t);
+ isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
+
+ /*
+ * Build the CT header and command in memory.
+ *
+ * Note that the CT header has to end up as Big Endian format in memory.
+ */
+ MEMZERO(&un.clocal, sizeof (un.clocal));
+ ct = &un.clocal.rftid_hdr;
+ ct->ct_revision = CT_REVISION;
+ ct->ct_fcs_type = CT_FC_TYPE_FC;
+ ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
+ ct->ct_cmd_resp = SNS_RFT_ID;
+ ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
+ rp = &un.clocal;
+ rp->rftid_portid[0] = fcp->isp_portid >> 16;
+ rp->rftid_portid[1] = fcp->isp_portid >> 8;
+ rp->rftid_portid[2] = fcp->isp_portid;
+ rp->rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
+ isp_put_rft_id(isp, rp, (rft_id_t *) &scp[XTXOFF]);
+
+ MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
+
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
+ mbs.param[1] = QENTRY_LEN;
+ mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
+ mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
+ mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
+ mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
+ mbs.timeout = 500000;
+ mbs.logval = MBLOGALL;
+ MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN);
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ FC_SCRATCH_RELEASE(isp);
+ return (-1);
+ }
+ MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN);
+ pt = &un.plocal;
+ isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
+ }
+ if (pt->ctp_status) {
+ FC_SCRATCH_RELEASE(isp);
+ isp_prt(isp, ISP_LOGWARN, "CT Passthrough returned 0x%x",
+ pt->ctp_status);
+ return (-1);
+ }
+
+ isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct);
+ FC_SCRATCH_RELEASE(isp);
+
+ if (ct->ct_cmd_resp == LS_RJT) {
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Register FC4 Type rejected");
+ return (-1);
+ } else if (ct->ct_cmd_resp == LS_ACC) {
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Register FC4 Type accepted");
+ return(0);
+ } else {
+ isp_prt(isp, ISP_LOGWARN,
+ "Register FC4 Type: 0x%x", ct->ct_cmd_resp);
+ return (-1);
+ }
+}
+
+u_int16_t
+isp_nxt_handle(struct ispsoftc *isp, u_int16_t handle)
+{
+ int i;
+ if (handle == NIL_HANDLE) {
+ if (FCPARAM(isp)->isp_topo == TOPO_F_PORT) {
+ handle = 0;
+ } else {
+ handle = SNS_ID+1;
+ }
+ } else {
+ handle += 1;
+ if (handle >= FL_ID && handle <= SNS_ID) {
+ handle = SNS_ID+1;
+ }
+ if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
+ handle = NPH_FL_ID+1;
+ }
+ if (FCPARAM(isp)->isp_2klogin) {
+ if (handle == NPH_MAX_2K) {
+ handle = 0;
+ }
+ } else {
+ if (handle == NPH_MAX) {
+ handle = 0;
+ }
+ }
+ }
+ if (handle == FCPARAM(isp)->isp_loopid) {
+ return (isp_nxt_handle(isp, handle));
+ }
+ for (i = 0; i < MAX_FC_TARG; i++) {
+ if (FCPARAM(isp)->portdb[i].state == FC_PORTDB_STATE_NIL) {
+ continue;
+ }
+ if (FCPARAM(isp)->portdb[i].handle == handle) {
+ return (isp_nxt_handle(isp, handle));
+ }
+ }
+ return (handle);
+}
+
/*
* Start a command. Locking is assumed done in the caller.
*/
@@ -2958,10 +4015,12 @@ int
isp_start(XS_T *xs)
{
struct ispsoftc *isp;
- u_int16_t nxti, optr, handle;
+ u_int32_t nxti, optr, handle;
u_int8_t local[QENTRY_LEN];
ispreq_t *reqp, *qep;
- int target, i;
+ void *cdbp;
+ u_int16_t *tptr;
+ int target, i, hdlidx = 0;
XS_INITERR(xs);
isp = XS_ISP(xs);
@@ -3000,201 +4059,54 @@ isp_start(XS_T *xs)
}
/*
- * Check to see whether we have good firmware state still or
- * need to refresh our port database for this target.
+ * Translate the target to device handle as appropriate, checking
+ * for correct device state as well.
*/
target = XS_TGT(xs);
if (IS_FC(isp)) {
fcparam *fcp = isp->isp_param;
- struct lportdb *lp;
-#ifdef HANDLE_LOOPSTATE_IN_OUTER_LAYERS
- if (fcp->isp_fwstate != FW_READY ||
- fcp->isp_loopstate != LOOP_READY) {
- return (CMD_RQLATER);
- }
-
- /*
- * If we're not on a Fabric, we can't have a target
- * above FL_PORT_ID-1.
- *
- * If we're on a fabric and *not* connected as an F-port,
- * we can't have a target less than FC_SNS_ID+1. This
- * keeps us from having to sort out the difference between
- * local public loop devices and those which we might get
- * from a switch's database.
- */
- if (fcp->isp_onfabric == 0) {
- if (target >= FL_PORT_ID) {
- XS_SETERR(xs, HBA_SELTIMEOUT);
- return (CMD_COMPLETE);
- }
- } else {
- if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
- XS_SETERR(xs, HBA_SELTIMEOUT);
- return (CMD_COMPLETE);
- }
- /*
- * We used to exclude having local loop ports
- * at the same time that we have fabric ports.
- * That is, we used to exclude having ports
- * at < FL_PORT_ID if we're FL-port.
- *
- * That's wrong. The only thing that could be
- * dicey is if the switch you're connected to
- * has these local loop ports appear on the
- * fabric and we somehow attach them twice.
- */
- }
-#else
- /*
- * Check for f/w being in ready state. If the f/w
- * isn't in ready state, then we don't know our
- * loop ID and the f/w hasn't completed logging
- * into all targets on the loop. If this is the
- * case, then bounce the command. We pretend this is
- * a SELECTION TIMEOUT error if we've never gone to
- * FW_READY state at all- in this case we may not
- * be hooked to a loop at all and we shouldn't hang
- * the machine for this. Otherwise, defer this command
- * until later.
- */
- if (fcp->isp_fwstate != FW_READY) {
- /*
- * Give ourselves at most a 250ms delay.
- */
- if (isp_fclink_test(isp, 250000)) {
- XS_SETERR(xs, HBA_SELTIMEOUT);
- if (fcp->loop_seen_once) {
- return (CMD_RQLATER);
- } else {
- return (CMD_COMPLETE);
- }
- }
- }
/*
- * If we're not on a Fabric, we can't have a target
- * above FL_PORT_ID-1.
- *
- * If we're on a fabric and *not* connected as an F-port,
- * we can't have a target less than FC_SNS_ID+1. This
- * keeps us from having to sort out the difference between
- * local public loop devices and those which we might get
- * from a switch's database.
+ * Try again later.
*/
- if (fcp->isp_onfabric == 0) {
- if (target >= FL_PORT_ID) {
- XS_SETERR(xs, HBA_SELTIMEOUT);
- return (CMD_COMPLETE);
- }
- } else {
- if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
- XS_SETERR(xs, HBA_SELTIMEOUT);
- return (CMD_COMPLETE);
- }
- if (fcp->isp_topo != TOPO_F_PORT &&
- target < FL_PORT_ID) {
- XS_SETERR(xs, HBA_SELTIMEOUT);
- return (CMD_COMPLETE);
- }
- }
-
- /*
- * If our loop state is such that we haven't yet received
- * a "Port Database Changed" notification (after a LIP or
- * a Loop Reset or firmware initialization), then defer
- * sending commands for a little while, but only if we've
- * seen a valid loop at one point (otherwise we can get
- * stuck at initialization time).
- */
- if (fcp->isp_loopstate < LOOP_PDB_RCVD) {
- XS_SETERR(xs, HBA_SELTIMEOUT);
- if (fcp->loop_seen_once) {
- return (CMD_RQLATER);
- } else {
- return (CMD_COMPLETE);
- }
- }
-
- /*
- * If we're in the middle of loop or fabric scanning
- * or merging the port databases, retry this command later.
- */
- if (fcp->isp_loopstate == LOOP_SCANNING_FABRIC ||
- fcp->isp_loopstate == LOOP_SCANNING_LOOP ||
- fcp->isp_loopstate == LOOP_SYNCING_PDB) {
+ if (fcp->isp_fwstate != FW_READY ||
+ fcp->isp_loopstate != LOOP_READY) {
return (CMD_RQLATER);
}
- /*
- * If our loop state is now such that we've just now
- * received a Port Database Change notification, then
- * we have to go off and (re)scan the fabric. We back
- * out and try again later if this doesn't work.
- */
- if (fcp->isp_loopstate == LOOP_PDB_RCVD && fcp->isp_onfabric) {
- if (isp_scan_fabric(isp, FC4_SCSI)) {
- return (CMD_RQLATER);
- }
- if (fcp->isp_fwstate != FW_READY ||
- fcp->isp_loopstate < LOOP_FSCAN_DONE) {
- return (CMD_RQLATER);
- }
- }
-
- /*
- * If our loop state is now such that we've just now
- * received a Port Database Change notification, then
- * we have to go off and (re)synchronize our port
- * database.
- */
- if (fcp->isp_loopstate < LOOP_READY) {
- if (isp_pdb_sync(isp)) {
- return (CMD_RQLATER);
- }
- if (fcp->isp_fwstate != FW_READY ||
- fcp->isp_loopstate != LOOP_READY) {
- return (CMD_RQLATER);
- }
+ if (XS_TGT(xs) >= MAX_FC_TARG) {
+ XS_SETERR(xs, HBA_SELTIMEOUT);
+ return (CMD_COMPLETE);
}
- /*
- * XXX: Here's were we would cancel any loop_dead flag
- * XXX: also cancel in dead_loop timeout that's running
- */
-#endif
-
- /*
- * Now check whether we should even think about pursuing this.
- */
- lp = &fcp->portdb[target];
- if (lp->valid == 0) {
+ hdlidx = fcp->isp_ini_map[XS_TGT(xs)] - 1;
+ isp_prt(isp, ISP_LOGDEBUG1, "XS_TGT(xs)=%d- hdlidx value %d",
+ XS_TGT(xs), hdlidx);
+ if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
XS_SETERR(xs, HBA_SELTIMEOUT);
return (CMD_COMPLETE);
}
- if ((lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) == 0) {
- isp_prt(isp, ISP_LOGDEBUG2,
- "Target %d does not have target service", target);
+ if (fcp->portdb[hdlidx].state == FC_PORTDB_STATE_ZOMBIE) {
+ return (CMD_RQLATER);
+ }
+ if (fcp->portdb[hdlidx].state != FC_PORTDB_STATE_VALID) {
XS_SETERR(xs, HBA_SELTIMEOUT);
return (CMD_COMPLETE);
}
- /*
- * Now turn target into what the actual Loop ID is.
- */
- target = lp->loopid;
- xs->sc_link->node_wwn = lp->node_wwn;
- xs->sc_link->port_wwn = lp->port_wwn;
-
+ target = fcp->portdb[hdlidx].handle;
+ xs->sc_link->node_wwn = fcp->portdb[hdlidx].node_wwn;
+ xs->sc_link->port_wwn = fcp->portdb[hdlidx].port_wwn;
}
/*
- * Next check to see if any HBA or Device
- * parameters need to be updated.
+ * Next check to see if any HBA or Device parameters need to be updated.
*/
if (isp->isp_update != 0) {
isp_update(isp);
}
+ start_again:
+
if (isp_getrqentry(isp, &nxti, &optr, (void *)&qep)) {
isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
XS_SETERR(xs, HBA_BOTCH);
@@ -3208,34 +4120,40 @@ isp_start(XS_T *xs)
*/
reqp = (ispreq_t *) local;
if (isp->isp_sendmarker) {
- u_int8_t n = (IS_DUALBUS(isp)? 2: 1);
- /*
- * Check ports to send markers for...
- */
- for (i = 0; i < n; i++) {
- if ((isp->isp_sendmarker & (1 << i)) == 0) {
- continue;
- }
- MEMZERO((void *) reqp, QENTRY_LEN);
- reqp->req_header.rqs_entry_count = 1;
- reqp->req_header.rqs_entry_type = RQSTYPE_MARKER;
- reqp->req_modifier = SYNC_ALL;
- reqp->req_target = i << 7; /* insert bus number */
- isp_put_request(isp, reqp, qep);
+ if (IS_24XX(isp)) {
+ isp_marker_24xx_t *m = (isp_marker_24xx_t *) qep;
+ MEMZERO(m, QENTRY_LEN);
+ m->mrk_header.rqs_entry_count = 1;
+ m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
+ m->mrk_modifier = SYNC_ALL;
+ isp_put_marker_24xx(isp, m, (isp_marker_24xx_t *)qep);
ISP_ADD_REQUEST(isp, nxti);
- isp->isp_sendmarker &= ~(1 << i);
- if (isp_getrqentry(isp, &nxti, &optr, (void *) &qep)) {
- isp_prt(isp, ISP_LOGDEBUG0,
- "Request Queue Overflow+");
- XS_SETERR(xs, HBA_BOTCH);
- return (CMD_EAGAIN);
+ isp->isp_sendmarker = 0;
+ goto start_again;
+ } else {
+ for (i = 0; i < (IS_DUALBUS(isp)? 2: 1); i++) {
+ isp_marker_t *m = (isp_marker_t *) qep;
+ if ((isp->isp_sendmarker & (1 << i)) == 0) {
+ continue;
+ }
+ MEMZERO(m, QENTRY_LEN);
+ m->mrk_header.rqs_entry_count = 1;
+ m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
+ m->mrk_target = (i << 7); /* bus # */
+ m->mrk_modifier = SYNC_ALL;
+ isp_put_marker(isp, m, (isp_marker_t *) qep);
+ ISP_ADD_REQUEST(isp, nxti);
+ isp->isp_sendmarker &= ~(1 << i);
+ goto start_again;
}
}
}
MEMZERO((void *)reqp, QENTRY_LEN);
reqp->req_header.rqs_entry_count = 1;
- if (IS_FC(isp)) {
+ if (IS_24XX(isp)) {
+ reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
+ } else if (IS_FC(isp)) {
reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
} else {
if (XS_CDBLEN(xs) > 12)
@@ -3245,7 +4163,26 @@ isp_start(XS_T *xs)
}
/* reqp->req_header.rqs_flags = 0; */
/* reqp->req_header.rqs_seqno = 0; */
- if (IS_FC(isp)) {
+ if (IS_24XX(isp)) {
+ int ttype;
+ if (XS_TAG_P(xs)) {
+ ttype = XS_TAG_TYPE(xs);
+ } else {
+ if (XS_CDBP(xs)[0] == 0x3) {
+ ttype = REQFLAG_HTAG;
+ } else {
+ ttype = REQFLAG_STAG;
+ }
+ }
+ if (ttype == REQFLAG_OTAG) {
+ ttype = FCP_CMND_TASK_ATTR_ORDERED;
+ } else if (ttype == REQFLAG_HTAG) {
+ ttype = FCP_CMND_TASK_ATTR_HEAD;
+ } else {
+ ttype = FCP_CMND_TASK_ATTR_SIMPLE;
+ }
+ ((ispreqt7_t *)reqp)->req_task_attribute = ttype;
+ } else if (IS_FC(isp)) {
/*
* See comment in isp_intr
*/
@@ -3253,7 +4190,7 @@ isp_start(XS_T *xs)
/*
* Fibre Channel always requires some kind of tag.
- * The QLogic drivers seem be happy not to use a tag,
+ * The Qlogic drivers seem be happy not to use a tag,
* but this breaks for some devices (IBM drives).
*/
if (XS_TAG_P(xs)) {
@@ -3276,21 +4213,45 @@ isp_start(XS_T *xs)
reqp->req_flags = XS_TAG_TYPE(xs);
}
}
- reqp->req_target = target | (XS_CHANNEL(xs) << 7);
+ cdbp = reqp->req_cdb;
+ tptr = &reqp->req_time;
+
if (IS_SCSI(isp)) {
+ reqp->req_target = target | (XS_CHANNEL(xs) << 7);
reqp->req_lun_trn = XS_LUN(xs);
reqp->req_cdblen = XS_CDBLEN(xs);
+ } else if (IS_24XX(isp)) {
+ fcportdb_t *lp;
+
+ lp = &FCPARAM(isp)->portdb[hdlidx];
+ ((ispreqt7_t *)reqp)->req_nphdl = target;
+ ((ispreqt7_t *)reqp)->req_tidlo = lp->portid;
+ ((ispreqt7_t *)reqp)->req_tidhi = lp->portid >> 16;
+ if (XS_LUN(xs) > 256) {
+ ((ispreqt7_t *)reqp)->req_lun[0] = XS_LUN(xs) >> 8;
+ ((ispreqt7_t *)reqp)->req_lun[0] |= 0x40;
+ }
+ ((ispreqt7_t *)reqp)->req_lun[1] = XS_LUN(xs);
+ cdbp = ((ispreqt7_t *)reqp)->req_cdb;
+ tptr = &((ispreqt7_t *)reqp)->req_time;
+ } else if (FCPARAM(isp)->isp_2klogin) {
+ ((ispreqt2e_t *)reqp)->req_target = target;
+ ((ispreqt2e_t *)reqp)->req_scclun = XS_LUN(xs);
+ } else if (FCPARAM(isp)->isp_sccfw) {
+ ((ispreqt2_t *)reqp)->req_target = target;
+ ((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
} else {
- if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)
- ((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
- else
- ((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
+ ((ispreqt2_t *)reqp)->req_target = target;
+ ((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
}
- MEMCPY(reqp->req_cdb, XS_CDBP(xs), XS_CDBLEN(xs));
+ MEMCPY(cdbp, XS_CDBP(xs), XS_CDBLEN(xs));
- reqp->req_time = XS_TIME(xs) / 1000;
- if (reqp->req_time == 0 && XS_TIME(xs)) {
- reqp->req_time = 1;
+ *tptr = XS_TIME(xs) / 1000;
+ if (*tptr == 0 && XS_TIME(xs)) {
+ *tptr = 1;
+ }
+ if (IS_24XX(isp) && *tptr > 0x1999) {
+ *tptr = 0x1999;
}
if (isp_save_xs(isp, xs, &handle)) {
@@ -3298,11 +4259,12 @@ isp_start(XS_T *xs)
XS_SETERR(xs, HBA_BOTCH);
return (CMD_EAGAIN);
}
+ /* Whew. Thankfully the same for type 7 requests */
reqp->req_handle = handle;
/*
* Set up DMA and/or do any bus swizzling of the request entry
- * so that the QLogic F/W understands what is being asked of it.
+ * so that the Qlogic F/W understands what is being asked of it.
*/
i = ISP_DMASETUP(isp, xs, reqp, &nxti, optr);
if (i != CMD_QUEUED) {
@@ -3314,7 +4276,7 @@ isp_start(XS_T *xs)
return (i);
}
XS_SETERR(xs, HBA_NOERROR);
- isp_prt(isp, ISP_LOGDEBUG2,
+ 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));
@@ -3334,7 +4296,9 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
XS_T *xs;
mbreg_t mbs;
int bus, tgt;
- u_int16_t handle;
+ u_int32_t handle;
+
+ MEMZERO(&mbs, sizeof (mbs));
switch (ctl) {
default:
@@ -3345,22 +4309,26 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
/*
* Issue a bus reset.
*/
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_BUS_RESET;
- if (IS_SCSI(isp)) {
- mbs.param[1] =
- ((sdparam *) isp->isp_param)->isp_bus_reset_delay;
- if (mbs.param[1] < 2)
+ if (IS_24XX(isp)) {
+ isp_prt(isp, ISP_LOGWARN, "RESET BUS NOT IMPLEMENTED");
+ break;
+ } else if (IS_FC(isp)) {
+ mbs.param[1] = 10;
+ bus = 0;
+ } else {
+ mbs.param[1] = SDPARAM(isp)->isp_bus_reset_delay;
+ if (mbs.param[1] < 2) {
mbs.param[1] = 2;
+ }
bus = *((int *) arg);
- if (IS_DUALBUS(isp))
+ if (IS_DUALBUS(isp)) {
mbs.param[2] = bus;
- } else {
- mbs.param[1] = 10;
- bus = 0;
+ }
}
+ mbs.param[0] = MBOX_BUS_RESET;
isp->isp_sendmarker |= (1 << bus);
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
break;
}
@@ -3370,12 +4338,25 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
case ISPCTL_RESET_DEV:
tgt = (*((int *) arg)) & 0xffff;
- bus = (*((int *) arg)) >> 16;
- MEMZERO(&mbs, sizeof (mbs));
+ if (IS_24XX(isp)) {
+ isp_prt(isp, ISP_LOGWARN, "RESET DEV NOT IMPLEMENTED");
+ break;
+ } else if (IS_FC(isp)) {
+ if (FCPARAM(isp)->isp_2klogin) {
+ mbs.param[1] = tgt;
+ mbs.ibits = (1 << 10);
+ } else {
+ mbs.param[1] = (tgt << 8);
+ }
+ bus = 0;
+ } else {
+ bus = (*((int *) arg)) >> 16;
+ mbs.param[1] = (bus << 15) | (tgt << 8);
+ }
mbs.param[0] = MBOX_ABORT_TARGET;
- mbs.param[1] = (tgt << 8) | (bus << 15);
mbs.param[2] = 3; /* 'delay', in seconds */
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
break;
}
@@ -3387,38 +4368,39 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
case ISPCTL_ABORT_CMD:
xs = (XS_T *) arg;
tgt = XS_TGT(xs);
+
handle = isp_find_handle(isp, xs);
if (handle == 0) {
isp_prt(isp, ISP_LOGWARN,
"cannot find handle for command to abort");
break;
}
- bus = XS_CHANNEL(xs);
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_ABORT;
- if (IS_FC(isp)) {
- if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
- mbs.param[1] = tgt << 8;
- mbs.param[4] = 0;
- mbs.param[5] = 0;
+ if (IS_24XX(isp)) {
+ isp_prt(isp, ISP_LOGWARN, "ABORT CMD NOT IMPLEMENTED");
+ break;
+ } else if (IS_FC(isp)) {
+ if (FCPARAM(isp)->isp_sccfw) {
+ if (FCPARAM(isp)->isp_2klogin) {
+ mbs.param[1] = tgt;
+ } else {
+ mbs.param[1] = tgt << 8;
+ }
mbs.param[6] = XS_LUN(xs);
} else {
mbs.param[1] = tgt << 8 | XS_LUN(xs);
}
} else {
- mbs.param[1] =
- (bus << 15) | (XS_TGT(xs) << 8) | XS_LUN(xs);
+ bus = XS_CHANNEL(xs);
+ mbs.param[1] = (bus << 15) | (tgt << 8) | XS_LUN(xs);
}
+ mbs.param[0] = MBOX_ABORT;
mbs.param[2] = handle;
- isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_ERROR);
- if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
- return (0);
+ mbs.logval = MBLOGALL & ~MBOX_COMMAND_ERROR;
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ break;
}
- /*
- * XXX: Look for command in the REQUEST QUEUE. That is,
- * XXX: It hasn't been picked up by firmware yet.
- */
- break;
+ return (0);
case ISPCTL_UPDATE_PARAMS:
@@ -3428,7 +4410,10 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
case ISPCTL_FCLINK_TEST:
if (IS_FC(isp)) {
- int usdelay = (arg)? *((int *) arg) : 250000;
+ int usdelay = *((int *) arg);
+ if (usdelay == 0) {
+ usdelay = 250000;
+ }
return (isp_fclink_test(isp, usdelay));
}
break;
@@ -3436,8 +4421,7 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
case ISPCTL_SCAN_FABRIC:
if (IS_FC(isp)) {
- int ftype = (arg)? *((int *) arg) : FC4_SCSI;
- return (isp_scan_fabric(isp, ftype));
+ return (isp_scan_fabric(isp));
}
break;
@@ -3457,28 +4441,64 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
case ISPCTL_SEND_LIP:
- if (IS_FC(isp)) {
- MEMZERO(&mbs, sizeof (mbs));
+ if (IS_FC(isp) && !IS_24XX(isp)) {
mbs.param[0] = MBOX_INIT_LIP;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ if (FCPARAM(isp)->isp_2klogin) {
+ mbs.ibits = (1 << 10);
+ }
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
return (0);
}
}
break;
- case ISPCTL_GET_POSMAP:
-
+ case ISPCTL_GET_PDB:
if (IS_FC(isp) && arg) {
- return (isp_getmap(isp, arg));
+ int id = *((int *)arg);
+ isp_pdb_t *pdb = arg;
+ return (isp_getpdb(isp, id, pdb, 1));
}
break;
+ case ISPCTL_GET_PORTNAME:
+ {
+ u_int64_t *wwnp = arg;
+ int loopid = *wwnp;
+ *wwnp = isp_get_portname(isp, loopid, 0);
+ if (*wwnp == (u_int64_t) -1) {
+ break;
+ } else {
+ return (0);
+ }
+ }
case ISPCTL_RUN_MBOXCMD:
- isp_mboxcmd(isp, arg, MBLOGALL);
+ isp_mboxcmd(isp, arg);
return(0);
+ case ISPCTL_PLOGX:
+ {
+ isp_plcmd_t *p = arg;
+ int r;
+
+ if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI ||
+ (p->handle != NIL_HANDLE)) {
+ return (isp_plogx(isp, p->handle, p->portid,
+ p->flags, 0));
+ }
+ do {
+ p->handle = isp_nxt_handle(isp, p->handle);
+ r = isp_plogx(isp, p->handle, p->portid, p->flags, 0);
+ if ((r & 0xffff) == MBOX_PORT_ID_USED) {
+ p->handle = r >> 16;
+ r = 0;
+ break;
+ }
+ } while ((r & 0xffff) == MBOX_LOOP_ID_USED);
+ return (r);
+ }
#ifdef ISP_TARGET_MODE
case ISPCTL_TOGGLE_TMODE:
{
@@ -3489,11 +4509,11 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
*/
if (IS_SCSI(isp)) {
int param = *(int *)arg;
- MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
mbs.param[1] = param & 0xffff;
mbs.param[2] = param >> 16;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
break;
}
@@ -3517,17 +4537,18 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
* of completions on a request queue at any one time.
*/
#ifndef MAX_REQUESTQ_COMPLETIONS
-#define MAX_REQUESTQ_COMPLETIONS 64
+#define MAX_REQUESTQ_COMPLETIONS 32
#endif
void
-isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
+isp_intr(struct ispsoftc *isp, u_int32_t isr, u_int16_t sema, u_int16_t mbox)
{
XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
- u_int16_t iptr, optr, junk;
+ u_int32_t iptr, optr, junk;
int i, nlooked = 0, ndone = 0;
again:
+ optr = isp->isp_residx;
/*
* Is this a mailbox related interrupt?
* The mailbox semaphore will be nonzero if so.
@@ -3538,7 +4559,7 @@ again:
if (isp->isp_mboxbsy) {
int obits = isp->isp_obits;
isp->isp_mboxtmp[0] = mbox;
- for (i = 1; i < MAX_MAILBOX; i++) {
+ for (i = 1; i < MAX_MAILBOX(isp); i++) {
if ((obits & (1 << i)) == 0) {
continue;
}
@@ -3553,17 +4574,14 @@ again:
MBOX_NOTIFY_COMPLETE(isp);
} else {
isp_prt(isp, ISP_LOGWARN,
- "Mbox Command Async (0x%x) with no waiters",
- mbox);
+ "mailbox cmd (0x%x) with no waiters", mbox);
}
} else if (isp_parse_async(isp, mbox) < 0) {
return;
}
if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) ||
isp->isp_state != ISP_RUNSTATE) {
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- ISP_WRITE(isp, BIU_SEMA, 0);
- return;
+ goto out;
}
}
@@ -3571,32 +4589,73 @@ again:
* We can't be getting this now.
*/
if (isp->isp_state != ISP_RUNSTATE) {
- isp_prt(isp, ISP_LOGWARN,
+ isp_prt(isp, ISP_LOGINFO,
"interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
/*
* Thank you very much! *Burrrp*!
*/
- WRITE_RESPONSE_QUEUE_OUT_POINTER(isp,
- READ_RESPONSE_QUEUE_IN_POINTER(isp));
+ ISP_WRITE(isp, isp->isp_respoutrp,
+ ISP_READ(isp, isp->isp_respinrp));
+ if (IS_24XX(isp)) {
+ ISP_DISABLE_INTS(isp);
+ }
+ goto out;
+ }
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- ISP_WRITE(isp, BIU_SEMA, 0);
- return;
+#ifdef ISP_TARGET_MODE
+ /*
+ * Check for ATIO Queue entries.
+ */
+ if (isp->isp_rspbsy == 0 && (isp->isp_role & ISP_ROLE_TARGET) &&
+ IS_24XX(isp)) {
+ iptr = ISP_READ(isp, isp->isp_atioinrp);
+ optr = ISP_READ(isp, isp->isp_atiooutrp);
+
+ isp->isp_rspbsy = 1;
+ while (optr != iptr) {
+ u_int8_t qe[QENTRY_LEN];
+ isphdr_t *hp;
+ u_int32_t oop;
+ void *addr;
+
+ oop = optr;
+ MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN);
+ addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
+ isp_get_hdr(isp, addr, (isphdr_t *)qe);
+ hp = (isphdr_t *)qe;
+ switch (hp->rqs_entry_type) {
+ case RQSTYPE_NOTIFY:
+ case RQSTYPE_ATIO:
+ (void) isp_target_notify(isp, addr, &oop);
+ break;
+ default:
+ isp_print_qentry(isp, "?ATIOQ entry?",
+ oop, addr);
+ break;
+ }
+ optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
+ ISP_WRITE(isp, isp->isp_atiooutrp, optr);
+ }
+ isp->isp_rspbsy = 0;
+ optr = isp->isp_residx;
}
+#endif
/*
* Get the current Response Queue Out Pointer.
*
- * If we're a 2300, we can ask what hardware what it thinks.
+ * If we're a 2300 or 2400, we can ask what hardware what it thinks.
*/
- if (IS_23XX(isp)) {
+ if (IS_23XX(isp) || IS_24XX(isp)) {
optr = ISP_READ(isp, isp->isp_respoutrp);
/*
* Debug: to be taken out eventually
*/
if (isp->isp_residx != optr) {
- isp_prt(isp, ISP_LOGWARN, "optr %x soft optr %x",
+ isp_prt(isp, ISP_LOGINFO,
+ "isp_intr: hard optr=%x, soft optr %x",
optr, isp->isp_residx);
+ isp->isp_residx = optr;
}
} else {
optr = isp->isp_residx;
@@ -3611,19 +4670,18 @@ again:
if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
i = 0;
do {
- iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
- junk = READ_RESPONSE_QUEUE_IN_POINTER(isp);
+ iptr = ISP_READ(isp, isp->isp_respinrp);
+ junk = ISP_READ(isp, isp->isp_respinrp);
} while (junk != iptr && ++i < 1000);
if (iptr != junk) {
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
isp_prt(isp, ISP_LOGWARN,
"Response Queue Out Pointer Unstable (%x, %x)",
iptr, junk);
- return;
+ goto out;
}
} else {
- iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
+ iptr = ISP_READ(isp, isp->isp_respinrp);
}
isp->isp_resodx = iptr;
@@ -3637,15 +4695,17 @@ again:
* make sure the old interrupt went away (to avoid 'ringing'
* effects), but that didn't stop this from occurring.
*/
- if (IS_23XX(isp)) {
+ if (IS_24XX(isp)) {
+ junk = 0;
+ } else if (IS_23XX(isp)) {
USEC_DELAY(100);
- iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
+ iptr = ISP_READ(isp, isp->isp_respinrp);
junk = ISP_READ(isp, BIU_R2HSTSLO);
} else {
junk = ISP_READ(isp, BIU_ISR);
}
if (optr == iptr) {
- if (IS_23XX(isp)) {
+ if (IS_23XX(isp) || IS_24XX(isp)) {
;
} else {
sema = ISP_READ(isp, BIU_SEMA);
@@ -3661,42 +4721,75 @@ again:
}
}
isp->isp_resodx = iptr;
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- ISP_WRITE(isp, BIU_SEMA, 0);
+
if (isp->isp_rspbsy) {
- return;
+ goto out;
}
isp->isp_rspbsy = 1;
-
while (optr != iptr) {
- ispstatusreq_t local, *sp = &local;
+ u_int8_t qe[QENTRY_LEN];
+ ispstatusreq_t *sp = (ispstatusreq_t *) qe;
isphdr_t *hp;
- int type;
+ int buddaboom, etype, scsi_status, completion_status;
+ int req_status_flags, req_state_flags;
+ u_int8_t *snsp, *resp;
+ u_int32_t rlen, slen;
+ long resid;
u_int16_t oop;
- int buddaboom = 0;
hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
oop = optr;
optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
nlooked++;
+ read_again:
+ buddaboom = req_status_flags = req_state_flags = 0;
+ resid = 0L;
+
/*
* Synchronize our view of this response queue entry.
*/
MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN);
-
- type = isp_get_response_type(isp, hp);
-
- if (type == RQSTYPE_RESPONSE) {
+ isp_get_hdr(isp, hp, &sp->req_header);
+ etype = sp->req_header.rqs_entry_type;
+
+ if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) {
+ isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe;
+ isp_get_24xx_response(isp,
+ (isp24xx_statusreq_t *)hp, sp2);
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp,
+ "Response Queue Entry", QENTRY_LEN, sp2);
+ }
+ scsi_status = sp2->req_scsi_status;
+ completion_status = sp2->req_completion_status;
+ req_state_flags = 0;
+ resid = sp2->req_resid;
+ } else if (etype == RQSTYPE_RESPONSE) {
isp_get_response(isp, (ispstatusreq_t *) hp, sp);
- } else if (type == RQSTYPE_RIO2) {
- isp_rio2_t rio;
- isp_get_rio2(isp, (isp_rio2_t *) hp, &rio);
- for (i = 0; i < rio.req_header.rqs_seqno; i++) {
- isp_fastpost_complete(isp, rio.req_handles[i]);
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp,
+ "Response Queue Entry", QENTRY_LEN, sp);
+ }
+ scsi_status = sp->req_scsi_status;
+ completion_status = sp->req_completion_status;
+ req_status_flags = sp->req_status_flags;
+ req_state_flags = sp->req_state_flags;
+ resid = sp->req_resid;
+ } else if (etype == RQSTYPE_RIO2) {
+ isp_rio2_t *rio = (isp_rio2_t *)qe;
+ isp_get_rio2(isp, (isp_rio2_t *) hp, rio);
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp,
+ "Response Queue Entry", QENTRY_LEN, rio);
+ }
+ for (i = 0; i < rio->req_header.rqs_seqno; i++) {
+ isp_fastpost_complete(isp, rio->req_handles[i]);
+ }
+ if (isp->isp_fpcchiwater < rio->req_header.rqs_seqno) {
+ isp->isp_fpcchiwater =
+ rio->req_header.rqs_seqno;
}
- if (isp->isp_fpcchiwater < rio.req_header.rqs_seqno)
- isp->isp_fpcchiwater = rio.req_header.rqs_seqno;
MEMZERO(hp, QENTRY_LEN); /* PERF */
continue;
} else {
@@ -3705,7 +4798,12 @@ again:
* may have updated the response queue pointers for
* us, so we reload our goal index.
*/
- if (isp_handle_other_response(isp, type, hp, &optr)) {
+ int r;
+ r = isp_handle_other_response(isp, etype, hp, &optr);
+ if (r < 0) {
+ goto read_again;
+ }
+ if (r > 0) {
iptr = isp->isp_resodx;
MEMZERO(hp, QENTRY_LEN); /* PERF */
continue;
@@ -3716,34 +4814,33 @@ again:
* we don't know how to deal with the rest of the
* response.
*/
- isp_get_response(isp, (ispstatusreq_t *) hp, sp);
/*
* It really has to be a bounced request just copied
* from the request queue to the response queue. If
* not, something bad has happened.
*/
- if (sp->req_header.rqs_entry_type != RQSTYPE_REQUEST) {
+ if (etype != RQSTYPE_REQUEST) {
isp_prt(isp, ISP_LOGERR, notresp,
- sp->req_header.rqs_entry_type, oop, optr,
- nlooked);
- if (isp->isp_dblev & ISP_LOGDEBUG0) {
- isp_print_bytes(isp, "Queue Entry",
- QENTRY_LEN, sp);
- }
+ etype, oop, optr, nlooked);
+ isp_print_bytes(isp,
+ "Request Queue Entry", QENTRY_LEN, sp);
MEMZERO(hp, QENTRY_LEN); /* PERF */
continue;
}
buddaboom = 1;
+ scsi_status = sp->req_scsi_status;
+ completion_status = sp->req_completion_status;
+ req_status_flags = sp->req_status_flags;
+ req_state_flags = sp->req_state_flags;
+ resid = sp->req_resid;
}
- if (sp->req_header.rqs_flags & 0xf) {
-#define _RQS_OFLAGS \
- ~(RQSFLAG_CONTINUATION|RQSFLAG_FULL|RQSFLAG_BADHEADER|RQSFLAG_BADPACKET)
+ if (sp->req_header.rqs_flags & RQSFLAG_MASK) {
if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
isp_prt(isp, ISP_LOGWARN,
"continuation segment");
- WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
+ ISP_WRITE(isp, isp->isp_respoutrp, optr);
continue;
}
if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
@@ -3754,53 +4851,47 @@ again:
*/
}
if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
- isp_prt(isp, ISP_LOGERR, "bad header flag");
+ isp_print_bytes(isp, "bad header flag",
+ QENTRY_LEN, sp);
buddaboom++;
}
if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
- isp_prt(isp, ISP_LOGERR, "bad request packet");
+ isp_print_bytes(isp, "bad request packet",
+ QENTRY_LEN, sp);
buddaboom++;
}
- if (sp->req_header.rqs_flags & _RQS_OFLAGS) {
- isp_prt(isp, ISP_LOGERR,
- "unknown flags (0x%x) in response",
- sp->req_header.rqs_flags);
- buddaboom++;
- }
-#undef _RQS_OFLAGS
}
+
if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) {
- MEMZERO(hp, QENTRY_LEN); /* PERF */
isp_prt(isp, ISP_LOGERR,
- "bad request handle %d (type 0x%x, flags 0x%x)",
- sp->req_handle, sp->req_header.rqs_entry_type,
- sp->req_header.rqs_flags);
- WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
+ "bad request handle %d (type 0x%x)",
+ sp->req_handle, etype);
+ MEMZERO(hp, QENTRY_LEN); /* PERF */
+ ISP_WRITE(isp, isp->isp_respoutrp, optr);
continue;
}
xs = isp_find_xs(isp, sp->req_handle);
if (xs == NULL) {
- u_int8_t ts = sp->req_completion_status & 0xff;
- MEMZERO(hp, QENTRY_LEN); /* PERF */
+ u_int8_t ts = completion_status & 0xff;
/*
* Only whine if this isn't the expected fallout of
* aborting the command.
*/
- if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) {
+ if (etype != RQSTYPE_RESPONSE) {
isp_prt(isp, ISP_LOGERR,
"cannot find handle 0x%x (type 0x%x)",
- sp->req_handle,
- sp->req_header.rqs_entry_type);
+ sp->req_handle, etype);
} else if (ts != RQCS_ABORTED) {
isp_prt(isp, ISP_LOGERR,
"cannot find handle 0x%x (status 0x%x)",
sp->req_handle, ts);
}
- WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
+ MEMZERO(hp, QENTRY_LEN); /* PERF */
+ ISP_WRITE(isp, isp->isp_respoutrp, optr);
continue;
}
isp_destroy_handle(isp, sp->req_handle);
- if (sp->req_status_flags & RQSTF_BUS_RESET) {
+ if (req_status_flags & RQSTF_BUS_RESET) {
XS_SETERR(xs, HBA_BUSRESET);
isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
}
@@ -3808,39 +4899,71 @@ again:
XS_SETERR(xs, HBA_BOTCH);
}
- if (IS_FC(isp) && (sp->req_scsi_status & RQCS_SV)) {
+ resp = NULL;
+ rlen = 0;
+ snsp = NULL;
+ slen = 0;
+ if (IS_24XX(isp) && (scsi_status & (RQCS_RV|RQCS_SV)) != 0) {
+ resp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
+ rlen = ((isp24xx_statusreq_t *)sp)->req_response_len;
+ } else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) {
+ resp = sp->req_response;
+ rlen = sp->req_response_len;
+ }
+ if (IS_FC(isp) && (scsi_status & RQCS_SV) != 0) {
/*
* Fibre Channel F/W doesn't say we got status
* if there's Sense Data instead. I guess they
* think it goes w/o saying.
*/
- sp->req_state_flags |= RQSF_GOT_STATUS;
+ req_state_flags |= RQSF_GOT_STATUS|RQSF_GOT_SENSE;
+ if (IS_24XX(isp)) {
+ snsp =
+ ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
+ snsp += rlen;
+ slen =
+ ((isp24xx_statusreq_t *)sp)->req_sense_len;
+ } else {
+ snsp = sp->req_sense_data;
+ slen = sp->req_sense_len;
+ }
+ } else if (IS_SCSI(isp) && (req_state_flags & RQSF_GOT_SENSE)) {
+ snsp = sp->req_sense_data;
+ slen = sp->req_sense_len;
}
- if (sp->req_state_flags & RQSF_GOT_STATUS) {
- *XS_STSP(xs) = sp->req_scsi_status & 0xff;
+ if (req_state_flags & RQSF_GOT_STATUS) {
+ *XS_STSP(xs) = scsi_status & 0xff;
}
- switch (sp->req_header.rqs_entry_type) {
+ switch (etype) {
case RQSTYPE_RESPONSE:
XS_SET_STATE_STAT(isp, xs, sp);
- isp_parse_status(isp, sp, xs);
+ if (resp && rlen >= 4 &&
+ resp[FCP_RSPNS_CODE_OFFSET] != 0) {
+ isp_prt(isp, ISP_LOGWARN,
+ "%d.%d.%d FCP RESPONSE: 0x%x",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
+ resp[FCP_RSPNS_CODE_OFFSET]);
+ XS_SETERR(xs, HBA_BOTCH);
+ }
+ if (IS_24XX(isp)) {
+ isp_parse_status_24xx(isp,
+ (isp24xx_statusreq_t *)sp, xs, &resid);
+ } else {
+ isp_parse_status(isp, (void *)sp, xs, &resid);
+ }
if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) &&
(*XS_STSP(xs) == SCSI_BUSY)) {
XS_SETERR(xs, HBA_TGTBSY);
}
if (IS_SCSI(isp)) {
- XS_RESID(xs) = sp->req_resid;
- if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
- (*XS_STSP(xs) == SCSI_CHECK) &&
- (sp->req_state_flags & RQSF_GOT_SENSE)) {
- XS_SAVE_SENSE(xs, sp);
- }
+ XS_RESID(xs) = resid;
/*
* A new synchronous rate was negotiated for
* this target. Mark state such that we'll go
* look up that which has changed later.
*/
- if (sp->req_status_flags & RQSTF_NEGOTIATION) {
+ if (req_status_flags & RQSTF_NEGOTIATION) {
int t = XS_TGT(xs);
sdparam *sdp = isp->isp_param;
sdp += XS_CHANNEL(xs);
@@ -3849,26 +4972,26 @@ again:
(1 << XS_CHANNEL(xs));
}
} else {
- if (sp->req_status_flags & RQSF_XFER_COMPLETE) {
+ if (req_status_flags & RQSF_XFER_COMPLETE) {
XS_RESID(xs) = 0;
- } else if (sp->req_scsi_status & RQCS_RESID) {
- XS_RESID(xs) = sp->req_resid;
+ } else if (scsi_status & RQCS_RESID) {
+ XS_RESID(xs) = resid;
} else {
XS_RESID(xs) = 0;
}
- if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
- (*XS_STSP(xs) == SCSI_CHECK) &&
- (sp->req_scsi_status & RQCS_SV)) {
- XS_SAVE_SENSE(xs, sp);
- /* solely for the benefit of debug */
- sp->req_state_flags |= RQSF_GOT_SENSE;
- }
+ }
+ if (snsp && slen) {
+ XS_SAVE_SENSE(xs, snsp, slen);
}
isp_prt(isp, ISP_LOGDEBUG2,
- "asked for %ld got resid %ld", (long) XS_XFRLEN(xs),
- (long) sp->req_resid);
+ "asked for %ld got raw resid %ld settled for %ld",
+ (long) XS_XFRLEN(xs), resid, (long) XS_RESID(xs));
break;
case RQSTYPE_REQUEST:
+ case RQSTYPE_A64:
+ case RQSTYPE_T2RQS:
+ case RQSTYPE_T3RQS:
+ case RQSTYPE_T7RQS:
if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
/*
* Force Queue Full status.
@@ -3879,16 +5002,19 @@ again:
/*
* ????
*/
+ XS_SETERR(xs, HBA_BOTCH);
isp_prt(isp, ISP_LOGDEBUG0,
"Request Queue Entry bounced back");
- XS_SETERR(xs, HBA_BOTCH);
+ if ((isp->isp_dblev & ISP_LOGDEBUG1) == 0) {
+ isp_print_bytes(isp, "Bounced Request",
+ QENTRY_LEN, qe);
+ }
}
XS_RESID(xs) = XS_XFRLEN(xs);
break;
default:
- isp_prt(isp, ISP_LOGWARN,
- "unhandled response queue type 0x%x",
- sp->req_header.rqs_entry_type);
+ isp_print_bytes(isp, "Unhandled Response Type",
+ QENTRY_LEN, qe);
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_BOTCH);
}
@@ -3896,17 +5022,18 @@ again:
}
/*
- * Free any dma resources. As a side effect, this may
- * also do any cache flushing necessary for data coherence. */
+ * Free any DMA resources. As a side effect, this may
+ * also do any cache flushing necessary for data coherence.
+ */
if (XS_XFRLEN(xs)) {
ISP_DMAFREE(isp, xs, sp->req_handle);
}
if (((isp->isp_dblev & (ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
- ((isp->isp_dblev & ISP_LOGDEBUG1) && ((!XS_NOERR(xs)) ||
+ ((isp->isp_dblev & ISP_LOGDEBUG0) && ((!XS_NOERR(xs)) ||
(*XS_STSP(xs) != SCSI_GOOD)))) {
char skey;
- if (sp->req_state_flags & RQSF_GOT_SENSE) {
+ if (req_state_flags & RQSF_GOT_SENSE) {
skey = XS_SNSKEY(xs) & 0xf;
if (skey < 10)
skey += '0';
@@ -3918,8 +5045,7 @@ again:
skey = '.';
}
isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs),
- XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs),
- (ulong)XS_RESID(xs),
+ XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), XS_RESID(xs),
*XS_STSP(xs), skey, XS_ERR(xs));
}
@@ -3938,13 +5064,23 @@ again:
* ISP's notion of what we've seen so far.
*/
if (nlooked) {
- WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
+ ISP_WRITE(isp, isp->isp_respoutrp, optr);
/*
- * While we're at it, read the request queue out pointer.
+ * While we're at it, read the requst queue out pointer.
*/
- isp->isp_reqodx = READ_REQUEST_QUEUE_OUT_POINTER(isp);
- if (isp->isp_rscchiwater < ndone)
+ isp->isp_reqodx = ISP_READ(isp, isp->isp_rqstoutrp);
+ if (isp->isp_rscchiwater < ndone) {
isp->isp_rscchiwater = ndone;
+ }
+ }
+
+out:
+
+ if (IS_24XX(isp)) {
+ ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
+ } else {
+ ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
+ ISP_WRITE(isp, BIU_SEMA, 0);
}
isp->isp_residx = optr;
@@ -3962,7 +5098,7 @@ again:
* Support routines.
*/
-static int
+int
isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
{
int rval = 0;
@@ -3979,26 +5115,32 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
case ASYNC_BUS_RESET:
isp->isp_sendmarker |= (1 << bus);
#ifdef ISP_TARGET_MODE
- if (isp_target_async(isp, bus, mbox))
+ if (isp_target_async(isp, bus, mbox)) {
rval = -1;
+ }
#endif
isp_async(isp, ISPASYNC_BUS_RESET, &bus);
break;
case ASYNC_SYSTEM_ERROR:
-#ifdef ISP_FW_CRASH_DUMP
+ isp->isp_state = ISP_CRASHED;
+ if (IS_FC(isp)) {
+ FCPARAM(isp)->isp_loopstate = LOOP_NIL;
+ FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
+ }
/*
- * If we have crash dumps enabled, it's up to the handler
- * for isp_async to reinit stuff and restart the firmware
- * after performing the crash dump. The reason we do things
- * this way is that we may need to activate a kernel thread
- * to do all the crash dump goop.
+ * Were we waiting for a mailbox command to complete?
+ * If so, it's dead, so wake up the waiter.
+ */
+ if (isp->isp_mboxbsy) {
+ isp->isp_obits = 1;
+ isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
+ MBOX_NOTIFY_COMPLETE(isp);
+ }
+ /*
+ * It's up to the handler for isp_async to reinit stuff and
+ * restart the firmware
*/
isp_async(isp, ISPASYNC_FW_CRASH, NULL);
-#else
- isp_async(isp, ISPASYNC_FW_CRASH, NULL);
- isp_reinit(isp);
- isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
-#endif
rval = -1;
break;
@@ -4016,7 +5158,7 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
* We don't need to be chatty about this- just unlatch things
* and move on.
*/
- mbox = READ_REQUEST_QUEUE_OUT_POINTER(isp);
+ mbox = ISP_READ(isp, isp->isp_rqstoutrp);
break;
case ASYNC_TIMEOUT_RESET:
@@ -4024,8 +5166,9 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
"timeout initiated SCSI bus reset of bus %d", bus);
isp->isp_sendmarker |= (1 << bus);
#ifdef ISP_TARGET_MODE
- if (isp_target_async(isp, bus, mbox))
+ if (isp_target_async(isp, bus, mbox)) {
rval = -1;
+ }
#endif
break;
@@ -4033,8 +5176,9 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
isp_prt(isp, ISP_LOGINFO, "device reset on bus %d", bus);
isp->isp_sendmarker |= (1 << bus);
#ifdef ISP_TARGET_MODE
- if (isp_target_async(isp, bus, mbox))
+ if (isp_target_async(isp, bus, mbox)) {
rval = -1;
+ }
#endif
break;
@@ -4125,29 +5269,33 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
int handle =
(ISP_READ(isp, OUTMAILBOX2) << 16) |
(ISP_READ(isp, OUTMAILBOX1));
- if (isp_target_async(isp, handle, mbox))
+ if (isp_target_async(isp, handle, mbox)) {
rval = -1;
+ } else {
+ /* count it as a fast posting intr */
+ isp->isp_fphccmplt++;
+ }
#else
isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
-#endif
isp->isp_fphccmplt++; /* count it as a fast posting intr */
+#endif
break;
}
+ case ASYNC_LIP_ERROR:
case ASYNC_LIP_F8:
case ASYNC_LIP_OCCURRED:
- FCPARAM(isp)->isp_lipseq =
- ISP_READ(isp, OUTMAILBOX1);
FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
isp->isp_sendmarker = 1;
- isp_mark_getpdb_all(isp);
+ ISP_MARK_PORTDB(isp, 1);
isp_async(isp, ISPASYNC_LIP, NULL);
#ifdef ISP_TARGET_MODE
- if (isp_target_async(isp, bus, mbox))
+ if (isp_target_async(isp, bus, mbox)) {
rval = -1;
+ }
#endif
/*
- * We've had problems with data corruption occurring on
+ * We've had problems with data corruption occuring on
* commands that complete (with no apparent error) after
* we receive a LIP. This has been observed mostly on
* Local Loop topologies. To be safe, let's just mark
@@ -4175,11 +5323,12 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
isp->isp_sendmarker = 1;
FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
- isp_mark_getpdb_all(isp);
+ ISP_MARK_PORTDB(isp, 1);
isp_async(isp, ISPASYNC_LOOP_UP, NULL);
#ifdef ISP_TARGET_MODE
- if (isp_target_async(isp, bus, mbox))
+ if (isp_target_async(isp, bus, mbox)) {
rval = -1;
+ }
#endif
break;
@@ -4187,11 +5336,12 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
isp->isp_sendmarker = 1;
FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
FCPARAM(isp)->isp_loopstate = LOOP_NIL;
- isp_mark_getpdb_all(isp);
+ ISP_MARK_PORTDB(isp, 1);
isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
#ifdef ISP_TARGET_MODE
- if (isp_target_async(isp, bus, mbox))
+ if (isp_target_async(isp, bus, mbox)) {
rval = -1;
+ }
#endif
break;
@@ -4199,50 +5349,49 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
isp->isp_sendmarker = 1;
FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
FCPARAM(isp)->isp_loopstate = LOOP_NIL;
- isp_mark_getpdb_all(isp);
+ ISP_MARK_PORTDB(isp, 1);
isp_async(isp, ISPASYNC_LOOP_RESET, NULL);
#ifdef ISP_TARGET_MODE
- if (isp_target_async(isp, bus, mbox))
+ if (isp_target_async(isp, bus, mbox)) {
rval = -1;
+ }
#endif
break;
case ASYNC_PDB_CHANGED:
isp->isp_sendmarker = 1;
FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
- isp_mark_getpdb_all(isp);
+ ISP_MARK_PORTDB(isp, 1);
isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_PDB);
break;
case ASYNC_CHANGE_NOTIFY:
- /*
- * Not correct, but it will force us to rescan the loop.
- */
- FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
- isp_mark_getpdb_all(isp);
+ if (FCPARAM(isp)->isp_topo == TOPO_F_PORT) {
+ FCPARAM(isp)->isp_loopstate = LOOP_LSCAN_DONE;
+ } else {
+ FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
+ }
+ ISP_MARK_PORTDB(isp, 1);
isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_SNS);
break;
case ASYNC_PTPMODE:
- if (FCPARAM(isp)->isp_onfabric)
- FCPARAM(isp)->isp_topo = TOPO_F_PORT;
- else
- FCPARAM(isp)->isp_topo = TOPO_N_PORT;
- isp_mark_getpdb_all(isp);
+ ISP_MARK_PORTDB(isp, 1);
isp->isp_sendmarker = 1;
FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
#ifdef ISP_TARGET_MODE
- if (isp_target_async(isp, bus, mbox))
+ if (isp_target_async(isp, bus, mbox)) {
rval = -1;
+ }
#endif
isp_prt(isp, ISP_LOGINFO, "Point-to-Point mode");
break;
case ASYNC_CONNMODE:
mbox = ISP_READ(isp, OUTMAILBOX1);
- isp_mark_getpdb_all(isp);
+ ISP_MARK_PORTDB(isp, 1);
switch (mbox) {
case ISP_CONN_LOOP:
isp_prt(isp, ISP_LOGINFO,
@@ -4258,13 +5407,7 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
break;
case ISP_CONN_FATAL:
isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
-#ifdef ISP_FW_CRASH_DUMP
isp_async(isp, ISPASYNC_FW_CRASH, NULL);
-#else
- isp_async(isp, ISPASYNC_FW_CRASH, NULL);
- isp_reinit(isp);
- isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
-#endif
return (-1);
case ISP_CONN_LOOPBACK:
isp_prt(isp, ISP_LOGWARN,
@@ -4281,6 +5424,15 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
break;
+ case ASYNC_RJT_SENT: /* same as ASYNC_QFULL_SENT */
+ if (IS_24XX(isp)) {
+ isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
+ break;
+ } else if (IS_2200(isp)) {
+ isp_prt(isp, ISP_LOGTDEBUG0, "QFULL sent");
+ break;
+ }
+ /* FALLTHROUGH */
default:
isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
break;
@@ -4288,9 +5440,9 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
if (bus & 0x100) {
int i, nh;
- u_int16_t handles[5];
+ u_int16_t handles[16];
- for (nh = 0, i = 1; i < MAX_MAILBOX; i++) {
+ for (nh = 0, i = 1; i < MAX_MAILBOX(isp); i++) {
if ((bus & (1 << i)) == 0) {
continue;
}
@@ -4301,8 +5453,9 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
isp_prt(isp, ISP_LOGDEBUG3,
"fast post completion of %u", handles[i]);
}
- if (isp->isp_fpcchiwater < nh)
+ if (isp->isp_fpcchiwater < nh) {
isp->isp_fpcchiwater = nh;
+ }
} else {
isp->isp_intoasync++;
}
@@ -4315,13 +5468,16 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
* this is not used currently.
*/
-static int
+int
isp_handle_other_response(struct ispsoftc *isp, int type,
- isphdr_t *hp, u_int16_t *optrp)
+ isphdr_t *hp, u_int32_t *optrp)
{
switch (type) {
case RQSTYPE_STATUS_CONT:
- isp_prt(isp, ISP_LOGINFO, "Ignored Continuation Response");
+ isp_prt(isp, ISP_LOGDEBUG0, "Ignored Continuation Response");
+ return (1);
+ case RQSTYPE_MARKER:
+ isp_prt(isp, ISP_LOGDEBUG0, "Marker Response");
return (1);
case RQSTYPE_ATIO:
case RQSTYPE_CTIO:
@@ -4333,6 +5489,9 @@ isp_handle_other_response(struct ispsoftc *isp, int type,
case RQSTYPE_ATIO2:
case RQSTYPE_CTIO2:
case RQSTYPE_CTIO3:
+ case RQSTYPE_CTIO7:
+ case RQSTYPE_ABTS_RCVD:
+ case RQSTYPE_ABTS_RSP:
isp->isp_rsltccmplt++; /* count as a response completion */
#ifdef ISP_TARGET_MODE
if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
@@ -4342,17 +5501,31 @@ isp_handle_other_response(struct ispsoftc *isp, int type,
/* FALLTHROUGH */
case RQSTYPE_REQUEST:
default:
- if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) {
- return (1);
+ USEC_DELAY(100);
+ if (type != isp_get_response_type(isp, hp)) {
+ /*
+ * This is questionable- we're just papering over
+ * something we've seen on SMP linux in target
+ * mode- we don't really know what's happening
+ * here that causes us to think we've gotten
+ * an entry, but that either the entry isn't
+ * filled out yet or our CPU read data is stale.
+ */
+ isp_prt(isp, ISP_LOGINFO,
+ "unstable type in response queue");
+ return (-1);
}
isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
isp_get_response_type(isp, hp));
+ if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) {
+ return (1);
+ }
return (0);
}
}
-static void
-isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
+void
+isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
{
switch (sp->req_completion_status & 0xff) {
case RQCS_COMPLETE:
@@ -4368,6 +5541,7 @@ isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_SELTIMEOUT);
+ *rp = XS_XFRLEN(xs);
}
return;
}
@@ -4380,6 +5554,7 @@ isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
case RQCS_DMA_ERROR:
isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ *rp = XS_XFRLEN(xs);
break;
case RQCS_TRANSPORT_ERROR:
@@ -4435,6 +5610,7 @@ isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
isp_prt(isp, ISP_LOGERR, "%s", buf);
isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf);
+ *rp = XS_XFRLEN(xs);
break;
}
case RQCS_RESET_OCCURRED:
@@ -4445,6 +5621,7 @@ isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_BUSRESET);
}
+ *rp = XS_XFRLEN(xs);
return;
case RQCS_ABORTED:
@@ -4460,15 +5637,8 @@ isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
/*
- * Check to see if we logged out the device.
+ * XXX: Check to see if we logged out of the device.
*/
- if (IS_FC(isp)) {
- if ((sp->req_completion_status & RQSTF_LOGOUT) &&
- FCPARAM(isp)->portdb[XS_TGT(xs)].valid &&
- FCPARAM(isp)->portdb[XS_TGT(xs)].fabric_dev) {
- FCPARAM(isp)->portdb[XS_TGT(xs)].relogin = 1;
- }
- }
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_CMDTIMEOUT);
}
@@ -4675,40 +5845,214 @@ isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
* No such port on the loop. Moral equivalent of SELTIMEO
*/
case RQCS_PORT_LOGGED_OUT:
+ {
+ const char *reason;
+ u_int8_t sts = sp->req_completion_status & 0xff;
+
/*
* It was there (maybe)- treat as a selection timeout.
*/
- if ((sp->req_completion_status & 0xff) == RQCS_PORT_UNAVAILABLE)
- isp_prt(isp, ISP_LOGINFO,
- "port unavailable for target %d", XS_TGT(xs));
- else
- isp_prt(isp, ISP_LOGINFO,
- "port logout for target %d", XS_TGT(xs));
+ if (sts == RQCS_PORT_UNAVAILABLE) {
+ reason = "unavailable";
+ } else {
+ reason = "logout";
+ }
+
+ isp_prt(isp, ISP_LOGINFO, "port %s for target %d",
+ reason, XS_TGT(xs));
+
/*
* If we're on a local loop, force a LIP (which is overkill)
* to force a re-login of this unit. If we're on fabric,
- * then we'll have to relogin as a matter of course.
+ * then we'll have to log in again as a matter of course.
*/
if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
mbreg_t mbs;
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_INIT_LIP;
+ if (FCPARAM(isp)->isp_2klogin) {
+ mbs.ibits = (1 << 10);
+ }
+ mbs.logval = MBLOGALL;
isp_mboxcmd_qnw(isp, &mbs, 1);
}
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_SELTIMEOUT);
+ }
+ return;
+ }
+ case RQCS_PORT_CHANGED:
+ isp_prt(isp, ISP_LOGWARN,
+ "port changed for target %d", XS_TGT(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_SELTIMEOUT);
+ }
+ return;
+
+ case RQCS_PORT_BUSY:
+ isp_prt(isp, ISP_LOGWARN,
+ "port busy for target %d", XS_TGT(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_TGTBSY);
+ }
+ return;
+
+ default:
+ isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
+ sp->req_completion_status);
+ break;
+ }
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_BOTCH);
+ }
+}
+
+void
+isp_parse_status_24xx(struct ispsoftc *isp, isp24xx_statusreq_t *sp,
+ XS_T *xs, long *rp)
+{
+ int ru_marked, sv_marked;
+ switch (sp->req_completion_status) {
+ case RQCS_COMPLETE:
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_NOERROR);
+ }
+ return;
+
+ case RQCS_DMA_ERROR:
+ isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ break;
+ case RQCS_TRANSPORT_ERROR:
+ isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ break;
+
+ case RQCS_RESET_OCCURRED:
+ isp_prt(isp, ISP_LOGWARN,
+ "bus reset destroyed command for %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_BUSRESET);
+ }
+ return;
+
+ case RQCS_ABORTED:
+ isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_ABORTED);
+ }
+ return;
+
+ case RQCS_TIMEOUT:
+ isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_CMDTIMEOUT);
+ }
+ return;
+
+ case RQCS_DATA_OVERRUN:
+ XS_RESID(xs) = sp->req_resid;
+ isp_prt(isp, ISP_LOGERR,
+ "data overrun for command on %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_DATAOVR);
+ }
+ return;
+
+ case RQCS_24XX_DRE: /* data reassembly error */
+ isp_prt(isp, ISP_LOGERR, "data reassembly error for target %d",
+ XS_TGT(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_ABORTED);
+ }
+ *rp = XS_XFRLEN(xs);
+ return;
+
+ case RQCS_24XX_TABORT: /* aborted by target */
+ isp_prt(isp, ISP_LOGERR, "target %d sent ABTS",
+ XS_TGT(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_ABORTED);
+ }
+ return;
+
+ case RQCS_DATA_UNDERRUN:
+ ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
/*
- * Probably overkill.
+ * We can get an underrun w/o things being marked
+ * if we got a non-zero status.
*/
- isp->isp_sendmarker = 1;
- FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
- isp_mark_getpdb_all(isp);
- isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
+ sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
+ if ((ru_marked == 0 && sv_marked == 0) ||
+ (sp->req_resid > XS_XFRLEN(xs))) {
+ isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
+ XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
+ (ru_marked)? "marked" : "not marked");
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_BOTCH);
+ }
+ return;
+ }
+ XS_RESID(xs) = sp->req_resid;
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "%d.%d.%d data underrun (%d) for command 0x%x",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
+ sp->req_resid, XS_CDBP(xs)[0] & 0xff);
if (XS_NOERR(xs)) {
- XS_SETERR(xs, HBA_SELTIMEOUT);
+ XS_SETERR(xs, HBA_NOERROR);
}
return;
+ case RQCS_PORT_UNAVAILABLE:
+ /*
+ * No such port on the loop. Moral equivalent of SELTIMEO
+ */
+ case RQCS_PORT_LOGGED_OUT:
+ {
+ const char *reason;
+ u_int8_t sts = sp->req_completion_status & 0xff;
+
+ /*
+ * It was there (maybe)- treat as a selection timeout.
+ */
+ if (sts == RQCS_PORT_UNAVAILABLE) {
+ reason = "unavailable";
+ } else {
+ reason = "logout";
+ }
+
+ isp_prt(isp, ISP_LOGINFO, "port %s for target %d",
+ reason, XS_TGT(xs));
+
+ /*
+ * If we're on a local loop, force a LIP (which is overkill)
+ * to force a re-login of this unit. If we're on fabric,
+ * then we'll have to log in again as a matter of course.
+ */
+ if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
+ FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
+ mbreg_t mbs;
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_INIT_LIP;
+ if (FCPARAM(isp)->isp_2klogin) {
+ mbs.ibits = (1 << 10);
+ }
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd_qnw(isp, &mbs, 1);
+ }
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_SELTIMEOUT);
+ }
+ return;
+ }
case RQCS_PORT_CHANGED:
isp_prt(isp, ISP_LOGWARN,
"port changed for target %d", XS_TGT(xs));
@@ -4717,10 +6061,22 @@ isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
}
return;
- case RQCS_PORT_BUSY:
+
+ case RQCS_24XX_ENOMEM: /* f/w resource unavailable */
isp_prt(isp, ISP_LOGWARN,
- "port busy for target %d", XS_TGT(xs));
+ "f/w resource unavailable for target %d", XS_TGT(xs));
+ if (XS_NOERR(xs)) {
+ *XS_STSP(xs) = SCSI_BUSY;
+ XS_SETERR(xs, HBA_TGTBSY);
+ }
+ return;
+
+ case RQCS_24XX_TMO: /* task management overrun */
+ isp_prt(isp, ISP_LOGWARN,
+ "command for target %d overlapped task management",
+ XS_TGT(xs));
if (XS_NOERR(xs)) {
+ *XS_STSP(xs) = SCSI_BUSY;
XS_SETERR(xs, HBA_TGTBSY);
}
return;
@@ -4735,7 +6091,7 @@ isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
}
}
-static void
+void
isp_fastpost_complete(struct ispsoftc *isp, u_int16_t fph)
{
XS_T *xs;
@@ -4745,7 +6101,7 @@ isp_fastpost_complete(struct ispsoftc *isp, u_int16_t fph)
}
xs = isp_find_xs(isp, fph);
if (xs == NULL) {
- isp_prt(isp, ISP_LOGWARN,
+ isp_prt(isp, ISP_LOGDEBUG1,
"Command for fast post handle 0x%x not found", fph);
return;
}
@@ -4768,15 +6124,17 @@ isp_fastpost_complete(struct ispsoftc *isp, u_int16_t fph)
isp_done(xs);
}
-static int
+int
isp_mbox_continue(struct ispsoftc *isp)
{
mbreg_t mbs;
u_int16_t *ptr;
+ u_int32_t offset;
switch (isp->isp_lastmbxcmd) {
case MBOX_WRITE_RAM_WORD:
case MBOX_READ_RAM_WORD:
+ case MBOX_WRITE_RAM_WORD_EXTENDED:
case MBOX_READ_RAM_WORD_EXTENDED:
break;
default:
@@ -4787,12 +6145,15 @@ isp_mbox_continue(struct ispsoftc *isp)
return (-1);
}
-
/*
* Clear the previous interrupt.
*/
- ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- ISP_WRITE(isp, BIU_SEMA, 0);
+ if (IS_24XX(isp)) {
+ ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
+ } else {
+ ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
+ ISP_WRITE(isp, BIU_SEMA, 0);
+ }
/*
* Continue with next word.
@@ -4801,27 +6162,46 @@ isp_mbox_continue(struct ispsoftc *isp)
ptr = isp->isp_mbxworkp;
switch (isp->isp_lastmbxcmd) {
case MBOX_WRITE_RAM_WORD:
- mbs.param[2] = *ptr++;
- mbs.param[1] = isp->isp_mbxwrk1++;
+ mbs.param[1] = isp->isp_mbxwrk1++;;
+ mbs.param[2] = *ptr++;;
break;
case MBOX_READ_RAM_WORD:
- case MBOX_READ_RAM_WORD_EXTENDED:
*ptr++ = isp->isp_mboxtmp[2];
mbs.param[1] = isp->isp_mbxwrk1++;
break;
+ case MBOX_WRITE_RAM_WORD_EXTENDED:
+ offset = isp->isp_mbxwrk1;
+ offset |= isp->isp_mbxwrk8 << 16;
+
+ mbs.param[2] = *ptr++;;
+ mbs.param[1] = offset;
+ mbs.param[8] = offset >> 16;
+ isp->isp_mbxwrk1 = ++offset;
+ isp->isp_mbxwrk8 = offset >> 16;
+ break;
+ case MBOX_READ_RAM_WORD_EXTENDED:
+ offset = isp->isp_mbxwrk1;
+ offset |= isp->isp_mbxwrk8 << 16;
+
+ *ptr++ = isp->isp_mboxtmp[2];
+ mbs.param[1] = offset;
+ mbs.param[8] = offset >> 16;
+ isp->isp_mbxwrk1 = ++offset;
+ isp->isp_mbxwrk8 = offset >> 16;
+ break;
}
isp->isp_mbxworkp = ptr;
+ isp->isp_mbxwrk0--;
mbs.param[0] = isp->isp_lastmbxcmd;
- isp->isp_mbxwrk0 -= 1;
+ mbs.logval = MBLOGALL;
isp_mboxcmd_qnw(isp, &mbs, 0);
return (0);
}
-
-#define HIBYT(x) ((x) >> 0x8)
-#define LOBYT(x) ((x) & 0xff)
-#define ISPOPMAP(a, b) (((a) << 8) | (b))
-static const u_int16_t mbpscsi[] = {
+#define HIWRD(x) ((x) >> 16)
+#define LOWRD(x) ((x) & 0xffff)
+#define ISPOPMAP(a, b) (((a) << 16) | (b))
+static const u_int32_t mbpscsi[] = {
ISPOPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */
ISPOPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */
ISPOPMAP(0x03, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */
@@ -4829,7 +6209,7 @@ static const u_int16_t mbpscsi[] = {
ISPOPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */
ISPOPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */
ISPOPMAP(0x3f, 0x3f), /* 0x06: MBOX_MAILBOX_REG_TEST */
- ISPOPMAP(0x03, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */
+ ISPOPMAP(0x07, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */
ISPOPMAP(0x01, 0x0f), /* 0x08: MBOX_ABOUT_FIRMWARE */
ISPOPMAP(0x00, 0x00), /* 0x09: */
ISPOPMAP(0x00, 0x00), /* 0x0a: */
@@ -4906,7 +6286,7 @@ static const u_int16_t mbpscsi[] = {
ISPOPMAP(0xdf, 0xdf), /* 0x51: DUMP RAM A64 */
ISPOPMAP(0xdf, 0xff), /* 0x52: INITIALIZE REQUEST QUEUE A64 */
ISPOPMAP(0xef, 0xff), /* 0x53: INITIALIZE RESPONSE QUEUE A64 */
- ISPOPMAP(0xcf, 0x01), /* 0x54: EXECUTE IOCB A64 */
+ ISPOPMAP(0xcf, 0x01), /* 0x54: EXECUCUTE COMMAND IOCB A64 */
ISPOPMAP(0x07, 0x01), /* 0x55: ENABLE TARGET MODE */
ISPOPMAP(0x03, 0x0f), /* 0x56: GET TARGET STATUS */
ISPOPMAP(0x00, 0x00), /* 0x57: */
@@ -4922,8 +6302,8 @@ static const u_int16_t mbpscsi[] = {
#define ISP_STRIPPED
#endif
-#ifndef ISP_STRIPPED
-static char *scsi_mbcmd_names[] = {
+#ifndef ISP_STRIPPED
+static const char *scsi_mbcmd_names[] = {
"NO-OP",
"LOAD RAM",
"EXEC FIRMWARE",
@@ -5021,23 +6401,23 @@ static char *scsi_mbcmd_names[] = {
};
#endif
-static const u_int16_t mbpfc[] = {
+static const u_int32_t mbpfc[] = {
ISPOPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */
ISPOPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */
- ISPOPMAP(0x03, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */
+ ISPOPMAP(0x0f, 0x01), /* 0x02: MBOX_EXEC_FIRMWARE */
ISPOPMAP(0xdf, 0x01), /* 0x03: MBOX_DUMP_RAM */
ISPOPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */
ISPOPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */
ISPOPMAP(0xff, 0xff), /* 0x06: MBOX_MAILBOX_REG_TEST */
- ISPOPMAP(0x03, 0x05), /* 0x07: MBOX_VERIFY_CHECKSUM */
+ ISPOPMAP(0x03, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */
ISPOPMAP(0x01, 0x4f), /* 0x08: MBOX_ABOUT_FIRMWARE */
- ISPOPMAP(0xdf, 0x01), /* 0x09: LOAD RAM */
+ ISPOPMAP(0xdf, 0x01), /* 0x09: MBOX_LOAD_RISC_RAM_2100 */
ISPOPMAP(0xdf, 0x01), /* 0x0a: DUMP RAM */
- ISPOPMAP(0x00, 0x00), /* 0x0b: */
+ ISPOPMAP(0x1ff, 0x01), /* 0x0b: MBOX_LOAD_RISC_RAM */
ISPOPMAP(0x00, 0x00), /* 0x0c: */
- ISPOPMAP(0x00, 0x00), /* 0x0d: */
+ ISPOPMAP(0x10f, 0x01), /* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
ISPOPMAP(0x01, 0x05), /* 0x0e: MBOX_CHECK_FIRMWARE */
- ISPOPMAP(0x03, 0x07), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED(1) */
+ ISPOPMAP(0x10f, 0x05), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
ISPOPMAP(0x1f, 0x11), /* 0x10: MBOX_INIT_REQ_QUEUE */
ISPOPMAP(0x2f, 0x21), /* 0x11: MBOX_INIT_RES_QUEUE */
ISPOPMAP(0x0f, 0x01), /* 0x12: MBOX_EXECUTE_IOCB */
@@ -5088,8 +6468,8 @@ static const u_int16_t mbpfc[] = {
ISPOPMAP(0x00, 0x00), /* 0x3f: */
ISPOPMAP(0x03, 0x01), /* 0x40: MBOX_LOOP_PORT_BYPASS */
ISPOPMAP(0x03, 0x01), /* 0x41: MBOX_LOOP_PORT_ENABLE */
- ISPOPMAP(0x03, 0x07), /* 0x42: MBOX_GET_RESOURCE_COUNTS */
- ISPOPMAP(0x01, 0x01), /* 0x43: MBOX_REQUEST_NON_PARTICIPATING_MODE */
+ ISPOPMAP(0x03, 0x07), /* 0x42: MBOX_GET_RESOURCE_COUNT */
+ ISPOPMAP(0x01, 0x01), /* 0x43: MBOX_REQUEST_OFFLINE_MODE */
ISPOPMAP(0x00, 0x00), /* 0x44: */
ISPOPMAP(0x00, 0x00), /* 0x45: */
ISPOPMAP(0x00, 0x00), /* 0x46: */
@@ -5118,7 +6498,7 @@ static const u_int16_t mbpfc[] = {
ISPOPMAP(0x07, 0x03), /* 0x5d: MBOX_GET_SET_DATA_RATE */
ISPOPMAP(0x00, 0x00), /* 0x5e: */
ISPOPMAP(0x00, 0x00), /* 0x5f: */
- ISPOPMAP(0xfd, 0x31), /* 0x60: MBOX_INIT_FIRMWARE */
+ ISPOPMAP(0xcd, 0x01), /* 0x60: MBOX_INIT_FIRMWARE */
ISPOPMAP(0x00, 0x00), /* 0x61: */
ISPOPMAP(0x01, 0x01), /* 0x62: MBOX_INIT_LIP */
ISPOPMAP(0xcd, 0x03), /* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
@@ -5148,18 +6528,19 @@ static const u_int16_t mbpfc[] = {
ISPOPMAP(0x00, 0x00), /* 0x7b: */
ISPOPMAP(0x4f, 0x03), /* 0x7c: Get ID List */
ISPOPMAP(0xcf, 0x01), /* 0x7d: SEND LFA */
- ISPOPMAP(0x07, 0x01) /* 0x7e: Lun RESET */
+ ISPOPMAP(0x0f, 0x01) /* 0x7e: LUN RESET */
};
/*
* Footnotes
*
* (1): this sets bits 21..16 in mailbox register #8, which we nominally
* do not access at this time in the core driver. The caller is
- * responsible for setting this register first (Gross!).
+ * responsible for setting this register first (Gross!). The assumption
+ * is that we won't overflow.
*/
-#ifndef ISP_STRIPPED
-static char *fc_mbcmd_names[] = {
+#ifndef ISP_STRIPPED
+static const char *fc_mbcmd_names[] = {
"NO-OP",
"LOAD RAM",
"EXEC FIRMWARE",
@@ -5171,7 +6552,7 @@ static char *fc_mbcmd_names[] = {
"ABOUT FIRMWARE",
"LOAD RAM",
"DUMP RAM",
- NULL,
+ "WRITE RAM WORD EXTENDED",
NULL,
"READ RAM WORD EXTENDED",
"CHECK FIRMWARE",
@@ -5226,12 +6607,12 @@ static char *fc_mbcmd_names[] = {
NULL,
"LOOP PORT BYPASS",
"LOOP PORT ENABLE",
- "GET RESOURCE COUNTS",
+ "GET RESOURCE COUNT",
"REQUEST NON PARTICIPATING MODE",
NULL,
NULL,
NULL,
- "GET PORT DATABASE,, ENHANCED",
+ "GET PORT DATABASE ENHANCED",
NULL,
NULL,
NULL,
@@ -5290,26 +6671,24 @@ static char *fc_mbcmd_names[] = {
};
#endif
-static void
+void
isp_mboxcmd_qnw(struct ispsoftc *isp, mbreg_t *mbp, int nodelay)
{
- unsigned int lim, ibits, obits, box, opcode;
- const u_int16_t *mcp;
+ unsigned int ibits, obits, box, opcode;
+ const u_int32_t *mcp;
if (IS_FC(isp)) {
mcp = mbpfc;
- lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
} else {
mcp = mbpscsi;
- lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
}
opcode = mbp->param[0];
- ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
- obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
- for (box = 0; box < MAX_MAILBOX; box++) {
+ ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
+ obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
+ ibits |= mbp->ibits;
+ obits |= mbp->obits;
+ for (box = 0; box < MAX_MAILBOX(isp); box++) {
if (ibits & (1 << box)) {
- isp_prt(isp, ISP_LOGDEBUG1, "IN mbox %d = 0x%x", box,
- mbp->param[box]);
ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
}
if (nodelay == 0) {
@@ -5321,7 +6700,11 @@ isp_mboxcmd_qnw(struct ispsoftc *isp, mbreg_t *mbp, int nodelay)
isp->isp_obits = obits;
isp->isp_mboxbsy = 1;
}
- ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
+ if (IS_24XX(isp)) {
+ ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
+ } else {
+ ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
+ }
/*
* Oddly enough, if we're not delaying for an answer,
* delay a bit to give the f/w a chance to pick up the
@@ -5332,12 +6715,13 @@ isp_mboxcmd_qnw(struct ispsoftc *isp, mbreg_t *mbp, int nodelay)
}
}
-static void
-isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
+void
+isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp)
{
- char *cname, *xname, tname[16], mname[16];
+ const char *cname, *xname;
+ char tname[16], mname[16];
unsigned int lim, ibits, obits, box, opcode;
- const u_int16_t *mcp;
+ const u_int32_t *mcp;
if (IS_FC(isp)) {
mcp = mbpfc;
@@ -5353,8 +6737,14 @@ isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
return;
}
- ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
- obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
+ ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
+ obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
+
+ /*
+ * Pick up any additional bits that the caller might have set.
+ */
+ ibits |= mbp->ibits;
+ obits |= mbp->obits;
if (ibits == 0 && obits == 0) {
mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
@@ -5365,10 +6755,15 @@ isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
/*
* Get exclusive usage of mailbox registers.
*/
- MBOX_ACQUIRE(isp);
+ if (MBOX_ACQUIRE(isp)) {
+ mbp->param[0] = MBOX_REGS_BUSY;
+ goto out;
+ }
- for (box = 0; box < MAX_MAILBOX; box++) {
+ for (box = 0; box < MAX_MAILBOX(isp); box++) {
if (ibits & (1 << box)) {
+ isp_prt(isp, ISP_LOGDEBUG1, "IN mbox %d = 0x%04x", box,
+ mbp->param[box]);
ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
}
isp->isp_mboxtmp[box] = mbp->param[box] = 0;
@@ -5385,39 +6780,43 @@ isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
/*
* Set Host Interrupt condition so that RISC will pick up mailbox regs.
*/
- ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
+ if (IS_24XX(isp)) {
+ ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
+ } else {
+ ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
+ }
/*
* While we haven't finished the command, spin our wheels here.
*/
- MBOX_WAIT_COMPLETE(isp);
+ MBOX_WAIT_COMPLETE(isp, mbp);
- if (isp->isp_mboxbsy) {
- /*
- * Command timed out.
- */
- isp->isp_mboxbsy = 0;
+ /*
+ * Did the command time out?
+ */
+ if (mbp->param[0] == MBOX_TIMEOUT) {
MBOX_RELEASE(isp);
- return;
+ goto out;
}
/*
* Copy back output registers.
*/
- for (box = 0; box < MAX_MAILBOX; box++) {
+ for (box = 0; box < MAX_MAILBOX(isp); box++) {
if (obits & (1 << box)) {
mbp->param[box] = isp->isp_mboxtmp[box];
- isp_prt(isp, ISP_LOGDEBUG1, "OUT mbox %d = 0x%x", box,
+ isp_prt(isp, ISP_LOGDEBUG1, "OUT mbox %d = 0x%04x", box,
mbp->param[box]);
}
}
MBOX_RELEASE(isp);
-
- if (logmask == 0 || opcode == MBOX_EXEC_FIRMWARE) {
+ out:
+ isp->isp_mboxbsy = 0;
+ if (mbp->logval == 0 || opcode == MBOX_EXEC_FIRMWARE) {
return;
}
-#ifdef ISP_STRIPPED
+#ifdef ISP_STRIPPED
cname = NULL;
#else
cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
@@ -5435,38 +6834,49 @@ isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
case MBOX_COMMAND_COMPLETE:
break;
case MBOX_INVALID_COMMAND:
- if (logmask & MBLOGMASK(MBOX_COMMAND_COMPLETE))
+ if (mbp->logval & MBLOGMASK(MBOX_COMMAND_COMPLETE)) {
xname = "INVALID COMMAND";
+ }
break;
case MBOX_HOST_INTERFACE_ERROR:
- if (logmask & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR))
+ if (mbp->logval & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR)) {
xname = "HOST INTERFACE ERROR";
+ }
break;
case MBOX_TEST_FAILED:
- if (logmask & MBLOGMASK(MBOX_TEST_FAILED))
+ if (mbp->logval & MBLOGMASK(MBOX_TEST_FAILED)) {
xname = "TEST FAILED";
+ }
break;
case MBOX_COMMAND_ERROR:
- if (logmask & MBLOGMASK(MBOX_COMMAND_ERROR))
+ if (mbp->logval & MBLOGMASK(MBOX_COMMAND_ERROR)) {
xname = "COMMAND ERROR";
+ }
break;
case MBOX_COMMAND_PARAM_ERROR:
- if (logmask & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR))
+ if (mbp->logval & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR)) {
xname = "COMMAND PARAMETER ERROR";
+ }
break;
case MBOX_LOOP_ID_USED:
- if (logmask & MBLOGMASK(MBOX_LOOP_ID_USED))
+ if (mbp->logval & MBLOGMASK(MBOX_LOOP_ID_USED)) {
xname = "LOOP ID ALREADY IN USE";
+ }
break;
case MBOX_PORT_ID_USED:
- if (logmask & MBLOGMASK(MBOX_PORT_ID_USED))
+ if (mbp->logval & MBLOGMASK(MBOX_PORT_ID_USED)) {
xname = "PORT ID ALREADY IN USE";
+ }
break;
case MBOX_ALL_IDS_USED:
- if (logmask & MBLOGMASK(MBOX_ALL_IDS_USED))
+ if (mbp->logval & MBLOGMASK(MBOX_ALL_IDS_USED)) {
xname = "ALL LOOP IDS IN USE";
+ }
+ break;
+ case MBOX_REGS_BUSY:
+ xname = "REGISTERS BUSY";
break;
- case 0: /* special case */
+ case MBOX_TIMEOUT:
xname = "TIMEOUT";
break;
default:
@@ -5474,12 +6884,13 @@ isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
xname = mname;
break;
}
- if (xname)
+ if (xname) {
isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
cname, xname);
+ }
}
-static void
+void
isp_fw_state(struct ispsoftc *isp)
{
if (IS_FC(isp)) {
@@ -5488,14 +6899,15 @@ isp_fw_state(struct ispsoftc *isp)
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_GET_FW_STATE;
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
fcp->isp_fwstate = mbs.param[1];
}
}
}
-static void
+void
isp_update(struct ispsoftc *isp)
{
int bus, upmask;
@@ -5508,7 +6920,7 @@ isp_update(struct ispsoftc *isp)
}
}
-static void
+void
isp_update_bus(struct ispsoftc *isp, int bus)
{
int tgt;
@@ -5550,17 +6962,16 @@ isp_update_bus(struct ispsoftc *isp, int bus)
*/
if (sdp->isp_devparam[tgt].dev_refresh) {
mbs.param[0] = MBOX_GET_TARGET_PARAMS;
- sdp->isp_devparam[tgt].dev_refresh = 0;
get = 1;
} else if (sdp->isp_devparam[tgt].dev_update) {
mbs.param[0] = MBOX_SET_TARGET_PARAMS;
+
/*
* Make sure goal_flags has "Renegotiate on Error"
* on and "Freeze Queue on Error" off.
*/
sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
-
mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
/*
@@ -5594,26 +7005,31 @@ isp_update_bus(struct ispsoftc *isp, int bus)
"bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
bus, tgt, mbs.param[2], mbs.param[3] >> 8,
mbs.param[3] & 0xff);
- sdp->isp_devparam[tgt].dev_update = 0;
- sdp->isp_devparam[tgt].dev_refresh = 1;
get = 0;
} else {
continue;
}
mbs.param[1] = (bus << 15) | (tgt << 8);
- isp_mboxcmd(isp, &mbs, MBLOGALL);
+ mbs.logval = MBLOGALL;
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ continue;
+ }
if (get == 0) {
isp->isp_sendmarker |= (1 << bus);
- continue;
+ sdp->isp_devparam[tgt].dev_update = 0;
+ sdp->isp_devparam[tgt].dev_refresh = 1;
+ } else {
+ sdp->isp_devparam[tgt].dev_refresh = 0;
+ flags = mbs.param[2];
+ period = mbs.param[3] & 0xff;
+ offset = mbs.param[3] >> 8;
+ sdp->isp_devparam[tgt].actv_flags = flags;
+ sdp->isp_devparam[tgt].actv_period = period;
+ sdp->isp_devparam[tgt].actv_offset = offset;
+ get = (bus << 16) | tgt;
+ (void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get);
}
- flags = mbs.param[2];
- period = mbs.param[3] & 0xff;
- offset = mbs.param[3] >> 8;
- sdp->isp_devparam[tgt].actv_flags = flags;
- sdp->isp_devparam[tgt].actv_period = period;
- sdp->isp_devparam[tgt].actv_offset = offset;
- get = (bus << 16) | tgt;
- (void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get);
}
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
@@ -5625,100 +7041,16 @@ isp_update_bus(struct ispsoftc *isp, int bus)
}
}
-#ifndef DEFAULT_FRAMESIZE
-#define DEFAULT_FRAMESIZE(isp) ICB_DFLT_FRMLEN
-#endif
#ifndef DEFAULT_EXEC_THROTTLE
#define DEFAULT_EXEC_THROTTLE(isp) ISP_EXEC_THROTTLE
#endif
-static void
+void
isp_setdfltparm(struct ispsoftc *isp, int channel)
{
int tgt;
sdparam *sdp;
- if (IS_FC(isp)) {
- fcparam *fcp = (fcparam *) isp->isp_param;
- int nvfail;
-
- fcp += channel;
- if (fcp->isp_gotdparms) {
- return;
- }
- fcp->isp_gotdparms = 1;
- fcp->isp_maxfrmlen = DEFAULT_FRAMESIZE(isp);
- fcp->isp_maxalloc = ICB_DFLT_ALLOC;
- fcp->isp_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
- fcp->isp_retry_delay = ICB_DFLT_RDELAY;
- fcp->isp_retry_count = ICB_DFLT_RCOUNT;
- /* Platform specific.... */
- fcp->isp_loopid = DEFAULT_LOOPID(isp);
- fcp->isp_nodewwn = DEFAULT_NODEWWN(isp);
- fcp->isp_portwwn = DEFAULT_PORTWWN(isp);
- fcp->isp_fwoptions = 0;
- fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
- fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
- fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
-#ifndef ISP_NO_FASTPOST_FC
- fcp->isp_fwoptions |= ICBOPT_FAST_POST;
-#endif
- if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
- fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
-
- /*
- * Make sure this is turned off now until we get
- * extended options from NVRAM
- */
- fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
-
- /*
- * Now try and read NVRAM unless told to not do so.
- * This will set fcparam's isp_nodewwn && isp_portwwn.
- */
- if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
- nvfail = isp_read_nvram(isp);
- if (nvfail)
- isp->isp_confopts |= ISP_CFG_NONVRAM;
- } else {
- nvfail = 1;
- }
- /*
- * Set node && port to override platform set defaults
- * unless the nvram read failed (or none was done),
- * or the platform code wants to use what had been
- * set in the defaults.
- */
- if (nvfail) {
- isp->isp_confopts |= ISP_CFG_OWNWWPN|ISP_CFG_OWNWWNN;
- }
- if (isp->isp_confopts & ISP_CFG_OWNWWNN) {
- isp_prt(isp, ISP_LOGCONFIG, "Using Node WWN 0x%08x%08x",
- (u_int32_t) (DEFAULT_NODEWWN(isp) >> 32),
- (u_int32_t) (DEFAULT_NODEWWN(isp) & 0xffffffff));
- ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
- } else {
- /*
- * We always start out with values derived
- * from NVRAM or our platform default.
- */
- ISP_NODEWWN(isp) = fcp->isp_nodewwn;
- }
- if (isp->isp_confopts & ISP_CFG_OWNWWPN) {
- isp_prt(isp, ISP_LOGCONFIG, "Using Port WWN 0x%08x%08x",
- (u_int32_t) (DEFAULT_PORTWWN(isp) >> 32),
- (u_int32_t) (DEFAULT_PORTWWN(isp) & 0xffffffff));
- ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
- } else {
- /*
- * We always start out with values derived
- * from NVRAM or our platform default.
- */
- ISP_PORTWWN(isp) = fcp->isp_portwwn;
- }
- return;
- }
-
sdp = (sdparam *) isp->isp_param;
sdp += channel;
@@ -5729,7 +7061,7 @@ isp_setdfltparm(struct ispsoftc *isp, int channel)
return;
}
sdp->isp_gotdparms = 1;
-
+ sdp->isp_bad_nvram = 0;
/*
* Establish some default parameters.
*/
@@ -5769,6 +7101,7 @@ isp_setdfltparm(struct ispsoftc *isp, int channel)
if (isp_read_nvram(isp) == 0) {
return;
}
+ sdp->isp_bad_nvram = 1;
}
/*
@@ -5779,7 +7112,8 @@ isp_setdfltparm(struct ispsoftc *isp, int channel)
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_GET_ACT_NEG_STATE;
- isp_mboxcmd(isp, &mbs, MBLOGNONE);
+ mbs.logval = MBLOGNONE;
+ isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
sdp->isp_req_ack_active_neg = 1;
sdp->isp_data_line_active_neg = 1;
@@ -5817,7 +7151,7 @@ isp_setdfltparm(struct ispsoftc *isp, int channel)
/*
* We default to Wide/Fast for versions less than a 1040
- * (unless its SBus).
+ * (unless it's SBus).
*/
if (IS_ULTRA3(isp)) {
off = ISP_80M_SYNCPARMS >> 8;
@@ -5852,20 +7186,125 @@ isp_setdfltparm(struct ispsoftc *isp, int channel)
}
}
+#ifndef DEFAULT_FRAMESIZE
+#define DEFAULT_FRAMESIZE(isp) ICB_DFLT_FRMLEN
+#endif
+void
+isp_setdfltfcparm(struct ispsoftc *isp)
+{
+ fcparam *fcp = FCPARAM(isp);
+
+ if (fcp->isp_gotdparms) {
+ return;
+ }
+ fcp->isp_gotdparms = 1;
+ fcp->isp_bad_nvram = 0;
+ fcp->isp_maxfrmlen = DEFAULT_FRAMESIZE(isp);
+ fcp->isp_maxalloc = ICB_DFLT_ALLOC;
+ fcp->isp_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
+ fcp->isp_retry_delay = ICB_DFLT_RDELAY;
+ fcp->isp_retry_count = ICB_DFLT_RCOUNT;
+ /* Platform specific.... */
+ fcp->isp_loopid = DEFAULT_LOOPID(isp);
+ fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp);
+ fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp);
+ fcp->isp_fwoptions = 0;
+ fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
+ fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
+ fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
+ fcp->isp_fwoptions |= ICBOPT_FAST_POST;
+ if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
+ fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
+ }
+
+ /*
+ * Make sure this is turned off now until we get
+ * extended options from NVRAM
+ */
+ fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
+
+ /*
+ * Now try and read NVRAM unless told to not do so.
+ * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
+ */
+ if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
+ int i, j = 0;
+ /*
+ * Give a couple of tries at reading NVRAM.
+ */
+ for (i = 0; i < 2; i++) {
+ j = isp_read_nvram(isp);
+ if (j == 0) {
+ break;
+ }
+ }
+ if (j) {
+ fcp->isp_bad_nvram = 1;
+ isp->isp_confopts |= ISP_CFG_NONVRAM;
+ isp->isp_confopts |= ISP_CFG_OWNWWPN;
+ isp->isp_confopts |= ISP_CFG_OWNWWNN;
+ }
+ } else {
+ isp->isp_confopts |= ISP_CFG_OWNWWPN|ISP_CFG_OWNWWNN;
+ }
+
+ /*
+ * Set node && port to override platform set defaults
+ * unless the nvram read failed (or none was done),
+ * or the platform code wants to use what had been
+ * set in the defaults.
+ */
+ if (isp->isp_confopts & ISP_CFG_OWNWWNN) {
+ isp_prt(isp, ISP_LOGCONFIG, "Using Node WWN 0x%08x%08x",
+ (u_int32_t) (DEFAULT_NODEWWN(isp) >> 32),
+ (u_int32_t) (DEFAULT_NODEWWN(isp) & 0xffffffff));
+ ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
+ } else {
+ /*
+ * We always start out with values derived
+ * from NVRAM or our platform default.
+ */
+ ISP_NODEWWN(isp) = fcp->isp_wwnn_nvram;
+ if (fcp->isp_wwnn_nvram == 0) {
+ isp_prt(isp, ISP_LOGCONFIG,
+ "bad WWNN- using default");
+ ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
+ }
+ }
+ if (isp->isp_confopts & ISP_CFG_OWNWWPN) {
+ isp_prt(isp, ISP_LOGCONFIG, "Using Port WWN 0x%08x%08x",
+ (u_int32_t) (DEFAULT_PORTWWN(isp) >> 32),
+ (u_int32_t) (DEFAULT_PORTWWN(isp) & 0xffffffff));
+ ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
+ } else {
+ /*
+ * We always start out with values derived
+ * from NVRAM or our platform default.
+ */
+ ISP_PORTWWN(isp) = fcp->isp_wwpn_nvram;
+ if (fcp->isp_wwpn_nvram == 0) {
+ isp_prt(isp, ISP_LOGCONFIG,
+ "bad WWPN- using default");
+ ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
+ }
+ }
+}
+
/*
* Re-initialize the ISP and complete all orphaned commands
* with a 'botched' notice. The reset/init routines should
* not disturb an already active list of commands.
- *
- * Locks held prior to coming here.
*/
void
isp_reinit(struct ispsoftc *isp)
{
XS_T *xs;
- u_int16_t handle;
+ u_int32_t tmp;
+ if (IS_FC(isp)) {
+ ISP_MARK_PORTDB(isp, 0);
+ }
isp_reset(isp);
if (isp->isp_state != ISP_RESETSTATE) {
isp_prt(isp, ISP_LOGERR, "isp_reinit cannot reset card");
@@ -5877,15 +7316,36 @@ isp_reinit(struct ispsoftc *isp)
if (isp->isp_state != ISP_RUNSTATE) {
isp_prt(isp, ISP_LOGERR,
"isp_reinit cannot restart card");
+ ISP_DISABLE_INTS(isp);
}
- }
+ } else {
+ ISP_DISABLE_INTS(isp);
+ if (IS_FC(isp)) {
+ /*
+ * If we're in ISP_ROLE_NONE, turn off the lasers.
+ */
+ if (!IS_24XX(isp)) {
+ ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
+ ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
+ ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
+ ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
+ ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
+ }
+ }
+ }
isp->isp_nactive = 0;
- for (handle = 1; (int) handle <= isp->isp_maxcmds; handle++) {
- xs = isp_find_xs(isp, handle);
+ for (tmp = 0; tmp < isp->isp_maxcmds; tmp++) {
+ u_int32_t handle;
+
+ xs = isp->isp_xflist[tmp];
if (xs == NULL) {
continue;
}
+ handle = isp_find_handle(isp, xs);
+ if (handle == 0) {
+ continue;
+ }
isp_destroy_handle(isp, handle);
if (XS_XFRLEN(xs)) {
ISP_DMAFREE(isp, xs, handle);
@@ -5896,15 +7356,18 @@ isp_reinit(struct ispsoftc *isp)
XS_SETERR(xs, HBA_BUSRESET);
isp_done(xs);
}
+#ifdef ISP_TARGET_MODE
+ MEMZERO(isp->isp_tgtlist, isp->isp_maxcmds * sizeof (void **));
+#endif
}
/*
* NVRAM Routines
*/
-static int
+int
isp_read_nvram(struct ispsoftc *isp)
{
- int i, amt;
+ int i, amt, retval;
u_int8_t csum, minversion;
union {
u_int8_t _x[ISP2100_NVRAM_SIZE];
@@ -5913,7 +7376,9 @@ isp_read_nvram(struct ispsoftc *isp)
#define nvram_data _n._x
#define nvram_words _n._s
- if (IS_FC(isp)) {
+ if (IS_24XX(isp)) {
+ return (isp_read_nvram_2400(isp));
+ } else if (IS_FC(isp)) {
amt = ISP2100_NVRAM_SIZE;
minversion = 1;
} else if (IS_ULTRA2(isp)) {
@@ -5924,13 +7389,10 @@ isp_read_nvram(struct ispsoftc *isp)
minversion = 2;
}
- /*
- * Just read the first two words first to see if we have a valid
- * NVRAM to continue reading the rest with.
- */
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < amt>>1; i++) {
isp_rdnvram_word(isp, i, &nvram_words[i]);
}
+
if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
nvram_data[2] != 'P') {
if (isp->isp_bustype != ISP_BT_SBUS) {
@@ -5938,22 +7400,24 @@ isp_read_nvram(struct ispsoftc *isp)
isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x",
nvram_data[0], nvram_data[1], nvram_data[2]);
}
- return (-1);
- }
- for (i = 2; i < amt>>1; i++) {
- isp_rdnvram_word(isp, i, &nvram_words[i]);
+ retval = -1;
+ goto out;
}
+
for (csum = 0, i = 0; i < amt; i++) {
csum += nvram_data[i];
}
if (csum != 0) {
isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
- return (-1);
+ retval = -1;
+ goto out;
}
+
if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
ISP_NVRAM_VERSION(nvram_data));
- return (-1);
+ retval = -1;
+ goto out;
}
if (IS_ULTRA3(isp)) {
@@ -5970,24 +7434,66 @@ isp_read_nvram(struct ispsoftc *isp)
} else {
isp_parse_nvram_2100(isp, nvram_data);
}
- return (0);
+ retval = 0;
+out:
+ return (retval);
#undef nvram_data
#undef nvram_words
}
-static void
+int
+isp_read_nvram_2400(struct ispsoftc *isp)
+{
+ u_int8_t *nvram_data = FCPARAM(isp)->isp_scratch;
+ int retval = 0;
+ u_int32_t addr, csum, lwrds, *dptr;
+
+ if (isp->isp_port) {
+ addr = ISP2400_NVRAM_PORT1_ADDR;
+ } else {
+ addr = ISP2400_NVRAM_PORT0_ADDR;
+ }
+
+ dptr = (u_int32_t *) nvram_data;
+ for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
+ isp_rd_2400_nvram(isp, addr++, dptr++);
+ }
+ if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
+ nvram_data[2] != 'P') {
+ isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
+ nvram_data[0], nvram_data[1], nvram_data[2]);
+ retval = -1;
+ goto out;
+ }
+ dptr = (u_int32_t *) nvram_data;
+ for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
+ u_int32_t tmp;
+ ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
+ csum += tmp;
+ }
+ if (csum != 0) {
+ isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
+ retval = -1;
+ goto out;
+ }
+ isp_parse_nvram_2400(isp, nvram_data);
+out:
+ return (retval);
+}
+
+void
isp_rdnvram_word(struct ispsoftc *isp, int wo, u_int16_t *rp)
{
int i, cbits;
- u_int16_t bit, rqst;
+ u_int16_t bit, rqst, junk;
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
- USEC_DELAY(2);
+ USEC_DELAY(10);
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
- USEC_DELAY(2);
+ USEC_DELAY(10);
if (IS_FC(isp)) {
- wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
+ wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
if (IS_2312(isp) && isp->isp_port) {
wo += 128;
}
@@ -6013,11 +7519,14 @@ isp_rdnvram_word(struct ispsoftc *isp, int wo, u_int16_t *rp)
bit = BIU_NVRAM_SELECT;
}
ISP_WRITE(isp, BIU_NVRAM, bit);
- USEC_DELAY(2);
+ USEC_DELAY(10);
+ junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
- USEC_DELAY(2);
+ USEC_DELAY(10);
+ junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
ISP_WRITE(isp, BIU_NVRAM, bit);
- USEC_DELAY(2);
+ USEC_DELAY(10);
+ junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
}
/*
* Now read the result back in (bits come back in MSB format).
@@ -6027,21 +7536,46 @@ isp_rdnvram_word(struct ispsoftc *isp, int wo, u_int16_t *rp)
u_int16_t rv;
*rp <<= 1;
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
- USEC_DELAY(2);
+ USEC_DELAY(10);
rv = ISP_READ(isp, BIU_NVRAM);
if (rv & BIU_NVRAM_DATAIN) {
*rp |= 1;
}
- USEC_DELAY(2);
+ USEC_DELAY(10);
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
- USEC_DELAY(2);
+ USEC_DELAY(10);
+ junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
}
ISP_WRITE(isp, BIU_NVRAM, 0);
- USEC_DELAY(2);
+ USEC_DELAY(10);
+ junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
ISP_SWIZZLE_NVRAM_WORD(isp, rp);
}
-static void
+void
+isp_rd_2400_nvram(struct ispsoftc *isp, u_int32_t addr, u_int32_t *rp)
+{
+ int loops = 0;
+ const u_int32_t base = 0x7ffe0000;
+ u_int32_t tmp = 0;
+
+ ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
+ for (loops = 0; loops < 5000; loops++) {
+ USEC_DELAY(10);
+ tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
+ if ((tmp & (1U << 31)) != 0) {
+ break;
+ }
+ }
+ if (tmp & (1U << 31)) {
+ *rp = ISP_READ(isp, BIU2400_FLASH_DATA);
+ ISP_SWIZZLE_NVRAM_LONG(isp, rp);
+ } else {
+ *rp = 0xffffffff;
+ }
+}
+
+void
isp_parse_nvram_1020(struct ispsoftc *isp, u_int8_t *nvram_data)
{
sdparam *sdp = (sdparam *) isp->isp_param;
@@ -6167,7 +7701,7 @@ isp_parse_nvram_1020(struct ispsoftc *isp, u_int8_t *nvram_data)
}
}
-static void
+void
isp_parse_nvram_1080(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
{
sdparam *sdp = (sdparam *) isp->isp_param;
@@ -6259,7 +7793,7 @@ isp_parse_nvram_1080(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
}
}
-static void
+void
isp_parse_nvram_12160(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
{
sdparam *sdp = (sdparam *) isp->isp_param;
@@ -6350,10 +7884,42 @@ isp_parse_nvram_12160(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
}
}
-static void
+void
+isp_fix_nvram_wwns(struct ispsoftc *isp)
+{
+ fcparam *fcp = FCPARAM(isp);
+
+ /*
+ * Make sure we have both Node and Port as non-zero values.
+ */
+ if (fcp->isp_wwnn_nvram != 0 && fcp->isp_wwpn_nvram == 0) {
+ fcp->isp_wwpn_nvram = fcp->isp_wwnn_nvram;
+ } else if (fcp->isp_wwnn_nvram == 0 && fcp->isp_wwpn_nvram != 0) {
+ fcp->isp_wwnn_nvram = fcp->isp_wwpn_nvram;
+ }
+
+ /*
+ * Make the Node and Port values sane if they're NAA == 2.
+ * This means to clear bits 48..56 for the Node WWN and
+ * make sure that there's some non-zero value in 48..56
+ * for the Port WWN.
+ */
+ if (fcp->isp_wwnn_nvram && fcp->isp_wwpn_nvram) {
+ if ((fcp->isp_wwnn_nvram & (((u_int64_t) 0xfff) << 48)) != 0 &&
+ (fcp->isp_wwnn_nvram >> 60) == 2) {
+ fcp->isp_wwnn_nvram &= ~((u_int64_t) 0xfff << 48);
+ }
+ if ((fcp->isp_wwpn_nvram & (((u_int64_t) 0xfff) << 48)) == 0 &&
+ (fcp->isp_wwpn_nvram >> 60) == 2) {
+ fcp->isp_wwpn_nvram |= ((u_int64_t) 1 << 56);
+ }
+ }
+}
+
+void
isp_parse_nvram_2100(struct ispsoftc *isp, u_int8_t *nvram_data)
{
- fcparam *fcp = (fcparam *) isp->isp_param;
+ fcparam *fcp = FCPARAM(isp);
u_int64_t wwn;
/*
@@ -6362,7 +7928,7 @@ isp_parse_nvram_2100(struct ispsoftc *isp, u_int8_t *nvram_data)
* I can find. However, we should account for this being set
* at some point in the future.
*
- * QLogic WWNs have an NAA of 2, but usually nothing shows up in
+ * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
* bits 48..60. In the case of the 2202, it appears that they do
* use bit 48 to distinguish between the two instances on the card.
* The 2204, which I've never seen, *probably* extends this method.
@@ -6375,9 +7941,9 @@ isp_parse_nvram_2100(struct ispsoftc *isp, u_int8_t *nvram_data)
wwn |= (((u_int64_t) 2)<< 60);
}
}
- fcp->isp_portwwn = wwn;
+ fcp->isp_wwpn_nvram = wwn;
if (IS_2200(isp) || IS_23XX(isp)) {
- wwn = ISP2200_NVRAM_NODE_NAME(nvram_data);
+ wwn = ISP2100_NVRAM_NODE_NAME(nvram_data);
if (wwn) {
isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
(u_int32_t) (wwn >> 32),
@@ -6389,70 +7955,113 @@ isp_parse_nvram_2100(struct ispsoftc *isp, u_int8_t *nvram_data)
} else {
wwn &= ~((u_int64_t) 0xfff << 48);
}
- fcp->isp_nodewwn = wwn;
+ fcp->isp_wwnn_nvram = wwn;
- /*
- * Make sure we have both Node and Port as non-zero values.
- */
- if (fcp->isp_nodewwn != 0 && fcp->isp_portwwn == 0) {
- fcp->isp_portwwn = fcp->isp_nodewwn;
- } else if (fcp->isp_nodewwn == 0 && fcp->isp_portwwn != 0) {
- fcp->isp_nodewwn = fcp->isp_portwwn;
+ isp_fix_nvram_wwns(isp);
+
+ fcp->isp_maxalloc = ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
+ if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
+ fcp->isp_maxfrmlen = ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
}
+ fcp->isp_retry_delay = ISP2100_NVRAM_RETRY_DELAY(nvram_data);
+ fcp->isp_retry_count = ISP2100_NVRAM_RETRY_COUNT(nvram_data);
+ if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
+ fcp->isp_loopid = ISP2100_NVRAM_HARDLOOPID(nvram_data);
+ }
+ if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
+ fcp->isp_execthrottle =
+ ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
+ }
+ fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d",
+ (u_int32_t) (fcp->isp_wwnn_nvram >> 32), (u_int32_t) fcp->isp_wwnn_nvram,
+ (u_int32_t) (fcp->isp_wwpn_nvram >> 32), (u_int32_t) fcp->isp_wwpn_nvram,
+ ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data),
+ ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data));
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "execthrottle %d fwoptions 0x%x hardloop %d tov %d",
+ ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
+ ISP2100_NVRAM_OPTIONS(nvram_data),
+ ISP2100_NVRAM_HARDLOOPID(nvram_data),
+ ISP2100_NVRAM_TOV(nvram_data));
+ fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data);
+ fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data);
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "xfwoptions 0x%x zfw options 0x%x",
+ ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data));
+}
- /*
- * Make the Node and Port values sane if they're NAA == 2.
- * This means to clear bits 48..56 for the Node WWN and
- * make sure that there's some non-zero value in 48..56
- * for the Port WWN.
- */
- if (fcp->isp_nodewwn && fcp->isp_portwwn) {
- if ((fcp->isp_nodewwn & (((u_int64_t) 0xfff) << 48)) != 0 &&
- (fcp->isp_nodewwn >> 60) == 2) {
- fcp->isp_nodewwn &= ~((u_int64_t) 0xfff << 48);
+void
+isp_parse_nvram_2400(struct ispsoftc *isp, u_int8_t *nvram_data)
+{
+ fcparam *fcp = FCPARAM(isp);
+ u_int64_t wwn;
+
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "NVRAM 0x%08x%08x 0x%08x%08x exchg_cnt %d maxframelen %d",
+ (u_int32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
+ (u_int32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
+ (u_int32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
+ (u_int32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
+ ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data),
+ ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "NVRAM execthr %d loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
+ ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data),
+ ISP2400_NVRAM_HARDLOOPID(nvram_data),
+ ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
+ ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
+ ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
+
+ wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
+ if (wwn) {
+ if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
+ wwn = 0;
}
- if ((fcp->isp_portwwn & (((u_int64_t) 0xfff) << 48)) == 0 &&
- (fcp->isp_portwwn >> 60) == 2) {
- fcp->isp_portwwn |= ((u_int64_t) 1 << 56);
+ }
+ fcp->isp_wwpn_nvram = wwn;
+
+ wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
+ if (wwn) {
+ if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
+ wwn = 0;
}
}
+ fcp->isp_wwnn_nvram = wwn;
- isp_prt(isp, ISP_LOGDEBUG0,
- "NVRAM: maxfrmlen %d execthrottle %d fwoptions 0x%x loopid %x",
- ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data),
- ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
- ISP2100_NVRAM_OPTIONS(nvram_data),
- ISP2100_NVRAM_HARDLOOPID(nvram_data));
-
- fcp->isp_maxalloc =
- ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
- if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0)
- fcp->isp_maxfrmlen =
- ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
- fcp->isp_retry_delay =
- ISP2100_NVRAM_RETRY_DELAY(nvram_data);
- fcp->isp_retry_count =
- ISP2100_NVRAM_RETRY_COUNT(nvram_data);
- if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
- fcp->isp_loopid =
- ISP2100_NVRAM_HARDLOOPID(nvram_data);
- if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0)
+ isp_fix_nvram_wwns(isp);
+
+ if (ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data)) {
+ fcp->isp_maxalloc = ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data);
+ }
+ if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
+ fcp->isp_maxfrmlen = ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
+ }
+ if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
+ fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
+ }
+ if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
fcp->isp_execthrottle =
- ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
- fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
+ ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data);
+ }
+ fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
+ fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
+ fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
}
#ifdef ISP_FW_CRASH_DUMP
-static void isp2200_fw_dump(struct ispsoftc *);
-static void isp2300_fw_dump(struct ispsoftc *);
+void isp2200_fw_dump(struct ispsoftc *);
+void isp2300_fw_dump(struct ispsoftc *);
-static void
+void
isp2200_fw_dump(struct ispsoftc *isp)
{
int i, j;
mbreg_t mbs;
u_int16_t *ptr;
+ MEMZERO(&mbs, sizeof (mbs));
ptr = FCPARAM(isp)->isp_dump_data;
if (ptr == NULL) {
isp_prt(isp, ISP_LOGERR,
@@ -6571,8 +8180,7 @@ isp2200_fw_dump(struct ispsoftc *isp)
break;
}
}
- ENABLE_INTS(isp);
- MEMZERO(&mbs, sizeof (mbs));
+ ISP_ENABLE_INTS(isp);
mbs.param[0] = MBOX_READ_RAM_WORD;
mbs.param[1] = 0x1000;
isp->isp_mbxworkp = (void *) ptr;
@@ -6591,13 +8199,14 @@ isp2200_fw_dump(struct ispsoftc *isp)
(void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
}
-static void
+void
isp2300_fw_dump(struct ispsoftc *isp)
{
int i, j;
mbreg_t mbs;
u_int16_t *ptr;
+ MEMZERO(&mbs, sizeof (mbs));
ptr = FCPARAM(isp)->isp_dump_data;
if (ptr == NULL) {
isp_prt(isp, ISP_LOGERR,
@@ -6714,7 +8323,7 @@ isp2300_fw_dump(struct ispsoftc *isp)
isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
return;
}
- ENABLE_INTS(isp);
+ ISP_ENABLE_INTS(isp);
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_READ_RAM_WORD;
mbs.param[1] = 0x800;
@@ -6729,20 +8338,13 @@ isp2300_fw_dump(struct ispsoftc *isp)
}
ptr = isp->isp_mbxworkp; /* finish fetch of final word */
*ptr++ = isp->isp_mboxtmp[2];
-
- /*
- * We don't have access to mailbox registers 8.. onward
- * in our 'common' device model- so we have to set it
- * here and hope it stays the same!
- */
- ISP_WRITE(isp, PCI_MBOX_REGS2300_OFF + (8 << 1), 0x1);
-
MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_READ_RAM_WORD_EXTENDED;
- mbs.param[1] = 0;
+ mbs.param[8] = 1;
isp->isp_mbxworkp = (void *) ptr;
isp->isp_mbxwrk0 = 0xffff; /* continuation count */
isp->isp_mbxwrk1 = 0x1; /* next SRAM address */
+ isp->isp_mbxwrk8 = 0x1;
isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGWARN,
@@ -6763,5 +8365,8 @@ isp_fw_dump(struct ispsoftc *isp)
isp2200_fw_dump(isp);
else if (IS_23XX(isp))
isp2300_fw_dump(isp);
+ else if (IS_24XX(isp))
+ isp_prt(isp, ISP_LOGERR, "24XX dump method undefined");
+
}
#endif
diff --git a/sys/dev/ic/isp_library.c b/sys/dev/ic/isp_library.c
index bf67fdbcd28..ffc955c0120 100644
--- a/sys/dev/ic/isp_library.c
+++ b/sys/dev/ic/isp_library.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isp_library.c,v 1.1 2008/11/16 00:00:13 krw Exp $ */
+/* $OpenBSD: isp_library.c,v 1.2 2009/06/24 11:00:53 krw Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -28,15 +28,32 @@
/*
* Qlogic Host Adapter Internal Library Functions
*/
-
+#ifdef __NetBSD__
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+#include <dev/ic/isp_netbsd.h>
+#endif
+#ifdef __FreeBSD__
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/isp/isp_library.c,v 1.14 2007/07/02 20:08:20 mjacob Exp $");
+#include <dev/isp/isp_freebsd.h>
+#endif
+#ifdef __OpenBSD__
#include <dev/ic/isp_openbsd.h>
+#endif
+#ifdef __linux__
+#include "isp_linux.h"
+#endif
+#ifdef __svr4__
+#include "isp_solaris.h"
+#endif
int
-isp_save_xs(struct ispsoftc *isp, XS_T *xs, u_int16_t *handlep)
+isp_save_xs(struct ispsoftc *isp, XS_T *xs, u_int32_t *handlep)
{
- int i, j;
+ u_int16_t i, j;
- for (j = isp->isp_lasthdls, i = 0; i < (int) isp->isp_maxcmds; i++) {
+ for (j = isp->isp_lasthdls, i = 0; i < isp->isp_maxcmds; i++) {
if (isp->isp_xflist[j] == NULL) {
break;
}
@@ -49,66 +66,58 @@ isp_save_xs(struct ispsoftc *isp, XS_T *xs, u_int16_t *handlep)
}
isp->isp_xflist[j] = xs;
*handlep = j+1;
- if (++j == isp->isp_maxcmds)
+ if (++j == isp->isp_maxcmds) {
j = 0;
- isp->isp_lasthdls = (u_int16_t)j;
+ }
+ isp->isp_lasthdls = (u_int32_t)j;
return (0);
}
XS_T *
-isp_find_xs(struct ispsoftc *isp, u_int16_t handle)
+isp_find_xs(struct ispsoftc *isp, u_int32_t handle)
{
- if (handle < 1 || handle > (u_int16_t) isp->isp_maxcmds) {
+ if (handle < 1 || handle > (u_int32_t) isp->isp_maxcmds) {
return (NULL);
} else {
return (isp->isp_xflist[handle - 1]);
}
}
-u_int16_t
+u_int32_t
isp_find_handle(struct ispsoftc *isp, XS_T *xs)
{
- int i;
+ u_int16_t i;
if (xs != NULL) {
for (i = 0; i < isp->isp_maxcmds; i++) {
if (isp->isp_xflist[i] == xs) {
- return ((u_int16_t) i+1);
+ return ((u_int32_t) (i+1));
}
}
}
return (0);
}
-int
-isp_handle_index(u_int16_t handle)
+u_int32_t
+isp_handle_index(u_int32_t handle)
{
- return (handle-1);
+ return (handle - 1);
}
void
-isp_destroy_handle(struct ispsoftc *isp, u_int16_t handle)
+isp_destroy_handle(struct ispsoftc *isp, u_int32_t handle)
{
- if (handle > 0 && handle <= (u_int16_t) isp->isp_maxcmds) {
- isp->isp_xflist[isp_handle_index(handle)] = NULL;
+ if (handle > 0 && handle <= (u_int32_t) isp->isp_maxcmds) {
+ isp->isp_xflist[handle - 1] = NULL;
}
}
-void
-isp_remove_handle(struct ispsoftc *isp, XS_T *xs)
-{
- isp_destroy_handle(isp, isp_find_handle(isp, xs));
-}
-
-int
-isp_getrqentry(struct ispsoftc *, u_int16_t *, u_int16_t *, void **);
-
int
-isp_getrqentry(struct ispsoftc *isp, u_int16_t *iptrp,
- u_int16_t *optrp, void **resultp)
+isp_getrqentry(struct ispsoftc *isp, u_int32_t *iptrp,
+ u_int32_t *optrp, void **resultp)
{
- volatile u_int16_t iptr, optr;
+ volatile u_int32_t iptr, optr;
- optr = isp->isp_reqodx = READ_REQUEST_QUEUE_OUT_POINTER(isp);
+ optr = isp->isp_reqodx = ISP_READ(isp, isp->isp_rqstoutrp);
iptr = isp->isp_reqidx;
*resultp = ISP_QUEUE_ENTRY(isp->isp_rquest, iptr);
iptr = ISP_NXT_QENTRY(iptr, RQUEST_QUEUE_LEN(isp));
@@ -122,6 +131,7 @@ isp_getrqentry(struct ispsoftc *isp, u_int16_t *iptrp,
return (0);
}
+#define TBA (4 * (((QENTRY_LEN >> 2) * 3) + 1) + 1)
void
isp_print_qentry(struct ispsoftc *isp, char *msg, int idx, void *arg)
{
@@ -141,7 +151,7 @@ isp_print_qentry(struct ispsoftc *isp, char *msg, int idx, void *arg)
}
void
-isp_print_bytes(struct ispsoftc *isp, char *msg, int amt, void *arg)
+isp_print_bytes(struct ispsoftc *isp, const char *msg, int amt, void *arg)
{
char buf[128];
u_int8_t *ptr = arg;
@@ -173,10 +183,6 @@ isp_print_bytes(struct ispsoftc *isp, char *msg, int amt, void *arg)
* action because things may have changed while we were doing this.
* Any failure or change of state causes us to return a nonzero value.
*
- * We honor HBA roles in that if we're not in Initiator mode, we don't
- * attempt to sync up the database (that's for somebody else to do,
- * if ever).
- *
* We assume we enter here with any locks held.
*/
@@ -186,35 +192,120 @@ isp_fc_runstate(struct ispsoftc *isp, int tval)
fcparam *fcp;
int *tptr;
- if (IS_SCSI(isp))
+ if (isp->isp_role == ISP_ROLE_NONE) {
return (0);
-
- tptr = tval? &tval : NULL;
- if (isp_control(isp, ISPCTL_FCLINK_TEST, tptr) != 0) {
- return (-1);
}
fcp = FCPARAM(isp);
- if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate < LOOP_PDB_RCVD)
- return (-1);
- if (isp_control(isp, ISPCTL_SCAN_FABRIC, NULL) != 0) {
- return (-1);
- }
- if (isp_control(isp, ISPCTL_SCAN_LOOP, NULL) != 0) {
- return (-1);
+ tptr = &tval;
+ if (fcp->isp_fwstate < FW_READY ||
+ fcp->isp_loopstate < LOOP_PDB_RCVD) {
+ if (isp_control(isp, ISPCTL_FCLINK_TEST, tptr) != 0) {
+ isp_prt(isp, ISP_LOGSANCFG,
+ "isp_fc_runstate: linktest failed");
+ return (-1);
+ }
+ if (fcp->isp_fwstate != FW_READY ||
+ fcp->isp_loopstate < LOOP_PDB_RCVD) {
+ isp_prt(isp, ISP_LOGSANCFG,
+ "isp_fc_runstate: f/w not ready");
+ return (-1);
+ }
}
if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
return (0);
}
+ if (isp_control(isp, ISPCTL_SCAN_LOOP, NULL) != 0) {
+ isp_prt(isp, ISP_LOGSANCFG,
+ "isp_fc_runstate: scan loop fails");
+ return (LOOP_PDB_RCVD);
+ }
+ if (isp_control(isp, ISPCTL_SCAN_FABRIC, NULL) != 0) {
+ isp_prt(isp, ISP_LOGSANCFG,
+ "isp_fc_runstate: scan fabric fails");
+ return (LOOP_LSCAN_DONE);
+ }
if (isp_control(isp, ISPCTL_PDB_SYNC, NULL) != 0) {
- return (-1);
+ isp_prt(isp, ISP_LOGSANCFG, "isp_fc_runstate: pdb_sync fails");
+ return (LOOP_FSCAN_DONE);
}
if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate != LOOP_READY) {
+ isp_prt(isp, ISP_LOGSANCFG,
+ "isp_fc_runstate: f/w not ready again");
return (-1);
}
return (0);
}
/*
+ * Fibre Channel Support- get the port database for the id.
+ */
+void
+isp_dump_portdb(struct ispsoftc *isp)
+{
+ fcparam *fcp = (fcparam *) isp->isp_param;
+ int i;
+
+ for (i = 0; i < MAX_FC_TARG; i++) {
+ char mb[4];
+ const char *dbs[8] = {
+ "NIL ",
+ "PROB",
+ "DEAD",
+ "CHGD",
+ "NEW ",
+ "PVLD",
+ "ZOMB",
+ "VLD "
+ };
+ const char *roles[4] = {
+ " UNK", " TGT", " INI", "TINI"
+ };
+ fcportdb_t *lp = &fcp->portdb[i];
+
+ if (lp->state == FC_PORTDB_STATE_NIL) {
+ continue;
+ }
+ if (lp->ini_map_idx) {
+ SNPRINTF(mb, sizeof (mb), "%3d",
+ ((int) lp->ini_map_idx) - 1);
+ } else {
+ SNPRINTF(mb, sizeof (mb), "---");
+ }
+ isp_prt(isp, ISP_LOGALL, "%d: hdl 0x%x %s al%d tgt %s %s "
+ "0x%06x =>%s 0x%06x; WWNN 0x%08x%08x WWPN 0x%08x%08x", i,
+ lp->handle, dbs[lp->state], lp->autologin, mb,
+ roles[lp->roles], lp->portid,
+ roles[lp->new_roles], lp->new_portid,
+ (u_int32_t) (lp->node_wwn >> 32),
+ (u_int32_t) (lp->node_wwn),
+ (u_int32_t) (lp->port_wwn >> 32),
+ (u_int32_t) (lp->port_wwn));
+ }
+}
+
+void
+isp_shutdown(struct ispsoftc *isp)
+{
+ if (IS_FC(isp)) {
+ if (IS_24XX(isp)) {
+ ISP_WRITE(isp, BIU2400_ICR, 0);
+ ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
+ } else {
+ ISP_WRITE(isp, BIU_ICR, 0);
+ ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
+ ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
+ ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
+ ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
+ ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
+ ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
+ }
+ } else {
+ ISP_WRITE(isp, BIU_ICR, 0);
+ ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
+ }
+}
+
+/*
* Functions to move stuff to a form that the QLogic RISC engine understands
* and functions to move stuff back to a form the processor understands.
*
@@ -225,12 +316,15 @@ isp_fc_runstate(struct ispsoftc *isp, int tval)
* (with a few exceptions for efficiency).
*/
+#define ISP_IS_SBUS(isp) \
+ (ISP_SBUS_SUPPORTED && (isp)->isp_bustype == ISP_BT_SBUS)
+
+#define ASIZE(x) (sizeof (x) / sizeof (x[0]))
/*
* Swizzle/Copy Functions
*/
-
void
-isp_copy_out_hdr(struct ispsoftc *isp, isphdr_t *hpsrc, isphdr_t *hpdst)
+isp_put_hdr(struct ispsoftc *isp, isphdr_t *hpsrc, isphdr_t *hpdst)
{
if (ISP_IS_SBUS(isp)) {
ISP_IOXPUT_8(isp, hpsrc->rqs_entry_type,
@@ -254,7 +348,7 @@ isp_copy_out_hdr(struct ispsoftc *isp, isphdr_t *hpsrc, isphdr_t *hpdst)
}
void
-isp_copy_in_hdr(struct ispsoftc *isp, isphdr_t *hpsrc, isphdr_t *hpdst)
+isp_get_hdr(struct ispsoftc *isp, isphdr_t *hpsrc, isphdr_t *hpdst)
{
if (ISP_IS_SBUS(isp)) {
ISP_IOXGET_8(isp, &hpsrc->rqs_entry_type,
@@ -293,7 +387,7 @@ void
isp_put_request(struct ispsoftc *isp, ispreq_t *rqsrc, ispreq_t *rqdst)
{
int i;
- isp_copy_out_hdr(isp, &rqsrc->req_header, &rqdst->req_header);
+ isp_put_hdr(isp, &rqsrc->req_header, &rqdst->req_header);
ISP_IOXPUT_32(isp, rqsrc->req_handle, &rqdst->req_handle);
if (ISP_IS_SBUS(isp)) {
ISP_IOXPUT_8(isp, rqsrc->req_lun_trn, &rqdst->req_target);
@@ -306,7 +400,7 @@ isp_put_request(struct ispsoftc *isp, ispreq_t *rqsrc, ispreq_t *rqdst)
ISP_IOXPUT_16(isp, rqsrc->req_flags, &rqdst->req_flags);
ISP_IOXPUT_16(isp, rqsrc->req_time, &rqdst->req_time);
ISP_IOXPUT_16(isp, rqsrc->req_seg_count, &rqdst->req_seg_count);
- for (i = 0; i < 12; i++) {
+ for (i = 0; i < ASIZE(rqsrc->req_cdb); i++) {
ISP_IOXPUT_8(isp, rqsrc->req_cdb[i], &rqdst->req_cdb[i]);
}
for (i = 0; i < ISP_RQDSEG; i++) {
@@ -318,153 +412,343 @@ isp_put_request(struct ispsoftc *isp, ispreq_t *rqsrc, ispreq_t *rqdst)
}
void
-isp_put_request_t2(struct ispsoftc *isp, ispreqt2_t *tqsrc, ispreqt2_t *tqdst)
+isp_put_marker(struct ispsoftc *isp, isp_marker_t *src, isp_marker_t *dst)
{
int i;
- isp_copy_out_hdr(isp, &tqsrc->req_header, &tqdst->req_header);
- ISP_IOXPUT_32(isp, tqsrc->req_handle, &tqdst->req_handle);
- ISP_IOXPUT_8(isp, tqsrc->req_lun_trn, &tqdst->req_lun_trn);
- ISP_IOXPUT_8(isp, tqsrc->req_target, &tqdst->req_target);
- ISP_IOXPUT_16(isp, tqsrc->req_scclun, &tqdst->req_scclun);
- ISP_IOXPUT_16(isp, tqsrc->req_flags, &tqdst->req_flags);
- ISP_IOXPUT_16(isp, tqsrc->req_reserved, &tqdst->req_reserved);
- ISP_IOXPUT_16(isp, tqsrc->req_time, &tqdst->req_time);
- ISP_IOXPUT_16(isp, tqsrc->req_seg_count, &tqdst->req_seg_count);
- for (i = 0; i < 16; i++) {
- ISP_IOXPUT_8(isp, tqsrc->req_cdb[i], &tqdst->req_cdb[i]);
+ isp_put_hdr(isp, &src->mrk_header, &dst->mrk_header);
+ ISP_IOXPUT_32(isp, src->mrk_handle, &dst->mrk_handle);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXPUT_8(isp, src->mrk_reserved0, &dst->mrk_target);
+ ISP_IOXPUT_8(isp, src->mrk_target, &dst->mrk_reserved0);
+ } else {
+ ISP_IOXPUT_8(isp, src->mrk_reserved0, &dst->mrk_reserved0);
+ ISP_IOXPUT_8(isp, src->mrk_target, &dst->mrk_target);
+ }
+ ISP_IOXPUT_16(isp, src->mrk_modifier, &dst->mrk_modifier);
+ ISP_IOXPUT_16(isp, src->mrk_flags, &dst->mrk_flags);
+ ISP_IOXPUT_16(isp, src->mrk_lun, &dst->mrk_lun);
+ for (i = 0; i < ASIZE(src->mrk_reserved1); i++) {
+ ISP_IOXPUT_8(isp, src->mrk_reserved1[i],
+ &dst->mrk_reserved1[i]);
}
- ISP_IOXPUT_32(isp, tqsrc->req_totalcnt, &tqdst->req_totalcnt);
+}
+
+void
+isp_put_marker_24xx(struct ispsoftc *isp,
+ isp_marker_24xx_t *src, isp_marker_24xx_t *dst)
+{
+ int i;
+ isp_put_hdr(isp, &src->mrk_header, &dst->mrk_header);
+ ISP_IOXPUT_32(isp, src->mrk_handle, &dst->mrk_handle);
+ ISP_IOXPUT_16(isp, src->mrk_nphdl, &dst->mrk_nphdl);
+ ISP_IOXPUT_8(isp, src->mrk_modifier, &dst->mrk_modifier);
+ ISP_IOXPUT_8(isp, src->mrk_reserved0, &dst->mrk_reserved0);
+ ISP_IOXPUT_8(isp, src->mrk_reserved1, &dst->mrk_reserved1);
+ ISP_IOXPUT_8(isp, src->mrk_vphdl, &dst->mrk_vphdl);
+ ISP_IOXPUT_8(isp, src->mrk_reserved2, &dst->mrk_reserved2);
+ for (i = 0; i < ASIZE(src->mrk_lun); i++) {
+ ISP_IOXPUT_8(isp, src->mrk_lun[i], &dst->mrk_lun[i]);
+ }
+ for (i = 0; i < ASIZE(src->mrk_reserved3); i++) {
+ ISP_IOXPUT_8(isp, src->mrk_reserved3[i],
+ &dst->mrk_reserved3[i]);
+ }
+}
+
+void
+isp_put_request_t2(struct ispsoftc *isp, ispreqt2_t *src, ispreqt2_t *dst)
+{
+ int i;
+ isp_put_hdr(isp, &src->req_header, &dst->req_header);
+ ISP_IOXPUT_32(isp, src->req_handle, &dst->req_handle);
+ ISP_IOXPUT_8(isp, src->req_lun_trn, &dst->req_lun_trn);
+ ISP_IOXPUT_8(isp, src->req_target, &dst->req_target);
+ ISP_IOXPUT_16(isp, src->req_scclun, &dst->req_scclun);
+ ISP_IOXPUT_16(isp, src->req_flags, &dst->req_flags);
+ ISP_IOXPUT_16(isp, src->req_reserved, &dst->req_reserved);
+ ISP_IOXPUT_16(isp, src->req_time, &dst->req_time);
+ ISP_IOXPUT_16(isp, src->req_seg_count, &dst->req_seg_count);
+ for (i = 0; i < ASIZE(src->req_cdb); i++) {
+ ISP_IOXPUT_8(isp, src->req_cdb[i], &dst->req_cdb[i]);
+ }
+ ISP_IOXPUT_32(isp, src->req_totalcnt, &dst->req_totalcnt);
for (i = 0; i < ISP_RQDSEG_T2; i++) {
- ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_base,
- &tqdst->req_dataseg[i].ds_base);
- ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_count,
- &tqdst->req_dataseg[i].ds_count);
+ ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_base,
+ &dst->req_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_count,
+ &dst->req_dataseg[i].ds_count);
}
}
void
-isp_put_request_t3(struct ispsoftc *isp, ispreqt3_t *tqsrc, ispreqt3_t *tqdst)
+isp_put_request_t2e(struct ispsoftc *isp, ispreqt2e_t *src, ispreqt2e_t *dst)
{
int i;
- isp_copy_out_hdr(isp, &tqsrc->req_header, &tqdst->req_header);
- ISP_IOXPUT_32(isp, tqsrc->req_handle, &tqdst->req_handle);
- ISP_IOXPUT_8(isp, tqsrc->req_lun_trn, &tqdst->req_lun_trn);
- ISP_IOXPUT_8(isp, tqsrc->req_target, &tqdst->req_target);
- ISP_IOXPUT_16(isp, tqsrc->req_scclun, &tqdst->req_scclun);
- ISP_IOXPUT_16(isp, tqsrc->req_flags, &tqdst->req_flags);
- ISP_IOXPUT_16(isp, tqsrc->req_reserved, &tqdst->req_reserved);
- ISP_IOXPUT_16(isp, tqsrc->req_time, &tqdst->req_time);
- ISP_IOXPUT_16(isp, tqsrc->req_seg_count, &tqdst->req_seg_count);
- for (i = 0; i < 16; i++) {
- ISP_IOXPUT_8(isp, tqsrc->req_cdb[i], &tqdst->req_cdb[i]);
+ isp_put_hdr(isp, &src->req_header, &dst->req_header);
+ ISP_IOXPUT_32(isp, src->req_handle, &dst->req_handle);
+ ISP_IOXPUT_16(isp, src->req_target, &dst->req_target);
+ ISP_IOXPUT_16(isp, src->req_scclun, &dst->req_scclun);
+ ISP_IOXPUT_16(isp, src->req_flags, &dst->req_flags);
+ ISP_IOXPUT_16(isp, src->req_reserved, &dst->req_reserved);
+ ISP_IOXPUT_16(isp, src->req_time, &dst->req_time);
+ ISP_IOXPUT_16(isp, src->req_seg_count, &dst->req_seg_count);
+ for (i = 0; i < ASIZE(src->req_cdb); i++) {
+ ISP_IOXPUT_8(isp, src->req_cdb[i], &dst->req_cdb[i]);
+ }
+ ISP_IOXPUT_32(isp, src->req_totalcnt, &dst->req_totalcnt);
+ for (i = 0; i < ISP_RQDSEG_T2; i++) {
+ ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_base,
+ &dst->req_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_count,
+ &dst->req_dataseg[i].ds_count);
}
- ISP_IOXPUT_32(isp, tqsrc->req_totalcnt, &tqdst->req_totalcnt);
+}
+
+void
+isp_put_request_t3(struct ispsoftc *isp, ispreqt3_t *src, ispreqt3_t *dst)
+{
+ int i;
+ isp_put_hdr(isp, &src->req_header, &dst->req_header);
+ ISP_IOXPUT_32(isp, src->req_handle, &dst->req_handle);
+ ISP_IOXPUT_8(isp, src->req_lun_trn, &dst->req_lun_trn);
+ ISP_IOXPUT_8(isp, src->req_target, &dst->req_target);
+ ISP_IOXPUT_16(isp, src->req_scclun, &dst->req_scclun);
+ ISP_IOXPUT_16(isp, src->req_flags, &dst->req_flags);
+ ISP_IOXPUT_16(isp, src->req_reserved, &dst->req_reserved);
+ ISP_IOXPUT_16(isp, src->req_time, &dst->req_time);
+ ISP_IOXPUT_16(isp, src->req_seg_count, &dst->req_seg_count);
+ for (i = 0; i < ASIZE(src->req_cdb); i++) {
+ ISP_IOXPUT_8(isp, src->req_cdb[i], &dst->req_cdb[i]);
+ }
+ ISP_IOXPUT_32(isp, src->req_totalcnt, &dst->req_totalcnt);
+ for (i = 0; i < ISP_RQDSEG_T3; i++) {
+ ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_base,
+ &dst->req_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_basehi,
+ &dst->req_dataseg[i].ds_basehi);
+ ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_count,
+ &dst->req_dataseg[i].ds_count);
+ }
+}
+
+void
+isp_put_request_t3e(struct ispsoftc *isp, ispreqt3e_t *src, ispreqt3e_t *dst)
+{
+ int i;
+ isp_put_hdr(isp, &src->req_header, &dst->req_header);
+ ISP_IOXPUT_32(isp, src->req_handle, &dst->req_handle);
+ ISP_IOXPUT_16(isp, src->req_target, &dst->req_target);
+ ISP_IOXPUT_16(isp, src->req_scclun, &dst->req_scclun);
+ ISP_IOXPUT_16(isp, src->req_flags, &dst->req_flags);
+ ISP_IOXPUT_16(isp, src->req_reserved, &dst->req_reserved);
+ ISP_IOXPUT_16(isp, src->req_time, &dst->req_time);
+ ISP_IOXPUT_16(isp, src->req_seg_count, &dst->req_seg_count);
+ for (i = 0; i < ASIZE(src->req_cdb); i++) {
+ ISP_IOXPUT_8(isp, src->req_cdb[i], &dst->req_cdb[i]);
+ }
+ ISP_IOXPUT_32(isp, src->req_totalcnt, &dst->req_totalcnt);
for (i = 0; i < ISP_RQDSEG_T3; i++) {
- ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_base,
- &tqdst->req_dataseg[i].ds_base);
- ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_basehi,
- &tqdst->req_dataseg[i].ds_basehi);
- ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_count,
- &tqdst->req_dataseg[i].ds_count);
+ ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_base,
+ &dst->req_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_basehi,
+ &dst->req_dataseg[i].ds_basehi);
+ ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_count,
+ &dst->req_dataseg[i].ds_count);
}
}
void
-isp_put_extended_request(struct ispsoftc *isp, ispextreq_t *xqsrc,
- ispextreq_t *xqdst)
+isp_put_extended_request(struct ispsoftc *isp, ispextreq_t *src, ispextreq_t *dst)
{
int i;
- isp_copy_out_hdr(isp, &xqsrc->req_header, &xqdst->req_header);
- ISP_IOXPUT_32(isp, xqsrc->req_handle, &xqdst->req_handle);
+ isp_put_hdr(isp, &src->req_header, &dst->req_header);
+ ISP_IOXPUT_32(isp, src->req_handle, &dst->req_handle);
if (ISP_IS_SBUS(isp)) {
- ISP_IOXPUT_8(isp, xqsrc->req_lun_trn, &xqdst->req_target);
- ISP_IOXPUT_8(isp, xqsrc->req_target, &xqdst->req_lun_trn);
+ ISP_IOXPUT_8(isp, src->req_lun_trn, &dst->req_target);
+ ISP_IOXPUT_8(isp, src->req_target, &dst->req_lun_trn);
} else {
- ISP_IOXPUT_8(isp, xqsrc->req_lun_trn, &xqdst->req_lun_trn);
- ISP_IOXPUT_8(isp, xqsrc->req_target, &xqdst->req_target);
+ ISP_IOXPUT_8(isp, src->req_lun_trn, &dst->req_lun_trn);
+ ISP_IOXPUT_8(isp, src->req_target, &dst->req_target);
}
- ISP_IOXPUT_16(isp, xqsrc->req_cdblen, &xqdst->req_cdblen);
- ISP_IOXPUT_16(isp, xqsrc->req_flags, &xqdst->req_flags);
- ISP_IOXPUT_16(isp, xqsrc->req_time, &xqdst->req_time);
- ISP_IOXPUT_16(isp, xqsrc->req_seg_count, &xqdst->req_seg_count);
- for (i = 0; i < 44; i++) {
- ISP_IOXPUT_8(isp, xqsrc->req_cdb[i], &xqdst->req_cdb[i]);
+ ISP_IOXPUT_16(isp, src->req_cdblen, &dst->req_cdblen);
+ ISP_IOXPUT_16(isp, src->req_flags, &dst->req_flags);
+ ISP_IOXPUT_16(isp, src->req_time, &dst->req_time);
+ ISP_IOXPUT_16(isp, src->req_seg_count, &dst->req_seg_count);
+ for (i = 0; i < ASIZE(src->req_cdb); i++) {
+ ISP_IOXPUT_8(isp, src->req_cdb[i], &dst->req_cdb[i]);
}
}
void
-isp_put_cont_req(struct ispsoftc *isp, ispcontreq_t *cqsrc, ispcontreq_t *cqdst)
+isp_put_request_t7(struct ispsoftc *isp, ispreqt7_t *src, ispreqt7_t *dst)
{
int i;
- isp_copy_out_hdr(isp, &cqsrc->req_header, &cqdst->req_header);
+ u_int32_t *a, *b;
+
+ isp_put_hdr(isp, &src->req_header, &dst->req_header);
+ ISP_IOXPUT_32(isp, src->req_handle, &dst->req_handle);
+ ISP_IOXPUT_16(isp, src->req_nphdl, &dst->req_nphdl);
+ ISP_IOXPUT_16(isp, src->req_time, &dst->req_time);
+ ISP_IOXPUT_16(isp, src->req_seg_count, &dst->req_seg_count);
+ ISP_IOXPUT_16(isp, src->req_reserved, &dst->req_reserved);
+ a = (u_int32_t *) src->req_lun;
+ b = (u_int32_t *) dst->req_lun;
+ for (i = 0; i < (ASIZE(src->req_lun) >> 2); i++ ) {
+ *b++ = ISP_SWAP32(isp, *a++);
+ }
+ ISP_IOXPUT_8(isp, src->req_alen_datadir, &dst->req_alen_datadir);
+ ISP_IOXPUT_8(isp, src->req_task_management, &dst->req_task_management);
+ ISP_IOXPUT_8(isp, src->req_task_attribute, &dst->req_task_attribute);
+ ISP_IOXPUT_8(isp, src->req_crn, &dst->req_crn);
+ a = (u_int32_t *) src->req_cdb;
+ b = (u_int32_t *) dst->req_cdb;
+ for (i = 0; i < (ASIZE(src->req_cdb) >> 2); i++) {
+ *b++ = ISP_SWAP32(isp, *a++);
+ }
+ ISP_IOXPUT_32(isp, src->req_dl, &dst->req_dl);
+ ISP_IOXPUT_16(isp, src->req_tidlo, &dst->req_tidlo);
+ ISP_IOXPUT_8(isp, src->req_tidhi, &dst->req_tidhi);
+ ISP_IOXPUT_8(isp, src->req_vpidx, &dst->req_vpidx);
+ ISP_IOXPUT_32(isp, src->req_dataseg.ds_base,
+ &dst->req_dataseg.ds_base);
+ ISP_IOXPUT_32(isp, src->req_dataseg.ds_basehi,
+ &dst->req_dataseg.ds_basehi);
+ ISP_IOXPUT_32(isp, src->req_dataseg.ds_count,
+ &dst->req_dataseg.ds_count);
+}
+
+void
+isp_put_24xx_abrt(struct ispsoftc *isp, isp24xx_abrt_t *src, isp24xx_abrt_t *dst)
+{
+ int i;
+ isp_put_hdr(isp, &src->abrt_header, &dst->abrt_header);
+ ISP_IOXPUT_32(isp, src->abrt_handle, &dst->abrt_handle);
+ ISP_IOXPUT_16(isp, src->abrt_nphdl, &dst->abrt_nphdl);
+ ISP_IOXPUT_16(isp, src->abrt_options, &dst->abrt_options);
+ ISP_IOXPUT_32(isp, src->abrt_cmd_handle, &dst->abrt_cmd_handle);
+ for (i = 0; i < ASIZE(src->abrt_reserved); i++) {
+ ISP_IOXPUT_8(isp, src->abrt_reserved[i],
+ &dst->abrt_reserved[i]);
+ }
+ ISP_IOXPUT_16(isp, src->abrt_tidlo, &dst->abrt_tidlo);
+ ISP_IOXPUT_8(isp, src->abrt_tidhi, &dst->abrt_tidhi);
+ ISP_IOXPUT_8(isp, src->abrt_vpidx, &dst->abrt_vpidx);
+ for (i = 0; i < ASIZE(src->abrt_reserved1); i++) {
+ ISP_IOXPUT_8(isp, src->abrt_reserved1[i],
+ &dst->abrt_reserved1[i]);
+ }
+}
+
+void
+isp_put_cont_req(struct ispsoftc *isp, ispcontreq_t *src, ispcontreq_t *dst)
+{
+ int i;
+ isp_put_hdr(isp, &src->req_header, &dst->req_header);
for (i = 0; i < ISP_CDSEG; i++) {
- ISP_IOXPUT_32(isp, cqsrc->req_dataseg[i].ds_base,
- &cqdst->req_dataseg[i].ds_base);
- ISP_IOXPUT_32(isp, cqsrc->req_dataseg[i].ds_count,
- &cqdst->req_dataseg[i].ds_count);
+ ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_base,
+ &dst->req_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_count,
+ &dst->req_dataseg[i].ds_count);
}
}
void
-isp_put_cont64_req(struct ispsoftc *isp, ispcontreq64_t *cqsrc,
- ispcontreq64_t *cqdst)
+isp_put_cont64_req(struct ispsoftc *isp, ispcontreq64_t *src, ispcontreq64_t *dst)
{
int i;
- isp_copy_out_hdr(isp, &cqsrc->req_header, &cqdst->req_header);
+ isp_put_hdr(isp, &src->req_header, &dst->req_header);
for (i = 0; i < ISP_CDSEG64; i++) {
- ISP_IOXPUT_32(isp, cqsrc->req_dataseg[i].ds_base,
- &cqdst->req_dataseg[i].ds_base);
- ISP_IOXPUT_32(isp, cqsrc->req_dataseg[i].ds_basehi,
- &cqdst->req_dataseg[i].ds_basehi);
- ISP_IOXPUT_32(isp, cqsrc->req_dataseg[i].ds_count,
- &cqdst->req_dataseg[i].ds_count);
+ ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_base,
+ &dst->req_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_basehi,
+ &dst->req_dataseg[i].ds_basehi);
+ ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_count,
+ &dst->req_dataseg[i].ds_count);
}
}
void
-isp_get_response(struct ispsoftc *isp, ispstatusreq_t *spsrc,
- ispstatusreq_t *spdst)
+isp_get_response(struct ispsoftc *isp, ispstatusreq_t *src, ispstatusreq_t *dst)
{
int i;
- isp_copy_in_hdr(isp, &spsrc->req_header, &spdst->req_header);
- ISP_IOXGET_32(isp, &spsrc->req_handle, spdst->req_handle);
- ISP_IOXGET_16(isp, &spsrc->req_scsi_status, spdst->req_scsi_status);
- ISP_IOXGET_16(isp, &spsrc->req_completion_status,
- spdst->req_completion_status);
- ISP_IOXGET_16(isp, &spsrc->req_state_flags, spdst->req_state_flags);
- ISP_IOXGET_16(isp, &spsrc->req_status_flags, spdst->req_status_flags);
- ISP_IOXGET_16(isp, &spsrc->req_time, spdst->req_time);
- ISP_IOXGET_16(isp, &spsrc->req_sense_len, spdst->req_sense_len);
- ISP_IOXGET_32(isp, &spsrc->req_resid, spdst->req_resid);
+ isp_get_hdr(isp, &src->req_header, &dst->req_header);
+ ISP_IOXGET_32(isp, &src->req_handle, dst->req_handle);
+ ISP_IOXGET_16(isp, &src->req_scsi_status, dst->req_scsi_status);
+ ISP_IOXGET_16(isp, &src->req_completion_status,
+ dst->req_completion_status);
+ ISP_IOXGET_16(isp, &src->req_state_flags, dst->req_state_flags);
+ ISP_IOXGET_16(isp, &src->req_status_flags, dst->req_status_flags);
+ ISP_IOXGET_16(isp, &src->req_time, dst->req_time);
+ ISP_IOXGET_16(isp, &src->req_sense_len, dst->req_sense_len);
+ ISP_IOXGET_32(isp, &src->req_resid, dst->req_resid);
for (i = 0; i < 8; i++) {
- ISP_IOXGET_8(isp, &spsrc->req_response[i],
- spdst->req_response[i]);
+ ISP_IOXGET_8(isp, &src->req_response[i],
+ dst->req_response[i]);
}
for (i = 0; i < 32; i++) {
- ISP_IOXGET_8(isp, &spsrc->req_sense_data[i],
- spdst->req_sense_data[i]);
+ ISP_IOXGET_8(isp, &src->req_sense_data[i],
+ dst->req_sense_data[i]);
+ }
+}
+
+void
+isp_get_24xx_response(struct ispsoftc *isp, isp24xx_statusreq_t *src,
+ isp24xx_statusreq_t *dst)
+{
+ int i;
+ u_int32_t *s, *d;
+
+ isp_get_hdr(isp, &src->req_header, &dst->req_header);
+ ISP_IOXGET_32(isp, &src->req_handle, dst->req_handle);
+ ISP_IOXGET_16(isp, &src->req_completion_status,
+ dst->req_completion_status);
+ ISP_IOXGET_16(isp, &src->req_oxid, dst->req_oxid);
+ ISP_IOXGET_32(isp, &src->req_resid, dst->req_resid);
+ ISP_IOXGET_16(isp, &src->req_reserved0, dst->req_reserved0);
+ ISP_IOXGET_16(isp, &src->req_state_flags, dst->req_state_flags);
+ ISP_IOXGET_16(isp, &src->req_reserved1, dst->req_reserved1);
+ ISP_IOXGET_16(isp, &src->req_scsi_status, dst->req_scsi_status);
+ ISP_IOXGET_32(isp, &src->req_fcp_residual, dst->req_fcp_residual);
+ ISP_IOXGET_32(isp, &src->req_sense_len, dst->req_sense_len);
+ ISP_IOXGET_32(isp, &src->req_response_len, dst->req_response_len);
+ s = (u_int32_t *)src->req_rsp_sense;
+ d = (u_int32_t *)dst->req_rsp_sense;
+ for (i = 0; i < (ASIZE(src->req_rsp_sense) >> 2); i++) {
+ d[i] = ISP_SWAP32(isp, s[i]);
}
}
void
-isp_get_response_x(struct ispsoftc *isp, ispstatus_cont_t *cpsrc,
- ispstatus_cont_t *cpdst)
+isp_get_24xx_abrt(struct ispsoftc *isp, isp24xx_abrt_t *src, isp24xx_abrt_t *dst)
{
int i;
- isp_copy_in_hdr(isp, &cpsrc->req_header, &cpdst->req_header);
- for (i = 0; i < 60; i++) {
- ISP_IOXGET_8(isp, &cpsrc->req_sense_data[i],
- cpdst->req_sense_data[i]);
+ isp_get_hdr(isp, &src->abrt_header, &dst->abrt_header);
+ ISP_IOXGET_32(isp, &src->abrt_handle, dst->abrt_handle);
+ ISP_IOXGET_16(isp, &src->abrt_nphdl, dst->abrt_nphdl);
+ ISP_IOXGET_16(isp, &src->abrt_options, dst->abrt_options);
+ ISP_IOXGET_32(isp, &src->abrt_cmd_handle, dst->abrt_cmd_handle);
+ for (i = 0; i < ASIZE(src->abrt_reserved); i++) {
+ ISP_IOXGET_8(isp, &src->abrt_reserved[i],
+ dst->abrt_reserved[i]);
+ }
+ ISP_IOXGET_16(isp, &src->abrt_tidlo, dst->abrt_tidlo);
+ ISP_IOXGET_8(isp, &src->abrt_tidhi, dst->abrt_tidhi);
+ ISP_IOXGET_8(isp, &src->abrt_vpidx, dst->abrt_vpidx);
+ for (i = 0; i < ASIZE(src->abrt_reserved1); i++) {
+ ISP_IOXGET_8(isp, &src->abrt_reserved1[i],
+ dst->abrt_reserved1[i]);
}
}
+
void
isp_get_rio2(struct ispsoftc *isp, isp_rio2_t *r2src, isp_rio2_t *r2dst)
{
int i;
- isp_copy_in_hdr(isp, &r2src->req_header, &r2dst->req_header);
- if (r2dst->req_header.rqs_seqno > 30)
+ isp_get_hdr(isp, &r2src->req_header, &r2dst->req_header);
+ if (r2dst->req_header.rqs_seqno > 30) {
r2dst->req_header.rqs_seqno = 30;
+ }
for (i = 0; i < r2dst->req_header.rqs_seqno; i++) {
ISP_IOXGET_16(isp, &r2src->req_handles[i],
r2dst->req_handles[i]);
@@ -475,53 +759,128 @@ isp_get_rio2(struct ispsoftc *isp, isp_rio2_t *r2src, isp_rio2_t *r2dst)
}
void
-isp_put_icb(struct ispsoftc *isp, isp_icb_t *Is, isp_icb_t *Id)
+isp_put_icb(struct ispsoftc *isp, isp_icb_t *src, isp_icb_t *dst)
+{
+ int i;
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXPUT_8(isp, src->icb_version, &dst->icb_reserved0);
+ ISP_IOXPUT_8(isp, src->icb_reserved0, &dst->icb_version);
+ } else {
+ ISP_IOXPUT_8(isp, src->icb_version, &dst->icb_version);
+ ISP_IOXPUT_8(isp, src->icb_reserved0, &dst->icb_reserved0);
+ }
+ ISP_IOXPUT_16(isp, src->icb_fwoptions, &dst->icb_fwoptions);
+ ISP_IOXPUT_16(isp, src->icb_maxfrmlen, &dst->icb_maxfrmlen);
+ ISP_IOXPUT_16(isp, src->icb_maxalloc, &dst->icb_maxalloc);
+ ISP_IOXPUT_16(isp, src->icb_execthrottle, &dst->icb_execthrottle);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXPUT_8(isp, src->icb_retry_count, &dst->icb_retry_delay);
+ ISP_IOXPUT_8(isp, src->icb_retry_delay, &dst->icb_retry_count);
+ } else {
+ ISP_IOXPUT_8(isp, src->icb_retry_count, &dst->icb_retry_count);
+ ISP_IOXPUT_8(isp, src->icb_retry_delay, &dst->icb_retry_delay);
+ }
+ for (i = 0; i < 8; i++) {
+ ISP_IOXPUT_8(isp, src->icb_portname[i], &dst->icb_portname[i]);
+ }
+ ISP_IOXPUT_16(isp, src->icb_hardaddr, &dst->icb_hardaddr);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXPUT_8(isp, src->icb_iqdevtype, &dst->icb_logintime);
+ ISP_IOXPUT_8(isp, src->icb_logintime, &dst->icb_iqdevtype);
+ } else {
+ ISP_IOXPUT_8(isp, src->icb_iqdevtype, &dst->icb_iqdevtype);
+ ISP_IOXPUT_8(isp, src->icb_logintime, &dst->icb_logintime);
+ }
+ for (i = 0; i < 8; i++) {
+ ISP_IOXPUT_8(isp, src->icb_nodename[i], &dst->icb_nodename[i]);
+ }
+ ISP_IOXPUT_16(isp, src->icb_rqstout, &dst->icb_rqstout);
+ ISP_IOXPUT_16(isp, src->icb_rspnsin, &dst->icb_rspnsin);
+ ISP_IOXPUT_16(isp, src->icb_rqstqlen, &dst->icb_rqstqlen);
+ ISP_IOXPUT_16(isp, src->icb_rsltqlen, &dst->icb_rsltqlen);
+ for (i = 0; i < 4; i++) {
+ ISP_IOXPUT_16(isp, src->icb_rqstaddr[i], &dst->icb_rqstaddr[i]);
+ }
+ for (i = 0; i < 4; i++) {
+ ISP_IOXPUT_16(isp, src->icb_respaddr[i], &dst->icb_respaddr[i]);
+ }
+ ISP_IOXPUT_16(isp, src->icb_lunenables, &dst->icb_lunenables);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXPUT_8(isp, src->icb_ccnt, &dst->icb_icnt);
+ ISP_IOXPUT_8(isp, src->icb_icnt, &dst->icb_ccnt);
+ } else {
+ ISP_IOXPUT_8(isp, src->icb_ccnt, &dst->icb_ccnt);
+ ISP_IOXPUT_8(isp, src->icb_icnt, &dst->icb_icnt);
+ }
+ ISP_IOXPUT_16(isp, src->icb_lunetimeout, &dst->icb_lunetimeout);
+ ISP_IOXPUT_16(isp, src->icb_reserved1, &dst->icb_reserved1);
+ ISP_IOXPUT_16(isp, src->icb_xfwoptions, &dst->icb_xfwoptions);
+ if (ISP_IS_SBUS(isp)) {
+ ISP_IOXPUT_8(isp, src->icb_racctimer, &dst->icb_idelaytimer);
+ ISP_IOXPUT_8(isp, src->icb_idelaytimer, &dst->icb_racctimer);
+ } else {
+ ISP_IOXPUT_8(isp, src->icb_racctimer, &dst->icb_racctimer);
+ ISP_IOXPUT_8(isp, src->icb_idelaytimer, &dst->icb_idelaytimer);
+ }
+ ISP_IOXPUT_16(isp, src->icb_zfwoptions, &dst->icb_zfwoptions);
+}
+
+void
+isp_put_icb_2400(struct ispsoftc *isp, isp_icb_2400_t *src, isp_icb_2400_t *dst)
{
int i;
- ISP_SWAP8(Is->icb_version, Is->icb_reserved0);
- ISP_IOXPUT_8(isp, Is->icb_version, &Id->icb_version);
- ISP_IOXPUT_8(isp, Is->icb_reserved0, &Id->icb_reserved0);
- ISP_IOXPUT_16(isp, Is->icb_fwoptions, &Id->icb_fwoptions);
- ISP_IOXPUT_16(isp, Is->icb_maxfrmlen, &Id->icb_maxfrmlen);
- ISP_IOXPUT_16(isp, Is->icb_maxalloc, &Id->icb_maxalloc);
- ISP_IOXPUT_16(isp, Is->icb_execthrottle, &Id->icb_execthrottle);
- ISP_SWAP8(Is->icb_retry_count, Is->icb_retry_delay);
- ISP_IOXPUT_8(isp, Is->icb_retry_count, &Id->icb_retry_count);
- ISP_IOXPUT_8(isp, Is->icb_retry_delay, &Id->icb_retry_delay);
+ ISP_IOXPUT_16(isp, src->icb_version, &dst->icb_version);
+ ISP_IOXPUT_16(isp, src->icb_reserved0, &dst->icb_reserved0);
+ ISP_IOXPUT_16(isp, src->icb_maxfrmlen, &dst->icb_maxfrmlen);
+ ISP_IOXPUT_16(isp, src->icb_execthrottle, &dst->icb_execthrottle);
+ ISP_IOXPUT_16(isp, src->icb_xchgcnt, &dst->icb_xchgcnt);
+ ISP_IOXPUT_16(isp, src->icb_hardaddr, &dst->icb_hardaddr);
for (i = 0; i < 8; i++) {
- ISP_IOXPUT_8(isp, Is->icb_portname[i], &Id->icb_portname[i]);
+ ISP_IOXPUT_8(isp, src->icb_portname[i], &dst->icb_portname[i]);
}
- ISP_IOXPUT_16(isp, Is->icb_hardaddr, &Id->icb_hardaddr);
- ISP_SWAP8(Is->icb_iqdevtype, Is->icb_logintime);
- ISP_IOXPUT_8(isp, Is->icb_iqdevtype, &Id->icb_iqdevtype);
- ISP_IOXPUT_8(isp, Is->icb_logintime, &Id->icb_logintime);
for (i = 0; i < 8; i++) {
- ISP_IOXPUT_8(isp, Is->icb_nodename[i], &Id->icb_nodename[i]);
+ ISP_IOXPUT_8(isp, src->icb_nodename[i], &dst->icb_nodename[i]);
+ }
+ ISP_IOXPUT_16(isp, src->icb_rspnsin, &dst->icb_rspnsin);
+ ISP_IOXPUT_16(isp, src->icb_rqstout, &dst->icb_rqstout);
+ ISP_IOXPUT_16(isp, src->icb_retry_count, &dst->icb_retry_count);
+ ISP_IOXPUT_16(isp, src->icb_priout, &dst->icb_priout);
+ ISP_IOXPUT_16(isp, src->icb_rsltqlen, &dst->icb_rsltqlen);
+ ISP_IOXPUT_16(isp, src->icb_rqstqlen, &dst->icb_rqstqlen);
+ ISP_IOXPUT_16(isp, src->icb_ldn_nols, &dst->icb_ldn_nols);
+ ISP_IOXPUT_16(isp, src->icb_prqstqlen, &dst->icb_prqstqlen);
+ for (i = 0; i < 4; i++) {
+ ISP_IOXPUT_16(isp, src->icb_rqstaddr[i], &dst->icb_rqstaddr[i]);
+ }
+ for (i = 0; i < 4; i++) {
+ ISP_IOXPUT_16(isp, src->icb_respaddr[i], &dst->icb_respaddr[i]);
}
- ISP_IOXPUT_16(isp, Is->icb_rqstout, &Id->icb_rqstout);
- ISP_IOXPUT_16(isp, Is->icb_rspnsin, &Id->icb_rspnsin);
- ISP_IOXPUT_16(isp, Is->icb_rqstqlen, &Id->icb_rqstqlen);
- ISP_IOXPUT_16(isp, Is->icb_rsltqlen, &Id->icb_rsltqlen);
for (i = 0; i < 4; i++) {
- ISP_IOXPUT_16(isp, Is->icb_rqstaddr[i], &Id->icb_rqstaddr[i]);
+ ISP_IOXPUT_16(isp, src->icb_priaddr[i], &dst->icb_priaddr[i]);
}
for (i = 0; i < 4; i++) {
- ISP_IOXPUT_16(isp, Is->icb_respaddr[i], &Id->icb_respaddr[i]);
+ ISP_IOXPUT_16(isp, src->icb_reserved1[i],
+ &dst->icb_reserved1[i]);
+ }
+ ISP_IOXPUT_16(isp, src->icb_atio_in, &dst->icb_atio_in);
+ ISP_IOXPUT_16(isp, src->icb_atioqlen, &dst->icb_atioqlen);
+ for (i = 0; i < 4; i++) {
+ ISP_IOXPUT_16(isp, src->icb_atioqaddr[i],
+ &dst->icb_atioqaddr[i]);
+ }
+ ISP_IOXPUT_16(isp, src->icb_idelaytimer, &dst->icb_idelaytimer);
+ ISP_IOXPUT_16(isp, src->icb_logintime, &dst->icb_logintime);
+ ISP_IOXPUT_32(isp, src->icb_fwoptions1, &dst->icb_fwoptions1);
+ ISP_IOXPUT_32(isp, src->icb_fwoptions2, &dst->icb_fwoptions2);
+ ISP_IOXPUT_32(isp, src->icb_fwoptions3, &dst->icb_fwoptions3);
+ for (i = 0; i < 12; i++) {
+ ISP_IOXPUT_16(isp, src->icb_reserved2[i],
+ &dst->icb_reserved2[i]);
}
- ISP_IOXPUT_16(isp, Is->icb_lunenables, &Id->icb_lunenables);
- ISP_SWAP8(Is->icb_ccnt, Is->icb_icnt);
- ISP_IOXPUT_8(isp, Is->icb_ccnt, &Id->icb_ccnt);
- ISP_IOXPUT_8(isp, Is->icb_icnt, &Id->icb_icnt);
- ISP_IOXPUT_16(isp, Is->icb_lunetimeout, &Id->icb_lunetimeout);
- ISP_IOXPUT_16(isp, Is->icb_xfwoptions, &Id->icb_xfwoptions);
- ISP_SWAP8(Is->icb_racctimer, Is->icb_idelaytimer);
- ISP_IOXPUT_8(isp, Is->icb_racctimer, &Id->icb_racctimer);
- ISP_IOXPUT_8(isp, Is->icb_idelaytimer, &Id->icb_idelaytimer);
- ISP_IOXPUT_16(isp, Is->icb_zfwoptions, &Id->icb_zfwoptions);
}
void
-isp_get_pdb(struct ispsoftc *isp, isp_pdb_t *src, isp_pdb_t *dst)
+isp_get_pdb_21xx(struct ispsoftc *isp, isp_pdb_21xx_t *src, isp_pdb_21xx_t *dst)
{
int i;
ISP_IOXGET_16(isp, &src->pdb_options, dst->pdb_options);
@@ -574,29 +933,204 @@ isp_get_pdb(struct ispsoftc *isp, isp_pdb_t *src, isp_pdb_t *dst)
ISP_IOXGET_16(isp, &src->pdb_sl_ptr, dst->pdb_sl_ptr);
}
+void
+isp_get_pdb_24xx(struct ispsoftc *isp, isp_pdb_24xx_t *src, isp_pdb_24xx_t *dst)
+{
+ int i;
+ ISP_IOXGET_16(isp, &src->pdb_flags, dst->pdb_flags);
+ ISP_IOXGET_8(isp, &src->pdb_curstate, dst->pdb_curstate);
+ ISP_IOXGET_8(isp, &src->pdb_laststate, dst->pdb_laststate);
+ for (i = 0; i < 4; i++) {
+ ISP_IOXGET_8(isp, &src->pdb_hardaddr_bits[i],
+ dst->pdb_hardaddr_bits[i]);
+ }
+ for (i = 0; i < 4; i++) {
+ ISP_IOXGET_8(isp, &src->pdb_portid_bits[i],
+ dst->pdb_portid_bits[i]);
+ }
+ ISP_IOXGET_16(isp, &src->pdb_retry_timer, dst->pdb_retry_timer);
+ ISP_IOXGET_16(isp, &src->pdb_handle, dst->pdb_handle);
+ ISP_IOXGET_16(isp, &src->pdb_rcv_dsize, dst->pdb_rcv_dsize);
+ ISP_IOXGET_16(isp, &src->pdb_reserved0, dst->pdb_reserved0);
+ ISP_IOXGET_16(isp, &src->pdb_prli_svc0, dst->pdb_prli_svc0);
+ ISP_IOXGET_16(isp, &src->pdb_prli_svc3, dst->pdb_prli_svc3);
+ for (i = 0; i < 8; i++) {
+ ISP_IOXGET_8(isp, &src->pdb_nodename[i], dst->pdb_nodename[i]);
+ }
+ for (i = 0; i < 8; i++) {
+ ISP_IOXGET_8(isp, &src->pdb_portname[i], dst->pdb_portname[i]);
+ }
+ for (i = 0; i < 24; i++) {
+ ISP_IOXGET_8(isp, &src->pdb_reserved1[i],
+ dst->pdb_reserved1[i]);
+ }
+}
/*
- * CT_HDR canonicalization- only needed for SNS responses
+ * PLOGI/LOGO IOCB canonicalization
*/
+
void
-isp_get_ct_hdr(struct ispsoftc *isp, ct_hdr_t *src, ct_hdr_t *dst)
+isp_get_plogx(struct ispsoftc *isp, isp_plogx_t *src, isp_plogx_t *dst)
+{
+ int i;
+ isp_get_hdr(isp, &src->plogx_header, &dst->plogx_header);
+ ISP_IOXGET_32(isp, &src->plogx_handle, dst->plogx_handle);
+ ISP_IOXGET_16(isp, &src->plogx_status, dst->plogx_status);
+ ISP_IOXGET_16(isp, &src->plogx_nphdl, dst->plogx_nphdl);
+ ISP_IOXGET_16(isp, &src->plogx_flags, dst->plogx_flags);
+ ISP_IOXGET_16(isp, &src->plogx_vphdl, dst->plogx_vphdl);
+ ISP_IOXGET_16(isp, &src->plogx_portlo, dst->plogx_portlo);
+ ISP_IOXGET_16(isp, &src->plogx_rspsz_porthi, dst->plogx_rspsz_porthi);
+ for (i = 0; i < 11; i++) {
+ ISP_IOXGET_16(isp, &src->plogx_ioparm[i].lo16,
+ dst->plogx_ioparm[i].lo16);
+ ISP_IOXGET_16(isp, &src->plogx_ioparm[i].hi16,
+ dst->plogx_ioparm[i].hi16);
+ }
+}
+
+void
+isp_put_plogx(struct ispsoftc *isp, isp_plogx_t *src, isp_plogx_t *dst)
{
- ISP_IOXGET_8(isp, &src->ct_revision, dst->ct_revision);
- ISP_IOXGET_8(isp, &src->ct_portid[0], dst->ct_portid[0]);
- ISP_IOXGET_8(isp, &src->ct_portid[1], dst->ct_portid[1]);
- ISP_IOXGET_8(isp, &src->ct_portid[2], dst->ct_portid[2]);
- ISP_IOXGET_8(isp, &src->ct_fcs_type, dst->ct_fcs_type);
- ISP_IOXGET_8(isp, &src->ct_fcs_subtype, dst->ct_fcs_subtype);
- ISP_IOXGET_8(isp, &src->ct_options, dst->ct_options);
- ISP_IOXGET_8(isp, &src->ct_res0, dst->ct_res0);
- ISP_IOXGET_16(isp, &src->ct_response, dst->ct_response);
- dst->ct_response = (dst->ct_response << 8) | (dst->ct_response >> 8);
- ISP_IOXGET_16(isp, &src->ct_resid, dst->ct_resid);
- dst->ct_resid = (dst->ct_resid << 8) | (dst->ct_resid >> 8);
- ISP_IOXGET_8(isp, &src->ct_res1, dst->ct_res1);
- ISP_IOXGET_8(isp, &src->ct_reason, dst->ct_reason);
- ISP_IOXGET_8(isp, &src->ct_explanation, dst->ct_explanation);
- ISP_IOXGET_8(isp, &src->ct_vunique, dst->ct_vunique);
+ int i;
+ isp_put_hdr(isp, &src->plogx_header, &dst->plogx_header);
+ ISP_IOXPUT_32(isp, src->plogx_handle, &dst->plogx_handle);
+ ISP_IOXPUT_16(isp, src->plogx_status, &dst->plogx_status);
+ ISP_IOXPUT_16(isp, src->plogx_nphdl, &dst->plogx_nphdl);
+ ISP_IOXPUT_16(isp, src->plogx_flags, &dst->plogx_flags);
+ ISP_IOXPUT_16(isp, src->plogx_vphdl, &dst->plogx_vphdl);
+ ISP_IOXPUT_16(isp, src->plogx_portlo, &dst->plogx_portlo);
+ ISP_IOXPUT_16(isp, src->plogx_rspsz_porthi, &dst->plogx_rspsz_porthi);
+ for (i = 0; i < 11; i++) {
+ ISP_IOXPUT_16(isp, src->plogx_ioparm[i].lo16,
+ &dst->plogx_ioparm[i].lo16);
+ ISP_IOXPUT_16(isp, src->plogx_ioparm[i].hi16,
+ &dst->plogx_ioparm[i].hi16);
+ }
+}
+
+/*
+ * CT Passthru canonicalization
+ */
+void
+isp_get_ct_pt(struct ispsoftc *isp, isp_ct_pt_t *src, isp_ct_pt_t *dst)
+{
+ int i;
+
+ isp_get_hdr(isp, &src->ctp_header, &dst->ctp_header);
+ ISP_IOXGET_32(isp, &src->ctp_handle, dst->ctp_handle);
+ ISP_IOXGET_16(isp, &src->ctp_status, dst->ctp_status);
+ ISP_IOXGET_16(isp, &src->ctp_nphdl, dst->ctp_nphdl);
+ ISP_IOXGET_16(isp, &src->ctp_cmd_cnt, dst->ctp_cmd_cnt);
+ ISP_IOXGET_16(isp, &src->ctp_vpidx, dst->ctp_vpidx);
+ ISP_IOXGET_16(isp, &src->ctp_time, dst->ctp_time);
+ ISP_IOXGET_16(isp, &src->ctp_reserved0, dst->ctp_reserved0);
+ ISP_IOXGET_16(isp, &src->ctp_rsp_cnt, dst->ctp_rsp_cnt);
+ for (i = 0; i < 5; i++) {
+ ISP_IOXGET_16(isp, &src->ctp_reserved1[i],
+ dst->ctp_reserved1[i]);
+ }
+ ISP_IOXGET_32(isp, &src->ctp_rsp_bcnt, dst->ctp_rsp_bcnt);
+ ISP_IOXGET_32(isp, &src->ctp_cmd_bcnt, dst->ctp_cmd_bcnt);
+ for (i = 0; i < 2; i++) {
+ ISP_IOXGET_32(isp, &src->ctp_dataseg[i].ds_base,
+ dst->ctp_dataseg[i].ds_base);
+ ISP_IOXGET_32(isp, &src->ctp_dataseg[i].ds_basehi,
+ dst->ctp_dataseg[i].ds_basehi);
+ ISP_IOXGET_32(isp, &src->ctp_dataseg[i].ds_count,
+ dst->ctp_dataseg[i].ds_count);
+ }
+}
+
+void
+isp_get_ms(struct ispsoftc *isp, isp_ms_t *src, isp_ms_t *dst)
+{
+ int i;
+
+ isp_get_hdr(isp, &src->ms_header, &dst->ms_header);
+ ISP_IOXGET_32(isp, &src->ms_handle, dst->ms_handle);
+ ISP_IOXGET_16(isp, &src->ms_nphdl, dst->ms_nphdl);
+ ISP_IOXGET_16(isp, &src->ms_status, dst->ms_status);
+ ISP_IOXGET_16(isp, &src->ms_flags, dst->ms_flags);
+ ISP_IOXGET_16(isp, &src->ms_reserved1, dst->ms_reserved1);
+ ISP_IOXGET_16(isp, &src->ms_time, dst->ms_time);
+ ISP_IOXGET_16(isp, &src->ms_cmd_cnt, dst->ms_cmd_cnt);
+ ISP_IOXGET_16(isp, &src->ms_tot_cnt, dst->ms_tot_cnt);
+ ISP_IOXGET_8(isp, &src->ms_type, dst->ms_type);
+ ISP_IOXGET_8(isp, &src->ms_r_ctl, dst->ms_r_ctl);
+ ISP_IOXGET_16(isp, &src->ms_rxid, dst->ms_rxid);
+ ISP_IOXGET_16(isp, &src->ms_reserved2, dst->ms_reserved2);
+ ISP_IOXGET_32(isp, &src->ms_rsp_bcnt, dst->ms_rsp_bcnt);
+ ISP_IOXGET_32(isp, &src->ms_cmd_bcnt, dst->ms_cmd_bcnt);
+ for (i = 0; i < 2; i++) {
+ ISP_IOXGET_32(isp, &src->ms_dataseg[i].ds_base,
+ dst->ms_dataseg[i].ds_base);
+ ISP_IOXGET_32(isp, &src->ms_dataseg[i].ds_basehi,
+ dst->ms_dataseg[i].ds_basehi);
+ ISP_IOXGET_32(isp, &src->ms_dataseg[i].ds_count,
+ dst->ms_dataseg[i].ds_count);
+ }
+}
+
+void
+isp_put_ct_pt(struct ispsoftc *isp, isp_ct_pt_t *src, isp_ct_pt_t *dst)
+{
+ int i;
+
+ isp_put_hdr(isp, &src->ctp_header, &dst->ctp_header);
+ ISP_IOXPUT_32(isp, src->ctp_handle, &dst->ctp_handle);
+ ISP_IOXPUT_16(isp, src->ctp_status, &dst->ctp_status);
+ ISP_IOXPUT_16(isp, src->ctp_nphdl, &dst->ctp_nphdl);
+ ISP_IOXPUT_16(isp, src->ctp_cmd_cnt, &dst->ctp_cmd_cnt);
+ ISP_IOXPUT_16(isp, src->ctp_vpidx, &dst->ctp_vpidx);
+ ISP_IOXPUT_16(isp, src->ctp_time, &dst->ctp_time);
+ ISP_IOXPUT_16(isp, src->ctp_reserved0, &dst->ctp_reserved0);
+ ISP_IOXPUT_16(isp, src->ctp_rsp_cnt, &dst->ctp_rsp_cnt);
+ for (i = 0; i < 5; i++) {
+ ISP_IOXPUT_16(isp, src->ctp_reserved1[i],
+ &dst->ctp_reserved1[i]);
+ }
+ ISP_IOXPUT_32(isp, src->ctp_rsp_bcnt, &dst->ctp_rsp_bcnt);
+ ISP_IOXPUT_32(isp, src->ctp_cmd_bcnt, &dst->ctp_cmd_bcnt);
+ for (i = 0; i < 2; i++) {
+ ISP_IOXPUT_32(isp, src->ctp_dataseg[i].ds_base,
+ &dst->ctp_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp, src->ctp_dataseg[i].ds_basehi,
+ &dst->ctp_dataseg[i].ds_basehi);
+ ISP_IOXPUT_32(isp, src->ctp_dataseg[i].ds_count,
+ &dst->ctp_dataseg[i].ds_count);
+ }
+}
+
+void
+isp_put_ms(struct ispsoftc *isp, isp_ms_t *src, isp_ms_t *dst)
+{
+ int i;
+
+ isp_put_hdr(isp, &src->ms_header, &dst->ms_header);
+ ISP_IOXPUT_32(isp, src->ms_handle, &dst->ms_handle);
+ ISP_IOXPUT_16(isp, src->ms_nphdl, &dst->ms_nphdl);
+ ISP_IOXPUT_16(isp, src->ms_status, &dst->ms_status);
+ ISP_IOXPUT_16(isp, src->ms_flags, &dst->ms_flags);
+ ISP_IOXPUT_16(isp, src->ms_reserved1, &dst->ms_reserved1);
+ ISP_IOXPUT_16(isp, src->ms_time, &dst->ms_time);
+ ISP_IOXPUT_16(isp, src->ms_cmd_cnt, &dst->ms_cmd_cnt);
+ ISP_IOXPUT_16(isp, src->ms_tot_cnt, &dst->ms_tot_cnt);
+ ISP_IOXPUT_8(isp, src->ms_type, &dst->ms_type);
+ ISP_IOXPUT_8(isp, src->ms_r_ctl, &dst->ms_r_ctl);
+ ISP_IOXPUT_16(isp, src->ms_rxid, &dst->ms_rxid);
+ ISP_IOXPUT_16(isp, src->ms_reserved2, &dst->ms_reserved2);
+ ISP_IOXPUT_32(isp, src->ms_rsp_bcnt, &dst->ms_rsp_bcnt);
+ ISP_IOXPUT_32(isp, src->ms_cmd_bcnt, &dst->ms_cmd_bcnt);
+ for (i = 0; i < 2; i++) {
+ ISP_IOXPUT_32(isp, src->ms_dataseg[i].ds_base,
+ &dst->ms_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp, src->ms_dataseg[i].ds_basehi,
+ &dst->ms_dataseg[i].ds_basehi);
+ ISP_IOXPUT_32(isp, src->ms_dataseg[i].ds_count,
+ &dst->ms_dataseg[i].ds_count);
+ }
}
/*
@@ -774,330 +1308,969 @@ isp_get_ga_nxt_response(struct ispsoftc *isp, sns_ga_nxt_rsp_t *src,
}
}
+void
+isp_get_els(struct ispsoftc *isp, els_t *src, els_t *dst)
+{
+ int i;
+
+ isp_get_hdr(isp, &src->els_hdr, &dst->els_hdr);
+ ISP_IOXGET_32(isp, &src->els_handle, dst->els_handle);
+ ISP_IOXGET_16(isp, &src->els_status, dst->els_status);
+ ISP_IOXGET_16(isp, &src->els_nphdl, dst->els_nphdl);
+ ISP_IOXGET_16(isp, &src->els_xmit_dsd_count, dst->els_xmit_dsd_count);
+ ISP_IOXGET_8(isp, &src->els_vphdl, dst->els_vphdl);
+ ISP_IOXGET_8(isp, &src->els_sof, dst->els_sof);
+ ISP_IOXGET_32(isp, &src->els_rxid, dst->els_rxid);
+ ISP_IOXGET_16(isp, &src->els_recv_dsd_count, dst->els_recv_dsd_count);
+ ISP_IOXGET_8(isp, &src->els_opcode, dst->els_opcode);
+ ISP_IOXGET_8(isp, &src->els_reserved2, dst->els_reserved1);
+ ISP_IOXGET_8(isp, &src->els_did_lo, dst->els_did_lo);
+ ISP_IOXGET_8(isp, &src->els_did_mid, dst->els_did_mid);
+ ISP_IOXGET_8(isp, &src->els_did_hi, dst->els_did_hi);
+ ISP_IOXGET_8(isp, &src->els_reserved2, dst->els_reserved2);
+ ISP_IOXGET_16(isp, &src->els_reserved3, dst->els_reserved3);
+ ISP_IOXGET_16(isp, &src->els_ctl_flags, dst->els_ctl_flags);
+ ISP_IOXGET_32(isp, &src->els_bytecnt, dst->els_bytecnt);
+ ISP_IOXGET_32(isp, &src->els_subcode1, dst->els_subcode1);
+ ISP_IOXGET_32(isp, &src->els_subcode2, dst->els_subcode2);
+ for (i = 0; i < 20; i++) {
+ ISP_IOXGET_8(isp, &src->els_reserved4[i],
+ dst->els_reserved4[i]);
+ }
+}
+
+void
+isp_put_els(struct ispsoftc *isp, els_t *src, els_t *dst)
+{
+ isp_put_hdr(isp, &src->els_hdr, &dst->els_hdr);
+ ISP_IOXPUT_32(isp, src->els_handle, &dst->els_handle);
+ ISP_IOXPUT_16(isp, src->els_status, &dst->els_status);
+ ISP_IOXPUT_16(isp, src->els_nphdl, &dst->els_nphdl);
+ ISP_IOXPUT_16(isp, src->els_xmit_dsd_count, &dst->els_xmit_dsd_count);
+ ISP_IOXPUT_8(isp, src->els_vphdl, &dst->els_vphdl);
+ ISP_IOXPUT_8(isp, src->els_sof, &dst->els_sof);
+ ISP_IOXPUT_32(isp, src->els_rxid, &dst->els_rxid);
+ ISP_IOXPUT_16(isp, src->els_recv_dsd_count, &dst->els_recv_dsd_count);
+ ISP_IOXPUT_8(isp, src->els_opcode, &dst->els_opcode);
+ ISP_IOXPUT_8(isp, src->els_reserved2, &dst->els_reserved1);
+ ISP_IOXPUT_8(isp, src->els_did_lo, &dst->els_did_lo);
+ ISP_IOXPUT_8(isp, src->els_did_mid, &dst->els_did_mid);
+ ISP_IOXPUT_8(isp, src->els_did_hi, &dst->els_did_hi);
+ ISP_IOXPUT_8(isp, src->els_reserved2, &dst->els_reserved2);
+ ISP_IOXPUT_16(isp, src->els_reserved3, &dst->els_reserved3);
+ ISP_IOXPUT_16(isp, src->els_ctl_flags, &dst->els_ctl_flags);
+ ISP_IOXPUT_32(isp, src->els_recv_bytecnt, &dst->els_recv_bytecnt);
+ ISP_IOXPUT_32(isp, src->els_xmit_bytecnt, &dst->els_xmit_bytecnt);
+ ISP_IOXPUT_32(isp, src->els_xmit_dsd_length, &dst->els_xmit_dsd_length);
+ ISP_IOXPUT_16(isp, src->els_xmit_dsd_a1500, &dst->els_xmit_dsd_a1500);
+ ISP_IOXPUT_16(isp, src->els_xmit_dsd_a3116, &dst->els_xmit_dsd_a3116);
+ ISP_IOXPUT_16(isp, src->els_xmit_dsd_a4732, &dst->els_xmit_dsd_a4732);
+ ISP_IOXPUT_16(isp, src->els_xmit_dsd_a6348, &dst->els_xmit_dsd_a6348);
+ ISP_IOXPUT_32(isp, src->els_recv_dsd_length, &dst->els_recv_dsd_length);
+ ISP_IOXPUT_16(isp, src->els_recv_dsd_a1500, &dst->els_recv_dsd_a1500);
+ ISP_IOXPUT_16(isp, src->els_recv_dsd_a3116, &dst->els_recv_dsd_a3116);
+ ISP_IOXPUT_16(isp, src->els_recv_dsd_a4732, &dst->els_recv_dsd_a4732);
+ ISP_IOXPUT_16(isp, src->els_recv_dsd_a6348, &dst->els_recv_dsd_a6348);
+}
+
+/*
+ * FC Structure Canonicalization
+ */
+
+void
+isp_get_fc_hdr(struct ispsoftc *isp, fc_hdr_t *src, fc_hdr_t *dst)
+{
+ ISP_IOZGET_8(isp, &src->r_ctl, dst->r_ctl);
+ ISP_IOZGET_8(isp, &src->d_id[0], dst->d_id[0]);
+ ISP_IOZGET_8(isp, &src->d_id[1], dst->d_id[1]);
+ ISP_IOZGET_8(isp, &src->d_id[2], dst->d_id[2]);
+ ISP_IOZGET_8(isp, &src->cs_ctl, dst->cs_ctl);
+ ISP_IOZGET_8(isp, &src->s_id[0], dst->s_id[0]);
+ ISP_IOZGET_8(isp, &src->s_id[1], dst->s_id[1]);
+ ISP_IOZGET_8(isp, &src->s_id[2], dst->s_id[2]);
+ ISP_IOZGET_8(isp, &src->type, dst->type);
+ ISP_IOZGET_8(isp, &src->f_ctl, dst->f_ctl);
+ ISP_IOZGET_8(isp, &src->seq_id, dst->seq_id);
+ ISP_IOZGET_8(isp, &src->df_ctl, dst->df_ctl);
+ ISP_IOZGET_16(isp, &src->seq_cnt, dst->seq_cnt);
+ /* XXX SOMETHING WAS AND STILL CONTINUES WRONG HERE XXX */
+#if 0
+ ISP_IOZGET_16(isp, &src->ox_id, dst->ox_id);
+ ISP_IOZGET_16(isp, &src->rx_id, dst->rx_id);
+#else
+ ISP_IOZGET_32(isp, &src->ox_id, dst->parameter);
+ dst->ox_id = dst->parameter;
+ dst->rx_id = dst->parameter >> 16;
+#endif
+ ISP_IOZGET_32(isp, &src->parameter, dst->parameter);
+}
+
+void
+isp_get_fcp_cmnd_iu(struct ispsoftc *isp, fcp_cmnd_iu_t *src, fcp_cmnd_iu_t *dst)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ ISP_IOZGET_8(isp, &src->fcp_cmnd_lun[i], dst->fcp_cmnd_lun[i]);
+ }
+ ISP_IOZGET_8(isp, &src->fcp_cmnd_crn, dst->fcp_cmnd_crn);
+ ISP_IOZGET_8(isp, &src->fcp_cmnd_task_attribute,
+ dst->fcp_cmnd_task_attribute);
+ ISP_IOZGET_8(isp, &src->fcp_cmnd_task_management,
+ dst->fcp_cmnd_task_management);
+ ISP_IOZGET_8(isp, &src->fcp_cmnd_alen_datadir,
+ dst->fcp_cmnd_alen_datadir);
+ for (i = 0; i < 16; i++) {
+ ISP_IOZGET_8(isp, &src->cdb_dl.sf.fcp_cmnd_cdb[i],
+ dst->cdb_dl.sf.fcp_cmnd_cdb[i]);
+ }
+ ISP_IOZGET_32(isp, &src->cdb_dl.sf.fcp_cmnd_dl,
+ dst->cdb_dl.sf.fcp_cmnd_dl);
+}
+
+void
+isp_put_rft_id(struct ispsoftc *isp, rft_id_t *src, rft_id_t *dst)
+{
+ int i;
+ isp_put_ct_hdr(isp, &src->rftid_hdr, &dst->rftid_hdr);
+ ISP_IOZPUT_8(isp, src->rftid_reserved, &dst->rftid_reserved);
+ for (i = 0; i < 3; i++) {
+ ISP_IOZPUT_8(isp, src->rftid_portid[i], &dst->rftid_portid[i]);
+ }
+ for (i = 0; i < 8; i++) {
+ ISP_IOZPUT_32(isp, src->rftid_fc4types[i],
+ &dst->rftid_fc4types[i]);
+ }
+}
+
+void
+isp_get_ct_hdr(struct ispsoftc *isp, ct_hdr_t *src, ct_hdr_t *dst)
+{
+ ISP_IOZGET_8(isp, &src->ct_revision, dst->ct_revision);
+ ISP_IOZGET_8(isp, &src->ct_in_id[0], dst->ct_in_id[0]);
+ ISP_IOZGET_8(isp, &src->ct_in_id[1], dst->ct_in_id[1]);
+ ISP_IOZGET_8(isp, &src->ct_in_id[2], dst->ct_in_id[2]);
+ ISP_IOZGET_8(isp, &src->ct_fcs_type, dst->ct_fcs_type);
+ ISP_IOZGET_8(isp, &src->ct_fcs_subtype, dst->ct_fcs_subtype);
+ ISP_IOZGET_8(isp, &src->ct_options, dst->ct_options);
+ ISP_IOZGET_8(isp, &src->ct_reserved0, dst->ct_reserved0);
+ ISP_IOZGET_16(isp, &src->ct_cmd_resp, dst->ct_cmd_resp);
+ ISP_IOZGET_16(isp, &src->ct_bcnt_resid, dst->ct_bcnt_resid);
+ ISP_IOZGET_8(isp, &src->ct_reserved1, dst->ct_reserved1);
+ ISP_IOZGET_8(isp, &src->ct_reason, dst->ct_reason);
+ ISP_IOZGET_8(isp, &src->ct_explanation, dst->ct_explanation);
+ ISP_IOZGET_8(isp, &src->ct_vunique, dst->ct_vunique);
+}
+
+void
+isp_put_ct_hdr(struct ispsoftc *isp, ct_hdr_t *src, ct_hdr_t *dst)
+{
+ ISP_IOZPUT_8(isp, src->ct_revision, &dst->ct_revision);
+ ISP_IOZPUT_8(isp, src->ct_in_id[0], &dst->ct_in_id[0]);
+ ISP_IOZPUT_8(isp, src->ct_in_id[1], &dst->ct_in_id[1]);
+ ISP_IOZPUT_8(isp, src->ct_in_id[2], &dst->ct_in_id[2]);
+ ISP_IOZPUT_8(isp, src->ct_fcs_type, &dst->ct_fcs_type);
+ ISP_IOZPUT_8(isp, src->ct_fcs_subtype, &dst->ct_fcs_subtype);
+ ISP_IOZPUT_8(isp, src->ct_options, &dst->ct_options);
+ ISP_IOZPUT_8(isp, src->ct_reserved0, &dst->ct_reserved0);
+ ISP_IOZPUT_16(isp, src->ct_cmd_resp, &dst->ct_cmd_resp);
+ ISP_IOZPUT_16(isp, src->ct_bcnt_resid, &dst->ct_bcnt_resid);
+ ISP_IOZPUT_8(isp, src->ct_reserved1, &dst->ct_reserved1);
+ ISP_IOZPUT_8(isp, src->ct_reason, &dst->ct_reason);
+ ISP_IOZPUT_8(isp, src->ct_explanation, &dst->ct_explanation);
+ ISP_IOZPUT_8(isp, src->ct_vunique, &dst->ct_vunique);
+}
+
#ifdef ISP_TARGET_MODE
+int
+isp_save_xs_tgt(struct ispsoftc *isp, void *xs, u_int32_t *handlep)
+{
+ int i;
+
+ for (i = 0; i < (int) isp->isp_maxcmds; i++) {
+ if (isp->isp_tgtlist[i] == NULL) {
+ break;
+ }
+ }
+ if (i == isp->isp_maxcmds) {
+ return (-1);
+ }
+ isp->isp_tgtlist[i] = xs;
+ *handlep = (i+1) | 0x8000;
+ return (0);
+}
+
+void *
+isp_find_xs_tgt(struct ispsoftc *isp, u_int32_t handle)
+{
+ if (handle == 0 || IS_TARGET_HANDLE(handle) == 0 ||
+ (handle & ISP_HANDLE_MASK) > isp->isp_maxcmds) {
+ isp_prt(isp, ISP_LOGERR, "bad handle in isp_find_xs_tgt");
+ return (NULL);
+ } else {
+ return (isp->isp_tgtlist[(handle & ISP_HANDLE_MASK) - 1]);
+ }
+}
+
+u_int32_t
+isp_find_tgt_handle(struct ispsoftc *isp, void *xs)
+{
+ int i;
+ if (xs != NULL) {
+ for (i = 0; i < isp->isp_maxcmds; i++) {
+ if (isp->isp_tgtlist[i] == xs) {
+ return ((i+1) & ISP_HANDLE_MASK);
+ }
+ }
+ }
+ return (0);
+}
+
void
-isp_put_atio(struct ispsoftc *isp, at_entry_t *atsrc, at_entry_t *atdst)
+isp_destroy_tgt_handle(struct ispsoftc *isp, u_int32_t handle)
+{
+ if (handle == 0 || IS_TARGET_HANDLE(handle) == 0 ||
+ (handle & ISP_HANDLE_MASK) > isp->isp_maxcmds) {
+ isp_prt(isp, ISP_LOGERR,
+ "bad handle in isp_destroy_tgt_handle");
+ } else {
+ isp->isp_tgtlist[(handle & ISP_HANDLE_MASK) - 1] = NULL;
+ }
+}
+
+void
+isp_put_atio(struct ispsoftc *isp, at_entry_t *src, at_entry_t *dst)
{
int i;
- isp_copy_out_hdr(isp, &atsrc->at_header, &atdst->at_header);
- ISP_IOXPUT_16(isp, atsrc->at_reserved, &atdst->at_reserved);
- ISP_IOXPUT_16(isp, atsrc->at_handle, &atdst->at_handle);
+ isp_put_hdr(isp, &src->at_header, &dst->at_header);
+ ISP_IOXPUT_16(isp, src->at_reserved, &dst->at_reserved);
+ ISP_IOXPUT_16(isp, src->at_handle, &dst->at_handle);
if (ISP_IS_SBUS(isp)) {
- ISP_IOXPUT_8(isp, atsrc->at_lun, &atdst->at_iid);
- ISP_IOXPUT_8(isp, atsrc->at_iid, &atdst->at_lun);
- ISP_IOXPUT_8(isp, atsrc->at_cdblen, &atdst->at_tgt);
- ISP_IOXPUT_8(isp, atsrc->at_tgt, &atdst->at_cdblen);
- ISP_IOXPUT_8(isp, atsrc->at_status, &atdst->at_scsi_status);
- ISP_IOXPUT_8(isp, atsrc->at_scsi_status, &atdst->at_status);
- ISP_IOXPUT_8(isp, atsrc->at_tag_val, &atdst->at_tag_type);
- ISP_IOXPUT_8(isp, atsrc->at_tag_type, &atdst->at_tag_val);
+ ISP_IOXPUT_8(isp, src->at_lun, &dst->at_iid);
+ ISP_IOXPUT_8(isp, src->at_iid, &dst->at_lun);
+ ISP_IOXPUT_8(isp, src->at_cdblen, &dst->at_tgt);
+ ISP_IOXPUT_8(isp, src->at_tgt, &dst->at_cdblen);
+ ISP_IOXPUT_8(isp, src->at_status, &dst->at_scsi_status);
+ ISP_IOXPUT_8(isp, src->at_scsi_status, &dst->at_status);
+ ISP_IOXPUT_8(isp, src->at_tag_val, &dst->at_tag_type);
+ ISP_IOXPUT_8(isp, src->at_tag_type, &dst->at_tag_val);
} else {
- ISP_IOXPUT_8(isp, atsrc->at_lun, &atdst->at_lun);
- ISP_IOXPUT_8(isp, atsrc->at_iid, &atdst->at_iid);
- ISP_IOXPUT_8(isp, atsrc->at_cdblen, &atdst->at_cdblen);
- ISP_IOXPUT_8(isp, atsrc->at_tgt, &atdst->at_tgt);
- ISP_IOXPUT_8(isp, atsrc->at_status, &atdst->at_status);
- ISP_IOXPUT_8(isp, atsrc->at_scsi_status,
- &atdst->at_scsi_status);
- ISP_IOXPUT_8(isp, atsrc->at_tag_val, &atdst->at_tag_val);
- ISP_IOXPUT_8(isp, atsrc->at_tag_type, &atdst->at_tag_type);
- }
- ISP_IOXPUT_32(isp, atsrc->at_flags, &atdst->at_flags);
+ ISP_IOXPUT_8(isp, src->at_lun, &dst->at_lun);
+ ISP_IOXPUT_8(isp, src->at_iid, &dst->at_iid);
+ ISP_IOXPUT_8(isp, src->at_cdblen, &dst->at_cdblen);
+ ISP_IOXPUT_8(isp, src->at_tgt, &dst->at_tgt);
+ ISP_IOXPUT_8(isp, src->at_status, &dst->at_status);
+ ISP_IOXPUT_8(isp, src->at_scsi_status,
+ &dst->at_scsi_status);
+ ISP_IOXPUT_8(isp, src->at_tag_val, &dst->at_tag_val);
+ ISP_IOXPUT_8(isp, src->at_tag_type, &dst->at_tag_type);
+ }
+ ISP_IOXPUT_32(isp, src->at_flags, &dst->at_flags);
for (i = 0; i < ATIO_CDBLEN; i++) {
- ISP_IOXPUT_8(isp, atsrc->at_cdb[i], &atdst->at_cdb[i]);
+ ISP_IOXPUT_8(isp, src->at_cdb[i], &dst->at_cdb[i]);
}
for (i = 0; i < QLTM_SENSELEN; i++) {
- ISP_IOXPUT_8(isp, atsrc->at_sense[i], &atdst->at_sense[i]);
+ ISP_IOXPUT_8(isp, src->at_sense[i], &dst->at_sense[i]);
}
}
void
-isp_get_atio(struct ispsoftc *isp, at_entry_t *atsrc, at_entry_t *atdst)
+isp_get_atio(struct ispsoftc *isp, at_entry_t *src, at_entry_t *dst)
{
int i;
- isp_copy_in_hdr(isp, &atsrc->at_header, &atdst->at_header);
- ISP_IOXGET_16(isp, &atsrc->at_reserved, atdst->at_reserved);
- ISP_IOXGET_16(isp, &atsrc->at_handle, atdst->at_handle);
+ isp_get_hdr(isp, &src->at_header, &dst->at_header);
+ ISP_IOXGET_16(isp, &src->at_reserved, dst->at_reserved);
+ ISP_IOXGET_16(isp, &src->at_handle, dst->at_handle);
if (ISP_IS_SBUS(isp)) {
- ISP_IOXGET_8(isp, &atsrc->at_lun, atdst->at_iid);
- ISP_IOXGET_8(isp, &atsrc->at_iid, atdst->at_lun);
- ISP_IOXGET_8(isp, &atsrc->at_cdblen, atdst->at_tgt);
- ISP_IOXGET_8(isp, &atsrc->at_tgt, atdst->at_cdblen);
- ISP_IOXGET_8(isp, &atsrc->at_status, atdst->at_scsi_status);
- ISP_IOXGET_8(isp, &atsrc->at_scsi_status, atdst->at_status);
- ISP_IOXGET_8(isp, &atsrc->at_tag_val, atdst->at_tag_type);
- ISP_IOXGET_8(isp, &atsrc->at_tag_type, atdst->at_tag_val);
+ ISP_IOXGET_8(isp, &src->at_lun, dst->at_iid);
+ ISP_IOXGET_8(isp, &src->at_iid, dst->at_lun);
+ ISP_IOXGET_8(isp, &src->at_cdblen, dst->at_tgt);
+ ISP_IOXGET_8(isp, &src->at_tgt, dst->at_cdblen);
+ ISP_IOXGET_8(isp, &src->at_status, dst->at_scsi_status);
+ ISP_IOXGET_8(isp, &src->at_scsi_status, dst->at_status);
+ ISP_IOXGET_8(isp, &src->at_tag_val, dst->at_tag_type);
+ ISP_IOXGET_8(isp, &src->at_tag_type, dst->at_tag_val);
} else {
- ISP_IOXGET_8(isp, &atsrc->at_lun, atdst->at_lun);
- ISP_IOXGET_8(isp, &atsrc->at_iid, atdst->at_iid);
- ISP_IOXGET_8(isp, &atsrc->at_cdblen, atdst->at_cdblen);
- ISP_IOXGET_8(isp, &atsrc->at_tgt, atdst->at_tgt);
- ISP_IOXGET_8(isp, &atsrc->at_status, atdst->at_status);
- ISP_IOXGET_8(isp, &atsrc->at_scsi_status,
- atdst->at_scsi_status);
- ISP_IOXGET_8(isp, &atsrc->at_tag_val, atdst->at_tag_val);
- ISP_IOXGET_8(isp, &atsrc->at_tag_type, atdst->at_tag_type);
- }
- ISP_IOXGET_32(isp, &atsrc->at_flags, atdst->at_flags);
+ ISP_IOXGET_8(isp, &src->at_lun, dst->at_lun);
+ ISP_IOXGET_8(isp, &src->at_iid, dst->at_iid);
+ ISP_IOXGET_8(isp, &src->at_cdblen, dst->at_cdblen);
+ ISP_IOXGET_8(isp, &src->at_tgt, dst->at_tgt);
+ ISP_IOXGET_8(isp, &src->at_status, dst->at_status);
+ ISP_IOXGET_8(isp, &src->at_scsi_status,
+ dst->at_scsi_status);
+ ISP_IOXGET_8(isp, &src->at_tag_val, dst->at_tag_val);
+ ISP_IOXGET_8(isp, &src->at_tag_type, dst->at_tag_type);
+ }
+ ISP_IOXGET_32(isp, &src->at_flags, dst->at_flags);
for (i = 0; i < ATIO_CDBLEN; i++) {
- ISP_IOXGET_8(isp, &atsrc->at_cdb[i], atdst->at_cdb[i]);
+ ISP_IOXGET_8(isp, &src->at_cdb[i], dst->at_cdb[i]);
}
for (i = 0; i < QLTM_SENSELEN; i++) {
- ISP_IOXGET_8(isp, &atsrc->at_sense[i], atdst->at_sense[i]);
+ ISP_IOXGET_8(isp, &src->at_sense[i], dst->at_sense[i]);
}
}
void
-isp_put_atio2(struct ispsoftc *isp, at2_entry_t *atsrc, at2_entry_t *atdst)
+isp_put_atio2(struct ispsoftc *isp, at2_entry_t *src, at2_entry_t *dst)
{
int i;
- isp_copy_out_hdr(isp, &atsrc->at_header, &atdst->at_header);
- ISP_IOXPUT_32(isp, atsrc->at_reserved, &atdst->at_reserved);
- ISP_IOXPUT_8(isp, atsrc->at_lun, &atdst->at_lun);
- ISP_IOXPUT_8(isp, atsrc->at_iid, &atdst->at_iid);
- ISP_IOXPUT_16(isp, atsrc->at_rxid, &atdst->at_rxid);
- ISP_IOXPUT_16(isp, atsrc->at_flags, &atdst->at_flags);
- ISP_IOXPUT_16(isp, atsrc->at_status, &atdst->at_status);
- ISP_IOXPUT_8(isp, atsrc->at_reserved1, &atdst->at_reserved1);
- ISP_IOXPUT_8(isp, atsrc->at_taskcodes, &atdst->at_taskcodes);
- ISP_IOXPUT_8(isp, atsrc->at_taskflags, &atdst->at_taskflags);
- ISP_IOXPUT_8(isp, atsrc->at_execodes, &atdst->at_execodes);
+ isp_put_hdr(isp, &src->at_header, &dst->at_header);
+ ISP_IOXPUT_32(isp, src->at_reserved, &dst->at_reserved);
+ ISP_IOXPUT_8(isp, src->at_lun, &dst->at_lun);
+ ISP_IOXPUT_8(isp, src->at_iid, &dst->at_iid);
+ ISP_IOXPUT_16(isp, src->at_rxid, &dst->at_rxid);
+ ISP_IOXPUT_16(isp, src->at_flags, &dst->at_flags);
+ ISP_IOXPUT_16(isp, src->at_status, &dst->at_status);
+ ISP_IOXPUT_8(isp, src->at_crn, &dst->at_crn);
+ ISP_IOXPUT_8(isp, src->at_taskcodes, &dst->at_taskcodes);
+ ISP_IOXPUT_8(isp, src->at_taskflags, &dst->at_taskflags);
+ ISP_IOXPUT_8(isp, src->at_execodes, &dst->at_execodes);
for (i = 0; i < ATIO2_CDBLEN; i++) {
- ISP_IOXPUT_8(isp, atsrc->at_cdb[i], &atdst->at_cdb[i]);
+ ISP_IOXPUT_8(isp, src->at_cdb[i], &dst->at_cdb[i]);
}
- ISP_IOXPUT_32(isp, atsrc->at_datalen, &atdst->at_datalen);
- ISP_IOXPUT_16(isp, atsrc->at_scclun, &atdst->at_scclun);
+ ISP_IOXPUT_32(isp, src->at_datalen, &dst->at_datalen);
+ ISP_IOXPUT_16(isp, src->at_scclun, &dst->at_scclun);
for (i = 0; i < 4; i++) {
- ISP_IOXPUT_16(isp, atsrc->at_wwpn[i], &atdst->at_wwpn[i]);
+ ISP_IOXPUT_16(isp, src->at_wwpn[i], &dst->at_wwpn[i]);
}
for (i = 0; i < 6; i++) {
- ISP_IOXPUT_16(isp, atsrc->at_reserved2[i],
- &atdst->at_reserved2[i]);
+ ISP_IOXPUT_16(isp, src->at_reserved2[i],
+ &dst->at_reserved2[i]);
}
- ISP_IOXPUT_16(isp, atsrc->at_oxid, &atdst->at_oxid);
+ ISP_IOXPUT_16(isp, src->at_oxid, &dst->at_oxid);
}
void
-isp_get_atio2(struct ispsoftc *isp, at2_entry_t *atsrc, at2_entry_t *atdst)
+isp_put_atio2e(struct ispsoftc *isp, at2e_entry_t *src, at2e_entry_t *dst)
{
int i;
- isp_copy_in_hdr(isp, &atsrc->at_header, &atdst->at_header);
- ISP_IOXGET_32(isp, &atsrc->at_reserved, atdst->at_reserved);
- ISP_IOXGET_8(isp, &atsrc->at_lun, atdst->at_lun);
- ISP_IOXGET_8(isp, &atsrc->at_iid, atdst->at_iid);
- ISP_IOXGET_16(isp, &atsrc->at_rxid, atdst->at_rxid);
- ISP_IOXGET_16(isp, &atsrc->at_flags, atdst->at_flags);
- ISP_IOXGET_16(isp, &atsrc->at_status, atdst->at_status);
- ISP_IOXGET_8(isp, &atsrc->at_reserved1, atdst->at_reserved1);
- ISP_IOXGET_8(isp, &atsrc->at_taskcodes, atdst->at_taskcodes);
- ISP_IOXGET_8(isp, &atsrc->at_taskflags, atdst->at_taskflags);
- ISP_IOXGET_8(isp, &atsrc->at_execodes, atdst->at_execodes);
+ isp_put_hdr(isp, &src->at_header, &dst->at_header);
+ ISP_IOXPUT_32(isp, src->at_reserved, &dst->at_reserved);
+ ISP_IOXPUT_16(isp, src->at_iid, &dst->at_iid);
+ ISP_IOXPUT_16(isp, src->at_rxid, &dst->at_rxid);
+ ISP_IOXPUT_16(isp, src->at_flags, &dst->at_flags);
+ ISP_IOXPUT_16(isp, src->at_status, &dst->at_status);
+ ISP_IOXPUT_8(isp, src->at_crn, &dst->at_crn);
+ ISP_IOXPUT_8(isp, src->at_taskcodes, &dst->at_taskcodes);
+ ISP_IOXPUT_8(isp, src->at_taskflags, &dst->at_taskflags);
+ ISP_IOXPUT_8(isp, src->at_execodes, &dst->at_execodes);
for (i = 0; i < ATIO2_CDBLEN; i++) {
- ISP_IOXGET_8(isp, &atsrc->at_cdb[i], atdst->at_cdb[i]);
+ ISP_IOXPUT_8(isp, src->at_cdb[i], &dst->at_cdb[i]);
}
- ISP_IOXGET_32(isp, &atsrc->at_datalen, atdst->at_datalen);
- ISP_IOXGET_16(isp, &atsrc->at_scclun, atdst->at_scclun);
+ ISP_IOXPUT_32(isp, src->at_datalen, &dst->at_datalen);
+ ISP_IOXPUT_16(isp, src->at_scclun, &dst->at_scclun);
for (i = 0; i < 4; i++) {
- ISP_IOXGET_16(isp, &atsrc->at_wwpn[i], atdst->at_wwpn[i]);
+ ISP_IOXPUT_16(isp, src->at_wwpn[i], &dst->at_wwpn[i]);
}
for (i = 0; i < 6; i++) {
- ISP_IOXGET_16(isp, &atsrc->at_reserved2[i],
- atdst->at_reserved2[i]);
+ ISP_IOXPUT_16(isp, src->at_reserved2[i],
+ &dst->at_reserved2[i]);
}
- ISP_IOXGET_16(isp, &atsrc->at_oxid, atdst->at_oxid);
+ ISP_IOXPUT_16(isp, src->at_oxid, &dst->at_oxid);
}
void
-isp_put_ctio(struct ispsoftc *isp, ct_entry_t *ctsrc, ct_entry_t *ctdst)
+isp_get_atio2(struct ispsoftc *isp, at2_entry_t *src, at2_entry_t *dst)
{
int i;
- isp_copy_out_hdr(isp, &ctsrc->ct_header, &ctdst->ct_header);
- ISP_IOXPUT_16(isp, ctsrc->ct_reserved, &ctdst->ct_reserved);
- ISP_IOXPUT_16(isp, ctsrc->ct_fwhandle, &ctdst->ct_fwhandle);
+ isp_get_hdr(isp, &src->at_header, &dst->at_header);
+ ISP_IOXGET_32(isp, &src->at_reserved, dst->at_reserved);
+ ISP_IOXGET_8(isp, &src->at_lun, dst->at_lun);
+ ISP_IOXGET_8(isp, &src->at_iid, dst->at_iid);
+ ISP_IOXGET_16(isp, &src->at_rxid, dst->at_rxid);
+ ISP_IOXGET_16(isp, &src->at_flags, dst->at_flags);
+ ISP_IOXGET_16(isp, &src->at_status, dst->at_status);
+ ISP_IOXGET_8(isp, &src->at_crn, dst->at_crn);
+ ISP_IOXGET_8(isp, &src->at_taskcodes, dst->at_taskcodes);
+ ISP_IOXGET_8(isp, &src->at_taskflags, dst->at_taskflags);
+ ISP_IOXGET_8(isp, &src->at_execodes, dst->at_execodes);
+ for (i = 0; i < ATIO2_CDBLEN; i++) {
+ ISP_IOXGET_8(isp, &src->at_cdb[i], dst->at_cdb[i]);
+ }
+ ISP_IOXGET_32(isp, &src->at_datalen, dst->at_datalen);
+ ISP_IOXGET_16(isp, &src->at_scclun, dst->at_scclun);
+ for (i = 0; i < 4; i++) {
+ ISP_IOXGET_16(isp, &src->at_wwpn[i], dst->at_wwpn[i]);
+ }
+ for (i = 0; i < 6; i++) {
+ ISP_IOXGET_16(isp, &src->at_reserved2[i],
+ dst->at_reserved2[i]);
+ }
+ ISP_IOXGET_16(isp, &src->at_oxid, dst->at_oxid);
+}
+
+void
+isp_get_atio2e(struct ispsoftc *isp, at2e_entry_t *src, at2e_entry_t *dst)
+{
+ int i;
+ isp_get_hdr(isp, &src->at_header, &dst->at_header);
+ ISP_IOXGET_32(isp, &src->at_reserved, dst->at_reserved);
+ ISP_IOXGET_16(isp, &src->at_iid, dst->at_iid);
+ ISP_IOXGET_16(isp, &src->at_rxid, dst->at_rxid);
+ ISP_IOXGET_16(isp, &src->at_flags, dst->at_flags);
+ ISP_IOXGET_16(isp, &src->at_status, dst->at_status);
+ ISP_IOXGET_8(isp, &src->at_crn, dst->at_crn);
+ ISP_IOXGET_8(isp, &src->at_taskcodes, dst->at_taskcodes);
+ ISP_IOXGET_8(isp, &src->at_taskflags, dst->at_taskflags);
+ ISP_IOXGET_8(isp, &src->at_execodes, dst->at_execodes);
+ for (i = 0; i < ATIO2_CDBLEN; i++) {
+ ISP_IOXGET_8(isp, &src->at_cdb[i], dst->at_cdb[i]);
+ }
+ ISP_IOXGET_32(isp, &src->at_datalen, dst->at_datalen);
+ ISP_IOXGET_16(isp, &src->at_scclun, dst->at_scclun);
+ for (i = 0; i < 4; i++) {
+ ISP_IOXGET_16(isp, &src->at_wwpn[i], dst->at_wwpn[i]);
+ }
+ for (i = 0; i < 6; i++) {
+ ISP_IOXGET_16(isp, &src->at_reserved2[i],
+ dst->at_reserved2[i]);
+ }
+ ISP_IOXGET_16(isp, &src->at_oxid, dst->at_oxid);
+}
+
+void
+isp_get_atio7(struct ispsoftc *isp, at7_entry_t *src, at7_entry_t *dst)
+{
+ ISP_IOXGET_8(isp, &src->at_type, dst->at_type);
+ ISP_IOXGET_8(isp, &src->at_count, dst->at_count);
+ ISP_IOXGET_16(isp, &src->at_ta_len, dst->at_ta_len);
+ ISP_IOXGET_32(isp, &src->at_rxid, dst->at_rxid);
+ isp_get_fc_hdr(isp, &src->at_hdr, &dst->at_hdr);
+ isp_get_fcp_cmnd_iu(isp, &src->at_cmnd, &dst->at_cmnd);
+}
+
+void
+isp_put_ctio(struct ispsoftc *isp, ct_entry_t *src, ct_entry_t *dst)
+{
+ int i;
+ isp_put_hdr(isp, &src->ct_header, &dst->ct_header);
+ ISP_IOXPUT_16(isp, src->ct_syshandle, &dst->ct_syshandle);
+ ISP_IOXPUT_16(isp, src->ct_fwhandle, &dst->ct_fwhandle);
if (ISP_IS_SBUS(isp)) {
- ISP_IOXPUT_8(isp, ctsrc->ct_iid, &ctdst->ct_lun);
- ISP_IOXPUT_8(isp, ctsrc->ct_lun, &ctdst->ct_iid);
- ISP_IOXPUT_8(isp, ctsrc->ct_tgt, &ctdst->ct_reserved2);
- ISP_IOXPUT_8(isp, ctsrc->ct_reserved2, &ctdst->ct_tgt);
- ISP_IOXPUT_8(isp, ctsrc->ct_status, &ctdst->ct_scsi_status);
- ISP_IOXPUT_8(isp, ctsrc->ct_scsi_status, &ctdst->ct_status);
- ISP_IOXPUT_8(isp, ctsrc->ct_tag_type, &ctdst->ct_tag_val);
- ISP_IOXPUT_8(isp, ctsrc->ct_tag_val, &ctdst->ct_tag_type);
+ ISP_IOXPUT_8(isp, src->ct_iid, &dst->ct_lun);
+ ISP_IOXPUT_8(isp, src->ct_lun, &dst->ct_iid);
+ ISP_IOXPUT_8(isp, src->ct_tgt, &dst->ct_reserved2);
+ ISP_IOXPUT_8(isp, src->ct_reserved2, &dst->ct_tgt);
+ ISP_IOXPUT_8(isp, src->ct_status, &dst->ct_scsi_status);
+ ISP_IOXPUT_8(isp, src->ct_scsi_status, &dst->ct_status);
+ ISP_IOXPUT_8(isp, src->ct_tag_type, &dst->ct_tag_val);
+ ISP_IOXPUT_8(isp, src->ct_tag_val, &dst->ct_tag_type);
} else {
- ISP_IOXPUT_8(isp, ctsrc->ct_iid, &ctdst->ct_iid);
- ISP_IOXPUT_8(isp, ctsrc->ct_lun, &ctdst->ct_lun);
- ISP_IOXPUT_8(isp, ctsrc->ct_tgt, &ctdst->ct_tgt);
- ISP_IOXPUT_8(isp, ctsrc->ct_reserved2, &ctdst->ct_reserved2);
- ISP_IOXPUT_8(isp, ctsrc->ct_scsi_status,
- &ctdst->ct_scsi_status);
- ISP_IOXPUT_8(isp, ctsrc->ct_status, &ctdst->ct_status);
- ISP_IOXPUT_8(isp, ctsrc->ct_tag_type, &ctdst->ct_tag_type);
- ISP_IOXPUT_8(isp, ctsrc->ct_tag_val, &ctdst->ct_tag_val);
- }
- ISP_IOXPUT_32(isp, ctsrc->ct_flags, &ctdst->ct_flags);
- ISP_IOXPUT_32(isp, ctsrc->ct_xfrlen, &ctdst->ct_xfrlen);
- ISP_IOXPUT_32(isp, ctsrc->ct_resid, &ctdst->ct_resid);
- ISP_IOXPUT_16(isp, ctsrc->ct_timeout, &ctdst->ct_timeout);
- ISP_IOXPUT_16(isp, ctsrc->ct_seg_count, &ctdst->ct_seg_count);
+ ISP_IOXPUT_8(isp, src->ct_iid, &dst->ct_iid);
+ ISP_IOXPUT_8(isp, src->ct_lun, &dst->ct_lun);
+ ISP_IOXPUT_8(isp, src->ct_tgt, &dst->ct_tgt);
+ ISP_IOXPUT_8(isp, src->ct_reserved2, &dst->ct_reserved2);
+ ISP_IOXPUT_8(isp, src->ct_scsi_status,
+ &dst->ct_scsi_status);
+ ISP_IOXPUT_8(isp, src->ct_status, &dst->ct_status);
+ ISP_IOXPUT_8(isp, src->ct_tag_type, &dst->ct_tag_type);
+ ISP_IOXPUT_8(isp, src->ct_tag_val, &dst->ct_tag_val);
+ }
+ ISP_IOXPUT_32(isp, src->ct_flags, &dst->ct_flags);
+ ISP_IOXPUT_32(isp, src->ct_xfrlen, &dst->ct_xfrlen);
+ ISP_IOXPUT_32(isp, src->ct_resid, &dst->ct_resid);
+ ISP_IOXPUT_16(isp, src->ct_timeout, &dst->ct_timeout);
+ ISP_IOXPUT_16(isp, src->ct_seg_count, &dst->ct_seg_count);
for (i = 0; i < ISP_RQDSEG; i++) {
- ISP_IOXPUT_32(isp, ctsrc->ct_dataseg[i].ds_base,
- &ctdst->ct_dataseg[i].ds_base);
- ISP_IOXPUT_32(isp, ctsrc->ct_dataseg[i].ds_count,
- &ctdst->ct_dataseg[i].ds_count);
+ ISP_IOXPUT_32(isp, src->ct_dataseg[i].ds_base,
+ &dst->ct_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp, src->ct_dataseg[i].ds_count,
+ &dst->ct_dataseg[i].ds_count);
}
}
void
-isp_get_ctio(struct ispsoftc *isp, ct_entry_t *ctsrc, ct_entry_t *ctdst)
+isp_get_ctio(struct ispsoftc *isp, ct_entry_t *src, ct_entry_t *dst)
{
int i;
- isp_copy_in_hdr(isp, &ctsrc->ct_header, &ctdst->ct_header);
- ISP_IOXGET_16(isp, &ctsrc->ct_reserved, ctdst->ct_reserved);
- ISP_IOXGET_16(isp, &ctsrc->ct_fwhandle, ctdst->ct_fwhandle);
+ isp_get_hdr(isp, &src->ct_header, &dst->ct_header);
+ ISP_IOXGET_16(isp, &src->ct_syshandle, dst->ct_syshandle);
+ ISP_IOXGET_16(isp, &src->ct_fwhandle, dst->ct_fwhandle);
if (ISP_IS_SBUS(isp)) {
- ISP_IOXGET_8(isp, &ctsrc->ct_lun, ctdst->ct_iid);
- ISP_IOXGET_8(isp, &ctsrc->ct_iid, ctdst->ct_lun);
- ISP_IOXGET_8(isp, &ctsrc->ct_reserved2, ctdst->ct_tgt);
- ISP_IOXGET_8(isp, &ctsrc->ct_tgt, ctdst->ct_reserved2);
- ISP_IOXGET_8(isp, &ctsrc->ct_status, ctdst->ct_scsi_status);
- ISP_IOXGET_8(isp, &ctsrc->ct_scsi_status, ctdst->ct_status);
- ISP_IOXGET_8(isp, &ctsrc->ct_tag_val, ctdst->ct_tag_type);
- ISP_IOXGET_8(isp, &ctsrc->ct_tag_type, ctdst->ct_tag_val);
+ ISP_IOXGET_8(isp, &src->ct_lun, dst->ct_iid);
+ ISP_IOXGET_8(isp, &src->ct_iid, dst->ct_lun);
+ ISP_IOXGET_8(isp, &src->ct_reserved2, dst->ct_tgt);
+ ISP_IOXGET_8(isp, &src->ct_tgt, dst->ct_reserved2);
+ ISP_IOXGET_8(isp, &src->ct_status, dst->ct_scsi_status);
+ ISP_IOXGET_8(isp, &src->ct_scsi_status, dst->ct_status);
+ ISP_IOXGET_8(isp, &src->ct_tag_val, dst->ct_tag_type);
+ ISP_IOXGET_8(isp, &src->ct_tag_type, dst->ct_tag_val);
} else {
- ISP_IOXGET_8(isp, &ctsrc->ct_lun, ctdst->ct_lun);
- ISP_IOXGET_8(isp, &ctsrc->ct_iid, ctdst->ct_iid);
- ISP_IOXGET_8(isp, &ctsrc->ct_reserved2, ctdst->ct_reserved2);
- ISP_IOXGET_8(isp, &ctsrc->ct_tgt, ctdst->ct_tgt);
- ISP_IOXGET_8(isp, &ctsrc->ct_status, ctdst->ct_status);
- ISP_IOXGET_8(isp, &ctsrc->ct_scsi_status,
- ctdst->ct_scsi_status);
- ISP_IOXGET_8(isp, &ctsrc->ct_tag_val, ctdst->ct_tag_val);
- ISP_IOXGET_8(isp, &ctsrc->ct_tag_type, ctdst->ct_tag_type);
- }
- ISP_IOXGET_32(isp, &ctsrc->ct_flags, ctdst->ct_flags);
- ISP_IOXGET_32(isp, &ctsrc->ct_xfrlen, ctdst->ct_xfrlen);
- ISP_IOXGET_32(isp, &ctsrc->ct_resid, ctdst->ct_resid);
- ISP_IOXGET_16(isp, &ctsrc->ct_timeout, ctdst->ct_timeout);
- ISP_IOXGET_16(isp, &ctsrc->ct_seg_count, ctdst->ct_seg_count);
+ ISP_IOXGET_8(isp, &src->ct_lun, dst->ct_lun);
+ ISP_IOXGET_8(isp, &src->ct_iid, dst->ct_iid);
+ ISP_IOXGET_8(isp, &src->ct_reserved2, dst->ct_reserved2);
+ ISP_IOXGET_8(isp, &src->ct_tgt, dst->ct_tgt);
+ ISP_IOXGET_8(isp, &src->ct_status, dst->ct_status);
+ ISP_IOXGET_8(isp, &src->ct_scsi_status,
+ dst->ct_scsi_status);
+ ISP_IOXGET_8(isp, &src->ct_tag_val, dst->ct_tag_val);
+ ISP_IOXGET_8(isp, &src->ct_tag_type, dst->ct_tag_type);
+ }
+ ISP_IOXGET_32(isp, &src->ct_flags, dst->ct_flags);
+ ISP_IOXGET_32(isp, &src->ct_xfrlen, dst->ct_xfrlen);
+ ISP_IOXGET_32(isp, &src->ct_resid, dst->ct_resid);
+ ISP_IOXGET_16(isp, &src->ct_timeout, dst->ct_timeout);
+ ISP_IOXGET_16(isp, &src->ct_seg_count, dst->ct_seg_count);
for (i = 0; i < ISP_RQDSEG; i++) {
ISP_IOXGET_32(isp,
- &ctsrc->ct_dataseg[i].ds_base,
- ctdst->ct_dataseg[i].ds_base);
+ &src->ct_dataseg[i].ds_base,
+ dst->ct_dataseg[i].ds_base);
ISP_IOXGET_32(isp,
- &ctsrc->ct_dataseg[i].ds_count,
- ctdst->ct_dataseg[i].ds_count);
- }
-}
-
-void
-isp_put_ctio2(struct ispsoftc *isp, ct2_entry_t *ctsrc, ct2_entry_t *ctdst)
-{
- int i;
- isp_copy_out_hdr(isp, &ctsrc->ct_header, &ctdst->ct_header);
- ISP_IOXPUT_16(isp, ctsrc->ct_reserved, &ctdst->ct_reserved);
- ISP_IOXPUT_16(isp, ctsrc->ct_fwhandle, &ctdst->ct_fwhandle);
- ISP_IOXPUT_8(isp, ctsrc->ct_lun, &ctdst->ct_lun);
- ISP_IOXPUT_8(isp, ctsrc->ct_iid, &ctdst->ct_iid);
- ISP_IOXPUT_16(isp, ctsrc->ct_rxid, &ctdst->ct_rxid);
- ISP_IOXPUT_16(isp, ctsrc->ct_flags, &ctdst->ct_flags);
- ISP_IOXPUT_16(isp, ctsrc->ct_timeout, &ctdst->ct_timeout);
- ISP_IOXPUT_16(isp, ctsrc->ct_seg_count, &ctdst->ct_seg_count);
- ISP_IOXPUT_32(isp, ctsrc->ct_resid, &ctdst->ct_resid);
- ISP_IOXPUT_32(isp, ctsrc->ct_reloff, &ctdst->ct_reloff);
- if ((ctsrc->ct_flags & CT2_FLAG_MMASK) == CT2_FLAG_MODE0) {
- ISP_IOXPUT_32(isp, ctsrc->rsp.m0._reserved,
- &ctdst->rsp.m0._reserved);
- ISP_IOXPUT_16(isp, ctsrc->rsp.m0._reserved2,
- &ctdst->rsp.m0._reserved2);
- ISP_IOXPUT_16(isp, ctsrc->rsp.m0.ct_scsi_status,
- &ctdst->rsp.m0.ct_scsi_status);
- ISP_IOXPUT_32(isp, ctsrc->rsp.m0.ct_xfrlen,
- &ctdst->rsp.m0.ct_xfrlen);
- if (ctsrc->ct_header.rqs_entry_type == RQSTYPE_CTIO2) {
+ &src->ct_dataseg[i].ds_count,
+ dst->ct_dataseg[i].ds_count);
+ }
+}
+
+void
+isp_put_ctio2(struct ispsoftc *isp, ct2_entry_t *src, ct2_entry_t *dst)
+{
+ int i;
+ isp_put_hdr(isp, &src->ct_header, &dst->ct_header);
+ ISP_IOXPUT_32(isp, src->ct_syshandle, &dst->ct_syshandle);
+ ISP_IOXPUT_8(isp, src->ct_lun, &dst->ct_lun);
+ ISP_IOXPUT_8(isp, src->ct_iid, &dst->ct_iid);
+ ISP_IOXPUT_16(isp, src->ct_rxid, &dst->ct_rxid);
+ ISP_IOXPUT_16(isp, src->ct_flags, &dst->ct_flags);
+ ISP_IOXPUT_16(isp, src->ct_timeout, &dst->ct_timeout);
+ ISP_IOXPUT_16(isp, src->ct_seg_count, &dst->ct_seg_count);
+ ISP_IOXPUT_32(isp, src->ct_resid, &dst->ct_resid);
+ ISP_IOXPUT_32(isp, src->ct_reloff, &dst->ct_reloff);
+ if ((src->ct_flags & CT2_FLAG_MMASK) == CT2_FLAG_MODE0) {
+ ISP_IOXPUT_32(isp, src->rsp.m0._reserved,
+ &dst->rsp.m0._reserved);
+ ISP_IOXPUT_16(isp, src->rsp.m0._reserved2,
+ &dst->rsp.m0._reserved2);
+ ISP_IOXPUT_16(isp, src->rsp.m0.ct_scsi_status,
+ &dst->rsp.m0.ct_scsi_status);
+ ISP_IOXPUT_32(isp, src->rsp.m0.ct_xfrlen,
+ &dst->rsp.m0.ct_xfrlen);
+ if (src->ct_header.rqs_entry_type == RQSTYPE_CTIO2) {
for (i = 0; i < ISP_RQDSEG_T2; i++) {
ISP_IOXPUT_32(isp,
- ctsrc->rsp.m0.ct_dataseg[i].ds_base,
- &ctdst->rsp.m0.ct_dataseg[i].ds_base);
+ src->rsp.m0.u.ct_dataseg[i].ds_base,
+ &dst->rsp.m0.u.ct_dataseg[i].ds_base);
ISP_IOXPUT_32(isp,
- ctsrc->rsp.m0.ct_dataseg[i].ds_count,
- &ctdst->rsp.m0.ct_dataseg[i].ds_count);
+ src->rsp.m0.u.ct_dataseg[i].ds_count,
+ &dst->rsp.m0.u.ct_dataseg[i].ds_count);
}
- } else if (ctsrc->ct_header.rqs_entry_type == RQSTYPE_CTIO3) {
+ } else if (src->ct_header.rqs_entry_type == RQSTYPE_CTIO3) {
for (i = 0; i < ISP_RQDSEG_T3; i++) {
ISP_IOXPUT_32(isp,
- ctsrc->rsp.m0.ct_dataseg64[i].ds_base,
- &ctdst->rsp.m0.ct_dataseg64[i].ds_base);
+ src->rsp.m0.u.ct_dataseg64[i].ds_base,
+ &dst->rsp.m0.u.ct_dataseg64[i].ds_base);
ISP_IOXPUT_32(isp,
- ctsrc->rsp.m0.ct_dataseg64[i].ds_basehi,
- &ctdst->rsp.m0.ct_dataseg64[i].ds_basehi);
+ src->rsp.m0.u.ct_dataseg64[i].ds_basehi,
+ &dst->rsp.m0.u.ct_dataseg64[i].ds_basehi);
ISP_IOXPUT_32(isp,
- ctsrc->rsp.m0.ct_dataseg64[i].ds_count,
- &ctdst->rsp.m0.ct_dataseg64[i].ds_count);
+ src->rsp.m0.u.ct_dataseg64[i].ds_count,
+ &dst->rsp.m0.u.ct_dataseg64[i].ds_count);
}
- } else if (ctsrc->ct_header.rqs_entry_type == RQSTYPE_CTIO4) {
- ISP_IOXPUT_16(isp, ctsrc->rsp.m0.ct_dslist.ds_type,
- &ctdst->rsp.m0.ct_dslist.ds_type);
- ISP_IOXPUT_32(isp, ctsrc->rsp.m0.ct_dslist.ds_segment,
- &ctdst->rsp.m0.ct_dslist.ds_segment);
- ISP_IOXPUT_32(isp, ctsrc->rsp.m0.ct_dslist.ds_base,
- &ctdst->rsp.m0.ct_dslist.ds_base);
+ } else if (src->ct_header.rqs_entry_type == RQSTYPE_CTIO4) {
+ ISP_IOXPUT_16(isp, src->rsp.m0.u.ct_dslist.ds_type,
+ &dst->rsp.m0.u.ct_dslist.ds_type);
+ ISP_IOXPUT_32(isp, src->rsp.m0.u.ct_dslist.ds_segment,
+ &dst->rsp.m0.u.ct_dslist.ds_segment);
+ ISP_IOXPUT_32(isp, src->rsp.m0.u.ct_dslist.ds_base,
+ &dst->rsp.m0.u.ct_dslist.ds_base);
}
- } else if ((ctsrc->ct_flags & CT2_FLAG_MMASK) == CT2_FLAG_MODE1) {
- ISP_IOXPUT_16(isp, ctsrc->rsp.m1._reserved,
- &ctdst->rsp.m1._reserved);
- ISP_IOXPUT_16(isp, ctsrc->rsp.m1._reserved2,
- &ctdst->rsp.m1._reserved2);
- ISP_IOXPUT_16(isp, ctsrc->rsp.m1.ct_senselen,
- &ctdst->rsp.m1.ct_senselen);
- ISP_IOXPUT_16(isp, ctsrc->rsp.m1.ct_scsi_status,
- &ctdst->rsp.m1.ct_scsi_status);
- ISP_IOXPUT_16(isp, ctsrc->rsp.m1.ct_resplen,
- &ctdst->rsp.m1.ct_resplen);
+ } else if ((src->ct_flags & CT2_FLAG_MMASK) == CT2_FLAG_MODE1) {
+ ISP_IOXPUT_16(isp, src->rsp.m1._reserved,
+ &dst->rsp.m1._reserved);
+ ISP_IOXPUT_16(isp, src->rsp.m1._reserved2,
+ &dst->rsp.m1._reserved2);
+ ISP_IOXPUT_16(isp, src->rsp.m1.ct_senselen,
+ &dst->rsp.m1.ct_senselen);
+ ISP_IOXPUT_16(isp, src->rsp.m1.ct_scsi_status,
+ &dst->rsp.m1.ct_scsi_status);
+ ISP_IOXPUT_16(isp, src->rsp.m1.ct_resplen,
+ &dst->rsp.m1.ct_resplen);
for (i = 0; i < MAXRESPLEN; i++) {
- ISP_IOXPUT_8(isp, ctsrc->rsp.m1.ct_resp[i],
- &ctdst->rsp.m1.ct_resp[i]);
+ ISP_IOXPUT_8(isp, src->rsp.m1.ct_resp[i],
+ &dst->rsp.m1.ct_resp[i]);
}
} else {
- ISP_IOXPUT_32(isp, ctsrc->rsp.m2._reserved,
- &ctdst->rsp.m2._reserved);
- ISP_IOXPUT_16(isp, ctsrc->rsp.m2._reserved2,
- &ctdst->rsp.m2._reserved2);
- ISP_IOXPUT_16(isp, ctsrc->rsp.m2._reserved3,
- &ctdst->rsp.m2._reserved3);
- ISP_IOXPUT_32(isp, ctsrc->rsp.m2.ct_datalen,
- &ctdst->rsp.m2.ct_datalen);
- ISP_IOXPUT_32(isp, ctsrc->rsp.m2.ct_fcp_rsp_iudata.ds_base,
- &ctdst->rsp.m2.ct_fcp_rsp_iudata.ds_base);
- ISP_IOXPUT_32(isp, ctsrc->rsp.m2.ct_fcp_rsp_iudata.ds_count,
- &ctdst->rsp.m2.ct_fcp_rsp_iudata.ds_count);
- }
-}
-
-void
-isp_get_ctio2(struct ispsoftc *isp, ct2_entry_t *ctsrc, ct2_entry_t *ctdst)
-{
- int i;
- isp_copy_in_hdr(isp, &ctsrc->ct_header, &ctdst->ct_header);
- ISP_IOXGET_16(isp, &ctsrc->ct_reserved, ctdst->ct_reserved);
- ISP_IOXGET_16(isp, &ctsrc->ct_fwhandle, ctdst->ct_fwhandle);
- ISP_IOXGET_8(isp, &ctsrc->ct_lun, ctdst->ct_lun);
- ISP_IOXGET_8(isp, &ctsrc->ct_iid, ctdst->ct_iid);
- ISP_IOXGET_16(isp, &ctsrc->ct_rxid, ctdst->ct_rxid);
- ISP_IOXGET_16(isp, &ctsrc->ct_flags, ctdst->ct_flags);
- ISP_IOXGET_16(isp, &ctsrc->ct_status, ctdst->ct_status);
- ISP_IOXGET_16(isp, &ctsrc->ct_timeout, ctdst->ct_timeout);
- ISP_IOXGET_16(isp, &ctsrc->ct_seg_count, ctdst->ct_seg_count);
- ISP_IOXGET_32(isp, &ctsrc->ct_reloff, ctdst->ct_reloff);
- ISP_IOXGET_32(isp, &ctsrc->ct_resid, ctdst->ct_resid);
- for (i = 0; i < 4; i++) {
- ISP_IOXGET_32(isp, &ctsrc->rsp.fw._reserved[i],
- ctdst->rsp.fw._reserved[i]);
+ ISP_IOXPUT_32(isp, src->rsp.m2._reserved,
+ &dst->rsp.m2._reserved);
+ ISP_IOXPUT_16(isp, src->rsp.m2._reserved2,
+ &dst->rsp.m2._reserved2);
+ ISP_IOXPUT_16(isp, src->rsp.m2._reserved3,
+ &dst->rsp.m2._reserved3);
+ ISP_IOXPUT_32(isp, src->rsp.m2.ct_datalen,
+ &dst->rsp.m2.ct_datalen);
+ ISP_IOXPUT_32(isp, src->rsp.m2.ct_fcp_rsp_iudata.ds_base,
+ &dst->rsp.m2.ct_fcp_rsp_iudata.ds_base);
+ ISP_IOXPUT_32(isp, src->rsp.m2.ct_fcp_rsp_iudata.ds_count,
+ &dst->rsp.m2.ct_fcp_rsp_iudata.ds_count);
}
- ISP_IOXGET_16(isp, &ctsrc->rsp.fw.ct_scsi_status,
- ctdst->rsp.fw.ct_scsi_status);
- for (i = 0; i < QLTM_SENSELEN; i++) {
- ISP_IOXGET_8(isp, &ctsrc->rsp.fw.ct_sense[i],
- ctdst->rsp.fw.ct_sense[i]);
+}
+
+void
+isp_put_ctio2e(struct ispsoftc *isp, ct2e_entry_t *src, ct2e_entry_t *dst)
+{
+ int i;
+ isp_put_hdr(isp, &src->ct_header, &dst->ct_header);
+ ISP_IOXPUT_32(isp, src->ct_syshandle, &dst->ct_syshandle);
+ ISP_IOXPUT_16(isp, src->ct_iid, &dst->ct_iid);
+ ISP_IOXPUT_16(isp, src->ct_rxid, &dst->ct_rxid);
+ ISP_IOXPUT_16(isp, src->ct_flags, &dst->ct_flags);
+ ISP_IOXPUT_16(isp, src->ct_timeout, &dst->ct_timeout);
+ ISP_IOXPUT_16(isp, src->ct_seg_count, &dst->ct_seg_count);
+ ISP_IOXPUT_32(isp, src->ct_resid, &dst->ct_resid);
+ ISP_IOXPUT_32(isp, src->ct_reloff, &dst->ct_reloff);
+ if ((src->ct_flags & CT2_FLAG_MMASK) == CT2_FLAG_MODE0) {
+ ISP_IOXPUT_32(isp, src->rsp.m0._reserved,
+ &dst->rsp.m0._reserved);
+ ISP_IOXPUT_16(isp, src->rsp.m0._reserved2,
+ &dst->rsp.m0._reserved2);
+ ISP_IOXPUT_16(isp, src->rsp.m0.ct_scsi_status,
+ &dst->rsp.m0.ct_scsi_status);
+ ISP_IOXPUT_32(isp, src->rsp.m0.ct_xfrlen,
+ &dst->rsp.m0.ct_xfrlen);
+ if (src->ct_header.rqs_entry_type == RQSTYPE_CTIO2) {
+ for (i = 0; i < ISP_RQDSEG_T2; i++) {
+ ISP_IOXPUT_32(isp,
+ src->rsp.m0.u.ct_dataseg[i].ds_base,
+ &dst->rsp.m0.u.ct_dataseg[i].ds_base);
+ ISP_IOXPUT_32(isp,
+ src->rsp.m0.u.ct_dataseg[i].ds_count,
+ &dst->rsp.m0.u.ct_dataseg[i].ds_count);
+ }
+ } else if (src->ct_header.rqs_entry_type == RQSTYPE_CTIO3) {
+ for (i = 0; i < ISP_RQDSEG_T3; i++) {
+ ISP_IOXPUT_32(isp,
+ src->rsp.m0.u.ct_dataseg64[i].ds_base,
+ &dst->rsp.m0.u.ct_dataseg64[i].ds_base);
+ ISP_IOXPUT_32(isp,
+ src->rsp.m0.u.ct_dataseg64[i].ds_basehi,
+ &dst->rsp.m0.u.ct_dataseg64[i].ds_basehi);
+ ISP_IOXPUT_32(isp,
+ src->rsp.m0.u.ct_dataseg64[i].ds_count,
+ &dst->rsp.m0.u.ct_dataseg64[i].ds_count);
+ }
+ } else if (src->ct_header.rqs_entry_type == RQSTYPE_CTIO4) {
+ ISP_IOXPUT_16(isp, src->rsp.m0.u.ct_dslist.ds_type,
+ &dst->rsp.m0.u.ct_dslist.ds_type);
+ ISP_IOXPUT_32(isp, src->rsp.m0.u.ct_dslist.ds_segment,
+ &dst->rsp.m0.u.ct_dslist.ds_segment);
+ ISP_IOXPUT_32(isp, src->rsp.m0.u.ct_dslist.ds_base,
+ &dst->rsp.m0.u.ct_dslist.ds_base);
+ }
+ } else if ((src->ct_flags & CT2_FLAG_MMASK) == CT2_FLAG_MODE1) {
+ ISP_IOXPUT_16(isp, src->rsp.m1._reserved,
+ &dst->rsp.m1._reserved);
+ ISP_IOXPUT_16(isp, src->rsp.m1._reserved2,
+ &dst->rsp.m1._reserved2);
+ ISP_IOXPUT_16(isp, src->rsp.m1.ct_senselen,
+ &dst->rsp.m1.ct_senselen);
+ ISP_IOXPUT_16(isp, src->rsp.m1.ct_scsi_status,
+ &dst->rsp.m1.ct_scsi_status);
+ ISP_IOXPUT_16(isp, src->rsp.m1.ct_resplen,
+ &dst->rsp.m1.ct_resplen);
+ for (i = 0; i < MAXRESPLEN; i++) {
+ ISP_IOXPUT_8(isp, src->rsp.m1.ct_resp[i],
+ &dst->rsp.m1.ct_resp[i]);
+ }
+ } else {
+ ISP_IOXPUT_32(isp, src->rsp.m2._reserved,
+ &dst->rsp.m2._reserved);
+ ISP_IOXPUT_16(isp, src->rsp.m2._reserved2,
+ &dst->rsp.m2._reserved2);
+ ISP_IOXPUT_16(isp, src->rsp.m2._reserved3,
+ &dst->rsp.m2._reserved3);
+ ISP_IOXPUT_32(isp, src->rsp.m2.ct_datalen,
+ &dst->rsp.m2.ct_datalen);
+ ISP_IOXPUT_32(isp, src->rsp.m2.ct_fcp_rsp_iudata.ds_base,
+ &dst->rsp.m2.ct_fcp_rsp_iudata.ds_base);
+ ISP_IOXPUT_32(isp, src->rsp.m2.ct_fcp_rsp_iudata.ds_count,
+ &dst->rsp.m2.ct_fcp_rsp_iudata.ds_count);
+ }
+}
+
+void
+isp_put_ctio7(struct ispsoftc *isp, ct7_entry_t *src, ct7_entry_t *dst)
+{
+ int i;
+
+ isp_put_hdr(isp, &src->ct_header, &dst->ct_header);
+ ISP_IOXPUT_32(isp, src->ct_syshandle, &dst->ct_syshandle);
+ ISP_IOXPUT_16(isp, src->ct_nphdl, &dst->ct_nphdl);
+ ISP_IOXPUT_16(isp, src->ct_timeout, &dst->ct_timeout);
+ ISP_IOXPUT_16(isp, src->ct_seg_count, &dst->ct_seg_count);
+ ISP_IOXPUT_8(isp, src->ct_vpindex, &dst->ct_vpindex);
+ ISP_IOXPUT_8(isp, src->ct_xflags, &dst->ct_xflags);
+ ISP_IOXPUT_16(isp, src->ct_iid_lo, &dst->ct_iid_lo);
+ ISP_IOXPUT_8(isp, src->ct_iid_hi, &dst->ct_iid_hi);
+ ISP_IOXPUT_8(isp, src->ct_reserved, &dst->ct_reserved);
+ ISP_IOXPUT_32(isp, src->ct_rxid, &dst->ct_rxid);
+ ISP_IOXPUT_16(isp, src->ct_senselen, &dst->ct_senselen);
+ ISP_IOXPUT_16(isp, src->ct_flags, &dst->ct_flags);
+ ISP_IOXPUT_32(isp, src->ct_resid, &dst->ct_resid);
+ ISP_IOXPUT_16(isp, src->ct_oxid, &dst->ct_oxid);
+ ISP_IOXPUT_16(isp, src->ct_scsi_status, &dst->ct_scsi_status);
+ if ((dst->ct_flags & CT7_FLAG_MMASK) == CT7_FLAG_MODE0) {
+ ISP_IOXPUT_32(isp, src->rsp.m0.reloff, &dst->rsp.m0.reloff);
+ ISP_IOXPUT_32(isp, src->rsp.m0.reserved0,
+ &dst->rsp.m0.reserved0);
+ ISP_IOXPUT_32(isp, src->rsp.m0.ct_xfrlen,
+ &dst->rsp.m0.ct_xfrlen);
+ ISP_IOXPUT_32(isp, src->rsp.m0.reserved1,
+ &dst->rsp.m0.reserved1);
+ ISP_IOXPUT_32(isp, src->rsp.m0.ds.ds_base,
+ &dst->rsp.m0.ds.ds_base);
+ ISP_IOXPUT_32(isp, src->rsp.m0.ds.ds_basehi,
+ &dst->rsp.m0.ds.ds_basehi);
+ ISP_IOXPUT_32(isp, src->rsp.m0.ds.ds_count,
+ &dst->rsp.m0.ds.ds_count);
+ } else if ((dst->ct_flags & CT7_FLAG_MMASK) == CT7_FLAG_MODE1) {
+ ISP_IOXPUT_16(isp, src->rsp.m1.ct_resplen,
+ &dst->rsp.m1.ct_resplen);
+ ISP_IOXPUT_16(isp, src->rsp.m1.reserved, &dst->rsp.m1.reserved);
+ for (i = 0; i < MAXRESPLEN_24XX; i++) {
+ ISP_IOXPUT_8(isp, src->rsp.m1.ct_resp[i],
+ &dst->rsp.m1.ct_resp[i]);
+ }
+ } else {
+ ISP_IOXPUT_32(isp, src->rsp.m2.reserved0,
+ &dst->rsp.m2.reserved0);
+ ISP_IOXPUT_32(isp, src->rsp.m2.ct_datalen,
+ &dst->rsp.m2.ct_datalen);
+ ISP_IOXPUT_32(isp, src->rsp.m2.reserved1,
+ &dst->rsp.m2.reserved1);
+ ISP_IOXPUT_32(isp, src->rsp.m2.ct_fcp_rsp_iudata.ds_base,
+ &dst->rsp.m2.ct_fcp_rsp_iudata.ds_base);
+ ISP_IOXPUT_32(isp, src->rsp.m2.ct_fcp_rsp_iudata.ds_basehi,
+ &dst->rsp.m2.ct_fcp_rsp_iudata.ds_basehi);
+ ISP_IOXPUT_32(isp, src->rsp.m2.ct_fcp_rsp_iudata.ds_count,
+ &dst->rsp.m2.ct_fcp_rsp_iudata.ds_count);
+ }
+}
+
+
+void
+isp_get_ctio2(struct ispsoftc *isp, ct2_entry_t *src, ct2_entry_t *dst)
+{
+ int i;
+
+ isp_get_hdr(isp, &src->ct_header, &dst->ct_header);
+ ISP_IOXGET_32(isp, &src->ct_syshandle, dst->ct_syshandle);
+ ISP_IOXGET_8(isp, &src->ct_lun, dst->ct_lun);
+ ISP_IOXGET_8(isp, &src->ct_iid, dst->ct_iid);
+ ISP_IOXGET_16(isp, &src->ct_rxid, dst->ct_rxid);
+ ISP_IOXGET_16(isp, &src->ct_flags, dst->ct_flags);
+ ISP_IOXGET_16(isp, &src->ct_status, dst->ct_status);
+ ISP_IOXGET_16(isp, &src->ct_timeout, dst->ct_timeout);
+ ISP_IOXGET_16(isp, &src->ct_seg_count, dst->ct_seg_count);
+ ISP_IOXGET_32(isp, &src->ct_reloff, dst->ct_reloff);
+ ISP_IOXGET_32(isp, &src->ct_resid, dst->ct_resid);
+ if ((dst->ct_flags & CT2_FLAG_MMASK) == CT2_FLAG_MODE0) {
+ ISP_IOXGET_32(isp, &src->rsp.m0._reserved,
+ dst->rsp.m0._reserved);
+ ISP_IOXGET_16(isp, &src->rsp.m0._reserved2,
+ dst->rsp.m0._reserved2);
+ ISP_IOXGET_16(isp, &src->rsp.m0.ct_scsi_status,
+ dst->rsp.m0.ct_scsi_status);
+ ISP_IOXGET_32(isp, &src->rsp.m0.ct_xfrlen,
+ dst->rsp.m0.ct_xfrlen);
+ if (dst->ct_header.rqs_entry_type == RQSTYPE_CTIO2) {
+ for (i = 0; i < ISP_RQDSEG_T2; i++) {
+ ISP_IOXGET_32(isp,
+ &src->rsp.m0.u.ct_dataseg[i].ds_base,
+ dst->rsp.m0.u.ct_dataseg[i].ds_base);
+ ISP_IOXGET_32(isp,
+ &src->rsp.m0.u.ct_dataseg[i].ds_count,
+ dst->rsp.m0.u.ct_dataseg[i].ds_count);
+ }
+ } else if (dst->ct_header.rqs_entry_type == RQSTYPE_CTIO3) {
+ for (i = 0; i < ISP_RQDSEG_T3; i++) {
+ ISP_IOXGET_32(isp,
+ &src->rsp.m0.u.ct_dataseg64[i].ds_base,
+ dst->rsp.m0.u.ct_dataseg64[i].ds_base);
+ ISP_IOXGET_32(isp,
+ &src->rsp.m0.u.ct_dataseg64[i].ds_basehi,
+ dst->rsp.m0.u.ct_dataseg64[i].ds_basehi);
+ ISP_IOXGET_32(isp,
+ &src->rsp.m0.u.ct_dataseg64[i].ds_count,
+ dst->rsp.m0.u.ct_dataseg64[i].ds_count);
+ }
+ } else if (dst->ct_header.rqs_entry_type == RQSTYPE_CTIO4) {
+ ISP_IOXGET_16(isp, &src->rsp.m0.u.ct_dslist.ds_type,
+ dst->rsp.m0.u.ct_dslist.ds_type);
+ ISP_IOXGET_32(isp, &src->rsp.m0.u.ct_dslist.ds_segment,
+ dst->rsp.m0.u.ct_dslist.ds_segment);
+ ISP_IOXGET_32(isp, &src->rsp.m0.u.ct_dslist.ds_base,
+ dst->rsp.m0.u.ct_dslist.ds_base);
+ }
+ } else if ((dst->ct_flags & CT2_FLAG_MMASK) == CT2_FLAG_MODE1) {
+ ISP_IOXGET_16(isp, &src->rsp.m1._reserved,
+ dst->rsp.m1._reserved);
+ ISP_IOXGET_16(isp, &src->rsp.m1._reserved2,
+ dst->rsp.m1._reserved2);
+ ISP_IOXGET_16(isp, &src->rsp.m1.ct_senselen,
+ dst->rsp.m1.ct_senselen);
+ ISP_IOXGET_16(isp, &src->rsp.m1.ct_scsi_status,
+ dst->rsp.m1.ct_scsi_status);
+ ISP_IOXGET_16(isp, &src->rsp.m1.ct_resplen,
+ dst->rsp.m1.ct_resplen);
+ for (i = 0; i < MAXRESPLEN; i++) {
+ ISP_IOXGET_8(isp, &src->rsp.m1.ct_resp[i],
+ dst->rsp.m1.ct_resp[i]);
+ }
+ } else {
+ ISP_IOXGET_32(isp, &src->rsp.m2._reserved,
+ dst->rsp.m2._reserved);
+ ISP_IOXGET_16(isp, &src->rsp.m2._reserved2,
+ dst->rsp.m2._reserved2);
+ ISP_IOXGET_16(isp, &src->rsp.m2._reserved3,
+ dst->rsp.m2._reserved3);
+ ISP_IOXGET_32(isp, &src->rsp.m2.ct_datalen,
+ dst->rsp.m2.ct_datalen);
+ ISP_IOXGET_32(isp, &src->rsp.m2.ct_fcp_rsp_iudata.ds_base,
+ dst->rsp.m2.ct_fcp_rsp_iudata.ds_base);
+ ISP_IOXGET_32(isp, &src->rsp.m2.ct_fcp_rsp_iudata.ds_count,
+ dst->rsp.m2.ct_fcp_rsp_iudata.ds_count);
+ }
+}
+
+void
+isp_get_ctio2e(struct ispsoftc *isp, ct2e_entry_t *src, ct2e_entry_t *dst)
+{
+ int i;
+
+ isp_get_hdr(isp, &src->ct_header, &dst->ct_header);
+ ISP_IOXGET_32(isp, &src->ct_syshandle, dst->ct_syshandle);
+ ISP_IOXGET_16(isp, &src->ct_iid, dst->ct_iid);
+ ISP_IOXGET_16(isp, &src->ct_rxid, dst->ct_rxid);
+ ISP_IOXGET_16(isp, &src->ct_flags, dst->ct_flags);
+ ISP_IOXGET_16(isp, &src->ct_status, dst->ct_status);
+ ISP_IOXGET_16(isp, &src->ct_timeout, dst->ct_timeout);
+ ISP_IOXGET_16(isp, &src->ct_seg_count, dst->ct_seg_count);
+ ISP_IOXGET_32(isp, &src->ct_reloff, dst->ct_reloff);
+ ISP_IOXGET_32(isp, &src->ct_resid, dst->ct_resid);
+ if ((dst->ct_flags & CT2_FLAG_MMASK) == CT2_FLAG_MODE0) {
+ ISP_IOXGET_32(isp, &src->rsp.m0._reserved,
+ dst->rsp.m0._reserved);
+ ISP_IOXGET_16(isp, &src->rsp.m0._reserved2,
+ dst->rsp.m0._reserved2);
+ ISP_IOXGET_16(isp, &src->rsp.m0.ct_scsi_status,
+ dst->rsp.m0.ct_scsi_status);
+ ISP_IOXGET_32(isp, &src->rsp.m0.ct_xfrlen,
+ dst->rsp.m0.ct_xfrlen);
+ if (src->ct_header.rqs_entry_type == RQSTYPE_CTIO2) {
+ for (i = 0; i < ISP_RQDSEG_T2; i++) {
+ ISP_IOXGET_32(isp,
+ &src->rsp.m0.u.ct_dataseg[i].ds_base,
+ dst->rsp.m0.u.ct_dataseg[i].ds_base);
+ ISP_IOXGET_32(isp,
+ &src->rsp.m0.u.ct_dataseg[i].ds_count,
+ dst->rsp.m0.u.ct_dataseg[i].ds_count);
+ }
+ } else if (dst->ct_header.rqs_entry_type == RQSTYPE_CTIO3) {
+ for (i = 0; i < ISP_RQDSEG_T3; i++) {
+ ISP_IOXGET_32(isp,
+ &src->rsp.m0.u.ct_dataseg64[i].ds_base,
+ dst->rsp.m0.u.ct_dataseg64[i].ds_base);
+ ISP_IOXGET_32(isp,
+ &src->rsp.m0.u.ct_dataseg64[i].ds_basehi,
+ dst->rsp.m0.u.ct_dataseg64[i].ds_basehi);
+ ISP_IOXGET_32(isp,
+ &src->rsp.m0.u.ct_dataseg64[i].ds_count,
+ dst->rsp.m0.u.ct_dataseg64[i].ds_count);
+ }
+ } else if (dst->ct_header.rqs_entry_type == RQSTYPE_CTIO4) {
+ ISP_IOXGET_16(isp, &src->rsp.m0.u.ct_dslist.ds_type,
+ dst->rsp.m0.u.ct_dslist.ds_type);
+ ISP_IOXGET_32(isp, &src->rsp.m0.u.ct_dslist.ds_segment,
+ dst->rsp.m0.u.ct_dslist.ds_segment);
+ ISP_IOXGET_32(isp, &src->rsp.m0.u.ct_dslist.ds_base,
+ dst->rsp.m0.u.ct_dslist.ds_base);
+ }
+ } else if ((dst->ct_flags & CT2_FLAG_MMASK) == CT2_FLAG_MODE1) {
+ ISP_IOXGET_16(isp, &src->rsp.m1._reserved,
+ dst->rsp.m1._reserved);
+ ISP_IOXGET_16(isp, &src->rsp.m1._reserved2,
+ dst->rsp.m1._reserved2);
+ ISP_IOXGET_16(isp, &src->rsp.m1.ct_senselen,
+ dst->rsp.m1.ct_senselen);
+ ISP_IOXGET_16(isp, &src->rsp.m1.ct_scsi_status,
+ dst->rsp.m1.ct_scsi_status);
+ ISP_IOXGET_16(isp, &src->rsp.m1.ct_resplen,
+ dst->rsp.m1.ct_resplen);
+ for (i = 0; i < MAXRESPLEN; i++) {
+ ISP_IOXGET_8(isp, &src->rsp.m1.ct_resp[i],
+ dst->rsp.m1.ct_resp[i]);
+ }
+ } else {
+ ISP_IOXGET_32(isp, &src->rsp.m2._reserved,
+ dst->rsp.m2._reserved);
+ ISP_IOXGET_16(isp, &src->rsp.m2._reserved2,
+ dst->rsp.m2._reserved2);
+ ISP_IOXGET_16(isp, &src->rsp.m2._reserved3,
+ dst->rsp.m2._reserved3);
+ ISP_IOXGET_32(isp, &src->rsp.m2.ct_datalen,
+ dst->rsp.m2.ct_datalen);
+ ISP_IOXGET_32(isp, &src->rsp.m2.ct_fcp_rsp_iudata.ds_base,
+ dst->rsp.m2.ct_fcp_rsp_iudata.ds_base);
+ ISP_IOXGET_32(isp, &src->rsp.m2.ct_fcp_rsp_iudata.ds_count,
+ dst->rsp.m2.ct_fcp_rsp_iudata.ds_count);
+ }
+}
+
+void
+isp_get_ctio7(struct ispsoftc *isp, ct7_entry_t *src, ct7_entry_t *dst)
+{
+ int i;
+
+ isp_get_hdr(isp, &src->ct_header, &dst->ct_header);
+ ISP_IOXGET_32(isp, &src->ct_syshandle, dst->ct_syshandle);
+ ISP_IOXGET_16(isp, &src->ct_nphdl, dst->ct_nphdl);
+ ISP_IOXGET_16(isp, &src->ct_timeout, dst->ct_timeout);
+ ISP_IOXGET_16(isp, &src->ct_seg_count, dst->ct_seg_count);
+ ISP_IOXGET_8(isp, &src->ct_vpindex, dst->ct_vpindex);
+ ISP_IOXGET_8(isp, &src->ct_xflags, dst->ct_xflags);
+ ISP_IOXGET_16(isp, &src->ct_iid_lo, dst->ct_iid_lo);
+ ISP_IOXGET_8(isp, &src->ct_iid_hi, dst->ct_iid_hi);
+ ISP_IOXGET_8(isp, &src->ct_reserved, dst->ct_reserved);
+ ISP_IOXGET_32(isp, &src->ct_rxid, dst->ct_rxid);
+ ISP_IOXGET_16(isp, &src->ct_senselen, dst->ct_senselen);
+ ISP_IOXGET_16(isp, &src->ct_flags, dst->ct_flags);
+ ISP_IOXGET_32(isp, &src->ct_resid, dst->ct_resid);
+ ISP_IOXGET_16(isp, &src->ct_oxid, dst->ct_oxid);
+ ISP_IOXGET_16(isp, &src->ct_scsi_status, dst->ct_scsi_status);
+ if ((dst->ct_flags & CT7_FLAG_MMASK) == CT7_FLAG_MODE0) {
+ ISP_IOXGET_32(isp, &src->rsp.m0.reloff, dst->rsp.m0.reloff);
+ ISP_IOXGET_32(isp, &src->rsp.m0.reserved0,
+ dst->rsp.m0.reserved0);
+ ISP_IOXGET_32(isp, &src->rsp.m0.ct_xfrlen,
+ dst->rsp.m0.ct_xfrlen);
+ ISP_IOXGET_32(isp, &src->rsp.m0.reserved1,
+ dst->rsp.m0.reserved1);
+ ISP_IOXGET_32(isp, &src->rsp.m0.ds.ds_base,
+ dst->rsp.m0.ds.ds_base);
+ ISP_IOXGET_32(isp, &src->rsp.m0.ds.ds_basehi,
+ dst->rsp.m0.ds.ds_basehi);
+ ISP_IOXGET_32(isp, &src->rsp.m0.ds.ds_count,
+ dst->rsp.m0.ds.ds_count);
+ } else if ((dst->ct_flags & CT7_FLAG_MMASK) == CT7_FLAG_MODE1) {
+ ISP_IOXGET_16(isp, &src->rsp.m1.ct_resplen,
+ dst->rsp.m1.ct_resplen);
+ ISP_IOXGET_16(isp, &src->rsp.m1.reserved, dst->rsp.m1.reserved);
+ for (i = 0; i < MAXRESPLEN_24XX; i++) {
+ ISP_IOXGET_8(isp, &src->rsp.m1.ct_resp[i],
+ dst->rsp.m1.ct_resp[i]);
+ }
+ } else {
+ ISP_IOXGET_32(isp, &src->rsp.m2.reserved0,
+ dst->rsp.m2.reserved0);
+ ISP_IOXGET_32(isp, &src->rsp.m2.ct_datalen,
+ dst->rsp.m2.ct_datalen);
+ ISP_IOXGET_32(isp, &src->rsp.m2.reserved1,
+ dst->rsp.m2.reserved1);
+ ISP_IOXGET_32(isp, &src->rsp.m2.ct_fcp_rsp_iudata.ds_base,
+ dst->rsp.m2.ct_fcp_rsp_iudata.ds_base);
+ ISP_IOXGET_32(isp, &src->rsp.m2.ct_fcp_rsp_iudata.ds_basehi,
+ dst->rsp.m2.ct_fcp_rsp_iudata.ds_basehi);
+ ISP_IOXGET_32(isp, &src->rsp.m2.ct_fcp_rsp_iudata.ds_count,
+ dst->rsp.m2.ct_fcp_rsp_iudata.ds_count);
}
}
@@ -1105,7 +2278,7 @@ void
isp_put_enable_lun(struct ispsoftc *isp, lun_entry_t *lesrc, lun_entry_t *ledst)
{
int i;
- isp_copy_out_hdr(isp, &lesrc->le_header, &ledst->le_header);
+ isp_put_hdr(isp, &lesrc->le_header, &ledst->le_header);
ISP_IOXPUT_32(isp, lesrc->le_reserved, &ledst->le_reserved);
if (ISP_IS_SBUS(isp)) {
ISP_IOXPUT_8(isp, lesrc->le_lun, &ledst->le_rsvd);
@@ -1142,7 +2315,7 @@ void
isp_get_enable_lun(struct ispsoftc *isp, lun_entry_t *lesrc, lun_entry_t *ledst)
{
int i;
- isp_copy_in_hdr(isp, &lesrc->le_header, &ledst->le_header);
+ isp_get_hdr(isp, &lesrc->le_header, &ledst->le_header);
ISP_IOXGET_32(isp, &lesrc->le_reserved, ledst->le_reserved);
if (ISP_IS_SBUS(isp)) {
ISP_IOXGET_8(isp, &lesrc->le_lun, ledst->le_rsvd);
@@ -1176,202 +2349,554 @@ isp_get_enable_lun(struct ispsoftc *isp, lun_entry_t *lesrc, lun_entry_t *ledst)
}
void
-isp_put_notify(struct ispsoftc *isp, in_entry_t *insrc, in_entry_t *indst)
+isp_put_notify(struct ispsoftc *isp, in_entry_t *src, in_entry_t *dst)
{
int i;
- isp_copy_out_hdr(isp, &insrc->in_header, &indst->in_header);
- ISP_IOXPUT_32(isp, insrc->in_reserved, &indst->in_reserved);
+ isp_put_hdr(isp, &src->in_header, &dst->in_header);
+ ISP_IOXPUT_32(isp, src->in_reserved, &dst->in_reserved);
if (ISP_IS_SBUS(isp)) {
- ISP_IOXPUT_8(isp, insrc->in_lun, &indst->in_iid);
- ISP_IOXPUT_8(isp, insrc->in_iid, &indst->in_lun);
- ISP_IOXPUT_8(isp, insrc->in_reserved2, &indst->in_tgt);
- ISP_IOXPUT_8(isp, insrc->in_tgt, &indst->in_reserved2);
- ISP_IOXPUT_8(isp, insrc->in_status, &indst->in_rsvd2);
- ISP_IOXPUT_8(isp, insrc->in_rsvd2, &indst->in_status);
- ISP_IOXPUT_8(isp, insrc->in_tag_val, &indst->in_tag_type);
- ISP_IOXPUT_8(isp, insrc->in_tag_type, &indst->in_tag_val);
+ ISP_IOXPUT_8(isp, src->in_lun, &dst->in_iid);
+ ISP_IOXPUT_8(isp, src->in_iid, &dst->in_lun);
+ ISP_IOXPUT_8(isp, src->in_reserved2, &dst->in_tgt);
+ ISP_IOXPUT_8(isp, src->in_tgt, &dst->in_reserved2);
+ ISP_IOXPUT_8(isp, src->in_status, &dst->in_rsvd2);
+ ISP_IOXPUT_8(isp, src->in_rsvd2, &dst->in_status);
+ ISP_IOXPUT_8(isp, src->in_tag_val, &dst->in_tag_type);
+ ISP_IOXPUT_8(isp, src->in_tag_type, &dst->in_tag_val);
} else {
- ISP_IOXPUT_8(isp, insrc->in_lun, &indst->in_lun);
- ISP_IOXPUT_8(isp, insrc->in_iid, &indst->in_iid);
- ISP_IOXPUT_8(isp, insrc->in_reserved2, &indst->in_reserved2);
- ISP_IOXPUT_8(isp, insrc->in_tgt, &indst->in_tgt);
- ISP_IOXPUT_8(isp, insrc->in_status, &indst->in_status);
- ISP_IOXPUT_8(isp, insrc->in_rsvd2, &indst->in_rsvd2);
- ISP_IOXPUT_8(isp, insrc->in_tag_val, &indst->in_tag_val);
- ISP_IOXPUT_8(isp, insrc->in_tag_type, &indst->in_tag_type);
- }
- ISP_IOXPUT_32(isp, insrc->in_flags, &indst->in_flags);
- ISP_IOXPUT_16(isp, insrc->in_seqid, &indst->in_seqid);
+ ISP_IOXPUT_8(isp, src->in_lun, &dst->in_lun);
+ ISP_IOXPUT_8(isp, src->in_iid, &dst->in_iid);
+ ISP_IOXPUT_8(isp, src->in_reserved2, &dst->in_reserved2);
+ ISP_IOXPUT_8(isp, src->in_tgt, &dst->in_tgt);
+ ISP_IOXPUT_8(isp, src->in_status, &dst->in_status);
+ ISP_IOXPUT_8(isp, src->in_rsvd2, &dst->in_rsvd2);
+ ISP_IOXPUT_8(isp, src->in_tag_val, &dst->in_tag_val);
+ ISP_IOXPUT_8(isp, src->in_tag_type, &dst->in_tag_type);
+ }
+ ISP_IOXPUT_32(isp, src->in_flags, &dst->in_flags);
+ ISP_IOXPUT_16(isp, src->in_seqid, &dst->in_seqid);
for (i = 0; i < IN_MSGLEN; i++) {
- ISP_IOXPUT_8(isp, insrc->in_msg[i], &indst->in_msg[i]);
+ ISP_IOXPUT_8(isp, src->in_msg[i], &dst->in_msg[i]);
}
for (i = 0; i < IN_RSVDLEN; i++) {
- ISP_IOXPUT_8(isp, insrc->in_reserved3[i],
- &indst->in_reserved3[i]);
+ ISP_IOXPUT_8(isp, src->in_reserved3[i],
+ &dst->in_reserved3[i]);
}
for (i = 0; i < QLTM_SENSELEN; i++) {
- ISP_IOXPUT_8(isp, insrc->in_sense[i],
- &indst->in_sense[i]);
+ ISP_IOXPUT_8(isp, src->in_sense[i],
+ &dst->in_sense[i]);
}
}
void
-isp_get_notify(struct ispsoftc *isp, in_entry_t *insrc, in_entry_t *indst)
+isp_get_notify(struct ispsoftc *isp, in_entry_t *src, in_entry_t *dst)
{
int i;
- isp_copy_in_hdr(isp, &insrc->in_header, &indst->in_header);
- ISP_IOXGET_32(isp, &insrc->in_reserved, indst->in_reserved);
+ isp_get_hdr(isp, &src->in_header, &dst->in_header);
+ ISP_IOXGET_32(isp, &src->in_reserved, dst->in_reserved);
if (ISP_IS_SBUS(isp)) {
- ISP_IOXGET_8(isp, &insrc->in_lun, indst->in_iid);
- ISP_IOXGET_8(isp, &insrc->in_iid, indst->in_lun);
- ISP_IOXGET_8(isp, &insrc->in_reserved2, indst->in_tgt);
- ISP_IOXGET_8(isp, &insrc->in_tgt, indst->in_reserved2);
- ISP_IOXGET_8(isp, &insrc->in_status, indst->in_rsvd2);
- ISP_IOXGET_8(isp, &insrc->in_rsvd2, indst->in_status);
- ISP_IOXGET_8(isp, &insrc->in_tag_val, indst->in_tag_type);
- ISP_IOXGET_8(isp, &insrc->in_tag_type, indst->in_tag_val);
+ ISP_IOXGET_8(isp, &src->in_lun, dst->in_iid);
+ ISP_IOXGET_8(isp, &src->in_iid, dst->in_lun);
+ ISP_IOXGET_8(isp, &src->in_reserved2, dst->in_tgt);
+ ISP_IOXGET_8(isp, &src->in_tgt, dst->in_reserved2);
+ ISP_IOXGET_8(isp, &src->in_status, dst->in_rsvd2);
+ ISP_IOXGET_8(isp, &src->in_rsvd2, dst->in_status);
+ ISP_IOXGET_8(isp, &src->in_tag_val, dst->in_tag_type);
+ ISP_IOXGET_8(isp, &src->in_tag_type, dst->in_tag_val);
} else {
- ISP_IOXGET_8(isp, &insrc->in_lun, indst->in_lun);
- ISP_IOXGET_8(isp, &insrc->in_iid, indst->in_iid);
- ISP_IOXGET_8(isp, &insrc->in_reserved2, indst->in_reserved2);
- ISP_IOXGET_8(isp, &insrc->in_tgt, indst->in_tgt);
- ISP_IOXGET_8(isp, &insrc->in_status, indst->in_status);
- ISP_IOXGET_8(isp, &insrc->in_rsvd2, indst->in_rsvd2);
- ISP_IOXGET_8(isp, &insrc->in_tag_val, indst->in_tag_val);
- ISP_IOXGET_8(isp, &insrc->in_tag_type, indst->in_tag_type);
- }
- ISP_IOXGET_32(isp, &insrc->in_flags, indst->in_flags);
- ISP_IOXGET_16(isp, &insrc->in_seqid, indst->in_seqid);
+ ISP_IOXGET_8(isp, &src->in_lun, dst->in_lun);
+ ISP_IOXGET_8(isp, &src->in_iid, dst->in_iid);
+ ISP_IOXGET_8(isp, &src->in_reserved2, dst->in_reserved2);
+ ISP_IOXGET_8(isp, &src->in_tgt, dst->in_tgt);
+ ISP_IOXGET_8(isp, &src->in_status, dst->in_status);
+ ISP_IOXGET_8(isp, &src->in_rsvd2, dst->in_rsvd2);
+ ISP_IOXGET_8(isp, &src->in_tag_val, dst->in_tag_val);
+ ISP_IOXGET_8(isp, &src->in_tag_type, dst->in_tag_type);
+ }
+ ISP_IOXGET_32(isp, &src->in_flags, dst->in_flags);
+ ISP_IOXGET_16(isp, &src->in_seqid, dst->in_seqid);
for (i = 0; i < IN_MSGLEN; i++) {
- ISP_IOXGET_8(isp, &insrc->in_msg[i], indst->in_msg[i]);
+ ISP_IOXGET_8(isp, &src->in_msg[i], dst->in_msg[i]);
}
for (i = 0; i < IN_RSVDLEN; i++) {
- ISP_IOXGET_8(isp, &insrc->in_reserved3[i],
- indst->in_reserved3[i]);
+ ISP_IOXGET_8(isp, &src->in_reserved3[i],
+ dst->in_reserved3[i]);
}
for (i = 0; i < QLTM_SENSELEN; i++) {
- ISP_IOXGET_8(isp, &insrc->in_sense[i],
- indst->in_sense[i]);
+ ISP_IOXGET_8(isp, &src->in_sense[i],
+ dst->in_sense[i]);
}
}
void
-isp_put_notify_fc(struct ispsoftc *isp, in_fcentry_t *insrc,
- in_fcentry_t *indst)
+isp_put_notify_fc(struct ispsoftc *isp, in_fcentry_t *src,
+ in_fcentry_t *dst)
+{
+ isp_put_hdr(isp, &src->in_header, &dst->in_header);
+ ISP_IOXPUT_32(isp, src->in_reserved, &dst->in_reserved);
+ ISP_IOXPUT_8(isp, src->in_lun, &dst->in_lun);
+ ISP_IOXPUT_8(isp, src->in_iid, &dst->in_iid);
+ ISP_IOXPUT_16(isp, src->in_scclun, &dst->in_scclun);
+ ISP_IOXPUT_32(isp, src->in_reserved2, &dst->in_reserved2);
+ ISP_IOXPUT_16(isp, src->in_status, &dst->in_status);
+ ISP_IOXPUT_16(isp, src->in_task_flags, &dst->in_task_flags);
+ ISP_IOXPUT_16(isp, src->in_seqid, &dst->in_seqid);
+}
+
+void
+isp_put_notify_fc_e(struct ispsoftc *isp, in_fcentry_e_t *src,
+ in_fcentry_e_t *dst)
+{
+ isp_put_hdr(isp, &src->in_header, &dst->in_header);
+ ISP_IOXPUT_32(isp, src->in_reserved, &dst->in_reserved);
+ ISP_IOXPUT_16(isp, src->in_iid, &dst->in_iid);
+ ISP_IOXPUT_16(isp, src->in_scclun, &dst->in_scclun);
+ ISP_IOXPUT_32(isp, src->in_reserved2, &dst->in_reserved2);
+ ISP_IOXPUT_16(isp, src->in_status, &dst->in_status);
+ ISP_IOXPUT_16(isp, src->in_task_flags, &dst->in_task_flags);
+ ISP_IOXPUT_16(isp, src->in_seqid, &dst->in_seqid);
+}
+
+void
+isp_put_notify_24xx(struct ispsoftc *isp, in_fcentry_24xx_t *src,
+ in_fcentry_24xx_t *dst)
+{
+ int i;
+
+ isp_put_hdr(isp, &src->in_header, &dst->in_header);
+ ISP_IOXPUT_32(isp, src->in_reserved, &dst->in_reserved);
+ ISP_IOXPUT_16(isp, src->in_nphdl, &dst->in_nphdl);
+ ISP_IOXPUT_16(isp, src->in_reserved1, &dst->in_reserved1);
+ ISP_IOXPUT_16(isp, src->in_flags, &dst->in_flags);
+ ISP_IOXPUT_16(isp, src->in_srr_rxid, &dst->in_srr_rxid);
+ ISP_IOXPUT_16(isp, src->in_status, &dst->in_status);
+ ISP_IOXPUT_8(isp, src->in_status_subcode, &dst->in_status_subcode);
+ ISP_IOXPUT_16(isp, src->in_reserved2, &dst->in_reserved2);
+ ISP_IOXPUT_32(isp, src->in_rxid, &dst->in_rxid);
+ ISP_IOXPUT_16(isp, src->in_srr_reloff_hi, &dst->in_srr_reloff_hi);
+ ISP_IOXPUT_16(isp, src->in_srr_reloff_lo, &dst->in_srr_reloff_lo);
+ ISP_IOXPUT_16(isp, src->in_srr_iu, &dst->in_srr_iu);
+ ISP_IOXPUT_16(isp, src->in_srr_oxid, &dst->in_srr_oxid);
+ for (i = 0; i < 18; i++) {
+ ISP_IOXPUT_8(isp, src->in_reserved3[i], &dst->in_reserved3[i]);
+ }
+ ISP_IOXPUT_8(isp, src->in_reserved4, &dst->in_reserved4);
+ ISP_IOXPUT_8(isp, src->in_vpindex, &dst->in_vpindex);
+ ISP_IOXPUT_32(isp, src->in_reserved5, &dst->in_reserved5);
+ ISP_IOXPUT_16(isp, src->in_portid_lo, &dst->in_portid_lo);
+ ISP_IOXPUT_8(isp, src->in_portid_hi, &dst->in_portid_hi);
+ ISP_IOXPUT_8(isp, src->in_reserved6, &dst->in_reserved6);
+ ISP_IOXPUT_16(isp, src->in_reserved7, &dst->in_reserved7);
+ ISP_IOXPUT_16(isp, src->in_oxid, &dst->in_oxid);
+}
+
+void
+isp_get_notify_fc(struct ispsoftc *isp, in_fcentry_t *src,
+ in_fcentry_t *dst)
{
- isp_copy_out_hdr(isp, &insrc->in_header, &indst->in_header);
- ISP_IOXPUT_32(isp, insrc->in_reserved, &indst->in_reserved);
- ISP_IOXPUT_8(isp, insrc->in_lun, &indst->in_lun);
- ISP_IOXPUT_8(isp, insrc->in_iid, &indst->in_iid);
- ISP_IOXPUT_16(isp, insrc->in_scclun, &indst->in_scclun);
- ISP_IOXPUT_32(isp, insrc->in_reserved2, &indst->in_reserved2);
- ISP_IOXPUT_16(isp, insrc->in_status, &indst->in_status);
- ISP_IOXPUT_16(isp, insrc->in_task_flags, &indst->in_task_flags);
- ISP_IOXPUT_16(isp, insrc->in_seqid, &indst->in_seqid);
+ isp_get_hdr(isp, &src->in_header, &dst->in_header);
+ ISP_IOXGET_32(isp, &src->in_reserved, dst->in_reserved);
+ ISP_IOXGET_8(isp, &src->in_lun, dst->in_lun);
+ ISP_IOXGET_8(isp, &src->in_iid, dst->in_iid);
+ ISP_IOXGET_16(isp, &src->in_scclun, dst->in_scclun);
+ ISP_IOXGET_32(isp, &src->in_reserved2, dst->in_reserved2);
+ ISP_IOXGET_16(isp, &src->in_status, dst->in_status);
+ ISP_IOXGET_16(isp, &src->in_task_flags, dst->in_task_flags);
+ ISP_IOXGET_16(isp, &src->in_seqid, dst->in_seqid);
}
void
-isp_get_notify_fc(struct ispsoftc *isp, in_fcentry_t *insrc,
- in_fcentry_t *indst)
+isp_get_notify_fc_e(struct ispsoftc *isp, in_fcentry_e_t *src,
+ in_fcentry_e_t *dst)
{
- isp_copy_in_hdr(isp, &insrc->in_header, &indst->in_header);
- ISP_IOXGET_32(isp, &insrc->in_reserved, indst->in_reserved);
- ISP_IOXGET_8(isp, &insrc->in_lun, indst->in_lun);
- ISP_IOXGET_8(isp, &insrc->in_iid, indst->in_iid);
- ISP_IOXGET_16(isp, &insrc->in_scclun, indst->in_scclun);
- ISP_IOXGET_32(isp, &insrc->in_reserved2, indst->in_reserved2);
- ISP_IOXGET_16(isp, &insrc->in_status, indst->in_status);
- ISP_IOXGET_16(isp, &insrc->in_task_flags, indst->in_task_flags);
- ISP_IOXGET_16(isp, &insrc->in_seqid, indst->in_seqid);
+ isp_get_hdr(isp, &src->in_header, &dst->in_header);
+ ISP_IOXGET_32(isp, &src->in_reserved, dst->in_reserved);
+ ISP_IOXGET_16(isp, &src->in_iid, dst->in_iid);
+ ISP_IOXGET_16(isp, &src->in_scclun, dst->in_scclun);
+ ISP_IOXGET_32(isp, &src->in_reserved2, dst->in_reserved2);
+ ISP_IOXGET_16(isp, &src->in_status, dst->in_status);
+ ISP_IOXGET_16(isp, &src->in_task_flags, dst->in_task_flags);
+ ISP_IOXGET_16(isp, &src->in_seqid, dst->in_seqid);
}
void
-isp_put_notify_ack(struct ispsoftc *isp, na_entry_t *nasrc, na_entry_t *nadst)
+isp_get_notify_24xx(struct ispsoftc *isp, in_fcentry_24xx_t *src,
+ in_fcentry_24xx_t *dst)
{
int i;
- isp_copy_out_hdr(isp, &nasrc->na_header, &nadst->na_header);
- ISP_IOXPUT_32(isp, nasrc->na_reserved, &nadst->na_reserved);
+
+ isp_get_hdr(isp, &src->in_header, &dst->in_header);
+ ISP_IOXGET_32(isp, &src->in_reserved, dst->in_reserved);
+ ISP_IOXGET_16(isp, &src->in_nphdl, dst->in_nphdl);
+ ISP_IOXGET_16(isp, &src->in_reserved1, dst->in_reserved1);
+ ISP_IOXGET_16(isp, &src->in_flags, dst->in_flags);
+ ISP_IOXGET_16(isp, &src->in_srr_rxid, dst->in_srr_rxid);
+ ISP_IOXGET_16(isp, &src->in_status, dst->in_status);
+ ISP_IOXGET_8(isp, &src->in_status_subcode, dst->in_status_subcode);
+ ISP_IOXGET_16(isp, &src->in_reserved2, dst->in_reserved2);
+ ISP_IOXGET_32(isp, &src->in_rxid, dst->in_rxid);
+ ISP_IOXGET_16(isp, &src->in_srr_reloff_hi, dst->in_srr_reloff_hi);
+ ISP_IOXGET_16(isp, &src->in_srr_reloff_lo, dst->in_srr_reloff_lo);
+ ISP_IOXGET_16(isp, &src->in_srr_iu, dst->in_srr_iu);
+ ISP_IOXGET_16(isp, &src->in_srr_oxid, dst->in_srr_oxid);
+ for (i = 0; i < 18; i++) {
+ ISP_IOXGET_8(isp, &src->in_reserved3[i], dst->in_reserved3[i]);
+ }
+ ISP_IOXGET_8(isp, &src->in_reserved4, dst->in_reserved4);
+ ISP_IOXGET_8(isp, &src->in_vpindex, dst->in_vpindex);
+ ISP_IOXGET_32(isp, &src->in_reserved5, dst->in_reserved5);
+ ISP_IOXGET_16(isp, &src->in_portid_lo, dst->in_portid_lo);
+ ISP_IOXGET_8(isp, &src->in_portid_hi, dst->in_portid_hi);
+ ISP_IOXGET_8(isp, &src->in_reserved6, dst->in_reserved6);
+ ISP_IOXGET_16(isp, &src->in_reserved7, dst->in_reserved7);
+ ISP_IOXGET_16(isp, &src->in_oxid, dst->in_oxid);
+}
+
+void
+isp_put_notify_ack(struct ispsoftc *isp, na_entry_t *src, na_entry_t *dst)
+{
+ int i;
+ isp_put_hdr(isp, &src->na_header, &dst->na_header);
+ ISP_IOXPUT_32(isp, src->na_reserved, &dst->na_reserved);
if (ISP_IS_SBUS(isp)) {
- ISP_IOXPUT_8(isp, nasrc->na_lun, &nadst->na_iid);
- ISP_IOXPUT_8(isp, nasrc->na_iid, &nadst->na_lun);
- ISP_IOXPUT_8(isp, nasrc->na_status, &nadst->na_event);
- ISP_IOXPUT_8(isp, nasrc->na_event, &nadst->na_status);
+ ISP_IOXPUT_8(isp, src->na_lun, &dst->na_iid);
+ ISP_IOXPUT_8(isp, src->na_iid, &dst->na_lun);
+ ISP_IOXPUT_8(isp, src->na_status, &dst->na_event);
+ ISP_IOXPUT_8(isp, src->na_event, &dst->na_status);
} else {
- ISP_IOXPUT_8(isp, nasrc->na_lun, &nadst->na_lun);
- ISP_IOXPUT_8(isp, nasrc->na_iid, &nadst->na_iid);
- ISP_IOXPUT_8(isp, nasrc->na_status, &nadst->na_status);
- ISP_IOXPUT_8(isp, nasrc->na_event, &nadst->na_event);
+ ISP_IOXPUT_8(isp, src->na_lun, &dst->na_lun);
+ ISP_IOXPUT_8(isp, src->na_iid, &dst->na_iid);
+ ISP_IOXPUT_8(isp, src->na_status, &dst->na_status);
+ ISP_IOXPUT_8(isp, src->na_event, &dst->na_event);
}
- ISP_IOXPUT_32(isp, nasrc->na_flags, &nadst->na_flags);
+ ISP_IOXPUT_32(isp, src->na_flags, &dst->na_flags);
for (i = 0; i < NA_RSVDLEN; i++) {
- ISP_IOXPUT_16(isp, nasrc->na_reserved3[i],
- &nadst->na_reserved3[i]);
+ ISP_IOXPUT_16(isp, src->na_reserved3[i],
+ &dst->na_reserved3[i]);
}
}
void
-isp_get_notify_ack(struct ispsoftc *isp, na_entry_t *nasrc, na_entry_t *nadst)
+isp_get_notify_ack(struct ispsoftc *isp, na_entry_t *src, na_entry_t *dst)
{
int i;
- isp_copy_in_hdr(isp, &nasrc->na_header, &nadst->na_header);
- ISP_IOXGET_32(isp, &nasrc->na_reserved, nadst->na_reserved);
+ isp_get_hdr(isp, &src->na_header, &dst->na_header);
+ ISP_IOXGET_32(isp, &src->na_reserved, dst->na_reserved);
if (ISP_IS_SBUS(isp)) {
- ISP_IOXGET_8(isp, &nasrc->na_lun, nadst->na_iid);
- ISP_IOXGET_8(isp, &nasrc->na_iid, nadst->na_lun);
- ISP_IOXGET_8(isp, &nasrc->na_status, nadst->na_event);
- ISP_IOXGET_8(isp, &nasrc->na_event, nadst->na_status);
+ ISP_IOXGET_8(isp, &src->na_lun, dst->na_iid);
+ ISP_IOXGET_8(isp, &src->na_iid, dst->na_lun);
+ ISP_IOXGET_8(isp, &src->na_status, dst->na_event);
+ ISP_IOXGET_8(isp, &src->na_event, dst->na_status);
} else {
- ISP_IOXGET_8(isp, &nasrc->na_lun, nadst->na_lun);
- ISP_IOXGET_8(isp, &nasrc->na_iid, nadst->na_iid);
- ISP_IOXGET_8(isp, &nasrc->na_status, nadst->na_status);
- ISP_IOXGET_8(isp, &nasrc->na_event, nadst->na_event);
+ ISP_IOXGET_8(isp, &src->na_lun, dst->na_lun);
+ ISP_IOXGET_8(isp, &src->na_iid, dst->na_iid);
+ ISP_IOXGET_8(isp, &src->na_status, dst->na_status);
+ ISP_IOXGET_8(isp, &src->na_event, dst->na_event);
}
- ISP_IOXGET_32(isp, &nasrc->na_flags, nadst->na_flags);
+ ISP_IOXGET_32(isp, &src->na_flags, dst->na_flags);
for (i = 0; i < NA_RSVDLEN; i++) {
- ISP_IOXGET_16(isp, &nasrc->na_reserved3[i],
- nadst->na_reserved3[i]);
+ ISP_IOXGET_16(isp, &src->na_reserved3[i],
+ dst->na_reserved3[i]);
}
}
void
-isp_put_notify_ack_fc(struct ispsoftc *isp, na_fcentry_t *nasrc,
- na_fcentry_t *nadst)
+isp_put_notify_ack_fc(struct ispsoftc *isp, na_fcentry_t *src,
+ na_fcentry_t *dst)
{
int i;
- isp_copy_out_hdr(isp, &nasrc->na_header, &nadst->na_header);
- ISP_IOXPUT_32(isp, nasrc->na_reserved, &nadst->na_reserved);
- ISP_IOXPUT_8(isp, nasrc->na_lun, &nadst->na_lun);
- ISP_IOXPUT_8(isp, nasrc->na_iid, &nadst->na_iid);
- ISP_IOXPUT_16(isp, nasrc->na_scclun, &nadst->na_scclun);
- ISP_IOXPUT_16(isp, nasrc->na_flags, &nadst->na_flags);
- ISP_IOXPUT_16(isp, nasrc->na_reserved2, &nadst->na_reserved2);
- ISP_IOXPUT_16(isp, nasrc->na_status, &nadst->na_status);
- ISP_IOXPUT_16(isp, nasrc->na_task_flags, &nadst->na_task_flags);
- ISP_IOXPUT_16(isp, nasrc->na_seqid, &nadst->na_seqid);
+ isp_put_hdr(isp, &src->na_header, &dst->na_header);
+ ISP_IOXPUT_32(isp, src->na_reserved, &dst->na_reserved);
+ ISP_IOXPUT_8(isp, src->na_reserved1, &dst->na_reserved1);
+ ISP_IOXPUT_8(isp, src->na_iid, &dst->na_iid);
+ ISP_IOXPUT_16(isp, src->na_response, &dst->na_response);
+ ISP_IOXPUT_16(isp, src->na_flags, &dst->na_flags);
+ ISP_IOXPUT_16(isp, src->na_reserved2, &dst->na_reserved2);
+ ISP_IOXPUT_16(isp, src->na_status, &dst->na_status);
+ ISP_IOXPUT_16(isp, src->na_task_flags, &dst->na_task_flags);
+ ISP_IOXPUT_16(isp, src->na_seqid, &dst->na_seqid);
for (i = 0; i < NA2_RSVDLEN; i++) {
- ISP_IOXPUT_16(isp, nasrc->na_reserved3[i],
- &nadst->na_reserved3[i]);
+ ISP_IOXPUT_16(isp, src->na_reserved3[i],
+ &dst->na_reserved3[i]);
}
}
void
-isp_get_notify_ack_fc(struct ispsoftc *isp, na_fcentry_t *nasrc,
- na_fcentry_t *nadst)
+isp_put_notify_ack_fc_e(struct ispsoftc *isp, na_fcentry_e_t *src,
+ na_fcentry_e_t *dst)
{
int i;
- isp_copy_in_hdr(isp, &nasrc->na_header, &nadst->na_header);
- ISP_IOXGET_32(isp, &nasrc->na_reserved, nadst->na_reserved);
- ISP_IOXGET_8(isp, &nasrc->na_lun, nadst->na_lun);
- ISP_IOXGET_8(isp, &nasrc->na_iid, nadst->na_iid);
- ISP_IOXGET_16(isp, &nasrc->na_scclun, nadst->na_scclun);
- ISP_IOXGET_16(isp, &nasrc->na_flags, nadst->na_flags);
- ISP_IOXGET_16(isp, &nasrc->na_reserved2, nadst->na_reserved2);
- ISP_IOXGET_16(isp, &nasrc->na_status, nadst->na_status);
- ISP_IOXGET_16(isp, &nasrc->na_task_flags, nadst->na_task_flags);
- ISP_IOXGET_16(isp, &nasrc->na_seqid, nadst->na_seqid);
+ isp_put_hdr(isp, &src->na_header, &dst->na_header);
+ ISP_IOXPUT_32(isp, src->na_reserved, &dst->na_reserved);
+ ISP_IOXPUT_16(isp, src->na_iid, &dst->na_iid);
+ ISP_IOXPUT_16(isp, src->na_response, &dst->na_response);
+ ISP_IOXPUT_16(isp, src->na_flags, &dst->na_flags);
+ ISP_IOXPUT_16(isp, src->na_reserved2, &dst->na_reserved2);
+ ISP_IOXPUT_16(isp, src->na_status, &dst->na_status);
+ ISP_IOXPUT_16(isp, src->na_task_flags, &dst->na_task_flags);
+ ISP_IOXPUT_16(isp, src->na_seqid, &dst->na_seqid);
for (i = 0; i < NA2_RSVDLEN; i++) {
- ISP_IOXGET_16(isp, &nasrc->na_reserved3[i],
- nadst->na_reserved3[i]);
+ ISP_IOXPUT_16(isp, src->na_reserved3[i],
+ &dst->na_reserved3[i]);
}
}
-#endif
+
+void
+isp_put_notify_24xx_ack(struct ispsoftc *isp, na_fcentry_24xx_t *src,
+ na_fcentry_24xx_t *dst)
+{
+ int i;
+
+ isp_put_hdr(isp, &src->na_header, &dst->na_header);
+ ISP_IOXPUT_32(isp, src->na_handle, &dst->na_handle);
+ ISP_IOXPUT_16(isp, src->na_nphdl, &dst->na_nphdl);
+ ISP_IOXPUT_16(isp, src->na_reserved1, &dst->na_reserved1);
+ ISP_IOXPUT_16(isp, src->na_flags, &dst->na_flags);
+ ISP_IOXPUT_16(isp, src->na_srr_rxid, &dst->na_srr_rxid);
+ ISP_IOXPUT_16(isp, src->na_status, &dst->na_status);
+ ISP_IOXPUT_8(isp, src->na_status_subcode, &dst->na_status_subcode);
+ ISP_IOXPUT_16(isp, src->na_reserved2, &dst->na_reserved2);
+ ISP_IOXPUT_32(isp, src->na_rxid, &dst->na_rxid);
+ ISP_IOXPUT_16(isp, src->na_srr_reloff_hi, &dst->na_srr_reloff_hi);
+ ISP_IOXPUT_16(isp, src->na_srr_reloff_lo, &dst->na_srr_reloff_lo);
+ ISP_IOXPUT_16(isp, src->na_srr_iu, &dst->na_srr_iu);
+ ISP_IOXPUT_16(isp, src->na_srr_flags, &dst->na_srr_flags);
+ for (i = 0; i < 18; i++) {
+ ISP_IOXPUT_8(isp, src->na_reserved3[i], &dst->na_reserved3[i]);
+ }
+ ISP_IOXPUT_8(isp, src->na_reserved4, &dst->na_reserved4);
+ ISP_IOXPUT_8(isp, src->na_vpindex, &dst->na_vpindex);
+ ISP_IOXPUT_8(isp, src->na_srr_reject_vunique,
+ &dst->na_srr_reject_vunique);
+ ISP_IOXPUT_8(isp, src->na_srr_reject_explanation,
+ &dst->na_srr_reject_explanation);
+ ISP_IOXPUT_8(isp, src->na_srr_reject_code, &dst->na_srr_reject_code);
+ ISP_IOXPUT_8(isp, src->na_reserved5, &dst->na_reserved5);
+ for (i = 0; i < 6; i++) {
+ ISP_IOXPUT_8(isp, src->na_reserved6[i], &dst->na_reserved6[i]);
+ }
+ ISP_IOXPUT_16(isp, src->na_oxid, &dst->na_oxid);
+}
+
+void
+isp_get_notify_ack_fc(struct ispsoftc *isp, na_fcentry_t *src,
+ na_fcentry_t *dst)
+{
+ int i;
+ isp_get_hdr(isp, &src->na_header, &dst->na_header);
+ ISP_IOXGET_32(isp, &src->na_reserved, dst->na_reserved);
+ ISP_IOXGET_8(isp, &src->na_reserved1, dst->na_reserved1);
+ ISP_IOXGET_8(isp, &src->na_iid, dst->na_iid);
+ ISP_IOXGET_16(isp, &src->na_response, dst->na_response);
+ ISP_IOXGET_16(isp, &src->na_flags, dst->na_flags);
+ ISP_IOXGET_16(isp, &src->na_reserved2, dst->na_reserved2);
+ ISP_IOXGET_16(isp, &src->na_status, dst->na_status);
+ ISP_IOXGET_16(isp, &src->na_task_flags, dst->na_task_flags);
+ ISP_IOXGET_16(isp, &src->na_seqid, dst->na_seqid);
+ for (i = 0; i < NA2_RSVDLEN; i++) {
+ ISP_IOXGET_16(isp, &src->na_reserved3[i],
+ dst->na_reserved3[i]);
+ }
+}
+
+void
+isp_get_notify_ack_fc_e(struct ispsoftc *isp, na_fcentry_e_t *src,
+ na_fcentry_e_t *dst)
+{
+ int i;
+ isp_get_hdr(isp, &src->na_header, &dst->na_header);
+ ISP_IOXGET_32(isp, &src->na_reserved, dst->na_reserved);
+ ISP_IOXGET_16(isp, &src->na_iid, dst->na_iid);
+ ISP_IOXGET_16(isp, &src->na_response, dst->na_response);
+ ISP_IOXGET_16(isp, &src->na_flags, dst->na_flags);
+ ISP_IOXGET_16(isp, &src->na_reserved2, dst->na_reserved2);
+ ISP_IOXGET_16(isp, &src->na_status, dst->na_status);
+ ISP_IOXGET_16(isp, &src->na_task_flags, dst->na_task_flags);
+ ISP_IOXGET_16(isp, &src->na_seqid, dst->na_seqid);
+ for (i = 0; i < NA2_RSVDLEN; i++) {
+ ISP_IOXGET_16(isp, &src->na_reserved3[i],
+ dst->na_reserved3[i]);
+ }
+}
+
+void
+isp_get_notify_ack_24xx(struct ispsoftc *isp, na_fcentry_24xx_t *src,
+ na_fcentry_24xx_t *dst)
+{
+ int i;
+
+ isp_get_hdr(isp, &src->na_header, &dst->na_header);
+ ISP_IOXGET_32(isp, &src->na_handle, dst->na_handle);
+ ISP_IOXGET_16(isp, &src->na_nphdl, dst->na_nphdl);
+ ISP_IOXGET_16(isp, &src->na_reserved1, dst->na_reserved1);
+ ISP_IOXGET_16(isp, &src->na_flags, dst->na_flags);
+ ISP_IOXGET_16(isp, &src->na_srr_rxid, dst->na_srr_rxid);
+ ISP_IOXGET_16(isp, &src->na_status, dst->na_status);
+ ISP_IOXGET_8(isp, &src->na_status_subcode, dst->na_status_subcode);
+ ISP_IOXGET_16(isp, &src->na_reserved2, dst->na_reserved2);
+ ISP_IOXGET_32(isp, &src->na_rxid, dst->na_rxid);
+ ISP_IOXGET_16(isp, &src->na_srr_reloff_hi, dst->na_srr_reloff_hi);
+ ISP_IOXGET_16(isp, &src->na_srr_reloff_lo, dst->na_srr_reloff_lo);
+ ISP_IOXGET_16(isp, &src->na_srr_iu, dst->na_srr_iu);
+ ISP_IOXGET_16(isp, &src->na_srr_flags, dst->na_srr_flags);
+ for (i = 0; i < 18; i++) {
+ ISP_IOXGET_8(isp, &src->na_reserved3[i], dst->na_reserved3[i]);
+ }
+ ISP_IOXGET_8(isp, &src->na_reserved4, dst->na_reserved4);
+ ISP_IOXGET_8(isp, &src->na_vpindex, dst->na_vpindex);
+ ISP_IOXGET_8(isp, &src->na_srr_reject_vunique,
+ dst->na_srr_reject_vunique);
+ ISP_IOXGET_8(isp, &src->na_srr_reject_explanation,
+ dst->na_srr_reject_explanation);
+ ISP_IOXGET_8(isp, &src->na_srr_reject_code, dst->na_srr_reject_code);
+ ISP_IOXGET_8(isp, &src->na_reserved5, dst->na_reserved5);
+ for (i = 0; i < 6; i++) {
+ ISP_IOXGET_8(isp, &src->na_reserved6[i], dst->na_reserved6[i]);
+ }
+ ISP_IOXGET_16(isp, &src->na_oxid, dst->na_oxid);
+}
+
+void
+isp_get_abts(struct ispsoftc *isp, abts_t *src, abts_t *dst)
+{
+ int i;
+
+ isp_get_hdr(isp, &src->abts_header, &dst->abts_header);
+ for (i = 0; i < 6; i++) {
+ ISP_IOXGET_8(isp, &src->abts_reserved0[i],
+ dst->abts_reserved0[i]);
+ }
+ ISP_IOXGET_16(isp, &src->abts_nphdl, dst->abts_nphdl);
+ ISP_IOXGET_16(isp, &src->abts_reserved1, dst->abts_reserved1);
+ ISP_IOXGET_16(isp, &src->abts_sof, dst->abts_sof);
+ ISP_IOXGET_32(isp, &src->abts_rxid_abts, dst->abts_rxid_abts);
+ ISP_IOXGET_16(isp, &src->abts_did_lo, dst->abts_did_lo);
+ ISP_IOXGET_8(isp, &src->abts_did_hi, dst->abts_did_hi);
+ ISP_IOXGET_8(isp, &src->abts_r_ctl, dst->abts_r_ctl);
+ ISP_IOXGET_16(isp, &src->abts_sid_lo, dst->abts_sid_lo);
+ ISP_IOXGET_8(isp, &src->abts_sid_hi, dst->abts_sid_hi);
+ ISP_IOXGET_8(isp, &src->abts_cs_ctl, dst->abts_cs_ctl);
+ ISP_IOXGET_16(isp, &src->abts_fs_ctl, dst->abts_fs_ctl);
+ ISP_IOXGET_8(isp, &src->abts_f_ctl, dst->abts_f_ctl);
+ ISP_IOXGET_8(isp, &src->abts_type, dst->abts_type);
+ ISP_IOXGET_16(isp, &src->abts_seq_cnt, dst->abts_seq_cnt);
+ ISP_IOXGET_8(isp, &src->abts_df_ctl, dst->abts_df_ctl);
+ ISP_IOXGET_8(isp, &src->abts_seq_id, dst->abts_seq_id);
+ ISP_IOXGET_16(isp, &src->abts_rx_id, dst->abts_rx_id);
+ ISP_IOXGET_16(isp, &src->abts_ox_id, dst->abts_ox_id);
+ ISP_IOXGET_32(isp, &src->abts_param, dst->abts_param);
+ for (i = 0; i < 16; i++) {
+ ISP_IOXGET_8(isp, &src->abts_reserved2[i],
+ dst->abts_reserved2[i]);
+ }
+ ISP_IOXGET_32(isp, &src->abts_rxid_task, dst->abts_rxid_task);
+}
+
+void
+isp_put_abts_rsp(struct ispsoftc *isp, abts_rsp_t *src, abts_rsp_t *dst)
+{
+ int i;
+
+ isp_put_hdr(isp, &src->abts_rsp_header, &dst->abts_rsp_header);
+ ISP_IOXPUT_32(isp, src->abts_rsp_handle, &dst->abts_rsp_handle);
+ ISP_IOXPUT_16(isp, src->abts_rsp_status, &dst->abts_rsp_status);
+ ISP_IOXPUT_16(isp, src->abts_rsp_nphdl, &dst->abts_rsp_nphdl);
+ ISP_IOXPUT_16(isp, src->abts_rsp_ctl_flags, &dst->abts_rsp_ctl_flags);
+ ISP_IOXPUT_16(isp, src->abts_rsp_sof, &dst->abts_rsp_sof);
+ ISP_IOXPUT_32(isp, src->abts_rsp_rxid_abts, &dst->abts_rsp_rxid_abts);
+ ISP_IOXPUT_16(isp, src->abts_rsp_did_lo, &dst->abts_rsp_did_lo);
+ ISP_IOXPUT_8(isp, src->abts_rsp_did_hi, &dst->abts_rsp_did_hi);
+ ISP_IOXPUT_8(isp, src->abts_rsp_r_ctl, &dst->abts_rsp_r_ctl);
+ ISP_IOXPUT_16(isp, src->abts_rsp_sid_lo, &dst->abts_rsp_sid_lo);
+ ISP_IOXPUT_8(isp, src->abts_rsp_sid_hi, &dst->abts_rsp_sid_hi);
+ ISP_IOXPUT_8(isp, src->abts_rsp_cs_ctl, &dst->abts_rsp_cs_ctl);
+ ISP_IOXPUT_16(isp, src->abts_rsp_f_ctl_lo, &dst->abts_rsp_f_ctl_lo);
+ ISP_IOXPUT_8(isp, src->abts_rsp_f_ctl_hi, &dst->abts_rsp_f_ctl_hi);
+ ISP_IOXPUT_8(isp, src->abts_rsp_type, &dst->abts_rsp_type);
+ ISP_IOXPUT_16(isp, src->abts_rsp_seq_cnt, &dst->abts_rsp_seq_cnt);
+ ISP_IOXPUT_8(isp, src->abts_rsp_df_ctl, &dst->abts_rsp_df_ctl);
+ ISP_IOXPUT_8(isp, src->abts_rsp_seq_id, &dst->abts_rsp_seq_id);
+ ISP_IOXPUT_16(isp, src->abts_rsp_rx_id, &dst->abts_rsp_rx_id);
+ ISP_IOXPUT_16(isp, src->abts_rsp_ox_id, &dst->abts_rsp_ox_id);
+ ISP_IOXPUT_32(isp, src->abts_rsp_param, &dst->abts_rsp_param);
+ if (src->abts_rsp_r_ctl == BA_ACC) {
+ ISP_IOXPUT_16(isp, src->abts_rsp_payload.ba_acc.reserved,
+ &dst->abts_rsp_payload.ba_acc.reserved);
+ ISP_IOXPUT_8(isp, src->abts_rsp_payload.ba_acc.last_seq_id,
+ &dst->abts_rsp_payload.ba_acc.last_seq_id);
+ ISP_IOXPUT_8(isp, src->abts_rsp_payload.ba_acc.seq_id_valid,
+ &dst->abts_rsp_payload.ba_acc.seq_id_valid);
+ ISP_IOXPUT_16(isp, src->abts_rsp_payload.ba_acc.aborted_rx_id,
+ &dst->abts_rsp_payload.ba_acc.aborted_rx_id);
+ ISP_IOXPUT_16(isp, src->abts_rsp_payload.ba_acc.aborted_ox_id,
+ &dst->abts_rsp_payload.ba_acc.aborted_ox_id);
+ ISP_IOXPUT_16(isp, src->abts_rsp_payload.ba_acc.high_seq_cnt,
+ &dst->abts_rsp_payload.ba_acc.high_seq_cnt);
+ ISP_IOXPUT_16(isp, src->abts_rsp_payload.ba_acc.low_seq_cnt,
+ &dst->abts_rsp_payload.ba_acc.low_seq_cnt);
+ for (i = 0; i < 4; i++) {
+ ISP_IOXPUT_16(isp,
+ src->abts_rsp_payload.ba_acc.reserved2[i],
+ &dst->abts_rsp_payload.ba_acc.reserved2[i]);
+ }
+ } else if (src->abts_rsp_r_ctl == BA_RJT) {
+ ISP_IOXPUT_8(isp, src->abts_rsp_payload.ba_rjt.vendor_unique,
+ &dst->abts_rsp_payload.ba_rjt.vendor_unique);
+ ISP_IOXPUT_8(isp, src->abts_rsp_payload.ba_rjt.explanation,
+ &dst->abts_rsp_payload.ba_rjt.explanation);
+ ISP_IOXPUT_8(isp, src->abts_rsp_payload.ba_rjt.reason,
+ &dst->abts_rsp_payload.ba_rjt.reason);
+ ISP_IOXPUT_8(isp, src->abts_rsp_payload.ba_rjt.reserved,
+ &dst->abts_rsp_payload.ba_rjt.reserved);
+ for (i = 0; i < 12; i++) {
+ ISP_IOXPUT_16(isp,
+ src->abts_rsp_payload.ba_rjt.reserved2[i],
+ &dst->abts_rsp_payload.ba_rjt.reserved2[i]);
+ }
+ } else {
+ for (i = 0; i < 16; i++) {
+ ISP_IOXPUT_8(isp, src->abts_rsp_payload.reserved[i],
+ &dst->abts_rsp_payload.reserved[i]);
+ }
+ }
+ ISP_IOXPUT_32(isp, src->abts_rsp_rxid_task, &dst->abts_rsp_rxid_task);
+}
+
+void
+isp_get_abts_rsp(struct ispsoftc *isp, abts_rsp_t *src, abts_rsp_t *dst)
+{
+ int i;
+
+ isp_get_hdr(isp, &src->abts_rsp_header, &dst->abts_rsp_header);
+ ISP_IOXGET_32(isp, &src->abts_rsp_handle, dst->abts_rsp_handle);
+ ISP_IOXGET_16(isp, &src->abts_rsp_status, dst->abts_rsp_status);
+ ISP_IOXGET_16(isp, &src->abts_rsp_nphdl, dst->abts_rsp_nphdl);
+ ISP_IOXGET_16(isp, &src->abts_rsp_ctl_flags, dst->abts_rsp_ctl_flags);
+ ISP_IOXGET_16(isp, &src->abts_rsp_sof, dst->abts_rsp_sof);
+ ISP_IOXGET_32(isp, &src->abts_rsp_rxid_abts, dst->abts_rsp_rxid_abts);
+ ISP_IOXGET_16(isp, &src->abts_rsp_did_lo, dst->abts_rsp_did_lo);
+ ISP_IOXGET_8(isp, &src->abts_rsp_did_hi, dst->abts_rsp_did_hi);
+ ISP_IOXGET_8(isp, &src->abts_rsp_r_ctl, dst->abts_rsp_r_ctl);
+ ISP_IOXGET_16(isp, &src->abts_rsp_sid_lo, dst->abts_rsp_sid_lo);
+ ISP_IOXGET_8(isp, &src->abts_rsp_sid_hi, dst->abts_rsp_sid_hi);
+ ISP_IOXGET_8(isp, &src->abts_rsp_cs_ctl, dst->abts_rsp_cs_ctl);
+ ISP_IOXGET_16(isp, &src->abts_rsp_f_ctl_lo, dst->abts_rsp_f_ctl_lo);
+ ISP_IOXGET_8(isp, &src->abts_rsp_f_ctl_hi, dst->abts_rsp_f_ctl_hi);
+ ISP_IOXGET_8(isp, &src->abts_rsp_type, dst->abts_rsp_type);
+ ISP_IOXGET_16(isp, &src->abts_rsp_seq_cnt, dst->abts_rsp_seq_cnt);
+ ISP_IOXGET_8(isp, &src->abts_rsp_df_ctl, dst->abts_rsp_df_ctl);
+ ISP_IOXGET_8(isp, &src->abts_rsp_seq_id, dst->abts_rsp_seq_id);
+ ISP_IOXGET_16(isp, &src->abts_rsp_rx_id, dst->abts_rsp_rx_id);
+ ISP_IOXGET_16(isp, &src->abts_rsp_ox_id, dst->abts_rsp_ox_id);
+ ISP_IOXGET_32(isp, &src->abts_rsp_param, dst->abts_rsp_param);
+ for (i = 0; i < 8; i++) {
+ ISP_IOXGET_8(isp, &src->abts_rsp_payload.rsp.reserved[i],
+ dst->abts_rsp_payload.rsp.reserved[i]);
+ }
+ ISP_IOXGET_32(isp, &src->abts_rsp_payload.rsp.subcode1,
+ dst->abts_rsp_payload.rsp.subcode1);
+ ISP_IOXGET_32(isp, &src->abts_rsp_payload.rsp.subcode2,
+ dst->abts_rsp_payload.rsp.subcode2);
+ ISP_IOXGET_32(isp, &src->abts_rsp_rxid_task, dst->abts_rsp_rxid_task);
+}
+#endif /* ISP_TARGET_MODE */
diff --git a/sys/dev/ic/isp_library.h b/sys/dev/ic/isp_library.h
index 3b9ec400c87..a42dcd322ec 100644
--- a/sys/dev/ic/isp_library.h
+++ b/sys/dev/ic/isp_library.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: isp_library.h,v 1.1 2008/11/16 00:00:13 krw Exp $ */
+/* $OpenBSD: isp_library.h,v 1.2 2009/06/24 11:00:53 krw Exp $ */
/* $FreeBSD: src/sys/dev/isp/isp_library.h,v 1.8 2007/04/02 01:04:20 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
@@ -29,122 +29,197 @@
#ifndef _ISP_LIBRARY_H
#define _ISP_LIBRARY_H
-#include <dev/ic/isp_openbsd.h>
-
-extern int isp_save_xs(struct ispsoftc *, XS_T *, u_int16_t *);
-extern XS_T *isp_find_xs(struct ispsoftc *, u_int16_t);
-extern u_int16_t isp_find_handle(struct ispsoftc *, XS_T *);
-extern int isp_handle_index(u_int16_t);
-extern void isp_destroy_handle(struct ispsoftc *, u_int16_t);
-extern void isp_remove_handle(struct ispsoftc *, XS_T *);
-
-extern int
-isp_getrqentry(struct ispsoftc *, u_int16_t *, u_int16_t *, void **);
-
+extern int isp_save_xs(ispsoftc_t *, XS_T *, u_int32_t *);
+extern XS_T *isp_find_xs(ispsoftc_t *, u_int32_t);
+extern u_int32_t isp_find_handle(ispsoftc_t *, XS_T *);
+extern u_int32_t isp_handle_index(u_int32_t);
+extern void isp_destroy_handle(ispsoftc_t *, u_int32_t);
+extern int isp_getrqentry(ispsoftc_t *, u_int32_t *, u_int32_t *, void **);
+extern void isp_print_qentry (ispsoftc_t *, char *, int, void *);
+extern void isp_print_bytes(ispsoftc_t *, const char *, int, void *);
+extern int isp_fc_runstate(ispsoftc_t *, int);
+extern void isp_dump_portdb(ispsoftc_t *);
+extern void isp_shutdown(ispsoftc_t *);
+extern void isp_put_hdr(ispsoftc_t *, isphdr_t *, isphdr_t *);
+extern void isp_get_hdr(ispsoftc_t *, isphdr_t *, isphdr_t *);
+extern int isp_get_response_type(ispsoftc_t *, isphdr_t *);
extern void
-isp_print_qentry (struct ispsoftc *, char *, int, void *);
-
-
-#define TBA (4 * (((QENTRY_LEN >> 2) * 3) + 1) + 1)
-
+isp_put_request(ispsoftc_t *, ispreq_t *, ispreq_t *);
extern void
-isp_print_bytes(struct ispsoftc *, char *, int, void *);
-
-extern int isp_fc_runstate(struct ispsoftc *, int);
-
-extern void isp_copy_out_hdr(struct ispsoftc *, isphdr_t *, isphdr_t *);
-extern void isp_copy_in_hdr(struct ispsoftc *, isphdr_t *, isphdr_t *);
-extern int isp_get_response_type(struct ispsoftc *, isphdr_t *);
-
+isp_put_marker(ispsoftc_t *, isp_marker_t *, isp_marker_t *);
+extern void
+isp_put_marker_24xx(ispsoftc_t *, isp_marker_24xx_t *, isp_marker_24xx_t *);
+extern void
+isp_put_request_t2(ispsoftc_t *, ispreqt2_t *, ispreqt2_t *);
+extern void
+isp_put_request_t2e(ispsoftc_t *, ispreqt2e_t *, ispreqt2e_t *);
extern void
-isp_put_request(struct ispsoftc *, ispreq_t *, ispreq_t *);
+isp_put_request_t3(ispsoftc_t *, ispreqt3_t *, ispreqt3_t *);
extern void
-isp_put_request_t2(struct ispsoftc *, ispreqt2_t *, ispreqt2_t *);
+isp_put_request_t3e(ispsoftc_t *, ispreqt3e_t *, ispreqt3e_t *);
extern void
-isp_put_request_t3(struct ispsoftc *, ispreqt3_t *, ispreqt3_t *);
+isp_put_extended_request(ispsoftc_t *, ispextreq_t *, ispextreq_t *);
extern void
-isp_put_extended_request(struct ispsoftc *, ispextreq_t *, ispextreq_t *);
+isp_put_request_t7(ispsoftc_t *, ispreqt7_t *, ispreqt7_t *);
extern void
-isp_put_cont_req(struct ispsoftc *, ispcontreq_t *, ispcontreq_t *);
+isp_put_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *);
extern void
-isp_put_cont64_req(struct ispsoftc *, ispcontreq64_t *, ispcontreq64_t *);
+isp_put_cont_req(ispsoftc_t *, ispcontreq_t *, ispcontreq_t *);
extern void
-isp_get_response(struct ispsoftc *, ispstatusreq_t *, ispstatusreq_t *);
+isp_put_cont64_req(ispsoftc_t *, ispcontreq64_t *, ispcontreq64_t *);
extern void
-isp_get_response_x(struct ispsoftc *, ispstatus_cont_t *, ispstatus_cont_t *);
+isp_get_response(ispsoftc_t *, ispstatusreq_t *, ispstatusreq_t *);
+extern void isp_get_24xx_response(ispsoftc_t *, isp24xx_statusreq_t *,
+ isp24xx_statusreq_t *);
+void
+isp_get_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *);
extern void
-isp_get_rio2(struct ispsoftc *, isp_rio2_t *, isp_rio2_t *);
+isp_get_rio2(ispsoftc_t *, isp_rio2_t *, isp_rio2_t *);
extern void
-isp_put_icb(struct ispsoftc *, isp_icb_t *, isp_icb_t *);
+isp_put_icb(ispsoftc_t *, isp_icb_t *, isp_icb_t *);
extern void
-isp_get_pdb(struct ispsoftc *, isp_pdb_t *, isp_pdb_t *);
+isp_put_icb_2400(ispsoftc_t *, isp_icb_2400_t *, isp_icb_2400_t *);
extern void
-isp_get_ct_hdr(struct ispsoftc *isp, ct_hdr_t *, ct_hdr_t *);
+isp_get_pdb_21xx(ispsoftc_t *, isp_pdb_21xx_t *, isp_pdb_21xx_t *);
extern void
-isp_put_sns_request(struct ispsoftc *, sns_screq_t *, sns_screq_t *);
+isp_get_pdb_24xx(ispsoftc_t *, isp_pdb_24xx_t *, isp_pdb_24xx_t *);
extern void
-isp_put_gid_ft_request(struct ispsoftc *, sns_gid_ft_req_t *,
+isp_get_plogx(ispsoftc_t *, isp_plogx_t *, isp_plogx_t *);
+extern void
+isp_put_plogx(ispsoftc_t *, isp_plogx_t *, isp_plogx_t *);
+extern void
+isp_get_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp_ct_pt_t *);
+extern void
+isp_get_ms(ispsoftc_t *isp, isp_ms_t *, isp_ms_t *);
+extern void
+isp_put_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp_ct_pt_t *);
+extern void
+isp_put_ms(ispsoftc_t *isp, isp_ms_t *, isp_ms_t *);
+extern void
+isp_put_sns_request(ispsoftc_t *, sns_screq_t *, sns_screq_t *);
+extern void
+isp_put_gid_ft_request(ispsoftc_t *, sns_gid_ft_req_t *,
sns_gid_ft_req_t *);
extern void
-isp_put_gxn_id_request(struct ispsoftc *, sns_gxn_id_req_t *,
+isp_put_gxn_id_request(ispsoftc_t *, sns_gxn_id_req_t *,
sns_gxn_id_req_t *);
extern void
-isp_get_sns_response(struct ispsoftc *, sns_scrsp_t *, sns_scrsp_t *, int);
+isp_get_sns_response(ispsoftc_t *, sns_scrsp_t *, sns_scrsp_t *, int);
extern void
-isp_get_gid_ft_response(struct ispsoftc *, sns_gid_ft_rsp_t *,
+isp_get_gid_ft_response(ispsoftc_t *, sns_gid_ft_rsp_t *,
sns_gid_ft_rsp_t *, int);
extern void
-isp_get_gxn_id_response(struct ispsoftc *, sns_gxn_id_rsp_t *,
+isp_get_gxn_id_response(ispsoftc_t *, sns_gxn_id_rsp_t *,
sns_gxn_id_rsp_t *);
extern void
-isp_get_gff_id_response(struct ispsoftc *, sns_gff_id_rsp_t *,
+isp_get_gff_id_response(ispsoftc_t *, sns_gff_id_rsp_t *,
sns_gff_id_rsp_t *);
extern void
-isp_get_ga_nxt_response(struct ispsoftc *, sns_ga_nxt_rsp_t *,
+isp_get_ga_nxt_response(ispsoftc_t *, sns_ga_nxt_rsp_t *,
sns_ga_nxt_rsp_t *);
+extern void
+isp_get_els(ispsoftc_t *, els_t *, els_t *);
+extern void
+isp_put_els(ispsoftc_t *, els_t *, els_t *);
+extern void
+isp_get_fc_hdr(ispsoftc_t *, fc_hdr_t *, fc_hdr_t *);
+extern void
+isp_get_fcp_cmnd_iu(ispsoftc_t *, fcp_cmnd_iu_t *, fcp_cmnd_iu_t *);
+extern void isp_put_rft_id(ispsoftc_t *, rft_id_t *, rft_id_t *);
+extern void isp_get_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
+extern void isp_put_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
+
+#define ISP_HANDLE_MASK 0x7fff
+
#ifdef ISP_TARGET_MODE
-#ifndef _ISP_TARGET_H
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+#include <dev/ic/isp_target.h>
+#elif defined(__FreeBSD__)
+#include <dev/isp/isp_target.h>
+#else
#include "isp_target.h"
#endif
+
+#define IS_TARGET_HANDLE(x) ((x) & 0x8000)
+
+extern int isp_save_xs_tgt(ispsoftc_t *, void *, u_int32_t *);
+extern void *isp_find_xs_tgt(ispsoftc_t *, u_int32_t);
+extern u_int32_t isp_find_tgt_handle(ispsoftc_t *, void *);
+extern void isp_destroy_tgt_handle(ispsoftc_t *, u_int32_t);
+
extern void
-isp_put_atio(struct ispsoftc *, at_entry_t *, at_entry_t *);
+isp_put_atio(ispsoftc_t *, at_entry_t *, at_entry_t *);
extern void
-isp_get_atio(struct ispsoftc *, at_entry_t *, at_entry_t *);
+isp_get_atio(ispsoftc_t *, at_entry_t *, at_entry_t *);
extern void
-isp_put_atio2(struct ispsoftc *, at2_entry_t *, at2_entry_t *);
+isp_put_atio2(ispsoftc_t *, at2_entry_t *, at2_entry_t *);
extern void
-isp_get_atio2(struct ispsoftc *, at2_entry_t *, at2_entry_t *);
+isp_put_atio2e(ispsoftc_t *, at2e_entry_t *, at2e_entry_t *);
extern void
-isp_put_ctio(struct ispsoftc *, ct_entry_t *, ct_entry_t *);
+isp_get_atio2(ispsoftc_t *, at2_entry_t *, at2_entry_t *);
extern void
-isp_get_ctio(struct ispsoftc *, ct_entry_t *, ct_entry_t *);
+isp_get_atio2e(ispsoftc_t *, at2e_entry_t *, at2e_entry_t *);
extern void
-isp_put_ctio2(struct ispsoftc *, ct2_entry_t *, ct2_entry_t *);
+isp_get_atio7(ispsoftc_t *isp, at7_entry_t *, at7_entry_t *);
extern void
-isp_get_ctio2(struct ispsoftc *, ct2_entry_t *, ct2_entry_t *);
+isp_put_ctio(ispsoftc_t *, ct_entry_t *, ct_entry_t *);
extern void
-isp_put_enable_lun(struct ispsoftc *, lun_entry_t *, lun_entry_t *);
+isp_get_ctio(ispsoftc_t *, ct_entry_t *, ct_entry_t *);
extern void
-isp_get_enable_lun(struct ispsoftc *, lun_entry_t *, lun_entry_t *);
+isp_put_ctio2(ispsoftc_t *, ct2_entry_t *, ct2_entry_t *);
extern void
-isp_put_notify(struct ispsoftc *, in_entry_t *, in_entry_t *);
+isp_put_ctio2e(ispsoftc_t *, ct2e_entry_t *, ct2e_entry_t *);
extern void
-isp_get_notify(struct ispsoftc *, in_entry_t *, in_entry_t *);
+isp_put_ctio7(ispsoftc_t *, ct7_entry_t *, ct7_entry_t *);
extern void
-isp_put_notify_fc(struct ispsoftc *, in_fcentry_t *, in_fcentry_t *);
+isp_get_ctio2(ispsoftc_t *, ct2_entry_t *, ct2_entry_t *);
extern void
-isp_get_notify_fc(struct ispsoftc *, in_fcentry_t *, in_fcentry_t *);
+isp_get_ctio2e(ispsoftc_t *, ct2e_entry_t *, ct2e_entry_t *);
extern void
-isp_put_notify_ack(struct ispsoftc *, na_entry_t *, na_entry_t *);
+isp_get_ctio7(ispsoftc_t *, ct7_entry_t *, ct7_entry_t *);
extern void
-isp_get_notify_ack(struct ispsoftc *, na_entry_t *, na_entry_t *);
+isp_put_enable_lun(ispsoftc_t *, lun_entry_t *, lun_entry_t *);
extern void
-isp_put_notify_ack_fc(struct ispsoftc *, na_fcentry_t *, na_fcentry_t *);
+isp_get_enable_lun(ispsoftc_t *, lun_entry_t *, lun_entry_t *);
extern void
-isp_get_notify_ack_fc(struct ispsoftc *, na_fcentry_t *, na_fcentry_t *);
-#endif
-
-#define ISP_IS_SBUS(isp) \
- (ISP_SBUS_SUPPORTED && (isp)->isp_bustype == ISP_BT_SBUS)
-
+isp_put_notify(ispsoftc_t *, in_entry_t *, in_entry_t *);
+extern void
+isp_get_notify(ispsoftc_t *, in_entry_t *, in_entry_t *);
+extern void
+isp_put_notify_fc(ispsoftc_t *, in_fcentry_t *, in_fcentry_t *);
+extern void
+isp_put_notify_fc_e(ispsoftc_t *, in_fcentry_e_t *, in_fcentry_e_t *);
+extern void
+isp_put_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *, in_fcentry_24xx_t *);
+extern void
+isp_get_notify_fc(ispsoftc_t *, in_fcentry_t *, in_fcentry_t *);
+extern void
+isp_get_notify_fc_e(ispsoftc_t *, in_fcentry_e_t *, in_fcentry_e_t *);
+extern void
+isp_get_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *, in_fcentry_24xx_t *);
+extern void
+isp_put_notify_ack(ispsoftc_t *, na_entry_t *, na_entry_t *);
+extern void
+isp_get_notify_ack(ispsoftc_t *, na_entry_t *, na_entry_t *);
+extern void
+isp_put_notify_24xx_ack(ispsoftc_t *, na_fcentry_24xx_t *, na_fcentry_24xx_t *);
+extern void
+isp_put_notify_ack_fc(ispsoftc_t *, na_fcentry_t *, na_fcentry_t *);
+extern void
+isp_put_notify_ack_fc_e(ispsoftc_t *, na_fcentry_e_t *, na_fcentry_e_t *);
+extern void isp_put_notify_ack_24xx(ispsoftc_t *, na_fcentry_24xx_t *,
+ na_fcentry_24xx_t *);
+extern void
+isp_get_notify_ack_fc(ispsoftc_t *, na_fcentry_t *, na_fcentry_t *);
+extern void
+isp_get_notify_ack_fc_e(ispsoftc_t *, na_fcentry_e_t *, na_fcentry_e_t *);
+extern void isp_get_notify_ack_24xx(ispsoftc_t *, na_fcentry_24xx_t *,
+ na_fcentry_24xx_t *);
+extern void
+isp_get_abts(ispsoftc_t *, abts_t *, abts_t *);
+extern void
+isp_put_abts_rsp(ispsoftc_t *, abts_rsp_t *, abts_rsp_t *);
+extern void
+isp_get_abts_rsp(ispsoftc_t *, abts_rsp_t *, abts_rsp_t *);
+#endif /* ISP_TARGET_MODE */
#endif /* _ISP_LIBRARY_H */
diff --git a/sys/dev/ic/isp_openbsd.c b/sys/dev/ic/isp_openbsd.c
index ef65d585b58..1f979ebba07 100644
--- a/sys/dev/ic/isp_openbsd.c
+++ b/sys/dev/ic/isp_openbsd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isp_openbsd.c,v 1.35 2009/02/16 21:19:06 miod Exp $ */
+/* $OpenBSD: isp_openbsd.c,v 1.36 2009/06/24 11:00:53 krw Exp $ */
/*
* Platform (OpenBSD) dependent common attachment code for QLogic adapters.
*
@@ -40,8 +40,6 @@
* San Francisco, CA, 94131
*/
-/* expand expensive inline functions here. */
-#define EXPENSIVE_INLINE
#include <dev/ic/isp_openbsd.h>
/*
@@ -66,18 +64,28 @@ static void ispminphys(struct buf *, struct scsi_link *);
static int32_t ispcmd_slow(XS_T *);
static int32_t ispcmd(XS_T *);
-static struct scsi_device isp_dev = { NULL, NULL, NULL, NULL };
+struct scsi_device isp_dev = { NULL, NULL, NULL, NULL };
-static int isp_polled_cmd (struct ispsoftc *, XS_T *);
-static void isp_wdog (void *);
-static void isp_requeue(void *);
-static void isp_trestart(void *);
-static void isp_restart(struct ispsoftc *);
+int isp_polled_cmd (struct ispsoftc *, XS_T *);
+void isp_wdog (void *);
+void isp_make_here(ispsoftc_t *, int);
+void isp_make_gone(ispsoftc_t *, int);
+void isp_requeue(void *);
+void isp_trestart(void *);
+void isp_restart(struct ispsoftc *);
+void isp_add2_blocked_queue(struct ispsoftc *isp, XS_T *xs);
+int isp_mstohz(int ms);
struct cfdriver isp_cd = {
NULL, "isp", DV_DULL
};
+static const char *roles[4] = {
+ "(none)", "Target", "Initiator", "Target/Initiator"
+};
+static const char prom3[] =
+ "PortID 0x%06x Departed from Target %u because of %s";
+#define isp_change_is_bad 0
/*
* Complete attachment of hardware, include subdevices.
@@ -104,8 +112,7 @@ isp_attach(struct ispsoftc *isp)
isp->isp_osinfo._adapter.scsi_cmd = ispcmd_slow;
if (IS_FC(isp)) {
lptr->adapter_buswidth = MAX_FC_TARG;
- /* We can set max lun width here */
- /* loopid set below */
+ lptr->adapter_target = MAX_FC_TARG; /* i.e. ignore. */
} else {
sdparam *sdp = isp->isp_param;
lptr->adapter_buswidth = MAX_TARGETS;
@@ -147,17 +154,10 @@ isp_attach(struct ispsoftc *isp)
*/
delay(4 * 1000000);
} else {
- fcparam *fcp = isp->isp_param;
- int defid = MAX_FC_TARG;
delay(2 * 1000000);
ISP_LOCK(isp);
isp_fc_runstate(isp, 10 * 1000000);
- if (fcp->isp_fwstate == FW_READY &&
- fcp->isp_loopstate >= LOOP_PDB_RCVD) {
- defid = fcp->isp_loopid;
- }
ISP_UNLOCK(isp);
- lptr->adapter_target = defid;
}
bzero(&saa, sizeof(saa));
@@ -195,7 +195,7 @@ ispminphys(struct buf *bp, struct scsi_link *sl)
minphys(bp);
}
-static int32_t
+int32_t
ispcmd_slow(XS_T *xs)
{
sdparam *sdp;
@@ -273,9 +273,7 @@ ispcmd_slow(XS_T *xs)
return (ispcmd(xs));
}
-static INLINE void isp_add2_blocked_queue(struct ispsoftc *, XS_T *);
-
-static INLINE void
+void
isp_add2_blocked_queue(struct ispsoftc *isp, XS_T *xs)
{
if (isp->isp_osinfo.wqf != NULL) {
@@ -287,7 +285,7 @@ isp_add2_blocked_queue(struct ispsoftc *isp, XS_T *xs)
xs->free_list.le_next = NULL;
}
-static int32_t
+int32_t
ispcmd(XS_T *xs)
{
struct ispsoftc *isp;
@@ -308,16 +306,16 @@ ispcmd(XS_T *xs)
ISP_LOCK(isp);
if (isp->isp_state < ISP_RUNSTATE) {
- DISABLE_INTS(isp);
+ ISP_DISABLE_INTS(isp);
isp_init(isp);
if (isp->isp_state != ISP_INITSTATE) {
- ENABLE_INTS(isp);
+ ISP_ENABLE_INTS(isp);
ISP_UNLOCK(isp);
XS_SETERR(xs, HBA_BOTCH);
return (CMD_COMPLETE);
}
isp->isp_state = ISP_RUNSTATE;
- ENABLE_INTS(isp);
+ ISP_ENABLE_INTS(isp);
}
/*
@@ -385,7 +383,7 @@ ispcmd(XS_T *xs)
return (result);
}
-static int
+int
isp_polled_cmd(struct ispsoftc *isp, XS_T *xs)
{
int result;
@@ -418,7 +416,8 @@ isp_polled_cmd(struct ispsoftc *isp, XS_T *xs)
infinite = 1;
while (mswait || infinite) {
- u_int16_t isr, sema, mbox;
+ u_int32_t isr;
+ u_int16_t sema, mbox;
if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
isp_intr(isp, isr, sema, mbox);
if (XS_CMD_DONE_P(xs)) {
@@ -470,7 +469,7 @@ isp_done(XS_T *xs)
}
}
-static void
+void
isp_wdog(void *arg)
{
XS_T *xs = arg;
@@ -485,7 +484,8 @@ isp_wdog(void *arg)
ISP_LOCK(isp);
handle = isp_find_handle(isp, xs);
if (handle) {
- u_int16_t isr, sema, mbox;
+ u_int32_t isr;
+ u_int16_t sema, mbox;
if (XS_CMD_DONE_P(xs)) {
isp_prt(isp, ISP_LOGDEBUG1,
@@ -534,7 +534,7 @@ isp_wdog(void *arg)
XS_CMD_S_CLEAR(xs);
isp_done(xs);
} else {
- u_int16_t nxti, optr;
+ u_int32_t optr, nxti;
ispreq_t local, *mp = &local, *qe;
isp_prt(isp, ISP_LOGWARN,
@@ -551,7 +551,7 @@ isp_wdog(void *arg)
MEMZERO((void *) mp, sizeof (*mp));
mp->req_header.rqs_entry_count = 1;
mp->req_header.rqs_entry_type = RQSTYPE_MARKER;
- mp->req_modifier = SYNC_ALL;
+ mp->req_cdblen = SYNC_ALL;
mp->req_target = XS_CHANNEL(xs) << 7;
isp_put_request(isp, mp, qe);
ISP_ADD_REQUEST(isp, nxti);
@@ -562,6 +562,18 @@ isp_wdog(void *arg)
ISP_UNLOCK(isp);
}
+void
+isp_make_here(ispsoftc_t *isp, int tgt)
+{
+ isp_prt(isp, ISP_LOGINFO, "target %d has arrived", tgt);
+}
+
+void
+isp_make_gone(ispsoftc_t *isp, int tgt)
+{
+ isp_prt(isp, ISP_LOGINFO, "target %d has departed", tgt);
+}
+
/*
* Free any associated resources prior to decommissioning and
* set the card to a known state (so it doesn't wake up and kick
@@ -576,7 +588,7 @@ isp_uninit(struct ispsoftc *isp)
/*
* Leave with interrupts disabled.
*/
- DISABLE_INTS(isp);
+ ISP_DISABLE_INTS(isp);
ISP_UNLOCK(isp);
}
@@ -584,7 +596,7 @@ isp_uninit(struct ispsoftc *isp)
/*
* Restart function for a command to be requeued later.
*/
-static void
+void
isp_requeue(void *arg)
{
int r;
@@ -629,7 +641,7 @@ isp_requeue(void *arg)
* Restart function after a LOOP UP event or a command completing,
* sometimes done as a timeout for some hysteresis.
*/
-static void
+void
isp_trestart(void *arg)
{
struct ispsoftc *isp = arg;
@@ -657,7 +669,7 @@ isp_trestart(void *arg)
}
}
-static void
+void
isp_restart(struct ispsoftc *isp)
{
struct scsi_xfer *list;
@@ -683,6 +695,14 @@ int
isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
{
int bus, tgt;
+ char *msg = NULL;
+ static const char prom[] =
+ "PortID 0x%06x handle 0x%x role %s %s\n"
+ " WWNN 0x%08x%08x WWPN 0x%08x%08x";
+ static const char prom2[] =
+ "PortID 0x%06x handle 0x%x role %s %s tgt %u\n"
+ " WWNN 0x%08x%08x WWPN 0x%08x%08x";
+ fcportdb_t *lp;
switch (cmd) {
case ISPASYNC_NEW_TGT_PARAMS:
@@ -779,147 +799,157 @@ isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
timeout_add(&isp->isp_osinfo.rqt, 1);
isp_prt(isp, ISP_LOGINFO, "Loop UP");
break;
- case ISPASYNC_PROMENADE:
- if (IS_FC(isp) && isp->isp_dblev) {
- const char *fmt = "Target %d (Loop 0x%x) Port ID 0x%x "
- "role %s %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x";
- const static char *roles[4] = {
- "No", "Target", "Initiator", "Target/Initiator"
- };
- fcparam *fcp = isp->isp_param;
- int tgt = *((int *) arg);
- struct lportdb *lp = &fcp->portdb[tgt];
-
- isp_prt(isp, ISP_LOGINFO, fmt, tgt, lp->loopid, lp->portid,
- roles[lp->roles & 0x3],
- (lp->valid)? "Arrived" : "Departed",
- (u_int32_t) (lp->port_wwn >> 32),
- (u_int32_t) (lp->port_wwn & 0xffffffffLL),
- (u_int32_t) (lp->node_wwn >> 32),
- (u_int32_t) (lp->node_wwn & 0xffffffffLL));
- break;
- }
- case ISPASYNC_CHANGE_NOTIFY:
- if (arg == (void *) 1) {
- isp_prt(isp, ISP_LOGINFO,
- "Name Server Database Changed");
+ case ISPASYNC_DEV_ARRIVED:
+ lp = arg;
+ lp->reserved = 0;
+ if ((isp->isp_role & ISP_ROLE_INITIATOR) &&
+ (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) {
+ int dbidx = lp - FCPARAM(isp)->portdb;
+ int i;
+
+ for (i = 0; i < MAX_FC_TARG; i++) {
+ if (i >= FL_ID && i <= SNS_ID) {
+ continue;
+ }
+ if (FCPARAM(isp)->isp_ini_map[i] == 0) {
+ break;
+ }
+ }
+ if (i < MAX_FC_TARG) {
+ FCPARAM(isp)->isp_ini_map[i] = dbidx + 1;
+ lp->ini_map_idx = i + 1;
+ printf("ISPASYNC_DEV_ARRIVED: %d/%d\n",
+ i, FCPARAM(isp)->isp_ini_map[i]);
+ } else {
+ isp_prt(isp, ISP_LOGWARN, "out of target ids");
+ isp_dump_portdb(isp);
+ }
+ }
+ if (lp->ini_map_idx) {
+ tgt = lp->ini_map_idx - 1;
+ isp_prt(isp, ISP_LOGCONFIG, prom2,
+ lp->portid, lp->handle,
+ roles[lp->roles], "arrived at", tgt,
+ (uint32_t) (lp->node_wwn >> 32),
+ (uint32_t) lp->node_wwn,
+ (uint32_t) (lp->port_wwn >> 32),
+ (uint32_t) lp->port_wwn);
+ isp_make_here(isp, tgt);
} else {
- isp_prt(isp, ISP_LOGINFO,
- "Name Server Database Changed");
+ isp_prt(isp, ISP_LOGCONFIG, prom,
+ lp->portid, lp->handle,
+ roles[lp->roles], "arrived",
+ (uint32_t) (lp->node_wwn >> 32),
+ (uint32_t) lp->node_wwn,
+ (uint32_t) (lp->port_wwn >> 32),
+ (uint32_t) lp->port_wwn);
}
break;
- case ISPASYNC_FABRIC_DEV:
- {
- int target, base, lim;
- fcparam *fcp = isp->isp_param;
- struct lportdb *lp = NULL;
- struct lportdb *clp = (struct lportdb *) arg;
- char *pt;
-
- switch (clp->port_type) {
- case 1:
- pt = " N_Port";
- break;
- case 2:
- pt = " NL_Port";
- break;
- case 3:
- pt = "F/NL_Port";
- break;
- case 0x7f:
- pt = " Nx_Port";
- break;
- case 0x81:
- pt = " F_port";
- break;
- case 0x82:
- pt = " FL_Port";
- break;
- case 0x84:
- pt = " E_port";
- break;
- default:
- pt = " ";
- break;
- }
-
- isp_prt(isp, ISP_LOGINFO,
- "%s Fabric Device @ PortID 0x%x", pt, clp->portid);
-
- /*
- * If we don't have an initiator role we bail.
- *
- * We just use ISPASYNC_FABRIC_DEV for announcement purposes.
- */
-
- if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
- break;
- }
-
- /*
- * Is this entry for us? If so, we bail.
- */
-
- if (fcp->isp_portid == clp->portid) {
- break;
- }
-
- /*
- * Else, the default policy is to find room for it in
- * our local port database. Later, when we execute
- * the call to isp_pdb_sync either this newly arrived
- * or already logged in device will be (re)announced.
- */
-
- if (fcp->isp_topo == TOPO_FL_PORT)
- base = FC_SNS_ID+1;
- else
- base = 0;
-
- if (fcp->isp_topo == TOPO_N_PORT)
- lim = 1;
- else
- lim = MAX_FC_TARG;
-
- /*
- * Is it already in our list?
- */
- for (target = base; target < lim; target++) {
- if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
- continue;
+ case ISPASYNC_DEV_CHANGED:
+ lp = arg;
+ if (isp_change_is_bad) {
+ lp->state = FC_PORTDB_STATE_NIL;
+ if (lp->ini_map_idx) {
+ tgt = lp->ini_map_idx - 1;
+ FCPARAM(isp)->isp_ini_map[tgt] = 0;
+ printf("ISPASYNC_DEV_CHANGED: %d/%d\n",
+ tgt, FCPARAM(isp)->isp_ini_map[tgt]);
+ lp->ini_map_idx = 0;
+ isp_prt(isp, ISP_LOGCONFIG, prom3,
+ lp->portid, tgt, "change is bad");
+ isp_make_gone(isp, tgt);
+ } else {
+ isp_prt(isp, ISP_LOGCONFIG, prom,
+ lp->portid, lp->handle,
+ roles[lp->roles],
+ "changed and departed",
+ (uint32_t) (lp->node_wwn >> 32),
+ (uint32_t) lp->node_wwn,
+ (uint32_t) (lp->port_wwn >> 32),
+ (uint32_t) lp->port_wwn);
}
- lp = &fcp->portdb[target];
- if (lp->port_wwn == clp->port_wwn &&
- lp->node_wwn == clp->node_wwn) {
- lp->fabric_dev = 1;
- break;
+ } else {
+ lp->portid = lp->new_portid;
+ lp->roles = lp->new_roles;
+ if (lp->ini_map_idx) {
+ int t = lp->ini_map_idx - 1;
+ FCPARAM(isp)->isp_ini_map[t] =
+ (lp - FCPARAM(isp)->portdb) + 1;
+ printf("ISPASYNC_DEV_CHANGED(2): %d/%d\n",
+ t, FCPARAM(isp)->isp_ini_map[t]);
+ tgt = lp->ini_map_idx - 1;
+ isp_prt(isp, ISP_LOGCONFIG, prom2,
+ lp->portid, lp->handle,
+ roles[lp->roles], "changed at", tgt,
+ (uint32_t) (lp->node_wwn >> 32),
+ (uint32_t) lp->node_wwn,
+ (uint32_t) (lp->port_wwn >> 32),
+ (uint32_t) lp->port_wwn);
+ } else {
+ isp_prt(isp, ISP_LOGCONFIG, prom,
+ lp->portid, lp->handle,
+ roles[lp->roles], "changed",
+ (uint32_t) (lp->node_wwn >> 32),
+ (uint32_t) lp->node_wwn,
+ (uint32_t) (lp->port_wwn >> 32),
+ (uint32_t) lp->port_wwn);
}
}
- if (target < lim) {
- break;
+ break;
+ case ISPASYNC_DEV_STAYED:
+ lp = arg;
+ if (lp->ini_map_idx) {
+ tgt = lp->ini_map_idx - 1;
+ isp_prt(isp, ISP_LOGCONFIG, prom2,
+ lp->portid, lp->handle,
+ roles[lp->roles], "stayed at", tgt,
+ (uint32_t) (lp->node_wwn >> 32),
+ (uint32_t) lp->node_wwn,
+ (uint32_t) (lp->port_wwn >> 32),
+ (uint32_t) lp->port_wwn);
+ } else {
+ isp_prt(isp, ISP_LOGCONFIG, prom,
+ lp->portid, lp->handle,
+ roles[lp->roles], "stayed",
+ (uint32_t) (lp->node_wwn >> 32),
+ (uint32_t) lp->node_wwn,
+ (uint32_t) (lp->port_wwn >> 32),
+ (uint32_t) lp->port_wwn);
}
- for (target = base; target < lim; target++) {
- if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
- continue;
- }
- lp = &fcp->portdb[target];
- if (lp->port_wwn == 0) {
- break;
- }
+ break;
+ case ISPASYNC_DEV_GONE:
+ lp = arg;
+ if (lp->ini_map_idx && lp->reserved == 0) {
+ lp->reserved = 1;
+ lp->state = FC_PORTDB_STATE_ZOMBIE;
+ tgt = lp->ini_map_idx - 1;
+ isp_prt(isp, ISP_LOGCONFIG, prom2,
+ lp->portid, lp->handle,
+ roles[lp->roles], "gone zombie at", tgt,
+ (uint32_t) (lp->node_wwn >> 32),
+ (uint32_t) lp->node_wwn,
+ (uint32_t) (lp->port_wwn >> 32),
+ (uint32_t) lp->port_wwn);
+ } else if (lp->reserved == 0) {
+ isp_prt(isp, ISP_LOGCONFIG, prom,
+ lp->portid, lp->handle,
+ roles[lp->roles], "departed",
+ (uint32_t) (lp->node_wwn >> 32),
+ (uint32_t) lp->node_wwn,
+ (uint32_t) (lp->port_wwn >> 32),
+ (uint32_t) lp->port_wwn);
}
- if (target == lim) {
- isp_prt(isp, ISP_LOGWARN,
- "out of space for fabric devices");
- break;
+ break;
+ case ISPASYNC_CHANGE_NOTIFY:
+ if (arg == ISPASYNC_CHANGE_PDB) {
+ msg = "Port Database Changed";
+ } else if (arg == ISPASYNC_CHANGE_SNS) {
+ msg = "Name Server Database Changed";
+ } else {
+ msg = "Other Change Notify";
}
- lp->port_type = clp->port_type;
- lp->fc4_type = clp->fc4_type;
- lp->node_wwn = clp->node_wwn;
- lp->port_wwn = clp->port_wwn;
- lp->portid = clp->portid;
- lp->fabric_dev = 1;
+ isp_prt(isp, ISP_LOGINFO, msg);
break;
- }
case ISPASYNC_FW_CRASH:
{
u_int16_t mbox1, mbox6;
@@ -961,3 +991,135 @@ isp_prt(struct ispsoftc *isp, int level, const char *fmt, ...)
va_end(ap);
printf("\n");
}
+
+int
+isp_mbox_acquire(ispsoftc_t *isp)
+{
+ if (isp->isp_osinfo.mboxbsy) {
+ return (1);
+ } else {
+ isp->isp_osinfo.mboxcmd_done = 0;
+ isp->isp_osinfo.mboxbsy = 1;
+ return (0);
+ }
+}
+
+void
+isp_lock(struct ispsoftc *isp)
+{
+ int s = splbio();
+ if (isp->isp_osinfo.islocked++ == 0) {
+ isp->isp_osinfo.splsaved = s;
+ } else {
+ splx(s);
+ }
+}
+
+void
+isp_unlock(struct ispsoftc *isp)
+{
+ if (isp->isp_osinfo.islocked-- <= 1) {
+ isp->isp_osinfo.islocked = 0;
+ splx(isp->isp_osinfo.splsaved);
+ }
+}
+
+u_int64_t
+isp_nanotime_sub(struct timespec *b, struct timespec *a)
+{
+ struct timespec x;
+ u_int64_t elapsed;
+ timespecsub(b, a, &x);
+ elapsed = GET_NANOSEC(&x);
+ if (elapsed == 0)
+ elapsed++;
+ return (elapsed);
+}
+
+void
+isp_mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
+{
+ unsigned int usecs = mbp->timeout;
+ unsigned int max, olim, ilim;
+
+ if (usecs == 0) {
+ usecs = MBCMD_DEFAULT_TIMEOUT;
+ }
+ max = isp->isp_mbxwrk0 + 1;
+
+ if (isp->isp_osinfo.mbox_sleep_ok) {
+ unsigned int ms = (usecs + 999) / 1000;
+
+ isp->isp_osinfo.mbox_sleep_ok = 0;
+ isp->isp_osinfo.mbox_sleeping = 1;
+ for (olim = 0; olim < max; olim++) {
+ tsleep(&isp->isp_mbxworkp, PRIBIO, "ispmbx_sleep",
+ isp_mstohz(ms));
+ if (isp->isp_osinfo.mboxcmd_done) {
+ break;
+ }
+ }
+ isp->isp_osinfo.mbox_sleep_ok = 1;
+ isp->isp_osinfo.mbox_sleeping = 0;
+ } else {
+ for (olim = 0; olim < max; olim++) {
+ for (ilim = 0; ilim < usecs; ilim += 100) {
+ uint32_t isr;
+ uint16_t sema, mbox;
+ if (isp->isp_osinfo.mboxcmd_done) {
+ break;
+ }
+ if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
+ isp_intr(isp, isr, sema, mbox);
+ if (isp->isp_osinfo.mboxcmd_done) {
+ break;
+ }
+ }
+ USEC_DELAY(100);
+ }
+ if (isp->isp_osinfo.mboxcmd_done) {
+ break;
+ }
+ }
+ }
+ if (isp->isp_osinfo.mboxcmd_done == 0) {
+ isp_prt(isp, ISP_LOGWARN,
+ "%s Mailbox Command (0x%x) Timeout (%uus)",
+ isp->isp_osinfo.mbox_sleep_ok? "Interrupting" : "Polled",
+ isp->isp_lastmbxcmd, usecs);
+ mbp->param[0] = MBOX_TIMEOUT;
+ isp->isp_osinfo.mboxcmd_done = 1;
+ }
+}
+
+void
+isp_mbox_notify_done(ispsoftc_t *isp)
+{
+ if (isp->isp_osinfo.mbox_sleeping) {
+ wakeup(&isp->isp_mbxworkp);
+ }
+ isp->isp_osinfo.mboxcmd_done = 1;
+}
+
+void
+isp_mbox_release(ispsoftc_t *isp)
+{
+ isp->isp_osinfo.mboxbsy = 0;
+}
+
+int
+isp_mstohz(int ms)
+{
+ int hz;
+ struct timeval t;
+ t.tv_sec = ms / 1000;
+ t.tv_usec = (ms % 1000) * 1000;
+ hz = tvtohz(&t);
+ if (hz < 0) {
+ hz = 0x7fffffff;
+ }
+ if (hz == 0) {
+ hz = 1;
+ }
+ return (hz);
+}
diff --git a/sys/dev/ic/isp_openbsd.h b/sys/dev/ic/isp_openbsd.h
index 19531cffcd2..01d3d6eccb7 100644
--- a/sys/dev/ic/isp_openbsd.h
+++ b/sys/dev/ic/isp_openbsd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: isp_openbsd.h,v 1.30 2008/11/17 00:22:13 krw Exp $ */
+/* $OpenBSD: isp_openbsd.h,v 1.31 2009/06/24 11:00:53 krw Exp $ */
/*
* OpenBSD Specific definitions for the QLogic ISP Host Adapter
*/
@@ -62,8 +62,8 @@
#define ISP_SBUS_SUPPORTED 0
#endif
-#define ISP_PLATFORM_VERSION_MAJOR 2
-#define ISP_PLATFORM_VERSION_MINOR 1
+#define ISP_PLATFORM_VERSION_MAJOR 5
+#define ISP_PLATFORM_VERSION_MINOR 9
struct isposinfo {
struct device _dev;
@@ -75,20 +75,29 @@ struct isposinfo {
u_int32_t islocked;
u_int32_t onintstack;
#if !(defined(__sparc__) && !defined(__sparcv9__))
+ bus_space_tag_t bus_tag;
+ bus_space_handle_t bus_handle;
bus_dma_tag_t dmatag;
- bus_dmamap_t rqdmap;
- bus_dmamap_t rsdmap;
- bus_dmamap_t scdmap; /* FC only */
+ bus_dmamap_t cdmap;
#define isp_dmatag isp_osinfo.dmatag
-#define isp_rqdmap isp_osinfo.rqdmap
-#define isp_rsdmap isp_osinfo.rsdmap
-#define isp_scdmap isp_osinfo.scdmap
+#define isp_cdmap isp_osinfo.cdmap
+#define isp_bus_tag isp_osinfo.bus_tag
+#define isp_bus_handle isp_osinfo.bus_handle
#endif
- unsigned int : 28,
-
- rtpend : 1,
+ uint32_t : 5,
+ simqfrozen : 3,
+ hysteresis : 8,
+ gdt_running : 1,
+ ldt_running : 1,
+ disabled : 1,
+ fcbsy : 1,
+ mbox_sleeping : 1,
+ mbox_sleep_ok : 1,
+ mboxcmd_done : 1,
+ mboxbsy : 1,
no_mbox_ints : 1,
- blocked : 2;
+ blocked : 2,
+ rtpend : 1;
int _iid;
union {
u_int64_t _wwn;
@@ -111,30 +120,20 @@ struct isposinfo {
* Required Macros/Defines
*/
-#define INLINE __inline
-
-/* We don't want expensive inline functions. */
-#define EXP_INLINE
-
-#define ISP2100_SCRLEN 0x800
+#define ISP2100_SCRLEN 0x1000
#define MEMZERO bzero
#define MEMCPY(dst, src, amt) bcopy((src), (dst), (amt))
#define SNPRINTF snprintf
-#define USEC_DELAY(x) delay(x)
-#define USEC_SLEEP(isp, x) \
- if (!MUST_POLL(isp)) \
- ISP_UNLOCK(isp); \
- delay(x); \
- if (!MUST_POLL(isp)) \
- ISP_LOCK(isp)
+#define USEC_DELAY delay
+#define USEC_SLEEP(isp, x) delay(x)
#define NANOTIME_T struct timespec
#define GET_NANOTIME nanotime
#define GET_NANOSEC(x) (((x)->tv_sec * 1000000000 + (x)->tv_nsec))
#define NANOTIME_SUB isp_nanotime_sub
-#define MAXISPREQUEST(isp) 256
+#define MAXISPREQUEST(isp) ((IS_FC(isp) || IS_ULTRA2(isp))? 1024 : 256)
#if !(defined(__sparc__) && !defined(__sparcv9__))
#define MEMORYBARRIER(isp, type, offset, size) \
@@ -142,32 +141,37 @@ switch (type) { \
case SYNC_REQUEST: \
{ \
off_t off = (off_t) offset * QENTRY_LEN; \
- bus_dmamap_sync(isp->isp_dmatag, isp->isp_rqdmap, \
+ bus_dmamap_sync(isp->isp_dmatag, isp->isp_cdmap, \
off, size, BUS_DMASYNC_PREWRITE); \
break; \
} \
case SYNC_RESULT: \
{ \
- off_t off = (off_t) offset * QENTRY_LEN; \
- bus_dmamap_sync(isp->isp_dmatag, isp->isp_rsdmap, \
+ off_t off = (off_t) offset * QENTRY_LEN + \
+ ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); \
+ bus_dmamap_sync(isp->isp_dmatag, isp->isp_cdmap, \
off, size, BUS_DMASYNC_POSTREAD); \
break; \
} \
case SYNC_SFORDEV: \
{ \
off_t off = (off_t) offset; \
- bus_dmamap_sync(isp->isp_dmatag, isp->isp_scdmap, \
+ bus_dmamap_sync(isp->isp_dmatag, isp->isp_cdmap, \
off, size, BUS_DMASYNC_PREWRITE); \
break; \
} \
case SYNC_SFORCPU: \
{ \
off_t off = (off_t) offset; \
- bus_dmamap_sync(isp->isp_dmatag, isp->isp_scdmap, \
+ bus_dmamap_sync(isp->isp_dmatag, isp->isp_cdmap, \
off, size, BUS_DMASYNC_POSTREAD); \
break; \
} \
case SYNC_REG: \
+ bus_space_barrier(isp->isp_bus_tag, \
+ isp->isp_bus_handle, offset, size, \
+ BUS_SPACE_BARRIER_READ); \
+ break; \
default: \
break; \
}
@@ -175,20 +179,18 @@ default: \
#define MEMORYBARRIER(isp, type, offset, size)
#endif
-#define MBOX_ACQUIRE(isp)
-#define MBOX_WAIT_COMPLETE isp_wait_complete
+#define MBOX_ACQUIRE isp_mbox_acquire
+#define MBOX_WAIT_COMPLETE isp_mbox_wait_complete
+#define MBOX_NOTIFY_COMPLETE isp_mbox_notify_done
+#define MBOX_RELEASE isp_mbox_release
-#define MBOX_NOTIFY_COMPLETE(isp) \
- if (isp->isp_osinfo.mboxwaiting) { \
- isp->isp_osinfo.mboxwaiting = 0; \
- wakeup(&isp->isp_osinfo.mboxwaiting); \
- } \
- isp->isp_mboxbsy = 0
-
-#define MBOX_RELEASE(isp)
-
-#define FC_SCRATCH_ACQUIRE(isp)
-#define FC_SCRATCH_RELEASE(isp)
+#define FC_SCRATCH_ACQUIRE(isp) \
+ if (isp->isp_osinfo.fcbsy) { \
+ isp_prt(isp, ISP_LOGWARN, \
+ "FC scratch area busy (line %d)!", __LINE__); \
+ } else \
+ isp->isp_osinfo.fcbsy = 1
+#define FC_SCRATCH_RELEASE(isp) isp->isp_osinfo.fcbsy = 0
#ifndef SCSI_GOOD
#define SCSI_GOOD 0x0
@@ -204,6 +206,11 @@ default: \
#endif
#define XS_T struct scsi_xfer
+#if !(defined(__sparc__) && !defined(__sparcv9__))
+#define XS_DMA_ADDR_T bus_addr_t
+#else
+#define XS_DMA_ADDR_T u_int32_t
+#endif
#define XS_CHANNEL(xs) (((xs)->sc_link->flags & SDEV_2NDBUS)? 1 : 0)
#define XS_ISP(xs) (xs)->sc_link->adapter_softc
#define XS_LUN(xs) ((int) (xs)->sc_link->lun)
@@ -238,12 +245,11 @@ default: \
#define XS_INITERR(xs) (xs)->error = 0, XS_CMD_S_CLEAR(xs)
-#define XS_SAVE_SENSE(xs, sp) \
+#define XS_SAVE_SENSE(xs, sp, len) \
if (xs->error == XS_NOERROR) { \
xs->error = XS_SENSE; \
} \
- bcopy(sp->req_sense_data, &(xs)->sense, \
- imin(XS_SNSLEN(xs), sp->req_sense_len))
+ bcopy(sp, &(xs)->sense, imin(XS_SNSLEN(xs), len))
#define XS_SET_STATE_STAT(a, b, c)
@@ -251,8 +257,8 @@ default: \
#define DEFAULT_LOOPID(x) 107
#define DEFAULT_NODEWWN(isp) (isp)->isp_osinfo.un._wwn
#define DEFAULT_PORTWWN(isp) (isp)->isp_osinfo.un._wwn
-#define ISP_NODEWWN(isp) FCPARAM(isp)->isp_nodewwn
-#define ISP_PORTWWN(isp) FCPARAM(isp)->isp_portwwn
+#define ISP_NODEWWN(isp) FCPARAM(isp)->isp_wwnn_nvram
+#define ISP_PORTWWN(isp) FCPARAM(isp)->isp_wwpn_nvram
#if BYTE_ORDER == BIG_ENDIAN
#ifdef ISP_SBUS_SUPPORTED
@@ -278,6 +284,16 @@ default: \
#define ISP_IOXGET_32(isp, s, d) d = swap32(*((u_int32_t *)s))
#endif
#define ISP_SWIZZLE_NVRAM_WORD(isp, rp) *rp = swap16(*rp)
+#define ISP_SWIZZLE_NVRAM_LONG(isp, rp) *rp = swap32(*rp)
+
+#define ISP_IOZGET_8(isp, s, d) d = (*((u_int8_t *)s))
+#define ISP_IOZGET_16(isp, s, d) d = (*((u_int16_t *)s))
+#define ISP_IOZGET_32(isp, s, d) d = (*((u_int32_t *)s))
+#define ISP_IOZPUT_8(isp, s, d) *(d) = s
+#define ISP_IOZPUT_16(isp, s, d) *(d) = s
+#define ISP_IOZPUT_32(isp, s, d) *(d) = s
+
+
#else
#define ISP_IOXPUT_8(isp, s, d) *(d) = s
#define ISP_IOXPUT_16(isp, s, d) *(d) = s
@@ -286,8 +302,20 @@ default: \
#define ISP_IOXGET_16(isp, s, d) d = *(s)
#define ISP_IOXGET_32(isp, s, d) d = *(s)
#define ISP_SWIZZLE_NVRAM_WORD(isp, rp)
+#define ISP_SWIZZLE_NVRAM_LONG(isp, rp)
+
+#define ISP_IOZPUT_8(isp, s, d) *(d) = s
+#define ISP_IOZPUT_16(isp, s, d) *(d) = swap16(s)
+#define ISP_IOZPUT_32(isp, s, d) *(d) = swap32(s)
+
+#define ISP_IOZGET_8(isp, s, d) d = (*((u_int8_t *)(s)))
+#define ISP_IOZGET_16(isp, s, d) d = swap16(*((u_int16_t *)(s)))
+#define ISP_IOZGET_32(isp, s, d) d = swap32(*((u_int32_t *)(s)))
#endif
+#define ISP_SWAP16(isp, s) swap16(s)
+#define ISP_SWAP32(isp, s) swap32(s)
+
/*
* Includes of common header files
*/
@@ -308,11 +336,14 @@ default: \
void isp_attach(struct ispsoftc *);
void isp_uninit(struct ispsoftc *);
-static INLINE void isp_lock(struct ispsoftc *);
-static INLINE void isp_unlock(struct ispsoftc *);
-static INLINE u_int64_t
-isp_nanotime_sub(struct timespec *, struct timespec *);
-static void isp_wait_complete(struct ispsoftc *);
+void isp_lock(struct ispsoftc *);
+void isp_unlock(struct ispsoftc *);
+void isp_prt(struct ispsoftc *, int level, const char *, ...);
+u_int64_t isp_nanotime_sub(struct timespec *, struct timespec *);
+int isp_mbox_acquire(ispsoftc_t *);
+void isp_mbox_wait_complete(ispsoftc_t *, mbreg_t *);
+void isp_mbox_notify_done(ispsoftc_t *);
+void isp_mbox_release(ispsoftc_t *);
/*
* Driver wide data...
@@ -345,88 +376,6 @@ static void isp_wait_complete(struct ispsoftc *);
#define XS_CMD_S_CLEAR(xs) (xs)->flags &= ~XS_PSTS_ALL
-/*
- * Platform specific 'INLINE' or support functions
- */
-static INLINE void
-isp_lock(struct ispsoftc *isp)
-{
- int s = splbio();
- if (isp->isp_osinfo.islocked++ == 0) {
- isp->isp_osinfo.splsaved = s;
- } else {
- splx(s);
- }
-}
-
-static INLINE void
-isp_unlock(struct ispsoftc *isp)
-{
- if (isp->isp_osinfo.islocked-- <= 1) {
- isp->isp_osinfo.islocked = 0;
- splx(isp->isp_osinfo.splsaved);
- }
-}
-
-static INLINE u_int64_t
-isp_nanotime_sub(struct timespec *b, struct timespec *a)
-{
- struct timespec x;
- u_int64_t elapsed;
- timespecsub(b, a, &x);
- elapsed = GET_NANOSEC(&x);
- if (elapsed == 0)
- elapsed++;
- return (elapsed);
-}
-
-static INLINE void
-isp_wait_complete(struct ispsoftc *isp)
-{
- int delaytime;
- if (isp->isp_mbxwrk0)
- delaytime = 60;
- else
- delaytime = 5;
- if (MUST_POLL(isp)) {
- int usecs = 0;
- delaytime *= 1000000; /* convert to usecs */
- while (usecs < delaytime) {
- u_int16_t isr, sema, mbox;
- if (isp->isp_mboxbsy == 0) {
- break;
- }
- if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
- isp_intr(isp, isr, sema, mbox);
- if (isp->isp_mboxbsy == 0) {
- break;
- }
- }
- USEC_DELAY(500);
- usecs += 500;
- }
- if (isp->isp_mboxbsy != 0) {
- isp_prt(isp, ISP_LOGWARN,
- "Polled Mailbox Command (0x%x) Timeout",
- isp->isp_lastmbxcmd);
- }
- } else {
- int rv = 0;
- isp->isp_osinfo.mboxwaiting = 1;
- while (isp->isp_osinfo.mboxwaiting && rv == 0) {
- rv = tsleep(&isp->isp_osinfo.mboxwaiting,
- PRIBIO, "isp_mboxcmd", delaytime * hz);
- }
- if (rv == EWOULDBLOCK) {
- isp->isp_mboxbsy = 0;
- isp->isp_osinfo.mboxwaiting = 0;
- isp_prt(isp, ISP_LOGWARN,
- "Interrupting Mailbox Command (0x%x) Timeout",
- isp->isp_lastmbxcmd);
- }
- }
-}
-
#include <dev/ic/isp_library.h>
#endif /* _ISP_OPENBSD_H */
diff --git a/sys/dev/ic/isp_stds.h b/sys/dev/ic/isp_stds.h
index be87fc89159..174731ebc45 100644
--- a/sys/dev/ic/isp_stds.h
+++ b/sys/dev/ic/isp_stds.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: isp_stds.h,v 1.1 2008/11/02 03:06:26 krw Exp $ */
+/* $OpenBSD: isp_stds.h,v 1.2 2009/06/24 11:00:53 krw Exp $ */
/* $FreeBSD: src/sys/dev/isp/isp_stds.h,v 1.4 2007/03/10 02:39:54 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
@@ -109,14 +109,14 @@ typedef struct {
typedef struct {
uint8_t ct_revision;
- uint8_t ct_portid[3];
+ uint8_t ct_in_id[3];
uint8_t ct_fcs_type;
uint8_t ct_fcs_subtype;
uint8_t ct_options;
- uint8_t ct_res0;
- uint16_t ct_response;
- uint16_t ct_resid;
- uint8_t ct_res1;
+ uint8_t ct_reserved0;
+ uint16_t ct_cmd_resp;
+ uint16_t ct_bcnt_resid;
+ uint8_t ct_reserved1;
uint8_t ct_reason;
uint8_t ct_explanation;
uint8_t ct_vunique;
diff --git a/sys/dev/ic/isp_target.c b/sys/dev/ic/isp_target.c
index d04983a9188..597b4b1ff96 100644
--- a/sys/dev/ic/isp_target.c
+++ b/sys/dev/ic/isp_target.c
@@ -1,33 +1,33 @@
-/* $OpenBSD: isp_target.c,v 1.15 2008/01/21 20:00:33 sobrado Exp $ */
+/* $OpenBSD: isp_target.c,v 1.16 2009/06/24 11:00:53 krw Exp $ */
+/*-
+ * Copyright (c) 1997-2007 by Matthew Jacob
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
/*
- * Machine and OS Independent Target Mode Code for the QLogic SCSI/FC adapters.
- *
- * Copyright (c) 1999, 2000, 2001 by Matthew Jacob
- * All rights reserved.
- * mjacob@feral.com
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters.
*/
-
/*
* Bug fixes gratefully acknowledged from:
* Oded Kedem <oded@kashya.com>
@@ -40,6 +40,8 @@
#include <dev/ic/isp_netbsd.h>
#endif
#ifdef __FreeBSD__
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/isp/isp_target.c,v 1.45 2007/10/12 06:03:43 kevlo Exp $");
#include <dev/isp/isp_freebsd.h>
#endif
#ifdef __OpenBSD__
@@ -54,19 +56,20 @@ static const char atiocope[] =
"ATIO returned for lun %d because it was in the middle of Bus Device Reset "
"on bus %d";
static const char atior[] =
- "ATIO returned on for lun %d on from IID %d because a Bus Reset occurred "
- "on bus %d";
-
-static void isp_got_msg(struct ispsoftc *, int, in_entry_t *);
-static void isp_got_msg_fc(struct ispsoftc *, int, in_fcentry_t *);
-static void isp_notify_ack(struct ispsoftc *, void *);
-static void isp_handle_atio(struct ispsoftc *, at_entry_t *);
-static void isp_handle_atio2(struct ispsoftc *, at2_entry_t *);
-static void isp_handle_ctio(struct ispsoftc *, ct_entry_t *);
-static void isp_handle_ctio2(struct ispsoftc *, ct2_entry_t *);
+ "ATIO returned on for lun %d on from loopid %d because a Bus Reset "
+ "occurred on bus %d";
+
+static void isp_got_msg(ispsoftc_t *, in_entry_t *);
+static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *);
+static void isp_got_tmf_24xx(ispsoftc_t *, at7_entry_t *);
+static void isp_handle_atio(ispsoftc_t *, at_entry_t *);
+static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *);
+static void isp_handle_ctio(ispsoftc_t *, ct_entry_t *);
+static void isp_handle_ctio2(ispsoftc_t *, ct2_entry_t *);
+static void isp_handle_ctio7(ispsoftc_t *, ct7_entry_t *);
/*
- * The QLogic driver gets an interrupt to look at response queue entries.
+ * The Qlogic driver gets an interrupt to look at response queue entries.
* Some of these are status completions for initiatior mode commands, but
* if target mode is enabled, we get a whole wad of response queue entries
* to be handled here.
@@ -86,7 +89,7 @@ static void isp_handle_ctio2(struct ispsoftc *, ct2_entry_t *);
* be moved and/or status to be sent) and finally finishing with sending
* to the f/w's response queue an ATIO which then completes the handshake
* with the f/w for that command. There's a lot of variations on this theme,
- * including flags you can set in the CTIO for the QLogic 2X00 fibre channel
+ * including flags you can set in the CTIO for the Qlogic 2X00 fibre channel
* cards that 'auto-replenish' the f/w's ATIO count, but this is the basic
* gist of it.
*
@@ -107,39 +110,62 @@ static void isp_handle_ctio2(struct ispsoftc *, ct2_entry_t *);
* has already swizzled it into the platform dependent from canonical form.
*
* Because of the way this driver is designed, unfortunately most of the
- * actual synchronization work has to be done in the platform-specific
- * code - we have no synchronization primitives in the common code.
+ * actual synchronization work has to be done in the platform specific
+ * code- we have no synchroniation primitives in the common code.
*/
int
-isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
+isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
{
- u_int16_t status, seqid;
+ uint16_t status;
+ uint32_t seqid;
union {
at_entry_t *atiop;
at2_entry_t *at2iop;
+ at2e_entry_t *at2eiop;
+ at7_entry_t *at7iop;
ct_entry_t *ctiop;
ct2_entry_t *ct2iop;
+ ct2e_entry_t *ct2eiop;
+ ct7_entry_t *ct7iop;
lun_entry_t *lunenp;
in_entry_t *inotp;
in_fcentry_t *inot_fcp;
+ in_fcentry_e_t *inote_fcp;
+ in_fcentry_24xx_t *inot_24xx;
na_entry_t *nackp;
na_fcentry_t *nack_fcp;
+ na_fcentry_e_t *nacke_fcp;
+ na_fcentry_24xx_t *nack_24xx;
isphdr_t *hp;
+ abts_t *abts;
+ abts_rsp_t *abts_rsp;
+ els_t *els;
void * *vp;
#define atiop unp.atiop
#define at2iop unp.at2iop
+#define at2eiop unp.at2eiop
+#define at7iop unp.at7iop
#define ctiop unp.ctiop
#define ct2iop unp.ct2iop
+#define ct2eiop unp.ct2eiop
+#define ct7iop unp.ct7iop
#define lunenp unp.lunenp
#define inotp unp.inotp
#define inot_fcp unp.inot_fcp
+#define inote_fcp unp.inote_fcp
+#define inot_24xx unp.inot_24xx
#define nackp unp.nackp
#define nack_fcp unp.nack_fcp
+#define nacke_fcp unp.nacke_fcp
+#define nack_24xx unp.nack_24xx
+#define abts unp.abts
+#define abts_rsp unp.abts_rsp
+#define els unp.els
#define hdrp unp.hp
} unp;
- u_int8_t local[QENTRY_LEN];
- int bus, type, rval = 1;
+ uint8_t local[QENTRY_LEN];
+ int bus, type, level, rval = 1;
type = isp_get_response_type(isp, (isphdr_t *)vptr);
unp.vp = vptr;
@@ -148,21 +174,72 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
switch(type) {
case RQSTYPE_ATIO:
- isp_get_atio(isp, atiop, (at_entry_t *) local);
- isp_handle_atio(isp, (at_entry_t *) local);
+ if (IS_24XX(isp)) {
+ int len;
+
+ isp_get_atio7(isp, at7iop, (at7_entry_t *) local);
+ at7iop = (at7_entry_t *) local;
+ /*
+ * Check for and do something with commands whose IULEN
+ * extends past a singel queue entry.
+ */
+ len = at7iop->at_ta_len & 0xfffff;
+ if (len > (QENTRY_LEN - 8)) {
+ len -= (QENTRY_LEN - 8);
+ isp_prt(isp, ISP_LOGINFO,
+ "long IU length (%d) ignored", len);
+ while (len > 0) {
+ *optrp = ISP_NXT_QENTRY(*optrp,
+ RESULT_QUEUE_LEN(isp));
+ len -= QENTRY_LEN;
+ }
+ }
+ /*
+ * Check for a task management function
+ */
+ if (at7iop->at_cmnd.fcp_cmnd_task_management) {
+ isp_got_tmf_24xx(isp, at7iop);
+ break;
+ }
+ /*
+ * Just go straight to outer layer for this one.
+ */
+ (void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
+ } else {
+ isp_get_atio(isp, atiop, (at_entry_t *) local);
+ isp_handle_atio(isp, (at_entry_t *) local);
+ }
break;
+
case RQSTYPE_CTIO:
isp_get_ctio(isp, ctiop, (ct_entry_t *) local);
isp_handle_ctio(isp, (ct_entry_t *) local);
break;
+
case RQSTYPE_ATIO2:
- isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
+ if (FCPARAM(isp)->isp_2klogin) {
+ isp_get_atio2e(isp, at2eiop, (at2e_entry_t *) local);
+ } else {
+ isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
+ }
isp_handle_atio2(isp, (at2_entry_t *) local);
break;
+
+ case RQSTYPE_CTIO3:
case RQSTYPE_CTIO2:
- isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
+ if (FCPARAM(isp)->isp_2klogin) {
+ isp_get_ctio2e(isp, ct2eiop, (ct2e_entry_t *) local);
+ } else {
+ isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
+ }
isp_handle_ctio2(isp, (ct2_entry_t *) local);
break;
+
+ case RQSTYPE_CTIO7:
+ isp_get_ctio7(isp, ct7iop, (ct7_entry_t *) local);
+ isp_handle_ctio7(isp, (ct7_entry_t *) local);
+ break;
+
case RQSTYPE_ENABLE_LUN:
case RQSTYPE_MODIFY_LUN:
isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local);
@@ -178,8 +255,42 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
* (we set this initially in the Enable Lun entry).
*/
bus = 0;
- if (IS_FC(isp)) {
- isp_get_notify_fc(isp, inot_fcp, (in_fcentry_t *)local);
+ if (IS_24XX(isp)) {
+ isp_get_notify_24xx(isp, inot_24xx,
+ (in_fcentry_24xx_t *)local);
+ inot_24xx = (in_fcentry_24xx_t *) local;
+ status = inot_24xx->in_status;
+ seqid = inot_24xx->in_rxid;
+ isp_prt(isp, ISP_LOGTDEBUG0,
+ "Immediate Notify status=0x%x seqid=0x%x",
+ status, seqid);
+ switch (status) {
+ case IN24XX_LIP_RESET:
+ case IN24XX_LINK_RESET:
+ case IN24XX_PORT_LOGOUT:
+ case IN24XX_PORT_CHANGED:
+ case IN24XX_LINK_FAILED:
+ case IN24XX_SRR_RCVD:
+ case IN24XX_ELS_RCVD:
+ (void) isp_async(isp, ISPASYNC_TARGET_ACTION,
+ &local);
+ break;
+ default:
+ isp_prt(isp, ISP_LOGINFO,
+ "isp_target_notify: unknown status (0x%x)",
+ status);
+ isp_notify_ack(isp, local);
+ break;
+ }
+ break;
+ } else if (IS_FC(isp)) {
+ if (FCPARAM(isp)->isp_2klogin) {
+ isp_get_notify_fc_e(isp, inote_fcp,
+ (in_fcentry_e_t *)local);
+ } else {
+ isp_get_notify_fc(isp, inot_fcp,
+ (in_fcentry_t *)local);
+ }
inot_fcp = (in_fcentry_t *) local;
status = inot_fcp->in_status;
seqid = inot_fcp->in_seqid;
@@ -193,29 +304,43 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
SET_BUS_VAL(inotp->in_iid, 0);
}
}
+
isp_prt(isp, ISP_LOGTDEBUG0,
"Immediate Notify On Bus %d, status=0x%x seqid=0x%x",
bus, status, seqid);
- /*
- * ACK it right away.
- */
- isp_notify_ack(isp, (status == IN_RESET)? NULL : local);
switch (status) {
- case IN_RESET:
- (void) isp_async(isp, ISPASYNC_BUS_RESET, &bus);
- break;
case IN_MSG_RECEIVED:
case IN_IDE_RECEIVED:
if (IS_FC(isp)) {
- isp_got_msg_fc(isp, bus, (in_fcentry_t *)local);
+ isp_got_msg_fc(isp, (in_fcentry_t *)local);
} else {
- isp_got_msg(isp, bus, (in_entry_t *)local);
+ isp_got_msg(isp, (in_entry_t *)local);
}
break;
case IN_RSRC_UNAVAIL:
- isp_prt(isp, ISP_LOGWARN, "Firmware out of ATIOs");
+ isp_prt(isp, ISP_LOGINFO, "Firmware out of ATIOs");
+ isp_notify_ack(isp, local);
+ break;
+ case IN_RESET:
+ {
+ /*
+ * We form the notify structure here because we need
+ * to mark it as needing a NOTIFY ACK on return.
+ */
+ tmd_notify_t notify;
+
+ MEMZERO(&notify, sizeof (tmd_notify_t));
+ notify.nt_hba = isp;
+ notify.nt_iid = INI_ANY;
+ /* nt_tgt set in outer layers */
+ notify.nt_lun = LUN_ANY;
+ notify.nt_tagval = TAG_ANY;
+ notify.nt_ncode = NT_BUS_RESET;
+ notify.nt_need_ack = 1;
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
break;
+ }
case IN_PORT_LOGOUT:
case IN_ABORT_TASK:
case IN_PORT_CHANGED:
@@ -223,8 +348,10 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
break;
default:
- isp_prt(isp, ISP_LOGERR,
- "bad status (0x%x) in isp_target_notify", status);
+ isp_prt(isp, ISP_LOGINFO,
+ "isp_target_notify: unknown status (0x%x)",
+ status);
+ isp_notify_ack(isp, local);
break;
}
break;
@@ -234,21 +361,68 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
* The ISP is acknowledging our acknowledgement of an
* Immediate Notify entry for some asynchronous event.
*/
- if (IS_FC(isp)) {
- isp_get_notify_ack_fc(isp, nack_fcp,
- (na_fcentry_t *)local);
+ if (IS_24XX(isp)) {
+ isp_get_notify_ack_24xx(isp, nack_24xx,
+ (na_fcentry_24xx_t *) local);
+ nack_24xx = (na_fcentry_24xx_t *) local;
+ if (nack_24xx->na_status != NA_OK) {
+ level = ISP_LOGINFO;
+ } else {
+ level = ISP_LOGTDEBUG1;
+ }
+ isp_prt(isp, level,
+ "Notify Ack Status=0x%x; Subcode 0x%x seqid=0x%x",
+ nack_24xx->na_status, nack_24xx->na_status_subcode,
+ nack_24xx->na_rxid);
+ } else if (IS_FC(isp)) {
+ if (FCPARAM(isp)->isp_2klogin) {
+ isp_get_notify_ack_fc_e(isp, nacke_fcp,
+ (na_fcentry_e_t *)local);
+ } else {
+ isp_get_notify_ack_fc(isp, nack_fcp,
+ (na_fcentry_t *)local);
+ }
nack_fcp = (na_fcentry_t *)local;
- isp_prt(isp, ISP_LOGTDEBUG1,
- "Notify Ack status=0x%x seqid 0x%x",
+ if (nack_fcp->na_status != NA_OK) {
+ level = ISP_LOGINFO;
+ } else {
+ level = ISP_LOGTDEBUG1;
+ }
+ isp_prt(isp, level,
+ "Notify Ack Status=0x%x seqid 0x%x",
nack_fcp->na_status, nack_fcp->na_seqid);
} else {
isp_get_notify_ack(isp, nackp, (na_entry_t *)local);
nackp = (na_entry_t *)local;
- isp_prt(isp, ISP_LOGTDEBUG1,
+ if (nackp->na_status != NA_OK) {
+ level = ISP_LOGINFO;
+ } else {
+ level = ISP_LOGTDEBUG1;
+ }
+ isp_prt(isp, level,
"Notify Ack event 0x%x status=0x%x seqid 0x%x",
nackp->na_event, nackp->na_status, nackp->na_seqid);
}
break;
+
+ case RQSTYPE_ABTS_RCVD:
+ isp_get_abts(isp, abts, (abts_t *)local);
+ (void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
+ break;
+ case RQSTYPE_ABTS_RSP:
+ isp_get_abts_rsp(isp, abts_rsp, (abts_rsp_t *)local);
+ abts_rsp = (abts_rsp_t *) local;
+ if (abts_rsp->abts_rsp_status) {
+ level = ISP_LOGINFO;
+ } else {
+ level = ISP_LOGTDEBUG0;
+ }
+ isp_prt(isp, level,
+ "ABTS RSP response[0x%x]: status=0x%x sub=(0x%x 0x%x)",
+ abts_rsp->abts_rsp_rxid_task, abts_rsp->abts_rsp_status,
+ abts_rsp->abts_rsp_payload.rsp.subcode1,
+ abts_rsp->abts_rsp_payload.rsp.subcode2);
+ break;
default:
isp_prt(isp, ISP_LOGERR,
"Unknown entry type 0x%x in isp_target_notify", type);
@@ -257,13 +431,24 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
}
#undef atiop
#undef at2iop
+#undef at2eiop
+#undef at7iop
#undef ctiop
#undef ct2iop
+#undef ct2eiop
+#undef ct7iop
#undef lunenp
#undef inotp
#undef inot_fcp
+#undef inote_fcp
+#undef inot_24xx
#undef nackp
#undef nack_fcp
+#undef nacke_fcp
+#undef hack_24xx
+#undef abts
+#undef abts_rsp
+#undef els
#undef hdrp
return (rval);
}
@@ -279,11 +464,11 @@ isp_target_notify(struct ispsoftc *isp, void *vptr, u_int16_t *optrp)
* response entry. The caller is responsible for synchronizing this.
*/
int
-isp_lun_cmd(struct ispsoftc *isp, int cmd, int bus, int tgt, int lun,
- int cmd_cnt, int inot_cnt, u_int32_t opaque)
+isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int tgt, int lun,
+ int cmd_cnt, int inot_cnt, uint32_t opaque)
{
lun_entry_t el;
- u_int16_t nxti, optr;
+ uint32_t nxti, optr;
void *outp;
@@ -315,10 +500,10 @@ isp_lun_cmd(struct ispsoftc *isp, int cmd, int bus, int tgt, int lun,
if (IS_SCSI(isp)) {
el.le_tgt = tgt;
el.le_lun = lun;
- } else if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
+ } else if (FCPARAM(isp)->isp_sccfw == 0) {
el.le_lun = lun;
}
- el.le_timeout = 2;
+ el.le_timeout = 30;
if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
isp_prt(isp, ISP_LOGERR,
@@ -333,11 +518,11 @@ isp_lun_cmd(struct ispsoftc *isp, int cmd, int bus, int tgt, int lun,
int
-isp_target_put_entry(struct ispsoftc *isp, void *ap)
+isp_target_put_entry(ispsoftc_t *isp, void *ap)
{
void *outp;
- u_int16_t nxti, optr;
- u_int8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
+ uint32_t nxti, optr;
+ uint8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
isp_prt(isp, ISP_LOGWARN,
@@ -349,31 +534,46 @@ isp_target_put_entry(struct ispsoftc *isp, void *ap)
isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp);
break;
case RQSTYPE_ATIO2:
- isp_put_atio2(isp, (at2_entry_t *) ap, (at2_entry_t *) outp);
+ if (FCPARAM(isp)->isp_2klogin) {
+ isp_put_atio2e(isp, (at2e_entry_t *) ap,
+ (at2e_entry_t *) outp);
+ } else {
+ isp_put_atio2(isp, (at2_entry_t *) ap,
+ (at2_entry_t *) outp);
+ }
break;
case RQSTYPE_CTIO:
isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp);
break;
case RQSTYPE_CTIO2:
- isp_put_ctio2(isp, (ct2_entry_t *) ap, (ct2_entry_t *) outp);
+ if (FCPARAM(isp)->isp_2klogin) {
+ isp_put_ctio2e(isp, (ct2e_entry_t *) ap,
+ (ct2e_entry_t *) outp);
+ } else {
+ isp_put_ctio2(isp, (ct2_entry_t *) ap,
+ (ct2_entry_t *) outp);
+ }
+ break;
+ case RQSTYPE_CTIO7:
+ isp_put_ctio7(isp, (ct7_entry_t *) ap, (ct7_entry_t *) outp);
break;
default:
isp_prt(isp, ISP_LOGERR,
"Unknown type 0x%x in isp_put_entry", etype);
return (-1);
}
-
ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);
ISP_ADD_REQUEST(isp, nxti);
return (0);
}
int
-isp_target_put_atio(struct ispsoftc *isp, void *arg)
+isp_target_put_atio(ispsoftc_t *isp, void *arg)
{
union {
at_entry_t _atio;
at2_entry_t _atio2;
+ at2e_entry_t _atio2e;
} atun;
MEMZERO(&atun, sizeof atun);
@@ -381,12 +581,16 @@ isp_target_put_atio(struct ispsoftc *isp, void *arg)
at2_entry_t *aep = arg;
atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2;
atun._atio2.at_header.rqs_entry_count = 1;
- if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
- atun._atio2.at_scclun = (u_int16_t) aep->at_scclun;
+ if (FCPARAM(isp)->isp_sccfw) {
+ atun._atio2.at_scclun = aep->at_scclun;
+ } else {
+ atun._atio2.at_lun = (uint8_t) aep->at_lun;
+ }
+ if (FCPARAM(isp)->isp_2klogin) {
+ atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid;
} else {
- atun._atio2.at_lun = (u_int8_t) aep->at_lun;
+ atun._atio2.at_iid = aep->at_iid;
}
- atun._atio2.at_iid = aep->at_iid;
atun._atio2.at_rxid = aep->at_rxid;
atun._atio2.at_status = CT_OK;
} else {
@@ -424,29 +628,62 @@ isp_target_put_atio(struct ispsoftc *isp, void *arg)
*/
int
-isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl)
+isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint32_t hdl)
{
int sts;
union {
ct_entry_t _ctio;
ct2_entry_t _ctio2;
+ ct2e_entry_t _ctio2e;
+ ct7_entry_t _ctio7;
} un;
MEMZERO(&un, sizeof un);
sts = code & 0xff;
- if (IS_FC(isp)) {
+ if (IS_24XX(isp)) {
+ at7_entry_t *aep = arg;
+ ct7_entry_t *cto = &un._ctio7;
+
+ cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
+ cto->ct_header.rqs_entry_count = 1;
+/* XXXX */ cto->ct_nphdl = aep->at_hdr.seq_id;
+ cto->ct_rxid = aep->at_rxid;
+ cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) |
+ aep->at_hdr.s_id[2];
+ cto->ct_iid_hi = aep->at_hdr.s_id[0];
+ cto->ct_oxid = aep->at_hdr.ox_id;
+ cto->ct_scsi_status = sts;
+ cto->ct_flags = CT7_FLAG_MODE1 | CT7_NO_DATA | CT7_SENDSTATUS;
+ if (sts == SCSI_CHECK && (code & ECMD_SVALID)) {
+ cto->rsp.m1.ct_resplen = 16;
+ cto->rsp.m1.ct_resp[0] = 0xf0;
+ cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
+ cto->rsp.m1.ct_resp[7] = 8;
+ cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
+ cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
+ }
+ if (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl) {
+ cto->ct_resid = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl;
+ cto->ct_scsi_status |= CT2_DATA_UNDER;
+ }
+ cto->ct_syshandle = hdl;
+ } else if (IS_FC(isp)) {
at2_entry_t *aep = arg;
ct2_entry_t *cto = &un._ctio2;
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
cto->ct_header.rqs_entry_count = 1;
- cto->ct_iid = aep->at_iid;
- if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
+ if (FCPARAM(isp)->isp_sccfw == 0) {
cto->ct_lun = aep->at_lun;
}
+ if (FCPARAM(isp)->isp_2klogin) {
+ un._ctio2e.ct_iid = ((at2e_entry_t *)aep)->at_iid;
+ } else {
+ cto->ct_iid = aep->at_iid;
+ }
cto->ct_rxid = aep->at_rxid;
- cto->rsp.m1.ct_scsi_status = sts & 0xff;
+ cto->rsp.m1.ct_scsi_status = sts;
cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1;
if (hdl == 0) {
cto->ct_flags |= CT2_CCINCR;
@@ -455,7 +692,7 @@ isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl)
cto->ct_resid = aep->at_datalen;
cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
}
- if ((sts & 0xff) == SCSI_CHECK && (sts & ECMD_SVALID)) {
+ if (sts == SCSI_CHECK && (code & ECMD_SVALID)) {
cto->rsp.m1.ct_resp[0] = 0xf0;
cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
cto->rsp.m1.ct_resp[7] = 8;
@@ -490,63 +727,87 @@ isp_endcmd(struct ispsoftc *isp, void *arg, u_int32_t code, u_int16_t hdl)
return (isp_target_put_entry(isp, &un));
}
+/*
+ * These are either broadcast events or specifically CTIO fast completion
+ */
int
-isp_target_async(struct ispsoftc *isp, int bus, int event)
+isp_target_async(ispsoftc_t *isp, int bus, int event)
{
- tmd_event_t evt;
- tmd_msg_t msg;
+ tmd_notify_t notify;
+
+ MEMZERO(&notify, sizeof (tmd_notify_t));
+ notify.nt_hba = isp;
+ notify.nt_iid = INI_ANY;
+ /* nt_tgt set in outer layers */
+ notify.nt_lun = LUN_ANY;
+ notify.nt_tagval = TAG_ANY;
+
+ if (IS_SCSI(isp)) {
+ TAG_INSERT_BUS(notify.nt_tagval, bus);
+ }
switch (event) {
- /*
- * These three we handle here to propagate an effective bus reset
- * upstream, but these do not require any immediate notify actions
- * so we return when done.
- */
- case ASYNC_LIP_F8:
- case ASYNC_LIP_OCCURRED:
case ASYNC_LOOP_UP:
+ case ASYNC_PTPMODE:
+ notify.nt_ncode = NT_LINK_UP;
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ break;
case ASYNC_LOOP_DOWN:
+ notify.nt_ncode = NT_LINK_DOWN;
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ break;
+ case ASYNC_LIP_ERROR:
+ case ASYNC_LIP_F8:
+ case ASYNC_LIP_OCCURRED:
case ASYNC_LOOP_RESET:
- case ASYNC_PTPMODE:
- /*
- * These don't require any immediate notify actions. We used
- * treat them like SCSI Bus Resets, but that was just plain
- * wrong. Let the normal CTIO completion report what occurred.
- */
- return (0);
-
+ notify.nt_ncode = NT_LIP_RESET;
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ break;
case ASYNC_BUS_RESET:
- case ASYNC_TIMEOUT_RESET:
- if (IS_FC(isp)) {
- return (0); /* we'll be getting an inotify instead */
- }
- evt.ev_bus = bus;
- evt.ev_event = event;
- (void) isp_async(isp, ISPASYNC_TARGET_EVENT, &evt);
+ case ASYNC_TIMEOUT_RESET: /* XXX: where does this come from ? */
+ notify.nt_ncode = NT_BUS_RESET;
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
break;
case ASYNC_DEVICE_RESET:
- /*
- * Bus Device Reset resets a specific target, so
- * we pass this as a synthesized message.
- */
- MEMZERO(&msg, sizeof msg);
- if (IS_FC(isp)) {
- msg.nt_iid = FCPARAM(isp)->isp_loopid;
+ notify.nt_ncode = NT_TARGET_RESET;
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
+ break;
+ case ASYNC_CTIO_DONE:
+ {
+ uint8_t storage[QENTRY_LEN];
+ memset(storage, 0, QENTRY_LEN);
+ if (IS_24XX(isp)) {
+ ct7_entry_t *ct = (ct7_entry_t *) storage;
+ ct->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
+ ct->ct_nphdl = CT7_OK;
+ ct->ct_syshandle = bus;
+ ct->ct_flags = CT7_SENDSTATUS|CT7_FASTPOST;
+ } else if (IS_FC(isp)) {
+ /* This should also suffice for 2K login code */
+ ct2_entry_t *ct = (ct2_entry_t *) storage;
+ ct->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
+ ct->ct_status = CT_OK;
+ ct->ct_syshandle = bus;
+ ct->ct_flags = CT2_SENDSTATUS|CT2_FASTPOST;
} else {
- msg.nt_iid = SDPARAM(isp)->isp_initiator_id;
+ ct_entry_t *ct = (ct_entry_t *) storage;
+ ct->ct_header.rqs_entry_type = RQSTYPE_CTIO;
+ ct->ct_status = CT_OK;
+ ct->ct_fwhandle = bus;
+ ct->ct_flags = CT_SENDSTATUS;
}
- msg.nt_bus = bus;
- msg.nt_msg[0] = MSG_BUS_DEV_RESET;
- (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
+ (void) isp_async(isp, ISPASYNC_TARGET_ACTION, storage);
break;
+ }
default:
isp_prt(isp, ISP_LOGERR,
"isp_target_async: unknown event 0x%x", event);
+ if (isp->isp_state == ISP_RUNSTATE) {
+ isp_notify_ack(isp, NULL);
+ }
break;
}
- if (isp->isp_state == ISP_RUNSTATE)
- isp_notify_ack(isp, NULL);
- return(0);
+ return (0);
}
@@ -559,25 +820,53 @@ isp_target_async(struct ispsoftc *isp, int bus, int event)
*/
static void
-isp_got_msg(struct ispsoftc *isp, int bus, in_entry_t *inp)
+isp_got_msg(ispsoftc_t *isp, in_entry_t *inp)
{
- u_int8_t status = inp->in_status & ~QLTM_SVALID;
+ tmd_notify_t nt;
+ uint8_t status = inp->in_status & ~QLTM_SVALID;
+
+ MEMZERO(&nt, sizeof (nt));
+ nt.nt_hba = isp;
+ nt.nt_iid = GET_IID_VAL(inp->in_iid);
+ nt.nt_tgt = inp->in_tgt;
+ nt.nt_lun = inp->in_lun;
+ IN_MAKE_TAGID(nt.nt_tagval, GET_BUS_VAL(inp->in_iid), 0, inp);
+ nt.nt_lreserved = inp;
if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) {
- tmd_msg_t msg;
-
- MEMZERO(&msg, sizeof (msg));
- msg.nt_bus = bus;
- msg.nt_iid = inp->in_iid;
- msg.nt_tgt = inp->in_tgt;
- msg.nt_lun = inp->in_lun;
- msg.nt_tagtype = inp->in_tag_type;
- msg.nt_tagval = inp->in_tag_val;
- MEMCPY(msg.nt_msg, inp->in_msg, IN_MSGLEN);
- (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
+ switch (inp->in_msg[0]) {
+ case MSG_ABORT:
+ nt.nt_ncode = NT_ABORT_TASK_SET;
+ break;
+ case MSG_BUS_DEV_RESET:
+ nt.nt_ncode = NT_TARGET_RESET;
+ break;
+ case MSG_ABORT_TAG:
+ nt.nt_ncode = NT_ABORT_TASK;
+ break;
+ case MSG_CLEAR_QUEUE:
+ nt.nt_ncode = NT_CLEAR_TASK_SET;
+ break;
+ case MSG_REL_RECOVERY:
+ nt.nt_ncode = NT_CLEAR_ACA;
+ break;
+ case MSG_TERM_IO_PROC:
+ nt.nt_ncode = NT_ABORT_TASK;
+ break;
+ case MSG_LUN_RESET:
+ nt.nt_ncode = NT_LUN_RESET;
+ break;
+ default:
+ isp_prt(isp, ISP_LOGERR,
+ "unhandled message 0x%x", inp->in_msg[0]);
+ isp_notify_ack(isp, inp);
+ return;
+ }
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
} else {
isp_prt(isp, ISP_LOGERR,
"unknown immediate notify status 0x%x", inp->in_status);
+ isp_notify_ack(isp, inp);
}
}
@@ -585,69 +874,140 @@ isp_got_msg(struct ispsoftc *isp, int bus, in_entry_t *inp)
* Synthesize a message from the task management flags in a FCP_CMND_IU.
*/
static void
-isp_got_msg_fc(struct ispsoftc *isp, int bus, in_fcentry_t *inp)
+isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp)
{
- int lun;
- static const char f1[] = "%s from iid %d lun %d seq 0x%x";
- static const char f2[] =
- "unknown %s 0x%x lun %d iid %d task flags 0x%x seq 0x%x\n";
-
- if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
- lun = inp->in_scclun;
+ tmd_notify_t nt;
+ static const char f1[] = "%s from N-port handle 0x%x lun %d seq 0x%x";
+ static const char f2[] = "unknown %s 0x%x lun %d N-Port handle 0x%x "
+ "task flags 0x%x seq 0x%x\n";
+ uint16_t seqid, loopid;
+
+ MEMZERO(&nt, sizeof (tmd_notify_t));
+ nt.nt_hba = isp;
+ if (FCPARAM(isp)->isp_2klogin) {
+ nt.nt_iid = ((in_fcentry_e_t *)inp)->in_iid;
+ loopid = ((in_fcentry_e_t *)inp)->in_iid;
+ seqid = ((in_fcentry_e_t *)inp)->in_seqid;
} else {
- lun = inp->in_lun;
+ nt.nt_iid = inp->in_iid;
+ loopid = inp->in_iid;
+ seqid = inp->in_seqid;
}
+ /* nt_tgt set in outer layers */
+ if (FCPARAM(isp)->isp_sccfw) {
+ nt.nt_lun = inp->in_scclun;
+ } else {
+ nt.nt_lun = inp->in_lun;
+ }
+ IN_FC_MAKE_TAGID(nt.nt_tagval, 0, 0, seqid);
+ nt.nt_need_ack = 1;
+ nt.nt_lreserved = inp;
if (inp->in_status != IN_MSG_RECEIVED) {
isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status",
- inp->in_status, lun, inp->in_iid,
- inp->in_task_flags, inp->in_seqid);
+ inp->in_status, nt.nt_lun, loopid, inp->in_task_flags,
+ inp->in_seqid);
+ isp_notify_ack(isp, inp);
+ return;
+ }
+
+ if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
+ loopid, nt.nt_lun, inp->in_seqid);
+ nt.nt_ncode = NT_ABORT_TASK_SET;
+ } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
+ loopid, nt.nt_lun, inp->in_seqid);
+ nt.nt_ncode = NT_CLEAR_TASK_SET;
+ } else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET",
+ loopid, nt.nt_lun, inp->in_seqid);
+ nt.nt_ncode = NT_LUN_RESET;
+ } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
+ loopid, nt.nt_lun, inp->in_seqid);
+ nt.nt_ncode = NT_TARGET_RESET;
+ } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
+ isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
+ loopid, nt.nt_lun, inp->in_seqid);
+ nt.nt_ncode = NT_CLEAR_ACA;
} else {
- tmd_msg_t msg;
-
- MEMZERO(&msg, sizeof (msg));
- msg.nt_bus = bus;
- msg.nt_iid = inp->in_iid;
- msg.nt_tagval = inp->in_seqid;
- msg.nt_lun = lun;
-
- if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK) {
- isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK",
- inp->in_iid, lun, inp->in_seqid);
- msg.nt_msg[0] = MSG_ABORT_TAG;
- } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
- isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
- inp->in_iid, lun, inp->in_seqid);
- msg.nt_msg[0] = MSG_CLEAR_QUEUE;
- } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
- isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
- inp->in_iid, lun, inp->in_seqid);
- msg.nt_msg[0] = MSG_BUS_DEV_RESET;
- } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
- isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
- inp->in_iid, lun, inp->in_seqid);
- /* ???? */
- msg.nt_msg[0] = MSG_REL_RECOVERY;
- } else if (inp->in_task_flags & TASK_FLAGS_TERMINATE_TASK) {
- isp_prt(isp, ISP_LOGINFO, f1, "TERMINATE TASK",
- inp->in_iid, lun, inp->in_seqid);
- msg.nt_msg[0] = MSG_TERM_IO_PROC;
- } else {
- isp_prt(isp, ISP_LOGWARN, f2, "task flag",
- inp->in_status, lun, inp->in_iid,
- inp->in_task_flags, inp->in_seqid);
- }
- if (msg.nt_msg[0]) {
- (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
- }
+ isp_prt(isp, ISP_LOGWARN, f2, "task flag", inp->in_status,
+ nt.nt_lun, loopid, inp->in_task_flags, inp->in_seqid);
+ isp_notify_ack(isp, inp);
+ return;
}
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
}
+#define HILO(x) (uint32_t) (x >> 32), (uint32_t) x
static void
-isp_notify_ack(struct ispsoftc *isp, void *arg)
+isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep)
+{
+ tmd_notify_t nt;
+ static const char f1[] =
+ "%s from PortID 0x%06x lun %d seq 0x%08x%08x";
+ static const char f2[] =
+ "unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%08x%08x";
+ uint32_t sid;
+
+ MEMZERO(&nt, sizeof (tmd_notify_t));
+ nt.nt_hba = isp;
+ nt.nt_iid = INI_ANY;
+ nt.nt_lun =
+ (aep->at_cmnd.fcp_cmnd_lun[0] << 8) |
+ (aep->at_cmnd.fcp_cmnd_lun[1]);
+ /*
+ * XXX: VPIDX HAS TO BE DERIVED FROM DESTINATION PORT
+ */
+ nt.nt_tagval = aep->at_rxid;
+ nt.nt_lreserved = aep;
+ sid =
+ (aep->at_hdr.s_id[0] << 16) |
+ (aep->at_hdr.s_id[1] << 8) |
+ (aep->at_hdr.s_id[2]);
+
+ if (aep->at_cmnd.fcp_cmnd_task_management &
+ FCP_CMND_TMF_ABORT_TASK_SET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
+ sid, nt.nt_lun, HILO(nt.nt_tagval));
+ nt.nt_ncode = NT_ABORT_TASK_SET;
+ } else if (aep->at_cmnd.fcp_cmnd_task_management &
+ FCP_CMND_TMF_CLEAR_TASK_SET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
+ sid, nt.nt_lun, HILO(nt.nt_tagval));
+ nt.nt_ncode = NT_CLEAR_TASK_SET;
+ } else if (aep->at_cmnd.fcp_cmnd_task_management &
+ FCP_CMND_TMF_LUN_RESET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET",
+ sid, nt.nt_lun, HILO(nt.nt_tagval));
+ nt.nt_ncode = NT_LUN_RESET;
+ } else if (aep->at_cmnd.fcp_cmnd_task_management &
+ FCP_CMND_TMF_TGT_RESET) {
+ isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
+ sid, nt.nt_lun, HILO(nt.nt_tagval));
+ nt.nt_ncode = NT_TARGET_RESET;
+ nt.nt_lun = LUN_ANY;
+ } else if (aep->at_cmnd.fcp_cmnd_task_management &
+ FCP_CMND_TMF_CLEAR_ACA) {
+ isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
+ sid, nt.nt_lun, HILO(nt.nt_tagval));
+ nt.nt_ncode = NT_CLEAR_ACA;
+ } else {
+ isp_prt(isp, ISP_LOGWARN, f2,
+ aep->at_cmnd.fcp_cmnd_task_management,
+ nt.nt_lun, sid, HILO(nt.nt_tagval));
+ isp_endcmd(isp, aep, 0, 0);
+ return;
+ }
+ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
+}
+
+void
+isp_notify_ack(ispsoftc_t *isp, void *arg)
{
char storage[QENTRY_LEN];
- u_int16_t nxti, optr;
+ uint32_t nxti, optr;
void *outp;
if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
@@ -658,30 +1018,82 @@ isp_notify_ack(struct ispsoftc *isp, void *arg)
MEMZERO(storage, QENTRY_LEN);
- if (IS_FC(isp)) {
+ if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) {
+ at7_entry_t *aep = arg;
+ isp_endcmd(isp, aep, 0, 0);
+ return;
+ } else if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ABTS_RSP)) {
+ abts_rsp_t *abts_rsp = (abts_rsp_t *) storage;
+ /*
+ * The caller will have set response values as appropriate
+ * in the ABTS structure just before calling us.
+ */
+ MEMCPY(abts_rsp, arg, QENTRY_LEN);
+ isp_put_abts_rsp(isp, abts_rsp, (abts_rsp_t *)outp);
+ } else if (IS_24XX(isp)) {
+ na_fcentry_24xx_t *na = (na_fcentry_24xx_t *) storage;
+ if (arg) {
+ in_fcentry_24xx_t *in = arg;
+ na->na_nphdl = in->in_nphdl;
+ na->na_status = in->in_status;
+ na->na_status_subcode = in->in_status_subcode;
+ na->na_rxid = in->in_rxid;
+ na->na_oxid = in->in_oxid;
+ if (in->in_status == IN24XX_SRR_RCVD) {
+ na->na_srr_rxid = in->in_srr_rxid;
+ na->na_srr_reloff_hi = in->in_srr_reloff_hi;
+ na->na_srr_reloff_lo = in->in_srr_reloff_lo;
+ na->na_srr_iu = in->in_srr_iu;
+ na->na_srr_flags = 1;
+ na->na_srr_reject_vunique = 0;
+ na->na_srr_reject_explanation = 1;
+ na->na_srr_reject_code = 1;
+ }
+ }
+ na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
+ na->na_header.rqs_entry_count = 1;
+ isp_put_notify_24xx_ack(isp, na, (na_fcentry_24xx_t *)outp);
+ } else if (IS_FC(isp)) {
na_fcentry_t *na = (na_fcentry_t *) storage;
+ int iid = 0;
+
if (arg) {
in_fcentry_t *inp = arg;
MEMCPY(storage, arg, sizeof (isphdr_t));
- na->na_iid = inp->in_iid;
- if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
- na->na_lun = inp->in_scclun;
+ if (FCPARAM(isp)->isp_2klogin) {
+ ((na_fcentry_e_t *)na)->na_iid =
+ ((in_fcentry_e_t *)inp)->in_iid;
+ iid = ((na_fcentry_e_t *)na)->na_iid;
} else {
- na->na_lun = inp->in_lun;
+ na->na_iid = inp->in_iid;
+ iid = na->na_iid;
}
- na->na_task_flags = inp->in_task_flags;
+ na->na_task_flags =
+ inp->in_task_flags & TASK_FLAGS_RESERVED_MASK;
na->na_seqid = inp->in_seqid;
na->na_flags = NAFC_RCOUNT;
na->na_status = inp->in_status;
if (inp->in_status == IN_RESET) {
na->na_flags |= NAFC_RST_CLRD;
}
+ if (inp->in_status == IN_MSG_RECEIVED) {
+ na->na_flags |= NAFC_TVALID;
+ na->na_response = 0; /* XXX SUCCEEDED XXX */
+ }
} else {
na->na_flags = NAFC_RST_CLRD;
}
na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
na->na_header.rqs_entry_count = 1;
- isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
+ if (FCPARAM(isp)->isp_2klogin) {
+ isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na,
+ (na_fcentry_e_t *)outp);
+ } else {
+ isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
+ }
+ isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u seqid %x "
+ "flags %x tflags %x response %x", iid, na->na_seqid,
+ na->na_flags, na->na_task_flags, na->na_response);
} else {
na_entry_t *na = (na_entry_t *) storage;
if (arg) {
@@ -700,13 +1112,16 @@ isp_notify_ack(struct ispsoftc *isp, void *arg)
na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
na->na_header.rqs_entry_count = 1;
isp_put_notify_ack(isp, na, (na_entry_t *)outp);
+ isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u lun %u tgt "
+ "%u seqid %x event %x", na->na_iid, na->na_lun, na->na_tgt,
+ na->na_seqid, na->na_event);
}
ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage);
ISP_ADD_REQUEST(isp, nxti);
}
static void
-isp_handle_atio(struct ispsoftc *isp, at_entry_t *aep)
+isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep)
{
int lun;
lun = aep->at_lun;
@@ -714,7 +1129,7 @@ isp_handle_atio(struct ispsoftc *isp, at_entry_t *aep)
* The firmware status (except for the QLTM_SVALID bit) indicates
* why this ATIO was sent to us.
*
- * If QLTM_SVALID is set, the firmware has recommended Sense Data.
+ * If QLTM_SVALID is set, the firware has recommended Sense Data.
*
* If the DISCONNECTS DISABLED bit is set in the flags field,
* we're still connected on the SCSI bus - i.e. the initiator
@@ -779,7 +1194,7 @@ isp_handle_atio(struct ispsoftc *isp, at_entry_t *aep)
default:
isp_prt(isp, ISP_LOGERR,
- "Unknown ATIO status 0x%x from initiator %d for lun %d",
+ "Unknown ATIO status 0x%x from loopid %d for lun %d",
aep->at_status, aep->at_iid, lun);
(void) isp_target_put_atio(isp, aep);
break;
@@ -787,21 +1202,27 @@ isp_handle_atio(struct ispsoftc *isp, at_entry_t *aep)
}
static void
-isp_handle_atio2(struct ispsoftc *isp, at2_entry_t *aep)
+isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep)
{
- int lun;
+ int lun, iid;
- if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
+ if (FCPARAM(isp)->isp_sccfw) {
lun = aep->at_scclun;
} else {
lun = aep->at_lun;
}
+ if (FCPARAM(isp)->isp_2klogin) {
+ iid = ((at2e_entry_t *)aep)->at_iid;
+ } else {
+ iid = aep->at_iid;
+ }
+
/*
* The firmware status (except for the QLTM_SVALID bit) indicates
* why this ATIO was sent to us.
*
- * If QLTM_SVALID is set, the firmware has recommended Sense Data.
+ * If QLTM_SVALID is set, the firware has recommended Sense Data.
*
* If the DISCONNECTS DISABLED bit is set in the flags field,
* we're still connected on the SCSI bus - i.e. the initiator
@@ -856,30 +1277,31 @@ isp_handle_atio2(struct ispsoftc *isp, at2_entry_t *aep)
* Ignore it because the async event will clear things
* up for us.
*/
- isp_prt(isp, ISP_LOGERR, atior, lun, aep->at_iid, 0);
+ isp_prt(isp, ISP_LOGERR, atior, lun, iid, 0);
break;
default:
isp_prt(isp, ISP_LOGERR,
- "Unknown ATIO2 status 0x%x from initiator %d for lun %d",
- aep->at_status, aep->at_iid, lun);
+ "Unknown ATIO2 status 0x%x from loopid %d for lun %d",
+ aep->at_status, iid, lun);
(void) isp_target_put_atio(isp, aep);
break;
}
}
static void
-isp_handle_ctio(struct ispsoftc *isp, ct_entry_t *ct)
+isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
{
void *xs;
int pl = ISP_LOGTDEBUG2;
char *fmsg = NULL;
if (ct->ct_syshandle) {
- xs = isp_find_xs(isp, ct->ct_syshandle);
- if (xs == NULL)
+ xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
+ if (xs == NULL) {
pl = ISP_LOGALL;
+ }
} else {
xs = NULL;
}
@@ -931,7 +1353,7 @@ isp_handle_ctio(struct ispsoftc *isp, ct_entry_t *ct)
if (fmsg == NULL)
fmsg = "ABORT TAG message sent by Initiator";
- isp_prt(isp, ISP_LOGWARN, "CTIO destroyed by %s", fmsg);
+ isp_prt(isp, ISP_LOGTDEBUG0, "CTIO destroyed by %s", fmsg);
break;
case CT_INVAL:
@@ -1030,16 +1452,17 @@ isp_handle_ctio(struct ispsoftc *isp, ct_entry_t *ct)
}
static void
-isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
+isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
{
- XS_T *xs;
+ void *xs;
int pl = ISP_LOGTDEBUG2;
char *fmsg = NULL;
if (ct->ct_syshandle) {
- xs = isp_find_xs(isp, ct->ct_syshandle);
- if (xs == NULL)
+ xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
+ if (xs == NULL) {
pl = ISP_LOGALL;
+ }
} else {
xs = NULL;
}
@@ -1069,7 +1492,7 @@ isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
* status. These CTIOs are handled in that same way as
* CT_ABORTED ones, so just fall through here.
*/
- fmsg = "TARGET RESET Task Management Function Received";
+ fmsg = "TARGET RESET";
/*FALLTHROUGH*/
case CT_RESET:
if (fmsg == NULL)
@@ -1081,10 +1504,12 @@ isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
* Bus Free and returns all outstanding CTIOs with the status
* set, then sends us an Immediate Notify entry.
*/
- if (fmsg == NULL)
- fmsg = "ABORT Task Management Function Received";
+ if (fmsg == NULL) {
+ fmsg = "ABORT";
+ }
- isp_prt(isp, ISP_LOGERR, "CTIO2 destroyed by %s", fmsg);
+ isp_prt(isp, ISP_LOGTDEBUG0,
+ "CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
break;
case CT_INVAL:
@@ -1110,16 +1535,18 @@ isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
if (fmsg == NULL)
fmsg = "Port Logout";
/*FALLTHROUGH*/
- case CT_PORTNOTAVAIL:
+ case CT_PORTUNAVAIL:
if (fmsg == NULL)
fmsg = "Port not available";
+ /*FALLTHROUGH*/
case CT_PORTCHANGED:
if (fmsg == NULL)
fmsg = "Port Changed";
+ /*FALLTHROUGH*/
case CT_NOACK:
if (fmsg == NULL)
fmsg = "unacknowledged Immediate Notify pending";
- isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
+ isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg);
break;
case CT_INVRXID:
@@ -1127,7 +1554,7 @@ isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
* CTIO rejected by the firmware because an invalid RX_ID.
* Just print a message.
*/
- isp_prt(isp, ISP_LOGERR,
+ isp_prt(isp, ISP_LOGWARN,
"CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
break;
@@ -1146,7 +1573,7 @@ isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
* order we got them.
*/
if (ct->ct_syshandle == 0) {
- if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
+ if ((ct->ct_flags & CT2_SENDSTATUS) == 0) {
isp_prt(isp, pl,
"intermediate CTIO completed ok");
} else {
@@ -1162,7 +1589,160 @@ isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
ISP_DMAFREE(isp, xs, ct->ct_syshandle);
}
- if (ct->ct_flags & CT_SENDSTATUS) {
+ if (ct->ct_flags & CT2_SENDSTATUS) {
+ /*
+ * Sent status and command complete.
+ *
+ * We're now really done with this command, so we
+ * punt to the platform dependent layers because
+ * only there can we do the appropriate command
+ * complete thread synchronization.
+ */
+ isp_prt(isp, pl, "status CTIO complete");
+ } else {
+ /*
+ * Final CTIO completed. Release DMA resources and
+ * notify platform dependent layers.
+ */
+ isp_prt(isp, pl, "data CTIO complete");
+ }
+ (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
+ /*
+ * The platform layer will destroy the handle if appropriate.
+ */
+ }
+}
+
+static void
+isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct)
+{
+ void *xs;
+ int pl = ISP_LOGTDEBUG2;
+ char *fmsg = NULL;
+
+ if (ct->ct_syshandle) {
+ xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
+ if (xs == NULL) {
+ pl = ISP_LOGALL;
+ }
+ } else {
+ xs = NULL;
+ }
+
+ switch(ct->ct_nphdl) {
+ case CT7_BUS_ERROR:
+ isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
+ /* FALL Through */
+ case CT7_DATA_OVER:
+ case CT7_DATA_UNDER:
+ case CT7_OK:
+ /*
+ * There are generally 2 possibilities as to why we'd get
+ * this condition:
+ * We sent or received data.
+ * We sent status & command complete.
+ */
+
+ break;
+
+ case CT7_RESET:
+ if (fmsg == NULL) {
+ fmsg = "LIP Reset";
+ }
+ /*FALLTHROUGH*/
+ case CT7_ABORTED:
+ /*
+ * When an Abort message is received the firmware goes to
+ * Bus Free and returns all outstanding CTIOs with the status
+ * set, then sends us an Immediate Notify entry.
+ */
+ if (fmsg == NULL) {
+ fmsg = "ABORT";
+ }
+ isp_prt(isp, ISP_LOGTDEBUG0,
+ "CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
+ break;
+
+ case CT7_TIMEOUT:
+ if (fmsg == NULL) {
+ fmsg = "command";
+ }
+ isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
+ break;
+
+ case CT7_ERR:
+ fmsg = "Completed with Error";
+ /*FALLTHROUGH*/
+ case CT7_LOGOUT:
+ if (fmsg == NULL) {
+ fmsg = "Port Logout";
+ }
+ /*FALLTHROUGH*/
+ case CT7_PORTUNAVAIL:
+ if (fmsg == NULL) {
+ fmsg = "Port not available";
+ }
+ /*FALLTHROUGH*/
+ case CT7_PORTCHANGED:
+ if (fmsg == NULL) {
+ fmsg = "Port Changed";
+ }
+ isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg);
+ break;
+
+ case CT7_INVRXID:
+ /*
+ * CTIO rejected by the firmware because an invalid RX_ID.
+ * Just print a message.
+ */
+ isp_prt(isp, ISP_LOGWARN,
+ "CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
+ break;
+
+ case CT7_REASSY_ERR:
+ isp_prt(isp, ISP_LOGWARN, "reassembly error");
+ break;
+
+ case CT7_SRR:
+ isp_prt(isp, ISP_LOGWARN, "SRR received");
+ break;
+
+ default:
+ isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x",
+ ct->ct_nphdl);
+ break;
+ }
+
+ if (xs == NULL) {
+ /*
+ * There may be more than one CTIO for a data transfer,
+ * or this may be a status CTIO we're not monitoring.
+ *
+ * The assumption is that they'll all be returned in the
+ * order we got them.
+ */
+ if (ct->ct_syshandle == 0) {
+ if (ct->ct_flags & CT7_TERMINATE) {
+ isp_prt(isp, ISP_LOGINFO,
+ "termination of 0x%x complete",
+ ct->ct_rxid);
+ } else if ((ct->ct_flags & CT7_SENDSTATUS) == 0) {
+ isp_prt(isp, pl,
+ "intermediate CTIO completed ok");
+ } else {
+ isp_prt(isp, pl,
+ "unmonitored CTIO completed ok");
+ }
+ } else {
+ isp_prt(isp, pl,
+ "NO xs for CTIO (handle 0x%x) status 0x%x",
+ ct->ct_syshandle, ct->ct_nphdl);
+ }
+ } else {
+ if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
+ ISP_DMAFREE(isp, xs, ct->ct_syshandle);
+ }
+ if (ct->ct_flags & CT2_SENDSTATUS) {
/*
* Sent status and command complete.
*
diff --git a/sys/dev/ic/isp_target.h b/sys/dev/ic/isp_target.h
index 93dcd1602fe..d40a068807e 100644
--- a/sys/dev/ic/isp_target.h
+++ b/sys/dev/ic/isp_target.h
@@ -1,30 +1,5 @@
-/* $OpenBSD: isp_target.h,v 1.13 2008/11/02 02:01:47 krw Exp $ */
+/* $OpenBSD: isp_target.h,v 1.14 2009/06/24 11:00:53 krw Exp $ */
/* $FreeBSD: src/sys/dev/isp/isp_target.h,v 1.30 2007/03/10 02:39:54 mjacob Exp $ */
-/*
- * Copyright (c) 1997, 1998
- * Patrick Stirling
- * pms@psconsult.com
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -170,33 +145,13 @@ typedef struct {
/*
* Values for the in_task_flags field- should only get one at a time!
*/
-#define TASK_FLAGS_ABORT_TASK (1<<9)
-#define TASK_FLAGS_CLEAR_TASK_SET (1<<10)
-#define TASK_FLAGS_TARGET_RESET (1<<13)
#define TASK_FLAGS_RESERVED_MASK (0xe700)
#define TASK_FLAGS_CLEAR_ACA (1<<14)
-#define TASK_FLAGS_TERMINATE_TASK (1<<15)
#define TASK_FLAGS_TARGET_RESET (1<<13)
#define TASK_FLAGS_LUN_RESET (1<<12)
#define TASK_FLAGS_CLEAR_TASK_SET (1<<10)
#define TASK_FLAGS_ABORT_TASK_SET (1<<9)
-#ifndef MSG_ABORT_TAG
-#define MSG_ABORT_TAG 0x06
-#endif
-#ifndef MSG_CLEAR_QUEUE
-#define MSG_CLEAR_QUEUE 0x0e
-#endif
-#ifndef MSG_BUS_DEV_RESET
-#define MSG_BUS_DEV_RESET 0x0b
-#endif
-#ifndef MSG_REL_RECOVERY
-#define MSG_REL_RECOVERY 0x10
-#endif
-#ifndef MSG_TERM_IO_PROC
-#define MSG_TERM_IO_PROC 0x11
-#endif
-
/*
* ISP24XX Immediate Notify
*/
@@ -268,9 +223,9 @@ typedef struct {
typedef struct {
isphdr_t na_header;
u_int32_t na_reserved;
- u_int8_t na_lun; /* lun */
- u_int8_t na_iid; /* initiator */
- u_int16_t na_scclun;
+ u_int8_t na_reserved1;
+ u_int8_t na_iid; /* initiator loop id */
+ u_int16_t na_response;
u_int16_t na_flags;
u_int16_t na_reserved2;
u_int16_t na_status;
@@ -367,21 +322,29 @@ typedef struct {
* Macros to create and fetch and test concatenated handle and tag value macros
*/
-#define AT_MAKE_TAGID(tid, aep) \
- tid = ((aep)->at_handle << 16); \
- if ((aep)->at_flags & AT_TQAE) \
- (tid) |= ((aep)->at_tag_val + 1)
+#define AT_MAKE_TAGID(tid, bus, inst, aep) \
+ tid = aep->at_handle; \
+ if (aep->at_flags & AT_TQAE) { \
+ tid |= (aep->at_tag_val << 16); \
+ tid |= (1 << 24); \
+ } \
+ tid |= (bus << 25); \
+ tid |= (inst << 26)
-#define CT_MAKE_TAGID(tid, ct) \
- tid = ((ct)->ct_fwhandle << 16); \
- if ((ct)->ct_flags & CT_TQAE) \
- (tid) |= ((ct)->ct_tag_val + 1)
+#define CT_MAKE_TAGID(tid, bus, inst, ct) \
+ tid = ct->ct_fwhandle; \
+ if (ct->ct_flags & CT_TQAE) { \
+ tid |= (ct->ct_tag_val << 16); \
+ tid |= (1 << 24); \
+ } \
+ tid |= ((bus & 0x1) << 25); \
+ tid |= (inst << 26)
-#define AT_HAS_TAG(val) ((val) & 0xffff)
-#define AT_GET_TAG(val) AT_HAS_TAG(val) - 1
+#define AT_HAS_TAG(val) ((val) & (1 << 24))
+#define AT_GET_TAG(val) (((val) >> 16) & 0xff)
#define AT_GET_INST(val) (((val) >> 26) & 0x3f)
#define AT_GET_BUS(val) (((val) >> 25) & 0x1)
-#define AT_GET_HANDLE(val) ((val) >> 16)
+#define AT_GET_HANDLE(val) ((val) & 0xffff)
#define IN_MAKE_TAGID(tid, bus, inst, inp) \
tid = inp->in_seqid; \
@@ -411,7 +374,7 @@ typedef struct {
u_int16_t at_rxid; /* response ID */
u_int16_t at_flags;
u_int16_t at_status; /* firmware status */
- u_int8_t at_reserved1;
+ u_int8_t at_crn; /* command reference number */
u_int8_t at_taskcodes;
u_int8_t at_taskflags;
u_int8_t at_execodes;
@@ -523,8 +486,7 @@ typedef struct {
*/
typedef struct {
isphdr_t ct_header;
- u_int16_t ct_reserved;
-#define ct_syshandle ct_reserved /* we use this */
+ u_int16_t ct_syshandle;
u_int16_t ct_fwhandle; /* required by f/w */
u_int8_t ct_lun; /* lun */
u_int8_t ct_iid; /* initiator id */
@@ -539,14 +501,7 @@ typedef struct {
u_int32_t ct_resid; /* residual length */
u_int16_t ct_timeout;
u_int16_t ct_seg_count;
- /*
- * This is so we can share tag name space with
- * CTIO{2,3,4} with the minimum of pain.
- */
- union {
- ispds_t ct_a[ISP_RQDSEG];
- } _u;
-#define ct_dataseg _u.ct_a
+ ispds_t ct_dataseg[ISP_RQDSEG];
} ct_entry_t;
/*
@@ -598,7 +553,7 @@ typedef struct {
#define CT_DATA_UNDER 0x15 /* (FC only) Data Underrun */
#define CT_BDR_MSG 0x17 /* Bus Device Reset msg received */
#define CT_TERMINATED 0x19 /* due to Terminate Transfer mbox cmd */
-#define CT_PORTNOTAVAIL 0x28 /* port not available */
+#define CT_PORTUNAVAIL 0x28 /* port not available */
#define CT_LOGOUT 0x29 /* port logout */
#define CT_PORTCHANGED 0x2A /* port changed */
#define CT_IDE 0x33 /* Initiator Detected Error */
@@ -627,8 +582,7 @@ typedef struct {
#define MAXRESPLEN 26
typedef struct {
isphdr_t ct_header;
- u_int16_t ct_reserved;
- u_int16_t ct_fwhandle; /* just to match CTIO */
+ u_int32_t ct_syshandle;
u_int8_t ct_lun; /* lun */
u_int8_t ct_iid; /* initiator id */
u_int16_t ct_rxid; /* response ID */
@@ -658,13 +612,10 @@ typedef struct {
u_int16_t ct_scsi_status;
u_int32_t ct_xfrlen;
union {
- ispds_t ct_a[ISP_RQDSEG_T2]; /* CTIO2 */
- ispds64_t ct_b[ISP_RQDSEG_T3]; /* CTIO3 */
- ispdslist_t ct_c; /* CTIO4 */
- } _u;
-#define ct_dataseg _u.ct_a
-#define ct_dataseg64 _u.ct_b
-#define ct_dslist _u.ct_c
+ ispds_t ct_dataseg[ISP_RQDSEG_T2];
+ ispds64_t ct_dataseg64[ISP_RQDSEG_T3];
+ ispdslist_t ct_dslist;
+ } u;
} m0;
struct {
u_int16_t _reserved;
@@ -681,14 +632,6 @@ typedef struct {
u_int32_t ct_datalen;
ispds_t ct_fcp_rsp_iudata;
} m2;
- /*
- * CTIO2 returned from F/W...
- */
- struct {
- u_int32_t _reserved[4];
- u_int16_t ct_scsi_status;
- u_int8_t ct_sense[QLTM_SENSELEN];
- } fw;
} rsp;
} ct2_entry_t;
@@ -740,10 +683,10 @@ typedef struct {
#define CT2_FLAG_MODE1 0x0001
#define CT2_FLAG_MODE2 0x0002
#define CT2_FLAG_MMASK 0x0003
-#define CT2_DATA_IN CT_DATA_IN
-#define CT2_DATA_OUT CT_DATA_OUT
-#define CT2_NO_DATA CT_NO_DATA
-#define CT2_DATAMASK CT_DATAMASK
+#define CT2_DATA_IN 0x0040
+#define CT2_DATA_OUT 0x0080
+#define CT2_NO_DATA 0x00C0
+#define CT2_DATAMASK 0x00C0
#define CT2_CCINCR 0x0100
#define CT2_FASTPOST 0x0200
#define CT2_CONFIRM 0x2000
@@ -948,7 +891,7 @@ typedef struct {
#define ISP_TDQE(isp, msg, idx, arg) \
if (isp->isp_dblev & ISP_LOGTDEBUG2) isp_print_qentry(isp, msg, idx, arg)
-#ifdef ISP_TARGET_FUNCTIONS
+#ifndef ISP_TOOLS
/*
* The functions below are for the publicly available
* target mode functions that are internal to the QLogic driver.
@@ -957,7 +900,7 @@ typedef struct {
/*
* This function handles new response queue entry appropriate for target mode.
*/
-int isp_target_notify(struct ispsoftc *, void *, u_int16_t *);
+int isp_target_notify(ispsoftc_t *, void *, u_int32_t *);
/*
* This function externalizes the ability to acknowledge an Immediate Notify
@@ -970,13 +913,13 @@ void isp_notify_ack(ispsoftc_t *, void *);
* (softc, cmd, bus, tgt, lun, cmd_cnt, inotify_cnt, opaque)
*/
#define DFLT_CMND_CNT 0xfe /* unmonitored */
-#define DFLT_INOT_CNT 16
-int isp_lun_cmd(struct ispsoftc *, int, int, int, int, int, int, u_int32_t);
+#define DFLT_INOT_CNT 0xfe /* unmonitored */
+int isp_lun_cmd(ispsoftc_t *, int, int, int, int, int, int, u_int32_t);
/*
* General request queue 'put' routine for target mode entries.
*/
-int isp_target_put_entry(struct ispsoftc *isp, void *);
+int isp_target_put_entry(ispsoftc_t *isp, void *);
/*
* General routine to put back an ATIO entry-
@@ -984,13 +927,13 @@ int isp_target_put_entry(struct ispsoftc *isp, void *);
* The argument is a pointer to a source ATIO
* or ATIO2.
*/
-int isp_target_put_atio(struct ispsoftc *, void *);
+int isp_target_put_atio(ispsoftc_t *, void *);
/*
* General routine to send a final CTIO for a command- used mostly for
* local responses.
*/
-int isp_endcmd(struct ispsoftc *, void *, u_int32_t, u_int16_t);
+int isp_endcmd(ispsoftc_t *, void *, u_int32_t, u_int32_t);
#define ECMD_SVALID 0x100
/*
@@ -998,7 +941,6 @@ int isp_endcmd(struct ispsoftc *, void *, u_int32_t, u_int16_t);
*
* Return nonzero if the interrupt that generated this event has been dismissed.
*/
-
-int isp_target_async(struct ispsoftc *, int, int);
+int isp_target_async(ispsoftc_t *, int, int);
#endif
#endif /* _ISP_TARGET_H */
diff --git a/sys/dev/ic/isp_tpublic.h b/sys/dev/ic/isp_tpublic.h
index 5c27602ba67..c6ff0aa6798 100644
--- a/sys/dev/ic/isp_tpublic.h
+++ b/sys/dev/ic/isp_tpublic.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: isp_tpublic.h,v 1.11 2008/11/01 18:54:27 krw Exp $ */
+/* $OpenBSD: isp_tpublic.h,v 1.12 2009/06/24 11:00:53 krw Exp $ */
/* $FreeBSD: src/sys/dev/isp/isp_tpublic.h,v 1.19 2007/05/05 20:17:23 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
@@ -39,10 +39,11 @@
*/
typedef enum {
QOUT_HBA_REG=0, /* the argument is a pointer to a hba_register_t */
- QOUT_TMD_START, /* the argument is a pointer to a tmd_cmd_t */
- QOUT_TMD_DONE, /* the argument is a pointer to a tmd_cmd_t */
- QOUT_TEVENT, /* the argument is a pointer to a tmd_event_t */
- QOUT_TMSG, /* the argument is a pointer to a tmd_msg_t */
+ QOUT_ENABLE, /* the argument is a pointer to a enadis_t */
+ QOUT_DISABLE, /* the argument is a pointer to a enadis_t */
+ QOUT_TMD_START, /* the argument is a pointer to a tmd_cmd_t */
+ QOUT_TMD_DONE, /* the argument is a pointer to a tmd_cmd_t */
+ QOUT_NOTIFY, /* the argument is a pointer to a tmd_notify_t */
QOUT_HBA_UNREG /* the argument is a pointer to a hba_register_t */
} tact_e;
@@ -51,28 +52,18 @@ typedef enum {
* MD driver to figure out what to do with.
*/
typedef enum {
- QIN_HBA_REG=6, /* the argument is a pointer to a hba_register_t */
- QIN_ENABLE, /* the argument is a pointer to a tmd_cmd_t */
- QIN_DISABLE, /* the argument is a pointer to a tmd_cmd_t */
+ QIN_HBA_REG=99, /* the argument is a pointer to a hba_register_t */
+ QIN_GETINFO, /* the argument is a pointer to a info_t */
+ QIN_SETINFO, /* the argument is a pointer to a info_t */
+ QIN_GETDLIST, /* the argument is a pointer to a fc_dlist_t */
+ QIN_ENABLE, /* the argument is a pointer to a enadis_t */
+ QIN_DISABLE, /* the argument is a pointer to a enadis_t */
QIN_TMD_CONT, /* the argument is a pointer to a tmd_cmd_t */
QIN_TMD_FIN, /* the argument is a pointer to a tmd_cmd_t */
+ QIN_NOTIFY_ACK, /* the argument is a pointer to a tmd_notify_t */
QIN_HBA_UNREG /* the argument is a pointer to a hba_register_t */
} qact_e;
-#ifndef IN_MSGLEN
-#define IN_MSGLEN 8
-#endif
-typedef struct {
- void * nt_hba; /* HBA tag */
- u_int64_t nt_iid; /* initiator id */
- u_int64_t nt_tgt; /* target id */
- u_int64_t nt_lun; /* logical unit */
- u_int8_t nt_bus; /* bus */
- u_int8_t nt_tagtype; /* tag type */
- u_int16_t nt_tagval; /* tag value */
- u_int8_t nt_msg[IN_MSGLEN]; /* message content */
-} tmd_msg_t;
-
/*
* This structure is used to register to other software modules the
* binding of an HBA identifier, driver name and instance and the
@@ -85,20 +76,18 @@ typedef struct {
*/
#define QR_VERSION 16
typedef struct {
- void * r_identity;
- char r_name[8];
- int r_inst;
- int r_lunwidth;
- int r_buswidth;
- void (*r_action)(int, void *);
+ /* NB: tags from here to r_version must never change */
+ void * r_identity;
+ void (*r_action)(qact_e, void *);
+ char r_name[8];
+ int r_inst;
+ int r_version;
+ u_int32_t r_locator;
+ u_int32_t r_nchannels;
+ enum { R_FC, R_SPI } r_type;
+ void * r_private;
} hba_register_t;
-typedef struct {
- void * ev_hba; /* HBA tag */
- u_int16_t ev_bus; /* bus */
- u_int16_t ev_event; /* type of async event */
-} tmd_event_t;
-
/*
* An information structure that is used to get or set per-channel transport layer parameters.
*/
@@ -295,26 +284,6 @@ typedef struct {
*
*/
-#ifndef _LP64
-#if defined(__alpha__) || defined(__sparcv9cpu) || defined(__sparc_v9__) ||\
- defined(__ia64__)
-#define _LP64
-#endif
-#endif
-
-#ifndef _TMD_PAD_LEN
-#ifdef _LP64
-#define _TMD_PAD_LEN 12
-#else
-#define _TMD_PAD_LEN 24
-#endif
-#endif
-#ifndef ATIO_CDBLEN
-#define ATIO_CDBLEN 26
-#endif
-#ifndef QLTM_SENSELEN
-#define QLTM_SENSELEN 18
-#endif
#ifndef TMD_CDBLEN
#define TMD_CDBLEN 16
#endif
@@ -331,20 +300,26 @@ typedef struct tmd_cmd {
void * cd_data; /* 'pointer' to data */
u_int64_t cd_iid; /* initiator ID */
u_int64_t cd_tgt; /* target id */
- u_int64_t cd_lun; /* logical unit */
- u_int8_t cd_bus; /* bus */
- u_int8_t cd_tagtype; /* tag type */
- u_int32_t cd_tagval; /* tag value */
- u_int8_t cd_cdb[ATIO_CDBLEN]; /* Command */
- u_int8_t cd_lflags; /* flags lower level sets */
- u_int8_t cd_hflags; /* flags higher level sets */
- u_int32_t cd_totlen; /* total data requirement */
+ u_int8_t cd_lun[8]; /* logical unit */
+ u_int64_t cd_tagval; /* tag value */
+ u_int32_t cd_channel; /* channel index */
+ u_int32_t cd_lflags; /* flags lower level sets */
+ u_int32_t cd_hflags; /* flags higher level sets */
+ u_int32_t cd_totlen; /* total data load */
u_int32_t cd_resid; /* total data residual */
u_int32_t cd_xfrlen; /* current data load */
int32_t cd_error; /* current error */
- u_int8_t cd_sense[QLTM_SENSELEN];
- u_int16_t cd_scsi_status; /* closing SCSI status */
- u_int8_t cd_reserved[_TMD_PAD_LEN];
+ u_int8_t cd_tagtype; /* tag type */
+ u_int8_t cd_scsi_status;
+ u_int8_t cd_sense[TMD_SENSELEN];
+ u_int8_t cd_cdb[TMD_CDBLEN];
+ union {
+ void * ptrs[QCDS / sizeof (void *)];
+ u_int64_t llongs[QCDS / sizeof (u_int64_t)];
+ u_int32_t longs[QCDS / sizeof (u_int32_t)];
+ u_int16_t shorts[QCDS / sizeof (u_int16_t)];
+ u_int8_t bytes[QCDS];
+ } cd_lreserved[4], cd_hreserved[4];
} tmd_cmd_t;
/* defined tags */
@@ -389,22 +364,21 @@ typedef struct tmd_cmd {
* flags CDFH_DATA_IN and CDFH_DATA_OUT define which direction.
*/
#define CDFL_SNSVALID 0x01 /* sense data (from f/w) good */
-#define CDFL_NODISC 0x02 /* disconnects disabled */
-#define CDFL_SENTSENSE 0x04 /* last action sent sense data */
-#define CDFL_SENTSTATUS 0x08 /* last action sent status */
-#define CDFL_BIDIR 0x0C /* bidirectional data */
-#define CDFL_ERROR 0x10 /* last action ended in error */
-#define CDFL_BUSY 0x40 /* this command is not on a free list */
-#define CDFL_PRIVATE_0 0x80 /* private layer flags */
-
+#define CDFL_SENTSTATUS 0x02 /* last action sent status */
+#define CDFL_DATA_IN 0x04 /* target (us) -> initiator (them) */
+#define CDFL_DATA_OUT 0x08 /* initiator (them) -> target (us) */
+#define CDFL_BIDIR 0x0C /* bidirectional data */
+#define CDFL_ERROR 0x10 /* last action ended in error */
+#define CDFL_NODISC 0x20 /* disconnects disabled */
+#define CDFL_SENTSENSE 0x40 /* last action sent sense data */
+#define CDFL_BUSY 0x80 /* this command is not on a free list */
+#define CDFL_PRIVATE 0xFF000000 /* private layer flags */
-#define CDFH_NODATA 0x00 /* no data transfer expected */
#define CDFH_SNSVALID 0x01 /* sense data (from outer layer) good */
#define CDFH_STSVALID 0x02 /* status valid */
#define CDFH_DATA_IN 0x04 /* target (us) -> initiator (them) */
#define CDFH_DATA_OUT 0x08 /* initiator (them) -> target (us) */
#define CDFH_DATA_MASK 0x0C /* mask to cover data direction */
-#define CDFH_PRIVATE_0 0x80 /* private layer flags */
#define CDFH_PRIVATE 0xFF000000 /* private layer flags */
diff --git a/sys/dev/ic/ispmbox.h b/sys/dev/ic/ispmbox.h
index b2ec96b60b6..b805c082923 100644
--- a/sys/dev/ic/ispmbox.h
+++ b/sys/dev/ic/ispmbox.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ispmbox.h,v 1.22 2008/11/02 03:17:22 krw Exp $ */
+/* $OpenBSD: ispmbox.h,v 1.23 2009/06/24 11:00:53 krw Exp $ */
/* $FreeBSD: src/sys/dev/isp/ispmbox.h,v 1.59 2007/03/10 02:39:54 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
@@ -165,10 +165,6 @@
#define MBOX_BUSY 0x04
-typedef struct {
- u_int16_t param[8];
-} mbreg_t;
-
/*
* Mailbox Command Complete Status Codes
*/
@@ -254,18 +250,6 @@ typedef struct {
*/
#define QENTRY_LEN 64
-#define WRITE_REQUEST_QUEUE_IN_POINTER(isp, value) \
- ISP_WRITE(isp, isp->isp_rqstinrp, value)
-
-#define READ_REQUEST_QUEUE_OUT_POINTER(isp) \
- ISP_READ(isp, isp->isp_rqstoutrp)
-
-#define READ_RESPONSE_QUEUE_IN_POINTER(isp) \
- ISP_READ(isp, isp->isp_respinrp)
-
-#define WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, value) \
- ISP_WRITE(isp, isp->isp_respoutrp, value)
-
/*
* Command Structure Definitions
*/
@@ -337,7 +321,7 @@ typedef struct {
#define RQSTYPE_T4RQS 0x15
#define RQSTYPE_ATIO2 0x16 /* Target Mode */
#define RQSTYPE_CTIO2 0x17 /* Target Mode */
-#define RQSTYPE_CSET0 0x18
+#define RQSTYPE_T7RQS 0x18
#define RQSTYPE_T3RQS 0x19
#define RQSTYPE_IP_XMIT_64 0x1b
#define RQSTYPE_CTIO4 0x1e /* Target Mode */
@@ -362,7 +346,6 @@ typedef struct {
u_int8_t req_lun_trn;
u_int8_t req_target;
u_int16_t req_cdblen;
-#define req_modifier req_cdblen /* marker packet */
u_int16_t req_flags;
u_int16_t req_reserved;
u_int16_t req_time;
@@ -826,7 +809,7 @@ typedef struct {
*
* Version One (prime) format.
*/
-typedef struct isp_icb {
+typedef struct {
u_int8_t icb_version;
u_int8_t icb_reserved0;
u_int16_t icb_fwoptions;
@@ -898,16 +881,15 @@ typedef struct isp_icb {
#define ICBXOPT_RIO_32BIT 2
#define ICBXOPT_RIO_16BIT_IOCB 3
#define ICBXOPT_RIO_32BIT_IOCB 4
-#define ICBXOPT_ZIO (1 << 5)
+#define ICBXOPT_ZIO 5
#define ICBXOPT_TIMER_MASK 0x7
+#define ICBZOPT_RATE_MASK 0xC000
+#define ICBZOPT_RATE_ONEGB 0x0000
+#define ICBZOPT_RATE_AUTO 0x8000
+#define ICBZOPT_RATE_TWOGB 0x4000
#define ICBZOPT_50_OHM 0x2000
#define ICBZOPT_ENA_OOF 0x0040 /* out of order frame handling */
-/* These 3 only apply to the 2300 */
-#define ICBZOPT_RATE_ONEGB (MBGSD_ONEGB << 14)
-#define ICBZOPT_RATE_TWOGB (MBGSD_TWOGB << 14)
-#define ICBZOPT_RATE_AUTO (MBGSD_AUTO << 14)
-
#define ICBZOPT_RSPSZ_MASK 0x0030
#define ICBZOPT_RSPSZ_24 0x0000
#define ICBZOPT_RSPSZ_12 0x0010
@@ -1030,22 +1012,6 @@ typedef struct {
array[ICB_NNM6] = (u_int8_t) ((wwn >> 48) & 0xff), \
array[ICB_NNM7] = (u_int8_t) ((wwn >> 56) & 0xff)
-/*
- * FC-AL Position Map
- *
- * This is an at most 128 byte map that returns either
- * the LILP or Firmware generated list of ports.
- *
- * We deviate a bit from the returned QLogic format to
- * use an extra bit to say whether this was a LILP or
- * f/w generated map.
- */
-typedef struct {
- u_int8_t fwmap : 1,
- count : 7;
- u_int8_t map[127];
-} fcpos_map_t;
-
#define MAKE_WWN_FROM_NODE_NAME(wwn, array) \
wwn = ((u_int64_t) array[ICB_NNM0]) | \
((u_int64_t) array[ICB_NNM1] << 8) | \
@@ -1099,7 +1065,7 @@ typedef struct {
u_int16_t pdb_loopid;
u_int16_t pdb_il_ptr;
u_int16_t pdb_sl_ptr;
-} isp_pdb_t;
+} isp_pdb_21xx_t;
#define PDB_OPTIONS_XMITTING (1<<11)
#define PDB_OPTIONS_LNKXMIT (1<<10)
@@ -1158,13 +1124,14 @@ typedef struct {
/*
* Common elements from the above two structures that are actually useful to us.
*/
-
-#define FS_ACC 0x8002
-#define FS_RJT 0x8001
-
-#define FC4_IP 5 /* ISO/EEC 8802-2 LLC/SNAP "Out of Order Delivery" */
-#define FC4_SCSI 8 /* SCSI-3 via Fivre Channel Protocol (FCP) */
-#define FC4_FC_SVC 0x20 /* Fibre Channel Services */
+typedef struct {
+ u_int16_t handle;
+ u_int16_t reserved;
+ u_int32_t s3_role : 8,
+ portid : 24;
+ u_int8_t portname[8];
+ u_int8_t nodename[8];
+} isp_pdb_t;
/*
* Genericized Port Login/Logout software structure
diff --git a/sys/dev/ic/ispreg.h b/sys/dev/ic/ispreg.h
index 2989672e587..5429c47d9dd 100644
--- a/sys/dev/ic/ispreg.h
+++ b/sys/dev/ic/ispreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ispreg.h,v 1.15 2008/10/25 22:53:30 krw Exp $ */
+/* $OpenBSD: ispreg.h,v 1.16 2009/06/24 11:00:53 krw Exp $ */
/* $FreeBSD: src/sys/dev/isp/ispreg.h,v 1.29 2007/03/10 02:39:54 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
@@ -203,7 +203,6 @@
#define BIU2100_FB_REGS (1 << 4) /* FrameBuffer Regs */
#define BIU2100_FPM0_REGS (2 << 4) /* FPM 0 Regs */
#define BIU2100_FPM1_REGS (3 << 4) /* FPM 1 Regs */
-#define BIU2100_PCI64 0x04 /* R: 64 Bit PCI slot */
#define BIU2100_NVRAM_OFFSET (1 << 14)
#define BIU2100_FLASH_UPPER_64K 0x04 /* RW: Upper 64K Bank Select */
#define BIU2100_FLASH_ENABLE 0x02 /* RW: Enable Flash RAM */
@@ -230,16 +229,7 @@
#define BIU2100_ICR_ENABLE_TXDMA_INT 0x0001
#define BIU2100_ICR_DISABLE_ALL_INTS 0x0000
-#define ENABLE_INTS(isp) (IS_SCSI(isp))? \
- ISP_WRITE(isp, BIU_ICR, BIU_ICR_ENABLE_RISC_INT | BIU_ICR_ENABLE_ALL_INTS) : \
- ISP_WRITE(isp, BIU_ICR, BIU2100_ICR_ENA_RISC_INT | BIU2100_ICR_ENABLE_ALL_INTS)
-
-#define INTS_ENABLED(isp) ((IS_SCSI(isp))? \
- (ISP_READ(isp, BIU_ICR) & (BIU_ICR_ENABLE_RISC_INT|BIU_ICR_ENABLE_ALL_INTS)) :\
- (ISP_READ(isp, BIU_ICR) & \
- (BIU2100_ICR_ENA_RISC_INT|BIU2100_ICR_ENABLE_ALL_INTS)))
-
-#define DISABLE_INTS(isp) ISP_WRITE(isp, BIU_ICR, 0)
+#define BIU2100_IMASK (BIU2100_ICR_ENA_RISC_INT|BIU2100_ICR_ENABLE_ALL_INTS)
/* BUS STATUS REGISTER */
#define BIU_ISR_DMA_INT 0x0020 /* DMA interrupt pending */
@@ -256,11 +246,14 @@
#define BIU2100_ISR_RXDMA_INT_PENDING 0x0002 /* Global interrupt pending */
#define BIU2100_ISR_TXDMA_INT_PENDING 0x0001 /* Global interrupt pending */
-#define INT_PENDING(isp, isr) (IS_FC(isp)? \
- ((isr & BIU2100_ISR_RISC_INT) != 0) : ((isr & BIU_ISR_RISC_INT) != 0))
+#define INT_PENDING(isp, isr) \
+ IS_FC(isp)? \
+ (IS_24XX(isp)? (isr & BIU2400_ISR_RISC_INT) : (isr & BIU2100_ISR_RISC_INT)) :\
+ (isr & BIU_ISR_RISC_INT)
#define INT_PENDING_MASK(isp) \
- (IS_FC(isp)? BIU2100_ISR_RISC_INT: BIU_ISR_RISC_INT)
+ (IS_FC(isp)? (IS_24XX(isp)? BIU2400_ISR_RISC_INT : BIU2100_ISR_RISC_INT) : \
+ (BIU_ISR_RISC_INT))
/* BUS SEMAPHORE REGISTER */
#define BIU_SEMA_STATUS 0x0002 /* Semaphore Status Bit */
@@ -464,12 +457,23 @@
#define MBOX_OFF(n) (MBOX_BLOCK + ((n) << 1))
#define NMBOX(isp) \
(((((isp)->isp_type & ISP_HA_SCSI) >= ISP_HA_SCSI_1040A) || \
- ((isp)->isp_type & ISP_HA_FC))? 8 : 6)
+ ((isp)->isp_type & ISP_HA_FC))? 12 : 6)
#define NMBOX_BMASK(isp) \
(((((isp)->isp_type & ISP_HA_SCSI) >= ISP_HA_SCSI_1040A) || \
- ((isp)->isp_type & ISP_HA_FC))? 0xff : 0x3f)
-
-#define MAX_MAILBOX 8
+ ((isp)->isp_type & ISP_HA_FC))? 0xfff : 0x3f)
+
+#define MAX_MAILBOX(isp) ((IS_FC(isp))? 12 : 8)
+#define MAILBOX_STORAGE 12
+/* if timeout == 0, then default timeout is picked */
+#define MBCMD_DEFAULT_TIMEOUT 100000 /* 100 ms */
+typedef struct {
+ u_int16_t param[MAILBOX_STORAGE];
+ u_int16_t ibits;
+ u_int16_t obits;
+ u_int32_t : 28,
+ logval : 4;
+ u_int32_t timeout;
+} mbreg_t;
/*
* Fibre Protocol Module and Frame Buffer Register Offsets/Definitions (2X00).
@@ -1046,7 +1050,7 @@
#define ISP2100_NVRAM_SIZE 256
/* ISP_NVRAM_VERSION is in same overall place */
#define ISP2100_NVRAM_RISCVER(c) (c)[6]
-#define ISP2100_NVRAM_OPTIONS(c) (c)[8]
+#define ISP2100_NVRAM_OPTIONS(c) ((c)[8] | ((c)[9] << 8))
#define ISP2100_NVRAM_MAXFRAMELENGTH(c) (((c)[10]) | ((c)[11] << 8))
#define ISP2100_NVRAM_MAXIOCBALLOCATION(c) (((c)[12]) | ((c)[13] << 8))
#define ISP2100_NVRAM_EXECUTION_THROTTLE(c) (((c)[14]) | ((c)[15] << 8))
@@ -1063,10 +1067,10 @@
(((u_int64_t)(c)[24]) << 8) | \
(((u_int64_t)(c)[25]) << 0))
-#define ISP2100_NVRAM_HARDLOOPID(c) (c)[26]
+#define ISP2100_NVRAM_HARDLOOPID(c) ((c)[26] | ((c)[27] << 8))
#define ISP2100_NVRAM_TOV(c) ((c)[29])
-#define ISP2200_NVRAM_NODE_NAME(c) (\
+#define ISP2100_NVRAM_NODE_NAME(c) (\
(((u_int64_t)(c)[30]) << 56) | \
(((u_int64_t)(c)[31]) << 48) | \
(((u_int64_t)(c)[32]) << 40) | \
@@ -1076,7 +1080,6 @@
(((u_int64_t)(c)[36]) << 8) | \
(((u_int64_t)(c)[37]) << 0))
-#define ISP2100_NVRAM_HBA_OPTIONS(c) (c)[70]
#define ISP2100_XFW_OPTIONS(c) ((c)[38] | ((c)[39] << 8))
#define ISP2100_RACC_TIMER(c) (c)[40]
@@ -1086,6 +1089,7 @@
#define ISP2100_SERIAL_LINK(c) ((c)[68] | ((c)[69] << 8))
+#define ISP2100_NVRAM_HBA_OPTIONS(c) ((c)[70] | ((c)[71] << 8))
#define ISP2100_NVRAM_HBA_DISABLE(c) ISPBSMX(c, 70, 0, 0x01)
#define ISP2100_NVRAM_BIOS_DISABLE(c) ISPBSMX(c, 70, 1, 0x01)
#define ISP2100_NVRAM_LUN_DISABLE(c) ISPBSMX(c, 70, 2, 0x01)
@@ -1106,7 +1110,7 @@
#define ISP2100_NVRAM_BOOT_LUN(c) (c)[80]
#define ISP2100_RESET_DELAY(c) (c)[81]
-#define ISP2200_HBA_FEATURES(c) (c)[232] | ((c)[233] << 8)
+#define ISP2100_HBA_FEATURES(c) ((c)[232] | ((c)[233] << 8))
/*
* Qlogic 2400 NVRAM is an array of 512 bytes with a 32 bit checksum.
diff --git a/sys/dev/ic/ispvar.h b/sys/dev/ic/ispvar.h
index fe90c295954..d0da6b35931 100644
--- a/sys/dev/ic/ispvar.h
+++ b/sys/dev/ic/ispvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ispvar.h,v 1.26 2008/11/02 03:17:22 krw Exp $ */
+/* $OpenBSD: ispvar.h,v 1.27 2009/06/24 11:00:53 krw Exp $ */
/* $FreeBSD: src/sys/dev/isp/ispvar.h,v 1.85 2007/07/02 20:08:20 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
@@ -36,49 +36,40 @@
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <dev/ic/isp_stds.h>
#include <dev/ic/ispmbox.h>
-#ifdef ISP_TARGET_MODE
-#include <dev/ic/isp_target.h>
-#include <dev/ic/isp_tpublic.h>
-#endif
#endif
#ifdef __FreeBSD__
#include <dev/isp/isp_stds.h>
#include <dev/isp/ispmbox.h>
-#ifdef ISP_TARGET_MODE
-#include <dev/isp/isp_target.h>
-#include <dev/isp/isp_tpublic.h>
-#endif
#endif
#ifdef __linux__
#include "isp_stds.h"
#include "ispmbox.h"
-#ifdef ISP_TARGET_MODE
-#include "isp_target.h"
-#include "isp_tpublic.h"
#endif
+#ifdef __svr4__
+#include "isp_stds.h"
+#include "ispmbox.h"
#endif
-#define ISP_CORE_VERSION_MAJOR 2
-#define ISP_CORE_VERSION_MINOR 7
+#define ISP_CORE_VERSION_MAJOR 3
+#define ISP_CORE_VERSION_MINOR 0
/*
* Vector for bus specific code to provide specific services.
*/
-struct ispsoftc;
+typedef struct ispsoftc ispsoftc_t;
struct ispmdvec {
int (*dv_rd_isr)
- (struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
- u_int16_t (*dv_rd_reg) (struct ispsoftc *, int);
- void (*dv_wr_reg) (struct ispsoftc *, int, u_int16_t);
+ (struct ispsoftc *, u_int32_t *, u_int16_t *, u_int16_t *);
+ u_int32_t (*dv_rd_reg) (struct ispsoftc *, int);
+ void (*dv_wr_reg) (struct ispsoftc *, int, u_int32_t);
int (*dv_mbxdma) (struct ispsoftc *);
- int (*dv_dmaset) (struct ispsoftc *,
- XS_T *, ispreq_t *, u_int16_t *, u_int16_t);
- void (*dv_dmaclr)
- (struct ispsoftc *, XS_T *, u_int16_t);
+ int (*dv_dmaset)
+ (struct ispsoftc *, XS_T *, ispreq_t *, u_int32_t *, u_int32_t);
+ void (*dv_dmaclr) (struct ispsoftc *, XS_T *, u_int32_t);
void (*dv_reset0) (struct ispsoftc *);
void (*dv_reset1) (struct ispsoftc *);
void (*dv_dregs) (struct ispsoftc *, const char *);
- u_int16_t *dv_ispfw; /* ptr to f/w */
+ const void * dv_ispfw; /* ptr to f/w */
u_int16_t dv_conf1;
u_int16_t dv_clock; /* clock frequency */
};
@@ -87,20 +78,11 @@ struct ispmdvec {
* Overall parameters
*/
#define MAX_TARGETS 16
-#define MAX_FC_TARG 256
+#define MAX_FC_TARG 512
#define ISP_MAX_TARGETS(isp) (IS_FC(isp)? MAX_FC_TARG : MAX_TARGETS)
#define ISP_MAX_LUNS(isp) (isp)->isp_maxluns
/*
- * 'Types'
- */
-#ifdef ISP_DAC_SUPPORTED
-typedef u_int64_t isp_dma_addr_t;
-#else
-typedef u_int32_t isp_dma_addr_t;
-#endif
-
-/*
* Macros to access ISP registers through bus specific layers-
* mostly wrappers to vector through the mdvec structure.
*/
@@ -163,7 +145,7 @@ typedef u_int32_t isp_dma_addr_t;
#define RESULT_QUEUE_LEN(x) \
(((MAXISPREQUEST(x) >> 2) < 64)? 64 : MAXISPREQUEST(x) >> 2)
#endif
-#define ISP_QUEUE_ENTRY(q, idx) ((q) + ((idx) * QENTRY_LEN))
+#define ISP_QUEUE_ENTRY(q, idx) (((u_int8_t *)q) + ((idx) * QENTRY_LEN))
#define ISP_QUEUE_SIZE(n) ((n) * QENTRY_LEN)
#define ISP_NXT_QENTRY(idx, qlen) (((idx) + 1) & ((qlen)-1))
#define ISP_QFREE(in, out, qlen) \
@@ -174,20 +156,22 @@ typedef u_int32_t isp_dma_addr_t;
#define ISP_ADD_REQUEST(isp, nxti) \
MEMORYBARRIER(isp, SYNC_REQUEST, isp->isp_reqidx, QENTRY_LEN); \
- WRITE_REQUEST_QUEUE_IN_POINTER(isp, nxti); \
+ ISP_WRITE(isp, isp->isp_rqstinrp, nxti); \
isp->isp_reqidx = nxti
/*
* SCSI Specific Host Adapter Parameters- per bus, per target
*/
-
typedef struct {
- u_int isp_gotdparms : 1,
+ u_int32_t : 10,
+ isp_bad_nvram : 1,
+ isp_gotdparms : 1,
isp_req_ack_active_neg : 1,
isp_data_line_active_neg: 1,
isp_cmd_dma_burst_enable: 1,
isp_data_dma_burst_enabl: 1,
isp_fifo_threshold : 3,
+ isp_ptisp : 1,
isp_ultramode : 1,
isp_diffmode : 1,
isp_lvdmode : 1,
@@ -249,14 +233,10 @@ typedef struct {
/*
* Fibre Channel Specifics
*/
-#define FL_PORT_ID 0x7e /* FL_Port Special ID */
-#define FC_PORT_ID 0x7f /* Fabric Controller Special ID */
-#define FC_SNS_ID 0x80 /* SNS Server Special ID */
-
-/* #define ISP_USE_GA_NXT 1 */ /* Use GA_NXT with switches */
-#ifndef GA_NXT_MAX
-#define GA_NXT_MAX 256
-#endif
+/* These are for non-2K Login Firmware cards */
+#define FL_ID 0x7e /* FL_Port Special ID */
+#define SNS_ID 0x80 /* SNS Server Special ID */
+#define NPH_MAX 0xfe
/* These are for 2K Login Firmware cards */
#define NPH_RESERVED 0x7F0 /* begin of reserved N-port handles */
@@ -333,64 +313,102 @@ typedef struct {
* value.
*/
typedef struct {
- u_int32_t isp_fwoptions : 16,
- isp_gbspeed : 2,
- isp_iid_set : 1,
- loop_seen_once : 1,
- isp_loopstate : 4, /* Current Loop State */
- isp_fwstate : 3, /* ISP F/W state */
+ /*
+ * This is the handle that the firmware needs in order for us to
+ * send commands to the device. For pre-24XX cards, this would be
+ * the 'loopid'.
+ */
+ u_int16_t handle;
+ /*
+ * The ini_map_idx, if nonzero, is the system virtual target ID (+1)
+ * as a cross-reference with the isp_ini_map.
+ *
+ * A device is 'autologin' if the firmware automatically logs into
+ * it (re-logins as needed). Basically, local private loop devices.
+ *
+ * The state is the current state of thsi entry.
+ *
+ * Role is Initiator, Target, Both
+ *
+ * Portid is obvious, as or node && port WWNs. The new_role and
+ * new_portid is for when we are pending a change.
+ */
+ u_int16_t ini_map_idx : 12,
+ autologin : 1, /* F/W does PLOGI/PLOGO */
+ state : 3;
+ u_int32_t reserved : 6,
+ roles : 2,
+ portid : 24;
+ u_int32_t new_reserved : 6,
+ new_roles : 2,
+ new_portid : 24;
+ u_int64_t node_wwn;
+ u_int64_t port_wwn;
+} fcportdb_t;
+
+#define FC_PORTDB_STATE_NIL 0
+#define FC_PORTDB_STATE_PROBATIONAL 1
+#define FC_PORTDB_STATE_DEAD 2
+#define FC_PORTDB_STATE_CHANGED 3
+#define FC_PORTDB_STATE_NEW 4
+#define FC_PORTDB_STATE_PENDING_VALID 5
+#define FC_PORTDB_STATE_ZOMBIE 6
+#define FC_PORTDB_STATE_VALID 7
+
+/*
+ * FC card specific information
+ */
+typedef struct {
+ u_int32_t : 10,
+ isp_tmode : 1,
+ isp_2klogin : 1,
+ isp_sccfw : 1,
+ isp_gbspeed : 3,
+ : 1,
+ : 1,
isp_gotdparms : 1,
+ isp_bad_nvram : 1,
+ isp_loopstate : 4, /* Current Loop State */
+ isp_fwstate : 4, /* ISP F/W state */
isp_topo : 3,
- isp_onfabric : 1;
- u_int8_t isp_iid; /* 'initiator' id */
- u_int8_t isp_loopid; /* hard loop id */
- u_int8_t isp_alpa; /* ALPA */
- u_int32_t isp_portid;
- volatile u_int16_t isp_lipseq; /* LIP sequence # */
+ loop_seen_once : 1;
+ u_int32_t : 8,
+ isp_portid : 24; /* S_ID */
+ u_int16_t isp_fwoptions;
+ u_int16_t isp_xfwoptions;
+ u_int16_t isp_zfwoptions;
+ u_int16_t isp_loopid; /* hard loop id */
u_int16_t isp_fwattr; /* firmware attributes */
- u_int8_t isp_execthrottle;
+ u_int16_t isp_execthrottle;
u_int8_t isp_retry_delay;
u_int8_t isp_retry_count;
u_int8_t isp_reserved;
u_int16_t isp_maxalloc;
u_int16_t isp_maxfrmlen;
- u_int64_t isp_nodewwn;
- u_int64_t isp_portwwn;
+ u_int64_t isp_wwnn_nvram;
+ u_int64_t isp_wwpn_nvram;
+
/*
- * Port Data Base. This is indexed by 'target', which is invariate.
- * However, elements within can move around due to loop changes,
- * so the actual loop ID passed to the F/W is in this structure.
- * The first time the loop is seen up, loopid will match the index
- * (except for fabric nodes which are above mapped above FC_SNS_ID
- * and are completely virtual), but subsequent LIPs can cause things
- * to move around.
+ * Our Port Data Base
*/
- struct lportdb {
- u_int32_t
- port_type : 8,
- loopid : 8,
- fc4_type : 4,
- last_fabric_dev : 1,
- : 2,
- relogin : 1,
- force_logout : 1,
- was_fabric_dev : 1,
- fabric_dev : 1,
- loggedin : 1,
- roles : 2,
- valid : 1;
- u_int32_t portid;
- u_int64_t node_wwn;
- u_int64_t port_wwn;
- } portdb[MAX_FC_TARG], tport[FC_PORT_ID];
+ fcportdb_t portdb[MAX_FC_TARG];
+
+ /*
+ * This maps system virtual 'target' id to a portdb entry.
+ *
+ * The mapping function is to take any non-zero entry and
+ * subtract one to get the portdb index. This means that
+ * entries which are zero are unmapped (i.e., don't exist).
+ */
+ u_int16_t isp_ini_map[MAX_FC_TARG];
/*
* Scratch DMA mapped in area to fetch Port Database stuff, etc.
*/
- caddr_t isp_scratch;
- isp_dma_addr_t isp_scdma;
+ void * isp_scratch;
+ XS_DMA_ADDR_T isp_scdma;
#ifdef ISP_FW_CRASH_DUMP
- u_int16_t *isp_dump_data;
+ u_int16_t * isp_dump_data;
#endif
} fcparam;
@@ -406,10 +424,10 @@ typedef struct {
#define LOOP_NIL 0
#define LOOP_LIP_RCVD 1
#define LOOP_PDB_RCVD 2
-#define LOOP_SCANNING_FABRIC 3
-#define LOOP_FSCAN_DONE 4
-#define LOOP_SCANNING_LOOP 5
-#define LOOP_LSCAN_DONE 6
+#define LOOP_SCANNING_LOOP 3
+#define LOOP_LSCAN_DONE 4
+#define LOOP_SCANNING_FABRIC 5
+#define LOOP_FSCAN_DONE 6
#define LOOP_SYNCING_PDB 7
#define LOOP_READY 8
@@ -422,7 +440,7 @@ typedef struct {
/*
* Soft Structure per host adapter
*/
-typedef struct ispsoftc {
+struct ispsoftc {
/*
* Platform (OS) specific data
*/
@@ -459,10 +477,12 @@ typedef struct ispsoftc {
u_int32_t isp_confopts; /* config options */
- u_int16_t isp_rqstinrp; /* register for REQINP */
- u_int16_t isp_rqstoutrp; /* register for REQOUTP */
- u_int16_t isp_respinrp; /* register for RESINP */
- u_int16_t isp_respoutrp; /* register for RESOUTP */
+ u_int32_t isp_rqstinrp; /* register for REQINP */
+ u_int32_t isp_rqstoutrp; /* register for REQOUTP */
+ u_int32_t isp_respinrp; /* register for RESINP */
+ u_int32_t isp_respoutrp; /* register for RESOUTP */
+ u_int32_t isp_atioinrp; /* register for ATIOINP */
+ u_int32_t isp_atiooutrp; /* register for ATIOOUTP */
/*
* Instrumentation
@@ -480,24 +500,25 @@ typedef struct ispsoftc {
* Volatile state
*/
- volatile u_int32_t
- isp_obits : 8, /* mailbox command output */
+ volatile u_int32_t : 8,
isp_mboxbsy : 1, /* mailbox command active */
isp_state : 3,
isp_sendmarker : 2, /* send a marker entry */
isp_update : 2, /* update parameters */
isp_nactive : 16; /* how many commands active */
- volatile u_int16_t isp_reqodx; /* index of last ISP pickup */
- volatile u_int16_t isp_reqidx; /* index of next request */
- volatile u_int16_t isp_residx; /* index of next result */
- volatile u_int16_t isp_resodx; /* index of next result */
- volatile u_int16_t isp_rspbsy;
- volatile u_int16_t isp_lasthdls; /* last handle seed */
- volatile u_int16_t isp_mboxtmp[MAX_MAILBOX];
+ volatile u_int32_t isp_reqodx; /* index of last ISP pickup */
+ volatile u_int32_t isp_reqidx; /* index of next request */
+ volatile u_int32_t isp_residx; /* index of next result */
+ volatile u_int32_t isp_resodx; /* index of next result */
+ volatile u_int32_t isp_rspbsy;
+ volatile u_int32_t isp_lasthdls; /* last handle seed */
+ volatile u_int32_t isp_obits; /* mailbox command output */
+ volatile u_int16_t isp_mboxtmp[MAILBOX_STORAGE];
volatile u_int16_t isp_lastmbxcmd; /* last mbox command sent */
volatile u_int16_t isp_mbxwrk0;
volatile u_int16_t isp_mbxwrk1;
volatile u_int16_t isp_mbxwrk2;
+ volatile u_int16_t isp_mbxwrk8;
void * isp_mbxworkp;
/*
@@ -505,14 +526,26 @@ typedef struct ispsoftc {
*/
XS_T **isp_xflist;
+#ifdef ISP_TARGET_MODE
+ /*
+ * Active target commands are stored here, indexed by handle function.
+ */
+ void **isp_tgtlist;
+#endif
+
/*
- * request/result queue pointers and dma handles for them.
+ * request/result queue pointers and DMA handles for them.
*/
- caddr_t isp_rquest;
- caddr_t isp_result;
- isp_dma_addr_t isp_rquest_dma;
- isp_dma_addr_t isp_result_dma;
-} ispsoftc_t;
+ void * isp_rquest;
+ void * isp_result;
+ XS_DMA_ADDR_T isp_rquest_dma;
+ XS_DMA_ADDR_T isp_result_dma;
+#ifdef ISP_TARGET_MODE
+ /* for 24XX only */
+ void * isp_atioq;
+ XS_DMA_ADDR_T isp_atioq_dma;
+#endif
+};
#define SDPARAM(isp) ((sdparam *) (isp)->isp_param)
#define FCPARAM(isp) ((fcparam *) (isp)->isp_param)
@@ -521,9 +554,10 @@ typedef struct ispsoftc {
* ISP Driver Run States
*/
#define ISP_NILSTATE 0
-#define ISP_RESETSTATE 1
-#define ISP_INITSTATE 2
-#define ISP_RUNSTATE 3
+#define ISP_CRASHED 1
+#define ISP_RESETSTATE 2
+#define ISP_INITSTATE 3
+#define ISP_RUNSTATE 4
/*
* ISP Configuration Options
@@ -567,8 +601,8 @@ typedef struct ispsoftc {
*
*/
#define ISP_ROLE_NONE 0x0
-#define ISP_ROLE_INITIATOR 0x1
-#define ISP_ROLE_TARGET 0x2
+#define ISP_ROLE_TARGET 0x1
+#define ISP_ROLE_INITIATOR 0x2
#define ISP_ROLE_BOTH (ISP_ROLE_TARGET|ISP_ROLE_INITIATOR)
#define ISP_ROLE_EITHER ISP_ROLE_BOTH
#ifndef ISP_DEFAULT_ROLES
@@ -649,7 +683,8 @@ typedef struct ispsoftc {
#define IS_FC(isp) ((isp)->isp_type & ISP_HA_FC)
#define IS_2100(isp) ((isp)->isp_type == ISP_HA_FC_2100)
#define IS_2200(isp) ((isp)->isp_type == ISP_HA_FC_2200)
-#define IS_23XX(isp) ((isp)->isp_type >= ISP_HA_FC_2300)
+#define IS_23XX(isp) ((isp)->isp_type >= ISP_HA_FC_2300 && \
+ (isp)->isp_type < ISP_HA_FC_2400)
#define IS_2300(isp) ((isp)->isp_type == ISP_HA_FC_2300)
#define IS_2312(isp) ((isp)->isp_type == ISP_HA_FC_2312)
#define IS_2322(isp) ((isp)->isp_type == ISP_HA_FC_2322)
@@ -658,15 +693,10 @@ typedef struct ispsoftc {
/*
* DMA related macros
*/
-#ifdef ISP_DAC_SUPPORTRED
-#define DMA_WD3(x) (((x) >> 48) & 0xffff)
-#define DMA_WD2(x) (((x) >> 32) & 0xffff)
-#else
-#define DMA_WD3(x) 0
-#define DMA_WD2(x) 0
-#endif
-#define DMA_WD1(x) (((x) >> 16) & 0xffff)
-#define DMA_WD0(x) (((x) & 0xffff))
+#define DMA_WD3(x) (((u_int16_t)(((u_int64_t)x) >> 48)) & 0xffff)
+#define DMA_WD2(x) (((u_int16_t)(((u_int64_t)x) >> 32)) & 0xffff)
+#define DMA_WD1(x) ((u_int16_t)((x) >> 16) & 0xffff)
+#define DMA_WD0(x) ((u_int16_t)((x) & 0xffff))
#define DMA_LO32(x) ((u_int32_t) (x))
#define DMA_HI32(x) ((u_int32_t)(((u_int64_t)x) >> 32))
@@ -705,7 +735,7 @@ void isp_fw_dump(struct ispsoftc *isp);
* semaphore register and first mailbox register (if appropriate). This also
* means that most spurious/bogus interrupts not for us can be filtered first.
*/
-void isp_intr(struct ispsoftc *, u_int16_t, u_int16_t, u_int16_t);
+void isp_intr(struct ispsoftc *, u_int32_t, u_int16_t, u_int16_t);
/*
@@ -768,9 +798,11 @@ typedef enum {
ISPCTL_SCAN_LOOP, /* (Re)scan Local Loop */
ISPCTL_PDB_SYNC, /* Synchronize Port Database */
ISPCTL_SEND_LIP, /* Send a LIP */
- ISPCTL_GET_POSMAP, /* Get FC-AL position map */
+ ISPCTL_GET_PORTNAME, /* get portname from an N-port handle */
ISPCTL_RUN_MBOXCMD, /* run a mailbox command */
- ISPCTL_TOGGLE_TMODE /* toggle target mode */
+ ISPCTL_TOGGLE_TMODE, /* toggle target mode */
+ ISPCTL_GET_PDB, /* get a single port database entry */
+ ISPCTL_PLOGX /* do a port login/logout */
} ispctl_t;
int isp_control(struct ispsoftc *, ispctl_t, void *);
@@ -823,11 +855,12 @@ typedef enum {
ISPASYNC_LIP, /* LIP Received */
ISPASYNC_LOOP_RESET, /* Loop Reset Received */
ISPASYNC_CHANGE_NOTIFY, /* FC Change Notification */
- ISPASYNC_FABRIC_DEV, /* FC Fabric Device Arrival */
- ISPASYNC_PROMENADE, /* FC Objects coming && going */
- ISPASYNC_TARGET_MESSAGE, /* target message */
- ISPASYNC_TARGET_EVENT, /* target asynchronous event */
- ISPASYNC_TARGET_ACTION, /* other target command action */
+ ISPASYNC_DEV_ARRIVED, /* FC Device Arrival */
+ ISPASYNC_DEV_CHANGED, /* FC Device Change */
+ ISPASYNC_DEV_STAYED, /* FC Device Stayed the Same */
+ ISPASYNC_DEV_GONE, /* FC Device Depart */
+ ISPASYNC_TARGET_NOTIFY, /* target asynchronous notification event */
+ ISPASYNC_TARGET_ACTION, /* target action requested */
ISPASYNC_CONF_CHANGE, /* Platform Configuration Change */
ISPASYNC_UNHANDLED_RESPONSE, /* Unhandled Response Entry */
ISPASYNC_FW_CRASH, /* Firmware has crashed */
@@ -850,12 +883,6 @@ int isp_async(struct ispsoftc *, ispasync_t, void *);
* but due to compiler differences on different platforms this won't be
* formally done here. Instead, it goes in each platform definition file.
*/
-#ifdef __GNUC__
-void isp_prt(struct ispsoftc *, int level, const char *, ...)
- __attribute__((__format__(__printf__,3,4)));
-#else
-void isp_prt(struct ispsoftc *, int level, const char *, ...);
-#endif
#define ISP_LOGALL 0x0 /* log always */
#define ISP_LOGCONFIG 0x1 /* log configuration messages */
@@ -866,7 +893,7 @@ void isp_prt(struct ispsoftc *, int level, const char *, ...);
#define ISP_LOGDEBUG1 0x20 /* log intermediate debug messages */
#define ISP_LOGDEBUG2 0x40 /* log most debug messages */
#define ISP_LOGDEBUG3 0x80 /* log high frequency debug messages */
-#define ISP_LOGDEBUG4 0x100 /* log high frequency debug messages */
+#define ISP_LOGSANCFG 0x100 /* log SAN configuration */
#define ISP_LOGTDEBUG0 0x200 /* log simple debug messages (target mode) */
#define ISP_LOGTDEBUG1 0x400 /* log intermediate debug messages (target) */
#define ISP_LOGTDEBUG2 0x800 /* log all debug messages (target) */
@@ -906,7 +933,7 @@ void isp_prt(struct ispsoftc *, int level, const char *, ...);
* of the same object is consistent.
*
* MBOX_ACQUIRE(struct ispsoftc *) acquire lock on mailbox regs
- * MBOX_WAIT_COMPLETE(struct ispsoftc *) wait for mailbox cmd to be done
+ * MBOX_WAIT_COMPLETE(struct ispsoftc *, mbreg_t *) wait for cmd to be done
* MBOX_NOTIFY_COMPLETE(struct ispsoftc *) notification of mbox cmd donee
* MBOX_RELEASE(struct ispsoftc *) release lock on mailbox regs
*
@@ -919,6 +946,7 @@ void isp_prt(struct ispsoftc *, int level, const char *, ...);
* SCSI_QFULL SCSI 'Queue Full' Status
*
* XS_T Platform SCSI transaction type (i.e., command for HBA)
+ * XS_DMA_ADDR_T Platform PCI DMA Address Type
* XS_ISP(xs) gets an instance out of an XS_T
* XS_CHANNEL(xs) gets the channel (bus # for DUALBUS cards) ""
* XS_TGT(xs) gets the target ""
@@ -950,17 +978,17 @@ void isp_prt(struct ispsoftc *, int level, const char *, ...);
* XS_NOERR(xs) there is no error currently set
* XS_INITERR(xs) initialize error state
*
- * XS_SAVE_SENSE(xs, sp) save sense data
+ * XS_SAVE_SENSE(xs, sp, len) save sense data
*
* XS_SET_STATE_STAT(isp, sp, xs) platform dependent interpreter of
* response queue entry status bits
*
*
* DEFAULT_IID(struct ispsoftc *) Default SCSI initiator ID
- * DEFAULT_LOOPID(struct ispsoftc *) Default FC Loop ID
- * DEFAULT_NODEWWN(struct ispsoftc *) Default Node WWN
- * DEFAULT_PORTWWN(struct ispsoftc *) Default Port WWN
- * DEFAULT_FRAMESIZE(struct ispsoftc *) Default Frame Size
+ * DEFAULT_LOOPID(struct ispsoftc *) Default FC Loop ID
+ * DEFAULT_NODEWWN(struct ispsoftc *) Default Node WWN
+ * DEFAULT_PORTWWN(struct ispsoftc *) Default Port WWN
+ * DEFAULT_FRAMESIZE(struct ispsoftc *) Default Frame Size
* DEFAULT_EXEC_THROTTLE(struct ispsoftc *) Default Execution Throttle
* These establish reasonable defaults for each platform.
* These must be available independent of card NVRAM and are
@@ -970,7 +998,7 @@ void isp_prt(struct ispsoftc *, int level, const char *, ...);
* ISP_PORTWWN(struct ispsoftc *) FC Port WWN to use
*
* These are to be used after NVRAM is read. The tags
- * in fcparam.isp_{node,port}wwn reflect the values
+ * in fcparam.isp_ww{n,p}n_nvram reflect the values
* read from NVRAM (possibly corrected for card botches).
* Each platform can take that information and override
* it or ignore and return the Node and Port WWNs to be
diff --git a/sys/dev/pci/isp_pci.c b/sys/dev/pci/isp_pci.c
index 3f12d0a40cd..a0caffdc95c 100644
--- a/sys/dev/pci/isp_pci.c
+++ b/sys/dev/pci/isp_pci.c
@@ -1,12 +1,8 @@
-/* $OpenBSD: isp_pci.c,v 1.46 2009/05/31 17:42:13 miod Exp $ */
-/*
- * PCI specific probe and attach routines for QLogic ISP SCSI adapters.
- *
- *---------------------------------------
- * Copyright (c) 1997, 1998, 1999 by Matthew Jacob
- * NASA/Ames Research Center
+/* $OpenBSD: isp_pci.c,v 1.47 2009/06/24 11:00:53 krw Exp $ */
+/* $FreeBSD: src/sys/dev/isp/isp_pci.c,v 1.148 2007/06/26 23:08:57 mjacob Exp $*/
+/*-
+ * Copyright (c) 1997-2006 by Matthew Jacob
* All rights reserved.
- *---------------------------------------
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -14,10 +10,7 @@
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
+ * 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
@@ -31,7 +24,10 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
+ */
+/*
+ * PCI specific probe and attach routines for Qlogic ISP SCSI adapters.
+ * FreeBSD Version.
*/
#include <dev/ic/isp_openbsd.h>
@@ -48,79 +44,36 @@
#include <mips64/archtype.h>
#endif
-static u_int16_t isp_pci_rd_reg(struct ispsoftc *, int);
-static void isp_pci_wr_reg(struct ispsoftc *, int, u_int16_t);
-#if !(defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT))
-static u_int16_t isp_pci_rd_reg_1080(struct ispsoftc *, int);
-static void isp_pci_wr_reg_1080(struct ispsoftc *, int, u_int16_t);
-#endif
-static int
-isp_pci_rd_isr(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
-#ifndef ISP_DISABLE_2300_SUPPORT
-static int
-isp_pci_rd_isr_2300(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
-#endif
-static int isp_pci_mbxdma(struct ispsoftc *);
-static int isp_pci_dmasetup(struct ispsoftc *, struct scsi_xfer *,
- ispreq_t *, u_int16_t *, u_int16_t);
-static void
-isp_pci_dmateardown (struct ispsoftc *, struct scsi_xfer *, u_int16_t);
-static void isp_pci_reset1 (struct ispsoftc *);
-static void isp_pci_dumpregs (struct ispsoftc *, const char *);
-static int isp_pci_intr (void *);
-
-#ifdef ISP_COMPILE_FW
-#define ISP_COMPILE_1040_FW 1
-#define ISP_COMPILE_1080_FW 1
-#define ISP_COMPILE_12160_FW 1
-#define ISP_COMPILE_2100_FW 1
-#define ISP_COMPILE_2200_FW 1
-#define ISP_COMPILE_2300_FW 1
-#endif
-
-#if defined(ISP_DISABLE_1040_SUPPORT) || !defined(ISP_COMPILE_1040_FW)
-#define ISP_1040_RISC_CODE NULL
-#else
-#define ISP_1040_RISC_CODE (u_int16_t *) isp_1040_risc_code
#include <dev/microcode/isp/asm_1040.h>
-#endif
-
-#if defined(ISP_DISABLE_1080_SUPPORT) || !defined(ISP_COMPILE_1080_FW)
-#define ISP_1080_RISC_CODE NULL
-#else
-#define ISP_1080_RISC_CODE (u_int16_t *) isp_1080_risc_code
#include <dev/microcode/isp/asm_1080.h>
-#endif
-
-#if defined(ISP_DISABLE_12160_SUPPORT) || !defined(ISP_COMPILE_12160_FW)
-#define ISP_12160_RISC_CODE (u_int16_t *) NULL
-#else
-#define ISP_12160_RISC_CODE (u_int16_t *) isp_12160_risc_code
#include <dev/microcode/isp/asm_12160.h>
-#endif
-
-#if defined(ISP_DISABLE_2100_SUPPORT) || !defined(ISP_COMPILE_2100_FW)
-#define ISP_2100_RISC_CODE NULL
-#else
-#define ISP_2100_RISC_CODE (u_int16_t *) isp_2100_risc_code
#include <dev/microcode/isp/asm_2100.h>
-#endif
-
-#if defined(ISP_DISABLE_2200_SUPPORT) || !defined(ISP_COMPILE_2200_FW)
-#define ISP_2200_RISC_CODE NULL
-#else
-#define ISP_2200_RISC_CODE (u_int16_t *) isp_2200_risc_code
#include <dev/microcode/isp/asm_2200.h>
-#endif
-
-#if defined(ISP_DISABLE_2300_SUPPORT) || !defined(ISP_COMPILE_2300_FW)
-#define ISP_2300_RISC_CODE NULL
-#else
-#define ISP_2300_RISC_CODE (u_int16_t *) isp_2300_risc_code
#include <dev/microcode/isp/asm_2300.h>
-#endif
+#include <dev/microcode/isp/asm_2400.h>
+
+#define BUS_PROBE_DEFAULT 0
+
+uint32_t isp_pci_rd_reg(ispsoftc_t *, int);
+void isp_pci_wr_reg(ispsoftc_t *, int, uint32_t);
+uint32_t isp_pci_rd_reg_1080(ispsoftc_t *, int);
+void isp_pci_wr_reg_1080(ispsoftc_t *, int, uint32_t);
+uint32_t isp_pci_rd_reg_2400(ispsoftc_t *, int);
+void isp_pci_wr_reg_2400(ispsoftc_t *, int, uint32_t);
+int isp_pci_rd_isr(ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *);
+int isp_pci_rd_isr_2300(ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *);
+int isp_pci_rd_isr_2400(ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *);
+int isp_pci_mbxdma(ispsoftc_t *);
+int isp_pci_dmasetup(ispsoftc_t *, XS_T *, ispreq_t *, uint32_t *, uint32_t);
+void isp_pci_reset0(ispsoftc_t *);
+void isp_pci_reset1(ispsoftc_t *);
+void isp_pci_dumpregs(ispsoftc_t *, const char *);
+
+
+int isp_pci_rd_debounced(struct ispsoftc *, int, u_int16_t *);
+int isp_pci_intr (void *);
+void isp_pci_dmateardown(struct ispsoftc *, XS_T *, u_int32_t);
-#ifndef ISP_DISABLE_1020_SUPPORT
static struct ispmdvec mdvec = {
isp_pci_rd_isr,
isp_pci_rd_reg,
@@ -128,15 +81,13 @@ static struct ispmdvec mdvec = {
isp_pci_mbxdma,
isp_pci_dmasetup,
isp_pci_dmateardown,
- NULL,
+ isp_pci_reset0,
isp_pci_reset1,
isp_pci_dumpregs,
- ISP_1040_RISC_CODE,
+ NULL,
BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
};
-#endif
-#ifndef ISP_DISABLE_1080_SUPPORT
static struct ispmdvec mdvec_1080 = {
isp_pci_rd_isr,
isp_pci_rd_reg_1080,
@@ -144,15 +95,13 @@ static struct ispmdvec mdvec_1080 = {
isp_pci_mbxdma,
isp_pci_dmasetup,
isp_pci_dmateardown,
- NULL,
+ isp_pci_reset0,
isp_pci_reset1,
isp_pci_dumpregs,
- ISP_1080_RISC_CODE,
+ isp_1080_risc_code,
BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
};
-#endif
-#ifndef ISP_DISABLE_12160_SUPPORT
static struct ispmdvec mdvec_12160 = {
isp_pci_rd_isr,
isp_pci_rd_reg_1080,
@@ -160,15 +109,13 @@ static struct ispmdvec mdvec_12160 = {
isp_pci_mbxdma,
isp_pci_dmasetup,
isp_pci_dmateardown,
- NULL,
+ isp_pci_reset0,
isp_pci_reset1,
isp_pci_dumpregs,
- ISP_12160_RISC_CODE,
+ isp_12160_risc_code,
BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
};
-#endif
-#ifndef ISP_DISABLE_2100_SUPPORT
static struct ispmdvec mdvec_2100 = {
isp_pci_rd_isr,
isp_pci_rd_reg,
@@ -176,14 +123,12 @@ static struct ispmdvec mdvec_2100 = {
isp_pci_mbxdma,
isp_pci_dmasetup,
isp_pci_dmateardown,
- NULL,
+ isp_pci_reset0,
isp_pci_reset1,
isp_pci_dumpregs,
- ISP_2100_RISC_CODE
+ isp_2100_risc_code
};
-#endif
-#ifndef ISP_DISABLE_2200_SUPPORT
static struct ispmdvec mdvec_2200 = {
isp_pci_rd_isr,
isp_pci_rd_reg,
@@ -191,14 +136,12 @@ static struct ispmdvec mdvec_2200 = {
isp_pci_mbxdma,
isp_pci_dmasetup,
isp_pci_dmateardown,
- NULL,
+ isp_pci_reset0,
isp_pci_reset1,
isp_pci_dumpregs,
- ISP_2200_RISC_CODE
+ isp_2200_risc_code
};
-#endif
-#ifndef ISP_DISABLE_2300_SUPPORT
static struct ispmdvec mdvec_2300 = {
isp_pci_rd_isr_2300,
isp_pci_rd_reg,
@@ -206,15 +149,58 @@ static struct ispmdvec mdvec_2300 = {
isp_pci_mbxdma,
isp_pci_dmasetup,
isp_pci_dmateardown,
- NULL,
+ isp_pci_reset0,
isp_pci_reset1,
isp_pci_dumpregs,
- ISP_2300_RISC_CODE
+ isp_2300_risc_code
+};
+
+static struct ispmdvec mdvec_2400 = {
+ isp_pci_rd_isr_2400,
+ isp_pci_rd_reg_2400,
+ isp_pci_wr_reg_2400,
+ isp_pci_mbxdma,
+ isp_pci_dmasetup,
+ isp_pci_dmateardown,
+ isp_pci_reset0,
+ isp_pci_reset1,
+ NULL
};
+
+#ifndef PCIM_CMD_INVEN
+#define PCIM_CMD_INVEN 0x10
+#endif
+#ifndef PCIM_CMD_BUSMASTEREN
+#define PCIM_CMD_BUSMASTEREN 0x0004
+#endif
+#ifndef PCIM_CMD_PERRESPEN
+#define PCIM_CMD_PERRESPEN 0x0040
+#endif
+#ifndef PCIM_CMD_SEREN
+#define PCIM_CMD_SEREN 0x0100
+#endif
+#ifndef PCIM_CMD_INTX_DISABLE
+#define PCIM_CMD_INTX_DISABLE 0x0400
+#endif
+
+#ifndef PCIR_COMMAND
+#define PCIR_COMMAND 0x04
+#endif
+
+#ifndef PCIR_CACHELNSZ
+#define PCIR_CACHELNSZ 0x0c
+#endif
+
+#ifndef PCIR_LATTIMER
+#define PCIR_LATTIMER 0x0d
+#endif
+
+#ifndef PCIR_ROMADDR
+#define PCIR_ROMADDR 0x30
#endif
#ifndef PCI_VENDOR_QLOGIC
-#define PCI_VENDOR_QLOGIC 0x1077
+#define PCI_VENDOR_QLOGIC 0x1077
#endif
#ifndef PCI_PRODUCT_QLOGIC_ISP1020
@@ -225,14 +211,6 @@ static struct ispmdvec mdvec_2300 = {
#define PCI_PRODUCT_QLOGIC_ISP1080 0x1080
#endif
-#ifndef PCI_PRODUCT_QLOGIC_ISP1240
-#define PCI_PRODUCT_QLOGIC_ISP1240 0x1240
-#endif
-
-#ifndef PCI_PRODUCT_QLOGIC_ISP1280
-#define PCI_PRODUCT_QLOGIC_ISP1280 0x1280
-#endif
-
#ifndef PCI_PRODUCT_QLOGIC_ISP10160
#define PCI_PRODUCT_QLOGIC_ISP10160 0x1016
#endif
@@ -241,6 +219,14 @@ static struct ispmdvec mdvec_2300 = {
#define PCI_PRODUCT_QLOGIC_ISP12160 0x1216
#endif
+#ifndef PCI_PRODUCT_QLOGIC_ISP1240
+#define PCI_PRODUCT_QLOGIC_ISP1240 0x1240
+#endif
+
+#ifndef PCI_PRODUCT_QLOGIC_ISP1280
+#define PCI_PRODUCT_QLOGIC_ISP1280 0x1280
+#endif
+
#ifndef PCI_PRODUCT_QLOGIC_ISP2100
#define PCI_PRODUCT_QLOGIC_ISP2100 0x2100
#endif
@@ -257,20 +243,32 @@ static struct ispmdvec mdvec_2300 = {
#define PCI_PRODUCT_QLOGIC_ISP2312 0x2312
#endif
+#ifndef PCI_PRODUCT_QLOGIC_ISP2322
+#define PCI_PRODUCT_QLOGIC_ISP2322 0x2322
+#endif
+
+#ifndef PCI_PRODUCT_QLOGIC_ISP2422
+#define PCI_PRODUCT_QLOGIC_ISP2422 0x2422
+#endif
+
+#ifndef PCI_PRODUCT_QLOGIC_ISP2432
+#define PCI_PRODUCT_QLOGIC_ISP2432 0x2432
+#endif
+
#ifndef PCI_PRODUCT_QLOGIC_ISP6312
#define PCI_PRODUCT_QLOGIC_ISP6312 0x6312
#endif
-#define PCI_QLOGIC_ISP ((PCI_PRODUCT_QLOGIC_ISP1020 << 16) | PCI_VENDOR_QLOGIC)
+#ifndef PCI_PRODUCT_QLOGIC_ISP6322
+#define PCI_PRODUCT_QLOGIC_ISP6322 0x6322
+#endif
-#define PCI_QLOGIC_ISP1080 \
- ((PCI_PRODUCT_QLOGIC_ISP1080 << 16) | PCI_VENDOR_QLOGIC)
-#define PCI_QLOGIC_ISP1240 \
- ((PCI_PRODUCT_QLOGIC_ISP1240 << 16) | PCI_VENDOR_QLOGIC)
+#define PCI_QLOGIC_ISP1020 \
+ ((PCI_PRODUCT_QLOGIC_ISP1020 << 16) | PCI_VENDOR_QLOGIC)
-#define PCI_QLOGIC_ISP1280 \
- ((PCI_PRODUCT_QLOGIC_ISP1280 << 16) | PCI_VENDOR_QLOGIC)
+#define PCI_QLOGIC_ISP1080 \
+ ((PCI_PRODUCT_QLOGIC_ISP1080 << 16) | PCI_VENDOR_QLOGIC)
#define PCI_QLOGIC_ISP10160 \
((PCI_PRODUCT_QLOGIC_ISP10160 << 16) | PCI_VENDOR_QLOGIC)
@@ -278,6 +276,12 @@ static struct ispmdvec mdvec_2300 = {
#define PCI_QLOGIC_ISP12160 \
((PCI_PRODUCT_QLOGIC_ISP12160 << 16) | PCI_VENDOR_QLOGIC)
+#define PCI_QLOGIC_ISP1240 \
+ ((PCI_PRODUCT_QLOGIC_ISP1240 << 16) | PCI_VENDOR_QLOGIC)
+
+#define PCI_QLOGIC_ISP1280 \
+ ((PCI_PRODUCT_QLOGIC_ISP1280 << 16) | PCI_VENDOR_QLOGIC)
+
#define PCI_QLOGIC_ISP2100 \
((PCI_PRODUCT_QLOGIC_ISP2100 << 16) | PCI_VENDOR_QLOGIC)
@@ -290,18 +294,28 @@ static struct ispmdvec mdvec_2300 = {
#define PCI_QLOGIC_ISP2312 \
((PCI_PRODUCT_QLOGIC_ISP2312 << 16) | PCI_VENDOR_QLOGIC)
+#define PCI_QLOGIC_ISP2322 \
+ ((PCI_PRODUCT_QLOGIC_ISP2322 << 16) | PCI_VENDOR_QLOGIC)
+
+#define PCI_QLOGIC_ISP2422 \
+ ((PCI_PRODUCT_QLOGIC_ISP2422 << 16) | PCI_VENDOR_QLOGIC)
+
+#define PCI_QLOGIC_ISP2432 \
+ ((PCI_PRODUCT_QLOGIC_ISP2432 << 16) | PCI_VENDOR_QLOGIC)
+
#define PCI_QLOGIC_ISP6312 \
((PCI_PRODUCT_QLOGIC_ISP6312 << 16) | PCI_VENDOR_QLOGIC)
+#define PCI_QLOGIC_ISP6322 \
+ ((PCI_PRODUCT_QLOGIC_ISP6322 << 16) | PCI_VENDOR_QLOGIC)
+
/*
* Odd case for some AMI raid cards... We need to *not* attach to this.
*/
#define AMI_RAID_SUBVENDOR_ID 0x101e
-
-#define IO_MAP_REG 0x10
-#define MEM_MAP_REG 0x14
-#define PCIR_ROMADDR 0x30
+#define IO_MAP_REG 0x10
+#define MEM_MAP_REG 0x14
#define PCI_DFLT_LTNCY 0x40
#define PCI_DFLT_LNSZ 0x10
@@ -314,9 +328,29 @@ static struct ispmdvec mdvec_2300 = {
#endif
#endif
-static int isp_pci_probe (struct device *, void *, void *);
-static void isp_pci_attach (struct device *, struct device *, void *);
+const struct pci_matchid ispdev[] = {
+ { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1020 },
+ { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1080 },
+ { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1240 },
+ { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1280 },
+ { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP10160 },
+ { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP12160 },
+ { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2100 },
+ { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2200 },
+ { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2300 },
+ { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2312 },
+ { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2322 },
+ { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2422 },
+ { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2432 },
+ { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP6312 },
+ { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP6322 },
+ { 0, 0 }
+};
+
+int isp_pci_probe (struct device *, void *, void *);
+void isp_pci_attach (struct device *, struct device *, void *);
+#define ISP_PCD(isp) ((struct isp_pcisoftc *)isp)->pci_dev
struct isp_pcisoftc {
struct ispsoftc pci_isp;
pci_chipset_tag_t pci_pc;
@@ -332,39 +366,7 @@ struct cfattach isp_pci_ca = {
sizeof (struct isp_pcisoftc), isp_pci_probe, isp_pci_attach
};
-#ifdef DEBUG
-const char vstring[] =
- "QLogic ISP Driver, NetBSD (pci) Platform Version %d.%d Core Version %d.%d";
-#endif
-
-const struct pci_matchid ispdev[] = {
-#ifndef ISP_DISABLE_1020_SUPPORT
- { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1020 },
-#endif
-#ifndef ISP_DISABLE_1080_SUPPORT
- { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1080 },
- { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1240 },
- { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1280 },
-#endif
-#ifndef ISP_DISABLE_12160_SUPPORT
- { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP10160 },
- { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP12160 },
-#endif
-#ifndef ISP_DISABLE_2100_SUPPORT
- { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2100 },
-#endif
-#ifndef ISP_DISABLE_2200_SUPPORT
- { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2200 },
-#endif
-#ifndef ISP_DISABLE_2300_SUPPORT
- { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2300 },
- { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2312 },
- { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP6312 },
-#endif
- { 0, 0 }
-};
-
-static int
+int
isp_pci_probe(struct device *parent, void *match, void *aux)
{
struct pci_attach_args *pa = aux;
@@ -386,7 +388,7 @@ isp_pci_probe(struct device *parent, void *match, void *aux)
}
-static void
+void
isp_pci_attach(struct device *parent, struct device *self, void *aux)
{
#ifdef DEBUG
@@ -395,7 +397,7 @@ isp_pci_attach(struct device *parent, struct device *self, void *aux)
static const char nomem[] = ": no mem for sdparam table\n";
u_int32_t data, rev, linesz = PCI_DFLT_LNSZ;
struct pci_attach_args *pa = aux;
- struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) self;
+ struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)self;
struct ispsoftc *isp = &pcs->pci_isp;
bus_space_tag_t st, iot, memt;
bus_space_handle_t sh, ioh, memh;
@@ -487,8 +489,8 @@ isp_pci_attach(struct device *parent, struct device *self, void *aux)
printf("\n");
#endif
- pcs->pci_st = st;
- pcs->pci_sh = sh;
+ pcs->pci_st = isp->isp_bus_tag = st;
+ pcs->pci_sh = isp->isp_bus_handle = sh;
pcs->pci_pc = pa->pa_pc;
pcs->pci_tag = pa->pa_tag;
pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;
@@ -497,8 +499,7 @@ isp_pci_attach(struct device *parent, struct device *self, void *aux)
pcs->pci_poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF;
pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;
rev = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG) & 0xff;
-#ifndef ISP_DISABLE_1020_SUPPORT
- if (pa->pa_id == PCI_QLOGIC_ISP) {
+ if (pa->pa_id == PCI_QLOGIC_ISP1020) {
isp->isp_mdvec = &mdvec;
isp->isp_type = ISP_HA_SCSI_UNKNOWN;
isp->isp_param = malloc(sizeof(sdparam), M_DEVBUF,
@@ -508,8 +509,6 @@ isp_pci_attach(struct device *parent, struct device *self, void *aux)
return;
}
}
-#endif
-#ifndef ISP_DISABLE_1080_SUPPORT
if (pa->pa_id == PCI_QLOGIC_ISP1080) {
isp->isp_mdvec = &mdvec_1080;
isp->isp_type = ISP_HA_SCSI_1080;
@@ -546,8 +545,6 @@ isp_pci_attach(struct device *parent, struct device *self, void *aux)
pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
ISP1080_DMA_REGS_OFF;
}
-#endif
-#ifndef ISP_DISABLE_12160_SUPPORT
if (pa->pa_id == PCI_QLOGIC_ISP10160) {
isp->isp_mdvec = &mdvec_12160;
isp->isp_type = ISP_HA_SCSI_10160;
@@ -572,8 +569,6 @@ isp_pci_attach(struct device *parent, struct device *self, void *aux)
pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
ISP1080_DMA_REGS_OFF;
}
-#endif
-#ifndef ISP_DISABLE_2100_SUPPORT
if (pa->pa_id == PCI_QLOGIC_ISP2100) {
isp->isp_mdvec = &mdvec_2100;
isp->isp_type = ISP_HA_FC_2100;
@@ -595,8 +590,6 @@ isp_pci_attach(struct device *parent, struct device *self, void *aux)
linesz = 1;
}
}
-#endif
-#ifndef ISP_DISABLE_2200_SUPPORT
if (pa->pa_id == PCI_QLOGIC_ISP2200) {
isp->isp_mdvec = &mdvec_2200;
isp->isp_type = ISP_HA_FC_2200;
@@ -621,18 +614,38 @@ isp_pci_attach(struct device *parent, struct device *self, void *aux)
}
#endif
}
-#endif
-#ifndef ISP_DISABLE_2300_SUPPORT
- if (pa->pa_id == PCI_QLOGIC_ISP2300 ||
- pa->pa_id == PCI_QLOGIC_ISP2312 ||
+ if (pa->pa_id == PCI_QLOGIC_ISP2300) {
+ isp->isp_mdvec = &mdvec_2300;
+ isp->isp_type = ISP_HA_FC_2300;
+ isp->isp_param = malloc(sizeof(fcparam), M_DEVBUF,
+ M_NOWAIT | M_ZERO);
+ if (isp->isp_param == NULL) {
+ printf(nomem);
+ return;
+ }
+ pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
+ PCI_MBOX_REGS2300_OFF;
+ }
+ if (pa->pa_id == PCI_QLOGIC_ISP2312 ||
pa->pa_id == PCI_QLOGIC_ISP6312) {
isp->isp_mdvec = &mdvec_2300;
- if (pa->pa_id == PCI_QLOGIC_ISP2300) {
- isp->isp_type = ISP_HA_FC_2300;
- } else {
- isp->isp_type = ISP_HA_FC_2312;
- isp->isp_port = pa->pa_function;
+ isp->isp_type = ISP_HA_FC_2312;
+ isp->isp_port = pa->pa_function;
+ isp->isp_param = malloc(sizeof(fcparam), M_DEVBUF,
+ M_NOWAIT | M_ZERO);
+ if (isp->isp_param == NULL) {
+ printf(nomem);
+ return;
}
+ pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
+ PCI_MBOX_REGS2300_OFF;
+ data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG);
+ }
+ if (pa->pa_id == PCI_QLOGIC_ISP2322 ||
+ pa->pa_id == PCI_QLOGIC_ISP6322) {
+ isp->isp_mdvec = &mdvec_2300;
+ isp->isp_type = ISP_HA_FC_2322;
+ isp->isp_port = pa->pa_function;
isp->isp_param = malloc(sizeof(fcparam), M_DEVBUF,
M_NOWAIT | M_ZERO);
if (isp->isp_param == NULL) {
@@ -643,7 +656,20 @@ isp_pci_attach(struct device *parent, struct device *self, void *aux)
PCI_MBOX_REGS2300_OFF;
data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG);
}
-#endif
+ if (pa->pa_id == PCI_QLOGIC_ISP2422 ||
+ pa->pa_id == PCI_QLOGIC_ISP2432) {
+ isp->isp_mdvec = &mdvec_2400;
+ isp->isp_type = ISP_HA_FC_2400;
+ isp->isp_port = pa->pa_function;
+ isp->isp_param = malloc(sizeof(fcparam), M_DEVBUF,
+ M_NOWAIT | M_ZERO);
+ if (isp->isp_param == NULL) {
+ printf(nomem);
+ return;
+ }
+ pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
+ PCI_MBOX_REGS2400_OFF;
+ }
/*
* Set up logging levels.
*/
@@ -739,7 +765,7 @@ isp_pci_attach(struct device *parent, struct device *self, void *aux)
free(isp->isp_param, M_DEVBUF);
return;
}
- ENABLE_INTS(isp);
+ ISP_ENABLE_INTS(isp);
isp_init(isp);
if (isp->isp_state != ISP_INITSTATE) {
isp_uninit(isp);
@@ -762,19 +788,22 @@ isp_pci_attach(struct device *parent, struct device *self, void *aux)
#define IspVirt2Off(a, x) \
(((struct isp_pcisoftc *)a)->pci_poff[((x) & _BLK_REG_MASK) >> \
- _BLK_REG_SHFT] + ((x) & 0xff))
+ _BLK_REG_SHFT] + ((x) & 0xfff))
#define BXR2(pcs, off) \
bus_space_read_2(pcs->pci_st, pcs->pci_sh, off)
#define BXW2(pcs, off, v) \
bus_space_write_2(pcs->pci_st, pcs->pci_sh, off, v)
+#define BXR4(pcs, off) \
+ bus_space_read_4(pcs->pci_st, pcs->pci_sh, off)
+#define BXW4(pcs, off, v) \
+ bus_space_write_4(pcs->pci_st, pcs->pci_sh, off, v)
-
-static INLINE int
+int
isp_pci_rd_debounced(struct ispsoftc *isp, int off, u_int16_t *rp)
{
- struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
- u_int16_t val0, val1;
+ struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
+ u_int32_t val0, val1;
int i = 0;
do {
@@ -788,11 +817,11 @@ isp_pci_rd_debounced(struct ispsoftc *isp, int off, u_int16_t *rp)
return (0);
}
-static int
-isp_pci_rd_isr(struct ispsoftc *isp, u_int16_t *isrp,
+int
+isp_pci_rd_isr(struct ispsoftc *isp, u_int32_t *isrp,
u_int16_t *semap, u_int16_t *mbp)
{
- struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
+ struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
u_int16_t isr, sema;
if (IS_2100(isp)) {
@@ -825,20 +854,19 @@ isp_pci_rd_isr(struct ispsoftc *isp, u_int16_t *isrp,
return (1);
}
-#ifndef ISP_DISABLE_2300_SUPPORT
-static int
-isp_pci_rd_isr_2300(struct ispsoftc *isp, u_int16_t *isrp,
+int
+isp_pci_rd_isr_2300(struct ispsoftc *isp, u_int32_t *isrp,
u_int16_t *semap, u_int16_t *mbox0p)
{
- struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
+ struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
+ u_int32_t hccr;
u_int32_t r2hisr;
if (!(BXR2(pcs, IspVirt2Off(isp, BIU_ISR)) & BIU2100_ISR_RISC_INT)) {
*isrp = 0;
return (0);
}
- r2hisr = bus_space_read_4(pcs->pci_st, pcs->pci_sh,
- IspVirt2Off(pcs, BIU_R2HSTSLO));
+ r2hisr = BXR4(pcs, IspVirt2Off(isp, BIU_R2HSTSLO));
isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr);
if ((r2hisr & BIU_R2HST_INTR) == 0) {
*isrp = 0;
@@ -875,16 +903,26 @@ isp_pci_rd_isr_2300(struct ispsoftc *isp, u_int16_t *isrp,
*semap = 0;
return (1);
default:
+ hccr = ISP_READ(isp, HCCR);
+ if (hccr & HCCR_PAUSE) {
+ ISP_WRITE(isp, HCCR, HCCR_RESET);
+ isp_prt(isp, ISP_LOGERR,
+ "RISC paused at interrupt (%x->%x)", hccr,
+ ISP_READ(isp, HCCR));
+ ISP_WRITE(isp, BIU_ICR, 0);
+ } else {
+ isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n",
+ r2hisr);
+ }
return (0);
}
}
-#endif
-static u_int16_t
+u_int32_t
isp_pci_rd_reg(struct ispsoftc *isp, int regoff)
{
u_int16_t rv;
- struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
+ struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
int oldconf = 0;
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
@@ -894,18 +932,57 @@ isp_pci_rd_reg(struct ispsoftc *isp, int regoff)
oldconf = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
oldconf | BIU_PCI_CONF1_SXP);
+ MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, BIU_CONF1), 2);
}
rv = BXR2(pcs, IspVirt2Off(isp, regoff));
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oldconf);
}
+ MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, BIU_CONF1), 2);
return (rv);
}
-static void
-isp_pci_wr_reg(struct ispsoftc *isp, int regoff, u_int16_t val)
+int
+isp_pci_rd_isr_2400(ispsoftc_t *isp, uint32_t *isrp,
+ uint16_t *semap, uint16_t *mbox0p)
{
- struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
+ struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
+ uint32_t r2hisr;
+
+ r2hisr = BXR4(pcs, IspVirt2Off(isp, BIU2400_R2HSTSLO));
+ isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr);
+ if ((r2hisr & BIU2400_R2HST_INTR) == 0) {
+ *isrp = 0;
+ return (0);
+ }
+ switch (r2hisr & BIU2400_R2HST_ISTAT_MASK) {
+ case ISP2400R2HST_ROM_MBX_OK:
+ case ISP2400R2HST_ROM_MBX_FAIL:
+ case ISP2400R2HST_MBX_OK:
+ case ISP2400R2HST_MBX_FAIL:
+ case ISP2400R2HST_ASYNC_EVENT:
+ *isrp = r2hisr & 0xffff;
+ *mbox0p = (r2hisr >> 16);
+ *semap = 1;
+ return (1);
+ case ISP2400R2HST_RSPQ_UPDATE:
+ case ISP2400R2HST_ATIO_RSPQ_UPDATE:
+ case ISP2400R2HST_ATIO_RQST_UPDATE:
+ *isrp = r2hisr & 0xffff;
+ *mbox0p = 0;
+ *semap = 0;
+ return (1);
+ default:
+ ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
+ isp_prt(isp, ISP_LOGERR, "unknown interrupt 0x%x\n", r2hisr);
+ return (0);
+ }
+}
+
+void
+isp_pci_wr_reg(struct ispsoftc *isp, int regoff, u_int32_t val)
+{
+ struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
int oldconf = 0;
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
@@ -915,23 +992,26 @@ isp_pci_wr_reg(struct ispsoftc *isp, int regoff, u_int16_t val)
oldconf = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
oldconf | BIU_PCI_CONF1_SXP);
+ MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, BIU_CONF1), 2);
}
BXW2(pcs, IspVirt2Off(isp, regoff), val);
+ MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, regoff), 2);
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oldconf);
+ MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, BIU_CONF1), 2);
}
+
}
-#if !(defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT))
-static u_int16_t
+u_int32_t
isp_pci_rd_reg_1080(struct ispsoftc *isp, int regoff)
{
- u_int16_t rv, oc = 0;
- struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
+ struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
+ u_int32_t rv, oc = 0;
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
(regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
- u_int16_t tc;
+ u_int32_t tc;
/*
* We will assume that someone has paused the RISC processor.
*/
@@ -942,27 +1022,30 @@ isp_pci_rd_reg_1080(struct ispsoftc *isp, int regoff)
else
tc |= BIU_PCI1080_CONF1_SXP0;
BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), tc);
+ MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, BIU_CONF1), 2);
} else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
oc | BIU_PCI1080_CONF1_DMA);
+ MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, BIU_CONF1), 2);
}
rv = BXR2(pcs, IspVirt2Off(isp, regoff));
if (oc) {
BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oc);
+ MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, BIU_CONF1), 2);
}
return (rv);
}
-static void
-isp_pci_wr_reg_1080(struct ispsoftc *isp, int regoff, u_int16_t val)
+void
+isp_pci_wr_reg_1080(struct ispsoftc *isp, int regoff, u_int32_t val)
{
- struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
+ struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
int oc = 0;
if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
(regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
- u_int16_t tc;
+ u_int32_t tc;
/*
* We will assume that someone has paused the RISC processor.
*/
@@ -973,26 +1056,155 @@ isp_pci_wr_reg_1080(struct ispsoftc *isp, int regoff, u_int16_t val)
else
tc |= BIU_PCI1080_CONF1_SXP0;
BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), tc);
+ MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, BIU_CONF1), 2);
} else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
oc | BIU_PCI1080_CONF1_DMA);
+ MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, BIU_CONF1), 2);
}
BXW2(pcs, IspVirt2Off(isp, regoff), val);
+ MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, regoff), 2);
if (oc) {
BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oc);
+ MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, BIU_CONF1), 2);
}
}
-#endif
-static int
+uint32_t
+isp_pci_rd_reg_2400(ispsoftc_t *isp, int regoff)
+{
+ struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
+ uint32_t rv;
+ int block = regoff & _BLK_REG_MASK;
+
+ switch (block) {
+ case BIU_BLOCK:
+ break;
+ case MBOX_BLOCK:
+ return (BXR2(pcs, IspVirt2Off(isp, regoff)));
+ case SXP_BLOCK:
+ isp_prt(isp, ISP_LOGWARN, "SXP_BLOCK read at 0x%x", regoff);
+ return (0xffffffff);
+ case RISC_BLOCK:
+ isp_prt(isp, ISP_LOGWARN, "RISC_BLOCK read at 0x%x", regoff);
+ return (0xffffffff);
+ case DMA_BLOCK:
+ isp_prt(isp, ISP_LOGWARN, "DMA_BLOCK read at 0x%x", regoff);
+ return (0xffffffff);
+ default:
+ isp_prt(isp, ISP_LOGWARN, "unknown block read at 0x%x", regoff);
+ return (0xffffffff);
+ }
+
+
+ switch (regoff) {
+ case BIU2400_FLASH_ADDR:
+ case BIU2400_FLASH_DATA:
+ case BIU2400_ICR:
+ case BIU2400_ISR:
+ case BIU2400_CSR:
+ case BIU2400_REQINP:
+ case BIU2400_REQOUTP:
+ case BIU2400_RSPINP:
+ case BIU2400_RSPOUTP:
+ case BIU2400_PRI_RQINP:
+ case BIU2400_PRI_RSPINP:
+ case BIU2400_ATIO_RSPINP:
+ case BIU2400_ATIO_REQINP:
+ case BIU2400_HCCR:
+ case BIU2400_GPIOD:
+ case BIU2400_GPIOE:
+ case BIU2400_HSEMA:
+ rv = BXR4(pcs, IspVirt2Off(isp, regoff));
+ break;
+ case BIU2400_R2HSTSLO:
+ rv = BXR4(pcs, IspVirt2Off(isp, regoff));
+ break;
+ case BIU2400_R2HSTSHI:
+ rv = BXR4(pcs, IspVirt2Off(isp, regoff)) >> 16;
+ break;
+ default:
+ isp_prt(isp, ISP_LOGERR,
+ "isp_pci_rd_reg_2400: unknown offset %x", regoff);
+ rv = 0xffffffff;
+ break;
+ }
+ return (rv);
+}
+
+void
+isp_pci_wr_reg_2400(ispsoftc_t *isp, int regoff, uint32_t val)
+{
+ struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
+ int block = regoff & _BLK_REG_MASK;
+
+ switch (block) {
+ case BIU_BLOCK:
+ break;
+ case MBOX_BLOCK:
+ BXW2(pcs, IspVirt2Off(isp, regoff), val);
+ MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, regoff), 2);
+ return;
+ case SXP_BLOCK:
+ isp_prt(isp, ISP_LOGWARN, "SXP_BLOCK write at 0x%x", regoff);
+ return;
+ case RISC_BLOCK:
+ isp_prt(isp, ISP_LOGWARN, "RISC_BLOCK write at 0x%x", regoff);
+ return;
+ case DMA_BLOCK:
+ isp_prt(isp, ISP_LOGWARN, "DMA_BLOCK write at 0x%x", regoff);
+ return;
+ default:
+ isp_prt(isp, ISP_LOGWARN, "unknown block write at 0x%x",
+ regoff);
+ break;
+ }
+
+ switch (regoff) {
+ case BIU2400_FLASH_ADDR:
+ case BIU2400_FLASH_DATA:
+ case BIU2400_ICR:
+ case BIU2400_ISR:
+ case BIU2400_CSR:
+ case BIU2400_REQINP:
+ case BIU2400_REQOUTP:
+ case BIU2400_RSPINP:
+ case BIU2400_RSPOUTP:
+ case BIU2400_PRI_RQINP:
+ case BIU2400_PRI_RSPINP:
+ case BIU2400_ATIO_RSPINP:
+ case BIU2400_ATIO_REQINP:
+ case BIU2400_HCCR:
+ case BIU2400_GPIOD:
+ case BIU2400_GPIOE:
+ case BIU2400_HSEMA:
+ BXW4(pcs, IspVirt2Off(isp, regoff), val);
+ MEMORYBARRIER(isp, SYNC_REG, IspVirt2Off(isp, regoff), 4);
+ break;
+ default:
+ isp_prt(isp, ISP_LOGERR,
+ "isp_pci_wr_reg_2400: bad offset 0x%x", regoff);
+ break;
+ }
+}
+
+
+struct imush {
+ ispsoftc_t *isp;
+ int error;
+};
+
+
+int
isp_pci_mbxdma(struct ispsoftc *isp)
{
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
bus_dma_tag_t dmat = isp->isp_dmatag;
bus_dma_segment_t sg;
+ bus_addr_t addr;
bus_size_t len;
- fcparam *fcp;
+ caddr_t base;
int rs, i;
if (isp->isp_rquest_dma) /* been here before? */
@@ -1033,62 +1245,48 @@ isp_pci_mbxdma(struct ispsoftc *isp)
}
/*
- * Allocate and map the request queue.
+ * Allocate and map the request, result queues, plus FC scratch area.
*/
len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
+ len += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
+ if (IS_FC(isp)) {
+ len += ISP2100_SCRLEN;
+ }
+
if (bus_dmamem_alloc(dmat, len, PAGE_SIZE, 0, &sg, 1, &rs,
BUS_DMA_NOWAIT) ||
bus_dmamem_map(isp->isp_dmatag, &sg, rs, len,
- (caddr_t *)&isp->isp_rquest, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
+ &base, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
goto dmafail;
}
if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
- &isp->isp_rqdmap) || bus_dmamap_load(dmat, isp->isp_rqdmap,
- (caddr_t)isp->isp_rquest, len, NULL,
+ &isp->isp_cdmap) || bus_dmamap_load(dmat, isp->isp_cdmap,
+ base, len, NULL,
BUS_DMA_NOWAIT)) {
goto dmafail;
}
- isp->isp_rquest_dma = isp->isp_rqdmap->dm_segs[0].ds_addr;
- /*
- * Allocate and map the result queue.
- */
- len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
- if (bus_dmamem_alloc(dmat, len, PAGE_SIZE, 0, &sg, 1, &rs,
- BUS_DMA_NOWAIT) ||
- bus_dmamem_map(dmat, &sg, rs, len, (caddr_t *)&isp->isp_result,
- BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
- goto dmafail;
- }
- if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
- &isp->isp_rsdmap) || bus_dmamap_load(isp->isp_dmatag,
- isp->isp_rsdmap, (caddr_t)isp->isp_result, len, NULL,
- BUS_DMA_NOWAIT)) {
- goto dmafail;
- }
- isp->isp_result_dma = isp->isp_rsdmap->dm_segs[0].ds_addr;
+ addr = isp->isp_cdmap->dm_segs[0].ds_addr;
+ isp->isp_rquest_dma = addr;
+ addr += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
+ isp->isp_result_dma = addr;
- if (IS_SCSI(isp)) {
- return (0);
- }
+ if (IS_FC(isp)) {
+ addr += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
+ FCPARAM(isp)->isp_scdma = addr;
- fcp = isp->isp_param;
- len = ISP2100_SCRLEN;
- if (bus_dmamem_alloc(dmat, len, PAGE_SIZE, 0, &sg, 1, &rs,
- BUS_DMA_NOWAIT) ||
- bus_dmamem_map(dmat, &sg, rs, len, (caddr_t *)&fcp->isp_scratch,
- BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
- goto dmafail;
}
- if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
- &isp->isp_scdmap) || bus_dmamap_load(dmat,
- isp->isp_scdmap, (caddr_t)fcp->isp_scratch, len, NULL,
- BUS_DMA_NOWAIT)) {
- goto dmafail;
+
+ isp->isp_rquest = base;
+ base += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
+ isp->isp_result = base;
+ if (IS_FC(isp)) {
+ base += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
+ FCPARAM(isp)->isp_scratch = base;
}
- fcp->isp_scdma = isp->isp_scdmap->dm_segs[0].ds_addr;
return (0);
+
dmafail:
isp_prt(isp, ISP_LOGERR, "mailbox dma setup failure");
for (i = 0; i < isp->isp_maxcmds; i++) {
@@ -1101,17 +1299,17 @@ dmafail:
return (1);
}
-static int
+int
isp_pci_dmasetup(struct ispsoftc *isp, XS_T *xs, ispreq_t *rq,
- u_int16_t *nxtip, u_int16_t optr)
+ u_int32_t *nxtip, u_int32_t optr)
{
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
bus_dmamap_t dmap;
- u_int16_t starti = isp->isp_reqidx, nxti = *nxtip;
+ u_int16_t nxti = *nxtip;
ispreq_t *qep;
int segcnt, seg, error, ovseg, seglim, drq;
- qep = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, starti);
+ qep = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx);
dmap = pcs->pci_xfer_dmap[isp_handle_index(rq->req_handle)];
if (xs->datalen == 0) {
rq->req_seg_count = 1;
@@ -1222,17 +1420,37 @@ mbxsync:
(ispextreq_t *)qep);
break;
case RQSTYPE_T2RQS:
- isp_put_request_t2(isp, (ispreqt2_t *) rq, (ispreqt2_t *) qep);
+ if (FCPARAM(isp)->isp_2klogin) {
+ isp_put_request_t2e(isp,
+ (ispreqt2e_t *) rq, (ispreqt2e_t *) qep);
+ } else {
+ isp_put_request_t2(isp,
+ (ispreqt2_t *) rq, (ispreqt2_t *) qep);
+ }
+ break;
+ case RQSTYPE_T3RQS:
+ if (FCPARAM(isp)->isp_2klogin) {
+ isp_put_request_t3e(isp,
+ (ispreqt3e_t *) rq, (ispreqt3e_t *) qep);
+ break;
+ }
+ /* FALLTHROUGH */
+ case RQSTYPE_A64:
+ isp_put_request_t3(isp, (ispreqt3_t *) rq, (ispreqt3_t *) qep);
+ break;
+ case RQSTYPE_T7RQS:
+ isp_put_request_t7(isp, (ispreqt7_t *) rq, (ispreqt7_t *) qep);
break;
}
*nxtip = nxti;
return (CMD_QUEUED);
}
-static int
+int
isp_pci_intr(void *arg)
{
- u_int16_t isr, sema, mbox;
+ u_int32_t isr;
+ u_int16_t sema, mbox;
struct ispsoftc *isp = (struct ispsoftc *)arg;
isp->isp_intcnt++;
@@ -1247,8 +1465,8 @@ isp_pci_intr(void *arg)
}
}
-static void
-isp_pci_dmateardown(struct ispsoftc *isp, XS_T *xs, u_int16_t handle)
+void
+isp_pci_dmateardown(struct ispsoftc *isp, XS_T *xs, u_int32_t handle)
{
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
bus_dmamap_t dmap = pcs->pci_xfer_dmap[isp_handle_index(handle)];
@@ -1258,22 +1476,39 @@ isp_pci_dmateardown(struct ispsoftc *isp, XS_T *xs, u_int16_t handle)
bus_dmamap_unload(isp->isp_dmatag, dmap);
}
-static void
+void
+isp_pci_reset0(ispsoftc_t *isp)
+{
+ ISP_DISABLE_INTS(isp);
+}
+
+void
isp_pci_reset1(struct ispsoftc *isp)
{
- /* Make sure the BIOS is disabled */
- isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS);
- if (isp->isp_osinfo.no_mbox_ints == 0) {
- ENABLE_INTS(isp);
+ if (!IS_24XX(isp)) {
+ /* Make sure the BIOS is disabled */
+ isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS);
}
+ /* and enable interrupts */
+ ISP_ENABLE_INTS(isp);
}
-static void
+void
isp_pci_dumpregs(struct ispsoftc *isp, const char *msg)
{
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
if (msg)
isp_prt(isp, ISP_LOGERR, "%s", msg);
+ if (IS_SCSI(isp))
+ isp_prt(isp, ISP_LOGERR, " biu_conf1=%x",
+ ISP_READ(isp, BIU_CONF1));
+ else
+ isp_prt(isp, ISP_LOGERR, " biu_csr=%x",
+ ISP_READ(isp, BIU2100_CSR));
+ isp_prt(isp, ISP_LOGERR, " biu_icr=%x biu_isr=%x biu_sema=%x ",
+ ISP_READ(isp, BIU_ICR), ISP_READ(isp, BIU_ISR),
+ ISP_READ(isp, BIU_SEMA));
+ isp_prt(isp, ISP_LOGERR, "risc_hccr=%x\n", ISP_READ(isp, HCCR));
isp_prt(isp, ISP_LOGERR, "PCI Status Command/Status=%x\n",
pci_conf_read(pcs->pci_pc, pcs->pci_tag, PCI_COMMAND_STATUS_REG));
}
diff --git a/sys/dev/sbus/isp_sbus.c b/sys/dev/sbus/isp_sbus.c
index 1d5007770cd..a92dfaebc20 100644
--- a/sys/dev/sbus/isp_sbus.c
+++ b/sys/dev/sbus/isp_sbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isp_sbus.c,v 1.12 2008/06/01 15:49:25 kettenis Exp $ */
+/* $OpenBSD: isp_sbus.c,v 1.13 2009/06/24 11:00:53 krw Exp $ */
/* $NetBSD: isp_sbus.c,v 1.46 2001/09/26 20:53:14 eeh Exp $ */
/*
@@ -79,13 +79,13 @@
static int isp_sbus_intr(void *);
static int
-isp_sbus_rd_isr(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
-static u_int16_t isp_sbus_rd_reg(struct ispsoftc *, int);
-static void isp_sbus_wr_reg (struct ispsoftc *, int, u_int16_t);
+isp_sbus_rd_isr(struct ispsoftc *, u_int32_t *, u_int16_t *, u_int16_t *);
+static u_int32_t isp_sbus_rd_reg(struct ispsoftc *, int);
+static void isp_sbus_wr_reg (struct ispsoftc *, int, u_int32_t);
static int isp_sbus_mbxdma(struct ispsoftc *);
-static int isp_sbus_dmasetup(struct ispsoftc *, XS_T *, ispreq_t *, u_int16_t *,
- u_int16_t);
-static void isp_sbus_dmateardown(struct ispsoftc *, XS_T *, u_int16_t);
+static int isp_sbus_dmasetup(struct ispsoftc *, XS_T *, ispreq_t *, u_int32_t *,
+ u_int32_t);
+static void isp_sbus_dmateardown(struct ispsoftc *, XS_T *, u_int32_t);
#ifndef ISP_1000_RISC_CODE
#define ISP_1000_RISC_CODE NULL
@@ -283,7 +283,7 @@ isp_sbus_attach(struct device *parent, struct device *self, void *aux)
ISP_UNLOCK(isp);
return;
}
- ENABLE_INTS(isp);
+ ISP_ENABLE_INTS(isp);
isp_init(isp);
if (isp->isp_state != ISP_INITSTATE) {
isp_uninit(isp);
@@ -306,7 +306,8 @@ isp_sbus_attach(struct device *parent, struct device *self, void *aux)
static int
isp_sbus_intr(void *arg)
{
- u_int16_t isr, sema, mbox;
+ u_int32_t isr;
+ u_int16_t sema, mbox;
struct ispsoftc *isp = arg;
isp->isp_intcnt++;
@@ -329,7 +330,7 @@ isp_sbus_intr(void *arg)
bus_space_read_2(sbc->sbus_bustag, sbc->sbus_reg, off)
static int
-isp_sbus_rd_isr(struct ispsoftc *isp, u_int16_t *isrp,
+isp_sbus_rd_isr(struct ispsoftc *isp, u_int32_t *isrp,
u_int16_t *semap, u_int16_t *mbp)
{
struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
@@ -350,7 +351,7 @@ isp_sbus_rd_isr(struct ispsoftc *isp, u_int16_t *isrp,
return (1);
}
-static u_int16_t
+static u_int32_t
isp_sbus_rd_reg(struct ispsoftc *isp, int regoff)
{
struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
@@ -360,7 +361,7 @@ isp_sbus_rd_reg(struct ispsoftc *isp, int regoff)
}
static void
-isp_sbus_wr_reg(struct ispsoftc *isp, int regoff, u_int16_t val)
+isp_sbus_wr_reg(struct ispsoftc *isp, int regoff, u_int32_t val)
{
struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
int offset = sbc->sbus_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
@@ -372,10 +373,12 @@ static int
isp_sbus_mbxdma(struct ispsoftc *isp)
{
struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
- bus_dma_segment_t reqseg, rspseg;
- int reqrs, rsprs, i, progress;
- size_t n;
+ bus_dma_segment_t seg;
+ bus_addr_t addr;
bus_size_t len;
+ caddr_t base;
+ size_t n;
+ int rs, i, progress;
if (isp->isp_rquest_dma)
return (0);
@@ -420,81 +423,51 @@ isp_sbus_mbxdma(struct ispsoftc *isp)
*/
progress = 0;
len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
- if (bus_dmamem_alloc(isp->isp_dmatag, len, 0, 0, &reqseg, 1, &reqrs,
+ len += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
+ if (bus_dmamem_alloc(isp->isp_dmatag, len, 0, 0, &seg, 1, &rs,
BUS_DMA_NOWAIT)) {
goto dmafail;
}
progress++;
- if (bus_dmamem_map(isp->isp_dmatag, &reqseg, reqrs, len,
- (caddr_t *)&isp->isp_rquest, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
+ if (bus_dmamem_map(isp->isp_dmatag, &seg, rs, len,
+ &base, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
goto dmafail;
}
progress++;
if (bus_dmamap_create(isp->isp_dmatag, len, 1, len, 0, BUS_DMA_NOWAIT,
- &isp->isp_rqdmap) != 0) {
- goto dmafail;
- }
- progress++;
- if (bus_dmamap_load(isp->isp_dmatag, isp->isp_rqdmap,
- isp->isp_rquest, len, NULL, BUS_DMA_NOWAIT) != 0) {
- goto dmafail;
- }
- progress++;
- isp->isp_rquest_dma = isp->isp_rqdmap->dm_segs[0].ds_addr;
-
- len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
- if (bus_dmamem_alloc(isp->isp_dmatag, len, 0, 0, &rspseg, 1, &rsprs,
- BUS_DMA_NOWAIT)) {
- goto dmafail;
- }
- progress++;
- if (bus_dmamem_map(isp->isp_dmatag, &rspseg, rsprs, len,
- (caddr_t *)&isp->isp_result, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
+ &isp->isp_cdmap) != 0) {
goto dmafail;
}
progress++;
- if (bus_dmamap_create(isp->isp_dmatag, len, 1, len, 0, BUS_DMA_NOWAIT,
- &isp->isp_rsdmap) != 0) {
+ if (bus_dmamap_load(isp->isp_dmatag, isp->isp_cdmap,
+ base, len, NULL, BUS_DMA_NOWAIT) != 0) {
goto dmafail;
}
progress++;
- if (bus_dmamap_load(isp->isp_dmatag, isp->isp_rsdmap,
- isp->isp_result, len, NULL, BUS_DMA_NOWAIT) != 0) {
- goto dmafail;
- }
- isp->isp_result_dma = isp->isp_rsdmap->dm_segs[0].ds_addr;
-
+ addr = isp->isp_cdmap->dm_segs[0].ds_addr;
+ isp->isp_rquest_dma = addr;
+ addr += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
+ isp->isp_result_dma = addr;
+
+ isp->isp_rquest = base;
+ base += ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
+ isp->isp_result = base;
return (0);
dmafail:
isp_prt(isp, ISP_LOGERR, "Mailbox DMA Setup Failure");
- if (progress >= 8) {
- bus_dmamap_unload(isp->isp_dmatag, isp->isp_rsdmap);
- }
- if (progress >= 7) {
- bus_dmamap_destroy(isp->isp_dmatag, isp->isp_rsdmap);
- }
- if (progress >= 6) {
- bus_dmamem_unmap(isp->isp_dmatag,
- isp->isp_result, ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)));
- }
- if (progress >= 5) {
- bus_dmamem_free(isp->isp_dmatag, &rspseg, rsprs);
- }
-
if (progress >= 4) {
- bus_dmamap_unload(isp->isp_dmatag, isp->isp_rqdmap);
+ bus_dmamap_unload(isp->isp_dmatag, isp->isp_cdmap);
}
if (progress >= 3) {
- bus_dmamap_destroy(isp->isp_dmatag, isp->isp_rqdmap);
+ bus_dmamap_destroy(isp->isp_dmatag, isp->isp_cdmap);
}
if (progress >= 2) {
- bus_dmamem_unmap(isp->isp_dmatag,
- isp->isp_rquest, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
+ bus_dmamem_unmap(isp->isp_dmatag, isp->isp_rquest, len);
}
if (progress >= 1) {
- bus_dmamem_free(isp->isp_dmatag, &reqseg, reqrs);
+ bus_dmamem_free(isp->isp_dmatag, &seg, rs);
}
for (i = 0; i < isp->isp_maxcmds; i++) {
@@ -514,7 +487,7 @@ dmafail:
static int
isp_sbus_dmasetup(struct ispsoftc *isp, XS_T *xs, ispreq_t *rq,
- u_int16_t *nxtip, u_int16_t optr)
+ u_int32_t *nxtip, u_int32_t optr)
{
struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
bus_dmamap_t dmap;
@@ -587,7 +560,7 @@ mbxsync:
}
static void
-isp_sbus_dmateardown(struct ispsoftc *isp, XS_T *xs, u_int16_t handle)
+isp_sbus_dmateardown(struct ispsoftc *isp, XS_T *xs, u_int32_t handle)
{
struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
bus_dmamap_t dmap;