10

On my Linux Mint 17.1 system I am using a Western Digital WD20EZRX HDD for backup. To minimize power consumption and to extend drive endurance, I want the HDD to normally be in spun-down standby state, and to only spin up when explicitly needed.

This can be achieved in two ways: The trivial approach would be setting the HDD into standby mode manually using hdparm -y /dev/sdb. However, the disadvantage would be the drive spinning up during startup until being set to sleep again by a script. Therefore I would like to let the drive Power-Up in Standby, PUIS, to prevent it from spinnung up in the first time.

Some WD drives support PUIS, although it is called PM2, Power Management 2 Mode by Western Digital. This feature is being enabled using Jumpers, as described in this WD Knowledge Base article. The result of this configuration can be verified using hdparm:

# hdparm -I /dev/sdb | grep "Power-Up In Standby"
   *    Power-Up In Standby feature set

However, the drive still spins up during boot, even before the Grub startup-screen is being displayed. Could this be a misconfigured Bootloader, which is looking for operating systems on all connected HDDs?

6
  • PUIS doesn't prevent the HDD from powering up initially, but the HDD will go to sleep when not in use, and the OS needs to know to power the HDD back on otherwise it will simulate a drive failure, and the OS hang up waiting on a file that will never come. I'm not certain of the exact details, just that initially it acts like it's not on even when it is. Also you can set this as a flag on the HDD, it doesn't just work via jumpers.
    – jfa
    Oct 28, 2016 at 19:55
  • It's probably implied by all involved parties in this QA, but it's becoming confusing so to clear this up. PUIS is a feature to allow staged powering up of drives. A server (or PC) with drives in PUIS mode will power on with such drives in stand-by,not spinning. Then BIOS,FW or kernel will issue commands to these drives to start spinning. If one of those does not support this feature,drives will fail to start.This QA and many others on internet are exploring possibility to use this feature to avoid initial spinning up of drive after waking up from sleep.Something it was not initially meant for
    – papo
    Dec 13, 2020 at 19:11
  • Interestingly by NAS does write to kernel log: Spinning up drive 0, 1, 2 ... So I went on and enabled PUIS on all drives. They failed to start on next boot. Both Samsung and WD. I booted PartedMagic then from UFD and they did start during boot to it. Didn't bother to investigate or try to fix it, as half of my drives use external power anyway. (no extra load on start on one) Just to consider how badly supported is this feature.
    – papo
    Dec 13, 2020 at 19:18
  • @jfa, you just contradicted yourself. First you said it only has the drive to go sleep when not in use, rather than not start at power on ( which is exactly what it does ). Then you said the OS needs to know how to tell it to turn on.
    – psusi
    Oct 14, 2023 at 16:37
  • 1
    @papo, I used to use PuiS exactly for keeping the drive from spinning up every time I resume from sleep. I had some kernel patches to allow it about a decade ago that I never got accepted upstream. I'm working on reviving them now and trying again.
    – psusi
    Oct 14, 2023 at 16:38

2 Answers 2

3

I searched for the exact thing a few years ago, for Linux Mint and an old HD that was only used for occasional data storage too.

