暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

pcie(七)- Linux PCI 驱动程序

囧囧妹 2022-08-14
351

点击上方蓝字【囧囧妹】一起学习,一起成长!

一,pcie设备关闭流程

在卸载 PCI 设备驱动程序时,需要执行以下步骤:

  • 禁止设备生成 IRQ

  • 释放 IRQ ( free_irq()
    )

  • 停止所有 DMA 

  • 释放 DMA 缓冲区(流式和一致性)

  • 从其他子系统(例如 scsi 或 netdev)注销

  • 禁止设备,不再响应 MMIO/IO 端口地址使用

  • 释放 MMIO/IO 端口资源

下面来看看每一步都具体做了些什么。


  • 停止设备irq

如果irq不进行注销,当IRQ 与另一个设备共享时,它就会打开“screaming interrupt”。

当共享 IRQ 被设置为“unhooked”时,使用相同 IRQ 线的其余设备仍需要启用 IRQ,因此,如果“unhooked”设备断言 IRQ 线,系统将响应假设它是其余设备之一断言 IRQ 线,由于没有其他设备将处理 IRQ,系统将被挂起,直到它决定不处理 IRQ 并屏蔽 IRQ(100,000 次迭代之后)。一旦共享 IRQ 被屏蔽,其余设备将停止正常运行。

这是使用 MSI 或 MSI-X(如果可用)的另一个原因,MSI 和 MSI-X 被定义为独占中断,因此不易受到“screaming interrupt”的影响。


  • 释放irq
一旦设备被注销(不再有 IRQ),就可以调用free_irq()释放irq,一旦处理了任何挂起的IRQ,此函数将返回,如果没有其他人使用它,则释放 IRQ。


  • 停止所有的dma

在尝试解除分配 DMA 控制数据之前需要停止所有 DMA 操作,不这样做可能会导致内存损坏、挂起,并且在某些芯片组上会发生硬崩溃。

在停止 IRQ 后停止 DMA 可以避免 IRQ 处理程序可能重新启动 DMA 引擎的竞争。


  • 释放dma缓冲区

停止 DMA 后,首先清理流式 DMA,即取消映射数据缓冲区并将缓冲区返回给“上游”所有者,然后清理包含控制数据的相关缓冲区。关于取消映射的接口会在dma节来介绍。


  • 从其它子系统注销

大多数低级 PCI 设备驱动程序支持一些其他子系统,如 USB、ALSA、SCSI、NetDev、Infiniband 等,所以要确保pci驱动程序不会丢失其他子系统的资源,一旦发生这种情况,当子系统尝试调用已卸载的驱动程序时会出现 Oops。


  • 禁止设备,不再响应 MMIO/IO 端口地址使用

通过io_unmap()来解映射MMIO 或 IO 端口资源,然后调用pci_disable_device(),这个与pci_enable_device()对应。调用pci_disable_device()之后就不可以再访问寄存器了。


  • 释放 MMIO/IO 端口资源

调用pci_release_region()以将 MMIO 或 IO 端口范围标记为可用,不这样做会导致无法重新加载驱动程序。


这样pci设备初始化和关闭的步骤就说完了,下面来看看linux如何访问pci的配置空间。


觉得不错,点击“分享”,“赞”,“在看”传播给更多热爱嵌入式的小伙伴吧!
文章转载自囧囧妹,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论