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 */
