hub_irq() --> kick_khubd()
唤醒等待队列khubd_wait。中断处理程序将到此结束
static void kick_khubd(struct usb_hub *hub)
{
unsigned long flags;
to_usb_interface(hub->intfdev)->pm_usage_cnt = 1;
spin_lock_irqsave(&hub_event_lock, flags);
if (list_empty(&hub->event_list)) {
list_add_tail(&hub->event_list, &hub_event_list); //(1)
wake_up(&khubd_wait); //(2)
}
spin_unlock_irqrestore(&hub_event_lock, flags);
}
(1) 将当前hub通过hub->event_list插入到静态双向链表hub_event_list中,等待hub_events()处理该hub上发生的事件
(2) 唤醒等待队列khubd_wait上的等待线程hub_thread
--------------------------------
/usr/src/linux-2.6.21.5/drivers/usb/core/hcd.c +2814
kick_khubd()将唤醒该进程,表示有hub events发生static int hub_thread(void *__unused)
{
do {
hub_events();
如果条件成立则将该线程(hub_thread)插入等待队列khubd_wait中,等待hub事件
wait_event_interruptible(khubd_wait,
!list_empty(&hub_event_list) || kthread_should_stop());
try_to_freeze();
} while (!kthread_should_stop() || !list_empty(&hub_event_list));
pr_debug("%s: khubd exiting\n", usbcore_name);
return 0;
}
--------------------------------
/usr/src/linux-2.6.21.5/drivers/usb/core/hcd.c +87
生成一个名为khubd_wait的等待队列头
static DECLARE_WAIT_QUEUE_HEAD(khubd_wait);
--------------------------------
/usr/src/linux-2.6.21.5/drivers/usb/core/hcd.c +84
生成一个名为hub_event_list静态双向链表头节点
khubd's worklist and its lock
static DEFINE_SPINLOCK(hub_event_lock);
static LIST_HEAD(hub_event_list);
转自:http://hi.baidu.com/zengzhaonong/blog/item/a450e8032d8837ee08fa93ef.html