aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorThomas Pugliese <thomas.pugliese@gmail.com>2013-12-09 14:40:29 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-06 14:08:17 -0500
commit6f7c6ef181ee93ba87892db997d8474a094b2695 (patch)
tree4db159bc13d862de54d602547b9cca449c0ba916 /drivers/usb/core
parent6fb6cd453c656633c2f0e32d954d3d7bba66f434 (diff)
usb: core: get config and string descriptors for unauthorized devices
commit 83e83ecb79a8225e79bc8e54e9aff3e0e27658a2 upstream. There is no need to skip querying the config and string descriptors for unauthorized WUSB devices when usb_new_device is called. It is allowed by WUSB spec. The only action that needs to be delayed until authorization time is the set config. This change allows user mode tools to see the config and string descriptors earlier in enumeration which is needed for some WUSB devices to function properly on Android systems. It also reduces the amount of divergent code paths needed for WUSB devices. Signed-off-by: Thomas Pugliese <thomas.pugliese@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/config.c7
-rw-r--r--drivers/usb/core/hub.c40
2 files changed, 7 insertions, 40 deletions
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index a6b2cabe7930..548d1996590f 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -651,10 +651,6 @@ void usb_destroy_configuration(struct usb_device *dev)
651 * 651 *
652 * hub-only!! ... and only in reset path, or usb_new_device() 652 * hub-only!! ... and only in reset path, or usb_new_device()
653 * (used by real hubs and virtual root hubs) 653 * (used by real hubs and virtual root hubs)
654 *
655 * NOTE: if this is a WUSB device and is not authorized, we skip the
656 * whole thing. A non-authorized USB device has no
657 * configurations.
658 */ 654 */
659int usb_get_configuration(struct usb_device *dev) 655int usb_get_configuration(struct usb_device *dev)
660{ 656{
@@ -666,8 +662,6 @@ int usb_get_configuration(struct usb_device *dev)
666 struct usb_config_descriptor *desc; 662 struct usb_config_descriptor *desc;
667 663
668 cfgno = 0; 664 cfgno = 0;
669 if (dev->authorized == 0) /* Not really an error */
670 goto out_not_authorized;
671 result = -ENOMEM; 665 result = -ENOMEM;
672 if (ncfg > USB_MAXCONFIG) { 666 if (ncfg > USB_MAXCONFIG) {
673 dev_warn(ddev, "too many configurations: %d, " 667 dev_warn(ddev, "too many configurations: %d, "
@@ -751,7 +745,6 @@ int usb_get_configuration(struct usb_device *dev)
751 745
752err: 746err:
753 kfree(desc); 747 kfree(desc);
754out_not_authorized:
755 dev->descriptor.bNumConfigurations = cfgno; 748 dev->descriptor.bNumConfigurations = cfgno;
756err2: 749err2:
757 if (result == -ENOMEM) 750 if (result == -ENOMEM)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 5ff6ab93c212..e604645a1290 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2231,18 +2231,13 @@ static int usb_enumerate_device(struct usb_device *udev)
2231 return err; 2231 return err;
2232 } 2232 }
2233 } 2233 }
2234 if (udev->wusb == 1 && udev->authorized == 0) { 2234
2235 udev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL); 2235 /* read the standard strings and cache them if present */
2236 udev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL); 2236 udev->product = usb_cache_string(udev, udev->descriptor.iProduct);
2237 udev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL); 2237 udev->manufacturer = usb_cache_string(udev,
2238 } 2238 udev->descriptor.iManufacturer);
2239 else { 2239 udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);
2240 /* read the standard strings and cache them if present */ 2240
2241 udev->product = usb_cache_string(udev, udev->descriptor.iProduct);
2242 udev->manufacturer = usb_cache_string(udev,
2243 udev->descriptor.iManufacturer);
2244 udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);
2245 }
2246 err = usb_enumerate_device_otg(udev); 2241 err = usb_enumerate_device_otg(udev);
2247 if (err < 0) 2242 if (err < 0)
2248 return err; 2243 return err;
@@ -2421,16 +2416,6 @@ int usb_deauthorize_device(struct usb_device *usb_dev)
2421 usb_dev->authorized = 0; 2416 usb_dev->authorized = 0;
2422 usb_set_configuration(usb_dev, -1); 2417 usb_set_configuration(usb_dev, -1);
2423 2418
2424 kfree(usb_dev->product);
2425 usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL);
2426 kfree(usb_dev->manufacturer);
2427 usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL);
2428 kfree(usb_dev->serial);
2429 usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL);
2430
2431 usb_destroy_configuration(usb_dev);
2432 usb_dev->descriptor.bNumConfigurations = 0;
2433
2434out_unauthorized: 2419out_unauthorized:
2435 usb_unlock_device(usb_dev); 2420 usb_unlock_device(usb_dev);
2436 return 0; 2421 return 0;
@@ -2458,17 +2443,7 @@ int usb_authorize_device(struct usb_device *usb_dev)
2458 goto error_device_descriptor; 2443 goto error_device_descriptor;
2459 } 2444 }
2460 2445
2461 kfree(usb_dev->product);
2462 usb_dev->product = NULL;
2463 kfree(usb_dev->manufacturer);
2464 usb_dev->manufacturer = NULL;
2465 kfree(usb_dev->serial);
2466 usb_dev->serial = NULL;
2467
2468 usb_dev->authorized = 1; 2446 usb_dev->authorized = 1;
2469 result = usb_enumerate_device(usb_dev);
2470 if (result < 0)
2471 goto error_enumerate;
2472 /* Choose and set the configuration. This registers the interfaces 2447 /* Choose and set the configuration. This registers the interfaces
2473 * with the driver core and lets interface drivers bind to them. 2448 * with the driver core and lets interface drivers bind to them.
2474 */ 2449 */
@@ -2484,7 +2459,6 @@ int usb_authorize_device(struct usb_device *usb_dev)
2484 } 2459 }
2485 dev_info(&usb_dev->dev, "authorized to connect\n"); 2460 dev_info(&usb_dev->dev, "authorized to connect\n");
2486 2461
2487error_enumerate:
2488error_device_descriptor: 2462error_device_descriptor:
2489 usb_autosuspend_device(usb_dev); 2463 usb_autosuspend_device(usb_dev);
2490error_autoresume: 2464error_autoresume: