我觉得:1 内核开发者可以使用宏来定义新的命令,这个命令可以避免别的预留的命令(在VFS层使用的,比如说你提到的0,1,2这些)产生冲突。
2 使用宏比使用直接的数字更容易不出错,无论是内核的开发者,还是这个设备的使用者,这个跟其他系统调用如kill,signal这些是一个道理。
3 的确你自己定义的文件,随便你写什么命令都可以,与其他类型的文件冲突也没关系,只要不与VFS层的冲突就可以了,也不需要专门定义宏。
4 还要考虑到linux不只有x86一个平台的,同一套iotcl需要跟不同的处理器兼容,直接使用数字的话在处理诸如大小端这类问题很麻烦,而且有些命令在不同的平台上值是不一样的(如_IOC_NONE在sparc上是1,而一般为0),为什么要这样取值我也不知道,详细可以研究相关的处理器架构或者ioctl代码。其实你看看这些宏的定义就清楚了。
5 最后摘抄一段源码的注释:
/* ioctl command encoding: 32 bits total, command in lower 16 bits,
  5  * size of the parameter structure in the lower 14 bits of the
  6  * upper 16 bits.
  7  * Encoding the size of the parameter structure in the ioctl request
  8  * is useful for catching programs compiled with old versions
  9  * and to avoid overwriting user space outside the user buffer area.
 10  * The highest 2 bits are reserved for indicating the ``access mode''.
 11  * NOTE: This limits the max parameter size to 16kB -1 !
 12  */
/*
  5  * The original linux ioctl numbering scheme was just a general
  6  * "anything goes" setup, where more or less random numbers were
  7  * assigned.  Sorry, I was clueless when I started out on this.
  8  *
  9  * On the alpha, we'll try to clean it up a bit, using a more sane
 10  * ioctl numbering, and also trying to be compatible with OSF/1 in
 11  * the process. I'd like to clean it up for the i386 as well, but
 12  * it's so painful recognizing both the new and the old numbers..
 13  */