]> git.proxmox.com Git - mirror_smartmontools-debian.git/blobdiff - atacmds.cpp
Imported Upstream version 6.4+svn4214
[mirror_smartmontools-debian.git] / atacmds.cpp
index 88ec6b94f8e04a6d044385b0e38b0152182c01c7..3a2bec4b74474c6361cbe9ec2029a53f5692d82d 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * atacmds.cpp
  * 
- * Home page of code is: http://smartmontools.sourceforge.net
+ * Home page of code is: http://www.smartmontools.org
  *
- * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2008-15 Christian Franke <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2002-11 Bruce Allen
+ * Copyright (C) 2008-15 Christian Franke
  * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
  * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
  *
 #include "config.h"
 #include "int64.h"
 #include "atacmds.h"
+#include "knowndrives.h"  // get_default_attr_defs()
 #include "utility.h"
 #include "dev_ata_cmd_set.h" // for parsed_ata_device
 
-const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 4048 2015-03-29 16:09:04Z chrfranke $"
+const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 4178 2015-11-23 18:44:27Z chrfranke $"
                                  ATACMDS_H_CVSID;
 
 // Print ATA debug messages?
@@ -170,7 +171,9 @@ bool parse_attribute_def(const char * opt, ata_vendor_attr_defs & defs,
   // Parse option
   int len = strlen(opt);
   int id = 0, n1 = -1, n2 = -1;
-  char fmtname[32+1], attrname[32+1];
+  char fmtname[32+1], attrname[32+1], hddssd[3+1];
+  attrname[0] = hddssd[0] = 0;
+
   if (opt[0] == 'N') {
     // "N,format[,name]"
     if (!(   sscanf(opt, "N,%32[^,]%n,%32[^,]%n", fmtname, &n1, attrname, &n2) >= 1
@@ -178,13 +181,16 @@ bool parse_attribute_def(const char * opt, ata_vendor_attr_defs & defs,
       return false;
   }
   else {
-    // "id,format[+][,name]"
-    if (!(   sscanf(opt, "%d,%32[^,]%n,%32[^,]%n", &id, fmtname, &n1, attrname, &n2) >= 2
-          && 1 <= id && id <= 255 && (n1 == len || n2 == len)))
+    // "id,format[+][,name[,HDD|SSD]]"
+    int n3 = -1;
+    if (!(   sscanf(opt, "%d,%32[^,]%n,%32[^,]%n,%3[DHS]%n",
+                    &id, fmtname, &n1, attrname, &n2, hddssd, &n3) >= 2
+          && 1 <= id && id <= 255
+          && (    n1 == len || n2 == len
+                  // ",HDD|SSD" for DEFAULT settings only
+              || (n3 == len && priority == PRIOR_DEFAULT))))
       return false;
   }
-  if (n1 == len)
-    attrname[0] = 0;
 
   unsigned flags = 0;
   // For "-v 19[78],increasing" above
@@ -196,6 +202,9 @@ bool parse_attribute_def(const char * opt, ata_vendor_attr_defs & defs,
   // Split "format[:byteorder]"
   char byteorder[8+1] = "";
   if (strchr(fmtname, ':')) {
+    if (priority == PRIOR_DEFAULT)
+      // TODO: Allow Byteorder in DEFAULT entry
+      return false;
     n1 = n2 = -1;
     if (!(   sscanf(fmtname, "%*[^:]%n:%8[012345rvwz]%n", &n1, byteorder, &n2) >= 1
           && n2 == (int)strlen(fmtname)))
@@ -220,6 +229,16 @@ bool parse_attribute_def(const char * opt, ata_vendor_attr_defs & defs,
   if (!*byteorder && (format == RAWFMT_RAW64 || format == RAWFMT_HEX64))
     flags |= (ATTRFLAG_NO_NORMVAL|ATTRFLAG_NO_WORSTVAL);
 
+  // ",HDD|SSD" suffix for DEFAULT settings
+  if (hddssd[0]) {
+    if (!strcmp(hddssd, "HDD"))
+      flags |= ATTRFLAG_HDD_ONLY;
+    else if (!strcmp(hddssd, "SSD"))
+      flags |= ATTRFLAG_SSD_ONLY;
+    else
+      return false;
+  }
+
   if (!id) {
     // "N,format" -> set format for all entries
     for (i = 0; i < MAX_ATTRIBUTE_NUM; i++) {
@@ -617,7 +636,7 @@ int smartcommandhandler(ata_device * device, smart_command_set command, int sele
 
   // If requested, invalidate serial number before any printing is done
   if ((command == IDENTIFY || command == PIDENTIFY) && !retval && dont_print_serial_number)
-    invalidate_serno((ata_identify_device *)data);
+    invalidate_serno( reinterpret_cast<ata_identify_device *>(data) );
 
   // If reporting is enabled, say what output was produced by the command
   if (ata_debugmode) {
@@ -831,9 +850,9 @@ int ata_read_identity(ata_device * device, ata_identify_device * buf, bool fix_s
     packet = true;
   }
 
-  unsigned i;
   if (fix_swapped_id) {
     // Swap ID strings
+    unsigned i;
     for (i = 0; i < sizeof(buf->serial_no)-1; i += 2)
       swap2((char *)(buf->serial_no+i));
     for (i = 0; i < sizeof(buf->fw_rev)-1; i += 2)
@@ -851,14 +870,12 @@ int ata_read_identity(ata_device * device, ata_identify_device * buf, bool fix_s
   // NetBSD kernel delivers IDENTIFY data in host byte order
   // TODO: Handle NetBSD case in os_netbsd.cpp
   if (isbigendian()){
-    
     // swap various capability words that are needed
+    unsigned i;
     for (i=0; i<33; i++)
       swap2((char *)(buf->words047_079+i));
-    
     for (i=80; i<=87; i++)
       swap2((char *)(rawshort+i));
-    
     for (i=0; i<168; i++)
       swap2((char *)(buf->words088_255+i));
   }
@@ -1859,35 +1876,12 @@ ata_attr_state ata_get_attr_state(const ata_smart_attribute & attr,
   return ATTRSTATE_OK;
 }
 
-// Get default raw value print format
-static ata_attr_raw_format get_default_raw_format(unsigned char id)
-{
-  switch (id) {
-  case 3:   // Spin-up time
-    return RAWFMT_RAW16_OPT_AVG16;
-
-  case 5:   // Reallocated sector count
-  case 196: // Reallocated event count
-    return RAWFMT_RAW16_OPT_RAW16;
-
-  case 9:   // Power on hours
-  case 240: // Head flying hours
-    return RAWFMT_RAW24_OPT_RAW8;
-
-  case 190: // Temperature
-  case 194:
-    return RAWFMT_TEMPMINMAX;
-
-  default:
-    return RAWFMT_RAW48;
-  }
-}
-
 // Get attribute raw value.
 uint64_t ata_get_attr_raw_value(const ata_smart_attribute & attr,
                                 const ata_vendor_attr_defs & defs)
 {
   const ata_vendor_attr_defs::entry & def = defs[attr.id];
+  // TODO: Allow Byteorder in DEFAULT entry
 
   // Use default byteorder if not specified
   const char * byteorder = def.byteorder;
@@ -1978,8 +1972,13 @@ std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
 
   // Get print format
   ata_attr_raw_format format = defs[attr.id].raw_format;
-  if (format == RAWFMT_DEFAULT)
-    format = get_default_raw_format(attr.id);
+  if (format == RAWFMT_DEFAULT) {
+     // Get format from DEFAULT entry
+     format = get_default_attr_defs()[attr.id].raw_format;
+     if (format == RAWFMT_DEFAULT)
+       // Unknown Attribute
+       format = RAWFMT_RAW48;
+  }
 
   // Print
   std::string s;
@@ -2158,212 +2157,23 @@ std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
   return s;
 }
 
-// Attribute names shouldn't be longer than 23 chars, otherwise they break the
-// output of smartctl.
-static const char * get_default_attr_name(unsigned char id, int rpm)
-{
-  bool hdd = (rpm > 1), ssd = (rpm == 1);
-
-  static const char Unknown_HDD_Attribute[] = "Unknown_HDD_Attribute";
-  static const char Unknown_SSD_Attribute[] = "Unknown_SSD_Attribute";
-
-  switch (id) {
-  case 1:
-    return "Raw_Read_Error_Rate";
-  case 2:
-    return "Throughput_Performance";
-  case 3:
-    return "Spin_Up_Time";
-  case 4:
-    return "Start_Stop_Count";
-  case 5:
-    return "Reallocated_Sector_Ct";
-  case 6:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Read_Channel_Margin";
-  case 7:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Seek_Error_Rate";
-  case 8:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Seek_Time_Performance";
-  case 9:
-    return "Power_On_Hours";
-  case 10:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Spin_Retry_Count";
-  case 11:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Calibration_Retry_Count";
-  case 12:
-    return "Power_Cycle_Count";
-  case 13:
-    return "Read_Soft_Error_Rate";
-  case 175:
-    if (hdd) return Unknown_HDD_Attribute;
-    return "Program_Fail_Count_Chip";
-  case 176:
-    if (hdd) return Unknown_HDD_Attribute;
-    return "Erase_Fail_Count_Chip";
-  case 177:
-    if (hdd) return Unknown_HDD_Attribute;
-    return "Wear_Leveling_Count";
-  case 178:
-    if (hdd) return Unknown_HDD_Attribute;
-    return "Used_Rsvd_Blk_Cnt_Chip";
-  case 179:
-    if (hdd) return Unknown_HDD_Attribute;
-    return "Used_Rsvd_Blk_Cnt_Tot";
-  case 180:
-    if (hdd) return Unknown_HDD_Attribute;
-    return "Unused_Rsvd_Blk_Cnt_Tot";
-  case 181:
-    return "Program_Fail_Cnt_Total";
-  case 182:
-    if (hdd) return Unknown_HDD_Attribute;
-    return "Erase_Fail_Count_Total";
-  case 183:
-    return "Runtime_Bad_Block";
-  case 184:
-    return "End-to-End_Error";
-  case 187:
-    return "Reported_Uncorrect";
-  case 188:
-    return "Command_Timeout";
-  case 189:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "High_Fly_Writes";
-  case 190:
-    // Western Digital uses this for temperature.
-    // It's identical to Attribute 194 except that it
-    // has a failure threshold set to correspond to the
-    // max allowed operating temperature of the drive, which 
-    // is typically 55C.  So if this attribute has failed
-    // in the past, it indicates that the drive temp exceeded
-    // 55C sometime in the past.
-    return "Airflow_Temperature_Cel";
-  case 191:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "G-Sense_Error_Rate";
-  case 192:
-    return "Power-Off_Retract_Count";
-  case 193:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Load_Cycle_Count";
-  case 194:
-    return "Temperature_Celsius";
-  case 195:
-    // Fujitsu: "ECC_On_The_Fly_Count";
-    return "Hardware_ECC_Recovered";
-  case 196:
-    return "Reallocated_Event_Count";
-  case 197:
-    return "Current_Pending_Sector";
-  case 198:
-    return "Offline_Uncorrectable";
-  case 199:
-    return "UDMA_CRC_Error_Count";
-  case 200:
-    if (ssd) return Unknown_SSD_Attribute;
-    // Western Digital
-    return "Multi_Zone_Error_Rate";
-  case 201:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Soft_Read_Error_Rate";
-  case 202:
-    if (ssd) return Unknown_SSD_Attribute;
-    // Fujitsu: "TA_Increase_Count"
-    return "Data_Address_Mark_Errs";
-  case 203:
-    // Fujitsu
-    return "Run_Out_Cancel";
-    // Maxtor: ECC Errors
-  case 204:
-    // Fujitsu: "Shock_Count_Write_Opern"
-    return "Soft_ECC_Correction";
-  case 205:
-    // Fujitsu: "Shock_Rate_Write_Opern"
-    return "Thermal_Asperity_Rate";
-  case 206:
-    // Fujitsu
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Flying_Height";
-  case 207:
-    // Maxtor
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Spin_High_Current";
-  case 208:
-    // Maxtor
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Spin_Buzz";
-  case 209:
-    // Maxtor
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Offline_Seek_Performnce";
-  case 220:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Disk_Shift";
-  case 221:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "G-Sense_Error_Rate";
-  case 222:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Loaded_Hours";
-  case 223:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Load_Retry_Count";
-  case 224:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Load_Friction";
-  case 225:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Load_Cycle_Count";
-  case 226:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Load-in_Time";
-  case 227:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Torq-amp_Count";
-  case 228:
-    return "Power-off_Retract_Count";
-  case 230:
-    // seen in IBM DTPA-353750
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Head_Amplitude";
-  case 231:
-    return "Temperature_Celsius";
-  case 232:
-    // seen in Intel X25-E SSD
-    return "Available_Reservd_Space";
-  case 233:
-    // seen in Intel X25-E SSD
-    if (hdd) return Unknown_HDD_Attribute;
-    return "Media_Wearout_Indicator";
-  case 240:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Head_Flying_Hours";
-  case 241:
-    return "Total_LBAs_Written";
-  case 242:
-    return "Total_LBAs_Read";
-  case 250:
-    return "Read_Error_Retry_Rate";
-  case 254:
-    if (ssd) return Unknown_SSD_Attribute;
-    return "Free_Fall_Sensor";
-  default:
-    return "Unknown_Attribute";
-  }
-}
-
 // Get attribute name
 std::string ata_get_smart_attr_name(unsigned char id, const ata_vendor_attr_defs & defs,
                                     int rpm /* = 0 */)
 {
   if (!defs[id].name.empty())
     return defs[id].name;
-  else
-    return get_default_attr_name(id, rpm);
+  else {
+     const ata_vendor_attr_defs::entry & def = get_default_attr_defs()[id];
+     if (def.name.empty())
+       return "Unknown_Attribute";
+     else if ((def.flags & ATTRFLAG_HDD_ONLY) && rpm == 1)
+       return "Unknown_SSD_Attribute";
+     else if ((def.flags & ATTRFLAG_SSD_ONLY) && rpm > 1)
+       return "Unknown_HDD_Attribute";
+     else
+       return def.name;
+  }
 }
 
 // Find attribute index for attribute id, -1 if not found.