1 /* $NetBSD: atactl.c,v 1.76 2016/05/10 08:08:59 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.76 2016/05/10 08:08:59 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 { 250, "Read error retry rate", NULL }, 339 { 254, "Free Fall Sensor", NULL }, 340 { 0, "Unknown", NULL }, 341 }; 342 343 static const struct bitinfo ata_sec_st[] = { 344 { WDC_SEC_SUPP, "supported" }, 345 { WDC_SEC_EN, "enabled" }, 346 { WDC_SEC_LOCKED, "locked" }, 347 { WDC_SEC_FROZEN, "frozen" }, 348 { WDC_SEC_EXP, "expired" }, 349 { WDC_SEC_ESE_SUPP, "enhanced erase support" }, 350 { WDC_SEC_LEV_MAX, "maximum level" }, 351 { 0, NULL }, 352 }; 353 354 int 355 main(int argc, char *argv[]) 356 { 357 int i; 358 const struct command *commands = NULL; 359 360 /* Must have at least: device command */ 361 if (argc < 3) 362 usage(); 363 364 /* Skip program name, get and skip device name and command. */ 365 dvname = argv[1]; 366 cmdname = argv[2]; 367 argv += 3; 368 argc -= 3; 369 370 /* 371 * Open the device 372 */ 373 fd = opendisk(dvname, O_RDWR, dvname_store, sizeof(dvname_store), 0); 374 if (fd == -1) { 375 if (errno == ENOENT) { 376 /* 377 * Device doesn't exist. Probably trying to open 378 * a device which doesn't use disk semantics for 379 * device name. Try again, specifying "cooked", 380 * which leaves off the "r" in front of the device's 381 * name. 382 */ 383 fd = opendisk(dvname, O_RDWR, dvname_store, 384 sizeof(dvname_store), 1); 385 if (fd == -1) 386 err(1, "%s", dvname); 387 } else 388 err(1, "%s", dvname); 389 } 390 391 /* 392 * Point the dvname at the actual device name that opendisk() opened. 393 */ 394 dvname = dvname_store; 395 396 /* Look up and call the command. */ 397 for (i = 0; device_commands[i].cmd_name != NULL; i++) { 398 if (strcmp(cmdname, device_commands[i].cmd_name) == 0) { 399 commands = &device_commands[i]; 400 break; 401 } 402 } 403 if (commands == NULL) { 404 for (i = 0; bus_commands[i].cmd_name != NULL; i++) { 405 if (strcmp(cmdname, bus_commands[i].cmd_name) == 0) { 406 commands = &bus_commands[i]; 407 break; 408 } 409 } 410 } 411 if (commands == NULL) 412 errx(1, "unknown command: %s", cmdname); 413 414 (*commands->cmd_func)(argc, argv); 415 exit(0); 416 } 417 418 static void 419 usage(void) 420 { 421 int i; 422 423 fprintf(stderr, "usage: %s device command [arg [...]]\n", 424 getprogname()); 425 426 fprintf(stderr, " Available device commands:\n"); 427 for (i=0; device_commands[i].cmd_name != NULL; i++) 428 fprintf(stderr, "\t%s %s\n", device_commands[i].cmd_name, 429 device_commands[i].arg_names); 430 431 fprintf(stderr, " Available bus commands:\n"); 432 for (i=0; bus_commands[i].cmd_name != NULL; i++) 433 fprintf(stderr, "\t%s %s\n", bus_commands[i].cmd_name, 434 bus_commands[i].arg_names); 435 436 exit(1); 437 } 438 439 /* 440 * Wrapper that calls ATAIOCCOMMAND and checks for errors 441 */ 442 443 static void 444 ata_command(struct atareq *req) 445 { 446 int error; 447 448 error = ioctl(fd, ATAIOCCOMMAND, req); 449 450 if (error == -1) 451 err(1, "ATAIOCCOMMAND failed"); 452 453 switch (req->retsts) { 454 455 case ATACMD_OK: 456 return; 457 case ATACMD_TIMEOUT: 458 fprintf(stderr, "ATA command timed out\n"); 459 exit(1); 460 case ATACMD_DF: 461 fprintf(stderr, "ATA device returned a Device Fault\n"); 462 exit(1); 463 case ATACMD_ERROR: 464 if (req->error & WDCE_ABRT) 465 fprintf(stderr, "ATA device returned Aborted " 466 "Command\n"); 467 else 468 fprintf(stderr, "ATA device returned error register " 469 "%0x\n", req->error); 470 exit(1); 471 default: 472 fprintf(stderr, "ATAIOCCOMMAND returned unknown result code " 473 "%d\n", req->retsts); 474 exit(1); 475 } 476 } 477 478 /* 479 * Print out strings associated with particular bitmasks 480 */ 481 482 static void 483 print_bitinfo(const char *bf, const char *af, u_int bits, 484 const struct bitinfo *binfo) 485 { 486 487 for (; binfo->bitmask != 0; binfo++) 488 if (bits & binfo->bitmask) 489 printf("%s%s%s", bf, binfo->string, af); 490 } 491 492 static void 493 print_bitinfo2(const char *bf, const char *af, u_int bits, u_int enables, 494 const struct bitinfo *binfo) 495 { 496 497 for (; binfo->bitmask != 0; binfo++) 498 if (bits & binfo->bitmask) 499 printf("%s%s (%s)%s", bf, binfo->string, 500 (enables & binfo->bitmask) ? "enabled" : "disabled", 501 af); 502 } 503 504 505 /* 506 * Try to print SMART temperature field 507 */ 508 509 static void 510 device_smart_temp(const struct ata_smart_attr *attr, uint64_t raw_value) 511 { 512 printf("%" PRIu8, attr->raw[0]); 513 if (attr->raw[0] != raw_value) 514 printf(" Lifetime min/max %" PRIu8 "/%" PRIu8, 515 attr->raw[2], attr->raw[4]); 516 } 517 518 519 /* 520 * Print out SMART attribute thresholds and values 521 */ 522 523 static void 524 print_smart_status(void *vbuf, void *tbuf) 525 { 526 const struct ata_smart_attributes *value_buf = vbuf; 527 const struct ata_smart_thresholds *threshold_buf = tbuf; 528 const struct ata_smart_attr *attr; 529 uint64_t raw_value; 530 int flags; 531 int i, j; 532 int aid; 533 uint8_t checksum; 534 535 for (i = checksum = 0; i < 512; i++) 536 checksum += ((const uint8_t *) value_buf)[i]; 537 if (checksum != 0) { 538 fprintf(stderr, "SMART attribute values checksum error\n"); 539 return; 540 } 541 542 for (i = checksum = 0; i < 512; i++) 543 checksum += ((const uint8_t *) threshold_buf)[i]; 544 if (checksum != 0) { 545 fprintf(stderr, "SMART attribute thresholds checksum error\n"); 546 return; 547 } 548 549 printf("id value thresh crit collect reliability description" 550 " raw\n"); 551 for (i = 0; i < 256; i++) { 552 int thresh = 0; 553 554 attr = NULL; 555 556 for (j = 0; j < 30; j++) { 557 if (value_buf->attributes[j].id == i) 558 attr = &value_buf->attributes[j]; 559 if (threshold_buf->thresholds[j].id == i) 560 thresh = threshold_buf->thresholds[j].value; 561 } 562 563 if (thresh && attr == NULL) 564 errx(1, "threshold but not attr %d", i); 565 if (attr == NULL) 566 continue; 567 568 if (attr->value == 0||attr->value == 0xFE||attr->value == 0xFF) 569 continue; 570 571 for (aid = 0; 572 smart_attrs[aid].id != i && smart_attrs[aid].id != 0; 573 aid++) 574 ; 575 576 flags = le16toh(attr->flags); 577 578 printf("%3d %3d %3d %-3s %-7s %stive %-27s ", 579 i, attr->value, thresh, 580 flags & WDSM_ATTR_ADVISORY ? "yes" : "no", 581 flags & WDSM_ATTR_COLLECTIVE ? "online" : "offline", 582 attr->value > thresh ? "posi" : "nega", 583 smart_attrs[aid].name); 584 585 for (j = 0, raw_value = 0; j < 6; j++) 586 raw_value += ((uint64_t)attr->raw[j]) << (8*j); 587 588 if (smart_attrs[aid].special) 589 (*smart_attrs[aid].special)(attr, raw_value); 590 else 591 printf("%" PRIu64, raw_value); 592 printf("\n"); 593 } 594 } 595 596 static const struct { 597 int number; 598 const char *name; 599 } selftest_name[] = { 600 { 0, "Off-line" }, 601 { 1, "Short off-line" }, 602 { 2, "Extended off-line" }, 603 { 127, "Abort off-line test" }, 604 { 129, "Short captive" }, 605 { 130, "Extended captive" }, 606 { 256, "Unknown test" }, /* larger than uint8_t */ 607 { 0, NULL } 608 }; 609 610 static const char *selftest_status[] = { 611 "No error", 612 "Aborted by the host", 613 "Interrupted by the host by reset", 614 "Fatal error or unknown test error", 615 "Unknown test element failed", 616 "Electrical test element failed", 617 "The Servo (and/or seek) test element failed", 618 "Read element of test failed", 619 "Reserved", 620 "Reserved", 621 "Reserved", 622 "Reserved", 623 "Reserved", 624 "Reserved", 625 "Reserved", 626 "Self-test in progress" 627 }; 628 629 static void 630 print_error_entry(int num, const struct ata_smart_error *le) 631 { 632 int i; 633 634 printf("Log entry: %d\n", num); 635 636 for (i = 0; i < 5; i++) 637 printf("\tCommand %d: dc=%02x sf=%02x sc=%02x sn=%02x cl=%02x " 638 "ch=%02x dh=%02x cmd=%02x time=%02x%02x%02x%02x\n", i, 639 le->command[i].device_control, 640 le->command[i].features, 641 le->command[i].sector_count, 642 le->command[i].sector_number, 643 le->command[i].cylinder_low, 644 le->command[i].cylinder_high, 645 le->command[i].device_head, 646 le->command[i].command, 647 le->command[i].timestamp[3], 648 le->command[i].timestamp[2], 649 le->command[i].timestamp[1], 650 le->command[i].timestamp[0]); 651 printf("\tError: err=%02x sc=%02x sn=%02x cl=%02x ch=%02x dh=%02x " 652 "status=%02x state=%02x lifetime=%02x%02x\n", 653 le->error_data.error, 654 le->error_data.sector_count, 655 le->error_data.sector_number, 656 le->error_data.cylinder_low, 657 le->error_data.cylinder_high, 658 le->error_data.device_head, 659 le->error_data.status, 660 le->error_data.state, 661 le->error_data.lifetime[1], 662 le->error_data.lifetime[0]); 663 printf("\tExtended: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x " 664 "%02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 665 le->error_data.extended_error[0], 666 le->error_data.extended_error[1], 667 le->error_data.extended_error[2], 668 le->error_data.extended_error[3], 669 le->error_data.extended_error[4], 670 le->error_data.extended_error[5], 671 le->error_data.extended_error[6], 672 le->error_data.extended_error[7], 673 le->error_data.extended_error[8], 674 le->error_data.extended_error[9], 675 le->error_data.extended_error[10], 676 le->error_data.extended_error[11], 677 le->error_data.extended_error[12], 678 le->error_data.extended_error[13], 679 le->error_data.extended_error[14], 680 le->error_data.extended_error[15], 681 le->error_data.extended_error[15], 682 le->error_data.extended_error[17], 683 le->error_data.extended_error[18]); 684 } 685 686 static void 687 print_error(const void *buf) 688 { 689 const struct ata_smart_errorlog *erlog = buf; 690 uint8_t checksum; 691 int i; 692 693 for (i = checksum = 0; i < 512; i++) 694 checksum += ((const uint8_t *) buf)[i]; 695 if (checksum != 0) { 696 fprintf(stderr, "SMART error log checksum error\n"); 697 return; 698 } 699 700 if (erlog->data_structure_revision != 1) { 701 fprintf(stderr, "Error log revision not 1 (found 0x%04x)\n", 702 erlog->data_structure_revision); 703 return; 704 } 705 706 if (erlog->mostrecenterror == 0) { 707 printf("No errors have been logged\n"); 708 return; 709 } 710 711 if (erlog->mostrecenterror > 5) { 712 fprintf(stderr, "Most recent error is too large\n"); 713 return; 714 } 715 716 for (i = erlog->mostrecenterror; i < 5; i++) 717 print_error_entry(i, &erlog->log_entries[i]); 718 for (i = 0; i < erlog->mostrecenterror; i++) 719 print_error_entry(i, &erlog->log_entries[i]); 720 printf("device error count: %d\n", erlog->device_error_count); 721 } 722 723 static void 724 print_selftest_entry(int num, const struct ata_smart_selftest *le) 725 { 726 const unsigned char *p; 727 size_t i; 728 729 /* check if all zero */ 730 for (p = (const void *)le, i = 0; i < sizeof(*le); i++) 731 if (p[i] != 0) 732 break; 733 if (i == sizeof(*le)) 734 return; 735 736 printf("Log entry: %d\n", num); 737 738 /* Get test name */ 739 for (i = 0; selftest_name[i].name != NULL; i++) 740 if (selftest_name[i].number == le->number) 741 break; 742 743 if (selftest_name[i].name == NULL) 744 printf("\tName: (%d)\n", le->number); 745 else 746 printf("\tName: %s\n", selftest_name[i].name); 747 printf("\tStatus: %s\n", selftest_status[le->status >> 4]); 748 /* XXX This generally should not be set when a self-test is completed, 749 and at any rate is useless. - mycroft */ 750 if (le->status >> 4 == 15) 751 printf("\tPercent of test remaining: %1d0\n", le->status & 0xf); 752 else if (le->status >> 4 != 0) 753 printf("\tLBA first error: %d\n", le32toh(le->lba_first_error)); 754 } 755 756 static void 757 print_selftest(const void *buf) 758 { 759 const struct ata_smart_selftestlog *stlog = buf; 760 uint8_t checksum; 761 int i; 762 763 for (i = checksum = 0; i < 512; i++) 764 checksum += ((const uint8_t *) buf)[i]; 765 if (checksum != 0) { 766 fprintf(stderr, "SMART selftest log checksum error\n"); 767 return; 768 } 769 770 if (le16toh(stlog->data_structure_revision) != 1) { 771 fprintf(stderr, "Self-test log revision not 1 (found 0x%04x)\n", 772 le16toh(stlog->data_structure_revision)); 773 return; 774 } 775 776 if (stlog->mostrecenttest == 0) { 777 printf("No self-tests have been logged\n"); 778 return; 779 } 780 781 if (stlog->mostrecenttest > 22) { 782 fprintf(stderr, "Most recent test is too large\n"); 783 return; 784 } 785 786 for (i = stlog->mostrecenttest; i < 22; i++) 787 print_selftest_entry(i, &stlog->log_entries[i]); 788 for (i = 0; i < stlog->mostrecenttest; i++) 789 print_selftest_entry(i, &stlog->log_entries[i]); 790 } 791 792 static const struct ataparams * 793 getataparams(void) 794 { 795 struct atareq req; 796 static union { 797 unsigned char inbuf[DEV_BSIZE]; 798 struct ataparams inqbuf; 799 } inbuf; 800 801 memset(&inbuf, 0, sizeof(inbuf)); 802 memset(&req, 0, sizeof(req)); 803 804 req.flags = ATACMD_READ; 805 req.command = WDCC_IDENTIFY; 806 req.databuf = &inbuf; 807 req.datalen = sizeof(inbuf); 808 req.timeout = 1000; 809 810 ata_command(&req); 811 812 return (&inbuf.inqbuf); 813 } 814 815 /* 816 * is_smart: 817 * 818 * Detect whether device supports SMART and SMART is enabled. 819 */ 820 821 static int 822 is_smart(void) 823 { 824 int retval = 0; 825 const struct ataparams *inqbuf; 826 const char *status; 827 828 inqbuf = getataparams(); 829 830 if (inqbuf->atap_cmd_def != 0 && inqbuf->atap_cmd_def != 0xffff) { 831 if (!(inqbuf->atap_cmd_set1 & WDC_CMD1_SMART)) { 832 fprintf(stderr, "SMART unsupported\n"); 833 } else { 834 if (inqbuf->atap_ata_major <= WDC_VER_ATA5 || 835 inqbuf->atap_cmd_set2 == 0xffff || 836 inqbuf->atap_cmd_set2 == 0x0000) { 837 status = "status unknown"; 838 retval = 2; 839 } else { 840 if (inqbuf->atap_cmd1_en & WDC_CMD1_SMART) { 841 status = "enabled"; 842 retval = 1; 843 } else { 844 status = "disabled"; 845 retval = 3; 846 } 847 } 848 printf("SMART supported, SMART %s\n", status); 849 } 850 } 851 return retval; 852 } 853 854 /* 855 * extract_string: copy a block of bytes out of ataparams and make 856 * a proper string out of it, truncating trailing spaces and preserving 857 * strict typing. And also, not doing unaligned accesses. 858 */ 859 static void 860 extract_string(char *buf, size_t bufmax, 861 const uint8_t *bytes, size_t numbytes, 862 int needswap) 863 { 864 unsigned i; 865 size_t j; 866 unsigned char ch1, ch2; 867 868 for (i = 0, j = 0; i < numbytes; i += 2) { 869 ch1 = bytes[i]; 870 ch2 = bytes[i+1]; 871 if (needswap && j < bufmax-1) { 872 buf[j++] = ch2; 873 } 874 if (j < bufmax-1) { 875 buf[j++] = ch1; 876 } 877 if (!needswap && j < bufmax-1) { 878 buf[j++] = ch2; 879 } 880 } 881 while (j > 0 && buf[j-1] == ' ') { 882 j--; 883 } 884 buf[j] = '\0'; 885 } 886 887 static void 888 compute_capacity(const struct ataparams *inqbuf, uint64_t *capacityp, 889 uint64_t *sectorsp, uint32_t *secsizep) 890 { 891 uint64_t capacity; 892 uint64_t sectors; 893 uint32_t secsize; 894 895 if (inqbuf->atap_cmd2_en != 0 && inqbuf->atap_cmd2_en != 0xffff && 896 inqbuf->atap_cmd2_en & ATA_CMD2_LBA48) { 897 sectors = 898 ((uint64_t)inqbuf->atap_max_lba[3] << 48) | 899 ((uint64_t)inqbuf->atap_max_lba[2] << 32) | 900 ((uint64_t)inqbuf->atap_max_lba[1] << 16) | 901 ((uint64_t)inqbuf->atap_max_lba[0] << 0); 902 } else if (inqbuf->atap_capabilities1 & WDC_CAP_LBA) { 903 sectors = (inqbuf->atap_capacity[1] << 16) | 904 inqbuf->atap_capacity[0]; 905 } else { 906 sectors = inqbuf->atap_cylinders * 907 inqbuf->atap_heads * inqbuf->atap_sectors; 908 } 909 910 secsize = 512; 911 912 if ((inqbuf->atap_secsz & ATA_SECSZ_VALID_MASK) == ATA_SECSZ_VALID) { 913 if (inqbuf->atap_secsz & ATA_SECSZ_LLS) { 914 secsize = 2 * /* words to bytes */ 915 (inqbuf->atap_lls_secsz[1] << 16 | 916 inqbuf->atap_lls_secsz[0] << 0); 917 } 918 } 919 920 capacity = sectors * secsize; 921 922 if (capacityp) 923 *capacityp = capacity; 924 if (sectorsp) 925 *sectorsp = sectors; 926 if (secsizep) 927 *secsizep = secsize; 928 } 929 930 /* 931 * DEVICE COMMANDS 932 */ 933 934 /* 935 * device_identify: 936 * 937 * Display the identity of the device 938 */ 939 static void 940 device_identify(int argc, char *argv[]) 941 { 942 const struct ataparams *inqbuf; 943 char model[sizeof(inqbuf->atap_model)+1]; 944 char revision[sizeof(inqbuf->atap_revision)+1]; 945 char serial[sizeof(inqbuf->atap_serial)+1]; 946 char hnum[12]; 947 uint64_t capacity; 948 uint64_t sectors; 949 uint32_t secsize; 950 int lb_per_pb; 951 int needswap = 0; 952 int i; 953 uint8_t checksum; 954 955 /* No arguments. */ 956 if (argc != 0) 957 usage(); 958 959 inqbuf = getataparams(); 960 961 if ((inqbuf->atap_integrity & WDC_INTEGRITY_MAGIC_MASK) == 962 WDC_INTEGRITY_MAGIC) { 963 for (i = checksum = 0; i < 512; i++) 964 checksum += ((const uint8_t *)inqbuf)[i]; 965 if (checksum != 0) 966 puts("IDENTIFY DEVICE data checksum invalid\n"); 967 } 968 969 #if BYTE_ORDER == LITTLE_ENDIAN 970 /* 971 * On little endian machines, we need to shuffle the string 972 * byte order. However, we don't have to do this for NEC or 973 * Mitsumi ATAPI devices 974 */ 975 976 if (!(inqbuf->atap_config != WDC_CFG_CFA_MAGIC && 977 (inqbuf->atap_config & WDC_CFG_ATAPI) && 978 ((inqbuf->atap_model[0] == 'N' && 979 inqbuf->atap_model[1] == 'E') || 980 (inqbuf->atap_model[0] == 'F' && 981 inqbuf->atap_model[1] == 'X')))) { 982 needswap = 1; 983 } 984 #endif 985 986 /* 987 * Copy the info strings out, stripping off blanks. 988 */ 989 extract_string(model, sizeof(model), 990 inqbuf->atap_model, sizeof(inqbuf->atap_model), 991 needswap); 992 extract_string(revision, sizeof(revision), 993 inqbuf->atap_revision, sizeof(inqbuf->atap_revision), 994 needswap); 995 extract_string(serial, sizeof(serial), 996 inqbuf->atap_serial, sizeof(inqbuf->atap_serial), 997 needswap); 998 999 printf("Model: %s, Rev: %s, Serial #: %s\n", 1000 model, revision, serial); 1001 1002 if (inqbuf->atap_cmd_ext != 0 && inqbuf->atap_cmd_ext != 0xffff && 1003 inqbuf->atap_cmd_ext & ATA_CMDE_WWN) 1004 printf("World Wide Name: %016" PRIX64 "\n", 1005 ((uint64_t)inqbuf->atap_wwn[0] << 48) | 1006 ((uint64_t)inqbuf->atap_wwn[1] << 32) | 1007 ((uint64_t)inqbuf->atap_wwn[2] << 16) | 1008 ((uint64_t)inqbuf->atap_wwn[3] << 0)); 1009 1010 printf("Device type: %s", 1011 inqbuf->atap_config == WDC_CFG_CFA_MAGIC ? "CF-ATA" : 1012 (inqbuf->atap_config & WDC_CFG_ATAPI ? "ATAPI" : "ATA")); 1013 if (inqbuf->atap_config != WDC_CFG_CFA_MAGIC) 1014 printf(", %s", 1015 inqbuf->atap_config & ATA_CFG_FIXED ? "fixed" : "removable"); 1016 printf("\n"); 1017 1018 compute_capacity(inqbuf, &capacity, §ors, &secsize); 1019 1020 humanize_number(hnum, sizeof(hnum), capacity, "bytes", 1021 HN_AUTOSCALE, HN_DIVISOR_1000); 1022 1023 printf("Capacity %s, %" PRIu64 " sectors, %" PRIu32 " bytes/sector\n", 1024 hnum, sectors, secsize); 1025 1026 printf("Cylinders: %d, heads: %d, sec/track: %d\n", 1027 inqbuf->atap_cylinders, inqbuf->atap_heads, 1028 inqbuf->atap_sectors); 1029 1030 lb_per_pb = 1; 1031 1032 if ((inqbuf->atap_secsz & ATA_SECSZ_VALID_MASK) == ATA_SECSZ_VALID) { 1033 if (inqbuf->atap_secsz & ATA_SECSZ_LPS) { 1034 lb_per_pb <<= inqbuf->atap_secsz & ATA_SECSZ_LPS_SZMSK; 1035 printf("Physical sector size: %d bytes\n", 1036 lb_per_pb * secsize); 1037 if ((inqbuf->atap_logical_align & 1038 ATA_LA_VALID_MASK) == ATA_LA_VALID) { 1039 printf("First physically aligned sector: %d\n", 1040 lb_per_pb - (inqbuf->atap_logical_align & 1041 ATA_LA_MASK)); 1042 } 1043 } 1044 } 1045 1046 if (((inqbuf->atap_sata_caps & SATA_NATIVE_CMDQ) || 1047 (inqbuf->atap_cmd_set2 & ATA_CMD2_RWQ)) && 1048 (inqbuf->atap_queuedepth & WDC_QUEUE_DEPTH_MASK)) 1049 printf("Command queue depth: %d\n", 1050 (inqbuf->atap_queuedepth & WDC_QUEUE_DEPTH_MASK) + 1); 1051 1052 printf("Device capabilities:\n"); 1053 print_bitinfo("\t", "\n", inqbuf->atap_capabilities1, ata_caps); 1054 1055 if (inqbuf->atap_ata_major != 0 && inqbuf->atap_ata_major != 0xffff) { 1056 printf("Device supports following standards:\n"); 1057 print_bitinfo("", " ", inqbuf->atap_ata_major, ata_vers); 1058 printf("\n"); 1059 } 1060 1061 if (inqbuf->atap_cmd_set1 != 0 && inqbuf->atap_cmd_set1 != 0xffff && 1062 inqbuf->atap_cmd_set2 != 0 && inqbuf->atap_cmd_set2 != 0xffff) { 1063 printf("Command set support:\n"); 1064 if (inqbuf->atap_cmd1_en != 0 && inqbuf->atap_cmd1_en != 0xffff) 1065 print_bitinfo2("\t", "\n", inqbuf->atap_cmd_set1, 1066 inqbuf->atap_cmd1_en, ata_cmd_set1); 1067 else 1068 print_bitinfo("\t", "\n", inqbuf->atap_cmd_set1, 1069 ata_cmd_set1); 1070 if (inqbuf->atap_cmd2_en != 0 && inqbuf->atap_cmd2_en != 0xffff) 1071 print_bitinfo2("\t", "\n", inqbuf->atap_cmd_set2, 1072 inqbuf->atap_cmd2_en, ata_cmd_set2); 1073 else 1074 print_bitinfo("\t", "\n", inqbuf->atap_cmd_set2, 1075 ata_cmd_set2); 1076 if (inqbuf->atap_cmd_ext != 0 && inqbuf->atap_cmd_ext != 0xffff) 1077 print_bitinfo("\t", "\n", inqbuf->atap_cmd_ext, 1078 ata_cmd_ext); 1079 } 1080 1081 if (inqbuf->atap_sata_caps != 0 && inqbuf->atap_sata_caps != 0xffff) { 1082 printf("Serial ATA capabilities:\n"); 1083 print_bitinfo("\t", "\n", 1084 inqbuf->atap_sata_caps, ata_sata_caps); 1085 1086 } 1087 1088 if (inqbuf->atap_sata_features_supp != 0 && 1089 inqbuf->atap_sata_features_supp != 0xffff) { 1090 printf("Serial ATA features:\n"); 1091 if (inqbuf->atap_sata_features_en != 0 && 1092 inqbuf->atap_sata_features_en != 0xffff) 1093 print_bitinfo2("\t", "\n", 1094 inqbuf->atap_sata_features_supp, 1095 inqbuf->atap_sata_features_en, ata_sata_feat); 1096 else 1097 print_bitinfo("\t", "\n", 1098 inqbuf->atap_sata_features_supp, ata_sata_feat); 1099 } 1100 1101 if ((inqbuf->atap_ata_major & WDC_VER_ATA7) && 1102 (inqbuf->support_dsm & ATA_SUPPORT_DSM_TRIM)) 1103 printf("TRIM supported\n"); 1104 1105 return; 1106 } 1107 1108 /* 1109 * device idle: 1110 * 1111 * issue the IDLE IMMEDIATE command to the drive 1112 */ 1113 static void 1114 device_idle(int argc, char *argv[]) 1115 { 1116 struct atareq req; 1117 1118 /* No arguments. */ 1119 if (argc != 0) 1120 usage(); 1121 1122 memset(&req, 0, sizeof(req)); 1123 1124 if (strcmp(cmdname, "idle") == 0) 1125 req.command = WDCC_IDLE_IMMED; 1126 else if (strcmp(cmdname, "standby") == 0) 1127 req.command = WDCC_STANDBY_IMMED; 1128 else 1129 req.command = WDCC_SLEEP; 1130 1131 req.timeout = 1000; 1132 1133 ata_command(&req); 1134 1135 return; 1136 } 1137 1138 /* 1139 * device apm: 1140 * 1141 * enable/disable/control the APM feature of the drive 1142 */ 1143 static void 1144 device_apm(int argc, char *argv[]) 1145 { 1146 struct atareq req; 1147 long l; 1148 1149 memset(&req, 0, sizeof(req)); 1150 if (argc >= 1) { 1151 req.command = SET_FEATURES; 1152 req.timeout = 1000; 1153 1154 if (strcmp(argv[0], "disable") == 0) 1155 req.features = WDSF_APM_DS; 1156 else if (strcmp(argv[0], "set") == 0 && argc >= 2 && 1157 (l = strtol(argv[1], NULL, 0)) >= 0 && l <= 253) { 1158 1159 req.features = WDSF_APM_EN; 1160 req.sec_count = l + 1; 1161 } else 1162 usage(); 1163 } else 1164 usage(); 1165 1166 ata_command(&req); 1167 } 1168 1169 1170 /* 1171 * Set the idle timer on the disk. Set it for either idle mode or 1172 * standby mode, depending on how we were invoked. 1173 */ 1174 1175 static void 1176 device_setidle(int argc, char *argv[]) 1177 { 1178 unsigned long idle; 1179 struct atareq req; 1180 char *end; 1181 1182 /* Only one argument */ 1183 if (argc != 1) 1184 usage(); 1185 1186 idle = strtoul(argv[0], &end, 0); 1187 1188 if (*end != '\0') { 1189 fprintf(stderr, "Invalid idle time: \"%s\"\n", argv[0]); 1190 exit(1); 1191 } 1192 1193 if (idle > 19800) { 1194 fprintf(stderr, "Idle time has a maximum value of 5.5 " 1195 "hours\n"); 1196 exit(1); 1197 } 1198 1199 if (idle != 0 && idle < 5) { 1200 fprintf(stderr, "Idle timer must be at least 5 seconds\n"); 1201 exit(1); 1202 } 1203 1204 memset(&req, 0, sizeof(req)); 1205 1206 if (idle <= 240*5) 1207 req.sec_count = idle / 5; 1208 else 1209 req.sec_count = idle / (30*60) + 240; 1210 1211 req.command = cmdname[3] == 's' ? WDCC_STANDBY : WDCC_IDLE; 1212 req.timeout = 1000; 1213 1214 ata_command(&req); 1215 1216 return; 1217 } 1218 1219 /* 1220 * Query the device for the current power mode 1221 */ 1222 1223 static void 1224 device_checkpower(int argc, char *argv[]) 1225 { 1226 struct atareq req; 1227 1228 /* No arguments. */ 1229 if (argc != 0) 1230 usage(); 1231 1232 memset(&req, 0, sizeof(req)); 1233 1234 req.command = WDCC_CHECK_PWR; 1235 req.timeout = 1000; 1236 req.flags = ATACMD_READREG; 1237 1238 ata_command(&req); 1239 1240 printf("Current power status: "); 1241 1242 switch (req.sec_count) { 1243 case 0x00: 1244 printf("Standby mode\n"); 1245 break; 1246 case 0x80: 1247 printf("Idle mode\n"); 1248 break; 1249 case 0xff: 1250 printf("Active mode\n"); 1251 break; 1252 default: 1253 printf("Unknown power code (%02x)\n", req.sec_count); 1254 } 1255 1256 return; 1257 } 1258 1259 /* 1260 * device_smart: 1261 * 1262 * Display SMART status 1263 */ 1264 static void 1265 device_smart(int argc, char *argv[]) 1266 { 1267 struct atareq req; 1268 unsigned char inbuf[DEV_BSIZE]; 1269 unsigned char inbuf2[DEV_BSIZE]; 1270 1271 if (argc < 1) 1272 usage(); 1273 1274 if (strcmp(argv[0], "enable") == 0) { 1275 memset(&req, 0, sizeof(req)); 1276 1277 req.features = WDSM_ENABLE_OPS; 1278 req.command = WDCC_SMART; 1279 req.cylinder = WDSMART_CYL; 1280 req.timeout = 1000; 1281 1282 ata_command(&req); 1283 1284 is_smart(); 1285 } else if (strcmp(argv[0], "disable") == 0) { 1286 memset(&req, 0, sizeof(req)); 1287 1288 req.features = WDSM_DISABLE_OPS; 1289 req.command = WDCC_SMART; 1290 req.cylinder = WDSMART_CYL; 1291 req.timeout = 1000; 1292 1293 ata_command(&req); 1294 1295 is_smart(); 1296 } else if (strcmp(argv[0], "status") == 0) { 1297 int rv; 1298 1299 rv = is_smart(); 1300 1301 if (!rv) { 1302 fprintf(stderr, "SMART not supported\n"); 1303 return; 1304 } else if (rv == 3) 1305 return; 1306 1307 memset(&inbuf, 0, sizeof(inbuf)); 1308 memset(&req, 0, sizeof(req)); 1309 1310 req.features = WDSM_STATUS; 1311 req.command = WDCC_SMART; 1312 req.cylinder = WDSMART_CYL; 1313 req.timeout = 1000; 1314 1315 ata_command(&req); 1316 1317 if (req.cylinder != WDSMART_CYL) { 1318 fprintf(stderr, "Threshold exceeds condition\n"); 1319 } 1320 1321 /* WDSM_RD_DATA and WDSM_RD_THRESHOLDS are optional 1322 * features, the following ata_command()'s may error 1323 * and exit(). 1324 */ 1325 1326 memset(&inbuf, 0, sizeof(inbuf)); 1327 memset(&req, 0, sizeof(req)); 1328 1329 req.flags = ATACMD_READ; 1330 req.features = WDSM_RD_DATA; 1331 req.command = WDCC_SMART; 1332 req.databuf = (caddr_t) inbuf; 1333 req.datalen = sizeof(inbuf); 1334 req.cylinder = WDSMART_CYL; 1335 req.timeout = 1000; 1336 1337 ata_command(&req); 1338 1339 memset(&inbuf2, 0, sizeof(inbuf2)); 1340 memset(&req, 0, sizeof(req)); 1341 1342 req.flags = ATACMD_READ; 1343 req.features = WDSM_RD_THRESHOLDS; 1344 req.command = WDCC_SMART; 1345 req.databuf = (caddr_t) inbuf2; 1346 req.datalen = sizeof(inbuf2); 1347 req.cylinder = WDSMART_CYL; 1348 req.timeout = 1000; 1349 1350 ata_command(&req); 1351 1352 print_smart_status(inbuf, inbuf2); 1353 1354 } else if (strcmp(argv[0], "offline") == 0) { 1355 if (argc != 2) 1356 usage(); 1357 if (!is_smart()) { 1358 fprintf(stderr, "SMART not supported\n"); 1359 return; 1360 } 1361 1362 memset(&req, 0, sizeof(req)); 1363 1364 req.features = WDSM_EXEC_OFFL_IMM; 1365 req.command = WDCC_SMART; 1366 req.cylinder = WDSMART_CYL; 1367 req.sec_num = atol(argv[1]); 1368 req.timeout = 10000; 1369 1370 ata_command(&req); 1371 } else if (strcmp(argv[0], "error-log") == 0) { 1372 if (!is_smart()) { 1373 fprintf(stderr, "SMART not supported\n"); 1374 return; 1375 } 1376 1377 memset(&inbuf, 0, sizeof(inbuf)); 1378 memset(&req, 0, sizeof(req)); 1379 1380 req.flags = ATACMD_READ; 1381 req.features = WDSM_RD_LOG; 1382 req.sec_count = 1; 1383 req.sec_num = 1; 1384 req.command = WDCC_SMART; 1385 req.databuf = (caddr_t) inbuf; 1386 req.datalen = sizeof(inbuf); 1387 req.cylinder = WDSMART_CYL; 1388 req.timeout = 1000; 1389 1390 ata_command(&req); 1391 1392 print_error(inbuf); 1393 } else if (strcmp(argv[0], "selftest-log") == 0) { 1394 if (!is_smart()) { 1395 fprintf(stderr, "SMART not supported\n"); 1396 return; 1397 } 1398 1399 memset(&inbuf, 0, sizeof(inbuf)); 1400 memset(&req, 0, sizeof(req)); 1401 1402 req.flags = ATACMD_READ; 1403 req.features = WDSM_RD_LOG; 1404 req.sec_count = 1; 1405 req.sec_num = 6; 1406 req.command = WDCC_SMART; 1407 req.databuf = (caddr_t) inbuf; 1408 req.datalen = sizeof(inbuf); 1409 req.cylinder = WDSMART_CYL; 1410 req.timeout = 1000; 1411 1412 ata_command(&req); 1413 1414 print_selftest(inbuf); 1415 1416 } else { 1417 usage(); 1418 } 1419 return; 1420 } 1421 1422 static void 1423 device_security(int argc, char *argv[]) 1424 { 1425 struct atareq req; 1426 const struct ataparams *inqbuf; 1427 unsigned char data[DEV_BSIZE]; 1428 char *pass; 1429 1430 /* need subcommand */ 1431 if (argc < 1) 1432 usage(); 1433 1434 memset(&req, 0, sizeof(req)); 1435 if (strcmp(argv[0], "status") == 0) { 1436 inqbuf = getataparams(); 1437 print_bitinfo("\t", "\n", inqbuf->atap_sec_st, ata_sec_st); 1438 } else if (strcmp(argv[0], "freeze") == 0) { 1439 req.command = WDCC_SECURITY_FREEZE; 1440 req.timeout = 1000; 1441 ata_command(&req); 1442 } else if ((strcmp(argv[0], "setpass") == 0) || 1443 (strcmp(argv[0], "unlock") == 0) || 1444 (strcmp(argv[0], "disable") == 0) || 1445 (strcmp(argv[0], "erase") == 0)) { 1446 if (argc != 2) 1447 usage(); 1448 if (strcmp(argv[1], "user") != 0) { 1449 if (strcmp(argv[1], "master") == 0) { 1450 fprintf(stderr, 1451 "Master passwords not supported\n"); 1452 exit(1); 1453 } else { 1454 usage(); 1455 } 1456 } 1457 1458 pass = getpass("Password:"); 1459 if (strlen(pass) > 32) { 1460 fprintf(stderr, "Password must be <=32 characters\n"); 1461 exit(1); 1462 } 1463 1464 req.flags |= ATACMD_WRITE; 1465 req.timeout = 1000; 1466 req.databuf = data; 1467 req.datalen = sizeof(data); 1468 memset(data, 0, sizeof(data)); 1469 strlcpy((void *)&data[2], pass, 32 + 1); 1470 1471 if (strcmp(argv[0], "setpass") == 0) { 1472 char orig[32 + 1]; 1473 strlcpy(orig, pass, 32 + 1); 1474 pass = getpass("Confirm password:"); 1475 if (0 != strcmp(orig, pass)) { 1476 fprintf(stderr, "Passwords do not match\n"); 1477 exit(1); 1478 } 1479 req.command = WDCC_SECURITY_SET_PASSWORD; 1480 } else if (strcmp(argv[0], "unlock") == 0) { 1481 req.command = WDCC_SECURITY_UNLOCK; 1482 } else if (strcmp(argv[0], "disable") == 0) { 1483 req.command = WDCC_SECURITY_DISABLE_PASSWORD; 1484 } else if (strcmp(argv[0], "erase") == 0) { 1485 struct atareq prepare; 1486 1487 inqbuf = getataparams(); 1488 1489 /* 1490 * XXX Any way to lock the device to make sure 1491 * this really is the command preceding the 1492 * SECURITY ERASE UNIT command? This would 1493 * probably have to be moved into the kernel to 1494 * do that. 1495 */ 1496 memset(&prepare, 0, sizeof(prepare)); 1497 prepare.command = WDCC_SECURITY_ERASE_PREPARE; 1498 prepare.timeout = 1000; 1499 ata_command(&prepare); 1500 1501 req.command = WDCC_SECURITY_ERASE_UNIT; 1502 1503 /* 1504 * Enable enhanced erase if it's supported. 1505 * 1506 * XXX should be a command-line option 1507 */ 1508 if (inqbuf->atap_sec_st & WDC_SEC_ESE_SUPP) { 1509 data[0] |= 0x2; 1510 req.timeout = (inqbuf->atap_eseu_time & 0xff) 1511 * 2 * 60 * 1000; 1512 } else { 1513 req.timeout = (inqbuf->atap_seu_time & 0xff) 1514 * 2 * 60 * 1000; 1515 } 1516 1517 /* 1518 * If the estimated time was 0xff (* 2 * 60 * 1519 * 1000 = 30600000), that means `>508 minutes'. 1520 * Estimate that we can handle 16 MB/sec, a 1521 * rate I just pulled out of my arse. 1522 */ 1523 if (req.timeout == 30600000) { 1524 uint64_t bytes, timeout; 1525 compute_capacity(inqbuf, &bytes, NULL, NULL); 1526 timeout = (bytes / (16 * 1024 * 1024)) * 1000; 1527 if (timeout > (uint64_t)INT_MAX) 1528 req.timeout = INT_MAX; 1529 else 1530 req.timeout = timeout; 1531 } 1532 1533 printf("Erasing may take up to %dh %dm %ds...\n", 1534 (req.timeout / 1000 / 60) / 60, 1535 (req.timeout / 1000 / 60) % 60, 1536 req.timeout % 60); 1537 } else { 1538 abort(); 1539 } 1540 1541 ata_command(&req); 1542 } else { 1543 usage(); 1544 } 1545 } 1546 1547 /* 1548 * bus_reset: 1549 * Reset an ATA bus (will reset all devices on the bus) 1550 */ 1551 static void 1552 bus_reset(int argc, char *argv[]) 1553 { 1554 int error; 1555 1556 /* no args */ 1557 if (argc != 0) 1558 usage(); 1559 1560 error = ioctl(fd, ATABUSIORESET, NULL); 1561 1562 if (error == -1) 1563 err(1, "ATABUSIORESET failed"); 1564 } 1565