2

Is there a "programmatic" way to determine whether a disk is spinning or not (spinning, not necessarily reading/writing)?

  • It's always spinning unless it's sleeping. Check if the drive is sleeping perhaps? – Ƭᴇcʜιᴇ007 Feb 22 '14 at 23:29
  • I don't see anything in the SMART attributes. There may be a way, but it would depend on the specific drive and controller. You would have to read the specifications to find out if it is possible. I seem to remember some old drives that had a bit that would be on for spinning. – cliff2310 Feb 23 '14 at 0:15
0

Whether a disk is spinning depends on its power mode; typically the spindle motor will be running in “Active” and “Idle” modes, and stopped in “Standby” and “Sleep” modes. (It gets a bit more complicated with drives with NV cache power management, which I don’t know enough about to cover here.)

If a drive is asleep it’s definitely not spinning (or doing anything else, including communicating with the host); otherwise you can interrogate it about its current mode.

For an ATA drive, the “Check Power Mode” command will do this. Send the value E5 in the command register, and it will return FF in the sector count register if the drive is active or idle.

Doing that programatically is venturing into Stack Overflow territory, but here’s a snippet of C that will do it on Windows:

int isSpinning = -1;
HANDLE hDevice = CreateFile(TEXT("\\\\.\\PHYSICALDRIVE0"), GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if (hDevice != INVALID_HANDLE_VALUE)
{
    DWORD cb = 0;
    ATA_PASS_THROUGH_EX cmd = {sizeof(ATA_PASS_THROUGH_EX)};
    cmd.AtaFlags = ATA_FLAGS_DRDY_REQUIRED; /*  Require drive to be ready  */
    cmd.TimeOutValue = 3;                   /*  Arbitrary timeout (seconds)  */
    cmd.CurrentTaskFile[6] = 0xE5;          /*  "Check Power Mode" in command register  */
    if (DeviceIoControl(hDevice, IOCTL_ATA_PASS_THROUGH, &cmd, sizeof(cmd), &cmd, sizeof(cmd), &cb, 0))
    {
        /*  FF in sector count register means the drive is 
            active or idle (and therefore spinning)  */
        isSpinning = cmd.CurrentTaskFile[1] == 0xFF;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.