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)
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to