summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp/isp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/isp/isp.c')
-rw-r--r--sys/dev/isp/isp.c4087
1 files changed, 2063 insertions, 2024 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 1ad4e91..a4a40a8 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -1,17 +1,17 @@
/*-
- * Copyright (c) 1997-2007 by Matthew Jacob
+ * Copyright (c) 1997-2009 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
@@ -23,6 +23,7 @@
* 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.
+ *
*/
/*
@@ -64,51 +65,52 @@ __FBSDID("$FreeBSD$");
*/
#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)
+#define ISP_MARK_PORTDB(a, b, c) \
+ isp_prt(isp, ISP_LOGSANCFG, \
+ "Chan %d ISP_MARK_PORTDB@LINE %d", b, __LINE__); \
+ isp_mark_portdb(a, b, c)
/*
* Local static data
*/
-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[] =
- "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
-static const char xact2[] =
- "HBA attempted queued transaction to target routine %d on target %d bus %d";
-static const char xact3[] =
- "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
-static const char pskip[] =
- "SCSI phase skipped for target %d.%d.%d";
-static const char topology[] =
- "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 %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[] =
- "%s RAAN 0x%x DLAN 0x%x DDMAB 0x%x CDMAB 0x%x SELTIME %d MQD %d";
-static const char sc2[] = "%s CHAN %d TGT %d FLAGS 0x%x 0x%x/0x%x";
-static const char sc3[] = "Generated";
+static const char fconf[] = "Chan %d PortDB[%d] changed:\n current =(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)\n database=(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)";
+static const char notresp[] = "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
+static const char xact1[] = "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
+static const char xact2[] = "HBA attempted queued transaction to target routine %d on target %d bus %d";
+static const char xact3[] = "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
+static const char pskip[] = "SCSI phase skipped for target %d.%d.%d";
+static const char topology[] = "Chan %d WWPN 0x%08x%08x PortID 0x%06x N-Port Handle %d, Connection '%s'";
+static const char finmsg[] = "%d.%d.%d: FIN dl%d resid %ld STS 0x%x SKEY %c XS_ERR=0x%x";
static const char sc4[] = "NVRAM";
-static const char bun[] =
- "bad underrun for %d.%d (count %d, resid %d, status %s)";
+static const char bun[] = "bad underrun for %d.%d (count %d, resid %d, status %s)";
+static const char lipd[] = "Chan %d LIP destroyed %d active commands";
+static const char sacq[] = "unable to acquire scratch area";
+
+static const uint8_t alpa_map[] = {
+ 0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda,
+ 0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce,
+ 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5,
+ 0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3,
+ 0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
+ 0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b,
+ 0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81,
+ 0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73,
+ 0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69,
+ 0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
+ 0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c,
+ 0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c,
+ 0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
+ 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26,
+ 0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
+ 0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00
+};
/*
* Local function prototypes.
*/
static int isp_parse_async(ispsoftc_t *, uint16_t);
-static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *,
- uint32_t *);
-static void
-isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *);
-static void
+static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *);
+static void isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *); static void
isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *);
static void isp_fastpost_complete(ispsoftc_t *, uint16_t);
static int isp_mbox_continue(ispsoftc_t *);
@@ -116,39 +118,37 @@ static void isp_scsi_init(ispsoftc_t *);
static void isp_scsi_channel_init(ispsoftc_t *, int);
static void isp_fibre_init(ispsoftc_t *);
static void isp_fibre_init_2400(ispsoftc_t *);
-static void isp_mark_portdb(ispsoftc_t *, int);
-static int isp_plogx(ispsoftc_t *, uint16_t, uint32_t, int, int);
+static void isp_mark_portdb(ispsoftc_t *, int, int);
+static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int, int);
static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t);
static int isp_port_logout(ispsoftc_t *, uint16_t, uint32_t);
-static int isp_getpdb(ispsoftc_t *, uint16_t, isp_pdb_t *, int);
-static uint64_t isp_get_portname(ispsoftc_t *, int, int);
-static int isp_fclink_test(ispsoftc_t *, int);
-static const char *ispfc_fw_statename(int);
-static int isp_pdb_sync(ispsoftc_t *);
-static int isp_scan_loop(ispsoftc_t *);
-static int isp_gid_ft_sns(ispsoftc_t *);
-static int isp_gid_ft_ct_passthru(ispsoftc_t *);
-static int isp_scan_fabric(ispsoftc_t *);
-static int isp_login_device(ispsoftc_t *, uint32_t, isp_pdb_t *, uint16_t *);
-static int isp_register_fc4_type(ispsoftc_t *);
-static int isp_register_fc4_type_24xx(ispsoftc_t *);
-static uint16_t isp_nxt_handle(ispsoftc_t *, uint16_t);
-static void isp_fw_state(ispsoftc_t *);
+static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *, int);
+static void isp_dump_chip_portdb(ispsoftc_t *, int, int);
+static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int);
+static int isp_fclink_test(ispsoftc_t *, int, int);
+static int isp_pdb_sync(ispsoftc_t *, int);
+static int isp_scan_loop(ispsoftc_t *, int);
+static int isp_gid_ft_sns(ispsoftc_t *, int);
+static int isp_gid_ft_ct_passthru(ispsoftc_t *, int);
+static int isp_scan_fabric(ispsoftc_t *, int);
+static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *);
+static int isp_register_fc4_type(ispsoftc_t *, int);
+static int isp_register_fc4_type_24xx(ispsoftc_t *, int);
+static uint16_t isp_nxt_handle(ispsoftc_t *, int, uint16_t);
+static void isp_fw_state(ispsoftc_t *, int);
static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int);
static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
-static void isp_update(ispsoftc_t *);
-static void isp_update_bus(ispsoftc_t *, int);
-static void isp_setdfltparm(ispsoftc_t *, int);
-static void isp_setdfltfcparm(ispsoftc_t *);
-static int isp_read_nvram(ispsoftc_t *);
-static int isp_read_nvram_2400(ispsoftc_t *);
+static void isp_spi_update(ispsoftc_t *, int);
+static void isp_setdfltsdparm(ispsoftc_t *);
+static void isp_setdfltfcparm(ispsoftc_t *, int);
+static int isp_read_nvram(ispsoftc_t *, int);
+static int isp_read_nvram_2400(ispsoftc_t *, uint8_t *);
static void isp_rdnvram_word(ispsoftc_t *, int, uint16_t *);
static void isp_rd_2400_nvram(ispsoftc_t *, uint32_t, uint32_t *);
static void isp_parse_nvram_1020(ispsoftc_t *, uint8_t *);
static void isp_parse_nvram_1080(ispsoftc_t *, int, uint8_t *);
static void isp_parse_nvram_12160(ispsoftc_t *, int, uint8_t *);
-static void isp_fix_nvram_wwns(ispsoftc_t *);
static void isp_parse_nvram_2100(ispsoftc_t *, uint8_t *);
static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
@@ -161,15 +161,20 @@ static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
*/
void
-isp_reset(ispsoftc_t *isp)
+isp_reset(ispsoftc_t *isp, int do_load_defaults)
{
mbreg_t mbs;
uint32_t code_org, val;
int loops, i, dodnld = 1;
- static const char *btype = "????";
+ const char *btype = "????";
static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
isp->isp_state = ISP_NILSTATE;
+ if (isp->isp_dead) {
+ isp_shutdown(isp);
+ ISP_DISABLE_INTS(isp);
+ return;
+ }
/*
* Basic types (SCSI, FibreChannel and PCI or SBus)
@@ -181,51 +186,6 @@ isp_reset(ispsoftc_t *isp)
* for SCSI adapters and do other settings for the 2100.
*/
- /*
- * Get the current running firmware revision out of the
- * chip before we hit it over the head (if this is our
- * first time through). Note that we store this as the
- * 'ROM' firmware revision- which it may not be. In any
- * case, we don't really use this yet, but we may in
- * the future.
- */
- if (isp->isp_touched == 0) {
- /*
- * First see whether or not we're sitting in the ISP PROM.
- * If we've just been reset, we'll have the string "ISP "
- * spread through outgoing mailbox registers 1-3. We do
- * this for PCI cards because otherwise we really don't
- * know what state the card is in and we could hang if
- * we try this command otherwise.
- *
- * For SBus cards, we just do this because they almost
- * certainly will be running firmware by now.
- */
- if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 ||
- ISP_READ(isp, OUTMAILBOX2) != 0x5020 ||
- ISP_READ(isp, OUTMAILBOX3) != 0x2020) {
- /*
- * Just in case it was paused...
- */
- 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;
- 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];
- isp->isp_romfw_rev[2] = mbs.param[3];
- }
- }
- isp->isp_touched = 1;
- }
-
ISP_DISABLE_INTS(isp);
/*
@@ -244,17 +204,16 @@ isp_reset(ispsoftc_t *isp)
}
/*
- * Set up DMA for the request and result queues.
+ * Set up DMA for the request and response queues.
*
* We do this now so we can use the request queue
- * for a dma
+ * for dma to load firmware from.
*/
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.
@@ -264,8 +223,6 @@ isp_reset(ispsoftc_t *isp)
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;
@@ -310,6 +267,9 @@ isp_reset(ispsoftc_t *isp)
case ISP_HA_FC_2400:
btype = "2422";
break;
+ case ISP_HA_FC_2500:
+ btype = "2532";
+ break;
default:
break;
}
@@ -326,11 +286,13 @@ isp_reset(ispsoftc_t *isp)
ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
}
} else if (IS_1240(isp)) {
- sdparam *sdp = isp->isp_param;
+ sdparam *sdp;
+
btype = "1240";
isp->isp_clock = 60;
+ sdp = SDPARAM(isp, 0);
sdp->isp_ultramode = 1;
- sdp++;
+ sdp = SDPARAM(isp, 1);
sdp->isp_ultramode = 1;
/*
* XXX: Should probably do some bus sensing.
@@ -355,7 +317,7 @@ isp_reset(ispsoftc_t *isp)
} else if (IS_ULTRA2(isp)) {
static const char m[] = "bus %d is in %s Mode";
uint16_t l;
- sdparam *sdp = isp->isp_param;
+ sdparam *sdp = SDPARAM(isp, 0);
isp->isp_clock = 100;
@@ -387,10 +349,10 @@ isp_reset(ispsoftc_t *isp)
}
if (IS_DUALBUS(isp)) {
- sdp++;
+ sdp = SDPARAM(isp, 1);
l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
l &= ISP1080_MODE_MASK;
- switch(l) {
+ switch (l) {
case ISP1080_LVD_MODE:
sdp->isp_lvdmode = 1;
isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
@@ -412,7 +374,7 @@ isp_reset(ispsoftc_t *isp)
}
}
} else {
- sdparam *sdp = isp->isp_param;
+ sdparam *sdp = SDPARAM(isp, 0);
i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
switch (i) {
default:
@@ -509,7 +471,7 @@ isp_reset(ispsoftc_t *isp)
/*
* Hit the chip over the head with hammer,
- * and give the ISP a chance to recover.
+ * and give it a chance to recover.
*/
if (IS_SCSI(isp)) {
@@ -517,15 +479,13 @@ isp_reset(ispsoftc_t *isp)
/*
* A slight delay...
*/
- USEC_DELAY(100);
+ ISP_DELAY(100);
/*
* Clear data && control DMA engines.
*/
- ISP_WRITE(isp, CDMA_CONTROL,
- DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
- ISP_WRITE(isp, DDMA_CONTROL,
- DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
+ ISP_WRITE(isp, CDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
+ ISP_WRITE(isp, DDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
} else if (IS_24XX(isp)) {
@@ -534,12 +494,12 @@ isp_reset(ispsoftc_t *isp)
*/
ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
for (val = loops = 0; loops < 30000; loops++) {
- USEC_DELAY(10);
+ ISP_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");
@@ -548,11 +508,10 @@ isp_reset(ispsoftc_t *isp)
/*
* 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);
+ ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
+ ISP_DELAY(100);
for (loops = 0; loops < 10000; loops++) {
- USEC_DELAY(5);
+ ISP_DELAY(5);
val = ISP_READ(isp, OUTMAILBOX0);
}
for (val = loops = 0; loops < 500000; loops ++) {
@@ -571,17 +530,14 @@ isp_reset(ispsoftc_t *isp)
/*
* A slight delay...
*/
- USEC_DELAY(100);
+ ISP_DELAY(100);
/*
* Clear data && control DMA engines.
*/
- ISP_WRITE(isp, CDMA2100_CONTROL,
- DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
- ISP_WRITE(isp, TDMA2100_CONTROL,
- DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
- ISP_WRITE(isp, RDMA2100_CONTROL,
- DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
+ ISP_WRITE(isp, CDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
+ ISP_WRITE(isp, TDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
+ ISP_WRITE(isp, RDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
}
/*
@@ -601,7 +557,7 @@ isp_reset(ispsoftc_t *isp)
if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
break;
}
- USEC_DELAY(100);
+ ISP_DELAY(100);
if (--loops < 0) {
ISP_DUMPREGS(isp, "chip reset timed out");
ISP_RESET0(isp);
@@ -629,17 +585,16 @@ isp_reset(ispsoftc_t *isp)
ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
} else {
ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
- USEC_DELAY(100);
+ ISP_DELAY(100);
ISP_WRITE(isp, BIU_SEMA, 0);
}
-
/*
* Post-RISC Reset stuff.
*/
if (IS_24XX(isp)) {
for (val = loops = 0; loops < 5000000; loops++) {
- USEC_DELAY(5);
+ ISP_DELAY(5);
val = ISP_READ(isp, OUTMAILBOX0);
if (val == 0) {
break;
@@ -663,8 +618,8 @@ isp_reset(ispsoftc_t *isp)
ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
}
- if (SDPARAM(isp)->isp_ptisp) {
- if (SDPARAM(isp)->isp_ultramode) {
+ if (SDPARAM(isp, 0)->isp_ptisp) {
+ if (SDPARAM(isp, 0)->isp_ultramode) {
while (ISP_READ(isp, RISC_MTR) != 0x1313) {
ISP_WRITE(isp, RISC_MTR, 0x1313);
ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
@@ -692,7 +647,12 @@ isp_reset(ispsoftc_t *isp)
ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
ISP_WRITE(isp, isp->isp_respinrp, 0);
ISP_WRITE(isp, isp->isp_respoutrp, 0);
-
+ if (IS_24XX(isp)) {
+ ISP_WRITE(isp, BIU2400_PRI_REQINP, 0);
+ ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0);
+ ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0);
+ ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
+ }
/*
* Do MD specific post initialization
@@ -702,15 +662,15 @@ isp_reset(ispsoftc_t *isp)
/*
* Wait for everything to finish firing up.
*
- * Avoid doing this on the 2312 because you can generate a PCI
+ * Avoid doing this on early 2312s because you can generate a PCI
* parity error (chip breakage).
*/
- if (IS_2312(isp)) {
- USEC_DELAY(100);
+ if (IS_2312(isp) && isp->isp_revision < 2) {
+ ISP_DELAY(100);
} else {
loops = MBOX_DELAY_COUNT;
while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
- USEC_DELAY(100);
+ ISP_DELAY(100);
if (--loops < 0) {
ISP_RESET0(isp);
isp_prt(isp, ISP_LOGERR,
@@ -727,19 +687,25 @@ isp_reset(ispsoftc_t *isp)
*/
/*
- * Do some sanity checking.
+ * Do some sanity checking by running a NOP command.
+ * If it succeeds, the ROM firmware is now running.
*/
- MEMZERO(&mbs, sizeof (mbs));
+ ISP_MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_NO_OP;
mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ isp_prt(isp, ISP_LOGERR, "NOP ommand failed (%x)", mbs.param[0]);
ISP_RESET0(isp);
return;
}
+ /*
+ * Do some operational tests
+ */
+
if (IS_SCSI(isp) || IS_24XX(isp)) {
- MEMZERO(&mbs, sizeof (mbs));
+ ISP_MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_MAILBOX_REG_TEST;
mbs.param[1] = 0xdead;
mbs.param[2] = 0xbeef;
@@ -758,10 +724,7 @@ isp_reset(ispsoftc_t *isp)
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],
- mbs.param[4], mbs.param[5]);
+ isp_prt(isp, ISP_LOGERR, "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)", mbs.param[1], mbs.param[2], mbs.param[3], mbs.param[4], mbs.param[5]);
return;
}
@@ -776,8 +739,7 @@ isp_reset(ispsoftc_t *isp)
* whether we have f/w at all and whether a config flag
* has disabled our download.
*/
- if ((isp->isp_mdvec->dv_ispfw == NULL) ||
- (isp->isp_confopts & ISP_CFG_NORELOAD)) {
+ if ((isp->isp_mdvec->dv_ispfw == NULL) || (isp->isp_confopts & ISP_CFG_NORELOAD)) {
dodnld = 0;
}
@@ -793,13 +755,6 @@ isp_reset(ispsoftc_t *isp)
const uint32_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 */
@@ -807,9 +762,7 @@ isp_reset(ispsoftc_t *isp)
for (;;) {
uint32_t la, wi, wl;
- isp_prt(isp, ISP_LOGDEBUG0,
- "load 0x%x words of code at load address 0x%x",
- ptr[3], ptr[2]);
+ 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];
@@ -828,23 +781,31 @@ isp_reset(ispsoftc_t *isp)
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;
+ MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
+ ISP_MEMZERO(&mbs, sizeof (mbs));
+ if (la < 0x10000 && nw < 0x10000) {
+ mbs.param[0] = MBOX_LOAD_RISC_RAM_2100;
+ 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);
+ } else {
+ 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_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
ISP_RESET0(isp);
return;
}
@@ -855,7 +816,7 @@ isp_reset(ispsoftc_t *isp)
break;
}
ptr += ptr[3];
- }
+ }
isp->isp_loaded_fw = 1;
} else if (dodnld && IS_23XX(isp)) {
const uint16_t *ptr = isp->isp_mdvec->dv_ispfw;
@@ -868,17 +829,15 @@ isp_reset(ispsoftc_t *isp)
for (;;) {
uint32_t nxtaddr;
- isp_prt(isp, ISP_LOGDEBUG0,
- "load 0x%x words of code at load address 0x%x",
- ptr[3], la);
+ 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]) {
uint16_t *cp;
- uint32_t nw;
-
+ uint16_t nw;
+
nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 1;
if (nw > wl) {
nw = wl;
@@ -891,22 +850,30 @@ isp_reset(ispsoftc_t *isp)
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;
+ MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
+ ISP_MEMZERO(&mbs, sizeof (mbs));
+ if (la < 0x10000) {
+ mbs.param[0] = MBOX_LOAD_RISC_RAM_2100;
+ 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);
+ } else {
+ 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_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
ISP_RESET0(isp);
return;
}
@@ -914,19 +881,6 @@ isp_reset(ispsoftc_t *isp)
}
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;
}
@@ -951,41 +905,45 @@ isp_reset(ispsoftc_t *isp)
union {
const uint16_t *cp;
uint16_t *np;
- } u;
- u.cp = isp->isp_mdvec->dv_ispfw;
- isp->isp_mbxworkp = &u.np[1];
- isp->isp_mbxwrk0 = u.np[3] - 1;
+ } ucd;
+ ucd.cp = isp->isp_mdvec->dv_ispfw;
+ isp->isp_mbxworkp = &ucd.np[1];
+ isp->isp_mbxwrk0 = ucd.np[3] - 1;
isp->isp_mbxwrk1 = code_org + 1;
- MEMZERO(&mbs, sizeof (mbs));
+ ISP_MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_WRITE_RAM_WORD;
mbs.param[1] = code_org;
- mbs.param[2] = u.np[0];
+ mbs.param[2] = ucd.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);
+ isp_prt(isp, ISP_LOGERR, "F/W download failed at word %d", isp->isp_mbxwrk1 - code_org);
ISP_RESET0(isp);
return;
}
- /*
- * Verify that it downloaded correctly.
- */
- MEMZERO(&mbs, sizeof (mbs));
+ } else {
+ isp->isp_loaded_fw = 0;
+ isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
+ }
+
+ /*
+ * If we loaded firmware, verify its checksum
+ */
+ if (isp->isp_loaded_fw) {
+ ISP_MEMZERO(&mbs, sizeof (mbs));
mbs.param[0] = MBOX_VERIFY_CHECKSUM;
- mbs.param[1] = code_org;
- mbs.logval = MBLOGNONE;
+ if (IS_24XX(isp)) {
+ mbs.param[1] = code_org >> 16;
+ mbs.param[2] = code_org;
+ } else {
+ mbs.param[1] = code_org;
+ }
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGERR, dcrc);
ISP_RESET0(isp);
return;
}
- isp->isp_loaded_fw = 1;
- } else {
- isp->isp_loaded_fw = 0;
- isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
}
/*
@@ -996,9 +954,7 @@ isp_reset(ispsoftc_t *isp)
*/
- MEMZERO(&mbs, sizeof (mbs));
- mbs.timeout = 1000000;
- mbs.param[0] = MBOX_EXEC_FIRMWARE;
+ MBSINIT(&mbs, MBOX_EXEC_FIRMWARE, MBLOGALL, 1000000);
if (IS_24XX(isp)) {
mbs.param[1] = code_org >> 16;
mbs.param[2] = code_org;
@@ -1007,6 +963,9 @@ isp_reset(ispsoftc_t *isp)
} else {
mbs.param[3] = 1;
}
+ if (IS_25XX(isp)) {
+ mbs.ibits |= 0x10;
+ }
} else if (IS_2322(isp)) {
mbs.param[1] = code_org;
if (isp->isp_loaded_fw) {
@@ -1017,8 +976,6 @@ isp_reset(ispsoftc_t *isp)
} 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) {
@@ -1029,37 +986,45 @@ isp_reset(ispsoftc_t *isp)
/*
* Give it a chance to finish starting up.
+ * Give the 24XX more time.
*/
- USEC_DELAY(250000);
-
- if (IS_SCSI(isp)) {
+ if (IS_24XX(isp)) {
+ ISP_DELAY(500000);
/*
- * Set CLOCK RATE, but only if asked to.
+ * Check to see if the 24XX firmware really started.
*/
- if (isp->isp_clock) {
- mbs.param[0] = MBOX_SET_CLOCK_RATE;
- mbs.param[1] = isp->isp_clock;
- mbs.logval = MBLOGNONE;
- isp_mboxcmd(isp, &mbs);
- /* we will try not to care if this fails */
+ if (mbs.param[1] == 0xdead) {
+ isp_prt(isp, ISP_LOGERR, "f/w didn't *really* start");
+ ISP_RESET0(isp);
+ return;
+ }
+ } else {
+ ISP_DELAY(250000);
+ if (IS_SCSI(isp)) {
+ /*
+ * Set CLOCK RATE, but only if asked to.
+ */
+ if (isp->isp_clock) {
+ mbs.param[0] = MBOX_SET_CLOCK_RATE;
+ mbs.param[1] = isp->isp_clock;
+ 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;
- mbs.logval = MBLOGALL;
+ /*
+ * Ask the chip for the current firmware version.
+ * This should prove that the new firmware is working.
+ */
+ MBSINIT(&mbs, MBOX_ABOUT_FIRMWARE, MBLOGALL, 0);
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;
- }
-
/*
* The SBus firmware that we are using apparently does not return
* major, minor, micro revisions in the mailbox registers, which
@@ -1075,17 +1040,15 @@ isp_reset(ispsoftc_t *isp)
isp->isp_fwrev[1] = 37;
#endif
isp->isp_fwrev[2] = 0;
- }
+ }
} else {
isp->isp_fwrev[0] = mbs.param[1];
isp->isp_fwrev[1] = mbs.param[2];
isp->isp_fwrev[2] = mbs.param[3];
}
- 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]);
+ isp_prt(isp, ISP_LOGCONFIG, "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]);
if (IS_FC(isp)) {
/*
@@ -1097,50 +1060,24 @@ isp_reset(ispsoftc_t *isp)
*/
if ((ISP_FW_OLDER_THAN(isp, 1, 17, 1))) {
#ifdef USE_SMALLER_2100_FIRMWARE
- FCPARAM(isp)->isp_fwattr = ISP_FW_ATTR_SCCLUN;
+ isp->isp_fwattr = ISP_FW_ATTR_SCCLUN;
#else
- FCPARAM(isp)->isp_fwattr = 0;
+ isp->isp_fwattr = 0;
#endif
} else {
- FCPARAM(isp)->isp_fwattr = mbs.param[6];
- isp_prt(isp, ISP_LOGDEBUG0,
- "Firmware Attributes = 0x%x", mbs.param[6]);
+ isp->isp_fwattr = mbs.param[6];
+ isp_prt(isp, ISP_LOGDEBUG0, "Firmware Attributes = 0x%x", mbs.param[6]);
}
- 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");
- }
- }
-
- if (isp->isp_romfw_rev[0] || isp->isp_romfw_rev[1] ||
- isp->isp_romfw_rev[2]) {
- isp_prt(isp, ISP_LOGCONFIG, "Last F/W revision was %d.%d.%d",
- isp->isp_romfw_rev[0], isp->isp_romfw_rev[1],
- isp->isp_romfw_rev[2]);
+ } else {
+#ifndef ISP_TARGET_MODE
+ isp->isp_fwattr = ISP_FW_ATTR_TMODE;
+#else
+ isp->isp_fwattr = 0;
+#endif
}
if (!IS_24XX(isp)) {
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
- mbs.logval = MBLOGALL;
+ MBSINIT(&mbs, MBOX_GET_FIRMWARE_STATUS, MBLOGALL, 0);
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
ISP_RESET0(isp);
@@ -1150,9 +1087,26 @@ isp_reset(ispsoftc_t *isp)
isp->isp_maxcmds = mbs.param[2];
}
}
- isp_prt(isp, ISP_LOGCONFIG,
- "%d max I/O command limit set", isp->isp_maxcmds);
- isp_fw_state(isp);
+ isp_prt(isp, ISP_LOGCONFIG, "%d max I/O command limit set", isp->isp_maxcmds);
+
+ /*
+ * If we don't have Multi-ID f/w loaded, we need to restrict channels to one.
+ * Only make this check for non-SCSI cards (I'm not sure firmware attributes
+ * work for them).
+ */
+ if (IS_FC(isp) && ISP_CAP_MULTI_ID(isp) == 0 && isp->isp_nchan > 1) {
+ isp_prt(isp, ISP_LOGWARN, "non-MULTIID f/w loaded, only can enable 1 of %d channels", isp->isp_nchan);
+ isp->isp_nchan = 1;
+ }
+
+ for (i = 0; i < isp->isp_nchan; i++) {
+ isp_fw_state(isp, i);
+ }
+ if (isp->isp_dead) {
+ isp_shutdown(isp);
+ ISP_DISABLE_INTS(isp);
+ return;
+ }
isp->isp_state = ISP_RESETSTATE;
@@ -1184,24 +1138,27 @@ isp_reset(ispsoftc_t *isp)
isp->isp_maxluns = 8;
}
} else {
- if (FCPARAM(isp)->isp_sccfw) {
+ if (ISP_CAP_SCCFW(isp)) {
isp->isp_maxluns = 16384;
} else {
isp->isp_maxluns = 16;
}
}
+
/*
- * Must do this first to get defaults established.
+ * We get some default values established. As a side
+ * effect, NVRAM is read here (unless overriden by
+ * a configuration flag).
*/
- if (IS_SCSI(isp)) {
- isp_setdfltparm(isp, 0);
- if (IS_DUALBUS(isp)) {
- isp_setdfltparm(isp, 1);
+ if (do_load_defaults) {
+ if (IS_SCSI(isp)) {
+ isp_setdfltsdparm(isp);
+ } else {
+ for (i = 0; i < isp->isp_nchan; i++) {
+ isp_setdfltfcparm(isp, i);
+ }
}
- } else {
- isp_setdfltfcparm(isp);
}
-
}
/*
@@ -1214,23 +1171,15 @@ void
isp_init(ispsoftc_t *isp)
{
if (IS_FC(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);
- }
+ if (IS_24XX(isp)) {
+ isp_fibre_init_2400(isp);
+ } else {
+ isp_fibre_init(isp);
}
} else {
isp_scsi_init(isp);
}
+ GET_NANOTIME(&isp->isp_init_time);
}
static void
@@ -1239,17 +1188,10 @@ isp_scsi_init(ispsoftc_t *isp)
sdparam *sdp_chan0, *sdp_chan1;
mbreg_t mbs;
- sdp_chan0 = isp->isp_param;
+ sdp_chan0 = SDPARAM(isp, 0);
sdp_chan1 = sdp_chan0;
if (IS_DUALBUS(isp)) {
- sdp_chan1++;
- }
-
- /*
- * If we have no role (neither target nor initiator), return.
- */
- if (isp->isp_role == ISP_ROLE_NONE) {
- return;
+ sdp_chan1 = SDPARAM(isp, 1);
}
/* First do overall per-card settings. */
@@ -1265,13 +1207,11 @@ isp_scsi_init(ispsoftc_t *isp)
* Set Retry Delay and Count.
* You set both channels at the same time.
*/
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SET_RETRY_COUNT;
+ MBSINIT(&mbs, MBOX_SET_RETRY_COUNT, MBLOGALL, 0);
mbs.param[1] = sdp_chan0->isp_retry_count;
mbs.param[2] = sdp_chan0->isp_retry_delay;
mbs.param[6] = sdp_chan1->isp_retry_count;
mbs.param[7] = sdp_chan1->isp_retry_delay;
- mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
@@ -1280,11 +1220,9 @@ isp_scsi_init(ispsoftc_t *isp)
/*
* Set ASYNC DATA SETUP time. This is very important.
*/
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
+ MBSINIT(&mbs, MBOX_SET_ASYNC_DATA_SETUP_TIME, MBLOGALL, 0);
mbs.param[1] = sdp_chan0->isp_async_data_setup;
mbs.param[2] = sdp_chan1->isp_async_data_setup;
- mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
@@ -1293,15 +1231,13 @@ isp_scsi_init(ispsoftc_t *isp)
/*
* Set ACTIVE Negation State.
*/
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SET_ACT_NEG_STATE;
+ MBSINIT(&mbs, MBOX_SET_ACT_NEG_STATE, MBLOGNONE, 0);
mbs.param[1] =
(sdp_chan0->isp_req_ack_active_neg << 4) |
(sdp_chan0->isp_data_line_active_neg << 5);
mbs.param[2] =
(sdp_chan1->isp_req_ack_active_neg << 4) |
(sdp_chan1->isp_data_line_active_neg << 5);
- mbs.logval = MBLOGNONE;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGERR,
@@ -1318,11 +1254,9 @@ isp_scsi_init(ispsoftc_t *isp)
/*
* Set the Tag Aging limit
*/
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT;
+ MBSINIT(&mbs, MBOX_SET_TAG_AGE_LIMIT, MBLOGALL, 0);
mbs.param[1] = sdp_chan0->isp_tag_aging;
mbs.param[2] = sdp_chan1->isp_tag_aging;
- 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)",
@@ -1333,11 +1267,9 @@ isp_scsi_init(ispsoftc_t *isp)
/*
* Set selection timeout.
*/
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SET_SELECT_TIMEOUT;
+ MBSINIT(&mbs, MBOX_SET_SELECT_TIMEOUT, MBLOGALL, 0);
mbs.param[1] = sdp_chan0->isp_selection_timeout;
mbs.param[2] = sdp_chan1->isp_selection_timeout;
- mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
@@ -1353,56 +1285,48 @@ isp_scsi_init(ispsoftc_t *isp)
*/
if (IS_ULTRA2(isp) || IS_1240(isp)) {
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_INIT_RES_QUEUE_A64;
+ MBSINIT(&mbs, MBOX_INIT_RES_QUEUE_A64, MBLOGALL, 0);
mbs.param[1] = RESULT_QUEUE_LEN(isp);
mbs.param[2] = DMA_WD1(isp->isp_result_dma);
mbs.param[3] = DMA_WD0(isp->isp_result_dma);
mbs.param[4] = 0;
mbs.param[6] = DMA_WD3(isp->isp_result_dma);
mbs.param[7] = DMA_WD2(isp->isp_result_dma);
- mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
}
isp->isp_residx = mbs.param[5];
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_INIT_REQ_QUEUE_A64;
+ MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE_A64, MBLOGALL, 0);
mbs.param[1] = RQUEST_QUEUE_LEN(isp);
mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
mbs.param[5] = 0;
mbs.param[6] = DMA_WD3(isp->isp_result_dma);
mbs.param[7] = DMA_WD2(isp->isp_result_dma);
- mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
}
isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
} else {
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_INIT_RES_QUEUE;
+ MBSINIT(&mbs, MBOX_INIT_RES_QUEUE, MBLOGALL, 0);
mbs.param[1] = RESULT_QUEUE_LEN(isp);
mbs.param[2] = DMA_WD1(isp->isp_result_dma);
mbs.param[3] = DMA_WD0(isp->isp_result_dma);
mbs.param[4] = 0;
- mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
}
isp->isp_residx = mbs.param[5];
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_INIT_REQ_QUEUE;
+ MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE, MBLOGALL, 0);
mbs.param[1] = RQUEST_QUEUE_LEN(isp);
mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
mbs.param[5] = 0;
- mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
@@ -1419,9 +1343,7 @@ isp_scsi_init(ispsoftc_t *isp)
* to assume not for them.
*/
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SET_FW_FEATURES;
- mbs.param[1] = 0;
+ MBSINIT(&mbs, MBOX_SET_FW_FEATURES, MBLOGALL, 0);
if (IS_ULTRA2(isp))
mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
#ifndef ISP_NO_RIO
@@ -1433,7 +1355,6 @@ isp_scsi_init(ispsoftc_t *isp)
#endif
if (mbs.param[1] != 0) {
uint16_t sfeat = mbs.param[1];
- mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGINFO,
@@ -1441,35 +1362,29 @@ isp_scsi_init(ispsoftc_t *isp)
}
}
- /*
- * Let the outer layers decide whether to issue a SCSI bus reset.
- */
isp->isp_state = ISP_INITSTATE;
}
static void
-isp_scsi_channel_init(ispsoftc_t *isp, int channel)
+isp_scsi_channel_init(ispsoftc_t *isp, int chan)
{
sdparam *sdp;
mbreg_t mbs;
int tgt;
- sdp = isp->isp_param;
- sdp += channel;
+ sdp = SDPARAM(isp, chan);
/*
* Set (possibly new) Initiator ID.
*/
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
- mbs.param[1] = (channel << 7) | sdp->isp_initiator_id;
- mbs.logval = MBLOGALL;
+ MBSINIT(&mbs, MBOX_SET_INIT_SCSI_ID, MBLOGALL, 0);
+ mbs.param[1] = (chan << 7) | sdp->isp_initiator_id;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
}
- isp_prt(isp, ISP_LOGINFO, "Initiator ID is %d on Channel %d",
- sdp->isp_initiator_id, channel);
+ isp_prt(isp, ISP_LOGINFO, "Chan %d Initiator ID is %d",
+ chan, sdp->isp_initiator_id);
/*
@@ -1505,9 +1420,8 @@ isp_scsi_channel_init(ispsoftc_t *isp, int channel)
*/
sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT;
#endif
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SET_TARGET_PARAMS;
- mbs.param[1] = (channel << 15) | (tgt << 8);
+ MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGNONE, 0);
+ mbs.param[1] = (chan << 15) | (tgt << 8);
mbs.param[2] = sdf;
if ((sdf & DPARM_SYNC) == 0) {
mbs.param[3] = 0;
@@ -1518,18 +1432,15 @@ isp_scsi_channel_init(ispsoftc_t *isp, int channel)
}
isp_prt(isp, ISP_LOGDEBUG0,
"Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
- channel, tgt, mbs.param[2], mbs.param[3] >> 8,
+ chan, tgt, mbs.param[2], mbs.param[3] >> 8,
mbs.param[3] & 0xff);
- mbs.logval = MBLOGNONE;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
sdf = DPARM_SAFE_DFLT;
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SET_TARGET_PARAMS;
- mbs.param[1] = (tgt << 8) | (channel << 15);
+ MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGALL, 0);
+ mbs.param[1] = (tgt << 8) | (chan << 15);
mbs.param[2] = sdf;
mbs.param[3] = 0;
- mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
continue;
@@ -1549,12 +1460,10 @@ isp_scsi_channel_init(ispsoftc_t *isp, int channel)
*/
sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING;
for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
- mbs.param[1] = (channel << 15) | (tgt << 8) | lun;
+ MBSINIT(&mbs, MBOX_SET_DEV_QUEUE_PARAMS, MBLOGALL, 0);
+ mbs.param[1] = (chan << 15) | (tgt << 8) | lun;
mbs.param[2] = sdp->isp_max_queue_depth;
mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
- mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
break;
@@ -1563,8 +1472,8 @@ isp_scsi_channel_init(ispsoftc_t *isp, int channel)
}
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
if (sdp->isp_devparam[tgt].dev_refresh) {
- isp->isp_sendmarker |= (1 << channel);
- isp->isp_update |= (1 << channel);
+ sdp->sendmarker = 1;
+ sdp->update = 1;
break;
}
}
@@ -1580,11 +1489,17 @@ isp_fibre_init(ispsoftc_t *isp)
isp_icb_t local, *icbp = &local;
mbreg_t mbs;
int ownloopid;
- uint64_t nwwn, pwwn;
- fcp = isp->isp_param;
+ /*
+ * We only support one channel on non-24XX cards
+ */
+ fcp = FCPARAM(isp, 0);
+ if (fcp->role == ISP_ROLE_NONE) {
+ isp->isp_state = ISP_INITSTATE;
+ return;
+ }
- MEMZERO(icbp, sizeof (*icbp));
+ ISP_MEMZERO(icbp, sizeof (*icbp));
icbp->icb_version = ICB_VERSION1;
icbp->icb_fwoptions = fcp->isp_fwoptions;
@@ -1619,24 +1534,24 @@ isp_fibre_init(ispsoftc_t *isp)
/*
* Make sure that target role reflects into fwoptions.
*/
- if (isp->isp_role & ISP_ROLE_TARGET) {
+ if (fcp->role & ISP_ROLE_TARGET) {
icbp->icb_fwoptions |= ICBOPT_TGT_ENABLE;
} else {
icbp->icb_fwoptions &= ~ICBOPT_TGT_ENABLE;
}
- if (isp->isp_role & ISP_ROLE_INITIATOR) {
+ if (fcp->role & ISP_ROLE_INITIATOR) {
icbp->icb_fwoptions &= ~ICBOPT_INI_DISABLE;
} else {
icbp->icb_fwoptions |= ICBOPT_INI_DISABLE;
}
- icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
+ icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
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);
+ DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
}
icbp->icb_maxalloc = fcp->isp_maxalloc;
@@ -1645,18 +1560,18 @@ isp_fibre_init(ispsoftc_t *isp)
"bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
icbp->icb_maxalloc = 16;
}
- icbp->icb_execthrottle = fcp->isp_execthrottle;
+ icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
if (icbp->icb_execthrottle < 1) {
isp_prt(isp, ISP_LOGERR,
- "bad execution throttle of %d- using 16",
- fcp->isp_execthrottle);
+ "bad execution throttle of %d- using %d",
+ DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
}
icbp->icb_retry_delay = fcp->isp_retry_delay;
icbp->icb_retry_count = fcp->isp_retry_count;
icbp->icb_hardaddr = fcp->isp_loopid;
ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
- if (icbp->icb_hardaddr > 125) {
+ if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
icbp->icb_hardaddr = 0;
ownloopid = 0;
}
@@ -1672,7 +1587,7 @@ isp_fibre_init(ispsoftc_t *isp)
/*
* Right now we just set extended options to prefer point-to-point
* over loop based upon some soft config options.
- *
+ *
* NB: for the 2300, ICBOPT_EXTENDED is required.
*/
if (IS_2200(isp) || IS_23XX(isp)) {
@@ -1680,7 +1595,7 @@ isp_fibre_init(ispsoftc_t *isp)
/*
* Prefer or force Point-To-Point instead Loop?
*/
- switch(isp->isp_confopts & ISP_CFG_PORT_PREF) {
+ switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
case ISP_CFG_NPORT:
icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP;
break;
@@ -1695,7 +1610,26 @@ isp_fibre_init(ispsoftc_t *isp)
break;
}
if (IS_2200(isp)) {
+ /*
+ * There seems to just be too much breakage here
+ * with RIO and Fast Posting- it probably actually
+ * works okay but this driver is messing it up.
+ * This card is really ancient by now, so let's
+ * just opt for safety and not use the feature.
+ */
+#if 0
+ if (ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
+ icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
+ icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
+ icbp->icb_racctimer = 4;
+ icbp->icb_idelaytimer = 8;
+ } else {
+ icbp->icb_fwoptions |= ICBOPT_FAST_POST;
+ }
+#else
+ icbp->icb_xfwoptions &= ~ICBXOPT_RIO_16BIT;
icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
+#endif
} else {
/*
* QLogic recommends that FAST Posting be turned
@@ -1704,8 +1638,7 @@ isp_fibre_init(ispsoftc_t *isp)
* after a delay (ZIO).
*/
icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
- if ((fcp->isp_xfwoptions & ICBXOPT_TIMER_MASK) ==
- ICBXOPT_ZIO) {
+ if ((fcp->isp_xfwoptions & ICBXOPT_TIMER_MASK) == ICBXOPT_ZIO) {
icbp->icb_xfwoptions |= ICBXOPT_ZIO;
icbp->icb_idelaytimer = 10;
}
@@ -1733,12 +1666,10 @@ isp_fibre_init(ispsoftc_t *isp)
* Turn on generate AE 8013 on all LIP Resets (2)
* Disable LIP F7 switching (8)
*/
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS;
+ MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
mbs.param[1] = 0xb;
mbs.param[2] = 0;
mbs.param[3] = 0;
- mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
@@ -1747,25 +1678,23 @@ isp_fibre_init(ispsoftc_t *isp)
icbp->icb_logintime = ICB_LOGIN_TOV;
icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV;
- nwwn = ISP_NODEWWN(isp);
- pwwn = ISP_PORTWWN(isp);
- if (nwwn && pwwn) {
+ if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
- MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn);
- MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
+ MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
+ MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
isp_prt(isp, ISP_LOGDEBUG1,
"Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
- ((uint32_t) (nwwn >> 32)),
- ((uint32_t) (nwwn & 0xffffffff)),
- ((uint32_t) (pwwn >> 32)),
- ((uint32_t) (pwwn & 0xffffffff)));
- } else if (pwwn) {
+ ((uint32_t) (fcp->isp_wwnn >> 32)),
+ ((uint32_t) (fcp->isp_wwnn)),
+ ((uint32_t) (fcp->isp_wwpn >> 32)),
+ ((uint32_t) (fcp->isp_wwpn)));
+ } else if (fcp->isp_wwpn) {
icbp->icb_fwoptions &= ~ICBOPT_BOTH_WWNS;
- MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
+ MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
isp_prt(isp, ISP_LOGDEBUG1,
"Setting ICB Port 0x%08x%08x",
- ((uint32_t) (pwwn >> 32)),
- ((uint32_t) (pwwn & 0xffffffff)));
+ ((uint32_t) (fcp->isp_wwpn >> 32)),
+ ((uint32_t) (fcp->isp_wwpn)));
} else {
isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
return;
@@ -1787,30 +1716,31 @@ isp_fibre_init(ispsoftc_t *isp)
icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
+ if (FC_SCRATCH_ACQUIRE(isp, 0)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ return;
+ }
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);
- FC_SCRATCH_ACQUIRE(isp);
isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
/*
* Init the firmware
*/
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_INIT_FIRMWARE;
+ MBSINIT(&mbs, MBOX_INIT_FIRMWARE, MBLOGALL, 30000000);
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 = 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);
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp));
isp_mboxcmd(isp, &mbs);
- FC_SCRATCH_RELEASE(isp);
+ FC_SCRATCH_RELEASE(isp, 0);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_print_bytes(isp, "isp_fibre_init", sizeof (*icbp), icbp);
return;
@@ -1831,65 +1761,71 @@ isp_fibre_init_2400(ispsoftc_t *isp)
fcparam *fcp;
isp_icb_2400_t local, *icbp = &local;
mbreg_t mbs;
- int ownloopid;
- uint64_t nwwn, pwwn;
+ int chan;
+
+ /*
+ * Check to see whether all channels have *some* kind of role
+ */
+ for (chan = 0; chan < isp->isp_nchan; chan++) {
+ fcp = FCPARAM(isp, chan);
+ if (fcp->role != ISP_ROLE_NONE) {
+ break;
+ }
+ }
+ if (chan == isp->isp_nchan) {
+ isp_prt(isp, ISP_LOGDEBUG0, "all %d channels with role 'none'", chan);
+ isp->isp_state = ISP_INITSTATE;
+ return;
+ }
- fcp = isp->isp_param;
+ /*
+ * Start with channel 0.
+ */
+ fcp = FCPARAM(isp, 0);
/*
* Turn on LIP F8 async event (1)
*/
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS;
+ MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
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;
+ ISP_MEMZERO(icbp, sizeof (*icbp));
+ icbp->icb_fwoptions1 = fcp->isp_fwoptions;
+ if (fcp->role & ISP_ROLE_TARGET) {
+ icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
} else {
- fcp->isp_fwoptions &= ~ICB2400_OPT1_TGT_ENABLE;
+ icbp->icb_fwoptions1 &= ~ICB2400_OPT1_TGT_ENABLE;
}
- if (isp->isp_role & ISP_ROLE_INITIATOR) {
- fcp->isp_fwoptions &= ~ICB2400_OPT1_INI_DISABLE;
+ if (fcp->role & ISP_ROLE_INITIATOR) {
+ icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
} else {
- fcp->isp_fwoptions |= ICB2400_OPT1_INI_DISABLE;
+ icbp->icb_fwoptions1 |= 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 = DEFAULT_FRAMESIZE(isp);
+ 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", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
}
- icbp->icb_execthrottle = fcp->isp_execthrottle;
+ icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
if (icbp->icb_execthrottle < 1) {
- isp_prt(isp, ISP_LOGERR,
- "bad execution throttle of %d- using 16",
- fcp->isp_execthrottle);
+ isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
}
- if (isp->isp_role & ISP_ROLE_TARGET) {
+ if (icbp->icb_fwoptions1 & ICB2400_OPT1_TGT_ENABLE) {
/*
* Get current resource count
*/
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_GET_RESOURCE_COUNT;
+ MBSINIT(&mbs, MBOX_GET_RESOURCE_COUNT, MBLOGALL, 0);
mbs.obits = 0x4cf;
- mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
@@ -1897,24 +1833,28 @@ isp_fibre_init_2400(ispsoftc_t *isp)
icbp->icb_xchgcnt = mbs.param[3];
}
- 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) {
+ if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
icbp->icb_hardaddr = 0;
- ownloopid = 0;
- }
- if (ownloopid) {
- icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS;
}
+ /*
+ * Force this on.
+ */
+ icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS;
+
icbp->icb_fwoptions2 = fcp->isp_xfwoptions;
- switch(isp->isp_confopts & ISP_CFG_PORT_PREF) {
+ switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
+#if 0
case ISP_CFG_NPORT:
+ /*
+ * XXX: This causes the f/w to crash.
+ */
icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_2_LOOP;
break;
+#endif
case ISP_CFG_NPORT_ONLY:
icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY;
@@ -1929,6 +1869,9 @@ isp_fibre_init_2400(ispsoftc_t *isp)
break;
}
+ /* force this on for now */
+ icbp->icb_fwoptions2 |= ICB2400_OPT2_ZIO;
+
switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) {
case ICB2400_OPT2_ZIO:
case ICB2400_OPT2_ZIO1:
@@ -1937,12 +1880,16 @@ isp_fibre_init_2400(ispsoftc_t *isp)
case 0:
break;
default:
- isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field",
- icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
+ 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;
}
+ /*
+ * We don't support FCTAPE, so clear it.
+ */
+ icbp->icb_fwoptions2 &= ~ICB2400_OPT2_FCTAPE;
+
icbp->icb_fwoptions3 = fcp->isp_zfwoptions;
icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_AUTO;
if (isp->isp_confopts & ISP_CFG_ONEGB) {
@@ -1960,26 +1907,16 @@ isp_fibre_init_2400(ispsoftc_t *isp)
}
icbp->icb_logintime = ICB_LOGIN_TOV;
- nwwn = ISP_NODEWWN(isp);
- pwwn = ISP_PORTWWN(isp);
-
- if (nwwn && pwwn) {
+ if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
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",
- ((uint32_t) (nwwn >> 32)),
- ((uint32_t) (nwwn & 0xffffffff)),
- ((uint32_t) (pwwn >> 32)),
- ((uint32_t) (pwwn & 0xffffffff)));
- } else if (pwwn) {
+ MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
+ MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
+ isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node 0x%08x%08x Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwnn >> 32)), ((uint32_t) (fcp->isp_wwnn)),
+ ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
+ } else if (fcp->isp_wwpn) {
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",
- ((uint32_t) (pwwn >> 32)),
- ((uint32_t) (pwwn & 0xffffffff)));
+ MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
+ isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node to be same as Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
} else {
isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
return;
@@ -1988,8 +1925,7 @@ isp_fibre_init_2400(ispsoftc_t *isp)
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);
+ isp_prt(isp, ISP_LOGERR, "bad request queue length %d", icbp->icb_rqstqlen);
return;
}
icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
@@ -2009,64 +1945,95 @@ isp_fibre_init_2400(ispsoftc_t *isp)
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));
+ /* unconditionally set up the ATIO queue if we support target mode */
+ 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: 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),
+ 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);
+ isp_print_bytes(isp, "isp_fibre_init_2400", sizeof (*icbp), icbp);
}
- FC_SCRATCH_ACQUIRE(isp);
+
+ if (FC_SCRATCH_ACQUIRE(isp, 0)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ return;
+ }
+ ISP_MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN);
isp_put_icb_2400(isp, icbp, fcp->isp_scratch);
+ /*
+ * Now fill in information about any additional channels
+ */
+ if (isp->isp_nchan > 1) {
+ isp_icb_2400_vpinfo_t vpinfo, *vdst;
+ vp_port_info_t pi, *pdst;
+ size_t amt = 0;
+ uint8_t *off;
+
+ vpinfo.vp_count = isp->isp_nchan - 1;
+ vpinfo.vp_global_options = 0;
+ off = fcp->isp_scratch;
+ off += ICB2400_VPINFO_OFF;
+ vdst = (isp_icb_2400_vpinfo_t *) off;
+ isp_put_icb_2400_vpinfo(isp, &vpinfo, vdst);
+ amt = ICB2400_VPINFO_OFF + sizeof (isp_icb_2400_vpinfo_t);
+ for (chan = 1; chan < isp->isp_nchan; chan++) {
+ fcparam *fcp2;
+
+ ISP_MEMZERO(&pi, sizeof (pi));
+ fcp2 = FCPARAM(isp, chan);
+ if (fcp2->role != ISP_ROLE_NONE) {
+ pi.vp_port_options = ICB2400_VPOPT_ENABLED;
+ if (fcp2->role & ISP_ROLE_INITIATOR) {
+ pi.vp_port_options |= ICB2400_VPOPT_INI_ENABLE;
+ }
+ if ((fcp2->role & ISP_ROLE_TARGET) == 0) {
+ pi.vp_port_options |= ICB2400_VPOPT_TGT_DISABLE;
+ }
+ MAKE_NODE_NAME_FROM_WWN(pi.vp_port_portname, fcp2->isp_wwpn);
+ MAKE_NODE_NAME_FROM_WWN(pi.vp_port_nodename, fcp2->isp_wwnn);
+ }
+ off = fcp->isp_scratch;
+ off += ICB2400_VPINFO_PORT_OFF(chan);
+ pdst = (vp_port_info_t *) off;
+ isp_put_vp_port_info(isp, &pi, pdst);
+ amt += ICB2400_VPOPT_WRITE_SIZE;
+ }
+ }
/*
* Init the firmware
*/
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_INIT_FIRMWARE;
+ MBSINIT(&mbs, 0, MBLOGALL, 30000000);
+ if (isp->isp_nchan > 1) {
+ mbs.param[0] = MBOX_INIT_FIRMWARE_MULTI_ID;
+ } else {
+ mbs.param[0] = MBOX_INIT_FIRMWARE;
+ }
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 = 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));
+ 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);
+ FC_SCRATCH_RELEASE(isp, 0);
+
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
}
@@ -2081,30 +2048,40 @@ isp_fibre_init_2400(ispsoftc_t *isp)
}
static void
-isp_mark_portdb(ispsoftc_t *isp, int onprobation)
+isp_mark_portdb(ispsoftc_t *isp, int chan, int disposition)
{
- fcparam *fcp = (fcparam *) isp->isp_param;
+ fcparam *fcp = FCPARAM(isp, chan);
int i;
+ if (chan < 0 || chan >= isp->isp_nchan) {
+ isp_prt(isp, ISP_LOGWARN, "isp_mark_portdb: bad channel %d", chan);
+ return;
+ }
for (i = 0; i < MAX_FC_TARG; i++) {
- if (onprobation == 0) {
- MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
+ if (fcp->portdb[i].target_mode) {
+ if (disposition < 0) {
+ isp_prt(isp, ISP_LOGTINFO, "isp_mark_portdb: Chan %d zeroing handle 0x" "%04x port 0x%06x", chan,
+ fcp->portdb[i].handle, fcp->portdb[i].portid);
+ ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
+ }
+ continue;
+ }
+ if (disposition == 0) {
+ ISP_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;
+ 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;
+ ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
+ fcp->portdb[i].state = FC_PORTDB_STATE_NIL;
break;
}
}
@@ -2116,14 +2093,18 @@ isp_mark_portdb(ispsoftc_t *isp, int onprobation)
* or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
*/
static int
-isp_plogx(ispsoftc_t *isp, uint16_t handle, uint32_t portid, int flags, int gs)
+isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid,
+ int flags, int gs)
{
mbreg_t mbs;
uint8_t q[QENTRY_LEN];
isp_plogx_t *plp;
+ fcparam *fcp;
uint8_t *scp;
uint32_t sst, parm1;
- int rval;
+ int rval, lev;
+ const char *msg;
+ char buf[64];
if (!IS_24XX(isp)) {
int action = flags & PLOGX_FLG_CMD_MASK;
@@ -2136,12 +2117,13 @@ isp_plogx(ispsoftc_t *isp, uint16_t handle, uint32_t portid, int flags, int gs)
}
}
- MEMZERO(q, QENTRY_LEN);
+ ISP_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_vphdl = chan;
plp->plogx_portlo = portid;
plp->plogx_rspsz_porthi = (portid >> 16) & 0xff;
plp->plogx_flags = flags;
@@ -2151,21 +2133,21 @@ isp_plogx(ispsoftc_t *isp, uint16_t handle, uint32_t portid, int flags, int gs)
}
if (gs == 0) {
- FC_SCRATCH_ACQUIRE(isp);
+ if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ return (-1);
+ }
}
- scp = FCPARAM(isp)->isp_scratch;
+ fcp = FCPARAM(isp, chan);
+ scp = fcp->isp_scratch;
isp_put_plogx(isp, plp, (isp_plogx_t *) scp);
-
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
+ MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
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;
+ 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);
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN);
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
@@ -2183,8 +2165,9 @@ isp_plogx(ispsoftc_t *isp, uint16_t handle, uint32_t portid, int flags, int gs)
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);
+ isp_prt(isp, ISP_LOGWARN,
+ "status 0x%x on port login IOCB chanel %d",
+ plp->plogx_status, chan);
rval = -1;
goto out;
}
@@ -2193,73 +2176,83 @@ isp_plogx(ispsoftc_t *isp, uint16_t handle, uint32_t portid, int flags, int gs)
parm1 = plp->plogx_ioparm[1].lo16 | (plp->plogx_ioparm[1].hi16 << 16);
rval = -1;
+ lev = ISP_LOGERR;
+ msg = NULL;
switch (sst) {
case PLOGX_IOCBERR_NOLINK:
- isp_prt(isp, ISP_LOGERR, "PLOGX failed- no link");
+ msg = "no link";
break;
case PLOGX_IOCBERR_NOIOCB:
- isp_prt(isp, ISP_LOGERR, "PLOGX failed- no IOCB buffer");
+ msg = "no IOCB buffer";
break;
case PLOGX_IOCBERR_NOXGHG:
- isp_prt(isp, ISP_LOGERR,
- "PLOGX failed- no Exchange Control Block");
+ msg = "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);
+ ISP_SNPRINTF(buf, sizeof (buf),
+ "reason 0x%x (last LOGIN state 0x%x)",
+ parm1 & 0xff, (parm1 >> 8) & 0xff);
+ msg = buf;
break;
case PLOGX_IOCBERR_NOFABRIC:
- isp_prt(isp, ISP_LOGERR, "PLOGX failed- no fabric");
+ msg = "no fabric";
break;
case PLOGX_IOCBERR_NOTREADY:
- isp_prt(isp, ISP_LOGERR, "PLOGX failed- f/w not ready");
+ msg = "firmware not ready";
break;
case PLOGX_IOCBERR_NOLOGIN:
- isp_prt(isp, ISP_LOGERR,
- "PLOGX failed- not logged in (last LOGIN state 0x%x)",
+ ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)",
parm1);
+ msg = buf;
rval = MBOX_NOT_LOGGED_IN;
break;
case PLOGX_IOCBERR_REJECT:
- isp_prt(isp, ISP_LOGERR, "PLOGX failed: LS_RJT = 0x%x", parm1);
+ ISP_SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1);
+ msg = buf;
break;
case PLOGX_IOCBERR_NOPCB:
- isp_prt(isp, ISP_LOGERR, "PLOGX failed- no PCB allocated");
+ msg = "no PCB allocated";
break;
case PLOGX_IOCBERR_EINVAL:
- isp_prt(isp, ISP_LOGERR,
- "PLOGX failed: invalid parameter at offset 0x%x", parm1);
+ ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x",
+ parm1);
+ msg = buf;
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);
+ lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
+ ISP_SNPRINTF(buf, sizeof (buf),
+ "already logged in with N-Port handle 0x%x", parm1);
+ msg = buf;
+ rval = MBOX_PORT_ID_USED | (parm1 << 16);
break;
case PLOGX_IOCBERR_HNDLUSED:
- isp_prt(isp, ISP_LOGDEBUG0,
- "N-port handle 0x%x already used for portid 0x%x",
- handle, parm1);
+ lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
+ ISP_SNPRINTF(buf, sizeof (buf),
+ "handle already used for PortID 0x%06x", parm1);
+ msg = buf;
rval = MBOX_LOOP_ID_USED;
break;
case PLOGX_IOCBERR_NOHANDLE:
- isp_prt(isp, ISP_LOGERR, "PLOGX failed- no handle allocated");
+ msg = "no handle allocated";
break;
case PLOGX_IOCBERR_NOFLOGI:
- isp_prt(isp, ISP_LOGERR, "PLOGX failed- no FLOGI_ACC");
+ msg = "no FLOGI_ACC";
break;
default:
- isp_prt(isp, ISP_LOGERR, "status %x from %x", plp->plogx_status,
- flags);
- rval = -1;
+ ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x",
+ plp->plogx_status, flags);
+ msg = buf;
break;
}
+ if (msg) {
+ isp_prt(isp, ISP_LOGERR,
+ "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s",
+ chan, portid, handle, msg);
+ }
out:
if (gs == 0) {
- FC_SCRATCH_RELEASE(isp);
+ FC_SCRATCH_RELEASE(isp, chan);
}
return (rval);
}
@@ -2269,9 +2262,8 @@ isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
{
mbreg_t mbs;
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_FABRIC_LOGIN;
- if (FCPARAM(isp)->isp_2klogin) {
+ MBSINIT(&mbs, MBOX_FABRIC_LOGIN, MBLOGNONE, 500000);
+ if (ISP_CAP_2KLOGIN(isp)) {
mbs.param[1] = handle;
mbs.ibits = (1 << 10);
} else {
@@ -2286,13 +2278,13 @@ isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
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",
+ "isp_port_login: 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",
+ "isp_port_login: handle 0x%04x in use for port id 0x%02xXXXX",
handle, mbs.param[1] & 0xff);
return (MBOX_LOOP_ID_USED);
@@ -2301,18 +2293,18 @@ isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
case MBOX_COMMAND_ERROR:
isp_prt(isp, ISP_LOGINFO,
- "isp_plogi_old: error 0x%x in PLOGI to port 0x%06x",
+ "isp_port_login: 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");
+ "isp_port_login: 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",
+ "isp_port_login: error 0x%x on port login of 0x%06x@0x%0x",
mbs.param[0], portid, handle);
return (mbs.param[0]);
}
@@ -2323,38 +2315,34 @@ isp_port_logout(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
{
mbreg_t mbs;
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_FABRIC_LOGOUT;
- if (FCPARAM(isp)->isp_2klogin) {
+ MBSINIT(&mbs, MBOX_FABRIC_LOGOUT, MBLOGNONE, 500000);
+ if (ISP_CAP_2KLOGIN(isp)) {
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]);
}
static int
-isp_getpdb(ispsoftc_t *isp, uint16_t id, isp_pdb_t *pdb, int dolock)
+isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
{
- fcparam *fcp = (fcparam *) isp->isp_param;
+ fcparam *fcp = FCPARAM(isp, chan);
mbreg_t mbs;
union {
isp_pdb_21xx_t fred;
isp_pdb_24xx_t bill;
} un;
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_GET_PORT_DB;
+ MBSINIT(&mbs, MBOX_GET_PORT_DB, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 250000);
if (IS_24XX(isp)) {
- mbs.ibits = 0x3ff;
+ mbs.ibits = (1 << 9)|(1 << 10);
mbs.param[1] = id;
- } else if (FCPARAM(isp)->isp_2klogin) {
+ mbs.param[9] = chan;
+ } else if (ISP_CAP_2KLOGIN(isp)) {
mbs.param[1] = id;
- mbs.ibits = (1 << 10);
} else {
mbs.param[1] = id << 8;
}
@@ -2362,68 +2350,111 @@ isp_getpdb(ispsoftc_t *isp, uint16_t id, isp_pdb_t *pdb, int dolock)
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.timeout = 250000;
- mbs.logval = MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR;
if (dolock) {
- FC_SCRATCH_ACQUIRE(isp);
+ if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ return (-1);
+ }
}
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (un));
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
if (dolock) {
- FC_SCRATCH_RELEASE(isp);
+ FC_SCRATCH_RELEASE(isp, chan);
}
- return (-1);
+ return (mbs.param[0]);
}
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);
+ ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
+ ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d Port 0x%06x flags 0x%x curstate %x",
+ chan, pdb->portid, un.bill.pdb_flags,
+ un.bill.pdb_curstate);
+ if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE ||
+ un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) {
+ mbs.param[0] = MBOX_NOT_LOGGED_IN;
+ if (dolock) {
+ FC_SCRATCH_RELEASE(isp, chan);
+ }
+ return (mbs.param[0]);
+ }
} 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);
+ ISP_MEMCPY(pdb->portname, un.fred.pdb_portname, 8);
+ ISP_MEMCPY(pdb->nodename, un.fred.pdb_nodename, 8);
}
if (dolock) {
- FC_SCRATCH_RELEASE(isp);
+ FC_SCRATCH_RELEASE(isp, chan);
}
return (0);
}
+static void
+isp_dump_chip_portdb(ispsoftc_t *isp, int chan, int dolock)
+{
+ isp_pdb_t pdb;
+ int lim, loopid;
+
+ if (ISP_CAP_2KLOGIN(isp)) {
+ lim = NPH_MAX_2K;
+ } else {
+ lim = NPH_MAX;
+ }
+ for (loopid = 0; loopid != lim; loopid++) {
+ if (isp_getpdb(isp, chan, loopid, &pdb, dolock)) {
+ continue;
+ }
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGINFO, "Chan %d Loopid 0x%04x "
+ "PortID 0x%06x WWPN 0x%02x%02x%02x%02x%02x%02x%02x%02x",
+ chan, loopid, pdb.portid, pdb.portname[0], pdb.portname[1],
+ pdb.portname[2], pdb.portname[3], pdb.portname[4],
+ pdb.portname[5], pdb.portname[6], pdb.portname[7]);
+ }
+}
+
static uint64_t
-isp_get_portname(ispsoftc_t *isp, int loopid, int nodename)
+isp_get_wwn(ispsoftc_t *isp, int chan, int loopid, int nodename)
{
- uint64_t wwn = (uint64_t) -1;
+ uint64_t wwn = INI_NONE;
+ fcparam *fcp = FCPARAM(isp, chan);
mbreg_t mbs;
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_GET_PORT_NAME;
- if (FCPARAM(isp)->isp_2klogin || IS_24XX(isp)) {
+ if (fcp->isp_fwstate < FW_READY ||
+ fcp->isp_loopstate < LOOP_PDB_RCVD) {
+ return (wwn);
+ }
+ MBSINIT(&mbs, MBOX_GET_PORT_NAME, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 500000);
+ if (ISP_CAP_2KLOGIN(isp)) {
mbs.param[1] = loopid;
mbs.ibits = (1 << 10);
if (nodename) {
mbs.param[10] = 1;
}
+ if (ISP_CAP_MULTI_ID(isp)) {
+ mbs.ibits |= (1 << 9);
+ mbs.param[9] = chan;
+ }
} 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 =
- (((uint64_t)(mbs.param[2] >> 8)) << 56) |
+ (((uint64_t)(mbs.param[2] >> 8)) << 56) |
(((uint64_t)(mbs.param[2] & 0xff)) << 48) |
(((uint64_t)(mbs.param[3] >> 8)) << 40) |
(((uint64_t)(mbs.param[3] & 0xff)) << 32) |
@@ -2450,27 +2481,20 @@ isp_get_portname(ispsoftc_t *isp, int loopid, int nodename)
*/
static int
-isp_fclink_test(ispsoftc_t *isp, int usdelay)
+isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
{
- static const char *toponames[] = {
- "Private Loop",
- "FL Port",
- "N-Port to N-Port",
- "F Port",
- "F Port (no FLOGI_ACC response)"
- };
mbreg_t mbs;
- int count, check_for_fabric;
+ int count, check_for_fabric, r;
uint8_t lwfs;
int loopid;
fcparam *fcp;
fcportdb_t *lp;
isp_pdb_t pdb;
- fcp = isp->isp_param;
+ fcp = FCPARAM(isp, chan);
- isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC Link Test Entry");
- ISP_MARK_PORTDB(isp, 1);
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d FC Link Test Entry", chan);
+ ISP_MARK_PORTDB(isp, chan, 1);
/*
* Wait up to N microseconds for F/W to go to a ready state.
@@ -2483,12 +2507,9 @@ isp_fclink_test(ispsoftc_t *isp, int usdelay)
NANOTIME_T hra, hrb;
GET_NANOTIME(&hra);
- isp_fw_state(isp);
+ isp_fw_state(isp, chan);
if (lwfs != 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));
+ isp_prt(isp, ISP_LOGCONFIG|ISP_LOGSANCFG, "Chan %d Firmware State <%s->%s>", chan, isp_fc_fw_statename((int)lwfs), isp_fc_fw_statename((int)fcp->isp_fwstate));
lwfs = fcp->isp_fwstate;
}
if (fcp->isp_fwstate == FW_READY) {
@@ -2502,10 +2523,7 @@ isp_fclink_test(ispsoftc_t *isp, int usdelay)
*/
enano = NANOTIME_SUB(&hrb, &hra);
- isp_prt(isp, ISP_LOGDEBUG1,
- "usec%d: 0x%lx->0x%lx enano 0x%x%08x",
- count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb),
- (uint32_t)(enano >> 32), (uint32_t)(enano & 0xffffffff));
+ isp_prt(isp, ISP_LOGDEBUG1, "usec%d: 0x%lx->0x%lx enano 0x%x%08x", count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb), (uint32_t)(enano >> 32), (uint32_t)(enano));
/*
* If the elapsed time is less than 1 millisecond,
@@ -2520,12 +2538,12 @@ isp_fclink_test(ispsoftc_t *isp, int usdelay)
count += 1000;
enano = (1000 * 1000) - enano;
while (enano > (uint64_t) 4000000000U) {
- USEC_SLEEP(isp, 4000000);
+ ISP_SLEEP(isp, 4000000);
enano -= (uint64_t) 4000000000U;
}
wrk = enano;
wrk /= 1000;
- USEC_SLEEP(isp, wrk);
+ ISP_SLEEP(isp, wrk);
} else {
while (enano > (uint64_t) 4000000000U) {
count += 4000000;
@@ -2536,27 +2554,31 @@ isp_fclink_test(ispsoftc_t *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");
+ isp_prt(isp, ISP_LOGSANCFG, "%s: chan %d not at FW_READY state", __func__, chan);
return (-1);
}
/*
* Get our Loop ID and Port ID.
*/
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_GET_LOOP_ID;
- mbs.logval = MBLOGALL;
+ MBSINIT(&mbs, MBOX_GET_LOOP_ID, MBLOGALL, 0);
+ if (ISP_CAP_MULTI_ID(isp)) {
+ mbs.param[9] = chan;
+ mbs.ibits = (1 << 9);
+ mbs.obits = (1 << 7);
+ }
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return (-1);
}
- if (FCPARAM(isp)->isp_2klogin) {
+ if (ISP_CAP_2KLOGIN(isp)) {
fcp->isp_loopid = mbs.param[1];
} else {
fcp->isp_loopid = mbs.param[1] & 0xff;
@@ -2583,21 +2605,52 @@ isp_fclink_test(ispsoftc_t *isp, int usdelay)
} else {
check_for_fabric = 0;
}
- } else if (fcp->isp_topo == TOPO_FL_PORT ||
- fcp->isp_topo == TOPO_F_PORT) {
+ } else if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_F_PORT) {
check_for_fabric = 1;
} else {
check_for_fabric = 0;
}
- if (IS_24XX(isp)) {
+ /*
+ * Check to make sure we got a valid loopid
+ * The 24XX seems to mess this up for multiple channels.
+ */
+ if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT) {
+ uint8_t alpa = fcp->isp_portid;
+
+ if (alpa == 0) {
+ /* "Cannot Happen" */
+ isp_prt(isp, ISP_LOGWARN, "Zero AL_PA for Loop Topology?");
+ } else {
+ int i;
+ for (i = 0; alpa_map[i]; i++) {
+ if (alpa_map[i] == alpa) {
+ break;
+ }
+ }
+ if (alpa_map[i] && fcp->isp_loopid != i) {
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d deriving loopid %d from AL_PA map (AL_PA 0x%x) and ignoring returned value %d (AL_PA 0x%x)", chan, i, alpa_map[i], fcp->isp_loopid, alpa);
+ fcp->isp_loopid = i;
+ }
+ }
+ }
+
+
+ if (IS_24XX(isp)) { /* XXX SHOULDN'T THIS BE FOR 2K F/W? XXX */
loopid = NPH_FL_ID;
} else {
loopid = FL_ID;
}
-
- if (check_for_fabric && isp_getpdb(isp, loopid, &pdb, 1) == 0) {
- int r;
+ if (check_for_fabric) {
+ r = isp_getpdb(isp, chan, loopid, &pdb, 1);
+ if (r && (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT)) {
+ isp_prt(isp, ISP_LOGWARN, "fabric topology but cannot get info about fabric controller (0x%x)", r);
+ fcp->isp_topo = TOPO_PTP_STUB;
+ }
+ } else {
+ r = -1;
+ }
+ if (r == 0) {
if (IS_2100(isp)) {
fcp->isp_topo = TOPO_FL_PORT;
}
@@ -2622,13 +2675,30 @@ isp_fclink_test(ispsoftc_t *isp, int usdelay)
lp->new_portid = lp->portid;
lp->new_roles = lp->roles;
if (IS_24XX(isp)) {
- r = isp_register_fc4_type_24xx(isp);
+ fcp->inorder = (mbs.param[7] & ISP24XX_INORDER) != 0;
+ if (ISP_FW_NEWER_THAN(isp, 4, 0, 27)) {
+ fcp->npiv_fabric = (mbs.param[7] & ISP24XX_NPIV_SAN) != 0;
+ if (fcp->npiv_fabric) {
+ isp_prt(isp, ISP_LOGCONFIG, "fabric supports NP-IV");
+ }
+ }
+ if (chan) {
+ fcp->isp_sns_hdl = NPH_SNS_HDLBASE + chan;
+ r = isp_plogx(isp, chan, fcp->isp_sns_hdl, SNS_PORT_ID, PLOGX_FLG_CMD_PLOGI | PLOGX_FLG_COND_PLOGI | PLOGX_FLG_SKIP_PRLI, 0);
+ if (r) {
+ isp_prt(isp, ISP_LOGWARN, "%s: Chan %d cannot log into SNS", __func__, chan);
+ return (-1);
+ }
+ } else {
+ fcp->isp_sns_hdl = NPH_SNS_ID;
+ }
+ r = isp_register_fc4_type_24xx(isp, chan);
} else {
- r = isp_register_fc4_type(isp);
+ fcp->isp_sns_hdl = SNS_ID;
+ r = isp_register_fc4_type(isp, chan);
}
if (r) {
- isp_prt(isp, ISP_LOGSANCFG,
- "isp_fclink_test: register fc4 type failed");
+ isp_prt(isp, ISP_LOGWARN|ISP_LOGSANCFG, "%s: register fc4 type failed", __func__);
return (-1);
}
} else {
@@ -2638,20 +2708,23 @@ not_on_fabric:
fcp->isp_gbspeed = 1;
if (IS_23XX(isp) || IS_24XX(isp)) {
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_GET_SET_DATA_RATE;
+ MBSINIT(&mbs, MBOX_GET_SET_DATA_RATE, MBLOGALL, 3000000);
mbs.param[1] = MBGSD_GET_RATE;
/* mbs.param[2] undefined if we're just getting rate */
- mbs.logval = MBLOGALL;
- mbs.timeout = 3000000;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
- if (mbs.param[1] == MBGSD_FOURGB) {
- isp_prt(isp, ISP_LOGINFO, "4Gb link speed/s");
+ if (mbs.param[1] == MBGSD_EIGHTGB) {
+ isp_prt(isp, ISP_LOGINFO, "Chan %d 8Gb link speed", chan);
+ fcp->isp_gbspeed = 8;
+ } else if (mbs.param[1] == MBGSD_FOURGB) {
+ isp_prt(isp, ISP_LOGINFO, "Chan %d 4Gb link speed", chan);
fcp->isp_gbspeed = 4;
- } if (mbs.param[1] == MBGSD_TWOGB) {
- isp_prt(isp, ISP_LOGINFO, "2Gb link speed/s");
+ } else if (mbs.param[1] == MBGSD_TWOGB) {
+ isp_prt(isp, ISP_LOGINFO, "Chan %d 2Gb link speed", chan);
fcp->isp_gbspeed = 2;
+ } else if (mbs.param[1] == MBGSD_ONEGB) {
+ isp_prt(isp, ISP_LOGINFO, "Chan %d 1Gb link speed", chan);
+ fcp->isp_gbspeed = 1;
}
}
}
@@ -2659,33 +2732,11 @@ not_on_fabric:
/*
* Announce ourselves, too.
*/
- 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,
- (uint32_t) (ISP_NODEWWN(isp) >> 32),
- (uint32_t) ISP_NODEWWN(isp),
- (uint32_t) (ISP_PORTWWN(isp) >> 32),
- (uint32_t) ISP_PORTWWN(isp));
- isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC Link Test Complete");
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGCONFIG, topology, chan, (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) fcp->isp_wwpn, fcp->isp_portid, fcp->isp_loopid, isp_fc_toponame(fcp));
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d FC Link Test Complete", chan);
return (0);
}
-static const char *
-ispfc_fw_statename(int state)
-{
- switch(state) {
- case FW_CONFIG_WAIT: return "Config Wait";
- case FW_WAIT_AL_PA: return "Waiting for AL_PA";
- case FW_WAIT_LOGIN: return "Wait Login";
- case FW_READY: return "Ready";
- case FW_LOSS_OF_SYNC: return "Loss Of Sync";
- case FW_ERROR: return "Error";
- case FW_REINIT: return "Re-Init";
- case FW_NON_PART: return "Nonparticipating";
- default: return "?????";
- }
-}
-
/*
* Complete the synchronization of our Port Database.
*
@@ -2707,9 +2758,9 @@ ispfc_fw_statename(int state)
* entities.
*/
static int
-isp_pdb_sync(ispsoftc_t *isp)
+isp_pdb_sync(ispsoftc_t *isp, int chan)
{
- fcparam *fcp = isp->isp_param;
+ fcparam *fcp = FCPARAM(isp, chan);
fcportdb_t *lp;
uint16_t dbidx;
@@ -2732,7 +2783,7 @@ isp_pdb_sync(ispsoftc_t *isp)
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) {
+ if (isp_scan_loop(isp, chan) != 0) {
isp_prt(isp, ISP_LOGWARN,
"isp_pdb_sync: isp_scan_loop failed");
return (-1);
@@ -2742,7 +2793,7 @@ isp_pdb_sync(ispsoftc_t *isp)
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) {
+ if (isp_scan_fabric(isp, chan) != 0) {
isp_prt(isp, ISP_LOGWARN,
"isp_pdb_sync: isp_scan_fabric failed");
return (-1);
@@ -2750,14 +2801,15 @@ isp_pdb_sync(ispsoftc_t *isp)
}
}
- isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Synchronizing PDBs");
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d Synchronizing PDBs", chan);
fcp->isp_loopstate = LOOP_SYNCING_PDB;
for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
lp = &fcp->portdb[dbidx];
- if (lp->state == FC_PORTDB_STATE_NIL) {
+ if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode) {
continue;
}
@@ -2774,12 +2826,13 @@ isp_pdb_sync(ispsoftc_t *isp)
case FC_PORTDB_STATE_PROBATIONAL:
case FC_PORTDB_STATE_DEAD:
/*
- * It's up to the outer layers to clear isp_ini_map.
+ * It's up to the outer layers to clear isp_dev_map.
*/
lp->state = FC_PORTDB_STATE_NIL;
- isp_async(isp, ISPASYNC_DEV_GONE, lp);
+ isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
if (lp->autologin == 0) {
- (void) isp_plogx(isp, lp->handle, lp->portid,
+ (void) isp_plogx(isp, chan, lp->handle,
+ lp->portid,
PLOGX_FLG_CMD_LOGO |
PLOGX_FLG_IMPLICIT |
PLOGX_FLG_FREE_NPHDL, 0);
@@ -2796,12 +2849,12 @@ isp_pdb_sync(ispsoftc_t *isp)
case FC_PORTDB_STATE_NEW:
/*
* It's up to the outer layers to assign a virtual
- * target id in isp_ini_map (if any).
+ * target id in isp_dev_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);
+ isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
lp->new_roles = 0;
lp->new_portid = 0;
lp->reserved = 0;
@@ -2812,7 +2865,7 @@ isp_pdb_sync(ispsoftc_t *isp)
* XXXX FIX THIS
*/
lp->state = FC_PORTDB_STATE_VALID;
- isp_async(isp, ISPASYNC_DEV_CHANGED, lp);
+ isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
lp->new_roles = 0;
lp->new_portid = 0;
lp->reserved = 0;
@@ -2821,12 +2874,12 @@ isp_pdb_sync(ispsoftc_t *isp)
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;
+ if (lp->dev_map_idx) {
+ int t = lp->dev_map_idx - 1;
+ fcp->isp_dev_map[t] = dbidx + 1;
}
lp->state = FC_PORTDB_STATE_VALID;
- isp_async(isp, ISPASYNC_DEV_STAYED, lp);
+ isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
if (dbidx != FL_ID) {
lp->new_roles = 0;
lp->new_portid = 0;
@@ -2840,7 +2893,7 @@ isp_pdb_sync(ispsoftc_t *isp)
isp_prt(isp, ISP_LOGWARN,
"isp_scan_loop: state %d for idx %d",
lp->state, dbidx);
- isp_dump_portdb(isp);
+ isp_dump_portdb(isp, chan);
}
}
@@ -2858,10 +2911,10 @@ isp_pdb_sync(ispsoftc_t *isp)
* Scan local loop for devices.
*/
static int
-isp_scan_loop(ispsoftc_t *isp)
+isp_scan_loop(ispsoftc_t *isp, int chan)
{
fcportdb_t *lp, tmp;
- fcparam *fcp = isp->isp_param;
+ fcparam *fcp = FCPARAM(isp, chan);
int i;
isp_pdb_t pdb;
uint16_t handle, lim = 0;
@@ -2879,53 +2932,68 @@ isp_scan_loop(ispsoftc_t *isp)
* 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.
+ * The firmware has (typically) peformed a PLOGI for us. We skip this
+ * step if we're a ISP_24XX in NP-IV mode.
*
* 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:
+ lim = LOCAL_LOOP_LIM;
+ break;
case TOPO_FL_PORT:
+ if (IS_24XX(isp) && isp->isp_nchan > 1) {
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d Skipping Local Loop Scan", chan);
+ fcp->isp_loopstate = LOOP_LSCAN_DONE;
+ return (0);
+ }
lim = LOCAL_LOOP_LIM;
break;
case TOPO_N_PORT:
lim = 2;
break;
default:
- isp_prt(isp, ISP_LOGDEBUG0, "no loop topology to scan");
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d no loop topology to scan", chan);
fcp->isp_loopstate = LOOP_LSCAN_DONE;
return (0);
}
fcp->isp_loopstate = LOOP_SCANNING_LOOP;
- isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC scan loop 0..%d", lim-1);
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d FC scan loop 0..%d", chan, lim-1);
/*
* Run through the list and get the port database info for each one.
*/
for (handle = 0; handle < lim; handle++) {
+ int r;
/*
- * But don't even try for ourselves...
- */
- if (handle == fcp->isp_loopid) {
+ * Don't scan "special" ids.
+ */
+ if (handle >= FL_ID && handle <= SNS_ID) {
continue;
}
-
+ if (ISP_CAP_2KLOGIN(isp)) {
+ if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
+ 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)) {
- uint64_t node_wwn = isp_get_portname(isp, handle, 1);
+ uint64_t node_wwn = isp_get_wwn(isp, chan, handle, 1);
if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d FC scan loop DONE (bad)", chan);
return (-1);
}
- if (node_wwn == 0) {
+ if (node_wwn == INI_NONE) {
continue;
}
}
@@ -2933,16 +3001,24 @@ isp_scan_loop(ispsoftc_t *isp)
/*
* Get the port database entity for this index.
*/
- if (isp_getpdb(isp, handle, &pdb, 1) != 0) {
+ r = isp_getpdb(isp, chan, handle, &pdb, 1);
+ if (r != 0) {
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "Chan %d FC scan loop handle %d returned %x",
+ chan, handle, r);
if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
- ISP_MARK_PORTDB(isp, 1);
+ ISP_MARK_PORTDB(isp, chan, 1);
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d FC scan loop DONE (bad)", chan);
return (-1);
}
continue;
}
if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
- ISP_MARK_PORTDB(isp, 1);
+ ISP_MARK_PORTDB(isp, chan, 1);
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d FC scan loop DONE (bad)", chan);
return (-1);
}
@@ -2954,8 +3030,10 @@ isp_scan_loop(ispsoftc_t *isp)
*/
if (IS_2100(isp) && pdb.handle != handle) {
isp_prt(isp, ISP_LOGWARN,
- "giving up on synchronizing the port database");
- ISP_MARK_PORTDB(isp, 1);
+ "Chan %d cannot synchronize port database", chan);
+ ISP_MARK_PORTDB(isp, chan, 1);
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d FC scan loop DONE (bad)", chan);
return (-1);
}
@@ -2978,12 +3056,23 @@ isp_scan_loop(ispsoftc_t *isp)
a = (tmp.node_wwn == 0);
b = (tmp.port_wwn == 0);
c = (tmp.portid == 0);
+ if (a == 0 && b == 0) {
+ tmp.node_wwn =
+ isp_get_wwn(isp, chan, handle, 1);
+ tmp.port_wwn =
+ isp_get_wwn(isp, chan, handle, 0);
+ if (tmp.node_wwn && tmp.port_wwn) {
+ isp_prt(isp, ISP_LOGINFO, "DODGED!");
+ goto cont;
+ }
+ }
isp_prt(isp, ISP_LOGWARN,
- "bad pdb (%1d%1d%1d) @ handle 0x%x", a, b, c,
- handle);
- isp_dump_portdb(isp);
+ "Chan %d bad pdb (%1d%1d%1d) @ handle 0x%x", chan,
+ a, b, c, handle);
+ isp_dump_portdb(isp, chan);
continue;
}
+ cont:
/*
* Now search the entire port database
@@ -2991,7 +3080,9 @@ isp_scan_loop(ispsoftc_t *isp)
*/
for (i = 0; i < MAX_FC_TARG; i++) {
lp = &fcp->portdb[i];
- if (lp->state == FC_PORTDB_STATE_NIL) {
+
+ if (lp->state == FC_PORTDB_STATE_NIL ||
+ lp->target_mode) {
continue;
}
if (lp->node_wwn != tmp.node_wwn) {
@@ -3008,10 +3099,12 @@ isp_scan_loop(ispsoftc_t *isp)
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);
+ "Chan %d [%d] not probational/zombie (0x%x)",
+ chan, i, lp->state);
+ isp_dump_portdb(isp, chan);
+ ISP_MARK_PORTDB(isp, chan, 1);
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d FC scan loop DONE (bad)", chan);
return (-1);
}
@@ -3031,12 +3124,12 @@ isp_scan_loop(ispsoftc_t *isp)
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);
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d Loop Port 0x%06x@0x%04x Pending "
+ "Valid", chan, tmp.portid, tmp.handle);
break;
}
-
+
/*
* We can wipe out the old handle value
* here because it's no longer valid.
@@ -3047,9 +3140,9 @@ isp_scan_loop(ispsoftc_t *isp)
* 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);
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d Loop Port 0x%06x@0x%04x changed",
+ chan, tmp.portid, tmp.handle);
lp->state = FC_PORTDB_STATE_CHANGED;
lp->new_portid = tmp.portid;
lp->new_roles = tmp.roles;
@@ -3068,17 +3161,21 @@ isp_scan_loop(ispsoftc_t *isp)
* for it and save info for later disposition.
*/
for (i = 0; i < MAX_FC_TARG; i++) {
+ if (fcp->portdb[i].target_mode) {
+ continue;
+ }
if (fcp->portdb[i].state == FC_PORTDB_STATE_NIL) {
break;
}
}
if (i == MAX_FC_TARG) {
- isp_prt(isp, ISP_LOGERR, "out of portdb entries");
+ isp_prt(isp, ISP_LOGERR,
+ "Chan %d out of portdb entries", chan);
continue;
}
lp = &fcp->portdb[i];
- MEMZERO(lp, sizeof (fcportdb_t));
+ ISP_MEMZERO(lp, sizeof (fcportdb_t));
lp->autologin = 1;
lp->state = FC_PORTDB_STATE_NEW;
lp->new_portid = tmp.portid;
@@ -3086,11 +3183,13 @@ isp_scan_loop(ispsoftc_t *isp)
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);
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d Loop Port 0x%06x@0x%04x is New Entry",
+ chan, tmp.portid, tmp.handle);
}
fcp->isp_loopstate = LOOP_LSCAN_DONE;
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d FC scan loop DONE", chan);
return (0);
}
@@ -3111,31 +3210,32 @@ isp_scan_loop(ispsoftc_t *isp)
*/
/*
- * Take less than half of our scratch area to store Port IDs
+ * Take less than half of our scratch area to store Port IDs
*/
-#define GIDLEN ((ISP2100_SCRLEN >> 1) - 16 - SNS_GID_FT_REQ_SIZE)
+#define GIDLEN ((ISP_FC_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))
+#define OGPOFF (ISP_FC_SCRLEN >> 1)
+#define ZTXOFF (ISP_FC_SCRLEN - (1 * QENTRY_LEN))
+#define CTXOFF (ISP_FC_SCRLEN - (2 * QENTRY_LEN))
+#define XTXOFF (ISP_FC_SCRLEN - (3 * QENTRY_LEN))
static int
-isp_gid_ft_sns(ispsoftc_t *isp)
+isp_gid_ft_sns(ispsoftc_t *isp, int chan)
{
union {
sns_gid_ft_req_t _x;
uint8_t _y[SNS_GID_FT_REQ_SIZE];
} un;
- fcparam *fcp = FCPARAM(isp);
+ fcparam *fcp = FCPARAM(isp, chan);
sns_gid_ft_req_t *rq = &un._x;
mbreg_t mbs;
- isp_prt(isp, ISP_LOGDEBUG0, "scanning fabric (GID_FT) via SNS");
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "Chan %d scanning fabric (GID_FT) via SNS", chan);
- MEMZERO(rq, SNS_GID_FT_REQ_SIZE);
+ ISP_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);
@@ -3149,15 +3249,13 @@ isp_gid_ft_sns(ispsoftc_t *isp)
isp_put_gid_ft_request(isp, rq, fcp->isp_scratch);
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE);
- MEMZERO(&mbs, sizeof (mbs));
+ MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 10000000);
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) {
@@ -3170,10 +3268,10 @@ isp_gid_ft_sns(ispsoftc_t *isp)
}
static int
-isp_gid_ft_ct_passthru(ispsoftc_t *isp)
+isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
{
mbreg_t mbs;
- fcparam *fcp = FCPARAM(isp);
+ fcparam *fcp = FCPARAM(isp, chan);
union {
isp_ct_pt_t plocal;
ct_hdr_t clocal;
@@ -3184,7 +3282,8 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp)
uint32_t *rp;
uint8_t *scp = fcp->isp_scratch;
- isp_prt(isp, ISP_LOGDEBUG0, "scanning fabric (GID_FT) via CT");
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "Chan %d scanning fabric (GID_FT) via CT", chan);
if (!IS_24XX(isp)) {
return (1);
@@ -3194,12 +3293,13 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp)
* Build a Passthrough IOCB in memory.
*/
pt = &un.plocal;
- MEMZERO(un.q, QENTRY_LEN);
+ ISP_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_nphdl = fcp->isp_sns_hdl;
pt->ctp_cmd_cnt = 1;
+ pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
pt->ctp_time = 30;
pt->ctp_rsp_cnt = 1;
pt->ctp_rsp_bcnt = GIDLEN;
@@ -3221,7 +3321,7 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp)
* Note that the CT header has to end up as Big Endian format in memory.
*/
ct = &un.clocal;
- MEMZERO(ct, sizeof (*ct));
+ ISP_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;
@@ -3235,16 +3335,13 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp)
isp_print_bytes(isp, "CT HDR + payload after put",
sizeof (*ct) + sizeof (uint32_t), &scp[XTXOFF]);
}
- MEMZERO(&scp[ZTXOFF], QENTRY_LEN);
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
+ ISP_MEMZERO(&scp[ZTXOFF], QENTRY_LEN);
+ MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
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) {
@@ -3258,8 +3355,9 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp)
}
if (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) {
- isp_prt(isp, ISP_LOGWARN, "CT Passthrough returned 0x%x",
- pt->ctp_status);
+ isp_prt(isp, ISP_LOGWARN,
+ "Chan %d ISP GID FT CT Passthrough returned 0x%x",
+ chan, pt->ctp_status);
return (-1);
}
MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN + 16);
@@ -3270,15 +3368,17 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp)
}
static int
-isp_scan_fabric(ispsoftc_t *isp)
+isp_scan_fabric(ispsoftc_t *isp, int chan)
{
- fcparam *fcp = FCPARAM(isp);
+ fcparam *fcp = FCPARAM(isp, chan);
uint32_t portid;
- uint16_t handle, oldhandle;
+ uint16_t handle, oldhandle, loopid;
+ isp_pdb_t pdb;
int portidx, portlim, r;
sns_gid_ft_rsp_t *rs0, *rs1;
- isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC Scan Fabric");
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d FC Scan Fabric", chan);
if (fcp->isp_fwstate != FW_READY ||
fcp->isp_loopstate < LOOP_LSCAN_DONE) {
return (-1);
@@ -3289,37 +3389,72 @@ isp_scan_fabric(ispsoftc_t *isp)
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)");
+ "Chan %d FC Scan Fabric Done (no fabric)", chan);
return (0);
}
- FC_SCRATCH_ACQUIRE(isp);
fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
+ if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ ISP_MARK_PORTDB(isp, chan, 1);
+ return (-1);
+ }
+ if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
+ FC_SCRATCH_RELEASE(isp, chan);
+ ISP_MARK_PORTDB(isp, chan, 1);
+ return (-1);
+ }
+
+ /*
+ * Make sure we still are logged into the fabric controller.
+ */
+ if (IS_24XX(isp)) { /* XXX SHOULDN'T THIS BE TRUE FOR 2K F/W? XXX */
+ loopid = NPH_FL_ID;
+ } else {
+ loopid = FL_ID;
+ }
+ r = isp_getpdb(isp, chan, loopid, &pdb, 0);
+ if (r == MBOX_NOT_LOGGED_IN) {
+ isp_dump_chip_portdb(isp, chan, 0);
+ }
+ if (r) {
+ fcp->isp_loopstate = LOOP_PDB_RCVD;
+ FC_SCRATCH_RELEASE(isp, chan);
+ ISP_MARK_PORTDB(isp, chan, 1);
+ return (-1);
+ }
if (IS_24XX(isp)) {
- r = isp_gid_ft_ct_passthru(isp);
+ r = isp_gid_ft_ct_passthru(isp, chan);
} else {
- r = isp_gid_ft_sns(isp);
+ r = isp_gid_ft_sns(isp, chan);
+ }
+
+ if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
+ FC_SCRATCH_RELEASE(isp, chan);
+ ISP_MARK_PORTDB(isp, chan, 1);
+ return (-1);
}
if (r > 0) {
fcp->isp_loopstate = LOOP_FSCAN_DONE;
- FC_SCRATCH_RELEASE(isp);
+ FC_SCRATCH_RELEASE(isp, chan);
return (0);
} else if (r < 0) {
fcp->isp_loopstate = LOOP_PDB_RCVD; /* try again */
- FC_SCRATCH_RELEASE(isp);
+ FC_SCRATCH_RELEASE(isp, chan);
return (0);
}
- if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
- FC_SCRATCH_RELEASE(isp);
- return (-1);
- }
MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN);
rs0 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+IGPOFF);
rs1 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+OGPOFF);
isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
+ if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
+ FC_SCRATCH_RELEASE(isp, chan);
+ ISP_MARK_PORTDB(isp, chan, 1);
+ return (-1);
+ }
if (rs1->snscb_cthdr.ct_cmd_resp != LS_ACC) {
int level;
if (rs1->snscb_cthdr.ct_reason == 9 &&
@@ -3328,10 +3463,11 @@ isp_scan_fabric(ispsoftc_t *isp)
} else {
level = ISP_LOGWARN;
}
- isp_prt(isp, level, "Fabric Nameserver rejected GID_FT "
- "(Reason=0x%x Expl=0x%x)", rs1->snscb_cthdr.ct_reason,
+ isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_FT"
+ " (Reason=0x%x Expl=0x%x)", chan,
+ rs1->snscb_cthdr.ct_reason,
rs1->snscb_cthdr.ct_explanation);
- FC_SCRATCH_RELEASE(isp);
+ FC_SCRATCH_RELEASE(isp, chan);
fcp->isp_loopstate = LOOP_FSCAN_DONE;
return (0);
}
@@ -3345,12 +3481,10 @@ isp_scan_fabric(ispsoftc_t *isp)
/*
* Prime the handle we will start using.
*/
- oldhandle = NIL_HANDLE;
+ oldhandle = FCPARAM(isp, 0)->isp_lasthdl;
/*
- * 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.
+ * Go through the list and remove duplicate port ids.
*/
portlim = 0;
@@ -3366,11 +3500,11 @@ isp_scan_fabric(ispsoftc_t *isp)
*/
if ((rs1->snscb_ports[portidx].control & 0x80) == 0) {
isp_prt(isp, ISP_LOGWARN,
- "fabric too big for scratch area: increase ISP2100_SCRLEN");
+ "fabric too big for scratch area: increase ISP_FC_SCRLEN");
}
portlim = portidx + 1;
isp_prt(isp, ISP_LOGSANCFG,
- "got %d ports back from name server", portlim);
+ "Chan %d got %d ports back from name server", chan, portlim);
for (portidx = 0; portidx < portlim; portidx++) {
int npidx;
@@ -3395,18 +3529,18 @@ isp_scan_fabric(ispsoftc_t *isp)
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);
+ "Chan %d removing duplicate PortID 0x%06x"
+ " entry from list", chan, portid);
}
}
/*
- * Okay, we now have a list of Port IDs for all FC4 SCSI devices
+ * 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.
+ * maybe still this one. We get some information to find out.
*
* Otherwise, it's a new fabric device, and we log into it
* (unconditionally). After searching the entire database
@@ -3417,7 +3551,6 @@ isp_scan_fabric(ispsoftc_t *isp)
for (portidx = 0; portidx < portlim; portidx++) {
fcportdb_t *lp;
- isp_pdb_t pdb;
uint64_t wwnn, wwpn;
int dbidx, nr;
@@ -3428,20 +3561,35 @@ isp_scan_fabric(ispsoftc_t *isp)
if (portid == 0) {
isp_prt(isp, ISP_LOGSANCFG,
- "skipping null PortID at idx %d", portidx);
+ "Chan %d skipping null PortID at idx %d",
+ chan, portidx);
continue;
}
/*
- * Skip ourselves...
+ * Skip ourselves here and on other channels. If we're
+ * multi-id, we can't check the portids in other FCPARAM
+ * arenas because the resolutions here aren't synchronized.
+ * The best way to do this is to exclude looking at portids
+ * that have the same domain and area code as our own
+ * portid.
*/
- if (portid == fcp->isp_portid) {
+ if (ISP_CAP_MULTI_ID(isp)) {
+ if ((portid >> 8) == (fcp->isp_portid >> 8)) {
+ isp_prt(isp, ISP_LOGSANCFG,
+ "Chan %d skip PortID 0x%06x",
+ chan, portid);
+ continue;
+ }
+ } else if (portid == fcp->isp_portid) {
isp_prt(isp, ISP_LOGSANCFG,
- "skip ourselves @ PortID 0x%06x", portid);
+ "Chan %d skip ourselves on @ PortID 0x%06x",
+ chan, portid);
continue;
}
+
isp_prt(isp, ISP_LOGSANCFG,
- "Checking Fabric Port 0x%06x", portid);
+ "Chan %d Checking Fabric Port 0x%06x", chan, portid);
/*
* We now search our Port Database for any
@@ -3452,7 +3600,8 @@ isp_scan_fabric(ispsoftc_t *isp)
for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
lp = &fcp->portdb[dbidx];
- if (lp->state != FC_PORTDB_STATE_PROBATIONAL) {
+ if (lp->state != FC_PORTDB_STATE_PROBATIONAL ||
+ lp->target_mode) {
continue;
}
if (lp->portid == portid) {
@@ -3485,18 +3634,18 @@ isp_scan_fabric(ispsoftc_t *isp)
*
*/
- r = isp_getpdb(isp, lp->handle, &pdb, 0);
+ r = isp_getpdb(isp, chan, lp->handle, &pdb, 0);
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
- FC_SCRATCH_RELEASE(isp);
- ISP_MARK_PORTDB(isp, 1);
+ FC_SCRATCH_RELEASE(isp, chan);
+ ISP_MARK_PORTDB(isp, chan, 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);
+ "Chan %d Fabric Port 0x%06x is dead",
+ chan, portid);
continue;
}
@@ -3514,7 +3663,7 @@ isp_scan_fabric(ispsoftc_t *isp)
wwpn != lp->port_wwn ||
wwnn != lp->node_wwn) {
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
- fconf, dbidx, pdb.handle, pdb.portid,
+ fconf, chan, dbidx, pdb.handle, pdb.portid,
(uint32_t) (wwnn >> 32), (uint32_t) wwnn,
(uint32_t) (wwpn >> 32), (uint32_t) wwpn,
lp->handle, portid,
@@ -3525,23 +3674,30 @@ isp_scan_fabric(ispsoftc_t *isp)
/*
* 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,
+ if (isp_login_device(isp, chan, 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);
+ FC_SCRATCH_RELEASE(isp, chan);
+ ISP_MARK_PORTDB(isp, chan, 1);
return (-1);
}
continue;
}
+ if (fcp->isp_loopstate !=
+ LOOP_SCANNING_FABRIC) {
+ FC_SCRATCH_RELEASE(isp, chan);
+ ISP_MARK_PORTDB(isp, chan, 1);
+ return (-1);
+ }
+ FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
if (wwpn != lp->port_wwn ||
@@ -3576,12 +3732,13 @@ isp_scan_fabric(ispsoftc_t *isp)
if (pdb.portid != lp->portid || nr != lp->roles ||
handle_changed) {
isp_prt(isp, ISP_LOGSANCFG,
- "Fabric Port 0x%06x changed", portid);
+ "Chan %d Fabric Port 0x%06x changed",
+ chan, portid);
lp->state = FC_PORTDB_STATE_CHANGED;
} else {
isp_prt(isp, ISP_LOGSANCFG,
- "Fabric Port 0x%06x Now Pending Valid",
- portid);
+ "Chan %d Fabric Port 0x%06x "
+ "Now Pending Valid", chan, portid);
lp->state = FC_PORTDB_STATE_PENDING_VALID;
}
continue;
@@ -3593,13 +3750,19 @@ isp_scan_fabric(ispsoftc_t *isp)
* with the same port id. While we're at it, mark where the
* last free entry was.
*/
-
+
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;
}
+ /*
+ * Skip any target mode entries.
+ */
+ if (lp->target_mode) {
+ continue;
+ }
if (lp->state == FC_PORTDB_STATE_NIL) {
if (dbidx == MAX_FC_TARG) {
dbidx = lp - fcp->portdb;
@@ -3615,9 +3778,9 @@ isp_scan_fabric(ispsoftc_t *isp)
}
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);
+ isp_prt(isp, ISP_LOGWARN, "Chan %d PortID 0x%06x "
+ "already at %d handle %d state %d",
+ chan, portid, dbidx, lp->handle, lp->state);
continue;
}
@@ -3643,14 +3806,20 @@ isp_scan_fabric(ispsoftc_t *isp)
* isp_login_device will check for handle and
* portid consistency after login.
*/
- if (isp_login_device(isp, portid, &pdb, &oldhandle)) {
+ if (isp_login_device(isp, chan, portid, &pdb, &oldhandle)) {
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
- FC_SCRATCH_RELEASE(isp);
- ISP_MARK_PORTDB(isp, 1);
+ FC_SCRATCH_RELEASE(isp, chan);
+ ISP_MARK_PORTDB(isp, chan, 1);
return (-1);
}
continue;
}
+ if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
+ FC_SCRATCH_RELEASE(isp, chan);
+ ISP_MARK_PORTDB(isp, chan, 1);
+ return (-1);
+ }
+ FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
handle = pdb.handle;
MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
@@ -3666,7 +3835,7 @@ isp_scan_fabric(ispsoftc_t *isp)
if (dbidx >= FL_ID && dbidx <= SNS_ID) {
continue;
}
- if (fcp->portdb[dbidx].state == FC_PORTDB_STATE_NIL) {
+ if (fcp->portdb[dbidx].target_mode) {
continue;
}
if (fcp->portdb[dbidx].node_wwn == wwnn &&
@@ -3676,7 +3845,7 @@ isp_scan_fabric(ispsoftc_t *isp)
}
if (dbidx == MAX_FC_TARG) {
- MEMZERO(lp, sizeof (fcportdb_t));
+ ISP_MEMZERO(lp, sizeof (fcportdb_t));
lp->handle = handle;
lp->node_wwn = wwnn;
lp->port_wwn = wwpn;
@@ -3684,14 +3853,15 @@ isp_scan_fabric(ispsoftc_t *isp)
lp->new_roles = nr;
lp->state = FC_PORTDB_STATE_NEW;
isp_prt(isp, ISP_LOGSANCFG,
- "Fabric Port 0x%06x is New Entry", portid);
+ "Chan %d Fabric Port 0x%06x is a New Entry",
+ chan, 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,
+ "Chan %d PortID 0x%x 0x%08x%08x/0x%08x%08x %ld "
+ "already at idx %d, state 0x%x", chan, portid,
(uint32_t) (wwnn >> 32), (uint32_t) wwnn,
(uint32_t) (wwpn >> 32), (uint32_t) wwpn,
(long) (lp - fcp->portdb), dbidx,
@@ -3713,23 +3883,25 @@ isp_scan_fabric(ispsoftc_t *isp)
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);
+ "Chan %d Zombie Fabric Port 0x%06x Now Changed",
+ chan, portid);
lp->state = FC_PORTDB_STATE_CHANGED;
} else {
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
- "Zombie Fabric Port 0x%06x Now Pending Valid",
- portid);
+ "Chan %d Zombie Fabric Port 0x%06x "
+ "Now Pending Valid", chan, portid);
lp->state = FC_PORTDB_STATE_PENDING_VALID;
}
}
- FC_SCRATCH_RELEASE(isp);
+ FC_SCRATCH_RELEASE(isp, chan);
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
- ISP_MARK_PORTDB(isp, 1);
+ ISP_MARK_PORTDB(isp, chan, 1);
return (-1);
}
fcp->isp_loopstate = LOOP_FSCAN_DONE;
- isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC Scan Fabric Done");
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d FC Scan Fabric Done", chan);
return (0);
}
@@ -3737,39 +3909,41 @@ isp_scan_fabric(ispsoftc_t *isp)
* Find an unused handle and try and use to login to a port.
*/
static int
-isp_login_device(ispsoftc_t *isp, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
+isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p,
+ uint16_t *ohp)
{
int lim, i, r;
uint16_t handle;
- if (FCPARAM(isp)->isp_2klogin) {
+ if (ISP_CAP_2KLOGIN(isp)) {
lim = NPH_MAX_2K;
} else {
lim = NPH_MAX;
}
- handle = isp_nxt_handle(isp, *ohp);
+ handle = isp_nxt_handle(isp, chan, *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);
+ r = isp_getpdb(isp, chan, handle, p, 0);
if (r == 0 && p->portid != portid) {
- (void) isp_plogx(isp, handle, portid,
+ (void) isp_plogx(isp, chan, handle, portid,
PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT, 1);
} else if (r == 0) {
break;
}
- if (FCPARAM(isp)->isp_loopstate != LOOP_SCANNING_FABRIC) {
+ if (FCPARAM(isp, chan)->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) {
+ r = isp_plogx(isp, chan, handle, portid,
+ PLOGX_FLG_CMD_PLOGI, 1);
+ if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
return (-1);
}
if (r == 0) {
@@ -3781,14 +3955,17 @@ isp_login_device(ispsoftc_t *isp, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
} else if (r != MBOX_LOOP_ID_USED) {
i = lim;
break;
+ } else if (r == MBOX_TIMEOUT) {
+ return (-1);
} else {
*ohp = handle;
- handle = isp_nxt_handle(isp, *ohp);
+ handle = isp_nxt_handle(isp, chan, *ohp);
}
}
if (i == lim) {
- isp_prt(isp, ISP_LOGWARN, "PLOGI 0x%06x failed", portid);
+ isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed",
+ chan, portid);
return (-1);
}
@@ -3797,34 +3974,35 @@ isp_login_device(ispsoftc_t *isp, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
* so we can crosscheck that it is still what we think it
* is and that we also have the role it plays
*/
- r = isp_getpdb(isp, handle, p, 0);
- if (FCPARAM(isp)->isp_loopstate != LOOP_SCANNING_FABRIC) {
+ r = isp_getpdb(isp, chan, handle, p, 0);
+ if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
return (-1);
}
if (r != 0) {
- isp_prt(isp, ISP_LOGERR, "new device 0x%06x@0x%x disappeared",
- portid, handle);
+ isp_prt(isp, ISP_LOGERR,
+ "Chan %d new device 0x%06x@0x%x disappeared",
+ chan, portid, handle);
return (-1);
}
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);
+ "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
+ chan, portid, handle, p->portid, p->handle);
return (-1);
}
return (0);
}
static int
-isp_register_fc4_type(ispsoftc_t *isp)
+isp_register_fc4_type(ispsoftc_t *isp, int chan)
{
- fcparam *fcp = isp->isp_param;
+ fcparam *fcp = FCPARAM(isp, chan);
uint8_t local[SNS_RFT_ID_REQ_SIZE];
sns_screq_t *reqp = (sns_screq_t *) local;
mbreg_t mbs;
- MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
+ ISP_MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
@@ -3835,20 +4013,20 @@ isp_register_fc4_type(ispsoftc_t *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);
- FC_SCRATCH_ACQUIRE(isp);
+ if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ return (-1);
+ }
isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_SEND_SNS;
+ MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 1000000);
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);
mbs.param[6] = DMA_WD3(fcp->isp_scdma);
mbs.param[7] = DMA_WD2(fcp->isp_scdma);
- mbs.logval = MBLOGALL;
- mbs.timeout = 10000000;
MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE);
isp_mboxcmd(isp, &mbs);
- FC_SCRATCH_RELEASE(isp);
+ FC_SCRATCH_RELEASE(isp, chan);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
return (0);
} else {
@@ -3857,10 +4035,10 @@ isp_register_fc4_type(ispsoftc_t *isp)
}
static int
-isp_register_fc4_type_24xx(ispsoftc_t *isp)
+isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
{
mbreg_t mbs;
- fcparam *fcp = FCPARAM(isp);
+ fcparam *fcp = FCPARAM(isp, chan);
union {
isp_ct_pt_t plocal;
rft_id_t clocal;
@@ -3871,17 +4049,22 @@ isp_register_fc4_type_24xx(ispsoftc_t *isp)
rft_id_t *rp;
uint8_t *scp = fcp->isp_scratch;
- FC_SCRATCH_ACQUIRE(isp);
+ if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ return (-1);
+ }
+
/*
* Build a Passthrough IOCB in memory.
*/
- MEMZERO(un.q, QENTRY_LEN);
+ ISP_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_nphdl = fcp->isp_sns_hdl;
pt->ctp_cmd_cnt = 1;
+ pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
pt->ctp_time = 1;
pt->ctp_rsp_cnt = 1;
pt->ctp_rsp_bcnt = sizeof (ct_hdr_t);
@@ -3893,13 +4076,16 @@ isp_register_fc4_type_24xx(ispsoftc_t *isp)
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]);
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp, "IOCB CT Request", QENTRY_LEN, pt);
+ }
/*
* 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));
+ ISP_MEMZERO(&un.clocal, sizeof (un.clocal));
ct = &un.clocal.rftid_hdr;
ct->ct_revision = CT_REVISION;
ct->ct_fcs_type = CT_FC_TYPE_FC;
@@ -3912,22 +4098,22 @@ isp_register_fc4_type_24xx(ispsoftc_t *isp)
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]);
+ if (isp->isp_dblev & ISP_LOGDEBUG1) {
+ isp_print_bytes(isp, "CT Header", QENTRY_LEN, &scp[XTXOFF]);
+ }
- MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
+ ISP_MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
+ MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 1000000);
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);
+ FC_SCRATCH_RELEASE(isp, chan);
return (-1);
}
MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN);
@@ -3937,36 +4123,38 @@ isp_register_fc4_type_24xx(ispsoftc_t *isp)
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);
+ FC_SCRATCH_RELEASE(isp, chan);
+ isp_prt(isp, ISP_LOGWARN,
+ "Chan %d Register FC4 Type CT Passthrough returned 0x%x",
+ chan, pt->ctp_status);
+ return (1);
}
isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct);
- FC_SCRATCH_RELEASE(isp);
+ FC_SCRATCH_RELEASE(isp, chan);
if (ct->ct_cmd_resp == LS_RJT) {
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
- "Register FC4 Type rejected");
+ "Chan %d Register FC4 Type rejected", chan);
return (-1);
} else if (ct->ct_cmd_resp == LS_ACC) {
isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
- "Register FC4 Type accepted");
- return(0);
+ "Chan %d Register FC4 Type accepted", chan);
+ return (0);
} else {
isp_prt(isp, ISP_LOGWARN,
- "Register FC4 Type: 0x%x", ct->ct_cmd_resp);
+ "Chan %d Register FC4 Type: 0x%x",
+ chan, ct->ct_cmd_resp);
return (-1);
}
}
static uint16_t
-isp_nxt_handle(ispsoftc_t *isp, uint16_t handle)
+isp_nxt_handle(ispsoftc_t *isp, int chan, uint16_t handle)
{
int i;
if (handle == NIL_HANDLE) {
- if (FCPARAM(isp)->isp_topo == TOPO_F_PORT) {
+ if (FCPARAM(isp, chan)->isp_topo == TOPO_F_PORT) {
handle = 0;
} else {
handle = SNS_ID+1;
@@ -3979,7 +4167,7 @@ isp_nxt_handle(ispsoftc_t *isp, uint16_t handle)
if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
handle = NPH_FL_ID+1;
}
- if (FCPARAM(isp)->isp_2klogin) {
+ if (ISP_CAP_2KLOGIN(isp)) {
if (handle == NPH_MAX_2K) {
handle = 0;
}
@@ -3989,15 +4177,16 @@ isp_nxt_handle(ispsoftc_t *isp, uint16_t handle)
}
}
}
- if (handle == FCPARAM(isp)->isp_loopid) {
- return (isp_nxt_handle(isp, handle));
+ if (handle == FCPARAM(isp, chan)->isp_loopid) {
+ return (isp_nxt_handle(isp, chan, handle));
}
for (i = 0; i < MAX_FC_TARG; i++) {
- if (FCPARAM(isp)->portdb[i].state == FC_PORTDB_STATE_NIL) {
+ if (FCPARAM(isp, chan)->portdb[i].state ==
+ FC_PORTDB_STATE_NIL) {
continue;
}
- if (FCPARAM(isp)->portdb[i].handle == handle) {
- return (isp_nxt_handle(isp, handle));
+ if (FCPARAM(isp, chan)->portdb[i].handle == handle) {
+ return (isp_nxt_handle(isp, chan, handle));
}
}
return (handle);
@@ -4011,25 +4200,17 @@ int
isp_start(XS_T *xs)
{
ispsoftc_t *isp;
- uint32_t nxti, optr, handle;
+ uint32_t handle;
uint8_t local[QENTRY_LEN];
- ispreq_t *reqp, *qep;
- void *cdbp;
+ ispreq_t *reqp;
+ void *cdbp, *qep;
uint16_t *tptr;
- int target, i, hdlidx = 0;
+ int target, dmaresult, hdlidx = 0;
XS_INITERR(xs);
isp = XS_ISP(xs);
/*
- * Check to make sure we're supporting initiator role.
- */
- if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
- XS_SETERR(xs, HBA_SELTIMEOUT);
- return (CMD_COMPLETE);
- }
-
- /*
* Now make sure we're running.
*/
@@ -4047,9 +4228,7 @@ isp_start(XS_T *xs)
*/
if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
- isp_prt(isp, ISP_LOGERR,
- "unsupported cdb length (%d, CDB[0]=0x%x)",
- XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
+ isp_prt(isp, ISP_LOGERR, "unsupported cdb length (%d, CDB[0]=0x%x)", XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
XS_SETERR(xs, HBA_BOTCH);
return (CMD_COMPLETE);
}
@@ -4060,13 +4239,17 @@ isp_start(XS_T *xs)
*/
target = XS_TGT(xs);
if (IS_FC(isp)) {
- fcparam *fcp = isp->isp_param;
+ fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
+
+ if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
+ XS_SETERR(xs, HBA_SELTIMEOUT);
+ return (CMD_COMPLETE);
+ }
/*
* Try again later.
*/
- if (fcp->isp_fwstate != FW_READY ||
- fcp->isp_loopstate != LOOP_READY) {
+ if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate != LOOP_READY) {
return (CMD_RQLATER);
}
@@ -4075,9 +4258,8 @@ isp_start(XS_T *xs)
return (CMD_COMPLETE);
}
- 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);
+ hdlidx = fcp->isp_dev_map[XS_TGT(xs)] - 1;
+ isp_prt(isp, ISP_LOGDEBUG2, "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);
@@ -4090,22 +4272,27 @@ isp_start(XS_T *xs)
return (CMD_COMPLETE);
}
target = fcp->portdb[hdlidx].handle;
- }
-
- /*
- * Next check to see if any HBA or Device parameters need to be updated.
- */
- if (isp->isp_update != 0) {
- isp_update(isp);
+ fcp->portdb[hdlidx].dirty = 1;
+ } else {
+ sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
+ if ((sdp->role & ISP_ROLE_INITIATOR) == 0) {
+ XS_SETERR(xs, HBA_SELTIMEOUT);
+ return (CMD_COMPLETE);
+ }
+ if (sdp->update) {
+ isp_spi_update(isp, XS_CHANNEL(xs));
+ }
}
start_again:
- if (isp_getrqentry(isp, &nxti, &optr, (void *)&qep)) {
+ qep = isp_getrqentry(isp);
+ if (qep == NULL) {
isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
XS_SETERR(xs, HBA_BOTCH);
return (CMD_EAGAIN);
}
+ XS_SETERR(xs, HBA_NOERROR);
/*
* Now see if we need to synchronize the ISP with respect to anything.
@@ -4113,47 +4300,38 @@ isp_start(XS_T *xs)
* than which we got here to send a command to.
*/
reqp = (ispreq_t *) local;
- if (isp->isp_sendmarker) {
+ ISP_MEMZERO(local, QENTRY_LEN);
+ if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) {
if (IS_24XX(isp)) {
- isp_marker_24xx_t *m = (isp_marker_24xx_t *) qep;
- MEMZERO(m, QENTRY_LEN);
+ isp_marker_24xx_t *m = (isp_marker_24xx_t *) reqp;
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 = 0;
- goto start_again;
+ isp_put_marker_24xx(isp, m, qep);
} 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;
- }
+ isp_marker_t *m = (isp_marker_t *) reqp;
+ m->mrk_header.rqs_entry_count = 1;
+ m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
+ m->mrk_target = (XS_CHANNEL(xs) << 7); /* bus # */
+ m->mrk_modifier = SYNC_ALL;
+ isp_put_marker(isp, m, qep);
}
+ ISP_SYNC_REQUEST(isp);
+ ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 0);
+ goto start_again;
}
- MEMZERO((void *)reqp, QENTRY_LEN);
reqp->req_header.rqs_entry_count = 1;
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)
+ if (XS_CDBLEN(xs) > 12) {
reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
- else
+ } else {
reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
+ }
}
/* reqp->req_header.rqs_flags = 0; */
/* reqp->req_header.rqs_seqno = 0; */
@@ -4180,7 +4358,7 @@ isp_start(XS_T *xs)
/*
* See comment in isp_intr
*/
- /* XS_RESID(xs) = 0; */
+ /* XS_SET_RESID(xs, 0); */
/*
* Fibre Channel always requires some kind of tag.
@@ -4200,10 +4378,8 @@ isp_start(XS_T *xs)
((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
}
} else {
- sdparam *sdp = (sdparam *)isp->isp_param;
- sdp += XS_CHANNEL(xs);
- if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) &&
- XS_TAG_P(xs)) {
+ sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
+ if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) && XS_TAG_P(xs)) {
reqp->req_flags = XS_TAG_TYPE(xs);
}
}
@@ -4217,10 +4393,11 @@ isp_start(XS_T *xs)
} else if (IS_24XX(isp)) {
fcportdb_t *lp;
- lp = &FCPARAM(isp)->portdb[hdlidx];
+ lp = &FCPARAM(isp, XS_CHANNEL(xs))->portdb[hdlidx];
((ispreqt7_t *)reqp)->req_nphdl = target;
((ispreqt7_t *)reqp)->req_tidlo = lp->portid;
((ispreqt7_t *)reqp)->req_tidhi = lp->portid >> 16;
+ ((ispreqt7_t *)reqp)->req_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(xs));
if (XS_LUN(xs) > 256) {
((ispreqt7_t *)reqp)->req_lun[0] = XS_LUN(xs) >> 8;
((ispreqt7_t *)reqp)->req_lun[0] |= 0x40;
@@ -4228,17 +4405,17 @@ isp_start(XS_T *xs)
((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) {
+ } else if (ISP_CAP_2KLOGIN(isp)) {
((ispreqt2e_t *)reqp)->req_target = target;
((ispreqt2e_t *)reqp)->req_scclun = XS_LUN(xs);
- } else if (FCPARAM(isp)->isp_sccfw) {
+ } else if (ISP_CAP_SCCFW(isp)) {
((ispreqt2_t *)reqp)->req_target = target;
((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
} else {
((ispreqt2_t *)reqp)->req_target = target;
((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
}
- MEMCPY(cdbp, XS_CDBP(xs), XS_CDBLEN(xs));
+ ISP_MEMCPY(cdbp, XS_CDBP(xs), XS_CDBLEN(xs));
*tptr = XS_TIME(xs) / 1000;
if (*tptr == 0 && XS_TIME(xs)) {
@@ -4257,24 +4434,21 @@ isp_start(XS_T *xs)
reqp->req_handle = handle;
/*
- * Set up DMA and/or do any bus swizzling of the request entry
+ * Set up DMA and/or do any platform dependent swizzling of the request entry
* so that the Qlogic F/W understands what is being asked of it.
+ *
+ * The callee is responsible for adding all requests at this point.
*/
- i = ISP_DMASETUP(isp, xs, reqp, &nxti, optr);
- if (i != CMD_QUEUED) {
+ dmaresult = ISP_DMASETUP(isp, xs, reqp);
+ if (dmaresult != CMD_QUEUED) {
isp_destroy_handle(isp, handle);
/*
* dmasetup sets actual error in packet, and
* return what we were given to return.
*/
- return (i);
+ return (dmaresult);
}
- XS_SETERR(xs, HBA_NOERROR);
- 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));
- ISP_ADD_REQUEST(isp, nxti);
+ 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));
isp->isp_nactive++;
return (CMD_QUEUED);
}
@@ -4285,20 +4459,15 @@ isp_start(XS_T *xs)
*/
int
-isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg)
+isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
{
XS_T *xs;
- mbreg_t mbs;
- int bus, tgt;
+ mbreg_t *mbr, mbs;
+ int chan, tgt;
uint32_t handle;
-
- MEMZERO(&mbs, sizeof (mbs));
+ va_list ap;
switch (ctl) {
- default:
- isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
- break;
-
case ISPCTL_RESET_BUS:
/*
* Issue a bus reset.
@@ -4308,60 +4477,128 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg)
break;
} else if (IS_FC(isp)) {
mbs.param[1] = 10;
- bus = 0;
+ chan = 0;
} else {
- mbs.param[1] = SDPARAM(isp)->isp_bus_reset_delay;
+ va_start(ap, ctl);
+ chan = va_arg(ap, int);
+ va_end(ap);
+ mbs.param[1] = SDPARAM(isp, chan)->isp_bus_reset_delay;
if (mbs.param[1] < 2) {
mbs.param[1] = 2;
}
- bus = *((int *) arg);
- if (IS_DUALBUS(isp)) {
- mbs.param[2] = bus;
- }
+ mbs.param[2] = chan;
}
- mbs.param[0] = MBOX_BUS_RESET;
- isp->isp_sendmarker |= (1 << bus);
- mbs.logval = MBLOGALL;
+ MBSINIT(&mbs, MBOX_BUS_RESET, MBLOGALL, 0);
+ ISP_SET_SENDMARKER(isp, chan, 1);
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
break;
}
isp_prt(isp, ISP_LOGINFO,
- "driver initiated bus reset of bus %d", bus);
+ "driver initiated bus reset of bus %d", chan);
return (0);
case ISPCTL_RESET_DEV:
- tgt = (*((int *) arg)) & 0xffff;
+ va_start(ap, ctl);
+ chan = va_arg(ap, int);
+ tgt = va_arg(ap, int);
+ va_end(ap);
if (IS_24XX(isp)) {
- isp_prt(isp, ISP_LOGWARN, "RESET DEV NOT IMPLEMENTED");
+ uint8_t local[QENTRY_LEN];
+ isp24xx_tmf_t *tmf;
+ isp24xx_statusreq_t *sp;
+ fcparam *fcp = FCPARAM(isp, chan);
+ fcportdb_t *lp;
+ int hdlidx;
+
+ hdlidx = fcp->isp_dev_map[tgt] - 1;
+ if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
+ isp_prt(isp, ISP_LOGWARN,
+ "Chan %d bad handle %d trying to reset"
+ "target %d", chan, hdlidx, tgt);
+ break;
+ }
+ lp = &fcp->portdb[hdlidx];
+ if (lp->state != FC_PORTDB_STATE_VALID) {
+ isp_prt(isp, ISP_LOGWARN,
+ "Chan %d handle %d for abort of target %d "
+ "no longer valid", chan,
+ hdlidx, tgt);
+ break;
+ }
+
+ tmf = (isp24xx_tmf_t *) local;
+ ISP_MEMZERO(tmf, QENTRY_LEN);
+ tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
+ tmf->tmf_header.rqs_entry_count = 1;
+ tmf->tmf_nphdl = lp->handle;
+ tmf->tmf_delay = 2;
+ tmf->tmf_timeout = 2;
+ tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
+ tmf->tmf_tidlo = lp->portid;
+ tmf->tmf_tidhi = lp->portid >> 16;
+ tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
+ isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
+ MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
+ mbs.param[1] = QENTRY_LEN;
+ 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);
+
+ if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ break;
+ }
+ isp_put_24xx_tmf(isp, tmf, fcp->isp_scratch);
+ MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN);
+ fcp->sendmarker = 1;
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ FC_SCRATCH_RELEASE(isp, chan);
+ break;
+ }
+ MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
+ QENTRY_LEN);
+ sp = (isp24xx_statusreq_t *) local;
+ isp_get_24xx_response(isp,
+ &((isp24xx_statusreq_t *)fcp->isp_scratch)[1], sp);
+ FC_SCRATCH_RELEASE(isp, chan);
+ if (sp->req_completion_status == 0) {
+ return (0);
+ }
+ isp_prt(isp, ISP_LOGWARN,
+ "Chan %d reset of target %d returned 0x%x",
+ chan, tgt, sp->req_completion_status);
break;
} else if (IS_FC(isp)) {
- if (FCPARAM(isp)->isp_2klogin) {
+ if (ISP_CAP_2KLOGIN(isp)) {
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[1] = (chan << 15) | (tgt << 8);
}
- mbs.param[0] = MBOX_ABORT_TARGET;
+ MBSINIT(&mbs, MBOX_ABORT_TARGET, MBLOGALL, 0);
mbs.param[2] = 3; /* 'delay', in seconds */
- mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
break;
}
isp_prt(isp, ISP_LOGINFO,
- "Target %d on Bus %d Reset Succeeded", tgt, bus);
- isp->isp_sendmarker |= (1 << bus);
+ "Target %d on Bus %d Reset Succeeded", tgt, chan);
+ ISP_SET_SENDMARKER(isp, chan, 1);
return (0);
case ISPCTL_ABORT_CMD:
- xs = (XS_T *) arg;
+ va_start(ap, ctl);
+ xs = va_arg(ap, XS_T *);
+ va_end(ap);
+
tgt = XS_TGT(xs);
+ chan = XS_CHANNEL(xs);
handle = isp_find_handle(isp, xs);
if (handle == 0) {
@@ -4370,11 +4607,74 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg)
break;
}
if (IS_24XX(isp)) {
- isp_prt(isp, ISP_LOGWARN, "ABORT CMD NOT IMPLEMENTED");
+ isp24xx_abrt_t local, *ab = &local, *ab2;
+ fcparam *fcp;
+ fcportdb_t *lp;
+ int hdlidx;
+
+ fcp = FCPARAM(isp, chan);
+ hdlidx = fcp->isp_dev_map[tgt] - 1;
+ if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
+ isp_prt(isp, ISP_LOGWARN,
+ "Chan %d bad handle %d trying to abort"
+ "target %d", chan, hdlidx, tgt);
+ break;
+ }
+ lp = &fcp->portdb[hdlidx];
+ if (lp->state != FC_PORTDB_STATE_VALID) {
+ isp_prt(isp, ISP_LOGWARN,
+ "Chan %d handle %d for abort of target %d "
+ "no longer valid", chan, hdlidx, tgt);
+ break;
+ }
+ isp_prt(isp, ISP_LOGALL,
+ "Chan %d Abort Cmd for N-Port 0x%04x @ Port "
+ "0x%06x %p", chan, lp->handle, lp->portid, xs);
+ ISP_MEMZERO(ab, QENTRY_LEN);
+ ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO;
+ ab->abrt_header.rqs_entry_count = 1;
+ ab->abrt_handle = lp->handle;
+ ab->abrt_cmd_handle = handle;
+ ab->abrt_tidlo = lp->portid;
+ ab->abrt_tidhi = lp->portid >> 16;
+ ab->abrt_vpidx = ISP_GET_VPIDX(isp, chan);
+
+ ISP_MEMZERO(&mbs, sizeof (mbs));
+ MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
+ mbs.param[1] = QENTRY_LEN;
+ 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);
+
+ if (FC_SCRATCH_ACQUIRE(isp, chan)) {
+ isp_prt(isp, ISP_LOGERR, sacq);
+ break;
+ }
+ isp_put_24xx_abrt(isp, ab, fcp->isp_scratch);
+ ab2 = (isp24xx_abrt_t *)
+ &((uint8_t *)fcp->isp_scratch)[QENTRY_LEN];
+ ab2->abrt_nphdl = 0xdeaf;
+ MEMORYBARRIER(isp, SYNC_SFORDEV, 0, 2 * QENTRY_LEN);
+ isp_mboxcmd(isp, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ FC_SCRATCH_RELEASE(isp, chan);
+ break;
+ }
+ MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
+ QENTRY_LEN);
+ isp_get_24xx_abrt(isp, ab2, ab);
+ FC_SCRATCH_RELEASE(isp, chan);
+ if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY) {
+ return (0);
+ }
+ isp_prt(isp, ISP_LOGWARN,
+ "Chan %d handle %d abort returned 0x%x", chan,
+ hdlidx, ab->abrt_nphdl);
break;
} else if (IS_FC(isp)) {
- if (FCPARAM(isp)->isp_sccfw) {
- if (FCPARAM(isp)->isp_2klogin) {
+ if (ISP_CAP_SCCFW(isp)) {
+ if (ISP_CAP_2KLOGIN(isp)) {
mbs.param[1] = tgt;
} else {
mbs.param[1] = tgt << 8;
@@ -4384,12 +4684,10 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg)
mbs.param[1] = tgt << 8 | XS_LUN(xs);
}
} else {
- bus = XS_CHANNEL(xs);
- mbs.param[1] = (bus << 15) | (tgt << 8) | XS_LUN(xs);
+ mbs.param[1] = (chan << 15) | (tgt << 8) | XS_LUN(xs);
}
- mbs.param[0] = MBOX_ABORT;
+ MBSINIT(&mbs, MBOX_ABORT, MBLOGALL & ~MBOX_COMMAND_ERROR, 0);
mbs.param[2] = handle;
- mbs.logval = MBLOGALL & ~MBOX_COMMAND_ERROR;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
break;
@@ -4398,49 +4696,64 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg)
case ISPCTL_UPDATE_PARAMS:
- isp_update(isp);
+ va_start(ap, ctl);
+ chan = va_arg(ap, int);
+ va_end(ap);
+ isp_spi_update(isp, chan);
return (0);
case ISPCTL_FCLINK_TEST:
if (IS_FC(isp)) {
- int usdelay = *((int *) arg);
+ int usdelay;
+ va_start(ap, ctl);
+ chan = va_arg(ap, int);
+ usdelay = va_arg(ap, int);
+ va_end(ap);
if (usdelay == 0) {
usdelay = 250000;
}
- return (isp_fclink_test(isp, usdelay));
+ return (isp_fclink_test(isp, chan, usdelay));
}
break;
case ISPCTL_SCAN_FABRIC:
if (IS_FC(isp)) {
- return (isp_scan_fabric(isp));
+ va_start(ap, ctl);
+ chan = va_arg(ap, int);
+ va_end(ap);
+ return (isp_scan_fabric(isp, chan));
}
break;
case ISPCTL_SCAN_LOOP:
if (IS_FC(isp)) {
- return (isp_scan_loop(isp));
+ va_start(ap, ctl);
+ chan = va_arg(ap, int);
+ va_end(ap);
+ return (isp_scan_loop(isp, chan));
}
break;
case ISPCTL_PDB_SYNC:
if (IS_FC(isp)) {
- return (isp_pdb_sync(isp));
+ va_start(ap, ctl);
+ chan = va_arg(ap, int);
+ va_end(ap);
+ return (isp_pdb_sync(isp, chan));
}
break;
case ISPCTL_SEND_LIP:
if (IS_FC(isp) && !IS_24XX(isp)) {
- mbs.param[0] = MBOX_INIT_LIP;
- if (FCPARAM(isp)->isp_2klogin) {
+ MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
+ if (ISP_CAP_2KLOGIN(isp)) {
mbs.ibits = (1 << 10);
}
- mbs.logval = MBLOGALL;
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
return (0);
@@ -4449,42 +4762,66 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg)
break;
case ISPCTL_GET_PDB:
- if (IS_FC(isp) && arg) {
- int id = *((int *)arg);
- isp_pdb_t *pdb = arg;
- return (isp_getpdb(isp, id, pdb, 1));
+ if (IS_FC(isp)) {
+ isp_pdb_t *pdb;
+ va_start(ap, ctl);
+ chan = va_arg(ap, int);
+ tgt = va_arg(ap, int);
+ pdb = va_arg(ap, isp_pdb_t *);
+ va_end(ap);
+ return (isp_getpdb(isp, chan, tgt, pdb, 1));
}
break;
- case ISPCTL_GET_PORTNAME:
+ case ISPCTL_GET_NAMES:
{
- uint64_t *wwnp = arg;
- int loopid = *wwnp;
- *wwnp = isp_get_portname(isp, loopid, 0);
- if (*wwnp == (uint64_t) -1) {
+ uint64_t *wwnn, *wwnp;
+ va_start(ap, ctl);
+ chan = va_arg(ap, int);
+ tgt = va_arg(ap, int);
+ wwnn = va_arg(ap, uint64_t *);
+ wwnp = va_arg(ap, uint64_t *);
+ va_end(ap);
+ if (wwnn == NULL && wwnp == NULL) {
break;
- } else {
- return (0);
}
+ if (wwnn) {
+ *wwnn = isp_get_wwn(isp, chan, tgt, 1);
+ if (*wwnn == INI_NONE) {
+ break;
+ }
+ }
+ if (wwnp) {
+ *wwnp = isp_get_wwn(isp, chan, tgt, 0);
+ if (*wwnp == INI_NONE) {
+ break;
+ }
+ }
+ return (0);
}
case ISPCTL_RUN_MBOXCMD:
-
- isp_mboxcmd(isp, arg);
- return(0);
-
+ {
+ va_start(ap, ctl);
+ mbr = va_arg(ap, mbreg_t *);
+ va_end(ap);
+ isp_mboxcmd(isp, mbr);
+ return (0);
+ }
case ISPCTL_PLOGX:
{
- isp_plcmd_t *p = arg;
+ isp_plcmd_t *p;
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));
+ va_start(ap, ctl);
+ p = va_arg(ap, isp_plcmd_t *);
+ va_end(ap);
+
+ if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) {
+ return (isp_plogx(isp, p->channel, 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);
+ p->handle = isp_nxt_handle(isp, p->channel, p->handle);
+ r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0);
if ((r & 0xffff) == MBOX_PORT_ID_USED) {
p->handle = r >> 16;
r = 0;
@@ -4493,28 +4830,10 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg)
} while ((r & 0xffff) == MBOX_LOOP_ID_USED);
return (r);
}
-#ifdef ISP_TARGET_MODE
- case ISPCTL_TOGGLE_TMODE:
- {
+ default:
+ isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
+ break;
- /*
- * We don't check/set against role here- that's the
- * responsibility for the outer layer to coordinate.
- */
- if (IS_SCSI(isp)) {
- int param = *(int *)arg;
- mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
- mbs.param[1] = param & 0xffff;
- mbs.param[2] = param >> 16;
- mbs.logval = MBLOGALL;
- isp_mboxcmd(isp, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- break;
- }
- }
- return (0);
- }
-#endif
}
return (-1);
}
@@ -4548,6 +4867,7 @@ again:
* The mailbox semaphore will be nonzero if so.
*/
if (sema) {
+ fmbox:
if (mbox & 0x4000) {
isp->isp_intmboxc++;
if (isp->isp_mboxbsy) {
@@ -4557,8 +4877,7 @@ again:
if ((obits & (1 << i)) == 0) {
continue;
}
- isp->isp_mboxtmp[i] =
- ISP_READ(isp, MBOX_OFF(i));
+ isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
}
if (isp->isp_mbxwrk0) {
if (isp_mbox_continue(isp) == 0) {
@@ -4567,14 +4886,12 @@ again:
}
MBOX_NOTIFY_COMPLETE(isp);
} else {
- isp_prt(isp, ISP_LOGWARN,
- "mailbox cmd (0x%x) with no waiters", mbox);
+ isp_prt(isp, ISP_LOGWARN, "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) {
+ if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) || isp->isp_state != ISP_RUNSTATE) {
goto out;
}
}
@@ -4583,13 +4900,17 @@ again:
* We can't be getting this now.
*/
if (isp->isp_state != ISP_RUNSTATE) {
- isp_prt(isp, ISP_LOGINFO,
- "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
+ /*
+ * This seems to happen to 23XX and 24XX cards- don't know why.
+ */
+ if (isp->isp_mboxbsy && isp->isp_lastmbxcmd == MBOX_ABOUT_FIRMWARE) {
+ goto fmbox;
+ }
+ isp_prt(isp, ISP_LOGINFO, "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
/*
* Thank you very much! *Burrrp*!
*/
- ISP_WRITE(isp, isp->isp_respoutrp,
- ISP_READ(isp, isp->isp_respinrp));
+ ISP_WRITE(isp, isp->isp_respoutrp, ISP_READ(isp, isp->isp_respinrp));
if (IS_24XX(isp)) {
ISP_DISABLE_INTS(isp);
}
@@ -4600,12 +4921,10 @@ again:
/*
* 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);
+ if (IS_24XX(isp)) {
+ iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
+ optr = ISP_READ(isp, BIU2400_ATIO_RSPOUTP);
- isp->isp_rspbsy = 1;
while (optr != iptr) {
uint8_t qe[QENTRY_LEN];
isphdr_t *hp;
@@ -4623,14 +4942,12 @@ again:
(void) isp_target_notify(isp, addr, &oop);
break;
default:
- isp_print_qentry(isp, "?ATIOQ entry?",
- oop, addr);
+ 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_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
}
- isp->isp_rspbsy = 0;
optr = isp->isp_residx;
}
#endif
@@ -4646,9 +4963,7 @@ again:
* Debug: to be taken out eventually
*/
if (isp->isp_residx != optr) {
- isp_prt(isp, ISP_LOGINFO,
- "isp_intr: hard optr=%x, soft optr %x",
- optr, isp->isp_residx);
+ isp_prt(isp, ISP_LOGINFO, "isp_intr: hard optr=%x, soft optr %x", optr, isp->isp_residx);
isp->isp_residx = optr;
}
} else {
@@ -4669,9 +4984,7 @@ again:
} while (junk != iptr && ++i < 1000);
if (iptr != junk) {
- isp_prt(isp, ISP_LOGWARN,
- "Response Queue Out Pointer Unstable (%x, %x)",
- iptr, junk);
+ isp_prt(isp, ISP_LOGWARN, "Response Queue Out Pointer Unstable (%x, %x)", iptr, junk);
goto out;
}
} else {
@@ -4692,7 +5005,7 @@ again:
if (IS_24XX(isp)) {
junk = 0;
} else if (IS_23XX(isp)) {
- USEC_DELAY(100);
+ ISP_DELAY(100);
iptr = ISP_READ(isp, isp->isp_respinrp);
junk = ISP_READ(isp, BIU_R2HSTSLO);
} else {
@@ -4709,18 +5022,11 @@ again:
}
}
isp->isp_intbogus++;
- isp_prt(isp, ISP_LOGDEBUG1,
- "bogus intr- isr %x (%x) iptr %x optr %x",
- isr, junk, iptr, optr);
+ isp_prt(isp, ISP_LOGDEBUG1, "bogus intr- isr %x (%x) iptr %x optr %x", isr, junk, iptr, optr);
}
}
isp->isp_resodx = iptr;
-
- if (isp->isp_rspbsy) {
- goto out;
- }
- isp->isp_rspbsy = 1;
while (optr != iptr) {
uint8_t qe[QENTRY_LEN];
ispstatusreq_t *sp = (ispstatusreq_t *) qe;
@@ -4749,11 +5055,9 @@ again:
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);
+ 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);
+ isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp2);
}
scsi_status = sp2->req_scsi_status;
completion_status = sp2->req_completion_status;
@@ -4762,8 +5066,7 @@ again:
} else if (etype == RQSTYPE_RESPONSE) {
isp_get_response(isp, (ispstatusreq_t *) hp, sp);
if (isp->isp_dblev & ISP_LOGDEBUG1) {
- isp_print_bytes(isp,
- "Response Queue Entry", QENTRY_LEN, sp);
+ isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp);
}
scsi_status = sp->req_scsi_status;
completion_status = sp->req_completion_status;
@@ -4774,17 +5077,15 @@ again:
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);
+ 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;
+ isp->isp_fpcchiwater = rio->req_header.rqs_seqno;
}
- MEMZERO(hp, QENTRY_LEN); /* PERF */
+ ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
continue;
} else {
/*
@@ -4793,13 +5094,22 @@ again:
* us, so we reload our goal index.
*/
int r;
- r = isp_handle_other_response(isp, etype, hp, &optr);
+ uint32_t tsto = oop;
+ r = isp_handle_other_response(isp, etype, hp, &tsto);
if (r < 0) {
goto read_again;
}
+ /*
+ * If somebody updated the output pointer, then reset
+ * optr to be one more than the updated amount.
+ */
+ while (tsto != oop) {
+ optr = ISP_NXT_QENTRY(tsto,
+ RESULT_QUEUE_LEN(isp));
+ }
if (r > 0) {
- iptr = isp->isp_resodx;
- MEMZERO(hp, QENTRY_LEN); /* PERF */
+ ISP_WRITE(isp, isp->isp_respoutrp, optr);
+ ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
continue;
}
@@ -4819,7 +5129,7 @@ again:
etype, oop, optr, nlooked);
isp_print_bytes(isp,
"Request Queue Entry", QENTRY_LEN, sp);
- MEMZERO(hp, QENTRY_LEN); /* PERF */
+ ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
continue;
}
buddaboom = 1;
@@ -4832,35 +5142,38 @@ again:
if (sp->req_header.rqs_flags & RQSFLAG_MASK) {
if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
- isp_prt(isp, ISP_LOGWARN,
- "continuation segment");
+ isp_print_bytes(isp, "unexpected continuation segment", QENTRY_LEN, sp);
ISP_WRITE(isp, isp->isp_respoutrp, optr);
continue;
}
if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
- isp_prt(isp, ISP_LOGDEBUG1,
- "internal queues full");
+ isp_prt(isp, ISP_LOGDEBUG0, "internal queues full");
/*
* We'll synthesize a QUEUE FULL message below.
*/
}
if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
- isp_print_bytes(isp, "bad header flag",
- QENTRY_LEN, sp);
+ isp_print_bytes(isp, "bad header flag", QENTRY_LEN, sp);
buddaboom++;
}
if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
- isp_print_bytes(isp, "bad request packet",
- QENTRY_LEN, sp);
+ isp_print_bytes(isp, "bad request packet", QENTRY_LEN, sp);
buddaboom++;
}
+ if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
+ isp_print_bytes(isp, "invalid entry count", QENTRY_LEN, sp);
+ buddaboom++;
+ }
+ if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
+ isp_print_bytes(isp, "invalid IOCB ordering", QENTRY_LEN, sp);
+ ISP_WRITE(isp, isp->isp_respoutrp, optr);
+ continue;
+ }
}
- if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) {
- isp_prt(isp, ISP_LOGERR,
- "bad request handle %d (type 0x%x)",
- sp->req_handle, etype);
- MEMZERO(hp, QENTRY_LEN); /* PERF */
+ if ((sp->req_handle != ISP_SPCL_HANDLE) && (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1)) {
+ isp_prt(isp, ISP_LOGERR, "bad request handle %d (type 0x%x)", sp->req_handle, etype);
+ ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
ISP_WRITE(isp, isp->isp_respoutrp, optr);
continue;
}
@@ -4869,25 +5182,21 @@ again:
uint8_t ts = completion_status & 0xff;
/*
* Only whine if this isn't the expected fallout of
- * aborting the command.
+ * aborting the command or resetting the target.
*/
if (etype != RQSTYPE_RESPONSE) {
- isp_prt(isp, ISP_LOGERR,
- "cannot find handle 0x%x (type 0x%x)",
- 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);
+ isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (type 0x%x)", sp->req_handle, etype);
+ } else if (ts != RQCS_ABORTED && ts != RQCS_RESET_OCCURRED && sp->req_handle != ISP_SPCL_HANDLE) {
+ isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)", sp->req_handle, ts);
}
- MEMZERO(hp, QENTRY_LEN); /* PERF */
+ ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
ISP_WRITE(isp, isp->isp_respoutrp, optr);
continue;
}
isp_destroy_handle(isp, sp->req_handle);
if (req_status_flags & RQSTF_BUS_RESET) {
XS_SETERR(xs, HBA_BUSRESET);
- isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
+ ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
}
if (buddaboom) {
XS_SETERR(xs, HBA_BOTCH);
@@ -4912,11 +5221,9 @@ again:
*/
req_state_flags |= RQSF_GOT_STATUS|RQSF_GOT_SENSE;
if (IS_24XX(isp)) {
- snsp =
- ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
+ snsp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
snsp += rlen;
- slen =
- ((isp24xx_statusreq_t *)sp)->req_sense_len;
+ slen = ((isp24xx_statusreq_t *)sp)->req_sense_len;
} else {
snsp = sp->req_sense_data;
slen = sp->req_sense_len;
@@ -4931,27 +5238,38 @@ again:
switch (etype) {
case RQSTYPE_RESPONSE:
- XS_SET_STATE_STAT(isp, xs, sp);
- 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 (resp && rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
+ const char *ptr;
+ char lb[64];
+ const char *rnames[6] = {
+ "Task Management Function Done",
+ "Data Length Differs From Burst Length",
+ "Invalid FCP Cmnd",
+ "FCP DATA RO mismatch with FCP DATA_XFR_RDY RO",
+ "Task Management Function Rejected",
+ "Task Management Function Failed",
+ };
+ if (resp[FCP_RSPNS_CODE_OFFSET] > 5) {
+ ISP_SNPRINTF(lb, sizeof lb, "Unknown FCP Response Code 0x%x", resp[FCP_RSPNS_CODE_OFFSET]);
+ ptr = lb;
+ } else {
+ ptr = rnames[resp[FCP_RSPNS_CODE_OFFSET]];
+ }
+ isp_prt(isp, ISP_LOGWARN, "%d.%d.%d FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x", XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), rlen, ptr, XS_CDBP(xs)[0] & 0xff);
+ if (resp[FCP_RSPNS_CODE_OFFSET] != 0) {
+ XS_SETERR(xs, HBA_BOTCH);
+ }
}
if (IS_24XX(isp)) {
- isp_parse_status_24xx(isp,
- (isp24xx_statusreq_t *)sp, xs, &resid);
+ 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)) {
+ 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) = resid;
+ XS_SET_RESID(xs, resid);
/*
* A new synchronous rate was negotiated for
* this target. Mark state such that we'll go
@@ -4959,56 +5277,45 @@ again:
*/
if (req_status_flags & RQSTF_NEGOTIATION) {
int t = XS_TGT(xs);
- sdparam *sdp = isp->isp_param;
- sdp += XS_CHANNEL(xs);
+ sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
sdp->isp_devparam[t].dev_refresh = 1;
- isp->isp_update |=
- (1 << XS_CHANNEL(xs));
+ sdp->update = 1;
}
} else {
if (req_status_flags & RQSF_XFER_COMPLETE) {
- XS_RESID(xs) = 0;
+ XS_SET_RESID(xs, 0);
} else if (scsi_status & RQCS_RESID) {
- XS_RESID(xs) = resid;
+ XS_SET_RESID(xs, resid);
} else {
- XS_RESID(xs) = 0;
+ XS_SET_RESID(xs, 0);
}
}
if (snsp && slen) {
XS_SAVE_SENSE(xs, snsp, slen);
+ } else if ((req_status_flags & RQSF_GOT_STATUS) && (scsi_status & 0xff) == SCSI_CHECK && IS_FC(isp)) {
+ isp_prt(isp, ISP_LOGWARN, "CHECK CONDITION w/o sense data for CDB=0x%x", XS_CDBP(xs)[0] & 0xff);
+ isp_print_bytes(isp, "CC with no Sense", QENTRY_LEN, qe);
}
- isp_prt(isp, ISP_LOGDEBUG2,
- "asked for %ld got raw resid %ld settled for %ld",
- (long) XS_XFRLEN(xs), resid, (long) XS_RESID(xs));
+ isp_prt(isp, ISP_LOGDEBUG2, "asked for %ld got raw resid %ld settled for %ld", (long) XS_XFRLEN(xs), resid, (long) XS_GET_RESID(xs));
break;
case RQSTYPE_REQUEST:
case RQSTYPE_A64:
case RQSTYPE_T2RQS:
case RQSTYPE_T3RQS:
case RQSTYPE_T7RQS:
- if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
+ if (!IS_24XX(isp) && (sp->req_header.rqs_flags & RQSFLAG_FULL)) {
/*
* Force Queue Full status.
*/
*XS_STSP(xs) = SCSI_QFULL;
XS_SETERR(xs, HBA_NOERROR);
} else if (XS_NOERR(xs)) {
- /*
- * ????
- */
XS_SETERR(xs, HBA_BOTCH);
- isp_prt(isp, ISP_LOGDEBUG0,
- "Request Queue Entry bounced back");
- if ((isp->isp_dblev & ISP_LOGDEBUG1) == 0) {
- isp_print_bytes(isp, "Bounced Request",
- QENTRY_LEN, qe);
- }
}
- XS_RESID(xs) = XS_XFRLEN(xs);
+ XS_SET_RESID(xs, XS_XFRLEN(xs));
break;
default:
- isp_print_bytes(isp, "Unhandled Response Type",
- QENTRY_LEN, qe);
+ isp_print_bytes(isp, "Unhandled Response Type", QENTRY_LEN, qe);
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_BOTCH);
}
@@ -5023,7 +5330,7 @@ again:
ISP_DMAFREE(isp, xs, sp->req_handle);
}
- if (((isp->isp_dblev & (ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
+ if (((isp->isp_dblev & (ISP_LOGDEBUG1|ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
((isp->isp_dblev & ISP_LOGDEBUG0) && ((!XS_NOERR(xs)) ||
(*XS_STSP(xs) != SCSI_GOOD)))) {
char skey;
@@ -5039,14 +5346,15 @@ again:
skey = '.';
}
isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs),
- XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), XS_RESID(xs),
+ XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), (long) XS_GET_RESID(xs),
*XS_STSP(xs), skey, XS_ERR(xs));
}
- if (isp->isp_nactive > 0)
+ if (isp->isp_nactive > 0) {
isp->isp_nactive--;
+ }
complist[ndone++] = xs; /* defer completion call until later */
- MEMZERO(hp, QENTRY_LEN); /* PERF */
+ ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
if (ndone == MAX_REQUESTQ_COMPLETIONS) {
break;
}
@@ -5078,7 +5386,6 @@ out:
}
isp->isp_residx = optr;
- isp->isp_rspbsy = 0;
for (i = 0; i < ndone; i++) {
xs = complist[i];
if (xs) {
@@ -5092,34 +5399,50 @@ out:
* Support routines.
*/
+#define GET_24XX_BUS(isp, chan, msg) \
+ if (IS_24XX(isp)) { \
+ chan = ISP_READ(isp, OUTMAILBOX3) & 0xff; \
+ if (chan >= isp->isp_nchan) { \
+ isp_prt(isp, ISP_LOGERR, "bogus channel %u for %s at line %d", chan, msg, __LINE__); \
+ break; \
+ } \
+ }
+
static int
isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
{
int rval = 0;
- int bus;
+ int pattern = 0;
+ uint16_t chan;
if (IS_DUALBUS(isp)) {
- bus = ISP_READ(isp, OUTMAILBOX6);
+ chan = ISP_READ(isp, OUTMAILBOX6);
} else {
- bus = 0;
+ chan = 0;
}
isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
switch (mbox) {
case ASYNC_BUS_RESET:
- isp->isp_sendmarker |= (1 << bus);
+ if (IS_FC(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "ILLEGAL ASYNC_BUS_RESET for FC card");
+ break;
+ }
+ ISP_SET_SENDMARKER(isp, chan, 1);
#ifdef ISP_TARGET_MODE
- if (isp_target_async(isp, bus, mbox)) {
+ if (isp_target_async(isp, chan, mbox)) {
rval = -1;
}
#endif
- isp_async(isp, ISPASYNC_BUS_RESET, &bus);
+ isp_async(isp, ISPASYNC_BUS_RESET, chan);
break;
case ASYNC_SYSTEM_ERROR:
+ isp->isp_dead = 1;
isp->isp_state = ISP_CRASHED;
if (IS_FC(isp)) {
- FCPARAM(isp)->isp_loopstate = LOOP_NIL;
- FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
+ FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
+ FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
}
/*
* Were we waiting for a mailbox command to complete?
@@ -5134,7 +5457,7 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
* It's up to the handler for isp_async to reinit stuff and
* restart the firmware
*/
- isp_async(isp, ISPASYNC_FW_CRASH, NULL);
+ isp_async(isp, ISPASYNC_FW_CRASH);
rval = -1;
break;
@@ -5147,6 +5470,17 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
break;
case ASYNC_QWAKEUP:
+#ifdef ISP_TARGET_MODE
+ if (IS_24XX(isp)) {
+ isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
+ break;
+ }
+#endif
+ if (IS_FC(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "ILLEGAL ASYNC_QWAKEUP for FC card");
+ break;
+ }
/*
* We've just been notified that the Queue has woken up.
* We don't need to be chatty about this- just unlatch things
@@ -5156,66 +5490,101 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
break;
case ASYNC_TIMEOUT_RESET:
+ if (IS_FC(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "ILLEGAL ASYNC_TIMEOUT_RESET for FC card");
+ break;
+ }
isp_prt(isp, ISP_LOGWARN,
- "timeout initiated SCSI bus reset of bus %d", bus);
- isp->isp_sendmarker |= (1 << bus);
+ "timeout initiated SCSI bus reset of chan %d", chan);
+ ISP_SET_SENDMARKER(isp, chan, 1);
#ifdef ISP_TARGET_MODE
- if (isp_target_async(isp, bus, mbox)) {
+ if (isp_target_async(isp, chan, mbox)) {
rval = -1;
}
#endif
break;
case ASYNC_DEVICE_RESET:
- isp_prt(isp, ISP_LOGINFO, "device reset on bus %d", bus);
- isp->isp_sendmarker |= (1 << bus);
+ if (IS_FC(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "ILLEGAL DEVICE_RESET for FC card");
+ break;
+ }
+ isp_prt(isp, ISP_LOGINFO, "device reset on chan %d", chan);
+ ISP_SET_SENDMARKER(isp, chan, 1);
#ifdef ISP_TARGET_MODE
- if (isp_target_async(isp, bus, mbox)) {
+ if (isp_target_async(isp, chan, mbox)) {
rval = -1;
}
#endif
break;
case ASYNC_EXTMSG_UNDERRUN:
+ if (IS_FC(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "ILLEGAL ASYNC_EXTMSG_UNDERRUN for FC card");
+ break;
+ }
isp_prt(isp, ISP_LOGWARN, "extended message underrun");
break;
case ASYNC_SCAM_INT:
+ if (IS_FC(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "ILLEGAL ASYNC_SCAM_INT for FC card");
+ break;
+ }
isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
break;
case ASYNC_HUNG_SCSI:
+ if (IS_FC(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "ILLEGAL ASYNC_HUNG_SCSI for FC card");
+ break;
+ }
isp_prt(isp, ISP_LOGERR,
"stalled SCSI Bus after DATA Overrun");
/* XXX: Need to issue SCSI reset at this point */
break;
case ASYNC_KILLED_BUS:
+ if (IS_FC(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "ILLEGAL ASYNC_KILLED_BUS for FC card");
+ break;
+ }
isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
break;
case ASYNC_BUS_TRANSIT:
+ if (IS_FC(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "ILLEGAL ASYNC_BUS_TRANSIT for FC card");
+ break;
+ }
mbox = ISP_READ(isp, OUTMAILBOX2);
switch (mbox & 0x1c00) {
case SXP_PINS_LVD_MODE:
isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
- SDPARAM(isp)->isp_diffmode = 0;
- SDPARAM(isp)->isp_ultramode = 0;
- SDPARAM(isp)->isp_lvdmode = 1;
+ SDPARAM(isp, chan)->isp_diffmode = 0;
+ SDPARAM(isp, chan)->isp_ultramode = 0;
+ SDPARAM(isp, chan)->isp_lvdmode = 1;
break;
case SXP_PINS_HVD_MODE:
isp_prt(isp, ISP_LOGINFO,
"Transition to Differential mode");
- SDPARAM(isp)->isp_diffmode = 1;
- SDPARAM(isp)->isp_ultramode = 0;
- SDPARAM(isp)->isp_lvdmode = 0;
+ SDPARAM(isp, chan)->isp_diffmode = 1;
+ SDPARAM(isp, chan)->isp_ultramode = 0;
+ SDPARAM(isp, chan)->isp_lvdmode = 0;
break;
case SXP_PINS_SE_MODE:
isp_prt(isp, ISP_LOGINFO,
"Transition to Single Ended mode");
- SDPARAM(isp)->isp_diffmode = 0;
- SDPARAM(isp)->isp_ultramode = 1;
- SDPARAM(isp)->isp_lvdmode = 0;
+ SDPARAM(isp, chan)->isp_diffmode = 0;
+ SDPARAM(isp, chan)->isp_ultramode = 1;
+ SDPARAM(isp, chan)->isp_lvdmode = 0;
break;
default:
isp_prt(isp, ISP_LOGWARN,
@@ -5226,32 +5595,28 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
* XXX: Set up to renegotiate again!
*/
/* Can only be for a 1080... */
- isp->isp_sendmarker |= (1 << bus);
+ ISP_SET_SENDMARKER(isp, chan, 1);
break;
- /*
- * We can use bus, which will always be zero for FC cards,
- * as a mailbox pattern accumulator to be checked below.
- */
case ASYNC_RIO5:
- bus = 0x1ce; /* outgoing mailbox regs 1-3, 6-7 */
+ pattern = 0xce; /* outgoing mailbox regs 1-3, 6-7 */
break;
case ASYNC_RIO4:
- bus = 0x14e; /* outgoing mailbox regs 1-3, 6 */
+ pattern = 0x4e; /* outgoing mailbox regs 1-3, 6 */
break;
case ASYNC_RIO3:
- bus = 0x10e; /* outgoing mailbox regs 1-3 */
+ pattern = 0x0e; /* outgoing mailbox regs 1-3 */
break;
case ASYNC_RIO2:
- bus = 0x106; /* outgoing mailbox regs 1-2 */
+ pattern = 0x06; /* outgoing mailbox regs 1-2 */
break;
case ASYNC_RIO1:
case ASYNC_CMD_CMPLT:
- bus = 0x102; /* outgoing mailbox regs 1 */
+ pattern = 0x02; /* outgoing mailbox regs 1 */
break;
case ASYNC_RIO_RESP:
@@ -5260,8 +5625,15 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
case ASYNC_CTIO_DONE:
{
#ifdef ISP_TARGET_MODE
- int handle =
- (ISP_READ(isp, OUTMAILBOX2) << 16) |
+ int handle;
+ if (IS_SCSI(isp) || IS_24XX(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "bad ASYNC_CTIO_DONE for %s cards",
+ IS_SCSI(isp)? "SCSI" : "24XX");
+ break;
+ }
+ handle =
+ (ISP_READ(isp, OUTMAILBOX2) << 16) |
(ISP_READ(isp, OUTMAILBOX1));
if (isp_target_async(isp, handle, mbox)) {
rval = -1;
@@ -5270,6 +5642,12 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
isp->isp_fphccmplt++;
}
#else
+ if (IS_SCSI(isp) || IS_24XX(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "bad ASYNC_CTIO_DONE for %s cards",
+ IS_SCSI(isp)? "SCSI" : "24XX");
+ break;
+ }
isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
isp->isp_fphccmplt++; /* count it as a fast posting intr */
#endif
@@ -5278,114 +5656,236 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
case ASYNC_LIP_ERROR:
case ASYNC_LIP_F8:
case ASYNC_LIP_OCCURRED:
- FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
- FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
- isp->isp_sendmarker = 1;
- ISP_MARK_PORTDB(isp, 1);
- isp_async(isp, ISPASYNC_LIP, NULL);
-#ifdef ISP_TARGET_MODE
- if (isp_target_async(isp, bus, mbox)) {
- rval = -1;
+ case ASYNC_PTPMODE:
+ if (IS_SCSI(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "bad LIP event for SCSI cards");
+ break;
}
-#endif
/*
- * 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
- * all active commands as dead.
+ * These are broadcast events that have to be sent across
+ * all active channels.
*/
- if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
- FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
- int i, j;
- for (i = j = 0; i < isp->isp_maxcmds; i++) {
- XS_T *xs;
- xs = isp->isp_xflist[i];
- if (xs != NULL) {
+ for (chan = 0; chan < isp->isp_nchan; chan++) {
+ fcparam *fcp = FCPARAM(isp, chan);
+ int topo = fcp->isp_topo;
+
+ if (fcp->role == ISP_ROLE_NONE) {
+ continue;
+ }
+
+ fcp->isp_fwstate = FW_CONFIG_WAIT;
+ fcp->isp_loopstate = LOOP_LIP_RCVD;
+ ISP_SET_SENDMARKER(isp, chan, 1);
+ ISP_MARK_PORTDB(isp, chan, 1);
+ isp_async(isp, ISPASYNC_LIP, chan);
+#ifdef ISP_TARGET_MODE
+ if (isp_target_async(isp, chan, mbox)) {
+ rval = -1;
+ }
+#endif
+ /*
+ * 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
+ * all active commands as dead.
+ */
+ if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
+ int i, j;
+ for (i = j = 0; i < isp->isp_maxcmds; i++) {
+ XS_T *xs;
+ xs = isp->isp_xflist[i];
+ if (xs == NULL) {
+ continue;
+ }
+ if (XS_CHANNEL(xs) != chan) {
+ continue;
+ }
j++;
XS_SETERR(xs, HBA_BUSRESET);
}
- }
- if (j) {
- isp_prt(isp, ISP_LOGERR,
- "LIP destroyed %d active commands", j);
+ if (j) {
+ isp_prt(isp, ISP_LOGERR, lipd, chan, j);
+ }
}
}
break;
case ASYNC_LOOP_UP:
- isp->isp_sendmarker = 1;
- FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
- FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
- ISP_MARK_PORTDB(isp, 1);
- isp_async(isp, ISPASYNC_LOOP_UP, NULL);
-#ifdef ISP_TARGET_MODE
- if (isp_target_async(isp, bus, mbox)) {
- rval = -1;
+ if (IS_SCSI(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "bad LOOP UP event for SCSI cards");
+ break;
}
+ /*
+ * This is a broadcast event that has to be sent across
+ * all active channels.
+ */
+ for (chan = 0; chan < isp->isp_nchan; chan++) {
+ fcparam *fcp = FCPARAM(isp, chan);
+
+ if (fcp->role == ISP_ROLE_NONE) {
+ continue;
+ }
+
+ ISP_SET_SENDMARKER(isp, chan, 1);
+
+ fcp->isp_fwstate = FW_CONFIG_WAIT;
+ fcp->isp_loopstate = LOOP_LIP_RCVD;
+ ISP_MARK_PORTDB(isp, chan, 1);
+ isp_async(isp, ISPASYNC_LOOP_UP, chan);
+#ifdef ISP_TARGET_MODE
+ if (isp_target_async(isp, chan, mbox)) {
+ rval = -1;
+ }
#endif
+ }
break;
case ASYNC_LOOP_DOWN:
- isp->isp_sendmarker = 1;
- FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
- FCPARAM(isp)->isp_loopstate = LOOP_NIL;
- ISP_MARK_PORTDB(isp, 1);
- isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
-#ifdef ISP_TARGET_MODE
- if (isp_target_async(isp, bus, mbox)) {
- rval = -1;
+ if (IS_SCSI(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "bad LOOP DOWN event for SCSI cards");
+ break;
}
+ /*
+ * This is a broadcast event that has to be sent across
+ * all active channels.
+ */
+ for (chan = 0; chan < isp->isp_nchan; chan++) {
+ fcparam *fcp = FCPARAM(isp, chan);
+
+ if (fcp->role == ISP_ROLE_NONE) {
+ continue;
+ }
+
+ ISP_SET_SENDMARKER(isp, chan, 1);
+ fcp->isp_fwstate = FW_CONFIG_WAIT;
+ fcp->isp_loopstate = LOOP_NIL;
+ ISP_MARK_PORTDB(isp, chan, 1);
+ isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
+#ifdef ISP_TARGET_MODE
+ if (isp_target_async(isp, chan, mbox)) {
+ rval = -1;
+ }
#endif
+ }
break;
case ASYNC_LOOP_RESET:
- isp->isp_sendmarker = 1;
- FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
- FCPARAM(isp)->isp_loopstate = LOOP_NIL;
- ISP_MARK_PORTDB(isp, 1);
- isp_async(isp, ISPASYNC_LOOP_RESET, NULL);
-#ifdef ISP_TARGET_MODE
- if (isp_target_async(isp, bus, mbox)) {
- rval = -1;
+ if (IS_SCSI(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "bad LIP RESET event for SCSI cards");
+ break;
}
+ /*
+ * This is a broadcast event that has to be sent across
+ * all active channels.
+ */
+ for (chan = 0; chan < isp->isp_nchan; chan++) {
+ fcparam *fcp = FCPARAM(isp, chan);
+
+ if (fcp->role == ISP_ROLE_NONE) {
+ continue;
+ }
+
+ ISP_SET_SENDMARKER(isp, chan, 1);
+ fcp->isp_fwstate = FW_CONFIG_WAIT;
+ fcp->isp_loopstate = LOOP_NIL;
+ ISP_MARK_PORTDB(isp, chan, 1);
+ isp_async(isp, ISPASYNC_LOOP_RESET, chan);
+#ifdef ISP_TARGET_MODE
+ if (isp_target_async(isp, chan, mbox)) {
+ rval = -1;
+ }
#endif
+ }
break;
case ASYNC_PDB_CHANGED:
- isp->isp_sendmarker = 1;
- FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
- ISP_MARK_PORTDB(isp, 1);
- isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_PDB);
- break;
+ {
+ int nphdl, nlstate, reason;
+ if (IS_SCSI(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "bad PDB CHANGED event for SCSI cards");
+ break;
+ }
+ /*
+ * We *should* get a channel out of the 24XX, but we don't seem
+ * to get more than a PDB CHANGED on channel 0, so turn it into
+ * a broadcast event.
+ */
+ if (IS_24XX(isp)) {
+ nphdl = ISP_READ(isp, OUTMAILBOX1);
+ nlstate = ISP_READ(isp, OUTMAILBOX2);
+ reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
+ } else {
+ nphdl = NIL_HANDLE;
+ nlstate = reason = 0;
+ }
+ for (chan = 0; chan < isp->isp_nchan; chan++) {
+ fcparam *fcp = FCPARAM(isp, chan);
+ if (fcp->role == ISP_ROLE_NONE) {
+ continue;
+ }
+ ISP_SET_SENDMARKER(isp, chan, 1);
+ fcp->isp_loopstate = LOOP_PDB_RCVD;
+ ISP_MARK_PORTDB(isp, chan, 1);
+ isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
+ ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
+ }
+ break;
+ }
case ASYNC_CHANGE_NOTIFY:
- if (FCPARAM(isp)->isp_topo == TOPO_F_PORT) {
- FCPARAM(isp)->isp_loopstate = LOOP_LSCAN_DONE;
+ {
+ int lochan, hichan;
+
+ if (IS_SCSI(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "bad CHANGE NOTIFY event for SCSI cards");
+ break;
+ }
+ if (ISP_FW_NEWER_THAN(isp, 4, 0, 25) && ISP_CAP_MULTI_ID(isp)) {
+ GET_24XX_BUS(isp, chan, "ASYNC_CHANGE_NOTIFY");
+ lochan = chan;
+ hichan = chan + 1;
} else {
- FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
+ lochan = 0;
+ hichan = isp->isp_nchan;
}
- ISP_MARK_PORTDB(isp, 1);
- isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_SNS);
- break;
+ for (chan = lochan; chan < hichan; chan++) {
+ fcparam *fcp = FCPARAM(isp, chan);
- case ASYNC_PTPMODE:
- 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)) {
- rval = -1;
+ if (fcp->role == ISP_ROLE_NONE) {
+ continue;
+ }
+
+ if (fcp->isp_topo == TOPO_F_PORT) {
+ fcp->isp_loopstate = LOOP_LSCAN_DONE;
+ } else {
+ fcp->isp_loopstate = LOOP_PDB_RCVD;
+ }
+ ISP_MARK_PORTDB(isp, chan, 1);
+ isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
+ ISPASYNC_CHANGE_SNS);
}
-#endif
- isp_prt(isp, ISP_LOGINFO, "Point-to-Point mode");
break;
+ }
case ASYNC_CONNMODE:
+ /*
+ * This only applies to 2100 amd 2200 cards
+ */
+ if (!IS_2200(isp) && !IS_2100(isp)) {
+ isp_prt(isp, ISP_LOGWARN,
+ "bad card for ASYNC_CONNMODE event");
+ break;
+ }
+ chan = 0;
mbox = ISP_READ(isp, OUTMAILBOX1);
- ISP_MARK_PORTDB(isp, 1);
+ ISP_MARK_PORTDB(isp, chan, 1);
switch (mbox) {
case ISP_CONN_LOOP:
isp_prt(isp, ISP_LOGINFO,
@@ -5400,8 +5900,10 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
"Point-to-Point -> Loop mode (BAD LIP)");
break;
case ISP_CONN_FATAL:
+ isp->isp_dead = 1;
+ isp->isp_state = ISP_CRASHED;
isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
- isp_async(isp, ISPASYNC_FW_CRASH, NULL);
+ isp_async(isp, ISPASYNC_FW_CRASH);
return (-1);
case ISP_CONN_LOOPBACK:
isp_prt(isp, ISP_LOGWARN,
@@ -5412,12 +5914,21 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
"Unknown connection mode (0x%x)", mbox);
break;
}
- isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
- isp->isp_sendmarker = 1;
- FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
- FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
+ isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
+ ISPASYNC_CHANGE_OTHER);
+ FCPARAM(isp, chan)->sendmarker = 1;
+ FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
+ FCPARAM(isp, chan)->isp_loopstate = LOOP_LIP_RCVD;
break;
+ case ASYNC_RCV_ERR:
+ if (IS_24XX(isp)) {
+ isp_prt(isp, ISP_LOGWARN, "Receive Error");
+ } else {
+ isp_prt(isp, ISP_LOGWARN,
+ "Unknown Async Code 0x%x", mbox);
+ }
+ break;
case ASYNC_RJT_SENT: /* same as ASYNC_QFULL_SENT */
if (IS_24XX(isp)) {
isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
@@ -5432,12 +5943,12 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
break;
}
- if (bus & 0x100) {
+ if (pattern) {
int i, nh;
uint16_t handles[16];
for (nh = 0, i = 1; i < MAX_MAILBOX(isp); i++) {
- if ((bus & (1 << i)) == 0) {
+ if ((pattern & (1 << i)) == 0) {
continue;
}
handles[nh++] = ISP_READ(isp, MBOX_OFF(i));
@@ -5493,9 +6004,18 @@ isp_handle_other_response(ispsoftc_t *isp, int type,
}
#endif
/* FALLTHROUGH */
+ case RQSTYPE_RPT_ID_ACQ:
+ if (IS_24XX(isp)) {
+ isp_ridacq_t rid;
+ isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
+ if (rid.ridacq_format == 0) {
+ }
+ return (1);
+ }
+ /* FALLTHROUGH */
case RQSTYPE_REQUEST:
default:
- USEC_DELAY(100);
+ ISP_DELAY(100);
if (type != isp_get_response_type(isp, hp)) {
/*
* This is questionable- we're just papering over
@@ -5511,9 +6031,6 @@ isp_handle_other_response(ispsoftc_t *isp, int type,
}
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);
}
}
@@ -5554,52 +6071,52 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
case RQCS_TRANSPORT_ERROR:
{
char buf[172];
- SNPRINTF(buf, sizeof (buf), "states=>");
+ ISP_SNPRINTF(buf, sizeof (buf), "states=>");
if (sp->req_state_flags & RQSF_GOT_BUS) {
- SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
}
if (sp->req_state_flags & RQSF_GOT_TARGET) {
- SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
}
if (sp->req_state_flags & RQSF_SENT_CDB) {
- SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
}
if (sp->req_state_flags & RQSF_XFRD_DATA) {
- SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
}
if (sp->req_state_flags & RQSF_GOT_STATUS) {
- SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
}
if (sp->req_state_flags & RQSF_GOT_SENSE) {
- SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
}
if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
- SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
}
- SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
if (sp->req_status_flags & RQSTF_DISCONNECT) {
- SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
}
if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
- SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
}
if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
- SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
}
if (sp->req_status_flags & RQSTF_BUS_RESET) {
- SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
}
if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
- SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
}
if (sp->req_status_flags & RQSTF_ABORTED) {
- SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
}
if (sp->req_status_flags & RQSTF_TIMEOUT) {
- SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
}
if (sp->req_status_flags & RQSTF_NEGOTIATION) {
- SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
+ ISP_SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
}
isp_prt(isp, ISP_LOGERR, "%s", buf);
isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
@@ -5608,20 +6125,24 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
break;
}
case RQCS_RESET_OCCURRED:
+ {
+ int chan;
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));
+ for (chan = 0; chan < isp->isp_nchan; chan++) {
+ FCPARAM(isp, chan)->sendmarker = 1;
+ }
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_BUSRESET);
}
*rp = XS_XFRLEN(xs);
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));
+ ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_ABORTED);
}
@@ -5639,9 +6160,9 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
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));
+ XS_SET_RESID(xs, sp->req_resid);
+ isp_prt(isp, ISP_LOGERR, "data overrun (%ld) for command on %d.%d.%d",
+ (long) XS_GET_RESID(xs), XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_DATAOVR);
}
@@ -5733,7 +6254,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
return;
}
}
- XS_RESID(xs) = sp->req_resid;
+ XS_SET_RESID(xs, sp->req_resid);
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_NOERROR);
}
@@ -5804,11 +6325,10 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
"Wide Negotiation failed for %d.%d.%d",
XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
if (IS_SCSI(isp)) {
- sdparam *sdp = isp->isp_param;
- sdp += XS_CHANNEL(xs);
+ sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
- isp->isp_update |= (1 << XS_CHANNEL(xs));
+ sdp->update = 1;
}
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_NOERROR);
@@ -5820,11 +6340,11 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
"SDTR Message failed for target %d.%d.%d",
XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
if (IS_SCSI(isp)) {
- sdparam *sdp = isp->isp_param;
+ sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
sdp += XS_CHANNEL(xs);
sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
- isp->isp_update |= (1 << XS_CHANNEL(xs));
+ sdp->update = 1;
}
break;
@@ -5860,15 +6380,13 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
* 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) {
+ if (FCPARAM(isp, 0)->isp_topo == TOPO_NL_PORT ||
+ FCPARAM(isp, 0)->isp_topo == TOPO_FL_PORT) {
mbreg_t mbs;
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_INIT_LIP;
- if (FCPARAM(isp)->isp_2klogin) {
+ MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
+ if (ISP_CAP_2KLOGIN(isp)) {
mbs.ibits = (1 << 10);
}
- mbs.logval = MBLOGALL;
isp_mboxcmd_qnw(isp, &mbs, 1);
}
if (XS_NOERR(xs)) {
@@ -5907,6 +6425,8 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
XS_T *xs, long *rp)
{
int ru_marked, sv_marked;
+ int chan = XS_CHANNEL(xs);
+
switch (sp->req_completion_status) {
case RQCS_COMPLETE:
if (XS_NOERR(xs)) {
@@ -5926,9 +6446,9 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
case RQCS_RESET_OCCURRED:
isp_prt(isp, ISP_LOGWARN,
- "bus reset destroyed command for %d.%d.%d",
+ "reset destroyed command for %d.%d.%d",
XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
- isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
+ FCPARAM(isp, chan)->sendmarker = 1;
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_BUSRESET);
}
@@ -5937,7 +6457,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
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));
+ FCPARAM(isp, chan)->sendmarker = 1;
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_ABORTED);
}
@@ -5952,7 +6472,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
return;
case RQCS_DATA_OVERRUN:
- XS_RESID(xs) = sp->req_resid;
+ XS_SET_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));
@@ -5962,8 +6482,9 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
return;
case RQCS_24XX_DRE: /* data reassembly error */
- isp_prt(isp, ISP_LOGERR, "data reassembly error for target %d",
- XS_TGT(xs));
+ isp_prt(isp, ISP_LOGERR,
+ "Chan %d data reassembly error for target %d",
+ chan, XS_TGT(xs));
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_ABORTED);
}
@@ -5971,8 +6492,8 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
return;
case RQCS_24XX_TABORT: /* aborted by target */
- isp_prt(isp, ISP_LOGERR, "target %d sent ABTS",
- XS_TGT(xs));
+ isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS",
+ chan, XS_TGT(xs));
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_ABORTED);
}
@@ -5981,7 +6502,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
case RQCS_DATA_UNDERRUN:
ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
/*
- * We can get an underrun w/o things being marked
+ * We can get an underrun w/o things being marked
* if we got a non-zero status.
*/
sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
@@ -5995,7 +6516,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
}
return;
}
- XS_RESID(xs) = sp->req_resid;
+ XS_SET_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),
@@ -6023,25 +6544,12 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
reason = "logout";
}
- isp_prt(isp, ISP_LOGINFO, "port %s for target %d",
- reason, XS_TGT(xs));
+ isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d",
+ chan, 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.
+ * There is no MBOX_INIT_LIP for the 24XX.
*/
- 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);
}
@@ -6049,7 +6557,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
}
case RQCS_PORT_CHANGED:
isp_prt(isp, ISP_LOGWARN,
- "port changed for target %d", XS_TGT(xs));
+ "port changed for target %d chan %d", XS_TGT(xs), chan);
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_SELTIMEOUT);
}
@@ -6058,7 +6566,8 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
case RQCS_24XX_ENOMEM: /* f/w resource unavailable */
isp_prt(isp, ISP_LOGWARN,
- "f/w resource unavailable for target %d", XS_TGT(xs));
+ "f/w resource unavailable for target %d chan %d",
+ XS_TGT(xs), chan);
if (XS_NOERR(xs)) {
*XS_STSP(xs) = SCSI_BUSY;
XS_SETERR(xs, HBA_TGTBSY);
@@ -6067,8 +6576,8 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
case RQCS_24XX_TMO: /* task management overrun */
isp_prt(isp, ISP_LOGWARN,
- "command for target %d overlapped task management",
- XS_TGT(xs));
+ "command for target %d overlapped task management for "
+ "chan %d", XS_TGT(xs), chan);
if (XS_NOERR(xs)) {
*XS_STSP(xs) = SCSI_BUSY;
XS_SETERR(xs, HBA_TGTBSY);
@@ -6076,8 +6585,9 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
return;
default:
- isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
- sp->req_completion_status);
+ isp_prt(isp, ISP_LOGERR,
+ "Unknown Completion Status 0x%x on chan %d",
+ sp->req_completion_status, chan);
break;
}
if (XS_NOERR(xs)) {
@@ -6095,7 +6605,7 @@ isp_fastpost_complete(ispsoftc_t *isp, uint16_t fph)
}
xs = isp_find_xs(isp, fph);
if (xs == NULL) {
- isp_prt(isp, ISP_LOGDEBUG1,
+ isp_prt(isp, ISP_LOGWARN,
"Command for fast post handle 0x%x not found", fph);
return;
}
@@ -6106,14 +6616,14 @@ isp_fastpost_complete(ispsoftc_t *isp, uint16_t fph)
* we must believe that SCSI status is zero and
* that all data transferred.
*/
- XS_SET_STATE_STAT(isp, xs, NULL);
- XS_RESID(xs) = 0;
+ XS_SET_RESID(xs, 0);
*XS_STSP(xs) = SCSI_GOOD;
if (XS_XFRLEN(xs)) {
ISP_DMAFREE(isp, xs, fph);
}
- if (isp->isp_nactive)
+ if (isp->isp_nactive) {
isp->isp_nactive--;
+ }
isp->isp_fphccmplt++;
isp_done(xs);
}
@@ -6152,7 +6662,7 @@ isp_mbox_continue(ispsoftc_t *isp)
/*
* Continue with next word.
*/
- MEMZERO(&mbs, sizeof (mbs));
+ ISP_MEMZERO(&mbs, sizeof (mbs));
ptr = isp->isp_mbxworkp;
switch (isp->isp_lastmbxcmd) {
case MBOX_WRITE_RAM_WORD:
@@ -6397,7 +6907,7 @@ static const uint32_t mbpfc[] = {
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, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */
+ ISPOPMAP(0x07, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */
ISPOPMAP(0x01, 0x4f), /* 0x08: MBOX_ABOUT_FIRMWARE */
ISPOPMAP(0xdf, 0x01), /* 0x09: MBOX_LOAD_RISC_RAM_2100 */
ISPOPMAP(0xdf, 0x01), /* 0x0a: DUMP RAM */
@@ -6462,9 +6972,9 @@ static const uint32_t mbpfc[] = {
ISPOPMAP(0x00, 0x00), /* 0x45: */
ISPOPMAP(0x00, 0x00), /* 0x46: */
ISPOPMAP(0xcf, 0x03), /* 0x47: GET PORT_DATABASE ENHANCED */
- ISPOPMAP(0x00, 0x00), /* 0x48: */
- ISPOPMAP(0x00, 0x00), /* 0x49: */
- ISPOPMAP(0x00, 0x00), /* 0x4a: */
+ ISPOPMAP(0xcd, 0x01), /* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */
+ ISPOPMAP(0xcd, 0x01), /* 0x49: MBOX_GET_VP_DATABASE */
+ ISPOPMAP(0x2cd, 0x01), /* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */
ISPOPMAP(0x00, 0x00), /* 0x4b: */
ISPOPMAP(0x00, 0x00), /* 0x4c: */
ISPOPMAP(0x00, 0x00), /* 0x4d: */
@@ -6521,7 +7031,7 @@ static const uint32_t mbpfc[] = {
/*
* Footnotes
*
- * (1): this sets bits 21..16 in mailbox register #8, which we nominally
+ * (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!). The assumption
* is that we won't overflow.
@@ -6600,9 +7110,9 @@ static const char *fc_mbcmd_names[] = {
NULL,
NULL,
"GET PORT DATABASE ENHANCED",
- NULL,
- NULL,
- NULL,
+ "INIT FIRMWARE MULTI ID",
+ "GET VP DATABASE",
+ "GET VP DATABASE ENTRY",
NULL,
NULL,
NULL,
@@ -6697,7 +7207,7 @@ isp_mboxcmd_qnw(ispsoftc_t *isp, mbreg_t *mbp, int nodelay)
* command.
*/
if (nodelay) {
- USEC_DELAY(1000);
+ ISP_DELAY(1000);
}
}
@@ -6748,7 +7258,7 @@ isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
for (box = 0; box < MAX_MAILBOX(isp); box++) {
if (ibits & (1 << box)) {
- isp_prt(isp, ISP_LOGDEBUG1, "IN mbox %d = 0x%04x", box,
+ isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box,
mbp->param[box]);
ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
}
@@ -6781,6 +7291,7 @@ isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
* Did the command time out?
*/
if (mbp->param[0] == MBOX_TIMEOUT) {
+ isp->isp_mboxbsy = 0;
MBOX_RELEASE(isp);
goto out;
}
@@ -6791,21 +7302,21 @@ isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
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%04x", box,
+ isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box,
mbp->param[box]);
}
}
+ isp->isp_mboxbsy = 0;
MBOX_RELEASE(isp);
out:
- isp->isp_mboxbsy = 0;
if (mbp->logval == 0 || opcode == MBOX_EXEC_FIRMWARE) {
return;
}
cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
if (cname == NULL) {
cname = tname;
- SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
+ ISP_SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
}
/*
@@ -6862,7 +7373,7 @@ isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
xname = "TIMEOUT";
break;
default:
- SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
+ ISP_SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
xname = mname;
break;
}
@@ -6873,15 +7384,13 @@ isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
}
static void
-isp_fw_state(ispsoftc_t *isp)
+isp_fw_state(ispsoftc_t *isp, int chan)
{
if (IS_FC(isp)) {
mbreg_t mbs;
- fcparam *fcp = isp->isp_param;
+ fcparam *fcp = FCPARAM(isp, chan);
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_GET_FW_STATE;
- mbs.logval = MBLOGALL;
+ MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0);
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
fcp->isp_fwstate = mbs.param[1];
@@ -6890,34 +7399,20 @@ isp_fw_state(ispsoftc_t *isp)
}
static void
-isp_update(ispsoftc_t *isp)
-{
- int bus, upmask;
-
- for (bus = 0, upmask = isp->isp_update; upmask != 0; bus++) {
- if (upmask & (1 << bus)) {
- isp_update_bus(isp, bus);
- }
- upmask &= ~(1 << bus);
- }
-}
-
-static void
-isp_update_bus(ispsoftc_t *isp, int bus)
+isp_spi_update(ispsoftc_t *isp, int chan)
{
int tgt;
mbreg_t mbs;
sdparam *sdp;
- isp->isp_update &= ~(1 << bus);
if (IS_FC(isp)) {
/*
* There are no 'per-bus' settings for Fibre Channel.
*/
return;
}
- sdp = isp->isp_param;
- sdp += bus;
+ sdp = SDPARAM(isp, chan);
+ sdp->update = 0;
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
uint16_t flags, period, offset;
@@ -6927,7 +7422,7 @@ isp_update_bus(ispsoftc_t *isp, int bus)
sdp->isp_devparam[tgt].dev_update = 0;
sdp->isp_devparam[tgt].dev_refresh = 0;
isp_prt(isp, ISP_LOGDEBUG0,
- "skipping target %d bus %d update", tgt, bus);
+ "skipping target %d bus %d update", tgt, chan);
continue;
}
/*
@@ -6937,7 +7432,7 @@ isp_update_bus(ispsoftc_t *isp, int bus)
* current device state, get the current parameters.
*/
- MEMZERO(&mbs, sizeof (mbs));
+ MBSINIT(&mbs, 0, MBLOGALL, 0);
/*
* Refresh overrides set
@@ -6985,20 +7480,19 @@ isp_update_bus(ispsoftc_t *isp, int bus)
(sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
isp_prt(isp, ISP_LOGDEBUG0,
"bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
- bus, tgt, mbs.param[2], mbs.param[3] >> 8,
+ chan, tgt, mbs.param[2], mbs.param[3] >> 8,
mbs.param[3] & 0xff);
get = 0;
} else {
continue;
}
- mbs.param[1] = (bus << 15) | (tgt << 8);
- mbs.logval = MBLOGALL;
+ mbs.param[1] = (chan << 15) | (tgt << 8);
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
continue;
}
if (get == 0) {
- isp->isp_sendmarker |= (1 << bus);
+ sdp->sendmarker = 1;
sdp->isp_devparam[tgt].dev_update = 0;
sdp->isp_devparam[tgt].dev_refresh = 1;
} else {
@@ -7009,48 +7503,41 @@ isp_update_bus(ispsoftc_t *isp, int bus)
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);
+ isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, chan, tgt);
}
}
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
if (sdp->isp_devparam[tgt].dev_update ||
sdp->isp_devparam[tgt].dev_refresh) {
- isp->isp_update |= (1 << bus);
+ sdp->update = 1;
break;
}
}
}
-#ifndef DEFAULT_EXEC_THROTTLE
-#define DEFAULT_EXEC_THROTTLE(isp) ISP_EXEC_THROTTLE
-#endif
-
static void
-isp_setdfltparm(ispsoftc_t *isp, int channel)
+isp_setdfltsdparm(ispsoftc_t *isp)
{
int tgt;
- sdparam *sdp;
-
- sdp = (sdparam *) isp->isp_param;
- sdp += channel;
+ sdparam *sdp, *sdp1;
- /*
- * Been there, done that, got the T-shirt...
- */
- if (sdp->isp_gotdparms) {
- return;
+ sdp = SDPARAM(isp, 0);
+ sdp->role = GET_DEFAULT_ROLE(isp, 0);
+ if (IS_DUALBUS(isp)) {
+ sdp1 = sdp + 1;
+ sdp1->role = GET_DEFAULT_ROLE(isp, 1);
+ } else {
+ sdp1 = NULL;
}
- sdp->isp_gotdparms = 1;
- sdp->isp_bad_nvram = 0;
+
/*
* Establish some default parameters.
*/
sdp->isp_cmd_dma_burst_enable = 0;
sdp->isp_data_dma_burst_enabl = 1;
sdp->isp_fifo_threshold = 0;
- sdp->isp_initiator_id = DEFAULT_IID(isp);
+ sdp->isp_initiator_id = DEFAULT_IID(isp, 0);
if (isp->isp_type >= ISP_HA_SCSI_1040) {
sdp->isp_async_data_setup = 9;
} else {
@@ -7073,50 +7560,6 @@ isp_setdfltparm(ispsoftc_t *isp, int channel)
}
/*
- * If we've not been told to avoid reading NVRAM, try and read it.
- * If we're successful reading it, we can then return because NVRAM
- * will tell us what the desired settings are. Otherwise, we establish
- * some reasonable 'fake' nvram and goal defaults.
- */
-
- if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
- if (isp_read_nvram(isp) == 0) {
- return;
- }
- sdp->isp_bad_nvram = 1;
- }
-
- /*
- * Now try and see whether we have specific values for them.
- */
- if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
- mbreg_t mbs;
-
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_GET_ACT_NEG_STATE;
- 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;
- } else {
- sdp->isp_req_ack_active_neg =
- (mbs.param[1+channel] >> 4) & 0x1;
- sdp->isp_data_line_active_neg =
- (mbs.param[1+channel] >> 5) & 0x1;
- }
- }
-
- isp_prt(isp, ISP_LOGDEBUG0, sc0, sc3,
- 0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
- sdp->isp_bus_reset_delay, sdp->isp_retry_count,
- sdp->isp_retry_delay, sdp->isp_async_data_setup);
- isp_prt(isp, ISP_LOGDEBUG0, sc1, sc3,
- sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
- sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
- sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
-
- /*
* The trick here is to establish a default for the default (honk!)
* state (goal_flags). Then try and get the current status from
* the card to fill in the current state. We don't, in fact, set
@@ -7161,49 +7604,97 @@ isp_setdfltparm(ispsoftc_t *isp, int channel)
sdp->isp_devparam[tgt].goal_period =
sdp->isp_devparam[tgt].nvrm_period = per;
- isp_prt(isp, ISP_LOGDEBUG0, sc2, sc3,
- channel, tgt, sdp->isp_devparam[tgt].nvrm_flags,
- sdp->isp_devparam[tgt].nvrm_offset,
- sdp->isp_devparam[tgt].nvrm_period);
}
+
+ /*
+ * If we're a dual bus card, just copy the data over
+ */
+ if (sdp1) {
+ *sdp1 = *sdp;
+ sdp1->isp_initiator_id = DEFAULT_IID(isp, 1);
+ }
+
+ /*
+ * If we've not been told to avoid reading NVRAM, try and read it.
+ * If we're successful reading it, we can then return because NVRAM
+ * will tell us what the desired settings are. Otherwise, we establish
+ * some reasonable 'fake' nvram and goal defaults.
+ */
+ if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
+ mbreg_t mbs;
+
+ if (isp_read_nvram(isp, 0) == 0) {
+ if (IS_DUALBUS(isp)) {
+ if (isp_read_nvram(isp, 1) == 0) {
+ return;
+ }
+ }
+ }
+ MBSINIT(&mbs, MBOX_GET_ACT_NEG_STATE, MBLOGNONE, 0);
+ 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;
+ if (sdp1) {
+ sdp1->isp_req_ack_active_neg = 1;
+ sdp1->isp_data_line_active_neg = 1;
+ }
+ } else {
+ sdp->isp_req_ack_active_neg =
+ (mbs.param[1] >> 4) & 0x1;
+ sdp->isp_data_line_active_neg =
+ (mbs.param[1] >> 5) & 0x1;
+ if (sdp1) {
+ sdp1->isp_req_ack_active_neg =
+ (mbs.param[2] >> 4) & 0x1;
+ sdp1->isp_data_line_active_neg =
+ (mbs.param[2] >> 5) & 0x1;
+ }
+ }
+ }
+
}
-#ifndef DEFAULT_FRAMESIZE
-#define DEFAULT_FRAMESIZE(isp) ICB_DFLT_FRMLEN
-#endif
static void
-isp_setdfltfcparm(ispsoftc_t *isp)
+isp_setdfltfcparm(ispsoftc_t *isp, int chan)
{
- fcparam *fcp = FCPARAM(isp);
+ fcparam *fcp = FCPARAM(isp, chan);
- if (fcp->isp_gotdparms) {
- return;
- }
- fcp->isp_gotdparms = 1;
- fcp->isp_bad_nvram = 0;
- fcp->isp_maxfrmlen = DEFAULT_FRAMESIZE(isp);
+ /*
+ * Establish some default parameters.
+ */
+ fcp->role = GET_DEFAULT_ROLE(isp, chan);
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_loopid = DEFAULT_LOOPID(isp, chan);
+ fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan);
+ fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan);
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;
+ fcp->isp_lasthdl = NIL_HANDLE;
+
+ if (IS_24XX(isp)) {
+ fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS;
+ fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS;
+ if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
+ fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX;
+ }
+ fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS;
+ } else {
+ 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;
}
- /*
- * 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.
@@ -7215,61 +7706,22 @@ isp_setdfltfcparm(ispsoftc_t *isp)
* Give a couple of tries at reading NVRAM.
*/
for (i = 0; i < 2; i++) {
- j = isp_read_nvram(isp);
+ j = isp_read_nvram(isp, chan);
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",
- (uint32_t) (DEFAULT_NODEWWN(isp) >> 32),
- (uint32_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",
- (uint32_t) (DEFAULT_PORTWWN(isp) >> 32),
- (uint32_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);
- }
- }
+ fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan);
+ fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan);
+ isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s",
+ chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn),
+ (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn),
+ isp_class3_roles[fcp->role]);
}
/*
@@ -7279,28 +7731,28 @@ isp_setdfltfcparm(ispsoftc_t *isp)
*/
void
-isp_reinit(ispsoftc_t *isp)
+isp_reinit(ispsoftc_t *isp, int do_load_defaults)
{
- XS_T *xs;
- uint32_t tmp;
+ int i;
+
+ isp_reset(isp, do_load_defaults);
- 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");
- } else if (isp->isp_role != ISP_ROLE_NONE) {
- isp_init(isp);
- if (isp->isp_state == ISP_INITSTATE) {
- isp->isp_state = ISP_RUNSTATE;
- }
- if (isp->isp_state != ISP_RUNSTATE) {
- isp_prt(isp, ISP_LOGERR,
- "isp_reinit cannot restart card");
- ISP_DISABLE_INTS(isp);
- }
- } else {
+ isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
+ ISP_DISABLE_INTS(isp);
+ goto cleanup;
+ }
+
+ isp_init(isp);
+
+ if (isp->isp_state == ISP_INITSTATE) {
+ isp->isp_state = ISP_RUNSTATE;
+ }
+
+ if (isp->isp_state != ISP_RUNSTATE) {
+#ifndef ISP_TARGET_MODE
+ isp_prt(isp, ISP_LOGWARN, "%s: not at runstate", __func__);
+#endif
ISP_DISABLE_INTS(isp);
if (IS_FC(isp)) {
/*
@@ -7315,51 +7767,36 @@ isp_reinit(ispsoftc_t *isp)
}
}
}
- isp->isp_nactive = 0;
- for (tmp = 0; tmp < isp->isp_maxcmds; tmp++) {
- uint32_t handle;
+ cleanup:
- 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);
- XS_RESID(xs) = XS_XFRLEN(xs);
- } else {
- XS_RESID(xs) = 0;
+ isp->isp_nactive = 0;
+
+ isp_clear_commands(isp);
+ if (IS_FC(isp)) {
+ for (i = 0; i < isp->isp_nchan; i++) {
+ ISP_MARK_PORTDB(isp, i, -1);
}
- 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
-isp_read_nvram(ispsoftc_t *isp)
+isp_read_nvram(ispsoftc_t *isp, int bus)
{
int i, amt, retval;
uint8_t csum, minversion;
union {
- uint8_t _x[ISP2100_NVRAM_SIZE];
- uint16_t _s[ISP2100_NVRAM_SIZE>>1];
+ uint8_t _x[ISP2400_NVRAM_SIZE];
+ uint16_t _s[ISP2400_NVRAM_SIZE>>1];
} _n;
#define nvram_data _n._x
#define nvram_words _n._s
if (IS_24XX(isp)) {
- return (isp_read_nvram_2400(isp));
+ return (isp_read_nvram_2400(isp, nvram_data));
} else if (IS_FC(isp)) {
amt = ISP2100_NVRAM_SIZE;
minversion = 1;
@@ -7403,14 +7840,11 @@ isp_read_nvram(ispsoftc_t *isp)
}
if (IS_ULTRA3(isp)) {
- isp_parse_nvram_12160(isp, 0, nvram_data);
- if (IS_12160(isp))
- isp_parse_nvram_12160(isp, 1, nvram_data);
+ isp_parse_nvram_12160(isp, bus, nvram_data);
} else if (IS_1080(isp)) {
- isp_parse_nvram_1080(isp, 0, nvram_data);
+ isp_parse_nvram_1080(isp, bus, nvram_data);
} else if (IS_1280(isp) || IS_1240(isp)) {
- isp_parse_nvram_1080(isp, 0, nvram_data);
- isp_parse_nvram_1080(isp, 1, nvram_data);
+ isp_parse_nvram_1080(isp, bus, nvram_data);
} else if (IS_SCSI(isp)) {
isp_parse_nvram_1020(isp, nvram_data);
} else {
@@ -7424,18 +7858,17 @@ out:
}
static int
-isp_read_nvram_2400(ispsoftc_t *isp)
+isp_read_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
{
- uint8_t *nvram_data = FCPARAM(isp)->isp_scratch;
int retval = 0;
uint32_t addr, csum, lwrds, *dptr;
-
+
if (isp->isp_port) {
addr = ISP2400_NVRAM_PORT1_ADDR;
} else {
addr = ISP2400_NVRAM_PORT0_ADDR;
}
-
+
dptr = (uint32_t *) nvram_data;
for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
isp_rd_2400_nvram(isp, addr++, dptr++);
@@ -7470,12 +7903,12 @@ isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
uint16_t bit, rqst, junk;
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
- USEC_DELAY(10);
+ ISP_DELAY(10);
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
- USEC_DELAY(10);
+ ISP_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;
}
@@ -7501,13 +7934,13 @@ isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
bit = BIU_NVRAM_SELECT;
}
ISP_WRITE(isp, BIU_NVRAM, bit);
- USEC_DELAY(10);
+ ISP_DELAY(10);
junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
- USEC_DELAY(10);
+ ISP_DELAY(10);
junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
ISP_WRITE(isp, BIU_NVRAM, bit);
- USEC_DELAY(10);
+ ISP_DELAY(10);
junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
}
/*
@@ -7518,18 +7951,18 @@ isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
uint16_t rv;
*rp <<= 1;
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
- USEC_DELAY(10);
+ ISP_DELAY(10);
rv = ISP_READ(isp, BIU_NVRAM);
if (rv & BIU_NVRAM_DATAIN) {
*rp |= 1;
}
- USEC_DELAY(10);
+ ISP_DELAY(10);
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
- USEC_DELAY(10);
+ ISP_DELAY(10);
junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
}
ISP_WRITE(isp, BIU_NVRAM, 0);
- USEC_DELAY(10);
+ ISP_DELAY(10);
junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */
ISP_SWIZZLE_NVRAM_WORD(isp, rp);
}
@@ -7538,12 +7971,15 @@ static void
isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
{
int loops = 0;
- const uint32_t base = 0x7ffe0000;
+ uint32_t base = 0x7ffe0000;
uint32_t tmp = 0;
+ if (IS_25XX(isp)) {
+ base = 0x7ff00000 | 0x48000;
+ }
ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
for (loops = 0; loops < 5000; loops++) {
- USEC_DELAY(10);
+ ISP_DELAY(10);
tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
if ((tmp & (1U << 31)) != 0) {
break;
@@ -7560,7 +7996,7 @@ isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
static void
isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data)
{
- sdparam *sdp = (sdparam *) isp->isp_param;
+ sdparam *sdp = SDPARAM(isp, 0);
int tgt;
sdp->isp_fifo_threshold =
@@ -7616,15 +8052,6 @@ isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data)
sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
- isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
- 0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
- sdp->isp_bus_reset_delay, sdp->isp_retry_count,
- sdp->isp_retry_delay, sdp->isp_async_data_setup);
- isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
- sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
- sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
- sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
-
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
sdp->isp_devparam[tgt].dev_enable =
ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
@@ -7670,10 +8097,6 @@ isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data)
if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
- isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
- 0, tgt, sdp->isp_devparam[tgt].nvrm_flags,
- sdp->isp_devparam[tgt].nvrm_offset,
- sdp->isp_devparam[tgt].nvrm_period);
sdp->isp_devparam[tgt].goal_offset =
sdp->isp_devparam[tgt].nvrm_offset;
sdp->isp_devparam[tgt].goal_period =
@@ -7686,11 +8109,9 @@ isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data)
static void
isp_parse_nvram_1080(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
{
- sdparam *sdp = (sdparam *) isp->isp_param;
+ sdparam *sdp = SDPARAM(isp, bus);
int tgt;
- sdp += bus;
-
sdp->isp_fifo_threshold =
ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
@@ -7728,16 +8149,6 @@ isp_parse_nvram_1080(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
sdp->isp_max_queue_depth =
ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
- isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
- bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
- sdp->isp_bus_reset_delay, sdp->isp_retry_count,
- sdp->isp_retry_delay, sdp->isp_async_data_setup);
- isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
- sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
- sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
- sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
-
-
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
sdp->isp_devparam[tgt].dev_enable =
ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
@@ -7762,10 +8173,6 @@ isp_parse_nvram_1080(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
sdp->isp_devparam[tgt].actv_flags = 0;
- isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
- bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
- sdp->isp_devparam[tgt].nvrm_offset,
- sdp->isp_devparam[tgt].nvrm_period);
sdp->isp_devparam[tgt].goal_offset =
sdp->isp_devparam[tgt].nvrm_offset;
sdp->isp_devparam[tgt].goal_period =
@@ -7778,11 +8185,9 @@ isp_parse_nvram_1080(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
static void
isp_parse_nvram_12160(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
{
- sdparam *sdp = (sdparam *) isp->isp_param;
+ sdparam *sdp = SDPARAM(isp, bus);
int tgt;
- sdp += bus;
-
sdp->isp_fifo_threshold =
ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
@@ -7820,15 +8225,6 @@ isp_parse_nvram_12160(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
sdp->isp_max_queue_depth =
ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
- isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
- bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
- sdp->isp_bus_reset_delay, sdp->isp_retry_count,
- sdp->isp_retry_delay, sdp->isp_async_data_setup);
- isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
- sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
- sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
- sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
-
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
sdp->isp_devparam[tgt].dev_enable =
ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
@@ -7853,10 +8249,6 @@ isp_parse_nvram_12160(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
sdp->isp_devparam[tgt].actv_flags = 0;
- isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
- bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
- sdp->isp_devparam[tgt].nvrm_offset,
- sdp->isp_devparam[tgt].nvrm_period);
sdp->isp_devparam[tgt].goal_offset =
sdp->isp_devparam[tgt].nvrm_offset;
sdp->isp_devparam[tgt].goal_period =
@@ -7867,41 +8259,9 @@ isp_parse_nvram_12160(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
}
static void
-isp_fix_nvram_wwns(ispsoftc_t *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 & (((uint64_t) 0xfff) << 48)) != 0 &&
- (fcp->isp_wwnn_nvram >> 60) == 2) {
- fcp->isp_wwnn_nvram &= ~((uint64_t) 0xfff << 48);
- }
- if ((fcp->isp_wwpn_nvram & (((uint64_t) 0xfff) << 48)) == 0 &&
- (fcp->isp_wwpn_nvram >> 60) == 2) {
- fcp->isp_wwpn_nvram |= ((uint64_t) 1 << 56);
- }
- }
-}
-
-static void
isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
{
- fcparam *fcp = FCPARAM(isp);
+ fcparam *fcp = FCPARAM(isp, 0);
uint64_t wwn;
/*
@@ -7918,7 +8278,7 @@ isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
if (wwn) {
isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
- (uint32_t) (wwn >> 32), (uint32_t) (wwn & 0xffffffff));
+ (uint32_t) (wwn >> 32), (uint32_t) (wwn));
if ((wwn >> 60) == 0) {
wwn |= (((uint64_t) 2)<< 60);
}
@@ -7929,7 +8289,7 @@ isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
if (wwn) {
isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
(uint32_t) (wwn >> 32),
- (uint32_t) (wwn & 0xffffffff));
+ (uint32_t) (wwn));
if ((wwn >> 60) == 0) {
wwn |= (((uint64_t) 2)<< 60);
}
@@ -7939,11 +8299,10 @@ isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
}
fcp->isp_wwnn_nvram = wwn;
- 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);
+ DEFAULT_FRAMESIZE(isp) =
+ 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);
@@ -7951,14 +8310,16 @@ isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
fcp->isp_loopid = ISP2100_NVRAM_HARDLOOPID(nvram_data);
}
if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
- fcp->isp_execthrottle =
+ DEFAULT_EXEC_THROTTLE(isp) =
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",
- (uint32_t) (fcp->isp_wwnn_nvram >> 32), (uint32_t) fcp->isp_wwnn_nvram,
- (uint32_t) (fcp->isp_wwpn_nvram >> 32), (uint32_t) fcp->isp_wwpn_nvram,
+ (uint32_t) (fcp->isp_wwnn_nvram >> 32),
+ (uint32_t) fcp->isp_wwnn_nvram,
+ (uint32_t) (fcp->isp_wwpn_nvram >> 32),
+ (uint32_t) fcp->isp_wwpn_nvram,
ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data),
ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data));
isp_prt(isp, ISP_LOGDEBUG0,
@@ -7977,7 +8338,7 @@ isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
static void
isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
{
- fcparam *fcp = FCPARAM(isp);
+ fcparam *fcp = FCPARAM(isp, 0);
uint64_t wwn;
isp_prt(isp, ISP_LOGDEBUG0,
@@ -8012,343 +8373,21 @@ isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
}
fcp->isp_wwnn_nvram = wwn;
- 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);
+ DEFAULT_FRAMESIZE(isp) =
+ 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 =
+ DEFAULT_EXEC_THROTTLE(isp) =
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(ispsoftc_t *);
-static void isp2300_fw_dump(ispsoftc_t *);
-
-static void
-isp2200_fw_dump(ispsoftc_t *isp)
-{
- int i, j;
- mbreg_t mbs;
- uint16_t *ptr;
-
- MEMZERO(&mbs, sizeof (mbs));
- ptr = FCPARAM(isp)->isp_dump_data;
- if (ptr == NULL) {
- isp_prt(isp, ISP_LOGERR,
- "No place to dump RISC registers and SRAM");
- return;
- }
- if (*ptr++) {
- isp_prt(isp, ISP_LOGERR,
- "dump area for RISC registers and SRAM already used");
- return;
- }
- ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
- for (i = 0; i < 100; i++) {
- USEC_DELAY(100);
- if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
- break;
- }
- }
- if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
- /*
- * PBIU Registers
- */
- for (i = 0; i < 8; i++) {
- *ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
- }
-
- /*
- * Mailbox Registers
- */
- for (i = 0; i < 8; i++) {
- *ptr++ = ISP_READ(isp, MBOX_BLOCK + (i << 1));
- }
-
- /*
- * DMA Registers
- */
- for (i = 0; i < 48; i++) {
- *ptr++ = ISP_READ(isp, DMA_BLOCK + 0x20 + (i << 1));
- }
-
- /*
- * RISC H/W Registers
- */
- ISP_WRITE(isp, BIU2100_CSR, 0);
- for (i = 0; i < 16; i++) {
- *ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
- }
-
- /*
- * RISC GP Registers
- */
- for (j = 0; j < 8; j++) {
- ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 8));
- for (i = 0; i < 16; i++) {
- *ptr++ =
- ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
- }
- }
-
- /*
- * Frame Buffer Hardware Registers
- */
- ISP_WRITE(isp, BIU2100_CSR, 0x10);
- for (i = 0; i < 16; i++) {
- *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
- }
-
- /*
- * Fibre Protocol Module 0 Hardware Registers
- */
- ISP_WRITE(isp, BIU2100_CSR, 0x20);
- for (i = 0; i < 64; i++) {
- *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
- }
-
- /*
- * Fibre Protocol Module 1 Hardware Registers
- */
- ISP_WRITE(isp, BIU2100_CSR, 0x30);
- for (i = 0; i < 64; i++) {
- *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
- }
- } else {
- isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
- return;
- }
- isp_prt(isp, ISP_LOGALL,
- "isp_fw_dump: RISC registers dumped successfully");
- ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
- for (i = 0; i < 100; i++) {
- USEC_DELAY(100);
- if (ISP_READ(isp, OUTMAILBOX0) == 0) {
- break;
- }
- }
- if (ISP_READ(isp, OUTMAILBOX0) != 0) {
- isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
- return;
- }
- ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
- for (i = 0; i < 100; i++) {
- USEC_DELAY(100);
- if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
- break;
- }
- }
- if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
- isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause After Reset");
- return;
- }
- ISP_WRITE(isp, RISC_EMB, 0xf2);
- ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
- for (i = 0; i < 100; i++) {
- USEC_DELAY(100);
- if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
- break;
- }
- }
- ISP_ENABLE_INTS(isp);
- mbs.param[0] = MBOX_READ_RAM_WORD;
- mbs.param[1] = 0x1000;
- isp->isp_mbxworkp = (void *) ptr;
- isp->isp_mbxwrk0 = 0xefff; /* continuation count */
- isp->isp_mbxwrk1 = 0x1001; /* next SRAM address */
- isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_prt(isp, ISP_LOGWARN,
- "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
- return;
- }
- ptr = isp->isp_mbxworkp; /* finish fetch of final word */
- *ptr++ = isp->isp_mboxtmp[2];
- isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped successfully");
- FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
- (void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
-}
-
-static void
-isp2300_fw_dump(ispsoftc_t *isp)
-{
- int i, j;
- mbreg_t mbs;
- uint16_t *ptr;
-
- MEMZERO(&mbs, sizeof (mbs));
- ptr = FCPARAM(isp)->isp_dump_data;
- if (ptr == NULL) {
- isp_prt(isp, ISP_LOGERR,
- "No place to dump RISC registers and SRAM");
- return;
- }
- if (*ptr++) {
- isp_prt(isp, ISP_LOGERR,
- "dump area for RISC registers and SRAM already used");
- return;
- }
- ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
- for (i = 0; i < 100; i++) {
- USEC_DELAY(100);
- if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
- break;
- }
- }
- if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
- /*
- * PBIU registers
- */
- for (i = 0; i < 8; i++) {
- *ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
- }
-
- /*
- * ReqQ-RspQ-Risc2Host Status registers
- */
- for (i = 0; i < 8; i++) {
- *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x10 + (i << 1));
- }
-
- /*
- * Mailbox Registers
- */
- for (i = 0; i < 32; i++) {
- *ptr++ =
- ISP_READ(isp, PCI_MBOX_REGS2300_OFF + (i << 1));
- }
-
- /*
- * Auto Request Response DMA registers
- */
- ISP_WRITE(isp, BIU2100_CSR, 0x40);
- for (i = 0; i < 32; i++) {
- *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
- }
-
- /*
- * DMA registers
- */
- ISP_WRITE(isp, BIU2100_CSR, 0x50);
- for (i = 0; i < 48; i++) {
- *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
- }
-
- /*
- * RISC hardware registers
- */
- ISP_WRITE(isp, BIU2100_CSR, 0);
- for (i = 0; i < 16; i++) {
- *ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
- }
-
- /*
- * RISC GP? registers
- */
- for (j = 0; j < 8; j++) {
- ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 9));
- for (i = 0; i < 16; i++) {
- *ptr++ =
- ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
- }
- }
-
- /*
- * frame buffer hardware registers
- */
- ISP_WRITE(isp, BIU2100_CSR, 0x10);
- for (i = 0; i < 64; i++) {
- *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
- }
-
- /*
- * FPM B0 hardware registers
- */
- ISP_WRITE(isp, BIU2100_CSR, 0x20);
- for (i = 0; i < 64; i++) {
- *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
- }
-
- /*
- * FPM B1 hardware registers
- */
- ISP_WRITE(isp, BIU2100_CSR, 0x30);
- for (i = 0; i < 64; i++) {
- *ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
- }
- } else {
- isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
- return;
- }
- isp_prt(isp, ISP_LOGALL,
- "isp_fw_dump: RISC registers dumped successfully");
- ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
- for (i = 0; i < 100; i++) {
- USEC_DELAY(100);
- if (ISP_READ(isp, OUTMAILBOX0) == 0) {
- break;
- }
- }
- if (ISP_READ(isp, OUTMAILBOX0) != 0) {
- isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
- return;
- }
- ISP_ENABLE_INTS(isp);
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_READ_RAM_WORD;
- mbs.param[1] = 0x800;
- isp->isp_mbxworkp = (void *) ptr;
- isp->isp_mbxwrk0 = 0xf7ff; /* continuation count */
- isp->isp_mbxwrk1 = 0x801; /* next SRAM address */
- isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_prt(isp, ISP_LOGWARN,
- "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
- return;
- }
- ptr = isp->isp_mbxworkp; /* finish fetch of final word */
- *ptr++ = isp->isp_mboxtmp[2];
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_READ_RAM_WORD_EXTENDED;
- 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,
- "RAM DUMP FAILED @ WORD %x", 0x10000 + isp->isp_mbxwrk1);
- return;
- }
- ptr = isp->isp_mbxworkp; /* finish final word */
- *ptr++ = mbs.param[2];
- isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped successfully");
- FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
- (void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
-}
-
-void
-isp_fw_dump(ispsoftc_t *isp)
-{
- if (IS_2200(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
OpenPOWER on IntegriCloud