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
60struct 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
87struct 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
97struct 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
118struct 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
131struct 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
143struct command {
144	const char *cmd_name;
145	const char *arg_names;
146	void (*cmd_func)(int, char *[]);
147};
148
149struct bitinfo {
150	u_int bitmask;
151	const char *string;
152};
153
154__dead static void	usage(void);
155static void	ata_command(struct atareq *);
156static int	satl_command(struct atareq *, int);
157static const uint8_t *satl_return_desc(const uint8_t *, size_t, uint8_t);
158static void	print_bitinfo(const char *, const char *, u_int,
159    const struct bitinfo *);
160static void	print_bitinfo2(const char *, const char *, u_int, u_int,
161    const struct bitinfo *);
162static void	print_smart_status(void *, void *, const char *);
163static void	print_error_entry(int, const struct ata_smart_error *);
164static void	print_selftest_entry(int, const struct ata_smart_selftest *);
165
166static void	print_error(const void *);
167static void	print_selftest(const void *);
168
169static void	fillataparams(void);
170
171static int	is_smart(void);
172
173static int	fd;				/* file descriptor for device */
174static int	use_satl;			/* tunnel through SATL */
175static const	char *dvname;			/* device name */
176static char	dvname_store[MAXPATHLEN];	/* for opendisk(3) */
177static const	char *cmdname;			/* command user issued */
178static const	struct ataparams *inqbuf;	/* inquiry buffer */
179static char	model[sizeof(inqbuf->atap_model)+1];
180static char	revision[sizeof(inqbuf->atap_revision)+1];
181static char	serial[sizeof(inqbuf->atap_serial)+1];
182
183static void	device_identify(int, char *[]);
184static void	device_setidle(int, char *[]);
185static void	device_idle(int, char *[]);
186static void	device_apm(int, char *[]);
187static void	device_checkpower(int, char *[]);
188static void	device_smart(int, char *[]);
189static void	device_security(int, char *[]);
190
191static void	device_smart_temp(const struct ata_smart_attr *, uint64_t);
192
193static 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
211static void	bus_reset(int, char *[]);
212
213static 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
223static 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
232static 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
244static 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
262static 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
279static 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
296static 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
306static 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 */
322static 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 */
412static 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 */
431static 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 */
438static 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 */
452static 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 */
464static 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
482static 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
493int
494main(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
557static void
558usage(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
582static void
583ata_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 */
635static int
636satl_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
784static const uint8_t *
785satl_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
821static void
822print_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
831static void
832print_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
848static void
849device_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
861static void
862print_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
964static 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
978static 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
997static void
998print_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
1054static void
1055print_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
1091static void
1092print_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
1124static void
1125print_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
1160static void
1161fillataparams(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
1194static int
1195is_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 */
1231static void
1232extract_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
1259static void
1260compute_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 */
1305static const char *
1306guess_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 */
1323static void
1324identify_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 */
1380static void
1381device_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 */
1510static void
1511device_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 */
1540static void
1541device_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
1572static void
1573device_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
1620static void
1621device_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 */
1661static void
1662device_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
1825static void
1826device_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 */
1953static void
1954bus_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