title: Confusion over ioctl() and kernel headers
body: <p>As far as I know, <code>ioctl()</code> is used to expose an "extended" system call interface to userspace applications. Rather than adding thousands of system calls that are unique to specific drivers, <code>ioctl()</code> is used to provide extensible driver-specific functions through a single system call. </p>
  
  <p>This seems clear enough. However, I'm trying to compile my first application that uses an <code>ioctl()</code> call, and I'm starting to doubt my understanding.</p>
  
  <p>Specifically, I want to make an <code>ioctl()</code> call to "sanitize" an eMMC device. Taking a look at <code>/usr/include/linux/mmc/ioctl.h</code> (or in kernel source at <code>include/uapi/linux/mmc/ioctl.h</code>), I can see this structure:</p>
  
  <pre><code>struct mmc_ioc_cmd {
          // Most fields omitted
          int write_flag;    
          __u32 opcode;
          __u32 arg;
  };
  </code></pre>
  
  <p>From userspace, I don't have any issues including this header and passing this structure into my <code>ioctl()</code> calls. </p>
  
  <p>So this is what my final sanitize snippet looks like:</p>
  
  <pre><code>int sanitize(int fd)
  {
    struct mmc_ioc_cmd command;
    memset(&amp;command, 0, sizeof(command));
  
    command.write_flag = 1;
    command.opcode = MMC_SWITCH;
    command.arg = EXT_CSD_SANITIZE_START &lt;&lt; 16;
  
    return ioctl(fd, MMC_IOC_CMD, &amp;command);
  }
  </code></pre>
  
  <p>My problem is that <code>MMC_SWITCH</code> and <code>EXT_CSD_SANITIZE_START</code> are both defined in kernel headers. Specifically, in my kernel source, they're both found at <code>include/linux/mmc/mmc.h</code>. </p>
  
  <p>Everything I've seen on the internet says to <strong>not</strong> include headers from the kernel source when building userspace projects. If that's the case, how can you reasonably use the MMC <code>ioctl()</code>? The kernel exposes the structure to pass into <code>ioctl()</code>, but it seems like you can only use the structure by filling it in with "hidden" constants hidden in the kernel source. </p>
  
  <p>My current solution is to copy the necessary constants from the kernel headers to my own project, but this feels dirty to me. </p>
  
  <p>Am I misunderstanding the use-case for <code>ioctl()</code>? Is this a design oversight? </p>