Linux内核USB3.0驱动框架分析--USB主机控制器hcd驱动分析

一,概述

usb主机控制器驱动一般以platform的形式将驱动注册进内核,,因此我们需要从前面一篇文章的框图说起。主要分析下图中橙色部分的内容。
在这里插入图片描述
二,usb主机控制器相关函数

2.1 usb_create_hcd

我们来看一下usb_create_hcd函数,该函数定义在drivers/usb/core/hcd.c:

struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,    // 参数1为ohci_s3c2410_hc_driver,参数2为s3c_device_ohci ->dev,参数3位s3c24xx
                struct device *dev, const char *bus_name)
{
   
        return __usb_create_hcd(driver, dev, dev, bus_name, NULL);
}

这里调用了__usb_create_hcd函数:

struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,   
                struct device *sysdev, struct device *dev, const char *bus_name,
                struct usb_hcd *primary_hcd)
{
   
        struct usb_hcd *hcd;

        hcd = kzalloc(sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL); // 动态申请内存空间,额外申请hcd私有数据大小的内存

        timer_setup(&hcd->rh_timer, rh_timer_func, 0);  // 初始化定时器,设置定时器超时函数

        hcd->driver = driver;   // 绑定hc_driver
       
        return hcd;
}

总结一下函数执行流程:

首先分配一个hcd的内存空间,包含私有数据空间;
设置hcd->rh_timer设置定时器超时函数rh_timer_func,主机控制器以轮询的方式查找端口变化状态;
设置 hcd->driver = &_hc_driver等 ;

hc_driver是usb主机控制器的驱动函数,实现了通过主机控制器硬件向外通信的方法。

2.2 rh_timer_func

定时器回调函数定义在drivers/usb/core/hcd.c文件中:

/* timer callback */
static void rh_timer_func (struct timer_list *t)
{
   
        struct usb_hcd *_hcd = from_timer(_hcd, t, rh_timer);

        usb_hcd_poll_rh_status(_hcd);
}

2.3 usc_add_hcd

用usb_hcd结构体定义好usb_hdc设备后,用usb_add_hcd函数向linux内核注册usb主机控制器驱动,函数定义在drivers/usb/core/hcd.c:

int usb_add_hcd(struct usb_hcd *hcd,
                unsigned int irqnum, unsigned long irqflags)
{
   
        int retval;
        struct usb_device *rhdev;

      
                        retval = usb_phy_roothub_set_mode(hcd->phy_roothub,
                                                          PHY_MODE_USB_HOST);
             

        retval = usb_register_bus(&hcd->self);
        if (retval < 0)
                goto err_register_bus;

        rhdev = usb_alloc_dev(NULL, &hcd->self, 0);
        if (rhdev == NULL) {
   
                dev_err(hcd->self.sysdev, "unable to allocate root hub\n");
                retval = -ENOMEM;
                goto err_allocate_root_hub;
        }
        mutex_lock(&usb_port_peer_mutex);
        hcd->self.root_hub = rhdev;
        mutex_unlock(&usb_port_peer_mutex);


       
        /* initialize tasklets */
        init_giveback_urb_bh(&hcd->high_prio_bh);
        init_giveback_urb_bh(&hcd->low_prio_bh);

       
    
        /* starting here, usbcore will pay attention to this root hub */
        retval = register_root_hub(hcd);
      
        if (hcd->uses_new_polling && HCD_POLL_RH(hcd))
                usb_hcd_poll_rh_status(hcd);     // 定时器轮询root hub端口状态

        return retval;
}

该函数代码比较长,这里挑重点说:

usb_register_bus(&hcd->self) ,将 hcd->usb_bus 注册到全局链表usb_bus_list;
usb_alloc_dev为根hub分配一个usb_device 结构(内核中,所有的真实的usb设备;比如hub,鼠标等都用usb_device结构来描述);
register_root_hub注册根hub设备到usb_bus_type;
usb_hcd_poll_rh_status定时器函数轮询hub端口状态;

usb主机控制器也只不过是分配了一个usb_hcd结构体,为它的根hub分配了一个usb_device 结构体࿰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孤舟簔笠翁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值