From: Oliver Neukum <[EMAIL PROTECTED]>
use anchors in suspend/resume handling
Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]>
Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
---
drivers/usb/usb-skeleton.c | 42 +++++++++++++++++++++++++++++++++++++-----
1 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index 1b1e669..59973ae 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -57,6 +57,7 @@ struct usb_skel {
__u8 bulk_in_endpointAddr; /* the address of the
bulk in endpoint */
__u8 bulk_out_endpointAddr; /* the address of the
bulk out endpoint */
int errors; /* the last request
tanked */
+ int open_count; /* count the number of
openers */
spinlock_t err_lock; /* lock for errors */
struct kref kref;
struct mutex io_mutex; /* synchronize I/O with
disconnect */
@@ -101,12 +102,26 @@ static int skel_open(struct inode *inode, struct file
*file)
/* increment our usage count for the device */
kref_get(&dev->kref);
- /* prevent the device from being autosuspended */
- retval = usb_autopm_get_interface(interface);
- if (retval) {
+ /* lock the device to allow correctly handling errors
+ * in resumption */
+ 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);
goto exit;
- }
+ } */
+ /* prevent the device from being autosuspended */
/* save our object in the file's private structure */
file->private_data = dev;
@@ -125,7 +140,7 @@ static int skel_release(struct inode *inode, struct file
*file)
/* allow the device to be autosuspended */
mutex_lock(&dev->io_mutex);
- if (dev->interface)
+ if (!--dev->open_count && dev->interface)
usb_autopm_put_interface(dev->interface);
mutex_unlock(&dev->io_mutex);
@@ -437,10 +452,27 @@ static void skel_draw_down(struct usb_skel *dev)
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 = {
.name = "skeleton",
.probe = skel_probe,
.disconnect = skel_disconnect,
+ .suspend = skel_suspend,
+ .resume = skel_resume,
.id_table = skel_table,
.supports_autosuspend = 1,
};
--
1.5.2.2
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel