linux xhci源码,xHCI驱动学习(1) 核心数据结构

虽然Linux内核拥有C语言构建的身体,但它骨子里散发的是面向对象的气质,这一个个的对象就是struct。面对一个内核模块的时候,首先要找出关键的struct和它们之间的关系,才能摸清代码的骨骼脉络。

大致浏览几眼xHCI相关的代码,很容易发现几个貌似重要的struct类型:usb_hcd、xhci_hcd和hc_driver,还有几个全局变量xhci_pci_driver、xhci_hc_driver和xhci_pci_hc_driver,再加上PCI总线相关的类型pci_dev和pci_driver。不要被这些眼花缭乱的名字吓到,今天要做的就是把这些结构之间的关系理顺。下面按照相关代码的执行顺序,看一下这些结构是如何被建立和初始化的。

先上图,下面分析的过程结束之后各个结构体就是这种关系:

0818b9ca8b590ca3270a3433284dd417.png

1. xhci-pci模块启动,执行xhci_pci_init函数

static int __init xhci_pci_init(void)

{

xhci_init_driver(&xhci_pci_hc_driver, xhci_pci_setup);

#ifdef CONFIG_PM

xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend;

xhci_pci_hc_driver.pci_resume = xhci_pci_resume;

#endif

return pci_register_driver(&xhci_pci_driver);

}

1.1 xhci_pci_init调用xhci_init_driver,初始化xhci_pci_hc_driver变量

xhci_init_driver函数是在xhci.c中定义的,主要作用就是把全局变量xhci_hc_driver的值一股脑赋给另一个全局变量xhci_pci_hc_driver。两者都是struct hc_driver类型,xhci_pci_hc_driver在xhci-pci.c中定义,是真正起作用的xHCI驱动,但它在定义的时候没有进行任何成员的初始化:

static struct hc_driver __read_mostly xhci_pci_hc_driver;

而xhci_hc_driver在xhci.c中定义,它包揽了所有的脏活累活:

static const struct hc_driver xhci_hc_driver = {

.description = "xhci-hcd",

.product_desc = "xHCI Host Controller",

.hcd_priv_size = sizeof(struct xhci_hcd *),

/* * generic hardware linkage */

.irq = xhci_irq,

.flags = HCD_MEMORY | HCD_USB3 | HCD_SHARED,

/* * basic lifecycle operations */

.reset = NULL, /* set in xhci_init_driver() */

.start = xhci_run,

.stop = xhci_stop,

.shutdown = xhci_shutdown,

/* * managing i/o requests and associated device resources */

.urb_enqueue = xhci_urb_enqueue,

.urb_dequeue = xhci_urb_dequeue,

.alloc_dev = xhci_alloc_dev,

.free_dev = xhci_free_dev,

.alloc_streams = xhci_alloc_streams,

.free_streams = xhci_free_streams,

.add_endpoint = xhci_add_endpoint,

.drop_endpoint = xhci_drop_endpoint,

.endpoint_reset = xhci_endpoint_reset,

.check_bandwidth = xhci_check_bandwidth,

.reset_bandwidth = xhci_reset_bandwidth,

.address_device = xhci_address_device,

.enable_device = xhci_enable_device,

.update_hub_device = xhci_update_hub_device,

.reset_device = xhci_discover_or_reset_device,

/* * scheduling support */

.get_frame_number = xhci_get_frame,

/* * root hub support */

.hub_control = xhci_hub_control,

.hub_status_data = xhci_hub_status_data,

.bus_suspend = xhci_bus_suspend,

.bus_resume = xhci_bus_resume,

/* * call back when device connected and addressed */

.update_device = xhci_update_device,

.set_usb2_hw_lpm = xhci_set_usb2_hardware_lpm,

.enable_usb3_lpm_timeout = xhci_enable_usb3_lpm_timeout,

.disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout,

.find_raw_port_number = xhci_find_raw_port_number,

};

void xhci_init_driver(struct hc_driver *drv, int (*setup_fn)(struct usb_hcd *))

{

BUG_ON(!setup_fn);

*drv = xhci_hc_driver;

drv->reset = setup_fn;

}

xhci_init_driver函数将xhci_hc_driver的值赋给xhci_pci_hc_driver后,前者也就退下了舞台。不信,你看:

(free-electrons是个好网站)

0818b9ca8b590ca3270a3433284dd417.png

1.2 xhci_pci_init调用pci_register_driver,将xhci_pci_driver注册为PCI设备驱动

xhci_pci_driver是xHCI控制器作为PCI设备对应的驱动,符合PCI设备驱动的标准类型struct pci_driver,在xhci-pci.c中静态定义并初始化:

/* pci driver glue; this is a "new style" PCI driver module */

static struct pci_dri

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值