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