[PATCH 3/3] hdio: improve HDIO support

Srikavin Ramkumar srikavinramkumar at gmail.com
Sat Aug 21 13:52:00 UTC 2021


Add decoders for HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR,
HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, HDIO_OBSOLETE_IDENTITY,
HDIO_GET_IDENTITY, HDIO_GET_KEEPSETTINGS, HDIO_SET_KEEPSETTINGS,
HDIO_GET_32BIT, HDIO_GET_NOWERR, HDIO_GET_DMA, HDIO_GET_NICE,
HDIO_SET_NICE, HDIO_GET_WCACHE, HDIO_GET_ACOUSTIC, HDIO_GET_ADDRESS,
HDIO_GET_BUSSTATE, HDIO_SET_BUSSTATE, and HDIO_DRIVE_RESET.

* maint/gendefs/hdio.def: New file.
* src/Makefile.am (libstrace_a_SOURCES): Add gen/generated.h and gen/gen_hdio.c.
* src/gen/gen_hdio.c: Add generated file.
* src/gen/generated.h: New file.
* src/hdio.c: Add call to generated file for unimplemented commands.
* src/xlat/hdio_busstates.in: New file.
* src/xlat/hdio_ide_nice.in: Likewise.
* tests/ioctl_hdio.c: Add tests for newly implemented commands.
---
 
 I used [1] as reference for the signatures of HDIO commands.

 [1]: https://www.kernel.org/doc/Documentation/ioctl/hdio.txt

 maint/gen/defs/hdio.def    |  36 ++++
 src/Makefile.am            |   2 +
 src/gen/gen_hdio.c         | 337 +++++++++++++++++++++++++++++++++++++
 src/gen/generated.h        |   4 +
 src/hdio.c                 |   4 +-
 src/xlat/hdio_busstates.in |   5 +
 src/xlat/hdio_ide_nice.in  |   5 +
 tests/ioctl_hdio.c         | 185 +++++++++++++++++---
 8 files changed, 556 insertions(+), 22 deletions(-)
 create mode 100644 maint/gen/defs/hdio.def
 create mode 100644 src/gen/gen_hdio.c
 create mode 100644 src/gen/generated.h
 create mode 100644 src/xlat/hdio_busstates.in
 create mode 100644 src/xlat/hdio_ide_nice.in

diff --git a/maint/gen/defs/hdio.def b/maint/gen/defs/hdio.def
new file mode 100644
index 000000000..33a9a8b25
--- /dev/null
+++ b/maint/gen/defs/hdio.def
@@ -0,0 +1,36 @@
+#import "defs/common.syzlang"
+
+include <linux/hdreg.h>
+
+include "xlat/hdio_ide_nice.h"
+include "xlat/hdio_busstates.h"
+
+ioctl$HDIO(fd fd, code kernel_ulong_t, arg3 kernel_ulong_t)
+
+ioctl$HDIO$GET_UNMASKINTR(fd fd, code const[HDIO_GET_UNMASKINTR], unmaskintr ptr[out, ulong])
+ioctl$HDIO$SET_UNMASKINTR(fd fd, code const[HDIO_SET_UNMASKINTR], unmaskintr kernel_ulong_t)
+
+ioctl$HDIO$GET_MULTCOUNT(fd fd, code const[HDIO_GET_MULTCOUNT], multcount ptr[out, ulong])
+ioctl$HDIO$SET_MULTCOUNT(fd fd, code const[HDIO_SET_MULTCOUNT], multcount kernel_ulong_t)
+
+ioctl$HDIO$OBSOLETE_IDENTITY(fd fd, code const[HDIO_OBSOLETE_IDENTITY], identity ptr[out, stringnoz[142]])
+ioctl$HDIO$GET_IDENTITY(fd fd, code const[HDIO_GET_IDENTITY], identity ptr[out, stringnoz[512]])
+
+ioctl$HDIO$GET_KEEPSETTINGS(fd fd, code const[HDIO_GET_KEEPSETTINGS], keep_settings ptr[out, ulong])
+ioctl$HDIO$SET_KEEPSETTINGS(fd fd, code const[HDIO_SET_KEEPSETTINGS], keep_settings kernel_ulong_t)
+
+ioctl$HDIO$GET_32BIT(fd fd, code const[HDIO_GET_32BIT], arg ptr[out, ulong])
+ioctl$HDIO$GET_NOWERR(fd fd, code const[HDIO_GET_NOWERR], arg ptr[out, ulong])
+ioctl$HDIO$GET_DMA(fd fd, code const[HDIO_GET_DMA], arg ptr[out, ulong])
+
+ioctl$HDIO$GET_NICE(fd fd, code const[HDIO_GET_NICE], arg ptr[out, or_flags[hdio_ide_nice, IDE_NICE_???, ulong]])
+ioctl$HDIO$SET_NICE(fd fd, code const[HDIO_SET_NICE], arg or_flags[hdio_ide_nice, IDE_NICE_???, kernel_ulong_t])
+
+ioctl$HDIO$GET_WCACHE(fd fd, code const[HDIO_GET_WCACHE], arg ptr[out, ulong])
+ioctl$HDIO$GET_ACOUSTIC(fd fd, code const[HDIO_GET_ACOUSTIC], arg ptr[out, ulong])
+ioctl$HDIO$GET_ADDRESS(fd fd, code const[HDIO_GET_ADDRESS], arg ptr[out, ulong])
+
+ioctl$HDIO$GET_BUSSTATE(fd fd, code const[HDIO_GET_BUSSTATE], arg ptr[out, xor_flags[hdio_busstates, BUSSTATE_???, ulong]])
+ioctl$HDIO$SET_BUSSTATE(fd fd, code const[HDIO_SET_BUSSTATE], arg xor_flags[hdio_busstates, BUSSTATE_???, kernel_ulong_t])
+
+ioctl$HDIO$DRIVE_RESET(fd fd, code const[HDIO_DRIVE_RESET], arg ptr[in, array[uint32_t, 3]])
diff --git a/src/Makefile.am b/src/Makefile.am
index b7e74a76e..3189abf44 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -132,6 +132,8 @@ libstrace_a_SOURCES =	\
 	fstatfs64.c \
 	futex.c		\
 	gcc_compat.h	\
