Date: Thu, 8 Jan 2009 13:32:08 +0000 (UTC) From: Rafal Jaworowski <raj@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r186902 - head/sys/dev/usb Message-ID: <200901081332.n08DW8Is023797@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: raj Date: Thu Jan 8 13:32:08 2009 New Revision: 186902 URL: http://svn.freebsd.org/changeset/base/186902 Log: Provide handler for USB controller error interrupts for Marvell EHCI device. Obtained from: Semihalf Modified: head/sys/dev/usb/ehci_mbus.c Modified: head/sys/dev/usb/ehci_mbus.c ============================================================================== --- head/sys/dev/usb/ehci_mbus.c Thu Jan 8 13:25:22 2009 (r186901) +++ head/sys/dev/usb/ehci_mbus.c Thu Jan 8 13:32:08 2009 (r186902) @@ -73,6 +73,19 @@ static device_shutdown_t ehci_mbus_shutd static device_suspend_t ehci_mbus_suspend; static device_resume_t ehci_mbus_resume; +static int err_intr(void *arg); + +struct resource *irq_err; +void *ih_err; + +#define USB_BRIDGE_INTR_CAUSE 0x210 +#define USB_BRIDGE_INTR_MASK 0x214 + +#define MV_USB_ADDR_DECODE_ERR (1 << 0) +#define MV_USB_HOST_UNDERFLOW (1 << 1) +#define MV_USB_HOST_OVERFLOW (1 << 2) +#define MV_USB_DEVICE_UNDERFLOW (1 << 3) + static int ehci_mbus_suspend(device_t self) { @@ -157,6 +170,15 @@ ehci_mbus_attach(device_t self) device_get_name(self)); sc->sc_size = MV_USB_SIZE - MV_USB_HOST_OFST; + rid = 0; + irq_err = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE); + if (irq_err == NULL) { + device_printf(self, "Could not allocate error irq\n"); + ehci_mbus_detach(self); + return (ENXIO); + } + /* * Notice: Marvell EHCI controller has TWO interrupt lines, so make sure to * use the correct rid for the main one (controller interrupt) -- @@ -181,6 +203,19 @@ ehci_mbus_attach(device_t self) sprintf(sc->sc_vendor, "Marvell"); sc->sc_id_vendor = EHCI_VENDORID_MRVL; + err = bus_setup_intr(self, irq_err, INTR_FAST | INTR_TYPE_BIO, + err_intr, NULL, sc, &ih_err); + if (err) { + device_printf(self, "Could not setup error irq, %d\n", err); + ih_err = NULL; + ehci_mbus_detach(self); + return (ENXIO); + } + + EWRITE4(sc, USB_BRIDGE_INTR_MASK, MV_USB_ADDR_DECODE_ERR | + MV_USB_HOST_UNDERFLOW | MV_USB_HOST_OVERFLOW | + MV_USB_DEVICE_UNDERFLOW); + err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO, NULL, (driver_intr_t*)ehci_intr, sc, &sc->ih); if (err) { @@ -277,6 +312,17 @@ ehci_mbus_detach(device_t self) err); sc->ih = NULL; } + EWRITE4(sc, USB_BRIDGE_INTR_MASK, 0); + + if (irq_err && ih_err) { + err = bus_teardown_intr(self, irq_err, ih_err); + + if (err) + device_printf(self, "Could not tear down irq, %d\n", + err); + ih_err = NULL; + } + if (sc->sc_bus.bdev) { device_delete_child(self, sc->sc_bus.bdev); sc->sc_bus.bdev = NULL; @@ -285,6 +331,10 @@ ehci_mbus_detach(device_t self) bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res); sc->irq_res = NULL; } + if (irq_err) { + bus_release_resource(self, SYS_RES_IRQ, 1, irq_err); + irq_err = NULL; + } if (sc->io_res) { bus_release_resource(self, SYS_RES_MEMORY, 0, sc->io_res); sc->io_res = NULL; @@ -294,6 +344,32 @@ ehci_mbus_detach(device_t self) return (0); } +static int +err_intr(void *arg) +{ + ehci_softc_t *sc = arg; + unsigned int cause; + + cause = EREAD4(sc, USB_BRIDGE_INTR_CAUSE); + if (cause) { + printf("IRQ ERR: cause: 0x%08x\n", cause); + if (cause & MV_USB_ADDR_DECODE_ERR) + printf("IRQ ERR: Address decoding error\n"); + if (cause & MV_USB_HOST_UNDERFLOW) + printf("IRQ ERR: USB Host Underflow\n"); + if (cause & MV_USB_HOST_OVERFLOW) + printf("IRQ ERR: USB Host Overflow\n"); + if (cause & MV_USB_DEVICE_UNDERFLOW) + printf("IRQ ERR: USB Device Underflow\n"); + if (cause & ~(MV_USB_ADDR_DECODE_ERR | MV_USB_HOST_UNDERFLOW | + MV_USB_HOST_OVERFLOW | MV_USB_DEVICE_UNDERFLOW)) + printf("IRQ ERR: Unknown error\n"); + + EWRITE4(sc, USB_BRIDGE_INTR_CAUSE, 0); + } + return (FILTER_HANDLED); +} + static device_method_t ehci_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ehci_mbus_probe),
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901081332.n08DW8Is023797>