diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2006-03-08 15:14:09 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-20 17:50:01 -0500 |
commit | 6aa35675bbc370e5f11baae7e01a9ab255d8030c (patch) | |
tree | f42b4adac70483f90bcb3c4de9c4d5db964cf43a /drivers/usb | |
parent | 11a223ae3b86b94391774512e5671600367a305c (diff) |
[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>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/hub.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 7dd28f8e1cea..8e65f7a237e4 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -1179,8 +1179,11 @@ static int choose_configuration(struct usb_device *udev) | |||
1179 | c = udev->config; | 1179 | c = udev->config; |
1180 | num_configs = udev->descriptor.bNumConfigurations; | 1180 | num_configs = udev->descriptor.bNumConfigurations; |
1181 | for (i = 0; i < num_configs; (i++, c++)) { | 1181 | for (i = 0; i < num_configs; (i++, c++)) { |
1182 | struct usb_interface_descriptor *desc = | 1182 | struct usb_interface_descriptor *desc = NULL; |
1183 | &c->intf_cache[0]->altsetting->desc; | 1183 | |
1184 | /* It's possible that a config has no interfaces! */ | ||
1185 | if (c->desc.bNumInterfaces > 0) | ||
1186 | desc = &c->intf_cache[0]->altsetting->desc; | ||
1184 | 1187 | ||
1185 | /* | 1188 | /* |
1186 | * HP's USB bus-powered keyboard has only one configuration | 1189 | * HP's USB bus-powered keyboard has only one configuration |
@@ -1215,7 +1218,8 @@ static int choose_configuration(struct usb_device *udev) | |||
1215 | /* If the first config's first interface is COMM/2/0xff | 1218 | /* If the first config's first interface is COMM/2/0xff |
1216 | * (MSFT RNDIS), rule it out unless Linux has host-side | 1219 | * (MSFT RNDIS), rule it out unless Linux has host-side |
1217 | * RNDIS support. */ | 1220 | * RNDIS support. */ |
1218 | if (i == 0 && desc->bInterfaceClass == USB_CLASS_COMM | 1221 | if (i == 0 && desc |
1222 | && desc->bInterfaceClass == USB_CLASS_COMM | ||
1219 | && desc->bInterfaceSubClass == 2 | 1223 | && desc->bInterfaceSubClass == 2 |
1220 | && desc->bInterfaceProtocol == 0xff) { | 1224 | && desc->bInterfaceProtocol == 0xff) { |
1221 | #ifndef CONFIG_USB_NET_RNDIS | 1225 | #ifndef CONFIG_USB_NET_RNDIS |
@@ -1231,8 +1235,8 @@ static int choose_configuration(struct usb_device *udev) | |||
1231 | * than a vendor-specific driver. */ | 1235 | * than a vendor-specific driver. */ |
1232 | else if (udev->descriptor.bDeviceClass != | 1236 | else if (udev->descriptor.bDeviceClass != |
1233 | USB_CLASS_VENDOR_SPEC && | 1237 | USB_CLASS_VENDOR_SPEC && |
1234 | desc->bInterfaceClass != | 1238 | (!desc || desc->bInterfaceClass != |
1235 | USB_CLASS_VENDOR_SPEC) { | 1239 | USB_CLASS_VENDOR_SPEC)) { |
1236 | best = c; | 1240 | best = c; |
1237 | break; | 1241 | break; |
1238 | } | 1242 | } |
@@ -3024,7 +3028,7 @@ int usb_reset_device(struct usb_device *udev) | |||
3024 | parent_hub = hdev_to_hub(parent_hdev); | 3028 | parent_hub = hdev_to_hub(parent_hdev); |
3025 | 3029 | ||
3026 | /* If we're resetting an active hub, take some special actions */ | 3030 | /* If we're resetting an active hub, take some special actions */ |
3027 | if (udev->actconfig && | 3031 | if (udev->actconfig && udev->actconfig->desc.bNumInterfaces > 0 && |
3028 | udev->actconfig->interface[0]->dev.driver == | 3032 | udev->actconfig->interface[0]->dev.driver == |
3029 | &hub_driver.driver && | 3033 | &hub_driver.driver && |
3030 | (hub = hdev_to_hub(udev)) != NULL) { | 3034 | (hub = hdev_to_hub(udev)) != NULL) { |