Skip to content

Commit 4169099

Browse files
AlanSterngregkh
authored andcommitted
USB: usbcore: Introduce usb_bulk_msg_killable()
The synchronous message API in usbcore (usb_control_msg(), usb_bulk_msg(), and so on) uses uninterruptible waits. However, drivers may call these routines in the context of a user thread, which means it ought to be possible to at least kill them. For this reason, introduce a new usb_bulk_msg_killable() function which behaves the same as usb_bulk_msg() except for using wait_for_completion_killable_timeout() instead of wait_for_completion_timeout(). The same can be done later for usb_control_msg() later on, if it turns out to be needed. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Suggested-by: Oliver Neukum <oneukum@suse.com> Link: https://lore.kernel.org/linux-usb/3acfe838-6334-4f6d-be7c-4bb01704b33d@rowland.harvard.edu/ Fixes: 1da177e ("Linux-2.6.12-rc2") CC: stable@vger.kernel.org Link: https://patch.msgid.link/248628b4-cc83-4e81-a620-3ce4e0376d41@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent e293015 commit 4169099

2 files changed

Lines changed: 72 additions & 12 deletions

File tree

drivers/usb/core/message.c

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,17 @@ static void usb_api_blocking_completion(struct urb *urb)
4242

4343

4444
/*
45-
* Starts urb and waits for completion or timeout. Note that this call
46-
* is NOT interruptible. Many device driver i/o requests should be
47-
* interruptible and therefore these drivers should implement their
48-
* own interruptible routines.
45+
* Starts urb and waits for completion or timeout.
46+
* Whether or not the wait is killable depends on the flag passed in.
47+
* For example, compare usb_bulk_msg() and usb_bulk_msg_killable().
4948
*/
50-
static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length)
49+
static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length,
50+
bool killable)
5151
{
5252
struct api_context ctx;
5353
unsigned long expire;
5454
int retval;
55+
long rc;
5556

5657
init_completion(&ctx.done);
5758
urb->context = &ctx;
@@ -61,12 +62,21 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length)
6162
goto out;
6263

6364
expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;
64-
if (!wait_for_completion_timeout(&ctx.done, expire)) {
65+
if (killable)
66+
rc = wait_for_completion_killable_timeout(&ctx.done, expire);
67+
else
68+
rc = wait_for_completion_timeout(&ctx.done, expire);
69+
if (rc <= 0) {
6570
usb_kill_urb(urb);
66-
retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status);
71+
if (ctx.status != -ENOENT)
72+
retval = ctx.status;
73+
else if (rc == 0)
74+
retval = -ETIMEDOUT;
75+
else
76+
retval = rc;
6777

6878
dev_dbg(&urb->dev->dev,
69-
"%s timed out on ep%d%s len=%u/%u\n",
79+
"%s timed out or killed on ep%d%s len=%u/%u\n",
7080
current->comm,
7181
usb_endpoint_num(&urb->ep->desc),
7282
usb_urb_dir_in(urb) ? "in" : "out",
@@ -100,7 +110,7 @@ static int usb_internal_control_msg(struct usb_device *usb_dev,
100110
usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,
101111
len, usb_api_blocking_completion, NULL);
102112

103-
retv = usb_start_wait_urb(urb, timeout, &length);
113+
retv = usb_start_wait_urb(urb, timeout, &length, false);
104114
if (retv < 0)
105115
return retv;
106116
else
@@ -385,10 +395,59 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
385395
usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
386396
usb_api_blocking_completion, NULL);
387397

388-
return usb_start_wait_urb(urb, timeout, actual_length);
398+
return usb_start_wait_urb(urb, timeout, actual_length, false);
389399
}
390400
EXPORT_SYMBOL_GPL(usb_bulk_msg);
391401

402+
/**
403+
* usb_bulk_msg_killable - Builds a bulk urb, sends it off and waits for completion in a killable state
404+
* @usb_dev: pointer to the usb device to send the message to
405+
* @pipe: endpoint "pipe" to send the message to
406+
* @data: pointer to the data to send
407+
* @len: length in bytes of the data to send
408+
* @actual_length: pointer to a location to put the actual length transferred
409+
* in bytes
410+
* @timeout: time in msecs to wait for the message to complete before
411+
* timing out (if 0 the wait is forever)
412+
*
413+
* Context: task context, might sleep.
414+
*
415+
* This function is just like usb_blk_msg() except that it waits in a
416+
* killable state.
417+
*
418+
* Return:
419+
* If successful, 0. Otherwise a negative error number. The number of actual
420+
* bytes transferred will be stored in the @actual_length parameter.
421+
*
422+
*/
423+
int usb_bulk_msg_killable(struct usb_device *usb_dev, unsigned int pipe,
424+
void *data, int len, int *actual_length, int timeout)
425+
{
426+
struct urb *urb;
427+
struct usb_host_endpoint *ep;
428+
429+
ep = usb_pipe_endpoint(usb_dev, pipe);
430+
if (!ep || len < 0)
431+
return -EINVAL;
432+
433+
urb = usb_alloc_urb(0, GFP_KERNEL);
434+
if (!urb)
435+
return -ENOMEM;
436+
437+
if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
438+
USB_ENDPOINT_XFER_INT) {
439+
pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
440+
usb_fill_int_urb(urb, usb_dev, pipe, data, len,
441+
usb_api_blocking_completion, NULL,
442+
ep->desc.bInterval);
443+
} else
444+
usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
445+
usb_api_blocking_completion, NULL);
446+
447+
return usb_start_wait_urb(urb, timeout, actual_length, true);
448+
}
449+
EXPORT_SYMBOL_GPL(usb_bulk_msg_killable);
450+
392451
/*-------------------------------------------------------------------*/
393452

394453
static void sg_clean(struct usb_sg_request *io)

include/linux/usb.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1868,8 +1868,9 @@ extern int usb_control_msg(struct usb_device *dev, unsigned int pipe,
18681868
extern int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe,
18691869
void *data, int len, int *actual_length, int timeout);
18701870
extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
1871-
void *data, int len, int *actual_length,
1872-
int timeout);
1871+
void *data, int len, int *actual_length, int timeout);
1872+
extern int usb_bulk_msg_killable(struct usb_device *usb_dev, unsigned int pipe,
1873+
void *data, int len, int *actual_length, int timeout);
18731874

18741875
/* wrappers around usb_control_msg() for the most common standard requests */
18751876
int usb_control_msg_send(struct usb_device *dev, __u8 endpoint, __u8 request,

0 commit comments

Comments
 (0)