core: don't allow open-source and open-drain flags at the same time
authorBartosz Golaszewski <bartekgola@gmail.com>
Wed, 15 Nov 2017 13:39:58 +0000 (14:39 +0100)
committerBartosz Golaszewski <bartekgola@gmail.com>
Thu, 30 Nov 2017 17:03:12 +0000 (18:03 +0100)
If the hardware actually allowed it, the electrical result would be
disastrous. This has only recently been fixed in the kernel, so add
a relevant check to the library as well.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
src/lib/core.c
tests/tests-line.c

index c17dffa757c4c58de5d9bdd322972b5d9ea071b9..a1d6e0e4a5f083a8b56a915ecdb003151f14b15a 100644 (file)
@@ -343,6 +343,12 @@ static int line_request_values(struct gpiod_line_bulk *bulk,
                return -1;
        }
 
+       if ((config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN) &&
+           (config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE)) {
+               errno = EINVAL;
+               return -1;
+       }
+
        memset(&req, 0, sizeof(req));
 
        if (config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN)
index 2071e8e73b67efdb279dfa073415630b6be77b18..bc151708cf3139e4caef08c254c4ae9389d6d1da 100644 (file)
@@ -513,6 +513,28 @@ TEST_DEFINE(line_open_source_open_drain_input_invalid,
            "gpiod_line - open-source & open-drain for input mode (invalid)",
            0, { 8 });
 
+static void line_open_source_open_drain_simultaneously(void)
+{
+       TEST_CLEANUP(test_close_chip) struct gpiod_chip *chip = NULL;
+       struct gpiod_line *line;
+       int rv;
+
+       chip = gpiod_chip_open(test_chip_path(0));
+       TEST_ASSERT_NOT_NULL(chip);
+
+       line = gpiod_chip_get_line(chip, 2);
+       TEST_ASSERT_NOT_NULL(line);
+
+       rv = gpiod_line_request_output_flags(line, TEST_CONSUMER,
+                               GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE |
+                               GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN, 1);
+       TEST_ASSERT_EQ(rv, -1);
+       TEST_ASSERT_ERRNO_IS(EINVAL);
+}
+TEST_DEFINE(line_open_source_open_drain_simultaneously,
+           "gpiod_line - open-source & open-drain flags simultaneously",
+           0, { 8 });
+
 static void line_null_consumer(void)
 {
        TEST_CLEANUP(test_close_chip) struct gpiod_chip *chip = NULL;