From owner-svn-src-all@freebsd.org Sat Oct 24 23:46:33 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D09F9A1EDC2; Sat, 24 Oct 2015 23:46:33 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9223E18C4; Sat, 24 Oct 2015 23:46:33 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t9ONkWU8012170; Sat, 24 Oct 2015 23:46:32 GMT (envelope-from cem@FreeBSD.org) Received: (from cem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t9ONkWxx012168; Sat, 24 Oct 2015 23:46:32 GMT (envelope-from cem@FreeBSD.org) Message-Id: <201510242346.t9ONkWxx012168@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cem set sender to cem@FreeBSD.org using -f From: "Conrad E. Meyer" Date: Sat, 24 Oct 2015 23:46:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r289912 - head/sys/dev/ioat X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 24 Oct 2015 23:46:33 -0000 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