svn commit: r197264 - stable/8/sys/dev/ciss

Scott Long scottl at FreeBSD.org
Thu Sep 17 05:27:33 UTC 2009


Author: scottl
Date: Thu Sep 17 05:27:32 2009
New Revision: 197264
URL: http://svn.freebsd.org/changeset/base/197264

Log:
  Merge r197260, r197261, r197262
  
  - Prevent a panic on modern controllers by increasing CISS_MAX_PHYSTGT to 256
  - Fix MSI and PERFORMANT interrupt programming.  Fixes hang on boot.
  - Fix locking bugs in ioctl handler
  
  Most of this has been soaking at Yahoo for several months, if not longer.  The
  quick MFC is due to the impending 8.0-RC1 build.
  
  Approved by:	re
  Obtained from:	Yahoo!

Modified:
  stable/8/sys/dev/ciss/   (props changed)
  stable/8/sys/dev/ciss/ciss.c
  stable/8/sys/dev/ciss/cissreg.h
  stable/8/sys/dev/ciss/cissvar.h

Modified: stable/8/sys/dev/ciss/ciss.c
==============================================================================
--- stable/8/sys/dev/ciss/ciss.c	Wed Sep 16 23:27:14 2009	(r197263)
+++ stable/8/sys/dev/ciss/ciss.c	Thu Sep 17 05:27:32 2009	(r197264)
@@ -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;
@@ -2559,15 +2567,16 @@ ciss_user_command(struct ciss_softc *sc,
     /*
      * Allocate an in-kernel databuffer if required, copy in user data.
      */
+    mtx_unlock(&sc->ciss_mtx);
     cr->cr_length = ioc->buf_size;
     if (ioc->buf_size > 0) {
 	if ((cr->cr_data = malloc(ioc->buf_size, CISS_MALLOC_CLASS, M_NOWAIT)) == NULL) {
 	    error = ENOMEM;
-	    goto out;
+	    goto out_unlocked;
 	}
 	if ((error = copyin(ioc->buf, cr->cr_data, ioc->buf_size))) {
 	    debug(0, "copyin: bad data buffer %p/%d", ioc->buf, ioc->buf_size);
-	    goto out;
+	    goto out_unlocked;
 	}
     }
 
@@ -2578,6 +2587,7 @@ ciss_user_command(struct ciss_softc *sc,
     bcopy(&ioc->Request, &cc->cdb, sizeof(cc->cdb));
 
     /* XXX anything else to populate here? */
+    mtx_lock(&sc->ciss_mtx);
 
     /*
      * Run the command.
@@ -2598,15 +2608,19 @@ ciss_user_command(struct ciss_softc *sc,
      * Copy the results back to the user.
      */
     bcopy(ce, &ioc->error_info, sizeof(*ce));
+    mtx_unlock(&sc->ciss_mtx);
     if ((ioc->buf_size > 0) &&
 	(error = copyout(cr->cr_data, ioc->buf, ioc->buf_size))) {
 	debug(0, "copyout: bad data buffer %p/%d", ioc->buf, ioc->buf_size);
-	goto out;
+	goto out_unlocked;
     }
 
     /* done OK */
     error = 0;
 
+out_unlocked:
+    mtx_lock(&sc->ciss_mtx);
+
 out:
     if ((cr != NULL) && (cr->cr_data != NULL))
 	free(cr->cr_data, CISS_MALLOC_CLASS);

Modified: stable/8/sys/dev/ciss/cissreg.h
==============================================================================
--- stable/8/sys/dev/ciss/cissreg.h	Wed Sep 16 23:27:14 2009	(r197263)
+++ stable/8/sys/dev/ciss/cissreg.h	Thu Sep 17 05:27:32 2009	(r197264)
@@ -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, \

Modified: stable/8/sys/dev/ciss/cissvar.h
==============================================================================
--- stable/8/sys/dev/ciss/cissvar.h	Wed Sep 16 23:27:14 2009	(r197263)
+++ stable/8/sys/dev/ciss/cissvar.h	Thu Sep 17 05:27:32 2009	(r197264)
@@ -176,7 +176,7 @@ struct ciss_pdrive
 
 #define CISS_PHYSICAL_SHIFT	5
 #define CISS_PHYSICAL_BASE	(1 << CISS_PHYSICAL_SHIFT)
-#define CISS_MAX_PHYSTGT	15
+#define CISS_MAX_PHYSTGT	256
 
 #define CISS_IS_PHYSICAL(bus)	(bus >= CISS_PHYSICAL_BASE)
 #define CISS_CAM_TO_PBUS(bus)	(bus - CISS_PHYSICAL_BASE)


More information about the svn-src-stable mailing list