Hi,

here's autosuspend for storage devices. It was surprisingly easy.
I've tested it and I can play an mp3 and see how the stick wakes
up every few seconds. Comments?
To test this you'll likely have to turn off haldaemon. This still
needs a solution.
Alan, do I recall correctly that you have a mouse with an internal
card reader? That would be the optimal test device. If storage and
hid cooperate on that hardware I'd be happy.

        Regards
                Oliver

--- linux-2.6.20/drivers/usb/storage/usb.c      2007-02-06 14:14:49.000000000 
+0100
+++ linux-2.6.20-autosusp/drivers/usb/storage/usb.c     2007-02-09 
16:10:35.000000000 +0100
@@ -190,11 +190,8 @@
 static int storage_suspend(struct usb_interface *iface, pm_message_t message)
 {
        struct us_data *us = usb_get_intfdata(iface);
-
-       /* Wait until no command is running */
-       mutex_lock(&us->dev_mutex);
-
        US_DEBUGP("%s\n", __FUNCTION__);
+
        if (us->suspend_resume_hook)
                (us->suspend_resume_hook)(us, US_SUSPEND);
        iface->dev.power.power_state.event = message.event;
@@ -202,7 +199,6 @@
        /* When runtime PM is working, we'll set a flag to indicate
         * whether we should autoresume when a SCSI request arrives. */
 
-       mutex_unlock(&us->dev_mutex);
        return 0;
 }
 
@@ -210,14 +206,12 @@
 {
        struct us_data *us = usb_get_intfdata(iface);
 
-       mutex_lock(&us->dev_mutex);
-
        US_DEBUGP("%s\n", __FUNCTION__);
+
        if (us->suspend_resume_hook)
                (us->suspend_resume_hook)(us, US_RESUME);
        iface->dev.power.power_state.event = PM_EVENT_ON;
 
-       mutex_unlock(&us->dev_mutex);
        return 0;
 }
 
@@ -300,6 +294,7 @@
 {
        struct us_data *us = (struct us_data *)__us;
        struct Scsi_Host *host = us_to_host(us);
+       int res;
 
        current->flags |= PF_NOFREEZE;
 
@@ -370,8 +365,15 @@
 
                /* we've got a command, let's do it! */
                else {
-                       US_DEBUG(usb_stor_show_command(us->srb));
-                       us->proto_handler(us->srb, us);
+                       res = usb_autopm_get_interface(us->pusb_intf);
+                       if (!res) {
+                               US_DEBUG(usb_stor_show_command(us->srb));
+                               us->proto_handler(us->srb, us);
+                               usb_autopm_put_interface(us->pusb_intf);
+                       } else {
+                               us->srb->result = DID_ERROR << 16;
+                               US_DEBUGP("Could not wake device\n");
+                       }
                }
 
                /* lock access to the state */
@@ -937,6 +939,7 @@
        }
 
        scsi_host_put(us_to_host(us));
+       usb_autopm_put_interface(us->pusb_intf);
        complete_and_exit(&threads_gone, 0);
 }
 
@@ -1026,6 +1029,7 @@
         * start it up. */
        scsi_host_get(us_to_host(us));
        atomic_inc(&total_threads);
+       usb_autopm_get_interface(intf); /* dropped in the scanning thread */
        wake_up_process(th);
 
        return 0;
@@ -1062,6 +1066,7 @@
        .pre_reset =    storage_pre_reset,
        .post_reset =   storage_post_reset,
        .id_table =     storage_usb_ids,
+       .supports_autosuspend = 1,
 };
 
 static int __init usb_stor_init(void)

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
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