1 /* $NetBSD: atactl.c,v 1.77 2016/10/04 21:37:46 mrg Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Ken Hornstein. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * atactl(8) - a program to control ATA devices. 34 */ 35 #include <sys/cdefs.h> 36 37 #ifndef lint 38 __RCSID("$NetBSD: atactl.c,v 1.77 2016/10/04 21:37:46 mrg Exp $"); 39 #endif 40 41 42 #include <sys/param.h> 43 #include <sys/ioctl.h> 44 #include <err.h> 45 #include <errno.h> 46 #include <fcntl.h> 47 #include <pwd.h> 48 #include <stdio.h> 49 #include <stdlib.h> 50 #include <string.h> 51 #include <unistd.h> 52 #include <util.h> 53 54 #include <dev/ata/atareg.h> 55 #include <sys/ataio.h> 56 57 struct ata_smart_error { 58 struct { 59 uint8_t device_control; 60 uint8_t features; 61 uint8_t sector_count; 62 uint8_t sector_number; 63 uint8_t cylinder_low; 64 uint8_t cylinder_high; 65 uint8_t device_head; 66 uint8_t command; 67 uint8_t timestamp[4]; 68 } command[5]; 69 struct { 70 uint8_t reserved; 71 uint8_t error; 72 uint8_t sector_count; 73 uint8_t sector_number; 74 uint8_t cylinder_low; 75 uint8_t cylinder_high; 76 uint8_t device_head; 77 uint8_t status; 78 uint8_t extended_error[19]; 79 uint8_t state; 80 uint8_t lifetime[2]; 81 } error_data; 82 } __packed; 83 84 struct ata_smart_errorlog { 85 uint8_t data_structure_revision; 86 uint8_t mostrecenterror; 87 struct ata_smart_error log_entries[5]; 88 uint16_t device_error_count; 89 uint8_t reserved[57]; 90 uint8_t checksum; 91 } __packed; 92 93 struct command { 94 const char *cmd_name; 95 const char *arg_names; 96 void (*cmd_func)(int, char *[]); 97 }; 98 99 struct bitinfo { 100 u_int bitmask; 101 const char *string; 102 }; 103 104 __dead static void usage(void); 105 static void ata_command(struct atareq *); 106 static void print_bitinfo(const char *, const char *, u_int, 107 const struct bitinfo *); 108 static void print_bitinfo2(const char *, const char *, u_int, u_int, 109 const struct bitinfo *); 110 static void print_smart_status(void *, void *); 111 static void print_error_entry(int, const struct ata_smart_error *); 112 static void print_selftest_entry(int, const struct ata_smart_selftest *); 113 114 static void print_error(const void *); 115 static void print_selftest(const void *); 116 117 static const struct ataparams *getataparams(void); 118 119 static int is_smart(void); 120 121 static int fd; /* file descriptor for device */ 122 static const char *dvname; /* device name */ 123 static char dvname_store[MAXPATHLEN]; /* for opendisk(3) */ 124 static const char *cmdname; /* command user issued */ 125 126 static void device_identify(int, char *[]); 127 static void device_setidle(int, char *[]); 128 static void device_idle(int, char *[]); 129 static void device_apm(int, char *[]); 130 static void device_checkpower(int, char *[]); 131 static void device_smart(int, char *[]); 132 static void device_security(int, char *[]); 133 134 static void device_smart_temp(const struct ata_smart_attr *, uint64_t); 135 136 static const struct command device_commands[] = { 137 { "identify", "", device_identify }, 138 { "setidle", "idle-timer", device_setidle }, 139 { "apm", "disable|set #", device_apm }, 140 { "setstandby", "standby-timer", device_setidle }, 141 { "idle", "", device_idle }, 142 { "standby", "", device_idle }, 143 { "sleep", "", device_idle }, 144 { "checkpower", "", device_checkpower }, 145 { "smart", 146 "enable|disable|status|offline #|error-log|selftest-log", 147 device_smart }, 148 { "security", 149 "status|freeze|[setpass|unlock|disable|erase] [user|master]", 150 device_security }, 151 { NULL, NULL, NULL }, 152 }; 153 154 static void bus_reset(int, char *[]); 155 156 static const struct command bus_commands[] = { 157 { "reset", "", bus_reset }, 158 { NULL, NULL, NULL }, 159 }; 160 161 /* 162 * Tables containing bitmasks used for error reporting and 163 * device identification. 164 */ 165 166 static const struct bitinfo ata_caps[] = { 167 { WDC_CAP_DMA, "DMA" }, 168 { WDC_CAP_LBA, "LBA" }, 169 { ATA_CAP_STBY, "ATA standby timer values" }, 170 { WDC_CAP_IORDY, "IORDY operation" }, 171 { WDC_CAP_IORDY_DSBL, "IORDY disabling" }, 172 { 0, NULL }, 173 }; 174 175 static const struct bitinfo ata_vers[] = { 176 { WDC_VER_ATA1, "ATA-1" }, 177 { WDC_VER_ATA2, "ATA-2" }, 178 { WDC_VER_ATA3, "ATA-3" }, 179 { WDC_VER_ATA4, "ATA-4" }, 180 { WDC_VER_ATA5, "ATA-5" }, 181 { WDC_VER_ATA6, "ATA-6" }, 182 { WDC_VER_ATA7, "ATA-7" }, 183 { WDC_VER_ATA8, "ATA-8" }, 184 { 0, NULL }, 185 }; 186 187 static const struct bitinfo ata_cmd_set1[] = { 188 { WDC_CMD1_NOP, "NOP command" }, 189 { WDC_CMD1_RB, "READ BUFFER command" }, 190 { WDC_CMD1_WB, "WRITE BUFFER command" }, 191 { WDC_CMD1_HPA, "Host Protected Area feature set" }, 192 { WDC_CMD1_DVRST, "DEVICE RESET command" }, 193 { WDC_CMD1_SRV, "SERVICE interrupt" }, 194 { WDC_CMD1_RLSE, "Release interrupt" }, 195 { WDC_CMD1_AHEAD, "Look-ahead" }, 196 { WDC_CMD1_CACHE, "Write cache" }, 197 { WDC_CMD1_PKT, "PACKET command feature set" }, 198 { WDC_CMD1_PM, "Power Management feature set" }, 199 { WDC_CMD1_REMOV, "Removable Media feature set" }, 200 { WDC_CMD1_SEC, "Security Mode feature set" }, 201 { WDC_CMD1_SMART, "SMART feature set" }, 202 { 0, NULL }, 203 }; 204 205 static const struct bitinfo ata_cmd_set2[] = { 206 { ATA_CMD2_FCE, "FLUSH CACHE EXT command" }, 207 { WDC_CMD2_FC, "FLUSH CACHE command" }, 208 { WDC_CMD2_DCO, "Device Configuration Overlay feature set" }, 209 { ATA_CMD2_LBA48, "48-bit Address feature set" }, 210 { WDC_CMD2_AAM, "Automatic Acoustic Management feature set" }, 211 { WDC_CMD2_SM, "SET MAX security extension" }, 212 { WDC_CMD2_SFREQ, "SET FEATURES required to spin-up after power-up" }, 213 { WDC_CMD2_PUIS, "Power-Up In Standby feature set" }, 214 { WDC_CMD2_RMSN, "Removable Media Status Notification feature set" }, 215 { ATA_CMD2_APM, "Advanced Power Management feature set" }, 216 { ATA_CMD2_CFA, "CFA feature set" }, 217 { ATA_CMD2_RWQ, "READ/WRITE DMA QUEUED commands" }, 218 { WDC_CMD2_DM, "DOWNLOAD MICROCODE command" }, 219 { 0, NULL }, 220 }; 221 222 static const struct bitinfo ata_cmd_ext[] = { 223 { ATA_CMDE_TLCONT, "Time-limited R/W feature set R/W Continuous mode" }, 224 { ATA_CMDE_TL, "Time-limited Read/Write" }, 225 { ATA_CMDE_URGW, "URG bit for WRITE STREAM DMA/PIO" }, 226 { ATA_CMDE_URGR, "URG bit for READ STREAM DMA/PIO" }, 227 { ATA_CMDE_WWN, "World Wide Name" }, 228 { ATA_CMDE_WQFE, "WRITE DMA QUEUED FUA EXT command" }, 229 { ATA_CMDE_WFE, "WRITE DMA/MULTIPLE FUA EXT commands" }, 230 { ATA_CMDE_GPL, "General Purpose Logging feature set" }, 231 { ATA_CMDE_STREAM, "Streaming feature set" }, 232 { ATA_CMDE_MCPTC, "Media Card Pass Through Command feature set" }, 233 { ATA_CMDE_MS, "Media serial number" }, 234 { ATA_CMDE_SST, "SMART self-test" }, 235 { ATA_CMDE_SEL, "SMART error logging" }, 236 { 0, NULL }, 237 }; 238 239 static const struct bitinfo ata_sata_caps[] = { 240 { SATA_SIGNAL_GEN1, "1.5Gb/s signaling" }, 241 { SATA_SIGNAL_GEN2, "3.0Gb/s signaling" }, 242 { SATA_SIGNAL_GEN3, "6.0Gb/s signaling" }, 243 { SATA_NATIVE_CMDQ, "Native Command Queuing" }, 244 { SATA_HOST_PWR_MGMT, "Host-Initiated Interface Power Management" }, 245 { SATA_PHY_EVNT_CNT, "PHY Event Counters" }, 246 { 0, NULL }, 247 }; 248 249 static const struct bitinfo ata_sata_feat[] = { 250 { SATA_NONZERO_OFFSETS, "Non-zero Offset DMA" }, 251 { SATA_DMA_SETUP_AUTO, "DMA Setup Auto Activate" }, 252 { SATA_DRIVE_PWR_MGMT, "Device-Initiated Interface Power Managment" }, 253 { SATA_IN_ORDER_DATA, "In-order Data Delivery" }, 254 { SATA_SW_STTNGS_PRS, "Software Settings Preservation" }, 255 { 0, NULL }, 256 }; 257 258 static const struct { 259 const int id; 260 const char *name; 261 void (*special)(const struct ata_smart_attr *, uint64_t); 262 } smart_attrs[] = { 263 { 1, "Raw read error rate", NULL }, 264 { 2, "Throughput performance", NULL }, 265 { 3, "Spin-up time", NULL }, 266 { 4, "Start/stop count", NULL }, 267 { 5, "Reallocated sector count", NULL }, 268 { 6, "Read channel margin", NULL }, 269 { 7, "Seek error rate", NULL }, 270 { 8, "Seek time performance", NULL }, 271 { 9, "Power-on hours count", NULL }, 272 { 10, "Spin retry count", NULL }, 273 { 11, "Calibration retry count", NULL }, 274 { 12, "Device power cycle count", NULL }, 275 { 13, "Soft read error rate", NULL }, 276 { 100, "Erase/Program Cycles", NULL }, 277 { 103, "Translation Table Rebuild", NULL }, 278 { 170, "Reserved Block Count", NULL }, 279 { 171, "Program Fail Count", NULL }, 280 { 172, "Erase Fail Count", NULL }, 281 { 173, "Wear Leveller Worst Case Erase Count", NULL }, 282 { 174, "Unexpected Power Loss", NULL }, 283 { 175, "Program Fail Count", NULL }, 284 { 176, "Erase Fail Count", NULL }, 285 { 177, "Wear Leveling Count", NULL }, 286 { 178, "Used Reserved Block Count", NULL }, 287 { 179, "Used Reserved Block Count", NULL }, 288 { 180, "Unused Reserved Block Count", NULL }, 289 { 181, "Program Fail Count", NULL }, 290 { 182, "Erase Fail Count", NULL }, 291 { 183, "SATA Downshift Error Count", NULL }, 292 { 184, "End-to-end error", NULL }, 293 { 185, "Head Stability", NULL }, 294 { 186, "Induced Op-Vibration Detection", NULL }, 295 { 187, "Reported uncorrect", NULL }, 296 { 188, "Command Timeout", NULL }, 297 { 189, "High Fly Writes", NULL }, 298 { 190, "Airflow Temperature", device_smart_temp }, 299 { 191, "G-sense error rate", NULL }, 300 { 192, "Power-off retract count", NULL }, 301 { 193, "Load cycle count", NULL }, 302 { 194, "Temperature", device_smart_temp}, 303 { 195, "Hardware ECC Recovered", NULL }, 304 { 196, "Reallocated event count", NULL }, 305 { 197, "Current pending sector", NULL }, 306 { 198, "Offline uncorrectable", NULL }, 307 { 199, "Ultra DMA CRC error count", NULL }, 308 { 200, "Write error rate", NULL }, 309 { 201, "Soft read error rate", NULL }, 310 { 202, "Data address mark errors", NULL }, 311 { 203, "Run out cancel", NULL }, 312 { 204, "Soft ECC correction", NULL }, 313 { 205, "Thermal asperity check", NULL }, 314 { 206, "Flying height", NULL }, 315 { 207, "Spin high current", NULL }, 316 { 208, "Spin buzz", NULL }, 317 { 209, "Offline seek performance", NULL }, 318 { 210, "Successful RAIN Recovery Count", NULL }, 319 { 220, "Disk shift", NULL }, 320 { 221, "G-Sense error rate", NULL }, 321 { 222, "Loaded hours", NULL }, 322 { 223, "Load/unload retry count", NULL }, 323 { 224, "Load friction", NULL }, 324 { 225, "Load/unload cycle count", NULL }, 325 { 226, "Load-in time", NULL }, 326 { 227, "Torque amplification count", NULL }, 327 { 228, "Power-off retract count", NULL }, 328 { 230, "GMR head amplitude", NULL }, 329 { 231, "Temperature", device_smart_temp }, 330 { 232, "Available reserved space", NULL }, 331 { 233, "Media wearout indicator", NULL }, 332 { 240, "Head flying hours", NULL }, 333 { 241, "Total LBAs Written", NULL }, 334 { 242, "Total LBAs Read", NULL }, 335 { 246, "Total Host Sector Writes", NULL }, 336 { 247, "Host Program NAND Pages Count", NULL }, 337 { 248, "FTL Program Pages Count ", NULL }, 338 { 249, "Total Raw NAND Writes (1GiB units)", NULL }, 339 { 250, "Read error retry rate", NULL }, 340 { 254, "Free Fall Sensor", NULL }, 341 { 0, "Unknown", NULL }, 342 }; 343 344 static const struct bitinfo ata_sec_st[] = { 345 { WDC_SEC_SUPP, "supported" }, 346 { WDC_SEC_EN, "enabled" }, 347 { WDC_SEC_LOCKED, "locked" }, 348 { WDC_SEC_FROZEN, "frozen" }, 349 { WDC_SEC_EXP, "expired" }, 350 { WDC_SEC_ESE_SUPP, "enhanced erase support" }, 351 { WDC_SEC_LEV_MAX, "maximum level" }, 352 { 0, NULL }, 353 }; 354 355 int 356 main(int argc, char *argv[]) 357 { 358 int i; 359 const struct command *commands = NULL; 360 361 /* Must have at least: device command */ 362 if (argc < 3) 363 usage(); 364 365 /* Skip program name, get and skip device name and command. */ 366 dvname = argv[1]; 367 cmdname = argv[2]; 368 argv += 3; 369 argc -= 3; 370 371 /* 372 * Open the device 373 */ 374 fd = opendisk(dvname, O_RDWR, dvname_store, sizeof(dvname_store), 0); 375 if (fd == -1) { 376 if (errno == ENOENT) { 377 /* 378 * Device doesn't exist. Probably trying to open 379 * a device which doesn't use disk semantics for 380 * device name. Try again, specifying "cooked", 381 * which leaves off the "r" in front of the device's 382 * name. 383 */ 384 fd = opendisk(dvname, O_RDWR, dvname_store, 385 sizeof(dvname_store), 1); 386 if (fd == -1) 387 err(1, "%s", dvname); 388 } else 389 err(1, "%s", dvname); 390 } 391 392 /* 393 * Point the dvname at the actual device name that opendisk() opened. 394 */ 395 dvname = dvname_store; 396 397 /* Look up and call the command. */ 398 for (i = 0; device_commands[i].cmd_name != NULL; i++) { 399 if (strcmp(cmdname, device_commands[i].cmd_name) == 0) { 400 commands = &device_commands[i]; 401 break; 402 } 403 } 404 if (commands == NULL) { 405 for (i = 0; bus_commands[i].cmd_name != NULL; i++) { 406 if (strcmp(cmdname, bus_commands[i].cmd_name) == 0) { 407 commands = &bus_commands[i]; 408 break; 409 } 410 } 411 } 412 if (commands == NULL) 413 errx(1, "unknown command: %s", cmdname); 414 415 (*commands->cmd_func)(argc, argv); 416 exit(0); 417 } 418 419 static void 420 usage(void) 421 { 422 int i; 423 424 fprintf(stderr, "usage: %s device command [arg [...]]\n", 425 getprogname()); 426 427 fprintf(stderr, " Available device commands:\n"); 428 for (i=0; device_commands[i].cmd_name != NULL; i++) 429 fprintf(stderr, "\t%s %s\n", device_commands[i].cmd_name, 430 device_commands[i].arg_names); 431 432 fprintf(stderr, " Available bus commands:\n"); 433 for (i=0; bus_commands[i].cmd_name != NULL; i++) 434 fprintf(stderr, "\t%s %s\n", bus_commands[i].cmd_name, 435 bus_commands[i].arg_names); 436 437 exit(1); 438 } 439 440 /* 441 * Wrapper that calls ATAIOCCOMMAND and checks for errors 442 */ 443 444 static void 445 ata_command(struct atareq *req) 446 { 447 int error; 448 449 error = ioctl(fd, ATAIOCCOMMAND, req); 450 451 if (error == -1) 452 err(1, "ATAIOCCOMMAND failed"); 453 454 switch (req->retsts) { 455 456 case ATACMD_OK: 457 return; 458 case ATACMD_TIMEOUT: 459 fprintf(stderr, "ATA command timed out\n"); 460 exit(1); 461 case ATACMD_DF: 462 fprintf(stderr, "ATA device returned a Device Fault\n"); 463 exit(1); 464 case ATACMD_ERROR: 465 if (req->error & WDCE_ABRT) 466 fprintf(stderr, "ATA device returned Aborted " 467 "Command\n"); 468 else 469 fprintf(stderr, "ATA device returned error register " 470 "%0x\n", req->error); 471 exit(1); 472 default: 473 fprintf(stderr, "ATAIOCCOMMAND returned unknown result code " 474 "%d\n", req->retsts); 475 exit(1); 476 } 477 } 478 479 /* 480 * Print out strings associated with particular bitmasks 481 */ 482 483 static void 484 print_bitinfo(const char *bf, const char *af, u_int bits, 485 const struct bitinfo *binfo) 486 { 487 488 for (; binfo->bitmask != 0; binfo++) 489 if (bits & binfo->bitmask) 490 printf("%s%s%s", bf, binfo->string, af); 491 } 492 493 static void 494 print_bitinfo2(const char *bf, const char *af, u_int bits, u_int enables, 495 const struct bitinfo *binfo) 496 { 497 498 for (; binfo->bitmask != 0; binfo++) 499 if (bits & binfo->bitmask) 500 printf("%s%s (%s)%s", bf, binfo->string, 501 (enables & binfo->bitmask) ? "enabled" : "disabled", 502 af); 503 } 504 505 506 /* 507 * Try to print SMART temperature field 508 */ 509 510 static void 511 device_smart_temp(const struct ata_smart_attr *attr, uint64_t raw_value) 512 { 513 printf("%" PRIu8, attr->raw[0]); 514 if (attr->raw[0] != raw_value) 515 printf(" Lifetime min/max %" PRIu8 "/%" PRIu8, 516 attr->raw[2], attr->raw[4]); 517 } 518 519 520 /* 521 * Print out SMART attribute thresholds and values 522 */ 523 524 static void 525 print_smart_status(void *vbuf, void *tbuf) 526 { 527 const struct ata_smart_attributes *value_buf = vbuf; 528 const struct ata_smart_thresholds *threshold_buf = tbuf; 529 const struct ata_smart_attr *attr; 530 uint64_t raw_value; 531 int flags; 532 int i, j; 533 int aid; 534 uint8_t checksum; 535 536 for (i = checksum = 0; i < 512; i++) 537 checksum += ((const uint8_t *) value_buf)[i]; 538 if (checksum != 0) { 539 fprintf(stderr, "SMART attribute values checksum error\n"); 540 return; 541 } 542 543 for (i = checksum = 0; i < 512; i++) 544 checksum += ((const uint8_t *) threshold_buf)[i]; 545 if (checksum != 0) { 546 fprintf(stderr, "SMART attribute thresholds checksum error\n"); 547 return; 548 } 549 550 printf("id value thresh crit collect reliability description" 551 " raw\n"); 552 for (i = 0; i < 256; i++) { 553 int thresh = 0; 554 555 attr = NULL; 556 557 for (j = 0; j < 30; j++) { 558 if (value_buf->attributes[j].id == i) 559 attr = &value_buf->attributes[j]; 560 if (threshold_buf->thresholds[j].id == i) 561 thresh = threshold_buf->thresholds[j].value; 562 } 563 564 if (thresh && attr == NULL) 565 errx(1, "threshold but not attr %d", i); 566 if (attr == NULL) 567 continue; 568 569 if (attr->value == 0||attr->value == 0xFE||attr->value == 0xFF) 570 continue; 571 572 for (aid = 0; 573 smart_attrs[aid].id != i && smart_attrs[aid].id != 0; 574 aid++) 575 ; 576 577 flags = le16toh(attr->flags); 578 579 printf("%3d %3d %3d %-3s %-7s %stive %-27s ", 580 i, attr->value, thresh, 581 flags & WDSM_ATTR_ADVISORY ? "yes" : "no", 582 flags & WDSM_ATTR_COLLECTIVE ? "online" : "offline", 583 attr->value > thresh ? "posi" : "nega", 584 smart_attrs[aid].name); 585 586 for (j = 0, raw_value = 0; j < 6; j++) 587 raw_value += ((uint64_t)attr->raw[j]) << (8*j); 588 589 if (smart_attrs[aid].special) 590 (*smart_attrs[aid].special)(attr, raw_value); 591 else 592 printf("%" PRIu64, raw_value); 593 printf("\n"); 594 } 595 } 596 597 static const struct { 598 int number; 599 const char *name; 600 } selftest_name[] = { 601 { 0, "Off-line" }, 602 { 1, "Short off-line" }, 603 { 2, "Extended off-line" }, 604 { 127, "Abort off-line test" }, 605 { 129, "Short captive" }, 606 { 130, "Extended captive" }, 607 { 256, "Unknown test" }, /* larger than uint8_t */ 608 { 0, NULL } 609 }; 610 611 static const char *selftest_status[] = { 612 "No error", 613 "Aborted by the host", 614 "Interrupted by the host by reset", 615 "Fatal error or unknown test error", 616 "Unknown test element failed", 617 "Electrical test element failed", 618 "The Servo (and/or seek) test element failed", 619 "Read element of test failed", 620 "Reserved", 621 "Reserved", 622 "Reserved", 623 "Reserved", 624 "Reserved", 625 "Reserved", 626 "Reserved", 627 "Self-test in progress" 628 }; 629 630 static void 631 print_error_entry(int num, const struct ata_smart_error *le) 632 { 633 int i; 634 635 printf("Log entry: %d\n", num); 636 637 for (i = 0; i < 5; i++) 638 printf("\tCommand %d: dc=%02x sf=%02x sc=%02x sn=%02x cl=%02x " 639 "ch=%02x dh=%02x cmd=%02x time=%02x%02x%02x%02x\n", i, 640 le->command[i].device_control, 641 le->command[i].features, 642 le->command[i].sector_count, 643 le->command[i].sector_number, 644 le->command[i].cylinder_low, 645 le->command[i].cylinder_high, 646 le->command[i].device_head, 647 le->command[i].command, 648 le->command[i].timestamp[3], 649 le->command[i].timestamp[2], 650 le->command[i].timestamp[1], 651 le->command[i].timestamp[0]); 652 printf("\tError: err=%02x sc=%02x sn=%02x cl=%02x ch=%02x dh=%02x " 653 "status=%02x state=%02x lifetime=%02x%02x\n", 654 le->error_data.error, 655 le->error_data.sector_count, 656 le->error_data.sector_number, 657 le->error_data.cylinder_low, 658 le->error_data.cylinder_high, 659 le->error_data.device_head, 660 le->error_data.status, 661 le->error_data.state, 662 le->error_data.lifetime[1], 663 le->error_data.lifetime[0]); 664 printf("\tExtended: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x " 665 "%02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 666 le->error_data.extended_error[0], 667 le->error_data.extended_error[1], 668 le->error_data.extended_error[2], 669 le->error_data.extended_error[3], 670 le->error_data.extended_error[4], 671 le->error_data.extended_error[5], 672 le->error_data.extended_error[6], 673 le->error_data.extended_error[7], 674 le->error_data.extended_error[8], 675 le->error_data.extended_error[9], 676 le->error_data.extended_error[10], 677 le->error_data.extended_error[11], 678 le->error_data.extended_error[12], 679 le->error_data.extended_error[13], 680 le->error_data.extended_error[14], 681 le->error_data.extended_error[15], 682 le->error_data.extended_error[15], 683 le->error_data.extended_error[17], 684 le->error_data.extended_error[18]); 685 } 686 687 static void 688 print_error(const void *buf) 689 { 690 const struct ata_smart_errorlog *erlog = buf; 691 uint8_t checksum; 692 int i; 693 694 for (i = checksum = 0; i < 512; i++) 695 checksum += ((const uint8_t *) buf)[i]; 696 if (checksum != 0) { 697 fprintf(stderr, "SMART error log checksum error\n"); 698 return; 699 } 700 701 if (erlog->data_structure_revision != 1) { 702 fprintf(stderr, "Error log revision not 1 (found 0x%04x)\n", 703 erlog->data_structure_revision); 704 return; 705 } 706 707 if (erlog->mostrecenterror == 0) { 708 printf("No errors have been logged\n"); 709 return; 710 } 711 712 if (erlog->mostrecenterror > 5) { 713 fprintf(stderr, "Most recent error is too large\n"); 714 return; 715 } 716 717 for (i = erlog->mostrecenterror; i < 5; i++) 718 print_error_entry(i, &erlog->log_entries[i]); 719 for (i = 0; i < erlog->mostrecenterror; i++) 720 print_error_entry(i, &erlog->log_entries[i]); 721 printf("device error count: %d\n", erlog->device_error_count); 722 } 723 724 static void 725 print_selftest_entry(int num, const struct ata_smart_selftest *le) 726 { 727 const unsigned char *p; 728 size_t i; 729 730 /* check if all zero */ 731 for (p = (const void *)le, i = 0; i < sizeof(*le); i++) 732 if (p[i] != 0) 733 break; 734 if (i == sizeof(*le)) 735 return; 736 737 printf("Log entry: %d\n", num); 738 739 /* Get test name */ 740 for (i = 0; selftest_name[i].name != NULL; i++) 741 if (selftest_name[i].number == le->number) 742 break; 743 744 if (selftest_name[i].name == NULL) 745 printf("\tName: (%d)\n", le->number); 746 else 747 printf("\tName: %s\n", selftest_name[i].name); 748 printf("\tStatus: %s\n", selftest_status[le->status >> 4]); 749 /* XXX This generally should not be set when a self-test is completed, 750 and at any rate is useless. - mycroft */ 751 if (le->status >> 4 == 15) 752 printf("\tPercent of test remaining: %1d0\n", le->status & 0xf); 753 else if (le->status >> 4 != 0) 754 printf("\tLBA first error: %d\n", le32toh(le->lba_first_error)); 755 } 756 757 static void 758 print_selftest(const void *buf) 759 { 760 const struct ata_smart_selftestlog *stlog = buf; 761 uint8_t checksum; 762 int i; 763 764 for (i = checksum = 0; i < 512; i++) 765 checksum += ((const uint8_t *) buf)[i]; 766 if (checksum != 0) { 767 fprintf(stderr, "SMART selftest log checksum error\n"); 768 return; 769 } 770 771 if (le16toh(stlog->data_structure_revision) != 1) { 772 fprintf(stderr, "Self-test log revision not 1 (found 0x%04x)\n", 773 le16toh(stlog->data_structure_revision)); 774 return; 775 } 776 777 if (stlog->mostrecenttest == 0) { 778 printf("No self-tests have been logged\n"); 779 return; 780 } 781 782 if (stlog->mostrecenttest > 22) { 783 fprintf(stderr, "Most recent test is too large\n"); 784 return; 785 } 786 787 for (i = stlog->mostrecenttest; i < 22; i++) 788 print_selftest_entry(i, &stlog->log_entries[i]); 789 for (i = 0; i < stlog->mostrecenttest; i++) 790 print_selftest_entry(i, &stlog->log_entries[i]); 791 } 792 793 static const struct ataparams * 794 getataparams(void) 795 { 796 struct atareq req; 797 static union { 798 unsigned char inbuf[DEV_BSIZE]; 799 struct ataparams inqbuf; 800 } inbuf; 801 802 memset(&inbuf, 0, sizeof(inbuf)); 803 memset(&req, 0, sizeof(req)); 804 805 req.flags = ATACMD_READ; 806 req.command = WDCC_IDENTIFY; 807 req.databuf = &inbuf; 808 req.datalen = sizeof(inbuf); 809 req.timeout = 1000; 810 811 ata_command(&req); 812 813 return (&inbuf.inqbuf); 814 } 815 816 /* 817 * is_smart: 818 * 819 * Detect whether device supports SMART and SMART is enabled. 820 */ 821 822 static int 823 is_smart(void) 824 { 825 int retval = 0; 826 const struct ataparams *inqbuf; 827 const char *status; 828 829 inqbuf = getataparams(); 830 831 if (inqbuf->atap_cmd_def != 0 && inqbuf->atap_cmd_def != 0xffff) { 832 if (!(inqbuf->atap_cmd_set1 & WDC_CMD1_SMART)) { 833 fprintf(stderr, "SMART unsupported\n"); 834 } else { 835 if (inqbuf->atap_ata_major <= WDC_VER_ATA5 || 836 inqbuf->atap_cmd_set2 == 0xffff || 837 inqbuf->atap_cmd_set2 == 0x0000) { 838 status = "status unknown"; 839 retval = 2; 840 } else { 841 if (inqbuf->atap_cmd1_en & WDC_CMD1_SMART) { 842 status = "enabled"; 843 retval = 1; 844 } else { 845 status = "disabled"; 846 retval = 3; 847 } 848 } 849 printf("SMART supported, SMART %s\n", status); 850 } 851 } 852 return retval; 853 } 854 855 /* 856 * extract_string: copy a block of bytes out of ataparams and make 857 * a proper string out of it, truncating trailing spaces and preserving 858 * strict typing. And also, not doing unaligned accesses. 859 */ 860 static void 861 extract_string(char *buf, size_t bufmax, 862 const uint8_t *bytes, size_t numbytes, 863 int needswap) 864 { 865 unsigned i; 866 size_t j; 867 unsigned char ch1, ch2; 868 869 for (i = 0, j = 0; i < numbytes; i += 2) { 870 ch1 = bytes[i]; 871 ch2 = bytes[i+1]; 872 if (needswap && j < bufmax-1) { 873 buf[j++] = ch2; 874 } 875 if (j < bufmax-1) { 876 buf[j++] = ch1; 877 } 878 if (!needswap && j < bufmax-1) { 879 buf[j++] = ch2; 880 } 881 } 882 while (j > 0 && buf[j-1] == ' ') { 883 j--; 884 } 885 buf[j] = '\0'; 886 } 887 888 static void 889 compute_capacity(const struct ataparams *inqbuf, uint64_t *capacityp, 890 uint64_t *sectorsp, uint32_t *secsizep) 891 { 892 uint64_t capacity; 893 uint64_t sectors; 894 uint32_t secsize; 895 896 if (inqbuf->atap_cmd2_en != 0 && inqbuf->atap_cmd2_en != 0xffff && 897 inqbuf->atap_cmd2_en & ATA_CMD2_LBA48) { 898 sectors = 899 ((uint64_t)inqbuf->atap_max_lba[3] << 48) | 900 ((uint64_t)inqbuf->atap_max_lba[2] << 32) | 901 ((uint64_t)inqbuf->atap_max_lba[1] << 16) | 902 ((uint64_t)inqbuf->atap_max_lba[0] << 0); 903 } else if (inqbuf->atap_capabilities1 & WDC_CAP_LBA) { 904 sectors = (inqbuf->atap_capacity[1] << 16) | 905 inqbuf->atap_capacity[0]; 906 } else { 907 sectors = inqbuf->atap_cylinders * 908 inqbuf->atap_heads * inqbuf->atap_sectors; 909 } 910 911 secsize = 512; 912 913 if ((inqbuf->atap_secsz & ATA_SECSZ_VALID_MASK) == ATA_SECSZ_VALID) { 914 if (inqbuf->atap_secsz & ATA_SECSZ_LLS) { 915 secsize = 2 * /* words to bytes */ 916 (inqbuf->atap_lls_secsz[1] << 16 | 917 inqbuf->atap_lls_secsz[0] << 0); 918 } 919 } 920 921 capacity = sectors * secsize; 922 923 if (capacityp) 924 *capacityp = capacity; 925 if (sectorsp) 926 *sectorsp = sectors; 927 if (secsizep) 928 *secsizep = secsize; 929 } 930 931 /* 932 * DEVICE COMMANDS 933 */ 934 935 /* 936 * device_identify: 937 * 938 * Display the identity of the device 939 */ 940 static void 941 device_identify(int argc, char *argv[]) 942 { 943 const struct ataparams *inqbuf; 944 char model[sizeof(inqbuf->atap_model)+1]; 945 char revision[sizeof(inqbuf->atap_revision)+1]; 946 char serial[sizeof(inqbuf->atap_serial)+1]; 947 char hnum[12]; 948 uint64_t capacity; 949 uint64_t sectors; 950 uint32_t secsize; 951 int lb_per_pb; 952 int needswap = 0; 953 int i; 954 uint8_t checksum; 955 956 /* No arguments. */ 957 if (argc != 0) 958 usage(); 959 960 inqbuf = getataparams(); 961 962 if ((inqbuf->atap_integrity & WDC_INTEGRITY_MAGIC_MASK) == 963 WDC_INTEGRITY_MAGIC) { 964 for (i = checksum = 0; i < 512; i++) 965 checksum += ((const uint8_t *)inqbuf)[i]; 966 if (checksum != 0) 967 puts("IDENTIFY DEVICE data checksum invalid\n"); 968 } 969 970 #if BYTE_ORDER == LITTLE_ENDIAN 971 /* 972 * On little endian machines, we need to shuffle the string 973 * byte order. However, we don't have to do this for NEC or 974 * Mitsumi ATAPI devices 975 */ 976 977 if (!(inqbuf->atap_config != WDC_CFG_CFA_MAGIC && 978 (inqbuf->atap_config & WDC_CFG_ATAPI) && 979 ((inqbuf->atap_model[0] == 'N' && 980 inqbuf->atap_model[1] == 'E') || 981 (inqbuf->atap_model[0] == 'F' && 982 inqbuf->atap_model[1] == 'X')))) { 983 needswap = 1; 984 } 985 #endif 986 987 /* 988 * Copy the info strings out, stripping off blanks. 989 */ 990 extract_string(model, sizeof(model), 991 inqbuf->atap_model, sizeof(inqbuf->atap_model), 992 needswap); 993 extract_string(revision, sizeof(revision), 994 inqbuf->atap_revision, sizeof(inqbuf->atap_revision), 995 needswap); 996 extract_string(serial, sizeof(serial), 997 inqbuf->atap_serial, sizeof(inqbuf->atap_serial), 998 needswap); 999 1000 printf("Model: %s, Rev: %s, Serial #: %s\n", 1001 model, revision, serial); 1002 1003 if (inqbuf->atap_cmd_ext != 0 && inqbuf->atap_cmd_ext != 0xffff && 1004 inqbuf->atap_cmd_ext & ATA_CMDE_WWN) 1005 printf("World Wide Name: %016" PRIX64 "\n", 1006 ((uint64_t)inqbuf->atap_wwn[0] << 48) | 1007 ((uint64_t)inqbuf->atap_wwn[1] << 32) | 1008 ((uint64_t)inqbuf->atap_wwn[2] << 16) | 1009 ((uint64_t)inqbuf->atap_wwn[3] << 0)); 1010 1011 printf("Device type: %s", 1012 inqbuf->atap_config == WDC_CFG_CFA_MAGIC ? "CF-ATA" : 1013 (inqbuf->atap_config & WDC_CFG_ATAPI ? "ATAPI" : "ATA")); 1014 if (inqbuf->atap_config != WDC_CFG_CFA_MAGIC) 1015 printf(", %s", 1016 inqbuf->atap_config & ATA_CFG_FIXED ? "fixed" : "removable"); 1017 printf("\n"); 1018 1019 compute_capacity(inqbuf, &capacity, §ors, &secsize); 1020 1021 humanize_number(hnum, sizeof(hnum), capacity, "bytes", 1022 HN_AUTOSCALE, HN_DIVISOR_1000); 1023 1024 printf("Capacity %s, %" PRIu64 " sectors, %" PRIu32 " bytes/sector\n", 1025 hnum, sectors, secsize); 1026 1027 printf("Cylinders: %d, heads: %d, sec/track: %d\n", 1028 inqbuf->atap_cylinders, inqbuf->atap_heads, 1029 inqbuf->atap_sectors); 1030 1031 lb_per_pb = 1; 1032 1033 if ((inqbuf->atap_secsz & ATA_SECSZ_VALID_MASK) == ATA_SECSZ_VALID) { 1034 if (inqbuf->atap_secsz & ATA_SECSZ_LPS) { 1035 lb_per_pb <<= inqbuf->atap_secsz & ATA_SECSZ_LPS_SZMSK; 1036 printf("Physical sector size: %d bytes\n", 1037 lb_per_pb * secsize); 1038 if ((inqbuf->atap_logical_align & 1039 ATA_LA_VALID_MASK) == ATA_LA_VALID) { 1040 printf("First physically aligned sector: %d\n", 1041 lb_per_pb - (inqbuf->atap_logical_align & 1042 ATA_LA_MASK)); 1043 } 1044 } 1045 } 1046 1047 if (((inqbuf->atap_sata_caps & SATA_NATIVE_CMDQ) || 1048 (inqbuf->atap_cmd_set2 & ATA_CMD2_RWQ)) && 1049 (inqbuf->atap_queuedepth & WDC_QUEUE_DEPTH_MASK)) 1050 printf("Command queue depth: %d\n", 1051 (inqbuf->atap_queuedepth & WDC_QUEUE_DEPTH_MASK) + 1); 1052 1053 printf("Device capabilities:\n"); 1054 print_bitinfo("\t", "\n", inqbuf->atap_capabilities1, ata_caps); 1055 1056 if (inqbuf->atap_ata_major != 0 && inqbuf->atap_ata_major != 0xffff) { 1057 printf("Device supports following standards:\n"); 1058 print_bitinfo("", " ", inqbuf->atap_ata_major, ata_vers); 1059 printf("\n"); 1060 } 1061 1062 if (inqbuf->atap_cmd_set1 != 0 && inqbuf->atap_cmd_set1 != 0xffff && 1063 inqbuf->atap_cmd_set2 != 0 && inqbuf->atap_cmd_set2 != 0xffff) { 1064 printf("Command set support:\n"); 1065 if (inqbuf->atap_cmd1_en != 0 && inqbuf->atap_cmd1_en != 0xffff) 1066 print_bitinfo2("\t", "\n", inqbuf->atap_cmd_set1, 1067 inqbuf->atap_cmd1_en, ata_cmd_set1); 1068 else 1069 print_bitinfo("\t", "\n", inqbuf->atap_cmd_set1, 1070 ata_cmd_set1); 1071 if (inqbuf->atap_cmd2_en != 0 && inqbuf->atap_cmd2_en != 0xffff) 1072 print_bitinfo2("\t", "\n", inqbuf->atap_cmd_set2, 1073 inqbuf->atap_cmd2_en, ata_cmd_set2); 1074 else 1075 print_bitinfo("\t", "\n", inqbuf->atap_cmd_set2, 1076 ata_cmd_set2); 1077 if (inqbuf->atap_cmd_ext != 0 && inqbuf->atap_cmd_ext != 0xffff) 1078 print_bitinfo("\t", "\n", inqbuf->atap_cmd_ext, 1079 ata_cmd_ext); 1080 } 1081 1082 if (inqbuf->atap_sata_caps != 0 && inqbuf->atap_sata_caps != 0xffff) { 1083 printf("Serial ATA capabilities:\n"); 1084 print_bitinfo("\t", "\n", 1085 inqbuf->atap_sata_caps, ata_sata_caps); 1086 1087 } 1088 1089 if (inqbuf->atap_sata_features_supp != 0 && 1090 inqbuf->atap_sata_features_supp != 0xffff) { 1091 printf("Serial ATA features:\n"); 1092 if (inqbuf->atap_sata_features_en != 0 && 1093 inqbuf->atap_sata_features_en != 0xffff) 1094 print_bitinfo2("\t", "\n", 1095 inqbuf->atap_sata_features_supp, 1096 inqbuf->atap_sata_features_en, ata_sata_feat); 1097 else 1098 print_bitinfo("\t", "\n", 1099 inqbuf->atap_sata_features_supp, ata_sata_feat); 1100 } 1101 1102 if ((inqbuf->atap_ata_major & WDC_VER_ATA7) && 1103 (inqbuf->support_dsm & ATA_SUPPORT_DSM_TRIM)) 1104 printf("TRIM supported\n"); 1105 1106 return; 1107 } 1108 1109 /* 1110 * device idle: 1111 * 1112 * issue the IDLE IMMEDIATE command to the drive 1113 */ 1114 static void 1115 device_idle(int argc, char *argv[]) 1116 { 1117 struct atareq req; 1118 1119 /* No arguments. */ 1120 if (argc != 0) 1121 usage(); 1122 1123 memset(&req, 0, sizeof(req)); 1124 1125 if (strcmp(cmdname, "idle") == 0) 1126 req.command = WDCC_IDLE_IMMED; 1127 else if (strcmp(cmdname, "standby") == 0) 1128 req.command = WDCC_STANDBY_IMMED; 1129 else 1130 req.command = WDCC_SLEEP; 1131 1132 req.timeout = 1000; 1133 1134 ata_command(&req); 1135 1136 return; 1137 } 1138 1139 /* 1140 * device apm: 1141 * 1142 * enable/disable/control the APM feature of the drive 1143 */ 1144 static void 1145 device_apm(int argc, char *argv[]) 1146 { 1147 struct atareq req; 1148 long l; 1149 1150 memset(&req, 0, sizeof(req)); 1151 if (argc >= 1) { 1152 req.command = SET_FEATURES; 1153 req.timeout = 1000; 1154 1155 if (strcmp(argv[0], "disable") == 0) 1156 req.features = WDSF_APM_DS; 1157 else if (strcmp(argv[0], "set") == 0 && argc >= 2 && 1158 (l = strtol(argv[1], NULL, 0)) >= 0 && l <= 253) { 1159 1160 req.features = WDSF_APM_EN; 1161 req.sec_count = l + 1; 1162 } else 1163 usage(); 1164 } else 1165 usage(); 1166 1167 ata_command(&req); 1168 } 1169 1170 1171 /* 1172 * Set the idle timer on the disk. Set it for either idle mode or 1173 * standby mode, depending on how we were invoked. 1174 */ 1175 1176 static void 1177 device_setidle(int argc, char *argv[]) 1178 { 1179 unsigned long idle; 1180 struct atareq req; 1181 char *end; 1182 1183 /* Only one argument */ 1184 if (argc != 1) 1185 usage(); 1186 1187 idle = strtoul(argv[0], &end, 0); 1188 1189 if (*end != '\0') { 1190 fprintf(stderr, "Invalid idle time: \"%s\"\n", argv[0]); 1191 exit(1); 1192 } 1193 1194 if (idle > 19800) { 1195 fprintf(stderr, "Idle time has a maximum value of 5.5 " 1196 "hours\n"); 1197 exit(1); 1198 } 1199 1200 if (idle != 0 && idle < 5) { 1201 fprintf(stderr, "Idle timer must be at least 5 seconds\n"); 1202 exit(1); 1203 } 1204 1205 memset(&req, 0, sizeof(req)); 1206 1207 if (idle <= 240*5) 1208 req.sec_count = idle / 5; 1209 else 1210 req.sec_count = idle / (30*60) + 240; 1211 1212 req.command = cmdname[3] == 's' ? WDCC_STANDBY : WDCC_IDLE; 1213 req.timeout = 1000; 1214 1215 ata_command(&req); 1216 1217 return; 1218 } 1219 1220 /* 1221 * Query the device for the current power mode 1222 */ 1223 1224 static void 1225 device_checkpower(int argc, char *argv[]) 1226 { 1227 struct atareq req; 1228 1229 /* No arguments. */ 1230 if (argc != 0) 1231 usage(); 1232 1233 memset(&req, 0, sizeof(req)); 1234 1235 req.command = WDCC_CHECK_PWR; 1236 req.timeout = 1000; 1237 req.flags = ATACMD_READREG; 1238 1239 ata_command(&req); 1240 1241 printf("Current power status: "); 1242 1243 switch (req.sec_count) { 1244 case 0x00: 1245 printf("Standby mode\n"); 1246 break; 1247 case 0x80: 1248 printf("Idle mode\n"); 1249 break; 1250 case 0xff: 1251 printf("Active mode\n"); 1252 break; 1253 default: 1254 printf("Unknown power code (%02x)\n", req.sec_count); 1255 } 1256 1257 return; 1258 } 1259 1260 /* 1261 * device_smart: 1262 * 1263 * Display SMART status 1264 */ 1265 static void 1266 device_smart(int argc, char *argv[]) 1267 { 1268 struct atareq req; 1269 unsigned char inbuf[DEV_BSIZE]; 1270 unsigned char inbuf2[DEV_BSIZE]; 1271 1272 if (argc < 1) 1273 usage(); 1274 1275 if (strcmp(argv[0], "enable") == 0) { 1276 memset(&req, 0, sizeof(req)); 1277 1278 req.features = WDSM_ENABLE_OPS; 1279 req.command = WDCC_SMART; 1280 req.cylinder = WDSMART_CYL; 1281 req.timeout = 1000; 1282 1283 ata_command(&req); 1284 1285 is_smart(); 1286 } else if (strcmp(argv[0], "disable") == 0) { 1287 memset(&req, 0, sizeof(req)); 1288 1289 req.features = WDSM_DISABLE_OPS; 1290 req.command = WDCC_SMART; 1291 req.cylinder = WDSMART_CYL; 1292 req.timeout = 1000; 1293 1294 ata_command(&req); 1295 1296 is_smart(); 1297 } else if (strcmp(argv[0], "status") == 0) { 1298 int rv; 1299 1300 rv = is_smart(); 1301 1302 if (!rv) { 1303 fprintf(stderr, "SMART not supported\n"); 1304 return; 1305 } else if (rv == 3) 1306 return; 1307 1308 memset(&inbuf, 0, sizeof(inbuf)); 1309 memset(&req, 0, sizeof(req)); 1310 1311 req.features = WDSM_STATUS; 1312 req.command = WDCC_SMART; 1313 req.cylinder = WDSMART_CYL; 1314 req.timeout = 1000; 1315 1316 ata_command(&req); 1317 1318 if (req.cylinder != WDSMART_CYL) { 1319 fprintf(stderr, "Threshold exceeds condition\n"); 1320 } 1321 1322 /* WDSM_RD_DATA and WDSM_RD_THRESHOLDS are optional 1323 * features, the following ata_command()'s may error 1324 * and exit(). 1325 */ 1326 1327 memset(&inbuf, 0, sizeof(inbuf)); 1328 memset(&req, 0, sizeof(req)); 1329 1330 req.flags = ATACMD_READ; 1331 req.features = WDSM_RD_DATA; 1332 req.command = WDCC_SMART; 1333 req.databuf = (caddr_t) inbuf; 1334 req.datalen = sizeof(inbuf); 1335 req.cylinder = WDSMART_CYL; 1336 req.timeout = 1000; 1337 1338 ata_command(&req); 1339 1340 memset(&inbuf2, 0, sizeof(inbuf2)); 1341 memset(&req, 0, sizeof(req)); 1342 1343 req.flags = ATACMD_READ; 1344 req.features = WDSM_RD_THRESHOLDS; 1345 req.command = WDCC_SMART; 1346 req.databuf = (caddr_t) inbuf2; 1347 req.datalen = sizeof(inbuf2); 1348 req.cylinder = WDSMART_CYL; 1349 req.timeout = 1000; 1350 1351 ata_command(&req); 1352 1353 print_smart_status(inbuf, inbuf2); 1354 1355 } else if (strcmp(argv[0], "offline") == 0) { 1356 if (argc != 2) 1357 usage(); 1358 if (!is_smart()) { 1359 fprintf(stderr, "SMART not supported\n"); 1360 return; 1361 } 1362 1363 memset(&req, 0, sizeof(req)); 1364 1365 req.features = WDSM_EXEC_OFFL_IMM; 1366 req.command = WDCC_SMART; 1367 req.cylinder = WDSMART_CYL; 1368 req.sec_num = atol(argv[1]); 1369 req.timeout = 10000; 1370 1371 ata_command(&req); 1372 } else if (strcmp(argv[0], "error-log") == 0) { 1373 if (!is_smart()) { 1374 fprintf(stderr, "SMART not supported\n"); 1375 return; 1376 } 1377 1378 memset(&inbuf, 0, sizeof(inbuf)); 1379 memset(&req, 0, sizeof(req)); 1380 1381 req.flags = ATACMD_READ; 1382 req.features = WDSM_RD_LOG; 1383 req.sec_count = 1; 1384 req.sec_num = 1; 1385 req.command = WDCC_SMART; 1386 req.databuf = (caddr_t) inbuf; 1387 req.datalen = sizeof(inbuf); 1388 req.cylinder = WDSMART_CYL; 1389 req.timeout = 1000; 1390 1391 ata_command(&req); 1392 1393 print_error(inbuf); 1394 } else if (strcmp(argv[0], "selftest-log") == 0) { 1395 if (!is_smart()) { 1396 fprintf(stderr, "SMART not supported\n"); 1397 return; 1398 } 1399 1400 memset(&inbuf, 0, sizeof(inbuf)); 1401 memset(&req, 0, sizeof(req)); 1402 1403 req.flags = ATACMD_READ; 1404 req.features = WDSM_RD_LOG; 1405 req.sec_count = 1; 1406 req.sec_num = 6; 1407 req.command = WDCC_SMART; 1408 req.databuf = (caddr_t) inbuf; 1409 req.datalen = sizeof(inbuf); 1410 req.cylinder = WDSMART_CYL; 1411 req.timeout = 1000; 1412 1413 ata_command(&req); 1414 1415 print_selftest(inbuf); 1416 1417 } else { 1418 usage(); 1419 } 1420 return; 1421 } 1422 1423 static void 1424 device_security(int argc, char *argv[]) 1425 { 1426 struct atareq req; 1427 const struct ataparams *inqbuf; 1428 unsigned char data[DEV_BSIZE]; 1429 char *pass; 1430 1431 /* need subcommand */ 1432 if (argc < 1) 1433 usage(); 1434 1435 memset(&req, 0, sizeof(req)); 1436 if (strcmp(argv[0], "status") == 0) { 1437 inqbuf = getataparams(); 1438 print_bitinfo("\t", "\n", inqbuf->atap_sec_st, ata_sec_st); 1439 } else if (strcmp(argv[0], "freeze") == 0) { 1440 req.command = WDCC_SECURITY_FREEZE; 1441 req.timeout = 1000; 1442 ata_command(&req); 1443 } else if ((strcmp(argv[0], "setpass") == 0) || 1444 (strcmp(argv[0], "unlock") == 0) || 1445 (strcmp(argv[0], "disable") == 0) || 1446 (strcmp(argv[0], "erase") == 0)) { 1447 if (argc != 2) 1448 usage(); 1449 if (strcmp(argv[1], "user") != 0) { 1450 if (strcmp(argv[1], "master") == 0) { 1451 fprintf(stderr, 1452 "Master passwords not supported\n"); 1453 exit(1); 1454 } else { 1455 usage(); 1456 } 1457 } 1458 1459 pass = getpass("Password:"); 1460 if (strlen(pass) > 32) { 1461 fprintf(stderr, "Password must be <=32 characters\n"); 1462 exit(1); 1463 } 1464 1465 req.flags |= ATACMD_WRITE; 1466 req.timeout = 1000; 1467 req.databuf = data; 1468 req.datalen = sizeof(data); 1469 memset(data, 0, sizeof(data)); 1470 strlcpy((void *)&data[2], pass, 32 + 1); 1471 1472 if (strcmp(argv[0], "setpass") == 0) { 1473 char orig[32 + 1]; 1474 strlcpy(orig, pass, 32 + 1); 1475 pass = getpass("Confirm password:"); 1476 if (0 != strcmp(orig, pass)) { 1477 fprintf(stderr, "Passwords do not match\n"); 1478 exit(1); 1479 } 1480 req.command = WDCC_SECURITY_SET_PASSWORD; 1481 } else if (strcmp(argv[0], "unlock") == 0) { 1482 req.command = WDCC_SECURITY_UNLOCK; 1483 } else if (strcmp(argv[0], "disable") == 0) { 1484 req.command = WDCC_SECURITY_DISABLE_PASSWORD; 1485 } else if (strcmp(argv[0], "erase") == 0) { 1486 struct atareq prepare; 1487 1488 inqbuf = getataparams(); 1489 1490 /* 1491 * XXX Any way to lock the device to make sure 1492 * this really is the command preceding the 1493 * SECURITY ERASE UNIT command? This would 1494 * probably have to be moved into the kernel to 1495 * do that. 1496 */ 1497 memset(&prepare, 0, sizeof(prepare)); 1498 prepare.command = WDCC_SECURITY_ERASE_PREPARE; 1499 prepare.timeout = 1000; 1500 ata_command(&prepare); 1501 1502 req.command = WDCC_SECURITY_ERASE_UNIT; 1503 1504 /* 1505 * Enable enhanced erase if it's supported. 1506 * 1507 * XXX should be a command-line option 1508 */ 1509 if (inqbuf->atap_sec_st & WDC_SEC_ESE_SUPP) { 1510 data[0] |= 0x2; 1511 req.timeout = (inqbuf->atap_eseu_time & 0xff) 1512 * 2 * 60 * 1000; 1513 } else { 1514 req.timeout = (inqbuf->atap_seu_time & 0xff) 1515 * 2 * 60 * 1000; 1516 } 1517 1518 /* 1519 * If the estimated time was 0xff (* 2 * 60 * 1520 * 1000 = 30600000), that means `>508 minutes'. 1521 * Estimate that we can handle 16 MB/sec, a 1522 * rate I just pulled out of my arse. 1523 */ 1524 if (req.timeout == 30600000) { 1525 uint64_t bytes, timeout; 1526 compute_capacity(inqbuf, &bytes, NULL, NULL); 1527 timeout = (bytes / (16 * 1024 * 1024)) * 1000; 1528 if (timeout > (uint64_t)INT_MAX) 1529 req.timeout = INT_MAX; 1530 else 1531 req.timeout = timeout; 1532 } 1533 1534 printf("Erasing may take up to %dh %dm %ds...\n", 1535 (req.timeout / 1000 / 60) / 60, 1536 (req.timeout / 1000 / 60) % 60, 1537 req.timeout % 60); 1538 } else { 1539 abort(); 1540 } 1541 1542 ata_command(&req); 1543 } else { 1544 usage(); 1545 } 1546 } 1547 1548 /* 1549 * bus_reset: 1550 * Reset an ATA bus (will reset all devices on the bus) 1551 */ 1552 static void 1553 bus_reset(int argc, char *argv[]) 1554 { 1555 int error; 1556 1557 /* no args */ 1558 if (argc != 0) 1559 usage(); 1560 1561 error = ioctl(fd, ATABUSIORESET, NULL); 1562 1563 if (error == -1) 1564 err(1, "ATABUSIORESET failed"); 1565 } 1566