Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usbcore: non-hub-specific uses of autosuspend

This patch (as741) makes the non-hub parts of usbcore actually use the
autosuspend facilities added by an earlier patch.

Devices opened through usbfs are autoresumed and then
autosuspended upon close.

Likewise for usb-skeleton.

Devices are autoresumed for usb_set_configuration.


Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Alan Stern and committed by
Greg Kroah-Hartman
01d883d4 645daaab

+28 -11
+8 -3
drivers/usb/core/devio.c
··· 558 558 dev = usbdev_lookup_minor(iminor(inode)); 559 559 if (!dev) 560 560 dev = inode->i_private; 561 - if (!dev) { 562 - kfree(ps); 561 + if (!dev) 563 562 goto out; 564 - } 563 + ret = usb_autoresume_device(dev, 1); 564 + if (ret) 565 + goto out; 566 + 565 567 usb_get_dev(dev); 566 568 ret = 0; 567 569 ps->dev = dev; ··· 583 581 list_add_tail(&ps->list, &dev->filelist); 584 582 file->private_data = ps; 585 583 out: 584 + if (ret) 585 + kfree(ps); 586 586 mutex_unlock(&usbfs_mutex); 587 587 return ret; 588 588 } ··· 608 604 releaseintf(ps, ifnum); 609 605 } 610 606 destroy_all_async(ps); 607 + usb_autosuspend_device(dev, 1); 611 608 usb_unlock_device(dev); 612 609 usb_put_dev(dev); 613 610 kfree(ps);
+2 -5
drivers/usb/core/generic.c
··· 172 172 173 173 /* if this is only an unbind, not a physical disconnect, then 174 174 * unconfigure the device */ 175 - if (udev->state == USB_STATE_CONFIGURED) 175 + if (udev->actconfig) 176 176 usb_set_configuration(udev, 0); 177 177 178 178 usb_remove_sysfs_dev_files(udev); 179 - 180 - /* in case the call failed or the device was suspended */ 181 - if (udev->state >= USB_STATE_CONFIGURED) 182 - usb_disable_device(udev, 0); 183 179 } 184 180 185 181 #ifdef CONFIG_PM ··· 204 208 .suspend = generic_suspend, 205 209 .resume = generic_resume, 206 210 #endif 211 + .supports_autosuspend = 1, 207 212 };
+7 -3
drivers/usb/core/message.c
··· 1366 1366 if (cp && configuration == 0) 1367 1367 dev_warn(&dev->dev, "config 0 descriptor??\n"); 1368 1368 1369 - if (dev->state == USB_STATE_SUSPENDED) 1370 - return -EHOSTUNREACH; 1371 - 1372 1369 /* Allocate memory for new interfaces before doing anything else, 1373 1370 * so that if we run out then nothing will have changed. */ 1374 1371 n = nintf = 0; ··· 1400 1403 configuration, -i); 1401 1404 } 1402 1405 1406 + /* Wake up the device so we can send it the Set-Config request */ 1407 + ret = usb_autoresume_device(dev, 1); 1408 + if (ret) 1409 + goto free_interfaces; 1410 + 1403 1411 /* if it's already configured, clear out old state first. 1404 1412 * getting rid of old interfaces means unbinding their drivers. 1405 1413 */ ··· 1424 1422 dev->actconfig = cp; 1425 1423 if (!cp) { 1426 1424 usb_set_device_state(dev, USB_STATE_ADDRESS); 1425 + usb_autosuspend_device(dev, 1); 1427 1426 goto free_interfaces; 1428 1427 } 1429 1428 usb_set_device_state(dev, USB_STATE_CONFIGURED); ··· 1493 1490 usb_create_sysfs_intf_files (intf); 1494 1491 } 1495 1492 1493 + usb_autosuspend_device(dev, 1); 1496 1494 return 0; 1497 1495 } 1498 1496
+11
drivers/usb/usb-skeleton.c
··· 90 90 goto exit; 91 91 } 92 92 93 + /* prevent the device from being autosuspended */ 94 + retval = usb_autopm_get_interface(interface); 95 + if (retval) 96 + goto exit; 97 + 93 98 /* increment our usage count for the device */ 94 99 kref_get(&dev->kref); 95 100 ··· 112 107 dev = (struct usb_skel *)file->private_data; 113 108 if (dev == NULL) 114 109 return -ENODEV; 110 + 111 + /* allow the device to be autosuspended */ 112 + mutex_lock(&dev->io_mutex); 113 + if (dev->interface) 114 + usb_autopm_put_interface(dev->interface); 115 + mutex_unlock(&dev->io_mutex); 115 116 116 117 /* decrement the count on our device */ 117 118 kref_put(&dev->kref, skel_delete);