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-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html