From owner-freebsd-current@FreeBSD.ORG Fri Mar 20 11:18:12 2009 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B434F1065674 for ; Fri, 20 Mar 2009 11:18:12 +0000 (UTC) (envelope-from dimitry@andric.com) Received: from tensor.andric.com (cl-327.ede-01.nl.sixxs.net [IPv6:2001:7b8:2ff:146::2]) by mx1.freebsd.org (Postfix) with ESMTP id 1BE6E8FC1B for ; Fri, 20 Mar 2009 11:18:12 +0000 (UTC) (envelope-from dimitry@andric.com) Received: from [IPv6:2001:7b8:3a7:0:1059:d890:bbc1:a26c] (unknown [IPv6:2001:7b8:3a7:0:1059:d890:bbc1:a26c]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by tensor.andric.com (Postfix) with ESMTPSA id 314645C42; Fri, 20 Mar 2009 12:18:11 +0100 (CET) Message-ID: <49C37B75.5060905@andric.com> Date: Fri, 20 Mar 2009 12:18:13 +0100 From: Dimitry Andric User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1b4pre) Gecko/20090319 Shredder/3.0b3pre MIME-Version: 1.0 To: Bruce Cran References: <49BE7C5A.2080103@icyb.net.ua> <10611.1237233778@critter.freebsd.dk> <20090320074833.67d615e2@gluon> In-Reply-To: <20090320074833.67d615e2@gluon> Content-Type: multipart/mixed; boundary="------------010002040505040009070701" Cc: Poul-Henning Kamp , freebsd-current@freebsd.org, Andriy Gapon Subject: Re: ata: printf on every spinup/spindown? X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Mar 2009 11:18:13 -0000 This is a multi-part message in MIME format. --------------010002040505040009070701 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit On 2009-03-20 08:48, Bruce Cran wrote: > Related to this, the ATA driver should probably have some means, either > automatically or via atacontrol, of setting the APM value on disks; I > bought a new laptop and immediately had to install > sysutils/ataidle in order to stop the heads loading/unloading several > times per minute by setting APM to 254. Apparently it's fairly common > for laptop drives to have overly aggressive power settings that need > intervention from the OS. I have been running with the attached patch since ages, and it still applies to -stable, hopefully to -current too. I have forgotten who the original author is, so my apologies for not crediting it... --------------010002040505040009070701 Content-Type: text/plain; name="atacontrol-20090320a.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="atacontrol-20090320a.diff" Index: sbin/atacontrol/atacontrol.8 =================================================================== RCS file: /home/ncvs/src/sbin/atacontrol/atacontrol.8,v retrieving revision 1.28.2.4 diff -u -p -r1.28.2.4 atacontrol.8 --- sbin/atacontrol/atacontrol.8 3 Mar 2009 07:56:42 -0000 1.28.2.4 +++ sbin/atacontrol/atacontrol.8 20 Mar 2009 11:15:05 -0000 @@ -65,6 +65,16 @@ .Ar device .Op Ar mode .Nm +.Ic feature +.Ar device +.Ic apm +.Ar apmlevel +.Nm +.Ic feature +.Ar device +.Ic acoustic +.Ar soundsupplevel +.Nm .Ic info .Ar channel .Nm @@ -195,6 +205,44 @@ Currently supported modes are: .Cm SATA150 , SATA300 , USB , USB1 , USB2 and .Cm BIOSDMA . +.It Ic feature / apm +Set disk drive Advanced Power Management (APM) level. +This command is generally used on laptop (notebook) hard disks to control +the power level consumed by the drive (at the expense of performance). +.Pp +The +.Ar apmlevel +may be set to one of: +.Cm off +(turn off APM), +.Cm maxperf +or +.Cm minpower +(optimize for maximum performance or minimum power, respectively), or +a numeric level which can be 0 to 127 inclusive indicating an increasing +level of performance over power savings. +The numeric levels may be prefixed by +.Cm s +which will allow the drive to include suspension as part of the +power savings. Note that not all hard drives will support the +.Cm off +command, and that the number of incremental power savings levels +do not typically have as wide of a range as this command will +support. +.It Ic feature / acoustic +Control disk drive Acoustic Management level. The +.Ar soundsupplevel +may be set to +.Cm off +which will turn off acoustic management, +.Cm maxperf +to optimize for maximum performance, +.Cm maxquiet +to optimize for maximum quiet, or a numeric level +from 0 to 124. The higher the numeric level, the higher the +theoretical sound level emitted from the drive. Note that few +devices support this command and even fewer will allow the +range of levels supported. .It Ic cap Show detailed info about the device on .Ar device . Index: sbin/atacontrol/atacontrol.c =================================================================== RCS file: /home/ncvs/src/sbin/atacontrol/atacontrol.c,v retrieving revision 1.43.2.5 diff -u -p -r1.43.2.5 atacontrol.c --- sbin/atacontrol/atacontrol.c 3 Mar 2009 07:56:42 -0000 1.43.2.5 +++ sbin/atacontrol/atacontrol.c 20 Mar 2009 11:15:05 -0000 @@ -107,6 +107,8 @@ usage(void) " atacontrol rebuild array\n" " atacontrol status array\n" " atacontrol mode device [mode]\n" + " atacontrol feature device apm apmlevel\n" + " atacontrol feature device acoustic soundsupplevel\n" " atacontrol cap device\n" " atacontrol spindown device [seconds]\n" ); @@ -381,6 +383,88 @@ main(int argc, char **argv) } exit(EX_OK); } + if (!strcmp(argv[1], "feature") && argc == 5) { + int disk; + char device[64]; + struct ata_ioc_request request; + + if (!(sscanf(argv[2], "ad%d", &disk) == 1 || + sscanf(argv[2], "acd%d", &disk) == 1 || + sscanf(argv[2], "afd%d", &disk) == 1 || + sscanf(argv[2], "ast%d", &disk) == 1)) { + fprintf(stderr, "atacontrol: Invalid device %s\n", + argv[2]); + exit(EX_USAGE); + } + sprintf(device, "/dev/%s", argv[2]); + if ((fd = open(device, O_RDONLY)) < 0) + err(1, "device not found"); + + bzero(&request, sizeof(struct ata_ioc_request)); + request.u.ata.command = ATA_SETFEATURES; + request.flags = ATA_CMD_CONTROL; + request.timeout = 500; + if (!strcmp(argv[3], "apm")) { + if (!strcmp(argv[4], "off")) { + request.u.ata.feature = ATA_SF_DIS_APM; + } + else if (!strcmp(argv[4], "maxperf")) { + request.u.ata.feature = ATA_SF_ENAB_APM; + request.u.ata.count = 0xfe; + } + else if (!strcmp(argv[4], "minpower")) { + request.u.ata.feature = ATA_SF_ENAB_APM; + request.u.ata.count = 0x01; + } + else { + int offset = 0; + + request.u.ata.feature = ATA_SF_ENAB_APM; + if (argv[4][0] == 's') { + offset = atoi(&argv[4][1]); + request.u.ata.count = 0x01; + } else { + offset = atoi(&argv[4][1]); + request.u.ata.count = 0x80; + } + if (offset >= 0 && offset <= 127) + request.u.ata.count += offset; + } + } + else if (!strcmp(argv[3], "acoustic")) { + if (!strcmp(argv[4], "off")) { + request.u.ata.feature = ATA_SF_DIS_ACCOUS; + } + else if (!strcmp(argv[4], "maxperf")) { + request.u.ata.feature = ATA_SF_ENAB_ACCOUS; + request.u.ata.count = 0xfe; + } + else if (!strcmp(argv[4], "maxquiet")) { + request.u.ata.feature = ATA_SF_ENAB_ACCOUS; + request.u.ata.count = 0x80; + } + else { + request.u.ata.feature = ATA_SF_ENAB_ACCOUS; + request.u.ata.count = atoi(argv[4]); + if (request.u.ata.count > 124) + request.u.ata.count = 124; + } + } + else + usage(); + + if (ioctl(fd, IOCATAREQUEST, &request) < 0) + err(1, "ioctl(IOCATAREQUEST)"); + + if (request.error != 0) { + fprintf(stderr, + "IOCATAREQUEST returned err status %d", + request.error); + exit(EX_IOERR); + } + + exit(EX_OK); + } if (!strcmp(argv[1], "cap") && argc == 3) { fd = open_dev(argv[2], O_RDONLY); ata_cap_print(fd); Index: sys/sys/ata.h =================================================================== RCS file: /home/ncvs/src/sys/sys/ata.h,v retrieving revision 1.36.2.3 diff -u -p -r1.36.2.3 ata.h --- sys/sys/ata.h 8 Apr 2008 10:48:21 -0000 1.36.2.3 +++ sys/sys/ata.h 20 Mar 2009 11:15:05 -0000 @@ -281,6 +281,10 @@ struct ata_params { #define ATA_SF_DIS_RELIRQ 0xdd /* disable release interrupt */ #define ATA_SF_ENAB_SRVIRQ 0x5e /* enable service interrupt */ #define ATA_SF_DIS_SRVIRQ 0xde /* disable service interrupt */ +#define ATA_SF_ENAB_APM 0x05 /* enable adv power mgmt */ +#define ATA_SF_DIS_APM 0x85 /* disable adv power mgmt */ +#define ATA_SF_ENAB_ACCOUS 0x42 /* enable acoustic mgmt */ +#define ATA_SF_DIS_ACCOUS 0xc2 /* disable acoustic mgmt */ #define ATA_SECURITY_FREEE_LOCK 0xf5 /* freeze security config */ #define ATA_READ_NATIVE_MAX_ADDDRESS 0xf8 /* read native max address */ #define ATA_SET_MAX_ADDRESS 0xf9 /* set max address */ --------------010002040505040009070701--