- 论坛徽章:
- 0
|
/*
*
*kernel:2.6.18
*file:Storage/usb.c
*Copyright (C) 2007, freegnu
*
*/
大概流程:usb_stor_init ()->usb_register()->bus_add_driver()->driver_attach()
->storage_probe
一句话:usb driver的注册是将driver 结构add 到 usb bus list中,在match成功后会将且add 到device结构中,然后执行storage_probe()
细节:- usb_stor_init()
- {
- //初始化usb_driver结构
- retval = usb_register(&usb_storage_driver);//注册usb_register 驱动结构
- if (retval == 0) {
- printk(KERN_INFO "USB Mass Storage support registered.\n");
- usb_usual_set_present(USB_US_TYPE_STOR);
- }
- return retval;
- }
-
- usb_register()->usb_register_driver()->driver_register()
- driver_register()
- {
- klist_init(&drv->klist_devices, klist_devices_get, klist_devices_put);//初始化klist链表
- init_completion(&drv->unloaded);//初始化unloaded等待队列
- return bus_add_driver(drv);
- }
-
- bus_add_driver()//将driver add 到bus中,和devicer中
- {
- struct bus_type * bus = get_bus(drv->bus);//获取总线类型,并将object记数减1?
-
- if (bus) {
- error = kobject_set_name(&drv->kobj, "%s", drv->name);设置kobje->name
- if (error) {
- put_bus(bus);
- return error;
- }
- drv->kobj.kset = &bus->drivers;
- if ((error = kobject_register(&drv->kobj))) {
- put_bus(bus);
- return error;
- }
-
- driver_attach(drv);//绑定device 和driver,并调用probe
- klist_add_tail(&drv->knode_bus, &bus->klist_drivers);//将 drvier add 到bus中
- module_add_driver(drv->owner, drv);
-
- driver_add_attrs(bus, drv);
- add_bind_files(drv);
- }
- return error;
- }
-
- driver_attach()->bus_for_each_dev()->__driver_attach()->driver_probe_device()
- int driver_probe_device(struct device_driver * drv, struct device * dev)
- {
- int ret = 0;
-
- if (drv->bus->match && !drv->bus->match(dev, drv))//match dev和driver
- goto Done;
-
- pr_debug("%s: Matched Device %s with Driver %s\n",
- drv->bus->name, dev->bus_id, drv->name);
- dev->driver = drv;
- if (dev->bus->probe) {//usb bus不提供probe()
- ret = dev->bus->probe(dev);
- if (ret) {
- dev->driver = NULL;
- goto ProbeFailed;
- }
- } else if (drv->probe) {//执行usb driver中提供的probe()
- ret = drv->probe(dev);
- if (ret) {
- dev->driver = NULL;
- goto ProbeFailed;
- }
- }
- device_bind_driver(dev);
- ret = 1;
- pr_debug("%s: Bound Device %s to Driver %s\n",
- drv->bus->name, dev->bus_id, drv->name);
- goto Done;
-
- ProbeFailed:
- if (ret == -ENODEV || ret == -ENXIO) {
- /* Driver matched, but didn't support device
- * or device not found.
- * Not an error; keep going.
- */
- ret = 0;
- } else {
- /* driver matched but the probe failed */
- printk(KERN_WARNING
- "%s: probe of %s failed with error %d\n",
- drv->name, dev->bus_id, ret);
- }
- Done:
- return ret;
- }
-
-
- int usb_device_match(struct device *dev, struct device_driver *drv)
- {
- struct usb_interface *intf;
- struct usb_driver *usb_drv;
- const struct usb_device_id *id;
-
- /* check for generic driver, which we don't match any device with */
- if (drv == &usb_generic_driver)
- return 0;
-
- intf = to_usb_interface(dev);
- usb_drv = to_usb_driver(drv);
-
- id = usb_match_id(intf, usb_drv->id_table);//若match成功返回usb driver 结构中
- //提供的 id_table表的id
- if (id)
- return 1;
-
- id = usb_match_dynamic_id(intf, usb_drv);
- if (id)
- return 1;
- return 0;
- }
复制代码
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/49/showart_452946.html |
|