在/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(); //1.usb debugfs初始化 if (retval) goto out; retval = bus_register(&usb_bus_type); //2.usb总线注册 if (retval) goto bus_register_failed; retval = bus_register_notifier(&usb_bus_type, &usb_bus_nb); //3.usb总线通知链注册 if (retval) goto bus_notifier_failed; retval = usb_major_init(); //4.注册usb主控器字符设备 if (retval) goto major_init_failed; retval = usb_register(&usbfs_driver); //5.注册usbfs驱动 if (retval) goto driver_register_failed; retval = usb_devio_init(); //6.usb设备字符设备初始化 if (retval) goto usb_devio_init_failed; retval = usbfs_init(); //7.usbfs初始化 if (retval) goto fs_init_failed; retval = usb_hub_init(); //8.usb hub初始化 if (retval) goto hub_init_failed; retval = usb_register_device_driver(&usb_generic_driver, THIS_MODULE); //9.usb注册同样设备驱动 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); //创建"$(debugfs)/usb" if (!usb_debug_root) return -ENOENT; usb_debug_devices = debugfs_create_file("devices", 0444,usb_debug_root, NULL,&usbfs_devices_fops); //创建"$(debugfs)/usb/device",捆绑usbfs_devices_fops结构体 if (!usb_debug_devices) { //若创建失败 debugfs_remove(usb_debug_root); //则必须把“$(debugfs)/usb”也删除掉 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) //usb设备 (void) usb_create_sysfs_dev_files(to_usb_device(dev)); else if (dev->type == &usb_if_device_type) //usb接口 (void) usb_create_sysfs_intf_files(to_usb_interface(dev)); break; case BUS_NOTIFY_DEL_DEVICE: //删除设备 if (dev->type == &usb_device_type) //usb设备 usb_remove_sysfs_dev_files(to_usb_device(dev)); else if (dev->type == &usb_if_device_type) //usb接口 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); //注册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"); //创建"/sys/class/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); //创建"/proc/bus/usb" 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) { //注册usb hub设备驱动 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, //hub连接上 .disconnect = hub_disconnect, //hub断开 .suspend = hub_suspend, //hub挂起 .resume = hub_resume, //hub唤醒 .reset_resume = hub_reset_resume, //hub复位唤醒 .pre_reset = hub_pre_reset, .post_reset = hub_post_reset, .unlocked_ioctl = hub_ioctl, .id_table = hub_id_table, //hub设备驱动 id表 .supports_autosuspend = 1, };
hub_thread守护进程
static int hub_thread(void *__unused) { set_freezable(); //设置可冻结 do { hub_events(); //hub事件处理函数 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); //第一次执行假设usb主控器还没注册 if (list_empty(&hub_event_list)) { //usb事件链表为空 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; //usb设备 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; //probe方法 new_udriver->drvwrap.driver.remove = usb_unbind_device; //remove方法 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); //调用usb_device_driver的probe方法 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 device state == configured ... usable */ usb_notify_add_device(udev); //发送设备添加通知 return 0; }
<---usb子系统相关结构体
--->usb主控器注册