Linux usb Host 详解

本文详细介绍了Linux系统中USB Host的各个组件,包括Usb Core驱动设备模型、USB Request Block、Usb Hub Driver、Usb Host Controller Driver以及Usb Client Software。Usb Core驱动模型分为Usb Device Layer和Usb Interface Layer,分别对应设备和接口驱动。Usb Request Block用于设备读写操作。Usb Hub Driver监控端口状态变化,创建或移除设备。Usb Host Controller Driver如EHCI,负责数据传输调度。最后,文章以usb鼠标驱动为例展示了Usb Client Software如何利用urb与USB设备交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.简介

整个 USB 系统的通讯模型如上图所示,本文详细解析其中 Host 各模块的架构和原理 (图中彩色部分)。

2. Usb Core 驱动设备模型

由前几节可知USB将Device进一步细分成了3个层级:Configuration 配置、Interface 接口、Endpoint 端点。

Usb  Core 为其中两个层次提供了 Device + Driver 的设备驱动模型,这两个层次分别是 Usb Device Layer 和 Usb  Interface Layer 层,一个Usb Device包含一个或多个Usb Interface。其中:

  • Usb Device Layer层。这一层的 Device 由 Hub 创建,Hub 本身也是一种 Usb Device;这一层的 Driver 完成的功能非常简单,基本就是帮 Usb Device 创建其包含的所有子 Usb Interface 的 Device,大部分场景下都是使用 usb_generic_driver。
  • Usb Interface Layer层。这一层的 Device 由上一级 Usb Device 在驱动 probe() 时创建;而这一层的 Driver 就是普通的业务 Usb 驱动,即 Usb 协议中所说的 Client Software。

2.1 Usb Device Layer

2.1.1 device (struct usb_device)

Usb Device Device 对应的数据结构为 struct usb_device,会在两种情况下被创建:

1、roothub device。在 HCD 驱动注册时创建:

/* (1) 首先创建和初始化 `usb_device` 结构:*/
usb_add_hcd() → usb_alloc_dev():
struct usb_device *usb_alloc_dev(struct usb_device *parent,
         struct usb_bus *bus, unsigned port1)
{


  /* (1.1) dev 总线初始化为 usb_bus_type */
  dev->dev.bus = &usb_bus_type;
  /* (1.2) dev 类型初始化为 usb_device_type,标明自己是一个 usb device */
  dev->dev.type = &usb_device_type;
  dev->dev.groups = usb_device_groups;


}


/* (2) 然后注册  `usb_device` 结构:*/
usb_add_hcd() → register_root_hub() → usb_new_device() → device_add()

2、普通 usb device。在 Hub 检测到端口有设备 attach 时创建:

/* (1) 首先创建和初始化 `usb_device` 结构:*/
hub_event() → port_event() → hub_port_connect_change() → hub_port_connect() → usb_alloc_dev()


/* (2) 然后注册  `usb_device` 结构:*/
hub_event() → port_event() → hub_port_connect_change() → hub_port_connect() → usb_new_device() → device_add()

2.1.2 driver (struct usb_device_driver)

Usb Device Driver 对应的数据结构为 struct usb_device_driver,使用 usb_register_device_driver() 函数进行注册:

int usb_register_device_driver(struct usb_device_driver *new_udriver,
    struct module *owner)
{


  /* (1) 设置for_devices标志为1,表面这个驱动时给 usb device 使用的 */
  new_udriver->drvwrap.for_devices = 1;
  new_udriver->drvwrap.driver.name = new_udriver->name;
  new_udriver->drvwrap.driver.bus = &usb_bus_type;
  new_udriver->drvwrap.driver.probe = usb_probe_device;
  new_udriver->drvwrap.driver.remove = usb_unbind_device;
  new_udriver->drvwrap.driver.owner = owner;
  new_udriver->drvwrap.driver.dev_groups = new_udriver->dev_groups;


  retval = driver_register(&new_udriver->drvwrap.driver);


}

