pci_device_id,PCI设备类型的标识符。在include/linux/mod_devicetable.h头文件中定义。
struct pci_device_id {
        __u32 vendor, device;           /* Vendor and device ID or PCI_ANY_ID*/
        __u32 subvendor, subdevice;     /* Subsystem ID's or PCI_ANY_ID */
        __u32 class, class_mask;        /* (class,subclass,prog-if) triplet */
        kernel_ulong_t driver_data;     /* Data private to the driver */
};
PCI设备的vendor、device和class的值都是预先定义好的,通过这些参数可以唯一确定设备厂商和设备类型。这些PCI设备的标准值在include/linux/pci_ids.h头文件中定义。
pci_device_id需要导出到用户空间,使模块装载系统在装载模块时知道什么模块对应什么硬件设备。宏MODULE_DEVICE_TABLE()完成该工作。
设备id一般用数组形式。如:

  • static struct pci_device_id rtl8139_pci_tbl[] = {
            {0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
            ....
    };
    MODULE_DEVICE_TABLE (pci, rtl8139_pci_tbl);
  • static struct pci_device_id e1000_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1000) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1001) },
        {0,}
    };
    MODULE_DEVICE_TABLE (pci, e1000_pci_tbl);

该语句创建一个名为__mod_pci_device_table的局部变量,只想struct pci_device_id数组。在稍后的内核构建过程中,depmod程序在所有的模块中搜索符号__mod_pci_device_table。如果找到了该符号,它把数据从该模块中抽出,添加到文件/lib/module/KERNEL_VERSION/module.pcimap中。当depmod结束之后,内核模块支持的所有PCI设备连同他们的模块名都在改文件中被列出。当内核告知热插拔系统一个新的PCI设备已经被发现时,热插拔系统使用module.pcimap文件来寻找要加载的适当的驱动程序。

MODULE_DEVICE_TABLE的第一个参数是设备的类型,如果是USB设备,那自然是usb(如果是PCI设备,那将是pci,这两个子系统用同一个宏来注册所支持的设备)。后面一个参数是设备表,这个设备表的最后一个元素是空的,用于标识结束。例:假如代码定义了USB_SKEL_VENDOR_ID是 0xfff0,USB_SKEL_PRODUCT_ID是0xfff0,也就是说,当有一个设备接到集线器时,usb子系统就会检查这个设备的 vendor ID和product ID,如果他们的值是0xfff0时,那么子系统就会调用这个模块作为设备的驱动。

http://www.ibm.com/developerworks/cn/linux/l-usb/index2.html

当usb设备插入时,为了使linux-hotplug(Linux中PCI、USB等设备热插拔支持)系统自动装载驱动程序,你需要创建一个MODULE_DEVICE_TABLE。代码如下(这个模块仅支持某一特定设备):

/* table of devices that work with this driver */
static struct usb_device_id skel_table [] = {
{ USB_DEVICE(USB_SKEL_VENDOR_ID,
USB_SKEL_PRODUCT_ID) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, skel_table);

USB_DEVICE宏利用厂商ID和产品ID为我们提供了一个设备的唯一标识。当系统插入一个ID匹配的USB设备到USB总线时,驱动会在USB core中注册。驱动程序中probe 函数也就会被调用。usb_device 结构指针、接口号和接口ID都会被传递到函数中。

static void * skel_probe(struct usb_device *dev,
unsigned int ifnum, const struct usb_device_id *id)

驱动程序需要确认插入的设备是否可以被接受,如果不接受,或者在初始化的过程中发生任何错误,probe函数返回一个NULL值。否则返回一个含有设备驱动程序状态的指针。通过这个指针,就可以访问所有结构中的回调函数。

MODULE_DEVICE_TABLE 的作用的更多相关文章

  1. Linux内核模块编程与内核模块LICENSE -《具体解释(第3版)》预读

    Linux内核模块简单介绍 Linux内核的总体结构已经很庞大,而其包括的组件或许多.我们如何把须要的部分都包括在内核中呢?一种方法是把全部须要的功能都编译到Linux内核.这会导致两个问题.一是生成 ...

  2. linux 下各个头文件的作用[典]

