From ef2eaedc2ec5332905a4784a38283a2d83234f3a Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Mon, 5 Dec 2011 01:36:26 +0100 Subject: [PATCH] Account for full-/lowspeed errors and ensure an error is set. For full- and lowspeed devices the unused ping status bit works as an additional error bit (albeit it's so generic that it isn't really useful). Include that bit when the error counter counts down to zero. Also ensure that an error is returned if the error counter reaches zero, but print a warning if none of the describing bits are set. --- src/add-ons/kernel/busses/usb/ehci.cpp | 15 +++++++++++++++ src/add-ons/kernel/busses/usb/ehci_hardware.h | 1 + 2 files changed, 16 insertions(+) diff --git a/src/add-ons/kernel/busses/usb/ehci.cpp b/src/add-ons/kernel/busses/usb/ehci.cpp index 5aa27232c8..70ea5b15d1 100644 --- a/src/add-ons/kernel/busses/usb/ehci.cpp +++ b/src/add-ons/kernel/busses/usb/ehci.cpp @@ -1500,9 +1500,24 @@ EHCI::FinishTransfers() callbackStatus = B_DEV_CRC_ERROR; reasons++; } + if ((transfer->queue_head->endpoint_chars + & EHCI_QH_CHARS_EPS_HIGH) == 0) { + // For full-/lowspeed endpoints the unused ping + // state bit is used as another error bit, it is + // unspecific however. + if ((status & EHCI_QTD_STATUS_LS_ERR) != 0) { + callbackStatus = B_DEV_STALLED; + reasons++; + } + } if (reasons > 1) callbackStatus = B_DEV_MULTIPLE_ERRORS; + else if (reasons == 0) { + TRACE_ERROR("error counter counted down to zero " + "but none of the error bits are set\n"); + callbackStatus = B_DEV_STALLED; + } } else if (status & EHCI_QTD_STATUS_BABBLE) { // there is a babble condition callbackStatus = transfer->incoming ? B_DEV_FIFO_OVERRUN : B_DEV_FIFO_UNDERRUN; diff --git a/src/add-ons/kernel/busses/usb/ehci_hardware.h b/src/add-ons/kernel/busses/usb/ehci_hardware.h index 5344332bf4..876414d184 100644 --- a/src/add-ons/kernel/busses/usb/ehci_hardware.h +++ b/src/add-ons/kernel/busses/usb/ehci_hardware.h @@ -237,6 +237,7 @@ typedef struct ehci_qtd { #define EHCI_QTD_STATUS_MISSED (1 << 2) // Missed Micro-Frame #define EHCI_QTD_STATUS_SPLIT (1 << 1) // Split Transaction State #define EHCI_QTD_STATUS_PING (1 << 0) // Ping State +#define EHCI_QTD_STATUS_LS_ERR (1 << 0) // Full-/Lowspeed Error #define EHCI_QTD_PAGE_MASK 0xfffff000