ChangeSet 1.1608.84.24, 2004/03/10 12:42:44-08:00, david-b@pacbell.net [PATCH] USB: usbcore doc update Some doc updates, mostly from Alan Stern, clarifying quetions folk have asked recently about unlinking and about iso transfers. drivers/usb/core/urb.c | 65 ++++++++++++++++++++++++++++++++++++++++--------- include/linux/usb.h | 27 ++++++++++---------- 2 files changed, 68 insertions(+), 24 deletions(-) diff -Nru a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c --- a/drivers/usb/core/urb.c Tue Mar 16 15:02:18 2004 +++ b/drivers/usb/core/urb.c Tue Mar 16 15:02:18 2004 @@ -116,7 +116,8 @@ * 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 - * (also called "request cancellation"). + * (a software-induced fault, also called "request cancelation"). + * * URBs may be submitted in interrupt context. * * The caller must have correctly initialized the URB before submitting @@ -127,12 +128,23 @@ * * 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 are finished with the urb. When the completion + * 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. + * The exceptions relate to periodic transfer scheduling. For both + * interrupt and isochronous urbs, as part of successful URB submission + * 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. + * * For control endpoints, the synchronous usb_control_msg() call is * often used (in non-interrupt context) instead of this call. * That is often used through convenience wrappers, for the requests @@ -143,15 +155,17 @@ * * URBs may be submitted to endpoints before previous ones complete, to * minimize the impact of interrupt latencies and system overhead on data - * throughput. This is required for continuous isochronous data streams, + * throughput. With that queuing policy, an endpoint's queue would never + * be empty. This is required for continuous isochronous data streams, * and may also be required for some kinds of interrupt transfers. Such - * queueing also maximizes bandwidth utilization by letting USB controllers + * queuing also maximizes bandwidth utilization by letting USB controllers * start work on later requests before driver software has finished the - * completion processing for earlier requests. + * completion processing for earlier (successful) requests. * - * Bulk and Isochronous URBs may always be queued. At this writing, all - * mainstream host controller drivers support queueing for control and - * interrupt transfer requests. + * As of Linux 2.6, all USB endpoint transfer queues support depths greater + * than one. This was previously a HCD-specific behavior, except for ISO + * transfers. Non-isochronous endpoint queues are inactive during cleanup + * after faults (transfer errors or cancelation). * * Reserved Bandwidth Transfers: * @@ -389,7 +403,7 @@ * When the URB_ASYNC_UNLINK transfer flag for the URB is clear, this * request is synchronous. Success is indicated by returning zero, * at which time the urb will have been unlinked and its completion - * handler will have been called with urb->status -ENOENT. Failure is + * handler will have been called with urb->status == -ENOENT. Failure is * indicated by any other return value. * * The synchronous cancelation mode may not be used @@ -400,8 +414,37 @@ * When the URB_ASYNC_UNLINK transfer flag for the URB is set, this * request is asynchronous. Success is indicated by returning -EINPROGRESS, * at which time the urb will normally not have been unlinked. - * The completion function will see urb->status -ECONNRESET. Failure + * The completion function will see urb->status == -ECONNRESET. Failure * is indicated by any other return value. + * + * Unlinking and Endpoint Queues: + * + * Host Controller Driver (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 any + * fault (such as an error, or being unlinked) 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. + * + * 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 control URBs 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. */ int usb_unlink_urb(struct urb *urb) { diff -Nru a/include/linux/usb.h b/include/linux/usb.h --- a/include/linux/usb.h Tue Mar 16 15:02:18 2004 +++ b/include/linux/usb.h Tue Mar 16 15:02:18 2004 @@ -495,8 +495,8 @@ * @minor_base: the start of the minor range for this driver. * * This structure is used for the usb_register_dev() and - * usb_unregister_dev() functions, to consolodate a number of the - * paramaters used for them. + * usb_unregister_dev() functions, to consolidate a number of the + * parameters used for them. */ struct usb_class_driver { char *name; @@ -554,7 +554,7 @@ * @urb_list: For use by current owner of the URB. * @pipe: Holds endpoint number, direction, type, and more. * Create these values with the eight macros available; - * usb_{snd,rcv}TYPEpipe(dev,endpoint), where the type is "ctrl" + * usb_{snd,rcv}TYPEpipe(dev,endpoint), where the TYPE is "ctrl" * (control), "bulk", "int" (interrupt), or "iso" (isochronous). * For example usb_sndbulkpipe() or usb_rcvintpipe(). Endpoint * numbers range from zero to fifteen. Note that "in" endpoint two @@ -573,8 +573,8 @@ * the I/O request will be performed (unless URB_NO_TRANSFER_DMA_MAP * is set). This buffer must be suitable for DMA; allocate it with * kmalloc() or equivalent. For transfers to "in" endpoints, contents - * of this buffer will be modified. This buffer is used for data - * phases of control transfers. + * of this buffer will be modified. This buffer is used for the data + * stage of control transfers. * @transfer_dma: When transfer_flags includes URB_NO_TRANSFER_DMA_MAP, * the device driver is saying that it provided this DMA address, * which the host controller driver should use in preference to the @@ -597,8 +597,7 @@ * device driver has provided this DMA address for the setup packet. * The host controller driver should use this in preference to * setup_packet. - * @start_frame: Returns the initial frame for interrupt or isochronous - * transfers. + * @start_frame: Returns the initial frame for isochronous transfers. * @number_of_packets: Lists the number of ISO transfer buffers. * @interval: Specifies the polling interval for interrupt or isochronous * transfers. The units are frames (milliseconds) for for full and low @@ -666,13 +665,14 @@ * Interrupt UBS must provide an interval, saying how often (in milliseconds * or, for highspeed devices, 125 microsecond units) * to poll for transfers. After the URB has been submitted, the interval - * and start_frame fields reflect how the transfer was actually scheduled. + * field reflects how the transfer was actually scheduled. * The polling interval may be more frequent than requested. * For example, some controllers have a maximum interval of 32 microseconds, * while others support intervals of up to 1024 microseconds. * Isochronous URBs also have transfer intervals. (Note that for isochronous * endpoints, as well as high speed interrupt endpoints, the encoding of - * the transfer interval in the endpoint descriptor is logarithmic.) + * the transfer interval in the endpoint descriptor is logarithmic. + * Device drivers must convert that value to linear units themselves.) * * Isochronous URBs normally use the URB_ISO_ASAP transfer flag, telling * the host controller to schedule the transfer as soon as bandwidth @@ -705,8 +705,9 @@ * The context field is normally used to link URBs back to the relevant * driver or request state. * - * When completion callback is invoked for non-isochronous URBs, the - * actual_length field tells how many bytes were transferred. + * When the completion callback is invoked for non-isochronous URBs, the + * actual_length field tells how many bytes were transferred. This field + * is updated even when the URB terminated with an error or was unlinked. * * ISO transfer status is reported in the status and actual_length fields * of the iso_frame_desc array, and the number of errors is reported in @@ -733,9 +734,9 @@ int actual_length; /* (return) actual transfer length */ unsigned char *setup_packet; /* (in) setup packet (control only) */ dma_addr_t setup_dma; /* (in) dma addr for setup_packet */ - int start_frame; /* (modify) start frame (INT/ISO) */ + int start_frame; /* (modify) start frame (ISO) */ int number_of_packets; /* (in) number of ISO packets */ - int interval; /* (in) transfer interval (INT/ISO) */ + int interval; /* (modify) transfer interval (INT/ISO) */ int error_count; /* (return) number of ISO errors */ int timeout; /* (in) timeout, in jiffies */ void *context; /* (in) context for completion */