ChangeSet 1.1455.1.22, 2003/07/15 14:53:20-07:00, david-b@pacbell.net [PATCH] USB: ohci minor tweaks Two small updates: - Report short control reads correctly in an exotic case that our regression tests cover. (Haven't run them with ohci for a long time, it seems...) - IRQ non-delivery bugs (ACPI, APIC, etc) can prevent urbs from unlinking. This prints a warning when that sort of non-USB bug is biting. drivers/usb/host/ohci-hcd.c | 3 +++ drivers/usb/host/ohci-q.c | 10 ++++++++++ 2 files changed, 13 insertions(+) diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c --- a/drivers/usb/host/ohci-hcd.c Thu Jul 17 17:05:01 2003 +++ b/drivers/usb/host/ohci-hcd.c Thu Jul 17 17:05:01 2003 @@ -319,6 +319,7 @@ int epnum = ep & USB_ENDPOINT_NUMBER_MASK; unsigned long flags; struct ed *ed; + unsigned limit = 1000; /* ASSERT: any requests/urbs are being unlinked */ /* ASSERT: nobody can be submitting urbs for this any more */ @@ -337,6 +338,8 @@ ed->state = ED_IDLE; switch (ed->state) { case ED_UNLINK: /* wait for hw to finish? */ + /* major IRQ delivery trouble loses INTR_SF too... */ + WARN_ON (limit-- == 0); spin_unlock_irqrestore (&ohci->lock, flags); set_current_state (TASK_UNINTERRUPTIBLE); schedule_timeout (1); diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c --- a/drivers/usb/host/ohci-q.c Thu Jul 17 17:05:01 2003 +++ b/drivers/usb/host/ohci-q.c Thu Jul 17 17:05:01 2003 @@ -43,6 +43,16 @@ spin_lock (&urb->lock); if (likely (urb->status == -EINPROGRESS)) urb->status = 0; + /* report short control reads right even though the data TD always + * has TD_R set. (much simpler, but creates the 1-td limit.) + */ + if (unlikely (urb->transfer_flags & URB_SHORT_NOT_OK) + && unlikely (usb_pipecontrol (urb->pipe)) + && urb->actual_length < urb->transfer_buffer_length + && usb_pipein (urb->pipe) + && urb->status == 0) { + urb->status = -EREMOTEIO; + } spin_unlock (&urb->lock); // what lock protects these?