Configure Advanced Power Management features on removable hard drives.

Ad hoc operations

Install hdparm utility to alter SATA/IDE device parameters.

$ sudo apt install hdparm
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  powermgmt-base
The following NEW packages will be installed:
  hdparm powermgmt-base
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 120 kB of archives.
After this operation, 280 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://deb.debian.org/debian bullseye/main arm64 hdparm arm64 9.60+ds-1 [110 kB]
Get:2 http://deb.debian.org/debian bullseye/main arm64 powermgmt-base all 1.36 [9,604 B]
Fetched 120 kB in 0s (452 kB/s)           
Selecting previously unselected package hdparm.
(Reading database ... 35576 files and directories currently installed.)
Preparing to unpack .../hdparm_9.60+ds-1_arm64.deb ...
Unpacking hdparm (9.60+ds-1) ...
Selecting previously unselected package powermgmt-base.
Preparing to unpack .../powermgmt-base_1.36_all.deb ...
Unpacking powermgmt-base (1.36) ...
Setting up powermgmt-base (1.36) ...
Setting up hdparm (9.60+ds-1) ...
Processing triggers for man-db (2.9.4-2) ...

Connect removable hard drive.

$ dmesg
[...]
[ 3039.380633] usb 2-1: new SuperSpeed USB device number 2 using xhci_hcd
[ 3039.401686] usb 2-1: New USB device found, idVendor=125f, idProduct=a35a, bcdDevice= 1.00
[ 3039.401713] usb 2-1: New USB device strings: Mfr=2, Product=3, SerialNumber=1
[ 3039.401730] usb 2-1: Product: HD650
[ 3039.401744] usb 2-1: Manufacturer: ADATA
[ 3039.401757] usb 2-1: SerialNumber: 4810358C3023
[ 3039.419479] scsi host0: uas
[ 3039.421405] scsi 0:0:0:0: Direct-Access     ADATA    HD650            0    PQ: 0 ANSI: 6
[ 3039.424750] sd 0:0:0:0: [sda] Spinning up disk...
[ 3039.509260] sd 0:0:0:0: Attached scsi generic sg0 type 0
[ 3040.448174] ....ready
[ 3043.548454] sd 0:0:0:0: [sda] 3907029168 512-byte logical blocks: (2.00 TB/1.82 TiB)
[ 3043.548465] sd 0:0:0:0: [sda] 4096-byte physical blocks
[ 3043.548611] sd 0:0:0:0: [sda] Write Protect is off
[ 3043.548618] sd 0:0:0:0: [sda] Mode Sense: 43 00 00 00
[ 3043.548824] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[ 3043.549403] sd 0:0:0:0: [sda] Optimal transfer size 33553920 bytes not a multiple of physical block size (4096 bytes)
[ 3043.851908]  sda: sda1
[ 3043.853299] sd 0:0:0:0: [sda] Attached SCSI disk

Display device identification data directly from the drive.

$ sudo hdparm -I /dev/sda
/dev/sda:

ATA device, with non-removable media
	Model Number:       ST2000LM007-1R8174                      
	Serial Number:      ZDZ19YVM
	Firmware Revision:  SBK2    
	Transport:          Serial, ATA8-AST, SATA 1.0a, SATA II Extensions, SATA Rev 2.5, SATA Rev 2.6, SATA Rev 3.0
Standards:
	Used: unknown (minor revision code 0x001f) 
	Supported: 10 9 8 7 6 5 
	Likely used: 10
Configuration:
	Logical		max	current
	cylinders	16383	16383
	heads		16	16
	sectors/track	63	63
	--
	CHS current addressable sectors:    16514064
	LBA    user addressable sectors:   268435455
	LBA48  user addressable sectors:  3907029168
	Logical  Sector size:                   512 bytes
	Physical Sector size:                  4096 bytes
	Logical Sector-0 offset:                  0 bytes
	device size with M = 1024*1024:     1907729 MBytes
	device size with M = 1000*1000:     2000398 MBytes (2000 GB)
	cache/buffer size  = unknown
	Form Factor: 2.5 inch
	Nominal Media Rotation Rate: 5400
