linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC/PATCH v6 1/5] usb: Add streams support to the gadget framework
@ 2011-04-14 13:35 Tatyana Brokhman
  2011-04-14 17:39 ` Alan Stern
  2011-04-15  4:19 ` Christoph Hellwig
  0 siblings, 2 replies; 4+ messages in thread
From: Tatyana Brokhman @ 2011-04-14 13:35 UTC (permalink / raw)
  To: gregkh
  Cc: linux-arm-msm, ablay, balbi, Tatyana Brokhman, Maya Erez,
	open list:USB GADGET/PERIPH..., open list

This patch defines necessary fields to support streaming for USB3.0.
It implements a new function (usb_ep_autoconfig_ss) to be used instead of
the existing usb_ep_autoconfig when working in SS mode and there is a
need to search for an endpoint according to the number of required
streams.


Signed-off-by: Maya Erez <merez@codeaurora.org>
Signed-off-by: Tatyana Brokhman <tlinder@codeaurora.org>

diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index e7e373a..f32f8d9 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -63,13 +63,16 @@ static int
 ep_matches (
 	struct usb_gadget		*gadget,
 	struct usb_ep			*ep,
-	struct usb_endpoint_descriptor	*desc
+	struct usb_endpoint_descriptor	*desc,
+	struct usb_ss_ep_comp_descriptor *ep_comp
 )
 {
 	u8		type;
 	const char	*tmp;
 	u16		max;
 
+	int		num_req_streams = 0;
+
 	/* endpoint already claimed? */
 	if (NULL != ep->driver_data)
 		return 0;
@@ -129,6 +132,22 @@ ep_matches (
 	}
 
 	/*
+	 * Get the number of required streams from the EP companion
+	 * descriptor and see if the EP matches it
+	 */
+	if (usb_endpoint_xfer_bulk(desc)) {
+		if (ep_comp) {
+			num_req_streams = ep_comp->bmAttributes & 0x1f;
+			if (num_req_streams > ep->num_supported_strms)
+				return 0;
+			/* Update the ep_comp descriptor if needed */
+			if (num_req_streams != ep->num_supported_strms)
+				ep_comp->bmAttributes = ep->num_supported_strms;
+		}
+
+	}
+
+	/*
 	 * If the protocol driver hasn't yet decided on wMaxPacketSize
 	 * and wants to know the maximum possible, provide the info.
 	 */
@@ -209,38 +228,53 @@ find_ep (struct usb_gadget *gadget, const char *name)
 }
 
 /**
- * usb_ep_autoconfig - choose an endpoint matching the descriptor
+ * usb_ep_autoconfig_ss() - choose an endpoint matching the ep
+ * descriptor and ep companion descriptor
  * @gadget: The device to which the endpoint must belong.
  * @desc: Endpoint descriptor, with endpoint direction and transfer mode
- *	initialized.  For periodic transfers, the maximum packet
- *	size must also be initialized.  This is modified on success.
+ *    initialized.  For periodic transfers, the maximum packet
+ *    size must also be initialized.  This is modified on
+ *    success.
+ * @ep_comp: Endpoint companion descriptor, with the required
+ *    number of streams. Will be modified when the chosen EP
+ *    supports a different number of streams.
  *
- * By choosing an endpoint to use with the specified descriptor, this
- * routine simplifies writing gadget drivers that work with multiple
- * USB device controllers.  The endpoint would be passed later to
- * usb_ep_enable(), along with some descriptor.
+ * This routine replaces the usb_ep_autoconfig when needed
+ * superspeed enhancments. If such enhancemnets are required,
+ * the FD should call usb_ep_autoconfig_ss directly and provide
+ * the additional ep_comp parameter.
+ *
+ * By choosing an endpoint to use with the specified descriptor,
+ * this routine simplifies writing gadget drivers that work with
+ * multiple USB device controllers.  The endpoint would be
+ * passed later to usb_ep_enable(), along with some descriptor.
  *
  * That second descriptor won't always be the same as the first one.
  * For example, isochronous endpoints can be autoconfigured for high
  * bandwidth, and then used in several lower bandwidth altsettings.
  * Also, high and full speed descriptors will be different.
  *
- * Be sure to examine and test the results of autoconfiguration on your
- * hardware.  This code may not make the best choices about how to use the
- * USB controller, and it can't know all the restrictions that may apply.
- * Some combinations of driver and hardware won't be able to autoconfigure.
+ * Be sure to examine and test the results of autoconfiguration
+ * on your hardware.  This code may not make the best choices
+ * about how to use the USB controller, and it can't know all
+ * the restrictions that may apply. Some combinations of driver
+ * and hardware won't be able to autoconfigure.
  *
  * On success, this returns an un-claimed usb_ep, and modifies the endpoint
  * descriptor bEndpointAddress.  For bulk endpoints, the wMaxPacket value
- * is initialized as if the endpoint were used at full speed.  To prevent
- * the endpoint from being returned by a later autoconfig call, claim it
- * by assigning ep->driver_data to some non-null value.
+ * is initialized as if the endpoint were used at full speed and
+ * the bmAttribute field in the ep companion descriptor is
+ * updated with the assigned number of streams if it is
+ * different from the original value. To prevent the endpoint
+ * from being returned by a later autoconfig call, claim it by
+ * assigning ep->driver_data to some non-null value.
  *
  * On failure, this returns a null endpoint descriptor.
  */
