Ticket #291: tempminmax-format.patch

File tempminmax-format.patch, 3.8 KB (added by Christian Franke, 11 years ago)

Patch for -v,tempminmax format. Handles negative temperatures and WDC counter.

  • atacmds.cpp

     
    19271927}
    19281928
    19291929
     1930static inline int check_temp_word(unsigned word)
     1931{
     1932  if (word <= 0x7f)
     1933    return 0x11; // >= 0, signed byte or word
     1934  if (word <= 0xff)
     1935    return 0x01; // < 0, signed byte
     1936  if (0xff80 <= word)
     1937    return 0x10; // < 0, signed word
     1938  return 0x00;
     1939}
     1940
     1941static bool check_temp_range(int t, unsigned char ut1, unsigned char ut2,
     1942                             int & lo, int & hi)
     1943{
     1944  int t1 = (signed char)ut1, t2 = (signed char)ut2;
     1945  if (t1 > t2) {
     1946    int tx = t1; t1 = t2; t2 = tx;
     1947  }
     1948
     1949  if (   -60 <= t1 && t1 <= t && t <= t2 && t2 <= 120
     1950      && !(t1 == -1 && t2 <= 0)                      ) {
     1951    lo = t1; hi = t2;
     1952    return true;
     1953  }
     1954  return false;
     1955}
     1956
    19301957// Format attribute raw value.
    19311958std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
    19321959                                      const ata_vendor_attr_defs & defs)
     
    20562083    // Temperature
    20572084    {
    20582085      // Search for possible min/max values
    2059       // 00 HH 00 LL 00 TT (Hitachi/IBM)
    2060       // 00 00 HH LL 00 TT (Maxtor, Samsung)
     2086      // [5][4][3][2][1][0] raw[]
     2087      // [ 2 ] [ 1 ] [ 0 ]  word[]
     2088      // xx HH xx LL xx TT (Hitachi/IBM)
     2089      // xx LL xx HH xx TT (Kingston SSDNow+)
     2090      // 00 00 HH LL xx TT (Maxtor, Samsung, Toshiba)
    20612091      // 00 00 00 HH LL TT (WDC)
    2062       unsigned char lo = 0, hi = 0;
    2063       int cnt = 0;
    2064       for (int i = 1; i < 6; i++) {
    2065         if (raw[i])
    2066           switch (cnt++) {
    2067             case 0:
    2068               lo = raw[i];
    2069               break;
    2070             case 1:
    2071               if (raw[i] < lo) {
    2072                 hi = lo; lo = raw[i];
    2073               }
    2074               else
    2075                 hi = raw[i];
    2076               break;
    2077           }
     2092      // CC CC HH LL xx TT (WDC, CCCC=over temperature count)
     2093      // (xx = 00/ff, possibly sign extension of lower byte)
     2094
     2095      int t = (signed char)raw[0];
     2096      int lo = 0, hi = 0;
     2097
     2098      int tformat;
     2099      int ctw0 = check_temp_word(word[0]);
     2100      if (!word[2]) {
     2101        if (!word[1] && ctw0)
     2102          // 00 00 00 00 xx TT
     2103          tformat = 0;
     2104        else if (ctw0 && check_temp_range(t, raw[2], raw[3], lo, hi))
     2105          // 00 00 HL LH xx TT
     2106          tformat = 1;
     2107        else if (!raw[3] && check_temp_range(t, raw[1], raw[2], lo, hi))
     2108          // 00 00 00 HL LH TT
     2109          tformat = 2;
     2110        else
     2111          tformat = -1;
    20782112      }
     2113      else if (ctw0) {
     2114        if (   (ctw0 & check_temp_word(word[1]) & check_temp_word(word[2])) != 0x00
     2115            && check_temp_range(t, raw[2], raw[4], lo, hi)                         )
     2116          // xx HL xx LH xx TT
     2117          tformat = 3;
     2118        else if (   word[2] < 0x7fff
     2119                 && check_temp_range(t, raw[2], raw[3], lo, hi)
     2120                 && hi >= 40                                   )
     2121          // CC CC HL LH xx TT
     2122          tformat = 4;
     2123        else
     2124          tformat = -2;
     2125      }
     2126      else
     2127        tformat = -3;
    20792128
    2080       unsigned char t = raw[0];
    2081       if (cnt == 0)
    2082         s = strprintf("%d", t);
    2083       else if (cnt == 2 && 0 < lo && lo <= t && t <= hi && hi < 128)
    2084         s = strprintf("%d (Min/Max %d/%d)", t, lo, hi);
    2085       else
    2086         s = strprintf("%d (%d %d %d %d %d)", t, raw[5], raw[4], raw[3], raw[2], raw[1]);
     2129      switch (tformat) {
     2130        case 0:
     2131          s = strprintf("%d", t);
     2132          break;
     2133        case 1: case 2: case 3:
     2134          s = strprintf("%d (Min/Max %d/%d)", t, lo, hi);
     2135          break;
     2136        case 4:
     2137          s = strprintf("%d (Min/Max %d/%d #%d)", t, lo, hi, word[2]);
     2138          break;
     2139        default:
     2140          s = strprintf("%d (%d %d %d %d %d)", raw[0], raw[5], raw[4], raw[3], raw[2], raw[1]);
     2141          break;
     2142      }
    20872143    }
    20882144    break;
    20892145