Capabilities:
	LBA, IORDY(can be disabled)
	Queue depth: 32
	Standby timer values: spec'd by Standard, no device specific minimum
	R/W multiple sector transfer: Max = 16	Current = 16
	Advanced power management level: 128
	Recommended acoustic management value: 208, current value: 208
	DMA: mdma0 mdma1 mdma2 udma0 udma1 udma2 udma3 udma4 udma5 *udma6 
	     Cycle time: min=120ns recommended=120ns
	PIO: pio0 pio1 pio2 pio3 pio4 
	     Cycle time: no flow control=120ns  IORDY flow control=120ns
Commands/features:
	Enabled	Supported:
	   *	SMART feature set
	    	Security Mode feature set
	   *	Power Management feature set
	   *	Write cache
	   *	Look-ahead
	   *	Host Protected Area feature set
	   *	WRITE_BUFFER command
	   *	READ_BUFFER command
	   *	NOP cmd
	   *	DOWNLOAD_MICROCODE
	   *	Advanced Power Management feature set
	    	Power-Up In Standby feature set
	   *	SET_FEATURES required to spinup after power up
	    	SET_MAX security extension
	   *	48-bit Address feature set
	   *	Device Configuration Overlay feature set
	   *	Mandatory FLUSH_CACHE
	   *	FLUSH_CACHE_EXT
	   *	SMART error logging
	   *	SMART self-test
	   *	General Purpose Logging feature set
	   *	WRITE_{DMA|MULTIPLE}_FUA_EXT
	   *	64-bit World wide name
	   *	IDLE_IMMEDIATE with UNLOAD
	    	Write-Read-Verify feature set
	   *	WRITE_UNCORRECTABLE_EXT command
	   *	{READ,WRITE}_DMA_EXT_GPL commands
	   *	Segmented DOWNLOAD_MICROCODE
	   *	Gen1 signaling speed (1.5Gb/s)
	   *	Gen2 signaling speed (3.0Gb/s)
	   *	Gen3 signaling speed (6.0Gb/s)
	   *	Native Command Queueing (NCQ)
	   *	Host-initiated interface power management
	   *	Phy event counters
	   *	Idle-Unload when NCQ is active
	   *	READ_LOG_DMA_EXT equivalent to READ_LOG_EXT
	    	DMA Setup Auto-Activate optimization
	    	Device-initiated interface power management
	    	Asynchronous notification (eg. media change)
	   *	Software settings preservation
	   *	SMART Command Transport (SCT) feature set
	   *	SCT Write Same (AC2)
	   *	SCT Features Control (AC4)
	   *	SCT Data Tables (AC5)
	    	unknown 206[12] (vendor specific)
	    	unknown 206[13] (vendor specific)
	   *	DOWNLOAD MICROCODE DMA command
Security: 
	Master password revision code = 65534
		supported
	not	enabled
	not	locked
	not	frozen
	not	expired: security count
		supported: enhanced erase
	332min for SECURITY ERASE UNIT. 332min for ENHANCED SECURITY ERASE UNIT.
Logical Unit WWN Device Identifier: 5000c500a57ae4f3
	NAA		: 5
	IEEE OUI	: 000c50
	Unique ID	: 0a57ae4f3
Checksum: correct

Check current drive state.

$ sudo hdparm -C /dev/sda
/dev/sda:
 drive state is:  active/idle

Determine current Advanced Power Management level.

According to the ATA/ATAPI Command Set – 2 (ACS-2) you can use values like 1 for minimum power consumption, 2 to 127 for intermediate power consumption using standby mode, 128 to 253 for intermediate power consumption without using standby mode, and 254 for maximum performance.

$ sudo hdparm -B /dev/sda
/dev/sda:
 APM_level	= 254

Define intermediate power consumption using standby mode.

$ sudo hdparm -B 127 /dev/sda
/dev/sda:
 setting Advanced Power Management level to 0x7f (127)
 APM_level	= 127

After internally predefined time period of inactivity device will enter standby mode (spin down).

$ sudo hdparm -C /dev/sda
/dev/sda:
 drive state is:  standby

Define standby (spin off) timer with works independently of the Advanced Power Management configuration.

