Re: [RFC/PATCH v3 2/4] usb: Configure endpoint according to gadget speed.

From: Mike Frysinger
Date: Tue Nov 09 2010 - 05:04:58 EST


maybe Bob has an opinion ...
-mike

On Mon, Nov 1, 2010 at 11:11, Tatyana Brokhman wrote:
> Add config_ep_by_speed() to configure the endpoint according to the gadget
> speed. Using this function will spare the FDs from handling the endpoint
> chosen descriptor.
>
> Signed-off-by: Tatyana Brokhman <tlinder@xxxxxxxxxxxxxx>
> ---
> Âdrivers/usb/gadget/composite.c Â| Â 76 +++++++++++++++++++++++++++++++++++++++
> Âdrivers/usb/gadget/epautoconf.c | Â Â1 +
> Âinclude/linux/usb/composite.h  |  21 +++++++++++
> Âinclude/linux/usb/gadget.h   Â|  Â8 +++--
> Â4 files changed, 103 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
> index 1160c55..ed6ec5b 100644
> --- a/drivers/usb/gadget/composite.c
> +++ b/drivers/usb/gadget/composite.c
> @@ -70,6 +70,82 @@ module_param(iSerialNumber, charp, 0);
> ÂMODULE_PARM_DESC(iSerialNumber, "SerialNumber string");
>
> Â/*-------------------------------------------------------------------------*/
> +/**
> + * next_ep_desc() - advance to the next EP descriptor
> + * @t: currect pointer within descriptor array
> + *
> + * Return: next EP descriptor or NULL
> + *
> + * Iterate over @t until either EP descriptor found or
> + * NULL (that indicates end of list) encountered
> + */
> +static struct usb_descriptor_header**
> +next_ep_desc(struct usb_descriptor_header **t)
> +{
> + Â Â Â for (; *t; t++) {
> + Â Â Â Â Â Â Â if ((*t)->bDescriptorType == USB_DT_ENDPOINT)
> + Â Â Â Â Â Â Â Â Â Â Â return t;
> + Â Â Â }
> + Â Â Â return NULL;
> +}
> +
> +/**
> + * config_ep_by_speed() - configures the given endpoint
> + * according to gadget speed.
> + * @g: pointer to the gadget
> + * @f: usb function
> + * @_ep: the endpoint to configure
> + *
> + * Return: error code, 0 on success
> + *
> + * This function chooses the right descriptors for a given
> + * endpoint according to gadget speed and saves in in the
> + * endpoint desc field. If the endpoint already has a descriptor
> + * assigned to it - overwrites it with currently corresponding
> + * descriptor. The endpoint maxpacket field is updated according
> + * to the choosen descriptor.
> + * Note: the supplied function should hold all the descriptors
> + * for supported speeds
> + */
> +int config_ep_by_speed(struct usb_gadget *g,
> + Â Â Â Â Â Â Â Â Â Â Â struct usb_function *f,
> + Â Â Â Â Â Â Â Â Â Â Â struct usb_ep *_ep)
> +{
> + Â Â Â struct usb_endpoint_descriptor *chosen_desc = NULL;
> + Â Â Â struct usb_descriptor_header **speed_desc = NULL;
> +
> + Â Â Â struct usb_descriptor_header **d_spd; /* cursor for speed desc */
> +
> + Â Â Â if (!g || !f || !_ep)
> + Â Â Â Â Â Â Â return -EIO;
> +
> + Â Â Â /* select desired speed */
> + Â Â Â switch (g->speed) {
> + Â Â Â case USB_SPEED_HIGH:
> + Â Â Â Â Â Â Â if (gadget_is_dualspeed(g)) {
> + Â Â Â Â Â Â Â Â Â Â Â speed_desc = f->hs_descriptors;
> + Â Â Â Â Â Â Â Â Â Â Â break;
> + Â Â Â Â Â Â Â }
> + Â Â Â Â Â Â Â /* else: fall through */
> + Â Â Â default:
> + Â Â Â Â Â Â Â speed_desc = f->descriptors;
> + Â Â Â }
> + Â Â Â /* find descriptors */
> + Â Â Â for (d_spd = next_ep_desc(speed_desc); d_spd;
> + Â Â Â Â Â Â d_spd = next_ep_desc(d_spd+1)) {
> + Â Â Â Â Â Â Â chosen_desc = (struct usb_endpoint_descriptor *)*d_spd;
> + Â Â Â Â Â Â Â if (chosen_desc->bEndpointAddress == _ep->bEndpointAddress)
> + Â Â Â Â Â Â Â Â Â Â Â goto ep_found;
> + Â Â Â }
> + Â Â Â return -EIO;
> +
> +ep_found:
> + Â Â Â /* commit results */
> + Â Â Â _ep->maxpacket = le16_to_cpu(chosen_desc->wMaxPacketSize);
> + Â Â Â _ep->desc = chosen_desc;
> +
> + Â Â Â return 0;
> +}
>
> Â/**
> Â* usb_add_function() - add a function to a configuration
> diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
> index 8a83248..84ce0fa 100644
> --- a/drivers/usb/gadget/epautoconf.c
> +++ b/drivers/usb/gadget/epautoconf.c
> @@ -184,6 +184,7 @@ ep_matches (
> Â Â Â Â Â Â Â Â Â Â Â Âsize = 64;
> Â Â Â Â Â Â Â Âdesc->wMaxPacketSize = cpu_to_le16(size);
> Â Â Â Â}
> + Â Â Â ep->bEndpointAddress = desc->bEndpointAddress;
> Â Â Â Âreturn 1;
> Â}
>
> diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
> index 6170681..1f18326 100644
> --- a/include/linux/usb/composite.h
> +++ b/include/linux/usb/composite.h
> @@ -138,6 +138,27 @@ int usb_function_activate(struct usb_function *);
> Âint usb_interface_id(struct usb_configuration *, struct usb_function *);
>
> Â/**
> + * config_ep_by_speed() - configures the given endpoint
> + * according to gadget speed.
> + * @g: pointer to the gadget
> + * @f: usb function
> + * @_ep: the endpoint to configure
> + *
> + * Return: error code, 0 on success
> + *
> + * This function chooses the right descriptors for a given
> + * endpoint according to gadget speed and saves in in the
> + * endpoint desc field. If the endpoint already has a descriptor
> + * assigned to it - overwrites it with currently corresponding
> + * descriptor. The endpoint maxpacket field is updated according
> + * to the choosen descriptor.
> + * Note: the supplied function should hold all the descriptors
> + * for supported speeds
> + */
> +int config_ep_by_speed(struct usb_gadget *g, struct usb_function *f,
> + Â Â Â Â Â Â Â Â Â Â Â struct usb_ep *_ep);
> +
> +/**
> Â* ep_choose - select descriptor endpoint at current device speed
> Â* @g: gadget, connected and running at some speed
> Â* @hs: descriptor to use for high speed operation
> diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
> index 131843d..e387922 100644
> --- a/include/linux/usb/gadget.h
> +++ b/include/linux/usb/gadget.h
> @@ -132,9 +132,10 @@ struct usb_ep_ops {
> Â* Â Â value can sometimes be reduced (hardware allowing), according to
> Â* Â Â Âthe endpoint descriptor used to configure the endpoint.
> Â* @driver_data:for use by the gadget driver.
> - * @desc:endpoint descriptor. ÂThis pointer set before endpoint
> - * Â Â is enabled and remains valid until the endpoint is
> - * Â Â disabled.
> + * @bEndpointAddress: used to identify the endpoint when finding
> + * Â Â descriptor that matches connection speed
> + * @desc:endpoint descriptor. Âthis pointer set before endpoint is enabled and
> + * Â Â remains valid until the endpoint is disabled.
> Â*
> Â* the bus controller driver lists all the general purpose endpoints in
> Â* gadget->ep_list. Âthe control endpoint (gadget->ep0) is not in that list,
> @@ -147,6 +148,7 @@ struct usb_ep {
>    Âconst struct usb_ep_ops     *ops;
>    Âstruct list_head        Âep_list;
>    Âunsigned            Âmaxpacket:16;
> + Â Â Â u8 Â Â Â Â Â Â Â Â Â Â Â Â Â Â ÂbEndpointAddress;
> Â Â Â Âstruct usb_endpoint_descriptor Â*desc;
> Â};
>
> --
> 1.6.3.3
>
> --
> Sent by an employee of the Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at Âhttp://vger.kernel.org/majordomo-info.html
> Please read the FAQ at Âhttp://www.tux.org/lkml/
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/