歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux USB subsystem --- USBFS driver registration

Linux USB subsystem --- USBFS driver registration

日期:2017/3/1 10:25:43   编辑:Linux編程

目的:對USB作深入學習,在此留下筆記。歡迎討論。

[Linux 3.2] [driver/usb/core/devio.c]

定義:usbfs_driver

  1. struct usb_driver usbfs_driver = {
  2. .name = "usbfs",
  3. .probe = driver_probe,
  4. .disconnect = driver_disconnect,
  5. .suspend = driver_suspend,
  6. .resume = driver_resume,
  7. };

[Linux 3.2] [include/linux/usb.h]

函數:usb_register();

  1. /* use a define to avoid include chaining to get THIS_MODULE & friends */
  2. #define usb_register(driver) \
  3. usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)

[Linux 3.2] [driver/usb/core/driver.c]

函數:usb_register_driver();

  1. /**
  2. * usb_register_driver - register a USB interface driver
  3. * @new_driver: USB operations for the interface driver
  4. * @owner: module owner of this driver.
  5. * @mod_name: module name string
  6. *
  7. * Registers a USB interface driver with the USB core. The list of
  8. * unattached interfaces will be rescanned whenever a new driver is
  9. * added, allowing the new driver to attach to any recognized interfaces.
  10. * Returns a negative error code on failure and 0 on success.
  11. *
  12. * NOTE: if you want your driver to use the USB major number, you must call
  13. * usb_register_dev() to enable that functionality. This function no longer
  14. * takes care of that.
  15. */
  16. int usb_register_driver(struct usb_driver *new_driver, struct module *owner,
  17. const char *mod_name)
  18. {
  19. int retval = 0;
  20. if (usb_disabled())
  21. return -ENODEV;
  22. new_driver->drvwrap.for_devices = 0;
  23. new_driver->drvwrap.driver.name = (char *) new_driver->name;
  24. new_driver->drvwrap.driver.bus = &usb_bus_type;
  25. new_driver->drvwrap.driver.probe = usb_probe_interface;
  26. new_driver->drvwrap.driver.remove = usb_unbind_interface;
  27. new_driver->drvwrap.driver.owner = owner;
  28. new_driver->drvwrap.driver.mod_name = mod_name;
  29. spin_lock_init(&new_driver->dynids.lock);
  30. INIT_LIST_HEAD(&new_driver->dynids.list);
  31. retval = driver_register(&new_driver->drvwrap.driver);
  32. if (retval)
  33. goto out;
  34. usbfs_update_special();
  35. retval = usb_create_newid_file(new_driver);
  36. if (retval)
  37. goto out_newid;
  38. retval = usb_create_removeid_file(new_driver);
  39. if (retval)
  40. goto out_removeid;
  41. pr_info("%s: registered new interface driver %s\n",
  42. usbcore_name, new_driver->name);
  43. out:
  44. return retval;
  45. out_removeid:
  46. usb_remove_newid_file(new_driver);
  47. out_newid:
  48. driver_unregister(&new_driver->drvwrap.driver);
  49. printk(KERN_ERR "%s: error %d registering interface "
  50. " driver %s\n",
  51. usbcore_name, retval, new_driver->name);
  52. goto out;
  53. }

此函數主要功能實現是通過driver_register實現。後面會詳細分析。

其余功能如下:

1. usbfs_update_special() ==> 跟usb文件系統相關,暫時不分析。

2. usb_create_newid_file() ==> 創建newid屬性文件,在/sys/bus/usb/drivers/usbfs/下面可以看到此文件。

3. usb_create_removeid_file() ==> 創建removeid屬性文件,在/sys/bus/usb/drivers/usbfs/下面可以看到此文件。

4. 輸出信息:usbcore: registered new interface driver usbfs

問題:newid與removeid屬性文件的作用是什麼?

回答:等待解答。

現在分析driver_register功能:

1. 首先判斷,些驅動所屬bus的subsys_private結構有沒有初始化。如果沒有,報bug信息。

2. 判斷需要注冊的driver和driver所屬的bus是否都有probe, remove, shutdown函數。如有,打印kernel warning信息。

3. 判斷此driver已經在driver所屬的bus上面注冊過了。如果注冊過了,打印錯誤信息,並返回。

4. 調用bus_add_driver來注冊driver。

5. 調用driver_add_groups來添加組屬性。

6. 返回。

最後對bus_add_driver進行分析。

  1. /**
  2. * bus_add_driver - Add a driver to the bus.
  3. * @drv: driver.
  4. */
  5. int bus_add_driver(struct device_driver *drv)
  6. {
  7. struct bus_type *bus;
  8. struct driver_private *priv;
  9. int error = 0;
  10. bus = bus_get(drv->bus);
  11. if (!bus)
  12. return -EINVAL;
  13. pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);
  14. priv = kzalloc(sizeof(*priv), GFP_KERNEL);
  15. if (!priv) {
  16. error = -ENOMEM;
  17. goto out_put_bus;
  18. }
  19. klist_init(&priv->klist_devices, NULL, NULL);
  20. priv->driver = drv;
  21. drv->p = priv;
  22. priv->kobj.kset = bus->p->drivers_kset;
  23. error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
  24. "%s", drv->name);
  25. if (error)
  26. goto out_unregister;
  27. if (drv->bus->p->drivers_autoprobe) {
  28. error = driver_attach(drv);
  29. if (error)
  30. goto out_unregister;
  31. }
  32. klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
  33. module_add_driver(drv->owner, drv);
  34. error = driver_create_file(drv, &driver_attr_uevent);
  35. if (error) {
  36. printk(KERN_ERR "%s: uevent attr (%s) failed\n",
  37. __func__, drv->name);
  38. }
  39. error = driver_add_attrs(bus, drv);
  40. if (error) {
  41. /* How the hell do we get out of this pickle? Give up */
  42. printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
  43. __func__, drv->name);
  44. }
  45. if (!drv->suppress_bind_attrs) {
  46. error = add_bind_files(drv);
  47. if (error) {
  48. /* Ditto */
  49. printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
  50. __func__, drv->name);
  51. }
  52. }
  53. kobject_uevent(&priv->kobj, KOBJ_ADD);
  54. return 0;
  55. out_unregister:
  56. kobject_put(&priv->kobj);
  57. kfree(drv->p);
  58. drv->p = NULL;
  59. out_put_bus:
  60. bus_put(bus);
  61. return error;
  62. }

其功能是向bus中添加一個driver。

1. bus_get() ==> bus的計數加1;

2. kzalloc,分配driver_private內存空間。

3. 初始化此driver的klist_devices鏈表。

4. kobject_init_and_add() ==> 在/sys/bus/usb/drivers/下面創建usbfs文件夾。

5. 如果總線支持drivers_autoprobe,調用driver_attach。(USB 總線支持)

6. driver_create_file ==> 在/sys/bus/usb/drivers/usbfs下面創建uevent屬性文件。

7. driver_add_attrs() ==> 將總線的屬性也加到/sys/bus/usb/drivers/usbfs

8. add_bind_files() ==> 在/sys/bus/usb/drivers/usbfs創建bind和unbind屬性文件。

9. kobject_uevent() ==> 發送一個KOBJ_ADD的事件。

在/sys/bus/usb/drivers/usbfs下面的文件:

bind module new_id remove_id uevent unbind

Copyright © Linux教程網 All Rights Reserved