Use value between 1 to 240 to define timer using a 5 second scale (5 seconds to 20 minutes), and 241 to 251 using a 30 minute scale (30 minutes to 5 hours and 30 minutes), 252 for 21 minutes, 253 for vendor specific value (between 8 to 12 hours), and 255 for 21 minutes 15 seconds.

$ sudo hdparm -S 120 /dev/sda
/dev/sda:
 setting standby to 120 (10 minutes)

These changes are not permanent and will remain in effect until hard drive is disconnected or operating system restarted.

Permanent solution

Inspect default hdparm configuration as you can use it to permanently store modifications.

$ cat /etc/hdparm.conf 
## This is the default configuration for hdparm for Debian.
## Any line that begins with a comment is ignored - add as many as you
## like.  Note that an in-line comment is not supported.  If a line
## consists of whitespace only (tabs, spaces, carriage return), it will be
## ignored, so you can space control fields as you like.  ANYTHING ELSE
## IS PARSED!!  This means that lines with stray characters or lines that
## use non # comment characters will be interpreted by the helper scripts (
## /lib/udev/hdparm, /usr/lib/pm-utils/power.d/95hdparm-apm ).
## This has probably minor, but potentially serious, side effects for your
## hard drives, so please follow the guidelines.  Patches to improve
## flexibilty welcome.  Please read /usr/share/doc/hdparm/README.Debian for
## notes about known issues, especially if you have an MD array.
##
## Note that if the init script causes boot problems, you can pass 'nohdparm'
## on the kernel command line, and hdparm will not run.
##
## Uncommenting the options below will cause them to be added to the DEFAULT
## string which is prepended to options listed in the blocks below.
##
## If an option is listed twice, the second instance replaces the first.
##
## /sbin/hdparm parses blocks of the form:
##      DEV {
##         option
##         option
##         ...
##      }
## This blocks will cause /sbin/hdparm OPTIONS DEV to be run.
## Where OPTIONS is the concatenation of all options previously defined
## outside of a block and all options defined with in the block.

# -q be quiet
quiet
# -a sector count for filesystem read-ahead
#read_ahead_sect = 12
# -A disable/enable the IDE drive's read-lookahead feature
#lookahead = on
# -b bus state
#bus = on
# -B apm setting
#apm = 255
# -B apm setting when on battery
#apm_battery = 127
# -c enable (E)IDE 32-bit I/O support - can be any of 0,1,3
#io32_support = 1
# -d disable/enable the "using_dma" flag for this drive
#dma = off
# -D enable/disable the on-drive defect management
#defect_mana = off
# -E cdrom speed
#cd_speed = 16
# -k disable/enable the "keep_settings_over_reset" flag for this drive
#keep_settings_over_reset = off
# -K disable/enable the drive's "keep_features_over_reset" flag
#keep_features_over_reset = on
# -m sector count for multiple sector I/O
#mult_sect_io = 32
# -P maximum sector count for the drive's internal prefetch mechanism
#prefetch_sect = 12
# -r read-only flag for device
#read_only = off
# -R Enable/Disable Write-Read-Verify, on to enable (R1), off to disable (R0)
# write_read_verify = off
# -s Turn on/off power on in standby mode
# poweron_standby = off
# -S standby (spindown) timeout for the drive
#spindown_time = 24
# "force_spindown_time" - the same as "-S", but will be applied even if disk
# doesn't support APM. Use on your own risk. This is debian specific option.
# See also #758988
#force_spindown_time = 24
# -u interrupt-unmask flag for the drive
#interrupt_unmask = on
# -W Disable/enable the IDE drive's write-caching feature
#write_cache = off
# -X IDE transfer mode for newer (E)IDE/ATA2 drives
#transfer_mode = 34
# -y force to immediately enter the standby mode
#standby
# -Y force to immediately enter the sleep mode
#sleep
# -Z Disable the power-saving function of certain Seagate drives
#disable_seagate
# -M Set the acoustic management properties of a drive
#acoustic_management
# -p Set the chipset PIO mode
# chipset_pio_mode
# --security-freeze Freeze the drive's security status
# security_freeze
# --security-unlock Unlock the drive's security
# security_unlock = PWD
# --security-set-pass Set security password
# security_pass = password
# --security-disable Disable drive locking
# security_disable
# --user-master Select password to use
# user-master = u
# --security-mode Set the security mode
# security_mode = h

