diff options
Diffstat (limited to 'drivers/usb/core/urb.c')
| -rw-r--r-- | drivers/usb/core/urb.c | 804 |
1 files changed, 637 insertions, 167 deletions
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index f2a1fed2a80..991386ceb4e 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -1,23 +1,23 @@ -#include <linux/config.h> #include <linux/module.h> #include <linux/string.h> #include <linux/bitops.h> #include <linux/slab.h> -#include <linux/init.h> - -#ifdef CONFIG_USB_DEBUG - #define DEBUG -#else - #undef DEBUG -#endif +#include <linux/log2.h> #include <linux/usb.h> -#include "hcd.h" +#include <linux/wait.h> +#include <linux/usb/hcd.h> +#include <linux/scatterlist.h> #define to_urb(d) container_of(d, struct urb, kref) + static void urb_destroy(struct kref *kref) { struct urb *urb = to_urb(kref); + + if (urb->transfer_flags & URB_FREE_BUFFER) + kfree(urb->transfer_buffer); + kfree(urb); } @@ -40,9 +40,10 @@ void usb_init_urb(struct urb *urb) if (urb) { memset(urb, 0, sizeof(*urb)); kref_init(&urb->kref); - spin_lock_init(&urb->lock); + INIT_LIST_HEAD(&urb->anchor_list); } } +EXPORT_SYMBOL_GPL(usb_init_urb); /** * usb_alloc_urb - creates a new urb for a USB driver to use @@ -51,29 +52,30 @@ void usb_init_urb(struct urb *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 = (struct urb *)kmalloc(sizeof(struct urb) + + urb = kmalloc(sizeof(struct urb) + iso_packets * sizeof(struct usb_iso_packet_descriptor), mem_flags); if (!urb) { - err("alloc_urb: kmalloc failed"); + printk(KERN_ERR "alloc_urb: kmalloc failed\n"); return NULL; } usb_init_urb(urb); return urb; } +EXPORT_SYMBOL_GPL(usb_alloc_urb); /** * usb_free_urb - frees the memory used by a urb when all users of it are finished @@ -82,14 +84,15 @@ struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags) * Must be called when a user of a urb is finished with it. When the last user * of the urb calls this function, the memory of the urb is freed. * - * Note: The transfer buffer associated with the urb is not freed, that must be - * done elsewhere. + * Note: The transfer buffer associated with the urb is not freed unless the + * URB_FREE_BUFFER transfer flag is set. */ void usb_free_urb(struct urb *urb) { if (urb) kref_put(&urb->kref, urb_destroy); } +EXPORT_SYMBOL_GPL(usb_free_urb); /** * usb_get_urb - increments the reference count of the urb @@ -99,16 +102,87 @@ void usb_free_urb(struct urb *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) +struct urb *usb_get_urb(struct urb *urb) { if (urb) kref_get(&urb->kref); return urb; } - - +EXPORT_SYMBOL_GPL(usb_get_urb); + +/** + * usb_anchor_urb - anchors an URB while it is processed + * @urb: pointer to the urb to anchor + * @anchor: pointer to the anchor + * + * This can be called to have access to URBs which are to be executed + * without bothering to track them + */ +void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor) +{ + unsigned long flags; + + spin_lock_irqsave(&anchor->lock, flags); + usb_get_urb(urb); + list_add_tail(&urb->anchor_list, &anchor->urb_list); + urb->anchor = anchor; + + 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 (usb_anchor_check_wakeup(anchor)) + wake_up(&anchor->wait); +} + +/** + * usb_unanchor_urb - unanchors an URB + * @urb: pointer to the urb to anchor + * + * Call this to stop the system keeping track of this URB + */ +void usb_unanchor_urb(struct urb *urb) +{ + unsigned long flags; + struct usb_anchor *anchor; + + if (!urb) + return; + + anchor = urb->anchor; + if (!anchor) + return; + + spin_lock_irqsave(&anchor->lock, flags); + /* + * At this point, we could be competing with another thread which + * has the same intention. To protect the urb from being unanchored + * twice, only the winner of the race gets the job. + */ + if (likely(anchor == urb->anchor)) + __usb_unanchor_urb(urb, anchor); + spin_unlock_irqrestore(&anchor->lock, flags); +} +EXPORT_SYMBOL_GPL(usb_unanchor_urb); + /*-------------------------------------------------------------------*/ /** @@ -121,7 +195,7 @@ struct urb * usb_get_urb(struct urb *urb) * describing that request to the USB subsystem. Request completion will * be indicated later, asynchronously, by calling the completion handler. * The three types of completion are success, error, and unlink - * (a software-induced fault, also called "request cancellation"). + * (a software-induced fault, also called "request cancellation"). * * URBs may be submitted in interrupt context. * @@ -131,13 +205,12 @@ struct urb * usb_get_urb(struct urb *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. @@ -146,9 +219,25 @@ struct urb * usb_get_urb(struct urb *urb) * urb->interval is modified to reflect the actual transfer period used * (normally some power of two units). And for isochronous urbs, * urb->start_frame is modified to reflect when the URB's transfers were - * scheduled to start. Not all isochronous transfer scheduling policies - * will work, but most host controller drivers should easily handle ISO - * queues going from now until 10-200 msec into the future. + * scheduled to start. + * + * Not all isochronous transfer scheduling policies will work, but most + * host controller drivers should easily handle ISO queues going from now + * until 10-200 msec into the future. Drivers should try to keep at + * least one or two msec of data in the queue; many controllers require + * that new transfers start at least 1 msec in the future when they are + * added. If the driver is unable to keep up and the queue empties out, + * the behavior for new submissions is governed by the URB_ISO_ASAP flag. + * If the flag is set, or if the queue is idle, then the URB is always + * assigned to the first available (and not yet expired) slot in the + * endpoint's schedule. If the flag is not set and the queue is active + * then the URB is always assigned to the next slot in the schedule + * following the end of the endpoint's previous URB, even if that slot is + * in the past. When a packet is assigned in this way to a slot that has + * already expired, the packet is not transmitted and the corresponding + * usb_iso_packet_descriptor's status field will return -EXDEV. If this + * would happen to all the packets in the URB, submission fails with a + * -EXDEV error code. * * For control endpoints, the synchronous usb_control_msg() call is * often used (in non-interrupt context) instead of this call. @@ -156,6 +245,9 @@ struct urb * usb_get_urb(struct urb *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 @@ -180,9 +272,15 @@ struct urb * usb_get_urb(struct urb *urb) * If the USB subsystem can't allocate sufficient bandwidth to perform * the periodic request, submitting such a periodic request should fail. * + * For devices under xHCI, the bandwidth is reserved at configuration time, or + * when the alt setting is selected. If there is not enough bus bandwidth, the + * configuration/alt setting request will fail. Therefore, submissions to + * periodic endpoints on devices under xHCI should never fail due to bandwidth + * constraints. + * * 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 @@ -204,7 +302,7 @@ struct urb * usb_get_urb(struct urb *urb) * semaphores), or * (c) current->state != TASK_RUNNING, this is the case only after * you've changed it. - * + * * GFP_NOIO is used in the block io path and error handling of storage * devices. * @@ -226,49 +324,71 @@ struct urb * usb_get_urb(struct urb *urb) */ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) { - int pipe, temp, max; - struct usb_device *dev; - struct usb_operations *op; - int is_out; + static int pipetypes[4] = { + PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT + }; + int xfertype, max; + struct usb_device *dev; + struct usb_host_endpoint *ep; + int is_out; + unsigned int allowed; - if (!urb || urb->hcpriv || !urb->complete) + if (!urb || !urb->complete) return -EINVAL; - if (!(dev = urb->dev) || - (dev->state < USB_STATE_DEFAULT) || - (!dev->bus) || (dev->devnum <= 0)) - return -ENODEV; - if (dev->bus->controller->power.power_state.event != PM_EVENT_ON - || dev->state == USB_STATE_SUSPENDED) - return -EHOSTUNREACH; - if (!(op = dev->bus->op) || !op->submit_urb) + if (urb->hcpriv) { + WARN_ONCE(1, "URB %p submitted while active\n", urb); + return -EBUSY; + } + + dev = urb->dev; + if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED)) return -ENODEV; + /* For now, get the endpoint from the pipe. Eventually drivers + * will be required to set urb->ep directly and we will eliminate + * urb->pipe. + */ + ep = usb_pipe_endpoint(dev, urb->pipe); + if (!ep) + return -ENOENT; + + urb->ep = ep; urb->status = -EINPROGRESS; urb->actual_length = 0; - urb->bandwidth = 0; /* Lots of sanity checks, so HCDs can rely on clean data * and don't need to duplicate tests */ - pipe = urb->pipe; - temp = usb_pipetype (pipe); - is_out = usb_pipeout (pipe); + xfertype = usb_endpoint_type(&ep->desc); + if (xfertype == USB_ENDPOINT_XFER_CONTROL) { + struct usb_ctrlrequest *setup = + (struct usb_ctrlrequest *) urb->setup_packet; - if (!usb_pipecontrol (pipe) && dev->state < USB_STATE_CONFIGURED) - return -ENODEV; + if (!setup) + return -ENOEXEC; + is_out = !(setup->bRequestType & USB_DIR_IN) || + !setup->wLength; + } else { + is_out = usb_endpoint_dir_out(&ep->desc); + } - /* FIXME there should be a sharable lock protecting us against - * config/altsetting changes and disconnects, kicking in here. - * (here == before maxpacket, and eventually endpoint type, - * checks get made.) - */ + /* Clear the internal flags and cache the direction for later use */ + urb->transfer_flags &= ~(URB_DIR_MASK | URB_DMA_MAP_SINGLE | + URB_DMA_MAP_PAGE | URB_DMA_MAP_SG | URB_MAP_LOCAL | + URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL | + URB_DMA_SG_COMBINED); + urb->transfer_flags |= (is_out ? URB_DIR_OUT : URB_DIR_IN); + + if (xfertype != USB_ENDPOINT_XFER_CONTROL && + dev->state < USB_STATE_CONFIGURED) + return -ENODEV; - max = usb_maxpacket (dev, pipe, is_out); + max = usb_endpoint_maxp(&ep->desc); if (max <= 0) { dev_dbg(&dev->dev, "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", - usb_pipeendpoint (pipe), is_out ? "out" : "in", - __FUNCTION__, max); + usb_endpoint_num(&ep->desc), is_out ? "out" : "in", + __func__, max); return -EMSGSIZE; } @@ -276,9 +396,19 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) * but drivers only control those sizes for ISO. * while we're checking, initialize return status. */ - if (temp == PIPE_ISOCHRONOUS) { + if (xfertype == USB_ENDPOINT_XFER_ISOC) { int n, len; + /* SuperSpeed isoc endpoints have up to 16 bursts of up to + * 3 packets each + */ + 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_HIGH) { int mult = 1 + ((max >> 11) & 0x03); @@ -286,58 +416,65 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) max *= mult; } - if (urb->number_of_packets <= 0) + if (urb->number_of_packets <= 0) return -EINVAL; for (n = 0; n < urb->number_of_packets; n++) { - len = urb->iso_frame_desc [n].length; - if (len < 0 || len > max) + len = urb->iso_frame_desc[n].length; + if (len < 0 || len > max) return -EMSGSIZE; - urb->iso_frame_desc [n].status = -EXDEV; - urb->iso_frame_desc [n].actual_length = 0; + 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 && + dev->speed != USB_SPEED_WIRELESS) { + 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 < 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 orig_flags = urb->transfer_flags; - unsigned int allowed; - - /* enforce simple/standard policy */ - allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | - URB_NO_INTERRUPT); - switch (temp) { - case PIPE_BULK: + + /* 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", + usb_pipetype(urb->pipe), pipetypes[xfertype]); + + /* Check against a simple/standard policy */ + allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT | URB_DIR_MASK | + URB_FREE_BUFFER); + switch (xfertype) { + case USB_ENDPOINT_XFER_BULK: if (is_out) allowed |= URB_ZERO_PACKET; /* FALLTHROUGH */ - case PIPE_CONTROL: + case USB_ENDPOINT_XFER_CONTROL: allowed |= URB_NO_FSBR; /* only affects UHCI */ /* FALLTHROUGH */ default: /* all non-iso endpoints */ if (!is_out) allowed |= URB_SHORT_NOT_OK; break; - case PIPE_ISOCHRONOUS: + case USB_ENDPOINT_XFER_ISOC: allowed |= URB_ISO_ASAP; break; } - urb->transfer_flags &= allowed; + allowed &= urb->transfer_flags; + + /* warn if submitter gave bogus flags */ + if (allowed != urb->transfer_flags) + dev_WARN(&dev->dev, "BOGUS urb flags, %x --> %x\n", + urb->transfer_flags, allowed); - /* fail if submitter gave bogus flags */ - if (urb->transfer_flags != orig_flags) { - err ("BOGUS urb flags, %x --> %x", - orig_flags, urb->transfer_flags); - return -EINVAL; - } - } -#endif /* * Force periodic transfer intervals to be legal values that are * a power of two (so HCDs don't need to). @@ -346,45 +483,64 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) * supports different values... this uses EHCI/UHCI defaults (and * EHCI can use smaller non-default values). */ - switch (temp) { - case PIPE_ISOCHRONOUS: - case PIPE_INTERRUPT: + switch (xfertype) { + case USB_ENDPOINT_XFER_ISOC: + case USB_ENDPOINT_XFER_INT: /* too small? */ - if (urb->interval <= 0) - return -EINVAL; + switch (dev->speed) { + case USB_SPEED_WIRELESS: + if ((urb->interval < 6) + && (xfertype == USB_ENDPOINT_XFER_INT)) + return -EINVAL; + default: + if (urb->interval <= 0) + return -EINVAL; + break; + } /* too big? */ switch (dev->speed) { + 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 + /* NOTE usb handles 2^15 */ if (urb->interval > (1024 * 8)) urb->interval = 1024 * 8; - temp = 1024 * 8; + max = 1024 * 8; break; case USB_SPEED_FULL: /* units are frames/msec */ case USB_SPEED_LOW: - if (temp == PIPE_INTERRUPT) { + if (xfertype == USB_ENDPOINT_XFER_INT) { if (urb->interval > 255) return -EINVAL; - // NOTE ohci only handles up to 32 - temp = 128; + /* NOTE ohci only handles up to 32 */ + max = 128; } else { if (urb->interval > 1024) urb->interval = 1024; - // NOTE usb and ohci handle up to 2^15 - temp = 1024; + /* NOTE usb and ohci handle up to 2^15 */ + max = 1024; } break; default: return -EINVAL; } - /* power of two? */ - while (temp > urb->interval) - temp >>= 1; - urb->interval = temp; + 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)); + } } - return op->submit_urb (urb, mem_flags); + return usb_hcd_submit_urb(urb, mem_flags); } +EXPORT_SYMBOL_GPL(usb_submit_urb); /*-------------------------------------------------------------------*/ @@ -393,64 +549,85 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) * @urb: pointer to urb describing a previously submitted request, * may be NULL * - * This routine cancels an in-progress request. URBs complete only - * once per submission, and may be canceled only once per submission. - * Successful cancellation means the requests's completion handler will - * be called with a status code indicating that the request has been - * canceled (rather than any other code) and will quickly be removed - * from host controller data structures. - * - * This request is always asynchronous. - * Success is indicated by returning -EINPROGRESS, - * at which time the URB will normally have been unlinked but not yet - * given back to the device driver. When it is called, the completion - * function will see urb->status == -ECONNRESET. Failure is indicated - * by any other return value. Unlinking will fail when the URB is not - * currently "linked" (i.e., it was never submitted, or it was unlinked - * before, or the hardware is already finished with it), even if the - * completion handler has not yet run. + * This routine cancels an in-progress request. URBs complete only once + * per submission, and may be canceled only once per submission. + * Successful cancellation means termination of @urb will be expedited + * and the completion handler will be called with a status code + * indicating that the request has been canceled (rather than any other + * 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. + * + * This request is asynchronous, however the HCD might call the ->complete() + * callback during unlink. Therefore when drivers call usb_unlink_urb(), they + * must not hold any locks that may be taken by the completion function. + * Success is indicated by returning -EINPROGRESS, at which time the URB will + * probably not yet have been given back to the device driver. When it is + * eventually called, the completion function will see @urb->status == + * -ECONNRESET. + * Failure is indicated by usb_unlink_urb() returning any other value. + * Unlinking will fail when @urb is not currently "linked" (i.e., it was + * never submitted, or it was unlinked before, or the hardware is already + * finished with it), even if the completion handler has not yet run. + * + * The URB must not be deallocated while this routine is running. In + * 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 + * root hubs but only to endpoint queues for physical USB devices.] + * * Host Controller Drivers (HCDs) place all the URBs for a particular * endpoint in a queue. Normally the queue advances as the controller * hardware processes each request. But when an URB terminates with an - * error its queue stops, at least until that URB's completion routine - * returns. It is guaranteed that the queue will not restart until all - * its unlinked URBs have been fully retired, with their completion - * routines run, even if that's not until some time after the original - * completion handler returns. Normally the same behavior and guarantees - * apply when an URB terminates because it was unlinked; however if an - * URB is unlinked before the hardware has started to execute it, then - * its queue is not guaranteed to stop until all the preceding URBs have - * completed. - * - * This means that USB device drivers can safely build deep queues for - * large or complex transfers, and clean them up reliably after any sort - * of aborted transfer by unlinking all pending URBs at the first fault. - * - * Note that an URB terminating early because a short packet was received - * will count as an error if and only if the URB_SHORT_NOT_OK flag is set. - * Also, that all unlinks performed in any URB completion handler must - * be asynchronous. - * - * Queues for isochronous endpoints are treated differently, because they - * advance at fixed rates. Such queues do not stop when an URB is unlinked. - * An unlinked URB may leave a gap in the stream of packets. It is undefined - * whether such gaps can be filled in. - * - * When a control URB terminates with an error, it is likely that the - * status stage of the transfer will not take place, even if it is merely - * a soft error resulting from a short-packet with URB_SHORT_NOT_OK set. + * error its queue generally stops (see below), at least until that URB's + * completion routine returns. It is guaranteed that a stopped queue + * will not restart until all its unlinked URBs have been fully retired, + * with their completion routines run, even if that's not until some time + * after the original completion handler returns. The same behavior and + * guarantee apply when an URB terminates because it was unlinked. + * + * Bulk and interrupt endpoint queues are guaranteed to stop whenever an + * URB terminates with any sort of error, including -ECONNRESET, -ENOENT, + * and -EREMOTEIO. Control endpoint queues behave the same way except + * that they are not guaranteed to stop for -EREMOTEIO errors. Queues + * for isochronous endpoints are treated differently, because they must + * advance at fixed rates. Such queues do not stop when an URB + * encounters an error or is unlinked. An unlinked isochronous URB may + * leave a gap in the stream of packets; it is undefined whether such + * gaps can be filled in. + * + * Note that early termination of an URB because a short packet was + * received will generate a -EREMOTEIO error if and only if the + * URB_SHORT_NOT_OK flag is set. By setting this flag, USB device + * drivers can build deep queues for large or complex bulk transfers + * and clean them up reliably after any sort of aborted transfer by + * unlinking all pending URBs at the first fault. + * + * When a control URB terminates with an error other than -EREMOTEIO, it + * is quite likely that the status stage of the transfer will not take + * place. */ int usb_unlink_urb(struct urb *urb) { if (!urb) return -EINVAL; - if (!(urb->dev && urb->dev->bus && urb->dev->bus->op)) + if (!urb->dev) return -ENODEV; - return urb->dev->bus->op->unlink_urb(urb, -ECONNRESET); + if (!urb->ep) + return -EIDRM; + return usb_hcd_unlink_urb(urb, -ECONNRESET); } +EXPORT_SYMBOL_GPL(usb_unlink_urb); /** * usb_kill_urb - cancel a transfer request and wait for it to finish @@ -468,31 +645,324 @@ int usb_unlink_urb(struct urb *urb) * with error -EPERM. Thus even if the URB's completion handler always * tries to resubmit, it will not succeed and the URB will become idle. * + * The URB must not be deallocated while this routine is running. In + * particular, when a driver calls this routine, it must insure that the + * completion handler cannot deallocate the URB. + * * This routine may not be used in an interrupt context (such as a bottom * half or a completion handler), or when holding a spinlock, or in other * situations where the caller can't schedule(). + * + * This routine should not be called by a driver after its disconnect + * method has returned. */ void usb_kill_urb(struct urb *urb) { - if (!(urb && urb->dev && urb->dev->bus && urb->dev->bus->op)) + might_sleep(); + if (!(urb && urb->dev && urb->ep)) + return; + atomic_inc(&urb->reject); + + usb_hcd_unlink_urb(urb, -ENOENT); + wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); + + atomic_dec(&urb->reject); +} +EXPORT_SYMBOL_GPL(usb_kill_urb); + +/** + * usb_poison_urb - reliably kill a transfer and prevent further use of an URB + * @urb: pointer to URB describing a previously submitted request, + * may be NULL + * + * This routine cancels an in-progress request. It is guaranteed that + * upon return all completion handlers will have finished and the URB + * will be totally idle and cannot be reused. These features make + * this an ideal way to stop I/O in a disconnect() callback. + * If the request has not already finished or been unlinked + * the completion handler will see urb->status == -ENOENT. + * + * After and while the routine runs, attempts to resubmit the URB will fail + * with error -EPERM. Thus even if the URB's completion handler always + * tries to resubmit, it will not succeed and the URB will become idle. + * + * The URB must not be deallocated while this routine is running. In + * particular, when a driver calls this routine, it must insure that the + * completion handler cannot deallocate the URB. + * + * This routine may not be used in an interrupt context (such as a bottom + * half or a completion handler), or when holding a spinlock, or in other + * situations where the caller can't schedule(). + * + * This routine should not be called by a driver after its disconnect + * method has returned. + */ +void usb_poison_urb(struct urb *urb) +{ + might_sleep(); + if (!urb) + return; + atomic_inc(&urb->reject); + + if (!urb->dev || !urb->ep) return; - spin_lock_irq(&urb->lock); - ++urb->reject; - spin_unlock_irq(&urb->lock); - urb->dev->bus->op->unlink_urb(urb, -ENOENT); + usb_hcd_unlink_urb(urb, -ENOENT); wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); +} +EXPORT_SYMBOL_GPL(usb_poison_urb); + +void usb_unpoison_urb(struct urb *urb) +{ + if (!urb) + return; + + atomic_dec(&urb->reject); +} +EXPORT_SYMBOL_GPL(usb_unpoison_urb); + +/** + * usb_block_urb - reliably prevent further use of an URB + * @urb: pointer to URB to be blocked, may be NULL + * + * After the routine has run, attempts to resubmit the URB will fail + * with error -EPERM. Thus even if the URB's completion handler always + * tries to resubmit, it will not succeed and the URB will become idle. + * + * The URB must not be deallocated while this routine is running. In + * particular, when a driver calls this routine, it must insure that the + * completion handler cannot deallocate the URB. + */ +void usb_block_urb(struct urb *urb) +{ + if (!urb) + return; + + atomic_inc(&urb->reject); +} +EXPORT_SYMBOL_GPL(usb_block_urb); + +/** + * usb_kill_anchored_urbs - cancel transfer requests en masse + * @anchor: anchor the requests are bound to + * + * this allows all outstanding URBs to be killed starting + * from the back of the queue + * + * This routine should not be called by a driver after its disconnect + * method has returned. + */ +void usb_kill_anchored_urbs(struct usb_anchor *anchor) +{ + struct urb *victim; - spin_lock_irq(&urb->lock); - --urb->reject; - spin_unlock_irq(&urb->lock); + 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); + spin_lock_irq(&anchor->lock); + } + spin_unlock_irq(&anchor->lock); +} +EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs); + + +/** + * usb_poison_anchored_urbs - cease all traffic from an anchor + * @anchor: anchor the requests are bound to + * + * this allows all outstanding URBs to be poisoned starting + * from the back of the queue. Newly added URBs will also be + * poisoned + * + * This routine should not be called by a driver after its disconnect + * method has returned. + */ +void usb_poison_anchored_urbs(struct usb_anchor *anchor) +{ + struct urb *victim; + + 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); + spin_lock_irq(&anchor->lock); + } + spin_unlock_irq(&anchor->lock); +} +EXPORT_SYMBOL_GPL(usb_poison_anchored_urbs); + +/** + * usb_unpoison_anchored_urbs - let an anchor be used successfully again + * @anchor: anchor the requests are bound to + * + * Reverses the effect of usb_poison_anchored_urbs + * the anchor can be used normally after it returns + */ +void usb_unpoison_anchored_urbs(struct usb_anchor *anchor) +{ + unsigned long flags; + struct urb *lazarus; + + spin_lock_irqsave(&anchor->lock, flags); + list_for_each_entry(lazarus, &anchor->urb_list, anchor_list) { + usb_unpoison_urb(lazarus); + } + anchor->poisoned = 0; + 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 + * + * this allows all outstanding URBs to be unlinked starting + * from the back of the queue. This function is asynchronous. + * The unlinking is just triggered. It may happen after this + * function has returned. + * + * This routine should not be called by a driver after its disconnect + * method has returned. + */ +void usb_unlink_anchored_urbs(struct usb_anchor *anchor) +{ + struct urb *victim; + + while ((victim = usb_get_from_anchor(anchor)) != NULL) { + usb_unlink_urb(victim); + usb_put_urb(victim); + } +} +EXPORT_SYMBOL_GPL(usb_unlink_anchored_urbs); + +/** + * usb_anchor_suspend_wakeups + * @anchor: the anchor you want to suspend wakeups on + * + * 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 + * + * 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_anchor_resume_wakeups(struct usb_anchor *anchor) +{ + if (!anchor) + return; + + atomic_dec(&anchor->suspend_wakeups); + if (usb_anchor_check_wakeup(anchor)) + wake_up(&anchor->wait); +} +EXPORT_SYMBOL_GPL(usb_anchor_resume_wakeups); + +/** + * usb_wait_anchor_empty_timeout - wait for an anchor to be unused + * @anchor: the anchor you want to become unused + * @timeout: how long you are willing to wait in milliseconds + * + * 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, + usb_anchor_check_wakeup(anchor), + msecs_to_jiffies(timeout)); +} +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, + * 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) +{ + struct urb *victim; + unsigned long flags; + + spin_lock_irqsave(&anchor->lock, flags); + if (!list_empty(&anchor->urb_list)) { + victim = list_entry(anchor->urb_list.next, struct urb, + anchor_list); + usb_get_urb(victim); + __usb_unanchor_urb(victim, anchor); + } else { + victim = NULL; + } + spin_unlock_irqrestore(&anchor->lock, flags); + + return victim; +} + +EXPORT_SYMBOL_GPL(usb_get_from_anchor); + +/** + * usb_scuttle_anchored_urbs - unanchor all an anchor's urbs + * @anchor: the anchor whose urbs you want to unanchor + * + * use this to get rid of all an anchor's urbs + */ +void usb_scuttle_anchored_urbs(struct usb_anchor *anchor) +{ + struct urb *victim; + unsigned long flags; + + 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); +} + +EXPORT_SYMBOL_GPL(usb_scuttle_anchored_urbs); + +/** + * usb_anchor_empty - is an anchor empty + * @anchor: the anchor you want to query + * + * Return: 1 if the anchor has no urbs associated with it. + */ +int usb_anchor_empty(struct usb_anchor *anchor) +{ + return list_empty(&anchor->urb_list); } -EXPORT_SYMBOL(usb_init_urb); -EXPORT_SYMBOL(usb_alloc_urb); -EXPORT_SYMBOL(usb_free_urb); -EXPORT_SYMBOL(usb_get_urb); -EXPORT_SYMBOL(usb_submit_urb); -EXPORT_SYMBOL(usb_unlink_urb); -EXPORT_SYMBOL(usb_kill_urb); +EXPORT_SYMBOL_GPL(usb_anchor_empty); |
