Greg:

This patch (as619) adds support for suspend/resume to the usblp driver.  

Alan Stern



Signed-off-by: Alan Stern <[EMAIL PROTECTED]>

---

In 2.6.15, any USB driver without such support will prevent the system
from suspending.  So it would be nice, although it's certainly not
critical, if this could be added to Linus's tree before 2.6.15 is
released.

I'm afraid we may see a flurry of "USB in 2.6.15 broke suspend" bug 
reports...  :-(

Index: usb-2.6/drivers/usb/class/usblp.c
===================================================================
--- usb-2.6.orig/drivers/usb/class/usblp.c
+++ usb-2.6/drivers/usb/class/usblp.c
@@ -54,6 +54,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/lp.h>
+#include <linux/suspend.h>
 #undef DEBUG
 #include <linux/usb.h>
 
@@ -152,6 +153,7 @@ struct usblp {
        unsigned char           used;                   /* True if open */
        unsigned char           present;                /* True if not 
disconnected */
        unsigned char           bidir;                  /* interface is 
bidirectional */
+       unsigned char           suspended;              /* Obvious... */
        unsigned char           *device_id_string;      /* IEEE 1284 DEVICE ID 
string (ptr) */
                                                        /* first 2 bytes are 
(big-endian) length */
 };
@@ -386,7 +388,8 @@ static int usblp_open(struct inode *inod
        if (usblp->bidir) {
                usblp->readcount = 0;
                usblp->readurb->dev = usblp->dev;
-               if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) {
+               if (usblp->suspended || usb_submit_urb(usblp->readurb,
+                               GFP_KERNEL) < 0) {
                        retval = -EIO;
                        usblp->used = 0;
                        file->private_data = NULL;
@@ -706,7 +709,8 @@ static ssize_t usblp_write(struct file *
 
                usblp->writeurb->dev = usblp->dev;
                usblp->wcomplete = 0;
-               err = usb_submit_urb(usblp->writeurb, GFP_KERNEL);
+               err = usblp->suspended ? -EIO :
+                               usb_submit_urb(usblp->writeurb, GFP_KERNEL);
                if (err) {
                        if (err != -ENOMEM)
                                count = -EIO;
@@ -775,7 +779,8 @@ static ssize_t usblp_read(struct file *f
                usblp->readurb->dev = usblp->dev;
                usblp->readcount = 0;
                usblp->rcomplete = 0;
-               if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0)
+               if (usblp->suspended || usb_submit_urb(usblp->readurb,
+                               GFP_KERNEL) < 0)
                        dbg("error submitting urb");
                count = -EIO;
                goto done;
@@ -793,7 +798,8 @@ static ssize_t usblp_read(struct file *f
                usblp->readcount = 0;
                usblp->readurb->dev = usblp->dev;
                usblp->rcomplete = 0;
-               if (usb_submit_urb(usblp->readurb, GFP_KERNEL)) {
+               if (usblp->suspended || usb_submit_urb(usblp->readurb,
+                               GFP_KERNEL)) {
                        count = -EIO;
                        goto done;
                }
@@ -849,6 +855,31 @@ static struct usb_class_driver usblp_cla
        .minor_base =   USBLP_MINOR_BASE,
 };
 
+#ifdef CONFIG_PM
+static int usblp_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct usblp *usblp = usb_get_intfdata(intf);
+
+       down(&usblp->sem);
+       usblp->suspended = 1;
+       usblp_unlink_urbs(usblp);
+       intf->dev.power.power_state.event = message.event;
+       up(&usblp->sem);
+       return 0;
+}
+
+static int usblp_resume(struct usb_interface *intf)
+{
+       struct usblp *usblp = usb_get_intfdata(intf);
+
+       down(&usblp->sem);
+       usblp->suspended = 0;
+       intf->dev.power.power_state.event = PM_EVENT_ON;
+       up(&usblp->sem);
+       return 0;
+}
+#endif
+
 static int usblp_probe(struct usb_interface *intf,
                       const struct usb_device_id *id)
 {
@@ -1190,6 +1221,10 @@ static struct usb_driver usblp_driver = 
        .probe =        usblp_probe,
        .disconnect =   usblp_disconnect,
        .id_table =     usblp_ids,
+#ifdef CONFIG_PM
+       .suspend =      usblp_suspend,
+       .resume =       usblp_resume,
+#endif
 };
 
 static int __init usblp_init(void)



-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to