Commit 104cc087 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

[PATCH] USB: Changes to core/config.c (7 of 9)

This patch changes the usb_parse_interface() routine so that it only
handles a single interface/altsetting descriptor at a time, rather than
trying to handle all the altsettings for an interface at once.  Besides
shrinking the code slightly, this has the advantage of not requiring the
interfaces to be listed in order or all the altsetting descriptors for an
interface to be contiguous.  While there probably aren't any devices that
have _discontiguous_ altsetting descriptors, there's no harm in allowing
it -- particularly since doing so provides an overall simplification.

This is another of those hard-to-read patches.  It moves most of the body
of the usb_parse_interface() function out of a loop, thereby changing the
indentation level without actually altering the code.
parent 326d4645
......@@ -99,20 +99,27 @@ static void usb_release_intf(struct device *dev)
kfree(intf);
}
static int usb_parse_interface(struct usb_interface *interface, unsigned char *buffer, int size)
static int usb_parse_interface(struct usb_host_config *config, unsigned char *buffer, int size)
{
unsigned char *buffer0 = buffer;
int i, len, numskipped, retval;
struct usb_descriptor_header *header;
struct usb_interface_descriptor *d;
int inum, asnum;
struct usb_interface *interface;
struct usb_host_interface *ifp;
int len, numskipped;
struct usb_descriptor_header *header;
unsigned char *begin;
ifp = interface->altsetting;
while (size >= sizeof(struct usb_descriptor_header)) {
struct usb_interface_descriptor *d;
int i, retval;
d = (struct usb_interface_descriptor *) buffer;
if (d->bAlternateSetting >= interface->num_altsetting) {
if (d->bDescriptorType != USB_DT_INTERFACE) {
warn("unexpected descriptor 0x%X, expecting interface, 0x%X",
d->bDescriptorType, USB_DT_INTERFACE);
return -EINVAL;
}
inum = d->bInterfaceNumber;
if (inum >= config->desc.bNumInterfaces) {
/* Skip to the next interface descriptor */
buffer += d->bLength;
......@@ -125,13 +132,22 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b
buffer += header->bLength;
size -= header->bLength;
}
continue;
return buffer - buffer0;
}
interface = config->interface[inum];
asnum = d->bAlternateSetting;
if (asnum >= interface->num_altsetting) {
warn("invalid alternate setting %d for interface %d",
asnum, inum);
return -EINVAL;
}
ifp = &interface->altsetting[asnum];
memcpy(&ifp->desc, buffer, USB_DT_INTERFACE_SIZE);
buffer += ifp->desc.bLength;
size -= ifp->desc.bLength;
buffer += d->bLength;
size -= d->bLength;
/* Skip over any Class Specific or Vendor Specific descriptors */
begin = buffer;
......@@ -193,16 +209,6 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b
size -= retval;
}
/* We check to see if it's an alternate to this one */
d = (struct usb_interface_descriptor *)buffer;
if (size < USB_DT_INTERFACE_SIZE
|| d->bDescriptorType != USB_DT_INTERFACE
|| !d->bAlternateSetting)
break;
++ifp;
}
return buffer - buffer0;
}
......@@ -344,8 +350,8 @@ int usb_parse_configuration(struct usb_host_config *config, char *buffer)
}
/* Parse all the interface/altsetting descriptors */
for (i = 0; i < nintf_orig; i++) {
retval = usb_parse_interface(config->interface[i], buffer, size);
while (size >= sizeof(struct usb_descriptor_header)) {
retval = usb_parse_interface(config, buffer, size);
if (retval < 0)
return retval;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment