else if (!strcmp(a->name, "reallocated-sector-count") ||
!strcmp(a->name, "current-pending-sector"))
a->pretty_value = fourtyeight & 0xFFFFFFFFU;
+ else if (!strcmp(a->name, "endurance-remaining") ||
+ !strcmp(a->name, "available-reserved-space"))
+ a->pretty_value = a->current_value;
+ else if (!strcmp(a->name, "total-lbas-written") ||
+ !strcmp(a->name, "total-lbas-read"))
+ a->pretty_value = fourtyeight * 65536LLU * 512LLU / 1000000LLU;
+ else if (!strcmp(a->name, "timed-workload-media-wear") ||
+ !strcmp(a->name, "timed-workload-host-reads"))
+ a->pretty_value = (double)fourtyeight / 1024LLU;
+ else if (!strcmp(a->name, "workload-timer"))
+ a->pretty_value = fourtyeight * 60 * 1000;
else
a->pretty_value = fourtyeight;
}
max_sectors = d->size / 512ULL;
- if (max_sectors > 0 && a->pretty_value > max_sectors) {
+ if (a->pretty_value == 0xffffffffULL ||
+ a->pretty_value == 0xffffffffffffffffULL ||
+ (max_sectors > 0 && a->pretty_value > max_sectors)) {
a->pretty_value = SK_SMART_ATTRIBUTE_UNIT_UNKNOWN;
d->attribute_verification_bad = TRUE;
} else {
[11] = { "calibration-retry-count", SK_SMART_ATTRIBUTE_UNIT_NONE, NULL },
[12] = { "power-cycle-count", SK_SMART_ATTRIBUTE_UNIT_NONE, NULL },
[13] = { "read-soft-error-rate", SK_SMART_ATTRIBUTE_UNIT_NONE, NULL },
+ [170] = { "available-reserved-space", SK_SMART_ATTRIBUTE_UNIT_PERCENT, NULL },
+ [171] = { "program-fail-count", SK_SMART_ATTRIBUTE_UNIT_NONE, NULL },
+ [172] = { "erase-fail-count", SK_SMART_ATTRIBUTE_UNIT_NONE, NULL },
+ [184] = { "end-to-end-error", SK_SMART_ATTRIBUTE_UNIT_NONE, NULL },
[187] = { "reported-uncorrect", SK_SMART_ATTRIBUTE_UNIT_SECTORS, verify_sectors },
+ [188] = { "command-timeout", SK_SMART_ATTRIBUTE_UNIT_NONE, NULL },
[189] = { "high-fly-writes", SK_SMART_ATTRIBUTE_UNIT_NONE, NULL },
[190] = { "airflow-temperature-celsius", SK_SMART_ATTRIBUTE_UNIT_MKELVIN, verify_temperature },
[191] = { "g-sense-error-rate", SK_SMART_ATTRIBUTE_UNIT_NONE, NULL },
[231] = { "temperature-celsius", SK_SMART_ATTRIBUTE_UNIT_MKELVIN, verify_temperature },
/* http://www.adtron.com/pdf/SMART_for_XceedLite_SATA_RevA.pdf */
- [232] = { "endurance-remaining", SK_SMART_ATTRIBUTE_UNIT_UNKNOWN, NULL },
+ [232] = { "endurance-remaining", SK_SMART_ATTRIBUTE_UNIT_PERCENT, NULL },
[233] = { "power-on-seconds-2", SK_SMART_ATTRIBUTE_UNIT_UNKNOWN, NULL },
[234] = { "uncorrectable-ecc-count", SK_SMART_ATTRIBUTE_UNIT_SECTORS, NULL },
[235] = { "good-block-rate", SK_SMART_ATTRIBUTE_UNIT_UNKNOWN, NULL },
[240] = { "head-flying-hours", SK_SMART_ATTRIBUTE_UNIT_MSECONDS, verify_long_time },
+ [241] = { "total-lbas-written", SK_SMART_ATTRIBUTE_UNIT_MB, NULL },
+ [242] = { "total-lbas-read", SK_SMART_ATTRIBUTE_UNIT_MB, NULL },
[250] = { "read-error-retry-rate", SK_SMART_ATTRIBUTE_UNIT_NONE, NULL }
};
/* %STRINGPOOLSTOP% */
typedef enum SkSmartQuirk {
- SK_SMART_QUIRK_9_POWERONMINUTES = 0x0001,
- SK_SMART_QUIRK_9_POWERONSECONDS = 0x0002,
- SK_SMART_QUIRK_9_POWERONHALFMINUTES = 0x0004,
- SK_SMART_QUIRK_192_EMERGENCYRETRACTCYCLECT = 0x0008,
- SK_SMART_QUIRK_193_LOADUNLOAD = 0x0010,
- SK_SMART_QUIRK_194_10XCELSIUS = 0x0020,
- SK_SMART_QUIRK_194_UNKNOWN = 0x0040,
- SK_SMART_QUIRK_200_WRITEERRORCOUNT = 0x0080,
- SK_SMART_QUIRK_201_DETECTEDTACOUNT = 0x0100,
- SK_SMART_QUIRK_5_UNKNOWN = 0x0200,
- SK_SMART_QUIRK_9_UNKNOWN = 0x0400,
- SK_SMART_QUIRK_197_UNKNOWN = 0x0800,
- SK_SMART_QUIRK_198_UNKNOWN = 0x1000,
- SK_SMART_QUIRK_190_UNKNOWN = 0x2000
+ SK_SMART_QUIRK_9_POWERONMINUTES = 0x000001,
+ SK_SMART_QUIRK_9_POWERONSECONDS = 0x000002,
+ SK_SMART_QUIRK_9_POWERONHALFMINUTES = 0x000004,
+ SK_SMART_QUIRK_192_EMERGENCYRETRACTCYCLECT = 0x000008,
+ SK_SMART_QUIRK_193_LOADUNLOAD = 0x000010,
+ SK_SMART_QUIRK_194_10XCELSIUS = 0x000020,
+ SK_SMART_QUIRK_194_UNKNOWN = 0x000040,
+ SK_SMART_QUIRK_200_WRITEERRORCOUNT = 0x000080,
+ SK_SMART_QUIRK_201_DETECTEDTACOUNT = 0x000100,
+ SK_SMART_QUIRK_5_UNKNOWN = 0x000200,
+ SK_SMART_QUIRK_9_UNKNOWN = 0x000400,
+ SK_SMART_QUIRK_197_UNKNOWN = 0x000800,
+ SK_SMART_QUIRK_198_UNKNOWN = 0x001000,
+ SK_SMART_QUIRK_190_UNKNOWN = 0x002000,
+ SK_SMART_QUIRK_232_AVAILABLERESERVEDSPACE = 0x004000,
+ SK_SMART_QUIRK_233_MEDIAWEAROUTINDICATOR = 0x008000,
+ SK_SMART_QUIRK_225_TOTALLBASWRITTEN = 0x010000,
+ SK_SMART_QUIRK_4_UNUSED = 0x020000,
+ SK_SMART_QUIRK_226_TIMEWORKLOADMEDIAWEAR = 0x040000,
+ SK_SMART_QUIRK_227_TIMEWORKLOADHOSTREADS = 0x080000,
+ SK_SMART_QUIRK_228_WORKLOADTIMER = 0x100000,
+ SK_SMART_QUIRK_3_UNUSED = 0x200000
} SkSmartQuirk;
/* %STRINGPOOLSTART% */
"197_UNKNOWN",
"198_UNKNOWN",
"190_UNKNOWN",
+ "232_AVAILABLERESERVEDSPACE",
+ "233_MEDIAWEAROUTINDICATOR",
+ "225_TOTALLBASWRITTEN",
+ "4_UNUSED",
+ "226_TIMEWORKLOADMEDIAWEAR",
+ "227_TIMEWORKLOADHOSTREADS",
+ "228_WORKLOADTIMER",
+ "3_UNUSED",
NULL
};
/* %STRINGPOOLSTOP% */
SK_SMART_QUIRK_5_UNKNOWN|
SK_SMART_QUIRK_190_UNKNOWN
}, {
+
+ /*** Intel */
+ "^INTEL SSDSA2CW[0-9]{3}G3$",
+ NULL,
+ SK_SMART_QUIRK_3_UNUSED|
+ SK_SMART_QUIRK_4_UNUSED|
+ SK_SMART_QUIRK_225_TOTALLBASWRITTEN|
+ SK_SMART_QUIRK_226_TIMEWORKLOADMEDIAWEAR|
+ SK_SMART_QUIRK_227_TIMEWORKLOADHOSTREADS|
+ SK_SMART_QUIRK_228_WORKLOADTIMER|
+ SK_SMART_QUIRK_232_AVAILABLERESERVEDSPACE|
+ SK_SMART_QUIRK_233_MEDIAWEAROUTINDICATOR
+ }, {
NULL,
NULL,
0
if (quirk) {
switch (id) {
+ case 3:
+ /* %STRINGPOOLSTART% */
+ if (quirk & SK_SMART_QUIRK_3_UNUSED) {
+ static const SkSmartAttributeInfo a = {
+ "spin-up-time", SK_SMART_ATTRIBUTE_UNIT_UNKNOWN, NULL
+ };
+ return &a;
+ }
+ /* %STRINGPOOLSTOP% */
+
+ break;
+
+ case 4:
+ /* %STRINGPOOLSTART% */
+ if (quirk & SK_SMART_QUIRK_4_UNUSED) {
+ static const SkSmartAttributeInfo a = {
+ "start-stop-count", SK_SMART_ATTRIBUTE_UNIT_UNKNOWN, NULL
+ };
+ return &a;
+ }
+ /* %STRINGPOOLSTOP% */
+
+ break;
case 5:
if (quirk & SK_SMART_QUIRK_5_UNKNOWN)
/* %STRINGPOOLSTOP% */
break;
+
+ case 225:
+ /* %STRINGPOOLSTART% */
+ if (quirk & SK_SMART_QUIRK_225_TOTALLBASWRITTEN) {
+ static const SkSmartAttributeInfo a = {
+ "total-lbas-written", SK_SMART_ATTRIBUTE_UNIT_MB, NULL
+ };
+ return &a;
+ }
+ /* %STRINGPOOLSTOP% */
+
+ break;
+
+ case 226:
+ /* %STRINGPOOLSTART% */
+ if (quirk & SK_SMART_QUIRK_226_TIMEWORKLOADMEDIAWEAR) {
+ static const SkSmartAttributeInfo a = {
+ "timed-workload-media-wear", SK_SMART_ATTRIBUTE_UNIT_SMALL_PERCENT, NULL
+ };
+ return &a;
+ }
+ /* %STRINGPOOLSTOP% */
+
+ break;
+
+ case 227:
+ /* %STRINGPOOLSTART% */
+ if (quirk & SK_SMART_QUIRK_227_TIMEWORKLOADHOSTREADS) {
+ static const SkSmartAttributeInfo a = {
+ "timed-workload-host-reads", SK_SMART_ATTRIBUTE_UNIT_SMALL_PERCENT, NULL
+ };
+ return &a;
+ }
+ /* %STRINGPOOLSTOP% */
+
+ break;
+
+ case 228:
+ /* %STRINGPOOLSTART% */
+ if (quirk & SK_SMART_QUIRK_228_WORKLOADTIMER) {
+ static const SkSmartAttributeInfo a = {
+ "workload-timer", SK_SMART_ATTRIBUTE_UNIT_MSECONDS, NULL
+ };
+ return &a;
+ }
+ /* %STRINGPOOLSTOP% */
+
+ break;
+
+ case 232:
+ /* %STRINGPOOLSTART% */
+ if (quirk & SK_SMART_QUIRK_232_AVAILABLERESERVEDSPACE) {
+ static const SkSmartAttributeInfo a = {
+ "available-reserved-space", SK_SMART_ATTRIBUTE_UNIT_PERCENT, NULL
+ };
+ return &a;
+ }
+ /* %STRINGPOOLSTOP% */
+ break;
+
+ case 233:
+ /* %STRINGPOOLSTART% */
+ if (quirk & SK_SMART_QUIRK_233_MEDIAWEAROUTINDICATOR) {
+ static const SkSmartAttributeInfo a = {
+ "media-wearout-indicator", SK_SMART_ATTRIBUTE_UNIT_PERCENT, NULL
+ };
+ return &a;
+ }
+ /* %STRINGPOOLSTOP% */
+ break;
+
}
}
[SK_SMART_ATTRIBUTE_UNIT_NONE] = "",
[SK_SMART_ATTRIBUTE_UNIT_MSECONDS] = "ms",
[SK_SMART_ATTRIBUTE_UNIT_SECTORS] = "sectors",
- [SK_SMART_ATTRIBUTE_UNIT_MKELVIN] = "mK"
+ [SK_SMART_ATTRIBUTE_UNIT_MKELVIN] = "mK",
+ [SK_SMART_ATTRIBUTE_UNIT_PERCENT] = "%",
+ [SK_SMART_ATTRIBUTE_UNIT_SMALL_PERCENT] = "%",
+ [SK_SMART_ATTRIBUTE_UNIT_MB] = "MB"
};
/* %STRINGPOOLSTOP% */
snprintf(s, len, "%llu sectors", (unsigned long long) pretty_value);
break;
+ case SK_SMART_ATTRIBUTE_UNIT_PERCENT:
+ snprintf(s, len, "%llu%%", (unsigned long long) pretty_value);
+ break;
+
+ case SK_SMART_ATTRIBUTE_UNIT_SMALL_PERCENT:
+ snprintf(s, len, "%0.3f%%", (double) pretty_value);
+ break;
+
+ case SK_SMART_ATTRIBUTE_UNIT_MB:
+ if (pretty_value >= 1000000LLU)
+ snprintf(s, len, "%0.3f TB", (double) pretty_value / 1000000LLU);
+ else if (pretty_value >= 1000LLU)
+ snprintf(s, len, "%0.3f GB", (double) pretty_value / 1000LLU);
+ else
+ snprintf(s, len, "%llu MB", (unsigned long long) pretty_value);
+ break;
+
case SK_SMART_ATTRIBUTE_UNIT_NONE:
snprintf(s, len, "%llu", (unsigned long long) pretty_value);
break;