VHCI 虚拟主机控制器与导入路径

VHCI 虚拟主机控制器与导入路径

1. HCD注册

vhci_hcd.c为每个配置的controller创建一个vhci_hcd.N平台设备。Probe依次:

  1. usb_create_hcd()创建primary USB2 HCD;
  2. usb_add_hcd()注册USB2 Root Hub;
  3. usb_create_shared_hcd()创建USB3 shared HCD;
  4. usb_add_hcd()注册USB3 Root Hub;
  5. 第一个primary HCD创建sysfs控制属性。

它没有MMIO、IRQ和DMA硬件,所有端口状态及传输完成由软件维护。

2. HCD接口

vhci_hc_driver实现:

  • start/stop
  • urb_enqueue/urb_dequeue
  • hub_status_data/hub_control
  • bus_suspend/bus_resume
  • alloc_streams/free_streams
  • get_frame_number

get_frame_number()仍报告未实现;PM代码也有明确FIXME。依赖精确frame或真实Host调度的驱动需谨慎。

3. 虚拟Root Hub

每个USB2和USB3 Root Hub分别有VHCI_HC_PORTS个端口。port_status[]模拟:

  • connection/change;
  • enable/suspend/reset;
  • power;
  • low/full/high/super speed。

Attach成功调用rh_port_connect()设置连接与变化位,再调用usb_hcd_poll_rh_status()。USB Core的Hub线程随后走标准枚举,读取远端设备descriptor并创建本地usb_device

4. Attach sysfs

用户态向attach写四个整数:

1
port sockfd devid speed

内核:

  • 将全局port映射到controller、USB2/USB3 HCD和rhport;
  • 验证speed与Hub类型匹配;
  • sockfd_lookup()取得stream socket;
  • 创建vhci_rxvhci_tx线程;
  • 设置远端devid和连接状态;
  • 模拟Root Hub connect。

status/status.N输出hub类型、port、状态、speed、devid、sockfd和本地busid。源码特意不输出socket内核指针,避免地址泄漏。

5. URB enqueue

本地class driver提交URB后:

1
2
3
4
5
6
7
8
vhci_urb_enqueue
-> validate vdev/status/buffer
-> usb_hcd_link_urb_to_ep
-> allocate vhci_priv
-> seqnum = atomic_inc
-> urb->hcpriv = priv
-> add priv_tx
-> wake vhci_tx

TX线程从priv_tx取请求,组装CMD_SUBMIT并发送;成功后转入priv_rx等待完成。OUT数据随请求发送,IN只发送期望长度。

枚举阶段对地址0设备的SET_ADDRESS由VHCI本地完成,并将状态从VDEV_ST_NOTASSIGNED转为VDEV_ST_USED,该请求不上网;其它descriptor/control URB仍通过远端取得。

6. Completion

vhci_rx_loop()收到RET_SUBMIT后:

  1. 按seqnum从priv_rx找到vhci_priv
  2. 解包status、actual length和ISO结果;
  3. 接收IN payload;
  4. 清除urb->hcpriv并从endpoint unlink;
  5. usb_hcd_giveback_urb()

从class driver角度,这与真实HCD异步完成没有API区别,但完成时延由网络和服务端HCD共同决定。

7. URB dequeue

若请求尚在priv_tx、还未发出,可本地移除并立即giveback。若已在priv_rx,创建vhci_unlink

1
2
3
4
new unlink seqnum + target submit seqnum
-> unlink_tx
-> CMD_UNLINK
-> RET_UNLINK / RET_SUBMIT race resolution

必须同时处理“取消回复先到”和“原URB已完成”两种顺序,确保每个URB只giveback一次。

8. Detach和网络错误

detach写port号,触发VDEV_EVENT_DOWN。EH关闭socket、停止线程、将所有未完成URB以-ENODEV完成,清空unlink链表并模拟Root Hub disconnect。

网络错误不会透明重连。重新attach会产生一次新的USB枚举,原class device实例已经销毁。

9. 容量

默认1个controller、USB2和USB3 Root Hub各8口,nports共16个全局端口位置;设备按speed分配到对应Hub。Kconfig可扩大controller和每类Hub的端口数量,但会增加静态对象、sysfs输出和并发连接资源。

文章互动

阅读 --

留言

0 条留言

正在加载留言…