Confusion over ioctl() and kernel headers
<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>