前面分析了usb hub 和 generic driver,顺便将枚举的前一部分看完了。本来我们应该继续分析class driver的最上层,即利用usb通信实现具体功能的驱动。我们将以usb-skeleton.c为例。但在分析usb-skeleton之前,我们注意到最上层的驱动都是针对usb interface的,usb driver里面的函数都用usb interface做参数,usb driver就是usb interface的驱动,因为usb interface就是一个完整的功能实体。 针对具体的设备usb device,它的驱动叫usb device driver。
截止到我们前面分析的流程,我们看到的都是usb device,而上层的class driver都是针对usb interface的。那么从usb device到usb interface的转换是如何实现的?还有内核如何挂载并区别对待这两种设备?
下面我们分析上面的这个问题。
接着上节的流程,在generic 的函数generic probe函数中,对usb device设备进行了usb_choose_configuration和usb_set_configuration。下面看usb_set_configuration函数的处理。
int usb_set_configuration(struct usb_device *dev, int configuration)
{
int i, ret;
struct usb_host_config *cp = NULL;
struct usb_interface **new_interfaces = NULL;
int n, nintf;
if (dev->authorized == 0 || configuration == -1)
configuration = 0;
else {
for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
if (dev->config[i].desc.bConfigurationValue ==
configuration) {
cp = &dev->config[i];
break;
}
}
}
if ((!cp && configuration != 0))
return -EINVAL;
/* The USB spec says configuration 0 means unconfigured.
* But if a device includes a configuration numbered 0,
* we will accept it as a correctly configured state.
* Use -1 if you really want to unconfigure the device.
*/
if (cp && configuration == 0)
dev_warn(&dev->dev, "config 0 descriptor??\n");
/* Allocate memory for new interfaces before doing anything else,
* so that if we run out then nothing will have changed. */
n = nintf = 0;
if (cp) {
nintf = cp->desc.bNumInterfaces;
new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
GFP_KERNEL);
if (!new_interfaces) {
dev_err(&dev->dev, "Out of memory\n");

本文深入探讨了USB设备驱动,从USB device到USB interface的转换过程,包括配置device、添加interface以及如何在内核中区分和挂载这两种设备。通过分析`usb_set_configuration`函数,揭示了设备初始化和probe函数调用的机制。
-----usb device 和 usb interface&spm=1001.2101.3001.5002&articleId=12868531&d=1&t=3&u=37d7d59af2014506be3db00cc4d4669a)
747

被折叠的 条评论
为什么被折叠?



