[PATCH] USB: usbcore: Don't assume a USB configuration includes any interfaces
In a couple of places, usbcore assumes that a USB device configuration will have a nonzero number of interfaces. Having no interfaces may or may not be allowed by the USB spec; in any event we shouldn't die if we encounter such a thing. This patch (as662) removes the assumptions. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
11a223ae3b
commit
6aa35675bb
@ -1179,8 +1179,11 @@ static int choose_configuration(struct usb_device *udev)
|
|||||||
c = udev->config;
|
c = udev->config;
|
||||||
num_configs = udev->descriptor.bNumConfigurations;
|
num_configs = udev->descriptor.bNumConfigurations;
|
||||||
for (i = 0; i < num_configs; (i++, c++)) {
|
for (i = 0; i < num_configs; (i++, c++)) {
|
||||||
struct usb_interface_descriptor *desc =
|
struct usb_interface_descriptor *desc = NULL;
|
||||||
&c->intf_cache[0]->altsetting->desc;
|
|
||||||
|
/* It's possible that a config has no interfaces! */
|
||||||
|
if (c->desc.bNumInterfaces > 0)
|
||||||
|
desc = &c->intf_cache[0]->altsetting->desc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HP's USB bus-powered keyboard has only one configuration
|
* HP's USB bus-powered keyboard has only one configuration
|
||||||
@ -1215,7 +1218,8 @@ static int choose_configuration(struct usb_device *udev)
|
|||||||
/* If the first config's first interface is COMM/2/0xff
|
/* If the first config's first interface is COMM/2/0xff
|
||||||
* (MSFT RNDIS), rule it out unless Linux has host-side
|
* (MSFT RNDIS), rule it out unless Linux has host-side
|
||||||
* RNDIS support. */
|
* RNDIS support. */
|
||||||
if (i == 0 && desc->bInterfaceClass == USB_CLASS_COMM
|
if (i == 0 && desc
|
||||||
|
&& desc->bInterfaceClass == USB_CLASS_COMM
|
||||||
&& desc->bInterfaceSubClass == 2
|
&& desc->bInterfaceSubClass == 2
|
||||||
&& desc->bInterfaceProtocol == 0xff) {
|
&& desc->bInterfaceProtocol == 0xff) {
|
||||||
#ifndef CONFIG_USB_NET_RNDIS
|
#ifndef CONFIG_USB_NET_RNDIS
|
||||||
@ -1231,8 +1235,8 @@ static int choose_configuration(struct usb_device *udev)
|
|||||||
* than a vendor-specific driver. */
|
* than a vendor-specific driver. */
|
||||||
else if (udev->descriptor.bDeviceClass !=
|
else if (udev->descriptor.bDeviceClass !=
|
||||||
USB_CLASS_VENDOR_SPEC &&
|
USB_CLASS_VENDOR_SPEC &&
|
||||||
desc->bInterfaceClass !=
|
(!desc || desc->bInterfaceClass !=
|
||||||
USB_CLASS_VENDOR_SPEC) {
|
USB_CLASS_VENDOR_SPEC)) {
|
||||||
best = c;
|
best = c;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3024,7 +3028,7 @@ int usb_reset_device(struct usb_device *udev)
|
|||||||
parent_hub = hdev_to_hub(parent_hdev);
|
parent_hub = hdev_to_hub(parent_hdev);
|
||||||
|
|
||||||
/* If we're resetting an active hub, take some special actions */
|
/* If we're resetting an active hub, take some special actions */
|
||||||
if (udev->actconfig &&
|
if (udev->actconfig && udev->actconfig->desc.bNumInterfaces > 0 &&
|
||||||
udev->actconfig->interface[0]->dev.driver ==
|
udev->actconfig->interface[0]->dev.driver ==
|
||||||
&hub_driver.driver &&
|
&hub_driver.driver &&
|
||||||
(hub = hdev_to_hub(udev)) != NULL) {
|
(hub = hdev_to_hub(udev)) != NULL) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user