USB core(三) - hub.c
2015-11-04 22:43
375 查看
core/hub.c文件中主要分为两块去理解:
一是hub_thread这个线程,当被唤醒后会调用hub_events
另外一个是root_hub经过与usb_device_driver匹配后添加的intf->dev,intf->dev与hub_driver匹配进入hub_probe函数。
hub_thread这个线程平时都处于睡眠状态,通过wake_up(&khubd_wait)将线程唤醒执行hub_events函数
在hub_events中主要做的事是从hub_events_list中获取struct usb_hub,然后读取这个usb_hub port的portstatus和portchange,将portstatus和portchange传给hub_port_connect_change处理。
hub_port_connect_change查看是否真有设备插入,如果有,则分配一个struct usb_device,然后获取这个usb_device的描述符等信息,最后添加这个usb_device,usb_device将会与usb_device_driver匹配进入generic_probe函数,之后添加intf->dev,与interface层面的usb driver匹配,进入xxx_probe函数。
一是hub_thread这个线程,当被唤醒后会调用hub_events
另外一个是root_hub经过与usb_device_driver匹配后添加的intf->dev,intf->dev与hub_driver匹配进入hub_probe函数。
hub_thread
hub_thread
static int hub_thread(void *__unused) { /* khubd needs to be freezable to avoid intefering with USB-PERSIST * port handover. Otherwise it might see that a full-speed device * was gone before the EHCI controller had handed its port over to * the companion full-speed controller. */ 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; }
hub_thread这个线程平时都处于睡眠状态,通过wake_up(&khubd_wait)将线程唤醒执行hub_events函数
hub_events
static void hub_events(void) { while (1) { spin_lock_irq(&hub_event_lock); //如果hub_event_list链表为空,那么什么都不做 if (list_empty(&hub_event_list)) { spin_unlock_irq(&hub_event_lock); break; } tmp = hub_event_list.next; list_del_init(tmp); //根据event_list,获得struct usb_hub hub = list_entry(tmp, struct usb_hub, event_list); spin_unlock_irq(&hub_event_lock); ... /* deal with port status changes */ for (i = 1; i <= hub->descriptor->bNbrPorts; i++) { //查看connect_change,wakeup_change,event_bits是否有变化, //有才继续执行下去,否则查看下一个port hub_port_status(hub, i, &portstatus, &portchange); if (portchange & USB_PORT_STAT_C_CONNECTION) { usb_clear_port_feature(hdev, i, USB_PORT_FEAT_C_CONNECTION); connect_change = 1; } if (portchange & USB_PORT_STAT_C_ENABLE) ... if (connect_change) hub_port_connect_change(hub, i, portstatus, portchange); } }
在hub_events中主要做的事是从hub_events_list中获取struct usb_hub,然后读取这个usb_hub port的portstatus和portchange,将portstatus和portchange传给hub_port_connect_change处理。
hub_port_connect_change
static void hub_port_connect_change(struct usb_hub *hub, int port1, u16 portstatus, u16 portchange) { struct usb_device *udev; hub_port_debounce_be_stable(hub, port1); udev = usb_alloc_dev(hdev, hdev->bus, port1); hub_port_init(hub, udev, port1, i); hub_port_reset(hub, port1, udev, delay, false); usb_control_msg(udev, usb_rcvaddr0pipe(), USB_REQ_GET_DESCRIPTOR... hub_port_reset(hub, port1, udev, delay, false); hub_set_address(udev, devnum); usb_get_device_descriptor(udev, 8); usb_new_device(udev); usb_enumerate_device(udev); usb_get_configuration(udev); announce_device(udev); device_add(&udev->dev); }
hub_port_connect_change查看是否真有设备插入,如果有,则分配一个struct usb_device,然后获取这个usb_device的描述符等信息,最后添加这个usb_device,usb_device将会与usb_device_driver匹配进入generic_probe函数,之后添加intf->dev,与interface层面的usb driver匹配,进入xxx_probe函数。
hub_probe
相关文章推荐
- 3Sum Closest 解答
- 课后作业
- Java实现通过递归遍历树形结构
- LightOJ - 1380 Teleport(最小树形图)
- 关于学习MMU的一点感想
- 关于学习MMU的一点感想
- 关于学习MMU的一点感想
- poj 1305
- JavaScript中的this
- diy高手在民间
- 安卓客户端和php服务端传输包含中文文件名的文件
- OC三大特性之一:封装的介绍
- 项目注释模板
- <HTML5秘籍>——第6章(美妙的CSS3字体和特效)
- 银行家算法
- LightOJ - 1026 Critical Links(桥)
- (学习笔记)栈数据结构中压(入)栈操作(C语言实现)
- iOS开发17-iOS 模态视图的使用
- VS2012下安装NuGet
- noip 11.3~11.4模拟总结