三、usb设备的识别过程

在这里梳理一下上一篇博客中的内容:(这张图来自https://blog.csdn.net/lizuobin2/article/details/51931161)

  上一篇博客刚好从平台设备、驱动的匹配分析到hub_irq这个函数这里。

static void hub_irq(struct urb *urb)
{
struct usb_hub *hub = urb->context;
int status = urb->status;
unsigned i;
unsigned long bits;
switch (status) {
....
case : // 端口的状态发生了变化
bits = ;
for (i = ; i < urb->actual_length; ++i)
bits |= ((unsigned long) ((*hub->buffer)[i]))
<< (i*);
hub->event_bits[] = bits; // 保存状态改变的信息
break;
} hub->nerrors = ;
/* Something happened, let khubd figure it out */
kick_khubd(hub); // 重要函数 唤醒hub线程
resubmit:
if (hub->quiescing)
return;
if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) !=
&& status != -ENODEV && status != -EPERM)
dev_err (hub->intfdev, "resubmit --> %d\n", status);
}

在kick_khubd(hub)中会唤醒执行wake_up(&khubd_wait)来唤醒一个程序。那么唤醒的到底是哪个程序呢?

int usb_hub_init(void)
{
// 这里注册了hub_driver 这个在上一篇博客中提到过
if (usb_register(&hub_driver) < ) {
}
// 这里创建了一个hub_thread 名字叫"khubd"
khubd_task = kthread_run(hub_thread, NULL, "khubd");
/* Fall through if kernel_thread failed */
usb_deregister(&hub_driver);
printk(KERN_ERR "%s: can't start khubd\n", usbcore_name);
return -;
}

现在可以看看在hub_thread这个线程中做一些什么事?

static int hub_thread(void *__unused)
{
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));
return ;
}

  在这个内核线程中主要执行hub_events(),但是平时应该是休眠状态,直到有事情发生,其他程序中将其唤醒。因此可以说是在hub_irq 函数中唤醒了hub_thread,使得hub_thread能够执行hub_events()

函数。

  当有usb设备插入时,主机控制器检测到hub端口状态的变化,会执行hub_irq函数,然后按照下图的函数调用顺序一路往下执行,实现usb设备的识别过程:

  (1)给新设备分配地址

(2)并将该地址告诉usb设备即设置usb地址

  (3)发出命令读取描述符

  (4)执行usb_new_device和device_add(向总线上添加usb设备)

  (5)device_add 之后又会执行usb_device_match函数和generic_probe函数,在generic_probe 函数中 选择和设置 配置 之后又会执行device_add(向usb总线上添加接口设备)

(6)device_add 之后又会执行usb_device_match函数(这个时候应该就根据id_table和自己写的设备驱动进行匹配操作了)和xx_probe函数(自己驱动的probe函数)。

      

  

最新文章

  1. Hammer.js--转载自李林峰的园子
  2. C语言的关键字,运算符,标识符
  3. JSP中request getParameter和getAttribute不同(转载)
  4. 苹果会在明后年推出13寸屏iPad吗?
  5. Emgu学习之(一)——Emgu介绍
  6. UIBarButtonItem变弹簧
  7. Tesseract训练笔记
  8. hdu2571
  9. [STL]单词转换
  10. PHP中CURL方法curl_setopt()函数的一些参数 (转)
  11. PYTHON小CASE
  12. hive 动态分区数设置
  13. CSS基础--常用样式
  14. Python学习总结 11 使用tempest测试OpenStack
  15. Kubernetes — Job与CronJob
  16. mobile_竖向滑屏
  17. jq 绑定事件和解绑事件
  18. 《Inside C#》笔记(十五) 非托管代码 下
  19. 关于ios下字体描边的一个细节
  20. java 快速开发框架平台 二次开发 代码生成器 springmvc SSM后台框架源码

热门文章

  1. 使用 tuned/tuned-adm工具动态调优系统CPU性能模式
  2. Sed---linux系统三剑客(二)
  3. admin源码分析
  4. 使用注解和xml两种方式整合Activemq与spring(gradle工程)
  5. flex布局时,vertical-align:middle无效
  6. jquery中 $.expr使用实例介绍
  7. Eclipse配置编写HTML/JS/CSS/JSP页面的自动提示
  8. jdk1.8 -- 自定义FunctionInterface
  9. ValueError: row index was 65536, not allowed by .xls format
  10. 笔记-3:mysql数据定义