如何转发/复用一组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”(或至少,“可选”一个)。我们称它们为t1t2。注意:对于我们的目的,表格不能被定义为const

2)也导出包含两个表“sizeof” S(假设s1s2 2个为size_t变量:size_t s1 = sizeof(t1)size_t s2 = sizeof(t2)

3)立即驱动程序的初始化之前,找出最大的两个表广告将其指针指向struct drm_driverioctls字段。该表将成为您合并的“目标”。当然,struct drm_driver也必须是非const。 您也必须相应地调整num_ioctls字段。

4)通过复制每个具有非NULL func字段的元素合并目标中的第二个表。要测试的元素的数量是sX/sizeof(struct drm_ioctl_descr),其中sX是第二个表的大小(即,如果目标是t2,则为s1,如果目标是t1,则为s2)。

5)现在您可以照常注册驱动程序。

好了,现在一个更清洁,“标准”的解决方案

在“缩小”版本实现所有的可选的ioctl的功能总是返回-EINVAL-EOPNOTSUPP。唯一的缺点是在你的表格中你总是必须提供所有的服务(甚至还没有实现的服务)。

+0

因此,本质上创建一个新的ioctl结构与所有现有的大小加上任何新的,并将该指针传递给.ioctl?是的,这可能工作,但我不确定它是否比只为不存在的代码声明存根函数更清洁;)谢谢 – Usernum0

+0

是的,正确的。而且,是的,它不是很干净。 (唯一的)优势是你不需要通过声明你可能最终需要的所有可能的存根来“预测未来”。 –

+0

是的,有道理。谢谢 – Usernum0