前面分析了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");
return -ENOMEM;
}
for (; n < nintf; ++n) {
new_inte