Linux那些事儿 之 戏说USB(21)向左走,向右走

原创 2007年10月08日 10:58:00
他们彼此深信,是瞬间迸发的热情,让他们相遇;
这样的确定是美丽的,但变幻无常更为美丽;
他们素未谋面,所以他们确定,彼此并无任何瓜葛,
但是自街道、楼梯、大堂传来的话语,
他们也许擦肩而过一百万次了吧?
我想问他们是否记得,
在旋转门面对面那一刹,
或是在人群中喃喃道出的“对不起”,
或是在电话的另一端道出的“打错了”,
但是,我早知道答案——
是的,他们并不记得。
他们会很讶异,原来缘份已经戏弄他们多年,
时机尚未成熟,变成他们的命运。
缘份,将他们推进、驱离,阻挡他们的去路,
忍住笑声,
然后闪到一旁。
……
我大学四年的历史是南门外老赵烤肉发展的历史,大一时,只是一间破败的小门面,大二时,地方大了些,大三时,有了金字招牌,装的也像了点样子,大四时,老板娘戴上了傻粗傻粗的金项链,我也在和同学翻了多少次的南门,吃了多少只烤鱼后,灌了多少瓶啤酒后看到了向左走向右走,于是知道了几米,于是少了些烤鱼少了些啤酒,于是看了更多的几米。随后不知道过了多久,看到徐家汇太平洋那里有了几米的小工艺品,于是买了个小记事本做纪念,不是没有其它的卖,而是都太昂贵,几米的漫画人人可以看,几米的工艺品不是人人都可以狠得下心去买。随后不知道又过了多久,有了杜琪峰和韦家辉的向左走向右走,对影片本身并没有多少特别的感觉,但还是知道了梁咏琪翻译的上面的那首诗。
伴着这首诗,让我们回到很久很久以前提到的函数usb_device_match,之前做的所有铺垫,只是为了与它再次相见。过去很久了么?“我们以前都失散过,十三年以后,还不是再遇见?我知道十三年时间很长,但如果十三年后能再见到也很好啊。如果十三年之后见不到,那再过十三年都会见得到也好啊,最重要是见得到。”
540 static int usb_device_match(struct device *dev, struct device_driver *drv)
541 {
542         /* devices and interfaces are handled separately */
543         if (is_usb_device(dev)) {
544
545                 /* interface drivers never match devices */
546                 if (!is_usb_device_driver(drv))
547                         return 0;
548
549                 /* TODO: Add real matching code */
550                 return 1;
551
552         } else {
553                 struct usb_interface *intf;
554                 struct usb_driver *usb_drv;
555                 const struct usb_device_id *id;
556
557                 /* device drivers never match interfaces */
558                 if (is_usb_device_driver(drv))
559                         return 0;
560
561                 intf = to_usb_interface(dev);
562                 usb_drv = to_usb_driver(drv);
563
564                 id = usb_match_id(intf, usb_drv->id_table);
565                 if (id)
566                         return 1;
567
568                 id = usb_match_dynamic_id(intf, usb_drv);
569                 if (id)
570                         return 1;
571         }
572
573         return 0;
574 }
USB的世界里,设备和驱动不会有向左走向右走那般的遗憾,缘分对于我们来说是不可言传的玄机,对于它们来说只是usb_device_match函数的两端。usb_device_match函数为它们指明向左走还是向右走,为它们指明哪个才是它们命中注定的缘,而我们的生活里却不会有这样的一个角色,所以只能有无数的“如果你尝试换个方向,你可能发现,一切原来都不一样。”这样的假设。
543行,第一次遇到这个函数的时候,我说了这里有两条路,一条给USB设备走,一条给USB接口走。前面站在这个路口上,将两条路上可能遇到的主要角色大都介绍了下,它们类似于影片刚开幕的演员列表里的领衔主演,总是会谋杀比较多的菲林。先来看看设备走的这条路,上面儿只有两个函数,好像要平坦的多,可以一下走到底儿的样子。
85 static inline int is_usb_device(const struct device *dev)
86 {
87         return dev->type == &usb_device_type;
88 }
drivers/usb/core/usb.h里定义的这个函数看长相就是个把门儿的角色,好像那些所谓高尚小区的门卫,看到你和你同事分别开一辆宝来和奥拓要进去,气势汹汹的过来告你,宝来才能进,奥拓一边儿去。这个函数就是要告诉你,是usb_device才能打这儿过,否则一边儿该干吗干吗去。但关键问题不是它让不让你进,而是它怎么知道你是不是usb_device,那些门卫起码也得认识啥是宝来啥是奥拓啊,否则直接拿奥拓充宝来不就可以开进去了,现在可是21世纪,假的比真的还流行的时代,塞几块硅胶就成性感女神流行代名词儿了。所以咱们要了解这里是怎么做到真的假不了的,关键就在于这个dev->type,设备的类型,看它是不是等于咱们定义的usb_device_type,也就是说usb设备类型,相等的话,那好说,他躬送你进去,不相等,那就此路不是为你开的,你找别的路吧。usb_device_type在drivers/usb/core/usb.c里定义
195 struct device_type usb_device_type = {
196         .name =         "usb_device",
197         .release =      usb_release_dev,
198 };
它和咱们前面看到的那个usb_bus_type差不多,一个表示总线的类型,一个表示设备的类型,总线有总线的类型,设备有设备的类型,就好像在那个红色中国的时期里,人有很多种成分儿,地主老财就不能混到贫下中农的革命队伍里,当时俺爷爷有几亩薄田,身子骨儿薄,找了几个人帮着种下,结果就成了剥削劳动人民血汗的地主老财,俺姥爷挑着个剃头担子走街串巷,帮人剃头谋几个小钱,结果被打到划成小手工业劳动者,他们顶着成分不好的帽子含辛茹苦好多年,做梦都想与贫下中农靠的近点儿再近点儿,可现在就不同了,谁还愿意去做贫下中农。
假设现在过来一个设备,经过判断,它要走的是设备这条路,可问题是,这个设备的type字段啥时候被初始化成usb_device_type了。嗯,这到是个问题,不过先按下它不表,继续向前走,带着疑问上路。
546行,又见到一个if,一个把门儿的,这年头儿,就是关关卡卡的多,走个人民的公路还有许多人民的收费站来收人民的钱。先看看它是干吗的,收的合理不合理。它就跟在上面的is_usb_device函数后面在drivers/usb/core/usb.h文件里定义
90 /* Do the same for device drivers and interface drivers. */
91
92 static inline int is_usb_device_driver(struct device_driver *drv)
93 {
94         return container_of(drv, struct usbdrv_wrap, driver)->
95                         for_devices;
96 }
这个函数的脸上就写着我是用来判断是不是usb device driver的,那咱们就要问问什么是usb device driver?前面不是一直都是说一个usb接口对应一个usb驱动么?作为一个吃社会主义粮长大的人,我可以负责任的告诉你前面说的一点错都没有,一个接口就是要对应一个usb驱动,可是我们不能只钻到接口的那个口里边儿,我们应该眼光放的更加开阔些,要知道接口在usb的世界里并不是老大,它上边儿还有配置,还有设备,都比它大。每个接口对应了一个独立的功能,是需要专门的驱动来和它交流,但是接口毕竟整体是作为一个usb设备而存在的,设备还可以有不同的配置,我们还可以为设备指定特定的配置,那谁来做这个事情?接口驱动么?它还不够级别,它的级别只够和接口会谈会谈。这个和整个usb设备进行对等交流的光荣任务就交给了struct usb_device _driver,即usb设备驱动,它和usb的接口驱动struct usb_driver都定义在include/linux/usb.h文件里
784 /**
785 * struct usb_driver - identifies USB interface driver to usbcore
786 * @name: The driver name should be unique among USB drivers,
787 *      and should normally be the same as the module name.
788 * @probe: Called to see if the driver is willing to manage a particular
789 *      interface on a device. If it is, probe returns zero and uses
790 *      dev_set_drvdata() to associate driver-specific data with the
791 *      interface. It may also use usb_set_interface() to specify the
792 *      appropriate altsetting. If unwilling to manage the interface,
793 *      return a negative errno value.
794 * @disconnect: Called when the interface is no longer accessible, usually
795 *      because its device has been (or is being) disconnected or the
796 *      driver module is being unloaded.
797 * @ioctl: Used for drivers that want to talk to userspace through
798 *      the "usbfs" filesystem. This lets devices provide ways to
799 *      expose information to user space regardless of where they
800 *      do (or don't) show up otherwise in the filesystem.
801 * @suspend: Called when the device is going to be suspended by the system.
802 * @resume: Called when the device is being resumed by the system.
803 * @pre_reset: Called by usb_reset_composite_device() when the device
804 *      is about to be reset.
805 * @post_reset: Called by usb_reset_composite_device() after the device
806 *      has been reset.
807 * @id_table: USB drivers use ID table to support hotplugging.
808 *      Export this with MODULE_DEVICE_TABLE(usb,...). This must be set
809 *      or your driver's probe function will never get called.
810 * @dynids: used internally to hold the list of dynamically added device
811 *      ids for this driver.
812 * @drvwrap: Driver-model core structure wrapper.
813  * @no_dynamic_id: if set to 1, the USB core will not allow dynamic ids to be
814 *      added to this driver by preventing the sysfs file from being created.
815 * @supports_autosuspend: if set to 0, the USB core will not allow autosuspend
816 *      for interfaces bound to this driver.
817 *
818 * USB interface drivers must provide a name, probe() and disconnect()
819 * methods, and an id_table. Other driver fields are optional.
820 *
821 * The id_table is used in hotplugging. It holds a set of descriptors,
822 * and specialized data may be associated with each entry. That table
823 * is used by both user and kernel mode hotplugging support.
824 *
825 * The probe() and disconnect() methods are called in a context where
826 * they can sleep, but they should avoid abusing the privilege. Most
827 * work to connect to a device should be done when the device is opened,
828 * and undone at the last close. The disconnect code needs to address
829 * concurrency issues with respect to open() and close() methods, as
830 * well as forcing all pending I/O requests to complete (by unlinking
831 * them as necessary, and blocking until the unlinks complete).
832 */
833 struct usb_driver {
834         const char *name;
835
836         int (*probe) (struct usb_interface *intf,
837                       const struct usb_device_id *id);
838
839         void (*disconnect) (struct usb_interface *intf);
840
841         int (*ioctl) (struct usb_interface *intf, unsigned int code,
842                         void *buf);
843
844         int (*suspend) (struct usb_interface *intf, pm_message_t message);
845         int (*resume) (struct usb_interface *intf);
846
847         void (*pre_reset) (struct usb_interface *intf);
848         void (*post_reset) (struct usb_interface *intf);
849
850         const struct usb_device_id *id_table;
851
852         struct usb_dynids dynids;
853         struct usbdrv_wrap drvwrap;
854         unsigned int no_dynamic_id:1;
855         unsigned int supports_autosuspend:1;
856 };
蒲松龄曰,每个男人的心中都有一个狐狸精,每个写usb驱动的人心中都有一个usb_driver。一般来说,我们平时所谓的编写usb驱动指的也就是写usb接口的驱动,需要以一个struct usb_driver结构的对象为中心,以设备的接口提供的功能为基础,开展usb驱动的建设。
834行,name,驱动程序的名字,对应了在/sys/bus/usb/drivers/下面的子目录名称。和我们每个人一样,它只是彼此区别的一个代号,不同的是我们可以有很多人叫张三或者李四,但这里的名字在所有的usb驱动中必须是唯一的。
836行,probe,用来看看这个usb驱动是否愿意接受某个接口的函数。每个驱动自诞生起,它的另一半就已经确定了,这个函数就是来判断哪个才是她苦苦等待的那个他。当然,这个他应该是他们,因为一个驱动往往可以支持多个接口。
839行,disconnect,当接口失去联系,或使用rmmod卸载驱动将它和接口强行分开时这个函数就会被调用。
841行,ioctl,当你的驱动有通过usbfs和用户空间交流的需要的话,就使用它吧。
844行,suspend,845行,resume,分别在设备被挂起和唤醒时使用。
847行,pre_reset,848行,post_reset,分别在设备将要复位(reset)和已经复位后使用。
850行,id_table,驱动支持的所有设备的花名册,所有的三宫六院要想受到宠幸都要在这里登记。驱动就靠这张表儿来识别是不是支持哪个设备接口的,如果不属于这张表,那就躲一边儿去吧。
852行,dynids,支持动态id的。什么是动态id?本来前面刚说每个驱动诞生时她的另一半在id_table里就已经确定了,可是谁规定了女同胞就一定要从一而终了,那是封建旧思想要打到的,听听她们内心的呼声“谁说我白,瘦,漂亮~我就跟他做好朋友”,Greg大侠显然也听到了,于是在一年多前的一个寒风萧萧的日子里平地一声吼,加入了动态id的机制。即使驱动已经加载了,也可以添加新的id给她,只要新id代表的设备存在,对她说“你又白又瘦又漂亮”,她就会和他绑定起来。
怎么添加新的id?到驱动所在的地方瞅瞅,也就是/sys/bus/usb/drivers目录下边儿,那里列出的每个目录就代表了一个usb驱动,随便选一个进去,能够看到一个new_id文件吧,使用echo将厂商和产品id写进去就可以了。看看Greg举的一个例子
echo 0557 2008 > /sys/bus/usb/drivers/foo_driver/new_id
就可以将16进制值0557和2008写到foo_driver驱动的设备id表里取。
853行,drvwrap,这个字段有点意思,struct usbdrv_wrap结构的,也在include/linux/usb.h里定义
774 /**
775 * struct usbdrv_wrap - wrapper for driver-model structure
776 * @driver: The driver-model core driver structure.
777 * @for_devices: Non-zero for device drivers, 0 for interface drivers.
778 */
779 struct usbdrv_wrap {
780         struct device_driver driver;
781         int for_devices;
782 };
近距离观察一下这个结构,它里面内容是比较的贫乏的,只有一个struct device_driver结构的对象和一个for_devices的整型字段。回想一下linux的设备模型,我们的心头就会产生这样的疑问,这里的struct device_driver对象不是应该嵌入到struct usb_driver结构里么,怎么这里又包装了一层?再包装这么一层当然不是为了美观,写代码的哥们儿没这么媚俗,这主要还是因为本来挺单纯的驱动在usb的世界里不得已分成了设备驱动和接口驱动两种,为了区分这两种驱动,就中间加了这么一层,添了个for_devices标志来判断是哪种。大家发现没,之前见识过的结构里,很多不是1就是0的标志使用的是位字段,特别是几个这样的标志放一块儿的时候,而这里的for_devices虽然也只能有两个值,但却没有使用位字段,为什么?简单的说就是这里没那个必要,那些使用位字段的是几个在一块儿,可以节省点儿存储空间,而这里只有这么一个,就是使用位字段也节省不了,就不用多此一举了,这个大家都知道哈,我有点多说了,还是言归整传。其实就这么说为了加个判断标志就硬生生的塞这么一层,还是会有点模糊的,不过,其它字段不敢说,这个drvwrap咱们以后肯定还会遇到它,这里先有个概念,混个面熟,等到再次相遇的那一刻,我保证你会明白它的用心。
854行,no_dynamic_id,可以用来禁止动态id的,设置了之后,驱动就从一而终吧,别七想八想了。
855行,supports_autosuspend,对autosuspend的支持,如果设置为0的话,就不再允许绑定到这个驱动的接口autosuspend。
struct usb_driver结构就暂时了解到这里,咱们再来看看所谓的usb设备驱动与接口驱动到底都有多大的不同。
859 /**
860 * struct usb_device_driver - identifies USB device driver to usbcore
861 * @name: The driver name should be unique among USB drivers,
862 *      and should normally be the same as the module name.
863 * @probe: Called to see if the driver is willing to manage a particular
864 *      device. If it is, probe returns zero and uses dev_set_drvdata()
865 *      to associate driver-specific data with the device. If unwilling
866 *      to manage the device, return a negative errno value.
867 * @disconnect: Called when the device is no longer accessible, usually
868 *      because it has been (or is being) disconnected or the driver's
869 *      module is being unloaded.
870 * @suspend: Called when the device is going to be suspended by the system.
871 * @resume: Called when the device is being resumed by the system.
872 * @drvwrap: Driver-model core structure wrapper.
873 * @supports_autosuspend: if set to 0, the USB core will not allow autosuspend
874 *      for devices bound to this driver.
875 *
876 * USB drivers must provide all the fields listed above except drvwrap.
877 */
878 struct usb_device_driver {
879         const char *name;
880
881         int (*probe) (struct usb_device *udev);
882         void (*disconnect) (struct usb_device *udev);
883
884         int (*suspend) (struct usb_device *udev, pm_message_t message);
885         int (*resume) (struct usb_device *udev);
886         struct usbdrv_wrap drvwrap;
887         unsigned int supports_autosuspend:1;
888 };
就当一个ppmm在走近你,你先用放光的眼睛上上下下的扫一遍,这个usb设备驱动比前面的接口驱动要苗条多了,除了少了很多东西外,剩下的将参数里的struct usb_interface换成struct usb_device后就几乎一摸一样了。友情提醒一下,这里说的是几乎,而不是完全,这是因为probe,它的参数里与接口驱动里的probe相比少了那个设备的花名册,也就是说它不用再去根据花名册来判断是不是愿意接受一个usb设备。那么这意味着什么?是它来者不拒,接受所有的usb设备?还是独锁深闺垂影自恋决绝所有人?当然只会是前者,不然这个usb设备驱动就完全毫无疑义了,这里不像咱们的政府大院儿,容不得毫无作用的东东存在。而且我们在内核里找来找去,也就只能找得着它在drivers/usb/core/generic.c文件里定义了usb_generic_driver这么一个对象
210 struct usb_device_driver usb_generic_driver = {
211         .name = "usb",
212         .probe = generic_probe,
213         .disconnect = generic_disconnect,
214 #ifdef CONFIG_PM
215         .suspend = generic_suspend,
216         .resume = generic_resume,
217 #endif
218         .supports_autosuspend = 1,
219 };
即使这么一个独苗儿,也早在usb_init的895行就已经注册给usb子系统了。那么我们该用什么样的言语表达自己的感受?所谓的usb设备驱动完全就是一个博爱的主儿,我们的core用它来与所有的usb设备进行交流,它们都交流些什么?现在人人都有一颗八卦的心,不过这是后话,我会告诉你的。
不管怎么说,总算是把usb接口的驱动和设备的驱动给过了一下,还是回到这节开头儿的usb_device_match函数,目前为止,设备这条路已经比较清晰了。就是如果设备过来了,走到了设备这条路,然后要判断下驱动是不是设备驱动,是不是针对整个设备的,如果不是的话,对不起,虽然这条路走对了,可是沿这条路,设备找不到对应的驱动,匹配不成功,就直接返回了,那如果驱动也确实是设备驱动那?代码里是直接返回1,表示匹配成功了,没有再花费哪怕多一点儿的精力。
本来这么说应该是可以了,可是我还是忍不住想告诉你,在某年某月某日之前的内核版本里,是没有很明确的struct usb_device_driver这样一个表示usb设备驱动的结构的,而是直接定义了struct device_driver结构类型的一个对象 usb_generic_driver来处理与整个设备相关的事情,相对应的,usb_device_match这个匹配函数也只有简简单单的一条路,在接口和对应的驱动之间做匹配,不用去理会整个usb设备的是是非非。但是在2006年的那个夏天,在我们为卡卡,为舍普琴科,为皮尔洛们疯狂的时候,黄建翔不是一个人在战斗,Alan Stern大侠也不是一个人在战斗,于是内核里多了struct usb_device_driver结构,usb_device_match这里也多了一条给设备走的路。
为什么?杨钰莹唱,我不想说我很困惑。是时候也有必要对usb设备在usb世界里的整个人生旅程做个介绍了。与usb_device_match短暂相遇便要再次分开,不过,最重要的是见得到。 
版权声明:本文为博主原创文章,未经博主允许不得转载。

