三、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函数)。

      

  

linux usb驱动记录(二)的更多相关文章

  1. linux usb驱动记录(一)

    一.linux 下的usb驱动框架 在linux系统中,usb驱动可以从两个角度去观察,一个是主机侧,一个是设备侧.linux usb 驱动的总体框架如下图所示:   从主机侧看usb驱动可分为四层: ...

  2. Linux USB驱动框架分析 【转】

    转自:http://blog.chinaunix.net/uid-11848011-id-96188.html 初次接触与OS相关的设备驱动编写,感觉还挺有意思的,为了不至于忘掉看过的东西,笔记跟总结 ...

  3. Linux USB驱动框架分析【转】

    转自:http://blog.csdn.net/jeffade/article/details/7701431 Linux USB驱动框架分析(一) 初次接触和OS相关的设备驱动编写,感觉还挺有意思的 ...

  4. linux usb 驱动详解

    linux usb 驱动详解 USB 设备驱动代码通过urb和所有的 USB 设备通讯.urb用 struct urb 结构描述(include/linux/usb.h ). urb 以一种异步的方式 ...

  5. Linux USB驱动

    linux usb 驱动详解 一 http://blog.163.com/cl2006ky@126/blog/static/87195173201131245557340/ USB设备驱动开发-USB ...

  6. Linux usb子系统(二):USB设备驱动usb-skeleton.c

    usb驱动分为通过usbfs操作设备的用户空间驱动,内核空间的内核驱动.两者不能同时进行,否则容易引发对共享资源访问的问题,死锁!使用了内核驱动,就不能在usbfs里驱动该设备. 下面转载的一篇分析u ...

  7. Linux USB驱动学习总结(二)---- USB设备驱动

    USB 设备驱动: 一.USB 描述符:(存在于USB 的E2PROM里面) 1.  设备描述符:struct usb_device_descriptor 2.  配置描述符:struct usb_c ...

  8. Linux USB驱动框架分析(2)【转】

    转自:http://blog.chinaunix.net/uid-23046336-id-3243543.html   看了http://blog.chinaunix.net/uid-11848011 ...

  9. Linux spi驱动分析(二)----SPI核心(bus、device_driver和device)

    一.spi总线注册 这里所说的SPI核心,就是指/drivers/spi/目录下spi.c文件中提供给其他文件的函数,首先看下spi核心的初始化函数spi_init(void).程序如下: 点击(此处 ...

随机推荐

  1. Security命名空间配置

    http://www.mossle.com/docs/springsecurity3/html/ns-config.html Security命名空间配置 2.1. 介绍 从Spring-2.0开始可 ...

  2. Ubuntu下Iptables的简单运用,开放/关闭端口,禁止/允许IP或IP段访问...

    首先添加规则有两个参数:-A和-I,其中-A是添加到规则的末尾:-I可以插入到指定位置,没有指定位置的话默认插入到规则的首部,由于匹配规则是从上往下,依次查找的,可能出现配置的规则冲突导致后续的规则不 ...

  3. 启动Nginx 出现 nginx: [emerg] unknown directive "锘?user" 错误

    出现这种情况 一般是修改配置文件 nginx.conf 造成的 如果你修改文件后出现 那基本上就是这个原因 启动不了 重新打开 改为UTF-8 无BOM编码

  4. DS博客大作业--树(李天明组)

    DS博客大作业--树 大作业博客要求 (10分) 1.树的存储结构说明 .树采用的是链式存储结构. .这段代码中定义了两个结构体.第一个是自定义为Name类型的结构体,里面的成员有字符串str和类型为 ...

  5. 第一周--------带标签的 continue

  6. linux_mysql学习系列

    Linux&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html 网站架构系列文章:http://www.cnblogs.co ...

  7. Kubernetes---资源控制器之ReplicationController、ReplicaSet和Deployment

    1.ReplicationController和ReplicaSet介绍 RC(ReplicationController)主要的作用就是用来确保容器应用的副本数始终保持在用户定义的副本数.即如果有容 ...

  8. Web应用中访问WEB-INF下的资源

    WEB-INF目录是出于保护资源文件的目的,只能我们开发人员自己查看不可以通过URL直接访问的: 有时候我们也想直接访问WEB-INF中的资源,那就需要用到请求转发了(重定向redirect是不可以的 ...

  9. HDU 3642 求体积交集

    Get The Treasury 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=3642 Problem Description Jack knows ...

  10. C/C++快读(快速读入)有多——安全AC

    在一些算法题目中中,有的程序会被卡常(数),就是说,程序虽然渐进复杂度,(通俗来讲:算法的时间复杂度)可以接受,但因为算法本身的时间常数过大,导致程序在一些算法竞赛中超时.这是,快读就显得尤为重要了. ...