## Blocks beginning with the keyword 'command_line' instead of a device
## identifier are not supported since the version 9.39-1 for backward
## compatibility by this version of hdparm. Options must be introduced
## by a correct device identifier instead, so that they will be applied
## when the device becomes available.

# Config examples:

#/dev/hda {
#	mult_sect_io = 16
#	write_cache = off
#	dma = on
#}

#/dev/disk/by-id/ata-WDC_WD10EFRX-68PJCN0_WD-WCC4J0998391 {
#        apm = 128
#        acoustic_management = 128
#        spindown_time = 240
#}

#/dev/cdroms/cdrom0 {
#	dma = on
#	interrupt_unmask = on
#	io32_support = 0
#}

Find path to the specific hard drive that uniquely identifies it.

$ find /dev/disk/ -follow -samefile /dev/sda
/dev/disk/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1:1.0-scsi-0:0:0:0
/dev/disk/by-id/wwn-0x5000c500a57ae4f3
/dev/disk/by-id/ata-ST2000LM007-1R8174_ZDZ19YVM

Use unique path to alter its default configuration.

$ sudo tee --append /etc/hdparm.conf << EOF

# ata-ST2000LM007-1R8174_ZDZ19YVM
/dev/disk/by-id/ata-ST2000LM007-1R8174_ZDZ19YVM {
        apm = 127
        spindown_time = 120
}
EOF
# ata-ST2000LM007-1R8174_ZDZ19YVM
/dev/disk/by-id/ata-ST2000LM007-1R8174_ZDZ19YVM {
        apm = 127
        spindown_time = 120
}
EOF

How changes are applied

Configuration is applied by the device event managing daemon.

$ udevadm test /block/sda
This program is for debugging only, it does not run any program
specified by a RUN key. It may show incorrect results, because
some values may be different, or not available at a simulation run.

