usb framwork & 设备枚举

一、层次结构

# app:   
-------------------------------------------
          USB设备驱动程序      // 解析usb设备通过usb总线传输过来的数据含义,或者发送特定含义的数据给usb设备
# 内核 --------------------------------------
          USB总线驱动程序      // 1. 识别, 2. 找到匹配的设备驱动, 3. 提供USB读写函数 (不关心数据含义)
        (drivers/usb/core/hub.c)
-------------------------------------------
           USB主机控制器
         UHCI OHCI EHCI XHCI
# 硬件      ---------------
              USB设备

二. USB主机控制器驱动(HCD hub control drvier)初始化工作

// 一、hub初始化

usb_hub_init
     // 1. hub drv注册
    usb_register(&hub_driver) 

         hub_probe
            hub_configure

                //(1) urb alloc
                hub->urb = usb_alloc_urb(0, GFP_KERNEL);

                //(2)fill urb    hub_irq urb完成处理函数 《☆ 1.2》
                usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq,hub, endpoint->bInterval);
                // (3) 提交urb
                hub_activate
                    usb_submit_urb(hub->urb, GFP_NOIO);

    // 2. 启动 “khubd” 线程 
    khubd_task = kthread_run(hub_thread, NULL, "khubd");  

    hub_thread
        do {
            hub_events();  // hub事件处理函数  《☆ 2.1》

             // 等待唤醒事件
            wait_event_freezable(khubd_wait,
                    !list_empty(&hub_event_list) ||
                    kthread_should_stop());  

        } while (!kthread_should_stop() || !list_empty(&hub_event_list));



//☆ 1.2 hub_irq   urb完成处理函数(说明hub上有事件发生了)
hub_irq
    kick_khubd(hub);    // 踢一脚(唤醒)“khubd” 线程    
    usb_submit_urb (hub->urb, GFP_ATOMIC)); // 重新提交urb



----------
// ☆ 2.1 hub事件处理函数 hub_events

    hub_events
        port_event(hub, i);  //检测那个port发生改变
            if (connect_change)
                hub_port_connect_change  
                    hub_port_connect

                        udev = usb_alloc_dev(hdev, hdev->bus, port1);
                                     dev->dev.bus = &usb_bus_type;

                        choose_address(udev); // 给新设备分配编号(地址)

                        hub_port_init   // usb 1-1: new full speed USB device using s3c2410-ohci and address 3
                            hub_set_address  // 把编号(地址)告诉USB设备

                            usb_get_device_descriptor(udev, 8);                     // 获取设备描述符长度
                            usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);    // 获取所有设备描述符 

                            usb_new_device(udev)   // ☆ 解析设备的各种描述符信息,分配资源,并与相应的设备驱动程序建立联系。
                                usb_enumerate_device
                                    usb_get_configuration(udev); // 把所有的描述符都读出来,并解析
                                        usb_get_descriptor
                                        usb_parse_configuration

                                device_add  // 把device放入usb_bus_type的dev链表, 
                                            // 从usb_bus_type的driver链表里取出usb_driver,
                                            // 把usb_interface和usb_driver的id_table比较
                                            // 如果能匹配,调用usb_driver的probe           




函数usb_new_device主要完成以下工作:

1.调用usb_set_address把新分配的设备地址传送给设备。

2.调用usb_get_descriptor获得设备的设备描述符,得到设备端点的包的最大长度,接下来的控制传输按这个数据包最大长度进行。

3.调用usb_get_configuration得到设备的所有配置描述符、接口描述符和端点描述符信息。

4.调用usb_set_configuration激活当前的配置作为默认工作配置。

5.在目录“proc/bus/usb”中为设备创建节点。

6.在USB子系统中,通过函数usb_find_drivers和usb_find_interface_driver,为设备的每一个接口寻找相应的驱动程序,驱动程序对接口进行配置并为它们分配所需的资源。当每个接口被成功驱动后,此设备就能正常工作了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值