]> git.proxmox.com Git - mirror_smartmontools-debian.git/blame - atacmds.cpp
Imported Upstream version 5.41+svn3365
[mirror_smartmontools-debian.git] / atacmds.cpp
CommitLineData
832b75ed 1/*
4d59bff9 2 * atacmds.cpp
832b75ed
GG
3 *
4 * Home page of code is: http://smartmontools.sourceforge.net
5 *
cfbba5b9
GI
6 * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
7 * Copyright (C) 2008-11 Christian Franke <smartmontools-support@lists.sourceforge.net>
832b75ed
GG
8 * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
9 * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
15 *
16 * You should have received a copy of the GNU General Public License
17 * (for example COPYING); if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * This code was originally developed as a Senior Thesis by Michael Cornwell
21 * at the Concurrent Systems Laboratory (now part of the Storage Systems
22 * Research Center), Jack Baskin School of Engineering, University of
23 * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
24 *
25 */
26
27#include <stdio.h>
28#include <string.h>
29#include <errno.h>
30#include <stdlib.h>
31#include <ctype.h>
32
33#include "config.h"
34#include "int64.h"
35#include "atacmds.h"
832b75ed 36#include "utility.h"
2127e193 37#include "dev_ata_cmd_set.h" // for parsed_ata_device
832b75ed 38
a7e8ffec 39const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 3345 2011-05-25 20:50:02Z chrfranke $"
2127e193 40 ATACMDS_H_CVSID;
832b75ed 41
cfbba5b9
GI
42// Print ATA debug messages?
43unsigned char ata_debugmode = 0;
44
45// Suppress serial number?
46// (also used in scsiprint.cpp)
47bool dont_print_serial_number = false;
48
832b75ed 49
2127e193
GI
50#define SMART_CYL_LOW 0x4F
51#define SMART_CYL_HI 0xC2
52
53// SMART RETURN STATUS yields SMART_CYL_HI,SMART_CYL_LOW to indicate drive
54// is healthy and SRET_STATUS_HI_EXCEEDED,SRET_STATUS_MID_EXCEEDED to
55// indicate that a threshhold exceeded condition has been detected.
56// Those values (byte pairs) are placed in ATA register "LBA 23:8".
57#define SRET_STATUS_HI_EXCEEDED 0x2C
58#define SRET_STATUS_MID_EXCEEDED 0xF4
59
832b75ed
GG
60// These Drive Identity tables are taken from hdparm 5.2, and are also
61// given in the ATA/ATAPI specs for the IDENTIFY DEVICE command. Note
62// that SMART was first added into the ATA/ATAPI-3 Standard with
63// Revision 3 of the document, July 25, 1995. Look at the "Document
64// Status" revision commands at the beginning of
a23d5117
GI
65// http://www.t13.org/Documents/UploadedDocuments/project/d2008r7b-ATA-3.pdf
66// to see this.
832b75ed
GG
67#define NOVAL_0 0x0000
68#define NOVAL_1 0xffff
69/* word 81: minor version number */
70#define MINOR_MAX 0x22
2127e193 71static const char * const minor_str[] = { /* word 81 value: */
832b75ed
GG
72 "Device does not report version", /* 0x0000 */
73 "ATA-1 X3T9.2 781D prior to revision 4", /* 0x0001 */
74 "ATA-1 published, ANSI X3.221-1994", /* 0x0002 */
75 "ATA-1 X3T9.2 781D revision 4", /* 0x0003 */
76 "ATA-2 published, ANSI X3.279-1996", /* 0x0004 */
77 "ATA-2 X3T10 948D prior to revision 2k", /* 0x0005 */
78 "ATA-3 X3T10 2008D revision 1", /* 0x0006 */ /* SMART NOT INCLUDED */
79 "ATA-2 X3T10 948D revision 2k", /* 0x0007 */
80 "ATA-3 X3T10 2008D revision 0", /* 0x0008 */
81 "ATA-2 X3T10 948D revision 3", /* 0x0009 */
82 "ATA-3 published, ANSI X3.298-199x", /* 0x000a */
83 "ATA-3 X3T10 2008D revision 6", /* 0x000b */ /* 1st VERSION WITH SMART */
84 "ATA-3 X3T13 2008D revision 7 and 7a", /* 0x000c */
85 "ATA/ATAPI-4 X3T13 1153D revision 6", /* 0x000d */
86 "ATA/ATAPI-4 T13 1153D revision 13", /* 0x000e */
87 "ATA/ATAPI-4 X3T13 1153D revision 7", /* 0x000f */
88 "ATA/ATAPI-4 T13 1153D revision 18", /* 0x0010 */
89 "ATA/ATAPI-4 T13 1153D revision 15", /* 0x0011 */
90 "ATA/ATAPI-4 published, ANSI NCITS 317-1998", /* 0x0012 */
91 "ATA/ATAPI-5 T13 1321D revision 3", /* 0x0013 */
92 "ATA/ATAPI-4 T13 1153D revision 14", /* 0x0014 */
93 "ATA/ATAPI-5 T13 1321D revision 1", /* 0x0015 */
94 "ATA/ATAPI-5 published, ANSI NCITS 340-2000", /* 0x0016 */
95 "ATA/ATAPI-4 T13 1153D revision 17", /* 0x0017 */
96 "ATA/ATAPI-6 T13 1410D revision 0", /* 0x0018 */
97 "ATA/ATAPI-6 T13 1410D revision 3a", /* 0x0019 */
98 "ATA/ATAPI-7 T13 1532D revision 1", /* 0x001a */
99 "ATA/ATAPI-6 T13 1410D revision 2", /* 0x001b */
100 "ATA/ATAPI-6 T13 1410D revision 1", /* 0x001c */
4d59bff9 101 "ATA/ATAPI-7 published, ANSI INCITS 397-2005",/* 0x001d */
832b75ed
GG
102 "ATA/ATAPI-7 T13 1532D revision 0", /* 0x001e */
103 "reserved", /* 0x001f */
104 "reserved", /* 0x0020 */
105 "ATA/ATAPI-7 T13 1532D revision 4a", /* 0x0021 */
106 "ATA/ATAPI-6 published, ANSI INCITS 361-2002" /* 0x0022 */
107};
108
109// NOTE ATA/ATAPI-4 REV 4 was the LAST revision where the device
110// attribute structures were NOT completely vendor specific. So any
111// disk that is ATA/ATAPI-4 or above can not be trusted to show the
112// vendor values in sensible format.
113
114// Negative values below are because it doesn't support SMART
2127e193 115static const int actual_ver[] = {
832b75ed
GG
116 /* word 81 value: */
117 0, /* 0x0000 WARNING: */
118 1, /* 0x0001 WARNING: */
119 1, /* 0x0002 WARNING: */
120 1, /* 0x0003 WARNING: */
121 2, /* 0x0004 WARNING: This array */
122 2, /* 0x0005 WARNING: corresponds */
123 -3, /*<== */ /* 0x0006 WARNING: *exactly* */
124 2, /* 0x0007 WARNING: to the ATA/ */
125 -3, /*<== */ /* 0x0008 WARNING: ATAPI version */
126 2, /* 0x0009 WARNING: listed in */
127 3, /* 0x000a WARNING: the */
128 3, /* 0x000b WARNING: minor_str */
129 3, /* 0x000c WARNING: array */
130 4, /* 0x000d WARNING: above. */
131 4, /* 0x000e WARNING: */
132 4, /* 0x000f WARNING: If you change */
133 4, /* 0x0010 WARNING: that one, */
134 4, /* 0x0011 WARNING: change this one */
135 4, /* 0x0012 WARNING: too!!! */
136 5, /* 0x0013 WARNING: */
137 4, /* 0x0014 WARNING: */
138 5, /* 0x0015 WARNING: */
139 5, /* 0x0016 WARNING: */
140 4, /* 0x0017 WARNING: */
141 6, /* 0x0018 WARNING: */
142 6, /* 0x0019 WARNING: */
143 7, /* 0x001a WARNING: */
144 6, /* 0x001b WARNING: */
145 6, /* 0x001c WARNING: */
4d59bff9 146 7, /* 0x001d WARNING: */
832b75ed
GG
147 7, /* 0x001e WARNING: */
148 0, /* 0x001f WARNING: */
149 0, /* 0x0020 WARNING: */
150 7, /* 0x0021 WARNING: */
151 6 /* 0x0022 WARNING: */
152};
153
cfbba5b9
GI
154// Compile time check of above array sizes
155typedef char assert_sizeof_minor_str [sizeof(minor_str) /sizeof(minor_str[0]) == MINOR_MAX+1 ? 1 : -1];
156typedef char assert_sizeof_actual_ver[sizeof(actual_ver)/sizeof(actual_ver[0]) == MINOR_MAX+1 ? 1 : -1];
157
2127e193
GI
158// Get ID and increase flag of current pending or offline
159// uncorrectable attribute.
bed94269 160unsigned char get_unc_attr_id(bool offline, const ata_vendor_attr_defs & defs,
2127e193
GI
161 bool & increase)
162{
163 unsigned char id = (!offline ? 197 : 198);
e9583e0c
GI
164 const ata_vendor_attr_defs::entry & def = defs[id];
165 if (def.flags & ATTRFLAG_INCREASING)
166 increase = true; // '-v 19[78],increasing' option
167 else if (def.name.empty() || (id == 198 && def.name == "Offline_Scan_UNC_SectCt"))
168 increase = false; // no or '-v 198,offlinescanuncsectorct' option
169 else
170 id = 0; // other '-v 19[78],...' option
2127e193
GI
171 return id;
172}
173
bed94269 174#if 0 // TODO: never used
832b75ed
GG
175// This are the meanings of the Self-test failure checkpoint byte.
176// This is in the self-test log at offset 4 bytes into the self-test
177// descriptor and in the SMART READ DATA structure at byte offset
178// 371. These codes are not well documented. The meanings returned by
179// this routine are used (at least) by Maxtor and IBM. Returns NULL if
180// not recognized. Currently the maximum length is 15 bytes.
181const char *SelfTestFailureCodeName(unsigned char which){
182
183 switch (which) {
184 case 0:
185 return "Write_Test";
186 case 1:
187 return "Servo_Basic";
188 case 2:
189 return "Servo_Random";
190 case 3:
191 return "G-list_Scan";
192 case 4:
193 return "Handling_Damage";
194 case 5:
195 return "Read_Scan";
196 default:
197 return NULL;
198 }
199}
bed94269
GI
200#endif
201
832b75ed 202
bed94269
GI
203// Table of raw print format names
204struct format_name_entry
832b75ed 205{
bed94269
GI
206 const char * name;
207 ata_attr_raw_format format;
208};
209
210const format_name_entry format_names[] = {
211 {"raw8" , RAWFMT_RAW8},
212 {"raw16" , RAWFMT_RAW16},
213 {"raw48" , RAWFMT_RAW48},
214 {"hex48" , RAWFMT_HEX48},
215 {"raw64" , RAWFMT_RAW64},
216 {"hex64" , RAWFMT_HEX64},
217 {"raw16(raw16)" , RAWFMT_RAW16_OPT_RAW16},
218 {"raw16(avg16)" , RAWFMT_RAW16_OPT_AVG16},
cfbba5b9
GI
219 {"raw24/raw24" , RAWFMT_RAW24_DIV_RAW24},
220 {"raw24/raw32" , RAWFMT_RAW24_DIV_RAW32},
bed94269
GI
221 {"sec2hour" , RAWFMT_SEC2HOUR},
222 {"min2hour" , RAWFMT_MIN2HOUR},
223 {"halfmin2hour" , RAWFMT_HALFMIN2HOUR},
cfbba5b9 224 {"msec24hour32" , RAWFMT_MSEC24_HOUR32},
bed94269
GI
225 {"tempminmax" , RAWFMT_TEMPMINMAX},
226 {"temp10x" , RAWFMT_TEMP10X},
227};
228
229const unsigned num_format_names = sizeof(format_names)/sizeof(format_names[0]);
230
231// Table to map old to new '-v' option arguments
232const char * map_old_vendor_opts[][2] = {
233 { "9,halfminutes" , "9,halfmin2hour,Power_On_Half_Minutes"},
234 { "9,minutes" , "9,min2hour,Power_On_Minutes"},
235 { "9,seconds" , "9,sec2hour,Power_On_Seconds"},
236 { "9,temp" , "9,tempminmax,Temperature_Celsius"},
237 {"192,emergencyretractcyclect" , "192,raw48,Emerg_Retract_Cycle_Ct"},
238 {"193,loadunload" , "193,raw24/raw24"},
239 {"194,10xCelsius" , "194,temp10x,Temperature_Celsius_x10"},
240 {"194,unknown" , "194,raw48,Unknown_Attribute"},
241 {"197,increasing" , "197,raw48+,Total_Pending_Sectors"}, // '+' sets flag
e9583e0c 242 {"198,offlinescanuncsectorct" , "198,raw48,Offline_Scan_UNC_SectCt"}, // see also get_unc_attr_id() above
bed94269
GI
243 {"198,increasing" , "198,raw48+,Total_Offl_Uncorrectabl"}, // '+' sets flag
244 {"200,writeerrorcount" , "200,raw48,Write_Error_Count"},
245 {"201,detectedtacount" , "201,raw48,Detected_TA_Count"},
246 {"220,temp" , "220,raw48,Temperature_Celsius"},
247};
248
249const unsigned num_old_vendor_opts = sizeof(map_old_vendor_opts)/sizeof(map_old_vendor_opts[0]);
250
251// Parse vendor attribute display def (-v option).
252// Return false on error.
253bool parse_attribute_def(const char * opt, ata_vendor_attr_defs & defs,
254 ata_vendor_def_prior priority)
255{
256 // Map old -> new options
257 unsigned i;
258 for (i = 0; i < num_old_vendor_opts; i++) {
259 if (!strcmp(opt, map_old_vendor_opts[i][0])) {
260 opt = map_old_vendor_opts[i][1];
261 break;
262 }
263 }
264
265 // Parse option
266 int len = strlen(opt);
267 int id = 0, n1 = -1, n2 = -1;
268 char fmtname[32+1], attrname[32+1];
269 if (opt[0] == 'N') {
270 // "N,format"
271 if (!( sscanf(opt, "N,%32[^,]%n,%32[^,]%n", fmtname, &n1, attrname, &n2) >= 1
272 && (n1 == len || n2 == len)))
273 return false;
2127e193
GI
274 }
275 else {
bed94269
GI
276 // "id,format[+][,name]"
277 if (!( sscanf(opt, "%d,%32[^,]%n,%32[^,]%n", &id, fmtname, &n1, attrname, &n2) >= 2
278 && 1 <= id && id <= 255 && (n1 == len || n2 == len)))
279 return false;
2127e193 280 }
bed94269
GI
281 if (n1 == len)
282 attrname[0] = 0;
2127e193 283
bed94269
GI
284 unsigned flags = 0;
285 // For "-v 19[78],increasing" above
286 if (fmtname[strlen(fmtname)-1] == '+') {
287 fmtname[strlen(fmtname)-1] = 0;
288 flags = ATTRFLAG_INCREASING;
289 }
290
a23d5117
GI
291 // Split "format[:byteorder]"
292 char byteorder[8+1] = "";
293 if (strchr(fmtname, ':')) {
294 if (!( sscanf(fmtname, "%*[^:]%n:%8[012345rvwz]%n", &n1, byteorder, &n2) >= 1
295 && n2 == (int)strlen(fmtname)))
296 return false;
297 fmtname[n1] = 0;
298 if (strchr(byteorder, 'v'))
299 flags |= (ATTRFLAG_NO_NORMVAL|ATTRFLAG_NO_WORSTVAL);
300 if (strchr(byteorder, 'w'))
301 flags |= ATTRFLAG_NO_WORSTVAL;
302 }
303
bed94269 304 // Find format name
2127e193 305 for (i = 0; ; i++) {
bed94269
GI
306 if (i >= num_format_names)
307 return false; // Not found
308 if (!strcmp(fmtname, format_names[i].name))
2127e193 309 break;
832b75ed 310 }
bed94269
GI
311 ata_attr_raw_format format = format_names[i].format;
312
a23d5117
GI
313 // 64-bit formats use the normalized and worst value bytes.
314 if (!*byteorder && (format == RAWFMT_RAW64 || format == RAWFMT_HEX64))
315 flags |= (ATTRFLAG_NO_NORMVAL|ATTRFLAG_NO_WORSTVAL);
832b75ed 316
2127e193 317 if (!id) {
bed94269
GI
318 // "N,format" -> set format for all entries
319 for (i = 0; i < MAX_ATTRIBUTE_NUM; i++) {
320 if (defs[i].priority >= priority)
321 continue;
322 if (attrname[0])
323 defs[i].name = attrname;
324 defs[i].priority = priority;
325 defs[i].raw_format = format;
326 defs[i].flags = flags;
a23d5117 327 strcpy(defs[i].byteorder, byteorder);
bed94269
GI
328 }
329 }
330 else if (defs[id].priority <= priority) {
331 // "id,format[,name]"
332 if (attrname[0])
333 defs[id].name = attrname;
334 defs[id].raw_format = format;
335 defs[id].priority = priority;
336 defs[id].flags = flags;
a23d5117 337 strcpy(defs[id].byteorder, byteorder);
832b75ed
GG
338 }
339
bed94269 340 return true;
832b75ed
GG
341}
342
bed94269 343
2127e193
GI
344// Return a multiline string containing a list of valid arguments for
345// parse_attribute_def(). The strings are preceeded by tabs and followed
832b75ed 346// (except for the last) by newlines.
2127e193
GI
347std::string create_vendor_attribute_arg_list()
348{
349 std::string s;
bed94269
GI
350 unsigned i;
351 for (i = 0; i < num_format_names; i++)
a23d5117 352 s += strprintf("%s\tN,%s[:012345rvwz][,ATTR_NAME]",
bed94269
GI
353 (i>0 ? "\n" : ""), format_names[i].name);
354 for (i = 0; i < num_old_vendor_opts; i++)
355 s += strprintf("\n\t%s", map_old_vendor_opts[i][0]);
832b75ed
GG
356 return s;
357}
358
359// swap two bytes. Point to low address
360void swap2(char *location){
361 char tmp=*location;
362 *location=*(location+1);
363 *(location+1)=tmp;
364 return;
365}
366
367// swap four bytes. Point to low address
368void swap4(char *location){
369 char tmp=*location;
370 *location=*(location+3);
371 *(location+3)=tmp;
372 swap2(location+1);
373 return;
374}
375
376// swap eight bytes. Points to low address
377void swap8(char *location){
378 char tmp=*location;
379 *location=*(location+7);
380 *(location+7)=tmp;
381 tmp=*(location+1);
382 *(location+1)=*(location+6);
383 *(location+6)=tmp;
384 swap4(location+2);
385 return;
386}
387
a7e8ffec
GI
388// Invalidate serial number and WWN and adjust checksum in IDENTIFY data
389static void invalidate_serno(ata_identify_device * id)
390{
a37e7145 391 unsigned char sum = 0;
a7e8ffec
GI
392 unsigned i;
393 for (i = 0; i < sizeof(id->serial_no); i++) {
a37e7145
GG
394 sum += id->serial_no[i]; sum -= id->serial_no[i] = 'X';
395 }
a7e8ffec
GI
396 unsigned char * b = (unsigned char *)id;
397 for (i = 2*108; i < 2*112; i++) { // words108-111: WWN
398 sum += b[i]; sum -= b[i] = 0x00;
399 }
400
a37e7145
GG
401#ifndef __NetBSD__
402 bool must_swap = !!isbigendian();
403 if (must_swap)
404 swapx(id->words088_255+255-88);
405#endif
406 if ((id->words088_255[255-88] & 0x00ff) == 0x00a5)
407 id->words088_255[255-88] += sum << 8;
408#ifndef __NetBSD__
409 if (must_swap)
410 swapx(id->words088_255+255-88);
411#endif
412}
413
2127e193 414static const char * const commandstrings[]={
832b75ed
GG
415 "SMART ENABLE",
416 "SMART DISABLE",
417 "SMART AUTOMATIC ATTRIBUTE SAVE",
418 "SMART IMMEDIATE OFFLINE",
419 "SMART AUTO OFFLINE",
420 "SMART STATUS",
421 "SMART STATUS CHECK",
422 "SMART READ ATTRIBUTE VALUES",
423 "SMART READ ATTRIBUTE THRESHOLDS",
424 "SMART READ LOG",
425 "IDENTIFY DEVICE",
426 "IDENTIFY PACKET DEVICE",
427 "CHECK POWER MODE",
428 "SMART WRITE LOG",
429 "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT ")\n"
430};
431
2127e193
GI
432
433static const char * preg(const ata_register & r, char * buf)
434{
435 if (!r.is_set())
436 //return "n/a ";
437 return "....";
438 sprintf(buf, "0x%02x", r.val()); return buf;
439}
440
cfbba5b9 441static void print_regs(const char * prefix, const ata_in_regs & r, const char * suffix = "\n")
2127e193
GI
442{
443 char bufs[7][4+1+13];
444 pout("%s FR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, CMD=%s%s", prefix,
445 preg(r.features, bufs[0]), preg(r.sector_count, bufs[1]), preg(r.lba_low, bufs[2]),
446 preg(r.lba_mid, bufs[3]), preg(r.lba_high, bufs[4]), preg(r.device, bufs[5]),
447 preg(r.command, bufs[6]), suffix);
448}
449
cfbba5b9 450static void print_regs(const char * prefix, const ata_out_regs & r, const char * suffix = "\n")
2127e193
GI
451{
452 char bufs[7][4+1+13];
453 pout("%sERR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, STS=%s%s", prefix,
454 preg(r.error, bufs[0]), preg(r.sector_count, bufs[1]), preg(r.lba_low, bufs[2]),
455 preg(r.lba_mid, bufs[3]), preg(r.lba_high, bufs[4]), preg(r.device, bufs[5]),
456 preg(r.status, bufs[6]), suffix);
457}
458
a37e7145 459static void prettyprint(const unsigned char *p, const char *name){
832b75ed 460 pout("\n===== [%s] DATA START (BASE-16) =====\n", name);
a37e7145 461 for (int i=0; i<512; i+=16, p+=16)
a23d5117 462#define P(n) (isprint((int)(p[n]))?(int)(p[n]):'.')
a37e7145
GG
463 // print complete line to avoid slow tty output and extra lines in syslog.
464 pout("%03d-%03d: %02x %02x %02x %02x %02x %02x %02x %02x "
a23d5117
GI
465 "%02x %02x %02x %02x %02x %02x %02x %02x"
466 " |%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c|"
467 "%c",
a37e7145
GG
468 i, i+16-1,
469 p[ 0], p[ 1], p[ 2], p[ 3], p[ 4], p[ 5], p[ 6], p[ 7],
a23d5117
GI
470 p[ 8], p[ 9], p[10], p[11], p[12], p[13], p[14], p[15],
471 P( 0), P( 1), P( 2), P( 3), P( 4), P( 5), P( 6), P( 7),
472 P( 8), P( 9), P(10), P(11), P(12), P(13), P(14), P(15),
473 '\n');
474#undef P
832b75ed
GG
475 pout("===== [%s] DATA END (512 Bytes) =====\n\n", name);
476}
477
478// This function provides the pretty-print reporting for SMART
479// commands: it implements the various -r "reporting" options for ATA
480// ioctls.
2127e193
GI
481int smartcommandhandler(ata_device * device, smart_command_set command, int select, char *data){
482 // TODO: Rework old stuff below
832b75ed
GG
483 // This conditional is true for commands that return data
484 int getsdata=(command==PIDENTIFY ||
485 command==IDENTIFY ||
486 command==READ_LOG ||
487 command==READ_THRESHOLDS ||
488 command==READ_VALUES ||
4d59bff9 489 command==CHECK_POWER_MODE);
832b75ed
GG
490
491 int sendsdata=(command==WRITE_LOG);
492
493 // If reporting is enabled, say what the command will be before it's executed
cfbba5b9 494 if (ata_debugmode) {
832b75ed
GG
495 // conditional is true for commands that use parameters
496 int usesparam=(command==READ_LOG ||
497 command==AUTO_OFFLINE ||
498 command==AUTOSAVE ||
499 command==IMMEDIATE_OFFLINE ||
500 command==WRITE_LOG);
501
2127e193 502 pout("\nREPORT-IOCTL: Device=%s Command=%s", device->get_dev_name(), commandstrings[command]);
832b75ed
GG
503 if (usesparam)
504 pout(" InputParameter=%d\n", select);
505 else
506 pout("\n");
507 }
508
509 if ((getsdata || sendsdata) && !data){
510 pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings[command]);
511 return -1;
512 }
513
514 // The reporting is cleaner, and we will find coding bugs faster, if
515 // the commands that failed clearly return empty (zeroed) data
516 // structures
517 if (getsdata) {
518 if (command==CHECK_POWER_MODE)
519 data[0]=0;
520 else
521 memset(data, '\0', 512);
522 }
523
524
a37e7145 525 // if requested, pretty-print the input data structure
cfbba5b9 526 if (ata_debugmode > 1 && sendsdata)
2127e193 527 //pout("REPORT-IOCTL: Device=%s Command=%s\n", device->get_dev_name(), commandstrings[command]);
a37e7145 528 prettyprint((unsigned char *)data, commandstrings[command]);
832b75ed 529
832b75ed 530 // now execute the command
2127e193
GI
531 int retval = -1;
532 {
533 ata_cmd_in in;
534 // Set common register values
535 switch (command) {
536 default: // SMART commands
537 in.in_regs.command = ATA_SMART_CMD;
538 in.in_regs.lba_high = SMART_CYL_HI; in.in_regs.lba_mid = SMART_CYL_LOW;
539 break;
540 case IDENTIFY: case PIDENTIFY: case CHECK_POWER_MODE: // Non SMART commands
541 break;
542 }
543 // Set specific values
544 switch (command) {
545 case IDENTIFY:
546 in.in_regs.command = ATA_IDENTIFY_DEVICE;
547 in.set_data_in(data, 1);
548 break;
549 case PIDENTIFY:
550 in.in_regs.command = ATA_IDENTIFY_PACKET_DEVICE;
551 in.set_data_in(data, 1);
552 break;
553 case CHECK_POWER_MODE:
554 in.in_regs.command = ATA_CHECK_POWER_MODE;
555 in.out_needed.sector_count = true; // Powermode returned here
556 break;
557 case READ_VALUES:
558 in.in_regs.features = ATA_SMART_READ_VALUES;
559 in.set_data_in(data, 1);
560 break;
561 case READ_THRESHOLDS:
562 in.in_regs.features = ATA_SMART_READ_THRESHOLDS;
563 in.in_regs.lba_low = 1; // TODO: CORRECT ???
564 in.set_data_in(data, 1);
565 break;
566 case READ_LOG:
567 in.in_regs.features = ATA_SMART_READ_LOG_SECTOR;
568 in.in_regs.lba_low = select;
569 in.set_data_in(data, 1);
570 break;
571 case WRITE_LOG:
572 in.in_regs.features = ATA_SMART_WRITE_LOG_SECTOR;
573 in.in_regs.lba_low = select;
574 in.set_data_out(data, 1);
575 break;
576 case ENABLE:
577 in.in_regs.features = ATA_SMART_ENABLE;
578 in.in_regs.lba_low = 1; // TODO: CORRECT ???
579 break;
580 case DISABLE:
581 in.in_regs.features = ATA_SMART_DISABLE;
582 in.in_regs.lba_low = 1; // TODO: CORRECT ???
583 break;
584 case STATUS_CHECK:
585 in.out_needed.lba_high = in.out_needed.lba_mid = true; // Status returned here
586 case STATUS:
587 in.in_regs.features = ATA_SMART_STATUS;
588 break;
589 case AUTO_OFFLINE:
590 in.in_regs.features = ATA_SMART_AUTO_OFFLINE;
591 in.in_regs.sector_count = select; // Caution: Non-DATA command!
592 break;
593 case AUTOSAVE:
594 in.in_regs.features = ATA_SMART_AUTOSAVE;
595 in.in_regs.sector_count = select; // Caution: Non-DATA command!
596 break;
597 case IMMEDIATE_OFFLINE:
598 in.in_regs.features = ATA_SMART_IMMEDIATE_OFFLINE;
599 in.in_regs.lba_low = select;
600 break;
601 default:
602 pout("Unrecognized command %d in smartcommandhandler()\n"
603 "Please contact " PACKAGE_BUGREPORT "\n", command);
604 device->set_err(ENOSYS);
2127e193
GI
605 return -1;
606 }
607
cfbba5b9 608 if (ata_debugmode)
2127e193
GI
609 print_regs(" Input: ", in.in_regs,
610 (in.direction==ata_cmd_in::data_in ? " IN\n":
611 in.direction==ata_cmd_in::data_out ? " OUT\n":"\n"));
612
613 ata_cmd_out out;
614 bool ok = device->ata_pass_through(in, out);
615
cfbba5b9 616 if (ata_debugmode && out.out_regs.is_set())
2127e193
GI
617 print_regs(" Output: ", out.out_regs);
618
619 if (ok) switch (command) {
620 default:
621 retval = 0;
622 break;
623 case CHECK_POWER_MODE:
a7e8ffec
GI
624 if (out.out_regs.sector_count.is_set()) {
625 data[0] = out.out_regs.sector_count;
626 retval = 0;
627 }
628 else {
629 pout("CHECK POWER MODE: incomplete response, ATA output registers missing\n");
630 device->set_err(ENOSYS);
631 retval = -1;
632 }
2127e193
GI
633 break;
634 case STATUS_CHECK:
635 // Cyl low and Cyl high unchanged means "Good SMART status"
636 if ((out.out_regs.lba_high == SMART_CYL_HI) &&
637 (out.out_regs.lba_mid == SMART_CYL_LOW))
638 retval = 0;
639 // These values mean "Bad SMART status"
640 else if ((out.out_regs.lba_high == SRET_STATUS_HI_EXCEEDED) &&
641 (out.out_regs.lba_mid == SRET_STATUS_MID_EXCEEDED))
642 retval = 1;
643 else if (out.out_regs.lba_mid == SMART_CYL_LOW) {
644 retval = 0;
cfbba5b9 645 if (ata_debugmode)
2127e193
GI
646 pout("SMART STATUS RETURN: half healthy response sequence, "
647 "probable SAT/USB truncation\n");
648 } else if (out.out_regs.lba_mid == SRET_STATUS_MID_EXCEEDED) {
649 retval = 1;
cfbba5b9 650 if (ata_debugmode)
2127e193
GI
651 pout("SMART STATUS RETURN: half unhealthy response sequence, "
652 "probable SAT/USB truncation\n");
a7e8ffec
GI
653 }
654 else if (!out.out_regs.is_set()) {
655 pout("SMART STATUS RETURN: incomplete response, ATA output registers missing\n");
656 device->set_err(ENOSYS);
657 retval = -1;
658 }
659 else {
2127e193 660 // We haven't gotten output that makes sense; print out some debugging info
a23d5117
GI
661 pout("Error SMART Status command failed\n");
662 pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE);
663 pout("Register values returned from SMART Status command are:\n");
664 print_regs(" ", out.out_regs);
a7e8ffec 665 device->set_err(EIO);
2127e193
GI
666 retval = -1;
667 }
668 break;
669 }
832b75ed
GG
670 }
671
a37e7145 672 // If requested, invalidate serial number before any printing is done
cfbba5b9 673 if ((command == IDENTIFY || command == PIDENTIFY) && !retval && dont_print_serial_number)
a37e7145
GG
674 invalidate_serno((ata_identify_device *)data);
675
832b75ed 676 // If reporting is enabled, say what output was produced by the command
cfbba5b9 677 if (ata_debugmode) {
2127e193
GI
678 if (device->get_errno())
679 pout("REPORT-IOCTL: Device=%s Command=%s returned %d errno=%d [%s]\n",
680 device->get_dev_name(), commandstrings[command], retval,
681 device->get_errno(), device->get_errmsg());
832b75ed 682 else
2127e193
GI
683 pout("REPORT-IOCTL: Device=%s Command=%s returned %d\n",
684 device->get_dev_name(), commandstrings[command], retval);
832b75ed
GG
685
686 // if requested, pretty-print the output data structure
cfbba5b9 687 if (ata_debugmode > 1 && getsdata) {
832b75ed
GG
688 if (command==CHECK_POWER_MODE)
689 pout("Sector Count Register (BASE-16): %02x\n", (unsigned char)(*data));
690 else
691 prettyprint((unsigned char *)data, commandstrings[command]);
692 }
693 }
2127e193 694
832b75ed
GG
695 return retval;
696}
697
a7e8ffec
GI
698// Get capacity and sector sizes from IDENTIFY data
699void ata_get_size_info(const ata_identify_device * id, ata_size_info & sizes)
2127e193 700{
a7e8ffec
GI
701 sizes.sectors = sizes.capacity = 0;
702 sizes.log_sector_size = sizes.phy_sector_size = 0;
703 sizes.log_sector_offset = 0;
704
705 // Return if no LBA support
706 if (!(id->words047_079[49-47] & 0x0200))
707 return;
708
709 // Determine 28-bit LBA capacity
710 unsigned lba28 = (unsigned)id->words047_079[61-47] << 16
711 | (unsigned)id->words047_079[60-47] ;
712
713 // Determine 48-bit LBA capacity if supported
714 uint64_t lba48 = 0;
715 if ((id->command_set_2 & 0xc400) == 0x4400)
716 lba48 = (uint64_t)id->words088_255[103-88] << 48
717 | (uint64_t)id->words088_255[102-88] << 32
718 | (uint64_t)id->words088_255[101-88] << 16
719 | (uint64_t)id->words088_255[100-88] ;
720
721 // Return if capacity unknown (ATAPI CD/DVD)
722 if (!(lba28 || lba48))
723 return;
724
725 // Determine sector sizes
726 sizes.log_sector_size = sizes.phy_sector_size = 512;
727
728 unsigned short word106 = id->words088_255[106-88];
729 if ((word106 & 0xc000) == 0x4000) {
730 // Long Logical/Physical Sectors (LLS/LPS) ?
731 if (word106 & 0x1000)
732 // Logical sector size is specified in 16-bit words
733 sizes.log_sector_size = sizes.phy_sector_size =
734 ((id->words088_255[118-88] << 16) | id->words088_255[117-88]) << 1;
735
736 if (word106 & 0x2000)
737 // Physical sector size is multiple of logical sector size
738 sizes.phy_sector_size <<= (word106 & 0x0f);
739
740 unsigned short word209 = id->words088_255[209-88];
741 if ((word209 & 0xc000) == 0x4000)
742 sizes.log_sector_offset = (word209 & 0x3fff) * sizes.log_sector_size;
743 }
744
745 // Some early 4KiB LLS disks (Samsung N3U-3) return bogus lba28 value
746 if (lba48 >= lba28 || (lba48 && sizes.log_sector_size > 512))
747 sizes.sectors = lba48;
748 else
749 sizes.sectors = lba28;
750
751 sizes.capacity = sizes.sectors * sizes.log_sector_size;
2127e193 752}
832b75ed
GG
753
754// This function computes the checksum of a single disk sector (512
755// bytes). Returns zero if checksum is OK, nonzero if the checksum is
756// incorrect. The size (512) is correct for all SMART structures.
2127e193
GI
757unsigned char checksum(const void * data)
758{
759 unsigned char sum = 0;
760 for (int i = 0; i < 512; i++)
761 sum += ((const unsigned char *)data)[i];
762 return sum;
763}
764
765// Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
766// bytes.
767static void swapbytes(char * out, const char * in, size_t n)
768{
769 for (size_t i = 0; i < n; i += 2) {
770 out[i] = in[i+1];
771 out[i+1] = in[i];
772 }
773}
774
775// Copies in to out, but removes leading and trailing whitespace.
776static void trim(char * out, const char * in)
777{
778 // Find the first non-space character (maybe none).
779 int first = -1;
832b75ed 780 int i;
2127e193
GI
781 for (i = 0; in[i]; i++)
782 if (!isspace((int)in[i])) {
783 first = i;
784 break;
785 }
832b75ed 786
2127e193
GI
787 if (first == -1) {
788 // There are no non-space characters.
789 out[0] = '\0';
790 return;
791 }
792
793 // Find the last non-space character.
794 for (i = strlen(in)-1; i >= first && isspace((int)in[i]); i--)
795 ;
796 int last = i;
797
798 strncpy(out, in+first, last-first+1);
799 out[last-first+1] = '\0';
800}
801
802// Convenience function for formatting strings from ata_identify_device
cfbba5b9 803void ata_format_id_string(char * out, const unsigned char * in, int n)
2127e193 804{
cfbba5b9 805 bool must_swap = true;
2127e193
GI
806#ifdef __NetBSD__
807 /* NetBSD kernel delivers IDENTIFY data in host byte order (but all else is LE) */
cfbba5b9 808 // TODO: Handle NetBSD case in os_netbsd.cpp
2127e193
GI
809 if (isbigendian())
810 must_swap = !must_swap;
811#endif
812
813 char tmp[65];
814 n = n > 64 ? 64 : n;
815 if (!must_swap)
cfbba5b9 816 strncpy(tmp, (const char *)in, n);
2127e193 817 else
cfbba5b9 818 swapbytes(tmp, (const char *)in, n);
2127e193
GI
819 tmp[n] = '\0';
820 trim(out, tmp);
832b75ed
GG
821}
822
823// returns -1 if command fails or the device is in Sleep mode, else
824// value of Sector Count register. Sector Count result values:
825// 00h device is in Standby mode.
826// 80h device is in Idle mode.
827// FFh device is in Active mode or Idle mode.
828
2127e193 829int ataCheckPowerMode(ata_device * device) {
832b75ed
GG
830 unsigned char result;
831
832 if ((smartcommandhandler(device, CHECK_POWER_MODE, 0, (char *)&result)))
833 return -1;
834
835 if (result!=0 && result!=0x80 && result!=0xff)
836 pout("ataCheckPowerMode(): ATA CHECK POWER MODE returned unknown Sector Count Register value %02x\n", result);
837
838 return (int)result;
839}
840
832b75ed
GG
841// Reads current Device Identity info (512 bytes) into buf. Returns 0
842// if all OK. Returns -1 if no ATA Device identity can be
843// established. Returns >0 if Device is ATA Packet Device (not SMART
844// capable). The value of the integer helps identify the type of
845// Packet device, which is useful so that the user can connect the
846// formal device number with whatever object is inside their computer.
cfbba5b9
GI
847int ata_read_identity(ata_device * device, ata_identify_device * buf, bool fix_swapped_id)
848{
832b75ed
GG
849 unsigned short *rawshort=(unsigned short *)buf;
850 unsigned char *rawbyte =(unsigned char *)buf;
851
852 // See if device responds either to IDENTIFY DEVICE or IDENTIFY
853 // PACKET DEVICE
cfbba5b9 854 bool packet = false;
832b75ed
GG
855 if ((smartcommandhandler(device, IDENTIFY, 0, (char *)buf))){
856 if (smartcommandhandler(device, PIDENTIFY, 0, (char *)buf)){
857 return -1;
858 }
cfbba5b9
GI
859 packet = true;
860 }
861
862 unsigned i;
863 if (fix_swapped_id) {
864 // Swap ID strings
865 for (i = 0; i < sizeof(buf->serial_no)-1; i += 2)
866 swap2((char *)(buf->serial_no+i));
867 for (i = 0; i < sizeof(buf->fw_rev)-1; i += 2)
868 swap2((char *)(buf->fw_rev+i));
869 for (i = 0; i < sizeof(buf->model)-1; i += 2)
870 swap2((char *)(buf->model+i));
832b75ed
GG
871 }
872
873#ifndef __NetBSD__
874 // if machine is big-endian, swap byte order as needed
a37e7145 875 // NetBSD kernel delivers IDENTIFY data in host byte order
cfbba5b9 876 // TODO: Handle NetBSD case in os_netbsd.cpp
832b75ed 877 if (isbigendian()){
832b75ed
GG
878
879 // swap various capability words that are needed
880 for (i=0; i<33; i++)
881 swap2((char *)(buf->words047_079+i));
882
883 for (i=80; i<=87; i++)
884 swap2((char *)(rawshort+i));
885
886 for (i=0; i<168; i++)
887 swap2((char *)(buf->words088_255+i));
888 }
889#endif
890
891 // If there is a checksum there, validate it
892 if ((rawshort[255] & 0x00ff) == 0x00a5 && checksum(rawbyte))
893 checksumwarning("Drive Identity Structure");
cfbba5b9
GI
894
895 // AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
896 // T13/1699-D Revision 6a (Final Draft), September 6, 2008.
897 // Sections 7.16.7 and 7.17.6:
898 //
899 // Word 0 of IDENTIFY DEVICE data:
900 // Bit 15 = 0 : ATA device
901 //
902 // Word 0 of IDENTIFY PACKET DEVICE data:
903 // Bits 15:14 = 10b : ATAPI device
904 // Bits 15:14 = 11b : Reserved
905 // Bits 12:8 : Device type (SPC-4, e.g 0x05 = CD/DVD)
906
907 // CF+ and CompactFlash Specification Revision 4.0, May 24, 2006.
908 // Section 6.2.1.6:
909 //
910 // Word 0 of IDENTIFY DEVICE data:
911 // 848Ah = Signature for CompactFlash Storage Card
912 // 044Ah = Alternate value turns on ATA device while preserving all retired bits
913 // 0040h = Alternate value turns on ATA device while zeroing all retired bits
914
915 // Assume ATA if IDENTIFY DEVICE returns CompactFlash Signature
916 if (!packet && rawbyte[1] == 0x84 && rawbyte[0] == 0x8a)
917 return 0;
918
832b75ed
GG
919 // If this is a PACKET DEVICE, return device type
920 if (rawbyte[1] & 0x80)
921 return 1+(rawbyte[1] & 0x1f);
922
923 // Not a PACKET DEVICE
924 return 0;
925}
926
927// Returns ATA version as an integer, and a pointer to a string
928// describing which revision. Note that Revision 0 of ATA-3 does NOT
929// support SMART. For this one case we return -3 rather than +3 as
930// the version number. See notes above.
2127e193
GI
931int ataVersionInfo(const char ** description, const ata_identify_device * drive, unsigned short * minor)
932{
832b75ed 933 // get major and minor ATA revision numbers
2127e193 934 unsigned short major = drive->major_rev_num;
832b75ed
GG
935 *minor=drive->minor_rev_num;
936
937 // First check if device has ANY ATA version information in it
938 if (major==NOVAL_0 || major==NOVAL_1) {
939 *description=NULL;
a23d5117 940 return 0; // No info found
832b75ed
GG
941 }
942
943 // The minor revision number has more information - try there first
944 if (*minor && (*minor<=MINOR_MAX)){
945 int std = actual_ver[*minor];
946 if (std) {
947 *description=minor_str[*minor];
948 return std;
949 }
950 }
a37e7145 951
cfbba5b9
GI
952 // Try new ATA-8 ACS minor revision numbers.
953 // Table 55 of T13/2015-D Revision 4a (ACS-2), December 9, 2010.
a37e7145
GG
954 // (not in actual_ver/minor_str to avoid large sparse tables)
955 const char *desc;
956 switch (*minor) {
957 case 0x0027: desc = "ATA-8-ACS revision 3c"; break;
2127e193 958 case 0x0028: desc = "ATA-8-ACS revision 6"; break;
a37e7145 959 case 0x0029: desc = "ATA-8-ACS revision 4"; break;
cfbba5b9 960 case 0x0031: desc = "ACS-2 revision 2"; break;
a37e7145 961 case 0x0033: desc = "ATA-8-ACS revision 3e"; break;
1953ff6d 962 case 0x0039: desc = "ATA-8-ACS revision 4c"; break;
a37e7145
GG
963 case 0x0042: desc = "ATA-8-ACS revision 3f"; break;
964 case 0x0052: desc = "ATA-8-ACS revision 3b"; break;
965 case 0x0107: desc = "ATA-8-ACS revision 2d"; break;
cfbba5b9 966 case 0x0110: desc = "ACS-2 revision 3"; break;
a37e7145
GG
967 default: desc = 0; break;
968 }
969 if (desc) {
970 *description = desc;
971 return 8;
972 }
973
832b75ed
GG
974 // HDPARM has a very complicated algorithm from here on. Since SMART only
975 // exists on ATA-3 and later standards, let's punt on this. If you don't
976 // like it, please fix it. The code's in CVS.
2127e193 977 int i;
832b75ed
GG
978 for (i=15; i>0; i--)
979 if (major & (0x1<<i))
980 break;
981
982 *description=NULL;
983 if (i==0)
984 return 1;
985 else
986 return i;
987}
988
a7e8ffec
GI
989// Get World Wide Name (WWN) fields.
990// Return NAA field or -1 if WWN is unsupported.
991// Table 34 of T13/1699-D Revision 6a (ATA8-ACS), September 6, 2008.
992// (WWN was introduced in ATA/ATAPI-7 and is mandatory since ATA8-ACS Revision 3b)
993int ata_get_wwn(const ata_identify_device * id, unsigned & oui, uint64_t & unique_id)
994{
995 // Don't use word 84 to be compatible with some older ATA-7 disks
996 unsigned short word087 = id->csf_default;
997 if ((word087 & 0xc100) != 0x4100)
998 return -1; // word not valid or WWN support bit 8 not set
999
1000 unsigned short word108 = id->words088_255[108-88];
1001 unsigned short word109 = id->words088_255[109-88];
1002 unsigned short word110 = id->words088_255[110-88];
1003 unsigned short word111 = id->words088_255[111-88];
1004
1005 oui = ((word108 & 0x0fff) << 12) | (word109 >> 4);
1006 unique_id = ((uint64_t)(word109 & 0xf) << 32)
1007 | (unsigned)((word110 << 16) | word111);
1008 return (word108 >> 12);
1009}
1010
832b75ed 1011// returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
2127e193
GI
1012int ataSmartSupport(const ata_identify_device * drive)
1013{
832b75ed
GG
1014 unsigned short word82=drive->command_set_1;
1015 unsigned short word83=drive->command_set_2;
1016
1017 // check if words 82/83 contain valid info
1018 if ((word83>>14) == 0x01)
1019 // return value of SMART support bit
1020 return word82 & 0x0001;
1021
1022 // since we can're rely on word 82, we don't know if SMART supported
1023 return -1;
1024}
1025
1026// returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
2127e193
GI
1027int ataIsSmartEnabled(const ata_identify_device * drive)
1028{
832b75ed
GG
1029 unsigned short word85=drive->cfs_enable_1;
1030 unsigned short word87=drive->csf_default;
1031
1032 // check if words 85/86/87 contain valid info
1033 if ((word87>>14) == 0x01)
1034 // return value of SMART enabled bit
1035 return word85 & 0x0001;
1036
1037 // Since we can't rely word85, we don't know if SMART is enabled.
1038 return -1;
1039}
1040
1041
1042// Reads SMART attributes into *data
2127e193 1043int ataReadSmartValues(ata_device * device, struct ata_smart_values *data){
832b75ed
GG
1044
1045 if (smartcommandhandler(device, READ_VALUES, 0, (char *)data)){
a7e8ffec 1046 pout("Error SMART Values Read failed: %s\n", device->get_errmsg());
832b75ed
GG
1047 return -1;
1048 }
1049
1050 // compute checksum
2127e193 1051 if (checksum(data))
832b75ed
GG
1052 checksumwarning("SMART Attribute Data Structure");
1053
a37e7145 1054 // swap endian order if needed
832b75ed
GG
1055 if (isbigendian()){
1056 int i;
1057 swap2((char *)&(data->revnumber));
1058 swap2((char *)&(data->total_time_to_complete_off_line));
1059 swap2((char *)&(data->smart_capability));
1060 for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
1061 struct ata_smart_attribute *x=data->vendor_attributes+i;
1062 swap2((char *)&(x->flags));
1063 }
1064 }
1065
1066 return 0;
1067}
1068
1069
1070// This corrects some quantities that are byte reversed in the SMART
1071// SELF TEST LOG
2127e193
GI
1072static void fixsamsungselftestlog(ata_smart_selftestlog * data)
1073{
832b75ed
GG
1074 // bytes 508/509 (numbered from 0) swapped (swap of self-test index
1075 // with one byte of reserved.
1076 swap2((char *)&(data->mostrecenttest));
1077
1078 // LBA low register (here called 'selftestnumber", containing
1079 // information about the TYPE of the self-test) is byte swapped with
1080 // Self-test execution status byte. These are bytes N, N+1 in the
1081 // entries.
2127e193 1082 for (int i = 0; i < 21; i++)
832b75ed
GG
1083 swap2((char *)&(data->selftest_struct[i].selftestnumber));
1084
1085 return;
1086}
1087
1088// Reads the Self Test Log (log #6)
2127e193
GI
1089int ataReadSelfTestLog (ata_device * device, ata_smart_selftestlog * data,
1090 unsigned char fix_firmwarebug)
1091{
832b75ed
GG
1092
1093 // get data from device
1094 if (smartcommandhandler(device, READ_LOG, 0x06, (char *)data)){
a7e8ffec 1095 pout("Error SMART Error Self-Test Log Read failed: %s\n", device->get_errmsg());
832b75ed
GG
1096 return -1;
1097 }
1098
1099 // compute its checksum, and issue a warning if needed
2127e193 1100 if (checksum(data))
832b75ed
GG
1101 checksumwarning("SMART Self-Test Log Structure");
1102
1103 // fix firmware bugs in self-test log
2127e193 1104 if (fix_firmwarebug == FIX_SAMSUNG)
832b75ed
GG
1105 fixsamsungselftestlog(data);
1106
a37e7145 1107 // swap endian order if needed
832b75ed
GG
1108 if (isbigendian()){
1109 int i;
1110 swap2((char*)&(data->revnumber));
1111 for (i=0; i<21; i++){
1112 struct ata_smart_selftestlog_struct *x=data->selftest_struct+i;
1113 swap2((char *)&(x->timestamp));
1114 swap4((char *)&(x->lbafirstfailure));
1115 }
1116 }
1117
1118 return 0;
1119}
1120
2127e193
GI
1121// Print checksum warning for multi sector log
1122static void check_multi_sector_sum(const void * data, unsigned nsectors, const char * msg)
1123{
1124 unsigned errs = 0;
1125 for (unsigned i = 0; i < nsectors; i++) {
1126 if (checksum((const unsigned char *)data + i*512))
1127 errs++;
1128 }
1129 if (errs > 0) {
1130 if (nsectors == 1)
1131 checksumwarning(msg);
1132 else
1133 checksumwarning(strprintf("%s (%u/%u)", msg, errs, nsectors).c_str());
1134 }
1135}
832b75ed 1136
2127e193
GI
1137// Read SMART Extended Self-test Log
1138bool ataReadExtSelfTestLog(ata_device * device, ata_smart_extselftestlog * log,
1139 unsigned nsectors)
1140{
1141 if (!ataReadLogExt(device, 0x07, 0x00, 0, log, nsectors))
1142 return false;
1143
1144 check_multi_sector_sum(log, nsectors, "SMART Extended Self-test Log Structure");
1145
1146 if (isbigendian()) {
1147 swapx(&log->log_desc_index);
1148 for (unsigned i = 0; i < nsectors; i++) {
1149 for (unsigned j = 0; j < 19; j++)
1150 swapx(&log->log_descs[i].timestamp);
1151 }
832b75ed 1152 }
2127e193
GI
1153 return true;
1154}
832b75ed 1155
2127e193
GI
1156
1157// Read GP Log page(s)
1158bool ataReadLogExt(ata_device * device, unsigned char logaddr,
1159 unsigned char features, unsigned page,
1160 void * data, unsigned nsectors)
1161{
1162 ata_cmd_in in;
1163 in.in_regs.command = ATA_READ_LOG_EXT;
1164 in.in_regs.features = features; // log specific
1165 in.set_data_in_48bit(data, nsectors);
1166 in.in_regs.lba_low = logaddr;
1167 in.in_regs.lba_mid_16 = page;
1168
1169 if (!device->ata_pass_through(in)) { // TODO: Debug output
1170 if (nsectors <= 1) {
1171 pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n",
1172 logaddr, features, page, nsectors, device->get_errmsg());
1173 return false;
1174 }
1175
1176 // Recurse to retry with single sectors,
1177 // multi-sector reads may not be supported by ioctl.
1178 for (unsigned i = 0; i < nsectors; i++) {
1179 if (!ataReadLogExt(device, logaddr,
1180 features, page + i,
1181 (char *)data + 512*i, 1))
1182 return false;
1183 }
832b75ed 1184 }
2127e193
GI
1185
1186 return true;
1187}
1188
1189// Read SMART Log page(s)
1190bool ataReadSmartLog(ata_device * device, unsigned char logaddr,
1191 void * data, unsigned nsectors)
1192{
1193 ata_cmd_in in;
1194 in.in_regs.command = ATA_SMART_CMD;
1195 in.in_regs.features = ATA_SMART_READ_LOG_SECTOR;
1196 in.set_data_in(data, nsectors);
1197 in.in_regs.lba_high = SMART_CYL_HI;
1198 in.in_regs.lba_mid = SMART_CYL_LOW;
1199 in.in_regs.lba_low = logaddr;
1200
1201 if (!device->ata_pass_through(in)) { // TODO: Debug output
1202 pout("ATA_SMART_READ_LOG failed: %s\n", device->get_errmsg());
1203 return false;
1204 }
1205 return true;
1206}
1207
1208
1209
1210// Reads the SMART or GPL Log Directory (log #0)
1211int ataReadLogDirectory(ata_device * device, ata_smart_log_directory * data, bool gpl)
1212{
1213 if (!gpl) { // SMART Log directory
1214 if (smartcommandhandler(device, READ_LOG, 0x00, (char *)data))
1215 return -1;
1216 }
1217 else { // GP Log directory
1218 if (!ataReadLogExt(device, 0x00, 0x00, 0, data, 1))
1219 return -1;
1220 }
1221
1222 // swap endian order if needed
1223 if (isbigendian())
1224 swapx(&data->logversion);
1225
832b75ed
GG
1226 return 0;
1227}
1228
1229
1230// Reads the selective self-test log (log #9)
2127e193 1231int ataReadSelectiveSelfTestLog(ata_device * device, struct ata_selective_self_test_log *data){
832b75ed
GG
1232
1233 // get data from device
1234 if (smartcommandhandler(device, READ_LOG, 0x09, (char *)data)){
a7e8ffec 1235 pout("Error SMART Read Selective Self-Test Log failed: %s\n", device->get_errmsg());
832b75ed
GG
1236 return -1;
1237 }
1238
1239 // compute its checksum, and issue a warning if needed
2127e193 1240 if (checksum(data))
832b75ed
GG
1241 checksumwarning("SMART Selective Self-Test Log Structure");
1242
1243 // swap endian order if needed
1244 if (isbigendian()){
1245 int i;
1246 swap2((char *)&(data->logversion));
1247 for (i=0;i<5;i++){
1248 swap8((char *)&(data->span[i].start));
1249 swap8((char *)&(data->span[i].end));
1250 }
1251 swap8((char *)&(data->currentlba));
1252 swap2((char *)&(data->currentspan));
1253 swap2((char *)&(data->flags));
1254 swap2((char *)&(data->pendingtime));
1255 }
1256
1257 if (data->logversion != 1)
2127e193 1258 pout("Note: selective self-test log revision number (%d) not 1 implies that no selective self-test has ever been run\n", data->logversion);
832b75ed
GG
1259
1260 return 0;
1261}
1262
1263// Writes the selective self-test log (log #9)
2127e193 1264int ataWriteSelectiveSelfTestLog(ata_device * device, ata_selective_selftest_args & args,
cfbba5b9
GI
1265 const ata_smart_values * sv, uint64_t num_sectors,
1266 const ata_selective_selftest_args * prev_args)
2127e193 1267{
a37e7145
GG
1268 // Disk size must be known
1269 if (!num_sectors) {
1270 pout("Disk size is unknown, unable to check selective self-test spans\n");
1271 return -1;
1272 }
1273
1274 // Read log
832b75ed 1275 struct ata_selective_self_test_log sstlog, *data=&sstlog;
832b75ed 1276 unsigned char *ptr=(unsigned char *)data;
832b75ed
GG
1277 if (ataReadSelectiveSelfTestLog(device, data)) {
1278 pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
1279 return -1;
1280 }
1281
2127e193
GI
1282 // Set log version
1283 data->logversion = 1;
832b75ed
GG
1284
1285 // Host is NOT allowed to write selective self-test log if a selective
1286 // self-test is in progress.
1287 if (0<data->currentspan && data->currentspan<6 && ((sv->self_test_exec_status)>>4)==15) {
1288 pout("Error SMART Selective or other Self-Test in progress.\n");
1289 return -4;
1290 }
a37e7145
GG
1291
1292 // Set start/end values based on old spans for special -t select,... options
1293 int i;
2127e193
GI
1294 for (i = 0; i < args.num_spans; i++) {
1295 int mode = args.span[i].mode;
1296 uint64_t start = args.span[i].start;
1297 uint64_t end = args.span[i].end;
a37e7145
GG
1298 if (mode == SEL_CONT) {// redo or next dependig on last test status
1299 switch (sv->self_test_exec_status >> 4) {
1300 case 1: case 2: // Aborted/Interrupted by host
1301 pout("Continue Selective Self-Test: Redo last span\n");
1302 mode = SEL_REDO;
1303 break;
1304 default: // All others
1305 pout("Continue Selective Self-Test: Start next span\n");
1306 mode = SEL_NEXT;
1307 break;
1308 }
1309 }
cfbba5b9
GI
1310
1311 if ( (mode == SEL_REDO || mode == SEL_NEXT)
1312 && prev_args && i < prev_args->num_spans
1313 && !data->span[i].start && !data->span[i].end) {
1314 // Some drives do not preserve the selective self-test log accross
1315 // power-cyles. If old span on drive is cleared use span provided
1316 // by caller. This is used by smartd (first span only).
1317 data->span[i].start = prev_args->span[i].start;
1318 data->span[i].end = prev_args->span[i].end;
1319 }
1320
a37e7145
GG
1321 switch (mode) {
1322 case SEL_RANGE: // -t select,START-END
1323 break;
1324 case SEL_REDO: // -t select,redo... => Redo current
1325 start = data->span[i].start;
1326 if (end > 0) { // -t select,redo+SIZE
1327 end--; end += start; // [oldstart, oldstart+SIZE)
1328 }
1329 else // -t select,redo
1330 end = data->span[i].end; // [oldstart, oldend]
1331 break;
1332 case SEL_NEXT: // -t select,next... => Do next
1333 if (data->span[i].end == 0) {
1334 start = end = 0; break; // skip empty spans
1335 }
1336 start = data->span[i].end + 1;
1337 if (start >= num_sectors)
1338 start = 0; // wrap around
1339 if (end > 0) { // -t select,next+SIZE
1340 end--; end += start; // (oldend, oldend+SIZE]
1341 }
1342 else { // -t select,next
1343 uint64_t oldsize = data->span[i].end - data->span[i].start + 1;
1344 end = start + oldsize - 1; // (oldend, oldend+oldsize]
1345 if (end >= num_sectors) {
1346 // Adjust size to allow round-robin testing without future size decrease
1347 uint64_t spans = (num_sectors + oldsize-1) / oldsize;
1348 uint64_t newsize = (num_sectors + spans-1) / spans;
1349 uint64_t newstart = num_sectors - newsize, newend = num_sectors - 1;
2127e193
GI
1350 pout("Span %d changed from %"PRIu64"-%"PRIu64" (%"PRIu64" sectors)\n",
1351 i, start, end, oldsize);
1352 pout(" to %"PRIu64"-%"PRIu64" (%"PRIu64" sectors) (%"PRIu64" spans)\n",
1353 newstart, newend, newsize, spans);
a37e7145
GG
1354 start = newstart; end = newend;
1355 }
1356 }
1357 break;
1358 default:
1359 pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode);
1360 return -1;
1361 }
1362 // Range check
1363 if (start < num_sectors && num_sectors <= end) {
1364 if (end != ~(uint64_t)0) // -t select,N-max
1365 pout("Size of self-test span %d decreased according to disk size\n", i);
1366 end = num_sectors - 1;
1367 }
1368 if (!(start <= end && end < num_sectors)) {
1369 pout("Invalid selective self-test span %d: %"PRIu64"-%"PRIu64" (%"PRIu64" sectors)\n",
1370 i, start, end, num_sectors);
1371 return -1;
1372 }
2127e193
GI
1373 // Return the actual mode and range to caller.
1374 args.span[i].mode = mode;
1375 args.span[i].start = start;
1376 args.span[i].end = end;
a37e7145
GG
1377 }
1378
832b75ed
GG
1379 // Clear spans
1380 for (i=0; i<5; i++)
1381 memset(data->span+i, 0, sizeof(struct test_span));
1382
1383 // Set spans for testing
2127e193
GI
1384 for (i = 0; i < args.num_spans; i++){
1385 data->span[i].start = args.span[i].start;
1386 data->span[i].end = args.span[i].end;
832b75ed
GG
1387 }
1388
1389 // host must initialize to zero before initiating selective self-test
1390 data->currentlba=0;
1391 data->currentspan=0;
1392
1393 // Perform off-line scan after selective test?
2127e193 1394 if (args.scan_after_select == 1)
832b75ed
GG
1395 // NO
1396 data->flags &= ~SELECTIVE_FLAG_DOSCAN;
2127e193 1397 else if (args.scan_after_select == 2)
832b75ed
GG
1398 // YES
1399 data->flags |= SELECTIVE_FLAG_DOSCAN;
1400
1401 // Must clear active and pending flags before writing
1402 data->flags &= ~(SELECTIVE_FLAG_ACTIVE);
1403 data->flags &= ~(SELECTIVE_FLAG_PENDING);
1404
1405 // modify pending time?
2127e193
GI
1406 if (args.pending_time)
1407 data->pendingtime = (unsigned short)(args.pending_time-1);
832b75ed
GG
1408
1409 // Set checksum to zero, then compute checksum
1410 data->checksum=0;
a37e7145 1411 unsigned char cksum=0;
832b75ed
GG
1412 for (i=0; i<512; i++)
1413 cksum+=ptr[i];
1414 cksum=~cksum;
1415 cksum+=1;
1416 data->checksum=cksum;
1417
a37e7145 1418 // swap endian order if needed
832b75ed 1419 if (isbigendian()){
832b75ed 1420 swap2((char *)&(data->logversion));
cfbba5b9
GI
1421 for (int b = 0; b < 5; b++) {
1422 swap8((char *)&(data->span[b].start));
1423 swap8((char *)&(data->span[b].end));
832b75ed
GG
1424 }
1425 swap8((char *)&(data->currentlba));
1426 swap2((char *)&(data->currentspan));
1427 swap2((char *)&(data->flags));
1428 swap2((char *)&(data->pendingtime));
1429 }
1430
1431 // write new selective self-test log
1432 if (smartcommandhandler(device, WRITE_LOG, 0x09, (char *)data)){
a7e8ffec 1433 pout("Error Write Selective Self-Test Log failed: %s\n", device->get_errmsg());
832b75ed
GG
1434 return -3;
1435 }
1436
1437 return 0;
1438}
1439
1440// This corrects some quantities that are byte reversed in the SMART
1441// ATA ERROR LOG.
2127e193
GI
1442static void fixsamsungerrorlog(ata_smart_errorlog * data)
1443{
832b75ed
GG
1444 // FIXED IN SAMSUNG -25 FIRMWARE???
1445 // Device error count in bytes 452-3
1446 swap2((char *)&(data->ata_error_count));
1447
1448 // FIXED IN SAMSUNG -22a FIRMWARE
1449 // step through 5 error log data structures
2127e193 1450 for (int i = 0; i < 5; i++){
832b75ed 1451 // step through 5 command data structures
2127e193 1452 for (int j = 0; j < 5; j++)
832b75ed
GG
1453 // Command data structure 4-byte millisec timestamp. These are
1454 // bytes (N+8, N+9, N+10, N+11).
1455 swap4((char *)&(data->errorlog_struct[i].commands[j].timestamp));
1456 // Error data structure two-byte hour life timestamp. These are
1457 // bytes (N+28, N+29).
1458 swap2((char *)&(data->errorlog_struct[i].error_struct.timestamp));
1459 }
1460 return;
1461}
1462
1463// NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
2127e193
GI
1464static void fixsamsungerrorlog2(ata_smart_errorlog * data)
1465{
832b75ed
GG
1466 // Device error count in bytes 452-3
1467 swap2((char *)&(data->ata_error_count));
1468 return;
1469}
1470
1471// Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1472// Error Log is #2, and the Extended Comprehensive SMART Error log is
1473// #3
2127e193
GI
1474int ataReadErrorLog (ata_device * device, ata_smart_errorlog *data,
1475 unsigned char fix_firmwarebug)
1476{
832b75ed
GG
1477
1478 // get data from device
1479 if (smartcommandhandler(device, READ_LOG, 0x01, (char *)data)){
a7e8ffec 1480 pout("Error SMART Error Log Read failed: %s\n", device->get_errmsg());
832b75ed
GG
1481 return -1;
1482 }
1483
1484 // compute its checksum, and issue a warning if needed
2127e193 1485 if (checksum(data))
832b75ed
GG
1486 checksumwarning("SMART ATA Error Log Structure");
1487
1488 // Some disks have the byte order reversed in some SMART Summary
1489 // Error log entries
2127e193 1490 if (fix_firmwarebug == FIX_SAMSUNG)
832b75ed 1491 fixsamsungerrorlog(data);
2127e193 1492 else if (fix_firmwarebug == FIX_SAMSUNG2)
832b75ed
GG
1493 fixsamsungerrorlog2(data);
1494
a37e7145 1495 // swap endian order if needed
832b75ed
GG
1496 if (isbigendian()){
1497 int i,j;
1498
1499 // Device error count in bytes 452-3
1500 swap2((char *)&(data->ata_error_count));
1501
1502 // step through 5 error log data structures
1503 for (i=0; i<5; i++){
1504 // step through 5 command data structures
1505 for (j=0; j<5; j++)
1506 // Command data structure 4-byte millisec timestamp
1507 swap4((char *)&(data->errorlog_struct[i].commands[j].timestamp));
1508 // Error data structure life timestamp
1509 swap2((char *)&(data->errorlog_struct[i].error_struct.timestamp));
1510 }
1511 }
1512
1513 return 0;
1514}
1515
2127e193
GI
1516// Read Extended Comprehensive Error Log
1517bool ataReadExtErrorLog(ata_device * device, ata_smart_exterrlog * log,
1518 unsigned nsectors)
1519{
1520 if (!ataReadLogExt(device, 0x03, 0x00, 0, log, nsectors))
1521 return false;
1522
1523 check_multi_sector_sum(log, nsectors, "SMART Extended Comprehensive Error Log Structure");
1524
1525 if (isbigendian()) {
1526 swapx(&log->device_error_count);
1527 swapx(&log->error_log_index);
1528
1529 for (unsigned i = 0; i < nsectors; i++) {
1530 for (unsigned j = 0; j < 4; j++)
1531 swapx(&log->error_logs[i].commands[j].timestamp);
1532 swapx(&log->error_logs[i].error.timestamp);
1533 }
1534 }
1535
1536 return true;
1537}
1538
1539
1540int ataReadSmartThresholds (ata_device * device, struct ata_smart_thresholds_pvt *data){
832b75ed
GG
1541
1542 // get data from device
1543 if (smartcommandhandler(device, READ_THRESHOLDS, 0, (char *)data)){
a7e8ffec 1544 pout("Error SMART Thresholds Read failed: %s\n", device->get_errmsg());
832b75ed
GG
1545 return -1;
1546 }
1547
1548 // compute its checksum, and issue a warning if needed
2127e193 1549 if (checksum(data))
832b75ed
GG
1550 checksumwarning("SMART Attribute Thresholds Structure");
1551
a37e7145 1552 // swap endian order if needed
832b75ed
GG
1553 if (isbigendian())
1554 swap2((char *)&(data->revnumber));
1555
1556 return 0;
1557}
1558
2127e193 1559int ataEnableSmart (ata_device * device ){
832b75ed 1560 if (smartcommandhandler(device, ENABLE, 0, NULL)){
a7e8ffec 1561 pout("Error SMART Enable failed: %s\n", device->get_errmsg());
832b75ed
GG
1562 return -1;
1563 }
1564 return 0;
1565}
1566
2127e193 1567int ataDisableSmart (ata_device * device ){
832b75ed
GG
1568
1569 if (smartcommandhandler(device, DISABLE, 0, NULL)){
a7e8ffec 1570 pout("Error SMART Disable failed: %s\n", device->get_errmsg());
832b75ed
GG
1571 return -1;
1572 }
1573 return 0;
1574}
1575
2127e193 1576int ataEnableAutoSave(ata_device * device){
832b75ed 1577 if (smartcommandhandler(device, AUTOSAVE, 241, NULL)){
a7e8ffec 1578 pout("Error SMART Enable Auto-save failed: %s\n", device->get_errmsg());
832b75ed
GG
1579 return -1;
1580 }
1581 return 0;
1582}
1583
2127e193 1584int ataDisableAutoSave(ata_device * device){
832b75ed
GG
1585
1586 if (smartcommandhandler(device, AUTOSAVE, 0, NULL)){
a7e8ffec 1587 pout("Error SMART Disable Auto-save failed: %s\n", device->get_errmsg());
832b75ed
GG
1588 return -1;
1589 }
1590 return 0;
1591}
1592
1593// In *ALL* ATA standards the Enable/Disable AutoOffline command is
1594// marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1595// vendors still support it for backwards compatibility. IBM documents
1596// it for some drives.
2127e193 1597int ataEnableAutoOffline (ata_device * device){
832b75ed
GG
1598
1599 /* timer hard coded to 4 hours */
1600 if (smartcommandhandler(device, AUTO_OFFLINE, 248, NULL)){
a7e8ffec 1601 pout("Error SMART Enable Automatic Offline failed: %s\n", device->get_errmsg());
832b75ed
GG
1602 return -1;
1603 }
1604 return 0;
1605}
1606
1607// Another Obsolete Command. See comments directly above, associated
1608// with the corresponding Enable command.
2127e193 1609int ataDisableAutoOffline (ata_device * device){
832b75ed
GG
1610
1611 if (smartcommandhandler(device, AUTO_OFFLINE, 0, NULL)){
a7e8ffec 1612 pout("Error SMART Disable Automatic Offline failed: %s\n", device->get_errmsg());
832b75ed
GG
1613 return -1;
1614 }
1615 return 0;
1616}
1617
1618// If SMART is enabled, supported, and working, then this call is
1619// guaranteed to return 1, else zero. Note that it should return 1
1620// regardless of whether the disk's SMART status is 'healthy' or
1621// 'failing'.
2127e193 1622int ataDoesSmartWork(ata_device * device){
832b75ed
GG
1623 int retval=smartcommandhandler(device, STATUS, 0, NULL);
1624
1625 if (-1 == retval)
1626 return 0;
1627
1628 return 1;
1629}
1630
1631// This function uses a different interface (DRIVE_TASK) than the
1632// other commands in this file.
2127e193 1633int ataSmartStatus2(ata_device * device){
832b75ed
GG
1634 return smartcommandhandler(device, STATUS_CHECK, 0, NULL);
1635}
1636
1637// This is the way to execute ALL tests: offline, short self-test,
1638// extended self test, with and without captive mode, etc.
2127e193
GI
1639// TODO: Move to ataprint.cpp ?
1640int ataSmartTest(ata_device * device, int testtype, const ata_selective_selftest_args & selargs,
1641 const ata_smart_values * sv, uint64_t num_sectors)
a37e7145 1642{
2127e193 1643 char cmdmsg[128]; const char *type, *captive;
a7e8ffec 1644 int cap, retval, select=0;
832b75ed
GG
1645
1646 // Boolean, if set, says test is captive
1647 cap=testtype & CAPTIVE_MASK;
1648
1649 // Set up strings that describe the type of test
1650 if (cap)
1651 captive="captive";
1652 else
1653 captive="off-line";
1654
1655 if (testtype==OFFLINE_FULL_SCAN)
1656 type="off-line";
1657 else if (testtype==SHORT_SELF_TEST || testtype==SHORT_CAPTIVE_SELF_TEST)
1658 type="Short self-test";
1659 else if (testtype==EXTEND_SELF_TEST || testtype==EXTEND_CAPTIVE_SELF_TEST)
1660 type="Extended self-test";
1661 else if (testtype==CONVEYANCE_SELF_TEST || testtype==CONVEYANCE_CAPTIVE_SELF_TEST)
1662 type="Conveyance self-test";
1663 else if ((select=(testtype==SELECTIVE_SELF_TEST || testtype==SELECTIVE_CAPTIVE_SELF_TEST)))
1664 type="Selective self-test";
1665 else
cfbba5b9 1666 type = 0;
832b75ed
GG
1667
1668 // If doing a selective self-test, first use WRITE_LOG to write the
1669 // selective self-test log.
2127e193
GI
1670 ata_selective_selftest_args selargs_io = selargs; // filled with info about actual spans
1671 if (select && (retval = ataWriteSelectiveSelfTestLog(device, selargs_io, sv, num_sectors))) {
832b75ed
GG
1672 if (retval==-4)
1673 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1674 return retval;
1675 }
1676
1677 // Print ouf message that we are sending the command to test
1678 if (testtype==ABORT_SELF_TEST)
1679 sprintf(cmdmsg,"Abort SMART off-line mode self-test routine");
cfbba5b9
GI
1680 else if (!type)
1681 sprintf(cmdmsg, "SMART EXECUTE OFF-LINE IMMEDIATE subcommand 0x%02x", testtype);
832b75ed
GG
1682 else
1683 sprintf(cmdmsg,"Execute SMART %s routine immediately in %s mode",type,captive);
1684 pout("Sending command: \"%s\".\n",cmdmsg);
1685
1686 if (select) {
1687 int i;
1688 pout("SPAN STARTING_LBA ENDING_LBA\n");
2127e193 1689 for (i = 0; i < selargs_io.num_spans; i++)
832b75ed 1690 pout(" %d %20"PRId64" %20"PRId64"\n", i,
2127e193
GI
1691 selargs_io.span[i].start,
1692 selargs_io.span[i].end);
832b75ed
GG
1693 }
1694
1695 // Now send the command to test
a7e8ffec
GI
1696 if (smartcommandhandler(device, IMMEDIATE_OFFLINE, testtype, NULL)) {
1697 if (!(cap && device->get_errno() == EIO)) {
1698 pout("Command \"%s\" failed: %s\n", cmdmsg, device->get_errmsg());
1699 return -1;
1700 }
832b75ed
GG
1701 }
1702
1703 // Since the command succeeded, tell user
1704 if (testtype==ABORT_SELF_TEST)
1705 pout("Self-testing aborted!\n");
cfbba5b9
GI
1706 else {
1707 pout("Drive command \"%s\" successful.\n", cmdmsg);
1708 if (type)
1709 pout("Testing has begun.\n");
1710 }
832b75ed
GG
1711 return 0;
1712}
1713
1714/* Test Time Functions */
2127e193
GI
1715int TestTime(const ata_smart_values *data, int testtype)
1716{
832b75ed
GG
1717 switch (testtype){
1718 case OFFLINE_FULL_SCAN:
1719 return (int) data->total_time_to_complete_off_line;
1720 case SHORT_SELF_TEST:
1721 case SHORT_CAPTIVE_SELF_TEST:
1722 return (int) data->short_test_completion_time;
1723 case EXTEND_SELF_TEST:
1724 case EXTEND_CAPTIVE_SELF_TEST:
1725 return (int) data->extend_test_completion_time;
1726 case CONVEYANCE_SELF_TEST:
1727 case CONVEYANCE_CAPTIVE_SELF_TEST:
1728 return (int) data->conveyance_test_completion_time;
1729 default:
1730 return 0;
1731 }
1732}
1733
1734// This function tells you both about the ATA error log and the
1735// self-test error log capability (introduced in ATA-5). The bit is
1736// poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1737// SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1738// word 84 and 87. Top two bits must match the pattern 01. BEFORE
1739// ATA-6 these top two bits still had to match the pattern 01, but the
1740// remaining bits were reserved (==0).
2127e193
GI
1741int isSmartErrorLogCapable (const ata_smart_values * data, const ata_identify_device * identity)
1742{
832b75ed
GG
1743 unsigned short word84=identity->command_set_extension;
1744 unsigned short word87=identity->csf_default;
1745 int isata6=identity->major_rev_num & (0x01<<6);
1746 int isata7=identity->major_rev_num & (0x01<<7);
1747
1748 if ((isata6 || isata7) && (word84>>14) == 0x01 && (word84 & 0x01))
1749 return 1;
1750
1751 if ((isata6 || isata7) && (word87>>14) == 0x01 && (word87 & 0x01))
1752 return 1;
1753
1754 // otherwise we'll use the poorly documented capability bit
1755 return data->errorlog_capability & 0x01;
1756}
1757
1758// See previous function. If the error log exists then the self-test
1759// log should (must?) also exist.
2127e193
GI
1760int isSmartTestLogCapable (const ata_smart_values * data, const ata_identify_device *identity)
1761{
832b75ed
GG
1762 unsigned short word84=identity->command_set_extension;
1763 unsigned short word87=identity->csf_default;
1764 int isata6=identity->major_rev_num & (0x01<<6);
1765 int isata7=identity->major_rev_num & (0x01<<7);
1766
1767 if ((isata6 || isata7) && (word84>>14) == 0x01 && (word84 & 0x02))
1768 return 1;
1769
1770 if ((isata6 || isata7) && (word87>>14) == 0x01 && (word87 & 0x02))
1771 return 1;
1772
1773
1774 // otherwise we'll use the poorly documented capability bit
2127e193 1775 return data->errorlog_capability & 0x01;
832b75ed
GG
1776}
1777
1778
2127e193
GI
1779int isGeneralPurposeLoggingCapable(const ata_identify_device *identity)
1780{
832b75ed
GG
1781 unsigned short word84=identity->command_set_extension;
1782 unsigned short word87=identity->csf_default;
1783
1784 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1785 // cleared to zero, the contents of word 84 contains valid support
1786 // information. If not, support information is not valid in this
1787 // word.
1788 if ((word84>>14) == 0x01)
1789 // If bit 5 of word 84 is set to one, the device supports the
1790 // General Purpose Logging feature set.
1791 return (word84 & (0x01 << 5));
1792
1793 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1794 // cleared to zero, the contents of words (87:85) contain valid
1795 // information. If not, information is not valid in these words.
1796 if ((word87>>14) == 0x01)
1797 // If bit 5 of word 87 is set to one, the device supports
1798 // the General Purpose Logging feature set.
1799 return (word87 & (0x01 << 5));
1800
1801 // not capable
1802 return 0;
1803}
1804
1805
1806// SMART self-test capability is also indicated in bit 1 of DEVICE
1807// IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1808// However this was only introduced in ATA-6 (but self-test log was in
1809// ATA-5).
2127e193
GI
1810int isSupportExecuteOfflineImmediate(const ata_smart_values *data)
1811{
1812 return data->offline_data_collection_capability & 0x01;
832b75ed 1813}
2127e193 1814
832b75ed
GG
1815// Note in the ATA-5 standard, the following bit is listed as "Vendor
1816// Specific". So it may not be reliable. The only use of this that I
1817// have found is in IBM drives, where it is well-documented. See for
1818// example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1819// hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
2127e193
GI
1820int isSupportAutomaticTimer(const ata_smart_values * data)
1821{
1822 return data->offline_data_collection_capability & 0x02;
832b75ed 1823}
2127e193
GI
1824int isSupportOfflineAbort(const ata_smart_values *data)
1825{
1826 return data->offline_data_collection_capability & 0x04;
832b75ed 1827}
2127e193
GI
1828int isSupportOfflineSurfaceScan(const ata_smart_values * data)
1829{
832b75ed
GG
1830 return data->offline_data_collection_capability & 0x08;
1831}
2127e193
GI
1832int isSupportSelfTest (const ata_smart_values * data)
1833{
832b75ed
GG
1834 return data->offline_data_collection_capability & 0x10;
1835}
2127e193
GI
1836int isSupportConveyanceSelfTest(const ata_smart_values * data)
1837{
832b75ed
GG
1838 return data->offline_data_collection_capability & 0x20;
1839}
2127e193
GI
1840int isSupportSelectiveSelfTest(const ata_smart_values * data)
1841{
832b75ed
GG
1842 return data->offline_data_collection_capability & 0x40;
1843}
1844
bed94269
GI
1845// Get attribute state
1846ata_attr_state ata_get_attr_state(const ata_smart_attribute & attr,
cfbba5b9
GI
1847 int attridx,
1848 const ata_smart_threshold_entry * thresholds,
1849 const ata_vendor_attr_defs & defs,
1850 unsigned char * threshval /* = 0 */)
bed94269
GI
1851{
1852 if (!attr.id)
1853 return ATTRSTATE_NON_EXISTING;
832b75ed 1854
bed94269
GI
1855 // Normalized values (current,worst,threshold) not valid
1856 // if specified by '-v' option.
1857 // (Some SSD disks uses these bytes to store raw value).
1858 if (defs[attr.id].flags & ATTRFLAG_NO_NORMVAL)
1859 return ATTRSTATE_NO_NORMVAL;
832b75ed 1860
cfbba5b9
GI
1861 // Normally threshold is at same index as attribute
1862 int i = attridx;
1863 if (thresholds[i].id != attr.id) {
1864 // Find threshold id in table
1865 for (i = 0; thresholds[i].id != attr.id; ) {
1866 if (++i >= NUMBER_ATA_SMART_ATTRIBUTES)
1867 // Threshold id missing or thresholds cannot be read
1868 return ATTRSTATE_NO_THRESHOLD;
1869 }
1870 }
1871 unsigned char threshold = thresholds[i].threshold;
832b75ed 1872
cfbba5b9
GI
1873 // Return threshold if requested
1874 if (threshval)
1875 *threshval = threshold;
832b75ed 1876
bed94269
GI
1877 // Don't report a failed attribute if its threshold is 0.
1878 // ATA-3 (X3T13/2008D Revision 7b) declares 0x00 as the "always passing"
1879 // threshold (Later ATA versions declare all thresholds as "obsolete").
1880 // In practice, threshold value 0 is often used for usage attributes.
cfbba5b9 1881 if (!threshold)
bed94269 1882 return ATTRSTATE_OK;
832b75ed 1883
bed94269 1884 // Failed now if current value is below threshold
cfbba5b9 1885 if (attr.current <= threshold)
bed94269 1886 return ATTRSTATE_FAILED_NOW;
832b75ed 1887
a23d5117 1888 // Failed in the past if worst value is below threshold
cfbba5b9 1889 if (!(defs[attr.id].flags & ATTRFLAG_NO_WORSTVAL) && attr.worst <= threshold)
bed94269 1890 return ATTRSTATE_FAILED_PAST;
832b75ed 1891
bed94269 1892 return ATTRSTATE_OK;
832b75ed
GG
1893}
1894
bed94269
GI
1895// Get default raw value print format
1896static ata_attr_raw_format get_default_raw_format(unsigned char id)
a37e7145 1897{
bed94269
GI
1898 switch (id) {
1899 case 3: // Spin-up time
1900 return RAWFMT_RAW16_OPT_AVG16;
a37e7145 1901
bed94269
GI
1902 case 5: // Reallocated sector count
1903 case 196: // Reallocated event count
1904 return RAWFMT_RAW16_OPT_RAW16;
1905
1906 case 190: // Temperature
1907 case 194:
1908 return RAWFMT_TEMPMINMAX;
1909
1910 default:
1911 return RAWFMT_RAW48;
a37e7145 1912 }
bed94269
GI
1913}
1914
1915// Get attribute raw value.
1916uint64_t ata_get_attr_raw_value(const ata_smart_attribute & attr,
1917 const ata_vendor_attr_defs & defs)
1918{
a23d5117
GI
1919 const ata_vendor_attr_defs::entry & def = defs[attr.id];
1920
1921 // Use default byteorder if not specified
1922 const char * byteorder = def.byteorder;
1923 if (!*byteorder) {
cfbba5b9
GI
1924 switch (def.raw_format) {
1925 case RAWFMT_RAW64:
1926 case RAWFMT_HEX64:
1927 byteorder = "543210wv"; break;
1928 case RAWFMT_RAW24_DIV_RAW32:
1929 case RAWFMT_MSEC24_HOUR32:
1930 byteorder = "r543210"; break;
1931 default:
1932 byteorder = "543210"; break;
1933 }
a23d5117
GI
1934 }
1935
1936 // Build 64-bit value from selected bytes
1937 uint64_t rawvalue = 0;
1938 for (int i = 0; byteorder[i]; i++) {
1939 unsigned char b;
1940 switch (byteorder[i]) {
1941 case '0': b = attr.raw[0]; break;
1942 case '1': b = attr.raw[1]; break;
1943 case '2': b = attr.raw[2]; break;
1944 case '3': b = attr.raw[3]; break;
1945 case '4': b = attr.raw[4]; break;
1946 case '5': b = attr.raw[5]; break;
1947 case 'r': b = attr.reserv; break;
1948 case 'v': b = attr.current; break;
1949 case 'w': b = attr.worst; break;
1950 default : b = 0; break;
1951 }
1952 rawvalue <<= 8; rawvalue |= b;
a37e7145 1953 }
a23d5117 1954
bed94269 1955 return rawvalue;
a37e7145
GG
1956}
1957
1958
bed94269
GI
1959// Format attribute raw value.
1960std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
1961 const ata_vendor_attr_defs & defs)
1962{
a23d5117 1963 // Get 48 bit or 64 bit raw value
bed94269 1964 uint64_t rawvalue = ata_get_attr_raw_value(attr, defs);
832b75ed 1965
a7e8ffec
GI
1966 // Split into bytes and words
1967 unsigned char raw[6];
1968 raw[0] = (unsigned char) rawvalue;
1969 raw[1] = (unsigned char)(rawvalue >> 8);
1970 raw[2] = (unsigned char)(rawvalue >> 16);
1971 raw[3] = (unsigned char)(rawvalue >> 24);
1972 raw[4] = (unsigned char)(rawvalue >> 32);
1973 raw[5] = (unsigned char)(rawvalue >> 40);
832b75ed 1974 unsigned word[3];
bed94269
GI
1975 word[0] = raw[0] | (raw[1] << 8);
1976 word[1] = raw[2] | (raw[3] << 8);
1977 word[2] = raw[4] | (raw[5] << 8);
832b75ed 1978
bed94269
GI
1979 // Get print format
1980 ata_attr_raw_format format = defs[attr.id].raw_format;
1981 if (format == RAWFMT_DEFAULT)
1982 format = get_default_raw_format(attr.id);
1983
1984 // Print
1985 std::string s;
1986 switch (format) {
1987 case RAWFMT_RAW8:
1988 s = strprintf("%d %d %d %d %d %d",
1989 raw[5], raw[4], raw[3], raw[2], raw[1], raw[0]);
832b75ed 1990 break;
bed94269
GI
1991
1992 case RAWFMT_RAW16:
1993 s = strprintf("%u %u %u", word[2], word[1], word[0]);
1994 break;
1995
1996 case RAWFMT_RAW48:
a23d5117 1997 case RAWFMT_RAW64:
bed94269
GI
1998 s = strprintf("%"PRIu64, rawvalue);
1999 break;
2000
2001 case RAWFMT_HEX48:
2002 s = strprintf("0x%012"PRIx64, rawvalue);
2003 break;
2004
bed94269
GI
2005 case RAWFMT_HEX64:
2006 s = strprintf("0x%016"PRIx64, rawvalue);
2007 break;
2008
2009 case RAWFMT_RAW16_OPT_RAW16:
2010 s = strprintf("%u", word[0]);
2127e193 2011 if (word[1] || word[2])
bed94269 2012 s += strprintf(" (%u, %u)", word[2], word[1]);
2127e193 2013 break;
bed94269
GI
2014
2015 case RAWFMT_RAW16_OPT_AVG16:
2016 s = strprintf("%u", word[0]);
2017 if (word[1])
2018 s += strprintf(" (Average %u)", word[1]);
2019 break;
2020
cfbba5b9
GI
2021 case RAWFMT_RAW24_DIV_RAW24:
2022 s = strprintf("%u/%u",
2023 (unsigned)(rawvalue >> 24), (unsigned)(rawvalue & 0x00ffffffULL));
2024 break;
2025
2026 case RAWFMT_RAW24_DIV_RAW32:
2027 s = strprintf("%u/%u",
2028 (unsigned)(rawvalue >> 32), (unsigned)(rawvalue & 0xffffffffULL));
bed94269
GI
2029 break;
2030
2031 case RAWFMT_MIN2HOUR:
2032 {
832b75ed 2033 // minutes
bed94269
GI
2034 int64_t temp = word[0]+(word[1]<<16);
2035 int64_t tmp1 = temp/60;
2036 int64_t tmp2 = temp%60;
2037 s = strprintf("%"PRIu64"h+%02"PRIu64"m", tmp1, tmp2);
2127e193 2038 if (word[2])
bed94269 2039 s += strprintf(" (%u)", word[2]);
832b75ed 2040 }
bed94269
GI
2041 break;
2042
2043 case RAWFMT_SEC2HOUR:
2044 {
832b75ed 2045 // seconds
bed94269
GI
2046 int64_t hours = rawvalue/3600;
2047 int64_t minutes = (rawvalue-3600*hours)/60;
2048 int64_t seconds = rawvalue%60;
2049 s = strprintf("%"PRIu64"h+%02"PRIu64"m+%02"PRIu64"s", hours, minutes, seconds);
832b75ed 2050 }
a37e7145 2051 break;
bed94269
GI
2052
2053 case RAWFMT_HALFMIN2HOUR:
2054 {
2055 // 30-second counter
2056 int64_t hours = rawvalue/120;
2057 int64_t minutes = (rawvalue-120*hours)/2;
2058 s += strprintf("%"PRIu64"h+%02"PRIu64"m", hours, minutes);
832b75ed 2059 }
832b75ed 2060 break;
bed94269 2061
cfbba5b9
GI
2062 case RAWFMT_MSEC24_HOUR32:
2063 {
2064 // hours + milliseconds
2065 unsigned hours = (unsigned)(rawvalue & 0xffffffffULL);
2066 unsigned milliseconds = (unsigned)(rawvalue >> 32);
2067 unsigned seconds = milliseconds / 1000;
2068 s = strprintf("%uh+%02um+%02u.%03us",
2069 hours, seconds / 60, seconds % 60, milliseconds % 1000);
2070 }
2071 break;
2072
bed94269 2073 case RAWFMT_TEMPMINMAX:
832b75ed 2074 // Temperature
bed94269
GI
2075 s = strprintf("%u", word[0]);
2076 if (word[1] || word[2]) {
2077 unsigned lo = ~0, hi = ~0;
2078 if (!raw[3]) {
2079 // 00 HH 00 LL 00 TT (IBM)
2080 hi = word[2]; lo = word[1];
2081 }
2082 else if (!word[2]) {
2083 // 00 00 HH LL 00 TT (Maxtor)
2084 hi = raw[3]; lo = raw[2];
2085 }
2086 if (lo > hi) {
2087 unsigned t = lo; lo = hi; hi = t;
2088 }
2089 if (lo <= word[0] && word[0] <= hi)
cfbba5b9 2090 s += strprintf(" (Min/Max %u/%u)", lo, hi);
bed94269
GI
2091 else
2092 s += strprintf(" (%d %d %d %d)", raw[5], raw[4], raw[3], raw[2]);
832b75ed 2093 }
832b75ed 2094 break;
bed94269
GI
2095
2096 case RAWFMT_TEMP10X:
2097 // ten times temperature in Celsius
2098 s = strprintf("%d.%d", word[0]/10, word[0]%10);
2127e193 2099 break;
bed94269 2100
832b75ed 2101 default:
bed94269
GI
2102 s = "?"; // Should not happen
2103 break;
832b75ed 2104 }
832b75ed 2105
bed94269
GI
2106 return s;
2107}
832b75ed 2108
bed94269
GI
2109// Attribute names shouldn't be longer than 23 chars, otherwise they break the
2110// output of smartctl.
2111static const char * get_default_attr_name(unsigned char id)
2112{
2113 switch (id) {
832b75ed 2114 case 1:
bed94269 2115 return "Raw_Read_Error_Rate";
832b75ed 2116 case 2:
bed94269 2117 return "Throughput_Performance";
832b75ed 2118 case 3:
bed94269 2119 return "Spin_Up_Time";
832b75ed 2120 case 4:
bed94269 2121 return "Start_Stop_Count";
832b75ed 2122 case 5:
bed94269 2123 return "Reallocated_Sector_Ct";
832b75ed 2124 case 6:
bed94269 2125 return "Read_Channel_Margin";
832b75ed 2126 case 7:
bed94269 2127 return "Seek_Error_Rate";
832b75ed 2128 case 8:
bed94269 2129 return "Seek_Time_Performance";
832b75ed 2130 case 9:
bed94269 2131 return "Power_On_Hours";
832b75ed 2132 case 10:
bed94269 2133 return "Spin_Retry_Count";
832b75ed 2134 case 11:
bed94269 2135 return "Calibration_Retry_Count";
832b75ed 2136 case 12:
bed94269 2137 return "Power_Cycle_Count";
832b75ed 2138 case 13:
bed94269 2139 return "Read_Soft_Error_Rate";
eb07ddf2 2140 case 175:
bed94269 2141 return "Program_Fail_Count_Chip";
eb07ddf2 2142 case 176:
bed94269 2143 return "Erase_Fail_Count_Chip";
eb07ddf2 2144 case 177:
bed94269 2145 return "Wear_Leveling_Count";
2127e193 2146 case 178:
bed94269 2147 return "Used_Rsvd_Blk_Cnt_Chip";
2127e193 2148 case 179:
bed94269 2149 return "Used_Rsvd_Blk_Cnt_Tot";
2127e193 2150 case 180:
bed94269 2151 return "Unused_Rsvd_Blk_Cnt_Tot";
eb07ddf2 2152 case 181:
bed94269 2153 return "Program_Fail_Cnt_Total";
eb07ddf2 2154 case 182:
bed94269 2155 return "Erase_Fail_Count_Total";
2127e193 2156 case 183:
bed94269 2157 return "Runtime_Bad_Block";
eb07ddf2 2158 case 184:
bed94269 2159 return "End-to-End_Error";
a37e7145 2160 case 187:
bed94269 2161 return "Reported_Uncorrect";
eb07ddf2 2162 case 188:
bed94269 2163 return "Command_Timeout";
a37e7145 2164 case 189:
bed94269 2165 return "High_Fly_Writes";
4d59bff9
GG
2166 case 190:
2167 // Western Digital uses this for temperature.
2168 // It's identical to Attribute 194 except that it
2169 // has a failure threshold set to correspond to the
2170 // max allowed operating temperature of the drive, which
2171 // is typically 55C. So if this attribute has failed
2172 // in the past, it indicates that the drive temp exceeded
2173 // 55C sometime in the past.
bed94269 2174 return "Airflow_Temperature_Cel";
832b75ed 2175 case 191:
bed94269 2176 return "G-Sense_Error_Rate";
832b75ed 2177 case 192:
bed94269 2178 return "Power-Off_Retract_Count";
832b75ed 2179 case 193:
bed94269 2180 return "Load_Cycle_Count";
832b75ed 2181 case 194:
bed94269 2182 return "Temperature_Celsius";
832b75ed 2183 case 195:
bed94269
GI
2184 // Fujitsu: "ECC_On_The_Fly_Count";
2185 return "Hardware_ECC_Recovered";
832b75ed 2186 case 196:
bed94269 2187 return "Reallocated_Event_Count";
832b75ed 2188 case 197:
bed94269 2189 return "Current_Pending_Sector";
832b75ed 2190 case 198:
bed94269 2191 return "Offline_Uncorrectable";
832b75ed 2192 case 199:
bed94269 2193 return "UDMA_CRC_Error_Count";
832b75ed 2194 case 200:
bed94269
GI
2195 // Western Digital
2196 return "Multi_Zone_Error_Rate";
832b75ed 2197 case 201:
bed94269 2198 return "Soft_Read_Error_Rate";
832b75ed 2199 case 202:
bed94269
GI
2200 // Fujitsu: "TA_Increase_Count"
2201 return "Data_Address_Mark_Errs";
832b75ed
GG
2202 case 203:
2203 // Fujitsu
bed94269 2204 return "Run_Out_Cancel";
832b75ed 2205 // Maxtor: ECC Errors
832b75ed 2206 case 204:
bed94269
GI
2207 // Fujitsu: "Shock_Count_Write_Opern"
2208 return "Soft_ECC_Correction";
832b75ed 2209 case 205:
bed94269
GI
2210 // Fujitsu: "Shock_Rate_Write_Opern"
2211 return "Thermal_Asperity_Rate";
832b75ed
GG
2212 case 206:
2213 // Fujitsu
bed94269 2214 return "Flying_Height";
832b75ed
GG
2215 case 207:
2216 // Maxtor
bed94269 2217 return "Spin_High_Current";
832b75ed
GG
2218 case 208:
2219 // Maxtor
bed94269 2220 return "Spin_Buzz";
832b75ed
GG
2221 case 209:
2222 // Maxtor
bed94269 2223 return "Offline_Seek_Performnce";
832b75ed 2224 case 220:
bed94269 2225 return "Disk_Shift";
832b75ed 2226 case 221:
bed94269 2227 return "G-Sense_Error_Rate";
832b75ed 2228 case 222:
bed94269 2229 return "Loaded_Hours";
832b75ed 2230 case 223:
bed94269 2231 return "Load_Retry_Count";
832b75ed 2232 case 224:
bed94269 2233 return "Load_Friction";
832b75ed 2234 case 225:
bed94269 2235 return "Load_Cycle_Count";
832b75ed 2236 case 226:
bed94269 2237 return "Load-in_Time";
832b75ed 2238 case 227:
bed94269 2239 return "Torq-amp_Count";
832b75ed 2240 case 228:
bed94269 2241 return "Power-off_Retract_Count";
832b75ed
GG
2242 case 230:
2243 // seen in IBM DTPA-353750
bed94269 2244 return "Head_Amplitude";
832b75ed 2245 case 231:
bed94269
GI
2246 return "Temperature_Celsius";
2247 case 232:
2248 // seen in Intel X25-E SSD
2249 return "Available_Reservd_Space";
2250 case 233:
2251 // seen in Intel X25-E SSD
2252 return "Media_Wearout_Indicator";
832b75ed 2253 case 240:
bed94269
GI
2254 return "Head_Flying_Hours";
2255 case 241:
2256 return "Total_LBAs_Written";
2257 case 242:
2258 return "Total_LBAs_Read";
832b75ed 2259 case 250:
bed94269
GI
2260 return "Read_Error_Retry_Rate";
2261 case 254:
2262 return "Free_Fall_Sensor";
832b75ed 2263 default:
bed94269 2264 return "Unknown_Attribute";
832b75ed 2265 }
832b75ed
GG
2266}
2267
bed94269
GI
2268// Get attribute name
2269std::string ata_get_smart_attr_name(unsigned char id, const ata_vendor_attr_defs & defs)
2127e193 2270{
bed94269
GI
2271 if (!defs[id].name.empty())
2272 return defs[id].name;
2273 else
2274 return get_default_attr_name(id);
2275}
2276
2277// Find attribute index for attribute id, -1 if not found.
2278int ata_find_attr_index(unsigned char id, const ata_smart_values & smartval)
2279{
2280 if (!id)
832b75ed 2281 return -1;
2127e193 2282 for (int i = 0; i < NUMBER_ATA_SMART_ATTRIBUTES; i++) {
bed94269
GI
2283 if (smartval.vendor_attributes[i].id == id)
2284 return i;
2285 }
832b75ed
GG
2286 return -1;
2287}
2288
4d59bff9
GG
2289// Return Temperature Attribute raw value selected according to possible
2290// non-default interpretations. If the Attribute does not exist, return 0
bed94269 2291unsigned char ata_return_temperature_value(const ata_smart_values * data, const ata_vendor_attr_defs & defs)
2127e193
GI
2292{
2293 for (int i = 0; i < 3; i++) {
4d59bff9
GG
2294 static const unsigned char ids[3] = {194, 9, 220};
2295 unsigned char id = ids[i];
bed94269
GI
2296 const ata_attr_raw_format format = defs[id].raw_format;
2297 if (!( (id == 194 && format == RAWFMT_DEFAULT)
2298 || format == RAWFMT_TEMPMINMAX || format == RAWFMT_TEMP10X))
4d59bff9 2299 continue;
bed94269
GI
2300 int idx = ata_find_attr_index(id, *data);
2301 if (idx < 0)
4d59bff9 2302 continue;
bed94269
GI
2303 uint64_t raw = ata_get_attr_raw_value(data->vendor_attributes[idx], defs);
2304 unsigned temp = (unsigned short)raw; // ignore possible min/max values in high words
2305 if (format == RAWFMT_TEMP10X) // -v N,temp10x
4d59bff9
GG
2306 temp = (temp+5) / 10;
2307 if (!(0 < temp && temp <= 255))
2308 continue;
2309 return temp;
2310 }
2311 // No valid attribute found
2312 return 0;
2313}
a37e7145 2314
2127e193 2315
a37e7145 2316// Read SCT Status
2127e193 2317int ataReadSCTStatus(ata_device * device, ata_sct_status_response * sts)
a37e7145
GG
2318{
2319 // read SCT status via SMART log 0xe0
2320 memset(sts, 0, sizeof(*sts));
2321 if (smartcommandhandler(device, READ_LOG, 0xe0, (char *)sts)){
a7e8ffec 2322 pout("Error Read SCT Status failed: %s\n", device->get_errmsg());
a37e7145
GG
2323 return -1;
2324 }
2325
2326 // swap endian order if needed
2327 if (isbigendian()){
2328 swapx(&sts->format_version);
2329 swapx(&sts->sct_version);
2330 swapx(&sts->sct_spec);
2331 swapx(&sts->ext_status_code);
2332 swapx(&sts->action_code);
2333 swapx(&sts->function_code);
2334 swapx(&sts->over_limit_count);
2335 swapx(&sts->under_limit_count);
2336 }
2337
2338 // Check format version
2339 if (!(sts->format_version == 2 || sts->format_version == 3)) {
2340 pout("Error unknown SCT Status format version %u, should be 2 or 3.\n", sts->format_version);
2341 return -1;
2342 }
2343 return 0;
2344}
2345
2346// Read SCT Temperature History Table and Status
2127e193 2347int ataReadSCTTempHist(ata_device * device, ata_sct_temperature_history_table * tmh,
a37e7145
GG
2348 ata_sct_status_response * sts)
2349{
2350 // Check initial status
2351 if (ataReadSCTStatus(device, sts))
2352 return -1;
2353
2354 // Do nothing if other SCT command is executing
2355 if (sts->ext_status_code == 0xffff) {
2356 pout("Another SCT command is executing, abort Read Data Table\n"
2357 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2358 sts->ext_status_code, sts->action_code, sts->function_code);
2359 return -1;
2360 }
2361
2362 ata_sct_data_table_command cmd; memset(&cmd, 0, sizeof(cmd));
2363 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2364 cmd.action_code = 5; // Data table command
2365 cmd.function_code = 1; // Read table
2366 cmd.table_id = 2; // Temperature History Table
2367
7f0798ef
GI
2368 // swap endian order if needed
2369 if (isbigendian()) {
2370 swapx(&cmd.action_code);
2371 swapx(&cmd.function_code);
2372 swapx(&cmd.table_id);
2373 }
2374
a37e7145
GG
2375 // write command via SMART log page 0xe0
2376 if (smartcommandhandler(device, WRITE_LOG, 0xe0, (char *)&cmd)){
a7e8ffec 2377 pout("Error Write SCT Data Table command failed: %s\n", device->get_errmsg());
a37e7145
GG
2378 return -1;
2379 }
2380
2381 // read SCT data via SMART log page 0xe1
2382 memset(tmh, 0, sizeof(*tmh));
2383 if (smartcommandhandler(device, READ_LOG, 0xe1, (char *)tmh)){
a7e8ffec 2384 pout("Error Read SCT Data Table failed: %s\n", device->get_errmsg());
a37e7145
GG
2385 return -1;
2386 }
2387
2388 // re-read and check SCT status
2389 if (ataReadSCTStatus(device, sts))
2390 return -1;
2391
2392 if (!(sts->ext_status_code == 0 && sts->action_code == 5 && sts->function_code == 1)) {
a23d5117 2393 pout("Error unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
a37e7145
GG
2394 sts->ext_status_code, sts->action_code, sts->function_code);
2395 return -1;
2396 }
2397
2398 // swap endian order if needed
2399 if (isbigendian()){
2400 swapx(&tmh->format_version);
2401 swapx(&tmh->sampling_period);
2402 swapx(&tmh->interval);
2403 }
2404
2405 // Check format version
2406 if (tmh->format_version != 2) {
2407 pout("Error unknown SCT Temperature History Format Version (%u), should be 2.\n", tmh->format_version);
2408 return -1;
2409 }
2410 return 0;
2411}
2412
2413// Set SCT Temperature Logging Interval
2127e193 2414int ataSetSCTTempInterval(ata_device * device, unsigned interval, bool persistent)
a37e7145
GG
2415{
2416 // Check initial status
2417 ata_sct_status_response sts;
2418 if (ataReadSCTStatus(device, &sts))
2419 return -1;
2420
2421 // Do nothing if other SCT command is executing
2422 if (sts.ext_status_code == 0xffff) {
2423 pout("Another SCT command is executing, abort Feature Control\n"
2424 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2425 sts.ext_status_code, sts.action_code, sts.function_code);
2426 return -1;
2427 }
2428
2429 ata_sct_feature_control_command cmd; memset(&cmd, 0, sizeof(cmd));
2430 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2431 cmd.action_code = 4; // Feature Control command
2432 cmd.function_code = 1; // Set state
2433 cmd.feature_code = 3; // Temperature logging interval
2434 cmd.state = interval;
2435 cmd.option_flags = (persistent ? 0x01 : 0x00);
2436
7f0798ef
GI
2437 // swap endian order if needed
2438 if (isbigendian()) {
2439 swapx(&cmd.action_code);
2440 swapx(&cmd.function_code);
2441 swapx(&cmd.feature_code);
2442 swapx(&cmd.state);
2443 swapx(&cmd.option_flags);
2444 }
2445
a37e7145
GG
2446 // write command via SMART log page 0xe0
2447 if (smartcommandhandler(device, WRITE_LOG, 0xe0, (char *)&cmd)){
a7e8ffec 2448 pout("Error Write SCT Feature Control Command failed: %s\n", device->get_errmsg());
a37e7145
GG
2449 return -1;
2450 }
2451
2452 // re-read and check SCT status
2453 if (ataReadSCTStatus(device, &sts))
2454 return -1;
2455
2456 if (!(sts.ext_status_code == 0 && sts.action_code == 4 && sts.function_code == 1)) {
2457 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2458 sts.ext_status_code, sts.action_code, sts.function_code);
2459 return -1;
2460 }
2461 return 0;
2462}
2463
7f0798ef
GI
2464// Get/Set SCT Error Recovery Control
2465static int ataGetSetSCTErrorRecoveryControltime(ata_device * device, unsigned type,
2466 bool set, unsigned short & time_limit)
2467{
2468 // Check initial status
2469 ata_sct_status_response sts;
2470 if (ataReadSCTStatus(device, &sts))
2471 return -1;
2472
2473 // Do nothing if other SCT command is executing
2474 if (sts.ext_status_code == 0xffff) {
2475 pout("Another SCT command is executing, abort Error Recovery Control\n"
2476 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2477 sts.ext_status_code, sts.action_code, sts.function_code);
2478 return -1;
2479 }
2480
2481 ata_sct_error_recovery_control_command cmd; memset(&cmd, 0, sizeof(cmd));
2482 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2483 cmd.action_code = 3; // Error Recovery Control command
2484 cmd.function_code = (set ? 1 : 2); // 1=Set timer, 2=Get timer
2485 cmd.selection_code = type; // 1=Read timer, 2=Write timer
2486 if (set)
2487 cmd.time_limit = time_limit;
2488
2489 // swap endian order if needed
2490 if (isbigendian()) {
2491 swapx(&cmd.action_code);
2492 swapx(&cmd.function_code);
2493 swapx(&cmd.selection_code);
2494 swapx(&cmd.time_limit);
2495 }
2496
2497 // write command via SMART log page 0xe0
2498 // TODO: Debug output
2499 ata_cmd_in in;
2500 in.in_regs.command = ATA_SMART_CMD;
2501 in.in_regs.lba_high = SMART_CYL_HI; in.in_regs.lba_mid = SMART_CYL_LOW;
2502 in.in_regs.features = ATA_SMART_WRITE_LOG_SECTOR;
2503 in.in_regs.lba_low = 0xe0;
2504 in.set_data_out(&cmd, 1);
2505
2506 if (!set)
2507 // Time limit returned in ATA registers
2508 in.out_needed.sector_count = in.out_needed.lba_low = true;
2509
2510 ata_cmd_out out;
2511 if (!device->ata_pass_through(in, out)) {
cfbba5b9
GI
2512 pout("Error Write SCT (%cet) Error Recovery Control Command failed: %s\n",
2513 (!set ? 'G' : 'S'), device->get_errmsg());
7f0798ef
GI
2514 return -1;
2515 }
2516
2517 // re-read and check SCT status
2518 if (ataReadSCTStatus(device, &sts))
2519 return -1;
2520
2521 if (!(sts.ext_status_code == 0 && sts.action_code == 3 && sts.function_code == (set ? 1 : 2))) {
2522 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2523 sts.ext_status_code, sts.action_code, sts.function_code);
2524 return -1;
2525 }
2526
2527 if (!set) {
2528 // Check whether registers are properly returned by ioctl()
2529 if (!(out.out_regs.sector_count.is_set() && out.out_regs.lba_low.is_set())) {
2530 // TODO: Output register support should be checked within each ata_pass_through()
2531 // implementation before command is issued.
2532 pout("Error SMART WRITE LOG does not return COUNT and LBA_LOW register\n");
2533 return -1;
2534 }
2535 // Return value to caller
2536 time_limit = out.out_regs.sector_count | (out.out_regs.lba_low << 8);
2537 }
2538
2539 return 0;
2540}
2541
2542// Get SCT Error Recovery Control
2543int ataGetSCTErrorRecoveryControltime(ata_device * device, unsigned type, unsigned short & time_limit)
2544{
2545 return ataGetSetSCTErrorRecoveryControltime(device, type, false/*get*/, time_limit);
2546}
2547
2548// Set SCT Error Recovery Control
2549int ataSetSCTErrorRecoveryControltime(ata_device * device, unsigned type, unsigned short time_limit)
2550{
2551 return ataGetSetSCTErrorRecoveryControltime(device, type, true/*set*/, time_limit);
2552}
2553
2554
2127e193 2555// Print one self-test log entry.
cfbba5b9
GI
2556// Returns:
2557// -1: self-test failed
2558// 1: extended self-test completed without error
2559// 0: otherwise
2560int ataPrintSmartSelfTestEntry(unsigned testnum, unsigned char test_type,
2561 unsigned char test_status,
2562 unsigned short timestamp,
2563 uint64_t failing_lba,
2564 bool print_error_only, bool & print_header)
2565{
2566 // Check status and type for return value
2567 int retval = 0;
2568 switch (test_status >> 4) {
2569 case 0x0:
2570 if ((test_type & 0x0f) == 0x02)
2571 retval = 1; // extended self-test completed without error
2572 break;
2573 case 0x3: case 0x4:
2574 case 0x5: case 0x6:
2575 case 0x7: case 0x8:
2576 retval = -1; // self-test failed
2577 break;
2578 }
2579
2580 if (retval >= 0 && print_error_only)
2581 return retval;
2582
2583 std::string msgtest;
2127e193
GI
2584 switch (test_type) {
2585 case 0x00: msgtest = "Offline"; break;
2586 case 0x01: msgtest = "Short offline"; break;
2587 case 0x02: msgtest = "Extended offline"; break;
2588 case 0x03: msgtest = "Conveyance offline"; break;
2589 case 0x04: msgtest = "Selective offline"; break;
2590 case 0x7f: msgtest = "Abort offline test"; break;
2591 case 0x81: msgtest = "Short captive"; break;
2592 case 0x82: msgtest = "Extended captive"; break;
2593 case 0x83: msgtest = "Conveyance captive"; break;
2594 case 0x84: msgtest = "Selective captive"; break;
2595 default:
2596 if ((0x40 <= test_type && test_type <= 0x7e) || 0x90 <= test_type)
cfbba5b9 2597 msgtest = strprintf("Vendor (0x%02x)", test_type);
2127e193 2598 else
cfbba5b9 2599 msgtest = strprintf("Reserved (0x%02x)", test_type);
2127e193
GI
2600 }
2601
cfbba5b9 2602 std::string msgstat;
2127e193
GI
2603 switch (test_status >> 4) {
2604 case 0x0: msgstat = "Completed without error"; break;
2605 case 0x1: msgstat = "Aborted by host"; break;
2606 case 0x2: msgstat = "Interrupted (host reset)"; break;
cfbba5b9
GI
2607 case 0x3: msgstat = "Fatal or unknown error"; break;
2608 case 0x4: msgstat = "Completed: unknown failure"; break;
2609 case 0x5: msgstat = "Completed: electrical failure"; break;
2610 case 0x6: msgstat = "Completed: servo/seek failure"; break;
2611 case 0x7: msgstat = "Completed: read failure"; break;
2612 case 0x8: msgstat = "Completed: handling damage??"; break;
2127e193 2613 case 0xf: msgstat = "Self-test routine in progress"; break;
cfbba5b9 2614 default: msgstat = strprintf("Unknown status (0x%x)", test_status >> 4);
2127e193
GI
2615 }
2616
2127e193
GI
2617 // Print header once
2618 if (print_header) {
2619 print_header = false;
2620 pout("Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2621 }
2622
2623 char msglba[32];
cfbba5b9 2624 if (retval < 0 && failing_lba < 0xffffffffffffULL)
2127e193
GI
2625 snprintf(msglba, sizeof(msglba), "%"PRIu64, failing_lba);
2626 else
2627 strcpy(msglba, "-");
2628
cfbba5b9
GI
2629 pout("#%2u %-19s %-29s %1d0%% %8u %s\n", testnum,
2630 msgtest.c_str(), msgstat.c_str(), test_status & 0x0f, timestamp, msglba);
2127e193 2631
cfbba5b9 2632 return retval;
2127e193
GI
2633}
2634
2635// Print Smart self-test log, used by smartctl and smartd.
2636// return value is:
2637// bottom 8 bits: number of entries found where self-test showed an error
2638// remaining bits: if nonzero, power on hours of last self-test where error was found
2639int ataPrintSmartSelfTestlog(const ata_smart_selftestlog * data, bool allentries,
2640 unsigned char fix_firmwarebug)
2641{
2642 if (allentries)
2643 pout("SMART Self-test log structure revision number %d\n",(int)data->revnumber);
2644 if ((data->revnumber!=0x0001) && allentries && fix_firmwarebug != FIX_SAMSUNG)
2645 pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
2646 if (data->mostrecenttest==0){
2647 if (allentries)
2648 pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
2649 return 0;
2650 }
2651
2652 bool noheaderprinted = true;
cfbba5b9
GI
2653 int errcnt = 0, hours = 0, igncnt = 0;
2654 int testno = 0, ext_ok_testno = -1;
2127e193
GI
2655
2656 // print log
2657 for (int i = 20; i >= 0; i--) {
2658 // log is a circular buffer
2659 int j = (i+data->mostrecenttest)%21;
2660 const ata_smart_selftestlog_struct * log = data->selftest_struct+j;
2661
2662 if (nonempty(log, sizeof(*log))) {
2663 // count entry based on non-empty structures -- needed for
2664 // Seagate only -- other vendors don't have blank entries 'in
2665 // the middle'
2666 testno++;
2667
2668 // T13/1321D revision 1c: (Data structure Rev #1)
2669
2670 //The failing LBA shall be the LBA of the uncorrectable sector
2671 //that caused the test to fail. If the device encountered more
2672 //than one uncorrectable sector during the test, this field
2673 //shall indicate the LBA of the first uncorrectable sector
2674 //encountered. If the test passed or the test failed for some
2675 //reason other than an uncorrectable sector, the value of this
2676 //field is undefined.
2677
2678 // This is true in ALL ATA-5 specs
2679 uint64_t lba48 = (log->lbafirstfailure < 0xffffffff ? log->lbafirstfailure : 0xffffffffffffULL);
2680
2681 // Print entry
cfbba5b9
GI
2682 int state = ataPrintSmartSelfTestEntry(testno,
2683 log->selftestnumber, log->selfteststatus,
2684 log->timestamp, lba48, !allentries, noheaderprinted);
2127e193 2685
cfbba5b9 2686 if (state < 0) {
f4ebf3d1 2687 // Self-test showed an error
cfbba5b9
GI
2688 if (ext_ok_testno < 0) {
2689 errcnt++;
f4ebf3d1 2690
cfbba5b9
GI
2691 // keep track of time of most recent error
2692 if (!hours)
2693 hours = log->timestamp;
2694 }
2695 else
2696 // Newer successful extended self-test exits
2697 igncnt++;
2698 }
2699 else if (state > 0 && ext_ok_testno < 0) {
2700 // Latest successful extended self-test
2701 ext_ok_testno = testno;
f4ebf3d1 2702 }
2127e193
GI
2703 }
2704 }
cfbba5b9
GI
2705
2706 if (igncnt)
2707 pout("%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2708 igncnt, igncnt+errcnt, ext_ok_testno);
2709
2710 if (!allentries && !noheaderprinted)
2127e193
GI
2711 pout("\n");
2712
cfbba5b9 2713 return ((hours << 8) | errcnt);
2127e193
GI
2714}
2715
a37e7145
GG
2716
2717/////////////////////////////////////////////////////////////////////////////
2718// Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
2719// an ATA device with same behaviour
2720
2127e193
GI
2721namespace {
2722
2723class parsed_ata_device
2724: public /*implements*/ ata_device_with_command_set
2725{
2726public:
2727 parsed_ata_device(smart_interface * intf, const char * dev_name);
2728
2729 virtual ~parsed_ata_device() throw();
2730
2731 virtual bool is_open() const;
2732
2733 virtual bool open();
a37e7145 2734
2127e193 2735 virtual bool close();
a37e7145 2736
2127e193
GI
2737 virtual bool ata_identify_is_cached() const;
2738
2739protected:
2740 virtual int ata_command_interface(smart_command_set command, int select, char * data);
2741
2742private:
2743 // Table of parsed commands, return value, data
2744 struct parsed_ata_command
2745 {
2746 smart_command_set command;
2747 int select;
2748 int retval, errval;
2749 char * data;
2750 };
2751
2752 enum { max_num_commands = 32 };
2753 parsed_ata_command m_command_table[max_num_commands];
2754
2755 int m_num_commands;
2756 int m_next_replay_command;
2757 bool m_replay_out_of_sync;
2758 bool m_ata_identify_is_cached;
2759};
a37e7145
GG
2760
2761static const char * nextline(const char * s, int & lineno)
2762{
2763 for (s += strcspn(s, "\r\n"); *s == '\r' || *s == '\n'; s++) {
2764 if (*s == '\r' && s[1] == '\n')
2765 s++;
2766 lineno++;
2767 }
2768 return s;
2769}
2770
2771static int name2command(const char * s)
2772{
2773 for (int i = 0; i < (int)(sizeof(commandstrings)/sizeof(commandstrings[0])); i++) {
2774 if (!strcmp(s, commandstrings[i]))
2775 return i;
2776 }
2777 return -1;
2778}
2779
2780static bool matchcpy(char * dest, size_t size, const char * src, const regmatch_t & srcmatch)
2781{
2782 if (srcmatch.rm_so < 0)
2783 return false;
2784 size_t n = srcmatch.rm_eo - srcmatch.rm_so;
2785 if (n >= size)
2786 n = size-1;
2787 memcpy(dest, src + srcmatch.rm_so, n);
2788 dest[n] = 0;
2789 return true;
2790}
2791
2792static inline int matchtoi(const char * src, const regmatch_t & srcmatch, int defval)
2793{
2794 if (srcmatch.rm_so < 0)
2795 return defval;
2796 return atoi(src + srcmatch.rm_so);
2797}
2798
2127e193
GI
2799parsed_ata_device::parsed_ata_device(smart_interface * intf, const char * dev_name)
2800: smart_device(intf, dev_name, "ata", ""),
2801 m_num_commands(0),
2802 m_next_replay_command(0),
2803 m_replay_out_of_sync(false),
2804 m_ata_identify_is_cached(false)
2805{
2806 memset(m_command_table, 0, sizeof(m_command_table));
2807}
2808
2809parsed_ata_device::~parsed_ata_device() throw()
2810{
2811 close();
2812}
2813
2814bool parsed_ata_device::is_open() const
2815{
2816 return (m_num_commands > 0);
2817}
a37e7145
GG
2818
2819// Parse stdin and build command table
2127e193 2820bool parsed_ata_device::open()
a37e7145 2821{
2127e193
GI
2822 const char * pathname = get_dev_name();
2823 if (strcmp(pathname, "-"))
2824 return set_err(EINVAL);
a37e7145
GG
2825 pathname = "<stdin>";
2826 // Fill buffer
2827 char buffer[64*1024];
2828 int size = 0;
2829 while (size < (int)sizeof(buffer)) {
2830 int nr = fread(buffer, 1, sizeof(buffer), stdin);
2831 if (nr <= 0)
2832 break;
2833 size += nr;
2834 }
2127e193
GI
2835 if (size <= 0)
2836 return set_err(ENOENT, "%s: Unexpected EOF", pathname);
2837 if (size >= (int)sizeof(buffer))
2838 return set_err(EIO, "%s: Buffer overflow", pathname);
a37e7145
GG
2839 buffer[size] = 0;
2840
2841 // Regex to match output from "-r ataioctl,2"
2842 static const char pattern[] = "^"
2843 "(" // (1
2127e193 2844 "REPORT-IOCTL: DeviceF?D?=[^ ]+ Command=([A-Z ]*[A-Z])" // (2)
a37e7145
GG
2845 "(" // (3
2846 "( InputParameter=([0-9]+))?" // (4 (5))
2847 "|"
2848 "( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
2849 ")" // )
2850 "[\r\n]" // EOL match necessary to match optional parts above
2851 "|"
2852 "===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
2127e193
GI
2853 "|"
2854 " *(En|Dis)abled status cached by OS, " // (11)
a37e7145
GG
2855 ")"; // )
2856
2857 // Compile regex
cfbba5b9 2858 const regular_expression regex(pattern, REG_EXTENDED);
a37e7145
GG
2859
2860 // Parse buffer
2861 const char * errmsg = 0;
2862 int i = -1, state = 0, lineno = 1;
2863 for (const char * line = buffer; *line; line = nextline(line, lineno)) {
2864 // Match line
2127e193 2865 if (!(line[0] == 'R' || line[0] == '=' || line[0] == ' '))
a37e7145 2866 continue;
2127e193 2867 const int nmatch = 1+11;
a37e7145 2868 regmatch_t match[nmatch];
2127e193 2869 if (!regex.execute(line, nmatch, match))
a37e7145
GG
2870 continue;
2871
2872 char cmdname[40];
2873 if (matchcpy(cmdname, sizeof(cmdname), line, match[2])) { // "REPORT-IOCTL:... Command=%s ..."
2874 int nc = name2command(cmdname);
2875 if (nc < 0) {
2876 errmsg = "Unknown ATA command name"; break;
2877 }
2878 if (match[7].rm_so < 0) { // "returned %d"
2879 // Start of command
2880 if (!(state == 0 || state == 2)) {
2881 errmsg = "Missing REPORT-IOCTL result"; break;
2882 }
2127e193 2883 if (++i >= max_num_commands) {
a37e7145
GG
2884 errmsg = "Too many ATA commands"; break;
2885 }
2127e193
GI
2886 m_command_table[i].command = (smart_command_set)nc;
2887 m_command_table[i].select = matchtoi(line, match[5], 0); // "InputParameter=%d"
a37e7145
GG
2888 state = 1;
2889 }
2890 else {
2891 // End of command
2127e193 2892 if (!(state == 1 && (int)m_command_table[i].command == nc)) {
a37e7145
GG
2893 errmsg = "Missing REPORT-IOCTL start"; break;
2894 }
2127e193
GI
2895 m_command_table[i].retval = matchtoi(line, match[7], -1); // "returned %d"
2896 m_command_table[i].errval = matchtoi(line, match[9], 0); // "errno=%d"
a37e7145
GG
2897 state = 2;
2898 }
2899 }
2900 else if (matchcpy(cmdname, sizeof(cmdname), line, match[10])) { // "===== [%s] DATA START "
2901 // Start of sector hexdump
2902 int nc = name2command(cmdname);
2127e193 2903 if (!(state == (nc == WRITE_LOG ? 1 : 2) && (int)m_command_table[i].command == nc)) {
a37e7145
GG
2904 errmsg = "Unexpected DATA START"; break;
2905 }
2906 line = nextline(line, lineno);
2907 char * data = (char *)malloc(512);
2908 unsigned j;
2909 for (j = 0; j < 32; j++) {
2910 unsigned b[16];
2911 unsigned u1, u2; int n1 = -1;
2912 if (!(sscanf(line, "%3u-%3u: "
2913 "%2x %2x %2x %2x %2x %2x %2x %2x "
2914 "%2x %2x %2x %2x %2x %2x %2x %2x%n",
2915 &u1, &u2,
2916 b+ 0, b+ 1, b+ 2, b+ 3, b+ 4, b+ 5, b+ 6, b+ 7,
2917 b+ 8, b+ 9, b+10, b+11, b+12, b+13, b+14, b+15, &n1) == 18
2918 && n1 >= 56 && u1 == j*16 && u2 == j*16+15))
2919 break;
2920 for (unsigned k = 0; k < 16; k++)
2921 data[j*16+k] = b[k];
2922 line = nextline(line, lineno);
2923 }
2924 if (j < 32) {
2925 free(data);
2926 errmsg = "Incomplete sector hex dump"; break;
2927 }
2127e193 2928 m_command_table[i].data = data;
a37e7145
GG
2929 if (nc != WRITE_LOG)
2930 state = 0;
2931 }
2127e193
GI
2932 else if (match[11].rm_so > 0) { // "(En|Dis)abled status cached by OS"
2933 m_ata_identify_is_cached = true;
2934 }
a37e7145
GG
2935 }
2936
2937 if (!(state == 0 || state == 2))
2938 errmsg = "Missing REPORT-IOCTL result";
2939
2940 if (!errmsg && i < 0)
2941 errmsg = "No information found";
2942
2127e193
GI
2943 m_num_commands = i+1;
2944 m_next_replay_command = 0;
2945 m_replay_out_of_sync = false;
a37e7145
GG
2946
2947 if (errmsg) {
2127e193
GI
2948 close();
2949 return set_err(EIO, "%s(%d): Syntax error: %s", pathname, lineno, errmsg);
a37e7145 2950 }
2127e193 2951 return true;
a37e7145
GG
2952}
2953
2954// Report warnings and free command table
2127e193 2955bool parsed_ata_device::close()
a37e7145 2956{
2127e193 2957 if (m_replay_out_of_sync)
a37e7145 2958 pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
2127e193
GI
2959 else if (m_next_replay_command != 0)
2960 pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", m_num_commands-m_next_replay_command);
a37e7145 2961
2127e193
GI
2962 for (int i = 0; i < m_num_commands; i++) {
2963 if (m_command_table[i].data) {
2964 free(m_command_table[i].data); m_command_table[i].data = 0;
a37e7145
GG
2965 }
2966 }
2127e193
GI
2967 m_num_commands = 0;
2968 m_next_replay_command = 0;
2969 m_replay_out_of_sync = false;
2970 return true;
2971}
2972
2973
2974bool parsed_ata_device::ata_identify_is_cached() const
2975{
2976 return m_ata_identify_is_cached;
a37e7145
GG
2977}
2978
2127e193 2979
a37e7145 2980// Simulate ATA command from command table
2127e193 2981int parsed_ata_device::ata_command_interface(smart_command_set command, int select, char * data)
a37e7145 2982{
2127e193
GI
2983 // Find command, try round-robin if out of sync
2984 int i = m_next_replay_command;
a37e7145 2985 for (int j = 0; ; j++) {
2127e193 2986 if (j >= m_num_commands) {
a37e7145
GG
2987 pout("REPLAY-IOCTL: Warning: Command not found\n");
2988 errno = ENOSYS;
2989 return -1;
2990 }
2127e193 2991 if (m_command_table[i].command == command && m_command_table[i].select == select)
a37e7145 2992 break;
2127e193
GI
2993 if (!m_replay_out_of_sync) {
2994 m_replay_out_of_sync = true;
a37e7145
GG
2995 pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i+1);
2996 }
2127e193 2997 if (++i >= m_num_commands)
a37e7145
GG
2998 i = 0;
2999 }
2127e193
GI
3000 m_next_replay_command = i;
3001 if (++m_next_replay_command >= m_num_commands)
3002 m_next_replay_command = 0;
a37e7145
GG
3003
3004 // Return command data
3005 switch (command) {
3006 case IDENTIFY:
3007 case PIDENTIFY:
3008 case READ_VALUES:
3009 case READ_THRESHOLDS:
3010 case READ_LOG:
2127e193
GI
3011 if (m_command_table[i].data)
3012 memcpy(data, m_command_table[i].data, 512);
a37e7145
GG
3013 break;
3014 case WRITE_LOG:
2127e193 3015 if (!(m_command_table[i].data && !memcmp(data, m_command_table[i].data, 512)))
a37e7145
GG
3016 pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
3017 break;
3018 case CHECK_POWER_MODE:
3019 data[0] = (char)0xff;
3020 default:
3021 break;
3022 }
3023
2127e193
GI
3024 if (m_command_table[i].errval)
3025 errno = m_command_table[i].errval;
3026 return m_command_table[i].retval;
3027}
3028
3029} // namespace
3030
3031ata_device * get_parsed_ata_device(smart_interface * intf, const char * dev_name)
3032{
3033 return new parsed_ata_device(intf, dev_name);
a37e7145 3034}