Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Sep 2015 16:48:04 +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: r287403 - head/sys/dev/ioat
Message-ID:  <201509021648.t82Gm451015184@repo.freebsd.org>

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



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