title: `ioctl` to read and write GPIO: invalid argument
body: <p>I'm imitating the <a href="https://elixir.bootlin.com/linux/v4.19.66/source/tools/gpio" rel="nofollow noreferrer">gpio-hammer</a> example in Linux source code. I'm using Raspberry Pi 3B+ and want an LED to blink.</p>
  
  <p>Here's what I do:</p>
  
  <pre class="lang-c prettyprint-override"><code>#include &lt;linux/gpio.h&gt;
  #include &lt;sys/ioctl.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;string.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;stdio.h&gt;
  
  int main(int argc, const char **argv) {
      int fd, ret;
      struct gpiohandle_request req;
      struct gpiohandle_data data;
  
      char *gpio_dev_name = "/dev/gpiochip0";
      unsigned int gpio_line = 8;
  
      memset(&amp;data.values, 0, sizeof(data.values));
  
      // open device
      fd = open(gpio_dev_name, 0);
      if (fd == -1) {
      fprintf(stderr, "Failed to open %s, %s\n",
                  gpio_dev_name, strerror(errno));
      }
  
      // request gpio output
      req.lineoffsets[0] = gpio_line;
      req.flags = GPIOHANDLE_REQUEST_OUTPUT | GPIOHANDLE_REQUEST_ACTIVE_LOW;
      strcpy(req.consumer_label, "blink");
      req.lines = 1;
      memcpy(req.default_values, &amp;data, sizeof(req.default_values));
  
      ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &amp;req);
      if (ret == -1) {
          fprintf(stderr, "Failed to issue %s (%d), %s\n",
                  "GPIO_GET_LINEHANDLE_IOCTL", ret, strerror(errno));
      }
  
      // blink
      while (1) {
          // read data
          ret = ioctl(fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &amp;data);
          if (ret == -1) {
              ret = -errno;
              fprintf(stderr, "Failed to issue %s (%d), %s\n", 
                      "GPIOHANDLE_GET_LINE_VALUES_IOCTL", ret, strerror(errno));
              exit(ret);
          }
  
          // flip digits
          data.values[0] = !data.values[0];
  
          // set data
          ret = ioctl(fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &amp;data);
          if (ret == -1) {
              ret = -errno;
              fprintf(stderr, "Failed to issue %s (%d), %s\n", 
                      "GPIOHANDLE_SET_LINE_VALUES_IOCTL", ret, strerror(errno));
              exit(ret);
          }
  
          // delay
          sleep(1);
      }
  }
  </code></pre>
  
  <p>I can compile the gpio-hammer example on RPi and run it with <code>./gpio-hammer -n gpiochip0 -o 8</code>. Attached to gpiochip0 line8 is an LED and it blinks.</p>
  
  <p>But my program does not work. It fails with</p>
  
  <pre><code>Failed to issue GPIOHANDLE_GET_LINE_VALUES_IOCTL (-22), Invalid argument
  </code></pre>
  
  <p>I looked into the implement of <a href="https://elixir.bootlin.com/linux/v4.19.66/source/drivers/gpio/gpiolib.c#L424" rel="nofollow noreferrer">gpiolib</a>. The <code>ioctl</code> of gpio line handle returns <code>EINVAL (22)</code> if ioctl cmd is not <code>GPIOHANDLE_GET_LINE_VALUES_IOCTL</code> nor <code>GPIOHANDLE_SET_LINE_VALUES_IOCTL</code>. But that's not the case. What's going wrong?</p>