Annotation of embedaddon/smartmontools/atacmds.h, revision 1.1
1.1 ! misho 1: /*
! 2: * atacmds.h
! 3: *
! 4: * Home page of code is: http://smartmontools.sourceforge.net
! 5: *
! 6: * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
! 7: * Copyright (C) 2008-11 Christian Franke <smartmontools-support@lists.sourceforge.net>
! 8: * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
! 9: *
! 10: * This program is free software; you can redistribute it and/or modify
! 11: * it under the terms of the GNU General Public License as published by
! 12: * the Free Software Foundation; either version 2, or (at your option)
! 13: * any later version.
! 14: *
! 15: * You should have received a copy of the GNU General Public License
! 16: * (for example COPYING); if not, write to the Free
! 17: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
! 18: *
! 19: * This code was originally developed as a Senior Thesis by Michael Cornwell
! 20: * at the Concurrent Systems Laboratory (now part of the Storage Systems
! 21: * Research Center), Jack Baskin School of Engineering, University of
! 22: * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
! 23: *
! 24: */
! 25:
! 26: #ifndef ATACMDS_H_
! 27: #define ATACMDS_H_
! 28:
! 29: #define ATACMDS_H_CVSID "$Id: atacmds.h 3316 2011-04-19 19:34:57Z chrfranke $"
! 30:
! 31: #include "dev_interface.h" // ata_device
! 32:
! 33: // Macro to check expected size of struct at compile time using a
! 34: // dummy typedef. On size mismatch, compiler reports a negative array
! 35: // size. If you see an error message of this form, it means that the
! 36: // #pragma pack(1) pragma below is not having the desired effect on
! 37: // your compiler.
! 38: #define ASSERT_SIZEOF_STRUCT(s, n) \
! 39: typedef char assert_sizeof_struct_##s[(sizeof(struct s) == (n)) ? 1 : -1]
! 40:
! 41: // Add __attribute__((packed)) if compiler supports it
! 42: // because some gcc versions (at least ARM) lack support of #pragma pack()
! 43: #ifdef HAVE_ATTR_PACKED
! 44: #define ATTR_PACKED __attribute__((packed))
! 45: #else
! 46: #define ATTR_PACKED
! 47: #endif
! 48:
! 49: typedef enum {
! 50: // returns no data, just succeeds or fails
! 51: ENABLE,
! 52: DISABLE,
! 53: AUTOSAVE,
! 54: IMMEDIATE_OFFLINE,
! 55: AUTO_OFFLINE,
! 56: STATUS, // just says if SMART is working or not
! 57: STATUS_CHECK, // says if disk's SMART status is healthy, or failing
! 58: // return 512 bytes of data:
! 59: READ_VALUES,
! 60: READ_THRESHOLDS,
! 61: READ_LOG,
! 62: IDENTIFY,
! 63: PIDENTIFY,
! 64: // returns 1 byte of data
! 65: CHECK_POWER_MODE,
! 66: // writes 512 bytes of data:
! 67: WRITE_LOG
! 68: } smart_command_set;
! 69:
! 70: // Possible values for fix_firmwarebug.
! 71: enum {
! 72: FIX_NOTSPECIFIED = 0,
! 73: FIX_NONE,
! 74: FIX_SAMSUNG,
! 75: FIX_SAMSUNG2,
! 76: FIX_SAMSUNG3
! 77: };
! 78:
! 79: // ATA Specification Command Register Values (Commands)
! 80: #define ATA_IDENTIFY_DEVICE 0xec
! 81: #define ATA_IDENTIFY_PACKET_DEVICE 0xa1
! 82: #define ATA_SMART_CMD 0xb0
! 83: #define ATA_CHECK_POWER_MODE 0xe5
! 84: // 48-bit commands
! 85: #define ATA_READ_LOG_EXT 0x2F
! 86:
! 87: // ATA Specification Feature Register Values (SMART Subcommands).
! 88: // Note that some are obsolete as of ATA-7.
! 89: #define ATA_SMART_READ_VALUES 0xd0
! 90: #define ATA_SMART_READ_THRESHOLDS 0xd1
! 91: #define ATA_SMART_AUTOSAVE 0xd2
! 92: #define ATA_SMART_SAVE 0xd3
! 93: #define ATA_SMART_IMMEDIATE_OFFLINE 0xd4
! 94: #define ATA_SMART_READ_LOG_SECTOR 0xd5
! 95: #define ATA_SMART_WRITE_LOG_SECTOR 0xd6
! 96: #define ATA_SMART_WRITE_THRESHOLDS 0xd7
! 97: #define ATA_SMART_ENABLE 0xd8
! 98: #define ATA_SMART_DISABLE 0xd9
! 99: #define ATA_SMART_STATUS 0xda
! 100: // SFF 8035i Revision 2 Specification Feature Register Value (SMART
! 101: // Subcommand)
! 102: #define ATA_SMART_AUTO_OFFLINE 0xdb
! 103:
! 104: // Sector Number values for ATA_SMART_IMMEDIATE_OFFLINE Subcommand
! 105: #define OFFLINE_FULL_SCAN 0
! 106: #define SHORT_SELF_TEST 1
! 107: #define EXTEND_SELF_TEST 2
! 108: #define CONVEYANCE_SELF_TEST 3
! 109: #define SELECTIVE_SELF_TEST 4
! 110: #define ABORT_SELF_TEST 127
! 111: #define SHORT_CAPTIVE_SELF_TEST 129
! 112: #define EXTEND_CAPTIVE_SELF_TEST 130
! 113: #define CONVEYANCE_CAPTIVE_SELF_TEST 131
! 114: #define SELECTIVE_CAPTIVE_SELF_TEST 132
! 115: #define CAPTIVE_MASK (0x01<<7)
! 116:
! 117: // Maximum allowed number of SMART Attributes
! 118: #define NUMBER_ATA_SMART_ATTRIBUTES 30
! 119:
! 120: // Needed parts of the ATA DRIVE IDENTIFY Structure. Those labeled
! 121: // word* are NOT used.
! 122: #pragma pack(1)
! 123: struct ata_identify_device {
! 124: unsigned short words000_009[10];
! 125: unsigned char serial_no[20];
! 126: unsigned short words020_022[3];
! 127: unsigned char fw_rev[8];
! 128: unsigned char model[40];
! 129: unsigned short words047_079[33];
! 130: unsigned short major_rev_num;
! 131: unsigned short minor_rev_num;
! 132: unsigned short command_set_1;
! 133: unsigned short command_set_2;
! 134: unsigned short command_set_extension;
! 135: unsigned short cfs_enable_1;
! 136: unsigned short word086;
! 137: unsigned short csf_default;
! 138: unsigned short words088_255[168];
! 139: } ATTR_PACKED;
! 140: #pragma pack()
! 141: ASSERT_SIZEOF_STRUCT(ata_identify_device, 512);
! 142:
! 143: /* ata_smart_attribute is the vendor specific in SFF-8035 spec */
! 144: #pragma pack(1)
! 145: struct ata_smart_attribute {
! 146: unsigned char id;
! 147: // meaning of flag bits: see MACROS just below
! 148: // WARNING: MISALIGNED!
! 149: unsigned short flags;
! 150: unsigned char current;
! 151: unsigned char worst;
! 152: unsigned char raw[6];
! 153: unsigned char reserv;
! 154: } ATTR_PACKED;
! 155: #pragma pack()
! 156: ASSERT_SIZEOF_STRUCT(ata_smart_attribute, 12);
! 157:
! 158: // MACROS to interpret the flags bits in the previous structure.
! 159: // These have not been implemented using bitflags and a union, to make
! 160: // it portable across bit/little endian and different platforms.
! 161:
! 162: // 0: Prefailure bit
! 163:
! 164: // From SFF 8035i Revision 2 page 19: Bit 0 (pre-failure/advisory bit)
! 165: // - If the value of this bit equals zero, an attribute value less
! 166: // than or equal to its corresponding attribute threshold indicates an
! 167: // advisory condition where the usage or age of the device has
! 168: // exceeded its intended design life period. If the value of this bit
! 169: // equals one, an attribute value less than or equal to its
! 170: // corresponding attribute threshold indicates a prefailure condition
! 171: // where imminent loss of data is being predicted.
! 172: #define ATTRIBUTE_FLAGS_PREFAILURE(x) (x & 0x01)
! 173:
! 174: // 1: Online bit
! 175:
! 176: // From SFF 8035i Revision 2 page 19: Bit 1 (on-line data collection
! 177: // bit) - If the value of this bit equals zero, then the attribute
! 178: // value is updated only during off-line data collection
! 179: // activities. If the value of this bit equals one, then the attribute
! 180: // value is updated during normal operation of the device or during
! 181: // both normal operation and off-line testing.
! 182: #define ATTRIBUTE_FLAGS_ONLINE(x) (x & 0x02)
! 183:
! 184:
! 185: // The following are (probably) IBM's, Maxtors and Quantum's definitions for the
! 186: // vendor-specific bits:
! 187: // 2: Performance type bit
! 188: #define ATTRIBUTE_FLAGS_PERFORMANCE(x) (x & 0x04)
! 189:
! 190: // 3: Errorrate type bit
! 191: #define ATTRIBUTE_FLAGS_ERRORRATE(x) (x & 0x08)
! 192:
! 193: // 4: Eventcount bit
! 194: #define ATTRIBUTE_FLAGS_EVENTCOUNT(x) (x & 0x10)
! 195:
! 196: // 5: Selfpereserving bit
! 197: #define ATTRIBUTE_FLAGS_SELFPRESERVING(x) (x & 0x20)
! 198:
! 199: // 6-15: Reserved for future use
! 200: #define ATTRIBUTE_FLAGS_OTHER(x) ((x) & 0xffc0)
! 201:
! 202:
! 203: /* ata_smart_values is format of the read drive Attribute command */
! 204: /* see Table 34 of T13/1321D Rev 1 spec (Device SMART data structure) for *some* info */
! 205: #pragma pack(1)
! 206: struct ata_smart_values {
! 207: unsigned short int revnumber;
! 208: struct ata_smart_attribute vendor_attributes [NUMBER_ATA_SMART_ATTRIBUTES];
! 209: unsigned char offline_data_collection_status;
! 210: unsigned char self_test_exec_status; //IBM # segments for offline collection
! 211: unsigned short int total_time_to_complete_off_line; // IBM different
! 212: unsigned char vendor_specific_366; // Maxtor & IBM curent segment pointer
! 213: unsigned char offline_data_collection_capability;
! 214: unsigned short int smart_capability;
! 215: unsigned char errorlog_capability;
! 216: unsigned char vendor_specific_371; // Maxtor, IBM: self-test failure checkpoint see below!
! 217: unsigned char short_test_completion_time;
! 218: unsigned char extend_test_completion_time;
! 219: unsigned char conveyance_test_completion_time;
! 220: unsigned char reserved_375_385[11];
! 221: unsigned char vendor_specific_386_510[125]; // Maxtor bytes 508-509 Attribute/Threshold Revision #
! 222: unsigned char chksum;
! 223: } ATTR_PACKED;
! 224: #pragma pack()
! 225: ASSERT_SIZEOF_STRUCT(ata_smart_values, 512);
! 226:
! 227: /* Maxtor, IBM: self-test failure checkpoint byte meaning:
! 228: 00 - write test
! 229: 01 - servo basic
! 230: 02 - servo random
! 231: 03 - G-list scan
! 232: 04 - Handling damage
! 233: 05 - Read scan
! 234: */
! 235:
! 236: /* Vendor attribute of SMART Threshold (compare to ata_smart_attribute above) */
! 237: #pragma pack(1)
! 238: struct ata_smart_threshold_entry {
! 239: unsigned char id;
! 240: unsigned char threshold;
! 241: unsigned char reserved[10];
! 242: } ATTR_PACKED;
! 243: #pragma pack()
! 244: ASSERT_SIZEOF_STRUCT(ata_smart_threshold_entry, 12);
! 245:
! 246: /* Format of Read SMART THreshold Command */
! 247: /* Compare to ata_smart_values above */
! 248: #pragma pack(1)
! 249: struct ata_smart_thresholds_pvt {
! 250: unsigned short int revnumber;
! 251: struct ata_smart_threshold_entry thres_entries[NUMBER_ATA_SMART_ATTRIBUTES];
! 252: unsigned char reserved[149];
! 253: unsigned char chksum;
! 254: } ATTR_PACKED;
! 255: #pragma pack()
! 256: ASSERT_SIZEOF_STRUCT(ata_smart_thresholds_pvt, 512);
! 257:
! 258:
! 259: // Table 42 of T13/1321D Rev 1 spec (Error Data Structure)
! 260: #pragma pack(1)
! 261: struct ata_smart_errorlog_error_struct {
! 262: unsigned char reserved;
! 263: unsigned char error_register;
! 264: unsigned char sector_count;
! 265: unsigned char sector_number;
! 266: unsigned char cylinder_low;
! 267: unsigned char cylinder_high;
! 268: unsigned char drive_head;
! 269: unsigned char status;
! 270: unsigned char extended_error[19];
! 271: unsigned char state;
! 272: unsigned short timestamp;
! 273: } ATTR_PACKED;
! 274: #pragma pack()
! 275: ASSERT_SIZEOF_STRUCT(ata_smart_errorlog_error_struct, 30);
! 276:
! 277:
! 278: // Table 41 of T13/1321D Rev 1 spec (Command Data Structure)
! 279: #pragma pack(1)
! 280: struct ata_smart_errorlog_command_struct {
! 281: unsigned char devicecontrolreg;
! 282: unsigned char featuresreg;
! 283: unsigned char sector_count;
! 284: unsigned char sector_number;
! 285: unsigned char cylinder_low;
! 286: unsigned char cylinder_high;
! 287: unsigned char drive_head;
! 288: unsigned char commandreg;
! 289: unsigned int timestamp;
! 290: } ATTR_PACKED;
! 291: #pragma pack()
! 292: ASSERT_SIZEOF_STRUCT(ata_smart_errorlog_command_struct, 12);
! 293:
! 294: // Table 40 of T13/1321D Rev 1 spec (Error log data structure)
! 295: #pragma pack(1)
! 296: struct ata_smart_errorlog_struct {
! 297: struct ata_smart_errorlog_command_struct commands[5];
! 298: struct ata_smart_errorlog_error_struct error_struct;
! 299: } ATTR_PACKED;
! 300: #pragma pack()
! 301: ASSERT_SIZEOF_STRUCT(ata_smart_errorlog_struct, 90);
! 302:
! 303: // Table 39 of T13/1321D Rev 1 spec (SMART error log sector)
! 304: #pragma pack(1)
! 305: struct ata_smart_errorlog {
! 306: unsigned char revnumber;
! 307: unsigned char error_log_pointer;
! 308: struct ata_smart_errorlog_struct errorlog_struct[5];
! 309: unsigned short int ata_error_count;
! 310: unsigned char reserved[57];
! 311: unsigned char checksum;
! 312: } ATTR_PACKED;
! 313: #pragma pack()
! 314: ASSERT_SIZEOF_STRUCT(ata_smart_errorlog, 512);
! 315:
! 316:
! 317: // Extended Comprehensive SMART Error Log data structures
! 318: // See Section A.7 of
! 319: // AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
! 320: // T13/1699-D Revision 6a (Working Draft), September 6, 2008.
! 321:
! 322: // Command data structure
! 323: // Table A.9 of T13/1699-D Revision 6a
! 324: #pragma pack(1)
! 325: struct ata_smart_exterrlog_command
! 326: {
! 327: unsigned char device_control_register;
! 328: unsigned char features_register;
! 329: unsigned char features_register_hi;
! 330: unsigned char count_register;
! 331: unsigned char count_register_hi;
! 332: unsigned char lba_low_register;
! 333: unsigned char lba_low_register_hi;
! 334: unsigned char lba_mid_register;
! 335: unsigned char lba_mid_register_hi;
! 336: unsigned char lba_high_register;
! 337: unsigned char lba_high_register_hi;
! 338: unsigned char device_register;
! 339: unsigned char command_register;
! 340:
! 341: unsigned char reserved;
! 342: unsigned int timestamp;
! 343: } ATTR_PACKED;
! 344: #pragma pack()
! 345: ASSERT_SIZEOF_STRUCT(ata_smart_exterrlog_command, 18);
! 346:
! 347: // Error data structure
! 348: // Table A.10 T13/1699-D Revision 6a
! 349: #pragma pack(1)
! 350: struct ata_smart_exterrlog_error
! 351: {
! 352: unsigned char device_control_register;
! 353: unsigned char error_register;
! 354: unsigned char count_register;
! 355: unsigned char count_register_hi;
! 356: unsigned char lba_low_register;
! 357: unsigned char lba_low_register_hi;
! 358: unsigned char lba_mid_register;
! 359: unsigned char lba_mid_register_hi;
! 360: unsigned char lba_high_register;
! 361: unsigned char lba_high_register_hi;
! 362: unsigned char device_register;
! 363: unsigned char status_register;
! 364:
! 365: unsigned char extended_error[19];
! 366: unsigned char state;
! 367: unsigned short timestamp;
! 368: } ATTR_PACKED;
! 369: #pragma pack()
! 370: ASSERT_SIZEOF_STRUCT(ata_smart_exterrlog_error, 34);
! 371:
! 372: // Error log data structure
! 373: // Table A.8 of T13/1699-D Revision 6a
! 374: #pragma pack(1)
! 375: struct ata_smart_exterrlog_error_log
! 376: {
! 377: ata_smart_exterrlog_command commands[5];
! 378: ata_smart_exterrlog_error error;
! 379: } ATTR_PACKED;
! 380: #pragma pack()
! 381: ASSERT_SIZEOF_STRUCT(ata_smart_exterrlog_error_log, 124);
! 382:
! 383: // Ext. Comprehensive SMART error log
! 384: // Table A.7 of T13/1699-D Revision 6a
! 385: #pragma pack(1)
! 386: struct ata_smart_exterrlog
! 387: {
! 388: unsigned char version;
! 389: unsigned char reserved1;
! 390: unsigned short error_log_index;
! 391: ata_smart_exterrlog_error_log error_logs[4];
! 392: unsigned short device_error_count;
! 393: unsigned char reserved2[9];
! 394: unsigned char checksum;
! 395: } ATTR_PACKED;
! 396: #pragma pack()
! 397: ASSERT_SIZEOF_STRUCT(ata_smart_exterrlog, 512);
! 398:
! 399:
! 400: // Table 45 of T13/1321D Rev 1 spec (Self-test log descriptor entry)
! 401: #pragma pack(1)
! 402: struct ata_smart_selftestlog_struct {
! 403: unsigned char selftestnumber; // Sector number register
! 404: unsigned char selfteststatus;
! 405: unsigned short int timestamp;
! 406: unsigned char selftestfailurecheckpoint;
! 407: unsigned int lbafirstfailure;
! 408: unsigned char vendorspecific[15];
! 409: } ATTR_PACKED;
! 410: #pragma pack()
! 411: ASSERT_SIZEOF_STRUCT(ata_smart_selftestlog_struct, 24);
! 412:
! 413: // Table 44 of T13/1321D Rev 1 spec (Self-test log data structure)
! 414: #pragma pack(1)
! 415: struct ata_smart_selftestlog {
! 416: unsigned short int revnumber;
! 417: struct ata_smart_selftestlog_struct selftest_struct[21];
! 418: unsigned char vendorspecific[2];
! 419: unsigned char mostrecenttest;
! 420: unsigned char reserved[2];
! 421: unsigned char chksum;
! 422: } ATTR_PACKED;
! 423: #pragma pack()
! 424: ASSERT_SIZEOF_STRUCT(ata_smart_selftestlog, 512);
! 425:
! 426: // Extended SMART Self-test log data structures
! 427: // See Section A.8 of
! 428: // AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
! 429: // T13/1699-D Revision 6a (Working Draft), September 6, 2008.
! 430:
! 431: // Extended Self-test log descriptor entry
! 432: // Table A.13 of T13/1699-D Revision 6a
! 433: #pragma pack(1)
! 434: struct ata_smart_extselftestlog_desc
! 435: {
! 436: unsigned char self_test_type;
! 437: unsigned char self_test_status;
! 438: unsigned short timestamp;
! 439: unsigned char checkpoint;
! 440: unsigned char failing_lba[6];
! 441: unsigned char vendorspecific[15];
! 442: } ATTR_PACKED;
! 443: #pragma pack()
! 444: ASSERT_SIZEOF_STRUCT(ata_smart_extselftestlog_desc, 26);
! 445:
! 446: // Extended Self-test log data structure
! 447: // Table A.12 of T13/1699-D Revision 6a
! 448: #pragma pack(1)
! 449: struct ata_smart_extselftestlog
! 450: {
! 451: unsigned char version;
! 452: unsigned char reserved1;
! 453: unsigned short log_desc_index;
! 454: struct ata_smart_extselftestlog_desc log_descs[19];
! 455: unsigned char vendor_specifc[2];
! 456: unsigned char reserved2[11];
! 457: unsigned char chksum;
! 458: } ATTR_PACKED;
! 459: #pragma pack()
! 460: ASSERT_SIZEOF_STRUCT(ata_smart_extselftestlog, 512);
! 461:
! 462: // SMART LOG DIRECTORY Table 52 of T13/1532D Vol 1 Rev 1a
! 463: #pragma pack(1)
! 464: struct ata_smart_log_entry {
! 465: unsigned char numsectors;
! 466: unsigned char reserved;
! 467: } ATTR_PACKED;
! 468: #pragma pack()
! 469: ASSERT_SIZEOF_STRUCT(ata_smart_log_entry, 2);
! 470:
! 471: #pragma pack(1)
! 472: struct ata_smart_log_directory {
! 473: unsigned short int logversion;
! 474: struct ata_smart_log_entry entry[255];
! 475: } ATTR_PACKED;
! 476: #pragma pack()
! 477: ASSERT_SIZEOF_STRUCT(ata_smart_log_directory, 512);
! 478:
! 479: // SMART SELECTIVE SELF-TEST LOG Table 61 of T13/1532D Volume 1
! 480: // Revision 3
! 481: #pragma pack(1)
! 482: struct test_span {
! 483: uint64_t start;
! 484: uint64_t end;
! 485: } ATTR_PACKED;
! 486: #pragma pack()
! 487: ASSERT_SIZEOF_STRUCT(test_span, 16);
! 488:
! 489: #pragma pack(1)
! 490: struct ata_selective_self_test_log {
! 491: unsigned short logversion;
! 492: struct test_span span[5];
! 493: unsigned char reserved1[337-82+1];
! 494: unsigned char vendor_specific1[491-338+1];
! 495: uint64_t currentlba;
! 496: unsigned short currentspan;
! 497: unsigned short flags;
! 498: unsigned char vendor_specific2[507-504+1];
! 499: unsigned short pendingtime;
! 500: unsigned char reserved2;
! 501: unsigned char checksum;
! 502: } ATTR_PACKED;
! 503: #pragma pack()
! 504: ASSERT_SIZEOF_STRUCT(ata_selective_self_test_log, 512);
! 505:
! 506: #define SELECTIVE_FLAG_DOSCAN (0x0002)
! 507: #define SELECTIVE_FLAG_PENDING (0x0008)
! 508: #define SELECTIVE_FLAG_ACTIVE (0x0010)
! 509:
! 510:
! 511: // SCT (SMART Command Transport) data structures
! 512: // See Sections 8.2 and 8.3 of:
! 513: // AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
! 514: // T13/1699-D Revision 3f (Working Draft), December 11, 2006.
! 515:
! 516: // SCT Status response (read with SMART_READ_LOG page 0xe0)
! 517: // Table 60 of T13/1699-D Revision 3f
! 518: #pragma pack(1)
! 519: struct ata_sct_status_response
! 520: {
! 521: unsigned short format_version; // 0-1: Status response format version number (2, 3)
! 522: unsigned short sct_version; // 2-3: Vendor specific version number
! 523: unsigned short sct_spec; // 4-5: SCT level supported (1)
! 524: unsigned int status_flags; // 6-9: Status flags (Bit 0: Segment initialized, Bits 1-31: reserved)
! 525: unsigned char device_state; // 10: Device State (0-5)
! 526: unsigned char bytes011_013[3]; // 11-13: reserved
! 527: unsigned short ext_status_code; // 14-15: Status of last SCT command (0xffff if executing)
! 528: unsigned short action_code; // 16-17: Action code of last SCT command
! 529: unsigned short function_code; // 18-19: Function code of last SCT command
! 530: unsigned char bytes020_039[20]; // 20-39: reserved
! 531: uint64_t lba_current; // 40-47: LBA of SCT command executing in background
! 532: unsigned char bytes048_199[152]; // 48-199: reserved
! 533: signed char hda_temp; // 200: Current temperature in Celsius (0x80 = invalid)
! 534: signed char min_temp; // 201: Minimum temperature this power cycle
! 535: signed char max_temp; // 202: Maximum temperature this power cycle
! 536: signed char life_min_temp; // 203: Minimum lifetime temperature
! 537: signed char life_max_temp; // 204: Maximum lifetime temperature
! 538: unsigned char byte205; // 205: reserved (T13/e06152r0-2: Average lifetime temperature)
! 539: unsigned int over_limit_count; // 206-209: # intervals since last reset with temperature > Max Op Limit
! 540: unsigned int under_limit_count; // 210-213: # intervals since last reset with temperature < Min Op Limit
! 541: unsigned char bytes214_479[266]; // 214-479: reserved
! 542: unsigned char vendor_specific[32];// 480-511: vendor specific
! 543: } ATTR_PACKED;
! 544: #pragma pack()
! 545: ASSERT_SIZEOF_STRUCT(ata_sct_status_response, 512);
! 546:
! 547: // SCT Error Recovery Control command (send with SMART_WRITE_LOG page 0xe0)
! 548: // Table 88 of T13/1699-D Revision 6a
! 549: #pragma pack(1)
! 550: struct ata_sct_error_recovery_control_command
! 551: {
! 552: unsigned short action_code; // 3 = Error Recovery Control
! 553: unsigned short function_code; // 1 = Set, 2 = Return
! 554: unsigned short selection_code; // 1 = Read Timer, 2 = Write Timer
! 555: unsigned short time_limit; // If set: Recovery time limit in 100ms units
! 556: unsigned short words004_255[252]; // reserved
! 557: } ATTR_PACKED;
! 558: #pragma pack()
! 559: ASSERT_SIZEOF_STRUCT(ata_sct_error_recovery_control_command, 512);
! 560:
! 561: // SCT Feature Control command (send with SMART_WRITE_LOG page 0xe0)
! 562: // Table 72 of T13/1699-D Revision 3f
! 563: #pragma pack(1)
! 564: struct ata_sct_feature_control_command
! 565: {
! 566: unsigned short action_code; // 4 = Feature Control
! 567: unsigned short function_code; // 1 = Set, 2 = Return, 3 = Return options
! 568: unsigned short feature_code; // 3 = Temperature logging interval
! 569: unsigned short state; // Interval
! 570: unsigned short option_flags; // Bit 0: persistent, Bits 1-15: reserved
! 571: unsigned short words005_255[251]; // reserved
! 572: } ATTR_PACKED;
! 573: #pragma pack()
! 574: ASSERT_SIZEOF_STRUCT(ata_sct_feature_control_command, 512);
! 575:
! 576: // SCT Data Table command (send with SMART_WRITE_LOG page 0xe0)
! 577: // Table 73 of T13/1699-D Revision 3f
! 578: #pragma pack(1)
! 579: struct ata_sct_data_table_command
! 580: {
! 581: unsigned short action_code; // 5 = Data Table
! 582: unsigned short function_code; // 1 = Read Table
! 583: unsigned short table_id; // 2 = Temperature History
! 584: unsigned short words003_255[253]; // reserved
! 585: } ATTR_PACKED;
! 586: #pragma pack()
! 587: ASSERT_SIZEOF_STRUCT(ata_sct_data_table_command, 512);
! 588:
! 589: // SCT Temperature History Table (read with SMART_READ_LOG page 0xe1)
! 590: // Table 75 of T13/1699-D Revision 3f
! 591: #pragma pack(1)
! 592: struct ata_sct_temperature_history_table
! 593: {
! 594: unsigned short format_version; // 0-1: Data table format version number (2)
! 595: unsigned short sampling_period; // 2-3: Temperature sampling period in minutes
! 596: unsigned short interval; // 4-5: Timer interval between history entries
! 597: signed char max_op_limit; // 6: Maximum recommended continuous operating temperature
! 598: signed char over_limit; // 7: Maximum temperature limit
! 599: signed char min_op_limit; // 8: Minimum recommended continuous operating limit
! 600: signed char under_limit; // 9: Minimum temperature limit
! 601: unsigned char bytes010_029[20]; // 10-29: reserved
! 602: unsigned short cb_size; // 30-31: Number of history entries (range 128-478)
! 603: unsigned short cb_index; // 32-33: Index of last updated entry (zero-based)
! 604: signed char cb[478]; // 34-(34+cb_size-1): Circular buffer of temperature values
! 605: } ATTR_PACKED;
! 606: #pragma pack()
! 607: ASSERT_SIZEOF_STRUCT(ata_sct_temperature_history_table, 512);
! 608:
! 609: // Possible values for span_args.mode
! 610: enum {
! 611: SEL_RANGE, // MIN-MAX
! 612: SEL_REDO, // redo this
! 613: SEL_NEXT, // do next range
! 614: SEL_CONT // redo or next depending of last test status
! 615: };
! 616:
! 617: // Arguments for selective self-test
! 618: struct ata_selective_selftest_args
! 619: {
! 620: // Arguments for each span
! 621: struct span_args
! 622: {
! 623: uint64_t start; // First block
! 624: uint64_t end; // Last block
! 625: int mode; // SEL_*, see above
! 626:
! 627: span_args()
! 628: : start(0), end(0), mode(SEL_RANGE) { }
! 629: };
! 630:
! 631: span_args span[5]; // Range and mode for 5 spans
! 632: int num_spans; // Number of spans
! 633: int pending_time; // One plus time in minutes to wait after powerup before restarting
! 634: // interrupted offline scan after selective self-test.
! 635: int scan_after_select; // Run offline scan after selective self-test:
! 636: // 0: don't change,
! 637: // 1: turn off scan after selective self-test,
! 638: // 2: turn on scan after selective self-test.
! 639:
! 640: ata_selective_selftest_args()
! 641: : num_spans(0), pending_time(0), scan_after_select(0) { }
! 642: };
! 643:
! 644: // Priority for vendor attribute defs
! 645: enum ata_vendor_def_prior
! 646: {
! 647: PRIOR_DEFAULT,
! 648: PRIOR_DATABASE,
! 649: PRIOR_USER
! 650: };
! 651:
! 652: // Raw attribute value print formats
! 653: enum ata_attr_raw_format
! 654: {
! 655: RAWFMT_DEFAULT,
! 656: RAWFMT_RAW8,
! 657: RAWFMT_RAW16,
! 658: RAWFMT_RAW48,
! 659: RAWFMT_HEX48,
! 660: RAWFMT_RAW64,
! 661: RAWFMT_HEX64,
! 662: RAWFMT_RAW16_OPT_RAW16,
! 663: RAWFMT_RAW16_OPT_AVG16,
! 664: RAWFMT_RAW24_DIV_RAW24,
! 665: RAWFMT_RAW24_DIV_RAW32,
! 666: RAWFMT_SEC2HOUR,
! 667: RAWFMT_MIN2HOUR,
! 668: RAWFMT_HALFMIN2HOUR,
! 669: RAWFMT_MSEC24_HOUR32,
! 670: RAWFMT_TEMPMINMAX,
! 671: RAWFMT_TEMP10X,
! 672: };
! 673:
! 674: // Attribute flags
! 675: enum {
! 676: ATTRFLAG_INCREASING = 0x01, // Value not reset (for reallocated/pending counts)
! 677: ATTRFLAG_NO_NORMVAL = 0x02, // Normalized value not valid
! 678: ATTRFLAG_NO_WORSTVAL = 0x04 // Worst value not valid
! 679: };
! 680:
! 681: // Vendor attribute display defs for all attribute ids
! 682: class ata_vendor_attr_defs
! 683: {
! 684: public:
! 685: struct entry
! 686: {
! 687: std::string name; // Attribute name, empty for default
! 688: ata_attr_raw_format raw_format; // Raw value print format
! 689: ata_vendor_def_prior priority; // Setting priority
! 690: unsigned flags; // ATTRFLAG_*
! 691: char byteorder[8+1]; // String [012345rvwz] to define byte order
! 692:
! 693: entry()
! 694: : raw_format(RAWFMT_DEFAULT),
! 695: priority(PRIOR_DEFAULT),
! 696: flags(0)
! 697: { byteorder[0] = 0; }
! 698: };
! 699:
! 700: entry & operator[](unsigned char id)
! 701: { return m_defs[id]; }
! 702:
! 703: const entry & operator[](unsigned char id) const
! 704: { return m_defs[id]; }
! 705:
! 706: private:
! 707: entry m_defs[256];
! 708: };
! 709:
! 710:
! 711: // Print ATA debug messages?
! 712: extern unsigned char ata_debugmode;
! 713:
! 714: // Suppress serial number?
! 715: extern bool dont_print_serial_number;
! 716:
! 717: // Get information from drive
! 718: int ata_read_identity(ata_device * device, ata_identify_device * buf, bool fix_swapped_id);
! 719: int ataCheckPowerMode(ata_device * device);
! 720:
! 721: /* Read S.M.A.R.T information from drive */
! 722: int ataReadSmartValues(ata_device * device,struct ata_smart_values *);
! 723: int ataReadSmartThresholds(ata_device * device, struct ata_smart_thresholds_pvt *);
! 724: int ataReadErrorLog (ata_device * device, ata_smart_errorlog *data,
! 725: unsigned char fix_firmwarebug);
! 726: int ataReadSelfTestLog(ata_device * device, ata_smart_selftestlog * data,
! 727: unsigned char fix_firmwarebug);
! 728: int ataReadSelectiveSelfTestLog(ata_device * device, struct ata_selective_self_test_log *data);
! 729: int ataSetSmartThresholds(ata_device * device, struct ata_smart_thresholds_pvt *);
! 730: int ataReadLogDirectory(ata_device * device, ata_smart_log_directory *, bool gpl);
! 731:
! 732: // Read GP Log page(s)
! 733: bool ataReadLogExt(ata_device * device, unsigned char logaddr,
! 734: unsigned char features, unsigned page,
! 735: void * data, unsigned nsectors);
! 736: // Read SMART Log page(s)
! 737: bool ataReadSmartLog(ata_device * device, unsigned char logaddr,
! 738: void * data, unsigned nsectors);
! 739: // Read SMART Extended Comprehensive Error Log
! 740: bool ataReadExtErrorLog(ata_device * device, ata_smart_exterrlog * log,
! 741: unsigned nsectors);
! 742: // Read SMART Extended Self-test Log
! 743: bool ataReadExtSelfTestLog(ata_device * device, ata_smart_extselftestlog * log,
! 744: unsigned nsectors);
! 745:
! 746: // Read SCT information
! 747: int ataReadSCTStatus(ata_device * device, ata_sct_status_response * sts);
! 748: int ataReadSCTTempHist(ata_device * device, ata_sct_temperature_history_table * tmh,
! 749: ata_sct_status_response * sts);
! 750: // Set SCT temperature logging interval
! 751: int ataSetSCTTempInterval(ata_device * device, unsigned interval, bool persistent);
! 752:
! 753: // Get/Set SCT Error Recovery Control
! 754: int ataGetSCTErrorRecoveryControltime(ata_device * device, unsigned type, unsigned short & time_limit);
! 755: int ataSetSCTErrorRecoveryControltime(ata_device * device, unsigned type, unsigned short time_limit);
! 756:
! 757:
! 758: /* Enable/Disable SMART on device */
! 759: int ataEnableSmart (ata_device * device);
! 760: int ataDisableSmart (ata_device * device);
! 761: int ataEnableAutoSave(ata_device * device);
! 762: int ataDisableAutoSave(ata_device * device);
! 763:
! 764: /* Automatic Offline Testing */
! 765: int ataEnableAutoOffline (ata_device * device);
! 766: int ataDisableAutoOffline (ata_device * device);
! 767:
! 768: /* S.M.A.R.T. test commands */
! 769: int ataSmartOfflineTest (ata_device * device);
! 770: int ataSmartExtendSelfTest (ata_device * device);
! 771: int ataSmartShortSelfTest (ata_device * device);
! 772: int ataSmartShortCapSelfTest (ata_device * device);
! 773: int ataSmartExtendCapSelfTest (ata_device * device);
! 774: int ataSmartSelfTestAbort (ata_device * device);
! 775: int ataWriteSelectiveSelfTestLog(ata_device * device, ata_selective_selftest_args & args,
! 776: const ata_smart_values * sv, uint64_t num_sectors,
! 777: const ata_selective_selftest_args * prev_spans = 0);
! 778:
! 779: // Returns the latest compatibility of ATA/ATAPI Version the device
! 780: // supports. Returns -1 if Version command is not supported
! 781: int ataVersionInfo(const char ** description, const ata_identify_device * drive, unsigned short * minor);
! 782:
! 783: // Get World Wide Name (WWN) fields.
! 784: // Return NAA field or -1 if WWN is unsupported.
! 785: int ata_get_wwn(const ata_identify_device * id, unsigned & oui, uint64_t & unique_id);
! 786:
! 787: // If SMART supported, this is guaranteed to return 1 if SMART is enabled, else 0.
! 788: int ataDoesSmartWork(ata_device * device);
! 789:
! 790: // returns 1 if SMART supported, 0 if not supported or can't tell
! 791: int ataSmartSupport(const ata_identify_device * drive);
! 792:
! 793: // Return values:
! 794: // 1: SMART enabled
! 795: // 0: SMART disabled
! 796: // -1: can't tell if SMART is enabled -- try issuing ataDoesSmartWork command to see
! 797: int ataIsSmartEnabled(const ata_identify_device * drive);
! 798:
! 799: int ataSmartStatus2(ata_device * device);
! 800:
! 801: int isSmartErrorLogCapable(const ata_smart_values * data, const ata_identify_device * identity);
! 802:
! 803: int isSmartTestLogCapable(const ata_smart_values * data, const ata_identify_device * identity);
! 804:
! 805: int isGeneralPurposeLoggingCapable(const ata_identify_device * identity);
! 806:
! 807: int isSupportExecuteOfflineImmediate(const ata_smart_values * data);
! 808:
! 809: int isSupportAutomaticTimer(const ata_smart_values * data);
! 810:
! 811: int isSupportOfflineAbort(const ata_smart_values * data);
! 812:
! 813: int isSupportOfflineSurfaceScan(const ata_smart_values * data);
! 814:
! 815: int isSupportSelfTest(const ata_smart_values * data);
! 816:
! 817: int isSupportConveyanceSelfTest(const ata_smart_values * data);
! 818:
! 819: int isSupportSelectiveSelfTest(const ata_smart_values * data);
! 820:
! 821: inline bool isSCTCapable(const ata_identify_device *drive)
! 822: { return !!(drive->words088_255[206-88] & 0x01); } // 0x01 = SCT support
! 823:
! 824: inline bool isSCTErrorRecoveryControlCapable(const ata_identify_device *drive)
! 825: { return ((drive->words088_255[206-88] & 0x09) == 0x09); } // 0x08 = SCT Error Recovery Control support
! 826:
! 827: inline bool isSCTFeatureControlCapable(const ata_identify_device *drive)
! 828: { return ((drive->words088_255[206-88] & 0x11) == 0x11); } // 0x10 = SCT Feature Control support
! 829:
! 830: inline bool isSCTDataTableCapable(const ata_identify_device *drive)
! 831: { return ((drive->words088_255[206-88] & 0x21) == 0x21); } // 0x20 = SCT Data Table support
! 832:
! 833: int ataSmartTest(ata_device * device, int testtype, const ata_selective_selftest_args & args,
! 834: const ata_smart_values * sv, uint64_t num_sectors);
! 835:
! 836: int TestTime(const ata_smart_values * data, int testtype);
! 837:
! 838: // Attribute state
! 839: enum ata_attr_state
! 840: {
! 841: ATTRSTATE_NON_EXISTING, // No such Attribute
! 842: ATTRSTATE_NO_NORMVAL, // Normalized value not valid
! 843: ATTRSTATE_NO_THRESHOLD, // Unknown or no threshold
! 844: ATTRSTATE_OK, // Never failed
! 845: ATTRSTATE_FAILED_PAST, // Failed in the past
! 846: ATTRSTATE_FAILED_NOW // Failed now
! 847: };
! 848:
! 849: // Get attribute state
! 850: ata_attr_state ata_get_attr_state(const ata_smart_attribute & attr,
! 851: int attridx,
! 852: const ata_smart_threshold_entry * thresholds,
! 853: const ata_vendor_attr_defs & defs,
! 854: unsigned char * threshval = 0);
! 855:
! 856: // Get attribute raw value.
! 857: uint64_t ata_get_attr_raw_value(const ata_smart_attribute & attr,
! 858: const ata_vendor_attr_defs & defs);
! 859:
! 860: // Format attribute raw value.
! 861: std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
! 862: const ata_vendor_attr_defs & defs);
! 863:
! 864: // Get attribute name
! 865: std::string ata_get_smart_attr_name(unsigned char id,
! 866: const ata_vendor_attr_defs & defs);
! 867:
! 868: // External handler function, for when a checksum is not correct. Can
! 869: // simply return if no action is desired, or can print error messages
! 870: // as needed, or exit. Is passed a string with the name of the Data
! 871: // Structure with the incorrect checksum.
! 872: void checksumwarning(const char *string);
! 873:
! 874: // Find attribute index for attribute id, -1 if not found.
! 875: int ata_find_attr_index(unsigned char id, const ata_smart_values & smartval);
! 876:
! 877: // Return Temperature Attribute raw value selected according to possible
! 878: // non-default interpretations. If the Attribute does not exist, return 0
! 879: unsigned char ata_return_temperature_value(const ata_smart_values * data, const ata_vendor_attr_defs & defs);
! 880:
! 881:
! 882: // This are the meanings of the Self-test failure checkpoint byte.
! 883: // This is in the self-test log at offset 4 bytes into the self-test
! 884: // descriptor and in the SMART READ DATA structure at byte offset
! 885: // 371. These codes are not well documented. The meanings returned by
! 886: // this routine are used (at least) by Maxtor and IBM. Returns NULL if
! 887: // not recognized.
! 888: const char *SelfTestFailureCodeName(unsigned char which);
! 889:
! 890:
! 891: #define MAX_ATTRIBUTE_NUM 256
! 892:
! 893: // Parse vendor attribute display def (-v option).
! 894: // Return false on error.
! 895: bool parse_attribute_def(const char * opt, ata_vendor_attr_defs & defs,
! 896: ata_vendor_def_prior priority);
! 897:
! 898: // Get ID and increase flag of current pending or offline
! 899: // uncorrectable attribute.
! 900: unsigned char get_unc_attr_id(bool offline, const ata_vendor_attr_defs & defs,
! 901: bool & increase);
! 902:
! 903: // Return a multiline string containing a list of valid arguments for
! 904: // parse_attribute_def().
! 905: std::string create_vendor_attribute_arg_list();
! 906:
! 907:
! 908: // These are two of the functions that are defined in os_*.c and need
! 909: // to be ported to get smartmontools onto another OS.
! 910: // Moved to C++ interface
! 911: //int ata_command_interface(int device, smart_command_set command, int select, char *data);
! 912: //int escalade_command_interface(int fd, int escalade_port, int escalade_type, smart_command_set command, int select, char *data);
! 913: //int marvell_command_interface(int device, smart_command_set command, int select, char *data);
! 914: //int highpoint_command_interface(int device, smart_command_set command, int select, char *data);
! 915: //int areca_command_interface(int fd, int disknum, smart_command_set command, int select, char *data);
! 916:
! 917:
! 918: // Optional functions of os_*.c
! 919: #ifdef HAVE_ATA_IDENTIFY_IS_CACHED
! 920: // Return true if OS caches the ATA identify sector
! 921: //int ata_identify_is_cached(int fd);
! 922: #endif
! 923:
! 924: // This function is exported to give low-level capability
! 925: int smartcommandhandler(ata_device * device, smart_command_set command, int select, char *data);
! 926:
! 927: // Print one self-test log entry.
! 928: // Returns:
! 929: // -1: failed self-test
! 930: // 1: extended self-test completed without error
! 931: // 0: otherwise
! 932: int ataPrintSmartSelfTestEntry(unsigned testnum, unsigned char test_type,
! 933: unsigned char test_status,
! 934: unsigned short timestamp,
! 935: uint64_t failing_lba,
! 936: bool print_error_only, bool & print_header);
! 937:
! 938: // Print Smart self-test log, used by smartctl and smartd.
! 939: int ataPrintSmartSelfTestlog(const ata_smart_selftestlog * data, bool allentries,
! 940: unsigned char fix_firmwarebug);
! 941:
! 942: // Get capacity and sector sizes from IDENTIFY data
! 943: struct ata_size_info
! 944: {
! 945: uint64_t sectors;
! 946: uint64_t capacity;
! 947: unsigned log_sector_size;
! 948: unsigned phy_sector_size;
! 949: unsigned log_sector_offset;
! 950: };
! 951:
! 952: void ata_get_size_info(const ata_identify_device * id, ata_size_info & sizes);
! 953:
! 954: // Convenience function for formatting strings from ata_identify_device.
! 955: void ata_format_id_string(char * out, const unsigned char * in, int n);
! 956:
! 957: // Utility routines.
! 958: unsigned char checksum(const void * data);
! 959:
! 960: void swap2(char *location);
! 961: void swap4(char *location);
! 962: void swap8(char *location);
! 963: // Typesafe variants using overloading
! 964: inline void swapx(unsigned short * p)
! 965: { swap2((char*)p); }
! 966: inline void swapx(unsigned int * p)
! 967: { swap4((char*)p); }
! 968: inline void swapx(uint64_t * p)
! 969: { swap8((char*)p); }
! 970:
! 971: // Return pseudo-device to parse "smartctl -r ataioctl,2 ..." output
! 972: // and simulate an ATA device with same behaviour
! 973: ata_device * get_parsed_ata_device(smart_interface * intf, const char * dev_name);
! 974:
! 975: #endif /* ATACMDS_H_ */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>