【转】Linux那些事儿 之 戏说USB(大结局)还是那个match

来源:互联网 发布:python decode 参数 编辑:程序博客网 时间:2024/04/30 08:04

从上次在几米的向左走向右走遇到usb总线的那个match函数 usb_device_match()开始到现在,遇到了设备,遇到了设备驱动,遇到了接口,也遇到了接口驱动,期间还多次遇到 usb_device_match(),又多次与它擦肩而过,“我们以前都失散过,十三年以后,还不是再遇见?”

其 实每个人都有一条共同之路,与正义和良知初恋,失身于上学,嫁给了钱,被世俗包养。每个设备也都有一条共同之路,与hub初恋,失身于 usb_generic_driver,嫁给了接口驱动,被usb总线保养。人类从没有真正自由过,少年时我们坐在课室里动弹不得,稍后又步入办公室,无 论外头阳光多好,还得超时加班,终于铅华洗尽,遍历人间沧桑,又要为子女忙碌,有几个人可以真正做自己想做的事?设备也没有真正自由过,刚开始时在 Default状态动弹不得,稍后步入Address,无论外头风光多好,都得与usb_generic_driver长厢厮守,没得选择,终于达到了 Configured,又必须为自己的接口殚精竭虑,以便usb_device_match()能够为它们找一个好人家。
不管怎么说,在这里我们会再次与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 }
设 备那条路已经走过了,现在走走552行接口那条路。558行,接口驱动的for_devices在usb_register _driver()里被初始化为0,所以这个把门儿的会痛痛快快的放行,继续往下走,561行,遇到一对儿似曾相识的宏to_usb_interface 和to_usb_driver,之所以说似曾相识,是因为早先已经遇到过一对儿to_usb_device和to_usb_device_driver。 这两对儿一对儿用于接口和接口驱动,一对儿用于设备和设备驱动,意思都很直白,还是看看include/linux/usb.h里的定义
159 #define to_usb_interface(d) container_of(d, struct usb_interface, dev)
857 #define to_usb_driver(d) container_of(d, struct usb_driver, drvwrap.driver)
再 往下走,就是两个函数usb_match_id和usb_match_dynamic_id,它们都是用来完成实际的匹配工作的,只不过前一个是从驱动的 id_table里找,看接口是不是被驱动所支持,后一个是从驱动的动态id链表dynids里找。就像女人分结婚的女人与不结婚的两种,男人分自愿结婚 与被迫结婚的两种,驱动的id表也分id_table和dynids两种。显然564~570这几行的意思就是将id_table放在一个比较高的优先级 的位置,从它里面找不到接口了才再从动态id链表里找。
当时讲到struct usb_driver结构的时候并没有详细讲它里面表示动态id的那个结构体struct usb_dynids,但是做人要厚道,不能太CCTV,所以现在补充一下,这个结构的定义在include/linux/usb.h里
760 struct usb_dynids {
761         spinlock_t lock;
762         struct list_head list;
763 };
它只有两个字段,一把锁,一个链表,都是在usb_register _driver()里面初始化的,这个list是驱动动态id链表的头儿,它里面的每个节点是用另外一个结构struct usb_dynid来表示
765 struct usb_dynid {
766         struct list_head node;
767         struct usb_device_id id;
768 };
这 里面就出现了一个struct usb_device_id结构体,也就是设备的id,每次添加一个动态id,就会向驱动的动态id链表里添加一个struct usb_dynid结构体。你现在应该可以想像到usb_match_id和usb_match_dynamic_id这两个函数除了查找的地方不一样, 其它应该是没什么差别的。所以接下来咱们只深入探讨一下usb_match_id函数,至于usb_match_dynamic_id(),如果你实在无 聊暂时找不到人生目标也可以去看看。它们都在driver.c里定义
447 /**
448 * usb_match_id - find first usb_device_id matching device or interface
449 * @interface: the interface of interest
450 * @id: array of usb_device_id structures, terminated by zero entry
451 *
452 * usb_match_id searches an array of usb_device_id's and returns
453 * the first one matching the device or interface, or null.
454 * This is used when binding (or rebinding) a driver to an interface.
455 * Most USB device drivers will use this indirectly, through the usb core,
456 * but some layered driver frameworks use it directly.
457 * These device tables are exported with MODULE_DEVICE_TABLE, through
458 * modutils, to support the driver loading functionality of USB hotplugging.
459 *
460 * What Matches:
461 *
462 * The "match_flags" element in a usb_device_id controls which
463 * members are used. If the corresponding bit is set, the
464 * value in the device_id must match its corresponding member
465 * in the device or interface descriptor, or else the device_id
466 * does not match.
467 *
468 * "driver_info" is normally used only by device drivers,
469 * but you can create a wildcard "matches anything" usb_device_id
470 * as a driver's "modules.usbmap" entry if you provide an id with
471 * only a nonzero "driver_info" field. If you do this, the USB device
472 * driver's probe() routine should use additional intelligence to
473 * decide whether to bind to the specified interface.
474 *
475 * What Makes Good usb_device_id Tables:
476 *
477 * The match algorithm is very simple, so that intelligence in
478 * driver selection must come from smart driver id records.
479 * Unless you have good reasons to use another selection policy,
480 * provide match elements only in related groups, and order match
481 * specifiers from specific to general. Use the macros provided
482 * for that purpose if you can.
483 *
484 * The most specific match specifiers use device descriptor
485 * data. These are commonly used with product-specific matches;
486 * the USB_DEVICE macro lets you provide vendor and product IDs,
487 * and you can also match against ranges of product revisions.
488 * These are widely used for devices with application or vendor
489 * specific bDeviceClass values.
490 *
491 * Matches based on device class/subclass/protocol specifications
492 * are slightly more general; use the USB_DEVICE_INFO macro, or
493 * its siblings. These are used with single-function devices
494 * where bDeviceClass doesn't specify that each interface has
495 * its own class.
496 *
497 * Matches based on interface class/subclass/protocol are the
498 * most general; they let drivers bind to any interface on a
499 * multiple-function device. Use the USB_INTERFACE_INFO
500 * macro, or its siblings, to match class-per-interface style
501 * devices (as recorded in bInterfaceClass).
502 *
503 * Note that an entry created by USB_INTERFACE_INFO won't match
504 * any interface if the device class is set to Vendor-Specific.
505 * This is deliberate; according to the USB spec the meanings of
506 * the interface class/subclass/protocol for these devices are also
507 * vendor-specific, and hence matching against a standard product
508 * class wouldn't work anyway. If you really want to use an
509 * interface-based match for such a device, create a match record
510 * that also specifies the vendor ID. (Unforunately there isn't a
511 * standard macro for creating records like this.)
512 *
513 * Within those groups, remember that not all combinations are
514 * meaningful. For example, don't give a product version range
515 * without vendor and product IDs; or specify a protocol without
516 * its associated class and subclass.
517 */
518 const struct usb_device_id *usb_match_id(struct usb_interface *interface,
519                                          const struct usb_device_id *id)
520 {
521         /* proc_connectinfo in devio.c may call us with id == NULL. */
522         if (id == NULL)
523                 return NULL;
524
525         /* It is important to check that id->driver_info is nonzero,
526            since an entry that is all zeroes except for a nonzero
527            id->driver_info is the way to create an entry that
528            indicates that the driver want to examine every
529            device and interface. */
530         for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
531                id->driver_info; id++) {
532                 if (usb_match_one_id(interface, id))
533                         return id;
534         }
535
536         return NULL;
537 }
522行,参数id指向的是驱动的那个设备花名册,即id_table,如果它为空,那肯定就是不可能会匹配成功了,这样的驱动就如usb驱动里的修女,起码表面上是对所有的接口不感兴趣的。
530 行,你可能会问为什么这里不详细介绍一下struct usb_device_id结构,主要是《我是U盘里》已经说得非常之详细和有趣了,俺这里实在没必要耗费时间和口舌去说它,另一方面,它里面的那些元素 都相当的暴露和直白,我相信依你的智商一眼就能明白个八九不离十,借那位亚裔的色情女星宫城咪咪竞选美州长时的竞选口号给struct usb_device_id结构用用:我始终暴露和诚实。
那 么这个for循环就是轮询设备花名册里的每个设备,如果符合了条件id->idVendor || id->bDeviceClass || id->bInterfaceClass || id->driver_info,就调用函数usb_match_one_id做深层次的匹配。本来,在动态id出现之前这个地方是没有 usb_match_one_id这么一个函数的,所有的匹配都在这个for循环里直接做了,但是动态id出现之后,同时出现了前面提到的 usb_match_dynamic_id函数,要在动态id链表里做同样的匹配,这就要避免代码重复,于是就将那些重复的代码提出来,组成了 usb_match_one_id函数。
for 循环的条件里可能出现的一种情况是,id的其它字段都为空,只有driver_info字段有实实在在的内容,这种情况下匹配是肯定成功的,不信的话等会 儿你可以看usb_match_one_id(),这种驱动对usb接口来说是比较随便的那种,不管啥接口都能和她对得上眼,为什么会出现这种情况?咱们 已经知道,匹配成功后,接着就会调用驱动自己的probe函数,驱动在它里面还会对接口做进一步的检查,如果真出现了这里所说的情况,意思也就是驱动将所 有的检查接口,和接口培养感情的步骤都揽在自己的probe函数里了,它会在那个时候将driver_info的内容取出来,然后想怎么处理就怎么处理, 本来么,id里边儿的driver_info就是给驱动保存数据用的。
还是看看usb_match_one_id()究竟是怎么匹配的吧,定义也在driver.c里
404 /* returns 0 if no match, 1 if match */
405 int usb_match_one_id(struct usb_interface *interface,
406                      const struct usb_device_id *id)
407 {
408         struct usb_host_interface *intf;
409         struct usb_device *dev;
410
411         /* proc_connectinfo in devio.c may call us with id == NULL. */
412         if (id == NULL)
413                 return 0;
414
415         intf = interface->cur_altsetting;
416         dev = interface_to_usbdev(interface);
417
418         if (!usb_match_device(dev, id))
419                 return 0;
420
421         /* The interface class, subclass, and protocol should never be
422          * checked for a match if the device class is Vendor Specific,
423          * unless the match record specifies the Vendor ID. */
424         if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&
425                         !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
426                         (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |
427                                 USB_DEVICE_ID_MATCH_INT_SUBCLASS |
428                                 USB_DEVICE_ID_MATCH_INT_PROTOCOL)))
429                 return 0;
430
431         if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
432             (id->bInterfaceClass != intf->desc.bInterfaceClass))
433                 return 0;
434
435         if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
436             (id->bInterfaceSubClass != intf->desc.bInterfaceSubClass))
437                 return 0;
438
439         if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
440             (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
441                 return 0;
442
443         return 1;
444 }
412行,这个id指向的就是驱动id_table里的某一项了。
415行,获得接口采用的设置,设置里可是有接口描述符的,要匹配接口和驱动,接口描述符里的信息是必不可少的。
416行,从接口的struct usb_interface结构体获得usb设备的struct usb_device结构体,interface_to_usbdev的定义在include/linux/usb.h里
160 #define interface_to_usbdev(intf) /
161         container_of(intf->dev.parent, struct usb_device, dev)
usb 设备和它里面的接口是怎么关联起来的呢?就是上面的那个parent,接口的parent早在usb_generic_driver的 generic_probe函数向设备模型提交设备里的每个接口的时候就被初始化好了,而且指定为接口所在的那个usb设备。这么一回顾, interface_to_usbdev的意思就很明显了,什么事就怕你去回忆,从这个角度看,金三顺的那句“回忆是没有任何力量的。”和整部电视剧一 样,纯粹就是瞎扯淡。
418 行,这里又冒出来个usb_match_device(),接口和驱动之间的感情还真不是那么好培养的,一层一层的,真是应了加菲猫的那句名言:爱情就象 照片,需要大量的暗房时间来培养。不过既然存在就是有来头的,它也不会毫无根据的出现,这里虽说是在接口和接口驱动之间匹配,但是接口的parent也是 必须要符合条件的,这即合情也合理啊,你好不容易鼓足了勇气向一个走在大街上一见钟情的mm表白,你觉得mm的第一反应是什么?依照行规,很可能就是:你 爸是干吗的?是大款么?是当官的么?你要说不,那就别等第二反应了。所以说接口要想得到驱动的芳心,自己的parent符合驱动的条件也是很重要的, usb_match_device()就是专门来匹配接口parent的。同样在driver.c里定义
368 /* returns 0 if no match, 1 if match */
369 int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)
370 {
371         if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
372             id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
373                 return 0;
374
375         if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
376             id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
377                 return 0;
378
379         /* No need to test id->bcdDevice_lo != 0, since 0 is never
380            greater than any unsigned number. */
381         if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
382             (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))
383                 return 0;
384
385         if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
386             (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
387                 return 0;
388
389         if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
390             (id->bDeviceClass != dev->descriptor.bDeviceClass))
391                 return 0;
392
393         if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
394             (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass))
395                 return 0;
396
397         if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
398             (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
399                 return 0;
400
401         return 1;
402 }
这 个函数采用了排比的修辞手法,美观的同时也增加了可读性。这一个个的if条件里都有一部分是将id的match_flags和一个宏相与,所以弄明白 match_flags的意思就很关键。罢了罢了,本来说不再浪费口舌在id里的那些字段上了,不过为了减少你蓦然回首的次数,这里再说一下这个 match_flags。
驱 动的花名册里每个设备都对应了一个struct usb_device_id结构体,这个结构体里有很多字段,都是驱动设定好的条条框框,接口必须完全满足里面的条件才能够被驱动所接受,所以说匹配的过 程就是检查接口是否满足这些条件的过程。同志们,千万不要认为爱情是骗来的,感情是睡来的,其实都是一个条件一个条件对照出来的,谁让这个世道上男人在某 些方面要处于弱势地位那。
当 然你可以每次都按照id的内容一个一个的比较下去,但是经常来说,一个驱动往往只是想设定其中的某几项,并不要求struct usb_device_id结构里的所有那些条件都要满足,萝卜白菜各有所爱么,有的人觉得你有身体就够了,有的人觉得你有钱就够了,有得人觉得你不但得 有身体有钱还要有权,如果你运气好,还可能碰到个只要你有时间的。match_flags就是为了方便各种各样的需求而生的,驱动可以将自己的条件组合起 来,match_flags的每一位对应一个条件,驱动care哪个条件了,就将那一位置1,否则就置0。当然,内核里对每个驱动可能会care的条件都 定义成了宏,供驱动去组合,它们都在include/linux/mod_devicetable.h里定义
122 /* Some useful macros to use to create struct usb_device_id */
123 #define USB_DEVICE_ID_MATCH_VENDOR              0x0001
124 #define USB_DEVICE_ID_MATCH_PRODUCT             0x0002
125 #define USB_DEVICE_ID_MATCH_DEV_LO              0x0004
126 #define USB_DEVICE_ID_MATCH_DEV_HI              0x0008
127 #define USB_DEVICE_ID_MATCH_DEV_CLASS           0x0010
128 #define USB_DEVICE_ID_MATCH_DEV_SUBCLASS        0x0020
129 #define USB_DEVICE_ID_MATCH_DEV_PROTOCOL        0x0040
130 #define USB_DEVICE_ID_MATCH_INT_CLASS           0x0080
131 #define USB_DEVICE_ID_MATCH_INT_SUBCLASS        0x0100
132 #define USB_DEVICE_ID_MATCH_INT_PROTOCOL        0x0200
你用自己的火眼金睛很容易的就能看出来这些数字分别表示了一个u16整数,也就是match_flags中的某一位。驱动比较在意哪个方面,就可以将match_flags里对应的位置1,在和接口匹配的时候自动就会去比较驱动设置的那个条件是否满足。那整个usb_match_device()函数就没什么说的了,就是从match_flags那里得到驱动都在意哪些条件,然后将设备保存在自己描述符里的自身信息与id里的相应条件进行比较,有一项比较不成功就说明匹配失败,如果一项符合了就接着看下一项,接口parent都满足条件了,就返回1,表示匹配成功了。
还 是回到usb_match_one_id()继续往下看,假设你运气还不错,parent满足了驱动的所有条件,得以走到了424行。这行还要对接口的 parent做点最后的确认,某办法,不都说自己有本事不如parent有本事么,驱动谨慎一点也可以理解。那么这行的意思就是,如果接口的 parent,usb设备是属于厂商定义的class,也就是不属于storage等等标准的class,就不再检查接口的class,subclass 和protocol了,除非match_flags里指定了条件USB_DEVICE_ID_MATCH_VENDOR。431行之后的三个if也不用多 说,前面是检查接口parent的,这里就是检查接口本身是不是满足驱动的条件的。
当 上面各个函数进行的所有检查都完全匹配时,usb总线的match函数usb_device_match就会返回1表示匹配成功,之后接着就会去调用驱动 的probe函数做更深入的处理,什么样的处理?这是每个驱动才知道的事情,反正到此为止,core的任务是已经圆满完成了,咱们的故事也就该结束了。
 
这 个core的故事,从match开始,到match结束,它虽说不会遍及core的边边角角所有部分,但应该也有那么十之七八。在match的两端是设备 和设备的驱动,是接口和接口的驱动,这个故事里遇到的人,遇到的事,早就安排在那里了,由不得我们去选择。在人生的路口上,早已经安排了那些人,那些事, 决定你向左走还是向右走。既然如此,那就随便走好了,想那么多干什么呢?
 
原创粉丝点击