Re: [RFC] Documentation update for Isochronous URB handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 9/11/2012 8:11 PM, Alan Stern wrote:
Here is a proposed update for the kernel's documentation on Isochronous
URBs.  It describes the behavior Clemens and I have been discussing,
which isn't implemented yet.  I'm working on separate patches to
implement the new behavior for EHCI, OHCI, and UHCI.

Pratyush, since you have been busily working on related issues for the
dwc3, you might be interested in this too.


Thanks for including me in CC. Whatever knowledge I have for the host software, this proposition seems correct to me.

Do you think that similar flag make sense in gadget framework too? Currently, gadget driver does not impose any restrictions on when to transmit a request by hardware, so peripheral driver always schedule as per its own criteria.

Regards
Pratyush

I have no idea how XHCI deals with these issues.

Anyway, everyone please take a quick look and let me know if this seems
okay.

Alan Stern



Index: usb-3.6/Documentation/usb/error-codes.txt
===================================================================
--- usb-3.6.orig/Documentation/usb/error-codes.txt
+++ usb-3.6/Documentation/usb/error-codes.txt
@@ -35,9 +35,8 @@ USB-specific:
  		d) ISO: number_of_packets is < 0
  		e) various other cases

--EAGAIN		a) specified ISO start frame too early
-		b) (using ISO-ASAP) too much scheduled for the future
-		   wait some time and try again.
+-EXDEV		ISO: URB_ISO_ASAP wasn't specified and all the frames
+		the URB would be scheduled in have already expired.

  -EFBIG		Host controller driver can't schedule that many ISO frames.

Index: usb-3.6/include/linux/usb.h
===================================================================
--- usb-3.6.orig/include/linux/usb.h
+++ usb-3.6/include/linux/usb.h
@@ -1101,8 +1101,8 @@ extern int usb_disabled(void);
   * Note: URB_DIR_IN/OUT is automatically set in usb_submit_urb().
   */
  #define URB_SHORT_NOT_OK	0x0001	/* report short reads as errors */
-#define URB_ISO_ASAP		0x0002	/* iso-only, urb->start_frame
-					 * ignored */
+#define URB_ISO_ASAP		0x0002	/* iso-only; use the first unexpired
+					 * slot in the schedule */
  #define URB_NO_TRANSFER_DMA_MAP	0x0004	/* urb->transfer_dma valid on submit */
  #define URB_NO_FSBR		0x0020	/* UHCI-specific */
  #define URB_ZERO_PACKET		0x0040	/* Finish bulk OUT with short packet */
@@ -1281,15 +1281,20 @@ typedef void (*usb_complete_t)(struct ur
   * 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
- * utilization allows, and then set start_frame to reflect the actual frame
- * selected during submission.  Otherwise drivers must specify the start_frame
- * and handle the case where the transfer can't begin then.  However, drivers
- * won't know how bandwidth is currently allocated, and while they can
- * find the current frame using usb_get_current_frame_number () they can't
- * know the range for that frame number.  (Ranges for frame counter values
- * are HC-specific, and can go from 256 to 65536 frames from "now".)
+ * If an isochronous endpoint queue isn't already running, the host
+ * controller will schedule a new URB to start as soon as bandwidth
+ * utilization allows.  If the queue is running then a new URB will be
+ * scheduled to start in the first transfer slot following the end of the
+ * preceding URB, if that slot has not already expired.  If the slot has
+ * expired (which can happen when IRQ delivery is delayed for a long time),
+ * the scheduling behavior depends on the URB_ISO_ASAP flag.  If the flag
+ * is clear then the URB will be scheduled to start in the expired slot,
+ * implying that some of its packets will not be transferred; if the flag
+ * is set then the URB will be scheduled in the first unexpired slot,
+ * breaking the queue's synchronization.  Upon URB completion, the
+ * start_frame field will be set to the (micro)frame number in which the
+ * transfer was scheduled.  Ranges for frame counter values are HC-specific
+ * and can go from as low as 256 to as high as 65536 frames.
   *
   * Isochronous URBs have a different data transfer model, in part because
   * the quality of service is only "best effort".  Callers provide specially
Index: usb-3.6/drivers/usb/core/urb.c
===================================================================
--- usb-3.6.orig/drivers/usb/core/urb.c
+++ usb-3.6/drivers/usb/core/urb.c
@@ -214,9 +214,25 @@ EXPORT_SYMBOL_GPL(usb_unanchor_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.

.



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux