Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Sep 2009 23:10:11 +0000 (UTC)
From:      Scott Long <scottl@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r197261 - head/sys/dev/ciss
Message-ID:  <200909162310.n8GNAB5X038525@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: scottl
Date: Wed Sep 16 23:10:10 2009
New Revision: 197261
URL: http://svn.freebsd.org/changeset/base/197261

Log:
  Make MSI and PERFORMANT interrupts work correctly.  Only require the minimum
  number of MSIX interrupts that are needed, and don't strictly check for 4.
  Enable enough interrupt mask bits so that the controller will generate
  interrupts in PERFORMANT mode.  This fixes the hang-on-boot issues that
  people were seeing with newer controllers.

Modified:
  head/sys/dev/ciss/ciss.c
  head/sys/dev/ciss/cissreg.h

Modified: head/sys/dev/ciss/ciss.c
==============================================================================
--- head/sys/dev/ciss/ciss.c	Wed Sep 16 22:52:20 2009	(r197260)
+++ head/sys/dev/ciss/ciss.c	Wed Sep 16 23:10:10 2009	(r197261)
@@ -736,11 +736,16 @@ setup:
 	ciss_printf(sc, "PERFORMANT Transport\n");
 	if ((ciss_force_interrupt != 1) && (ciss_setup_msix(sc) == 0)) {
 	    intr = ciss_perf_msi_intr;
-	    sc->ciss_interrupt_mask = CISS_TL_PERF_INTR_MSI;
 	} else {
 	    intr = ciss_perf_intr;
-	    sc->ciss_interrupt_mask = CISS_TL_PERF_INTR_OPQ;
 	}
+	/* XXX The docs say that the 0x01 bit is only for SAS controllers.
+	 * Unfortunately, there is no good way to know if this is a SAS
+	 * controller.  Hopefully enabling this bit universally will work OK.
+	 * It seems to work fine for SA6i controllers.
+	 */
+        sc->ciss_interrupt_mask = CISS_TL_PERF_INTR_OPQ | CISS_TL_PERF_INTR_MSI;
+
     } else {
 	ciss_printf(sc, "SIMPLE Transport\n");
 	/* MSIX doesn't seem to work in SIMPLE mode, only enable if it forced */
@@ -834,7 +839,10 @@ ciss_setup_msix(struct ciss_softc *sc)
 	return (EINVAL);
 
     val = pci_msix_count(sc->ciss_dev);
-    if ((val != CISS_MSI_COUNT) || (pci_alloc_msix(sc->ciss_dev, &val) != 0))
+    if (val < CISS_MSI_COUNT)
+	return (EINVAL);
+    val = MIN(val, CISS_MSI_COUNT);
+    if (pci_alloc_msix(sc->ciss_dev, &val) != 0)
 	return (EINVAL);
 
     sc->ciss_msi = val;

Modified: head/sys/dev/ciss/cissreg.h
==============================================================================
--- head/sys/dev/ciss/cissreg.h	Wed Sep 16 22:52:20 2009	(r197260)
+++ head/sys/dev/ciss/cissreg.h	Wed Sep 16 23:10:10 2009	(r197261)
@@ -736,7 +736,8 @@ struct ciss_bmic_flush_cache {
 #define CISS_TL_PERF_CLEAR_INT(sc)		CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_ODC, CISS_TL_SIMPLE_ODC_CLEAR)
 #define CISS_CYCLE_MASK		0x00000001
 
-#define CISS_MSI_COUNT	4
+/* Only need one MSI/MSI-X vector */
+#define CISS_MSI_COUNT	1
 
 #define CISS_TL_SIMPLE_DISABLE_INTERRUPTS(sc) \
 	CISS_TL_SIMPLE_WRITE(sc, CISS_TL_SIMPLE_IMR, \



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