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