+    gen/gen_hdio.c  \
+    gen/generated.h \
 	get_personality.c \
 	get_personality.h \
 	get_robust_list.c \
diff --git a/src/gen/gen_hdio.c b/src/gen/gen_hdio.c
new file mode 100644
index 000000000..b558a4ebd
--- /dev/null
+++ b/src/gen/gen_hdio.c
@@ -0,0 +1,337 @@
+/* AUTOMATICALLY GENERATED FROM defs/hdio.def - DO NOT EDIT */
+
+#include <stddef.h>
+#include "generated.h"
+
+typedef kernel_ulong_t kernel_size_t;
+
+#include <linux/hdreg.h>
+#include "xlat/hdio_ide_nice.h"
+#include "xlat/hdio_busstates.h"
+static int
+var_leaf_ioctl_HDIO_DRIVE_RESET(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	tprint_arg_next();
+	/* arg: arg (array *) */
+	/* using decoder from defs/common.syzlang:26:1 */
+
+	{
+		uint32_t int_buffer;
+		print_array(tcp, (arg), (3), &int_buffer, sizeof(int_buffer), tfetch_mem, print_uint32_array_member, 0);
+	}
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_32BIT(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	if (entering(tcp)) {
+		tprint_arg_next();
+		return 0;
+	}
+	/* arg: arg (unsigned long *) */
+	/* using decoder from defs/common.syzlang:41:1 */
+
+	if (exiting(tcp)) {
+		printnum_ulong(tcp, (arg));
+	}
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_ACOUSTIC(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	if (entering(tcp)) {
+		tprint_arg_next();
+		return 0;
+	}
+	/* arg: arg (unsigned long *) */
+	/* using decoder from defs/common.syzlang:41:1 */
+
+	if (exiting(tcp)) {
+		printnum_ulong(tcp, (arg));
+	}
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_ADDRESS(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	if (entering(tcp)) {
+		tprint_arg_next();
+		return 0;
+	}
+	/* arg: arg (unsigned long *) */
+	/* using decoder from defs/common.syzlang:41:1 */
+
+	if (exiting(tcp)) {
+		printnum_ulong(tcp, (arg));
+	}
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_BUSSTATE(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	if (entering(tcp)) {
+		tprint_arg_next();
+		return 0;
+	}
+	/* arg: arg (unsigned long *) */
+	unsigned long tmpvar_arg;
+	if (!umove_or_printaddr(tcp, arg, &tmpvar_arg)) {
+		tprint_indirect_begin();
+		printxval(hdio_busstates, tmpvar_arg, "BUSSTATE_???");
+		tprint_indirect_end();
+	}
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_DMA(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	if (entering(tcp)) {
+		tprint_arg_next();
+		return 0;
+	}
+	/* arg: arg (unsigned long *) */
+	/* using decoder from defs/common.syzlang:41:1 */
+
+	if (exiting(tcp)) {
+		printnum_ulong(tcp, (arg));
+	}
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_IDENTITY(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	if (entering(tcp)) {
+		tprint_arg_next();
+		return 0;
+	}
+	/* arg: identity (stringnoz *) */
+	/* using decoder from defs/common.syzlang:5:1 */
+
+	if (entering(tcp)) {
+		printstrn(tcp, (arg), (512));
+	} else if (syserror(tcp)) {
+		printaddr((arg));
+	} else {
+		printstrn(tcp, (arg), (512));
+	}
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_KEEPSETTINGS(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	if (entering(tcp)) {
+		tprint_arg_next();
+		return 0;
+	}
+	/* arg: keep_settings (unsigned long *) */
+	/* using decoder from defs/common.syzlang:41:1 */
+
+	if (exiting(tcp)) {
+		printnum_ulong(tcp, (arg));
+	}
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_MULTCOUNT(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	if (entering(tcp)) {
+		tprint_arg_next();
+		return 0;
+	}
+	/* arg: multcount (unsigned long *) */
+	/* using decoder from defs/common.syzlang:41:1 */
+
+	if (exiting(tcp)) {
+		printnum_ulong(tcp, (arg));
+	}
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_NICE(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	if (entering(tcp)) {
+		tprint_arg_next();
+		return 0;
+	}
+	/* arg: arg (unsigned long *) */
+	unsigned long tmpvar_arg;
+	if (!umove_or_printaddr(tcp, arg, &tmpvar_arg)) {
+		tprint_indirect_begin();
+		printflags(hdio_ide_nice, tmpvar_arg, "IDE_NICE_???");
+		tprint_indirect_end();
+	}
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_NOWERR(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	if (entering(tcp)) {
+		tprint_arg_next();
+		return 0;
+	}
+	/* arg: arg (unsigned long *) */
+	/* using decoder from defs/common.syzlang:41:1 */
+
+	if (exiting(tcp)) {
+		printnum_ulong(tcp, (arg));
+	}
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_UNMASKINTR(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	if (entering(tcp)) {
+		tprint_arg_next();
+		return 0;
+	}
+	/* arg: unmaskintr (unsigned long *) */
+	/* using decoder from defs/common.syzlang:41:1 */
+
+	if (exiting(tcp)) {
+		printnum_ulong(tcp, (arg));
+	}
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_WCACHE(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	if (entering(tcp)) {
+		tprint_arg_next();
+		return 0;
+	}
+	/* arg: arg (unsigned long *) */
+	/* using decoder from defs/common.syzlang:41:1 */
+
+	if (exiting(tcp)) {
+		printnum_ulong(tcp, (arg));
+	}
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_OBSOLETE_IDENTITY(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	if (entering(tcp)) {
+		tprint_arg_next();
+		return 0;
+	}
+	/* arg: identity (stringnoz *) */
+	/* using decoder from defs/common.syzlang:5:1 */
+
+	if (entering(tcp)) {
+		printstrn(tcp, (arg), (142));
+	} else if (syserror(tcp)) {
+		printaddr((arg));
+	} else {
+		printstrn(tcp, (arg), (142));
+	}
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_BUSSTATE(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	tprint_arg_next();
+	/* arg: arg (kernel_ulong_t) */
+	printxval(hdio_busstates, arg, "BUSSTATE_???");
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_KEEPSETTINGS(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	tprint_arg_next();
+	/* arg: keep_settings (kernel_ulong_t) */
+	PRINT_VAL_U((kernel_ulong_t) arg);
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_MULTCOUNT(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	tprint_arg_next();
+	/* arg: multcount (kernel_ulong_t) */
+	PRINT_VAL_U((kernel_ulong_t) arg);
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_NICE(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	tprint_arg_next();
+	/* arg: arg (kernel_ulong_t) */
+	printflags(hdio_ide_nice, arg, "IDE_NICE_???");
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_UNMASKINTR(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	tprint_arg_next();
+	/* arg: unmaskintr (kernel_ulong_t) */
+	PRINT_VAL_U((kernel_ulong_t) arg);
+
+	return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	return RVAL_DECODED;
+}
+int
+var_ioctl_HDIO(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+	if ((code) == (HDIO_DRIVE_RESET)) {
+		return var_leaf_ioctl_HDIO_DRIVE_RESET(tcp, code, arg);
+	} else if ((code) == (HDIO_GET_32BIT)) {
+		return var_leaf_ioctl_HDIO_GET_32BIT(tcp, code, arg);
+	} else if ((code) == (HDIO_GET_ACOUSTIC)) {
+		return var_leaf_ioctl_HDIO_GET_ACOUSTIC(tcp, code, arg);
+	} else if ((code) == (HDIO_GET_ADDRESS)) {
+		return var_leaf_ioctl_HDIO_GET_ADDRESS(tcp, code, arg);
+	} else if ((code) == (HDIO_GET_BUSSTATE)) {
+		return var_leaf_ioctl_HDIO_GET_BUSSTATE(tcp, code, arg);
+	} else if ((code) == (HDIO_GET_DMA)) {
+		return var_leaf_ioctl_HDIO_GET_DMA(tcp, code, arg);
+	} else if ((code) == (HDIO_GET_IDENTITY)) {
+		return var_leaf_ioctl_HDIO_GET_IDENTITY(tcp, code, arg);
+	} else if ((code) == (HDIO_GET_KEEPSETTINGS)) {
+		return var_leaf_ioctl_HDIO_GET_KEEPSETTINGS(tcp, code, arg);
+	} else if ((code) == (HDIO_GET_MULTCOUNT)) {
+		return var_leaf_ioctl_HDIO_GET_MULTCOUNT(tcp, code, arg);
+	} else if ((code) == (HDIO_GET_NICE)) {
+		return var_leaf_ioctl_HDIO_GET_NICE(tcp, code, arg);
+	} else if ((code) == (HDIO_GET_NOWERR)) {
+		return var_leaf_ioctl_HDIO_GET_NOWERR(tcp, code, arg);
+	} else if ((code) == (HDIO_GET_UNMASKINTR)) {
+		return var_leaf_ioctl_HDIO_GET_UNMASKINTR(tcp, code, arg);
+	} else if ((code) == (HDIO_GET_WCACHE)) {
+		return var_leaf_ioctl_HDIO_GET_WCACHE(tcp, code, arg);
+	} else if ((code) == (HDIO_OBSOLETE_IDENTITY)) {
+		return var_leaf_ioctl_HDIO_OBSOLETE_IDENTITY(tcp, code, arg);
+	} else if ((code) == (HDIO_SET_BUSSTATE)) {
+		return var_leaf_ioctl_HDIO_SET_BUSSTATE(tcp, code, arg);
+	} else if ((code) == (HDIO_SET_KEEPSETTINGS)) {
+		return var_leaf_ioctl_HDIO_SET_KEEPSETTINGS(tcp, code, arg);
+	} else if ((code) == (HDIO_SET_MULTCOUNT)) {
+		return var_leaf_ioctl_HDIO_SET_MULTCOUNT(tcp, code, arg);
+	} else if ((code) == (HDIO_SET_NICE)) {
+		return var_leaf_ioctl_HDIO_SET_NICE(tcp, code, arg);
+	} else if ((code) == (HDIO_SET_UNMASKINTR)) {
+		return var_leaf_ioctl_HDIO_SET_UNMASKINTR(tcp, code, arg);
+	} else {
+		return var_leaf_ioctl_HDIO(tcp, code, arg);
+	}
+}
diff --git a/src/gen/generated.h b/src/gen/generated.h
new file mode 100644
index 000000000..ab8a7bab2
--- /dev/null
+++ b/src/gen/generated.h
@@ -0,0 +1,4 @@
+#include "defs.h"
+
+int
+var_ioctl_HDIO(struct tcb *tcp, unsigned int code, kernel_ulong_t arg);
diff --git a/src/hdio.c b/src/hdio.c
index 9a260a423..b681dc6fa 100644
--- a/src/hdio.c
+++ b/src/hdio.c
@@ -19,6 +19,8 @@ typedef struct hd_geometry struct_hd_geometry;
 
 #include "xlat/hdio_drive_cmds.h"
 
+#include "gen/generated.h"
+
 static int
 print_hdio_getgeo(struct tcb *const tcp, const kernel_ulong_t arg)
 {
@@ -113,7 +115,7 @@ MPERS_PRINTER_DECL(int, hdio_ioctl, struct tcb *const tcp,
 	case HDIO_DRIVE_CMD:
 		return print_hdio_drive_cmd(tcp, arg);
 	default:
-		return RVAL_DECODED;
+		return var_ioctl_HDIO(tcp, code, arg);
 	}
 
 	return RVAL_IOCTL_DECODED;
diff --git a/src/xlat/hdio_busstates.in b/src/xlat/hdio_busstates.in
new file mode 100644
index 000000000..7daea8584
--- /dev/null
+++ b/src/xlat/hdio_busstates.in
@@ -0,0 +1,5 @@
+#enum
+#include <linux/hdreg.h>
+BUSSTATE_OFF        0
+BUSSTATE_ON         1
+BUSSTATE_TRISTATE   2
diff --git a/src/xlat/hdio_ide_nice.in b/src/xlat/hdio_ide_nice.in
new file mode 100644
index 000000000..6dd3bb0fd
--- /dev/null
+++ b/src/xlat/hdio_ide_nice.in
@@ -0,0 +1,5 @@
+1 << IDE_NICE_DSC_OVERLAP
+1 << IDE_NICE_ATAPI_OVERLAP
+1 << IDE_NICE_1
+1 << IDE_NICE_0
+1 << IDE_NICE_2
diff --git a/tests/ioctl_hdio.c b/tests/ioctl_hdio.c
index c90165f05..449fd09bc 100644
--- a/tests/ioctl_hdio.c
+++ b/tests/ioctl_hdio.c
@@ -14,6 +14,10 @@
 #include <stdlib.h>
 #include <linux/hdreg.h>
 #include <sys/ioctl.h>
+#include "xlat.h"
+
+#include "xlat/hdio_busstates.h"
+#include "xlat/hdio_ide_nice.h"
 
 static const char *errstr;
 
@@ -59,7 +63,7 @@ main(int argc, char *argv[])
 	for (size_t i = 0; i < num_skip; i++) {
 		long ret = ioctl(-1, HDIO_GET_UNMASKINTR, 0);
 
-		printf("ioctl(-1, %s, 0) = %s%s\n",
+		printf("ioctl(-1, %s, NULL) = %s%s\n",
 		       XLAT_STR(HDIO_GET_UNMASKINTR), sprintrc(ret),
 		       ret == INJECT_RETVAL ? " (INJECTED)" : "");
 
@@ -72,7 +76,7 @@ main(int argc, char *argv[])
 
 	if (!locked)
 		error_msg_and_fail("Hasn't locked on ioctl(-1"
-				   ", HDIO_GET_UNMASKINTR, 0) returning %d",
+				   ", HDIO_GET_UNMASKINTR, NULL) returning %d",
 				   INJECT_RETVAL);
 #endif
 
@@ -83,38 +87,19 @@ main(int argc, char *argv[])
 		uint32_t cmd;
 		const char *str;
 	} unsupp_cmds[] = {
-		{ ARG_STR(HDIO_GET_UNMASKINTR) },
-		{ ARG_STR(HDIO_GET_MULTCOUNT) },
 		{ ARG_STR(HDIO_GET_QDMA) },
 		{ ARG_STR(HDIO_SET_XFER) },
-		{ ARG_STR(HDIO_OBSOLETE_IDENTITY) },
-		{ ARG_STR(HDIO_GET_KEEPSETTINGS) },
-		{ ARG_STR(HDIO_GET_32BIT) },
-		{ ARG_STR(HDIO_GET_NOWERR) },
-		{ ARG_STR(HDIO_GET_DMA) },
-		{ ARG_STR(HDIO_GET_NICE) },
-		{ ARG_STR(HDIO_GET_IDENTITY) },
-		{ ARG_STR(HDIO_GET_WCACHE) },
-		{ ARG_STR(HDIO_GET_ACOUSTIC) },
-		{ ARG_STR(HDIO_GET_ADDRESS) },
-		{ ARG_STR(HDIO_GET_BUSSTATE) },
 		{ ARG_STR(HDIO_TRISTATE_HWIF) },
-		{ ARG_STR(HDIO_DRIVE_RESET) },
 		{ ARG_STR(HDIO_DRIVE_TASKFILE) },
 		{ ARG_STR(HDIO_DRIVE_TASK) },
-		{ ARG_STR(HDIO_SET_MULTCOUNT) },
-		{ ARG_STR(HDIO_SET_UNMASKINTR) },
-		{ ARG_STR(HDIO_SET_KEEPSETTINGS) },
 		{ ARG_STR(HDIO_SET_32BIT) },
 		{ ARG_STR(HDIO_SET_NOWERR) },
 		{ ARG_STR(HDIO_SET_DMA) },
 		{ ARG_STR(HDIO_SET_PIO_MODE) },
 		{ ARG_STR(HDIO_SCAN_HWIF) },
 		{ ARG_STR(HDIO_UNREGISTER_HWIF) },
-		{ ARG_STR(HDIO_SET_NICE) },
 		{ ARG_STR(HDIO_SET_WCACHE) },
 		{ ARG_STR(HDIO_SET_ACOUSTIC) },
-		{ ARG_STR(HDIO_SET_BUSSTATE) },
 		{ ARG_STR(HDIO_SET_QDMA) },
 		{ ARG_STR(HDIO_SET_ADDRESS) },
 	};
@@ -220,6 +205,164 @@ main(int argc, char *argv[])
 	}
 	printf("}) = %s\n", errstr);
 
+	/* HDIO_DRIVE_RESET */
+	printf("ioctl(-1, %s, NULL) = %s\n", XLAT_STR(HDIO_DRIVE_RESET), errstr);
+	do_ioctl_ptr(HDIO_DRIVE_RESET, 0);
+
+	printf("ioctl(-1, %s, %p) = %s\n", XLAT_STR(HDIO_DRIVE_RESET),
+		   (void *) 0xdeadbeef, errstr);
+	do_ioctl(HDIO_DRIVE_RESET, 0xdeadbeef);
+
+	printf("ioctl(-1, %s, [%u, %u, %u]) = %s\n", XLAT_STR(HDIO_DRIVE_RESET),
+		   (unsigned) 0xdeadbeef, (unsigned) 0xAAAAAAAA, (unsigned) 0xbeefbeef, errstr);
+	int drive_reset_args[3] = {0xdeadbeef, 0xAAAAAAAA, 0xbeefbeef};
+	do_ioctl_ptr(HDIO_DRIVE_RESET, &drive_reset_args);
+
+	/* Getters of the form ioctl(..., ..., &val) */
+	static const struct {
+		uint32_t cmd;
+		const char *str;
+	} getter_cmds[] = {
+		{ ARG_STR(HDIO_GET_32BIT) },
+		{ ARG_STR(HDIO_GET_ACOUSTIC) },
+		{ ARG_STR(HDIO_GET_ADDRESS) },
+		{ ARG_STR(HDIO_GET_DMA) },
+		{ ARG_STR(HDIO_GET_KEEPSETTINGS) },
+		{ ARG_STR(HDIO_GET_MULTCOUNT) },
+		{ ARG_STR(HDIO_GET_NOWERR) },
+		{ ARG_STR(HDIO_GET_UNMASKINTR) },
+		{ ARG_STR(HDIO_GET_WCACHE) },
+	};
+
+	for (size_t i = 0; i < ARRAY_SIZE(getter_cmds); i++) {
+		unsigned long val = 0xdeadbeef;
+
+		rc = do_ioctl_ptr(getter_cmds[i].cmd, &val);
+		printf("ioctl(-1, " XLAT_FMT ", ", XLAT_SEL(getter_cmds[i].cmd, getter_cmds[i].str));
+		if (rc >= 0) {
+			printf("[%lu]", val);
+		} else {
+			printf("%p", &val);
+		}
+		printf(") = %s\n", errstr);
+	}
+
+	/* Setters of the form ioctl(..., ..., val) */
+	static const struct {
+		uint32_t cmd;
+		const char *str;
+	} setter_cmds[] = {
+			{ ARG_STR(HDIO_SET_KEEPSETTINGS) },
+			{ ARG_STR(HDIO_SET_MULTCOUNT) },
+			{ ARG_STR(HDIO_SET_UNMASKINTR) },
+	};
+
+	for (size_t i = 0; i < ARRAY_SIZE(setter_cmds); i++) {
+		unsigned long val = 0xdeadbeef;
+
+		rc = do_ioctl(setter_cmds[i].cmd, val);
+		printf("ioctl(-1, " XLAT_FMT ", %lu) = %s\n", XLAT_SEL(setter_cmds[i].cmd, setter_cmds[i].str),
+			   val, errstr);
+	}
+
+	/* HDIO_OBSOLETE_IDENTITY */
+	do_ioctl_ptr(HDIO_OBSOLETE_IDENTITY, NULL);
+	printf("ioctl(-1, %s, NULL) = %s\n", XLAT_STR(HDIO_OBSOLETE_IDENTITY), errstr);
+
+	char obsolete_identity[142];
+	rc = do_ioctl_ptr(HDIO_OBSOLETE_IDENTITY, obsolete_identity);
+
+	printf("ioctl(-1, %s, ", XLAT_STR(HDIO_OBSOLETE_IDENTITY));
+
+	if (rc >= 0) {
+		print_quoted_memory(obsolete_identity, DEFAULT_STRLEN);
+		printf("...");
+	} else {
+		printf("%p", obsolete_identity);
+	}
+	printf(") = %s\n", errstr);
+
+	/* HDIO_GET_IDENTITY */
+	do_ioctl_ptr(HDIO_GET_IDENTITY, NULL);
+	printf("ioctl(-1, %s, NULL) = %s\n", XLAT_STR(HDIO_GET_IDENTITY), errstr);
+
+	char identity[512];
+	rc = do_ioctl_ptr(HDIO_GET_IDENTITY, identity);
+
+	printf("ioctl(-1, %s, ", XLAT_STR(HDIO_GET_IDENTITY));
+
+	if (rc >= 0) {
+		print_quoted_memory(identity, DEFAULT_STRLEN);
+		printf("...");
+	} else {
+		printf("%p", identity);
+	}
+	printf(") = %s\n", errstr);
+
+	/* HDIO_GET_NICE */
+	unsigned long nice_val = 0xdeadffff;
+
+	rc = do_ioctl_ptr(HDIO_GET_NICE, &nice_val);
+	printf("ioctl(-1, %s, ", XLAT_STR(HDIO_GET_NICE));
+	if (rc >= 0) {
+		printf("[");
+#if XLAT_RAW
+		printf("%#lx", nice_val);
+#else
+#if XLAT_VERBOSE
+			printf("%#lx /* ", nice_val);
+#endif
+		printflags(hdio_ide_nice, nice_val, "IDE_NICE_???");
+#if XLAT_VERBOSE
+			printf(" */");
+#endif
+#endif
+		printf("]");
+	} else {
+		printf("%p", &nice_val);
+	}
+	printf(") = %s\n", errstr);
+
+	/* HDIO_SET_NICE */
+	nice_val = 0xc0dec0de;
+	do_ioctl(HDIO_SET_NICE, nice_val);
+	printf("ioctl(-1, %s, ", XLAT_STR(HDIO_SET_NICE));
+#if XLAT_RAW
+	printf("%#lx", nice_val);
+#else
+#if XLAT_VERBOSE
+	printf("%#lx /* ", nice_val);
+#endif
+	printflags(hdio_ide_nice, nice_val, "IDE_NICE_???");
+#if XLAT_VERBOSE
+	printf(" */");
+#endif
+#endif
+	printf(") = %s\n", errstr);
+
+	/* HDIO_GET_BUSSTATE */
+	unsigned long busstate_value = 0xdeadffff;
+
+	rc = do_ioctl_ptr(HDIO_GET_BUSSTATE, &busstate_value);
+	printf("ioctl(-1, %s, ", XLAT_STR(HDIO_GET_BUSSTATE));
+	if (rc >= 0) {
+		printf("[");
+		printxval(hdio_busstates, busstate_value, "BUSSTATE_???");
+		printf("]");
+	} else {
+		printf("%p", &busstate_value);
+	}
+	printf(") = %s\n", errstr);
+
+
+	/* HDIO_SET_BUSSTATE */
+	busstate_value = 0xc0dec0de;
+
+	do_ioctl(HDIO_SET_BUSSTATE, busstate_value);
+	printf("ioctl(-1, %s, ", XLAT_STR(HDIO_SET_BUSSTATE));
+	printxval(hdio_busstates, busstate_value, "BUSSTATE_???");
+	printf(") = %s\n", errstr);
+
 	puts("+++ exited with 0 +++");
 	return 0;
 }
-- 
2.25.1



More information about the Strace-devel mailing list