[PATCH v3 5/6] tests: check decoding of GPIO v2 ioctls
Kent Gibson
warthog618 at gmail.com
Sat Jan 23 00:04:04 UTC 2021
Add tests for decoding of GPIO v2 ioctls.
Signed-off-by: Kent Gibson <warthog618 at gmail.com>
---
tests/ioctl_gpio.c | 344 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 344 insertions(+)
diff --git a/tests/ioctl_gpio.c b/tests/ioctl_gpio.c
index 6d526c1b..248bb612 100644
--- a/tests/ioctl_gpio.c
+++ b/tests/ioctl_gpio.c
@@ -12,6 +12,7 @@
#if HAVE_LINUX_GPIO_H
#include <errno.h>
+#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -23,11 +24,14 @@
"GPIOHANDLE_REQUEST_ACTIVE_LOW|GPIOHANDLE_REQUEST_OPEN_SOURCE")
# define str_info_flags XLAT_KNOWN(0xc, \
"GPIOLINE_FLAG_ACTIVE_LOW|GPIOLINE_FLAG_OPEN_DRAIN")
+# define str_line_flags XLAT_KNOWN(0x102, \
+ "GPIO_V2_LINE_FLAG_ACTIVE_LOW|GPIO_V2_LINE_FLAG_BIAS_PULL_UP")
#define UNK_GPIO_FLAG 0x8000
# define str_handle_unk_flag XLAT_UNKNOWN(UNK_GPIO_FLAG, "GPIOHANDLE_REQUEST_???")
# define str_info_unk_flag XLAT_UNKNOWN(UNK_GPIO_FLAG, "GPIOLINE_FLAG_???")
+# define str_line_unk_flag XLAT_UNKNOWN(UNK_GPIO_FLAG, "GPIO_V2_LINE_FLAG_???")
#if VERBOSE
# define str_line_seq "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, " \
@@ -334,6 +338,339 @@ test_print_gpiohandle_set_config(void)
XLAT_STR(GPIOHANDLE_SET_CONFIG_IOCTL), errstr);
}
+static void
+print_gpio_v2_line_attr(struct_gpio_v2_line_attribute *attr)
+{
+ printf("{");
+ switch (attr->id) {
+ case GPIO_V2_LINE_ATTR_ID_FLAGS:
+ printf("flags=%#" PRIx64 NRAW(" /* GPIO_V2_LINE_FLAG_??? */"),
+ attr->flags);
+ break;
+ case GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES:
+ printf("values=%#" PRIx64, attr->values);
+ break;
+ case GPIO_V2_LINE_ATTR_ID_DEBOUNCE:
+ printf("debounce_period_us=%u", attr->debounce_period_us);
+ break;
+ default:
+ printf("id=%u, data=%#" PRIx64, attr->id, attr->values);
+ break;
+ }
+ printf("}");
+}
+
+static void
+test_print_gpio_v2_line_info(void)
+{
+ long rc;
+
+ do_ioctl(GPIO_V2_GET_LINEINFO_IOCTL, 0);
+ printf("ioctl(-1, %s, NULL) = %s\n",
+ XLAT_STR(GPIO_V2_GET_LINEINFO_IOCTL), errstr);
+
+ TAIL_ALLOC_OBJECT_CONST_PTR(struct_gpio_v2_line_info, p_lineinfo);
+
+ strcpy(p_lineinfo->name, "line name");
+ strcpy(p_lineinfo->consumer, "line consumer");
+ p_lineinfo->offset = 0x32;
+ p_lineinfo->num_attrs = 0;
+ p_lineinfo->flags = GPIO_V2_LINE_FLAG_ACTIVE_LOW|GPIO_V2_LINE_FLAG_BIAS_PULL_UP;
+ memset(p_lineinfo->padding, 0, sizeof(p_lineinfo->padding));
+
+ do_ioctl_ptr(GPIO_V2_GET_LINEINFO_IOCTL, (char *) p_lineinfo + 1);
+ printf("ioctl(-1, %s, %p) = %s\n",
+ XLAT_STR(GPIO_V2_GET_LINEINFO_IOCTL), (char *) p_lineinfo + 1, errstr);
+
+ /* GPIO_V2_GET_LINEINFO_IOCTL */
+ rc = do_ioctl_ptr(GPIO_V2_GET_LINEINFO_IOCTL, p_lineinfo);
+ printf("ioctl(-1, %s, {offset=50}",
+ XLAT_STR(GPIO_V2_GET_LINEINFO_IOCTL));
+ if (rc >= 0)
+ printf(" => {name=\"line name\", consumer=\"line consumer\", flags="
+ str_line_flags ", num_attrs=0}");
+ printf(") = %s\n", errstr);
+
+ /* GPIO_V2_GET_LINEINFO_WATCH_IOCTL */
+ rc = do_ioctl_ptr(GPIO_V2_GET_LINEINFO_WATCH_IOCTL, p_lineinfo);
+ printf("ioctl(-1, %s, {offset=50}",
+ XLAT_STR(GPIO_V2_GET_LINEINFO_WATCH_IOCTL));
+ if (rc >= 0)
+ printf(" => {name=\"line name\", consumer=\"line consumer\", flags="
+ str_line_flags ", num_attrs=0}");
+ printf(") = %s\n", errstr);
+
+ /* unknown flag */
+ p_lineinfo->offset = 0x35;
+ p_lineinfo->flags = UNK_GPIO_FLAG;
+ rc = do_ioctl_ptr(GPIO_V2_GET_LINEINFO_IOCTL, p_lineinfo);
+ printf("ioctl(-1, %s, {offset=53}",
+ XLAT_STR(GPIO_V2_GET_LINEINFO_IOCTL));
+ if (rc >= 0)
+ printf(" => {name=\"line name\", consumer=\"line consumer\", flags="
+ str_line_unk_flag ", num_attrs=0}");
+ printf(") = %s\n", errstr);
+ p_lineinfo->flags = GPIO_V2_LINE_FLAG_ACTIVE_LOW|GPIO_V2_LINE_FLAG_BIAS_PULL_UP;
+
+ /* with non-zero padding */
+ p_lineinfo->offset = 0x36;
+ p_lineinfo->padding[2] = 0xdeadd0d0;
+ rc = do_ioctl_ptr(GPIO_V2_GET_LINEINFO_IOCTL, p_lineinfo);
+ printf("ioctl(-1, %s, {offset=54}",
+ XLAT_STR(GPIO_V2_GET_LINEINFO_IOCTL));
+ if (rc >= 0)
+ printf(" => {name=\"line name\", consumer=\"line consumer\", flags="
+ str_line_flags ", num_attrs=0, padding=[0, 0, 0xdeadd0d0, 0]}");
+ printf(") = %s\n", errstr);
+ memset(p_lineinfo->padding, 0, sizeof(p_lineinfo->padding));
+
+ /* num_attrs = 1 */
+ p_lineinfo->offset = 0x37;
+ memset(p_lineinfo->attrs, 0, sizeof(p_lineinfo->attrs));
+ p_lineinfo->num_attrs = 1;
+ p_lineinfo->attrs[0].id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE;
+ p_lineinfo->attrs[0].debounce_period_us = 0xdeadbeef;
+
+ rc = do_ioctl_ptr(GPIO_V2_GET_LINEINFO_IOCTL, p_lineinfo);
+ printf("ioctl(-1, %s, {offset=55}",
+ XLAT_STR(GPIO_V2_GET_LINEINFO_IOCTL));
+ if (rc >= 0)
+ printf(" => {name=\"line name\", consumer=\"line consumer\", flags="
+ str_line_flags ", num_attrs=1, attrs=[{debounce_period_us=3735928559}]}");
+ printf(") = %s\n", errstr);
+
+ /* num_attrs = 1 with non-zero padding */
+ p_lineinfo->offset = 0x38;
+ memset(p_lineinfo->attrs, 0, sizeof(p_lineinfo->attrs));
+ p_lineinfo->num_attrs = 1;
+ p_lineinfo->attrs[0].id = GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES;
+ p_lineinfo->attrs[0].values = 0xdeadbeefba11c0da;
+ p_lineinfo->attrs[0].padding = 0xfeedface;
+
+ rc = do_ioctl_ptr(GPIO_V2_GET_LINEINFO_IOCTL, p_lineinfo);
+ printf("ioctl(-1, %s, {offset=56}",
+ XLAT_STR(GPIO_V2_GET_LINEINFO_IOCTL));
+ if (rc >= 0)
+ printf(" => {name=\"line name\", consumer=\"line consumer\", flags="
+ str_line_flags ", num_attrs=1, "
+ "attrs=[{id=2, padding=0xfeedface, data=0xdeadbeefba11c0da}]}");
+ printf(") = %s\n", errstr);
+
+ /* num_attrs > GPIO_V2_LINE_NUM_ATTRS_MAX */
+ memset(p_lineinfo->attrs, 0, sizeof(p_lineinfo->attrs));
+ p_lineinfo->num_attrs = GPIO_V2_LINE_NUM_ATTRS_MAX;
+ for (int i = 0; i < GPIO_V2_LINE_NUM_ATTRS_MAX; i++) {
+ p_lineinfo->attrs[i].id = i + 1;
+ p_lineinfo->attrs[i].flags = 0xafeddeadd0d00000 + i;
+ }
+ p_lineinfo->offset = 0x39;
+ p_lineinfo->num_attrs = GPIO_V2_LINE_NUM_ATTRS_MAX + 1;
+ rc = do_ioctl_ptr(GPIO_V2_GET_LINEINFO_IOCTL, p_lineinfo);
+ printf("ioctl(-1, %s, {offset=57}",
+ XLAT_STR(GPIO_V2_GET_LINEINFO_IOCTL));
+ if (rc >= 0) {
+ printf(" => {name=\"line name\", consumer=\"line consumer\", flags="
+ str_line_flags ", num_attrs=11, attrs=[");
+ for (int i = 0; i < GPIO_V2_LINE_NUM_ATTRS_MAX; i++) {
+ print_gpio_v2_line_attr(&p_lineinfo->attrs[i]);
+ if (i != GPIO_V2_LINE_NUM_ATTRS_MAX-1)
+ printf(", ");
+ }
+ printf("]}");
+ }
+ printf(") = %s\n", errstr);
+}
+
+static void
+test_print_gpio_v2_line_request(void)
+{
+ long rc;
+
+ do_ioctl(GPIO_V2_GET_LINE_IOCTL, 0);
+ printf("ioctl(-1, %s, NULL) = %s\n",
+ XLAT_STR(GPIO_V2_GET_LINE_IOCTL), errstr);
+
+ TAIL_ALLOC_OBJECT_CONST_PTR(struct_gpio_v2_line_request, p_line_request);
+
+ p_line_request->offsets[0] = 0x12;
+ p_line_request->offsets[1] = 0x23;
+ p_line_request->offsets[2] = 0x34;
+ p_line_request->offsets[3] = 0x45;
+ strcpy(p_line_request->consumer, "line consumer");
+ memset(&p_line_request->config, 0, sizeof(p_line_request->config));
+ p_line_request->num_lines = 4;
+ p_line_request->event_buffer_size = 0;
+ memset(p_line_request->padding, 0, sizeof(p_line_request->padding));
+ p_line_request->fd = 0x64;
+
+ do_ioctl_ptr(GPIO_V2_GET_LINE_IOCTL, (char *) p_line_request + 1);
+ printf("ioctl(-1, %s, %p) = %s\n",
+ XLAT_STR(GPIO_V2_GET_LINE_IOCTL), (char *) p_line_request + 1, errstr);
+
+ rc = do_ioctl_ptr(GPIO_V2_GET_LINE_IOCTL, p_line_request);
+ printf("ioctl(-1, %s, {num_lines=4, offsets=[18, 35, 52, 69], "
+ "config={flags=0, num_attrs=0}, consumer=\"line consumer\"}",
+ XLAT_STR(GPIO_V2_GET_LINE_IOCTL));
+ if (rc >= 0)
+ printf(" => {fd=100}");
+ printf(") = %s\n", errstr);
+
+ /* with event_buffer_size */
+ p_line_request->event_buffer_size = 0xdeafdace;
+ rc = do_ioctl_ptr(GPIO_V2_GET_LINE_IOCTL, p_line_request);
+ printf("ioctl(-1, %s, {num_lines=4, offsets=[18, 35, 52, 69], "
+ "config={flags=0, num_attrs=0}, consumer=\"line consumer\", "
+ "event_buffer_size=3736066766}",
+ XLAT_STR(GPIO_V2_GET_LINE_IOCTL));
+ if (rc >= 0)
+ printf(" => {fd=100}");
+ printf(") = %s\n", errstr);
+ p_line_request->event_buffer_size = 0;
+
+ /* with non-zero-padding */
+ p_line_request->padding[1] = 0xfeedface;
+ rc = do_ioctl_ptr(GPIO_V2_GET_LINE_IOCTL, p_line_request);
+ printf("ioctl(-1, %s, {num_lines=4, offsets=[18, 35, 52, 69], "
+ "config={flags=0, num_attrs=0}, consumer=\"line consumer\", "
+ "padding=[0, 0xfeedface, 0, 0, 0]}",
+ XLAT_STR(GPIO_V2_GET_LINE_IOCTL));
+ if (rc >= 0)
+ printf(" => {fd=100}");
+ printf(") = %s\n", errstr);
+ p_line_request->padding[1] = 0;
+
+ /* num_lines > GPIO_V2_LINES_MAX */
+ p_line_request->num_lines = GPIO_V2_LINES_MAX + 1;
+ for (int i = 0; i < GPIO_V2_LINES_MAX; i++)
+ p_line_request->offsets[i] = i + 1;
+ rc = do_ioctl_ptr(GPIO_V2_GET_LINE_IOCTL, p_line_request);
+ printf("ioctl(-1, %s, {num_lines=65, offsets=" str_line_seq
+ ", config={flags=0, num_attrs=0}, consumer=\"line consumer\"}",
+ XLAT_STR(GPIO_V2_GET_LINE_IOCTL));
+ if (rc >= 0)
+ printf(" => {fd=100}");
+ printf(") = %s\n", errstr);
+}
+
+static void
+test_print_gpio_v2_line_get_values(void)
+{
+ long rc;
+
+ do_ioctl(GPIO_V2_LINE_GET_VALUES_IOCTL, 0);
+ printf("ioctl(-1, %s, NULL) = %s\n",
+ XLAT_STR(GPIO_V2_LINE_GET_VALUES_IOCTL), errstr);
+
+ TAIL_ALLOC_OBJECT_CONST_PTR(struct_gpio_v2_line_values, p_line_values);
+
+ p_line_values->bits = 0xcacafeedfacecafe;
+ p_line_values->mask = 0xfadebeaddeedbabe;
+
+ do_ioctl_ptr(GPIO_V2_LINE_GET_VALUES_IOCTL, (char *) p_line_values + 1);
+ printf("ioctl(-1, %s, %p) = %s\n",
+ XLAT_STR(GPIO_V2_LINE_GET_VALUES_IOCTL), (char *) p_line_values + 1, errstr);
+
+ rc = do_ioctl_ptr(GPIO_V2_LINE_GET_VALUES_IOCTL, p_line_values);
+ printf("ioctl(-1, %s, {mask=0xfadebeaddeedbabe}",
+ XLAT_STR(GPIO_V2_LINE_GET_VALUES_IOCTL));
+ if (rc >= 0)
+ printf(" => {bits=0xcacafeedfacecafe}");
+ printf(") = %s\n", errstr);
+}
+
+static void
+test_print_gpio_v2_line_set_values(void)
+{
+ do_ioctl(GPIO_V2_LINE_SET_VALUES_IOCTL, 0);
+ printf("ioctl(-1, %s, NULL) = %s\n",
+ XLAT_STR(GPIO_V2_LINE_SET_VALUES_IOCTL), errstr);
+
+ TAIL_ALLOC_OBJECT_CONST_PTR(struct_gpio_v2_line_values, p_line_values);
+
+ p_line_values->bits = 0xcacafeedfacecafe;
+ p_line_values->mask = 0xfadebeaddeedbabe;
+
+ do_ioctl_ptr(GPIO_V2_LINE_SET_VALUES_IOCTL, (char *) p_line_values + 1);
+ printf("ioctl(-1, %s, %p) = %s\n",
+ XLAT_STR(GPIO_V2_LINE_SET_VALUES_IOCTL), (char *) p_line_values + 1, errstr);
+
+ do_ioctl_ptr(GPIO_V2_LINE_SET_VALUES_IOCTL, p_line_values);
+ printf("ioctl(-1, %s, {bits=0xcacafeedfacecafe, mask=0xfadebeaddeedbabe}) = %s\n",
+ XLAT_STR(GPIO_V2_LINE_SET_VALUES_IOCTL),
+ errstr);
+}
+
+static void
+test_print_gpio_v2_line_set_config(void)
+{
+ do_ioctl(GPIO_V2_LINE_SET_CONFIG_IOCTL, 0);
+ printf("ioctl(-1, %s, NULL) = %s\n",
+ XLAT_STR(GPIO_V2_LINE_SET_CONFIG_IOCTL), errstr);
+
+ TAIL_ALLOC_OBJECT_CONST_PTR(struct_gpio_v2_line_config, p_line_config);
+
+ p_line_config->flags = GPIO_V2_LINE_FLAG_ACTIVE_LOW|GPIO_V2_LINE_FLAG_BIAS_PULL_UP;
+ p_line_config->num_attrs = 0;
+ memset(p_line_config->attrs, 0, sizeof(p_line_config->attrs));
+ memset(p_line_config->padding, 0, sizeof(p_line_config->padding));
+
+ do_ioctl_ptr(GPIO_V2_LINE_SET_CONFIG_IOCTL, (char *) p_line_config + 1);
+ printf("ioctl(-1, %s, %p) = %s\n",
+ XLAT_STR(GPIO_V2_LINE_SET_CONFIG_IOCTL), (char *) p_line_config + 1, errstr);
+
+ do_ioctl_ptr(GPIO_V2_LINE_SET_CONFIG_IOCTL, p_line_config);
+ printf("ioctl(-1, %s, {flags=" str_line_flags ", num_attrs=0}) = %s\n",
+ XLAT_STR(GPIO_V2_LINE_SET_CONFIG_IOCTL), errstr);
+
+ /* unknown flag */
+ p_line_config->flags = UNK_GPIO_FLAG;
+ do_ioctl_ptr(GPIO_V2_LINE_SET_CONFIG_IOCTL, p_line_config);
+ printf("ioctl(-1, %s, {flags=" str_line_unk_flag
+ ", num_attrs=0}) = %s\n",
+ XLAT_STR(GPIO_V2_LINE_SET_CONFIG_IOCTL), errstr);
+ p_line_config->flags = GPIO_V2_LINE_FLAG_ACTIVE_LOW|GPIO_V2_LINE_FLAG_BIAS_PULL_UP;
+
+ /* with non-zero-padding */
+ p_line_config->padding[1] = 0xfeedface;
+ do_ioctl_ptr(GPIO_V2_LINE_SET_CONFIG_IOCTL, p_line_config);
+ printf("ioctl(-1, %s, {flags=" str_line_flags
+ ", num_attrs=0, padding=[0, 0xfeedface, 0, 0, 0]}) = %s\n",
+ XLAT_STR(GPIO_V2_LINE_SET_CONFIG_IOCTL), errstr);
+ p_line_config->padding[1] = 0;
+
+ /* num_attrs > GPIO_V2_LINE_NUM_ATTRS_MAX */
+ for (int i = 0; i < GPIO_V2_LINE_NUM_ATTRS_MAX; i++) {
+ p_line_config->attrs[i].mask = 2 * i + 1;
+ p_line_config->attrs[i].attr.id = GPIO_V2_LINE_ATTR_ID_FLAGS;
+ p_line_config->attrs[i].attr.flags =
+ GPIO_V2_LINE_FLAG_ACTIVE_LOW|GPIO_V2_LINE_FLAG_BIAS_PULL_UP;
+ }
+ p_line_config->num_attrs = GPIO_V2_LINE_NUM_ATTRS_MAX + 1;
+ do_ioctl_ptr(GPIO_V2_LINE_SET_CONFIG_IOCTL, p_line_config);
+ printf("ioctl(-1, %s, {flags=" str_line_flags ", num_attrs=11, attrs=[",
+ XLAT_STR(GPIO_V2_LINE_SET_CONFIG_IOCTL));
+ for (int i = 0; i < GPIO_V2_LINE_NUM_ATTRS_MAX - 1; i++)
+ printf("{flags=" str_line_flags ", mask=0x%x}, ", 2 * i + 1);
+ printf("{flags=" str_line_flags ", mask=0x13}]}) = %s\n", errstr);
+
+ /* num_attrs = 1 */
+ p_line_config->num_attrs = 1;
+ do_ioctl_ptr(GPIO_V2_LINE_SET_CONFIG_IOCTL, p_line_config);
+ printf("ioctl(-1, %s, {flags=" str_line_flags ", num_attrs=1, attrs=[{flags="
+ str_line_flags ", mask=0x1}]}) = %s\n",
+ XLAT_STR(GPIO_V2_LINE_SET_CONFIG_IOCTL), errstr);
+
+ /* num_attrs = 1 with non-zero padding*/
+ p_line_config->attrs[0].attr.padding = 0xfeedface;
+ p_line_config->attrs[0].attr.values = 0xdeadbeefba11c0da;
+ do_ioctl_ptr(GPIO_V2_LINE_SET_CONFIG_IOCTL, p_line_config);
+ printf("ioctl(-1, %s, {flags=" str_line_flags ", num_attrs=1, attrs=["
+ "{attr={id=%u, padding=0xfeedface, data=0xdeadbeefba11c0da}, "
+ "mask=0x1}]}) = %s\n",
+ XLAT_STR(GPIO_V2_LINE_SET_CONFIG_IOCTL),
+ GPIO_V2_LINE_ATTR_ID_FLAGS, errstr);
+}
+
int
main(int argc, char *argv[])
{
@@ -384,6 +721,13 @@ main(int argc, char *argv[])
test_print_gpiohandle_set_values();
test_print_gpiohandle_set_config();
+ /* GPIO v2 ioctls */
+ test_print_gpio_v2_line_info();
+ test_print_gpio_v2_line_request();
+ test_print_gpio_v2_line_get_values();
+ test_print_gpio_v2_line_set_values();
+ test_print_gpio_v2_line_set_config();
+
puts("+++ exited with 0 +++");
return 0;
}
--
2.30.0
More information about the Strace-devel
mailing list