Greg,

Anything wrong with this patch ?

thanks
                Franck

Franck Bui-Huu wrote:
> This patch uses completion timeout instead of a timer to implement
> a timeout when submitting an URB in usb_start_wait_urb().
> 
> It also fixes a small issue. With the previous code, if no timeout
> happened and the URB's status was set to ECONNRESET value, the code
> assumed wrongly that a timeout had occured.
> 
> Signed-off-by: Franck Bui-Huu <[EMAIL PROTECTED]>
> ---
>  drivers/usb/core/message.c |   73 
> +++++++++++++++++---------------------------
>  1 files changed, 29 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
> index 08fb20f..6213c6d 100644
> --- a/drivers/usb/core/message.c
> +++ b/drivers/usb/core/message.c
> @@ -24,59 +24,44 @@ 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 interruptible 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 (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);
> +     if (unlikely(status))
> +             goto out;
> +
> +     expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;
> +     if (!wait_for_completion_timeout(&done, expire)) {
> +
> +             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);
> +
> +             usb_kill_urb(urb);
> +             status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status;
> +     } else
>               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);
> -     }
> -
> +out:
>       if (actual_length)
>               *actual_length = urb->actual_length;
> +
>       usb_free_urb(urb);
>       return status;
>  }


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
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