我试图在drm内核中添加自己的ioctl。我已经有了以下内容:
static struct drm_driver my_driver = {
//stuff
.ioctls = my_ioctls,
};
然后从那里我有:
struct drm_ioctl_desc my_ioctls[] = {
// other stuff
DRM_IOCTL_DEF_DRV(MYIOCTL1, myfuncptr, myflags),
DRM_IOCTL_DEF_DRV(MYIOCTL2, myfuncptr2, myflags),
DRM_IOCTL_DEF_DRV(MYIOCTL3, myfuncptr3, myflags),
DRM_IOCTL_DEF_DRV(MYIOCTL4, myfuncptr4, myflags),
}
但是我如何复用一组ioctl并将它们处理在另一个可能编译或不编译的文件/子文件夹中?
即。我不想在my_ioctls结构中定义其他ioctl,因为如果使用某个配置,它们可能会调用未定义的函数。有没有办法在其他地方定义它们并在那种情况下处理它们?
谢谢! (我对其中一些有点新鲜,我认为我理解基础知识,但我可能会忽略一些东西。)
答案 0 :(得分:0)
一种可能的方法(粗鲁,对于更清洁的解决方案,见下文)是通过在调用特定于drm的设备分配器(例如drm_dev_alloc
)之前立即合并两个不同的表来构建ioctl表。这两个表来自不同的驱动程序部分,包含不同的服务子集。可选部分可能依赖于编译器宏来创建表的完整版本或“存根”(空)版本。这是一个非常棘手的解决方案,并且肯定容易出错。基本上,给定两个表,你必须
1)将每个表导出为“extern”(或者至少是“可选”表)。我们称他们为t1
和t2
。注意:出于我们的目的,无法定义表格const
。
2)还导出两个包含两个表“sizeof
”的size_t变量(假设为s1
和s2
:size_t s1 = sizeof(t1)
和size_t s2 = sizeof(t2)
)
3)在驱动程序初始化之前,确定两个表中最大的一个,并将其指针指向ioctls
的{{1}}字段。该表将是您合并的“目标”。当然,struct drm_driver
也必须是非struct drm_driver
。
此外,您还必须相应地调整const
字段。
4)通过复制具有非NULL num_ioctls
字段的每个元素来合并目标中的第二个表。要测试的元素数量为func
,其中sX是第二个表的大小(如果目标是sX/sizeof(struct drm_ioctl_descr)
,则为s1
;如果目标为{t2
,则为s2
{1}})。
5)现在你可以像往常一样注册驱动程序。
好的,现在是一个更干净,更“标准”的解决方案:
在“简化”版本中,将所有可选ioctl作为函数始终返回t1
或-EINVAL
。唯一的缺点是,在您的表中,您始终必须提供所有服务(即使尚未实现的服务)。