diff options
Diffstat (limited to 'drivers/usb/core/urb.c')
| -rw-r--r-- | drivers/usb/core/urb.c | 346 |
1 files changed, 228 insertions, 118 deletions
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 16927fa88fbd..ff8df16cca35 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -1,12 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Released under the GPLv2 only. + */ + #include <linux/module.h> #include <linux/string.h> #include <linux/bitops.h> #include <linux/slab.h> -#include <linux/init.h> #include <linux/log2.h> +#include <linux/kmsan.h> #include <linux/usb.h> #include <linux/wait.h> #include <linux/usb/hcd.h> +#include <linux/scatterlist.h> #define to_urb(d) container_of(d, struct urb, kref) @@ -40,6 +46,7 @@ void usb_init_urb(struct urb *urb) if (urb) { memset(urb, 0, sizeof(*urb)); kref_init(&urb->kref); + INIT_LIST_HEAD(&urb->urb_list); INIT_LIST_HEAD(&urb->anchor_list); } } @@ -52,26 +59,23 @@ EXPORT_SYMBOL_GPL(usb_init_urb); * valid options for this. * * Creates an urb for the USB driver to use, initializes a few internal - * structures, incrementes the usage counter, and returns a pointer to it. - * - * If no memory is available, NULL is returned. + * structures, increments the usage counter, and returns a pointer to it. * * If the driver want to use this urb for interrupt, control, or bulk * endpoints, pass '0' as the number of iso packets. * * The driver must call usb_free_urb() when it is finished with the urb. + * + * Return: A pointer to the new urb, or %NULL if no memory is available. */ struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags) { struct urb *urb; - urb = kmalloc(sizeof(struct urb) + - iso_packets * sizeof(struct usb_iso_packet_descriptor), - mem_flags); - if (!urb) { - printk(KERN_ERR "alloc_urb: kmalloc failed\n"); + urb = kmalloc(struct_size(urb, iso_frame_desc, iso_packets), + mem_flags); + if (!urb) return NULL; - } usb_init_urb(urb); return urb; } @@ -102,7 +106,7 @@ EXPORT_SYMBOL_GPL(usb_free_urb); * host controller driver. This allows proper reference counting to happen * for urbs. * - * A pointer to the urb with the incremented reference counter is returned. + * Return: A pointer to the urb with the incremented reference counter. */ struct urb *usb_get_urb(struct urb *urb) { @@ -129,21 +133,26 @@ void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor) list_add_tail(&urb->anchor_list, &anchor->urb_list); urb->anchor = anchor; - if (unlikely(anchor->poisoned)) { + if (unlikely(anchor->poisoned)) atomic_inc(&urb->reject); - } spin_unlock_irqrestore(&anchor->lock, flags); } EXPORT_SYMBOL_GPL(usb_anchor_urb); +static int usb_anchor_check_wakeup(struct usb_anchor *anchor) +{ + return atomic_read(&anchor->suspend_wakeups) == 0 && + list_empty(&anchor->urb_list); +} + /* Callers must hold anchor->lock */ static void __usb_unanchor_urb(struct urb *urb, struct usb_anchor *anchor) { urb->anchor = NULL; list_del(&urb->anchor_list); usb_put_urb(urb); - if (list_empty(&anchor->urb_list)) + if (usb_anchor_check_wakeup(anchor)) wake_up(&anchor->wait); } @@ -179,6 +188,46 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb); /*-------------------------------------------------------------------*/ +static const int pipetypes[4] = { + PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT +}; + +/** + * usb_pipe_type_check - sanity check of a specific pipe for a usb device + * @dev: struct usb_device to be checked + * @pipe: pipe to check + * + * This performs a light-weight sanity check for the endpoint in the + * given usb device. It returns 0 if the pipe is valid for the specific usb + * device, otherwise a negative error code. + */ +int usb_pipe_type_check(struct usb_device *dev, unsigned int pipe) +{ + const struct usb_host_endpoint *ep; + + ep = usb_pipe_endpoint(dev, pipe); + if (!ep) + return -EINVAL; + if (usb_pipetype(pipe) != pipetypes[usb_endpoint_type(&ep->desc)]) + return -EINVAL; + return 0; +} +EXPORT_SYMBOL_GPL(usb_pipe_type_check); + +/** + * usb_urb_ep_type_check - sanity check of endpoint in the given urb + * @urb: urb to be checked + * + * This performs a light-weight sanity check for the endpoint in the + * given urb. It returns 0 if the urb contains a valid endpoint, otherwise + * a negative error code. + */ +int usb_urb_ep_type_check(const struct urb *urb) +{ + return usb_pipe_type_check(urb->dev, urb->pipe); +} +EXPORT_SYMBOL_GPL(usb_urb_ep_type_check); + /** * usb_submit_urb - issue an asynchronous transfer request for an endpoint * @urb: pointer to the urb describing the request @@ -199,13 +248,12 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb); * the particular kind of transfer, although they will not initialize * any transfer flags. * - * Successful submissions return 0; otherwise this routine returns a - * negative error number. If the submission is successful, the complete() - * callback from the URB will be called exactly once, when the USB core and - * Host Controller Driver (HCD) are finished with the URB. When the completion - * function is called, control of the URB is returned to the device - * driver which issued the request. The completion handler may then - * immediately free or reuse that URB. + * If the submission is successful, the complete() callback from the URB + * will be called exactly once, when the USB core and Host Controller Driver + * (HCD) are finished with the URB. When the completion function is called, + * control of the URB is returned to the device driver which issued the + * request. The completion handler may then immediately free or reuse that + * URB. * * With few exceptions, USB device drivers should never access URB fields * provided by usbcore or the HCD until its complete() is called. @@ -240,6 +288,9 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb); * that are standardized in the USB 2.0 specification. For bulk * endpoints, a synchronous usb_bulk_msg() call is available. * + * Return: + * 0 on successful submissions. A negative error number otherwise. + * * Request Queuing: * * URBs may be submitted to endpoints before previous ones complete, to @@ -272,7 +323,7 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb); * * Device drivers must explicitly request that repetition, by ensuring that * some URB is always on the endpoint's queue (except possibly for short - * periods during completion callacks). When there is no longer an urb + * periods during completion callbacks). When there is no longer an urb * queued, the endpoint's bandwidth reservation is canceled. This means * drivers can use their completion handlers to ensure they keep bandwidth * they need, by reinitializing and resubmitting the just-completed urb @@ -320,6 +371,8 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) struct usb_device *dev; struct usb_host_endpoint *ep; int is_out; + unsigned int allowed; + bool is_eusb2_isoch_double; if (!urb || !urb->complete) return -EINVAL; @@ -356,6 +409,15 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) return -ENOEXEC; is_out = !(setup->bRequestType & USB_DIR_IN) || !setup->wLength; + dev_WARN_ONCE(&dev->dev, (usb_pipeout(urb->pipe) != is_out), + "BOGUS control dir, pipe %x doesn't match bRequestType %x\n", + urb->pipe, setup->bRequestType); + if (le16_to_cpu(setup->wLength) != urb->transfer_buffer_length) { + dev_dbg(&dev->dev, "BOGUS control len %d doesn't match transfer length %d\n", + le16_to_cpu(setup->wLength), + urb->transfer_buffer_length); + return -EBADR; + } } else { is_out = usb_endpoint_dir_out(&ep->desc); } @@ -366,13 +428,15 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL | URB_DMA_SG_COMBINED); urb->transfer_flags |= (is_out ? URB_DIR_OUT : URB_DIR_IN); + kmsan_handle_urb(urb, is_out); if (xfertype != USB_ENDPOINT_XFER_CONTROL && dev->state < USB_STATE_CONFIGURED) return -ENODEV; max = usb_endpoint_maxp(&ep->desc); - if (max <= 0) { + is_eusb2_isoch_double = usb_endpoint_is_hs_isoc_double(dev, ep); + if (!max && !is_eusb2_isoch_double) { dev_dbg(&dev->dev, "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", usb_endpoint_num(&ep->desc), is_out ? "out" : "in", @@ -390,18 +454,27 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) /* SuperSpeed isoc endpoints have up to 16 bursts of up to * 3 packets each */ - if (dev->speed == USB_SPEED_SUPER) { + if (dev->speed >= USB_SPEED_SUPER) { int burst = 1 + ep->ss_ep_comp.bMaxBurst; int mult = USB_SS_MULT(ep->ss_ep_comp.bmAttributes); max *= burst; max *= mult; } - /* "high bandwidth" mode, 1-3 packets/uframe? */ + if (dev->speed == USB_SPEED_SUPER_PLUS && + USB_SS_SSP_ISOC_COMP(ep->ss_ep_comp.bmAttributes)) { + struct usb_ssp_isoc_ep_comp_descriptor *isoc_ep_comp; + + isoc_ep_comp = &ep->ssp_isoc_ep_comp; + max = le32_to_cpu(isoc_ep_comp->dwBytesPerInterval); + } + + /* High speed, 1-3 packets/uframe, max 6 for eUSB2 double bw */ if (dev->speed == USB_SPEED_HIGH) { - int mult = 1 + ((max >> 11) & 0x03); - max &= 0x07ff; - max *= mult; + if (is_eusb2_isoch_double) + max = le32_to_cpu(ep->eusb2_isoc_ep_comp.dwBytesPerInterval); + else + max *= usb_endpoint_maxp_mult(&ep->desc); } if (urb->number_of_packets <= 0) @@ -413,25 +486,27 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) urb->iso_frame_desc[n].status = -EXDEV; urb->iso_frame_desc[n].actual_length = 0; } + } else if (urb->num_sgs && !urb->dev->bus->no_sg_constraint) { + struct scatterlist *sg; + int i; + + for_each_sg(urb->sg, sg, urb->num_sgs - 1, i) + if (sg->length % max) + return -EINVAL; } /* the I/O buffer must be mapped/unmapped, except when length=0 */ if (urb->transfer_buffer_length > INT_MAX) return -EMSGSIZE; -#ifdef DEBUG - /* stuff that drivers shouldn't do, but which shouldn't + /* + * stuff that drivers shouldn't do, but which shouldn't * cause problems in HCDs if they get it wrong. */ - { - unsigned int allowed; - static int pipetypes[4] = { - PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT - }; /* Check that the pipe's type matches the endpoint's type */ - if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) - dev_WARN(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n", + if (usb_pipe_type_check(urb->dev, urb->pipe)) + dev_warn_once(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n", usb_pipetype(urb->pipe), pipetypes[xfertype]); /* Check against a simple/standard policy */ @@ -439,12 +514,10 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) URB_FREE_BUFFER); switch (xfertype) { case USB_ENDPOINT_XFER_BULK: + case USB_ENDPOINT_XFER_INT: if (is_out) allowed |= URB_ZERO_PACKET; - /* FALLTHROUGH */ - case USB_ENDPOINT_XFER_CONTROL: - allowed |= URB_NO_FSBR; /* only affects UHCI */ - /* FALLTHROUGH */ + fallthrough; default: /* all non-iso endpoints */ if (!is_out) allowed |= URB_SHORT_NOT_OK; @@ -459,8 +532,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) if (allowed != urb->transfer_flags) dev_WARN(&dev->dev, "BOGUS urb flags, %x --> %x\n", urb->transfer_flags, allowed); - } -#endif + /* * Force periodic transfer intervals to be legal values that are * a power of two (so HCDs don't need to). @@ -473,28 +545,18 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) case USB_ENDPOINT_XFER_ISOC: case USB_ENDPOINT_XFER_INT: /* too small? */ - switch (dev->speed) { - case USB_SPEED_WIRELESS: - if (urb->interval < 6) - return -EINVAL; - break; - default: - if (urb->interval <= 0) - return -EINVAL; - break; - } + if (urb->interval <= 0) + return -EINVAL; + /* too big? */ switch (dev->speed) { + case USB_SPEED_SUPER_PLUS: case USB_SPEED_SUPER: /* units are 125us */ /* Handle up to 2^(16-1) microframes */ if (urb->interval > (1 << 15)) return -EINVAL; max = 1 << 15; break; - case USB_SPEED_WIRELESS: - if (urb->interval > 16) - return -EINVAL; - break; case USB_SPEED_HIGH: /* units are microframes */ /* NOTE usb handles 2^15 */ if (urb->interval > (1024 * 8)) @@ -518,10 +580,8 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) default: return -EINVAL; } - if (dev->speed != USB_SPEED_WIRELESS) { - /* Round down to a power of 2, no more than max */ - urb->interval = min(max, 1 << ilog2(urb->interval)); - } + /* Round down to a power of 2, no more than max */ + urb->interval = min(max, 1 << ilog2(urb->interval)); } return usb_hcd_submit_urb(urb, mem_flags); @@ -543,10 +603,9 @@ EXPORT_SYMBOL_GPL(usb_submit_urb); * code). * * Drivers should not call this routine or related routines, such as - * usb_kill_urb() or usb_unlink_anchored_urbs(), after their disconnect - * method has returned. The disconnect function should synchronize with - * a driver's I/O routines to insure that all URB-related activity has - * completed before it returns. + * usb_kill_urb(), after their disconnect method has returned. The + * disconnect function should synchronize with a driver's I/O routines + * to insure that all URB-related activity has completed before it returns. * * This request is asynchronous, however the HCD might call the ->complete() * callback during unlink. Therefore when drivers call usb_unlink_urb(), they @@ -564,6 +623,9 @@ EXPORT_SYMBOL_GPL(usb_submit_urb); * particular, when a driver calls this routine, it must insure that the * completion handler cannot deallocate the URB. * + * Return: -EINPROGRESS on success. See description for other values on + * failure. + * * Unlinking and Endpoint Queues: * * [The behaviors and guarantees described below do not apply to virtual @@ -645,6 +707,12 @@ void usb_kill_urb(struct urb *urb) if (!(urb && urb->dev && urb->ep)) return; atomic_inc(&urb->reject); + /* + * Order the write of urb->reject above before the read + * of urb->use_count below. Pairs with the barriers in + * __usb_hcd_giveback_urb() and usb_hcd_submit_urb(). + */ + smp_mb__after_atomic(); usb_hcd_unlink_urb(urb, -ENOENT); wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); @@ -686,6 +754,12 @@ void usb_poison_urb(struct urb *urb) if (!urb) return; atomic_inc(&urb->reject); + /* + * Order the write of urb->reject above before the read + * of urb->use_count below. Pairs with the barriers in + * __usb_hcd_giveback_urb() and usb_hcd_submit_urb(). + */ + smp_mb__after_atomic(); if (!urb->dev || !urb->ep) return; @@ -726,11 +800,12 @@ void usb_block_urb(struct urb *urb) EXPORT_SYMBOL_GPL(usb_block_urb); /** - * usb_kill_anchored_urbs - cancel transfer requests en masse + * usb_kill_anchored_urbs - kill all URBs associated with an anchor * @anchor: anchor the requests are bound to * - * this allows all outstanding URBs to be killed starting - * from the back of the queue + * This kills all outstanding URBs starting from the back of the queue, + * with guarantee that no completer callbacks will take place from the + * anchor after this function returns. * * This routine should not be called by a driver after its disconnect * method has returned. @@ -738,20 +813,26 @@ EXPORT_SYMBOL_GPL(usb_block_urb); void usb_kill_anchored_urbs(struct usb_anchor *anchor) { struct urb *victim; + int surely_empty; - spin_lock_irq(&anchor->lock); - while (!list_empty(&anchor->urb_list)) { - victim = list_entry(anchor->urb_list.prev, struct urb, - anchor_list); - /* we must make sure the URB isn't freed before we kill it*/ - usb_get_urb(victim); - spin_unlock_irq(&anchor->lock); - /* this will unanchor the URB */ - usb_kill_urb(victim); - usb_put_urb(victim); + do { spin_lock_irq(&anchor->lock); - } - spin_unlock_irq(&anchor->lock); + while (!list_empty(&anchor->urb_list)) { + victim = list_entry(anchor->urb_list.prev, + struct urb, anchor_list); + /* make sure the URB isn't freed before we kill it */ + usb_get_urb(victim); + spin_unlock_irq(&anchor->lock); + /* this will unanchor the URB */ + usb_kill_urb(victim); + usb_put_urb(victim); + spin_lock_irq(&anchor->lock); + } + surely_empty = usb_anchor_check_wakeup(anchor); + + spin_unlock_irq(&anchor->lock); + cpu_relax(); + } while (!surely_empty); } EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs); @@ -770,21 +851,27 @@ EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs); void usb_poison_anchored_urbs(struct usb_anchor *anchor) { struct urb *victim; + int surely_empty; - spin_lock_irq(&anchor->lock); - anchor->poisoned = 1; - while (!list_empty(&anchor->urb_list)) { - victim = list_entry(anchor->urb_list.prev, struct urb, - anchor_list); - /* we must make sure the URB isn't freed before we kill it*/ - usb_get_urb(victim); - spin_unlock_irq(&anchor->lock); - /* this will unanchor the URB */ - usb_poison_urb(victim); - usb_put_urb(victim); + do { spin_lock_irq(&anchor->lock); - } - spin_unlock_irq(&anchor->lock); + anchor->poisoned = 1; + while (!list_empty(&anchor->urb_list)) { + victim = list_entry(anchor->urb_list.prev, + struct urb, anchor_list); + /* make sure the URB isn't freed before we kill it */ + usb_get_urb(victim); + spin_unlock_irq(&anchor->lock); + /* this will unanchor the URB */ + usb_poison_urb(victim); + usb_put_urb(victim); + spin_lock_irq(&anchor->lock); + } + surely_empty = usb_anchor_check_wakeup(anchor); + + spin_unlock_irq(&anchor->lock); + cpu_relax(); + } while (!surely_empty); } EXPORT_SYMBOL_GPL(usb_poison_anchored_urbs); @@ -808,28 +895,39 @@ void usb_unpoison_anchored_urbs(struct usb_anchor *anchor) spin_unlock_irqrestore(&anchor->lock, flags); } EXPORT_SYMBOL_GPL(usb_unpoison_anchored_urbs); + /** - * usb_unlink_anchored_urbs - asynchronously cancel transfer requests en masse - * @anchor: anchor the requests are bound to + * usb_anchor_suspend_wakeups + * @anchor: the anchor you want to suspend wakeups on * - * this allows all outstanding URBs to be unlinked starting - * from the back of the queue. This function is asynchronous. - * The unlinking is just tiggered. It may happen after this - * function has returned. + * Call this to stop the last urb being unanchored from waking up any + * usb_wait_anchor_empty_timeout waiters. This is used in the hcd urb give- + * back path to delay waking up until after the completion handler has run. + */ +void usb_anchor_suspend_wakeups(struct usb_anchor *anchor) +{ + if (anchor) + atomic_inc(&anchor->suspend_wakeups); +} +EXPORT_SYMBOL_GPL(usb_anchor_suspend_wakeups); + +/** + * usb_anchor_resume_wakeups + * @anchor: the anchor you want to resume wakeups on * - * This routine should not be called by a driver after its disconnect - * method has returned. + * Allow usb_wait_anchor_empty_timeout waiters to be woken up again, and + * wake up any current waiters if the anchor is empty. */ -void usb_unlink_anchored_urbs(struct usb_anchor *anchor) +void usb_anchor_resume_wakeups(struct usb_anchor *anchor) { - struct urb *victim; + if (!anchor) + return; - while ((victim = usb_get_from_anchor(anchor)) != NULL) { - usb_unlink_urb(victim); - usb_put_urb(victim); - } + atomic_dec(&anchor->suspend_wakeups); + if (usb_anchor_check_wakeup(anchor)) + wake_up(&anchor->wait); } -EXPORT_SYMBOL_GPL(usb_unlink_anchored_urbs); +EXPORT_SYMBOL_GPL(usb_anchor_resume_wakeups); /** * usb_wait_anchor_empty_timeout - wait for an anchor to be unused @@ -838,11 +936,14 @@ EXPORT_SYMBOL_GPL(usb_unlink_anchored_urbs); * * Call this is you want to be sure all an anchor's * URBs have finished + * + * Return: Non-zero if the anchor became unused. Zero on timeout. */ int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor, unsigned int timeout) { - return wait_event_timeout(anchor->wait, list_empty(&anchor->urb_list), + return wait_event_timeout(anchor->wait, + usb_anchor_check_wakeup(anchor), msecs_to_jiffies(timeout)); } EXPORT_SYMBOL_GPL(usb_wait_anchor_empty_timeout); @@ -851,8 +952,11 @@ EXPORT_SYMBOL_GPL(usb_wait_anchor_empty_timeout); * usb_get_from_anchor - get an anchor's oldest urb * @anchor: the anchor whose urb you want * - * this will take the oldest urb from an anchor, + * This will take the oldest urb from an anchor, * unanchor and return it + * + * Return: The oldest urb from @anchor, or %NULL if @anchor has no + * urbs associated with it. */ struct urb *usb_get_from_anchor(struct usb_anchor *anchor) { @@ -885,14 +989,20 @@ void usb_scuttle_anchored_urbs(struct usb_anchor *anchor) { struct urb *victim; unsigned long flags; + int surely_empty; + + do { + spin_lock_irqsave(&anchor->lock, flags); + while (!list_empty(&anchor->urb_list)) { + victim = list_entry(anchor->urb_list.prev, + struct urb, anchor_list); + __usb_unanchor_urb(victim, anchor); + } + surely_empty = usb_anchor_check_wakeup(anchor); - spin_lock_irqsave(&anchor->lock, flags); - while (!list_empty(&anchor->urb_list)) { - victim = list_entry(anchor->urb_list.prev, struct urb, - anchor_list); - __usb_unanchor_urb(victim, anchor); - } - spin_unlock_irqrestore(&anchor->lock, flags); + spin_unlock_irqrestore(&anchor->lock, flags); + cpu_relax(); + } while (!surely_empty); } EXPORT_SYMBOL_GPL(usb_scuttle_anchored_urbs); @@ -901,7 +1011,7 @@ EXPORT_SYMBOL_GPL(usb_scuttle_anchored_urbs); * usb_anchor_empty - is an anchor empty * @anchor: the anchor you want to query * - * returns 1 if the anchor has no urbs associated with it + * Return: 1 if the anchor has no urbs associated with it. */ int usb_anchor_empty(struct usb_anchor *anchor) { |
