PCI 设备使能、电源管理、复位与恢复

PCI 设备使能、电源管理、复位与恢复

1. 枚举不等于可用

枚举完成只说明配置空间可访问并创建了pci_dev。功能驱动通常还要:

1
2
3
4
5
pci_enable_device_mem()
-> dma_set_mask_and_coherent()
-> pci_request_regions()
-> pci_set_master()
-> 分配 DMA/IRQ 并初始化设备

pci_enable_device()位于pci.c:2163pci_disable_device()位于 2351 行。Core 维护 enable 计数,多个调用者必须成对释放。

2. Command 寄存器

  • PCI_COMMAND_IO允许 I/O Port decode;
  • PCI_COMMAND_MEMORY允许 MMIO BAR decode;
  • PCI_COMMAND_MASTER允许设备主动发起 DMA;
  • pci_set_master()位于pci.c:4587
  • pci_clear_master()位于 4598 行。

设备移除或严重错误时应先停止硬件队列,再 clear master。只清 Bus Master 位不能保证设备内部 DMA 状态机已经停止。

3. PCI PM 状态

常见状态:

  • D0:完全工作;
  • D1/D2:可选中间状态;
  • D3hot:配置空间仍通常可访问;
  • D3cold:辅助电源可能关闭,配置空间不可访问。

pci_set_power_state()位于pci.c:1556。实际转换会综合 PM Capability、平台固件、父桥电源及 runtime PM。d3cold_allowed仅表示策略允许,不保证平台一定实现 D3cold。

4. 状态保存与恢复

pci_save_state()位于pci.c:1755pci_restore_state()位于 1871 行。保存内容除标准配置头外,还可包含 MSI、PCIe Capability、AER、SR-IOV、ATS 等扩展状态。

恢复顺序的核心原则:

  1. 上游桥和链路先可访问;
  2. 恢复 BAR、Command 及扩展能力;
  3. 重建设备私有寄存器、队列和 DMA;
  4. 最后解屏蔽中断。

PCI Core 无法保存厂商私有 MMIO 寄存器,必须由功能驱动 suspend/resume 回调处理。

5. 驱动 PM 回调

pci-driver.c将 Driver Core PM 映射到 PCI 驱动。现代驱动通过driver.pmdev_pm_ops实现 suspend、resume、freeze、thaw、poweroff、restore 和 runtime PM。

系统休眠与 runtime suspend 的约束不同:

  • runtime PM 需处理随时唤醒和引用计数;
  • system suspend 还涉及 wakeup、noirq 阶段和父子设备顺序;
  • 桥下设备必须先于上游桥 suspend,恢复顺序相反。

6. 复位方法

pci_reset_function()位于pci.c:5595。Core 会探测可用方法,常见包括:

方法 粒度与风险
Function Level Reset 仅 Function,优先使用
AF FLR PCI AF Capability 提供的功能级复位
PM reset D3hot→D0,可能受设备 PM 实现限制
Secondary Bus Reset 影响桥下所有设备
Slot reset 由 Hotplug/平台实现,影响物理槽
Vendor reset 由 quirk 或设备驱动提供

复位前必须确认设备未被其它 Function、VF 或用户共享。多功能设备即使支持单 Function reset,也可能共享不可见硬件资源。

7. Reset 锁

调用pci_reset_function_locked()要求调用者先完成设备锁定/排他检查。VFIO 等用户尤其需要:

  • 阻止并发配置访问;
  • 禁止新 DMA;
  • 验证 IOMMU 映射和 IRQ 已撤销;
  • reset 后恢复到可重新初始化而非“继续原队列”的状态。

sysfs reset属性最终也进入 PCI reset 框架,但并非所有设备都会暴露该属性。

8. AER 错误恢复

功能驱动可提供struct pci_error_handlers

1
2
3
4
error_detected()
-> mmio_enabled()
-> slot_reset()
-> resume()

错误严重度和各驱动返回值决定是否需要 reset、断开设备或继续。slot_reset()后设备通常相当于刚上电,必须重新配置私有寄存器;不能只返回PCI_ERS_RESULT_RECOVERED

9. Surprise Removal

设备意外消失时,配置读可能返回全 1。此时:

  • 不反复读 BAR/MMIO;
  • 禁止重新提交 DMA;
  • 中断 handler 识别设备 gone 状态;
  • remove 路径等待工作队列和引用释放;
  • 上游热插拔逻辑负责拓扑注销。

10. RK3588 控制器 PM

Rockchip DWC 控制器自身还要管理 regulator、clock、reset、PHY、PERST#和 LTSSM。控制器 resume 成功且 Link Up 后,PCI Core 才能恢复下游设备。功能驱动 PM 正常而控制器链路未恢复时,所有配置读仍会失败。

文章互动

阅读 --

留言

0 条留言

正在加载留言…