Index: octusb.h =================================================================== --- octusb.h (revision 229069) +++ octusb.h (working copy) @@ -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 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; Index: octusb_octeon.c =================================================================== --- octusb_octeon.c (revision 229069) +++ octusb_octeon.c (working copy) @@ -94,6 +94,7 @@ struct octusb_octeon_softc *sc = device_get_softc(dev); int err; int rid; + int i, nports; /* setup controller interface softc */ @@ -107,12 +108,29 @@ 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 +139,7 @@ } 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 +160,7 @@ struct octusb_octeon_softc *sc = device_get_softc(dev); device_t bdev; int err; + int i, nports; if (sc->sc_dci.sc_bus.bdev) { bdev = sc->sc_dci.sc_bus.bdev; @@ -161,21 +170,27 @@ /* 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; + 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; + } } - 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; - } usb_bus_mem_free_all(&sc->sc_dci.sc_bus, NULL); return (0);