Commit 01d883d4 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

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: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 645daaab
...@@ -558,10 +558,12 @@ static int usbdev_open(struct inode *inode, struct file *file) ...@@ -558,10 +558,12 @@ static int usbdev_open(struct inode *inode, struct file *file)
dev = usbdev_lookup_minor(iminor(inode)); dev = usbdev_lookup_minor(iminor(inode));
if (!dev) if (!dev)
dev = inode->i_private; dev = inode->i_private;
if (!dev) { if (!dev)
kfree(ps);
goto out; goto out;
} ret = usb_autoresume_device(dev, 1);
if (ret)
goto out;
usb_get_dev(dev); usb_get_dev(dev);
ret = 0; ret = 0;
ps->dev = dev; ps->dev = dev;
...@@ -581,6 +583,8 @@ static int usbdev_open(struct inode *inode, struct file *file) ...@@ -581,6 +583,8 @@ static int usbdev_open(struct inode *inode, struct file *file)
list_add_tail(&ps->list, &dev->filelist); list_add_tail(&ps->list, &dev->filelist);
file->private_data = ps; file->private_data = ps;
out: out:
if (ret)
kfree(ps);
mutex_unlock(&usbfs_mutex); mutex_unlock(&usbfs_mutex);
return ret; return ret;
} }
...@@ -604,6 +608,7 @@ static int usbdev_release(struct inode *inode, struct file *file) ...@@ -604,6 +608,7 @@ static int usbdev_release(struct inode *inode, struct file *file)
releaseintf(ps, ifnum); releaseintf(ps, ifnum);
} }
destroy_all_async(ps); destroy_all_async(ps);
usb_autosuspend_device(dev, 1);
usb_unlock_device(dev); usb_unlock_device(dev);
usb_put_dev(dev); usb_put_dev(dev);
kfree(ps); kfree(ps);
......
...@@ -172,14 +172,10 @@ static void generic_disconnect(struct usb_device *udev) ...@@ -172,14 +172,10 @@ static void generic_disconnect(struct usb_device *udev)
/* if this is only an unbind, not a physical disconnect, then /* if this is only an unbind, not a physical disconnect, then
* unconfigure the device */ * unconfigure the device */
if (udev->state == USB_STATE_CONFIGURED) if (udev->actconfig)
usb_set_configuration(udev, 0); usb_set_configuration(udev, 0);
usb_remove_sysfs_dev_files(udev); usb_remove_sysfs_dev_files(udev);
/* in case the call failed or the device was suspended */
if (udev->state >= USB_STATE_CONFIGURED)
usb_disable_device(udev, 0);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -208,4 +204,5 @@ struct usb_device_driver usb_generic_driver = { ...@@ -208,4 +204,5 @@ struct usb_device_driver usb_generic_driver = {
.suspend = generic_suspend, .suspend = generic_suspend,
.resume = generic_resume, .resume = generic_resume,
#endif #endif
.supports_autosuspend = 1,
}; };
...@@ -1366,9 +1366,6 @@ int usb_set_configuration(struct usb_device *dev, int configuration) ...@@ -1366,9 +1366,6 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
if (cp && configuration == 0) if (cp && configuration == 0)
dev_warn(&dev->dev, "config 0 descriptor??\n"); dev_warn(&dev->dev, "config 0 descriptor??\n");
if (dev->state == USB_STATE_SUSPENDED)
return -EHOSTUNREACH;
/* Allocate memory for new interfaces before doing anything else, /* Allocate memory for new interfaces before doing anything else,
* so that if we run out then nothing will have changed. */ * so that if we run out then nothing will have changed. */
n = nintf = 0; n = nintf = 0;
...@@ -1403,6 +1400,11 @@ int usb_set_configuration(struct usb_device *dev, int configuration) ...@@ -1403,6 +1400,11 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
configuration, -i); configuration, -i);
} }
/* Wake up the device so we can send it the Set-Config request */
ret = usb_autoresume_device(dev, 1);
if (ret)
goto free_interfaces;
/* if it's already configured, clear out old state first. /* if it's already configured, clear out old state first.
* getting rid of old interfaces means unbinding their drivers. * getting rid of old interfaces means unbinding their drivers.
*/ */
...@@ -1422,6 +1424,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) ...@@ -1422,6 +1424,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
dev->actconfig = cp; dev->actconfig = cp;
if (!cp) { if (!cp) {
usb_set_device_state(dev, USB_STATE_ADDRESS); usb_set_device_state(dev, USB_STATE_ADDRESS);
usb_autosuspend_device(dev, 1);
goto free_interfaces; goto free_interfaces;
} }
usb_set_device_state(dev, USB_STATE_CONFIGURED); usb_set_device_state(dev, USB_STATE_CONFIGURED);
...@@ -1490,6 +1493,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) ...@@ -1490,6 +1493,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
usb_create_sysfs_intf_files (intf); usb_create_sysfs_intf_files (intf);
} }
usb_autosuspend_device(dev, 1);
return 0; return 0;
} }
......
...@@ -90,6 +90,11 @@ static int skel_open(struct inode *inode, struct file *file) ...@@ -90,6 +90,11 @@ static int skel_open(struct inode *inode, struct file *file)
goto exit; goto exit;
} }
/* prevent the device from being autosuspended */
retval = usb_autopm_get_interface(interface);
if (retval)
goto exit;
/* increment our usage count for the device */ /* increment our usage count for the device */
kref_get(&dev->kref); kref_get(&dev->kref);
...@@ -108,6 +113,12 @@ static int skel_release(struct inode *inode, struct file *file) ...@@ -108,6 +113,12 @@ static int skel_release(struct inode *inode, struct file *file)
if (dev == NULL) if (dev == NULL)
return -ENODEV; return -ENODEV;
/* allow the device to be autosuspended */
mutex_lock(&dev->io_mutex);
if (dev->interface)
usb_autopm_put_interface(dev->interface);
mutex_unlock(&dev->io_mutex);
/* decrement the count on our device */ /* decrement the count on our device */
kref_put(&dev->kref, skel_delete); kref_put(&dev->kref, skel_delete);
return 0; return 0;
......
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