From 4085ff6fcfa78eae897d339e97a2956de475a3f7 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 28 Feb 2009 16:06:53 +0000 Subject: [PATCH] * Check for and discard not enabled interrupts in EHCI. * Simplify acknowledging interrupts a bit. Might help with bug #2083 in case the controller would interrupt on a port change or frame list rollover even though those aren't enabled by us. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29354 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/busses/usb/ehci.cpp | 26 +++++++++---------- src/add-ons/kernel/busses/usb/ehci_hardware.h | 1 + 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/add-ons/kernel/busses/usb/ehci.cpp b/src/add-ons/kernel/busses/usb/ehci.cpp index 97dd423e63..2465b00b23 100644 --- a/src/add-ons/kernel/busses/usb/ehci.cpp +++ b/src/add-ons/kernel/busses/usb/ehci.cpp @@ -795,51 +795,49 @@ EHCI::Interrupt() acquire_spinlock(&lock); // check if any interrupt was generated - uint32 status = ReadOpReg(EHCI_USBSTS); + uint32 status = ReadOpReg(EHCI_USBSTS) & EHCI_USBSTS_INTMASK; if ((status & fEnabledInterrupts) == 0) { + if (status != 0) { + TRACE("discarding not enabled interrupts 0x%08lx\n", status); + WriteOpReg(EHCI_USBSTS, status); + } + release_spinlock(&lock); return B_UNHANDLED_INTERRUPT; } - uint32 acknowledge = 0; bool asyncAdvance = false; bool finishTransfers = false; int32 result = B_HANDLED_INTERRUPT; if (status & EHCI_USBSTS_USBINT) { TRACE("transfer finished\n"); - acknowledge |= EHCI_USBSTS_USBINT; result = B_INVOKE_SCHEDULER; finishTransfers = true; } if (status & EHCI_USBSTS_USBERRINT) { TRACE("transfer error\n"); - acknowledge |= EHCI_USBSTS_USBERRINT; result = B_INVOKE_SCHEDULER; finishTransfers = true; } - if (status & EHCI_USBSTS_PORTCHANGE) { + if (status & EHCI_USBSTS_FLROLLOVER) + TRACE("frame list rollover\n"); + + if (status & EHCI_USBSTS_PORTCHANGE) TRACE("port change detected\n"); - acknowledge |= EHCI_USBSTS_PORTCHANGE; - } if (status & EHCI_USBSTS_INTONAA) { TRACE("interrupt on async advance\n"); - acknowledge |= EHCI_USBSTS_INTONAA; asyncAdvance = true; result = B_INVOKE_SCHEDULER; } - if (status & EHCI_USBSTS_HOSTSYSERR) { + if (status & EHCI_USBSTS_HOSTSYSERR) TRACE_ERROR("host system error!\n"); - acknowledge |= EHCI_USBSTS_HOSTSYSERR; - } - - if (acknowledge) - WriteOpReg(EHCI_USBSTS, acknowledge); + WriteOpReg(EHCI_USBSTS, status); release_spinlock(&lock); if (asyncAdvance) diff --git a/src/add-ons/kernel/busses/usb/ehci_hardware.h b/src/add-ons/kernel/busses/usb/ehci_hardware.h index 01b01bb0c8..112bea8f32 100644 --- a/src/add-ons/kernel/busses/usb/ehci_hardware.h +++ b/src/add-ons/kernel/busses/usb/ehci_hardware.h @@ -56,6 +56,7 @@ #define EHCI_USBSTS_PORTCHANGE (1 << 2) // Port Change Detected #define EHCI_USBSTS_USBERRINT (1 << 1) // USB Error Interrupt #define EHCI_USBSTS_USBINT (1 << 0) // USB Interrupt +#define EHCI_USBSTS_INTMASK 0x3f // USB Interrupt Enable Register (EHCI Spec 2.3.3)