http://blog.csdn.net/zkami/article/details/3861261
--------------------------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
...
}
}
drm_ioctl定義于drm_drv.c處理i915 driver的所有ioctl請求
-> drm_unlocked_ioctl
-> ioctl = &drm_ioctls[nr]; -----定義于drm_drv.c
cmd = ioctl->cmd;
func = ioctl->func;
//定義于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),