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