Load module index
Skipping empty file: /etc/systemd/network/99-default.link
Skipping empty file: /etc/systemd/network/73-usb-net-by-mac.link
Created link configuration context.
Reading rules file: /usr/lib/udev/rules.d/10-local-rpi.rules
Reading rules file: /usr/lib/udev/rules.d/15-i2c-modprobe.rules
Reading rules file: /usr/lib/udev/rules.d/40-usb_modeswitch.rules
Reading rules file: /usr/lib/udev/rules.d/50-firmware.rules
Reading rules file: /usr/lib/udev/rules.d/50-udev-default.rules
Reading rules file: /usr/lib/udev/rules.d/55-dm.rules
Reading rules file: /usr/lib/udev/rules.d/60-autosuspend.rules
Reading rules file: /usr/lib/udev/rules.d/60-block.rules
Reading rules file: /usr/lib/udev/rules.d/60-cdrom_id.rules
Reading rules file: /usr/lib/udev/rules.d/60-crda.rules
Reading rules file: /usr/lib/udev/rules.d/60-drm.rules
Reading rules file: /usr/lib/udev/rules.d/60-evdev.rules
Reading rules file: /usr/lib/udev/rules.d/60-fido-id.rules
Reading rules file: /usr/lib/udev/rules.d/60-flashrom.rules
Reading rules file: /usr/lib/udev/rules.d/60-input-id.rules
Reading rules file: /usr/lib/udev/rules.d/60-persistent-alsa.rules
Reading rules file: /usr/lib/udev/rules.d/60-persistent-input.rules
Reading rules file: /usr/lib/udev/rules.d/60-persistent-storage-dm.rules
Reading rules file: /usr/lib/udev/rules.d/60-persistent-storage-tape.rules
Reading rules file: /usr/lib/udev/rules.d/60-persistent-storage.rules
Reading rules file: /usr/lib/udev/rules.d/60-persistent-v4l.rules
Reading rules file: /usr/lib/udev/rules.d/60-rpi.gpio-common.rules
Reading rules file: /usr/lib/udev/rules.d/60-sensor.rules
Reading rules file: /usr/lib/udev/rules.d/60-serial.rules
Reading rules file: /usr/lib/udev/rules.d/60-triggerhappy.rules
Reading rules file: /usr/lib/udev/rules.d/64-btrfs.rules
Reading rules file: /usr/lib/udev/rules.d/69-libmtp.rules
Reading rules file: /usr/lib/udev/rules.d/70-joystick.rules
Reading rules file: /usr/lib/udev/rules.d/70-microbit.rules
Reading rules file: /usr/lib/udev/rules.d/70-mouse.rules
Reading rules file: /usr/lib/udev/rules.d/70-power-switch.rules
Reading rules file: /usr/lib/udev/rules.d/70-touchpad.rules
Reading rules file: /usr/lib/udev/rules.d/70-uaccess.rules
Reading rules file: /usr/lib/udev/rules.d/71-seat.rules
Reading rules file: /usr/lib/udev/rules.d/73-seat-late.rules
Reading rules file: /usr/lib/udev/rules.d/73-special-net-names.rules
Reading rules file: /usr/lib/udev/rules.d/75-net-description.rules
Reading rules file: /usr/lib/udev/rules.d/75-probe_mtd.rules
Reading rules file: /usr/lib/udev/rules.d/78-sound-card.rules
Reading rules file: /usr/lib/udev/rules.d/80-debian-compat.rules
Reading rules file: /usr/lib/udev/rules.d/80-drivers.rules
Reading rules file: /usr/lib/udev/rules.d/80-ifupdown.rules
Reading rules file: /usr/lib/udev/rules.d/80-net-setup-link.rules
Reading rules file: /usr/lib/udev/rules.d/80-noobs.rules
Reading rules file: /usr/lib/udev/rules.d/80-udisks2.rules
Reading rules file: /usr/lib/udev/rules.d/85-hdparm.rules
Reading rules file: /usr/lib/udev/rules.d/85-hwclock.rules
Reading rules file: /usr/lib/udev/rules.d/85-regulatory.rules
Reading rules file: /usr/lib/udev/rules.d/90-alsa-restore.rules
Reading rules file: /usr/lib/udev/rules.d/90-console-setup.rules
Reading rules file: /usr/lib/udev/rules.d/90-pi-bluetooth.rules
Reading rules file: /usr/lib/udev/rules.d/95-dm-notify.rules
Reading rules file: /usr/lib/udev/rules.d/96-e2scrub.rules
Reading rules file: /usr/lib/udev/rules.d/97-hid2hci.rules
Reading rules file: /etc/udev/rules.d/99-com.rules
Reading rules file: /usr/lib/udev/rules.d/99-systemd.rules
DEVPATH=/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb2/2-1/2-1:1.0/host0/target0:0:0/0:0:0:0/block/sda
DEVNAME=/dev/sda
DEVTYPE=disk
DISKSEQ=28
MAJOR=8
MINOR=0
ACTION=add
SUBSYSTEM=block
TAGS=:systemd:
ID_VENDOR=ADATA
ID_VENDOR_ENC=ADATA\x20\x20\x20
ID_VENDOR_ID=125f
ID_MODEL=HD650
ID_MODEL_ENC=HD650\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
ID_MODEL_ID=a35a
ID_REVISION=0
ID_SERIAL=ADATA_HD650_4810358C3023-0:0
ID_SERIAL_SHORT=4810358C3023
ID_TYPE=disk
ID_INSTANCE=0:0
ID_BUS=usb
ID_USB_INTERFACES=:080650:080662:
ID_USB_INTERFACE_NUM=00
ID_USB_DRIVER=uas
DEVLINKS=/dev/disk/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1:1.0-scsi-0:0:0:0 /dev/disk/by-id/usb-ADATA_HD650_4810358C3023-0:0
ID_PATH=platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1:1.0-scsi-0:0:0:0
ID_PATH_TAG=platform-fd500000_pcie-pci-0000_01_00_0-usb-0_1_1_0-scsi-0_0_0_0
CURRENT_TAGS=:systemd:
run: '/lib/udev/hdparm'
Unload module index
Unloaded link configuration context.

Inspect /usr/lib/udev/rules.d/85-hdparm.rules rule definition, /usr/lib/udev/hdparm and /usr/lib/pm-utils/power.d/95hdparm-apm shell script for more details.