Force spin-down of external hard-drive on linux (raspberry pi)

Yes, it is possible but will require some custom development work and not trivial and the code is going to be specific to the USB->SATA bridge chip INSIDE of your enclosure.

The deal is that the USB bridge serves as more than an electrical convertor. A USB-attached HDD emulates a SCSI drive which has a different command set. While the standard read/write/seek commands translate all the time the more exotic spin up/down do not. Most chips won't do that. Furthermore there is NOT a universal chip level API. So If I wrote the code I would have to have a programming manual for the USB bridge chip.

Bottom line, unless you have programming specifics on the chip and are familiar with the ATA and SCSI instruction set and encapsulating pass-through commands, then you're just going to have to do without. Too much work and no standard.


It is entirely possible that the signals you are sending are neglected. You did not provide the output of

sudo hdparm -I /dev/sdX

which would have told us the disk capabilities, but many disks simply do not respond to these commands.

Luckily, there is a very convenient utility, hd-idle, which you can download from here, allowing you to force a disk spin down after some specified lapse of time. The program has been developed especially for Debian, (but it works on Linux in general), so that its installation should be very easy to you. I just hope it also works on an ARM architecture, something which I cannot test.

Edit: it compiles and installs correctly on raspbian.


I didn't have luck with hd-idle; it ran but didn't function. I ended up writing the script below:

#!/bin/bash
# This script looks for recent disk access, and if nothing has changed, puts /dev/"drive" into spindown mode.
# This should be used only is the hdparm power management function is not working.
# Call this script with cron or manually as desired
#
#
#
# Change which drive this script looks at by changing the drive variable below:
drive="sda"
#
#
current=`date`
caller=$(ps ax | grep "^ *$PPID" | awk '{print $NF}')
filename="/tmp/diskaccess.txt"
if [ -f "$filename" ]; then
    stat_old=`cat "$filename" | tr -dc "[:digit:]"`
    stat_new=`cat /sys/block/"$drive"/stat | tr -dc "[:digit:]"`
    if [ "$stat_old" == "$stat_new" ]; then
        stat="0"
        echo "The disk hasn't been used; spinning down /dev/$drive"
        echo $stat_old
        hdparm -y /dev/$drive > /dev/null
    else
        stat="1"
        echo $stat_old
        echo $stat_new
        echo "The drive has been used..."
        echo $stat_new > $filename
    fi
else
    echo "/tmp/diskaccess.txt file does not exist; creating it now."
    echo $stat_new > $filename
fi
echo $stat " - " $drive " - " $current " - by: " $caller >> /tmp/diskaccesslog.txt