千家信息网

xHci-PCI驱动设计

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,xHci-PCI驱动设计虽然Linux内核拥有C语言构建的身体,但它骨子里散发的是面向对象的气质,这一个个的对象就是struct。面对一个内核模块的时候,首先要找出关键的struct和它们之间的关系,
千家信息网最后更新 2026年10月31日xHci-PCI驱动设计

xHci-PCI驱动设计

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

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

重要的配置:

xHCI是USB 3.x的host controller规范,首先进入drivers/usb/host目录浏览一下,其实从文件名就可以知道,跟xHCI关系最密切的必然是xhci.c。保险起见还是看一下KConfig:

config USB_XHCI_HCD
tristate "xHCI HCD (USB 3.0)support"
---help---
TheeXtensible Host Controller Interface (xHCI) is standard forUSB 3.0
"SuperSpeed"host controller hardware.

Tocompile this driver as a module, choose M here: the
module will be called xhci-hcd.

ifUSB_XHCI_HCD

config USB_XHCI_PCI
tristate
depends on PCI
defaulty

config USB_XHCI_PLATFORM
tristate

config USB_XHCI_MVEBU
tristate "xHCI support forMarvell Armada 375/38x"
select USB_XHCI_PLATFORM
depends on ARCH_MVEBU || COMPILE_TEST
---help---
Say'Y'to enable the support for the xHCI host controller
found in Marvell Armada 375/38x ARM SOCs.

config USB_XHCI_RCAR
tristate "xHCI support forRenesas R-Car SoCs"
select USB_XHCI_PLATFORM
depends on ARCH_SHMOBILE || COMPILE_TEST
---help---
Say'Y'to enable the support for the xHCI host controller
found in Renesas R-Car ARM SoCs.

endif # USB_XHCI_HCD

主要配置项叫做USB_XHCI_HCD,另外还有USB_XHCI_PCI和USB_XHCI_PLATFORM。再看Makefile,直接搜索XHCI有关的内容:

xhci-hcd-y := xhci.oxhci-mem.o
xhci-hcd-y += xhci-ring.o xhci-hub.oxhci-dbg.o
xhci-hcd-y += xhci-trace.o

xhci-plat-hcd-y := xhci-plat.o
ifneq ($(CONFIG_USB_XHCI_MVEBU), )
xhci-plat-hcd-y +=xhci-mvebu.o
endif
ifneq ($(CONFIG_USB_XHCI_RCAR), )
xhci-plat-hcd-y +=xhci-rcar.o
endif

obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o
obj-$(CONFIG_USB_XHCI_PLATFORM) +=xhci-plat-hcd.o

obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o

USB_XHCI_PCI,顾名思义,是xHCI驱动和PCI总线驱动之间的"接口"(内核开发者称这种"接口"为glue)。USB控制器大多是PCI设备,若控制器连接到PCI总线上,那么自然是先由PCI驱动发现该设备,识别之后才能交给xHCI驱动处理。所以实际上,作为glue的xhci-pci模块代码要早于xhci-hcd模块代码开始工作,因此关键的初始化过程放在xhci-pci里面。

现在进入正题:

xHCI相关的代码,很容易发现几个貌似重要的struct类型:usb_hcd、xhci_hcd和hc_driver,还有几个全局变量xhci_pci_driver、xhci_hc_driver和xhci_pci_hc_driver,再加上PCI总线相关的类型pci_dev和pci_driver。

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

staticint__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
returnpci_register_driver(&xhci_pci_driver);
}

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

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;
}

staticstructhc_driver __read_mostly xhci_pci_hc_driver;

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

