Please find attached a kernel patch to enable ATA drive spin-down after a specified interval. I'm using this on my laptop now with much success; I'm offering it primarily for testing purposes. I'll toss it onto mobile if it seems okay. This is simply an update of an earlier patch for 4.x; it's been updated to reflect the new ata_command syntax and some rearrangements in ata-disk.c. The net effect of this patch is to provide a sysctl, hw.ata.suspend, that sets the disk auto-spindown delay in seconds. This must be set at boot in loader.conf, and the value is sent to the drive on initialization, and again on reinit (such as after a suspend/resume cycle). There -should- be no effect if hw.ata.suspend is not set. The original patch was apparently to be superceded by code from Soren Schmidt, but I haven't been able to find any. If anyone has any leads on what this real solution would be, drop me a line, I'll be happy to help test. The one judgement I had to make when writing this was whether to place the suspend code before or after ATA_UNLOCK_CH. I've placed it -after- the call. Anyone with more familiarity of the ATA subsystem, let me know if this was the right decision. -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 _at__at_ -70,9 +70,11 _at__at_ 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 */ _at__at_ -83,6 +85,8 _at__at_ "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) _at__at_ -185,6 +189,12 _at__at_ #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; _at__at_ -856,6 +866,11 _at__at_ 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."); + } } voidReceived on Fri Apr 11 2003 - 15:07:22 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:03 UTC