- Linux那些事儿之我是USB
- 肖林甫 肖季东 任桥伟
- 2443字
- 2020-08-27 00:52:24
31.驱动的生命线(一)
usb_generic_driver是一个USB设备都会争先恐后地找它配对儿。
现在开始就沿着usb_generic_driver的成名之路走一走,设备的生命线你可以想当然地认为是从你的USB设备连接到Hub的某个端口时开始,驱动的生命线就必须得回溯到USB子系统的初始化函数usb_register_device_driver。
895 retval = usb_register_device_driver(&usb_generic_driver, THIS_MODULE); 896 if (!retval) 897 goto out;
在USB子系统初始化时,就调用了driver.c里面的usb_register_device_driver函数将usb_generic_driver注册给系统了,下面来看一看。
671 int usb_register_device_driver(struct usb_device_driver *new_udriver, 672 struct module *owner) 673 { 674 int retval = 0; 675 676 if (usb_disabled()) 677 return -ENODEV; 678 679 new_udriver->drvwrap.for_devices = 1; 680 new_udriver->drvwrap.driver.name = (char *) new_udriver->name; 681 new_udriver->drvwrap.driver.bus = &usb_bus_type; 682 new_udriver->drvwrap.driver.probe = usb_probe_device; 683 new_udriver->drvwrap.driver.remove = usb_unbind_device; 684 new_udriver->drvwrap.driver.owner = owner; 685 686 retval = driver_register(&new_udriver->drvwrap.driver); 687 688 if (!retval) { 689 pr_info("%s: registered new device driver %s\n", 690 usbcore_name, new_udriver->name); 691 usbfs_update_special(); 692 } else { 693 printk(KERN_ERR "%s: error %d registering device " 694 " driver %s\n", 695 usbcore_name, retval, new_udriver->name); 696 } 697 698 return retval; 699 }
676行,判断USB子系统是不是在你启动内核时就被禁止了,如果是,它的生命也就太短暂了。
679行,for_devices就是在这儿被初始化为1的,有了它,match里的is_usb_device_driver才有章可循,有凭可依。
下面就是充实了usb_generic_driver里嵌入的struct device_driver结构体,usb_generic_ driver就是通过它和设备模型连上关系的。name就是usb_generic_driver的名字,即USB,所属的总线类型同样被设置为usb_bus_type,然后是指定probe函数和remove函数。
686行,调用设备模型的函数driver_register将usb_generic_driver添加到USB总线的那条驱动链表里。
usb_generic_driver和USB设备匹配成功后,就会调用682行指定的probe函数usb_probe_ device(),现在看一看driver.c中定义的这个函数。
152 static int usb_probe_device(struct device *dev) 153 { 154 struct usb_device_driver *udriver = to_usb_device_driver(dev->driver); 155 struct usb_device *udev; 156 int error = -ENODEV; 157 158 dev_dbg(dev, "%s\n", __FUNCTION__); 159 160 if (!is_usb_device(dev)) /* Sanity check */ 161 return error; 162 163 udev = to_usb_device(dev); 164 165 /* TODO: Add real matching code */ 166 167 /* The device should always appear to be in use 168 * unless the driver suports autosuspend. 169 */ 170 udev->pm_usage_cnt = !(udriver->supports_autosuspend); 171 172 error = udriver->probe(udev); 173 return error; 174 }
154行,to_usb_device_driver是include/linux/usb.h中定义的一个宏,和前面遇到的那个to_usb_device有异曲同工之妙。
889 #define to_usb_device_driver(d) container_of(d, struct usb_device_driver, \ 890 drvwrap.driver)
160行,match函数543行的函数又调到这儿来“把门儿”了,如果你这个设备的类型不是usb_device_type,那怎么从前面走到这儿的它管不着,但是到它这里就不可能再蒙混过关了。你的设备虽然和usb_generic_driver是配对成功了,但是还要经过判断。
163行,前面刚提到to_usb_device就到这里来了。
170行,pm_usage_cnt和supports_autosuspend这两个前面都提到过。每个struct usb_I nterface或struct usb_device里都有一个pm_usage_cnt,每个struct usb_driver或struct usb_device_ driver里都有一个supports_autosuspend。只有pm_usage_cnt为0时才会允许接口autosuspend,如果supports_autosuspen为0就不再允许绑定到这个驱动的接口autosuspend。
接口?设备?需要时,接口是接口,设备是设备;不需要时,接口设备一个样。这里就是不需要时,所以将上面的接口换成设备套,就是:pm_usage_cnt为0时才会允许设备autosuspend,supports_autosuspend为0,就不再允许绑定到这个驱动的设备autosuspend。
所有的USB设备都是绑定到usb_generic_driver上面的,usb_generic_driver的supports_ autosuspend字段又是为1的,所以这行就是将设备struct usb_device结构体的pm_usage_cnt置为了0,也就是说允许设备autosuspend。但是不是说将pm_usage_cnt轻轻松松置为0,设备就能够autosuspend了,驱动必须实现一对suspend/resume函数供PM子系统驱使,usb_generic_ driver里的这对函数就是generic_suspend/generic_resume。
172行,这里要调用usb_generic_driver自己私有的probe函数generic_probe()对你的设备进行进一步的审查,它在generic.c中定义。
153 static int generic_probe(struct usb_device *udev) 154 { 155 int err, c; 156 157 /* put device-specific files into sysfs */ 158 usb_create_sysfs_dev_files(udev); 159 160 /* Choose and set the configuration. This registers the interfaces 161 * with the driver core and lets interface drivers bind to them. 162 */ 163 c = choose_configuration(udev); 164 if (c >= 0) { 165 err = usb_set_configuration(udev, c); 166 if (err) { 167 dev_err(&udev->dev, "can't set config #%d, error %d\n", 168 c, err); 169 /* This need not be fatal. The user can try to 170 * set other configurations. */ 171 } 172 } 173 174 /* USB device state == configured ... usable */ 175 usb_notify_add_device(udev); 176 177 return 0; 178 }
这函数说简单也简单,说复杂也复杂,简单的是外表,复杂的是内心。用一句话去概括,就是从设备众多配置中选择一个合适的,然后去配置设备,从而让设备进入期待已久的Configured状态。先看一看是怎么选择一个配置的,调用的是generic.c里的choose_configuration函数。
42 static int choose_configuration(struct usb_device *udev) 43 { 44 int i; 45 int num_configs; 46 int insufficient_power = 0; 47 struct usb_host_config *c, *best; 48 49 best = NULL; 50 c = udev->config; 51 num_configs = udev->descriptor.bNumConfigurations; 52 for (i = 0; i < num_configs; (i++, c++)) { 53 struct usb_interface_descriptor *desc = NULL; 54 55 /* It's possible that a config has no interfaces! */ 56 if (c->desc.bNumInterfaces > 0) 57 desc = &c->intf_cache[0]->altsetting->desc; 58 59 /* 60 * HP's USB bus-powered keyboard has only one configuration 61 * and it clai ms to be self-powered; other devices may have 62 * similar errors in their descriptors. If the next test 63 * were allowed to execute, such configurations would always 64 * be rejected and the devices would not work as expected. 65 * In the meantime, we run the risk of selecting a config 66 * that requires external power at a time when that power 67 * isn't available. It see ms to be the lesser of two evils. 68 * 69 * Bugzilla #6448 reports a device that appears to crash 70 * when it receives a GET_DEVICE_STATUS request! We don't 71 * have any other way to tell whether a device is self-powered, 72 * but since we don't use that information anywhere but here, 73 * the call has been removed. 74 * 75 * Maybe the GET_DEVICE_STATUS call and the test below can 76 * be reinstated when device firmwares become more reliable. 77 * Don't hold your breath. 78 */ 79 #if 0 80 /* Rule out self-powered configs for a bus-powered device */ 81 if (bus_powered && (c->desc.bmAttributes & 82 USB_CONFIG_ATT_SELFPOWER)) 83 continue; 84 #endif 85 86 /* 87 * The next test may not be as effective as it should be. 88 * Some hubs have errors in their descriptor, claiming 89 * to be self-powered when they are really bus-powered. 90 * We will overestimate the amount of current such hubs 91 * make available for each port. 92 * 93 * This is a fairly benign sort of failure. It won't 94 * cause us to reject configurations that we should have 95 * accepted. 96 */ 97 98 /* Rule out configs that draw too much bus current */ 99 if (c->desc.bMaxPower * 2 > udev->bus_mA) { 100 insufficient_power++; 101 continue; 102 } 103 104 /* When the first config's first interface is one of Microsoft's 105 * pet nonstandard Ethernet-over-USB protocols, ignore it unless 106 * this kernel has enabled the necessary host side driver. 107 */ 108 if (i == 0 && desc && (is_rndis(desc)||is_activesync(desc))) { 109 #if !defined(CONFIG_USB_NET_RNDIS_HOST) && !defined(CONFIG_USB_NET_RNDIS_HOST_MODULE) 110 continue; 111 #else 112 best = c; 113 #endif 114 } 115 116 /* From the remaining configs, choose the first one whose 117 * first interface is for a non-vendor-specific class. 118 * Reason: Linux is more likely to have a class driver 119 * than a vendor-specific driver. */ 120 else if (udev->descriptor.bDeviceClass != 121 USB_CLASS_VENDOR_SPEC && 122 (!desc || desc->bInterfaceClass != 123 USB_CLASS_VENDOR_SPEC)) { 124 best = c; 125 break; 126 } 127 128 /* If all the remaining configs are vendor-specific, 129 * choose the first one. */ 130 else if (!best) 131 best = c; 132 } 133 134 if (insufficient_power > 0) 135 dev_info(&udev->dev, "rejected %d configuration%s " 136 "due to insufficient available bus power\n", 137 insufficient_power, plural(insufficient_power)); 138 139 if (best) { 140 i = best->desc.bConfigurationValue; 141 dev_info(&udev->dev, 142 "configuration #%d chosen from %d choice%s\n", 143 i, num_configs, plural(num_configs)); 144 } else { 145 i = -1; 146 dev_warn(&udev->dev, 147 "no configuration chosen from %d choice%s\n", 148 num_configs, plural(num_configs)); 149 } 150 return i; 151 }
设备各个配置的详细信息在设备自身的漫漫人生旅途中就已经获取并存放在相关的几个成员里了,怎么从中挑选一个让人满意的配置?显然谁都会说去一个一个地浏览每个配置,查看有没有称心如意的,于是就有了52行的for循环。
刚看到这个for循环就有点儿傻眼了,居然注释要远远多于代码,我们把这个for循环分成三大段,59行到84行这一段,你什么都可以不看,就是不能不看那个#if 0,一见到它,就意味着你可以略过这么一大段代码了。
第二段是98行到102行,这一段牵扯到最让人无可奈何的一对矛盾,索取与给予。一个配置索取的电流比Hub所能给予的还要大,显然它不会是一个让人满意的配置。
第三段是108行到131行,关于这段只说一个原则,Linux更喜欢那些标准的东西,比如USB_CLASS_VIDEO、USB_CLASS_AUDIO等设备和接口就更讨人喜欢一些,所以就会优先选择非USB_CLASS_VENDOR_SPEC的接口。
for循环之后,剩下的那些部分都是调试用的,输出一些调试信息,不需要去关心,不过里面出现了一个有趣的函数plural,它是一个在generic.c开头儿定义的内联函数。
23 static inline const char *plural(int n) 24 { 25 return (n == 1 ? "" : "s"); 26 }
参数n为1返回一个空字符串,否则返回一个“s”,看使用了这个函数的打印语句,就明白它是用来打印一个英语名词的单复数的,复数的话就加上一个“s”。
不管你疑惑也好,满意也好,choose_configuration就是这样按照自己的标准挑选了一个比较合自己心意的配置,接下来当然就是要用这个配置去配置设备以便让它迈进Configured状态了。