--------------------------drm/libdrm/xf86drm.c-------------------
int drmIoctl(int fd, unsigned long request, void *arg)
-> ioctl(fd, request, arg);
其中request定义于drm.h, 只是一个unsigned long, 代表了一个ioctl请求号
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, struct drm_version)
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, struct drm_unique)
#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, struct drm_auth)
#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, struct drm_irq_busid)
...
e.g
drmGetMap(fd, i, &offset, &size, &type, &flags, &handle, &mtrr);
-> drmIoctl(fd, DRM_IOCTL_GET_MAP, &map)
-> ioctl(fd, DRM_IOCTL_GET_MAP, &map);
#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, struct drm_map)
其实就相当于DRM_IOCTL_GET_MAP = ((DRM_IOCTL_BASE)<<8)|0x04
--------------------------i915_drv.c-------------------
那末ioctl是在哪里处理的呢?
首先初始化i915 driver的实例,在这里会对i915 driver的每个函数赋值.
static struct drm_driver driver = {
.ioctls = i915_ioctls, //i915 driver特定的ioctl --- i915_dma.c
//比如:gem相关的ioctl
.fops = {
...
.ioctl = drm_ioctl, //common的ioctl --- drm_drv.c
...
}
}
/**
* Called whenever a process performs an ioctl on /dev/drm.
*
* /param inode device inode.
* /param file_priv DRM file private.
* /param cmd command.
* /param arg user argument.
* /return zero on success or negative number on failure.
*
* Looks up the ioctl function in the ::ioctls table, checking for root
* previleges if so required, and dispatches to the respective function.
*
* Copies data in and out according to the size and direction given in cmd,
* which must match the ioctl cmd known by the kernel. The kernel uses a 512
* byte stack buffer to store the ioctl arguments in kernel space. Should we
* ever need much larger ioctl arguments, we may need to allocate memory.
*/
drm_ioctl定义于drm_drv.c处理i915 driver的所有ioctl请求
-> drm_unlocked_ioctl
-> ioctl = &drm_ioctls[nr]; -----定义于drm_drv.c
cmd = ioctl->cmd;
func = ioctl->func;
/** Ioctl table */
//定义于drm_drv.c该表维护了ioctl的入口函数
//各入口函数也许分布在不同的.c文件,需要回调其函数
static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0),
...
DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0), --- drm_ioctl.c
DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY),
...
}
其中i915_ioctls定义于i915_dma.c,该表维护了i915专有的ioctl的入口函数
struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH),
DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH),
DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH),
DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH),
...