summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/isp.c2409
-rw-r--r--sys/dev/ic/isp_inline.h180
-rw-r--r--sys/dev/ic/isp_openbsd.c446
-rw-r--r--sys/dev/ic/isp_openbsd.h409
-rw-r--r--sys/dev/ic/isp_target.c257
-rw-r--r--sys/dev/ic/isp_target.h24
-rw-r--r--sys/dev/ic/ispmbox.h59
-rw-r--r--sys/dev/ic/ispreg.h13
-rw-r--r--sys/dev/ic/ispvar.h266
9 files changed, 2217 insertions, 1846 deletions
diff --git a/sys/dev/ic/isp.c b/sys/dev/ic/isp.c
index 23e0c6af910..66c3403a77e 100644
--- a/sys/dev/ic/isp.c
+++ b/sys/dev/ic/isp.c
@@ -1,10 +1,10 @@
-/* $OpenBSD: isp.c,v 1.16 2000/07/06 05:31:48 mjacob Exp $ */
+/* $OpenBSD: isp.c,v 1.17 2000/10/16 01:01:58 mjacob Exp $ */
/*
* Machine and OS Independent (well, as best as possible)
* code for the Qlogic ISP SCSI adapters.
*
- * Copyright (c) 1997, 1998, 1999 by Matthew Jacob
- * NASA/Ames Research Center
+ * Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob
+ * Feral Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -13,10 +13,7 @@
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
+ * 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
@@ -54,6 +51,9 @@
#ifdef __linux__
#include "isp_linux.h"
#endif
+#ifdef __svr4__
+#include "isp_solaris.h"
+#endif
/*
* General defines
@@ -64,7 +64,44 @@
/*
* Local static data
*/
-
+static char *warnlun =
+ "WARNING- cannot determine Expanded LUN capability- limiting to one LUN";
+static char *portshift =
+ "Target %d Loop ID 0x%x (Port 0x%x) => Loop 0x%x (Port 0x%x)";
+static char *portdup =
+ "Target %d duplicates Target %d- killing off both";
+static char *retained =
+ "Retaining Loop ID 0x%x for Target %d (Port 0x%x)";
+#ifdef ISP2100_FABRIC
+static char *lretained =
+ "Retained login of Target %d (Loop ID 0x%x) Port 0x%x";
+static char *plogout =
+ "Logging out Target %d at Loop ID 0x%x (Port 0x%x)";
+static char *plogierr =
+ "Command Error in PLOGI for Port 0x%x (0x%x)";
+static char *nopdb =
+ "Could not get PDB for Device @ Port 0x%x";
+static char *pdbmfail1 =
+ "PDB Loop ID info for Device @ Port 0x%x does not match up (0x%x)";
+static char *pdbmfail2 =
+ "PDB Port info for Device @ Port 0x%x does not match up (0x%x)";
+static char *ldumped =
+ "Target %d (Loop ID 0x%x) Port 0x%x dumped after login info mismatch";
+#endif
+static char *notresp =
+ "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d)";
+static char *xact1 =
+ "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
+static char *xact2 =
+ "HBA attempted queued transaction to target routine %d on target %d bus %d";
+static char *xact3 =
+ "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
+static char *pskip =
+ "SCSI phase skipped for target %d.%d.%d";
+static char *topology =
+ "Loop ID %d, AL_PA 0x%x, Port ID 0x%x, Loop State 0x%x, Topology '%s'";
+static char *finmsg =
+ "(%d.%d.%d): FIN dl%d resid%d STS 0x%x SKEY %c XS_ERR=0x%x";
/*
* Local function prototypes.
*/
@@ -72,7 +109,7 @@ static int isp_parse_async __P((struct ispsoftc *, int));
static int isp_handle_other_response
__P((struct ispsoftc *, ispstatusreq_t *, u_int16_t *));
static void isp_parse_status
-__P((struct ispsoftc *, ispstatusreq_t *, ISP_SCSI_XFER_T *));
+__P((struct ispsoftc *, ispstatusreq_t *, XS_T *));
static void isp_fastpost_complete __P((struct ispsoftc *, u_int32_t));
static void isp_scsi_init __P((struct ispsoftc *));
static void isp_scsi_channel_init __P((struct ispsoftc *, int));
@@ -81,14 +118,14 @@ static void isp_mark_getpdb_all __P((struct ispsoftc *));
static int isp_getpdb __P((struct ispsoftc *, int, isp_pdb_t *));
static u_int64_t isp_get_portname __P((struct ispsoftc *, int, int));
static int isp_fclink_test __P((struct ispsoftc *, int));
+static char *isp2100_fw_statename __P((int));
static int isp_same_lportdb __P((struct lportdb *, struct lportdb *));
static int isp_pdb_sync __P((struct ispsoftc *, int));
#ifdef ISP2100_FABRIC
static int isp_scan_fabric __P((struct ispsoftc *));
#endif
static void isp_fw_state __P((struct ispsoftc *));
-static void isp_dumpregs __P((struct ispsoftc *, const char *));
-static void isp_mboxcmd __P((struct ispsoftc *, mbreg_t *));
+static void isp_mboxcmd __P((struct ispsoftc *, mbreg_t *, int));
static void isp_update __P((struct ispsoftc *));
static void isp_update_bus __P((struct ispsoftc *, int));
@@ -100,7 +137,6 @@ static void isp_parse_nvram_1080 __P((struct ispsoftc *, int, u_int8_t *));
static void isp_parse_nvram_12160 __P((struct ispsoftc *, int, u_int8_t *));
static void isp_parse_nvram_2100 __P((struct ispsoftc *, u_int8_t *));
-
/*
* Reset Hardware.
*
@@ -118,16 +154,14 @@ isp_reset(isp)
isp->isp_state = ISP_NILSTATE;
+
/*
* Basic types (SCSI, FibreChannel and PCI or SBus)
* have been set in the MD code. We figure out more
* here.
- */
- isp->isp_dblev = DFLT_DBLEVEL;
-
- /*
+ *
* After we've fired this chip up, zero out the conf1 register
- * for SCSI adapters and other settings for the 2100.
+ * for SCSI adapters and do other settings for the 2100.
*/
/*
@@ -140,19 +174,27 @@ isp_reset(isp)
*/
if ((touched = isp->isp_touched) == 0) {
/*
- * Just in case it was paused...
+ * 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.
*/
- ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
- mbs.param[0] = MBOX_ABOUT_FIRMWARE;
- isp_mboxcmd(isp, &mbs);
- /*
- * If this fails, it probably means we're running
- * an old prom, if anything at all...
- */
- 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];
+ if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 ||
+ ISP_READ(isp, OUTMAILBOX2) != 0x5020 ||
+ ISP_READ(isp, OUTMAILBOX3) != 0x2020) {
+ /*
+ * Just in case it was paused...
+ */
+ ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
+ mbs.param[0] = MBOX_ABOUT_FIRMWARE;
+ isp_mboxcmd(isp, &mbs, MBLOGNONE);
+ /*
+ * This *shouldn't* fail.....
+ */
+ 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;
}
@@ -187,7 +229,7 @@ isp_reset(isp)
* XXX: Should probably do some bus sensing.
*/
} else if (IS_ULTRA2(isp)) {
- static char *m = "%s: bus %d is in %s Mode\n";
+ static char *m = "bus %d is in %s Mode";
u_int16_t l;
sdparam *sdp = isp->isp_param;
@@ -206,19 +248,19 @@ isp_reset(isp)
switch (l) {
case ISP1080_LVD_MODE:
sdp->isp_lvdmode = 1;
- CFGPRINTF(m, isp->isp_name, 0, "LVD");
+ isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD");
break;
case ISP1080_HVD_MODE:
sdp->isp_diffmode = 1;
- CFGPRINTF(m, isp->isp_name, 0, "Differential");
+ isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential");
break;
case ISP1080_SE_MODE:
sdp->isp_ultramode = 1;
- CFGPRINTF(m, isp->isp_name, 0, "Single-Ended");
+ isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended");
break;
default:
- CFGPRINTF("%s: unknown mode on bus %d (0x%x)\n",
- isp->isp_name, 0, l);
+ isp_prt(isp, ISP_LOGERR,
+ "unknown mode on bus %d (0x%x)", 0, l);
break;
}
@@ -229,19 +271,21 @@ isp_reset(isp)
switch(l) {
case ISP1080_LVD_MODE:
sdp->isp_lvdmode = 1;
- CFGPRINTF(m, isp->isp_name, 1, "LVD");
+ isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
break;
case ISP1080_HVD_MODE:
sdp->isp_diffmode = 1;
- CFGPRINTF(m, isp->isp_name, 1, "Differential");
+ isp_prt(isp, ISP_LOGCONFIG,
+ m, 1, "Differential");
break;
case ISP1080_SE_MODE:
sdp->isp_ultramode = 1;
- CFGPRINTF(m, isp->isp_name, 1, "Single-Ended");
+ isp_prt(isp, ISP_LOGCONFIG,
+ m, 1, "Single-Ended");
break;
default:
- CFGPRINTF("%s: unknown mode on bus %d (0x%x)\n",
- isp->isp_name, 1, l);
+ isp_prt(isp, ISP_LOGERR,
+ "unknown mode on bus %d (0x%x)", 1, l);
break;
}
}
@@ -250,8 +294,7 @@ isp_reset(isp)
i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
switch (i) {
default:
- PRINTF("%s: unknown chip rev. 0x%x- assuming a 1020\n",
- isp->isp_name, i);
+ isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
/* FALLTHROUGH */
case 1:
revname = "1020";
@@ -294,7 +337,7 @@ isp_reset(isp)
* and/or differential mode.
*/
if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
- CFGPRINTF("%s: Differential Mode\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGCONFIG, "Differential Mode");
sdp->isp_diffmode = 1;
} else {
sdp->isp_diffmode = 0;
@@ -306,7 +349,7 @@ isp_reset(isp)
i &= RISC_PSR_PCI_ULTRA;
}
if (i != 0) {
- CFGPRINTF("%s: Ultra Mode Capable\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable");
sdp->isp_ultramode = 1;
/*
* If we're in Ultra Mode, we have to be 60Mhz clock-
@@ -349,15 +392,7 @@ again:
/*
* A slight delay...
*/
- SYS_DELAY(100);
-
-#if 0
- PRINTF("%s: mbox0-5: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
- isp->isp_name, ISP_READ(isp, OUTMAILBOX0),
- ISP_READ(isp, OUTMAILBOX1), ISP_READ(isp, OUTMAILBOX2),
- ISP_READ(isp, OUTMAILBOX3), ISP_READ(isp, OUTMAILBOX4),
- ISP_READ(isp, OUTMAILBOX5));
-#endif
+ USEC_DELAY(100);
/*
* Clear data && control DMA engines.
@@ -373,7 +408,7 @@ again:
/*
* A slight delay...
*/
- SYS_DELAY(100);
+ USEC_DELAY(100);
/*
* Clear data && control DMA engines.
@@ -398,9 +433,9 @@ again:
if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
break;
}
- SYS_DELAY(100);
+ USEC_DELAY(100);
if (--loops < 0) {
- isp_dumpregs(isp, "chip reset timed out");
+ ISP_DUMPREGS(isp, "chip reset timed out");
return;
}
}
@@ -420,7 +455,7 @@ again:
* Reset RISC Processor
*/
ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
- SYS_DELAY(100);
+ USEC_DELAY(100);
/*
* Establish some initial burst rate stuff.
@@ -472,10 +507,10 @@ again:
*/
loops = MBOX_DELAY_COUNT;
while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
- SYS_DELAY(100);
+ USEC_DELAY(100);
if (--loops < 0) {
- PRINTF("%s: MBOX_BUSY never cleared on reset\n",
- isp->isp_name);
+ isp_prt(isp, ISP_LOGERR,
+ "MBOX_BUSY never cleared on reset");
return;
}
}
@@ -490,9 +525,8 @@ again:
* Do some sanity checking.
*/
mbs.param[0] = MBOX_NO_OP;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_dumpregs(isp, "NOP test failed");
return;
}
@@ -503,16 +537,17 @@ again:
mbs.param[3] = 0xffff;
mbs.param[4] = 0x1111;
mbs.param[5] = 0xa5a5;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_dumpregs(isp,
- "Mailbox Register test didn't complete");
return;
}
if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
mbs.param[5] != 0xa5a5) {
- isp_dumpregs(isp, "Register Test Failed");
+ 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;
}
@@ -533,17 +568,15 @@ again:
}
if (dodnld) {
- u_int16_t fwlen = isp->isp_mdvec->dv_fwlen;
- if (fwlen == 0)
- fwlen = isp->isp_mdvec->dv_ispfw[3]; /* usually here */
+ u_int16_t fwlen = isp->isp_mdvec->dv_ispfw[3];
for (i = 0; i < fwlen; i++) {
mbs.param[0] = MBOX_WRITE_RAM_WORD;
- mbs.param[1] = isp->isp_mdvec->dv_codeorg + i;
+ mbs.param[1] = ISP_CODE_ORG + i;
mbs.param[2] = isp->isp_mdvec->dv_ispfw[i];
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGNONE);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: F/W download failed at word %d\n",
- isp->isp_name, i);
+ isp_prt(isp, ISP_LOGERR,
+ "F/W download failed at word %d", i);
dodnld = 0;
goto again;
}
@@ -553,14 +586,16 @@ again:
* Verify that it downloaded correctly.
*/
mbs.param[0] = MBOX_VERIFY_CHECKSUM;
- mbs.param[1] = isp->isp_mdvec->dv_codeorg;
- isp_mboxcmd(isp, &mbs);
+ mbs.param[1] = ISP_CODE_ORG;
+ isp_mboxcmd(isp, &mbs, MBLOGNONE);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_dumpregs(isp, "ram checksum failure");
+ isp_prt(isp, ISP_LOGERR, "Ram Checksum Failure");
return;
}
+ isp->isp_loaded_fw = 1;
} else {
- IDPRINTF(3, ("%s: skipping f/w download\n", isp->isp_name));
+ isp->isp_loaded_fw = 0;
+ isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
}
/*
@@ -571,13 +606,10 @@ again:
*/
mbs.param[0] = MBOX_EXEC_FIRMWARE;
- if (isp->isp_mdvec->dv_codeorg)
- mbs.param[1] = isp->isp_mdvec->dv_codeorg;
- else
- mbs.param[1] = 0x1000;
- isp_mboxcmd(isp, &mbs);
+ mbs.param[1] = ISP_CODE_ORG;
+ isp_mboxcmd(isp, &mbs, MBLOGNONE);
/* give it a chance to start */
- SYS_DELAY(500);
+ USEC_DELAY(500);
if (IS_SCSI(isp)) {
/*
@@ -586,26 +618,24 @@ again:
if (isp->isp_clock) {
mbs.param[0] = MBOX_SET_CLOCK_RATE;
mbs.param[1] = isp->isp_clock;
- isp_mboxcmd(isp, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("failed to set clockrate (0x%x)\n",
- mbs.param[0]);
- /* but continue */
- }
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
+ /* we will try not to care if this fails */
}
}
+
mbs.param[0] = MBOX_ABOUT_FIRMWARE;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("could not get f/w started (0x%x)\n", mbs.param[0]);
return;
}
- CFGPRINTF("%s: Board Revision %s, %s F/W Revision %d.%d.%d\n",
- isp->isp_name, revname, dodnld? "loaded" : "resident",
- mbs.param[1], mbs.param[2], mbs.param[3]);
+ isp_prt(isp, ISP_LOGCONFIG,
+ "Board Revision %s, %s F/W Revision %d.%d.%d", revname,
+ dodnld? "loaded" : "resident", mbs.param[1], mbs.param[2],
+ mbs.param[3]);
if (IS_FC(isp)) {
if (ISP_READ(isp, BIU2100_CSR) & BIU2100_PCI64) {
- CFGPRINTF("%s: in 64-Bit PCI slot\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGCONFIG,
+ "Installed in 64-Bit PCI slot");
}
}
@@ -614,27 +644,26 @@ again:
isp->isp_fwrev[2] = mbs.param[3];
if (isp->isp_romfw_rev[0] || isp->isp_romfw_rev[1] ||
isp->isp_romfw_rev[2]) {
- CFGPRINTF("%s: Last F/W revision was %d.%d.%d\n", isp->isp_name,
+ 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]);
}
mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: could not GET FIRMWARE STATUS\n", isp->isp_name);
return;
}
isp->isp_maxcmds = mbs.param[2];
- CFGPRINTF("%s: %d max I/O commands supported\n",
- isp->isp_name, mbs.param[2]);
+ isp_prt(isp, ISP_LOGINFO,
+ "%d max I/O commands supported", mbs.param[2]);
isp_fw_state(isp);
/*
* Set up DMA for the request and result mailboxes.
*/
if (ISP_MBOXDMASETUP(isp) != 0) {
- PRINTF("%s: can't setup dma mailboxes\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
return;
}
isp->isp_state = ISP_RESETSTATE;
@@ -671,9 +700,7 @@ again:
if (IS_SCSI(isp)) {
isp->isp_maxluns = 8;
} else {
- PRINTF("%s: WARNING- cannot determine Expanded "
- "LUN capability- limiting to one LUN\n",
- isp->isp_name);
+ isp_prt(isp, ISP_LOGALL, warnlun);
isp->isp_maxluns = 1;
}
}
@@ -697,7 +724,6 @@ isp_init(isp)
if (IS_DUALBUS(isp)) {
isp_setdfltparm(isp, 1);
}
-
if (IS_FC(isp)) {
isp_fibre_init(isp);
} else {
@@ -723,7 +749,7 @@ isp_scsi_init(isp)
/*
* If we have fast memory timing enabled, turn it on.
*/
- if (isp->isp_fast_mttr) {
+ if (sdp_chan0->isp_fast_mttr) {
ISP_WRITE(isp, RISC_MTR, 0x1313);
}
@@ -737,10 +763,8 @@ isp_scsi_init(isp)
mbs.param[6] = sdp_chan1->isp_retry_count;
mbs.param[7] = sdp_chan1->isp_retry_delay;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: failed to set retry count and retry delay\n",
- isp->isp_name);
return;
}
@@ -750,10 +774,8 @@ isp_scsi_init(isp)
mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
mbs.param[1] = sdp_chan0->isp_async_data_setup;
mbs.param[2] = sdp_chan1->isp_async_data_setup;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: failed to set asynchronous data setup time\n",
- isp->isp_name);
return;
}
@@ -768,10 +790,10 @@ isp_scsi_init(isp)
(sdp_chan1->isp_req_ack_active_neg << 4) |
(sdp_chan1->isp_data_line_active_neg << 5);
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGNONE);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: failed to set active negation state "
- "(%d,%d),(%d,%d)\n", isp->isp_name,
+ isp_prt(isp, ISP_LOGERR,
+ "failed to set active negation state (%d,%d), (%d,%d)",
sdp_chan0->isp_req_ack_active_neg,
sdp_chan0->isp_data_line_active_neg,
sdp_chan1->isp_req_ack_active_neg,
@@ -787,11 +809,10 @@ isp_scsi_init(isp)
mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT;
mbs.param[1] = sdp_chan0->isp_tag_aging;
mbs.param[2] = sdp_chan1->isp_tag_aging;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: failed to set tag age limit (%d,%d)\n",
- isp->isp_name, sdp_chan0->isp_tag_aging,
- sdp_chan1->isp_tag_aging);
+ isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
+ sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
return;
}
@@ -801,9 +822,8 @@ isp_scsi_init(isp)
mbs.param[0] = MBOX_SET_SELECT_TIMEOUT;
mbs.param[1] = sdp_chan0->isp_selection_timeout;
mbs.param[2] = sdp_chan1->isp_selection_timeout;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: failed to set selection timeout\n", isp->isp_name);
return;
}
@@ -817,30 +837,27 @@ isp_scsi_init(isp)
*/
mbs.param[0] = MBOX_INIT_RES_QUEUE;
- mbs.param[1] = RESULT_QUEUE_LEN;
+ mbs.param[1] = RESULT_QUEUE_LEN(isp);
mbs.param[2] = DMA_MSW(isp->isp_result_dma);
mbs.param[3] = DMA_LSW(isp->isp_result_dma);
mbs.param[4] = 0;
mbs.param[5] = 0;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: set of response queue failed\n", isp->isp_name);
return;
}
- isp->isp_residx = 0;
+ isp->isp_residx = mbs.param[5];
mbs.param[0] = MBOX_INIT_REQ_QUEUE;
- mbs.param[1] = RQUEST_QUEUE_LEN;
+ mbs.param[1] = RQUEST_QUEUE_LEN(isp);
mbs.param[2] = DMA_MSW(isp->isp_rquest_dma);
mbs.param[3] = DMA_LSW(isp->isp_rquest_dma);
mbs.param[4] = 0;
- mbs.param[5] = 0;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: set of request queue failed\n", isp->isp_name);
return;
}
- isp->isp_reqidx = isp->isp_reqodx = 0;
+ isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
/*
* Turn on Fast Posting, LVD transitions
@@ -859,13 +876,10 @@ isp_scsi_init(isp)
mbs.param[1] |= FW_FEATURE_FAST_POST;
if (mbs.param[1] != 0) {
u_int16_t sfeat = mbs.param[1];
- isp_mboxcmd(isp, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: cannot enable FW features (0x%x)\n",
- isp->isp_name, sfeat);
- } else {
- CFGPRINTF("%s: enabled FW features (0x%x)\n",
- isp->isp_name, sfeat);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
+ if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
+ isp_prt(isp, ISP_LOGINFO,
+ "Enabled FW features (0x%x)", sfeat);
}
}
@@ -892,12 +906,12 @@ isp_scsi_channel_init(isp, channel)
*/
mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
mbs.param[1] = (channel << 7) | sdp->isp_initiator_id;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: cannot set initiator id on bus %d to %d\n",
- isp->isp_name, channel, sdp->isp_initiator_id);
return;
}
+ isp_prt(isp, ISP_LOGINFO, "Initiator ID is %d", sdp->isp_initiator_id);
+
/*
* Set current per-target parameters to a safe minimum.
@@ -907,107 +921,71 @@ isp_scsi_channel_init(isp, channel)
u_int16_t sdf;
if (sdp->isp_devparam[tgt].dev_enable == 0) {
- IDPRINTF(2, ("%s: skipping target %d bus %d settings\n",
- isp->isp_name, tgt, channel));
continue;
}
-
+ sdf = DPARM_SAFE_DFLT;
/*
- * If we're in LVD mode, then we pretty much should
- * only disable tagged queuing.
+ * It is not quite clear when this changed over so that
+ * we could force narrow and async for 1000/1020 cards,
+ * but assume that this is only the case for loaded
+ * firmware.
*/
- if (IS_ULTRA2(isp) && sdp->isp_lvdmode) {
- sdf = DPARM_DEFAULT & ~DPARM_TQING;
- } else {
- int rvf = ISP_FW_REVX(isp->isp_fwrev);
- sdf = DPARM_SAFE_DFLT;
-
- /*
- * It is not quite clear when this changed over so that
- * we could force narrow and async, so assume >= 7.55
- * for i/t F/W and = 4.55 for initiator f/w.
- */
- if ((ISP_FW_REV(4, 55, 0) <= rvf &&
- (ISP_FW_REV(5, 0, 0) > rvf)) ||
- (ISP_FW_REV(7, 55, 0) <= rvf)) {
- sdf |= DPARM_NARROW | DPARM_ASYNC;
- }
+ if (isp->isp_loaded_fw) {
+ sdf |= DPARM_NARROW | DPARM_ASYNC;
}
mbs.param[0] = MBOX_SET_TARGET_PARAMS;
mbs.param[1] = (tgt << 8) | (channel << 15);
mbs.param[2] = sdf;
- mbs.param[3] =
- (sdp->isp_devparam[tgt].sync_offset << 8) |
- (sdp->isp_devparam[tgt].sync_period);
- isp_mboxcmd(isp, &mbs);
+ if ((sdf & DPARM_SYNC) == 0) {
+ mbs.param[3] = 0;
+ } else {
+ mbs.param[3] =
+ (sdp->isp_devparam[tgt].sync_offset << 8) |
+ (sdp->isp_devparam[tgt].sync_period);
+ }
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
sdf = DPARM_SAFE_DFLT;
mbs.param[0] = MBOX_SET_TARGET_PARAMS;
mbs.param[1] = (tgt << 8) | (channel << 15);
mbs.param[2] = sdf;
- mbs.param[3] =
- (sdp->isp_devparam[tgt].sync_offset << 8) |
- (sdp->isp_devparam[tgt].sync_period);
- isp_mboxcmd(isp, &mbs);
+ mbs.param[3] = 0;
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: failed even to set defaults for "
- "target %d\n", isp->isp_name, tgt);
continue;
}
}
-#if 0
- /*
- * We don't update dev_flags with what we've set
- * because that's not the ultimate goal setting.
- * If we succeed with the command, we *do* update
- * cur_dflags by getting target parameters.
- */
- mbs.param[0] = MBOX_GET_TARGET_PARAMS;
- mbs.param[1] = (tgt << 8) | (channel << 15);
- isp_mboxcmd(isp, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- /*
- * Urrr.... We'll set cur_dflags to DPARM_SAFE_DFLT so
- * we don't try and do tags if tags aren't enabled.
- */
- sdp->isp_devparam[tgt].cur_dflags = DPARM_SAFE_DFLT;
- } else {
- sdp->isp_devparam[tgt].cur_dflags = mbs.param[2];
- sdp->isp_devparam[tgt].cur_offset = mbs.param[3] >> 8;
- sdp->isp_devparam[tgt].cur_period = mbs.param[3] & 0xff;
- }
- IDPRINTF(3, ("%s: set flags 0x%x got 0x%x back for target %d\n",
- isp->isp_name, sdf, mbs.param[2], tgt));
-
-#else
- /*
- * We don't update any information because we need to run
- * at least one command per target to cause a new state
- * to be latched.
- */
-#endif
/*
+ * We don't update any information directly from the f/w
+ * because we need to run at least one command to cause a
+ * new state to be latched up. So, we just assume that we
+ * converge to the values we just had set.
+ *
* Ensure that we don't believe tagged queuing is enabled yet.
* It turns out that sometimes the ISP just ignores our
* attempts to set parameters for devices that it hasn't
* seen yet.
*/
- sdp->isp_devparam[tgt].cur_dflags &= ~DPARM_TQING;
- for (lun = 0; lun < isp->isp_maxluns; lun++) {
+ sdp->isp_devparam[tgt].cur_dflags = sdf & ~DPARM_TQING;
+ for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
mbs.param[1] = (channel << 15) | (tgt << 8) | lun;
mbs.param[2] = sdp->isp_max_queue_depth;
mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: failed to set device queue "
- "parameters for target %d, lun %d\n",
- isp->isp_name, tgt, lun);
break;
}
}
}
+ for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
+ if (sdp->isp_devparam[tgt].dev_refresh) {
+ isp->isp_sendmarker |= (1 << channel);
+ isp->isp_update |= (1 << channel);
+ break;
+ }
+ }
}
/*
@@ -1023,41 +1001,30 @@ isp_fibre_init(isp)
isp_icb_t *icbp;
mbreg_t mbs;
int loopid;
+ u_int64_t nwwn, pwwn;
fcp = isp->isp_param;
- /*
- * For systems that don't have BIOS methods for which
- * we can easily change the NVRAM based loopid, we'll
- * override that here. Note that when we initialize
- * the firmware we may get back a different loopid than
- * we asked for anyway. XXX This is probably not the
- * best way to figure this out XXX
- */
-#ifndef __i386__
loopid = DEFAULT_LOOPID(isp);
-#else
- loopid = fcp->isp_loopid;
-#endif
-
icbp = (isp_icb_t *) fcp->isp_scratch;
MEMZERO(icbp, sizeof (*icbp));
icbp->icb_version = ICB_VERSION1;
-#ifdef ISP_TARGET_MODE
- fcp->isp_fwoptions = ICBOPT_TGT_ENABLE;
-#else
- fcp->isp_fwoptions = 0;
-#endif
- fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
+
+ /*
+ * Firmware Options are either retrieved from NVRAM or
+ * are patched elsewhere. We check them for sanity here
+ * and make changes based on board revision, but otherwise
+ * let others decide policy.
+ */
+
/*
* If this is a 2100 < revision 5, we have to turn off FAIRNESS.
*/
if ((isp->isp_type == ISP_HA_FC_2100) && isp->isp_revision < 5) {
fcp->isp_fwoptions &= ~ICBOPT_FAIRNESS;
}
- fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
- fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
+
/*
* We have to use FULL LOGIN even though it resets the loop too much
* because otherwise port database entries don't get updated after
@@ -1066,11 +1033,11 @@ isp_fibre_init(isp)
if (ISP_FW_REVX(isp->isp_fwrev) < ISP_FW_REV(1, 17, 0)) {
fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
}
-#ifndef ISP_NO_FASTPOST_FC
- fcp->isp_fwoptions |= ICBOPT_FAST_POST;
-#endif
- if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
- fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
+
+ /*
+ * Insist on Port Database Update Async notifications
+ */
+ fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
/*
* We don't set ICBOPT_PORTNAME because we want our
@@ -1081,26 +1048,31 @@ isp_fibre_init(isp)
icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
- PRINTF("%s: bad frame length (%d) from NVRAM- using %d\n",
- isp->isp_name, fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN);
+ isp_prt(isp, ISP_LOGERR,
+ "bad frame length (%d) from NVRAM- using %d",
+ fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN);
icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
}
icbp->icb_maxalloc = fcp->isp_maxalloc;
if (icbp->icb_maxalloc < 1) {
- PRINTF("%s: bad maximum allocation (%d)- using 16\n",
- isp->isp_name, fcp->isp_maxalloc);
+ isp_prt(isp, ISP_LOGERR,
+ "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
icbp->icb_maxalloc = 16;
}
icbp->icb_execthrottle = fcp->isp_execthrottle;
if (icbp->icb_execthrottle < 1) {
- PRINTF("%s: bad execution throttle of %d- using 16\n",
- isp->isp_name, fcp->isp_execthrottle);
+ isp_prt(isp, ISP_LOGERR,
+ "bad execution throttle of %d- using 16",
+ fcp->isp_execthrottle);
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 = loopid;
-#ifdef PRET_A_PORTE
+ /*
+ * Right now we just set extended options to prefer point-to-point
+ * over loop based upon some soft config options.
+ */
if (IS_2200(isp)) {
icbp->icb_fwoptions |= ICBOPT_EXTENDED;
/*
@@ -1111,21 +1083,31 @@ isp_fibre_init(isp)
else
icbp->icb_xfwoptions = ICBXOPT_LOOP_2_PTP;
}
-#endif
icbp->icb_logintime = 60; /* 60 second login timeout */
- if (fcp->isp_nodewwn) {
- MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_nodewwn);
- MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_portwwn);
+ nwwn = ISP_NODEWWN(isp);
+ pwwn = ISP_PORTWWN(isp);
+ if (nwwn && pwwn) {
+ MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn);
+ MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
+ ((u_int32_t) (nwwn >> 32)),
+ ((u_int32_t) (nwwn & 0xffffffff)),
+ ((u_int32_t) (pwwn >> 32)),
+ ((u_int32_t) (pwwn & 0xffffffff)));
} else {
+ isp_prt(isp, ISP_LOGDEBUG1, "Not using any WWNs");
fcp->isp_fwoptions &= ~(ICBOPT_USE_PORTNAME|ICBOPT_FULL_LOGIN);
}
- icbp->icb_rqstqlen = RQUEST_QUEUE_LEN;
- icbp->icb_rsltqlen = RESULT_QUEUE_LEN;
+ icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
+ icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_LSW(isp->isp_rquest_dma);
icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_MSW(isp->isp_rquest_dma);
icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_LSW(isp->isp_result_dma);
icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_MSW(isp->isp_result_dma);
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "isp_fibre_init: fwoptions 0x%x", fcp->isp_fwoptions);
ISP_SWIZZLE_ICB(isp, icbp);
/*
@@ -1135,29 +1117,18 @@ isp_fibre_init(isp)
fcp->isp_fwstate = FW_CONFIG_WAIT;
fcp->isp_loopstate = LOOP_NIL;
- MemoryBarrier();
- for (;;) {
- mbs.param[0] = MBOX_INIT_FIRMWARE;
- mbs.param[1] = 0;
- mbs.param[2] = DMA_MSW(fcp->isp_scdma);
- mbs.param[3] = DMA_LSW(fcp->isp_scdma);
- mbs.param[4] = 0;
- mbs.param[5] = 0;
- mbs.param[6] = 0;
- mbs.param[7] = 0;
- isp_mboxcmd(isp, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: INIT FIRMWARE failed (code 0x%x)\n",
- isp->isp_name, mbs.param[0]);
- if (mbs.param[0] & 0x8000) {
- SYS_DELAY(1000);
- continue;
- }
- return;
- }
- break;
+ mbs.param[0] = MBOX_INIT_FIRMWARE;
+ mbs.param[1] = 0;
+ mbs.param[2] = DMA_MSW(fcp->isp_scdma);
+ mbs.param[3] = DMA_LSW(fcp->isp_scdma);
+ mbs.param[4] = 0;
+ mbs.param[5] = 0;
+ mbs.param[6] = 0;
+ mbs.param[7] = 0;
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ return;
}
-
isp->isp_reqidx = isp->isp_reqodx = 0;
isp->isp_residx = 0;
isp->isp_sendmarker = 1;
@@ -1208,26 +1179,12 @@ isp_getpdb(isp, id, pdbp)
*/
mbs.param[6] = 0;
mbs.param[7] = 0;
- isp_mboxcmd(isp, &mbs);
- switch (mbs.param[0]) {
- case MBOX_COMMAND_COMPLETE:
- MemoryBarrier();
+ isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
+ if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
ISP_UNSWIZZLE_AND_COPY_PDBP(isp, pdbp, fcp->isp_scratch);
- break;
- case MBOX_HOST_INTERFACE_ERROR:
- PRINTF("%s: DMA error getting port database\n", isp->isp_name);
- return (-1);
- case MBOX_COMMAND_PARAM_ERROR:
- /* Not Logged In */
- IDPRINTF(3, ("%s: Param Error on Get Port Database for id %d\n",
- isp->isp_name, id));
- return (-1);
- default:
- PRINTF("%s: error 0x%x getting port database for ID %d\n",
- isp->isp_name, mbs.param[0], id);
- return (-1);
+ return (0);
}
- return (0);
+ return (-1);
}
static u_int64_t
@@ -1243,7 +1200,7 @@ isp_get_portname(isp, loopid, nodename)
mbs.param[1] = loopid << 8;
if (nodename)
mbs.param[1] |= 1;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
wwn =
(((u_int64_t)(mbs.param[2] & 0xff)) << 56) |
@@ -1263,9 +1220,9 @@ isp_get_portname(isp, loopid, nodename)
*/
static int
-isp_fclink_test(isp, waitdelay)
+isp_fclink_test(isp, usdelay)
struct ispsoftc *isp;
- int waitdelay;
+ int usdelay;
{
static char *toponames[] = {
"Private Loop",
@@ -1284,21 +1241,69 @@ isp_fclink_test(isp, waitdelay)
fcp = isp->isp_param;
/*
+ * XXX: Here is where we would start a 'loop dead' timeout
+ */
+
+ /*
* Wait up to N microseconds for F/W to go to a ready state.
*/
lwfs = FW_CONFIG_WAIT;
- for (count = 0; count < waitdelay; count += 100) {
+ count = 0;
+ while (count < usdelay) {
+ u_int64_t enano;
+ u_int32_t wrk;
+ NANOTIME_T hra, hrb;
+
+ GET_NANOTIME(&hra);
isp_fw_state(isp);
if (lwfs != fcp->isp_fwstate) {
- PRINTF("%s: Firmware State %s -> %s\n",
- isp->isp_name, isp2100_fw_statename((int)lwfs),
+ isp_prt(isp, ISP_LOGINFO, "Firmware State <%s->%s>",
+ isp2100_fw_statename((int)lwfs),
isp2100_fw_statename((int)fcp->isp_fwstate));
lwfs = fcp->isp_fwstate;
}
if (fcp->isp_fwstate == FW_READY) {
break;
}
- SYS_DELAY(100); /* wait 100 microseconds */
+ GET_NANOTIME(&hrb);
+
+ /*
+ * Get the elapsed time in nanoseconds.
+ * Always guaranteed to be non-zero.
+ */
+ enano = NANOTIME_SUB(&hrb, &hra);
+
+ /*
+ * If the elapsed time is less than 1 millisecond,
+ * delay a period of time up to that millisecond of
+ * waiting.
+ */
+ isp_prt(isp, ISP_LOGDEBUG3, "usec%d: 0x%lx->0x%lx enano %u",
+ count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb),
+ enano);
+
+ /*
+ * This peculiar code is an attempt to try and avoid
+ * invoking u_int64_t math support functions for some
+ * platforms where linkage is a problem.
+ */
+ if (enano < (1000 * 1000)) {
+ count += 1000;
+ enano = (1000 * 1000) - enano;
+ while (enano > (u_int64_t) 4000000000U) {
+ USEC_DELAY(4000000);
+ enano -= (u_int64_t) 4000000000U;
+ }
+ wrk = enano;
+ USEC_DELAY(wrk/1000);
+ } else {
+ while (enano > (u_int64_t) 4000000000U) {
+ count += 4000000;
+ enano -= (u_int64_t) 4000000000U;
+ }
+ wrk = enano;
+ count += (wrk / 1000);
+ }
}
/*
@@ -1312,9 +1317,8 @@ isp_fclink_test(isp, waitdelay)
* Get our Loop ID (if possible). We really need to have it.
*/
mbs.param[0] = MBOX_GET_LOOP_ID;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: GET LOOP ID failed\n", isp->isp_name);
return (-1);
}
fcp->isp_loopid = mbs.param[1];
@@ -1382,17 +1386,28 @@ isp_fclink_test(isp, waitdelay)
fcp->portdb[FL_PORT_ID].valid = 0;
}
- CFGPRINTF("%s: Loop ID %d, AL_PA 0x%x, Port ID 0x%x Loop State "
- "0x%x topology '%s'\n", isp->isp_name, fcp->isp_loopid,
- fcp->isp_alpa, fcp->isp_portid, fcp->isp_loopstate,
- toponames[fcp->isp_topo]);
+ isp_prt(isp, ISP_LOGINFO, topology, fcp->isp_loopid, fcp->isp_alpa,
+ fcp->isp_portid, fcp->isp_loopstate, toponames[fcp->isp_topo]);
return (0);
}
-/*
- * Compare two local port db entities and return 1 if they're the same, else 0.
- */
+static char *
+isp2100_fw_statename(state)
+ 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 "?????";
+ }
+}
static int
isp_same_lportdb(a, b)
@@ -1503,8 +1518,8 @@ isp_pdb_sync(isp, target)
if (lim++ < FL_PORT_ID) {
continue;
}
- PRINTF("%s: giving up on synchronizing the port "
- "database\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGWARN,
+ "giving up on synchronizing the port database");
return (-1);
}
@@ -1608,9 +1623,8 @@ isp_pdb_sync(isp, target)
* just change the actual loop ID we'd use.
*/
if (fcp->portdb[i].loopid != loopid) {
- PRINTF("%s: Target ID %d Loop 0x%x (Port 0x%x) "
- "=> Loop 0x%x (Port 0x%x) \n",
- isp->isp_name, i, fcp->portdb[i].loopid,
+ isp_prt(isp, ISP_LOGINFO, portshift, i,
+ fcp->portdb[i].loopid,
fcp->portdb[i].portid, loopid,
tport[loopid].portid);
}
@@ -1628,9 +1642,7 @@ isp_pdb_sync(isp, target)
fcp->portdb[j].port_wwn) {
continue;
}
- PRINTF("%s: Target ID %d Duplicates Target ID "
- "%d- killing off both\n",
- isp->isp_name, j, i);
+ isp_prt(isp, ISP_LOGWARN, portdup, j, i);
/*
* Invalidate the 'old' *and* 'new' ones.
* This is really harsh and not quite right,
@@ -1663,7 +1675,7 @@ isp_pdb_sync(isp, target)
}
/* "Cannot Happen" */
if (lim == FL_PORT_ID) {
- PRINTF("%s: remap overflow?\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGWARN, "Remap Overflow");
continue;
}
i = lim;
@@ -1759,10 +1771,9 @@ isp_pdb_sync(isp, target)
nwwnn == lp->node_wwn && nwwpn == lp->port_wwn &&
lp->roles == nrole) {
lp->loggedin = lp->valid = 1;
- IDPRINTF(1, ("%s: retained login of Target %d "
- "(Loop 0x%x) Port ID 0x%x\n",
- isp->isp_name, (int) (lp - fcp->portdb),
- (int) lp->loopid, lp->portid));
+ isp_prt(isp, ISP_LOGINFO, lretained,
+ (int) (lp - fcp->portdb),
+ (int) lp->loopid, lp->portid);
continue;
}
}
@@ -1775,11 +1786,10 @@ isp_pdb_sync(isp, target)
mbs.param[1] = lp->loopid << 8;
mbs.param[2] = 0;
mbs.param[3] = 0;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGNONE);
lp->loggedin = 0;
- IDPRINTF(1, ("%s: Logging out target %d at Loop ID %d "
- "(port id 0x%x)\n", isp->isp_name,
- (int) (lp - fcp->portdb), lp->loopid, lp->portid));
+ isp_prt(isp, ISP_LOGINFO, plogout,
+ (int) (lp - fcp->portdb), lp->loopid, lp->portid);
}
/*
@@ -1796,7 +1806,8 @@ isp_pdb_sync(isp, target)
/* only issue a PLOGI if not logged in */
mbs.param[1] |= 0x1;
}
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL & ~(MBOX_LOOP_ID_USED |
+ MBOX_PORT_ID_USED | MBOX_COMMAND_ERROR));
switch (mbs.param[0]) {
case MBOX_LOOP_ID_USED:
/*
@@ -1812,11 +1823,9 @@ isp_pdb_sync(isp, target)
*/
if (mbs.param[1] != 0) {
loopid = mbs.param[1];
- IDPRINTF(1, ("%s: Retaining loopid 0x%x"
- " for Target %d (port id 0x%x)\n",
- isp->isp_name, loopid,
- (int) (lp - fcp->portdb),
- lp->portid));
+ isp_prt(isp, ISP_LOGINFO, retained,
+ loopid, (int) (lp - fcp->portdb),
+ lp->portid);
} else {
loopid = MAX_FC_TARG;
break;
@@ -1827,9 +1836,8 @@ isp_pdb_sync(isp, target)
lp->loopid = loopid;
break;
case MBOX_COMMAND_ERROR:
- PRINTF("%s: command error in PLOGI for port "
- " 0x%x (0x%x)\n", isp->isp_name, portid,
- mbs.param[1]);
+ isp_prt(isp, ISP_LOGINFO, plogierr,
+ portid, mbs.param[1]);
/* FALLTHROUGH */
case MBOX_ALL_IDS_USED: /* We're outta IDs */
default:
@@ -1851,22 +1859,19 @@ isp_pdb_sync(isp, target)
* Make sure we can get the approriate port information.
*/
if (isp_getpdb(isp, lp->loopid, &pdb) != 0) {
- PRINTF("%s: could not get PDB for device@port 0x%x\n",
- isp->isp_name, lp->portid);
+ isp_prt(isp, ISP_LOGWARN, nopdb, lp->portid);
goto dump_em;
}
if (pdb.pdb_loopid != lp->loopid) {
- PRINTF("%s: PDB loopid info for device@port 0x%x does "
- "not match up (0x%x)\n", isp->isp_name, lp->portid,
- pdb.pdb_loopid);
+ isp_prt(isp, ISP_LOGWARN, pdbmfail1,
+ lp->portid, pdb.pdb_loopid);
goto dump_em;
}
if (lp->portid != (u_int32_t) BITS2WORD(pdb.pdb_portid_bits)) {
- PRINTF("%s: PDB port info for device@port 0x%x does "
- "not match up (0x%x)\n", isp->isp_name, lp->portid,
- BITS2WORD(pdb.pdb_portid_bits));
+ isp_prt(isp, ISP_LOGWARN, pdbmfail2,
+ lp->portid, BITS2WORD(pdb.pdb_portid_bits));
goto dump_em;
}
@@ -1901,19 +1906,19 @@ isp_pdb_sync(isp, target)
}
dump_em:
lp->valid = 0;
- PRINTF("%s: Target %d (Loop 0x%x) Port ID 0x%x dumped after "
- "login\n", isp->isp_name, loopid, lp->loopid, lp->portid);
+ isp_prt(isp, ISP_LOGINFO,
+ ldumped, loopid, lp->loopid, lp->portid);
mbs.param[0] = MBOX_FABRIC_LOGOUT;
mbs.param[1] = lp->loopid << 8;
mbs.param[2] = 0;
mbs.param[3] = 0;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGNONE);
}
#endif
/*
* If we get here, we've for sure seen not only a valid loop
* but know what is or isn't on it, so mark this for usage
- * in ispscsicmd.
+ * in isp_start.
*/
fcp->loop_seen_once = 1;
return (0);
@@ -1953,11 +1958,8 @@ isp_scan_fabric(isp)
mbs.param[3] = DMA_LSW(fcp->isp_scdma);
mbs.param[6] = 0;
mbs.param[7] = 0;
- MemoryBarrier();
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- IDPRINTF(1, ("%s: SNS failed (0x%x)\n", isp->isp_name,
- mbs.param[0]));
return (-1);
}
ISP_UNSWIZZLE_SNS_RSP(isp, resp, SNS_GAN_RESP_SIZE >> 1);
@@ -1984,9 +1986,9 @@ isp_scan_fabric(isp)
* Start a command. Locking is assumed done in the caller.
*/
-int32_t
-ispscsicmd(xs)
- ISP_SCSI_XFER_T *xs;
+int
+isp_start(xs)
+ XS_T *xs;
{
struct ispsoftc *isp;
u_int16_t iptr, optr;
@@ -2003,7 +2005,7 @@ ispscsicmd(xs)
isp = XS_ISP(xs);
if (isp->isp_state != ISP_RUNSTATE) {
- PRINTF("%s: adapter not ready\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
XS_SETERR(xs, HBA_BOTCH);
return (CMD_COMPLETE);
}
@@ -2016,8 +2018,9 @@ ispscsicmd(xs)
*/
if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
- PRINTF("%s: unsupported cdb length (%d, CDB[0]=0x%x)\n",
- isp->isp_name, 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);
}
@@ -2067,7 +2070,10 @@ ispscsicmd(xs)
* until later.
*/
if (fcp->isp_fwstate != FW_READY) {
- if (isp_fclink_test(isp, FC_FW_READY_DELAY)) {
+ /*
+ * Give ourselves at most a 250ms delay.
+ */
+ if (isp_fclink_test(isp, 250000)) {
XS_SETERR(xs, HBA_SELTIMEOUT);
if (fcp->loop_seen_once) {
return (CMD_RQLATER);
@@ -2108,6 +2114,11 @@ ispscsicmd(xs)
}
/*
+ * XXX: Here's were we would cancel any loop_dead flag
+ * XXX: also cancel in dead_loop timeout that's running
+ */
+
+ /*
* Now check whether we should even think about pursuing this.
*/
lp = &fcp->portdb[target];
@@ -2116,8 +2127,8 @@ ispscsicmd(xs)
return (CMD_COMPLETE);
}
if ((lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) == 0) {
- IDPRINTF(3, ("%s: target %d is not a target\n",
- isp->isp_name, target));
+ isp_prt(isp, ISP_LOGDEBUG2,
+ "Target %d does not have target service", target);
XS_SETERR(xs, HBA_SELTIMEOUT);
return (CMD_COMPLETE);
}
@@ -2136,7 +2147,7 @@ ispscsicmd(xs)
}
if (isp_getrqentry(isp, &iptr, &optr, (void **) &reqp)) {
- IDPRINTF(2, ("%s: Request Queue Overflow\n", isp->isp_name));
+ isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
XS_SETERR(xs, HBA_BOTCH);
return (CMD_EAGAIN);
}
@@ -2161,12 +2172,11 @@ ispscsicmd(xs)
reqp->req_modifier = SYNC_ALL;
reqp->req_target = i << 7; /* insert bus number */
ISP_SWIZZLE_REQUEST(isp, reqp);
- MemoryBarrier();
ISP_ADD_REQUEST(isp, iptr);
if (isp_getrqentry(isp, &iptr, &optr, (void **)&reqp)) {
- IDPRINTF(2, ("%s: Request Queue Overflow+\n",
- isp->isp_name));
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "Request Queue Overflow+");
XS_SETERR(xs, HBA_BOTCH);
return (CMD_EAGAIN);
}
@@ -2196,9 +2206,13 @@ ispscsicmd(xs)
* The Qlogic drivers seem be happy not to use a tag,
* but this breaks for some devices (IBM drives).
*/
- if (XS_CANTAG(xs)) {
- t2reqp->req_flags = XS_KINDOF_TAG(xs);
+ if (XS_TAG_P(xs)) {
+ t2reqp->req_flags = XS_TAG_TYPE(xs);
} else {
+ /*
+ * If we don't know what tag to use, use HEAD OF QUEUE
+ * for Request Sense or Ordered (for safety's sake).
+ */
if (XS_CDBP(xs)[0] == 0x3) /* REQUEST SENSE */
t2reqp->req_flags = REQFLAG_HTAG;
else
@@ -2207,8 +2221,8 @@ ispscsicmd(xs)
} else {
sdparam *sdp = (sdparam *)isp->isp_param;
if ((sdp->isp_devparam[target].cur_dflags & DPARM_TQING) &&
- XS_CANTAG(xs)) {
- reqp->req_flags = XS_KINDOF_TAG(xs);
+ XS_TAG_P(xs)) {
+ reqp->req_flags = XS_TAG_TYPE(xs);
}
}
reqp->req_target = target | (XS_CHANNEL(xs) << 7);
@@ -2235,7 +2249,7 @@ ispscsicmd(xs)
reqp->req_time = 5;
}
if (isp_save_xs(isp, xs, &reqp->req_handle)) {
- IDPRINTF(2, ("%s: out of xflist pointers\n", isp->isp_name));
+ isp_prt(isp, ISP_LOGDEBUG1, "out of xflist pointers");
XS_SETERR(xs, HBA_BOTCH);
return (CMD_EAGAIN);
}
@@ -2253,10 +2267,9 @@ ispscsicmd(xs)
return (i);
}
XS_SETERR(xs, HBA_NOERROR);
- IDPRINTF(5, ("%s(%d.%d.%d): START cmd 0x%x datalen %d\n",
- isp->isp_name, XS_CHANNEL(xs), target, XS_LUN(xs),
- reqp->req_cdb[0], XS_XFRLEN(xs)));
- MemoryBarrier();
+ isp_prt(isp, ISP_LOGDEBUG2,
+ "START cmd for %d.%d.%d cmd 0x%x datalen %d",
+ XS_CHANNEL(xs), target, XS_LUN(xs), XS_CDBP(xs)[0], XS_XFRLEN(xs));
ISP_ADD_REQUEST(isp, iptr);
isp->isp_nactive++;
if (isp->isp_sendmarker)
@@ -2277,15 +2290,14 @@ isp_control(isp, ctl, arg)
ispctl_t ctl;
void *arg;
{
- ISP_SCSI_XFER_T *xs;
+ XS_T *xs;
mbreg_t mbs;
int bus, tgt;
u_int32_t handle;
switch (ctl) {
default:
- PRINTF("%s: isp_control unknown control op %x\n",
- isp->isp_name, ctl);
+ isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
break;
case ISPCTL_RESET_BUS:
@@ -2307,13 +2319,12 @@ isp_control(isp, ctl, arg)
bus = 0;
}
isp->isp_sendmarker |= (1 << bus);
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_dumpregs(isp, "isp_control SCSI bus reset failed");
break;
}
- CFGPRINTF("%s: driver initiated bus reset of bus %d\n",
- isp->isp_name, bus);
+ isp_prt(isp, ISP_LOGINFO,
+ "driver initiated bus reset of bus %d", bus);
return (0);
case ISPCTL_RESET_DEV:
@@ -2322,24 +2333,22 @@ isp_control(isp, ctl, arg)
mbs.param[0] = MBOX_ABORT_TARGET;
mbs.param[1] = (tgt << 8) | (bus << 15);
mbs.param[2] = 3; /* 'delay', in seconds */
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: isp_control MBOX_RESET_DEV failure (code "
- "%x)\n", isp->isp_name, mbs.param[0]);
break;
}
- PRINTF("%s: Target %d on Bus %d Reset Succeeded\n",
- isp->isp_name, tgt, bus);
+ isp_prt(isp, ISP_LOGINFO,
+ "Target %d on Bus %d Reset Succeeded", tgt, bus);
isp->isp_sendmarker |= (1 << bus);
return (0);
case ISPCTL_ABORT_CMD:
- xs = (ISP_SCSI_XFER_T *) arg;
+ xs = (XS_T *) arg;
tgt = XS_TGT(xs);
handle = isp_find_handle(isp, xs);
if (handle == 0) {
- PRINTF("%s: isp_control- cannot find command to abort "
- "in active list\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGWARN,
+ "cannot find handle for command to abort");
break;
}
bus = XS_CHANNEL(xs);
@@ -2359,21 +2368,15 @@ isp_control(isp, ctl, arg)
}
mbs.param[3] = handle >> 16;
mbs.param[2] = handle & 0xffff;
- isp_mboxcmd(isp, &mbs);
- switch (mbs.param[0]) {
- case MBOX_COMMAND_COMPLETE:
- IDPRINTF(1,
- ("%s: command (handle 0x%x) for %d.%d.%d aborted\n",
- isp->isp_name, handle, bus, tgt, XS_LUN(xs)));
- /* FALLTHROUGH */
- case MBOX_COMMAND_ERROR:
- break;
- default:
- PRINTF("%s: command (handle 0x%x) abort failed (%x)\n",
- isp->isp_name, handle, mbs.param[0]);
- break;
+ isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_ERROR);
+ if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
+ return (0);
}
- return (0);
+ /*
+ * XXX: Look for command in the REQUEST QUEUE. That is,
+ * XXX: It hasen't been picked up by firmware yet.
+ */
+ break;
case ISPCTL_UPDATE_PARAMS:
isp_update(isp);
@@ -2381,7 +2384,8 @@ isp_control(isp, ctl, arg)
case ISPCTL_FCLINK_TEST:
if (IS_FC(isp)) {
- return (isp_fclink_test(isp, FC_FW_READY_DELAY));
+ int usdelay = (arg)? *((int *) arg) : 250000;
+ return (isp_fclink_test(isp, usdelay));
}
break;
@@ -2390,22 +2394,46 @@ isp_control(isp, ctl, arg)
return (isp_pdb_sync(isp, -1));
}
break;
-
#ifdef ISP_TARGET_MODE
case ISPCTL_TOGGLE_TMODE:
+ {
+ int ena = *(int *)arg;
if (IS_SCSI(isp)) {
- int ena = *(int *)arg;
mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
mbs.param[1] = (ena)? ENABLE_TARGET_FLAG : 0;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: cannot %sable target mode (0x%x)\n",
- isp->isp_name, ena? "en" : "dis",
- mbs.param[0]);
break;
}
+ } else {
+ fcparam *fcp = isp->isp_param;
+ /*
+ * We assume somebody has quiesced this bus.
+ */
+ if (ena) {
+ if (fcp->isp_fwoptions & ICBOPT_TGT_ENABLE) {
+ return (0);
+ }
+ fcp->isp_fwoptions |= ICBOPT_TGT_ENABLE;
+ } else {
+ if (!(fcp->isp_fwoptions & ICBOPT_TGT_ENABLE)) {
+ return (0);
+ }
+ fcp->isp_fwoptions &= ~ICBOPT_TGT_ENABLE;
+ }
+ isp->isp_state = ISP_NILSTATE;
+ isp_reset(isp);
+ if (isp->isp_state != ISP_RESETSTATE) {
+ break;
+ }
+ isp_init(isp);
+ if (isp->isp_state != ISP_INITSTATE) {
+ break;
+ }
+ isp->isp_state = ISP_RUNSTATE;
}
return (0);
+ }
#endif
}
return (-1);
@@ -2418,12 +2446,18 @@ isp_control(isp, ctl, arg)
* and the locking will be held throughout this function.
*/
+/*
+ * Limit our stack depth by sticking with the max likely number
+ * of completions on a request queue at any one time.
+ */
+#define MAX_REQUESTQ_COMPLETIONS 32
+
int
isp_intr(arg)
void *arg;
{
- ISP_SCSI_XFER_T *complist[RESULT_QUEUE_LEN], *xs;
struct ispsoftc *isp = arg;
+ XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
u_int16_t iptr, optr, isr, sema, junk;
int i, nlooked = 0, ndone = 0;
@@ -2434,8 +2468,8 @@ isp_intr(arg)
junk = ISP_READ(isp, BIU_ISR);
} while (isr != junk && ++i < 1000);
if (isr != junk) {
- PRINTF("%s: isr unsteady (%x, %x)\n",
- isp->isp_name, isr, junk);
+ isp_prt(isp, ISP_LOGWARN,
+ "isr unsteady (%x, %x)", isr, junk);
}
i = 0;
do {
@@ -2443,14 +2477,14 @@ isp_intr(arg)
junk = ISP_READ(isp, BIU_SEMA);
} while (sema != junk && ++i < 1000);
if (sema != junk) {
- PRINTF("%s: sema unsteady (%x, %x)\n",
- isp->isp_name, sema, junk);
+ isp_prt(isp, ISP_LOGWARN,
+ "sema unsteady (%x, %x)", sema, junk);
}
} else {
isr = ISP_READ(isp, BIU_ISR);
sema = ISP_READ(isp, BIU_SEMA);
}
- IDPRINTF(5, ("%s: isp_intr isr %x sem %x\n", isp->isp_name, isr, sema));
+ isp_prt(isp, ISP_LOGDEBUG3, "isp_intr isr %x sem %x", isr, sema);
isr &= INT_PENDING_MASK(isp);
sema &= BIU_SEMA_LOCK;
if (isr == 0 && sema == 0) {
@@ -2467,8 +2501,8 @@ isp_intr(arg)
junk = ISP_READ(isp, OUTMAILBOX0);;
} while (junk != mbox && ++i < 1000);
if (mbox != junk) {
- PRINTF("%s: mailbox0 unsteady (%x, %x)\n",
- isp->isp_name, mbox, junk);
+ isp_prt(isp, ISP_LOGWARN,
+ "mailbox0 unsteady (%x, %x)", mbox, junk);
ISP_WRITE(isp, BIU_SEMA, 0);
ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
return (1);
@@ -2489,13 +2523,13 @@ isp_intr(arg)
}
MBOX_NOTIFY_COMPLETE(isp);
} else {
- PRINTF("%s: Command Mbox 0x%x\n",
- isp->isp_name, mbox);
+ isp_prt(isp, ISP_LOGWARN,
+ "Mbox Command Async (0x%x) with no waiters",
+ mbox);
}
} else {
u_int32_t fhandle = isp_parse_async(isp, (int) mbox);
- IDPRINTF(4, ("%s: Async Mbox 0x%x\n",
- isp->isp_name, mbox));
+ isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
if (fhandle > 0) {
isp_fastpost_complete(isp, fhandle);
}
@@ -2511,8 +2545,8 @@ isp_intr(arg)
* We can't be getting this now.
*/
if (isp->isp_state != ISP_RUNSTATE) {
- PRINTF("%s: interrupt (isr=%x, sema=%x) when not ready\n",
- isp->isp_name, isr, sema);
+ isp_prt(isp, ISP_LOGWARN,
+ "interrupt (isr=%x, sema=%x) when not ready", isr, sema);
ISP_WRITE(isp, INMAILBOX5, ISP_READ(isp, OUTMAILBOX5));
ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
ISP_WRITE(isp, BIU_SEMA, 0);
@@ -2533,8 +2567,8 @@ isp_intr(arg)
if (iptr != junk) {
ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
- PRINTF("%s: mailbox5 unsteady (%x, %x)\n",
- isp->isp_name, iptr, junk);
+ isp_prt(isp, ISP_LOGWARN,
+ "mailbox5 unsteady (%x, %x)", iptr, junk);
return (1);
}
} else {
@@ -2556,8 +2590,9 @@ isp_intr(arg)
* effects), but that didn't stop this from occurring.
*/
junk = ISP_READ(isp, BIU_ISR);
- IDPRINTF(2, ("%s: null intr- isr %x (%x) iptr %x optr %x\n",
- isp->isp_name, isr, junk, iptr, optr));
+ isp_prt(isp, ISP_LOGDEBUG2,
+ "bogus intr- isr %x (%x) iptr %x optr %x",
+ isr, junk, iptr, optr);
}
while (optr != iptr) {
@@ -2567,17 +2602,17 @@ isp_intr(arg)
sp = (ispstatusreq_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
oop = optr;
- optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN);
+ optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
nlooked++;
- MemoryBarrier();
/*
* Do any appropriate unswizzling of what the Qlogic f/w has
* written into memory so it makes sense to us. This is a
- * per-platform thing.
+ * per-platform thing. Also includes any memory barriers.
*/
- ISP_UNSWIZZLE_RESPONSE(isp, sp);
+ ISP_UNSWIZZLE_RESPONSE(isp, sp, oop);
if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) {
if (isp_handle_other_response(isp, sp, &optr) == 0) {
+ MEMZERO(sp, sizeof (isphdr_t));
continue;
}
/*
@@ -2586,10 +2621,9 @@ isp_intr(arg)
* not, something bad has happened.
*/
if (sp->req_header.rqs_entry_type != RQSTYPE_REQUEST) {
- PRINTF("%s: not RESPONSE in RESPONSE Queue "
- "(type 0x%x) @ idx %d (next %d)\n",
- isp->isp_name,
+ isp_prt(isp, ISP_LOGERR, notresp,
sp->req_header.rqs_entry_type, oop, optr);
+ MEMZERO(sp, sizeof (isphdr_t));
continue;
}
buddaboom = 1;
@@ -2599,44 +2633,47 @@ isp_intr(arg)
#define _RQS_OFLAGS \
~(RQSFLAG_CONTINUATION|RQSFLAG_FULL|RQSFLAG_BADHEADER|RQSFLAG_BADPACKET)
if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
- IDPRINTF(4, ("%s: continuation segment\n",
- isp->isp_name));
+ isp_prt(isp, ISP_LOGWARN,
+ "continuation segment");
ISP_WRITE(isp, INMAILBOX5, optr);
continue;
}
if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
- IDPRINTF(2, ("%s: internal queues full\n",
- isp->isp_name));
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "internal queues full");
/*
* We'll synthesize a QUEUE FULL message below.
*/
}
if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
- PRINTF("%s: bad header\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGERR, "bad header flag");
buddaboom++;
}
if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
- PRINTF("%s: bad request packet\n",
- isp->isp_name);
+ isp_prt(isp, ISP_LOGERR, "bad request packet");
buddaboom++;
}
if (sp->req_header.rqs_flags & _RQS_OFLAGS) {
- PRINTF("%s: unknown flags in response (0x%x)\n",
- isp->isp_name, sp->req_header.rqs_flags);
+ isp_prt(isp, ISP_LOGERR,
+ "unknown flags (0x%x) in response",
+ sp->req_header.rqs_flags);
buddaboom++;
}
#undef _RQS_OFLAGS
}
if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) {
- PRINTF("%s: bad request handle %d\n", isp->isp_name,
- sp->req_handle);
+ MEMZERO(sp, sizeof (isphdr_t));
+ isp_prt(isp, ISP_LOGERR,
+ "bad request handle %d", sp->req_handle);
ISP_WRITE(isp, INMAILBOX5, optr);
continue;
}
xs = isp_find_xs(isp, sp->req_handle);
if (xs == NULL) {
- PRINTF("%s: NULL xs in xflist (handle 0x%x)\n",
- isp->isp_name, sp->req_handle);
+ MEMZERO(sp, sizeof (isphdr_t));
+ isp_prt(isp, ISP_LOGERR,
+ "cannot find handle 0x%x in xflist",
+ sp->req_handle);
ISP_WRITE(isp, INMAILBOX5, optr);
continue;
}
@@ -2647,92 +2684,119 @@ isp_intr(arg)
if (buddaboom) {
XS_SETERR(xs, HBA_BOTCH);
}
- XS_STS(xs) = sp->req_scsi_status & 0xff;
- if (IS_SCSI(isp)) {
- if (sp->req_state_flags & RQSF_GOT_SENSE) {
- MEMCPY(XS_SNSP(xs), sp->req_sense_data,
- XS_SNSLEN(xs));
- XS_SNS_IS_VALID(xs);
- }
+
+ if (IS_FC(isp) && (sp->req_scsi_status & RQCS_SV)) {
/*
- * A new synchronous rate was negotiated for this
- * target. Mark state such that we'll go look up
- * that which has changed later.
+ * Fibre Channel F/W doesn't say we got status
+ * if there's Sense Data instead. I guess they
+ * think it goes w/o saying.
*/
- if (sp->req_status_flags & RQSTF_NEGOTIATION) {
- sdparam *sdp = isp->isp_param;
- sdp += XS_CHANNEL(xs);
- sdp->isp_devparam[XS_TGT(xs)].dev_refresh = 1;
- isp->isp_update |= (1 << XS_CHANNEL(xs));
- }
- } else {
- if (sp->req_scsi_status & RQCS_SV) {
- int amt = min(XS_SNSLEN(xs), sp->req_sense_len);
- MEMCPY(XS_SNSP(xs), sp->req_sense_data, amt);
- XS_SNS_IS_VALID(xs);
- sp->req_state_flags |= RQSF_GOT_SENSE;
- } else if (XS_STS(xs) == SCSI_CHECK) {
- IDPRINTF(2,
- ("%s: check condition with no sense data\n",
- isp->isp_name));
- }
+ sp->req_state_flags |= RQSF_GOT_STATUS;
}
- if (XS_NOERR(xs) && XS_STS(xs) == SCSI_BUSY) {
- XS_SETERR(xs, HBA_TGTBSY);
+ if (sp->req_state_flags & RQSF_GOT_STATUS) {
+ *XS_STSP(xs) = sp->req_scsi_status & 0xff;
}
- if (sp->req_header.rqs_entry_type == RQSTYPE_RESPONSE) {
- if (XS_NOERR(xs)) {
- if (sp->req_completion_status != RQCS_COMPLETE) {
- isp_parse_status(isp, sp, xs);
- } else {
- XS_SETERR(xs, HBA_NOERROR);
- }
+ switch (sp->req_header.rqs_entry_type) {
+ case RQSTYPE_RESPONSE:
+ XS_SET_STATE_STAT(isp, xs, sp);
+ isp_parse_status(isp, sp, xs);
+ if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) &&
+ (*XS_STSP(xs) == SCSI_BUSY)) {
+ XS_SETERR(xs, HBA_TGTBSY);
+ }
+ if (IS_SCSI(isp)) {
+ XS_RESID(xs) = sp->req_resid;
+ if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
+ (*XS_STSP(xs) == SCSI_CHECK) &&
+ (sp->req_state_flags & RQSF_GOT_SENSE)) {
+ XS_SAVE_SENSE(xs, sp);
+ }
+ /*
+ * A new synchronous rate was negotiated for
+ * this target. Mark state such that we'll go
+ * look up that which has changed later.
+ */
+ if (sp->req_status_flags & RQSTF_NEGOTIATION) {
+ int t = XS_TGT(xs);
+ sdparam *sdp = isp->isp_param;
+ sdp += XS_CHANNEL(xs);
+ sdp->isp_devparam[t].dev_refresh = 1;
+ isp->isp_update |=
+ (1 << XS_CHANNEL(xs));
+ }
+ } else {
+ if (sp->req_status_flags & RQSF_XFER_COMPLETE) {
+ XS_RESID(xs) = 0;
+ } else if (sp->req_scsi_status & RQCS_RESID) {
+ XS_RESID(xs) = sp->req_resid;
+ } else {
+ XS_RESID(xs) = 0;
+ }
+ if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
+ (*XS_STSP(xs) == SCSI_CHECK) &&
+ (sp->req_scsi_status & RQCS_SV)) {
+ XS_SAVE_SENSE(xs, sp);
+ }
}
- } else if (sp->req_header.rqs_entry_type == RQSTYPE_REQUEST) {
+ isp_prt(isp, ISP_LOGDEBUG2, "asked for %d got resid %d",
+ XS_XFRLEN(xs), sp->req_resid);
+ break;
+ case RQSTYPE_REQUEST:
if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
/*
* Force Queue Full status.
*/
- XS_STS(xs) = SCSI_QFULL;
+ *XS_STSP(xs) = SCSI_QFULL;
XS_SETERR(xs, HBA_NOERROR);
} else if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_BOTCH);
}
- } else {
- PRINTF("%s: unhandled respose queue type 0x%x\n",
- isp->isp_name, sp->req_header.rqs_entry_type);
+ XS_RESID(xs) = XS_XFRLEN(xs);
+ break;
+ default:
+ isp_prt(isp, ISP_LOGWARN,
+ "unhandled respose queue type 0x%x",
+ sp->req_header.rqs_entry_type);
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_BOTCH);
}
+ break;
}
- if (IS_SCSI(isp)) {
- XS_RESID(xs) = sp->req_resid;
- } else if (sp->req_scsi_status & RQCS_RU) {
- XS_RESID(xs) = sp->req_resid;
- IDPRINTF(4, ("%s: cnt %d rsd %d\n", isp->isp_name,
- XS_XFRLEN(xs), sp->req_resid));
- }
+
+ /*
+ * Free any dma resources. As a side effect, this may
+ * also do any cache flushing necessary for data coherence. */
if (XS_XFRLEN(xs)) {
ISP_DMAFREE(isp, xs, sp->req_handle);
}
- if ((isp->isp_dblev >= 5) ||
- (isp->isp_dblev > 2 && !XS_NOERR(xs))) {
- PRINTF("%s(%d.%d): FIN dl%d resid%d STS %x",
- isp->isp_name, XS_TGT(xs), XS_LUN(xs),
- XS_XFRLEN(xs), XS_RESID(xs), XS_STS(xs));
+
+ if (((isp->isp_dblev & (ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
+ ((isp->isp_dblev & ISP_LOGDEBUG1) && !XS_NOERR(xs))) {
+ char skey;
if (sp->req_state_flags & RQSF_GOT_SENSE) {
- PRINTF(" Skey: %x", XS_SNSKEY(xs));
- if (!(XS_IS_SNS_VALID(xs))) {
- PRINTF(" BUT NOT SET");
- }
+ skey = XS_SNSKEY(xs) & 0xf;
+ if (skey < 10)
+ skey += '0';
+ else
+ skey += 'a';
+ } else if (*XS_STSP(xs) == SCSI_CHECK) {
+ skey = '?';
+ } else {
+ skey = '.';
}
- PRINTF(" XS_ERR=0x%x\n", (unsigned int) XS_ERR(xs));
+ isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs),
+ XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), XS_RESID(xs),
+ *XS_STSP(xs), skey, XS_ERR(xs));
}
if (isp->isp_nactive > 0)
isp->isp_nactive--;
complist[ndone++] = xs; /* defer completion call until later */
+ MEMZERO(sp, sizeof (isphdr_t));
+ if (ndone == MAX_REQUESTQ_COMPLETIONS) {
+ break;
+ }
}
/*
@@ -2749,7 +2813,7 @@ isp_intr(arg)
for (i = 0; i < ndone; i++) {
xs = complist[i];
if (xs) {
- XS_CMD_DONE(xs);
+ isp_done(xs);
}
}
return (1);
@@ -2774,8 +2838,6 @@ isp_parse_async(isp, mbox)
}
switch (mbox) {
- case MBOX_COMMAND_COMPLETE: /* sometimes these show up */
- break;
case ASYNC_BUS_RESET:
isp->isp_sendmarker |= (1 << bus);
#ifdef ISP_TARGET_MODE
@@ -2785,18 +2847,18 @@ isp_parse_async(isp, mbox)
break;
case ASYNC_SYSTEM_ERROR:
mbox = ISP_READ(isp, OUTMAILBOX1);
- PRINTF("%s: Internal FW Error @ RISC Addr 0x%x\n",
- isp->isp_name, mbox);
- isp_restart(isp);
+ isp_prt(isp, ISP_LOGERR,
+ "Internal FW Error @ RISC Addr 0x%x", mbox);
+ isp_reinit(isp);
/* no point continuing after this */
return (-1);
case ASYNC_RQS_XFER_ERR:
- PRINTF("%s: Request Queue Transfer Error\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
break;
case ASYNC_RSP_XFER_ERR:
- PRINTF("%s: Response Queue Transfer Error\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
break;
case ASYNC_QWAKEUP:
@@ -2809,8 +2871,8 @@ isp_parse_async(isp, mbox)
break;
case ASYNC_TIMEOUT_RESET:
- PRINTF("%s: timeout initiated SCSI bus reset of bus %d\n",
- isp->isp_name, bus);
+ isp_prt(isp, ISP_LOGWARN,
+ "timeout initiated SCSI bus reset of bus %d\n", bus);
isp->isp_sendmarker |= (1 << bus);
#ifdef ISP_TARGET_MODE
isp_target_async(isp, bus, mbox);
@@ -2818,7 +2880,7 @@ isp_parse_async(isp, mbox)
break;
case ASYNC_DEVICE_RESET:
- PRINTF("%s: device reset on bus %d\n", isp->isp_name, bus);
+ isp_prt(isp, ISP_LOGINFO, "device reset on bus %d", bus);
isp->isp_sendmarker |= (1 << bus);
#ifdef ISP_TARGET_MODE
isp_target_async(isp, bus, mbox);
@@ -2826,50 +2888,49 @@ isp_parse_async(isp, mbox)
break;
case ASYNC_EXTMSG_UNDERRUN:
- PRINTF("%s: extended message underrun\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGWARN, "extended message underrun");
break;
case ASYNC_SCAM_INT:
- PRINTF("%s: SCAM interrupt\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
break;
case ASYNC_HUNG_SCSI:
- PRINTF("%s: stalled SCSI Bus after DATA Overrun\n",
- isp->isp_name);
+ 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:
- PRINTF("%s: SCSI Bus reset after DATA Overrun\n",
- isp->isp_name);
+ isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
break;
case ASYNC_BUS_TRANSIT:
mbox = ISP_READ(isp, OUTMAILBOX2);
switch (mbox & 0x1c00) {
case SXP_PINS_LVD_MODE:
- PRINTF("%s: Transition to LVD mode\n", isp->isp_name);
- ((sdparam *)isp->isp_param)->isp_diffmode = 0;
- ((sdparam *)isp->isp_param)->isp_ultramode = 0;
- ((sdparam *)isp->isp_param)->isp_lvdmode = 1;
+ isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
+ SDPARAM(isp)->isp_diffmode = 0;
+ SDPARAM(isp)->isp_ultramode = 0;
+ SDPARAM(isp)->isp_lvdmode = 1;
break;
case SXP_PINS_HVD_MODE:
- PRINTF("%s: Transition to Differential mode\n",
- isp->isp_name);
- ((sdparam *)isp->isp_param)->isp_diffmode = 1;
- ((sdparam *)isp->isp_param)->isp_ultramode = 0;
- ((sdparam *)isp->isp_param)->isp_lvdmode = 0;
+ isp_prt(isp, ISP_LOGINFO,
+ "Transition to Differential mode");
+ SDPARAM(isp)->isp_diffmode = 1;
+ SDPARAM(isp)->isp_ultramode = 0;
+ SDPARAM(isp)->isp_lvdmode = 0;
break;
case SXP_PINS_SE_MODE:
- PRINTF("%s: Transition to Single Ended mode\n",
- isp->isp_name);
- ((sdparam *)isp->isp_param)->isp_diffmode = 0;
- ((sdparam *)isp->isp_param)->isp_ultramode = 1;
- ((sdparam *)isp->isp_param)->isp_lvdmode = 0;
+ 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;
break;
default:
- PRINTF("%s: Transition to unknown mode 0x%x\n",
- isp->isp_name, mbox);
+ isp_prt(isp, ISP_LOGWARN,
+ "Transition to Unknown Mode 0x%x", mbox);
break;
}
/*
@@ -2882,23 +2943,32 @@ isp_parse_async(isp, mbox)
case ASYNC_CMD_CMPLT:
fast_post_handle = (ISP_READ(isp, OUTMAILBOX2) << 16) |
ISP_READ(isp, OUTMAILBOX1);
- IDPRINTF(4, ("%s: fast post completion of %u\n", isp->isp_name,
- fast_post_handle));
+ isp_prt(isp, ISP_LOGDEBUG3, "fast post completion of %u",
+ fast_post_handle);
break;
case ASYNC_CTIO_DONE:
- /* Should only occur when Fast Posting Set for 2100s */
- PRINTF("%s: CTIO done\n", isp->isp_name);
+#ifdef ISP_TARGET_MODE
+ /*
+ * Bus gets overloaded with the handle. Dual bus
+ * cards don't put bus# into the handle.
+ */
+ bus = (ISP_READ(isp, OUTMAILBOX2) << 16) |
+ ISP_READ(isp, OUTMAILBOX1);
+ isp_target_async(isp, bus, mbox);
+#else
+ isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
+#endif
break;
case ASYNC_LIP_OCCURRED:
- ((fcparam *) isp->isp_param)->isp_lipseq =
+ FCPARAM(isp)->isp_lipseq =
ISP_READ(isp, OUTMAILBOX1);
- ((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
- ((fcparam *) isp->isp_param)->isp_loopstate = LOOP_LIP_RCVD;
+ FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
+ FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
isp->isp_sendmarker = 1;
isp_mark_getpdb_all(isp);
- IDPRINTF(1, ("%s: LIP occurred\n", isp->isp_name));
+ isp_prt(isp, ISP_LOGINFO, "LIP occurred");
#ifdef ISP_TARGET_MODE
isp_target_async(isp, bus, mbox);
#endif
@@ -2906,8 +2976,8 @@ isp_parse_async(isp, mbox)
case ASYNC_LOOP_UP:
isp->isp_sendmarker = 1;
- ((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
- ((fcparam *) isp->isp_param)->isp_loopstate = LOOP_LIP_RCVD;
+ FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
+ FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
isp_mark_getpdb_all(isp);
isp_async(isp, ISPASYNC_LOOP_UP, NULL);
#ifdef ISP_TARGET_MODE
@@ -2917,8 +2987,8 @@ isp_parse_async(isp, mbox)
case ASYNC_LOOP_DOWN:
isp->isp_sendmarker = 1;
- ((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
- ((fcparam *) isp->isp_param)->isp_loopstate = LOOP_NIL;
+ FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
+ FCPARAM(isp)->isp_loopstate = LOOP_NIL;
isp_mark_getpdb_all(isp);
isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
#ifdef ISP_TARGET_MODE
@@ -2928,10 +2998,10 @@ isp_parse_async(isp, mbox)
case ASYNC_LOOP_RESET:
isp->isp_sendmarker = 1;
- ((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
- ((fcparam *) isp->isp_param)->isp_loopstate = LOOP_NIL;
+ FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
+ FCPARAM(isp)->isp_loopstate = LOOP_NIL;
isp_mark_getpdb_all(isp);
- PRINTF("%s: Loop RESET\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGINFO, "Loop RESET");
#ifdef ISP_TARGET_MODE
isp_target_async(isp, bus, mbox);
#endif
@@ -2939,9 +3009,9 @@ isp_parse_async(isp, mbox)
case ASYNC_PDB_CHANGED:
isp->isp_sendmarker = 1;
- ((fcparam *) isp->isp_param)->isp_loopstate = LOOP_PDB_RCVD;
+ FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
isp_mark_getpdb_all(isp);
- IDPRINTF(1, ("%s: Port Database Changed\n", isp->isp_name));
+ isp_prt(isp, ISP_LOGINFO, "Port Database Changed");
break;
case ASYNC_CHANGE_NOTIFY:
@@ -2949,54 +3019,52 @@ isp_parse_async(isp, mbox)
/*
* Not correct, but it will force us to rescan the loop.
*/
- ((fcparam *) isp->isp_param)->isp_loopstate = LOOP_PDB_RCVD;
+ FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
isp_async(isp, ISPASYNC_CHANGE_NOTIFY, NULL);
break;
case ASYNC_PTPMODE:
- if (((fcparam *) isp->isp_param)->isp_onfabric)
- ((fcparam *) isp->isp_param)->isp_topo = TOPO_N_PORT;
+ if (FCPARAM(isp)->isp_onfabric)
+ FCPARAM(isp)->isp_topo = TOPO_N_PORT;
else
- ((fcparam *) isp->isp_param)->isp_topo = TOPO_F_PORT;
+ FCPARAM(isp)->isp_topo = TOPO_F_PORT;
isp_mark_getpdb_all(isp);
isp->isp_sendmarker = 1;
- ((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
- ((fcparam *) isp->isp_param)->isp_loopstate = LOOP_LIP_RCVD;
+ FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
+ FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
#ifdef ISP_TARGET_MODE
isp_target_async(isp, bus, mbox);
#endif
- PRINTF("%s: Point-to-Point mode\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGINFO, "Point-to-Point mode");
break;
case ASYNC_CONNMODE:
mbox = ISP_READ(isp, OUTMAILBOX1);
switch (mbox) {
case ISP_CONN_LOOP:
- PRINTF("%s: Point-to-Point -> Loop mode\n",
- isp->isp_name);
+ isp_prt(isp, ISP_LOGINFO, "Point-to-Point->Loop mode");
break;
case ISP_CONN_PTP:
- PRINTF("%s: Loop -> Point-to-Point mode\n",
- isp->isp_name);
+ isp_prt(isp, ISP_LOGINFO, "Loop->Point-to-Point mode");
break;
case ISP_CONN_BADLIP:
- PRINTF("%s: Point-to-Point -> Loop mode (1)\n",
- isp->isp_name);
+ isp_prt(isp, ISP_LOGWARN,
+ "Point-to-Point->Loop mode (1)");
break;
case ISP_CONN_FATAL:
- PRINTF("%s: FATAL CONNECTION ERROR\n", isp->isp_name);
- isp_restart(isp);
+ isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
+ isp_reinit(isp);
/* no point continuing after this */
return (-1);
case ISP_CONN_LOOPBACK:
- PRINTF("%s: Looped Back in Point-to-Point mode\n",
- isp->isp_name);
+ isp_prt(isp, ISP_LOGWARN,
+ "Looped Back in Point-to-Point mode");
}
break;
default:
- PRINTF("%s: unknown async code 0x%x\n", isp->isp_name, mbox);
+ isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
break;
}
return (fast_post_handle);
@@ -3015,6 +3083,9 @@ isp_handle_other_response(isp, sp, optrp)
u_int16_t *optrp;
{
switch (sp->req_header.rqs_entry_type) {
+ case RQSTYPE_STATUS_CONT:
+ isp_prt(isp, ISP_LOGINFO, "Ignored Continuation Response");
+ return (0);
case RQSTYPE_ATIO:
case RQSTYPE_CTIO:
case RQSTYPE_ENABLE_LUN:
@@ -3028,11 +3099,12 @@ isp_handle_other_response(isp, sp, optrp)
#ifdef ISP_TARGET_MODE
return (isp_target_notify(isp, sp, optrp));
#else
+ optrp = optrp;
/* FALLTHROUGH */
#endif
case RQSTYPE_REQUEST:
default:
- PRINTF("%s: unhandled response type 0x%x\n", isp->isp_name,
+ isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
sp->req_header.rqs_entry_type);
return (-1);
}
@@ -3042,189 +3114,258 @@ static void
isp_parse_status(isp, sp, xs)
struct ispsoftc *isp;
ispstatusreq_t *sp;
- ISP_SCSI_XFER_T *xs;
+ XS_T *xs;
{
- switch (sp->req_completion_status) {
+ switch (sp->req_completion_status & 0xff) {
case RQCS_COMPLETE:
- XS_SETERR(xs, HBA_NOERROR);
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_NOERROR);
+ }
return;
case RQCS_INCOMPLETE:
if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
- IDPRINTF(3, ("%s: Selection Timeout for %d.%d.%d\n",
- isp->isp_name, XS_TGT(xs), XS_LUN(xs),
- XS_CHANNEL(xs)));
- XS_SETERR(xs, HBA_SELTIMEOUT);
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "Selection Timeout for %d.%d.%d",
+ XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_SELTIMEOUT);
+ }
return;
}
- PRINTF("%s: command incomplete for %d.%d.%d, state 0x%x\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
+ isp_prt(isp, ISP_LOGERR,
+ "command incomplete for %d.%d.%d, state 0x%x",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
sp->req_state_flags);
break;
case RQCS_DMA_ERROR:
- PRINTF("%s: DMA error for command on %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
break;
case RQCS_TRANSPORT_ERROR:
- PRINTF("%s: transport error for %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
- isp_prtstst(sp);
+ {
+ char buf[172];
+ buf[0] = 0;
+ STRNCAT(buf, "states=>", sizeof buf);
+ if (sp->req_state_flags & RQSF_GOT_BUS) {
+ STRNCAT(buf, " GOT_BUS", sizeof buf);
+ }
+ if (sp->req_state_flags & RQSF_GOT_TARGET) {
+ STRNCAT(buf, " GOT_TGT", sizeof buf);
+ }
+ if (sp->req_state_flags & RQSF_SENT_CDB) {
+ STRNCAT(buf, " SENT_CDB", sizeof buf);
+ }
+ if (sp->req_state_flags & RQSF_XFRD_DATA) {
+ STRNCAT(buf, " XFRD_DATA", sizeof buf);
+ }
+ if (sp->req_state_flags & RQSF_GOT_STATUS) {
+ STRNCAT(buf, " GOT_STS", sizeof buf);
+ }
+ if (sp->req_state_flags & RQSF_GOT_SENSE) {
+ STRNCAT(buf, " GOT_SNS", sizeof buf);
+ }
+ if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
+ STRNCAT(buf, " XFR_CMPLT", sizeof buf);
+ }
+ STRNCAT(buf, "\nstatus=>", sizeof buf);
+ if (sp->req_status_flags & RQSTF_DISCONNECT) {
+ STRNCAT(buf, " Disconnect", sizeof buf);
+ }
+ if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
+ STRNCAT(buf, " Sync_xfr", sizeof buf);
+ }
+ if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
+ STRNCAT(buf, " Parity", sizeof buf);
+ }
+ if (sp->req_status_flags & RQSTF_BUS_RESET) {
+ STRNCAT(buf, " Bus_Reset", sizeof buf);
+ }
+ if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
+ STRNCAT(buf, " Device_Reset", sizeof buf);
+ }
+ if (sp->req_status_flags & RQSTF_ABORTED) {
+ STRNCAT(buf, " Aborted", sizeof buf);
+ }
+ if (sp->req_status_flags & RQSTF_TIMEOUT) {
+ STRNCAT(buf, " Timeout", sizeof buf);
+ }
+ if (sp->req_status_flags & RQSTF_NEGOTIATION) {
+ STRNCAT(buf, " Negotiation", sizeof buf);
+ }
+ isp_prt(isp, ISP_LOGERR, "%s", buf);
+ isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf);
break;
-
+ }
case RQCS_RESET_OCCURRED:
- IDPRINTF(1, ("%s: bus reset destroyed command for %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)));
+ 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));
- XS_SETERR(xs, HBA_BUSRESET);
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_BUSRESET);
+ }
return;
case RQCS_ABORTED:
- PRINTF("%s: command aborted for %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ 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));
- XS_SETERR(xs, HBA_ABORTED);
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_ABORTED);
+ }
return;
case RQCS_TIMEOUT:
- IDPRINTF(2, ("%s: command timed out for %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)));
- XS_SETERR(xs, HBA_CMDTIMEOUT);
+ isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_CMDTIMEOUT);
+ }
return;
case RQCS_DATA_OVERRUN:
- if (IS_FC(isp)) {
- XS_RESID(xs) = sp->req_resid;
- break;
+ XS_RESID(xs) = sp->req_resid;
+ isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_DATAOVR);
}
- PRINTF("%s: data overrun for command on %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
- XS_SETERR(xs, HBA_DATAOVR);
return;
case RQCS_COMMAND_OVERRUN:
- PRINTF("%s: command overrun for command on %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_prt(isp, ISP_LOGERR,
+ "command overrun for command on %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
break;
case RQCS_STATUS_OVERRUN:
- PRINTF("%s: status overrun for command on %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_prt(isp, ISP_LOGERR,
+ "status overrun for command on %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
break;
case RQCS_BAD_MESSAGE:
- PRINTF("%s: msg not COMMAND COMPLETE after status %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_prt(isp, ISP_LOGERR,
+ "msg not COMMAND COMPLETE after status %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
break;
case RQCS_NO_MESSAGE_OUT:
- PRINTF("%s: No MESSAGE OUT phase after selection on %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_prt(isp, ISP_LOGERR,
+ "No MESSAGE OUT phase after selection on %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
break;
case RQCS_EXT_ID_FAILED:
- PRINTF("%s: EXTENDED IDENTIFY failed %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_prt(isp, ISP_LOGERR, "EXTENDED IDENTIFY failed %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
break;
case RQCS_IDE_MSG_FAILED:
- PRINTF("%s: INITIATOR DETECTED ERROR rejected by %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_prt(isp, ISP_LOGERR,
+ "INITIATOR DETECTED ERROR rejected by %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
break;
case RQCS_ABORT_MSG_FAILED:
- PRINTF("%s: ABORT OPERATION rejected by %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_prt(isp, ISP_LOGERR, "ABORT OPERATION rejected by %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
break;
case RQCS_REJECT_MSG_FAILED:
- PRINTF("%s: MESSAGE REJECT rejected by %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_prt(isp, ISP_LOGERR, "MESSAGE REJECT rejected by %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
break;
case RQCS_NOP_MSG_FAILED:
- PRINTF("%s: NOP rejected by %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_prt(isp, ISP_LOGERR, "NOP rejected by %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
break;
case RQCS_PARITY_ERROR_MSG_FAILED:
- PRINTF("%s: MESSAGE PARITY ERROR rejected by %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_prt(isp, ISP_LOGERR,
+ "MESSAGE PARITY ERROR rejected by %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
break;
case RQCS_DEVICE_RESET_MSG_FAILED:
- PRINTF("%s: BUS DEVICE RESET rejected by %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_prt(isp, ISP_LOGWARN,
+ "BUS DEVICE RESET rejected by %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
break;
case RQCS_ID_MSG_FAILED:
- PRINTF("%s: IDENTIFY rejected by %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_prt(isp, ISP_LOGERR, "IDENTIFY rejected by %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
break;
case RQCS_UNEXP_BUS_FREE:
- PRINTF("%s: %d.%d.%d had an unexpected bus free\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_prt(isp, ISP_LOGERR, "%d.%d.%d had an unexpected bus free",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
break;
case RQCS_DATA_UNDERRUN:
- if (IS_FC(isp)) {
- XS_RESID(xs) = sp->req_resid;
+ XS_RESID(xs) = sp->req_resid;
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_NOERROR);
}
- XS_SETERR(xs, HBA_NOERROR);
return;
case RQCS_XACT_ERR1:
- PRINTF("%s: HBA attempted queued transaction with disconnect "
- "not set for %d.%d.%d\n", isp->isp_name, XS_CHANNEL(xs),
+ isp_prt(isp, ISP_LOGERR, xact1, XS_CHANNEL(xs),
XS_TGT(xs), XS_LUN(xs));
break;
case RQCS_XACT_ERR2:
- PRINTF("%s: HBA attempted queued transaction to target "
- "routine %d on target %d, bus %d\n", isp->isp_name,
+ isp_prt(isp, ISP_LOGERR, xact2,
XS_LUN(xs), XS_TGT(xs), XS_CHANNEL(xs));
break;
case RQCS_XACT_ERR3:
- PRINTF("%s: HBA attempted queued transaction for target %d lun "
- "%d on bus %d when queueing disabled\n", isp->isp_name,
- XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
+ isp_prt(isp, ISP_LOGERR, xact3, XS_TGT(xs),
+ XS_LUN(xs), XS_CHANNEL(xs));
break;
case RQCS_BAD_ENTRY:
- PRINTF("%s: invalid IOCB entry type detected\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
break;
case RQCS_QUEUE_FULL:
- IDPRINTF(3, ("%s: internal queues full for target %d lun %d "
- "bus %d, status 0x%x\n", isp->isp_name, XS_TGT(xs),
- XS_LUN(xs), XS_CHANNEL(xs), XS_STS(xs)));
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "internal queues full for %d.%d.%d status 0x%x", XS_TGT(xs),
+ XS_LUN(xs), XS_CHANNEL(xs), *XS_STSP(xs));
/*
* If QFULL or some other status byte is set, then this
* isn't an error, per se.
*/
- if (XS_STS(xs) != 0) {
+ if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
XS_SETERR(xs, HBA_NOERROR);
return;
}
break;
case RQCS_PHASE_SKIPPED:
- PRINTF("%s: SCSI phase skipped (e.g., COMMAND COMPLETE w/o "
- "STATUS phase) for target %d lun %d bus %d\n",
- isp->isp_name, XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
+ isp_prt(isp, ISP_LOGERR, pskip,
+ XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
break;
case RQCS_ARQS_FAILED:
- PRINTF("%s: Auto Request Sense failed for %d.%d.%d\n",
- isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ isp_prt(isp, ISP_LOGERR,
+ "Auto Request Sense failed for %d.%d.%d",
+ XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_ARQFAIL);
+ }
return;
case RQCS_WIDE_FAILED:
- PRINTF("%s: Wide Negotiation failed for %d.%d.%d\n",
- isp->isp_name, XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
+ isp_prt(isp, ISP_LOGERR,
+ "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);
@@ -3232,12 +3373,15 @@ isp_parse_status(isp, sp, xs)
sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
isp->isp_update |= (1 << XS_CHANNEL(xs));
}
- XS_SETERR(xs, HBA_NOERROR);
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_NOERROR);
+ }
return;
case RQCS_SYNCXFER_FAILED:
- PRINTF("%s: SDTR Message failed for target %d.%d.%d\n",
- isp->isp_name, XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
+ isp_prt(isp, ISP_LOGERR,
+ "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;
sdp += XS_CHANNEL(xs);
@@ -3248,46 +3392,57 @@ isp_parse_status(isp, sp, xs)
break;
case RQCS_LVD_BUSERR:
- PRINTF("%s: Bad LVD condition while talking to %d.%d.%d\n",
- isp->isp_name, XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
+ isp_prt(isp, ISP_LOGERR,
+ "Bad LVD condition while talking to %d.%d.%d",
+ XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
break;
case RQCS_PORT_UNAVAILABLE:
/*
* No such port on the loop. Moral equivalent of SELTIMEO
*/
- IDPRINTF(3, ("%s: Port Unavailable for target %d\n",
- isp->isp_name, XS_TGT(xs)));
- XS_SETERR(xs, HBA_SELTIMEOUT);
+ isp_prt(isp, ISP_LOGINFO,
+ "Port Unavailable for target %d", XS_TGT(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_SELTIMEOUT);
+ }
return;
case RQCS_PORT_LOGGED_OUT:
/*
* It was there (maybe)- treat as a selection timeout.
*/
- IDPRINTF(2, ("%s: port logout for target %d\n",
- isp->isp_name, XS_TGT(xs)));
- XS_SETERR(xs, HBA_SELTIMEOUT);
+ isp_prt(isp, ISP_LOGINFO,
+ "port logout for target %d", XS_TGT(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_SELTIMEOUT);
+ }
return;
case RQCS_PORT_CHANGED:
- PRINTF("%s: port changed for target %d\n",
- isp->isp_name, XS_TGT(xs));
- XS_SETERR(xs, HBA_SELTIMEOUT);
+ isp_prt(isp, ISP_LOGWARN,
+ "port changed for target %d", XS_TGT(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_SELTIMEOUT);
+ }
return;
case RQCS_PORT_BUSY:
- PRINTF("%s: port busy for target %d\n",
- isp->isp_name, XS_TGT(xs));
- XS_SETERR(xs, HBA_TGTBSY);
+ isp_prt(isp, ISP_LOGWARN,
+ "port busy for target %d", XS_TGT(xs));
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_TGTBSY);
+ }
return;
default:
- PRINTF("%s: completion status 0x%x\n",
- isp->isp_name, sp->req_completion_status);
+ isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
+ sp->req_completion_status);
break;
}
- XS_SETERR(xs, HBA_BOTCH);
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_BOTCH);
+ }
}
static void
@@ -3295,15 +3450,15 @@ isp_fastpost_complete(isp, fph)
struct ispsoftc *isp;
u_int32_t fph;
{
- ISP_SCSI_XFER_T *xs;
+ XS_T *xs;
if (fph < 1) {
return;
}
xs = isp_find_xs(isp, fph);
if (xs == NULL) {
- PRINTF("%s: command for fast posting handle 0x%x not found\n",
- isp->isp_name, fph);
+ isp_prt(isp, ISP_LOGWARN,
+ "Command for fast post handle 0x%x not found", fph);
return;
}
isp_destroy_handle(isp, fph);
@@ -3313,14 +3468,15 @@ isp_fastpost_complete(isp, 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_STS(xs) = 0;
+ *XS_STSP(xs) = SCSI_GOOD;
if (XS_XFRLEN(xs)) {
ISP_DMAFREE(isp, xs, fph);
}
- XS_CMD_DONE(xs);
if (isp->isp_nactive)
isp->isp_nactive--;
+ isp_done(xs);
}
#define HIBYT(x) ((x) >> 0x8)
@@ -3423,6 +3579,105 @@ static u_int16_t mbpscsi[] = {
ISPOPMAP(0x01, 0x01) /* 0x5d: GET NOST DATA */
};
+#ifndef ISP_STRIPEED
+static char *scsi_mbcmd_names[] = {
+ "NO-OP",
+ "LOAD RAM",
+ "EXEC FIRMWARE",
+ "DUMP RAM",
+ "WRITE RAM WORD",
+ "READ RAM WORD",
+ "MAILBOX REG TEST",
+ "VERIFY CHECKSUM",
+ "ABOUT FIRMWARE",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "CHECK FIRMWARE",
+ NULL,
+ "INIT REQUEST QUEUE",
+ "INIT RESULT QUEUE",
+ "EXECUTE IOCB",
+ "WAKE UP",
+ "STOP FIRMWARE",
+ "ABORT",
+ "ABORT DEVICE",
+ "ABORT TARGET",
+ "BUS RESET",
+ "STOP QUEUE",
+ "START QUEUE",
+ "SINGLE STEP QUEUE",
+ "ABORT QUEUE",
+ "GET DEV QUEUE STATUS",
+ NULL,
+ "GET FIRMWARE STATUS",
+ "GET INIT SCSI ID",
+ "GET SELECT TIMEOUT",
+ "GET RETRY COUNT",
+ "GET TAG AGE LIMIT",
+ "GET CLOCK RATE",
+ "GET ACT NEG STATE",
+ "GET ASYNC DATA SETUP TIME",
+ "GET PCI PARAMS",
+ "GET TARGET PARAMS",
+ "GET DEV QUEUE PARAMS",
+ "GET RESET DELAY PARAMS",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "SET INIT SCSI ID",
+ "SET SELECT TIMEOUT",
+ "SET RETRY COUNT",
+ "SET TAG AGE LIMIT",
+ "SET CLOCK RATE",
+ "SET ACT NEG STATE",
+ "SET ASYNC DATA SETUP TIME",
+ "SET PCI CONTROL PARAMS",
+ "SET TARGET PARAMS",
+ "SET DEV QUEUE PARAMS",
+ "SET RESET DELAY PARAMS",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "RETURN BIOS BLOCK ADDR",
+ "WRITE FOUR RAM WORDS",
+ "EXEC BIOS IOCB",
+ NULL,
+ NULL,
+ "SET SYSTEM PARAMETER",
+ "GET SYSTEM PARAMETER",
+ NULL,
+ "GET SCAM CONFIGURATION",
+ "SET SCAM CONFIGURATION",
+ "SET FIRMWARE FEATURES",
+ "GET FIRMWARE FEATURES",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "LOAD RAM A64",
+ "DUMP RAM A64",
+ "INITIALIZE REQUEST QUEUE A64",
+ "INITIALIZE RESPONSE QUEUE A64",
+ "EXECUTE IOCB A64",
+ "ENABLE TARGET MODE",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "SET DATA OVERRUN RECOVERY MODE",
+ "GET DATA OVERRUN RECOVERY MODE",
+ "SET HOST DATA",
+ "GET NOST DATA",
+};
+#endif
+
static u_int16_t mbpfc[] = {
ISPOPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */
ISPOPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */
@@ -3553,11 +3808,145 @@ static u_int16_t mbpfc[] = {
ISPOPMAP(0x07, 0x01) /* 0x7e: Lun RESET */
};
+#ifndef ISP_STRIPPED
+static char *fc_mbcmd_names[] = {
+ "NO-OP",
+ "LOAD RAM",
+ "EXEC FIRMWARE",
+ "DUMP RAM",
+ "WRITE RAM WORD",
+ "READ RAM WORD",
+ "MAILBOX REG TEST",
+ "VERIFY CHECKSUM",
+ "ABOUT FIRMWARE",
+ "LOAD RAM",
+ "DUMP RAM",
+ NULL,
+ NULL,
+ NULL,
+ "CHECK FIRMWARE",
+ NULL,
+ "INIT REQUEST QUEUE",
+ "INIT RESULT QUEUE",
+ "EXECUTE IOCB",
+ "WAKE UP",
+ "STOP FIRMWARE",
+ "ABORT",
+ "ABORT DEVICE",
+ "ABORT TARGET",
+ "BUS RESET",
+ "STOP QUEUE",
+ "START QUEUE",
+ "SINGLE STEP QUEUE",
+ "ABORT QUEUE",
+ "GET DEV QUEUE STATUS",
+ NULL,
+ "GET FIRMWARE STATUS",
+ "GET LOOP ID",
+ NULL,
+ "GET RETRY COUNT",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "GET FIRMWARE OPTIONS",
+ "GET PORT QUEUE PARAMS",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "SET RETRY COUNT",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "SET FIRMWARE OPTIONS",
+ "SET PORT QUEUE PARAMS",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "LOOP PORT BYPASS",
+ "LOOP PORT ENABLE",
+ "GET RESOURCE COUNTS",
+ "REQUEST NON PARTICIPATING MODE",
+ NULL,
+ NULL,
+ NULL,
+ "GET PORT DATABASE,, ENHANCED",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "EXECUTE IOCB A64",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "INIT FIRMWARE",
+ NULL,
+ "INIT LIP",
+ "GET FC-AL POSITION MAP",
+ "GET PORT DATABASE",
+ "CLEAR ACA",
+ "TARGET RESET",
+ "CLEAR TASK SET",
+ "ABORT TASK SET",
+ "GET FW STATE",
+ "GET PORT NAME",
+ "GET LINK STATUS",
+ "INIT LIP RESET",
+ NULL,
+ "SEND SNS",
+ "FABRIC LOGIN",
+ "SEND CHANGE REQUEST",
+ "FABRIC LOGOUT",
+ "INIT LIP LOGIN",
+ NULL,
+ "LOGIN LOOP PORT",
+ "GET PORT/NODE NAME LIST",
+ "SET VENDOR ID",
+ "INITIALIZE IP MAILBOX",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "Get ID List",
+ "SEND LFA",
+ "Lun RESET"
+};
+#endif
+
static void
-isp_mboxcmd(isp, mbp)
+isp_mboxcmd(isp, mbp, logmask)
struct ispsoftc *isp;
mbreg_t *mbp;
+ int logmask;
{
+ char *cname, *xname, tname[16], mname[16];
unsigned int lim, ibits, obits, box, opcode;
u_int16_t *mcp;
@@ -3571,7 +3960,7 @@ isp_mboxcmd(isp, mbp)
if ((opcode = mbp->param[0]) >= lim) {
mbp->param[0] = MBOX_INVALID_COMMAND;
- PRINTF("%s: unknown command 0x%x\n", isp->isp_name, opcode);
+ isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
return;
}
@@ -3580,11 +3969,15 @@ isp_mboxcmd(isp, mbp)
if (ibits == 0 && obits == 0) {
mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
- PRINTF("%s: no parameters for opcode 0x%x\n", isp->isp_name,
- opcode);
+ isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
return;
}
+ /*
+ * Get exclusive usage of mailbox registers.
+ */
+ MBOX_ACQUIRE(isp);
+
for (box = 0; box < MAX_MAILBOX; box++) {
if (ibits & (1 << box)) {
ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
@@ -3605,7 +3998,7 @@ isp_mboxcmd(isp, mbp)
/*
* Give the f/w a chance to pick this up.
*/
- SYS_DELAY(250);
+ USEC_DELAY(250);
/*
@@ -3622,180 +4015,84 @@ isp_mboxcmd(isp, mbp)
}
}
+ MBOX_RELEASE(isp);
+
+ if (logmask == 0 || opcode == MBOX_EXEC_FIRMWARE) {
+ return;
+ }
+#ifdef ISP_STRIPPED
+ cname = NULL;
+#else
+ cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
+#endif
+ if (cname == NULL) {
+ SNPRINTF(cname, sizeof tname, "opcode %x", opcode);
+ }
+
/*
* Just to be chatty here...
*/
+ xname = NULL;
switch (mbp->param[0]) {
case MBOX_COMMAND_COMPLETE:
break;
case MBOX_INVALID_COMMAND:
- IDPRINTF(2, ("%s: mbox cmd %x failed with INVALID_COMMAND\n",
- isp->isp_name, opcode));
+ if (logmask & MBLOGMASK(MBOX_COMMAND_COMPLETE))
+ xname = "INVALID COMMAND";
break;
case MBOX_HOST_INTERFACE_ERROR:
- PRINTF("%s: mbox cmd %x failed with HOST_INTERFACE_ERROR\n",
- isp->isp_name, opcode);
+ if (logmask & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR))
+ xname = "HOST INTERFACE ERROR";
break;
case MBOX_TEST_FAILED:
- PRINTF("%s: mbox cmd %x failed with TEST_FAILED\n",
- isp->isp_name, opcode);
+ if (logmask & MBLOGMASK(MBOX_TEST_FAILED))
+ xname = "TEST FAILED";
break;
case MBOX_COMMAND_ERROR:
- if (opcode != MBOX_ABOUT_FIRMWARE)
- PRINTF("%s: mbox cmd %x failed with COMMAND_ERROR\n",
- isp->isp_name, opcode);
+ if (logmask & MBLOGMASK(MBOX_COMMAND_ERROR))
+ xname = "COMMAND ERROR";
break;
case MBOX_COMMAND_PARAM_ERROR:
- switch (opcode) {
- case MBOX_GET_PORT_DB:
- case MBOX_GET_PORT_NAME:
- case MBOX_GET_DEV_QUEUE_PARAMS:
- break;
- default:
- PRINTF("%s: mbox cmd %x failed with "
- "COMMAND_PARAM_ERROR\n", isp->isp_name, opcode);
- }
+ if (logmask & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR))
+ xname = "COMMAND PARAMETER ERROR";
break;
-
case MBOX_LOOP_ID_USED:
+ if (logmask & MBLOGMASK(MBOX_LOOP_ID_USED))
+ xname = "LOOP ID ALREADY IN USE";
+ break;
case MBOX_PORT_ID_USED:
+ if (logmask & MBLOGMASK(MBOX_PORT_ID_USED))
+ xname = "PORT ID ALREADY IN USE";
+ break;
case MBOX_ALL_IDS_USED:
+ if (logmask & MBLOGMASK(MBOX_ALL_IDS_USED))
+ xname = "ALL LOOP IDS IN USE";
+ break;
+ case 0: /* special case */
+ xname = "TIMEOUT";
break;
-
default:
- /*
- * The expected return of EXEC_FIRMWARE is zero.
- */
- if ((opcode == MBOX_EXEC_FIRMWARE && mbp->param[0] != 0) ||
- (opcode != MBOX_EXEC_FIRMWARE)) {
- PRINTF("%s: mbox cmd %x failed with error %x\n",
- isp->isp_name, opcode, mbp->param[0]);
- }
+ SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
+ xname = mname;
break;
}
-}
-
-void
-isp_lostcmd(isp, xs)
- struct ispsoftc *isp;
- ISP_SCSI_XFER_T *xs;
-{
- mbreg_t mbs;
-
- mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
- isp_mboxcmd(isp, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_dumpregs(isp, "couldn't GET FIRMWARE STATUS");
- return;
- }
- if (mbs.param[1]) {
- PRINTF("%s: %d commands on completion queue\n",
- isp->isp_name, mbs.param[1]);
- }
- if (XS_NULL(xs))
- return;
-
- mbs.param[0] = MBOX_GET_DEV_QUEUE_STATUS;
- mbs.param[1] = (XS_TGT(xs) << 8) | XS_LUN(xs); /* XXX: WHICH BUS? */
- isp_mboxcmd(isp, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_dumpregs(isp, "couldn't GET DEVICE QUEUE STATUS");
- return;
- }
- PRINTF("%s: lost command for target %d lun %d, %d active of %d, "
- "Queue State: %x\n", isp->isp_name, XS_TGT(xs),
- XS_LUN(xs), mbs.param[2], mbs.param[3], mbs.param[1]);
-
- isp_dumpregs(isp, "lost command");
- /*
- * XXX: Need to try and do something to recover.
- */
-}
-
-static void
-isp_dumpregs(isp, msg)
- struct ispsoftc *isp;
- const char *msg;
-{
- PRINTF("%s: %s\n", isp->isp_name, msg);
- if (IS_SCSI(isp))
- PRINTF(" biu_conf1=%x", ISP_READ(isp, BIU_CONF1));
- else
- PRINTF(" biu_csr=%x", ISP_READ(isp, BIU2100_CSR));
- PRINTF(" biu_icr=%x biu_isr=%x biu_sema=%x ", ISP_READ(isp, BIU_ICR),
- ISP_READ(isp, BIU_ISR), ISP_READ(isp, BIU_SEMA));
- PRINTF("risc_hccr=%x\n", ISP_READ(isp, HCCR));
-
-
- if (IS_SCSI(isp)) {
- ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
- PRINTF(" cdma_conf=%x cdma_sts=%x cdma_fifostat=%x\n",
- ISP_READ(isp, CDMA_CONF), ISP_READ(isp, CDMA_STATUS),
- ISP_READ(isp, CDMA_FIFO_STS));
- PRINTF(" ddma_conf=%x ddma_sts=%x ddma_fifostat=%x\n",
- ISP_READ(isp, DDMA_CONF), ISP_READ(isp, DDMA_STATUS),
- ISP_READ(isp, DDMA_FIFO_STS));
- PRINTF(" sxp_int=%x sxp_gross=%x sxp(scsi_ctrl)=%x\n",
- ISP_READ(isp, SXP_INTERRUPT),
- ISP_READ(isp, SXP_GROSS_ERR),
- ISP_READ(isp, SXP_PINS_CTRL));
- ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
- }
- PRINTF(" mbox regs: %x %x %x %x %x\n",
- ISP_READ(isp, OUTMAILBOX0), ISP_READ(isp, OUTMAILBOX1),
- ISP_READ(isp, OUTMAILBOX2), ISP_READ(isp, OUTMAILBOX3),
- ISP_READ(isp, OUTMAILBOX4));
- ISP_DUMPREGS(isp);
+ if (xname)
+ isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
+ cname, xname);
}
static void
isp_fw_state(isp)
struct ispsoftc *isp;
{
- mbreg_t mbs;
if (IS_FC(isp)) {
- int once = 0;
+ mbreg_t mbs;
fcparam *fcp = isp->isp_param;
-again:
+
mbs.param[0] = MBOX_GET_FW_STATE;
- isp_mboxcmd(isp, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- IDPRINTF(1, ("%s: isp_fw_state 0x%x\n", isp->isp_name,
- mbs.param[0]));
- switch (mbs.param[0]) {
- case ASYNC_PDB_CHANGED:
- if (once++ < 10) {
- goto again;
- }
- fcp->isp_fwstate = FW_CONFIG_WAIT;
- fcp->isp_loopstate = LOOP_PDB_RCVD;
- goto again;
- case ASYNC_LIP_OCCURRED:
- fcp->isp_lipseq = mbs.param[1];
- /* FALLTHROUGH */
- case ASYNC_LOOP_UP:
- fcp->isp_fwstate = FW_CONFIG_WAIT;
- fcp->isp_loopstate = LOOP_LIP_RCVD;
- if (once++ < 10) {
- goto again;
- }
- break;
- case ASYNC_LOOP_RESET:
- case ASYNC_LOOP_DOWN:
- fcp->isp_fwstate = FW_CONFIG_WAIT;
- fcp->isp_loopstate = LOOP_NIL;
- /* FALLTHROUGH */
- case ASYNC_CHANGE_NOTIFY:
- if (once++ < 10) {
- goto again;
- }
- break;
- }
- PRINTF("%s: GET FIRMWARE STATE failed (0x%x)\n",
- isp->isp_name, mbs.param[0]);
- return;
- }
- fcp->isp_fwstate = mbs.param[1];
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
+ if (mbs.param[0] == MBOX_COMMAND_COMPLETE)
+ fcp->isp_fwstate = mbs.param[1];
}
}
@@ -3803,13 +4100,13 @@ static void
isp_update(isp)
struct ispsoftc *isp;
{
- int bus;
+ int bus, upmask;
- for (bus = 0; isp->isp_update != 0; bus++) {
- if (isp->isp_update & (1 << bus)) {
+ for (bus = 0, upmask = isp->isp_update; upmask != 0; bus++) {
+ if (upmask & (1 << bus)) {
isp_update_bus(isp, bus);
- isp->isp_update ^= (1 << bus);
}
+ upmask &= ~(1 << bus);
}
}
@@ -3822,10 +4119,13 @@ isp_update_bus(isp, bus)
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;
@@ -3834,35 +4134,57 @@ isp_update_bus(isp, bus)
int get;
if (sdp->isp_devparam[tgt].dev_enable == 0) {
- IDPRINTF(2, ("%s: skipping target %d bus %d update\n",
- isp->isp_name, tgt, bus));
+ sdp->isp_devparam[tgt].dev_update = 0;
+ sdp->isp_devparam[tgt].dev_refresh = 0;
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "skipping target %d bus %d update", tgt, bus);
continue;
}
-
/*
* If the goal is to update the status of the device,
* take what's in dev_flags and try and set the device
* toward that. Otherwise, if we're just refreshing the
* current device state, get the current parameters.
*/
- if (sdp->isp_devparam[tgt].dev_update) {
+
+ /*
+ * Refresh overrides set
+ */
+ if (sdp->isp_devparam[tgt].dev_refresh) {
+ mbs.param[0] = MBOX_GET_TARGET_PARAMS;
+ sdp->isp_devparam[tgt].dev_refresh = 0;
+ get = 1;
+ } else if (sdp->isp_devparam[tgt].dev_update) {
mbs.param[0] = MBOX_SET_TARGET_PARAMS;
+ /*
+ * Make sure dev_flags has "Renegotiate on Error"
+ * on and "Freeze Queue on Error" off.
+ */
+ sdp->isp_devparam[tgt].dev_flags |= DPARM_RENEG;
+ sdp->isp_devparam[tgt].dev_flags &= ~DPARM_QFRZ;
+
mbs.param[2] = sdp->isp_devparam[tgt].dev_flags;
+
/*
- * Insist that PARITY must be enabled if SYNC
- * is enabled.
+ * Insist that PARITY must be enabled
+ * if SYNC or WIDE is enabled.
*/
- if (mbs.param[2] & DPARM_SYNC) {
+ if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
mbs.param[2] |= DPARM_PARITY;
}
- mbs.param[3] =
- (sdp->isp_devparam[tgt].sync_offset << 8) |
- (sdp->isp_devparam[tgt].sync_period);
- sdp->isp_devparam[tgt].dev_update = 0;
+
+ if ((mbs.param[2] & DPARM_SYNC) == 0) {
+ mbs.param[3] = 0;
+ } else {
+ mbs.param[3] =
+ (sdp->isp_devparam[tgt].sync_offset << 8) |
+ (sdp->isp_devparam[tgt].sync_period);
+ }
/*
* A command completion later that has
- * RQSTF_NEGOTIATION set will cause
- * the dev_refresh/announce cycle.
+ * RQSTF_NEGOTIATION set canl cause
+ * the dev_refresh/announce cycle also.
+ &
*
* Note: It is really important to update our current
* flags with at least the state of TAG capabilities-
@@ -3873,27 +4195,18 @@ isp_update_bus(isp, bus)
sdp->isp_devparam[tgt].cur_dflags &= ~DPARM_TQING;
sdp->isp_devparam[tgt].cur_dflags |=
(sdp->isp_devparam[tgt].dev_flags & DPARM_TQING);
+ isp_prt(isp, ISP_LOGDEBUG2,
+ "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
+ bus, tgt, mbs.param[2], mbs.param[3] >> 8,
+ mbs.param[3] & 0xff);
+ sdp->isp_devparam[tgt].dev_update = 0;
sdp->isp_devparam[tgt].dev_refresh = 1;
- IDPRINTF(3, ("%s: bus %d set tgt %d flags 0x%x off 0x%x"
- " period 0x%x\n", isp->isp_name, bus, tgt,
- mbs.param[2], mbs.param[3] >> 8,
- mbs.param[3] & 0xff));
get = 0;
- } else if (sdp->isp_devparam[tgt].dev_refresh) {
- mbs.param[0] = MBOX_GET_TARGET_PARAMS;
- sdp->isp_devparam[tgt].dev_refresh = 0;
- get = 1;
} else {
continue;
}
mbs.param[1] = (bus << 15) | (tgt << 8) ;
- isp_mboxcmd(isp, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- PRINTF("%s: failed to %cet SCSI parameters for "
- "target %d\n", isp->isp_name, (get)? 'g' : 's',
- tgt);
- continue;
- }
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (get == 0) {
isp->isp_sendmarker |= (1 << bus);
continue;
@@ -3907,6 +4220,14 @@ isp_update_bus(isp, bus)
get = (bus << 16) | tgt;
(void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get);
}
+
+ 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);
+ break;
+ }
+ }
}
static void
@@ -3927,26 +4248,37 @@ isp_setdfltparm(isp, channel)
fcp->isp_gotdparms = 1;
fcp->isp_maxfrmlen = ICB_DFLT_FRMLEN;
fcp->isp_maxalloc = ICB_DFLT_ALLOC;
- fcp->isp_execthrottle = ICB_DFLT_THROTTLE;
+ fcp->isp_execthrottle = ISP_EXEC_THROTTLE;
fcp->isp_retry_delay = ICB_DFLT_RDELAY;
fcp->isp_retry_count = ICB_DFLT_RCOUNT;
/* Platform specific.... */
fcp->isp_loopid = DEFAULT_LOOPID(isp);
- fcp->isp_nodewwn = DEFAULT_WWN(isp);
- if ((fcp->isp_nodewwn >> 60) == 2) {
- fcp->isp_nodewwn &= ~((u_int64_t) 0xfff << 48);
- fcp->isp_portwwn = fcp->isp_nodewwn |
- (((u_int64_t)(isp->isp_unit+1)) << 48);
- } else {
- fcp->isp_portwwn = fcp->isp_nodewwn;
- }
+ fcp->isp_nodewwn = DEFAULT_NODEWWN(isp);
+ fcp->isp_portwwn = DEFAULT_PORTWWN(isp);
+ fcp->isp_fwoptions = 0;
+ fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
+ fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
+ fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
+#ifndef ISP_NO_FASTPOST_FC
+ fcp->isp_fwoptions |= ICBOPT_FAST_POST;
+#endif
+ if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
+ fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
+
+ /*
+ * Make sure this is turned off now until we get
+ * extended options from NVRAM
+ */
+ fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
+
/*
* Now try and read NVRAM
*/
if ((isp->isp_confopts & (ISP_CFG_NONVRAM|ISP_CFG_OWNWWN)) ||
(isp_read_nvram(isp))) {
- PRINTF("%s: Node WWN 0x%08x%08x, Port WWN 0x%08x%08x\n",
- isp->isp_name, (u_int32_t) (fcp->isp_nodewwn >> 32),
+ isp_prt(isp, ISP_LOGINFO,
+ "Node WWN 0x%08x%08x, Port WWN 0x%08x%08x",
+ (u_int32_t) (fcp->isp_nodewwn >> 32),
(u_int32_t) (fcp->isp_nodewwn & 0xffffffff),
(u_int32_t) (fcp->isp_portwwn >> 32),
(u_int32_t) (fcp->isp_portwwn & 0xffffffff));
@@ -3982,9 +4314,8 @@ isp_setdfltparm(isp, channel)
*/
if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
mbs.param[0] = MBOX_GET_ACT_NEG_STATE;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- IDPRINTF(2, ("could not GET ACT NEG STATE\n"));
sdp->isp_req_ack_active_neg = 1;
sdp->isp_data_line_active_neg = 1;
} else {
@@ -3998,10 +4329,12 @@ isp_setdfltparm(isp, channel)
sdp->isp_data_line_active_neg = 1;
}
- IDPRINTF(3, ("%s: defaulting bus %d REQ/ACK Active Negation is %d\n",
- isp->isp_name, channel, sdp->isp_req_ack_active_neg));
- IDPRINTF(3, ("%s: defaulting bus %d DATA Active Negation is %d\n",
- isp->isp_name, channel, sdp->isp_data_line_active_neg));
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "defaulting bus %d REQ/ACK Active Negation is %d",
+ channel, sdp->isp_req_ack_active_neg);
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "defaulting bus %d DATA Active Negation is %d",
+ channel, sdp->isp_data_line_active_neg);
/*
* The trick here is to establish a default for the default (honk!)
@@ -4028,16 +4361,26 @@ isp_setdfltparm(isp, channel)
ISP_10M_SYNCPARMS >> 8;
sdp->isp_devparam[tgt].sync_period =
ISP_10M_SYNCPARMS & 0xff;
+ } else if (IS_ULTRA3(isp)) {
+ sdp->isp_devparam[tgt].sync_offset =
+ ISP_80M_SYNCPARMS >> 8;
+ sdp->isp_devparam[tgt].sync_period =
+ ISP_80M_SYNCPARMS & 0xff;
} else if (IS_ULTRA2(isp)) {
sdp->isp_devparam[tgt].sync_offset =
ISP_40M_SYNCPARMS >> 8;
sdp->isp_devparam[tgt].sync_period =
ISP_40M_SYNCPARMS & 0xff;
- } else {
+ } else if (IS_1240(isp)) {
sdp->isp_devparam[tgt].sync_offset =
ISP_20M_SYNCPARMS >> 8;
sdp->isp_devparam[tgt].sync_period =
ISP_20M_SYNCPARMS & 0xff;
+ } else {
+ sdp->isp_devparam[tgt].sync_offset =
+ ISP_20M_SYNCPARMS_1040 >> 8;
+ sdp->isp_devparam[tgt].sync_period =
+ ISP_20M_SYNCPARMS_1040 & 0xff;
}
/*
@@ -4048,7 +4391,7 @@ isp_setdfltparm(isp, channel)
mbs.param[0] = MBOX_GET_TARGET_PARAMS;
mbs.param[1] = tgt << 8;
- isp_mboxcmd(isp, &mbs);
+ isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
continue;
}
@@ -4084,11 +4427,11 @@ isp_setdfltparm(isp, channel)
ISP_10M_SYNCPARMS & 0xff;
}
}
- IDPRINTF(3, ("%s: bus %d tgt %d flags %x offset %x period %x\n",
- isp->isp_name, channel, tgt,
- sdp->isp_devparam[tgt].dev_flags,
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "Initial bus %d tgt %d flags %x offset %x period %x",
+ channel, tgt, sdp->isp_devparam[tgt].dev_flags,
sdp->isp_devparam[tgt].sync_offset,
- sdp->isp_devparam[tgt].sync_period));
+ sdp->isp_devparam[tgt].sync_period);
}
/*
@@ -4097,22 +4440,21 @@ isp_setdfltparm(isp, channel)
sdp->isp_cmd_dma_burst_enable = 1;
sdp->isp_data_dma_burst_enabl = 1;
sdp->isp_fifo_threshold = 0;
- sdp->isp_initiator_id = 7;
- /* XXXX This is probably based upon clock XXXX */
+ sdp->isp_initiator_id = DEFAULT_IID(isp);
if (isp->isp_type >= ISP_HA_SCSI_1040) {
sdp->isp_async_data_setup = 9;
} else {
sdp->isp_async_data_setup = 6;
}
sdp->isp_selection_timeout = 250;
- sdp->isp_max_queue_depth = MAXISPREQUEST;
+ sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
sdp->isp_tag_aging = 8;
sdp->isp_bus_reset_delay = 3;
sdp->isp_retry_count = 2;
sdp->isp_retry_delay = 2;
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
- sdp->isp_devparam[tgt].exc_throttle = 16;
+ sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
sdp->isp_devparam[tgt].dev_enable = 1;
}
}
@@ -4126,10 +4468,10 @@ isp_setdfltparm(isp, channel)
*/
void
-isp_restart(isp)
+isp_reinit(isp)
struct ispsoftc *isp;
{
- ISP_SCSI_XFER_T *xs;
+ XS_T *xs;
u_int32_t handle;
isp_reset(isp);
@@ -4140,11 +4482,11 @@ isp_restart(isp)
}
}
if (isp->isp_state != ISP_RUNSTATE) {
- PRINTF("%s: isp_restart cannot restart ISP\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGERR, "isp_reinit cannot restart ISP");
}
isp->isp_nactive = 0;
- for (handle = 1; handle <= (int) isp->isp_maxcmds; handle++) {
+ for (handle = 1; (int) handle <= isp->isp_maxcmds; handle++) {
xs = isp_find_xs(isp, handle);
if (xs == NULL) {
continue;
@@ -4157,7 +4499,7 @@ isp_restart(isp)
XS_RESID(xs) = 0;
}
XS_SETERR(xs, HBA_BUSRESET);
- XS_CMD_DONE(xs);
+ isp_done(xs);
}
}
@@ -4198,9 +4540,9 @@ isp_read_nvram(isp)
if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
nvram_data[2] != 'P') {
if (isp->isp_bustype != ISP_BT_SBUS) {
- PRINTF("%s: invalid NVRAM header (%x,%x,%x,%x)\n",
- isp->isp_name, nvram_data[0], nvram_data[1],
- nvram_data[2], nvram_data[3]);
+ isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
+ isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x",
+ nvram_data[0], nvram_data[1], nvram_data[2]);
}
return (-1);
}
@@ -4211,11 +4553,11 @@ isp_read_nvram(isp)
csum += nvram_data[i];
}
if (csum != 0) {
- PRINTF("%s: invalid NVRAM checksum\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
return (-1);
}
if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
- PRINTF("%s: version %d NVRAM not understood\n", isp->isp_name,
+ isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
ISP_NVRAM_VERSION(nvram_data));
return (-1);
}
@@ -4233,7 +4575,6 @@ isp_read_nvram(isp)
} else {
isp_parse_nvram_2100(isp, nvram_data);
}
- IDPRINTF(3, ("%s: NVRAM is valid\n", isp->isp_name));
return (0);
#undef nvram_data
#undef nvram_words
@@ -4249,9 +4590,9 @@ isp_rdnvram_word(isp, wo, rp)
u_int16_t bit, rqst;
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
- SYS_DELAY(2);
+ USEC_DELAY(2);
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
- SYS_DELAY(2);
+ USEC_DELAY(2);
if (IS_FC(isp)) {
wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
@@ -4277,11 +4618,11 @@ isp_rdnvram_word(isp, wo, rp)
bit = BIU_NVRAM_SELECT;
}
ISP_WRITE(isp, BIU_NVRAM, bit);
- SYS_DELAY(2);
+ USEC_DELAY(2);
ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
- SYS_DELAY(2);
+ USEC_DELAY(2);
ISP_WRITE(isp, BIU_NVRAM, bit);
- SYS_DELAY(2);
+ USEC_DELAY(2);
}
/*
* Now read the result back in (bits come back in MSB format).
@@ -4291,20 +4632,18 @@ isp_rdnvram_word(isp, wo, rp)
u_int16_t rv;
*rp <<= 1;
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
- SYS_DELAY(2);
+ USEC_DELAY(2);
rv = ISP_READ(isp, BIU_NVRAM);
if (rv & BIU_NVRAM_DATAIN) {
*rp |= 1;
}
- SYS_DELAY(2);
+ USEC_DELAY(2);
ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
- SYS_DELAY(2);
+ USEC_DELAY(2);
}
ISP_WRITE(isp, BIU_NVRAM, 0);
- SYS_DELAY(2);
-#if BYTE_ORDER == BIG_ENDIAN
- *rp = ((*rp >> 8) | ((*rp & 0xff) << 8));
-#endif
+ USEC_DELAY(2);
+ ISP_SWIZZLE_NVRAM_WORD(isp, rp);
}
static void
@@ -4313,8 +4652,6 @@ isp_parse_nvram_1020(isp, nvram_data)
u_int8_t *nvram_data;
{
int i;
- static char *tru = "true";
- static char *not = "false";
sdparam *sdp = (sdparam *) isp->isp_param;
sdp->isp_fifo_threshold =
@@ -4367,36 +4704,7 @@ isp_parse_nvram_1020(isp, nvram_data)
sdp->isp_max_queue_depth =
ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
- isp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
- if (isp->isp_dblev > 2) {
- PRINTF("%s: NVRAM values:\n", isp->isp_name);
- PRINTF(" Fifo Threshold = 0x%x\n",
- sdp->isp_fifo_threshold);
- PRINTF(" Bus Reset Delay = %d\n",
- sdp->isp_bus_reset_delay);
- PRINTF(" Retry Count = %d\n",
- sdp->isp_retry_count);
- PRINTF(" Retry Delay = %d\n",
- sdp->isp_retry_delay);
- PRINTF(" Tag Age Limit = %d\n",
- sdp->isp_tag_aging);
- PRINTF(" Selection Timeout = %d\n",
- sdp->isp_selection_timeout);
- PRINTF(" Max Queue Depth = %d\n",
- sdp->isp_max_queue_depth);
- PRINTF(" Async Data Setup = 0x%x\n",
- sdp->isp_async_data_setup);
- PRINTF(" REQ/ACK Active Negation = %s\n",
- sdp->isp_req_ack_active_neg? tru : not);
- PRINTF(" Data Line Active Negation = %s\n",
- sdp->isp_data_line_active_neg? tru : not);
- PRINTF(" Data DMA Burst Enable = %s\n",
- sdp->isp_data_dma_burst_enabl? tru : not);
- PRINTF(" Cmd DMA Burst Enable = %s\n",
- sdp->isp_cmd_dma_burst_enable? tru : not);
- PRINTF(" Fast MTTR = %s\n",
- isp->isp_fast_mttr? tru : not);
- }
+ sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
for (i = 0; i < MAX_TARGETS; i++) {
sdp->isp_devparam[i].dev_enable =
ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i);
@@ -4413,12 +4721,10 @@ isp_parse_nvram_1020(isp, nvram_data)
* be a shorter period than this.
*/
if (sdp->isp_devparam[i].sync_period < 0x19) {
- sdp->isp_devparam[i].sync_period =
- 0x19;
+ sdp->isp_devparam[i].sync_period = 0x19;
}
if (sdp->isp_devparam[i].sync_offset > 0xc) {
- sdp->isp_devparam[i].sync_offset =
- 0x0c;
+ sdp->isp_devparam[i].sync_offset = 0x0c;
}
} else {
if (sdp->isp_devparam[i].sync_offset > 0x8) {
@@ -4428,15 +4734,7 @@ isp_parse_nvram_1020(isp, nvram_data)
sdp->isp_devparam[i].dev_flags = 0;
if (ISP_NVRAM_TGT_RENEG(nvram_data, i))
sdp->isp_devparam[i].dev_flags |= DPARM_RENEG;
- if (ISP_NVRAM_TGT_QFRZ(nvram_data, i)) {
- PRINTF("%s: not supporting QFRZ option for "
- "target %d\n", isp->isp_name, i);
- }
sdp->isp_devparam[i].dev_flags |= DPARM_ARQ;
- if (ISP_NVRAM_TGT_ARQ(nvram_data, i) == 0) {
- PRINTF("%s: not disabling ARQ option for "
- "target %d\n", isp->isp_name, i);
- }
if (ISP_NVRAM_TGT_TQING(nvram_data, i))
sdp->isp_devparam[i].dev_flags |= DPARM_TQING;
if (ISP_NVRAM_TGT_SYNC(nvram_data, i))
@@ -4448,15 +4746,6 @@ isp_parse_nvram_1020(isp, nvram_data)
if (ISP_NVRAM_TGT_DISC(nvram_data, i))
sdp->isp_devparam[i].dev_flags |= DPARM_DISC;
sdp->isp_devparam[i].cur_dflags = 0; /* we don't know */
- if (isp->isp_dblev > 2) {
- PRINTF(" Target %d: Enabled %d Throttle %d "
- "Offset %d Period %d Flags 0x%x\n", i,
- sdp->isp_devparam[i].dev_enable,
- sdp->isp_devparam[i].exc_throttle,
- sdp->isp_devparam[i].sync_offset,
- sdp->isp_devparam[i].sync_period,
- sdp->isp_devparam[i].dev_flags);
- }
}
}
@@ -4466,8 +4755,6 @@ isp_parse_nvram_1080(isp, bus, nvram_data)
int bus;
u_int8_t *nvram_data;
{
- static char *tru = "true";
- static char *not = "false";
int i;
sdparam *sdp = (sdparam *) isp->isp_param;
sdp += bus;
@@ -4511,34 +4798,6 @@ isp_parse_nvram_1080(isp, bus, nvram_data)
sdp->isp_max_queue_depth =
ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
- if (isp->isp_dblev >= 3) {
- PRINTF("%s: ISP1080 bus %d NVRAM values:\n",
- isp->isp_name, bus);
- PRINTF(" Initiator ID = %d\n",
- sdp->isp_initiator_id);
- PRINTF(" Fifo Threshold = 0x%x\n",
- sdp->isp_fifo_threshold);
- PRINTF(" Bus Reset Delay = %d\n",
- sdp->isp_bus_reset_delay);
- PRINTF(" Retry Count = %d\n",
- sdp->isp_retry_count);
- PRINTF(" Retry Delay = %d\n",
- sdp->isp_retry_delay);
- PRINTF(" Tag Age Limit = %d\n",
- sdp->isp_tag_aging);
- PRINTF(" Selection Timeout = %d\n",
- sdp->isp_selection_timeout);
- PRINTF(" Max Queue Depth = %d\n",
- sdp->isp_max_queue_depth);
- PRINTF(" Async Data Setup = 0x%x\n",
- sdp->isp_async_data_setup);
- PRINTF(" REQ/ACK Active Negation = %s\n",
- sdp->isp_req_ack_active_neg? tru : not);
- PRINTF(" Data Line Active Negation = %s\n",
- sdp->isp_data_line_active_neg? tru : not);
- PRINTF(" Cmd DMA Burst Enable = %s\n",
- sdp->isp_cmd_dma_burst_enable? tru : not);
- }
for (i = 0; i < MAX_TARGETS; i++) {
sdp->isp_devparam[i].dev_enable =
ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i, bus);
@@ -4551,17 +4810,7 @@ isp_parse_nvram_1080(isp, bus, nvram_data)
sdp->isp_devparam[i].dev_flags = 0;
if (ISP1080_NVRAM_TGT_RENEG(nvram_data, i, bus))
sdp->isp_devparam[i].dev_flags |= DPARM_RENEG;
- if (ISP1080_NVRAM_TGT_QFRZ(nvram_data, i, bus)) {
- PRINTF("%s: not supporting QFRZ option "
- "for target %d bus %d\n",
- isp->isp_name, i, bus);
- }
sdp->isp_devparam[i].dev_flags |= DPARM_ARQ;
- if (ISP1080_NVRAM_TGT_ARQ(nvram_data, i, bus) == 0) {
- PRINTF("%s: not disabling ARQ option "
- "for target %d bus %d\n",
- isp->isp_name, i, bus);
- }
if (ISP1080_NVRAM_TGT_TQING(nvram_data, i, bus))
sdp->isp_devparam[i].dev_flags |= DPARM_TQING;
if (ISP1080_NVRAM_TGT_SYNC(nvram_data, i, bus))
@@ -4573,16 +4822,6 @@ isp_parse_nvram_1080(isp, bus, nvram_data)
if (ISP1080_NVRAM_TGT_DISC(nvram_data, i, bus))
sdp->isp_devparam[i].dev_flags |= DPARM_DISC;
sdp->isp_devparam[i].cur_dflags = 0;
- if (isp->isp_dblev >= 3) {
- PRINTF(" Target %d: Ena %d Throttle "
- "%d Offset %d Period %d Flags "
- "0x%x\n", i,
- sdp->isp_devparam[i].dev_enable,
- sdp->isp_devparam[i].exc_throttle,
- sdp->isp_devparam[i].sync_offset,
- sdp->isp_devparam[i].sync_period,
- sdp->isp_devparam[i].dev_flags);
- }
}
}
@@ -4592,8 +4831,6 @@ isp_parse_nvram_12160(isp, bus, nvram_data)
int bus;
u_int8_t *nvram_data;
{
- static char *tru = "true";
- static char *not = "false";
sdparam *sdp = (sdparam *) isp->isp_param;
int i;
@@ -4638,35 +4875,6 @@ isp_parse_nvram_12160(isp, bus, nvram_data)
sdp->isp_max_queue_depth =
ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
- if (isp->isp_dblev >= 3) {
- PRINTF("%s: ISP12160 bus %d NVRAM values:\n",
- isp->isp_name, bus);
- PRINTF(" Initiator ID = %d\n",
- sdp->isp_initiator_id);
- PRINTF(" Fifo Threshold = 0x%x\n",
- sdp->isp_fifo_threshold);
- PRINTF(" Bus Reset Delay = %d\n",
- sdp->isp_bus_reset_delay);
- PRINTF(" Retry Count = %d\n",
- sdp->isp_retry_count);
- PRINTF(" Retry Delay = %d\n",
- sdp->isp_retry_delay);
- PRINTF(" Tag Age Limit = %d\n",
- sdp->isp_tag_aging);
- PRINTF(" Selection Timeout = %d\n",
- sdp->isp_selection_timeout);
- PRINTF(" Max Queue Depth = %d\n",
- sdp->isp_max_queue_depth);
- PRINTF(" Async Data Setup = 0x%x\n",
- sdp->isp_async_data_setup);
- PRINTF(" REQ/ACK Active Negation = %s\n",
- sdp->isp_req_ack_active_neg? tru : not);
- PRINTF(" Data Line Active Negation = %s\n",
- sdp->isp_data_line_active_neg? tru : not);
- PRINTF(" Cmd DMA Burst Enable = %s\n",
- sdp->isp_cmd_dma_burst_enable? tru : not);
- }
-
for (i = 0; i < MAX_TARGETS; i++) {
sdp->isp_devparam[i].dev_enable =
ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i, bus);
@@ -4679,15 +4887,7 @@ isp_parse_nvram_12160(isp, bus, nvram_data)
sdp->isp_devparam[i].dev_flags = 0;
if (ISP12160_NVRAM_TGT_RENEG(nvram_data, i, bus))
sdp->isp_devparam[i].dev_flags |= DPARM_RENEG;
- if (ISP12160_NVRAM_TGT_QFRZ(nvram_data, i, bus)) {
- PRINTF("%s: not supporting QFRZ option "
- "for target %d bus %d\n", isp->isp_name, i, bus);
- }
sdp->isp_devparam[i].dev_flags |= DPARM_ARQ;
- if (ISP12160_NVRAM_TGT_ARQ(nvram_data, i, bus) == 0) {
- PRINTF("%s: not disabling ARQ option "
- "for target %d bus %d\n", isp->isp_name, i, bus);
- }
if (ISP12160_NVRAM_TGT_TQING(nvram_data, i, bus))
sdp->isp_devparam[i].dev_flags |= DPARM_TQING;
if (ISP12160_NVRAM_TGT_SYNC(nvram_data, i, bus))
@@ -4699,15 +4899,6 @@ isp_parse_nvram_12160(isp, bus, nvram_data)
if (ISP12160_NVRAM_TGT_DISC(nvram_data, i, bus))
sdp->isp_devparam[i].dev_flags |= DPARM_DISC;
sdp->isp_devparam[i].cur_dflags = 0;
- if (isp->isp_dblev >= 3) {
- PRINTF(" Target %d: Ena %d Throttle %d Offset %d "
- "Period %d Flags 0x%x\n", i,
- sdp->isp_devparam[i].dev_enable,
- sdp->isp_devparam[i].exc_throttle,
- sdp->isp_devparam[i].sync_offset,
- sdp->isp_devparam[i].sync_period,
- sdp->isp_devparam[i].dev_flags);
- }
}
}
@@ -4717,54 +4908,63 @@ isp_parse_nvram_2100(isp, nvram_data)
u_int8_t *nvram_data;
{
fcparam *fcp = (fcparam *) isp->isp_param;
- union {
- struct {
-#if BYTE_ORDER == BIG_ENDIAN
- u_int32_t hi32;
- u_int32_t lo32;
-#else
- u_int32_t lo32;
- u_int32_t hi32;
-#endif
- } wd;
- u_int64_t full64;
- } wwnstore;
+ u_int64_t wwn;
/*
- * There is supposed to be WWNN storage as distinct
- * from WWPN storage in NVRAM, but it doesn't appear
- * to be used sanely.
+ * There is NVRAM storage for both Port and Node entities-
+ * but the Node entity appears to be unused on all the cards
+ * I can find. However, we should account for this being set
+ * at some point in the future.
+ *
+ * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
+ * bits 48..60. In the case of the 2202, it appears that they do
+ * use bit 48 to distinguish between the two instances on the card.
+ * The 2204, which I've never seen, *probably* extends this method.
*/
+ wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
+ if (wwn) {
+ isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
+ (u_int32_t) (wwn >> 32), (u_int32_t) (wwn & 0xffffffff));
+ if ((wwn >> 60) == 0) {
+ wwn |= (((u_int64_t) 2)<< 60);
+ }
+ }
+ fcp->isp_portwwn = wwn;
+ wwn = ISP2100_NVRAM_NODE_NAME(nvram_data);
+ if (wwn) {
+ isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
+ (u_int32_t) (wwn >> 32), (u_int32_t) (wwn & 0xffffffff));
+ if ((wwn >> 60) == 0) {
+ wwn |= (((u_int64_t) 2)<< 60);
+ }
+ }
+ fcp->isp_nodewwn = wwn;
- wwnstore.full64 = ISP2100_NVRAM_PORT_NAME(nvram_data);
- if (wwnstore.full64 != 0LL) {
- switch ((int) (wwnstore.full64 >> 60)) {
- case 0:
- /*
- * Broken cards with nothing in the top nibble.
- * Pah.
- */
- wwnstore.full64 |= (2LL << 60);
- /* FALLTHROUGH */
- case 2:
- fcp->isp_portwwn = wwnstore.full64;
- fcp->isp_nodewwn = wwnstore.full64;
- fcp->isp_nodewwn &= ~((0xfffLL) << 48);
- if (fcp->isp_nodewwn == fcp->isp_portwwn) {
- fcp->isp_portwwn |=
- (((u_int64_t)(isp->isp_unit+1)) << 48);
- }
- break;
- default:
- fcp->isp_portwwn = wwnstore.full64;
- fcp->isp_nodewwn = wwnstore.full64;
+ /*
+ * Make sure we have both Node and Port as non-zero values.
+ */
+ if (fcp->isp_nodewwn != 0 && fcp->isp_portwwn == 0) {
+ fcp->isp_portwwn = fcp->isp_nodewwn;
+ } else if (fcp->isp_nodewwn == 0 && fcp->isp_portwwn != 0) {
+ fcp->isp_nodewwn = fcp->isp_portwwn;
+ }
+
+ /*
+ * Make the Node and Port values sane if they're NAA == 2.
+ * This means to clear bits 48..56 for the Node WWN and
+ * make sure that there's some non-zero value in 48..56
+ * for the Port WWN.
+ */
+ if (fcp->isp_nodewwn && fcp->isp_portwwn) {
+ if ((fcp->isp_nodewwn & (((u_int64_t) 0xfff) << 48)) != 0 &&
+ (fcp->isp_nodewwn >> 60) == 2) {
+ fcp->isp_nodewwn &= ~((u_int64_t) 0xfff << 48);
+ }
+ if ((fcp->isp_portwwn & (((u_int64_t) 0xfff) << 48)) == 0 &&
+ (fcp->isp_portwwn >> 60) == 2) {
+ fcp->isp_portwwn |= ((u_int64_t) 1 << 56);
}
}
- CFGPRINTF("%s: Node WWN 0x%08x%08x, Port WWN 0x%08x%08x\n",
- isp->isp_name, (u_int32_t) (fcp->isp_nodewwn >> 32),
- (u_int32_t) (fcp->isp_nodewwn & 0xffffffff),
- (u_int32_t) (fcp->isp_portwwn >> 32),
- (u_int32_t) (fcp->isp_portwwn & 0xffffffff));
fcp->isp_maxalloc =
ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
@@ -4779,23 +4979,6 @@ isp_parse_nvram_2100(isp, nvram_data)
fcp->isp_execthrottle =
ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
- if (isp->isp_dblev > 2) {
- PRINTF("%s: NVRAM values:\n", isp->isp_name);
- PRINTF(" Max IOCB Allocation = %d\n",
- fcp->isp_maxalloc);
- PRINTF(" Max Frame Length = %d\n",
- fcp->isp_maxfrmlen);
- PRINTF(" Execution Throttle = %d\n",
- fcp->isp_execthrottle);
- PRINTF(" Retry Count = %d\n",
- fcp->isp_retry_count);
- PRINTF(" Retry Delay = %d\n",
- fcp->isp_retry_delay);
- PRINTF(" Hard Loop ID = %d\n",
- fcp->isp_loopid);
- PRINTF(" Options = 0x%x\n",
- fcp->isp_fwoptions);
- PRINTF(" HBA Options = 0x%x\n",
- ISP2100_NVRAM_HBA_OPTIONS(nvram_data));
- }
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "fwoptions from nvram are 0x%x", fcp->isp_fwoptions);
}
diff --git a/sys/dev/ic/isp_inline.h b/sys/dev/ic/isp_inline.h
index 08dbbbbfc4b..00eea381150 100644
--- a/sys/dev/ic/isp_inline.h
+++ b/sys/dev/ic/isp_inline.h
@@ -1,13 +1,11 @@
-/* $OpenBSD: isp_inline.h,v 1.4 2000/07/06 05:31:48 mjacob Exp $ */
+/* $OpenBSD: isp_inline.h,v 1.5 2000/10/16 01:01:59 mjacob Exp $ */
/*
- * Qlogic Inline Functions
+ * Qlogic Host Adapter Inline Functions
*
- *---------------------------------------
- * Copyright (c) 1999 by Matthew Jacob
+ * Copyright (c) 1999, 2000 by Matthew Jacob
* Feral Software
* All rights reserved.
* mjacob@feral.com
- *---------------------------------------
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -15,10 +13,7 @@
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
+ * 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
@@ -37,109 +32,6 @@
#ifndef _ISP_INLINE_H
#define _ISP_INLINE_H
-static INLINE void isp_prtstst __P((ispstatusreq_t *));
-static INLINE char *isp2100_fw_statename __P((int));
-static INLINE char *isp2100_pdb_statename __P((int));
-
-
-static INLINE void
-isp_prtstst(sp)
- ispstatusreq_t *sp;
-{
- char buf[172];
- buf[0] = 0;
- STRNCAT(buf, "states=>", sizeof buf);
- if (sp->req_state_flags & RQSF_GOT_BUS) {
- STRNCAT(buf, " GOT_BUS", sizeof buf);
- }
- if (sp->req_state_flags & RQSF_GOT_TARGET) {
- STRNCAT(buf, " GOT_TGT", sizeof buf);
- }
- if (sp->req_state_flags & RQSF_SENT_CDB) {
- STRNCAT(buf, " SENT_CDB", sizeof buf);
- }
- if (sp->req_state_flags & RQSF_XFRD_DATA) {
- STRNCAT(buf, " XFRD_DATA", sizeof buf);
- }
- if (sp->req_state_flags & RQSF_GOT_STATUS) {
- STRNCAT(buf, " GOT_STS", sizeof buf);
- }
- if (sp->req_state_flags & RQSF_GOT_SENSE) {
- STRNCAT(buf, " GOT_SNS", sizeof buf);
- }
- if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
- STRNCAT(buf, " XFR_CMPLT", sizeof buf);
- }
- STRNCAT(buf, "\nstatus=>", sizeof buf);
- if (sp->req_status_flags & RQSTF_DISCONNECT) {
- STRNCAT(buf, " Disconnect", sizeof buf);
- }
- if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
- STRNCAT(buf, " Sync_xfr", sizeof buf);
- }
- if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
- STRNCAT(buf, " Parity", sizeof buf);
- }
- if (sp->req_status_flags & RQSTF_BUS_RESET) {
- STRNCAT(buf, " Bus_Reset", sizeof buf);
- }
- if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
- STRNCAT(buf, " Device_Reset", sizeof buf);
- }
- if (sp->req_status_flags & RQSTF_ABORTED) {
- STRNCAT(buf, " Aborted", sizeof buf);
- }
- if (sp->req_status_flags & RQSTF_TIMEOUT) {
- STRNCAT(buf, " Timeout", sizeof buf);
- }
- if (sp->req_status_flags & RQSTF_NEGOTIATION) {
- STRNCAT(buf, " Negotiation", sizeof buf);
- }
- PRINTF(buf, "%s\n", buf);
-}
-
-static INLINE char *
-isp2100_fw_statename(state)
- int state;
-{
- static char buf[16];
- 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:
- sprintf(buf, "0x%x", state);
- return buf;
- }
-}
-
-static INLINE char *isp2100_pdb_statename(int pdb_state)
-{
- static char buf[16];
- switch(pdb_state) {
- case PDB_STATE_DISCOVERY: return "Port Discovery";
- case PDB_STATE_WDISC_ACK: return "Waiting Port Discovery ACK";
- case PDB_STATE_PLOGI: return "Port Login";
- case PDB_STATE_PLOGI_ACK: return "Wait Port Login ACK";
- case PDB_STATE_PRLI: return "Process Login";
- case PDB_STATE_PRLI_ACK: return "Wait Process Login ACK";
- case PDB_STATE_LOGGED_IN: return "Logged In";
- case PDB_STATE_PORT_UNAVAIL: return "Port Unavailable";
- case PDB_STATE_PRLO: return "Process Logout";
- case PDB_STATE_PRLO_ACK: return "Wait Process Logout ACK";
- case PDB_STATE_PLOGO: return "Port Logout";
- case PDB_STATE_PLOG_ACK: return "Wait Port Logout ACK";
- default:
- sprintf(buf, "0x%x", pdb_state);
- return buf;
- }
-}
-
/*
* Handle Functions.
* For each outstanding command there will be a non-zero handle.
@@ -148,13 +40,13 @@ static INLINE char *isp2100_pdb_statename(int pdb_state)
*/
static INLINE int
-isp_save_xs __P((struct ispsoftc *, ISP_SCSI_XFER_T *, u_int32_t *));
+isp_save_xs __P((struct ispsoftc *, XS_T *, u_int32_t *));
-static INLINE ISP_SCSI_XFER_T *
+static INLINE XS_T *
isp_find_xs __P((struct ispsoftc *, u_int32_t));
static INLINE u_int32_t
-isp_find_handle __P((struct ispsoftc *, ISP_SCSI_XFER_T *));
+isp_find_handle __P((struct ispsoftc *, XS_T *));
static INLINE int
isp_handle_index __P((u_int32_t));
@@ -163,12 +55,12 @@ static INLINE void
isp_destroy_handle __P((struct ispsoftc *, u_int32_t));
static INLINE void
-isp_remove_handle __P((struct ispsoftc *, ISP_SCSI_XFER_T *));
+isp_remove_handle __P((struct ispsoftc *, XS_T *));
static INLINE int
isp_save_xs(isp, xs, handlep)
struct ispsoftc *isp;
- ISP_SCSI_XFER_T *xs;
+ XS_T *xs;
u_int32_t *handlep;
{
int i, j;
@@ -188,11 +80,11 @@ isp_save_xs(isp, xs, handlep)
*handlep = j+1;
if (++j == isp->isp_maxcmds)
j = 0;
- isp->isp_lasthdls = j;
+ isp->isp_lasthdls = (u_int16_t)j;
return (0);
}
-static INLINE ISP_SCSI_XFER_T *
+static INLINE XS_T *
isp_find_xs(isp, handle)
struct ispsoftc *isp;
u_int32_t handle;
@@ -207,7 +99,7 @@ isp_find_xs(isp, handle)
static INLINE u_int32_t
isp_find_handle(isp, xs)
struct ispsoftc *isp;
- ISP_SCSI_XFER_T *xs;
+ XS_T *xs;
{
int i;
if (xs != NULL) {
@@ -240,7 +132,7 @@ isp_destroy_handle(isp, handle)
static INLINE void
isp_remove_handle(isp, xs)
struct ispsoftc *isp;
- ISP_SCSI_XFER_T *xs;
+ XS_T *xs;
{
isp_destroy_handle(isp, isp_find_handle(isp, xs));
}
@@ -260,7 +152,7 @@ isp_getrqentry(isp, iptrp, optrp, resultp)
optr = isp->isp_reqodx = ISP_READ(isp, OUTMAILBOX4);
iptr = isp->isp_reqidx;
*resultp = ISP_QUEUE_ENTRY(isp->isp_rquest, iptr);
- iptr = ISP_NXT_QENTRY(iptr, RQUEST_QUEUE_LEN);
+ iptr = ISP_NXT_QENTRY(iptr, RQUEST_QUEUE_LEN(isp));
if (iptr == optr) {
return (1);
}
@@ -274,6 +166,8 @@ isp_getrqentry(isp, iptrp, optrp, resultp)
static INLINE void
isp_print_qentry __P((struct ispsoftc *, char *, int, void *));
+
+#define TBA (4 * (((QENTRY_LEN >> 2) * 3) + 1) + 1)
static INLINE void
isp_print_qentry(isp, msg, idx, arg)
struct ispsoftc *isp;
@@ -281,14 +175,48 @@ isp_print_qentry(isp, msg, idx, arg)
int idx;
void *arg;
{
+ char buf[TBA];
int amt, i, j;
u_int8_t *ptr = arg;
- PRINTF("%s %s index %d:\n", isp->isp_name, msg, idx);
- for (amt = i = 0; i < 4; i++) {
+
+ for (buf[0] = 0, amt = i = 0; i < 4; i++) {
+ buf[0] = 0;
for (j = 0; j < (QENTRY_LEN >> 2); j++) {
- PRINTF(" %02x", ptr[amt++] & 0xff);
+ SNPRINTF(buf, TBA, "%s %02x", buf, ptr[amt++] & 0xff);
+ }
+ STRNCAT(buf, "\n", TBA);
+ }
+ isp_prt(isp, ISP_LOGALL, "%s index %d:%s", msg, idx, buf);
+}
+
+static INLINE void
+isp_print_bytes __P((struct ispsoftc *, char *, int, void *));
+
+static INLINE void
+isp_print_bytes(isp, msg, amt, arg)
+ struct ispsoftc *isp;
+ char *msg;
+ int amt;
+ void *arg;
+{
+ char buf[128];
+ u_int8_t *ptr = arg;
+ int off;
+
+ if (msg)
+ isp_prt(isp, ISP_LOGALL, "%s:", msg);
+ off = 0;
+ buf[0] = 0;
+ while (off < amt) {
+ int j, to;
+ to = off;
+ for (j = 0; j < 16; j++) {
+ SNPRINTF(buf, 128, "%s %02x", buf, ptr[off++] & 0xff);
+ if (off == amt)
+ break;
}
- PRINTF("\n");
+ isp_prt(isp, ISP_LOGALL, "0x%08x:%s", to, buf);
+ buf[0] = 0;
}
}
#endif /* _ISP_INLINE_H */
diff --git a/sys/dev/ic/isp_openbsd.c b/sys/dev/ic/isp_openbsd.c
index 900af61ac92..914bafb0fcf 100644
--- a/sys/dev/ic/isp_openbsd.c
+++ b/sys/dev/ic/isp_openbsd.c
@@ -1,12 +1,9 @@
-/* $OpenBSD: isp_openbsd.c,v 1.11 2000/07/07 19:00:47 mjacob Exp $ */
+/* $OpenBSD: isp_openbsd.c,v 1.12 2000/10/16 01:02:00 mjacob Exp $ */
/*
* Platform (OpenBSD) dependent common attachment code for Qlogic adapters.
*
- *---------------------------------------
- * Copyright (c) 1999 by Matthew Jacob
- * NASA/Ames Research Center
+ * Copyright (c) 1999, 2000 by Matthew Jacob
* All rights reserved.
- *---------------------------------------
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -14,10 +11,8 @@
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
+ * 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
@@ -34,7 +29,6 @@
*
* The author may be reached via electronic communications at
*
- * mjacob@nas.nasa.gov
* mjacob@feral.com
*
* or, via United States Postal Address
@@ -48,17 +42,6 @@
#include <dev/ic/isp_openbsd.h>
-static void ispminphys __P((struct buf *));
-static int32_t ispcmd_slow __P((ISP_SCSI_XFER_T *));
-static int32_t ispcmd __P((ISP_SCSI_XFER_T *));
-
-static struct scsi_device isp_dev = { NULL, NULL, NULL, NULL };
-
-static int isp_poll __P((struct ispsoftc *, ISP_SCSI_XFER_T *, int));
-static void isp_wdog __P((void *));
-static void isp_requeue(void *);
-static void isp_internal_restart(void *);
-
/*
* Set a timeout for the watchdogging of a command.
*
@@ -77,6 +60,17 @@ static void isp_internal_restart(void *);
*/
#define _XT(xs) ((((xs)->timeout/1000) * hz) + (3 * hz))
+static void ispminphys __P((struct buf *));
+static int32_t ispcmd_slow __P((XS_T *));
+static int32_t ispcmd __P((XS_T *));
+
+static struct scsi_device isp_dev = { NULL, NULL, NULL, NULL };
+
+static int isp_polled_cmd __P((struct ispsoftc *, XS_T *));
+static void isp_wdog __P((void *));
+static void isp_requeue(void *);
+static void isp_internal_restart(void *);
+
struct cfdriver isp_cd = {
NULL, "isp", DV_DULL
};
@@ -139,11 +133,13 @@ isp_attach(isp)
*/
if (IS_SCSI(isp)) {
int bus = 0;
+ ISP_LOCK(isp);
(void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
if (IS_DUALBUS(isp)) {
bus++;
(void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
}
+ ISP_UNLOCK(isp);
/*
* wait for the bus to settle.
*/
@@ -151,39 +147,37 @@ isp_attach(isp)
isp->isp_name);
delay(4 * 1000000);
} else {
- int i, j;
+ int defid;
fcparam *fcp = isp->isp_param;
+ delay(2 * 1000000);
+ defid = MAX_FC_TARG;
+ ISP_LOCK(isp);
/*
- * wait for the loop to settle.
+ * We probably won't have clock interrupts running,
+ * so we'll be really short (smoke test, really)
+ * at this time.
*/
- printf("%s: waiting 2 seconds for loop reset settling\n",
- isp->isp_name);
- delay(2 * 1000000);
- for (j = 0; j < 5; j++) {
- for (i = 0; i < 5; i++) {
- if (isp_control(isp, ISPCTL_FCLINK_TEST, NULL))
- continue;
- /*
- * Wait extra time to see if the f/w
- * eventually completed an FLOGI that
- * will allow us to know we're on a
- * fabric.
- */
- if (fcp->isp_onfabric == 0) {
- delay(1 * 1000000);
- continue;
- }
- break;
- }
+ if (isp_control(isp, ISPCTL_FCLINK_TEST, NULL)) {
+ (void) isp_control(isp, ISPCTL_PDB_SYNC, NULL);
if (fcp->isp_fwstate == FW_READY &&
fcp->isp_loopstate >= LOOP_PDB_RCVD) {
- break;
+ defid = fcp->isp_loopid;
}
}
+ ISP_UNLOCK(isp);
lptr->adapter_target = fcp->isp_loopid;
}
/*
+ * After this point, we *could* be doing the new configuration
+ * schema which allows interrups, so we can do tsleep/wakeup
+ * for mailbox stuff at that point.
+ */
+#if 0
+ isp->isp_osinfo.no_mbox_ints = 0;
+#endif
+
+ /*
* And attach children (if any).
*/
config_found((void *)isp, lptr, scsiprint);
@@ -216,7 +210,7 @@ ispminphys(bp)
static int32_t
ispcmd_slow(xs)
- ISP_SCSI_XFER_T *xs;
+ XS_T *xs;
{
sdparam *sdp;
int tgt, chan;
@@ -289,8 +283,6 @@ ispcmd_slow(xs)
}
}
if (chan == (IS_12X0(isp)? 2 : 1)) {
- CFGPRINTF("%s: allowing sync/wide negotiation and "
- "tag usage\n", isp->isp_name);
isp->isp_osinfo._adapter.scsipi_cmd = ispcmd;
if (IS_12X0(isp))
isp->isp_update |= 2;
@@ -301,11 +293,10 @@ ispcmd_slow(xs)
static int32_t
ispcmd(xs)
- ISP_SCSI_XFER_T *xs;
+ XS_T *xs;
{
struct ispsoftc *isp;
int result;
- int s;
/*
* Make sure that there's *some* kind of sane setting.
@@ -315,13 +306,13 @@ ispcmd(xs)
isp = XS_ISP(xs);
- s = splbio();
+ ISP_LOCK(isp);
if (isp->isp_state < ISP_RUNSTATE) {
DISABLE_INTS(isp);
isp_init(isp);
if (isp->isp_state != ISP_INITSTATE) {
ENABLE_INTS(isp);
- (void) splx(s);
+ ISP_UNLOCK(isp);
XS_SETERR(xs, HBA_BOTCH);
return (CMD_COMPLETE);
}
@@ -333,10 +324,10 @@ ispcmd(xs)
* Check for queue blockage...
*/
if (isp->isp_osinfo.blocked) {
- IDPRINTF(2, ("%s: blocked\n", isp->isp_name));
+ isp_prt(isp, ISP_LOGDEBUG2, "blocked");
if (xs->flags & SCSI_POLL) {
xs->error = XS_DRIVER_STUFFUP;
- splx(s);
+ ISP_UNLOCK(isp);
return (TRY_AGAIN_LATER);
}
if (isp->isp_osinfo.wqf != NULL) {
@@ -346,35 +337,66 @@ ispcmd(xs)
}
isp->isp_osinfo.wqt = xs;
xs->free_list.le_next = NULL;
- splx(s);
+ ISP_UNLOCK(isp);
return (SUCCESSFULLY_QUEUED);
}
- result = ispscsicmd(xs);
- if ((xs->flags & SCSI_POLL) == 0) {
- switch (result) {
- case CMD_QUEUED:
- result = SUCCESSFULLY_QUEUED;
- if (xs->timeout) {
- timeout_add(&xs->stimeout, _XT(xs));
- }
- break;
- case CMD_EAGAIN:
- result = TRY_AGAIN_LATER;
- break;
- case CMD_RQLATER:
- result = SUCCESSFULLY_QUEUED;
- timeout_set(&xs->stimeout, isp_requeue, xs);
- timeout_add(&xs->stimeout, hz);
- break;
- case CMD_COMPLETE:
- result = COMPLETE;
- break;
- }
- (void) splx(s);
+ if (xs->flags & SCSI_POLL) {
+ volatile u_int8_t ombi = isp->isp_osinfo.no_mbox_ints;
+ isp->isp_osinfo.no_mbox_ints = 1;
+ result = isp_polled_cmd(isp, xs);
+ isp->isp_osinfo.no_mbox_ints = ombi;
+ ISP_UNLOCK(isp);
return (result);
}
+ result = isp_start(xs);
+
+#if 0
+{
+ static int na[16] = { 0 };
+ if (na[isp->isp_unit] < isp->isp_nactive) {
+ isp_prt(isp, ISP_LOGALL, "active hiwater %d", isp->isp_nactive);
+ na[isp->isp_unit] = isp->isp_nactive;
+ }
+}
+#endif
+
+ switch (result) {
+ case CMD_QUEUED:
+ result = SUCCESSFULLY_QUEUED;
+ if (xs->timeout) {
+ timeout_add(&xs->stimeout, _XT(xs));
+ }
+ break;
+ case CMD_EAGAIN:
+#if 0
+ result = TRY_AGAIN_LATER;
+ break;
+#endif
+ case CMD_RQLATER:
+ result = SUCCESSFULLY_QUEUED;
+ timeout_set(&xs->stimeout, isp_requeue, xs);
+ timeout_add(&xs->stimeout, hz);
+ break;
+ case CMD_COMPLETE:
+ result = COMPLETE;
+ break;
+ }
+ ISP_UNLOCK(isp);
+ return (result);
+}
+
+static int
+isp_polled_cmd(isp, xs)
+ struct ispsoftc *isp;
+ XS_T *xs;
+{
+ int result;
+ int infinite = 0, mswait;
+
+ result = isp_start(xs);
+
switch (result) {
case CMD_QUEUED:
result = SUCCESSFULLY_QUEUED;
@@ -392,33 +414,45 @@ ispcmd(xs)
}
+ if (result != SUCCESSFULLY_QUEUED) {
+ return (result);
+ }
+
/*
- * We can't use interrupts so poll on completion.
+ * If we can't use interrupts, poll on completion.
*/
- if (result == SUCCESSFULLY_QUEUED) {
- if (isp_poll(isp, xs, xs->timeout)) {
- /*
- * If no other error occurred but we didn't finish,
- * something bad happened.
- */
- if (XS_CMD_DONE_P(xs) == 0) {
- if (isp_control(isp, ISPCTL_ABORT_CMD, xs)) {
- isp_restart(isp);
- }
- if (XS_NOERR(xs)) {
- XS_SETERR(xs, HBA_BOTCH);
- }
+ if ((mswait = XS_TIME(xs)) == 0)
+ infinite = 1;
+
+ while (mswait || infinite) {
+ if (isp_intr((void *)isp)) {
+ if (XS_CMD_DONE_P(xs)) {
+ break;
}
}
- result = COMPLETE;
+ USEC_DELAY(1000);
+ mswait -= 1;
+ }
+
+ /*
+ * If no other error occurred but we didn't finish,
+ * something bad happened.
+ */
+ if (XS_CMD_DONE_P(xs) == 0) {
+ if (isp_control(isp, ISPCTL_ABORT_CMD, xs)) {
+ isp_reinit(isp);
+ }
+ if (XS_NOERR(xs)) {
+ XS_SETERR(xs, HBA_BOTCH);
+ }
}
- (void) splx(s);
+ result = COMPLETE;
return (result);
}
void
isp_done(xs)
- ISP_SCSI_XFER_T *xs;
+ XS_T *xs;
{
XS_CMD_S_DONE(xs);
if (XS_CMD_WDOG_P(xs) == 0) {
@@ -427,65 +461,45 @@ isp_done(xs)
}
if (XS_CMD_GRACE_P(xs)) {
struct ispsoftc *isp = XS_ISP(xs);
- PRINTF("%s: finished command on borrowed time\n",
- isp->isp_name);
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "finished command on borrowed time");
}
XS_CMD_S_CLEAR(xs);
scsi_done(xs);
}
}
-static int
-isp_poll(isp, xs, mswait)
- struct ispsoftc *isp;
- ISP_SCSI_XFER_T *xs;
- int mswait;
-{
-
- while (mswait) {
- /* Try the interrupt handling routine */
- (void)isp_intr((void *)isp);
-
- /* See if the xs is now done */
- if (XS_CMD_DONE_P(xs)) {
- return (0);
- }
- delay(1000); /* wait one millisecond */
- mswait--;
- }
- return (1);
-}
-
-
static void
isp_wdog(arg)
void *arg;
{
- ISP_SCSI_XFER_T *xs = arg;
+ XS_T *xs = arg;
struct ispsoftc *isp = XS_ISP(xs);
u_int32_t handle;
- int s = splbio();
/*
* We've decided this command is dead. Make sure we're not trying
* to kill a command that's already dead by getting it's handle and
* and seeing whether it's still alive.
*/
+ ISP_LOCK(isp);
handle = isp_find_handle(isp, xs);
if (handle) {
u_int16_t r, r1, i;
if (XS_CMD_DONE_P(xs)) {
- PRINTF("%s: watchdog found done cmd (handle 0x%x)\n",
- isp->isp_name, handle);
- (void) splx(s);
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "watchdog found done cmd (handle 0x%x)",
+ handle);
+ ISP_UNLOCK(isp);
return;
}
if (XS_CMD_WDOG_P(xs)) {
- PRINTF("%s: recursive watchdog (handle 0x%x)\n",
- isp->isp_name, handle);
- (void) splx(s);
+ isp_prt(isp, ISP_LOGDEBUG1,
+ "recursive watchdog (handle 0x%x)",
+ handle);
+ ISP_UNLOCK(isp);
return;
}
@@ -494,13 +508,13 @@ isp_wdog(arg)
i = 0;
do {
r = ISP_READ(isp, BIU_ISR);
- SYS_DELAY(1);
+ USEC_DELAY(1);
r1 = ISP_READ(isp, BIU_ISR);
} while (r != r1 && ++i < 1000);
if (INT_PENDING(isp, r) && isp_intr(isp) && XS_CMD_DONE_P(xs)) {
- IDPRINTF(1, ("%s: watchdog cleanup (%x, %x)\n",
- isp->isp_name, handle, r));
+ isp_prt(isp, ISP_LOGDEBUG1, "watchdog cleanup (%x, %x)",
+ isp->isp_name, handle, r);
XS_CMD_C_WDOG(xs);
isp_done(xs);
} else if (XS_CMD_GRACE_P(xs)) {
@@ -516,8 +530,7 @@ isp_wdog(arg)
if (XS_XFRLEN(xs)) {
ISP_DMAFREE(isp, xs, handle);
}
- printf("%s: watchdog timeout (%x, %x)\n",
- isp->isp_name, handle, r);
+ printf("%s: watchdog timeout (%x, %x)\n", handle, r);
isp_destroy_handle(isp, handle);
XS_SETERR(xs, XS_TIMEOUT);
XS_CMD_S_CLEAR(xs);
@@ -526,13 +539,13 @@ isp_wdog(arg)
u_int16_t iptr, optr;
ispreq_t *mp;
- IDPRINTF(2, ("%s: possible command timeout (%x, %x)\n",
- isp->isp_name, handle, r));
+ isp_prt(isp, ISP_LOGDEBUG2,
+ "possible command timeout (%x, %x)", handle, r);
XS_CMD_C_WDOG(xs);
timeout_add(&xs->stimeout, _XT(xs));
if (isp_getrqentry(isp, &iptr, &optr, (void **) &mp)) {
- (void) splx(s);
+ ISP_UNLOCK(isp);
return;
}
XS_CMD_S_GRACE(xs);
@@ -542,13 +555,12 @@ isp_wdog(arg)
mp->req_modifier = SYNC_ALL;
mp->req_target = XS_CHANNEL(xs) << 7;
ISP_SWIZZLE_REQUEST(isp, mp);
- MemoryBarrier();
ISP_ADD_REQUEST(isp, iptr);
}
} else if (isp->isp_dblev) {
- PRINTF("%s: watchdog with no command\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGDEBUG2, "watchdog with no command");
}
- (void) splx(s);
+ ISP_UNLOCK(isp);
}
/*
@@ -562,13 +574,13 @@ void
isp_uninit(isp)
struct ispsoftc *isp;
{
- int s = splbio();
+ ISP_LOCK(isp);
/*
* Leave with interrupts disabled.
*/
DISABLE_INTS(isp);
- splx(s);
+ ISP_UNLOCK(isp);
}
/*
@@ -579,7 +591,7 @@ isp_requeue(void *arg)
{
struct scsi_xfer *xs = arg;
struct ispsoftc *isp = XS_ISP(xs);
- int s = splbio();
+ ISP_LOCK(isp);
switch (ispcmd_slow(xs)) {
case SUCCESSFULLY_QUEUED:
printf("%s: isp_command_reque: queued %d.%d\n",
@@ -592,15 +604,17 @@ isp_requeue(void *arg)
case TRY_AGAIN_LATER:
printf("%s: EAGAIN for %d.%d\n",
isp->isp_name, XS_TGT(xs), XS_LUN(xs));
- /* FALLTHROUGH */
+ timeout_set(&xs->stimeout, isp_requeue, xs);
+ timeout_add(&xs->stimeout, hz);
+ break;
case COMPLETE:
/* can only be an error */
if (XS_NOERR(xs))
XS_SETERR(xs, XS_DRIVER_STUFFUP);
- XS_CMD_DONE(xs);
+ XS_CMD_S_DONE(xs);
break;
}
- (void) splx(s);
+ ISP_UNLOCK(isp);
}
/*
@@ -611,23 +625,21 @@ static void
isp_internal_restart(void *arg)
{
struct ispsoftc *isp = arg;
- int result, nrestarted = 0, s;
+ int result, nrestarted = 0;
- s = splbio();
+ ISP_LOCK(isp);
if (isp->isp_osinfo.blocked == 0) {
struct scsi_xfer *xs;
while ((xs = isp->isp_osinfo.wqf) != NULL) {
isp->isp_osinfo.wqf = xs->free_list.le_next;
xs->free_list.le_next = NULL;
- DISABLE_INTS(isp);
- result = ispscsicmd(xs);
- ENABLE_INTS(isp);
+ result = isp_start(xs);
if (result != CMD_QUEUED) {
printf("%s: botched command restart (0x%x)\n",
isp->isp_name, result);
if (XS_NOERR(xs))
XS_SETERR(xs, XS_DRIVER_STUFFUP);
- XS_CMD_DONE(xs);
+ XS_CMD_S_DONE(xs);
} else if (xs->timeout) {
timeout_add(&xs->stimeout, _XT(xs));
}
@@ -635,7 +647,7 @@ isp_internal_restart(void *arg)
}
printf("%s: requeued %d commands\n", isp->isp_name, nrestarted);
}
- (void) splx(s);
+ ISP_UNLOCK(isp);
}
int
@@ -645,7 +657,7 @@ isp_async(isp, cmd, arg)
void *arg;
{
int bus, tgt;
- int s = splbio();
+
switch (cmd) {
case ISPASYNC_NEW_TGT_PARAMS:
if (IS_SCSI(isp) && isp->isp_dblev) {
@@ -657,11 +669,17 @@ isp_async(isp, cmd, arg)
bus = (tgt >> 16) & 0xffff;
tgt &= 0xffff;
sdp += bus;
-
flags = sdp->isp_devparam[tgt].cur_dflags;
period = sdp->isp_devparam[tgt].cur_period;
+
if ((flags & DPARM_SYNC) && period &&
(sdp->isp_devparam[tgt].cur_offset) != 0) {
+ /*
+ * There's some ambiguity about our negotiated speed
+ * if we haven't detected LVD mode correctly (which
+ * seems to happen, unfortunately). If we're in LVD
+ * mode, then different rules apply about speed.
+ */
if (sdp->isp_lvdmode || period < 0xc) {
switch (period) {
case 0x9:
@@ -688,25 +706,26 @@ isp_async(isp, cmd, arg)
}
switch (flags & (DPARM_WIDE|DPARM_TQING)) {
case DPARM_WIDE:
- wt = ", 16 bit wide\n";
+ wt = ", 16 bit wide";
break;
case DPARM_TQING:
- wt = ", Tagged Queueing Enabled\n";
+ wt = ", Tagged Queueing Enabled";
break;
case DPARM_WIDE|DPARM_TQING:
- wt = ", 16 bit wide, Tagged Queueing Enabled\n";
+ wt = ", 16 bit wide, Tagged Queueing Enabled";
break;
default:
- wt = "\n";
+ wt = " ";
break;
}
if (mhz) {
- CFGPRINTF("%s: Bus %d Target %d at %dMHz Max "
- "Offset %d%s", isp->isp_name, bus, tgt, mhz,
- sdp->isp_devparam[tgt].cur_offset, wt);
+ isp_prt(isp, ISP_LOGINFO,
+ "Bus %d Target %d at %dMHz Max Offset %d%s",
+ bus, tgt, mhz, sdp->isp_devparam[tgt].cur_offset,
+ wt);
} else {
- CFGPRINTF("%s: Bus %d Target %d Async Mode%s",
- isp->isp_name, bus, tgt, wt);
+ isp_prt(isp, ISP_LOGINFO,
+ "Bus %d Target %d Async Mode%s", bus, tgt, wt);
}
break;
}
@@ -715,7 +734,7 @@ isp_async(isp, cmd, arg)
bus = *((int *) arg);
else
bus = 0;
- printf("%s: SCSI bus %d reset detected\n", isp->isp_name, bus);
+ isp_prt(isp, ISP_LOGINFO, "SCSI bus %d reset detected", bus);
break;
case ISPASYNC_LOOP_DOWN:
/*
@@ -723,18 +742,18 @@ isp_async(isp, cmd, arg)
* of commands we are firing off that are sure to die.
*/
isp->isp_osinfo.blocked = 1;
- printf("%s: Loop DOWN\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGINFO, "Loop DOWN");
break;
case ISPASYNC_LOOP_UP:
isp->isp_osinfo.blocked = 0;
timeout_set(&isp->isp_osinfo.rqt, isp_internal_restart, isp);
timeout_add(&isp->isp_osinfo.rqt, 1);
- printf("%s: Loop UP\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGINFO, "Loop UP");
break;
case ISPASYNC_PDB_CHANGED:
if (IS_FC(isp) && isp->isp_dblev) {
- const char *fmt = "%s: Target %d (Loop 0x%x) Port ID 0x%x "
- "role %s %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x\n";
+ const char *fmt = "Target %d (Loop 0x%x) Port ID 0x%x "
+ "role %s %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x";
const static char *roles[4] = {
"No", "Target", "Initiator", "Target/Initiator"
};
@@ -748,7 +767,7 @@ isp_async(isp, cmd, arg)
} else {
ptr = "disappeared";
}
- printf(fmt, isp->isp_name, tgt, lp->loopid, lp->portid,
+ isp_prt(isp, ISP_LOGINFO, fmt, tgt, lp->loopid, lp->portid,
roles[lp->roles & 0x3], ptr,
(u_int32_t) (lp->port_wwn >> 32),
(u_int32_t) (lp->port_wwn & 0xffffffffLL),
@@ -756,25 +775,24 @@ isp_async(isp, cmd, arg)
(u_int32_t) (lp->node_wwn & 0xffffffffLL));
break;
}
+#ifdef ISP2100_FABRIC
case ISPASYNC_CHANGE_NOTIFY:
- printf("%s: Name Server Database Changed\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGINFO, "Name Server Database Changed");
break;
case ISPASYNC_FABRIC_DEV:
{
int target;
struct lportdb *lp;
- char *pt;
- sns_ganrsp_t *resp = (sns_ganrsp_t *) arg;
+ sns_scrsp_t *resp = (sns_scrsp_t *) arg;
u_int32_t portid;
- u_int64_t wwpn, wwnn;
+ u_int64_t wwn;
fcparam *fcp = isp->isp_param;
portid =
(((u_int32_t) resp->snscb_port_id[0]) << 16) |
(((u_int32_t) resp->snscb_port_id[1]) << 8) |
(((u_int32_t) resp->snscb_port_id[2]));
-
- wwpn =
+ wwn =
(((u_int64_t)resp->snscb_portname[0]) << 56) |
(((u_int64_t)resp->snscb_portname[1]) << 48) |
(((u_int64_t)resp->snscb_portname[2]) << 40) |
@@ -784,60 +802,14 @@ isp_async(isp, cmd, arg)
(((u_int64_t)resp->snscb_portname[6]) << 8) |
(((u_int64_t)resp->snscb_portname[7]));
- wwnn =
- (((u_int64_t)resp->snscb_nodename[0]) << 56) |
- (((u_int64_t)resp->snscb_nodename[1]) << 48) |
- (((u_int64_t)resp->snscb_nodename[2]) << 40) |
- (((u_int64_t)resp->snscb_nodename[3]) << 32) |
- (((u_int64_t)resp->snscb_nodename[4]) << 24) |
- (((u_int64_t)resp->snscb_nodename[5]) << 16) |
- (((u_int64_t)resp->snscb_nodename[6]) << 8) |
- (((u_int64_t)resp->snscb_nodename[7]));
- if (portid == 0 || wwpn == 0) {
- break;
- }
+ isp_prt(isp, ISP_LOGINFO,
+ "Fabric Device (Type 0x%x)@PortID 0x%x WWN 0x%08x%08x",
+ resp->snscb_port_type, portid, ((u_int32_t)(wwn >> 32)),
+ ((u_int32_t)(wwn & 0xffffffff)));
- switch (resp->snscb_port_type) {
- case 1:
- pt = " N_Port";
- break;
- case 2:
- pt = " NL_Port";
- break;
- case 3:
- pt = "F/NL_Port";
- break;
- case 0x7f:
- pt = " Nx_Port";
- break;
- case 0x81:
- pt = " F_port";
- break;
- case 0x82:
- pt = " FL_Port";
- break;
- case 0x84:
- pt = " E_port";
- break;
- default:
- pt = "?";
- break;
- }
- CFGPRINTF("%s: %s @ 0x%x, Node 0x%08x%08x Port %08x%08x\n",
- isp->isp_name, pt, portid,
- ((u_int32_t) (wwnn >> 32)), ((u_int32_t) wwnn),
- ((u_int32_t) (wwpn >> 32)), ((u_int32_t) wwpn));
-#if 0
- if ((resp->snscb_fc4_types[1] & 0x1) == 0) {
- printf("Types 0..3: 0x%x 0x%x 0x%x 0x%x\n",
- resp->snscb_fc4_types[0], resp->snscb_fc4_types[1],
- resp->snscb_fc4_types[3], resp->snscb_fc4_types[3]);
- break;
- }
-#endif
for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) {
lp = &fcp->portdb[target];
- if (lp->port_wwn == wwpn && lp->node_wwn == wwnn)
+ if (lp->port_wwn == wwn)
break;
}
if (target < MAX_FC_TARG) {
@@ -849,18 +821,38 @@ isp_async(isp, cmd, arg)
break;
}
if (target == MAX_FC_TARG) {
- printf("%s: no more space for fabric devices\n",
- isp->isp_name);
- break;
+ isp_prt(isp, ISP_LOGWARN,
+ "no more space for fabric devices");
+ return (-1);
}
- lp->node_wwn = wwnn;
- lp->port_wwn = wwpn;
+ lp->port_wwn = lp->node_wwn = wwn;
lp->portid = portid;
break;
}
+#endif
default:
break;
}
- (void) splx(s);
return (0);
}
+
+void
+#ifdef __STDC__
+isp_prt(struct ispsoftc *isp, int level, const char *fmt, ...)
+#else
+isp_log(isp, fmt, va_alist)
+ struct ispsoftc *isp;
+ char *fmt;
+ va_dcl;
+#endif
+{
+ va_list ap;
+ if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) {
+ return;
+ }
+ printf("%s: ", isp->isp_name);
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+ printf("\n");
+}
diff --git a/sys/dev/ic/isp_openbsd.h b/sys/dev/ic/isp_openbsd.h
index 89f34fb2633..1d8d2c511ae 100644
--- a/sys/dev/ic/isp_openbsd.h
+++ b/sys/dev/ic/isp_openbsd.h
@@ -1,39 +1,30 @@
-/* $OpenBSD: isp_openbsd.h,v 1.9 2000/07/06 05:31:48 mjacob Exp $ */
+/* $OpenBSD: isp_openbsd.h,v 1.10 2000/10/16 01:02:00 mjacob Exp $ */
/*
* OpenBSD Specific definitions for the Qlogic ISP Host Adapter
- *
- *---------------------------------------
- * Copyright (c) 1999 by Matthew Jacob
- * NASA/Ames Research Center
+ */
+/*
+ * Copyright (C) 1999, 2000 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 immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
*
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
#ifndef _ISP_OPENBSD_H
#define _ISP_OPENBSD_H
@@ -50,7 +41,6 @@
#include <sys/user.h>
#include <sys/queue.h>
-
#include <scsi/scsi_all.h>
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
@@ -62,117 +52,199 @@
#include <vm/vm_param.h>
#include <vm/pmap.h>
-#define ISP_PLATFORM_VERSION_MAJOR 0
-#define ISP_PLATFORM_VERSION_MINOR 10
-#define ISP_SCSI_XFER_T struct scsi_xfer
+#define ISP_PLATFORM_VERSION_MAJOR 1
+#define ISP_PLATFORM_VERSION_MINOR 0
+
struct isposinfo {
struct device _dev;
struct scsi_link _link[2];
struct scsi_adapter _adapter;
- int blocked;
+ int splsaved;
+ int mboxwaiting;
+ u_int32_t islocked;
+ u_int32_t onintstack;
+ unsigned int : 30,
+ no_mbox_ints : 1,
+ blocked : 1;
union {
- int _seed;
+ u_int64_t _wwn;
u_int16_t _discovered[2];
} un;
-#define seed un._seed
#define discovered un._discovered
struct scsi_xfer *wqf, *wqt;
struct timeout rqt;
};
-#define MBOX_WAIT_COMPLETE(isp) \
- { \
- int j; \
- for (j = 0; j < 60 * 2000; j++) { \
- if (isp_intr(isp) == 0) { \
- SYS_DELAY(500); \
- } \
- if (isp->isp_mboxbsy == 0) \
- break; \
- } \
- if (isp->isp_mboxbsy != 0) \
- printf("%s: mailbox timeout\n", isp->isp_name); \
- }
+/*
+ * Required Macros/Defines
+ */
-#define MBOX_NOTIFY_COMPLETE(isp) isp->isp_mboxbsy = 0
+#define INLINE inline
-#define MAXISPREQUEST 256
#define ISP2100_FABRIC 1
#define ISP2100_SCRLEN 0x400
-#include <dev/ic/ispreg.h>
-#include <dev/ic/ispvar.h>
-#include <dev/ic/ispmbox.h>
+#define MEMZERO bzero
+#define MEMCPY(dst, src, amt) bcopy((src), (dst), (amt))
+#define SNPRINTF snprintf
+#define STRNCAT strncat
+#define USEC_DELAY(x) delay(x)
-#define IDPRINTF(lev, x) if (isp->isp_dblev >= lev) printf x
-#define PRINTF printf
+#define NANOTIME_T struct timeval
+#define GET_NANOTIME microtime
+#define GET_NANOSEC(x) (((x)->tv_sec * 1000000 + (x)->tv_usec) * 1000)
+#define NANOTIME_SUB isp_microtime_sub
-#define MEMZERO bzero
-#define MEMCPY(dst, src, count) bcopy((src), (dst), (count))
+#define MAXISPREQUEST(isp) 256
#ifdef __alpha__
-#define MemoryBarrier alpha_mb
+#define MEMORYBARRIER(isp, type, offset, size) alpha_mb()
#else
-#define MemoryBarrier()
+#define MEMORYBARRIER(isp, type, offset, size)
#endif
-#define DMA_MSW(x) (((x) >> 16) & 0xffff)
-#define DMA_LSW(x) (((x) & 0xffff))
-
-#if defined(SCSIDEBUG)
-#define DFLT_DBLEVEL 3
-#define CFGPRINTF printf
-#elif defined(DEBUG)
-#define DFLT_DBLEVEL 2
-#define CFGPRINTF printf
-#elif defined(DIAGNOSTIC)
-#define DFLT_DBLEVEL 1
-#define CFGPRINTF if (0) printf
-#else
-#define DFLT_DBLEVEL 0
-#define CFGPRINTF if (0) printf
-#endif
+#define MBOX_ACQUIRE(isp)
+#define MBOX_WAIT_COMPLETE isp_wait_complete
+
+#define MBOX_NOTIFY_COMPLETE(isp) \
+ if (isp->isp_osinfo.mboxwaiting) { \
+ isp->isp_osinfo.mboxwaiting = 0; \
+ wakeup(&isp->isp_osinfo.mboxwaiting); \
+ } \
+ isp->isp_mboxbsy = 0
-#define ISP_LOCKVAL_DECL int isp_spl_save
-#define ISP_ILOCKVAL_DECL ISP_LOCKVAL_DECL
-#define ISP_LOCK(x) isp_spl_save = splbio()
-#define ISP_UNLOCK(x) (void) splx(isp_spl_save)
-#define ISP_ILOCK ISP_LOCK
-#define ISP_IUNLOCK ISP_UNLOCK
+#define MBOX_RELEASE(isp)
+#ifndef SCSI_GOOD
+#define SCSI_GOOD 0x0
+#endif
+#ifndef SCSI_CHECK
+#define SCSI_CHECK 0x2
+#endif
+#ifndef SCSI_BUSY
+#define SCSI_BUSY 0x8
+#endif
+#ifndef SCSI_QFULL
+#define SCSI_QFULL 0x28
+#endif
-#define XS_NULL(xs) xs == NULL || xs->sc_link == NULL
+#define XS_T struct scsi_xfer
+#define XS_CHANNEL(xs) (((xs)->sc_link->flags & SDEV_2NDBUS)? 1 : 0)
#define XS_ISP(xs) (xs)->sc_link->adapter_softc
#define XS_LUN(xs) ((int) (xs)->sc_link->lun)
#define XS_TGT(xs) ((int) (xs)->sc_link->target)
-#define XS_RESID(xs) (xs)->resid
-#define XS_CHANNEL(xs) (((xs)->sc_link->flags & SDEV_2NDBUS)? 1 : 0)
-#define XS_XFRLEN(xs) (xs)->datalen
-#define XS_CDBLEN(xs) (xs)->cmdlen
#define XS_CDBP(xs) ((caddr_t) (xs)->cmd)
-#define XS_STS(xs) (xs)->status
+#define XS_CDBLEN(xs) (xs)->cmdlen
+#define XS_XFRLEN(xs) (xs)->datalen
#define XS_TIME(xs) (xs)->timeout
+#define XS_RESID(xs) (xs)->resid
+#define XS_STSP(xs) (&(xs)->status)
#define XS_SNSP(xs) (&(xs)->sense)
#define XS_SNSLEN(xs) (sizeof (xs)->sense)
#define XS_SNSKEY(xs) ((xs)->sense.flags)
+#define XS_TAG_P(xs) (((xs)->flags & SCSI_POLL) != 0)
+#define XS_TAG_TYPE(xs) REQFLAG_STAG
+
+#define XS_SETERR(xs, v) (xs)->error = v
+
+# define HBA_NOERROR XS_NOERROR
+# define HBA_BOTCH XS_DRIVER_STUFFUP
+# define HBA_CMDTIMEOUT XS_TIMEOUT
+# define HBA_SELTIMEOUT XS_SELTIMEOUT
+# define HBA_TGTBSY XS_BUSY
+# define HBA_BUSRESET XS_RESET
+# define HBA_ABORTED XS_DRIVER_STUFFUP
+# define HBA_DATAOVR XS_DRIVER_STUFFUP
+# define HBA_ARQFAIL XS_DRIVER_STUFFUP
+
+#define XS_ERR(xs) (xs)->error
+
+#define XS_NOERR(xs) (xs)->error == XS_NOERROR
-#define HBA_NOERROR XS_NOERROR
-#define HBA_BOTCH XS_DRIVER_STUFFUP
-#define HBA_CMDTIMEOUT XS_TIMEOUT
-#define HBA_SELTIMEOUT XS_SELTIMEOUT
-#define HBA_TGTBSY XS_BUSY
-#ifdef XS_RESET
-#define HBA_BUSRESET XS_RESET
+#define XS_INITERR(xs) (xs)->error = 0, XS_CMD_S_CLEAR(xs)
+
+#define XS_SAVE_SENSE(xs, sp) \
+ bcopy(sp->req_sense_data, &(xs)->sense, \
+ imin(XS_SNSLEN(xs), sp->req_sense_len))
+
+#define XS_SET_STATE_STAT(a, b, c)
+
+#define DEFAULT_IID(x) 7
+#define DEFAULT_LOOPID(x) 107
+#define DEFAULT_NODEWWN(isp) (isp)->isp_osinfo.un._wwn
+#define DEFAULT_PORTWWN(isp) (isp)->isp_osinfo.un._wwn
+#define ISP_NODEWWN(isp) FCPARAM(isp)->isp_nodewwn
+#define ISP_PORTWWN(isp) FCPARAM(isp)->isp_portwwn
+
+#define ISP_UNSWIZZLE_AND_COPY_PDBP(isp, dest, src) \
+ if((void *)src != (void *)dest) bcopy(src, dest, sizeof (isp_pdb_t))
+#define ISP_SWIZZLE_ICB(a, b)
+#ifdef __sparc__
+#define ISP_SWIZZLE_REQUEST(a, b) \
+ ISP_SBUSIFY_ISPHDR(a, &(b)->req_header); \
+ ISP_SBUSIFY_ISPREQ(a, b)
+#define ISP_UNSWIZZLE_RESPONSE(a, b, c) \
+ ISP_SBUSIFY_ISPHDR(a, &(b)->req_header)
+#else
+#define ISP_SWIZZLE_REQUEST(a, b)
+#define ISP_UNSWIZZLE_RESPONSE(a, b, c)
+#endif
+#define ISP_SWIZZLE_SNS_REQ(a, b)
+#define ISP_UNSWIZZLE_SNS_RSP(a, b, c)
+#ifdef __sparc__
+#define ISP_SWIZZLE_NVRAM_WORD(isp, rp) \
+ { \
+ u_int16_t tmp = *rp >> 8; \
+ tmp |= ((*rp & 0xff) << 8); \
+ *rp = tmp; \
+ }
#else
-#define HBA_BUSRESET XS_DRIVER_STUFFUP
+#define ISP_SWIZZLE_NVRAM_WORD(isp, rp)
#endif
-#define HBA_ABORTED XS_DRIVER_STUFFUP
-#define HBA_DATAOVR XS_DRIVER_STUFFUP
-#define HBA_ARQFAIL XS_DRIVER_STUFFUP
-#define XS_SNS_IS_VALID(xs) (xs)->error = XS_SENSE
-#define XS_IS_SNS_VALID(xs) ((xs)->error == XS_SENSE)
+/*
+ * Includes of common header files
+ */
+
+#include <dev/ic/ispreg.h>
+#include <dev/ic/ispvar.h>
+#include <dev/ic/ispmbox.h>
+
+/*
+ * isp_osinfo definitions, extensions and shorthand.
+ */
+#define isp_name isp_osinfo._dev.dv_xname
+#define isp_unit isp_osinfo._dev.dv_unit
+
+/*
+ * Driver prototypes..
+ */
+void isp_attach __P((struct ispsoftc *));
+void isp_uninit __P((struct ispsoftc *));
+
+static inline void isp_lock __P((struct ispsoftc *));
+static inline void isp_unlock __P((struct ispsoftc *));
+static inline char *strncat __P((char *, const char *, size_t));
+static inline u_int64_t
+isp_microtime_sub __P((struct timeval *, struct timeval *));
+static void isp_wait_complete __P((struct ispsoftc *));
+
+/*
+ * Driver wide data...
+ */
+
+/*
+ * Locking macros...
+ */
+#define ISP_LOCK isp_lock
+#define ISP_UNLOCK isp_unlock
+#define ISP_ILOCK(x) isp_lock(x); isp->isp_osinfo.onintstack++
+#define ISP_IUNLOCK(x) isp->isp_osinfo.onintstack--; isp_unlock(x)
+
+/*
+ * Platform private flags
+ */
#define XS_PSTS_INWDOG 0x10000
#define XS_PSTS_GRACE 0x20000
@@ -192,68 +264,36 @@ struct isposinfo {
#define XS_CMD_S_CLEAR(xs) (xs)->flags &= ~XS_PSTS_ALL
-#define XS_INITERR(xs) (xs)->error = 0, XS_CMD_S_CLEAR(xs)
-#define XS_SETERR(xs, v) (xs)->error = v
-#define XS_ERR(xs) (xs)->error
-#define XS_NOERR(xs) (xs)->error == XS_NOERROR
-
-#define XS_CMD_DONE isp_done
-
/*
- * We use whether or not we're a polled command to decide about tagging.
+ * Platform specific 'inline' or support functions
*/
-#define XS_CANTAG(xs) (((xs)->flags & SCSI_POLL) != 0)
-
-/*
- * This is our default tag (ordered).
- */
-#define XS_KINDOF_TAG(xs) REQFLAG_OTAG
-
-#define CMD_COMPLETE 100
-#define CMD_EAGAIN 101
-#define CMD_QUEUED 102
-#define CMD_RQLATER 103
-
-#define isp_name isp_osinfo._dev.dv_xname
-#define isp_unit isp_osinfo._dev.dv_unit
-
-#define SCSI_QFULL 0x28
-
-#define SYS_DELAY(x) delay(x)
-
-#define WATCH_INTERVAL 30
-
-#define FC_FW_READY_DELAY (5 * 1000000)
-#define DEFAULT_LOOPID(x) 107
-#define DEFAULT_WWN(x) (0x1000b00d00000000LL + (x)->isp_osinfo.seed)
-
-extern void isp_attach __P((struct ispsoftc *));
-extern void isp_uninit __P((struct ispsoftc *));
-extern void isp_done __P((ISP_SCSI_XFER_T *));
-
+static inline void
+isp_lock(isp)
+ struct ispsoftc *isp;
+{
+ int s = splbio();
+ if (isp->isp_osinfo.islocked++ == 0) {
+ isp->isp_osinfo.splsaved = s;
+ } else {
+ splx(s);
+ }
+}
-#define ISP_UNSWIZZLE_AND_COPY_PDBP(isp, dest, src) \
- bcopy(src, dest, sizeof (isp_pdb_t))
-#define ISP_SWIZZLE_ICB(a, b)
-#ifdef __sparc__
-#define ISP_SWIZZLE_CONTINUATION(a, b) ISP_SBUSIFY_ISPHDR(a, &(b)->req_header)
-#define ISP_SWIZZLE_REQUEST(a, b) \
- ISP_SBUSIFY_ISPHDR(a, &(b)->req_header); \
- ISP_SBUSIFY_ISPREQ(a, b)
-#define ISP_UNSWIZZLE_RESPONSE(a, b) \
- ISP_SBUSIFY_ISPHDR(a, &(b)->req_header)
-#else
-#define ISP_SWIZZLE_CONTINUATION(a, b)
-#define ISP_SWIZZLE_REQUEST(a, b)
-#define ISP_UNSWIZZLE_RESPONSE(a, b)
-#endif
-#define ISP_SWIZZLE_SNS_REQ(a, b)
-#define ISP_UNSWIZZLE_SNS_RSP(a, b, c)
+static inline void
+isp_unlock(isp)
+ struct ispsoftc *isp;
+{
+ if (isp->isp_osinfo.islocked-- <= 1) {
+ isp->isp_osinfo.islocked = 0;
+ splx(isp->isp_osinfo.splsaved);
+ }
+}
-#define STRNCAT strncat
-static inline char *strncat(char *, const char *, size_t);
static inline char *
-strncat(char *d, const char *s, size_t c)
+strncat(d, s, c)
+ char *d;
+ const char *s;
+ size_t c;
{
char *t = d;
@@ -270,8 +310,63 @@ strncat(char *d, const char *s, size_t c)
return (t);
}
+static inline u_int64_t
+isp_microtime_sub(b, a)
+ struct timeval *b;
+ struct timeval *a;
+{
+ struct timeval x;
+ u_int64_t elapsed;
+ timersub(b, a, &x);
+ elapsed = GET_NANOSEC(&x);
+ if (elapsed == 0)
+ elapsed++;
+ return (elapsed);
+}
+
+static inline void
+isp_wait_complete(isp)
+ struct ispsoftc *isp;
+{
+ if (isp->isp_osinfo.onintstack || isp->isp_osinfo.no_mbox_ints) {
+ int usecs = 0;
+ while (usecs < 2 * 1000000) {
+ (void) isp_intr(isp);
+ if (isp->isp_mboxbsy == 0) {
+ break;
+ }
+ USEC_DELAY(500);
+ usecs += 500;
+ }
+ if (isp->isp_mboxbsy != 0) {
+ isp_prt(isp, ISP_LOGWARN, "Mailbox Cmd (poll) Timeout");
+ }
+ } else {
+ int rv = 0;
+ isp->isp_osinfo.mboxwaiting = 1;
+ while (isp->isp_osinfo.mboxwaiting && rv == 0) {
+ static struct timeval fivesec = { 5, 0 };
+ int timo;
+ struct timeval tv;
+ microtime(&tv);
+ timeradd(&tv, &fivesec, &tv);
+ if ((timo = hzto(&tv)) == 0) {
+ timo = 1;
+ }
+ rv = tsleep(&isp->isp_osinfo.mboxwaiting,
+ PRIBIO, "isp_mboxcmd", timo);
+ }
+ if (rv == EWOULDBLOCK) {
+ isp->isp_mboxbsy = 0;
+ isp->isp_osinfo.mboxwaiting = 0;
+ isp_prt(isp, ISP_LOGWARN, "Mailbox Cmd (intr) Timeout");
+ }
+ }
+}
-#define INLINE inline
+/*
+ * Common inline functions
+ */
#include <dev/ic/isp_inline.h>
-#endif /* _ISP_OPENBSD_H */
+#endif /* _ISP_NETBSD_H */
diff --git a/sys/dev/ic/isp_target.c b/sys/dev/ic/isp_target.c
index d6b7fd14b9e..4718c2b6f61 100644
--- a/sys/dev/ic/isp_target.c
+++ b/sys/dev/ic/isp_target.c
@@ -1,8 +1,8 @@
-/* $OpenBSD: isp_target.c,v 1.2 2000/07/06 05:31:48 mjacob Exp $ */
+/* $OpenBSD: isp_target.c,v 1.3 2000/10/16 01:02:00 mjacob Exp $ */
/*
* Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters.
*
- * Copyright (c) 1999 by Matthew Jacob
+ * Copyright (c) 1999, 2000 by Matthew Jacob
* All rights reserved.
* mjacob@feral.com
*
@@ -12,10 +12,7 @@
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
+ * 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
@@ -49,7 +46,10 @@
#endif
#ifdef ISP_TARGET_MODE
-int isp_tdebug = 0;
+static char *atiocope =
+ "ATIO returned for lun %d because it was in the middle of Bus Device Reset";
+static char *atior =
+ "ATIO returned for lun %d from initiator %d because a Bus Reset occurred";
static void isp_got_msg __P((struct ispsoftc *, int, in_entry_t *));
static void isp_got_msg_fc __P((struct ispsoftc *, int, in_fcentry_t *));
@@ -179,8 +179,8 @@ isp_target_notify(isp, vptr, optrp)
inotp->in_iid &= ~0x80;
}
}
- ITDEBUG(2, ("isp_target_notify: Immediate Notify, "
- "status=0x%x seqid=0x%x\n", status, seqid));
+ isp_prt(isp, ISP_LOGTDEBUG1,
+ "Immediate Notify, status=0x%x seqid=0x%x", status, seqid);
switch (status) {
case IN_RESET:
(void) isp_async(isp, ISPASYNC_BUS_RESET, &bus);
@@ -194,26 +194,29 @@ isp_target_notify(isp, vptr, optrp)
}
break;
case IN_RSRC_UNAVAIL:
- PRINTF("%s: Firmware out of ATIOs\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGWARN, "Firmware out of ATIOs");
break;
case IN_ABORT_TASK:
- PRINTF("%s: Abort Task for Initiator %d RX_ID 0x%x\n",
- isp->isp_name, inot_fcp->in_iid, seqid);
+ isp_prt(isp, ISP_LOGWARN,
+ "Abort Task for Initiator %d RX_ID 0x%x",
+ inot_fcp->in_iid, seqid);
break;
case IN_PORT_LOGOUT:
- PRINTF("%s: Port Logout for Initiator %d RX_ID 0x%x\n",
- isp->isp_name, inot_fcp->in_iid, seqid);
+ isp_prt(isp, ISP_LOGWARN,
+ "Port Logout for Initiator %d RX_ID 0x%x",
+ inot_fcp->in_iid, seqid);
break;
case IN_PORT_CHANGED:
- PRINTF("%s: Port Changed for Initiator %d RX_ID 0x%x\n",
- isp->isp_name, inot_fcp->in_iid, seqid);
+ isp_prt(isp, ISP_LOGWARN,
+ "Port Changed for Initiator %d RX_ID 0x%x",
+ inot_fcp->in_iid, seqid);
break;
case IN_GLOBAL_LOGO:
- PRINTF("%s: All ports logged out\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGWARN, "All ports logged out");
break;
default:
- PRINTF("%s: bad status (0x%x) in isp_target_notify\n",
- isp->isp_name, status);
+ isp_prt(isp, ISP_LOGERR,
+ "bad status (0x%x) in isp_target_notify", status);
break;
}
isp_notify_ack(isp, vptr);
@@ -225,18 +228,19 @@ isp_target_notify(isp, vptr, optrp)
* Immediate Notify entry for some asynchronous event.
*/
if (IS_FC(isp)) {
- ITDEBUG(2, ("%s: Notify Ack status=0x%x seqid 0x%x\n",
- isp->isp_name, nack_fcp->na_status,
- nack_fcp->na_seqid));
+ isp_prt(isp, ISP_LOGTDEBUG1,
+ "Notify Ack status=0x%x seqid 0x%x",
+ nack_fcp->na_status, nack_fcp->na_seqid);
} else {
- ITDEBUG(2, ("%s: Notify Ack event 0x%x status=0x%x "
- "seqid 0x%x\n", isp->isp_name, nackp->na_event,
- nackp->na_status, nackp->na_seqid));
+ isp_prt(isp, ISP_LOGTDEBUG1,
+ "Notify Ack event 0x%x status=0x%x seqid 0x%x",
+ nackp->na_event, nackp->na_status, nackp->na_seqid);
}
break;
default:
- PRINTF("%s: Unknown entry type 0x%x in isp_target_notify",
- isp->isp_name, hdrp->rqs_entry_type);
+ isp_prt(isp, ISP_LOGERR,
+ "Unknown entry type 0x%x in isp_target_notify",
+ hdrp->rqs_entry_type);
rval = -1;
break;
}
@@ -310,8 +314,8 @@ isp_lun_cmd(isp, cmd, bus, tgt, lun, opaque)
}
if (isp_getrqentry(isp, &iptr, &optr, &outp)) {
- PRINTF("%s: Request Queue Overflow in isp_lun_cmd\n",
- isp->isp_name);
+ isp_prt(isp, ISP_LOGWARN,
+ "Request Queue Overflow in isp_lun_cmd");
return (-1);
}
ISP_SWIZ_ENABLE_LUN(isp, outp, &el);
@@ -331,8 +335,8 @@ isp_target_put_entry(isp, ap)
u_int8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
if (isp_getrqentry(isp, &iptr, &optr, &outp)) {
- PRINTF("%s: Request Queue Overflow in isp_target_put_entry "
- "for type 0x%x\n", isp->isp_name, etype);
+ isp_prt(isp, ISP_LOGWARN,
+ "Request Queue Overflow in isp_target_put_entry");
return (-1);
}
switch (etype) {
@@ -349,8 +353,8 @@ isp_target_put_entry(isp, ap)
ISP_SWIZ_CTIO2(isp, outp, ap);
break;
default:
- PRINTF("%s: Unknown type 0x%x in isp_put_entry\n",
- isp->isp_name, etype);
+ isp_prt(isp, ISP_LOGERR,
+ "Unknown type 0x%x in isp_put_entry", etype);
return (-1);
}
@@ -518,22 +522,21 @@ isp_target_async(isp, bus, event)
*/
MEMZERO(&msg, sizeof msg);
if (IS_FC(isp)) {
- msg.nt_iid =
- ((fcparam *)isp->isp_param)->isp_loopid;
+ msg.nt_iid = FCPARAM(isp)->isp_loopid;
} else {
- msg.nt_iid =
- ((sdparam *)isp->isp_param)->isp_initiator_id;
+ msg.nt_iid = SDPARAM(isp)->isp_initiator_id;
}
msg.nt_bus = bus;
msg.nt_msg[0] = MSG_BUS_DEV_RESET;
(void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
break;
default:
- PRINTF("%s: isp_target_async: unknown event 0x%x\n",
- isp->isp_name, event);
+ isp_prt(isp, ISP_LOGERR,
+ "isp_target_async: unknown event 0x%x", event);
break;
}
- isp_notify_ack(isp, NULL);
+ if (isp->isp_state == ISP_RUNSTATE)
+ isp_notify_ack(isp, NULL);
}
@@ -566,8 +569,8 @@ isp_got_msg(isp, bus, inp)
MEMCPY(msg.nt_msg, inp->in_msg, IN_MSGLEN);
(void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg);
} else {
- PRINTF("%s: unknown immediate notify status 0x%x\n",
- isp->isp_name, inp->in_status);
+ isp_prt(isp, ISP_LOGERR,
+ "unknown immediate notify status 0x%x", inp->in_status);
}
}
@@ -580,12 +583,12 @@ isp_got_msg_fc(isp, bus, inp)
int bus;
in_fcentry_t *inp;
{
- static char *f1 = "%s: %s from iid %d lun %d seq 0x%x\n";
+ static char *f1 = "%s from iid %d lun %d seq 0x%x";
static char *f2 =
- "%s: unknown %s 0x%x lun %d iid %d task flags 0x%x seq 0x%x\n";
+ "unknown %s 0x%x lun %d iid %d task flags 0x%x seq 0x%x\n";
if (inp->in_status != IN_MSG_RECEIVED) {
- PRINTF(f2, isp->isp_name, "immediate notify status",
+ isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status",
inp->in_status, inp->in_lun, inp->in_iid,
inp->in_task_flags, inp->in_seqid);
} else {
@@ -602,28 +605,28 @@ isp_got_msg_fc(isp, bus, inp)
msg.nt_tagval = inp->in_seqid;
if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK) {
- PRINTF(f1, isp->isp_name, "ABORT TASK",
+ isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK",
inp->in_iid, inp->in_lun, inp->in_seqid);
msg.nt_msg[0] = MSG_ABORT_TAG;
} else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
- PRINTF(f1, isp->isp_name, "CLEAR TASK SET",
+ isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
inp->in_iid, inp->in_lun, inp->in_seqid);
msg.nt_msg[0] = MSG_CLEAR_QUEUE;
} else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
- PRINTF(f1, isp->isp_name, "TARGET RESET",
+ isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
inp->in_iid, inp->in_lun, inp->in_seqid);
msg.nt_msg[0] = MSG_BUS_DEV_RESET;
} else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
- PRINTF(f1, isp->isp_name, "CLEAR ACA",
+ isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
inp->in_iid, inp->in_lun, inp->in_seqid);
/* ???? */
msg.nt_msg[0] = MSG_REL_RECOVERY;
} else if (inp->in_task_flags & TASK_FLAGS_TERMINATE_TASK) {
- PRINTF(f1, isp->isp_name, "TERMINATE TASK",
+ isp_prt(isp, ISP_LOGINFO, f1, "TERMINATE TASK",
inp->in_iid, inp->in_lun, inp->in_seqid);
msg.nt_msg[0] = MSG_TERM_IO_PROC;
} else {
- PRINTF(f2, isp->isp_name, "task flag",
+ isp_prt(isp, ISP_LOGWARN, f2, "task flag",
inp->in_status, inp->in_lun, inp->in_iid,
inp->in_task_flags, inp->in_seqid);
}
@@ -643,8 +646,8 @@ isp_notify_ack(isp, arg)
void *outp;
if (isp_getrqentry(isp, &iptr, &optr, &outp)) {
- PRINTF("%s: Request Queue Overflow For isp_notify_ack\n",
- isp->isp_name);
+ isp_prt(isp, ISP_LOGWARN,
+ "Request Queue Overflow For isp_notify_ack");
return;
}
@@ -720,8 +723,8 @@ isp_handle_atio(isp, aep)
/*
* ATIO rejected by the firmware due to disabled lun.
*/
- PRINTF("%s: rejected ATIO for disabled lun %d\n",
- isp->isp_name, lun);
+ isp_prt(isp, ISP_LOGERR,
+ "rejected ATIO for disabled lun %d", lun);
break;
case AT_NOCAP:
/*
@@ -729,8 +732,9 @@ isp_handle_atio(isp, aep)
* We sent an ATIO that overflowed the firmware's
* command resource count.
*/
- PRINTF("%s: rejected ATIO for lun %d because of command count"
- " overflow\n", isp->isp_name, lun);
+ isp_prt(isp, ISP_LOGERR,
+ "rejected ATIO for lun %d because of command count"
+ " overflow", lun);
break;
case AT_BDR_MSG:
@@ -743,9 +747,7 @@ isp_handle_atio(isp, aep)
* not increment it. Therefore we should never get
* this status here.
*/
- PRINTF("%s: ATIO returned for lun %d because it was in the "
- " middle of coping with a Bus Device Reset\n",
- isp->isp_name, lun);
+ isp_prt(isp, ISP_LOGERR, atiocope, lun);
break;
case AT_CDB: /* Got a CDB */
@@ -765,15 +767,14 @@ isp_handle_atio(isp, aep)
* Ignore it because the async event will clear things
* up for us.
*/
- PRINTF("%s: ATIO returned for lun %d from initiator %d because"
- " a Bus Reset occurred\n", isp->isp_name, lun,
- aep->at_iid);
+ isp_prt(isp, ISP_LOGWARN, atior, lun, aep->at_iid);
break;
default:
- PRINTF("%s: Unknown ATIO status 0x%x from initiator %d for lun"
- " %d\n", isp->isp_name, aep->at_status, aep->at_iid, lun);
+ isp_prt(isp, ISP_LOGERR,
+ "Unknown ATIO status 0x%x from initiator %d for lun %d",
+ aep->at_status, aep->at_iid, lun);
(void) isp_target_put_atio(isp, aep->at_iid, aep->at_tgt,
lun, aep->at_tag_type, aep->at_tag_val);
break;
@@ -810,8 +811,8 @@ isp_handle_atio2(isp, aep)
/*
* ATIO rejected by the firmware due to disabled lun.
*/
- PRINTF("%s: rejected ATIO2 for disabled lun %d\n",
- isp->isp_name, lun);
+ isp_prt(isp, ISP_LOGERR,
+ "rejected ATIO2 for disabled lun %d", lun);
break;
case AT_NOCAP:
/*
@@ -819,8 +820,8 @@ isp_handle_atio2(isp, aep)
* We sent an ATIO that overflowed the firmware's
* command resource count.
*/
- PRINTF("%s: rejected ATIO2 for lun %d because of command count"
- " overflow\n", isp->isp_name, lun);
+ isp_prt(isp, ISP_LOGERR,
+ "rejected ATIO2 for lun %d- command count overflow", lun);
break;
case AT_BDR_MSG:
@@ -833,9 +834,7 @@ isp_handle_atio2(isp, aep)
* not increment it. Therefore we should never get
* this status here.
*/
- PRINTF("%s: ATIO2 returned for lun %d because it was in the "
- " middle of coping with a Bus Device Reset\n",
- isp->isp_name, lun);
+ isp_prt(isp, ISP_LOGERR, atiocope, lun);
break;
case AT_CDB: /* Got a CDB */
@@ -854,15 +853,14 @@ isp_handle_atio2(isp, aep)
* Ignore it because the async event will clear things
* up for us.
*/
- PRINTF("%s: ATIO2 returned for lun %d from initiator %d because"
- " a Bus Reset occurred\n", isp->isp_name, lun,
- aep->at_iid);
+ isp_prt(isp, ISP_LOGERR, atior, lun, aep->at_iid);
break;
default:
- PRINTF("%s: Unknown ATIO2 status 0x%x from initiator %d for lun"
- " %d\n", isp->isp_name, aep->at_status, aep->at_iid, lun);
+ isp_prt(isp, ISP_LOGERR,
+ "Unknown ATIO2 status 0x%x from initiator %d for lun %d",
+ aep->at_status, aep->at_iid, lun);
(void) isp_target_put_atio(isp, aep->at_iid, 0, lun, 0, 0);
break;
}
@@ -873,16 +871,16 @@ isp_handle_ctio(isp, ct)
struct ispsoftc *isp;
ct_entry_t *ct;
{
- ISP_SCSI_XFER_T *xs;
- int pl = 0;
+ XS_T *xs;
+ int pl = ISP_LOGTDEBUG2;
char *fmsg = NULL;
if (ct->ct_reserved) {
xs = isp_find_xs(isp, ct->ct_reserved);
if (xs == NULL)
- pl = 0;
+ pl = ISP_LOGALL;
} else {
- pl = 2;
+ pl = ISP_LOGTDEBUG1;
xs = NULL;
}
@@ -902,8 +900,8 @@ isp_handle_ctio(isp, ct)
/*
* Nothing to do in this case.
*/
- IDPRINTF(pl, ("%s:CTIO- iid %d disconnected OK\n",
- isp->isp_name, ct->ct_iid));
+ isp_prt(isp, pl, "CTIO- iid %d disconnected OK",
+ ct->ct_iid);
return;
}
break;
@@ -933,7 +931,7 @@ isp_handle_ctio(isp, ct)
if (fmsg == NULL)
fmsg = "ABORT TASK sent by Initiator";
- PRINTF("%s: CTIO destroyed by %s\n", isp->isp_name, fmsg);
+ isp_prt(isp, ISP_LOGWARN, "CTIO destroyed by %s", fmsg);
break;
case CT_INVAL:
@@ -941,8 +939,9 @@ isp_handle_ctio(isp, ct)
* CTIO rejected by the firmware due to disabled lun.
* "Cannot Happen".
*/
- PRINTF("%s: Firmware rejected CTIO for disabled lun %d\n",
- isp->isp_name, ct->ct_lun);
+ isp_prt(isp, ISP_LOGERR,
+ "Firmware rejected CTIO for disabled lun %d",
+ ct->ct_lun);
break;
case CT_NOPATH:
@@ -952,8 +951,9 @@ isp_handle_ctio(isp, ct)
* we tried to access the bus while a non-disconnecting
* command is in process.
*/
- PRINTF("%s: Firmware rejected CTIO for bad nexus %d/%d/%d\n",
- isp->isp_name, ct->ct_iid, ct->ct_tgt, ct->ct_lun);
+ isp_prt(isp, ISP_LOGERR,
+ "Firmware rejected CTIO for bad nexus %d/%d/%d",
+ ct->ct_iid, ct->ct_tgt, ct->ct_lun);
break;
case CT_RSELTMO:
@@ -962,7 +962,7 @@ isp_handle_ctio(isp, ct)
case CT_TIMEOUT:
if (fmsg == NULL)
fmsg = "Command";
- PRINTF("%s: Firmware timed out on %s\n", isp->isp_name, fmsg);
+ isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
break;
case CT_ERR:
@@ -980,7 +980,7 @@ isp_handle_ctio(isp, ct)
if (fmsg == NULL)
fmsg = "unacknowledged Immediate Notify pending";
- PRINTF("%s: CTIO returned by f/w- %s\n", isp->isp_name, fmsg);
+ isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
#if 0
if (status & SENSEVALID) {
bcopy((caddr_t) (cep + CTIO_SENSE_OFFSET),
@@ -991,7 +991,7 @@ isp_handle_ctio(isp, ct)
#endif
break;
default:
- PRINTF("%s: Unknown CTIO status 0x%x\n", isp->isp_name,
+ isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
ct->ct_status & ~QLTM_SVALID);
break;
}
@@ -1006,19 +1006,16 @@ isp_handle_ctio(isp, ct)
*/
if (ct->ct_reserved == 0) {
if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
- IDPRINTF(pl,
- ("%s: intermediate CTIO completed ok\n",
- isp->isp_name));
+ isp_prt(isp, pl,
+ "intermediate CTIO completed ok");
} else {
- IDPRINTF(pl,
- ("%s: unmonitored CTIO completed ok\n",
- isp->isp_name));
+ isp_prt(isp, pl,
+ "unmonitored CTIO completed ok");
}
} else {
- IDPRINTF(pl,
- ("%s: NO xs for CTIO (handle 0x%x) status 0x%x\n",
- isp->isp_name, ct->ct_reserved,
- ct->ct_status & ~QLTM_SVALID));
+ isp_prt(isp, pl,
+ "NO xs for CTIO (handle 0x%x) status 0x%x",
+ ct->ct_reserved, ct->ct_status & ~QLTM_SVALID);
}
} else {
if (ct->ct_flags & CT_SENDSTATUS) {
@@ -1030,15 +1027,13 @@ isp_handle_ctio(isp, ct)
* only there can we do the appropriate command
* complete thread synchronization.
*/
- IDPRINTF(pl,
- ("%s:status CTIO complete\n", isp->isp_name));
+ isp_prt(isp, pl, "status CTIO complete");
} else {
/*
* Final CTIO completed. Release DMA resources and
* notify platform dependent layers.
*/
- IDPRINTF(pl,
- ("%s: data CTIO complete\n", isp->isp_name));
+ isp_prt(isp, pl, "data CTIO complete");
ISP_DMAFREE(isp, xs, ct->ct_reserved);
}
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
@@ -1053,16 +1048,16 @@ isp_handle_ctio2(isp, ct)
struct ispsoftc *isp;
ct2_entry_t *ct;
{
- ISP_SCSI_XFER_T *xs;
- int pl = 3;
+ XS_T *xs;
+ int pl = ISP_LOGTDEBUG2;
char *fmsg = NULL;
if (ct->ct_reserved) {
xs = isp_find_xs(isp, ct->ct_reserved);
if (xs == NULL)
- pl = 0;
+ pl = ISP_LOGALL;
} else {
- pl = 2;
+ pl = ISP_LOGTDEBUG1;
xs = NULL;
}
@@ -1102,14 +1097,14 @@ isp_handle_ctio2(isp, ct)
if (fmsg == NULL)
fmsg = "ABORT TASK sent by Initiator";
- PRINTF("%s: CTIO2 destroyed by %s\n", isp->isp_name, fmsg);
+ isp_prt(isp, ISP_LOGERR, "CTIO2 destroyed by %s", fmsg);
break;
case CT_INVAL:
/*
* CTIO rejected by the firmware - invalid data direction.
*/
- PRINTF("%s: CTIO2 had wrong data directiond\n", isp->isp_name);
+ isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data directiond");
break;
case CT_NOPATH:
@@ -1119,8 +1114,9 @@ isp_handle_ctio2(isp, ct)
* we tried to access the bus while a non-disconnecting
* command is in process.
*/
- PRINTF("%s: Firmware rejected CTIO2 for bad nexus %d->%d\n",
- isp->isp_name, ct->ct_iid, ct->ct_lun);
+ isp_prt(isp, ISP_LOGERR,
+ "Firmware rejected CTIO2 for bad nexus %d->%d",
+ ct->ct_iid, ct->ct_lun);
break;
case CT_RSELTMO:
@@ -1129,7 +1125,7 @@ isp_handle_ctio2(isp, ct)
case CT_TIMEOUT:
if (fmsg == NULL)
fmsg = "Command";
- PRINTF("%s: Firmware timed out on %s\n", isp->isp_name, fmsg);
+ isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
break;
case CT_ERR:
@@ -1154,7 +1150,7 @@ isp_handle_ctio2(isp, ct)
if (fmsg == NULL)
fmsg = "unacknowledged Immediate Notify pending";
- PRINTF("%s: CTIO returned by f/w- %s\n", isp->isp_name, fmsg);
+ isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
#if 0
if (status & SENSEVALID) {
bcopy((caddr_t) (cep + CTIO_SENSE_OFFSET),
@@ -1170,13 +1166,13 @@ isp_handle_ctio2(isp, ct)
* CTIO rejected by the firmware because an invalid RX_ID.
* Just print a message.
*/
- PRINTF("%s: CTIO2 completed with Invalid RX_ID 0x%x\n",
- isp->isp_name, ct->ct_rxid);
+ isp_prt(isp, ISP_LOGERR,
+ "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
break;
default:
- IDPRINTF(pl, ("%s: Unknown CTIO status 0x%x\n", isp->isp_name,
- ct->ct_status & ~QLTM_SVALID));
+ isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
+ ct->ct_status & ~QLTM_SVALID);
break;
}
@@ -1190,19 +1186,16 @@ isp_handle_ctio2(isp, ct)
*/
if (ct->ct_reserved == 0) {
if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
- IDPRINTF(pl,
- ("%s: intermediate CTIO completed ok\n",
- isp->isp_name));
+ isp_prt(isp, pl,
+ "intermediate CTIO completed ok");
} else {
- IDPRINTF(pl,
- ("%s: unmonitored CTIO completed ok\n",
- isp->isp_name));
+ isp_prt(isp, pl,
+ "unmonitored CTIO completed ok");
}
} else {
- IDPRINTF(pl,
- ("%s: NO xs for CTIO (handle 0x%x) status 0x%x\n",
- isp->isp_name, ct->ct_reserved,
- ct->ct_status & ~QLTM_SVALID));
+ isp_prt(isp, pl,
+ "NO xs for CTIO (handle 0x%x) status 0x%x",
+ ct->ct_reserved, ct->ct_status & ~QLTM_SVALID);
}
} else {
if (ct->ct_flags & CT_SENDSTATUS) {
@@ -1214,15 +1207,13 @@ isp_handle_ctio2(isp, ct)
* only there can we do the appropriate command
* complete thread synchronization.
*/
- IDPRINTF(pl,
- ("%s: status CTIO complete\n", isp->isp_name));
+ isp_prt(isp, pl, "status CTIO complete");
} else {
/*
* Final CTIO completed. Release DMA resources and
* notify platform dependent layers.
*/
- IDPRINTF(pl,
- ("%s: data CTIO complete\n", isp->isp_name));
+ isp_prt(isp, pl, "data CTIO complete");
ISP_DMAFREE(isp, xs, ct->ct_reserved);
}
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
diff --git a/sys/dev/ic/isp_target.h b/sys/dev/ic/isp_target.h
index 725a9dfb2e7..03c4e3135dc 100644
--- a/sys/dev/ic/isp_target.h
+++ b/sys/dev/ic/isp_target.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: isp_target.h,v 1.2 2000/07/06 05:31:48 mjacob Exp $ */
+/* $OpenBSD: isp_target.h,v 1.3 2000/10/16 01:02:00 mjacob Exp $ */
/*
* Qlogic Target Mode Structure and Flag Definitions
*
@@ -7,7 +7,7 @@
* pms@psconsult.com
* All rights reserved.
*
- * Additional Copyright (c) 1999
+ * Additional Copyright (c) 1999< 2000
* Matthew Jacob
* mjacob@feral.com
* All rights reserved.
@@ -19,10 +19,7 @@
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
+ * 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
@@ -129,6 +126,7 @@ typedef struct {
/*
* Values for the in_status field
*/
+#define IN_REJECT 0x0D /* Message Reject message received */
#define IN_RESET 0x0E /* Bus Reset occurred */
#define IN_NO_RCAP 0x16 /* requested capability not available */
#define IN_IDE_RECEIVED 0x33 /* Initiator Detected Error msg received */
@@ -138,6 +136,7 @@ typedef struct {
#define IN_PORT_LOGOUT 0x29 /* port has logged out (FC) */
#define IN_PORT_CHANGED 0x2A /* port changed */
#define IN_GLOBAL_LOGO 0x2E /* all ports logged out */
+#define IN_NO_NEXUS 0x3B /* Nexus not established */
/*
* Values for the in_task_flags field- should only get one at a time!
@@ -323,6 +322,7 @@ typedef struct {
#define CT_NO_DATA 0x000000C0 /* bits 6&7, Data direction */
#define CT_CCINCR 0x00000100 /* bit 8, autoincrement atio count */
#define CT_DATAMASK 0x000000C0 /* bits 6&7, Data direction */
+#define CT_INISYNCWIDE 0x00004000 /* bit 14, Do Sync/Wide Negotiation */
#define CT_NODISC 0x00008000 /* bit 15, Disconnects disabled */
#define CT_DSDP 0x01000000 /* bit 24, Disable Save Data Pointers */
#define CT_SENDRDP 0x04000000 /* bit 26, Send Restore Pointers msg */
@@ -341,12 +341,15 @@ typedef struct {
#define CT_RSELTMO 0x0A /* reselection timeout after 2 tries */
#define CT_TIMEOUT 0x0B /* timed out */
#define CT_RESET 0x0E /* SCSI Bus Reset occurred */
+#define CT_PARITY 0x0F /* Uncorrectable Parity Error */
+#define CT_PANIC 0x13 /* Unrecoverable Error */
#define CT_PHASE_ERROR 0x14 /* Bus phase sequence error */
#define CT_BDR_MSG 0x17 /* Bus Device Reset msg received */
#define CT_TERMINATED 0x19 /* due to Terminate Transfer mbox cmd */
#define CT_PORTNOTAVAIL 0x28 /* port not available */
#define CT_LOGOUT 0x29 /* port logout */
#define CT_PORTCHANGED 0x2A /* port changed */
+#define CT_IDE 0x33 /* Initiator Detected Error */
#define CT_NOACK 0x35 /* Outstanding Immed. Notify. entry */
/*
@@ -502,7 +505,7 @@ typedef struct {
#define ISP_SWIZ_CTIO(isp, dest, vsrc) \
{ \
- ct_entry_t *source = (ct_entry-t *) vsrc; \
+ ct_entry_t *source = (ct_entry_t *) vsrc; \
ct_entry_t *local, *vdst; \
if ((void *)dest == (void *)vsrc) { \
MEMCPY(vsrc, &local, sizeof (ct_entry_t)); \
@@ -605,11 +608,8 @@ typedef struct {
* Debug macros
*/
-extern int isp_tdebug;
#define ISP_TDQE(isp, msg, idx, arg) \
- if (isp_tdebug > 3) isp_print_qentry(isp, msg, idx, arg)
-
-#define ITDEBUG(level, msg) if (isp_tdebug >= level) PRINTF msg
+ if (isp->isp_dblev & ISP_LOGTDEBUG2) isp_print_qentry(isp, msg, idx, arg)
/*
* The functions below are target mode functions that
@@ -624,7 +624,7 @@ int isp_target_notify __P((struct ispsoftc *, void *, u_int16_t *));
/*
* Enable/Disable/Modify a logical unit.
*/
-#define DFLT_CMD_CNT (RESULT_QUEUE_LEN >> 1)
+#define DFLT_CMD_CNT 32 /* XX */
#define DFLT_INOTIFY (4)
int isp_lun_cmd __P((struct ispsoftc *, int, int, int, int, u_int32_t));
diff --git a/sys/dev/ic/ispmbox.h b/sys/dev/ic/ispmbox.h
index 1d298dbd751..0186e830b52 100644
--- a/sys/dev/ic/ispmbox.h
+++ b/sys/dev/ic/ispmbox.h
@@ -1,12 +1,9 @@
-/* $OpenBSD: ispmbox.h,v 1.9 2000/07/06 05:31:49 mjacob Exp $ */
+/* $OpenBSD: ispmbox.h,v 1.10 2000/10/16 01:02:01 mjacob Exp $ */
/*
* Mailbox and Queue Entry Definitions for for Qlogic ISP SCSI adapters.
*
- *---------------------------------------
- * Copyright (c) 1997, 1998, 1999 by Matthew Jacob
- * NASA/Ames Research Center
+ * Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob
* All rights reserved.
- *---------------------------------------
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -14,10 +11,7 @@
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
+ * 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
@@ -160,6 +154,9 @@ typedef struct {
#define MBOX_LOOP_ID_USED 0x4008
#define MBOX_ALL_IDS_USED 0x4009
#define MBOX_NOT_LOGGED_IN 0x400A
+#define MBLOGALL 0x000f
+#define MBLOGNONE 0x0000
+#define MBLOGMASK(x) ((x) & 0xf)
/*
* Asynchronous event status codes
@@ -371,7 +368,7 @@ typedef struct {
#define req_response_len req_time /* FC only */
u_int16_t req_sense_len;
u_int32_t req_resid;
- u_int8_t _res1[8];
+ u_int8_t req_response[8]; /* FC only */
u_int8_t req_sense_data[32];
} ispstatusreq_t;
@@ -381,20 +378,25 @@ typedef struct {
*/
#define RQCS_RU 0x800 /* Residual Under */
#define RQCS_RO 0x400 /* Residual Over */
+#define RQCS_RESID (RQCS_RU|RQCS_RO)
#define RQCS_SV 0x200 /* Sense Length Valid */
-#define RQCS_RV 0x100 /* Residual Valid */
+#define RQCS_RV 0x100 /* FCP Response Length Valid */
/*
* Completion Status Codes.
*/
#define RQCS_COMPLETE 0x0000
-#define RQCS_INCOMPLETE 0x0001
#define RQCS_DMA_ERROR 0x0002
-#define RQCS_TRANSPORT_ERROR 0x0003
#define RQCS_RESET_OCCURRED 0x0004
#define RQCS_ABORTED 0x0005
#define RQCS_TIMEOUT 0x0006
#define RQCS_DATA_OVERRUN 0x0007
+#define RQCS_DATA_UNDERRUN 0x0015
+#define RQCS_QUEUE_FULL 0x001C
+
+/* 1X00 Only Completion Codes */
+#define RQCS_INCOMPLETE 0x0001
+#define RQCS_TRANSPORT_ERROR 0x0003
#define RQCS_COMMAND_OVERRUN 0x0008
#define RQCS_STATUS_OVERRUN 0x0009
#define RQCS_BAD_MESSAGE 0x000a
@@ -408,26 +410,24 @@ typedef struct {
#define RQCS_DEVICE_RESET_MSG_FAILED 0x0012
#define RQCS_ID_MSG_FAILED 0x0013
#define RQCS_UNEXP_BUS_FREE 0x0014
-#define RQCS_DATA_UNDERRUN 0x0015
#define RQCS_XACT_ERR1 0x0018
#define RQCS_XACT_ERR2 0x0019
#define RQCS_XACT_ERR3 0x001A
#define RQCS_BAD_ENTRY 0x001B
-#define RQCS_QUEUE_FULL 0x001C
#define RQCS_PHASE_SKIPPED 0x001D
#define RQCS_ARQS_FAILED 0x001E
#define RQCS_WIDE_FAILED 0x001F
#define RQCS_SYNCXFER_FAILED 0x0020
#define RQCS_LVD_BUSERR 0x0021
-/* 2100 Only Completion Codes */
+/* 2X00 Only Completion Codes */
#define RQCS_PORT_UNAVAILABLE 0x0028
#define RQCS_PORT_LOGGED_OUT 0x0029
#define RQCS_PORT_CHANGED 0x002A
#define RQCS_PORT_BUSY 0x002B
/*
- * State Flags (not applicable to 2100)
+ * 1X00 specific State Flags
*/
#define RQSF_GOT_BUS 0x0100
#define RQSF_GOT_TARGET 0x0200
@@ -438,7 +438,7 @@ typedef struct {
#define RQSF_XFER_COMPLETE 0x4000
/*
- * Status Flags (not applicable to 2100)
+ * 1X00 Status Flags
*/
#define RQSTF_DISCONNECT 0x0001
#define RQSTF_SYNCHRONOUS 0x0002
@@ -450,6 +450,29 @@ typedef struct {
#define RQSTF_NEGOTIATION 0x0080
/*
+ * 2X00 specific state flags
+ */
+/* RQSF_SENT_CDB */
+/* RQSF_XFRD_DATA */
+/* RQSF_GOT_STATUS */
+/* RQSF_XFER_COMPLETE */
+
+/*
+ * 2X00 specific status flags
+ */
+/* RQSTF_ABORTED */
+/* RQSTF_TIMEOUT */
+#define RQSTF_DMA_ERROR 0x0080
+#define RQSTF_LOGOUT 0x2000
+
+/*
+ * Miscellaneous
+ */
+#ifndef ISP_EXEC_THROTTLE
+#define ISP_EXEC_THROTTLE 16
+#endif
+
+/*
* FC (ISP2100) specific data structures
*/
diff --git a/sys/dev/ic/ispreg.h b/sys/dev/ic/ispreg.h
index bacf424cb8f..ab985321f61 100644
--- a/sys/dev/ic/ispreg.h
+++ b/sys/dev/ic/ispreg.h
@@ -1,10 +1,9 @@
-/* $OpenBSD: ispreg.h,v 1.8 2000/07/06 05:31:49 mjacob Exp $ */
+/* $OpenBSD: ispreg.h,v 1.9 2000/10/16 01:02:01 mjacob Exp $ */
/*
* Machine Independent (well, as best as possible) register
* definitions for Qlogic ISP SCSI adapters.
*
- * Copyright (c) 1997, 1998, 1999 by Matthew Jacob
- * NASA/Ames Research Center
+ * Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -13,10 +12,7 @@
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
+ * 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
@@ -79,6 +75,9 @@
#define ISP1080_DMA_REGS_OFF 0x60
#define DMA_REGS_OFF 0x00 /* same as BIU block */
+#define SBUS_REGSIZE 0x450
+#define PCI_REGSIZE 0x100
+
/*
* NB: The *_BLOCK definitions have no specific hardware meaning.
* They serve simply to note to the MD layer which block of
diff --git a/sys/dev/ic/ispvar.h b/sys/dev/ic/ispvar.h
index b87c8e8d1e1..c0daaa3ab6b 100644
--- a/sys/dev/ic/ispvar.h
+++ b/sys/dev/ic/ispvar.h
@@ -1,22 +1,17 @@
-/* $OpenBSD: ispvar.h,v 1.11 2000/07/06 05:31:49 mjacob Exp $ */
+/* $OpenBSD: ispvar.h,v 1.12 2000/10/16 01:02:01 mjacob Exp $ */
/*
* Soft Definitions for for Qlogic ISP SCSI adapters.
*
- *---------------------------------------
- * Copyright (c) 1997, 1998, 1999 by Matthew Jacob
- * NASA/Ames Research Center
+ * Copyright (c) 1997, 1998, 1999, 2000 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 immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
+ * 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
@@ -58,8 +53,8 @@
#endif
#endif
-#define ISP_CORE_VERSION_MAJOR 1
-#define ISP_CORE_VERSION_MINOR 16
+#define ISP_CORE_VERSION_MAJOR 2
+#define ISP_CORE_VERSION_MINOR 0
/*
* Vector for bus specific code to provide specific services.
@@ -70,23 +65,20 @@ struct ispmdvec {
void (*dv_wr_reg) __P((struct ispsoftc *, int, u_int16_t));
int (*dv_mbxdma) __P((struct ispsoftc *));
int (*dv_dmaset) __P((struct ispsoftc *,
- ISP_SCSI_XFER_T *, ispreq_t *, u_int16_t *, u_int16_t));
+ XS_T *, ispreq_t *, u_int16_t *, u_int16_t));
void (*dv_dmaclr)
- __P((struct ispsoftc *, ISP_SCSI_XFER_T *, u_int32_t));
+ __P((struct ispsoftc *, XS_T *, u_int32_t));
void (*dv_reset0) __P((struct ispsoftc *));
void (*dv_reset1) __P((struct ispsoftc *));
- void (*dv_dregs) __P((struct ispsoftc *));
+ void (*dv_dregs) __P((struct ispsoftc *, const char *));
const u_int16_t *dv_ispfw; /* ptr to f/w */
- u_int16_t dv_fwlen; /* length of f/w */
- u_int16_t dv_codeorg; /* code ORG for f/w */
- u_int32_t dv_fwrev; /* f/w revision */
- /*
- * Initial values for conf1 register
- */
u_int16_t dv_conf1;
u_int16_t dv_clock; /* clock frequency */
};
+/*
+ * Overall parameters
+ */
#define MAX_TARGETS 16
#ifdef ISP2100_FABRIC
#define MAX_FC_TARG 256
@@ -99,7 +91,8 @@ struct ispmdvec {
/*
- * Macros to read, write ISP registers through bus specific code.
+ * Macros to access ISP registers through bus specific layers-
+ * mostly wrappers to vector through the mdvec structure.
*/
#define ISP_READ(isp, reg) \
@@ -122,8 +115,8 @@ struct ispmdvec {
if ((isp)->isp_mdvec->dv_reset0) (*(isp)->isp_mdvec->dv_reset0)((isp))
#define ISP_RESET1(isp) \
if ((isp)->isp_mdvec->dv_reset1) (*(isp)->isp_mdvec->dv_reset1)((isp))
-#define ISP_DUMPREGS(isp) \
- if ((isp)->isp_mdvec->dv_dregs) (*(isp)->isp_mdvec->dv_dregs)((isp))
+#define ISP_DUMPREGS(isp, m) \
+ if ((isp)->isp_mdvec->dv_dregs) (*(isp)->isp_mdvec->dv_dregs)((isp),(m))
#define ISP_SETBITS(isp, reg, val) \
(*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) | (val))
@@ -131,25 +124,41 @@ struct ispmdvec {
#define ISP_CLRBITS(isp, reg, val) \
(*(isp)->isp_mdvec->dv_wr_reg)((isp), (reg), ISP_READ((isp), (reg)) & ~(val))
-/* this is the size of a queue entry (request and response) */
+/*
+ * The MEMORYBARRIER macro is defined per platform (to provide synchronization
+ * on Request and Response Queues, Scratch DMA areas, and Registers)
+ *
+ * Defined Memory Barrier Synchronization Types
+ */
+#define SYNC_REQUEST 0 /* request queue synchronization */
+#define SYNC_RESULT 1 /* result queue synchronization */
+#define SYNC_SFORDEV 2 /* scratch, sync for ISP */
+#define SYNC_SFORCPU 3 /* scratch, sync for CPU */
+#define SYNC_REG 4 /* for registers */
+
+/*
+ * Request/Response Queue defines and macros.
+ * The maximum is defined per platform (and can be based on board type).
+ */
+/* This is the size of a queue entry (request and response) */
#define QENTRY_LEN 64
-/* both request and result queue length must be a power of two */
-#define RQUEST_QUEUE_LEN MAXISPREQUEST
-/* I've seen wierdnesses with the result queue < 64 */
-#if MAXISPREQUEST > 64
-#define RESULT_QUEUE_LEN (MAXISPREQUEST/2)
-#else
-#define RESULT_QUEUE_LEN MAXISPREQUEST
-#endif
+/* Both request and result queue length must be a power of two */
+#define RQUEST_QUEUE_LEN(x) MAXISPREQUEST(x)
+#define RESULT_QUEUE_LEN(x) \
+ (((MAXISPREQUEST(x) >> 2) < 64)? 64 : MAXISPREQUEST(x) >> 2)
#define ISP_QUEUE_ENTRY(q, idx) ((q) + ((idx) * QENTRY_LEN))
#define ISP_QUEUE_SIZE(n) ((n) * QENTRY_LEN)
#define ISP_NXT_QENTRY(idx, qlen) (((idx) + 1) & ((qlen)-1))
-#define ISP_QAVAIL(in, out, qlen) \
+#define ISP_QFREE(in, out, qlen) \
((in == out)? (qlen - 1) : ((in > out)? \
((qlen - 1) - (in - out)) : (out - in - 1)))
+#define ISP_QAVAIL(isp) \
+ ISP_QFREE(isp->isp_reqidx, isp->isp_reqodx, RQUEST_QUEUE_LEN(isp))
#define ISP_ADD_REQUEST(isp, iptr) \
- ISP_WRITE(isp, INMAILBOX4, iptr), isp->isp_reqidx = iptr
+ MEMORYBARRIER(isp, SYNC_REQUEST, iptr, QENTRY_LEN); \
+ ISP_WRITE(isp, INMAILBOX4, iptr); \
+ isp->isp_reqidx = iptr
/*
* SCSI Specific Host Adapter Parameters- per bus, per target
@@ -165,7 +174,7 @@ typedef struct {
isp_ultramode : 1,
isp_diffmode : 1,
isp_lvdmode : 1,
- : 1,
+ isp_fast_mttr : 1, /* fast sram */
isp_initiator_id : 4,
isp_async_data_setup : 4;
u_int16_t isp_selection_timeout;
@@ -200,15 +209,18 @@ typedef struct {
#define DPARM_ARQ 0x0400
#define DPARM_QFRZ 0x0200
#define DPARM_RENEG 0x0100
-#define DPARM_NARROW 0x0080 /* Possibly only available with >= 7.55 fw */
-#define DPARM_ASYNC 0x0040 /* Possibly only available with >= 7.55 fw */
+#define DPARM_NARROW 0x0080
+#define DPARM_ASYNC 0x0040
+#define DPARM_PPR 0x0020
#define DPARM_DEFAULT (0xFF00 & ~DPARM_QFRZ)
#define DPARM_SAFE_DFLT (DPARM_DEFAULT & ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING))
/* technically, not really correct, as they need to be rated based upon clock */
-#define ISP_40M_SYNCPARMS 0x080a
-#define ISP_20M_SYNCPARMS 0x080c
+#define ISP_80M_SYNCPARMS 0x0c09
+#define ISP_40M_SYNCPARMS 0x0c0a
+#define ISP_20M_SYNCPARMS 0x0c0c
+#define ISP_20M_SYNCPARMS_1040 0x080c
#define ISP_10M_SYNCPARMS 0x0c19
#define ISP_08M_SYNCPARMS 0x0c25
#define ISP_05M_SYNCPARMS 0x0c32
@@ -293,7 +305,7 @@ typedef struct {
/*
* Soft Structure per host adapter
*/
-struct ispsoftc {
+typedef struct ispsoftc {
/*
* Platform (OS) specific data
*/
@@ -317,12 +329,12 @@ struct ispsoftc {
u_int8_t isp_revision; /* HBA Chip H/W Revision */
u_int32_t isp_maxluns; /* maximum luns supported */
- u_int32_t : 4,
+ u_int32_t
isp_touched : 1, /* board ever seen? */
- isp_fast_mttr : 1, /* fast sram */
- isp_bustype : 1, /* SBus or PCI */
: 1,
- isp_dblev : 8, /* debug level */
+ isp_bustype : 1, /* SBus or PCI */
+ isp_loaded_fw : 1, /* loaded firmware */
+ isp_dblev : 12, /* debug log mask */
isp_clock : 8, /* input clock */
isp_confopts : 8; /* config options */
@@ -346,7 +358,7 @@ struct ispsoftc {
/*
* Active commands are stored here, indexed by handle functions.
*/
- ISP_SCSI_XFER_T **isp_xflist;
+ XS_T **isp_xflist;
/*
* request/result queue pointers and dma handles for them.
@@ -355,13 +367,13 @@ struct ispsoftc {
caddr_t isp_result;
u_int32_t isp_rquest_dma;
u_int32_t isp_result_dma;
-};
+} ispsoftc_t;
#define SDPARAM(isp) ((sdparam *) (isp)->isp_param)
#define FCPARAM(isp) ((fcparam *) (isp)->isp_param)
/*
- * ISP States
+ * ISP Driver Run States
*/
#define ISP_NILSTATE 0
#define ISP_RESETSTATE 1
@@ -377,6 +389,10 @@ struct ispsoftc {
#define ISP_CFG_OWNWWN 0x02 /* override NVRAM wwn */
#define ISP_CFG_NPORT 0x04 /* try to force N- instead of L-Port */
+/*
+ * Firmware related defines
+ */
+#define ISP_CODE_ORG 0x1000 /* default f/w code start */
#define ISP_FW_REV(maj, min, mic) ((maj << 24) | (min << 16) | mic)
#define ISP_FW_REVX(xp) ((xp[0]<<24) | (xp[1] << 16) | xp[2])
@@ -420,9 +436,14 @@ struct ispsoftc {
#define IS_2100(isp) (isp->isp_type == ISP_HA_FC_2100)
#define IS_2200(isp) (isp->isp_type == ISP_HA_FC_2200)
+/*
+ * DMA cookie macros
+ */
+#define DMA_MSW(x) (((x) >> 16) & 0xffff)
+#define DMA_LSW(x) (((x) & 0xffff))
/*
- * Function Prototypes
+ * Core System Function Prototypes
*/
/*
@@ -439,7 +460,7 @@ void isp_init __P((struct ispsoftc *));
/*
* Reset the ISP and call completion for any orphaned commands.
*/
-void isp_restart __P((struct ispsoftc *));
+void isp_reinit __P((struct ispsoftc *));
/*
* Interrupt Service Routine
@@ -447,9 +468,19 @@ void isp_restart __P((struct ispsoftc *));
int isp_intr __P((void *));
/*
- * Command Entry Point
+ * Command Entry Point- Platform Dependent layers call into this
*/
-int32_t ispscsicmd __P((ISP_SCSI_XFER_T *));
+int isp_start __P((XS_T *));
+/* these values are what isp_start returns */
+#define CMD_COMPLETE 101 /* command completed */
+#define CMD_EAGAIN 102 /* busy- maybe retry later */
+#define CMD_QUEUED 103 /* command has been queued for execution */
+#define CMD_RQLATER 104 /* requeue this command later */
+
+/*
+ * Command Completion Point- Core layers call out from this with completed cmds
+ */
+void isp_done __P((XS_T *));
/*
* Platform Dependent to External to Internal Control Function
@@ -492,8 +523,137 @@ typedef enum {
int isp_async __P((struct ispsoftc *, ispasync_t, void *));
/*
- * lost command routine (XXXX IN TRANSITION XXXX)
+ * Platform Dependent Error and Debug Printout
*/
-void isp_lostcmd __P((struct ispsoftc *, ISP_SCSI_XFER_T *));
+void isp_prt __P((struct ispsoftc *, int level, const char *, ...));
+#define ISP_LOGALL 0x0 /* log always */
+#define ISP_LOGCONFIG 0x1 /* log configuration messages */
+#define ISP_LOGINFO 0x2 /* log informational messages */
+#define ISP_LOGWARN 0x4 /* log warning messages */
+#define ISP_LOGERR 0x8 /* log error messages */
+#define ISP_LOGDEBUG0 0x10 /* log simple debug messages */
+#define ISP_LOGDEBUG1 0x20 /* log intermediate debug messages */
+#define ISP_LOGDEBUG2 0x40 /* log most debug messages */
+#define ISP_LOGDEBUG3 0x100 /* log high frequency debug messages */
+#define ISP_LOGTDEBUG0 0x200 /* log simple debug messages (target mode) */
+#define ISP_LOGTDEBUG1 0x400 /* log intermediate debug messages (target) */
+#define ISP_LOGTDEBUG2 0x800 /* log all debug messages (target) */
+/*
+ * Each Platform provides it's own isposinfo substructure of the ispsoftc
+ * defined above.
+ *
+ * Each platform must also provide the following macros/defines:
+ *
+ *
+ * INLINE - platform specific define for 'inline' functions
+ *
+ * ISP2100_FABRIC - defines whether FABRIC support is enabled
+ * ISP2100_SCRLEN - length for the Fibre Channel scratch DMA area
+ *
+ * MEMZERO(dst, src) platform zeroing function
+ * MEMCPY(dst, src, count) platform copying function
+ * SNPRINTF(buf, bufsize, fmt, ...) snprintf
+ * STRNCAT(dstbuf, size, srcbuf) strncat
+ * USEC_DELAY(usecs) microsecond spindelay function
+ *
+ * NANOTIME_T nanosecond time type
+ *
+ * GET_NANOTIME(NANOTIME_T *) get current nanotime.
+ *
+ * GET_NANOSEC(NANOTIME_T *) get u_int64_t from NANOTIME_T
+ *
+ * NANOTIME_SUB(NANOTIME_T *, NANOTIME_T *)
+ * subtract two NANOTIME_T values
+ *
+ *
+ * MAXISPREQUEST(struct ispsoftc *) maximum request queue size
+ * for this particular board type
+ *
+ * MEMORYBARRIER(struct ispsoftc *, barrier_type, offset, size)
+ *
+ * Function/Macro the provides memory synchronization on
+ * various objects so that the ISP's and the system's view
+ * of the same object is consistent.
+ *
+ * MBOX_ACQUIRE(struct ispsoftc *) acquire lock on mailbox regs
+ * MBOX_WAIT_COMPLETE(struct ispsoftc *) wait for mailbox cmd to be done
+ * MBOX_NOTIFY_COMPLETE(struct ispsoftc *) notification of mbox cmd donee
+ * MBOX_RELEASE(struct ispsoftc *) release lock on mailbox regs
+ *
+ *
+ * SCSI_GOOD SCSI 'Good' Status
+ * SCSI_CHECK SCSI 'Check Condition' Status
+ * SCSI_BUSY SCSI 'Busy' Status
+ * SCSI_QFULL SCSI 'Queue Full' Status
+ *
+ * XS_T Platform SCSI transaction type (i.e., command for HBA)
+ * XS_ISP(xs) gets an instance out of an XS_T
+ * XS_CHANNEL(xs) gets the channel (bus # for DUALBUS cards) ""
+ * XS_TGT(xs) gets the target ""
+ * XS_LUN(xs) gets the lun ""
+ * XS_CDBP(xs) gets a pointer to the scsi CDB ""
+ * XS_CDBLEN(xs) gets the CDB's length ""
+ * XS_XFRLEN(xs) gets the associated data transfer length ""
+ * XS_TIME(xs) gets the time (in milliseconds) for this command
+ * XS_RESID(xs) gets the current residual count
+ * XS_STSP(xs) gets a pointer to the SCSI status byte ""
+ * XS_SNSP(xs) gets a pointer to the associate sense data
+ * XS_SNSLEN(xs) gets the length of sense data storage
+ * XS_SNSKEY(xs) dereferences XS_SNSP to get the current stored Sense Key
+ * XS_TAG_P(xs) predicate of whether this command should be tagged
+ * XS_TAG_TYPE(xs) which type of tag to use
+ * XS_SETERR(xs) set error state
+ *
+ * HBA_NOERROR command has no erros
+ * HBA_BOTCH hba botched something
+ * HBA_CMDTIMEOUT command timed out
+ * HBA_SELTIMEOUT selection timed out (also port logouts for FC)
+ * HBA_TGTBSY target returned a BUSY status
+ * HBA_BUSRESET bus reset destroyed command
+ * HBA_ABORTED command was aborted (by request)
+ * HBA_DATAOVR a data overrun was detected
+ * HBA_ARQFAIL Automatic Request Sense failed
+ *
+ * XS_ERR(xs) return current error state
+ * XS_NOERR(xs) there is no error currently set
+ * XS_INITERR(xs) initialize error state
+ *
+ * XS_SAVE_SENSE(xs, sp) save sense data
+ *
+ * XS_SET_STATE_STAT(isp, sp, xs) platform dependent interpreter of
+ * response queue entry status bits
+ *
+ *
+ * DEFAULT_IID(struct ispsoftc *) Default SCSI initiator ID
+ * DEFAULT_LOOPID(struct ispsoftc *) Default FC Loop ID
+ * DEFAULT_NODEWWN(struct ispsoftc *) Default Node WWN
+ * DEFAULT_PORTWWN(struct ispsoftc *) Default Port WWN
+ * These establish reasonable defaults for each platform.
+ * These must be available independent of card NVRAM and are
+ * to be used should NVRAM not be readable.
+ *
+ * ISP_NODEWWN(struct ispsoftc *) FC Node WWN to use
+ * ISP_PORTWWN(struct ispsoftc *) FC Port WWN to use
+ *
+ * These are to be used after NVRAM is read. The tags
+ * in fcparam.isp_{node,port}wwn reflect the values
+ * read from NVRAM (possibly corrected for card botches).
+ * Each platform can take that information and override
+ * it or ignore and return the Node and Port WWNs to be
+ * used when sending the Qlogic f/w the Initialization Control
+ * Block.
+ *
+ * (XXX these do endian specific transformations- in transition XXX)
+ * ISP_SWIZZLE_ICB
+ * ISP_UNSWIZZLE_AND_COPY_PDBP
+ * ISP_SWIZZLE_CONTINUATION
+ * ISP_SWIZZLE_REQUEST
+ * ISP_UNSWIZZLE_RESPONSE
+ * ISP_SWIZZLE_SNS_REQ
+ * ISP_UNSWIZZLE_SNS_RSP
+ * ISP_SWIZZLE_NVRAM_WORD
+ *
+ *
+ */
#endif /* _ISPVAR_H */