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