[PATCH] ATA disk spin-down for -current

Cliff L. Biffle cbiffle at safety.net
Sat Apr 12 14:38:58 PDT 2003


Allo all.  I've ported the 4.x patch that enabled ATA disk spin-down to the 
5.x kernel.  (It looks like it'd also work on recent 4.x.)  Since I got the 
original patch out of this list's archives, I thought I'd send it back.

Basically this just updates the ata_command calls to the new LBA format rather 
than the older C/H/S.

I'm relatively unfamiliar with the ATA subsystem, and I -think- putting the 
suspend call after ATA_UNLOCK_CH is correct.  If anyone knows better, let me 
know.

Anyway, I've been using this on my laptop with great success.  Suspend time is 
set (in seconds) in hw.ata.suspend; this must be done at boot in loader.conf, 
as it's read-only at runtime.

Comments?  Corrections?

-Cliff L. Biffle

--- src/sys/dev/ata/ata-disk.c.orig	Fri Apr 11 12:50:37 2003
+++ src/sys/dev/ata/ata-disk.c	Fri Apr 11 13:05:54 2003
@@ -70,9 +70,11 @@
 static int ata_dma = 1;
 static int ata_wc = 1;
 static int ata_tags = 0; 
+static int ata_suspend = 0;
 TUNABLE_INT("hw.ata.ata_dma", &ata_dma);
 TUNABLE_INT("hw.ata.wc", &ata_wc);
 TUNABLE_INT("hw.ata.tags", &ata_tags);
+TUNABLE_INT("hw.ata.suspend", &ata_suspend);
 static MALLOC_DEFINE(M_AD, "AD driver", "ATA disk driver");
 
 /* sysctl vars */
@@ -83,6 +85,8 @@
 	   "ATA disk write caching");
 SYSCTL_INT(_hw_ata, OID_AUTO, tags, CTLFLAG_RD, &ata_tags, 0,
 	   "ATA disk tagged queuing support");
+SYSCTL_INT(_hw_ata, OID_AUTO, suspend, CTLFLAG_RD, &ata_suspend, 0,
+	   "ATA disk suspend timer");
 
 void
 ad_attach(struct ata_device *atadev)
@@ -185,6 +189,12 @@
 #endif
     ATA_UNLOCK_CH(atadev->channel);
 
+	 if(ata_suspend > 0) {
+		 /* attempt suspend mode.  The drive uses increments of ten seconds */
+		 if(ata_command(atadev, 0xe2, 0, ata_suspend/10, 0, ATA_WAIT_INTR))
+			 ata_prtdev(atadev, "suspend mode failed.");
+	 }
+
     adp->disk.d_open = adopen;
     adp->disk.d_close = adclose;
     adp->disk.d_strategy = adstrategy;
@@ -856,6 +866,11 @@
     ata_command(atadev, ATA_C_SET_MULTI, 0,
 		adp->transfersize / DEV_BSIZE, 0, ATA_WAIT_READY);
     atadev->setmode(atadev, adp->device->mode);
+	 if(ata_suspend > 0) {
+		 /* attempt suspend mode.  The drive uses increments of ten seconds */
+		 if(ata_command(atadev, 0xe2, 0, ata_suspend/10, 0, ATA_WAIT_READY))
+			 ata_prtdev(atadev, "suspend mode failed.");
+	 }
 }
 
 void



More information about the freebsd-mobile mailing list