xref: /netbsd-src/sbin/atactl/atactl.c (revision 2c1310a89ca1305a139ac63ec5a862c60f13a098)
1 /*	$NetBSD: atactl.c,v 1.85 2020/12/20 10:19:30 jmcneill 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.85 2020/12/20 10:19:30 jmcneill 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 #include <dev/scsipi/scsi_spc.h>
58 #include <sys/scsiio.h>
59 
60 struct ata_smart_error {
61 	struct {
62 		uint8_t device_control;
63 		uint8_t features;
64 		uint8_t sector_count;
65 		uint8_t sector_number;
66 		uint8_t cylinder_low;
67 		uint8_t cylinder_high;
68 		uint8_t device_head;
69 		uint8_t command;
70 		uint8_t timestamp[4];
71 	} command[5];
72 	struct {
73 		uint8_t reserved;
74 		uint8_t error;
75 		uint8_t sector_count;
76 		uint8_t sector_number;
77 		uint8_t cylinder_low;
78 		uint8_t cylinder_high;
79 		uint8_t device_head;
80 		uint8_t status;
81 		uint8_t extended_error[19];
82 		uint8_t state;
83 		uint8_t lifetime[2];
84 	} error_data;
85 } __packed;
86 
87 struct ata_smart_errorlog {
88 	uint8_t			data_structure_revision;
89 	uint8_t			mostrecenterror;
90 	struct ata_smart_error	log_entries[5];
91 	uint16_t		device_error_count;
92 	uint8_t			reserved[57];
93 	uint8_t			checksum;
94 } __packed;
95 
96 #define SCSI_ATA_PASS_THROUGH_16	0x85
97 struct scsi_ata_pass_through_16 {
98 	uint8_t			opcode;
99 	uint8_t			byte2;
100 #define SATL_NODATA	0x06
101 #define SATL_PIO_IN	0x08
102 #define SATL_PIO_OUT	0x0a
103 #define	SATL_EXTEND	0x01
104 	uint8_t			byte3;
105 #define SATL_CKCOND	0x20
106 #define SATL_READ	0x08
107 #define SATL_BLOCKS	0x04
108 #define SATL_LEN(x)	((x) & 0x03)
109 	uint8_t			features[2];
110 	uint8_t			sector_count[2];
111 	uint8_t			lba[6];
112 	uint8_t			device;
113 	uint8_t			ata_cmd;
114 	uint8_t			control;
115 } __packed;
116 
117 #define SCSI_ATA_PASS_THROUGH_12	0xa1
118 struct scsi_ata_pass_through_12 {
119 	uint8_t			opcode;
120 	uint8_t			byte2;
121 	uint8_t			byte3;
122 	uint8_t			features[1];
123 	uint8_t			sector_count[1];
124 	uint8_t			lba[3];
125 	uint8_t			device;
126 	uint8_t			ata_cmd;
127 	uint8_t			reserved;
128 	uint8_t			control;
129 } __packed;
130 
131 struct scsi_ata_return_descriptor {
132 	uint8_t			descr;
133 #define SCSI_ATA_RETURN_DESCRIPTOR	9
134 	uint8_t			additional_length;
135 	uint8_t			extend;
136 	uint8_t			error;
137 	uint8_t			sector_count[2];
138 	uint8_t			lba[6];
139 	uint8_t			device;
140 	uint8_t			status;
141 } __packed;
142 
143 struct command {
144 	const char *cmd_name;
145 	const char *arg_names;
146 	void (*cmd_func)(int, char *[]);
147 };
148 
149 struct bitinfo {
150 	u_int bitmask;
151 	const char *string;
152 };
153 
154 __dead static void	usage(void);
155 static void	ata_command(struct atareq *);
156 static int	satl_command(struct atareq *, int);
157 static const uint8_t *satl_return_desc(const uint8_t *, size_t, uint8_t);
158 static void	print_bitinfo(const char *, const char *, u_int,
159     const struct bitinfo *);
160 static void	print_bitinfo2(const char *, const char *, u_int, u_int,
161     const struct bitinfo *);
162 static void	print_smart_status(void *, void *, const char *);
163 static void	print_error_entry(int, const struct ata_smart_error *);
164 static void	print_selftest_entry(int, const struct ata_smart_selftest *);
165 
166 static void	print_error(const void *);
167 static void	print_selftest(const void *);
168 
169 static void	fillataparams(void);
170 
171 static int	is_smart(void);
172 
173 static int	fd;				/* file descriptor for device */
174 static int	use_satl;			/* tunnel through SATL */
175 static const	char *dvname;			/* device name */
176 static char	dvname_store[MAXPATHLEN];	/* for opendisk(3) */
177 static const	char *cmdname;			/* command user issued */
178 static const	struct ataparams *inqbuf;	/* inquiry buffer */
179 static char	model[sizeof(inqbuf->atap_model)+1];
180 static char	revision[sizeof(inqbuf->atap_revision)+1];
181 static char	serial[sizeof(inqbuf->atap_serial)+1];
182 
183 static void	device_identify(int, char *[]);
184 static void	device_setidle(int, char *[]);
185 static void	device_idle(int, char *[]);
186 static void	device_apm(int, char *[]);
187 static void	device_checkpower(int, char *[]);
188 static void	device_smart(int, char *[]);
189 static void	device_security(int, char *[]);
190 
191 static void	device_smart_temp(const struct ata_smart_attr *, uint64_t);
192 
193 static const struct command device_commands[] = {
194 	{ "identify",	"",			device_identify },
195 	{ "setidle",	"idle-timer",		device_setidle },
196 	{ "apm",	"disable|set #",	device_apm },
197 	{ "setstandby",	"standby-timer",	device_setidle },
198 	{ "idle",	"",			device_idle },
199 	{ "standby",	"",			device_idle },
200 	{ "sleep",	"",			device_idle },
201 	{ "checkpower",	"",			device_checkpower },
202 	{ "smart",
203 		"enable|disable|status [vendor]|offline #|error-log|selftest-log",
204 						device_smart },
205 	{ "security",
206 		"status|freeze|[setpass|unlock|disable|erase] [user|master]",
207 						device_security },
208 	{ NULL,		NULL,			NULL },
209 };
210 
211 static void	bus_reset(int, char *[]);
212 
213 static const struct command bus_commands[] = {
214 	{ "reset",	"",			bus_reset },
215 	{ NULL,		NULL,			NULL },
216 };
217 
218 /*
219  * Tables containing bitmasks used for error reporting and
220  * device identification.
221  */
222 
223 static const struct bitinfo ata_caps[] = {
224 	{ WDC_CAP_DMA, "DMA" },
225 	{ WDC_CAP_LBA, "LBA" },
226 	{ ATA_CAP_STBY, "ATA standby timer values" },
227 	{ WDC_CAP_IORDY, "IORDY operation" },
228 	{ WDC_CAP_IORDY_DSBL, "IORDY disabling" },
229 	{ 0, NULL },
230 };
231 
232 static const struct bitinfo ata_vers[] = {
233 	{ WDC_VER_ATA1,	"ATA-1" },
234 	{ WDC_VER_ATA2,	"ATA-2" },
235 	{ WDC_VER_ATA3,	"ATA-3" },
236 	{ WDC_VER_ATA4,	"ATA-4" },
237 	{ WDC_VER_ATA5,	"ATA-5" },
238 	{ WDC_VER_ATA6,	"ATA-6" },
239 	{ WDC_VER_ATA7,	"ATA-7" },
240 	{ WDC_VER_ATA8, "ATA-8" },
241 	{ 0, NULL },
242 };
243 
244 static const struct bitinfo ata_cmd_set1[] = {
245 	{ WDC_CMD1_NOP, "NOP command" },
246 	{ WDC_CMD1_RB, "READ BUFFER command" },
247 	{ WDC_CMD1_WB, "WRITE BUFFER command" },
248 	{ WDC_CMD1_HPA, "Host Protected Area feature set" },
249 	{ WDC_CMD1_DVRST, "DEVICE RESET command" },
250 	{ WDC_CMD1_SRV, "SERVICE interrupt" },
251 	{ WDC_CMD1_RLSE, "Release interrupt" },
252 	{ WDC_CMD1_AHEAD, "Look-ahead" },
253 	{ WDC_CMD1_CACHE, "Write cache" },
254 	{ WDC_CMD1_PKT, "PACKET command feature set" },
255 	{ WDC_CMD1_PM, "Power Management feature set" },
256 	{ WDC_CMD1_REMOV, "Removable Media feature set" },
257 	{ WDC_CMD1_SEC, "Security Mode feature set" },
258 	{ WDC_CMD1_SMART, "SMART feature set" },
259 	{ 0, NULL },
260 };
261 
262 static const struct bitinfo ata_cmd_set2[] = {
263 	{ ATA_CMD2_FCE, "FLUSH CACHE EXT command" },
264 	{ WDC_CMD2_FC, "FLUSH CACHE command" },
265 	{ WDC_CMD2_DCO, "Device Configuration Overlay feature set" },
266 	{ ATA_CMD2_LBA48, "48-bit Address feature set" },
267 	{ WDC_CMD2_AAM, "Automatic Acoustic Management feature set" },
268 	{ WDC_CMD2_SM, "SET MAX security extension" },
269 	{ WDC_CMD2_SFREQ, "SET FEATURES required to spin-up after power-up" },
270 	{ WDC_CMD2_PUIS, "Power-Up In Standby feature set" },
271 	{ WDC_CMD2_RMSN, "Removable Media Status Notification feature set" },
272 	{ ATA_CMD2_APM, "Advanced Power Management feature set" },
273 	{ ATA_CMD2_CFA, "CFA feature set" },
274 	{ ATA_CMD2_RWQ, "READ/WRITE DMA QUEUED commands" },
275 	{ WDC_CMD2_DM, "DOWNLOAD MICROCODE command" },
276 	{ 0, NULL },
277 };
278 
279 static const struct bitinfo ata_cmd_ext[] = {
280 	{ ATA_CMDE_TLCONT, "Time-limited R/W feature set R/W Continuous mode" },
281 	{ ATA_CMDE_TL, "Time-limited Read/Write" },
282 	{ ATA_CMDE_URGW, "URG bit for WRITE STREAM DMA/PIO" },
283 	{ ATA_CMDE_URGR, "URG bit for READ STREAM DMA/PIO" },
284 	{ ATA_CMDE_WWN, "World Wide Name" },
285 	{ ATA_CMDE_WQFE, "WRITE DMA QUEUED FUA EXT command" },
286 	{ ATA_CMDE_WFE, "WRITE DMA/MULTIPLE FUA EXT commands" },
287 	{ ATA_CMDE_GPL, "General Purpose Logging feature set" },
288 	{ ATA_CMDE_STREAM, "Streaming feature set" },
289 	{ ATA_CMDE_MCPTC, "Media Card Pass Through Command feature set" },
290 	{ ATA_CMDE_MS, "Media serial number" },
291 	{ ATA_CMDE_SST, "SMART self-test" },
292 	{ ATA_CMDE_SEL, "SMART error logging" },
293 	{ 0, NULL },
294 };
295 
296 static const struct bitinfo ata_sata_caps[] = {
297 	{ SATA_SIGNAL_GEN1, "1.5Gb/s signaling" },
298 	{ SATA_SIGNAL_GEN2, "3.0Gb/s signaling" },
299 	{ SATA_SIGNAL_GEN3, "6.0Gb/s signaling" },
300 	{ SATA_NATIVE_CMDQ, "Native Command Queuing" },
301 	{ SATA_HOST_PWR_MGMT, "Host-Initiated Interface Power Management" },
302 	{ SATA_PHY_EVNT_CNT, "PHY Event Counters" },
303 	{ 0, NULL },
304 };
305 
306 static const struct bitinfo ata_sata_feat[] = {
307 	{ SATA_NONZERO_OFFSETS, "Non-zero Offset DMA" },
308 	{ SATA_DMA_SETUP_AUTO, "DMA Setup Auto Activate" },
309 	{ SATA_DRIVE_PWR_MGMT, "Device-Initiated Interface Power Management" },
310 	{ SATA_IN_ORDER_DATA, "In-order Data Delivery" },
311 	{ SATA_SW_STTNGS_PRS, "Software Settings Preservation" },
312 	{ 0, NULL },
313 };
314 
315 /*
316  * Global SMART attribute table.  All known attributes should be defined
317  * here with overrides outside of the standard in a vendor specific table.
318  *
319  * XXX Some of these should be duplicated to vendor-specific tables now that
320  * XXX they exist and have non generic names.
321  */
322 static const struct attr_table {
323 	const unsigned	id;
324 	const char	*name;
325 	void (*special)(const struct ata_smart_attr *, uint64_t);
326 } smart_attrs[] = {
327 	{   1,		"Raw read error rate", NULL },
328 	{   2,		"Throughput performance", NULL },
329 	{   3,		"Spin-up time", NULL },
330 	{   4,		"Start/stop count", NULL },
331 	{   5,		"Reallocated sector count", NULL },
332 	{   6,		"Read channel margin", NULL },
333 	{   7,		"Seek error rate", NULL },
334 	{   8,		"Seek time performance", NULL },
335 	{   9,		"Power-on hours count", NULL },
336 	{  10,		"Spin retry count", NULL },
337 	{  11,		"Calibration retry count", NULL },
338 	{  12,		"Device power cycle count", NULL },
339 	{  13,		"Soft read error rate", NULL },
340 	{ 100,          "Erase/Program Cycles", NULL },
341 	{ 103,          "Translation Table Rebuild", NULL },
342 	{ 170,          "Reserved Block Count", NULL },
343 	{ 171,          "Program Fail Count", NULL },
344 	{ 172,          "Erase Fail Count", NULL },
345 	{ 173,          "Wear Leveller Worst Case Erase Count", NULL },
346 	{ 174,          "Unexpected Power Loss Count", NULL },
347 	{ 175,          "Program Fail Count", NULL },
348 	{ 176,          "Erase Fail Count", NULL },
349 	{ 177,          "Wear Leveling Count", NULL },
350 	{ 178,          "Used Reserved Block Count", NULL },
351 	{ 179,          "Used Reserved Block Count", NULL },
352 	{ 180,          "Unused Reserved Block Count", NULL },
353 	{ 181,          "Program Fail Count", NULL },
354 	{ 182,          "Erase Fail Count", NULL },
355 	{ 183,          "Runtime Bad Block", NULL },
356 	{ 184,          "End-to-end error", NULL },
357 	{ 185,          "Head Stability", NULL },
358 	{ 186,          "Induced Op-Vibration Detection", NULL },
359 	{ 187,          "Reported Uncorrectable Errors", NULL },
360 	{ 188,          "Command Timeout", NULL },
361 	{ 189,          "High Fly Writes", NULL },
362 	{ 190,          "Airflow Temperature",		device_smart_temp },
363 	{ 191,		"G-sense error rate", NULL },
364 	{ 192,		"Power-off retract count", NULL },
365 	{ 193,		"Load cycle count", NULL },
366 	{ 194,		"Temperature",			device_smart_temp},
367 	{ 195,		"Hardware ECC Recovered", NULL },
368 	{ 196,		"Reallocated event count", NULL },
369 	{ 197,		"Current pending sector", NULL },
370 	{ 198,		"Offline uncorrectable", NULL },
371 	{ 199,		"Ultra DMA CRC error count", NULL },
372 	{ 200,		"Write error rate", NULL },
373 	{ 201,		"Soft read error rate", NULL },
374 	{ 202,		"Data address mark errors", NULL },
375 	{ 203,		"Run out cancel", NULL },
376 	{ 204,		"Soft ECC correction", NULL },
377 	{ 205,		"Thermal asperity check", NULL },
378 	{ 206,		"Flying height", NULL },
379 	{ 207,		"Spin high current", NULL },
380 	{ 208,		"Spin buzz", NULL },
381 	{ 209,		"Offline seek performance", NULL },
382 	{ 210,		"Successful RAIN Recovery Count", NULL },
383 	{ 220,		"Disk shift", NULL },
384 	{ 221,		"G-Sense error rate", NULL },
385 	{ 222,		"Loaded hours", NULL },
386 	{ 223,		"Load/unload retry count", NULL },
387 	{ 224,		"Load friction", NULL },
388 	{ 225,		"Load/unload cycle count", NULL },
389 	{ 226,		"Load-in time", NULL },
390 	{ 227,		"Torque amplification count", NULL },
391 	{ 228,		"Power-off retract count", NULL },
392 	{ 230,		"GMR head amplitude", NULL },
393 	{ 231,		"Temperature",			device_smart_temp },
394 	{ 232,		"Available reserved space", NULL },
395 	{ 233,		"Media wearout indicator", NULL },
396 	{ 240,		"Head flying hours", NULL },
397 	{ 241,		"Total LBAs Written", NULL },
398 	{ 242,		"Total LBAs Read", NULL },
399 	{ 246,		"Total Host Sector Writes", NULL },
400 	{ 247,		"Host Program NAND Pages Count", NULL },
401 	{ 248,		"FTL Program Pages Count", NULL },
402 	{ 249,		"Total Raw NAND Writes (1GiB units)", NULL },
403 	{ 250,		"Read error retry rate", NULL },
404 	{ 254,		"Free Fall Sensor", NULL },
405 	{   0,		"Unknown", NULL },
406 };
407 
408 /*
409  * Micron specific SMART attributes published by Micron in:
410  * "TN-FD-22: Client SATA SSD SMART Attribute Reference"
411  */
412 static const struct attr_table micron_smart_names[] = {
413 	{   5,		"Reallocated NAND block count", NULL },
414 	{ 173,          "Average block erase count", NULL },
415 	{ 181,          "Non 4K aligned access count", NULL },
416 	{ 183,          "SATA Downshift Error Count", NULL },
417 	{ 184,          "Error correction count", NULL },
418 	{ 189,          "Factory bad block count", NULL },
419 	{ 197,		"Current pending ECC count", NULL },
420 	{ 198,		"SMART offline scan uncorrectable error count", NULL },
421 	{ 202,		"Percent lifetime used", NULL },
422 	{ 206,		"Write error rate", NULL },
423 	{ 247,		"Number of NAND pages of data written by the host", NULL },
424 	{ 248,		"Number of NAND pages written by the FTL", NULL },
425 	{   0,		"Unknown", NULL },
426 };
427 
428 /*
429  * Intel specific SMART attributes.  Fill me in with more.
430  */
431 static const struct attr_table intel_smart_names[] = {
432 	{ 183,          "SATA Downshift Error Count", NULL },
433 };
434 
435 /*
436  * Samsung specific SMART attributes.  Fill me in with more.
437  */
438 static const struct attr_table samsung_smart_names[] = {
439 	{ 235,          "POR Recovery Count", NULL },
440 	{ 243,          "SATA Downshift Count", NULL },
441 	{ 244,          "Thermal Throttle Status", NULL },
442 	{ 245,          "Timed Workload Media Wear", NULL },
443 	{ 251,          "NAND Writes", NULL },
444 };
445 
446 
447 /*
448  * Vendor-specific SMART attribute table.  Can be used to override
449  * a particular attribute name and special printer function, with the
450  * default is the main table.
451  */
452 static const struct vendor_name_table {
453 	const char *name;
454 	const struct attr_table *table;
455 } vendor_smart_names[] = {
456 	{ "Micron",		micron_smart_names },
457 	{ "Intel",		intel_smart_names },
458 	{ "Samsung",		samsung_smart_names },
459 };
460 
461 /*
462  * Global model -> vendor table.  Extend this to regexp.
463  */
464 static const struct model_to_vendor_table {
465 	const char *model;
466 	const char *vendor;
467 } model_to_vendor[] = {
468 	{ "Crucial",		"Micron" },
469 	{ "Micron",		"Micron" },
470 	{ "C300-CT",		"Micron" },
471 	{ "C400-MT",		"Micron" },
472 	{ "M4-CT",		"Micron" },
473 	{ "M500",		"Micron" },
474 	{ "M510",		"Micron" },
475 	{ "M550",		"Micron" },
476 	{ "MTFDDA",		"Micron" },
477 	{ "EEFDDA",		"Micron" },
478 	{ "INTEL",		"Intel" },
479 	{ "SAMSUNG",		"Samsung" },
480 };
481 
482 static const struct bitinfo ata_sec_st[] = {
483 	{ WDC_SEC_SUPP,		"supported" },
484 	{ WDC_SEC_EN,		"enabled" },
485 	{ WDC_SEC_LOCKED,	"locked" },
486 	{ WDC_SEC_FROZEN,	"frozen" },
487 	{ WDC_SEC_EXP,		"expired" },
488 	{ WDC_SEC_ESE_SUPP,	"enhanced erase support" },
489 	{ WDC_SEC_LEV_MAX,	"maximum level" },
490 	{ 0,			NULL },
491 };
492 
493 int
main(int argc,char * argv[])494 main(int argc, char *argv[])
495 {
496 	int i;
497 	const struct command *commands = NULL;
498 
499 	/* Must have at least: device command */
500 	if (argc < 3)
501 		usage();
502 
503 	/* Skip program name, get and skip device name and command. */
504 	dvname = argv[1];
505 	cmdname = argv[2];
506 	argv += 3;
507 	argc -= 3;
508 
509 	/*
510 	 * Open the device
511 	 */
512 	fd = opendisk(dvname, O_RDWR, dvname_store, sizeof(dvname_store), 0);
513 	if (fd == -1) {
514 		if (errno == ENOENT) {
515 			/*
516 			 * Device doesn't exist.  Probably trying to open
517 			 * a device which doesn't use disk semantics for
518 			 * device name.  Try again, specifying "cooked",
519 			 * which leaves off the "r" in front of the device's
520 			 * name.
521 			 */
522 			fd = opendisk(dvname, O_RDWR, dvname_store,
523 			    sizeof(dvname_store), 1);
524 			if (fd == -1)
525 				err(1, "%s", dvname);
526 		} else
527 			err(1, "%s", dvname);
528 	}
529 
530 	/*
531 	 * Point the dvname at the actual device name that opendisk() opened.
532 	 */
533 	dvname = dvname_store;
534 
535 	/* Look up and call the command. */
536 	for (i = 0; device_commands[i].cmd_name != NULL; i++) {
537 		if (strcmp(cmdname, device_commands[i].cmd_name) == 0) {
538 			commands = &device_commands[i];
539 			break;
540 		}
541 	}
542 	if (commands == NULL) {
543 		for (i = 0; bus_commands[i].cmd_name != NULL; i++) {
544 			if (strcmp(cmdname, bus_commands[i].cmd_name) == 0) {
545 				commands = &bus_commands[i];
546 				break;
547 			}
548 		}
549 	}
550 	if (commands == NULL)
551 		errx(1, "unknown command: %s", cmdname);
552 
553 	(*commands->cmd_func)(argc, argv);
554 	exit(0);
555 }
556 
557 static void
usage(void)558 usage(void)
559 {
560 	int i;
561 
562 	fprintf(stderr, "usage: %s device command [arg [...]]\n",
563 	    getprogname());
564 
565 	fprintf(stderr, "   Available device commands:\n");
566 	for (i=0; device_commands[i].cmd_name != NULL; i++)
567 		fprintf(stderr, "\t%s %s\n", device_commands[i].cmd_name,
568 					    device_commands[i].arg_names);
569 
570 	fprintf(stderr, "   Available bus commands:\n");
571 	for (i=0; bus_commands[i].cmd_name != NULL; i++)
572 		fprintf(stderr, "\t%s %s\n", bus_commands[i].cmd_name,
573 					    bus_commands[i].arg_names);
574 
575 	exit(1);
576 }
577 
578 /*
579  * Wrapper that calls ATAIOCCOMMAND and checks for errors
580  */
581 
582 static void
ata_command(struct atareq * req)583 ata_command(struct atareq *req)
584 {
585 	int error;
586 
587 	switch (use_satl) {
588 	case 0:
589 		error = ioctl(fd, ATAIOCCOMMAND, req);
590 		if (error == 0)
591 			break;
592 		if (errno != ENOTTY)
593 			err(1, "ATAIOCCOMMAND failed");
594 		use_satl = 1;
595 		/* FALLTHROUGH */
596 	case 1:
597 		error = satl_command(req, 16);
598 		if (error == 0)
599 			return;
600 		use_satl = 2;
601 		/* FALLTHROUGH */
602 	case 2:
603 		(void) satl_command(req, 12);
604 		return;
605 	}
606 
607 	switch (req->retsts) {
608 
609 	case ATACMD_OK:
610 		return;
611 	case ATACMD_TIMEOUT:
612 		fprintf(stderr, "ATA command timed out\n");
613 		exit(1);
614 	case ATACMD_DF:
615 		fprintf(stderr, "ATA device returned a Device Fault\n");
616 		exit(1);
617 	case ATACMD_ERROR:
618 		if (req->error & WDCE_ABRT)
619 			fprintf(stderr, "ATA device returned Aborted "
620 				"Command\n");
621 		else
622 			fprintf(stderr, "ATA device returned error register "
623 				"%0x\n", req->error);
624 		exit(1);
625 	default:
626 		fprintf(stderr, "ATAIOCCOMMAND returned unknown result code "
627 			"%d\n", req->retsts);
628 		exit(1);
629 	}
630 }
631 
632 /*
633  * Wrapper that calls SCIOCCOMMAND for a tunneled ATA command
634  */
635 static int
satl_command(struct atareq * req,int cmdlen)636 satl_command(struct atareq *req, int cmdlen)
637 {
638 	scsireq_t sreq;
639 	int error;
640 	union {
641 		struct scsi_ata_pass_through_12 cmd12;
642 		struct scsi_ata_pass_through_16 cmd16;
643 	} c;
644 	uint8_t b2, b3;
645 	const uint8_t *desc;
646 
647 	b2 = SATL_NODATA;
648 	if (req->datalen > 0) {
649 		if (req->flags & ATACMD_READ)
650 			b2 = SATL_PIO_IN;
651 		else
652 			b2 = SATL_PIO_OUT;
653 	}
654 
655 	b3 = SATL_BLOCKS;
656 	if (req->datalen > 0) {
657 		b3 |= 2; /* sector count holds count */
658 	} else {
659 		b3 |= SATL_CKCOND;
660 	}
661 	if (req->datalen == 0 || req->flags & ATACMD_READ)
662 		b3 |= SATL_READ;
663 
664 	switch (cmdlen) {
665 	case 16:
666 		c.cmd16.opcode = SCSI_ATA_PASS_THROUGH_16;
667 		c.cmd16.byte2 = b2;
668 		c.cmd16.byte3 = b3;
669 		c.cmd16.features[0] = 0;
670 		c.cmd16.features[1] = req->features;
671 		c.cmd16.sector_count[0] = 0;
672 		c.cmd16.sector_count[1] = req->sec_count;
673 		c.cmd16.lba[0] = 0;
674 		c.cmd16.lba[1] = req->sec_num;
675 		c.cmd16.lba[2] = 0;
676 		c.cmd16.lba[3] = req->cylinder;
677 		c.cmd16.lba[4] = 0;
678 		c.cmd16.lba[5] = req->cylinder >> 8;
679 		c.cmd16.device = 0;
680 		c.cmd16.ata_cmd = req->command;
681 		c.cmd16.control = 0;
682 		break;
683 	case 12:
684 		c.cmd12.opcode = SCSI_ATA_PASS_THROUGH_12;
685 		c.cmd12.byte2 = b2;
686 		c.cmd12.byte3 = b3;
687 		c.cmd12.features[0] = req->features;
688 		c.cmd12.sector_count[0] = req->sec_count;
689 		c.cmd12.lba[0] = req->sec_num;
690 		c.cmd12.lba[1] = req->cylinder;
691 		c.cmd12.lba[2] = req->cylinder >> 8;
692 		c.cmd12.device = 0;
693 		c.cmd12.reserved = 0;
694 		c.cmd12.ata_cmd = req->command;
695 		c.cmd12.control = 0;
696 		break;
697 	default:
698 		fprintf(stderr, "ATA command with bad length\n");
699 		exit(1);
700 	}
701 
702 	memset(&sreq, 0, sizeof(sreq));
703 	memcpy(sreq.cmd, &c, cmdlen);
704 	sreq.cmdlen = cmdlen;
705 	sreq.databuf = req->databuf;
706 	sreq.datalen = req->datalen;
707 	sreq.senselen = sizeof(sreq.sense);
708 	sreq.timeout = req->timeout;
709 
710 	if (sreq.datalen > 0) {
711 		if (req->flags & ATACMD_READ)
712 			sreq.flags |= SCCMD_READ;
713 		if (req->flags & ATACMD_WRITE)
714 			sreq.flags |= SCCMD_WRITE;
715 	}
716 
717 	error = ioctl(fd, SCIOCCOMMAND, &sreq);
718 	if (error == -1)
719 		err(1, "SCIOCCOMMAND failed");
720 
721 	req->datalen = sreq.datalen_used;
722 	req->retsts = ATACMD_OK;
723 	req->error = 0;
724 
725 	switch (sreq.retsts) {
726 	case SCCMD_OK:
727 		return 0;
728 	case SCCMD_TIMEOUT:
729 		fprintf(stderr, "SATL command timed out\n");
730 		exit(1);
731 	case SCCMD_BUSY:
732 		fprintf(stderr, "SATL command returned busy\n");
733 		exit(1);
734 	case SCCMD_SENSE:
735 		desc = NULL;
736 		switch (SSD_RCODE(sreq.sense[0])) {
737 		case 0x00:
738 			return 0;
739 		case 0x70:
740 			if (sreq.sense[2] == SKEY_NO_SENSE)
741 				return 0;
742 			if (sreq.sense[2] == SKEY_ILLEGAL_REQUEST)
743 				return 1;
744 			break;
745 		case 0x72:
746 		case 0x73:
747 			desc = satl_return_desc(sreq.sense, sreq.senselen_used,
748 				SCSI_ATA_RETURN_DESCRIPTOR);
749 			break;
750 		default:
751 			break;
752 		}
753 
754 		if (desc && desc[1] >= 12) {
755 			req->sec_count = desc[5];
756 			req->sec_num = desc[7];
757 			req->head = (desc[12] & 0xf0) |
758 			            ((desc[7] >> 24) & 0x0f);
759 			req->cylinder = desc[11] << 8 | desc[9];
760 			req->retsts = desc[13];
761 			req->error = desc[3];
762 			return 0;
763 		}
764 
765 		fprintf(stderr, "SATL command error: rcode %02x key %u\n",
766 			SSD_RCODE(sreq.sense[0]),
767 			SSD_SENSE_KEY(sreq.sense[2]));
768 		if (desc) {
769 			int i, n;
770 			n = desc[1]+2;
771 			printf("ATA Return Descriptor:");
772 			for (i=0; i<n; ++i)
773 				printf(" %02x",desc[i]);
774 			printf("\n");
775 		}
776 		exit(1);
777 	default:
778 		fprintf(stderr, "SCSIIOCCOMMAND returned unknown result code "
779 			"%d\n", sreq.retsts);
780 		exit(1);
781 	}
782 }
783 
784 static const uint8_t *
satl_return_desc(const uint8_t * sense,size_t len,uint8_t type)785 satl_return_desc(const uint8_t *sense, size_t len, uint8_t type)
786 {
787 	const uint8_t *p, *endp;
788 	size_t l, extra;
789 
790 	if (len < 8)
791 		return NULL;
792 	extra = sense[7];
793 	len -= 8;
794 	if (extra < len)
795 		len = extra;
796 	if (len < 2)
797 		return NULL;
798 
799 	switch (sense[0]) {
800 	case 0x72:
801 	case 0x73:
802 		p = &sense[8];
803 		endp = &p[len-1];
804 		while (p < endp) {
805 			if (p[0] == type)
806 				return p;
807 			l = p[1];
808 			p += l + 2;
809 		}
810 		break;
811 	}
812 
813 	return NULL;
814 }
815 
816 
817 /*
818  * Print out strings associated with particular bitmasks
819  */
820 
821 static void
print_bitinfo(const char * bf,const char * af,u_int bits,const struct bitinfo * binfo)822 print_bitinfo(const char *bf, const char *af, u_int bits,
823     const struct bitinfo *binfo)
824 {
825 
826 	for (; binfo->bitmask != 0; binfo++)
827 		if (bits & binfo->bitmask)
828 			printf("%s%s%s", bf, binfo->string, af);
829 }
830 
831 static void
print_bitinfo2(const char * bf,const char * af,u_int bits,u_int enables,const struct bitinfo * binfo)832 print_bitinfo2(const char *bf, const char *af, u_int bits, u_int enables,
833     const struct bitinfo *binfo)
834 {
835 
836 	for (; binfo->bitmask != 0; binfo++)
837 		if (bits & binfo->bitmask)
838 			printf("%s%s (%s)%s", bf, binfo->string,
839 			    (enables & binfo->bitmask) ? "enabled" : "disabled",
840 			    af);
841 }
842 
843 
844 /*
845  * Try to print SMART temperature field
846  */
847 
848 static void
device_smart_temp(const struct ata_smart_attr * attr,uint64_t raw_value)849 device_smart_temp(const struct ata_smart_attr *attr, uint64_t raw_value)
850 {
851 	printf("%" PRIu8, attr->raw[0]);
852 	if (attr->raw[0] != raw_value)
853 		printf(" Lifetime min/max %" PRIu8 "/%" PRIu8,
854 		    attr->raw[2], attr->raw[4]);
855 }
856 
857 /*
858  * Print out SMART attribute thresholds and values
859  */
860 
861 static void
print_smart_status(void * vbuf,void * tbuf,const char * vendor)862 print_smart_status(void *vbuf, void *tbuf, const char *vendor)
863 {
864 	const struct ata_smart_attributes *value_buf = vbuf;
865 	const struct ata_smart_thresholds *threshold_buf = tbuf;
866 	const struct ata_smart_attr *attr;
867 	uint64_t raw_value;
868 	int flags;
869 	unsigned i, j;
870 	unsigned aid, vid;
871 	uint8_t checksum;
872 	const struct attr_table *vendor_table = NULL;
873 	void (*special)(const struct ata_smart_attr *, uint64_t);
874 
875 	if (vendor) {
876 		for (i = 0; i < __arraycount(vendor_smart_names); i++) {
877 			if (strcasecmp(vendor,
878 			    vendor_smart_names[i].name) == 0) {
879 				vendor_table = vendor_smart_names[i].table;
880 				break;
881 			}
882 		}
883 		if (vendor_table == NULL)
884 			fprintf(stderr,
885 			    "SMART vendor '%s' has no special table\n", vendor);
886 	}
887 
888 	for (i = checksum = 0; i < 512; i++)
889 		checksum += ((const uint8_t *) value_buf)[i];
890 	if (checksum != 0) {
891 		fprintf(stderr, "SMART attribute values checksum error\n");
892 		return;
893 	}
894 
895 	for (i = checksum = 0; i < 512; i++)
896 		checksum += ((const uint8_t *) threshold_buf)[i];
897 	if (checksum != 0) {
898 		fprintf(stderr, "SMART attribute thresholds checksum error\n");
899 		return;
900 	}
901 
902 	printf("id value thresh crit collect reliability description"
903 	    "                 raw\n");
904 	for (i = 0; i < 256; i++) {
905 		int thresh = 0;
906 		const char *name = NULL;
907 
908 		attr = NULL;
909 
910 		for (j = 0; j < 30; j++) {
911 			if (value_buf->attributes[j].id == i)
912 				attr = &value_buf->attributes[j];
913 			if (threshold_buf->thresholds[j].id == i)
914 				thresh = threshold_buf->thresholds[j].value;
915 		}
916 
917 		if (thresh && attr == NULL)
918 			errx(1, "threshold but not attr %d", i);
919 		if (attr == NULL)
920 			continue;
921 
922 		if (attr->value == 0||attr->value == 0xFE||attr->value == 0xFF)
923 			continue;
924 
925 		for (aid = 0;
926 		     smart_attrs[aid].id != i && smart_attrs[aid].id != 0;
927 		     aid++)
928 			;
929 
930 		if (vendor_table) {
931 			for (vid = 0;
932 			     vendor_table[vid].id != i && vendor_table[vid].id != 0;
933 			     vid++)
934 				;
935 			if (vendor_table[vid].id != 0) {
936 				name = vendor_table[vid].name;
937 				special = vendor_table[vid].special;
938 			}
939 		}
940 		if (name == NULL) {
941 			name = smart_attrs[aid].name;
942 			special = smart_attrs[aid].special;
943 		}
944 
945 		flags = le16toh(attr->flags);
946 
947 		printf("%3d %3d  %3d     %-3s %-7s %stive    %-27s ",
948 		    i, attr->value, thresh,
949 		    flags & WDSM_ATTR_ADVISORY ? "yes" : "no",
950 		    flags & WDSM_ATTR_COLLECTIVE ? "online" : "offline",
951 		    attr->value > thresh ? "posi" : "nega", name);
952 
953 		for (j = 0, raw_value = 0; j < 6; j++)
954 			raw_value += ((uint64_t)attr->raw[j]) << (8*j);
955 
956 		if (special)
957 			(*special)(attr, raw_value);
958 		else
959 			printf("%" PRIu64, raw_value);
960 		printf("\n");
961 	}
962 }
963 
964 static const struct {
965 	int number;
966 	const char *name;
967 } selftest_name[] = {
968 	{ 0, "Off-line" },
969 	{ 1, "Short off-line" },
970 	{ 2, "Extended off-line" },
971 	{ 127, "Abort off-line test" },
972 	{ 129, "Short captive" },
973 	{ 130, "Extended captive" },
974 	{ 256, "Unknown test" }, /* larger than uint8_t */
975 	{ 0, NULL }
976 };
977 
978 static const char *selftest_status[] = {
979 	"No error",
980 	"Aborted by the host",
981 	"Interrupted by the host by reset",
982 	"Fatal error or unknown test error",
983 	"Unknown test element failed",
984 	"Electrical test element failed",
985 	"The Servo (and/or seek) test element failed",
986 	"Read element of test failed",
987 	"Reserved",
988 	"Reserved",
989 	"Reserved",
990 	"Reserved",
991 	"Reserved",
992 	"Reserved",
993 	"Reserved",
994 	"Self-test in progress"
995 };
996 
997 static void
print_error_entry(int num,const struct ata_smart_error * le)998 print_error_entry(int num, const struct ata_smart_error *le)
999 {
1000 	int i;
1001 
1002 	printf("Log entry: %d\n", num);
1003 
1004 	for (i = 0; i < 5; i++)
1005 		printf("\tCommand %d: dc=%02x sf=%02x sc=%02x sn=%02x cl=%02x "
1006 		    "ch=%02x dh=%02x cmd=%02x time=%02x%02x%02x%02x\n", i,
1007 		    le->command[i].device_control,
1008 		    le->command[i].features,
1009 		    le->command[i].sector_count,
1010 		    le->command[i].sector_number,
1011 		    le->command[i].cylinder_low,
1012 		    le->command[i].cylinder_high,
1013 		    le->command[i].device_head,
1014 		    le->command[i].command,
1015 		    le->command[i].timestamp[3],
1016 		    le->command[i].timestamp[2],
1017 		    le->command[i].timestamp[1],
1018 		    le->command[i].timestamp[0]);
1019 	printf("\tError: err=%02x sc=%02x sn=%02x cl=%02x ch=%02x dh=%02x "
1020 	    "status=%02x state=%02x lifetime=%02x%02x\n",
1021 	    le->error_data.error,
1022 	    le->error_data.sector_count,
1023 	    le->error_data.sector_number,
1024 	    le->error_data.cylinder_low,
1025 	    le->error_data.cylinder_high,
1026 	    le->error_data.device_head,
1027 	    le->error_data.status,
1028 	    le->error_data.state,
1029 	    le->error_data.lifetime[1],
1030 	    le->error_data.lifetime[0]);
1031 	printf("\tExtended: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x "
1032 	    "%02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
1033 	    le->error_data.extended_error[0],
1034 	    le->error_data.extended_error[1],
1035 	    le->error_data.extended_error[2],
1036 	    le->error_data.extended_error[3],
1037 	    le->error_data.extended_error[4],
1038 	    le->error_data.extended_error[5],
1039 	    le->error_data.extended_error[6],
1040 	    le->error_data.extended_error[7],
1041 	    le->error_data.extended_error[8],
1042 	    le->error_data.extended_error[9],
1043 	    le->error_data.extended_error[10],
1044 	    le->error_data.extended_error[11],
1045 	    le->error_data.extended_error[12],
1046 	    le->error_data.extended_error[13],
1047 	    le->error_data.extended_error[14],
1048 	    le->error_data.extended_error[15],
1049 	    le->error_data.extended_error[15],
1050 	    le->error_data.extended_error[17],
1051 	    le->error_data.extended_error[18]);
1052 }
1053 
1054 static void
print_error(const void * buf)1055 print_error(const void *buf)
1056 {
1057 	const struct ata_smart_errorlog *erlog = buf;
1058 	uint8_t checksum;
1059 	int i;
1060 
1061 	for (i = checksum = 0; i < 512; i++)
1062 		checksum += ((const uint8_t *) buf)[i];
1063 	if (checksum != 0) {
1064 		fprintf(stderr, "SMART error log checksum error\n");
1065 		return;
1066 	}
1067 
1068 	if (erlog->data_structure_revision != 1) {
1069 		fprintf(stderr, "Error log revision not 1 (found 0x%04x)\n",
1070 		    erlog->data_structure_revision);
1071 		return;
1072 	}
1073 
1074 	if (erlog->mostrecenterror == 0) {
1075 		printf("No errors have been logged\n");
1076 		return;
1077 	}
1078 
1079 	if (erlog->mostrecenterror > 5) {
1080 		fprintf(stderr, "Most recent error is too large\n");
1081 		return;
1082 	}
1083 
1084 	for (i = erlog->mostrecenterror; i < 5; i++)
1085 		print_error_entry(i, &erlog->log_entries[i]);
1086 	for (i = 0; i < erlog->mostrecenterror; i++)
1087 		print_error_entry(i, &erlog->log_entries[i]);
1088 	printf("device error count: %d\n", erlog->device_error_count);
1089 }
1090 
1091 static void
print_selftest_entry(int num,const struct ata_smart_selftest * le)1092 print_selftest_entry(int num, const struct ata_smart_selftest *le)
1093 {
1094 	const unsigned char *p;
1095 	size_t i;
1096 
1097 	/* check if all zero */
1098 	for (p = (const void *)le, i = 0; i < sizeof(*le); i++)
1099 		if (p[i] != 0)
1100 			break;
1101 	if (i == sizeof(*le))
1102 		return;
1103 
1104 	printf("Log entry: %d\n", num);
1105 
1106 	/* Get test name */
1107 	for (i = 0; selftest_name[i].name != NULL; i++)
1108 		if (selftest_name[i].number == le->number)
1109 			break;
1110 
1111 	if (selftest_name[i].name == NULL)
1112 		printf("\tName: (%d)\n", le->number);
1113 	else
1114 		printf("\tName: %s\n", selftest_name[i].name);
1115 	printf("\tStatus: %s\n", selftest_status[le->status >> 4]);
1116 	/* XXX This generally should not be set when a self-test is completed,
1117 	   and at any rate is useless.  - mycroft */
1118 	if (le->status >> 4 == 15)
1119 		printf("\tPercent of test remaining: %1d0\n", le->status & 0xf);
1120 	else if (le->status >> 4 != 0)
1121 		printf("\tLBA first error: %d\n", le32toh(le->lba_first_error));
1122 }
1123 
1124 static void
print_selftest(const void * buf)1125 print_selftest(const void *buf)
1126 {
1127 	const struct ata_smart_selftestlog *stlog = buf;
1128 	uint8_t checksum;
1129 	int i;
1130 
1131 	for (i = checksum = 0; i < 512; i++)
1132 		checksum += ((const uint8_t *) buf)[i];
1133 	if (checksum != 0) {
1134 		fprintf(stderr, "SMART selftest log checksum error\n");
1135 		return;
1136 	}
1137 
1138 	if (le16toh(stlog->data_structure_revision) != 1) {
1139 		fprintf(stderr, "Self-test log revision not 1 (found 0x%04x)\n",
1140 		    le16toh(stlog->data_structure_revision));
1141 		return;
1142 	}
1143 
1144 	if (stlog->mostrecenttest == 0) {
1145 		printf("No self-tests have been logged\n");
1146 		return;
1147 	}
1148 
1149 	if (stlog->mostrecenttest > 22) {
1150 		fprintf(stderr, "Most recent test is too large\n");
1151 		return;
1152 	}
1153 
1154 	for (i = stlog->mostrecenttest; i < 22; i++)
1155 		print_selftest_entry(i, &stlog->log_entries[i]);
1156 	for (i = 0; i < stlog->mostrecenttest; i++)
1157 		print_selftest_entry(i, &stlog->log_entries[i]);
1158 }
1159 
1160 static void
fillataparams(void)1161 fillataparams(void)
1162 {
1163 	struct atareq req;
1164 	static union {
1165 		unsigned char inbuf[DEV_BSIZE];
1166 		struct ataparams inqbuf;
1167 	} inbuf;
1168 	static int first = 1;
1169 
1170 	if (!first)
1171 		return;
1172 	first = 0;
1173 
1174 	memset(&inbuf, 0, sizeof(inbuf));
1175 	memset(&req, 0, sizeof(req));
1176 
1177 	req.flags = ATACMD_READ;
1178 	req.command = WDCC_IDENTIFY;
1179 	req.databuf = &inbuf;
1180 	req.datalen = sizeof(inbuf);
1181 	req.timeout = 1000;
1182 
1183 	ata_command(&req);
1184 
1185 	inqbuf = &inbuf.inqbuf;
1186 }
1187 
1188 /*
1189  * is_smart:
1190  *
1191  *	Detect whether device supports SMART and SMART is enabled.
1192  */
1193 
1194 static int
is_smart(void)1195 is_smart(void)
1196 {
1197 	int retval = 0;
1198 	const char *status;
1199 
1200 	fillataparams();
1201 
1202 	if (inqbuf->atap_cmd_def != 0 && inqbuf->atap_cmd_def != 0xffff) {
1203 		if (!(inqbuf->atap_cmd_set1 & WDC_CMD1_SMART)) {
1204 			fprintf(stderr, "SMART unsupported\n");
1205 		} else {
1206 			if (inqbuf->atap_ata_major <= WDC_VER_ATA5 ||
1207 			    inqbuf->atap_cmd_set2 == 0xffff ||
1208 			    inqbuf->atap_cmd_set2 == 0x0000) {
1209 				status = "status unknown";
1210 				retval = 2;
1211 			} else {
1212 				if (inqbuf->atap_cmd1_en & WDC_CMD1_SMART) {
1213 					status = "enabled";
1214 					retval = 1;
1215 				} else {
1216 					status = "disabled";
1217 					retval = 3;
1218 				}
1219 			}
1220 			printf("SMART supported, SMART %s\n", status);
1221 		}
1222 	}
1223 	return retval;
1224 }
1225 
1226 /*
1227  * extract_string: copy a block of bytes out of ataparams and make
1228  * a proper string out of it, truncating trailing spaces and preserving
1229  * strict typing. And also, not doing unaligned accesses.
1230  */
1231 static void
extract_string(char * buf,size_t bufmax,const uint8_t * bytes,size_t numbytes,int needswap)1232 extract_string(char *buf, size_t bufmax,
1233 	       const uint8_t *bytes, size_t numbytes,
1234 	       int needswap)
1235 {
1236 	unsigned i;
1237 	size_t j;
1238 	unsigned char ch1, ch2;
1239 
1240 	for (i = 0, j = 0; i < numbytes; i += 2) {
1241 		ch1 = bytes[i];
1242 		ch2 = bytes[i+1];
1243 		if (needswap && j < bufmax-1) {
1244 			buf[j++] = ch2;
1245 		}
1246 		if (j < bufmax-1) {
1247 			buf[j++] = ch1;
1248 		}
1249 		if (!needswap && j < bufmax-1) {
1250 			buf[j++] = ch2;
1251 		}
1252 	}
1253 	while (j > 0 && buf[j-1] == ' ') {
1254 		j--;
1255 	}
1256 	buf[j] = '\0';
1257 }
1258 
1259 static void
compute_capacity(uint64_t * capacityp,uint64_t * sectorsp,uint32_t * secsizep)1260 compute_capacity(uint64_t *capacityp, uint64_t *sectorsp, uint32_t *secsizep)
1261 {
1262 	uint64_t capacity;
1263 	uint64_t sectors;
1264 	uint32_t secsize;
1265 
1266 	if (inqbuf->atap_cmd2_en != 0 && inqbuf->atap_cmd2_en != 0xffff &&
1267 	    inqbuf->atap_cmd2_en & ATA_CMD2_LBA48) {
1268 		sectors =
1269 		    ((uint64_t)inqbuf->atap_max_lba[3] << 48) |
1270 		    ((uint64_t)inqbuf->atap_max_lba[2] << 32) |
1271 		    ((uint64_t)inqbuf->atap_max_lba[1] << 16) |
1272 		    ((uint64_t)inqbuf->atap_max_lba[0] <<  0);
1273 	} else if (inqbuf->atap_capabilities1 & WDC_CAP_LBA) {
1274 		sectors = (inqbuf->atap_capacity[1] << 16) |
1275 		    inqbuf->atap_capacity[0];
1276 	} else {
1277 		sectors = inqbuf->atap_cylinders *
1278 		    inqbuf->atap_heads * inqbuf->atap_sectors;
1279 	}
1280 
1281 	secsize = 512;
1282 
1283 	if ((inqbuf->atap_secsz & ATA_SECSZ_VALID_MASK) == ATA_SECSZ_VALID) {
1284 		if (inqbuf->atap_secsz & ATA_SECSZ_LLS) {
1285 			secsize = 2 *		/* words to bytes */
1286 			    (inqbuf->atap_lls_secsz[1] << 16 |
1287 			    inqbuf->atap_lls_secsz[0] <<  0);
1288 		}
1289 	}
1290 
1291 	capacity = sectors * secsize;
1292 
1293 	if (capacityp)
1294 		*capacityp = capacity;
1295 	if (sectorsp)
1296 		*sectorsp = sectors;
1297 	if (secsizep)
1298 		*secsizep = secsize;
1299 }
1300 
1301 /*
1302  * Inspect the inqbuf and guess what vendor to use.  This list is fairly
1303  * basic, and probably should be converted into a regexp scheme.
1304  */
1305 static const char *
guess_vendor(void)1306 guess_vendor(void)
1307 {
1308 
1309 	unsigned i;
1310 
1311 	for (i = 0; i < __arraycount(model_to_vendor); i++)
1312 		if (strncasecmp(model, model_to_vendor[i].model,
1313 				strlen(model_to_vendor[i].model)) == 0)
1314 			return model_to_vendor[i].vendor;
1315 
1316 	return NULL;
1317 }
1318 
1319 /*
1320  * identify_fixup() - Given an obtained ataparams, fix up the endian and
1321  * other issues before using them.
1322  */
1323 static void
identify_fixup(void)1324 identify_fixup(void)
1325 {
1326 	int needswap = 0;
1327 
1328 	if ((inqbuf->atap_integrity & WDC_INTEGRITY_MAGIC_MASK) ==
1329 	    WDC_INTEGRITY_MAGIC) {
1330 		int i;
1331 		uint8_t checksum;
1332 
1333 		for (i = checksum = 0; i < 512; i++)
1334 			checksum += ((const uint8_t *)inqbuf)[i];
1335 		if (checksum != 0)
1336 			puts("IDENTIFY DEVICE data checksum invalid\n");
1337 	}
1338 
1339 #if BYTE_ORDER == LITTLE_ENDIAN
1340 	/*
1341 	 * On little endian machines, we need to shuffle the string
1342 	 * byte order.  However, we don't have to do this for NEC or
1343 	 * Mitsumi ATAPI devices
1344 	 */
1345 
1346 	if (!(inqbuf->atap_config != WDC_CFG_CFA_MAGIC &&
1347 	      (inqbuf->atap_config & WDC_CFG_ATAPI) &&
1348 	      ((inqbuf->atap_model[0] == 'N' &&
1349 		  inqbuf->atap_model[1] == 'E') ||
1350 	       (inqbuf->atap_model[0] == 'F' &&
1351 		  inqbuf->atap_model[1] == 'X')))) {
1352 		needswap = 1;
1353 	}
1354 #endif
1355 
1356 	/*
1357 	 * Copy the info strings out, stripping off blanks.
1358 	 */
1359 	extract_string(model, sizeof(model),
1360 		inqbuf->atap_model, sizeof(inqbuf->atap_model),
1361 		needswap);
1362 	extract_string(revision, sizeof(revision),
1363 		inqbuf->atap_revision, sizeof(inqbuf->atap_revision),
1364 		needswap);
1365 	extract_string(serial, sizeof(serial),
1366 		inqbuf->atap_serial, sizeof(inqbuf->atap_serial),
1367 		needswap);
1368 
1369 }
1370 
1371 /*
1372  * DEVICE COMMANDS
1373  */
1374 
1375 /*
1376  * device_identify:
1377  *
1378  *	Display the identity of the device
1379  */
1380 static void
device_identify(int argc,char * argv[])1381 device_identify(int argc, char *argv[])
1382 {
1383 	char hnum[12];
1384 	uint64_t capacity;
1385 	uint64_t sectors;
1386 	uint32_t secsize;
1387 	int lb_per_pb;
1388 
1389 	/* No arguments. */
1390 	if (argc != 0)
1391 		usage();
1392 
1393 	fillataparams();
1394 	identify_fixup();
1395 
1396 	printf("Model: %s, Rev: %s, Serial #: %s\n",
1397 		model, revision, serial);
1398 
1399 	if (inqbuf->atap_cmd_ext != 0 && inqbuf->atap_cmd_ext != 0xffff &&
1400 	    inqbuf->atap_cmd_ext & ATA_CMDE_WWN)
1401 		printf("World Wide Name: %016" PRIX64 "\n",
1402 		    ((uint64_t)inqbuf->atap_wwn[0] << 48) |
1403 		    ((uint64_t)inqbuf->atap_wwn[1] << 32) |
1404 		    ((uint64_t)inqbuf->atap_wwn[2] << 16) |
1405 		    ((uint64_t)inqbuf->atap_wwn[3] <<  0));
1406 
1407 	printf("Device type: %s",
1408 		inqbuf->atap_config == WDC_CFG_CFA_MAGIC ? "CF-ATA" :
1409 		 (inqbuf->atap_config & WDC_CFG_ATAPI ? "ATAPI" : "ATA"));
1410 	if (inqbuf->atap_config != WDC_CFG_CFA_MAGIC)
1411 		printf(", %s",
1412 		 inqbuf->atap_config & ATA_CFG_FIXED ? "fixed" : "removable");
1413 	printf("\n");
1414 
1415 	compute_capacity(&capacity, &sectors, &secsize);
1416 
1417 	humanize_number(hnum, sizeof(hnum), capacity, "bytes",
1418 		HN_AUTOSCALE, HN_DIVISOR_1000);
1419 
1420 	printf("Capacity %s, %" PRIu64 " sectors, %" PRIu32 " bytes/sector\n",
1421 		       hnum, sectors, secsize);
1422 
1423 	printf("Cylinders: %d, heads: %d, sec/track: %d\n",
1424 		inqbuf->atap_cylinders, inqbuf->atap_heads,
1425 		inqbuf->atap_sectors);
1426 
1427 	lb_per_pb = 1;
1428 
1429 	if ((inqbuf->atap_secsz & ATA_SECSZ_VALID_MASK) == ATA_SECSZ_VALID) {
1430 		if (inqbuf->atap_secsz & ATA_SECSZ_LPS) {
1431 			lb_per_pb <<= inqbuf->atap_secsz & ATA_SECSZ_LPS_SZMSK;
1432 			printf("Physical sector size: %d bytes\n",
1433 			    lb_per_pb * secsize);
1434 			if ((inqbuf->atap_logical_align &
1435 			    ATA_LA_VALID_MASK) == ATA_LA_VALID) {
1436 				printf("First physically aligned sector: %d\n",
1437 				    lb_per_pb - (inqbuf->atap_logical_align &
1438 					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
device_idle(int argc,char * argv[])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
device_apm(int argc,char * argv[])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
device_setidle(int argc,char * argv[])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
device_checkpower(int argc,char * argv[])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
device_smart(int argc,char * argv[])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
device_security(int argc,char * argv[])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
bus_reset(int argc,char * argv[])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