如何转发/复用一组ioctls?
我想在DRM内核中添加我自己的ioctls。我已经有下列要求:如何转发/复用一组ioctls?
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的,并让他们在另一个文件/子文件夹处理可能会或可能不会被编译?
I.e.我不想在my_ioctls结构中定义其他ioctls,因为它们可能是调用未定义的函数,如果使用某个配置。有什么方法可以在别的地方定义它们并在那种情况下处理它们?
谢谢! (我是一个有点新的一些这方面,我想我了解的基础知识,但我可能会被忽视的东西。)
一种可能的方法(粗鲁,一个更干净的解决方案见下文)正在建设一个ioctl通过在调用DRM专用设备分配器之前立即合并两个不同的表(例如drm_dev_alloc
)。这两个表格来自不同的驱动程序部分,并包含不同的服务子集。可选部分可能依赖编译器宏来创建表的完整版本或“存根”(空)版本。这是一个相当棘手的解决方案,肯定会出错。基本上,鉴于这两个表,你必须
1)导出每个表为“extern”(或至少,“可选”一个)。我们称它们为t1
和t2
。注意:对于我们的目的,表格不能被定义为const
。
2)也导出包含两个表“sizeof
” S(假设s1
和s2
2个为size_t变量:size_t s1 = sizeof(t1)
和size_t s2 = sizeof(t2)
)
3)立即驱动程序的初始化之前,找出最大的两个表广告将其指针指向struct drm_driver
的ioctls
字段。该表将成为您合并的“目标”。当然,struct drm_driver
也必须是非const
。 您也必须相应地调整num_ioctls
字段。
4)通过复制每个具有非NULL func
字段的元素合并目标中的第二个表。要测试的元素的数量是sX/sizeof(struct drm_ioctl_descr)
,其中sX是第二个表的大小(即,如果目标是t2
,则为s1
,如果目标是t1
,则为s2
)。
5)现在您可以照常注册驱动程序。
好了,现在一个更清洁,“标准”的解决方案:
在“缩小”版本实现所有的可选的ioctl的功能总是返回-EINVAL
或-EOPNOTSUPP
。唯一的缺点是在你的表格中你总是必须提供所有的服务(甚至还没有实现的服务)。
因此,本质上创建一个新的ioctl结构与所有现有的大小加上任何新的,并将该指针传递给.ioctl?是的,这可能工作,但我不确定它是否比只为不存在的代码声明存根函数更清洁;)谢谢 – Usernum0
是的,正确的。而且,是的,它不是很干净。 (唯一的)优势是你不需要通过声明你可能最终需要的所有可能的存根来“预测未来”。 –
是的,有道理。谢谢 – Usernum0