You are not logged in.
Hi everyone,
I have a Western Digital harddrive installed in my desktop which I only use for occasional backups. Since I try to have my machine to be as silent as possible I of course wanted to avoid having this loud harddrive spinning all the time and since my rootfs is on a SSD I of course don't even need to power it up when I boot my computer.
So I researched a bit and found out about the Power-Up in Standby (PUIS) feature, which Western Digital calls PM2 and according to Western Digital documents it can be enabled with putting a jumper on specific pins of the harddrive. So I did that and started my computer..
Problem: The harddrive still spins up everytime I power-up my computer and (even worse) every time I resume from suspend, which I use all the time!
So my solution was to just use hdparm with hdparm -Y dev to spin it down manually, respectively I now also created a systemd unit that just calls this command when I resume from suspend. This if of course also not ideal, since the drive spins up and down for no reason, which of course won't be good for the longevity of the device.
A weird thing I noticed are some entries in the kernel message buffer, maybe anyone can explain what those might mean, as I have not found any useful information on those error message (eg "qc timeout")
Here's a `dmesg | tail` after resuming from `systemctl suspend`. The harddrive is connected to ata2
<snip>
[ +0.081854] PM: resume of devices complete after 184.437 msecs
[ +0.000109] PM: Finishing wakeup.
[ +0.000001] Restarting tasks ... done.
[ +0.154784] ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[ +0.009993] ata5: SATA link down (SStatus 0 SControl 300)
[ +0.003323] ata2: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[ +0.000031] ata6: SATA link down (SStatus 0 SControl 300)
[ +0.003329] ata3: SATA link down (SStatus 0 SControl 300)
[ +2.728660] ata1.00: configured for UDMA/133
[ +0.121187] e1000e: eno1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: Rx/Tx
[ +2.149156] ata2.00: qc timeout (cmd 0xef)
[ +0.000011] ata2.00: failed to IDENTIFY (SPINUP failed, err_mask=0x4)
[ +0.000003] ata2.00: revalidation failed (errno=-5)
[ +2.241052] ata2: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[ +0.870976] ata2.00: configured for UDMA/133
The harddrive model is WDC WD10EALX-009BA0 my motherboard is an Intel BL67BL. As far as I think my motherboard should support this feature, but I couldn't find any proof for that.
Please let me know if any other information or logfiles might be needed to investigate my issue.
Thanks for any clues you can give me to solve this problem!
Offline
Hi, I tried that some years ago with my wdc drives (WD2001FASS), but with a different results than you. In my case, drives does not spin up at all, then at POST (Asus M2N32-SLI Deluxe) there is a long delay, and drive is not detected.
I guess, PUIS feature is only used for large RAID enviroments, to avoid big current peak on powerup, not for other usage case.
Weird, your drive should not spinup on powerup, the same thing happens if you only connect the power cable?
Offline
[...]
Weird, your drive should not spinup on powerup, the same thing happens if you only connect the power cable?
When I only connect the power cable of the drive it also didn't spin up without the jumper. Because before I just did it this way, but I don't want to open my case and replug it all the time I want to use that drive..
Though I think it could be a software issue, according to the dmesg output I posted. If I don't have PM2 enabled with the jumper the drive also starts to spin up earlier when I resume, with PM2 enabled there is some delay. This message
ata2.00: failed to IDENTIFY (SPINUP failed, err_mask=0x4)
makes me assume that the drive doesn't spin up at first because of the PM2 but some software part then decides to force the spin up anyway. No idea. Maybe I should try connecting it to a different motherboard to see if it's really the BIOSes fault, could that be?
Offline
I know this is an old post.
I'm also interested in this feature and would like to be able to spin up a drive only when needed.
For example, my situation: my OS is on a SSD, my data are on a HD, and I have 2 or 3 more HDs for backup. I use those 2 or 3 HDs not very often, perhaps once a week, so it would be nice to have all the cables connected, all ready, and spin up a HD only when I need it.
I think this situation is similar to other people's situation, nowadays, for one reason or another.
I know power up in standby is designed to prevent current peaks in large disks arrays, so I think that, by design, the HD is supposed to spin up anyway, it's just a matter of when it will spin up. Nevertheless, it still would be nice to use this feature to achieve the goal I wrote few lines above.
What I have experimented: I found a drive supporting the PUIS feature (a seagate barracuda ST500DM002), enabled PUIS via hdparm -s command, in the computer BIOS set the correspondig SATA port as "disabled" and turned off the pc. I read about that in other forums and they say it depends on your motherboard: some MB fully support this feature and you can leave the SATA port enabled, some MB don't support it and you can trick it by setting the SATA port as disabled (as in my case, apparently it works because the kernel will probe the SATA ports without caring about the BIOS settings), some MB don't support it and there's no way to make it work.
Also, I noticed that with UEFI the situation may be different: if I set the SATA port as disabled, the OS is no longer able to probe that SATA port, in dmesg I found "ataX.00: DUMMY", the same as other SATA ports where no drive was attached. The same happens if I disable a SATA port where a normal HD, without PUIS enabled, is attached.
Anyway, I powered up the computer: the drive did not spin up until the OS booted, so I think I can say that PUIS worked, if we stand by the description of that feature. After the OS had booted, searching in dmesg returned the following lines
ataX.00: qc timeout (cmd 0xef)
ataX.00: failed to IDENTIFY (SPINUP failed, err_mask=0x4)
ataX.00: revalidation failed (errno=-5)
ataX: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
ataX.00: configured for UDMA/133
I think this is when the drive is spun up: the first try raises an error and the drive is spun up with some other command, the second try is succesful.
Searching in the linux kernel source code (latest stable, 4.8.2) I found in drivers/ata/libata-core.c:
if (!tried_spinup && (id[2] == 0x37c8 || id[2] == 0x738c)) {
tried_spinup = 1;
/*
* Drive powered-up in standby mode, and requires a specific
* SET_FEATURES spin-up subcommand before it will accept
* anything other than the original IDENTIFY command.
*/
err_mask = ata_dev_set_feature(dev, SETFEATURES_SPINUP, 0);
if (err_mask && id[2] != 0x738c) {
rc = -EIO;
reason = "SPINUP failed";
goto err_out;
}
/*
* If the drive initially returned incomplete IDENTIFY info,
* we now must reissue the IDENTIFY command.
*/
if (id[2] == 0x37c8)
goto retry;
}
The same lines are present in earlier versions.
I think that if I change that code I can tell the ata driver to leave alone a drive if found in a PUIS state. Problem: I know nothing about C programming. I'm trying to learn something about it, but I can tell it will not be easy. I think the ideal would be to create a boot parameter with which the user can decide what to do if a drive in PUIS state is found.
What do you think about this?
Offline
Ok guys, I did something (but not involving C programming), and I can say I met my goal.
For starters, I just commented out the libata-core section, just to try. I recompiled the kernel with this "patched" libata-core and started the pc with a HD with puis enabled: the HD did not spin up, I logged in my X session without problems. Checking dmesg, there were just loads of error when the kernel tried to query the HD, nothing strange. Special file /dev/sdb existed, but not /dev/sdb1 and so on.
So, it was time for the quest for spinning up the HD. Luckly, I found in hdparm source code the same set features subcommand reported in libata-core, it is issued when hdparm disables puis on the HD.
So, doing (all commands must be run with administrative privileges):
hdparm -s0 /dev/sdb
spins up the HD, but also disables puis, so we need to reenable it:
hdparm -s1 --yes-i-know-what-i-am-doing /dev/sdb
Then, to access partitions, we have to soft remove the HD
echo 1 > /sys/block/sdb/device/delete
and rescan the bus:
echo "- - -" > /sys/class/scsi_host/host1/scan
Now we can access the disk and its partitions normally as usual.
It's not elegant, especially disabling and reenabling puis to spin up the drive, but it works.
I'm thinking about patching hdparm to add a switch to just spin up the drive, without disabling puis, but again I know nothing about C programming. I still think the best would be a boot parameter to decide what to do when a disk in puis state is found, instead of commenting out the section in libata-core, but again, this is all I can do now.
For now I'm happy with this method.
Offline
Updates.
I found a better way to spin up the disk (always needs administrative privileges):
sg_sat_set_features --feature=7 /dev/sdX
or
sg_sat_set_features -f 7 /dev/sdX
This command is part of sg3_utils package (usually included in standard installation of many linux distros), it sends commands via the SAT ATA PASS-THROUGH SCSI command, and the --feature=7 spins up the disk and nothing else, no need to turn off and on power up in standby via hdparm.
I searched for weeks a simple solution like that, I was modifying hdparm source code... and it was really that easy.
A note for UEFI motherboards: I used few UEFI mobos, and it seems they do not support PUIS, or better, they spin up the disk before the grub screen appears. But, if I have two disks connected, one PUIS disabled and one PUIS enabled, the disk with PUIS disabled spins up right away when I press the power button, the disk with PUIS enabled spins up right before grub screen. However, the result is the disk spinning up anyway.
A simple workaround is using a PCI-ex sata controller: I used one of these little cards, with Asmedia 1060 controller and it works, meaning the disks do not spin up until I send the command. I know these cards usually have limited bandwith beacuse they use PCI-ex 1x 2.0 slots, but they're cheap and if you have to use just one or two disks they're ok.
Offline
If we can't avoid patching libata, might as well disable PUIS drives on boot to get rid of endless error messages. The downside is we've to tell the kernel to re-enable them on request, since userspace tools like sg_sat* expect an entry inside /dev.
Take a look at my tentative patch for that feature. I hope someone will consider sparing his time to rework it to kernel standards and propose it upstream. I wrote the patch against clean v4.19.56.
Remember to set "libata.spinup_control=0" kernel parameter in the bootloader after recompiling the module and rebuilding your initramfs image!
Then you should
echo 1 > /sys/module/libata/parameters/spinup_control
and issue a rescan to the drive you want to spin up.
echo '- - -' > devices/pci0000:00/0000:00:1f.2/ata4/host3/scsi_host/host3/scan
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -171,6 +171,10 @@ static int atapi_an;
module_param(atapi_an, int, 0444);
MODULE_PARM_DESC(atapi_an, "Enable ATAPI AN media presence notification (0=0ff [default], 1=on)");
+static int spinup_control = 1;
+module_param(spinup_control, int, 0644);
+MODULE_PARM_DESC(spinup_control, "Spin up standby drives (0=PUIS drives disabled, 1=standby drives can spin up [default])");
+
MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("Library module for ATA devices");
MODULE_LICENSE("GPL");
@@ -1978,28 +1982,40 @@ retry:
goto err_out;
}
- if (!tried_spinup && (id[2] == 0x37c8 || id[2] == 0x738c)) {
+ /*
+ * My drives indicate with 0x738c that media is ready when PUIS
+ * is enabled, in conflict with the relevant standards.
+ * The compliant behavior therefore prevents spun-up and ready
+ * drives from being recognized on reboot.
+ * I had no choice but to remove "|| id[2] == 0x738c))".
+ */
+ if (!tried_spinup && (id[2] == 0x37c8)) {
tried_spinup = 1;
/*
* Drive powered-up in standby mode, and requires a specific
* SET_FEATURES spin-up subcommand before it will accept
* anything other than the original IDENTIFY command.
*/
- err_mask = ata_dev_set_feature(dev, SETFEATURES_SPINUP, 0);
- if (err_mask && id[2] != 0x738c) {
- rc = -EIO;
- reason = "SPINUP failed";
- goto err_out;
- }
- /*
- * If the drive initially returned incomplete IDENTIFY info,
- * we now must reissue the IDENTIFY command.
- */
- if (id[2] == 0x37c8)
+ if (spinup_control) {
+ err_mask = ata_dev_set_feature(dev, SETFEATURES_SPINUP, 0);
+ if (err_mask) {
+ rc = -EIO;
+ reason = "SPINUP failed";
+ goto err_out;
+ }
+ /*
+ * If the drive initially returned incomplete IDENTIFY info,
+ * we now must reissue the IDENTIFY command.
+ */
goto retry;
+ } else {
+ dev->horkage |= ATA_HORKAGE_DISABLE;
+ ata_dev_notice(dev, "horkage modified (drive powered-up in standby)\n");
+ }
}
- if ((flags & ATA_READID_POSTRESET) &&
+ if (spinup_control && (flags & ATA_READID_POSTRESET) &&
(class == ATA_DEV_ATA || class == ATA_DEV_ZAC)) {
/*
* The exact sequence expected by certain pre-ATA4 drives is:
Mods (seth and WorMzy): cut the gaslighting. Implement the "sage" button for old threads. BS security claims shouldn't show up on the Web unchallenged. Enabling BS and silencing the right solutions is a very low life tactic. My post was abiding by the CoC, and offered steps on network security that isn't reliant on archaic non-solutions.
Offline
Thanks for the patch!
In the meantime I used a hardware solution: I attached a few pushbuttons to the HD wires, so I can switch them on and off through them, connected the pushbuttons to a programmable microcontroller, so I can switch them on and off via usb, using a command line to program the microcontroller.
I hope this patch makes his way upstream: I tried to write a similar one myself, without success, and it looks exaclty like what I had in mind!
Offline