接前一篇文章:libdrm全解析十五 —— 源码全解析(12)
本文参考以下博文:
DRM 驱动程序开发(VKMS)
特此致谢!
本文继续对include/drm/drm.h中实际功能宏定义进行讲解。
21. DRM_IOCTL_ADD_BUFS
第21个宏是DRM_IOCTL_ADD_BUFS,相应代码如下:
#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, struct drm_buf_desc)
结合之前文章中的_IOWR(type,nr,size)的最终定义,得到如下代码:
#define DRM_IOCTL_ADD_BUFS ( ((3) << 30) | (('d') << 8) | ((0x16) << 0) | ((sizeof(struct drm_buf_desc)) << 16) )
struct drm_buf_desc在同文件(include/drm/drm.h)中定义,代码如下:
/** DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type.** \sa drmAddBufs().*/
struct drm_buf_desc {int count; /**< Number of buffers of this size */int size; /**< Size in bytes */int low_mark; /**< Low water mark */int high_mark; /**< High water mark */enum {_DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */_DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */_DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */_DRM_FB_BUFFER = 0x08, /**< Buffer is in frame buffer */_DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */} flags;unsigned long agp_start; /**<* Start address of where the AGP buffers are* in the AGP aperture*/
};
drm_buf_desc结构中各成员的意义代码注释描述得很清楚了,在此无需赘述。
DRM_IOCTL_ADD_BUFS对应的Userspace API为:drmAddBufs()。该函数也是在xf86drm.c中,代码如下:
/*** Make buffers available for DMA transfers.** \param fd file descriptor.* \param count number of buffers.* \param size size of each buffer.* \param flags buffer allocation flags.* \param agp_offset offset in the AGP aperture** \return number of buffers allocated, negative on error.** \internal* This function is a wrapper around DRM_IOCTL_ADD_BUFS ioctl.** \sa drm_buf_desc.*/
drm_public int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,int agp_offset)
{drm_buf_desc_t request;memclear(request);request.count = count;request.size = size;request.flags = (int)flags;request.agp_start = agp_offset;if (drmIoctl(fd, DRM_IOCTL_ADD_BUFS, &request))return -errno;return request.count;
}
函数的作用是使缓冲(buffers)适合DMA传输。此函数在后文具体讲解函数的时候进行详细解析。在此先认识一下、有个印象就好。
22. DRM_IOCTL_MARK_BUFS
第22个宏是DRM_IOCTL_MARK_BUFS,相应代码如下:
#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, struct drm_buf_desc)
结合之前文章中的_IOW(type,nr,size)的最终定义,得到如下代码:
#define DRM_IOCTL_MAKE_BUFS ( ((1) << 30) | (('d') << 8) | ((0x17) << 0) | ((sizeof(struct drm_buf_desc)) << 16) )
struct drm_buf_desc上边已经列出了,在此不重复。
DRM_IOCTL_MARK_BUFS对应的Userspace API为:drmMarkBufs()。该函数也是在xf86drm.c中,代码如下:
drm_public int drmMarkBufs(int fd, double low, double high)
{drm_buf_info_t info;int i;memclear(info);if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))return -EINVAL;if (!info.count)return -EINVAL;if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))return -ENOMEM;if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {int retval = -errno;drmFree(info.list);return retval;}for (i = 0; i < info.count; i++) {info.list[i].low_mark = low * info.list[i].count;info.list[i].high_mark = high * info.list[i].count;if (drmIoctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) {int retval = -errno;drmFree(info.list);return retval;}}drmFree(info.list);return 0;
}
该函数与上边DRM_IOCTL_ADD_BUFS对应的drmAddBufs函数联系较为紧密。此函数在后文具体讲解函数的时候进行详细解析。在此先认识一下、有个印象就好。
其余宏定义将在后续文章中继续解析。