Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 104558
b: refs/heads/master
c: a4c39c4
h: refs/heads/master
v: v3
  • Loading branch information
David Brownell authored and Greg Kroah-Hartman committed Jul 21, 2008
1 parent dd7d268 commit ffb9975
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a7707adf9ee8de3c5b67e3793b98888f551ad00d
refs/heads/master: a4c39c41bf3592684e36fa0dbbd4ab1a31f969b9
76 changes: 75 additions & 1 deletion trunk/drivers/usb/gadget/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ int usb_gadget_config_buf(
/* config descriptor first */
if (length < USB_DT_CONFIG_SIZE || !desc)
return -EINVAL;
*cp = *config;
*cp = *config;

/* then interface/endpoint/class/vendor/... */
len = usb_descriptor_fillbuf(USB_DT_CONFIG_SIZE + (u8*)buf,
Expand All @@ -115,3 +115,77 @@ int usb_gadget_config_buf(
return len;
}

/**
* usb_copy_descriptors - copy a vector of USB descriptors
* @src: null-terminated vector to copy
* Context: initialization code, which may sleep
*
* This makes a copy of a vector of USB descriptors. Its primary use
* is to support usb_function objects which can have multiple copies,
* each needing different descriptors. Functions may have static
* tables of descriptors, which are used as templates and customized
* with identifiers (for interfaces, strings, endpoints, and more)
* as needed by a given function instance.
*/
struct usb_descriptor_header **__init
usb_copy_descriptors(struct usb_descriptor_header **src)
{
struct usb_descriptor_header **tmp;
unsigned bytes;
unsigned n_desc;
void *mem;
struct usb_descriptor_header **ret;

/* count descriptors and their sizes; then add vector size */
for (bytes = 0, n_desc = 0, tmp = src; *tmp; tmp++, n_desc++)
bytes += (*tmp)->bLength;
bytes += (n_desc + 1) * sizeof(*tmp);

mem = kmalloc(bytes, GFP_KERNEL);
if (!mem)
return NULL;

/* fill in pointers starting at "tmp",
* to descriptors copied starting at "mem";
* and return "ret"
*/
tmp = mem;
ret = mem;
mem += (n_desc + 1) * sizeof(*tmp);
while (*src) {
memcpy(mem, *src, (*src)->bLength);
*tmp = mem;
tmp++;
mem += (*src)->bLength;
src++;
}
*tmp = NULL;

return ret;
}

/**
* usb_find_endpoint - find a copy of an endpoint descriptor
* @src: original vector of descriptors
* @copy: copy of @src
* @ep: endpoint descriptor found in @src
*
* This returns the copy of the @match descriptor made for @copy. Its
* intended use is to help remembering the endpoint descriptor to use
* when enabling a given endpoint.
*/
struct usb_endpoint_descriptor *__init
usb_find_endpoint(
struct usb_descriptor_header **src,
struct usb_descriptor_header **copy,
struct usb_endpoint_descriptor *match
)
{
while (*src) {
if (*src == (void *) match)
return (void *)*copy;
src++;
copy++;
}
return NULL;
}
1 change: 1 addition & 0 deletions trunk/drivers/usb/gadget/epautoconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ ep_matches (
/* MATCH!! */

/* report address */
desc->bEndpointAddress &= USB_DIR_IN;
if (isdigit (ep->name [2])) {
u8 num = simple_strtol (&ep->name [2], NULL, 10);
desc->bEndpointAddress |= num;
Expand Down
19 changes: 19 additions & 0 deletions trunk/include/linux/usb/gadget.h
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,25 @@ int usb_descriptor_fillbuf(void *, unsigned,
int usb_gadget_config_buf(const struct usb_config_descriptor *config,
void *buf, unsigned buflen, const struct usb_descriptor_header **desc);

/* copy a NULL-terminated vector of descriptors */
struct usb_descriptor_header **usb_copy_descriptors(
struct usb_descriptor_header **);

/* return copy of endpoint descriptor given original descriptor set */
struct usb_endpoint_descriptor *usb_find_endpoint(
struct usb_descriptor_header **src,
struct usb_descriptor_header **copy,
struct usb_endpoint_descriptor *match);

/**
* usb_free_descriptors - free descriptors returned by usb_copy_descriptors()
* @v: vector of descriptors
*/
static inline void usb_free_descriptors(struct usb_descriptor_header **v)
{
kfree(v);
}

/*-------------------------------------------------------------------------*/

/* utility wrapping a simple endpoint selection policy */
Expand Down

0 comments on commit ffb9975

Please sign in to comment.