赞
踩
1、roothub通常被集成在了主控制器。
初始化driver/core/usb.c中
- static int __init usb_init(void)
- {
- 。。。
- retval = usb_hub_init();
- if (retval)
- goto hub_init_failed;
- 。。。
- return retval;
- }
- int usb_hub_init(void)
- {
- if (usb_register(&hub_driver) < 0) { //先注册hub驱动</span></strong>
- 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)) //判断创建的进程是否正确</strong>
- return 0;
-
- /* Fall through if kernel_thread failed */
- usb_deregister(&hub_driver);
- printk(KERN_ERR "%s: can't start khubd\n", usbcore_name);
-
- return -1;
- }

判断空间开辟是否正确判断:通常将最后一页来存放错误号的,当返回的指针指向了最后页就代表错误。
#define MAX_ERRNO 4095 #ifndef __ASSEMBLY__ #define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO) //例如32bit 最高地址0xffffffff,最后页地址0xfffff000-0xffffffff static inline void * __must_check ERR_PTR(long error) { return (void *) error; } static inline long __must_check PTR_ERR(const void *ptr) { return (long) ptr; } static inline long __must_check IS_ERR(const void *ptr) { return IS_ERR_VALUE((unsigned long)ptr); }
- #define list_entry(ptr,type,member) \
- container_of(ptr,type,member) //ptr是type变量中的member成员的指针,通过该ptr得type指针。
- static int hub_thread(void *__unused)
- {
- set_freezable();
- do {
- hub_events();
- wait_event_freezable(khubd_wait,
- !list_empty(&hub_event_list) || //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;
- }
wait_event_interruptible= sleep until a condition gets true,即条件为假则休眠
总:设置一个链表hub_event_list,设置一个总的函数hub_event()
分:每个hub都有个event_list,当有hub的event_list发生变化时,把该event_list插到hub_event_list中
总:再触发总hub_event()
分:hub_event又根据event_list确定是哪个struct usb_hub或者哪个hub有问题
接着看hub_event
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) { /* Grab the first entry at the beginning of the list */ spin_lock_irq(&hub_event_lock); if (list_empty(&hub_event_list)) { spin_unlock_irq(&hub_event_lock); >break; } .....
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。