[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