Scsi - Index of

Scsi - Index of Scsi - Index of

07.06.2013 Views

功课,正因为如此,作为一个实际的usb设备驱动,它在初始化阶段所要做的事情就很少,很简单 了, 直接调用usb_register 即可.事实上,没有人是理所当然应该为你做什么的,但usb core 这么 做 了.所以每一个写usb 设备驱动的人应该铭记,usb device driver 绝不是一个人在工作,在他身 后,是usb core 所提供的默默无闻又不可或缺的支持. 总线,设备,和驱动(下) bus 上的两张链表记录了每一个device 和driver,那么device 和driver 这两者之间又是如何联系起来 的 呢?此刻,必须抛出这样一个问题,先有device 还是driver? 很久很久以前,在那激情燃烧的岁月里,先有的是device,每一个要用的device 在计算机启动之前就已经插 好了,插放在它应该在的位置上,然后计算机启动,然后操作系统开始初始化,总线开始扫描设备,每找到一个 设备,就为其申请一个struct device 结构,并且挂入总线中的devices 链表中来,然后每一个驱动程序开 始 初始化,开始注册其struct device_driver 结构,然后它去总线的devices 链表中去寻找(遍历),去寻找每 一个还没有绑定driver 的设备,即struct device 中的struct device_driver 指针仍为空的设备,然后它 会 去观察这种设备的特征,看是否是他所支持的设备,如果是,那么调用一个叫做device_bind_driver 的函 数, 然后他们就结为了秦晋之好.换句话说,把struct device 中的struct device_driver driver 指向这个 driver,而struct device_driver driver 把struct device 加入他的那张struct list_head devices 链表 中来.就这样,bus,device,和driver,这三者之间或者说他们中的两两之间,就给联系上了.知道其中之一,就 能找到另外两个.一荣俱荣,一损俱损. 但现在情况变了,在这红莲绽放的日子里,在这樱花伤逝的日子里,出现了一种新的名词,叫热插拔.device 可以在计算机启动以后在插入或者拔出计算机了.因此,很难再说是先有device 还是先有driver 了.因为 都 有可能.device 可以在任何时刻出现,而driver 也可以在任何时刻被加载,所以,出现的情况就是,每当一个 struct device 诞生,它就会去bus 的drivers 链表中寻找自己的另一半,反之,每当一个一个struct device_driver 诞生,它就去bus 的devices 链表中寻找它的那些设备.如果找到了合适的,那么ok,和之 前 那种情况一下,调用device_bind_driver 绑定好.如果找不到,没有关系,等待吧,等到昙花再开,等到风景 看 透,心中相信,这世界上总有一个人是你所等的,只是还没有遇到而已. 好,继续,事实上,完善这个三角关系,正是每一个设备驱动初始化阶段所完成的重要使命之一.让我们还是回 到代码中来,usb_register 这个函数调用是调用了,但是传递给他的参数是什么呢? 我们注意到,那句调用是这样子的, 1064 /* register the driver, return usb_register return code if error */ 1065 retval = usb_register(&usb_storage_driver); 是的,传递了一个叫做usb_storage_driver 的家伙,这是什么?同一文件 中,drivers/usb/storage/usb.c: 16 232 struct usb_driver usb_storage_driver = {

233 .owner = THIS_MODULE, 234 .name = "usb-storage", 235 .probe = storage_probe, 236 .disconnect = storage_disconnect, 237 .id_table = storage_usb_ids, 238 }; 可以看到这里定义了一个struct usb_driver 的结构体变量,usb_storage_driver,关于usb_driver 我 们 上节已经说过了,当时主要说的是其中的成员driver,而眼下要讲的则是另外几个成员.首先,.owner 和.name 这两个没啥好多说的,owner 这玩艺是用来给模块计数的,每个模块都这么用,赋值总是 THIS_MODULE,而name 就是这个模块的名字,usb core 会处理它,所以如果这个模块正常被加载了的 话, 使用lsmod 命令能看到一个叫做usb-storage 的模块名.重点要讲一讲,.probe 和.disconnect 以及这 个 id_table. 我是谁的他? probe,disconnect,id_table,这三个咚咚中首先要登场亮相的是id_table,它是干嘛用的呢? 我们说过,一个device 只能绑定一个driver,但driver 并非只能支持一种设备,道理很简单,比如 我有两块U盘,那么我可以一起都插入,但是我只需要加载一个模块,usb-storage,没听说过插入 两块U 盘就得加载两次驱动程序的,除非这两块U 盘本身就得使用不同的驱动程序.也正是因为 一个模块可以被多个设备共用,才会有模块计数这么一个说法. ok,既然一个driver 可以支持多个device,那么当发现一个device 的时候,如何知道哪个driver 才是她的Mr.Right 呢?这就是id_table 的用处,让每一个struct usb_driver 准备一张表,里边 注明该driver 支持哪些设备,这总可以了吧.如果你这个设备属于这张表里的,那么ok,绑定吧,如 果不属于这张表里的,那么不好意思,您请便.哪凉快上哪去. 来自struct usb_driver 中的id_table, const struct usb_device_id *id_table; 实际上是一个指针,一个struct usb_device_id 结构体的指针,当然赋了值以后就是代表一个数 组名了,正如我们在定义struct usb_driver usb_storage_driver 中所赋的值那 样,.id_table=storage_usb_ids,那好,我们来看一下usb_device_id 这究竟是怎样一个结构 体. struct usb_device_id 来自include/linux/mod_devicetable.h, 40 /* 41 * Device table entry for "new style" table-driven USB drivers. 42 * User mode code can read these tables to choose which modules to load. 43 * Declare the table as a MODULE_DEVICE_TABLE. 44 * 45 * A probe() parameter will point to a matching entry from this table. 46 * Use the driver_info field for each match to hold information tied 17 47 * to that match: device quirks, etc. 48 *

功课,正因为如此,作为一个实际的usb设备驱动,它在初始化阶段所要做的事情就很少,很简单<br />

了,<br />

直接调用usb_register 即可.事实上,没有人是理所当然应该为你做什么的,但usb core 这么<br />

做<br />

了.所以每一个写usb 设备驱动的人应该铭记,usb device driver 绝不是一个人在工作,在他身<br />

后,是usb core 所提供的默默无闻又不可或缺的支持.<br />

总线,设备,和驱动(下)<br />

bus 上的两张链表记录了每一个device 和driver,那么device 和driver 这两者之间又是如何联系起来<br />

的<br />

呢?此刻,必须抛出这样一个问题,先有device 还是driver?<br />

很久很久以前,在那激情燃烧的岁月里,先有的是device,每一个要用的device 在计算机启动之前就已经插<br />

好了,插放在它应该在的位置上,然后计算机启动,然后操作系统开始初始化,总线开始扫描设备,每找到一个<br />

设备,就为其申请一个struct device 结构,并且挂入总线中的devices 链表中来,然后每一个驱动程序开<br />

始<br />

初始化,开始注册其struct device_driver 结构,然后它去总线的devices 链表中去寻找(遍历),去寻找每<br />

一个还没有绑定driver 的设备,即struct device 中的struct device_driver 指针仍为空的设备,然后它<br />

会<br />

去观察这种设备的特征,看是否是他所支持的设备,如果是,那么调用一个叫做device_bind_driver 的函<br />

数,<br />

然后他们就结为了秦晋之好.换句话说,把struct device 中的struct device_driver driver 指向这个<br />

driver,而struct device_driver driver 把struct device 加入他的那张struct list_head devices 链表<br />

中来.就这样,bus,device,和driver,这三者之间或者说他们中的两两之间,就给联系上了.知道其中之一,就<br />

能找到另外两个.一荣俱荣,一损俱损.<br />

但现在情况变了,在这红莲绽放的日子里,在这樱花伤逝的日子里,出现了一种新的名词,叫热插拔.device<br />

可以在计算机启动以后在插入或者拔出计算机了.因此,很难再说是先有device 还是先有driver 了.因为<br />

都<br />

有可能.device 可以在任何时刻出现,而driver 也可以在任何时刻被加载,所以,出现的情况就是,每当一个<br />

struct device 诞生,它就会去bus 的drivers 链表中寻找自己的另一半,反之,每当一个一个struct<br />

device_driver 诞生,它就去bus 的devices 链表中寻找它的那些设备.如果找到了合适的,那么ok,和之<br />

前<br />

那种情况一下,调用device_bind_driver 绑定好.如果找不到,没有关系,等待吧,等到昙花再开,等到风景<br />

看<br />

透,心中相信,这世界上总有一个人是你所等的,只是还没有遇到而已.<br />

好,继续,事实上,完善这个三角关系,正是每一个设备驱动初始化阶段所完成的重要使命之一.让我们还是回<br />

到代码中来,usb_register 这个函数调用是调用了,但是传递给他的参数是什么呢?<br />

我们注意到,那句调用是这样子的,<br />

1064 /* register the driver, return usb_register return code if error */<br />

1065 retval = usb_register(&usb_storage_driver);<br />

是的,传递了一个叫做usb_storage_driver 的家伙,这是什么?同一文件<br />

中,drivers/usb/storage/usb.c:<br />

16<br />

232 struct usb_driver usb_storage_driver = {

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!