Re: [PATCH 5/5] USB: Support for allocating USB 3.0 streams.

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

 



On Fri, 2 Apr 2010, Sarah Sharp wrote:

> Bulk endpoint streams were added in the USB 3.0 specification.  Streams
> allow a device driver to overload a bulk endpoint so that multiple
> transfers can be queued at once.
> 
> The device then decides which transfer it wants to work on first, and can
> queue part of a transfer before it switches to a new stream.  All this
> switching is invisible to the device driver, which just gets a completion
> for the URB.  Drivers that use streams must be able to handle URBs
> completing in a different order than they were submitted to the endpoint.
> 
> This requires adding new API to set up xHCI data structures to support
> multiple queues ("stream rings") per endpoint.  Drivers will allocate a
> number of stream IDs before enqueueing URBs to the bulk endpoints of the
> device, and free the stream IDs in their disconnect function.  See
> Documentation/usb/bulk-streams.txt for details.
> 
> The new mass storage device class, USB Attached SCSI Protocol (UASP), uses
> these streams API.
> 
> Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
> ---
>  drivers/usb/core/driver.c   |   54 +++++++++++++++++++++++++++++++++++++++++++
>  drivers/usb/core/hcd.h      |   10 ++++++++
>  drivers/usb/host/xhci-pci.c |    2 +
>  include/linux/usb.h         |   10 ++++++++
>  4 files changed, 76 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
> index f3c2338..cc599da 100644
> --- a/drivers/usb/core/driver.c
> +++ b/drivers/usb/core/driver.c
> @@ -497,6 +497,60 @@ void usb_driver_release_interface(struct usb_driver *driver,
>  }
>  EXPORT_SYMBOL_GPL(usb_driver_release_interface);
>  
> +/* Sets up a group of bulk endpoints to have num_streams stream IDs available.
> + * Drivers may queue multiple transfers to different stream IDs, which may
> + * complete in a different order than they were queued.
> + */
> +int usb_alloc_streams(struct usb_interface *interface,
> +		struct usb_host_endpoint **eps, unsigned int num_eps,
> +		unsigned int num_streams, gfp_t mem_flags)
> +{
> +	struct usb_hcd *hcd;
> +	struct usb_device *dev;
> +	int i;
> +
> +	dev = interface_to_usbdev(interface);
> +	hcd = bus_to_hcd(dev->bus);
> +	if (!hcd->driver->alloc_streams || !hcd->driver->free_streams)
> +		return -EINVAL;
> +	if (dev->speed != USB_SPEED_SUPER)
> +		return -EINVAL;
> +
> +	/* Streams only apply to bulk endpoints. */
> +	for (i = 0; i < num_eps; i++)
> +		if (!usb_endpoint_xfer_bulk(&eps[i]->desc))
> +			return -EINVAL;
> +
> +	return hcd->driver->alloc_streams(hcd, dev, eps, num_eps,
> +			num_streams, mem_flags);
> +}
> +EXPORT_SYMBOL_GPL(usb_alloc_streams);
> +
> +/* Reverts a group of bulk endpoints back to not using stream IDs.
> + * Can fail if we are given bad arguments.
> + */
> +void usb_free_streams(struct usb_interface *interface,
> +		struct usb_host_endpoint **eps, unsigned int num_eps,
> +		gfp_t mem_flags)
> +{
> +	struct usb_hcd *hcd;
> +	struct usb_device *dev;
> +	int i;
> +
> +	dev = interface_to_usbdev(interface);
> +	hcd = bus_to_hcd(dev->bus);
> +	if (dev->speed != USB_SPEED_SUPER)
> +		return;
> +
> +	/* Streams only apply to bulk endpoints. */
> +	for (i = 0; i < num_eps; i++)
> +		if (!usb_endpoint_xfer_bulk(&eps[i]->desc))
> +			return;
> +
> +	hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags);
> +}
> +EXPORT_SYMBOL_GPL(usb_free_streams);

Don't these routines belong in hcd.c rather than driver.c?  They are 
basically glue between the core and the HCDs, after all.

Alan Stern

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