接前一篇文章:libdrm全解析四 —— 源码全解析(1)
本文参考以下博文:
Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法与解析
特此致谢!
上一篇文章深入讲解了include/drm/drm.h中的几个基础宏定义。再次贴出代码如下:
#define DRM_IOCTL_BASE 'd'
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type)
#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type)
本文开始逐个讲解具有实际意义的宏。
1. DRM_IOCTL_VERSION
第1个宏是DRM_IOCTL_VERSION,相应代码如下:
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, struct drm_version)
结合上一篇文章中的_IOWR(type,nr,size)的最终定义,得到如下代码:
#define DRM_IOCTL_VERSION ( ((3) << 30) | (('d') << 8) | ((0x00) << 0) | ((sizeof(struct drm_version)) << 16) )
struct drm_version在同文件(include/drm/drm.h)中定义,代码如下:
/*
* DRM_IOCTL_VERSION ioctl argument type.
*
* \sa drmGetVersion().
*/
struct drm_version {
int version_major; /**< Major version */
int version_minor; /**< Minor version */
int version_patchlevel; /**< Patch level */
__kernel_size_t name_len; /**< Length of name buffer */
char *name; /**< Name of driver */
__kernel_size_t date_len; /**< Length of date buffer */
char *date; /**< User-space buffer to hold date */
__kernel_size_t desc_len; /**< Length of desc buffer */
char *desc; /**< User-space buffer to hold desc */
};
drm_version结构中的各成员的意义代码注释描述得很清楚了,在此无需赘述。
DRM_IOCTL_VERSION对应的Userspace API为:drmGetVersion()。该函数在xf86drm.c中,代码如下:
/**
* Query the driver version information.
*
* \param fd file descriptor.
*
* \return pointer to a drmVersion structure which should be freed with
* drmFreeVersion().
*
* \note Similar information is available via /proc/dri.
*
* \internal
* It gets the version information via successive DRM_IOCTL_VERSION ioctls,
* first with zeros to get the string lengths, and then the actually strings.
* It also null-terminates them since they might not be already.
*/
drm_public drmVersionPtr drmGetVersion(int fd)
{
drmVersionPtr retval;
drm_version_t *version = drmMalloc(sizeof(*version));
if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
drmFreeKernelVersion(version);
return NULL;
}
if (version->name_len)
version->name = drmMalloc(version->name_len + 1);
if (version->date_len)
version->date = drmMalloc(version->date_len + 1);
if (version->desc_len)
version->desc = drmMalloc(version->desc_len + 1);
if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
drmMsg("DRM_IOCTL_VERSION: %s\n", strerror(errno));
drmFreeKernelVersion(version);
return NULL;
}
/* The results might not be null-terminated strings, so terminate them. */
if (version->name_len) version->name[version->name_len] = '\0';
if (version->date_len) version->date[version->date_len] = '\0';
if (version->desc_len) version->desc[version->desc_len] = '\0';
retval = drmMalloc(sizeof(*retval));
drmCopyVersion(retval, version);
drmFreeKernelVersion(version);
return retval;
}
函数的作用是获取Driver版本信息,即上面的name、desc、date、major、minor字段。此函数在后文具体讲解函数的时候进行详细解析。在此先认识一下、有个印象就好。
2. DRM_IOCTL_GET_UNIQUE
第2个宏是DRM_IOCTL_GET_UNIQUE,相应代码如下:
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, struct drm_unique)
结合上一篇文章中的_IOWR(type,nr,size)的最终定义,得到如下代码:
#define DRM_IOCTL_GET_UNIQUE ( ((3) << 30) | (('d') << 8) | ((0x01) << 0) | ((sizeof(struct drm_unique)) << 16) )
struct drm_unique在同文件(include/drm/drm.h)中定义,代码如下:
/*
* DRM_IOCTL_GET_UNIQUE ioctl argument type.
*
* \sa drmGetBusid() and drmSetBusId().
*/
struct drm_unique {
__kernel_size_t unique_len; /**< Length of unique */
char *unique; /**< Unique name for driver instantiation */
};
drm_unique结构中的各成员的意义代码注释描述得很清楚了,在此无需赘述。
DRM_IOCTL_GET_UNIQUE对应的Userspace API为:drmGetBusid()。该函数也是在xf86drm.c中,代码如下:
/**
* Get the bus ID of the device.
*
* \param fd file descriptor.
*
* \return bus ID string.
*
* \internal
* This function gets the bus ID via successive DRM_IOCTL_GET_UNIQUE ioctls to
* get the string length and data, passing the arguments in a drm_unique
* structure.
*/
drm_public char *drmGetBusid(int fd)
{
drm_unique_t u;
memclear(u);
if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
return NULL;
u.unique = drmMalloc(u.unique_len + 1);
if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) {
drmFree(u.unique);
return NULL;
}
u.unique[u.unique_len] = '\0';
return u.unique;
}
函数的作用是获取Bus ID。此函数在后文具体讲解函数的时候进行详细解析。在此先认识一下、有个印象就好。
其余宏定义将在后续文章中继续解析。