Scsi - Index of
Scsi - Index of Scsi - Index of
功课,正因为如此,作为一个实际的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 *
- Page 1 and 2: 摘要 ............................
- Page 3 and 4: 迷雾重重的Bulk 传输(二)....
- Page 5 and 6: 引子 也许是在复旦养成了
- Page 7 and 8: usb.h datafab.h dpcm.h initializers
- Page 9 and 10: 的Linux 内核划分为许许多
- Page 11 and 12: 目录下执行make 了.Ok,make 之
- Page 13 and 14: 只 是一个usb 接口.这些口
- Page 15 and 16: 中也定义了这么一些数据
- Page 17: 511 * @driver: the driver model cor
- Page 21 and 22: 91 * construct these entries. Each
- Page 23 and 24: 324 struct usb_host_config *actconf
- Page 25 and 26: 22 88 * @class_dev: driver model's
- Page 27 and 28: 必须给各个地方取名,完了
- Page 29 and 30: 26 136 trans_cmnd transport; /* tra
- Page 31 and 32: 944 init_MUTEX_LOCKED(&(us->sema));
- Page 33 and 34: 147 #if !defined(CONFIG_BLK_DEV_UB)
- Page 35 and 36: 124 #define USB_DEVICE_ID_MATCH_DEV
- Page 37 and 38: intf 来代替. us 之所以重要,
- Page 39 and 40: 睡眠,那就得用GPF_ATOMIC,这
- Page 41 and 42: 504 if (msg >= 0 && !(unusual_dev->
- Page 43 and 44: 179 } 180 181 static struct us_unus
- Page 45 and 46: 711 /* Submitted by Hartmut Wahl */
- Page 47 and 48: 3. useProtocol 为US_SC_DEVICE, use
- Page 49 and 50: Bus 004 Device 001: ID 0000:0000 Bu
- Page 51 and 52: 993 result = get_pipes(us); 994 if
- Page 53 and 54: 631 us->transport_reset = usb_stor_
- Page 55 and 56: 659 us->max_lun = 0; 660 break; 661
- Page 57 and 58: 740 /* Calculate and store the pipe
- Page 59 and 60: storage 会有两个bulk 端点,用
- Page 61 and 62: 比如说,复旦大学,有一个主
- Page 63 and 64: 1079 #define PIPE_ISOCHRONOUS 0 108
- Page 65 and 66: 782 us->unusual_dev->initFunction(u
- Page 67 and 68: 630 * each frame is in the fields o
功课,正因为如此,作为一个实际的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 = {