The solutions I found (don't have the links handy anymore) were the same that it looks like you found: a few hard drives might have a jumper setting that should cause the drive to stay sleeping / not spin up at boot time. But it did not work, my results were the exact same as yours, it still spins up at boot. I didn't find any fixes for that, for all I know it was the BIOS/GRUB/linux, separately or working together, or just the HD itself that wasn't listening.

I did some "hot plug"/"hot swap" testing, connecting the power to a (SATA) hard drive while the computer was up & running. It generated some log entries (dmesg & /var/log/syslog) and worked successfully. Then when done with the drive (sync, unmount, sleep/hdparm -y) unplugging the power again. Worked! But it apparently needs a compatible motherboard & OS, so YMMV.

However, pulling the power plug to use the drive isn't very convenient or easy, so I wired up a double-pole single-throw switch - DPST, Wikipedia has a diagram - has 4 terminals, for the 2 separate power wires (12V & 5V?), to keep them separate and turn them both on/off at the same time. Connecting it to the HD's power, I can turn on & off the drive whenever needed.

Update:

Hot swapping used to work on Linux Mint 14/15/16, but for some reason it quit working on 17 & up, I'm guessing some kernel change stopped it. Now hot swapping a hard drive on only appears to work, but the drive reads as corrupted, only a power-on reboot gets it working successfully. Maybe there's an easy way to get it working again, or some recompiled kernel is required with some special switches...?

Update 2

Hot swapping is apparently working again for Ubuntu 16.04 (Mint 18 should work too).

2
  • 1
    When you want to hot unplug the drive, you should ( as root ) echo 1 > /sys/block/sdXX/device/delete. This tells the scsi disk driver to put the drive to sleep and unbind from it. That way you wont get a bunch of errors when you yank the drive out and the kernel notices it's disappeared.
    – psusi
    Oct 14, 2023 at 16:42
  • @psusi Interesting thanks! Do you know if there's a way to reverse the delete and "reset" the drive? I've been wondering for years if "resetting" a usb drive using something similar would be possible
    – Xen2050
    Nov 27, 2023 at 8:48
7

The linux kernel spins up the drive. Take a look at these lines from drivers/ata/libata-core.c (kernel source code):

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;
}

If you comment these lines and recompile the kernel, the drives will not spin up. Then you'll need a command to spin them up, for example when hdparm disables PUIS it spins up the drive. Take a look at this link.

That's all I know about PUIS.

Edit: I just noticed that your drive spins up before the grub screen: this means the motherboard is spinning up the drive. You can try disabling the corresponding sata port in your BIOS/UEFI configuration, if it allows such a thing, and try again. If it's working, the drive will remain still until the kernel spins it up, after the grub screen and before the user login prompt, and you can find in dmesg

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)

At this point, if you hack the kernel, the drive will not spin up at all like I described earlier.

Edit 2: I found a better command to spin up the disk:

sg_sat_set_features --feature=7 /dev/sdX

it's part of the sg3_utils package, requires root privileges, but spins up the disk nicely. Post updated on the arch linux forum, that's my final solution for now. A small summary of that post:

  • if your PUIS enabled disk spins up before boot loader screen, try disabling the corresponding sata port, or try a PCI-ex sata controller card
  • recompile the kernel to disable the command that spins up the disks in PUIS state
  • use sg_sat_set_feature to spin up the disk
  • rescan sata port to gain access to partitions

Edit 3: Some kind soul wrote a patch, on the archlinux forum: https://bbs.archlinux.org/viewtopic.php?pid=1855326#p1855326

Transcription:

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:

Credit to az12shareart, who registerd to arch linux forum just to write this, I think.

5
  • this is very informative. What I'd like to do is have a headless Linux server that use as a NAS, but that will go into S3 standby mode and upon waking up not spin up the hard drives. Your suggestions can likely get me that far. But then I'd like the system to spin up the drive when it's actually accessed without needing to manually issue that sg_sat_set_features command. But do so automatically on demand. Any suggestions? Thanks. Apr 6, 2018 at 15:27
  • This looks like it could work on a laptop, but might be more trouble than it's worth...
    – Michael
    Jul 7, 2018 at 17:26
  • Thank you a lot for doing the real work and digging this out! I referred to your answer in my answer: unix.stackexchange.com/questions/129454/…
    – anon
    Apr 16, 2023 at 14:35
  • 1
    By the way: This REALLY should be turned into a proper patch and submitted to kernel.org / Torvalds or something. (Like, with a kernel init parameter and/or /sys switch.)
    – anon
    Apr 16, 2023 at 14:40
  • 1
    @Michael: if anyone is wondering: It works fine on my laptop. (At least with my modifications.) But kernel patching is unusually easy on Gentoo. (I just had to drop the .patch file in the correct directory, and the build system would pick it up automatically on kernel updates.)
    – anon
    Apr 16, 2023 at 14:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .