diff mbox

[U-Boot,06/11] usb: ehci: Add timeout on interrupt endpoint operations

Message ID 1355363731-10103-7-git-send-email-sjg@chromium.org
State Superseded, archived
Delegated to: Marek Vasut
Headers show

Commit Message

Simon Glass Dec. 13, 2012, 1:55 a.m. UTC
From: Vincent Palatin <vpalatin@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@chromium.org>

Signed-off-by: Simon Glass <sjg@chromium.org>
---
 drivers/usb/host/ehci-hcd.c |   18 ++++++++++++++++--
 1 files changed, 16 insertions(+), 2 deletions(-)

Comments

Marek Vasut Dec. 13, 2012, 5:35 p.m. UTC | #1
Dear Simon Glass,

> From: Vincent Palatin <vpalatin@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@chromium.org>
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---

I like it. Let's use errno.h and rebase on top of u-boot-usb.git ... I just 
pushed it.

Best regards,
Marek Vasut
Simon Glass Dec. 14, 2012, 2:04 a.m. UTC | #2
Hi Marek,

On Thu, Dec 13, 2012 at 9:35 AM, Marek Vasut <marex@denx.de> wrote:
> Dear Simon Glass,
>
>> From: Vincent Palatin <vpalatin@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@chromium.org>
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>
> I like it. Let's use errno.h and rebase on top of u-boot-usb.git ... I just
> pushed it.

OK I have had a crack at that and will resend.

Regards,
Simon

>
> Best regards,
> Marek Vasut
diff mbox

Patch

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;
 }