13.繁华落尽

13.繁华落尽

看过了Linux设备模型的繁花似锦,该是体味境界之美了。

Linux设备模型中的总线落实在USB子系统里就是usb_bus_type,它在usb_init函数的874行注册,在drivers/usb/core/driver.c文件中定义:

1523 struct bus_type usb_bus_type = {
1524    .name =       "usb",
1525    .match =      usb_device_match,
1526    .uevent =     usb_uevent,
1527    .suspend =    usb_suspend,
1528    .resume =     usb_resume,
1529 };

name自然就是USB总线的绰号。match这个函数指针就比较有意思了,它充当了一个红娘的角色,在总线的设备和驱动之间“牵线搭桥”,但明显这里match的条件不是那么苛刻,要更为实际一些。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 }

540行,经历了繁华的Linux设备模型,这两个参数我们都已经很熟悉了,对应的就是总线两条链表里的设备和驱动。总线上有新设备或新的驱动添加时,这个函数总是会被调用,如果指定的驱动程序能够处理指定的设备,也就是匹配成功,函数返回0。梦想是美好的,现实是残酷的,匹配是未必会成功的,红娘再努力,双方对不上眼也是实在没办法的事。

543行,一遇到if和else,我们就知道又处在两难境地了,代码里我们可选择的太多,生活里我们可选择的太少。这里的岔路口只有两条路:一条给USB设备走,一条给USB接口走,各走各的路,分开了,就不再相见。