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