    linux 下各个头文件的作用   2.6.30.4的头文件的位置和2.6.25.8的不一样,除去内核源码下的include目录外, 在arch/arm/mach-s3c2410/和arch/arm/ ...

  3. MODULE_DEVICE_TABLE的理解【转】

    本文转载自:http://blog.csdn.net/sidely/article/details/39666471 在Linux IIC驱动中看到一段代码: static struct platfo ...

  4. if __name__== "__main__" 的意思(作用)python代码复用

    if __name__== "__main__" 的意思(作用)python代码复用 转自:大步's Blog  http://www.dabu.info/if-__-name__ ...

  5. (转载)linux下各个文件夹的作用

    linux下的文件结构,看看每个文件夹都是干吗用的/bin 二进制可执行命令 /dev 设备特殊文件 /etc 系统管理和配置文件 /etc/rc.d 启动的配置文件和脚本 /home 用户主目录的基 ...

  6. github中的watch、star、fork的作用

    [转自:http://www.jianshu.com/p/6c366b53ea41] 在每个 github 项目的右上角,都有三个按钮,分别是 watch.star.fork,但是有些刚开始使用 gi ...

  7. web.xml中welcome-file-list的作用

    今天尝试使用struts2+ urlrewrite+sitemesh部署项目,结果发现welcome-file-list中定义的欢迎页不起作用: <welcome-file-list> & ...

  8. web.xml中load-on-startup的作用

    如下一段配置,熟悉DWR的再熟悉不过了:<servlet>   <servlet-name>dwr-invoker</servlet-name>   <ser ...

  9. SQLSERVER中NULL位图的作用

    SQLSERVER中NULL位图的作用 首先感谢宋沄剑提供的文章和sqlskill网站:www.sqlskills.com,看下面文章之前请先看一下下面两篇文章 SQL Server误区30日谈-Da ...

随机推荐

  1. Mac下GitHub以及GitHub Desktop使用实战

    Hub是一个面向开源及私有软件项目的托管平台.开源代码库以及版本控制系统,因为只支持 Git 作为唯一的版本库格式进行托管,故名 GitHub.通常在Windows下使用GitHub的教程是非常多的, ...

  2. Xcode的路径小知识纪录

    Xcode的路径小知识纪录 模拟器应用程序的安装路径 /Users/aplle/资源库/Application Support/iPhone Simulator/7.1/Applications Xc ...

  3. js中用变量作为$()内id的值、动态获取id,及获取其下面的class元素

    在开发中写了一个公共方法对模板tpl进行渲染,然而他的id是通过变量传值过来的,在网上查阅后找到解决方法,写法如下: $("#"+tplVal).html(html); 用$(&q ...

  4. Solidity语言基础 和 Etherum ERC20合约基础

    1. 类型只能从第一次赋值中推断出来,因此以下代码中的循环是无限的,  小. for (var i = 0; i < 2000; i++) { ... } --- Solidity Types ...

  5. html标签三

    1.下拉框和下拉表框 <select name="" id="" multiple> <option value="xx" ...

  6. js 立即执行函数

    1.我们首先要搞明白:函数表达式和函数声明的区别. 函数表达式:既可以为匿名函数也可以有函数名,但是调用的时候都是通过函数左边的变量func来调用 var func = function(){ ale ...

  7. maven 单元测试 ( http://www.cnblogs.com/qinpengming/p/5225380.html )

     对junit单元测试的报告:类似这样的结果 ------------------------------------------------------- T E S T S ----------- ...

  8. fedora 使用

    我们在这篇指南中将介绍安装Fedora 23工作站版本后要完成的一些实用操作,以便用起来更爽. 1.更新Fedora 23程序包 哪怕你可能刚刚安装/升级了Fedora 23,仍很可能会有需要更新的程 ...

  9. 采用JavaMelody监控Tomcat服务——安装手册

    #1.获取安装包 .zip mv probe.war <tomcat dir>/webapps #3.设置tomcat用户信息 vi <tomcat dir>/conf/tom ...

  10. &和&&的区别是什么

    1)&是按位与操作符,a&b是把a和b都转换成二进制数后,然后再进行按位与的运算.&&是逻辑与运算符,a&&b就是当且仅当两个操作数都为true时,其结 ...