以USB串口驱动pl2303为例子分析。
首先是要有一个总管usb设备的驱动,就是定义在generic.c中的 usb_device_driver;该结构在usb.c中注册:
int usb_register_device_driver(struct usb_device_driver *new_udriver, struct module *owner) { int retval = 0; if (usb_disabled()) return -ENODEV; new_udriver->drvwrap.for_devices = 1; new_udriver->drvwrap.driver.name = (char *) new_udriver->name; new_udriver->drvwrap.driver.bus = &usb_bus_type; new_udriver->drvwrap.driver.probe = usb_probe_device; new_udriver->drvwrap.driver.remove = usb_unbind_device; new_udriver->drvwrap.driver.owner = owner; retval = driver_register(&new_udriver->drvwrap.driver); if (!retval) { pr_info("%s: registered new device driver %s\n", usbcore_name, new_udriver->name); usbfs_update_special(); } else { printk(KERN_ERR "%s: error %d registering device " " driver %s\n", usbcore_name, retval, new_udriver->name); } return retval; }
usb_register_device_driver(&usb_generic_driver, THIS_MODULE) -> driver_register(这是usb device驱动,for_devices = 1);
记住,整个usb驱动架构中就注册了一个这样的设备驱动。
其次是具体设备的usb驱动usb_driver(如PL2303),他们都是用usb_register ->usb_register_driver -> driver_register来注册的(这是注册USB interface驱动,for_devices = 0):
int usb_register_driver(struct usb_driver *new_driver, struct module *owner, const char *mod_name) { int retval = 0; if (usb_disabled()) return -ENODEV; new_driver->drvwrap.for_devices = 0; new_driver->drvwrap.driver.name = (char *) new_driver->name; new_driver->drvwrap.driver.bus = &usb_bus_type; new_driver->drvwrap.driver.probe = usb_probe_interface; new_driver->drvwrap.driver.remove = usb_unbind_interface; new_driver->drvwrap.driver.owner = owner; new_driver->drvwrap.driver.mod_name = mod_name; spin_lock_init(&new_driver->dynids.lock); INIT_LIST_HEAD(&new_driver->dynids.list); retval = driver_register(&new_driver->drvwrap.driver); if (retval) goto out; usbfs_update_special(); retval = usb_create_newid_file(new_driver); if (retval) goto out_newid; retval = usb_create_removeid_file(new_driver); if (retval) goto out_removeid; ............................................................
hub_events -> hub_port_connect_change -> usb_alloc_dev -> 创建udev,并且赋值:
dev->dev.bus = &usb_bus_type;
dev->dev.type = &usb_device_type;//这是以后匹配device_driver的依据
dev->dev.groups = usb_device_groups;
->usb_new_device(udev) -> device_add,这样,就将检测到的USB设备添加到USB总线usb_bus_type上了。
而接着在device_add -> bus_probe_device中会用bus_for_each_drv遍历前面注册在usb总线上的驱动,这个时候总线上有很多device_driver,但是我们要调用前面usb_register_device_driver注册的通用设备描述符解析驱动。
这是如何匹配到的呢?进入USB总线usb_bus_type的match函数看看匹配规则就知道了:
static int usb_device_match(struct device *dev, struct device_driver *drv) { /* devices and interfaces are handled separately */ if (is_usb_device(dev)) { /* interface drivers never match devices */ if (!is_usb_device_driver(drv)) return 0; /* TODO: Add real matching code */ return 1; } else if (is_usb_interface(dev)) { struct usb_interface *intf; struct usb_driver *usb_drv; const struct usb_device_id *id; /* device drivers never match interfaces */ if (is_usb_device_driver(drv)) return 0; intf = to_usb_interface(dev); usb_drv = to_usb_driver(drv); id = usb_match_id(intf, usb_drv->id_table); if (id) return 1; id = usb_match_dynamic_id(intf, usb_drv); if (id) return 1; } return 0; }
static inline int is_usb_device(const struct device *dev) { return dev->type == &usb_device_type; }
根据前面usb_alloc_dev的赋值,该条件已经符合;接着is_usb_device_driver函数的定义:
static inline int is_usb_device_driver(struct device_driver *drv) { return container_of(drv, struct usbdrv_wrap, driver)-> for_devices; }
static int usb_probe_device(struct device *dev) { ....... error = udriver->probe(udev); ....... }
做一些简单的判断然后调用generic.c的usb_device_driver结构体的probe。再次强调,这是通用的配置描述符驱动是根据上述分,所有的usb插入设备都析的规则找到它,并调用他的probe方法来获得配置描述符:
static int generic_probe(struct usb_device *udev) { int err, c; /* Choose and set the configuration. This registers the interfaces * with the driver core and lets interface drivers bind to them. */ if (usb_device_is_owned(udev)) ; /* Don't configure if the device is owned */ else if (udev->authorized == 0) dev_err(&udev->dev, "Device is not authorized for usage\n"); else { c = usb_choose_configuration(udev); if (c >= 0) { err = usb_set_configuration(udev, c); if (err) { dev_err(&udev->dev, "can't set config #%d, error %d\n", c, err); /* This need not be fatal. The user can try to * set other configurations. */ } } } /* USB device state == configured ... usable */ usb_notify_add_device(udev); return 0; }
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; struct usb_hcd *hcd = bus_to_hcd(dev->bus); int n, nintf; 。。。。。。 new_interfaces = kmalloc(nintf * sizeof(*new_interfaces), 。。。。。。 for (; n < nintf; ++n) { new_interfaces[n] = kzalloc( sizeof(struct usb_interface), GFP_NOIO); 。。。。。。 usb_enable_interface(dev, intf, true); intf->dev.parent = &dev->dev; intf->dev.driver = NULL; intf->dev.bus = &usb_bus_type; intf->dev.type = &usb_if_device_type; intf->dev.groups = usb_interface_groups; intf->dev.dma_mask = dev->dev.dma_mask; INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); 。。。。。。 for (i = 0; i < nintf; ++i) { struct usb_interface *intf = cp->interface[i]; dev_dbg(&dev->dev, "adding %s (config #%d, interface %d)\n", dev_name(&intf->dev), configuration, intf->cur_altsetting->desc.bInterfaceNumber); device_enable_async_suspend(&intf->dev); ret = device_add(&intf->dev); if (ret != 0) { dev_err(&dev->dev, "device_add(%s) --> %d\n", dev_name(&intf->dev), ret); continue; } create_intf_ep_devs(intf); 。。。。。。
static inline int is_usb_interface(const struct device *dev) { return dev->type == &usb_if_device_type; }
匹配成功后,调用通用的usb_probe_interface:
static int usb_probe_interface(struct device *dev) { 。。。。。。 if (intf->needs_altsetting0) { error = usb_set_interface(udev, intf->altsetting[0]. desc.bInterfaceNumber, 0); 。。。。。。 error = driver->probe(intf, id); 。。。。。。
static struct usb_driver pl2303_driver = { .name = "pl2303", .probe = usb_serial_probe, .disconnect = usb_serial_disconnect, .id_table = id_table, .suspend = usb_serial_suspend, .resume = usb_serial_resume, .no_dynamic_id = 1, .supports_autosuspend = 1, };
从上面可以看出,USB子系统已经为我们实现了大部分架构,我们驱动要做的事情只要实现接口描述符(interface descriptor)的处理即可,这就要求根据USB协议规则和具体的USB芯片手册来操作。
下一篇就来分析常用的USB协议和一个具体的接口描述符驱动。