staticconststruct hc_driver xhci_hc_driver = {
.description = "xhci-hcd",
.product_desc = "xHCI Host Controller",
.hcd_priv_size= sizeof(structxhci_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,
};

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

xhci_pci_driver被专业人员称为pcidriver glue,属于一种新型的PCI驱动模块。

xhci_pci_init调用pci_register_driver,将xhci_pci_driver注册为PCI设备驱动。在xhci-pci.c中静态定义并初始化:

/* pci driver glue; this is a"new style" PCI driver module */
staticstructpci_driver xhci_pci_driver = {
.name= (char*) hcd_name,
.id_table = pci_ids,

.probe = xhci_pci_probe,
.remove = xhci_pci_remove,
/* suspend and resume implemented later */

.shutdown = usb_hcd_pci_shutdown,
#ifdef CONFIG_PM
.driver = {
.pm = &usb_hcd_pci_pm_ops
},
#endif
};

id_table包含了驱动支持的PCI设备类型,PCI总线就是靠它判断驱动和设备能否配对。这里的id_table成员设置为pci_ids,它也是静态定义的全局变量:

/* PCI driver selectionmetadata; PCI hotplugging uses this */
staticconststructpci_device_id pci_ids[] = { {
/* handle any USB 3.0 xHCI controller */
PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_XHCI, ~0),
.driver_data = (unsignedlong)&xhci_pci_hc_driver,
},
{ /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE(pci, pci_ids);

pci_ids中唯一一个元素的driver_data成员指向刚才在xhci_pci_init中完成初始化的xhci_pci_hc_driver变量,这就将作为PCI设备驱动的xhci_pci_driver和作为USB主机控制器设备驱动xhci_pci_hc_driver联系了起来。

staticintxhci_pci_setup(struct usb_hcd *hcd)
{
structxhci_hcd *xhci;
structpci_dev *pdev =to_pci_dev(hcd->self.controller);
int retval;
//uDP720202芯片的配置
xhci_fwdownload(hcd);
//创建了对xHCI至关重要的数据结构--xhci_hcd类型,并完成了大量的初始化工作
retval = xhci_gen_setup(hcd, xhci_pci_quirks);
if(retval)
return retval;

xhci = hcd_to_xhci(hcd);
if(!usb_hcd_is_primary_hcd(hcd))
return0;

pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn);
xhci_dbg(xhci, "GotSBRN %u\n", (unsignedint)xhci->sbrn);

/* Find any debug ports */
retval = xhci_pci_reinit(xhci, pdev);
if(!retval)
return retval;

kfree(xhci);
returnretval;
}

USB 3.1 Spec中Figure 3-1可以知道,USB 3.x的Host包含两个roothub,对应两条USB总线,一条连接USB 2.0设备,一条连接USB 3.x设备。

xhci_pci_probe调用usb_hcd_pci_probe,创建usb_hcd和xhci_hcd。回到最初的示意图,现在所有的连接都已经完成!

int usb_hcd_pci_probe(struct pci_dev *dev, conststruct pci_device_id *id)
{
structhc_driver *driver;
structusb_hcd *hcd;
int retval;
int hcd_irq = 0;

if(usb_disabled())
return-ENODEV;

if(!id)
return-EINVAL;
driver= (structhc_driver *)id->driver_data;
if(!driver)
return-EINVAL;

if(pci_enable_device(dev) < 0)
return-ENODEV;

/*
* The xHCI driver has its own irq management
* make sure irq setup is not touched for xhciin generic hcd code
*/
if((driver->flags & HCD_MASK) != HCD_USB3) {
if(!dev->irq) {
dev_err(&dev->dev,
"Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
pci_name(dev));
retval= -ENODEV;
gotodisable_pci;
}
hcd_irq= dev->irq;
}

hcd =usb_create_hcd(driver, &dev->dev, pci_name(dev));
if(!hcd) {
retval= -ENOMEM;
gotodisable_pci;
}
......
returnretval;
}

uDP720202芯片的配置的时序图:

//@@----------------------PCI 信息
#define XHCI_FWFILENAME_720201_202ES20 "renesas/K2011070.mem"
//uDp720202 寄存器配置
#define XHCI_VENDOR_ID_720202 (0x1912)
#define XHCI_DEVICE_ID_720202 (0x0015)
#define XHCI_DEVICE_REV_ES20 (0x02)


//@@---------------------- FM下载配置寄存器
#define PCICNF0F4 0xF4 // 来自芯片寄存器手册
/*
0 = FWdownload enable (1), RW
1 = FWdownload lock (1) or unlock (0), need 0 to perform download, RW(Write Once)
6:4 =Result code, RO -- processing (0), success (1), error (2),
8 =Set Data 0, RW
9 =Set Data 1, RW
16:31= (used for serial EEPROM read/write. 31= serial EEPROM present.)
*/
#define PCICNF0F4_FWDOWNLOADENABLE_B (0)
#define PCICNF0F4_FWDOWNLOADLOCK_B (1)
#define PCICNF0F4_SETDATA0_B (8)
#define PCICNF0F4_SETDATA1_B (9)
#define PCICNF0F4_RESULT_B (4)

#define PCICNF0F8 0xF8 // 数据页 0

#define PCICNF0FC 0xFC // 数据页 1

主要调用过程:


驱动 设备 变量 配置 总线 模块 类型 代码 全局 就是 重要 内核 寄存器 成员 控制器 数据 芯片 设备驱动 过程 控制 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网最新的科技 疫情对互联网科技公司影响 深圳互联网络科技有限公司 奇酷互联网科技公司 南京欣网互联网科技 腾讯科技 互联网女皇 齐家互联网科技有限公司 重庆科技学院互联网 互联网金融监管科技 互联网科技素材视频竖屏 科技大学互联网专业好不好 互联网科技热点资讯 中国的互联网科技企业的崛起 迪庆互联网科技招生 互联网行业科技股 南博望互联网科技有限公司 滨湖区互联网智能科技产品有哪些 江苏互联网智能科技产品出厂价 万物互联网智能科技 绵阳真晨互联网科技有限公司 山东特亿宝互联网科技有限公司 重生之互联网科技帝国 科技互联网公司装修 互联网与科技金融数据 极限挑战互联网科技 多迪互联网科技有限公司 2021互联网科技公司排名 互联网与数字科技关系 恒生科技指数 中概互联网 华人运通互联网科技公司
0