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