注册的 Usb Device Driver 驱动非常少,一般情况下所有的 Usb Device Device 都会适配到 usb_generic_driver。因为这一层次驱动的目的很单纯,就是给 Usb Device 下所有的 Interface 创建对应的 Usb Interface Device。

usb_init() → usb_register_device_driver() :


static int __init usb_init(void)
{


  retval = usb_register_device_driver(&usb_generic_driver, THIS_MODULE);


}


struct usb_device_driver usb_generic_driver = {
  .name =  "usb",
  .match = usb_generic_driver_match,
  .probe = usb_generic_driver_probe,
  .disconnect = usb_generic_driver_disconnect,
#ifdef  CONFIG_PM
  .suspend = usb_generic_driver_suspend,
  .resume = usb_generic_driver_resume,
#endif
  .supports_autosuspend = 1,
};

驱动 probe() 过程:

usb_probe_device() → usb_generic_driver_probe() → usb_set_configuration():


int usb_set_configuration(struct usb_device *dev, int configuration)
{


  /* (1) 创建和初始化 `struct usb_interface` */
  for (i = 0; i < nintf; ++i) {
    /* (1.1) dev 总线初始化为 usb_bus_type */
    intf->dev.bus = &usb_bus_type;
    /* (1.2) dev 类型初始化为 usb_if_device_type,标明自己是一个 usb interface */
    intf->dev.type = &usb_if_device_type;
    intf->dev.groups = usb_interface_groups;
  }


  /* (2) 注册 `struct usb_interface` */
  for (i = 0; i < nintf; ++i) {
    ret = device_add(&intf->dev);
  }


}

2.1.3 bus (usb_bus_type)

可以看到 struct usb_device 和 struct usb_interface 使用的总线都是 usb_bus_type。他们是通过字段 dev.type 来区分的:

/* (1) `struct usb_device` 的 `dev.type` 值为 `usb_device_type`:*/
usb_add_hcd() → usb_alloc_dev():
struct usb_device *usb_alloc_dev(struct usb_device *parent,
         struct usb_bus *bus, unsigned port1)
{
  dev->dev.type = &usb_device_type;
}


/* (2) `struct usb_interface` 的 `dev.type` 值为 `usb_if_device_type` */
usb_probe_device() → usb_generic_driver_probe() → usb_set_configuration():
int usb_set_configuration(struct usb_device *dev, int configuration)
{
  for (i = 0; i < nintf; ++i) {
    intf->dev.type = &usb_if_device_type;
  }
}


static inline int is_usb_device(const struct device *dev)
{
  /* (3) 判断当前 Device 是否为 Usb Device */
  return dev->type == &usb_device_type;
}


static inline int is_usb_interface(const struct device *dev)
{
  /* (4) 判断当前 Device 是否为 Usb Interface */
  return dev->type == &usb_if_device_type;
}

另外 struct usb_device_driver 和 struct usb_driver 使用的总线都是 usb_bus_type。他们是通过字段 drvwrap.for_devices 来区分的:

/* (1) `struct usb_device_driver` 的 `drvwrap.for_devices` 值为 1:*/
int usb_register_device_driver(struct usb_device_driver *new_udriver,
    struct module *owner)
{
  new_udriver->drvwrap.for_devices = 1;
}


/* (2) `struct usb_driver` 的 `drvwrap.for_devices` 值为 0:*/
int usb_register_driver(struct usb_driver *new_driver, struct module *owner,
      const char *mod_name)
{
  new_driver->drvwrap.for_devices = 0;
}


/* (3) 判断当前 Driver 是适配 Usb Device 还是 Usb Interface */
static inline int is_usb_device_driver(struct device_driver *drv)
{
  return container_of(drv, struct usbdrv_wrap, driver)->
      for_devices;
}

在 usb_bus_type 的 match() 函数中利用 dev.type 进行判别分开处理:

struct bus_type usb_bus_type = {
  .name =    "usb",
  .match =  usb_device_match,
  .uevent =  usb_uevent,
  .need_parent_lock =  true,
};


static int usb_device_match(struct device *dev, struct device_driver *drv)
{
  /* devices and interfaces are handled separately */
  /* (1) 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值