Commit 758f7e16 authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman

USB: usb-skeleton" use anchors in suspend/resume handling

use anchors in suspend/resume handling
Signed-off-by: default avatarOliver Neukum <oneukum@suse.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent e73c7247
...@@ -57,6 +57,7 @@ struct usb_skel { ...@@ -57,6 +57,7 @@ struct usb_skel {
__u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
__u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */
int errors; /* the last request tanked */ int errors; /* the last request tanked */
int open_count; /* count the number of openers */
spinlock_t err_lock; /* lock for errors */ spinlock_t err_lock; /* lock for errors */
struct kref kref; struct kref kref;
struct mutex io_mutex; /* synchronize I/O with disconnect */ struct mutex io_mutex; /* synchronize I/O with disconnect */
...@@ -101,12 +102,26 @@ static int skel_open(struct inode *inode, struct file *file) ...@@ -101,12 +102,26 @@ static int skel_open(struct inode *inode, struct file *file)
/* increment our usage count for the device */ /* increment our usage count for the device */
kref_get(&dev->kref); kref_get(&dev->kref);
/* prevent the device from being autosuspended */ /* lock the device to allow correctly handling errors
retval = usb_autopm_get_interface(interface); * in resumption */
if (retval) { mutex_lock(&dev->io_mutex);
if (!dev->open_count++) {
retval = usb_autopm_get_interface(interface);
if (retval) {
dev->open_count--;
mutex_unlock(&dev->io_mutex);
kref_put(&dev->kref, skel_delete);
goto exit;
}
} /* else { //uncomment this block if you want exclusive open
retval = -EBUSY;
dev->open_count--;
mutex_unlock(&dev->io_mutex);
kref_put(&dev->kref, skel_delete); kref_put(&dev->kref, skel_delete);
goto exit; goto exit;
} } */
/* prevent the device from being autosuspended */
/* save our object in the file's private structure */ /* save our object in the file's private structure */
file->private_data = dev; file->private_data = dev;
...@@ -125,7 +140,7 @@ static int skel_release(struct inode *inode, struct file *file) ...@@ -125,7 +140,7 @@ static int skel_release(struct inode *inode, struct file *file)
/* allow the device to be autosuspended */ /* allow the device to be autosuspended */
mutex_lock(&dev->io_mutex); mutex_lock(&dev->io_mutex);
if (dev->interface) if (!--dev->open_count && dev->interface)
usb_autopm_put_interface(dev->interface); usb_autopm_put_interface(dev->interface);
mutex_unlock(&dev->io_mutex); mutex_unlock(&dev->io_mutex);
...@@ -437,10 +452,27 @@ static void skel_draw_down(struct usb_skel *dev) ...@@ -437,10 +452,27 @@ static void skel_draw_down(struct usb_skel *dev)
usb_kill_anchored_urbs(&dev->submitted); usb_kill_anchored_urbs(&dev->submitted);
} }
static int skel_suspend(struct usb_interface *intf, pm_message_t message)
{
struct usb_skel *dev = usb_get_intfdata(intf);
if (!dev)
return 0;
skel_draw_down(dev);
return 0;
}
static int skel_resume (struct usb_interface *intf)
{
return 0;
}
static struct usb_driver skel_driver = { static struct usb_driver skel_driver = {
.name = "skeleton", .name = "skeleton",
.probe = skel_probe, .probe = skel_probe,
.disconnect = skel_disconnect, .disconnect = skel_disconnect,
.suspend = skel_suspend,
.resume = skel_resume,
.id_table = skel_table, .id_table = skel_table,
.supports_autosuspend = 1, .supports_autosuspend = 1,
}; };
......
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