[U-Boot] [PATCH 06/11] usb: ehci: Add timeout on interrupt endpoint operations
Simon Glass
sjg at chromium.org
Thu Dec 13 02:55:26 CET 2012
From: Vincent Palatin <vpalatin at chromium.org>
Ensure we cannot get stuck in the keyboard scanning if something wrong
happens (USB device unplugged or fatal I/O error)
Signed-off-by: Vincent Palatin <vpalatin at chromium.org>
Signed-off-by: Simon Glass <sjg at chromium.org>
---
drivers/usb/host/ehci-hcd.c | 18 ++++++++++++++++--
1 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 0f4bc49..51aa4b3 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1191,6 +1191,7 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
{
struct ehci_ctrl *ctrl = dev->controller;
int result = -1;
+ unsigned long timeout;
if (disable_periodic(ctrl) < 0) {
debug("FATAL: periodic should never fail, but did");
@@ -1199,6 +1200,7 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
periodic_schedules--;
struct QH *cur = &ctrl->periodic_queue;
+ timeout = get_timer(0) + 500; /* abort after 500ms */
while (!(cur->qh_link & QH_LINK_TERMINATE)) {
debug("considering %p, with qh_link %x\n", cur, cur->qh_link);
if (NEXT_QH(cur) == queue->first) {
@@ -1208,6 +1210,11 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
goto out;
}
cur = NEXT_QH(cur);
+ if (get_timer(0) > timeout) {
+ printf("Timeout destroying interrupt endpoint queue\n");
+ result = -1;
+ break;
+ }
}
if (periodic_schedules > 0)
@@ -1229,6 +1236,8 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
{
void *backbuffer;
struct int_queue *queue;
+ unsigned long timeout;
+ int result = 0;
debug("dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d",
dev, pipe, buffer, length, interval);
@@ -1253,8 +1262,13 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
queue = create_int_queue(dev, pipe, 1, length, buffer);
/* TODO: pick some useful timeout rule */
+ timeout = get_timer(0) + USB_TIMEOUT_MS(pipe);
while ((backbuffer = poll_int_queue(dev, queue)) == NULL)
- ;
+ if (get_timer(0) > timeout) {
+ printf("Timeout poll on interrupt endpoint\n");
+ result = -1;
+ break;
+ }
if (backbuffer != buffer) {
debug("got wrong buffer back (%x instead of %x)\n",
@@ -1266,5 +1280,5 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
return -1;
/* everything worked out fine */
- return 0;
+ return result;
}
--
1.7.7.3
More information about the U-Boot
mailing list