raspberrypi / linux

Kernel source tree for Raspberry Pi-provided kernel builds. Issues unrelated to the linux kernel should be posted on the community forum at https://forums.raspberrypi.com/
Other
11.12k stars 4.98k forks source link

USB reset/poweroff handling for HDD #4065

Open ElVasquito opened 3 years ago

ElVasquito commented 3 years ago

I previously used a PI3 mainly for retro gaming, so I have some little experience tinkering with it. Now I just aquired a PI4 to use it as a NAS, with a 2.5" 2TB USB3 HDD powered directly from the PI, fully updated/upgraded/dist-upgraded. I am powering the PI through the GPIO header, using pins 2+4 for +5V, 6+9 for ground, with thick and short wires (not the regular colored ones which are very thin).

Issue:

On reset or poweroff, the hard drive makes a loud clicking/rattling of the head. The "Power-Off_Retract_Count" item in the hard disk's SMART info is increasing as I poweroff/reset the PI. If I reboot or poweroff my PC or laptop with the drive connected, there's definitely no clicking, so there seems to be an issue on how the USB ports are handled on reset/poweroff of the PI3+PI4 (and maybe the older ones as well?). Originally, I had two clicks from the HDD, one right on reset (just when the screen goes blank) and another one while POSTing, I prevented this last click by adding USB_MSD_PWR_OFF_TIME=0 to the EEPROM, but for the one on reset/poweroff I haven't found anything that would prevent it. What I noticed is that when issuing the reboot/poweroff command, the OS unloads its stuff, and suddenly (while the HDD LED is still blinking rapidly) the reset occurs, like it is not giving the drive some extra time to park its heads gracefully before cutting the power to the ports. This clicking definitely shorts the lifespan of the drive's head. Is this power-reset really needed? I've seen this mentioned already, here: https://www.raspberrypi.org/forums/viewtopic.php?t=247093 but the solution was of no help to me because I am not booting from SD, so the proposed script can't be run as the HDD can't be umounted till the very end. But still, I think it is a good idea: send a sleep command to the drive after unloading the OS and just before the reset/poweroff. The sleep command will park the head normally, without the abrupt clicking. Can this be implemented somehow?

Thanks in advance for any clues!

JamesH65 commented 3 years ago

I have always found that HDD clicking is caused by a lack of power. When they start up these HDD's pull quite a bit of current - the Pi may not be able to supply enough. Try powering the device via a powered hub to test.

timg236 commented 3 years ago

There's no way to avoid the power-reset when the SOC is reset it's not under software control.

USB_MSD_PWR_OFF_TIME is there to allow the power to be disconnected for an extended period of time e.g. for devices that take time to spin up. Setting this to zero avoids the USB port power being disconnected via the XHCI controller.

A powered hub can sometimes help here because the drive will remain powered, although, the HUB SATA controller still needs to handle the upstream port power reset correctly.

ElVasquito commented 3 years ago

@JamesH65 not a power issue, the clicking only occurs on reset/poweroff

@timg236 too bad to hear that the power cycling on reset is not under software control, maybe a design flaw? I mean, no PC would click a drive's head on poweroff/reset. So maybe the actual solution is to have the possibility to send a standard sleep command to the drive right before performing the reset, when it is already off?

timg236 commented 3 years ago

You could try modifying the shutdown scripts to use hdparm to disable the drive, possibly using a RAM FS to ensure any scripts are available.

ElVasquito commented 3 years ago

Can I create a RAM FS on the shutdown script and copy the necessary files to go from there? Which files would be needed in such case and how to transfer the control to the OS over there? Or maybe the RAM FS needs to be already set up once the shutdown script executes? I am no Linux expert, can you point me in the right direction? TIA

ElVasquito commented 3 years ago

Also found this, which is on the PI2: https://discourse.osmc.tv/t/shutdown-script-for-hdd-eject/1267 How can "sudo hdparm -Y /dev/sda" be executed right at the end of the shutdown process if /dev/sda is the boot drive? The RAM FS is a possible solution but the question, again, is which files (apart from hdparm itself) would go in there so /dev/sda can be umounted before running hdparm?

ElVasquito commented 3 years ago

I created a little 1M tmpfs ramdrive on /var/ramfs and placed a copy of the hdparm binary in there. Is it then logical to call /var/ramfs/hdparm -Y /dev/sda2 && sleep 3 from /etc/init.d/udev (where exactly?), or it would crash/corrupt the shutdown process? Sorry if this is basic stuff, I'm learning.

ElVasquito commented 3 years ago

Ok, after reading more about the shutdown process, I threw out the ramdrive idea, made this script:

#!/bin/sh
hdparm -FfyY /dev/disk/by-id/usb-HGST_HTS_541010A9E680_234643131333-0:0
sleep 3
if [ "$1" = "poweroff" ]; then
    echo gpio | sudo tee /sys/class/leds/led1/trigger
    while :; do sleep 1; done
fi

And placed it in /usr/lib/systemd/system-shutdown/sleephdd.shutdown Now, the HDD goes silently to sleep and does not click anymore on reboot or poweroff, yeehaw!!! I had to differentiate the poweroff from the restart because for some reason the drive goes on again and clicks when the green LED is about to start blinking, so I stay in an endless loop and manually turn off the red LED to know it is safe to poweroff the board. I'm pretty sure this is not the cleanest way to handle this, but hey, it works. I guess some low level kernel code needs to be checked to resolve this in the right way.