forked from Minki/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>
This commit is contained in:
parent
645daaab0b
commit
01d883d44a
@ -558,10 +558,12 @@ static int usbdev_open(struct inode *inode, struct file *file)
|
||||
dev = usbdev_lookup_minor(iminor(inode));
|
||||
if (!dev)
|
||||
dev = inode->i_private;
|
||||
if (!dev) {
|
||||
kfree(ps);
|
||||
if (!dev)
|
||||
goto out;
|
||||
}
|
||||
ret = usb_autoresume_device(dev, 1);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
usb_get_dev(dev);
|
||||
ret = 0;
|
||||
ps->dev = dev;
|
||||
@ -581,6 +583,8 @@ static int usbdev_open(struct inode *inode, struct file *file)
|
||||
list_add_tail(&ps->list, &dev->filelist);
|
||||
file->private_data = ps;
|
||||
out:
|
||||
if (ret)
|
||||
kfree(ps);
|
||||
mutex_unlock(&usbfs_mutex);
|
||||
return ret;
|
||||
}
|
||||
@ -604,6 +608,7 @@ static int usbdev_release(struct inode *inode, struct file *file)
|
||||
releaseintf(ps, ifnum);
|
||||
}
|
||||
destroy_all_async(ps);
|
||||
usb_autosuspend_device(dev, 1);
|
||||
usb_unlock_device(dev);
|
||||
usb_put_dev(dev);
|
||||
kfree(ps);
|
||||
|
@ -172,14 +172,10 @@ static void generic_disconnect(struct usb_device *udev)
|
||||
|
||||
/* if this is only an unbind, not a physical disconnect, then
|
||||
* unconfigure the device */
|
||||
if (udev->state == USB_STATE_CONFIGURED)
|
||||
if (udev->actconfig)
|
||||
usb_set_configuration(udev, 0);
|
||||
|
||||
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
|
||||
@ -208,4 +204,5 @@ struct usb_device_driver usb_generic_driver = {
|
||||
.suspend = generic_suspend,
|
||||
.resume = generic_resume,
|
||||
#endif
|
||||
.supports_autosuspend = 1,
|
||||
};
|
||||
|
@ -1366,9 +1366,6 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
|
||||
if (cp && configuration == 0)
|
||||
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,
|
||||
* so that if we run out then nothing will have changed. */
|
||||
n = nintf = 0;
|
||||
@ -1403,6 +1400,11 @@ free_interfaces:
|
||||
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.
|
||||
* getting rid of old interfaces means unbinding their drivers.
|
||||
*/
|
||||
@ -1422,6 +1424,7 @@ free_interfaces:
|
||||
dev->actconfig = cp;
|
||||
if (!cp) {
|
||||
usb_set_device_state(dev, USB_STATE_ADDRESS);
|
||||
usb_autosuspend_device(dev, 1);
|
||||
goto free_interfaces;
|
||||
}
|
||||
usb_set_device_state(dev, USB_STATE_CONFIGURED);
|
||||
@ -1490,6 +1493,7 @@ free_interfaces:
|
||||
usb_create_sysfs_intf_files (intf);
|
||||
}
|
||||
|
||||
usb_autosuspend_device(dev, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -90,6 +90,11 @@ static int skel_open(struct inode *inode, struct file *file)
|
||||
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 */
|
||||
kref_get(&dev->kref);
|
||||
|
||||
@ -108,6 +113,12 @@ static int skel_release(struct inode *inode, struct file *file)
|
||||
if (dev == NULL)
|
||||
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 */
|
||||
kref_put(&dev->kref, skel_delete);
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user