This patch uses completion timeout instead of a timer to implement
a timeout when submitting an URB in usb_start_wait_urb().
Signed-off-by: Franck Bui-Huu <[EMAIL PROTECTED]>
---
ok, this function is still uninterruptible and I updated its
comment. It also converts timeout from ms into jiffies before
calling scheduler's service.
drivers/usb/core/message.c | 73 ++++++++++++++++++--------------------------
1 files changed, 30 insertions(+), 43 deletions(-)
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 08fb20f..9e9e840 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -24,59 +24,46 @@ static void usb_api_blocking_completion(
}
-static void timeout_kill(unsigned long data)
-{
- struct urb *urb = (struct urb *) data;
-
- usb_unlink_urb(urb);
-}
-
-// Starts urb and waits for completion or timeout
-// note that this call is NOT interruptible, while
-// many device driver i/o requests should be interruptible
-static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
+/*
+ * Starts urb and waits for completion or timeout. Note that this call
+ * is NOT interruptible. Many device driver i/o requests should be
+ * interruptible and therefore these drivers should implement their
+ * own interruptibe routines.
+ */
+static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length)
{
- struct completion done;
- struct timer_list timer;
- int status;
+ struct completion done;
+ unsigned long expire;
+ int status;
init_completion(&done);
urb->context = &done;
urb->actual_length = 0;
status = usb_submit_urb(urb, GFP_NOIO);
+ if (unlikely(status))
+ goto out;
- if (status == 0) {
- if (timeout > 0) {
- init_timer(&timer);
- timer.expires = jiffies + msecs_to_jiffies(timeout);
- timer.data = (unsigned long)urb;
- timer.function = timeout_kill;
- /* grr. timeout _should_ include submit delays. */
- add_timer(&timer);
- }
- wait_for_completion(&done);
- status = urb->status;
- /* note: HCDs return ETIMEDOUT for other reasons too */
- if (status == -ECONNRESET) {
- dev_dbg(&urb->dev->dev,
- "%s timed out on ep%d%s len=%d/%d\n",
- current->comm,
- usb_pipeendpoint(urb->pipe),
- usb_pipein(urb->pipe) ? "in" : "out",
- urb->actual_length,
- urb->transfer_buffer_length
- );
- if (urb->actual_length > 0)
- status = 0;
- else
- status = -ETIMEDOUT;
- }
- if (timeout > 0)
- del_timer_sync(&timer);
+ expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;
+ if (!wait_for_completion_timeout(&done, expire)) {
+ usb_unlink_urb(urb);
}
-
+ status = urb->status;
+ /* note: HCDs return ETIMEDOUT for other reasons too */
+ if (status == -ECONNRESET) {
+ status = urb->actual_length > 0 ? 0 : -ETIMEDOUT;
+
+ dev_dbg(&urb->dev->dev,
+ "%s timed out on ep%d%s len=%d/%d\n",
+ current->comm,
+ usb_pipeendpoint(urb->pipe),
+ usb_pipein(urb->pipe) ? "in" : "out",
+ urb->actual_length,
+ urb->transfer_buffer_length);
+ }
+out:
if (actual_length)
*actual_length = urb->actual_length;
+
usb_free_urb(urb);
return status;
}
--
1.4.0.g64e8
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel