1*7419d6e4SChuck Tuffli /*
2*7419d6e4SChuck Tuffli * Copyright (c) 2021 Chuck Tuffli <chuck@tuffli.net>
3*7419d6e4SChuck Tuffli *
4*7419d6e4SChuck Tuffli * Permission to use, copy, modify, and distribute this software for any
5*7419d6e4SChuck Tuffli * purpose with or without fee is hereby granted, provided that the above
6*7419d6e4SChuck Tuffli * copyright notice and this permission notice appear in all copies.
7*7419d6e4SChuck Tuffli *
8*7419d6e4SChuck Tuffli * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9*7419d6e4SChuck Tuffli * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10*7419d6e4SChuck Tuffli * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11*7419d6e4SChuck Tuffli * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12*7419d6e4SChuck Tuffli * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13*7419d6e4SChuck Tuffli * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14*7419d6e4SChuck Tuffli * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*7419d6e4SChuck Tuffli */
16*7419d6e4SChuck Tuffli #include <stddef.h>
17*7419d6e4SChuck Tuffli
18*7419d6e4SChuck Tuffli #include "libsmart.h"
19*7419d6e4SChuck Tuffli #include "libsmart_priv.h"
20*7419d6e4SChuck Tuffli
21*7419d6e4SChuck Tuffli /* Strings from "SMART Attribute Descriptions" (SAD) */
22*7419d6e4SChuck Tuffli static const char *
23*7419d6e4SChuck Tuffli desc_ata_data[] = {
24*7419d6e4SChuck Tuffli [1] = "Read Error Rate",
25*7419d6e4SChuck Tuffli [2] = "Throughput Performance",
26*7419d6e4SChuck Tuffli [3] = "Spin-Up Time",
27*7419d6e4SChuck Tuffli [4] = "Start/Stop Count",
28*7419d6e4SChuck Tuffli [5] = "Reallocated Sectors Count",
29*7419d6e4SChuck Tuffli [6] = "Read Channel Margin",
30*7419d6e4SChuck Tuffli [7] = "Seek Error Rate",
31*7419d6e4SChuck Tuffli [8] = "Seek Time Performance",
32*7419d6e4SChuck Tuffli [9] = "Power-On Hours",
33*7419d6e4SChuck Tuffli [10] = "Spin Retry Count",
34*7419d6e4SChuck Tuffli [11] = "Calibration Retry Count",
35*7419d6e4SChuck Tuffli [12] = "Power Cycle Count",
36*7419d6e4SChuck Tuffli [13] = "Soft Read Error Rate",
37*7419d6e4SChuck Tuffli [22] = "Current Helium Level", /* HGST */
38*7419d6e4SChuck Tuffli [170] = "Available Reserved Space", /* Intel */
39*7419d6e4SChuck Tuffli [171] = "SSD Program Fail", /* Kingston? */
40*7419d6e4SChuck Tuffli [172] = "SSD Erase Fail Count", /* Kingston? */
41*7419d6e4SChuck Tuffli [173] = "SSD Wear Leveling Count", /* HPE SSD Endurance Limit */
42*7419d6e4SChuck Tuffli [174] = "Unexpected Power Loss Count", /* Intel */
43*7419d6e4SChuck Tuffli [175] = "Power Loss Protection Failure", /* Intel */
44*7419d6e4SChuck Tuffli [176] = "Erase Fail Count (chip)",
45*7419d6e4SChuck Tuffli [177] = "Wear Range Delta",
46*7419d6e4SChuck Tuffli [179] = "Used Reserved Block Count Total",
47*7419d6e4SChuck Tuffli /* [180] = HPE, Seagate, Intel differences */
48*7419d6e4SChuck Tuffli [181] = "Non-4K Aligned Access Count", /* Micron. Conflict Kingston */
49*7419d6e4SChuck Tuffli [182] = "Erase Fail Count",
50*7419d6e4SChuck Tuffli [183] = "Runtime Bad Block",
51*7419d6e4SChuck Tuffli [184] = "End-to-End Error",
52*7419d6e4SChuck Tuffli [185] = "Head Stability", /* WD */
53*7419d6e4SChuck Tuffli [186] = "Induced Op-Vibration Detection", /* WD */
54*7419d6e4SChuck Tuffli [187] = "Reported Uncorrectable Errors",
55*7419d6e4SChuck Tuffli [188] = "Command Timeout",
56*7419d6e4SChuck Tuffli [189] = "High Fly Writes",
57*7419d6e4SChuck Tuffli [190] = "Airflow Temperature", /* WDC, HPE conflict */
58*7419d6e4SChuck Tuffli [191] = "G-Sense Error Rate",
59*7419d6e4SChuck Tuffli [192] = "Power-Off Count", /* HPE, Seagate */
60*7419d6e4SChuck Tuffli [193] = "Load/Unload Cycle Count",
61*7419d6e4SChuck Tuffli [194] = "Temperature Celsius",
62*7419d6e4SChuck Tuffli [195] = "Hardware ECC Recovered",
63*7419d6e4SChuck Tuffli [196] = "Reallocation Event Count",
64*7419d6e4SChuck Tuffli [197] = "Current Pending Sector Count",
65*7419d6e4SChuck Tuffli [198] = "Uncorrectable Sector Count", /* Fujitsu */
66*7419d6e4SChuck Tuffli [199] = "UltraDMA CRC Error Count",
67*7419d6e4SChuck Tuffli [200] = "Write Error Rate",
68*7419d6e4SChuck Tuffli [201] = "Soft Read Error Rate",
69*7419d6e4SChuck Tuffli [202] = "Data Address Mark Errors",
70*7419d6e4SChuck Tuffli [203] = "Run Out Cancel",
71*7419d6e4SChuck Tuffli [204] = "Soft ECC Correction",
72*7419d6e4SChuck Tuffli [205] = "Thermal Asperity Rate",
73*7419d6e4SChuck Tuffli [206] = "Flying Height",
74*7419d6e4SChuck Tuffli [207] = "Spin High Current",
75*7419d6e4SChuck Tuffli [208] = "Spin Buzz",
76*7419d6e4SChuck Tuffli [209] = "Offline Seek Performnce",
77*7419d6e4SChuck Tuffli [210] = "Vibration, During Write", /* Maxtor */
78*7419d6e4SChuck Tuffli [211] = "Vibration During Write", /* Acronis */
79*7419d6e4SChuck Tuffli [212] = "Shock During Write", /* Acronis */
80*7419d6e4SChuck Tuffli [220] = "Disk Shift",
81*7419d6e4SChuck Tuffli [221] = "G-Sense Error Rate",
82*7419d6e4SChuck Tuffli [222] = "Loaded Hours",
83*7419d6e4SChuck Tuffli [223] = "Load/Unload Retry Count",
84*7419d6e4SChuck Tuffli [224] = "Load Friction",
85*7419d6e4SChuck Tuffli [225] = "Load/Unload Cycle Count",
86*7419d6e4SChuck Tuffli [226] = "Load-in Time",
87*7419d6e4SChuck Tuffli [227] = "Torque Amplification Count",
88*7419d6e4SChuck Tuffli [228] = "Power-off Retract Cycle",
89*7419d6e4SChuck Tuffli [230] = "GMR Head Amplitude Drive Life Protection Status",
90*7419d6e4SChuck Tuffli [231] = "Temperature SSD Life Left", /* Kingston */
91*7419d6e4SChuck Tuffli [232] = "Endurance Remaining", /* Multiple conflict */
92*7419d6e4SChuck Tuffli [233] = "Power-On Hours", /* Multiple conflict */
93*7419d6e4SChuck Tuffli [234] = "Average Erase Count", /* Multiple conflict */
94*7419d6e4SChuck Tuffli [235] = "Good Block Count", /* Multiple conflict */
95*7419d6e4SChuck Tuffli [240] = "Head Flying Hours",
96*7419d6e4SChuck Tuffli [241] = "Total LBAs Written",
97*7419d6e4SChuck Tuffli [242] = "Total LBAs Read",
98*7419d6e4SChuck Tuffli [243] = "Total LBAs Written Expanded", /* Multiple conflict */
99*7419d6e4SChuck Tuffli [244] = "Total LBAs Read Expanded", /* Multiple conflict */
100*7419d6e4SChuck Tuffli [250] = "Read Error Rate",
101*7419d6e4SChuck Tuffli [251] = "Minimum Spares Remaining",
102*7419d6e4SChuck Tuffli [252] = "Newly Added Bad Flash Block",
103*7419d6e4SChuck Tuffli [254] = "Free Fall Protection"
104*7419d6e4SChuck Tuffli };
105*7419d6e4SChuck Tuffli
106*7419d6e4SChuck Tuffli const char *
__smart_ata_desc(uint32_t page,uint32_t id)107*7419d6e4SChuck Tuffli __smart_ata_desc(uint32_t page, uint32_t id)
108*7419d6e4SChuck Tuffli {
109*7419d6e4SChuck Tuffli const char *desc = NULL;
110*7419d6e4SChuck Tuffli
111*7419d6e4SChuck Tuffli switch (page) {
112*7419d6e4SChuck Tuffli case PAGE_ID_ATA_SMART_READ_DATA:
113*7419d6e4SChuck Tuffli if (desc_ata_data[id] != NULL)
114*7419d6e4SChuck Tuffli desc = desc_ata_data[id];
115*7419d6e4SChuck Tuffli break;
116*7419d6e4SChuck Tuffli case PAGE_ID_ATA_SMART_RET_STATUS:
117*7419d6e4SChuck Tuffli desc = "SMART Status";
118*7419d6e4SChuck Tuffli break;
119*7419d6e4SChuck Tuffli default:
120*7419d6e4SChuck Tuffli ;
121*7419d6e4SChuck Tuffli }
122*7419d6e4SChuck Tuffli
123*7419d6e4SChuck Tuffli return (desc);
124*7419d6e4SChuck Tuffli }
125*7419d6e4SChuck Tuffli
126*7419d6e4SChuck Tuffli const char *
__smart_scsi_err_desc(uint32_t id)127*7419d6e4SChuck Tuffli __smart_scsi_err_desc(uint32_t id)
128*7419d6e4SChuck Tuffli {
129*7419d6e4SChuck Tuffli const char *param = NULL;
130*7419d6e4SChuck Tuffli
131*7419d6e4SChuck Tuffli switch (id) {
132*7419d6e4SChuck Tuffli case 0:
133*7419d6e4SChuck Tuffli param = "Errors corrected without substantial delay";
134*7419d6e4SChuck Tuffli break;
135*7419d6e4SChuck Tuffli case 1:
136*7419d6e4SChuck Tuffli param = "Errors corrected with possible delays";
137*7419d6e4SChuck Tuffli break;
138*7419d6e4SChuck Tuffli case 2:
139*7419d6e4SChuck Tuffli param = "Total retries";
140*7419d6e4SChuck Tuffli break;
141*7419d6e4SChuck Tuffli case 3:
142*7419d6e4SChuck Tuffli param = "Total errors corrected";
143*7419d6e4SChuck Tuffli break;
144*7419d6e4SChuck Tuffli case 4:
145*7419d6e4SChuck Tuffli param = "Total times correction algorithm processed";
146*7419d6e4SChuck Tuffli break;
147*7419d6e4SChuck Tuffli case 5:
148*7419d6e4SChuck Tuffli param = "Total bytes processed";
149*7419d6e4SChuck Tuffli break;
150*7419d6e4SChuck Tuffli case 6:
151*7419d6e4SChuck Tuffli param = "Total uncorrected errors";
152*7419d6e4SChuck Tuffli break;
153*7419d6e4SChuck Tuffli default:
154*7419d6e4SChuck Tuffli return (NULL);
155*7419d6e4SChuck Tuffli }
156*7419d6e4SChuck Tuffli
157*7419d6e4SChuck Tuffli return (param);
158*7419d6e4SChuck Tuffli }
159