Package: hddtemp
Version: 0.3-beta15-52+b1
Severity: normal
Tags: patch upstream

Hello,

Some of my (older) WD Reds kept waking up from standby when checking
temperatures with hddtemp. At the same time smartctl didn't wake them up.
I traced the problem down to the SMART enabling code which is ran on
every hddtemp execution, even if SMART is already enabled.
It is assumed to be a no-op in such cases but apparently it's not for some
(sleeping) drives.

Attached patch adds check for current state of ENABLE SMART flag and calls
enable command only if needed.

Best Regards,
Jacek

-- System Information:
Debian Release: 9.8
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 4.9.0-8-amd64 (SMP w/2 CPU cores)
Locale: LANG=pl_PL.UTF-8, LC_CTYPE=pl_PL.UTF-8 (charmap=UTF-8), 
LANGUAGE=pl_PL.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages hddtemp depends on:
ii  debconf [debconf-2.0]  1.5.61
ii  libc6                  2.24-11+deb9u4
ii  lsb-base               9.20161125

hddtemp recommends no packages.

Versions of packages hddtemp suggests:
pn  ksensors  <none>

-- Configuration Files:
/etc/hddtemp.db changed [not included]

-- debconf information excluded
diff -ru hddtemp-0.3-beta15/src/sata.c hddtemp-0.3-beta15-skz/src/sata.c
--- hddtemp-0.3-beta15/src/sata.c       2019-03-18 23:56:57.000000000 +0100
+++ hddtemp-0.3-beta15-skz/src/sata.c   2019-03-19 00:01:00.388342505 +0100
@@ -93,6 +93,24 @@
   }
 }
 
+static int sata_is_smart_enabled (int device) {
+  unsigned char cmd[4] = { WIN_IDENTIFY, 0, 0, 1 };
+  unsigned char identify[512];
+
+  if(device != -1 && sata_pass_thru(device, cmd, identify) == 0)
+  {
+    // "If bit 14 of word 87 is set to one and bit 15 of word 87 is 
+    // cleared to zero, the contents of words 85-87 contain valid information."
+    if ((identify[87*2+1]>>(14-8)) != 0x01)
+      return -1;
+    // "If bit 0 of word 85 is set to one, the SMART feature set has been
+    // enabled via the SMART ENABLE OPERATIONS command."
+    return identify[85*2] & 0x01;
+  }
+
+  return -1;
+}
+
 static unsigned char* sata_search_temperature(const unsigned char* smart_data, 
int attribute_id) {
   int i, n;
 
@@ -136,7 +154,7 @@
   }
   
   /* get SMART values */
-  if(sata_enable_smart(dsk->fd) != 0) {
+  if(sata_is_smart_enabled(dsk->fd) != 1 && sata_enable_smart(dsk->fd) != 0) {
     enum e_gettemp ret;
     if(errno == EIO) {
       snprintf(dsk->errormsg, MAX_ERRORMSG_SIZE, _("S.M.A.R.T. not 
available"));

Reply via email to