Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 24 Oct 2015 23:46:32 +0000 (UTC)
From:      "Conrad E. Meyer" <cem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r289912 - head/sys/dev/ioat
Message-ID:  <201510242346.t9ONkWxx012168@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201510242346.t9ONkWxx012168>