From owner-svn-src-head@freebsd.org Wed Sep 2 16:48:04 2015 Return-Path: Delivered-To: svn-src-head@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 CC3649C9E72; Wed, 2 Sep 2015 16:48:04 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::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 BD4A11D54; Wed, 2 Sep 2015 16:48:04 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t82Gm4H1015185; Wed, 2 Sep 2015 16:48:04 GMT (envelope-from cem@FreeBSD.org) Received: (from cem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t82Gm451015184; Wed, 2 Sep 2015 16:48:04 GMT (envelope-from cem@FreeBSD.org) Message-Id: <201509021648.t82Gm451015184@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cem set sender to cem@FreeBSD.org using -f From: "Conrad E. Meyer" Date: Wed, 2 Sep 2015 16:48:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r287403 - 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-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Sep 2015 16:48:05 -0000 Author: cem Date: Wed Sep 2 16:48:03 2015 New Revision: 287403 URL: https://svnweb.freebsd.org/changeset/base/287403 Log: ioat: re-initialize interrupts after resetting hw on BDXDE Resetting some generations of the I/OAT hardware (just BDXDE for now) resets the corresponding MSI-X registers. So, teardown and re-initialize interrupts after resetting the hardware. Reviewed by: jimharris Approved by: markj (mentor) Sponsored by: EMC / Isilon Storage Division Differential Revision: https://reviews.freebsd.org/D3549 Modified: head/sys/dev/ioat/ioat.c Modified: head/sys/dev/ioat/ioat.c ============================================================================== --- head/sys/dev/ioat/ioat.c Wed Sep 2 16:30:45 2015 (r287402) +++ head/sys/dev/ioat/ioat.c Wed Sep 2 16:48:03 2015 (r287403) @@ -53,12 +53,14 @@ __FBSDID("$FreeBSD$"); static int ioat_probe(device_t device); static int ioat_attach(device_t device); 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 ioat_map_pci_bar(struct ioat_softc *ioat); static void ioat_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error); -static int ioat_interrupt_setup(struct ioat_softc *ioat); static void ioat_interrupt_handler(void *arg); +static boolean_t ioat_is_bdxde(struct ioat_softc *ioat); static void ioat_process_events(struct ioat_softc *ioat); static inline uint32_t ioat_get_active(struct ioat_softc *ioat); static inline uint32_t ioat_get_ring_space(struct ioat_softc *ioat); @@ -220,13 +222,15 @@ ioat_attach(device_t device) goto err; ioat->version = ioat_read_cbver(ioat); - ioat_interrupt_setup(ioat); - if (ioat->version < IOAT_VER_3_0) { error = ENODEV; goto err; } + error = ioat_setup_intr(ioat); + if (error != 0) + return (error); + error = ioat3_attach(device); if (error != 0) goto err; @@ -273,15 +277,23 @@ ioat_detach(device_t device) bus_dma_tag_destroy(ioat->hw_desc_tag); + ioat_teardown_intr(ioat); + + return (0); +} + +static int +ioat_teardown_intr(struct ioat_softc *ioat) +{ + if (ioat->tag != NULL) - bus_teardown_intr(device, ioat->res, ioat->tag); + bus_teardown_intr(ioat->device, ioat->res, ioat->tag); if (ioat->res != NULL) - bus_release_resource(device, SYS_RES_IRQ, + bus_release_resource(ioat->device, SYS_RES_IRQ, rman_get_rid(ioat->res), ioat->res); - pci_release_msi(device); - + pci_release_msi(ioat->device); return (0); } @@ -455,7 +467,7 @@ ioat_dmamap_cb(void *arg, bus_dma_segmen * Interrupt setup and handlers */ static int -ioat_interrupt_setup(struct ioat_softc *ioat) +ioat_setup_intr(struct ioat_softc *ioat) { uint32_t num_vectors; int error; @@ -498,6 +510,23 @@ ioat_interrupt_setup(struct ioat_softc * return (0); } +static boolean_t +ioat_is_bdxde(struct ioat_softc *ioat) +{ + u_int32_t pciid; + + pciid = pci_get_devid(ioat->device); + switch (pciid) { + case 0x6f508086: + case 0x6f518086: + case 0x6f528086: + case 0x6f538086: + return (TRUE); + } + + return (FALSE); +} + static void ioat_interrupt_handler(void *arg) { @@ -918,7 +947,7 @@ ioat_reset_hw(struct ioat_softc *ioat) { uint64_t status; uint32_t chanerr; - int timeout; + int timeout, error; status = ioat_get_chansts(ioat); if (is_ioat_active(status) || is_ioat_idle(status)) @@ -953,6 +982,20 @@ ioat_reset_hw(struct ioat_softc *ioat) if (timeout == 20) return (ETIMEDOUT); + /* + * BDXDE models reset MSI-X registers on device reset. We must + * teardown and re-setup interrupts. + */ + if (ioat_is_bdxde(ioat)) { + error = ioat_teardown_intr(ioat); + if (error) + return (error); + + error = ioat_setup_intr(ioat); + if (error) + return (error); + } + return (0); }