当前位置:   article > 正文

linux那些事之hub--初始_hub的初始 复旦人甲

hub的初始 复旦人甲

1、roothub通常被集成在了主控制器。

初始化driver/core/usb.c中

  1. static int __init usb_init(void)
  2. {
  3. 。。。
  4. retval = usb_hub_init();
  5. if (retval)
  6. goto hub_init_failed;
  7. 。。。
  8. return retval;
  9. }
  1. int usb_hub_init(void)
  2. {
  3. if (usb_register(&hub_driver) < 0) { //先注册hub驱动</span></strong>
  4. printk(KERN_ERR "%s: can't register hub driver\n",
  5. usbcore_name);
  6. return -1;
  7. }
  8. khubd_task = kthread_run(hub_thread, NULL, "khubd");
  9. if (!IS_ERR(khubd_task)) //判断创建的进程是否正确</strong>
  10. return 0;
  11. /* Fall through if kernel_thread failed */
  12. usb_deregister(&hub_driver);
  13. printk(KERN_ERR "%s: can't start khubd\n", usbcore_name);
  14. return -1;
  15. }
判断空间开辟是否正确判断:通常将最后一页来存放错误号的,当返回的指针指向了最后页就代表错误。

  1. #define MAX_ERRNO 4095
  2. #ifndef __ASSEMBLY__
  3. #define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO) //例如32bit 最高地址0xffffffff,最后页地址0xfffff000-0xffffffff
  4. static inline void * __must_check ERR_PTR(long error)
  5. {
  6. return (void *) error;
  7. }
  8. static inline long __must_check PTR_ERR(const void *ptr)
  9. {
  10. return (long) ptr;
  11. }
  12. static inline long __must_check IS_ERR(const void *ptr)
  13. {
  14. return IS_ERR_VALUE((unsigned long)ptr);
  15. }
  1. #define list_entry(ptr,type,member) \
  2. container_of(ptr,type,member) //ptr是type变量中的member成员的指针,通过该ptr得type指针。


  1. static int hub_thread(void *__unused)
  2. {
  3. set_freezable();
  4. do {
  5. hub_events();
  6. wait_event_freezable(khubd_wait,
  7. !list_empty(&hub_event_list) || //hub_event_list 为全局变量
  8. kthread_should_stop());
  9. } while (!kthread_should_stop() || !list_empty(&hub_event_list));
  10. pr_debug("%s: khubd exiting\n", usbcore_name);
  11. return 0;
  12. }
wait_event_interruptible= sleep until a condition gets true,即条件为假则休眠


在hub中采用总分总分的结构来处理hub事件,如先

总:设置一个链表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

  1. static void hub_events(void)
  2. {
  3. struct list_head *tmp;
  4. struct usb_device *hdev;
  5. struct usb_interface *intf;
  6. struct usb_hub *hub;
  7. struct device *hub_dev;
  8. u16 hubstatus;
  9. u16 hubchange;
  10. u16 portstatus;
  11. u16 portchange;
  12. int i, ret;
  13. int connect_change;
  14. while (1) {
  15. /* Grab the first entry at the beginning of the list */
  16. spin_lock_irq(&hub_event_lock);
  17. if (list_empty(&hub_event_list)) {
  18. spin_unlock_irq(&hub_event_lock);
  19. >break;
  20. }
  21. .....

这里判断 hub_event_list为空,则直接退出该函数,线程hub_thread睡眠




声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/263501
推荐阅读
相关标签
  

闽ICP备14008679号