Linux那些事儿 之 戏说USB(17)向左走,向右走

drivers/usb/core/driver.c static int usb_device_match(struct device *dev, struct device_driver *drv...
  • zhqh100
  • zhqh100
  • 2015年03月25日 11:38
  • 503

向左走,向右走

她决定离开这个荒寒的城市,他决定到一个阳光灿烂的地方去旅行。拖着行李的他们在喷水池再次相遇。天空开始变得晴朗,远方飘来平安夜悠扬的歌声。 《向左走,向右走》是都市里的故事,是一本几米献给那些注定相遇...
  • huooy5555oy4
  • huooy5555oy4
  • 2014年04月24日 16:00
  • 143

Linux那些事儿 之 戏说USB(5)我是谁

我是谁?USB一遍一遍问着自己,当然它不会真的是一颗树。USB只是Linux庞大家族里的一个小部落,host controller是它们的族长,族里的每个USB设备都需要被系统识别,被我们识别。虽然清...
  • zhqh100
  • zhqh100
  • 2015年03月24日 11:05
  • 400

Linux那些事儿 之 戏说USB(21)设备的生命线(四)

继续urb urb_list,还记得每个端点都会有的那个urb队列么?那个队列就是由这里的urb_list一个一个的链接起来的。HCD每收到一个urb,就会将它添加到这个urb指定的那个端点的urb...
  • zhqh100
  • zhqh100
  • 2015年03月25日 16:40
  • 1032

向左走向右走: InnoDB or MyISAM

欢迎访问个人原创网址 : http://www.phpthinking.com/archives/456 MyISAM 是MySQL中默认的存储引擎,一般来说不是有太多人关心这个东西。决定使...
  • Ksly_Tkol
  • Ksly_Tkol
  • 2014年09月27日 23:12
  • 1059

Linux那些事儿 之 戏说USB(34)接口的驱动

从上节的上节我们已经知道,usb_generic_driver在自己的生命线里,以一己之力将设备的各个接口送给了linux的设备模型,让usb总线的match函数,也就是usb_device_matc...
  • zhqh100
  • zhqh100
  • 2015年03月28日 21:06
  • 441

Linux那些事儿 之 戏说USB(4)最终奥义

一个完整的USB系统应该实现上面图里的各个部分,图里主要显示了四个层次,USB物理设备(USB Physical Device)、客户软件(Client SW)、USB系统软件(USB System ...
  • zhqh100
  • zhqh100
  • 2015年03月24日 10:40
  • 531

Linux那些事儿 之 戏说USB(16)配置

接着看usb设备的配置吧,在include/linux/usb.h里定义 struct usb_host_config { struct usb_config_descriptor desc; ...
  • zhqh100
  • zhqh100
  • 2015年03月25日 11:04
  • 924

Linux那些事儿 之 戏说USB(9)面纱

int retval; if (nousb) { pr_info("%s: USB support disabled\n", usbcore_name); return 0; }第2行知道...
  • zhqh100
  • zhqh100
  • 2015年03月24日 15:30
  • 613

Linux那些事儿 之 戏说USB(8)从这里开始

USB core从USB子系统的初始化开始,我们也需要从那里开始,它们在文件drivers/usb/core/usb.c 938 subsys_initcall(usb_init); 939 modu...
  • zhqh100
  • zhqh100
  • 2015年03月24日 14:33
  • 640
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux那些事儿 之 戏说USB(21)向左走,向右走
举报原因:
原因补充:

(最多只允许输入30个字)