邮箱:zhuimengcanyang@163.com 痴爱嵌入式技术的蜗牛
分类: LINUX
2015-12-09 15:07:19
kthread_run(hub_thread, NULL, "khubd"); 线程: hub_thread(void *__unused) /** 处理hub 口上发生的事情: 比如USB 插入或者拔下 * 如果有此类事情发生,则调用: hub_port_connect_change(); * 在函数hub_port_connect_change 中就完成USB 设备的枚举过程, * 实现USB 设备的查找,获取描述符,以及安装USB设备相对应驱动的过程。 */ hub_events(); // 如果端口连接发生变化(USB设备插入或者拔出等) hub_port_connect_change(hub, i, portstatus, portchange); usb_alloc_dev(hdev, hdev->bus, port1); choose_address(udev); // 分配一个地址给USB设备 hub_port_init(hub, udev, port1, i); hub_set_address(udev); // 设置USB设备的地址 usb_get_device_descriptor(udev, 8); // 获取需要的设备描述符 usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE); usb_new_device(udev); // udev: struct usb_device usb_get_configuration(udev) // 获取配置信息 device_add(&udev->dev) device_add(&udev->dev); // udev->dev: struct device bus_attach_device(dev) // 将设备(usb device)绑定到bus上去 struct bus_type *bus = dev->bus; // usb_bus_type if (bus->drivers_autoprobe) // 这个变量哪里设置了?? device_attach(dev) // 这里是注册device (对应的是usb interface) /* 从dev指定bus的drv链表上,取出drv和dev一一进行比较 * 调用__device_attach, 如果匹配则最终会调用bus中的.match 函数 */ bus_for_each_drv(dev->bus, NULL, dev, __device_attach); => __device_attach driver_probe_device(drv, dev) //从bus 的drv 链表取出drv 和dev 进行比较匹配,调用函数:usb_device_match drv->bus->match(dev, drv) // 相当于调用:usb_device_match really_probe(dev, drv); // 如果drv 和dev 匹配,则调用probe 函数 drv->probe(dev) // 调用drv上的probe函数:usb_probe_interface (注:这里是USB interface) => usb_probe_interface intf = to_usb_interface(dev); udev = interface_to_usbdev(intf); usb_match_id(intf, driver->id_table); usb_match_dynamic_id(intf, driver); usb_autoresume_device(udev); usb_autosuspend_device(udev); // 如果hub上没有event事件发生,则进入休眠状态,谁来唤醒? wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)||kthread_should_stop()); |
static void hub_irq(struct urb *urb)问题3: 谁来调用: hub_irq
static void kick_khubd(struct usb_hub *hub)
wake_up(&khubd_wait);
static int hub_configure(struct usb_hub *hub,
// 当提交完成urb后,将调用完成函数: hub_irq, 这里只是初始化该函数
usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq, hub, endpoint->bInterval);
usb_register(struct usb_driver *driver) // (struct usb_driver)
usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
new_driver->drvwrap.driver.bus = &usb_bus_type; // (new_driver->drvwrap.driver: struct device_driver driver)
new_driver->drvwrap.driver.probe = usb_probe_interface;
new_driver->drvwrap.driver.remove = usb_unbind_interface;
driver_register(&new_driver->drvwrap.driver); // 注册struct device_driver driver结构体 --> usb_driver
bus_add_driver(drv);
if (drv->bus->drivers_autoprobe)
driver_attach(drv);
// 从usb_bus_type总线的dev链表中取出dev,和该driver进行一一比较
bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
// 执行该函数
__driver_attach(struct device * dev, void * data)
if (!dev->driver)
driver_probe_device(drv, dev);
// 从usb_bus_type总线中取出.match函数,进行比较
drv->bus->match(dev, drv) // 这里:drv->bus->match = usb_bus_type.match = usb_device_match
=> usb_device_match(struct device *dev, struct device_driver *drv)
// 比较接口(USB的接口intf)和driver中的id_table是否对应
usb_match_id(intf, usb_drv->id_table);
really_probe(dev, drv);
drv->probe(dev); // drv->probe = usb_probe_interface
=> usb_probe_interface
// 从struct device找到usb_interface和usb_device
intf = to_usb_interface(dev);
udev = interface_to_usbdev(intf);
// 比较intf和driver中的id_table
// 因为在usb驱动中,需要建立usb intf 和 usb driver的对应关系
usb_match_id(intf, driver->id_table);
usb_match_dynamic_id(intf, driver);
//
usb_autoresume_device(udev);
driver->probe(intf, id); // 这个是用户自己编写驱动需要提供的probe函数
usb_autosuspend_device(udev);