在/drivers/usb/core/Usb.c中,subsys_initcall(usb_init)声明了usb子系统入口函数usb_init
- static int __init usb_init(void)
- {
- int retval;
- if (nousb) {
- pr_info("%s: USB support disabled\n", usbcore_name);
- return 0;
- }
- retval = usb_debugfs_init();
- if (retval)
- goto out;
- retval = bus_register(&usb_bus_type);
- if (retval)
- goto bus_register_failed;
- retval = bus_register_notifier(&usb_bus_type, &usb_bus_nb);
- if (retval)
- goto bus_notifier_failed;
- retval = usb_major_init();
- if (retval)
- goto major_init_failed;
- retval = usb_register(&usbfs_driver);
- if (retval)
- goto driver_register_failed;
- retval = usb_devio_init();
- if (retval)
- goto usb_devio_init_failed;
- retval = usbfs_init();
- if (retval)
- goto fs_init_failed;
- retval = usb_hub_init();
- if (retval)
- goto hub_init_failed;
- retval = usb_register_device_driver(&usb_generic_driver, THIS_MODULE);
- if (!retval)
- goto out;
- usb_hub_cleanup();
- hub_init_failed:
- usbfs_cleanup();
- fs_init_failed:
- usb_devio_cleanup();
- usb_devio_init_failed:
- usb_deregister(&usbfs_driver);
- driver_register_failed:
- usb_major_cleanup();
- major_init_failed:
- bus_unregister_notifier(&usb_bus_type, &usb_bus_nb);
- bus_notifier_failed:
- bus_unregister(&usb_bus_type);
- bus_register_failed:
- usb_debugfs_cleanup();
- out:
- return retval;
- }
1.usb_debugfs_init --usb debugfs初始化
- static int usb_debugfs_init(void)
- {
- usb_debug_root = debugfs_create_dir("usb", NULL);
- if (!usb_debug_root)
- return -ENOENT;
- usb_debug_devices = debugfs_create_file("devices", 0444,usb_debug_root, NULL,&usbfs_devices_fops);
-
- if (!usb_debug_devices) {
- debugfs_remove(usb_debug_root);
- usb_debug_root = NULL;
- return -ENOENT;
- }
- return 0;
- }
要使用debugfs下面的usb功能,需要先挂着debugfs(mount -t debugfs none $(debugfs) ),具体初始化了啥调试接口,看下usbfs_devices_fops操作函数集
2.usb总线的注册
- struct bus_type usb_bus_type = {
- .name = "usb",
- .match = usb_device_match,
- .uevent = usb_uevent,
- #ifdef CONFIG_USB_SUSPEND
- .pm = &usb_bus_pm_ops,
- #endif
- };
这里总线的match方法是usb设备与usb驱动匹配的函数.
3.注册usb总线通知链
- int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb)
- {
- return blocking_notifier_chain_register(&bus->p->bus_notifier, nb);
- }
当总线添加删除设备的时候会调用usb_bus_nb指定的notifier_cal方法,既usb_bus_notify
- static int usb_bus_notify(struct notifier_block *nb, unsigned long action,void *data)
- {
- struct device *dev = data;
- switch (action) {
- case BUS_NOTIFY_ADD_DEVICE:
- if (dev->type == &usb_device_type)
- (void) usb_create_sysfs_dev_files(to_usb_device(dev));
- else if (dev->type == &usb_if_device_type)
- (void) usb_create_sysfs_intf_files(to_usb_interface(dev));
- break;
- case BUS_NOTIFY_DEL_DEVICE:
- if (dev->type == &usb_device_type)
- usb_remove_sysfs_dev_files(to_usb_device(dev));
- else if (dev->type == &usb_if_device_type)
- usb_remove_sysfs_intf_files(to_usb_interface(dev));
- break;
- }
- return 0;
- }
4.初始化usb主控器字符设备,USB_MAJOR=180
- int usb_major_init(void)
- {
- int error;
- error = register_chrdev(USB_MAJOR, "usb", &usb_fops);
- if (error)
- printk(KERN_ERR "Unable to get major %d for usb devices\n",USB_MAJOR);
- return error;
- }
捆绑usb_fops
- static const struct file_operations usb_fops = {
- .owner = THIS_MODULE,
- .open = usb_open,
- .llseek = noop_llseek,
- };
5.注册usbfs_driver
- struct usb_driver usbfs_driver = {
- .name = "usbfs",
- .probe = driver_probe,
- .disconnect = driver_disconnect,
- .suspend = driver_suspend,
- .resume = driver_resume,
- };
6.usb_devio_init USB_DEVICE_DEV=189
- int __init usb_devio_init(void)
- {
- int retval;
- retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX,"usb_device");
- if (retval) {
- printk(KERN_ERR "Unable to register minors for usb_device\n");
- goto out;
- }
- cdev_init(&usb_device_cdev, &usbdev_file_operations);
- retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
- if (retval) {
- printk(KERN_ERR "Unable to get usb_device major %d\n",USB_DEVICE_MAJOR);
- goto error_cdev;
- }
- #ifdef CONFIG_USB_DEVICE_CLASS
- usb_classdev_class = class_create(THIS_MODULE, "usb_device");
- if (IS_ERR(usb_classdev_class)) {
- printk(KERN_ERR "Unable to register usb_device class\n");
- retval = PTR_ERR(usb_classdev_class);
- cdev_del(&usb_device_cdev);
- usb_classdev_class = NULL;
- goto out;
- }
- usb_classdev_class->dev_kobj = NULL;
- #endif
- usb_register_notify(&usbdev_nb);
- out:
- return retval;
- error_cdev:
- unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
- goto out;
- }
usb注册的通知链
- void usb_register_notify(struct notifier_block *nb)
- {
- blocking_notifier_chain_register(&usb_notifier_list, nb);
- }
usb通知链表头为usb_notifier_list
在/drivers/usb/core/Notify.c文件中,有四个函数()对usb_notifier_list中发送通知,这四个函数如下:
usb_notify_add_device //有设备添加
usb_notify_remove_device //有设备移除
usb_notify_add_bus //总线添加
usb_notify_remove_bus //总线移除
当这些事件发生后会调用usbdev_nb指定的notifier_cal方法,既usbdev_notify
- static int usbdev_notify(struct notifier_block *self,unsigned long action, void *dev)
- {
- switch (action) {
- case USB_DEVICE_ADD:
- if (usb_classdev_add(dev))
- return NOTIFY_BAD;
- break;
- case USB_DEVICE_REMOVE:
- usb_classdev_remove(dev);
- usbdev_remove(dev);
- break;
- }
- return NOTIFY_OK;
- }
7.usbfs初始化
- int __init usbfs_init(void)
- {
- int retval;
- retval = register_filesystem(&usb_fs_type);
- if (retval)
- return retval;
- usb_register_notify(&usbfs_nb);
- usbdir = proc_mkdir("bus/usb", NULL);
- return 0;
- }
通知链回调函数
- static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev)
- {
- switch (action) {
- case USB_DEVICE_ADD:
- usbfs_add_device(dev);
- break;
- case USB_DEVICE_REMOVE:
- usbfs_remove_device(dev);
- break;
- case USB_BUS_ADD:
- usbfs_add_bus(dev);
- break;
- case USB_BUS_REMOVE:
- usbfs_remove_bus(dev);
- }
- usbfs_update_special();
- usbfs_conn_disc_event();
- return NOTIFY_OK;
- }
8.usb hub初始化
- int usb_hub_init(void)
- {
- if (usb_register(&hub_driver) < 0) {
- printk(KERN_ERR "%s: can't register hub driver\n",usbcore_name);
- return -1;
- }
- khubd_task = kthread_run(hub_thread, NULL, "khubd");
- if (!IS_ERR(khubd_task))
- return 0;
- usb_deregister(&hub_driver);
- printk(KERN_ERR "%s: can't start khubd\n", usbcore_name);
- return -1;
- }
hub也是usb设备,所以需要注册器设备驱动,创建hub_thread守护进程
捆绑的hub usb设备驱动
- static struct usb_driver hub_driver = {
- .name = "hub",
- .probe = hub_probe,
- .disconnect = hub_disconnect,
- .suspend = hub_suspend,
- .resume = hub_resume,
- .reset_resume = hub_reset_resume,
- .pre_reset = hub_pre_reset,
- .post_reset = hub_post_reset,
- .unlocked_ioctl = hub_ioctl,
- .id_table = hub_id_table,
- .supports_autosuspend = 1,
- };
hub_thread守护进程
- static int hub_thread(void *__unused)
- {
- set_freezable();
- do {
- hub_events();
- wait_event_freezable(khubd_wait,!list_empty(&hub_event_list) ||kthread_should_stop());
- } while (!kthread_should_stop() || !list_empty(&hub_event_list));
- pr_debug("%s: khubd exiting\n", usbcore_name);
- return 0;
- }
这里while循环是在hub_event_list不为空时候循环执行
当hub_events执行完,会执行wait_event_freezable进入睡眠,其他函数调用wake_up(&khubd_wait)唤醒队列
hub_events函数
- static void hub_events(void)
- {
- struct list_head *tmp;
- struct usb_device *hdev;
- struct usb_interface *intf;
- struct usb_hub *hub;
- struct device *hub_dev;
- u16 hubstatus;
- u16 hubchange;
- u16 portstatus;
- u16 portchange;
- int i, ret;
- int connect_change;
-
- while (1) {
- spin_lock_irq(&hub_event_lock);
-
- if (list_empty(&hub_event_list)) {
- spin_unlock_irq(&hub_event_lock);
- break;
- }
- tmp = hub_event_list.next;
- list_del_init(tmp);
- hub = list_entry(tmp, struct usb_hub, event_list);
- kref_get(&hub->kref);
- spin_unlock_irq(&hub_event_lock);
- hdev = hub->hdev;
- hub_dev = hub->intfdev;
- intf = to_usb_interface(hub_dev);
- usb_lock_device(hdev);
- if (unlikely(hub->disconnected))
- goto loop_disconnected;
- if (hdev->state == USB_STATE_NOTATTACHED) {
- hub->error = -ENODEV;
- hub_quiesce(hub, HUB_DISCONNECT);
- goto loop;
- }
- ret = usb_autopm_get_interface(intf);
- if (ret) {
- dev_dbg(hub_dev, "Can't autoresume: %d\n", ret);
- goto loop;
- }
- if (hub->quiescing)
- goto loop_autopm;
- if (hub->error) {
- dev_dbg (hub_dev, "resetting for error %d\n",hub->error);
- ret = usb_reset_device(hdev);
- if (ret) {
- dev_dbg (hub_dev,"error resetting hub: %d\n", ret);
- goto loop_autopm;
- }
- hub->nerrors = 0;
- hub->error = 0;
- }
- for (i = 1; i <= hub->descriptor->bNbrPorts; i++) {
- if (test_bit(i, hub->busy_bits))
- continue;
- connect_change = test_bit(i, hub->change_bits);
- if (!test_and_clear_bit(i, hub->event_bits) &&!connect_change)
- continue;
- ret = hub_port_status(hub, i,&portstatus, &portchange);
- if (ret < 0)
- continue;
- if (portchange & USB_PORT_STAT_C_CONNECTION) {
- clear_port_feature(hdev, i,USB_PORT_FEAT_C_CONNECTION);
- connect_change = 1;
- }
- if (portchange & USB_PORT_STAT_C_ENABLE) {
- if (!connect_change)
- dev_dbg (hub_dev,"port %d enable change,status %08x\n",i, portstatus);
- clear_port_feature(hdev, i,USB_PORT_FEAT_C_ENABLE);
- if (!(portstatus & USB_PORT_STAT_ENABLE)&& !connect_change&& hdev->children[i-1]) {
- dev_err (hub_dev,"port %i disabled by hub (EMI?),re-enabling...\n",i);
- connect_change = 1;
- }
- }
- if (portchange & USB_PORT_STAT_C_SUSPEND) {
- struct usb_device *udev;
- clear_port_feature(hdev, i,USB_PORT_FEAT_C_SUSPEND);
- udev = hdev->children[i-1];
- if (udev) {
- msleep(10);
- usb_lock_device(udev);
- ret = usb_remote_wakeup(hdev->children[i-1]);
- usb_unlock_device(udev);
- if (ret < 0)
- connect_change = 1;
- } else {
- ret = -ENODEV;
- hub_port_disable(hub, i, 1);
- }
- dev_dbg (hub_dev,"resume on port %d, status %d\n",i, ret);
- }
-
- if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
- dev_err (hub_dev,"over-current change on port %d\n",i);
- clear_port_feature(hdev, i,USB_PORT_FEAT_C_OVER_CURRENT);
- hub_power_on(hub, true);
- }
- if (portchange & USB_PORT_STAT_C_RESET) {
- dev_dbg (hub_dev,"reset change on port %d\n",i);
- clear_port_feature(hdev, i,USB_PORT_FEAT_C_RESET);
- }
-
- if (connect_change)
- hub_port_connect_change(hub, i,portstatus, portchange);
- }
- if (test_and_clear_bit(0, hub->event_bits) == 0)
- ;
- else if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)
- dev_err (hub_dev, "get_hub_status failed\n");
- else {
- if (hubchange & HUB_CHANGE_LOCAL_POWER) {
- dev_dbg (hub_dev, "power change\n");
- clear_hub_feature(hdev, C_HUB_LOCAL_POWER);
- if (hubstatus & HUB_STATUS_LOCAL_POWER)
- hub->limited_power = 1;
- else
- hub->limited_power = 0;
- }
- if (hubchange & HUB_CHANGE_OVERCURRENT) {
- dev_dbg (hub_dev, "overcurrent change\n");
- msleep(500);
- clear_hub_feature(hdev, C_HUB_OVER_CURRENT);
- hub_power_on(hub, true);
- }
- }
- loop_autopm:
- usb_autopm_put_interface_no_suspend(intf);
- loop:
- usb_autopm_put_interface(intf);
- loop_disconnected:
- usb_unlock_device(hdev);
- kref_put(&hub->kref, hub_release);
- }
- }
9.usb注册通用设备驱动
- 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_device_driver结构体是usb_driver的简化版本,这里注册的是usb设备(非接口)驱动
usb总线的match方法对usb设备和usb接口做了区分处理,针对usb设备,直接match的,(分析match时候再细化)
然后调用usb设备驱动的probe方法
- static int usb_probe_device(struct device *dev)
- {
- struct usb_device_driver *udriver = to_usb_device_driver(dev->driver);
- struct usb_device *udev = to_usb_device(dev);
- int error = 0;
- dev_dbg(dev, "%s\n", __func__);
- if (!udriver->supports_autosuspend)
- error = usb_autoresume_device(udev);
- if (!error)
- error = udriver->probe(udev);
- return error;
- }
接着调用usb_generic_driver的probe方法
- struct usb_device_driver usb_generic_driver = {
- .name = "usb",
- .probe = generic_probe,
- .disconnect = generic_disconnect,
- #ifdef CONFIG_PM
- .suspend = generic_suspend,
- .resume = generic_resume,
- #endif
- .supports_autosuspend = 1,
- };
所以generic_probe函数会接着被调用
- static int generic_probe(struct usb_device *udev)
- {
- int err, c;
- if (usb_device_is_owned(udev))
- ;
- 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);
- }
- }
- }
-
- usb_notify_add_device(udev);
- return 0;
- }