-struct usb_ep *usb_ep_autoconfig (
+struct usb_ep *usb_ep_autoconfig_ss(
 	struct usb_gadget		*gadget,
-	struct usb_endpoint_descriptor	*desc
+	struct usb_endpoint_descriptor	*desc,
+	struct usb_ss_ep_comp_descriptor *ep_comp
 )
 {
 	struct usb_ep	*ep;
@@ -254,23 +288,24 @@ struct usb_ep *usb_ep_autoconfig (
 	if (gadget_is_net2280 (gadget) && type == USB_ENDPOINT_XFER_INT) {
 		/* ep-e, ep-f are PIO with only 64 byte fifos */
 		ep = find_ep (gadget, "ep-e");
-		if (ep && ep_matches (gadget, ep, desc))
+		if (ep && ep_matches(gadget, ep, desc, ep_comp))
 			return ep;
 		ep = find_ep (gadget, "ep-f");
-		if (ep && ep_matches (gadget, ep, desc))
+		if (ep && ep_matches(gadget, ep, desc, ep_comp))
 			return ep;
 
 	} else if (gadget_is_goku (gadget)) {
 		if (USB_ENDPOINT_XFER_INT == type) {
 			/* single buffering is enough */
-			ep = find_ep (gadget, "ep3-bulk");
-			if (ep && ep_matches (gadget, ep, desc))
+			ep = find_ep(gadget, "ep3-bulk");
+			if (ep && ep_matches(gadget, ep, desc, ep_comp))
 				return ep;
 		} else if (USB_ENDPOINT_XFER_BULK == type
 				&& (USB_DIR_IN & desc->bEndpointAddress)) {
 			/* DMA may be available */
-			ep = find_ep (gadget, "ep2-bulk");
-			if (ep && ep_matches (gadget, ep, desc))
+			ep = find_ep(gadget, "ep2-bulk");
+			if (ep && ep_matches(gadget, ep, desc,
+					      ep_comp))
 				return ep;
 		}
 
@@ -289,14 +324,14 @@ struct usb_ep *usb_ep_autoconfig (
 				ep = find_ep(gadget, "ep2out");
 		} else
 			ep = NULL;
-		if (ep && ep_matches (gadget, ep, desc))
+		if (ep && ep_matches(gadget, ep, desc, ep_comp))
 			return ep;
 #endif
 	}
 
 	/* Second, look at endpoints until an unclaimed one looks usable */
 	list_for_each_entry (ep, &gadget->ep_list, ep_list) {
-		if (ep_matches (gadget, ep, desc))
+		if (ep_matches(gadget, ep, desc, ep_comp))
 			return ep;
 	}
 
@@ -305,6 +340,46 @@ struct usb_ep *usb_ep_autoconfig (
 }
 
 /**
+ * usb_ep_autoconfig() - choose an endpoint matching the
+ * descriptor
+ * @gadget: The device to which the endpoint must belong.
+ * @desc: Endpoint descriptor, with endpoint direction and transfer mode
+ *	initialized.  For periodic transfers, the maximum packet
+ *	size must also be initialized.  This is modified on success.
+ *
+ * By choosing an endpoint to use with the specified descriptor, this
+ * routine simplifies writing gadget drivers that work with multiple
+ * USB device controllers.  The endpoint would be passed later to
+ * usb_ep_enable(), along with some descriptor.
+ *
+ * That second descriptor won't always be the same as the first one.
+ * For example, isochronous endpoints can be autoconfigured for high
+ * bandwidth, and then used in several lower bandwidth altsettings.
+ * Also, high and full speed descriptors will be different.
+ *
+ * Be sure to examine and test the results of autoconfiguration on your
+ * hardware.  This code may not make the best choices about how to use the
+ * USB controller, and it can't know all the restrictions that may apply.
+ * Some combinations of driver and hardware won't be able to autoconfigure.
+ *
+ * On success, this returns an un-claimed usb_ep, and modifies the endpoint
+ * descriptor bEndpointAddress.  For bulk endpoints, the wMaxPacket value
+ * is initialized as if the endpoint were used at full speed.  To prevent
+ * the endpoint from being returned by a later autoconfig call, claim it
+ * by assigning ep->driver_data to some non-null value.
+ *
+ * On failure, this returns a null endpoint descriptor.
+ */
+struct usb_ep *usb_ep_autoconfig(
+	struct usb_gadget		*gadget,
+	struct usb_endpoint_descriptor	*desc
+)
+{
+	return usb_ep_autoconfig_ss(gadget, desc, NULL);
+}
+
+
+/**
  * usb_ep_autoconfig_reset - reset endpoint autoconfig state
  * @gadget: device for which autoconfig state will be reset
  *
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index d76f9eb..ede67e6 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -34,6 +34,8 @@ struct usb_ep;
  *     by adding a zero length packet as needed;
  * @short_not_ok: When reading data, makes short packets be
  *     treated as errors (queue stops advancing till cleanup).
+ * @reserved: reserved bits
+ * @stream_id: the stream id
  * @complete: Function called when request completes, so this request and
  *	its buffer may be re-used.  The function will always be called with
  *	interrupts disabled, and it must not sleep.
@@ -84,6 +86,9 @@ struct usb_request {
 	unsigned		no_interrupt:1;
 	unsigned		zero:1;
 	unsigned		short_not_ok:1;
+	unsigned		reserved:13;
+
+	unsigned		stream_id:16;
 
 	void			(*complete)(struct usb_ep *ep,
 					struct usb_request *req);
@@ -131,6 +136,8 @@ struct usb_ep_ops {
  * @maxpacket:The maximum packet size used on this endpoint.  The initial
  *	value can sometimes be reduced (hardware allowing), according to
  *      the endpoint descriptor used to configure the endpoint.
+ * @num_supported_strms:The number of maximum streams supported
+ *	by this EP (0 - 16, actual number is 2^n)
  * @mult: multiplier, 'mult' value for SS Isoc EPs
  * @maxburst: the maximum number of bursts supported by this EP (for usb3)
  * @driver_data:for use by the gadget driver.
@@ -152,6 +159,7 @@ struct usb_ep {
 	const struct usb_ep_ops	*ops;
 	struct list_head	ep_list;
 	unsigned		maxpacket:16;
+	int			num_supported_strms;
 	unsigned				mult:2;
 	unsigned				pad:1;
 	unsigned				maxburst:4;
@@ -921,6 +929,11 @@ static inline void usb_free_descriptors(struct usb_descriptor_header **v)
 extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *,
 			struct usb_endpoint_descriptor *) __devinit;
 
+
+extern struct usb_ep *usb_ep_autoconfig_ss(struct usb_gadget *,
+			struct usb_endpoint_descriptor *,
+			struct usb_ss_ep_comp_descriptor *) __devinit;
+
 extern void usb_ep_autoconfig_reset(struct usb_gadget *) __devinit;
 
 #endif /* __LINUX_USB_GADGET_H */
-- 
1.7.3.3

--
Sent by a Consultant for Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [RFC/PATCH v6 1/5] usb: Add streams support to the gadget framework
  2011-04-14 13:35 [RFC/PATCH v6 1/5] usb: Add streams support to the gadget framework Tatyana Brokhman
@ 2011-04-14 17:39 ` Alan Stern
  2011-04-15  4:19 ` Christoph Hellwig
  1 sibling, 0 replies; 4+ messages in thread
From: Alan Stern @ 2011-04-14 17:39 UTC (permalink / raw)
  To: Tatyana Brokhman
  Cc: gregkh, linux-arm-msm, ablay, balbi, Maya Erez,
	open list:USB GADGET/PERIPH..., open list

On Thu, 14 Apr 2011, Tatyana Brokhman wrote:

> This patch defines necessary fields to support streaming for USB3.0.
> It implements a new function (usb_ep_autoconfig_ss) to be used instead of
> the existing usb_ep_autoconfig when working in SS mode and there is a
> need to search for an endpoint according to the number of required
> streams.

Suggestions for some small improvements...

> --- a/include/linux/usb/gadget.h
> +++ b/include/linux/usb/gadget.h
> @@ -34,6 +34,8 @@ struct usb_ep;
>   *     by adding a zero length packet as needed;
>   * @short_not_ok: When reading data, makes short packets be
>   *     treated as errors (queue stops advancing till cleanup).
> + * @reserved: reserved bits
> + * @stream_id: the stream id

If you move stream_id to the start of the bitfields then you won't need 
to reserve any bits.

Also, the comment should explain a little more.  For example:

 * @stream_id: The stream id, when USB-3.0 bulk streams are being used.

> @@ -131,6 +136,8 @@ struct usb_ep_ops {
>   * @maxpacket:The maximum packet size used on this endpoint.  The initial
>   *	value can sometimes be reduced (hardware allowing), according to
>   *      the endpoint descriptor used to configure the endpoint.
> + * @num_supported_strms:The number of maximum streams supported
> + *	by this EP (0 - 16, actual number is 2^n)

Ugh!  Call this max_streams instead.  The comment should say "maximum 
number of streams", not "number of maximum streams".

>   * @mult: multiplier, 'mult' value for SS Isoc EPs
>   * @maxburst: the maximum number of bursts supported by this EP (for usb3)
>   * @driver_data:for use by the gadget driver.
> @@ -152,6 +159,7 @@ struct usb_ep {
>  	const struct usb_ep_ops	*ops;
>  	struct list_head	ep_list;
>  	unsigned		maxpacket:16;
> +	int			num_supported_strms;

You might also want to make this a 16-bit unsigned field, instead of 
sticking an integer between two bitfields.

>  	unsigned				mult:2;
>  	unsigned				pad:1;
>  	unsigned				maxburst:4;

Alan Stern


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC/PATCH v6 1/5] usb: Add streams support to the gadget framework
  2011-04-14 13:35 [RFC/PATCH v6 1/5] usb: Add streams support to the gadget framework Tatyana Brokhman
  2011-04-14 17:39 ` Alan Stern
@ 2011-04-15  4:19 ` Christoph Hellwig
  2011-04-16 17:19   ` Tanya Brokhman
  1 sibling, 1 reply; 4+ messages in thread
From: Christoph Hellwig @ 2011-04-15  4:19 UTC (permalink / raw)
  To: Tatyana Brokhman
  Cc: gregkh, linux-arm-msm, ablay, balbi, Maya Erez,
	open list:USB GADGET/PERIPH..., open list

As I already told you before please do not create new SCSI target code
that doesn't use the target core in drivers/target.  Thanks!


^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: [RFC/PATCH v6 1/5] usb: Add streams support to the gadget framework
  2011-04-15  4:19 ` Christoph Hellwig
@ 2011-04-16 17:19   ` Tanya Brokhman
  0 siblings, 0 replies; 4+ messages in thread
From: Tanya Brokhman @ 2011-04-16 17:19 UTC (permalink / raw)
  To: 'Christoph Hellwig'
  Cc: gregkh, linux-arm-msm, ablay, balbi, 'Maya Erez',
	'open list:USB GADGET/PERIPH...', 'open list'

Hi Christoph

At the moment we're not familiar with the SCSI target code you referred us
to. Since some learning is required in order to do as you suggested, we
thought that first we would like to have a full functional version of the
UAS gadget driver. Looking into the SCSI target code is in our TODO list, we
didn't ignore your inputs. On the contrary, we would appreciate more inputs
from you in the future. Thanks!

Best regards,
Tanya Brokhman
Consultant for Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum


> -----Original Message-----
> From: Christoph Hellwig [mailto:hch@infradead.org]
> Sent: Friday, April 15, 2011 7:20 AM
> To: Tatyana Brokhman
> Cc: gregkh@suse.de; linux-arm-msm@vger.kernel.org;
> ablay@codeaurora.org; balbi@ti.com; Maya Erez; open list:USB
> GADGET/PERIPH...; open list
> Subject: Re: [RFC/PATCH v6 1/5] usb: Add streams support to the gadget
> framework
> 
> As I already told you before please do not create new SCSI target code
> that doesn't use the target core in drivers/target.  Thanks!



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-04-16 17:18 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-14 13:35 [RFC/PATCH v6 1/5] usb: Add streams support to the gadget framework Tatyana Brokhman
2011-04-14 17:39 ` Alan Stern
2011-04-15  4:19 ` Christoph Hellwig
2011-04-16 17:19   ` Tanya Brokhman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).