USB card reader autosuspend

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Oliver:

I did a little testing.  You are right that we will run into problems
with card readers that don't properly track media changes while at low
power.  Going through all the partition/volume ID/RAID detection stuff
every few seconds (thanks to hal's polling) would be a real drain.

To avoid these problems, I changed sd to make it autosuspend only when
the device file is closed _and_ there is no medium present.  The patch
below is just a proof-of-principle; in the end we'll want something
more flexible.  Maybe a sysfs attribute to select the conditions under
which autosuspend is allowed.

What do you think?

Alan Stern


Index: usb-2.6/drivers/scsi/sd.c
===================================================================
--- usb-2.6.orig/drivers/scsi/sd.c
+++ usb-2.6/drivers/scsi/sd.c
@@ -759,9 +759,12 @@ static int sd_open(struct block_device *
 
 	sdev = sdkp->device;
 
-	retval = scsi_autopm_get_device(sdev);
-	if (retval)
-		goto error_autopm;
+	/* We autosuspended iff no medium was present */
+	if (!sdkp->media_present) {
+		retval = scsi_autopm_get_device(sdev);
+		if (retval)
+			goto error_autopm;
+	}
 
 	/*
 	 * If the device is in error recovery, wait until it is done.
@@ -807,7 +810,8 @@ static int sd_open(struct block_device *
 	return 0;
 
 error_out:
-	scsi_autopm_put_device(sdev);
+	if (!sdkp->media_present)
+		scsi_autopm_put_device(sdev);
 error_autopm:
 	scsi_disk_put(sdkp);
 	return retval;	
@@ -841,7 +845,8 @@ static int sd_release(struct gendisk *di
 	 * XXX is followed by a "rmmod sd_mod"?
 	 */
 
-	scsi_autopm_put_device(sdev);
+	if (!sdkp->media_present)
+		scsi_autopm_put_device(sdev);
 	scsi_disk_put(sdkp);
 	return 0;
 }
@@ -2247,7 +2252,8 @@ static void sd_probe_async(void *data, a
 
 	sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
 		  sdp->removable ? "removable " : "");
-	scsi_autopm_put_device(sdp);
+	if (!sdkp->media_present)
+		scsi_autopm_put_device(sdp);
 	put_device(&sdkp->dev);
 }
 
@@ -2368,7 +2374,8 @@ static int sd_remove(struct device *dev)
 	struct scsi_disk *sdkp;
 
 	sdkp = dev_get_drvdata(dev);
-	scsi_autopm_get_device(sdkp->device);
+	if (!sdkp->media_present)
+		scsi_autopm_get_device(sdkp->device);
 
 	async_synchronize_full();
 	blk_queue_prep_rq(sdkp->device->request_queue, scsi_prep_fn);

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux