autosuspend for storage devices

Oliver Neukum <[email protected]>
Newsgroups gmane.linux.usb.devel
Message-ID <[email protected]>
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
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.