Edit online

关键流程设计

6 Dec 2024
Read time: 1 minute(s)

初始化流程

HCD 驱动的入口是 platform 驱动,初始化流程先获取 irq、reg、clk、reset 等资源并进行初始化,最后调用 usb_add_hcd() 向系统中注册。

大致的流程如下:
|-->ehci_platform_init()
    |-->ehci_init_driver()
    |-->platform_driver_register()
        |-->aic_ehci_platform_probe()
            |-->hcd = usb_create_hcd()
            |-->irq = platform_get_irq(dev, 0);
            |-->priv->clks[i] = of_clk_get(dev->dev.of_node, i);
            |-->priv->rst[i] = devm_reset_control_get_shared_by_index(&dev->dev, i);
            |-->hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
            |-->aic_ehci_platform_power_on()
                |-->reset_control_deassert(priv->rst[i]);
                |-->clk_prepare_enable(priv->clks[i]);
            |-->usb_add_hcd(hcd, irq, IRQF_SHARED);

普通 URB 处理流程


image2

如上图所示,一个普通 urb 的处理分为两步:

  • urb enqueue。首先调用 hcd 的 .urb_enqueue() 函数,将需要传输的数据插入到硬件控制器的链表当中。

  • urb complete。在链表中的一帧数据传输完成后硬件会产生 complete 中断,在中断服务程序中对相应 urb 发送 complete 信号,让 usb_start_wait_urb() 的流程继续执行。

Roothub URB 处理流程


image3

如上图所示,roothub urb 的处理分为两种类型:

  • ep0 control urb。对于 roothub control urb,HCD 需要使用软件来模拟,实际上 urb 没有发送到硬件控制器中,因为是软件模拟所以无需等待 complete 可以立即释放。

  • 获取端口状态 urb。这类 urb 会阻塞等待端口状态改变,一旦端口状态改变会触发硬件中断,在中断处理中唤醒对应 urb 的 complete 信号,让 usb_start_wait_urb() 的流程继续执行。