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
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to