Author: gonzo
Date: Sun Jan  1 09:12:21 2012
New Revision: 229168
URL: http://svn.freebsd.org/changeset/base/229168

Log:
  - Properly set IRQ handlers for all USB ports

Modified:
  head/sys/mips/cavium/usb/octusb.h
  head/sys/mips/cavium/usb/octusb_octeon.c

Modified: head/sys/mips/cavium/usb/octusb.h
==============================================================================
--- head/sys/mips/cavium/usb/octusb.h   Sun Jan  1 03:38:36 2012        
(r229167)
+++ head/sys/mips/cavium/usb/octusb.h   Sun Jan  1 09:12:21 2012        
(r229168)
@@ -29,14 +29,7 @@
 #define        _OCTUSB_H_
 
 #define        OCTUSB_MAX_DEVICES MIN(USB_MAX_DEVICES, 64)
-/*
- * The second port is on a different IRQ and so we disable it for now.
- */
-#if 1
-#define        OCTUSB_MAX_PORTS        1       /* hardcoded */
-#else
 #define        OCTUSB_MAX_PORTS        2       /* hardcoded */
-#endif
 #define        OCTUSB_MAX_FIXUP        4096    /* bytes */
 #define        OCTUSB_INTR_ENDPT       0x01
 
@@ -121,8 +114,8 @@ struct octusb_softc {
 
        struct usb_device *sc_devices[OCTUSB_MAX_DEVICES];
 
-       struct resource *sc_irq_res;
-       void   *sc_intr_hdl;
+       struct resource *sc_irq_res[OCTUSB_MAX_PORTS];
+       void   *sc_intr_hdl[OCTUSB_MAX_PORTS];
 
        struct octusb_port sc_port[OCTUSB_MAX_PORTS];
        device_t sc_dev;

Modified: head/sys/mips/cavium/usb/octusb_octeon.c
==============================================================================
--- head/sys/mips/cavium/usb/octusb_octeon.c    Sun Jan  1 03:38:36 2012        
(r229167)
+++ head/sys/mips/cavium/usb/octusb_octeon.c    Sun Jan  1 09:12:21 2012        
(r229168)
@@ -94,6 +94,8 @@ octusb_octeon_attach(device_t dev)
        struct octusb_octeon_softc *sc = device_get_softc(dev);
        int err;
        int rid;
+       int nports;
+       int i;
 
        /* setup controller interface softc */
 
@@ -107,12 +109,29 @@ octusb_octeon_attach(device_t dev)
            USB_GET_DMA_TAG(dev), NULL)) {
                return (ENOMEM);
        }
-       rid = 0;
-       sc->sc_dci.sc_irq_res =
-           bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
-                              CVMX_IRQ_USB, CVMX_IRQ_USB, 1, RF_ACTIVE);
-       if (!(sc->sc_dci.sc_irq_res)) {
-               goto error;
+       nports = cvmx_usb_get_num_ports();
+       if (nports > OCTUSB_MAX_PORTS)
+               panic("octusb: too many USB ports %d", nports);
+       for (i = 0; i < nports; i++) {
+               rid = 0;
+               sc->sc_dci.sc_irq_res[i] =
+                   bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+                              CVMX_IRQ_USB0 + i, CVMX_IRQ_USB0 + i, 1, 
RF_ACTIVE);
+               if (!(sc->sc_dci.sc_irq_res[i])) {
+                       goto error;
+               }
+
+#if (__FreeBSD_version >= 700031)
+               err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res[i], 
INTR_TYPE_BIO | INTR_MPSAFE,
+                   NULL, (driver_intr_t *)octusb_interrupt, sc, 
&sc->sc_dci.sc_intr_hdl[i]);
+#else
+               err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res[i], 
INTR_TYPE_BIO | INTR_MPSAFE,
+                   (driver_intr_t *)octusb_interrupt, sc, 
&sc->sc_dci.sc_intr_hdl[i]);
+#endif
+               if (err) {
+                       sc->sc_dci.sc_intr_hdl[i] = NULL;
+                       goto error;
+               }
        }
 
        sc->sc_dci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
@@ -121,17 +140,7 @@ octusb_octeon_attach(device_t dev)
        }
        device_set_ivars(sc->sc_dci.sc_bus.bdev, &sc->sc_dci.sc_bus);
 
-#if (__FreeBSD_version >= 700031)
-       err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res, INTR_TYPE_BIO | 
INTR_MPSAFE,
-           NULL, (driver_intr_t *)octusb_interrupt, sc, 
&sc->sc_dci.sc_intr_hdl);
-#else
-       err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res, INTR_TYPE_BIO | 
INTR_MPSAFE,
-           (driver_intr_t *)octusb_interrupt, sc, &sc->sc_dci.sc_intr_hdl);
-#endif
-       if (err) {
-               sc->sc_dci.sc_intr_hdl = NULL;
-               goto error;
-       }
+
        err = octusb_init(&sc->sc_dci);
        if (!err) {
                err = device_probe_and_attach(sc->sc_dci.sc_bus.bdev);
@@ -152,6 +161,8 @@ octusb_octeon_detach(device_t dev)
        struct octusb_octeon_softc *sc = device_get_softc(dev);
        device_t bdev;
        int err;
+       int nports;
+       int i;
 
        if (sc->sc_dci.sc_bus.bdev) {
                bdev = sc->sc_dci.sc_bus.bdev;
@@ -161,20 +172,26 @@ octusb_octeon_detach(device_t dev)
        /* during module unload there are lots of children leftover */
        device_delete_children(dev);
 
-       if (sc->sc_dci.sc_irq_res && sc->sc_dci.sc_intr_hdl) {
+       if (sc->sc_dci.sc_irq_res[0] && sc->sc_dci.sc_intr_hdl[0])
                /*
-                * only call octusb_octeon_uninit() after octusb_octeon_init()
-                */
+                * only call octusb_octeon_uninit() after octusb_octeon_init()
+                */
                octusb_uninit(&sc->sc_dci);
 
-               err = bus_teardown_intr(dev, sc->sc_dci.sc_irq_res,
-                   sc->sc_dci.sc_intr_hdl);
-               sc->sc_dci.sc_intr_hdl = NULL;
-       }
-       if (sc->sc_dci.sc_irq_res) {
-               bus_release_resource(dev, SYS_RES_IRQ, 0,
-                   sc->sc_dci.sc_irq_res);
-               sc->sc_dci.sc_irq_res = NULL;
+       nports = cvmx_usb_get_num_ports();
+       if (nports > OCTUSB_MAX_PORTS)
+               panic("octusb: too many USB ports %d", nports);
+       for (i = 0; i < nports; i++) {
+               if (sc->sc_dci.sc_irq_res[0] && sc->sc_dci.sc_intr_hdl[0]) {
+                       err = bus_teardown_intr(dev, sc->sc_dci.sc_irq_res[i],
+                           sc->sc_dci.sc_intr_hdl[i]);
+                       sc->sc_dci.sc_intr_hdl[i] = NULL;
+               }
+               if (sc->sc_dci.sc_irq_res) {
+                       bus_release_resource(dev, SYS_RES_IRQ, 0,
+                           sc->sc_dci.sc_irq_res[i]);
+                       sc->sc_dci.sc_irq_res[i] = NULL;
+               }
        }
        usb_bus_mem_free_all(&sc->sc_dci.sc_bus, NULL);
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to