svn commit: r289912 - head/sys/dev/ioat
Conrad E. Meyer
cem at FreeBSD.org
Sat Oct 24 23:46:33 UTC 2015
Author: cem
Date: Sat Oct 24 23:46:32 2015
New Revision: 289912
URL: https://svnweb.freebsd.org/changeset/base/289912
Log:
ioat: Actually bring the hardware back online after reset
We need to reset the chancmp and chainaddr MMIO registers to bring the
device back to a working state.
Name the chanerr bits while we're here.
Sponsored by: EMC / Isilon Storage Division
Modified:
head/sys/dev/ioat/ioat.c
head/sys/dev/ioat/ioat_hw.h
Modified: head/sys/dev/ioat/ioat.c
==============================================================================
--- head/sys/dev/ioat/ioat.c Sat Oct 24 23:46:20 2015 (r289911)
+++ head/sys/dev/ioat/ioat.c Sat Oct 24 23:46:32 2015 (r289912)
@@ -59,7 +59,7 @@ static int ioat_detach(device_t device);
static int ioat_setup_intr(struct ioat_softc *ioat);
static int ioat_teardown_intr(struct ioat_softc *ioat);
static int ioat3_attach(device_t device);
-static int ioat3_selftest(struct ioat_softc *ioat);
+static int ioat_start_channel(struct ioat_softc *ioat);
static int ioat_map_pci_bar(struct ioat_softc *ioat);
static void ioat_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg,
int error);
@@ -256,7 +256,7 @@ ioat_attach(device_t device)
if (error != 0)
goto err;
- error = ioat3_selftest(ioat);
+ error = ioat_reset_hw(ioat);
if (error != 0)
goto err;
@@ -326,7 +326,7 @@ ioat_teardown_intr(struct ioat_softc *io
}
static int
-ioat3_selftest(struct ioat_softc *ioat)
+ioat_start_channel(struct ioat_softc *ioat)
{
uint64_t status;
uint32_t chanerr;
@@ -435,14 +435,6 @@ ioat3_attach(device_t device)
ioat->head = 0;
ioat->tail = 0;
ioat->last_seen = 0;
-
- error = ioat_reset_hw(ioat);
- if (error != 0)
- return (error);
-
- ioat_write_chanctrl(ioat, IOAT_CHANCTRL_RUN);
- ioat_write_chancmp(ioat, ioat->comp_update_bus_addr);
- ioat_write_chainaddr(ioat, ring[0]->hw_desc_bus_addr);
return (0);
}
@@ -469,6 +461,7 @@ ioat_comp_update_map(void *arg, bus_dma_
{
struct ioat_softc *ioat = arg;
+ KASSERT(error == 0, ("%s: error:%d", __func__, error));
ioat->comp_update_bus_addr = seg[0].ds_addr;
}
@@ -477,6 +470,7 @@ ioat_dmamap_cb(void *arg, bus_dma_segmen
{
bus_addr_t *baddr;
+ KASSERT(error == 0, ("%s: error:%d", __func__, error));
baddr = arg;
*baddr = segs->ds_addr;
}
@@ -1006,7 +1000,7 @@ ioat_reset_hw(struct ioat_softc *ioat)
{
uint64_t status;
uint32_t chanerr;
- int timeout;
+ unsigned timeout;
status = ioat_get_chansts(ioat);
if (is_ioat_active(status) || is_ioat_idle(status))
@@ -1021,6 +1015,8 @@ ioat_reset_hw(struct ioat_softc *ioat)
if (timeout == 20)
return (ETIMEDOUT);
+ KASSERT(ioat_get_active(ioat) == 0, ("active after quiesce"));
+
chanerr = ioat_read_4(ioat, IOAT_CHANERR_OFFSET);
ioat_write_4(ioat, IOAT_CHANERR_OFFSET, chanerr);
@@ -1055,7 +1051,34 @@ ioat_reset_hw(struct ioat_softc *ioat)
pci_restore_state(ioat->device);
}
- return (0);
+ /* Reset attempts to return the hardware to "halted." */
+ status = ioat_get_chansts(ioat);
+ if (is_ioat_active(status) || is_ioat_idle(status)) {
+ /* So this really shouldn't happen... */
+ ioat_log_message(0, "Device is active after a reset?\n");
+ ioat_write_chanctrl(ioat, IOAT_CHANCTRL_RUN);
+ return (0);
+ }
+
+ chanerr = ioat_read_4(ioat, IOAT_CHANERR_OFFSET);
+ ioat_halted_debug(ioat, chanerr);
+ if (chanerr != 0)
+ return (EIO);
+
+ /*
+ * Bring device back online after reset. Writing CHAINADDR brings the
+ * device back to active.
+ *
+ * The internal ring counter resets to zero, so we have to start over
+ * at zero as well.
+ */
+ ioat->tail = ioat->head = 0;
+ ioat->last_seen = 0;
+
+ ioat_write_chanctrl(ioat, IOAT_CHANCTRL_RUN);
+ ioat_write_chancmp(ioat, ioat->comp_update_bus_addr);
+ ioat_write_chainaddr(ioat, ioat->ring[0]->hw_desc_bus_addr);
+ return (ioat_start_channel(ioat));
}
static int
Modified: head/sys/dev/ioat/ioat_hw.h
==============================================================================
--- head/sys/dev/ioat/ioat_hw.h Sat Oct 24 23:46:20 2015 (r289911)
+++ head/sys/dev/ioat/ioat_hw.h Sat Oct 24 23:46:32 2015 (r289912)
@@ -97,6 +97,35 @@ __FBSDID("$FreeBSD$");
#define IOAT_CHANERR_OFFSET 0xA8
+#define IOAT_CHANERR_XSADDERR (1 << 0)
+#define IOAT_CHANERR_XDADDERR (1 << 1)
+#define IOAT_CHANERR_NDADDERR (1 << 2)
+#define IOAT_CHANERR_DERR (1 << 3)
+#define IOAT_CHANERR_CHADDERR (1 << 4)
+#define IOAT_CHANERR_CCMDERR (1 << 5)
+#define IOAT_CHANERR_CUNCORERR (1 << 6)
+#define IOAT_CHANERR_DUNCORERR (1 << 7)
+#define IOAT_CHANERR_RDERR (1 << 8)
+#define IOAT_CHANERR_WDERR (1 << 9)
+#define IOAT_CHANERR_DCERR (1 << 10)
+#define IOAT_CHANERR_DXSERR (1 << 11)
+#define IOAT_CHANERR_CMPADDERR (1 << 12)
+#define IOAT_CHANERR_INTCFGERR (1 << 13)
+#define IOAT_CHANERR_SEDERR (1 << 14)
+#define IOAT_CHANERR_UNAFFERR (1 << 15)
+#define IOAT_CHANERR_CXPERR (1 << 16)
+/* Reserved. (1 << 17) */
+#define IOAT_CHANERR_DCNTERR (1 << 18)
+#define IOAT_CHANERR_DIFFERR (1 << 19)
+#define IOAT_CHANERR_GTVERR (1 << 20)
+#define IOAT_CHANERR_ATVERR (1 << 21)
+#define IOAT_CHANERR_RTVERR (1 << 22)
+#define IOAT_CHANERR_BBERR (1 << 23)
+#define IOAT_CHANERR_RDIFFERR (1 << 24)
+#define IOAT_CHANERR_RGTVERR (1 << 25)
+#define IOAT_CHANERR_RATVERR (1 << 26)
+#define IOAT_CHANERR_RRTVERR (1 << 27)
+
#define IOAT_CFG_CHANERR_INT_OFFSET 0x180
#define IOAT_CFG_CHANERRMASK_INT_OFFSET 0x184
More information about the svn-src-head
mailing list