- Linux那些事儿之我是USB
- 肖林甫 肖季东 任桥伟
- 564字
- 2020-08-27 00:52:23
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接口走,各走各的路,分开了,就不再相见。