From: Vincent Palatin <vpala...@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 <vpala...@chromium.org>

Signed-off-by: Simon Glass <s...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to