usb: gadget: configure endpoint according to gadget speed
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@codeaurora.org> Signed-off-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
72c973dd2b
commit
48767a4e82
4 changed files with 92 additions and 0 deletions
|
@ -74,6 +74,91 @@ MODULE_PARM_DESC(iSerialNumber, "SerialNumber string");
|
||||||
static char composite_manufacturer[50];
|
static char composite_manufacturer[50];
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* for_each_ep_desc()- iterate over endpoint descriptors in the
|
||||||
|
* descriptors list
|
||||||
|
* @start: pointer within descriptor array.
|
||||||
|
* @ep_desc: endpoint descriptor to use as the loop cursor
|
||||||
|
*/
|
||||||
|
#define for_each_ep_desc(start, ep_desc) \
|
||||||
|
for (ep_desc = next_ep_desc(start); \
|
||||||
|
ep_desc; ep_desc = next_ep_desc(ep_desc+1))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 it 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 chosen 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_each_ep_desc(speed_desc, d_spd) {
|
||||||
|
chosen_desc = (struct usb_endpoint_descriptor *)*d_spd;
|
||||||
|
if (chosen_desc->bEndpointAddress == _ep->address)
|
||||||
|
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
|
* usb_add_function() - add a function to a configuration
|
||||||
|
|
|
@ -191,6 +191,7 @@ ep_matches (
|
||||||
size = 64;
|
size = 64;
|
||||||
desc->wMaxPacketSize = cpu_to_le16(size);
|
desc->wMaxPacketSize = cpu_to_le16(size);
|
||||||
}
|
}
|
||||||
|
ep->address = desc->bEndpointAddress;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,9 @@ int usb_function_activate(struct usb_function *);
|
||||||
|
|
||||||
int usb_interface_id(struct usb_configuration *, struct usb_function *);
|
int usb_interface_id(struct usb_configuration *, struct usb_function *);
|
||||||
|
|
||||||
|
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
|
* ep_choose - select descriptor endpoint at current device speed
|
||||||
* @g: gadget, connected and running at some speed
|
* @g: gadget, connected and running at some speed
|
||||||
|
|
|
@ -133,6 +133,8 @@ struct usb_ep_ops {
|
||||||
* value can sometimes be reduced (hardware allowing), according to
|
* value can sometimes be reduced (hardware allowing), according to
|
||||||
* the endpoint descriptor used to configure the endpoint.
|
* the endpoint descriptor used to configure the endpoint.
|
||||||
* @driver_data:for use by the gadget driver.
|
* @driver_data:for use by the gadget driver.
|
||||||
|
* @address: used to identify the endpoint when finding descriptor that
|
||||||
|
* matches connection speed
|
||||||
* @desc: endpoint descriptor. This pointer is set before the endpoint is
|
* @desc: endpoint descriptor. This pointer is set before the endpoint is
|
||||||
* enabled and remains valid until the endpoint is disabled.
|
* enabled and remains valid until the endpoint is disabled.
|
||||||
*
|
*
|
||||||
|
@ -147,6 +149,7 @@ struct usb_ep {
|
||||||
const struct usb_ep_ops *ops;
|
const struct usb_ep_ops *ops;
|
||||||
struct list_head ep_list;
|
struct list_head ep_list;
|
||||||
unsigned maxpacket:16;
|
unsigned maxpacket:16;
|
||||||
|
u8 address;
|
||||||
const struct usb_endpoint_descriptor *desc;
|
const struct usb_endpoint_descriptor *desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue