【发布时间】:2016-08-15 21:47:36
【问题描述】:
目前正在开发 PCI 设备驱动程序。该设备的编程如下:
当 DMA 传输完成时,设备会向 PC 发送一个 MSI 中断,其中包含 MSI 数据“001”二进制。
现在我正在为这个 pci 设备编写驱动程序,对于 MSI 部分,我有一些问题。
在维基百科中,它说:
MSI 允许设备将少量中断描述数据写入特殊的内存映射 I/O 地址,然后芯片组将相应的中断传递给处理器。
Q1:所以在我的情况下,small amount of interrupt-describing data 是从 pci 设备发送到 PC 的"001"?
在我的驱动程序代码中,MSI irq 是这样注册的:
err = pci_enable_msi(my_pci_dev);
err = request_irq(my_pci_dev->irq, irq_handler, 0, "PCI_FPGA_CARD", NULL);
irq_handler 的定义如下:
static irqreturn_t irq_handler(int irq, void *dev_id)
{
printk(KERN_INFO "(irq_handler): Called\n");
return IRQ_HANDLED;
}
Q2:有了上面的3个内核函数,我们如何才能得到消息"001"?
Q3:PCI 设备最多支持 8 个 MSI 向量,所以要使用所有这 8 个向量,我应该在下面使用哪个代码或者都不正确:
err = pci_enable_msi_block(my_pci_dev,8);
err = request_irq(my_pci_dev->irq, irq_handler, 0, "PCI_FPGA_CARD", NULL);
或
err = pci_enable_msi(my_pci_dev);
err = request_irq(my_pci_dev->irq, irq_handler_0, 0, "PCI_FPGA_CARD", NULL);
err = request_irq(my_pci_dev->irq, irq_handler_1, 0, "PCI_FPGA_CARD", NULL);
err = request_irq(my_pci_dev->irq, irq_handler_2, 0, "PCI_FPGA_CARD", NULL);
err = request_irq(my_pci_dev->irq, irq_handler_3, 0, "PCI_FPGA_CARD", NULL);
err = request_irq(my_pci_dev->irq, irq_handler_4, 0, "PCI_FPGA_CARD", NULL);
err = request_irq(my_pci_dev->irq, irq_handler_5, 0, "PCI_FPGA_CARD", NULL);
err = request_irq(my_pci_dev->irq, irq_handler_6, 0, "PCI_FPGA_CARD", NULL);
err = request_irq(my_pci_dev->irq, irq_handler_7, 0, "PCI_FPGA_CARD", NULL);
3 个问题 ~~ 感谢您的帮助。
【问题讨论】:
-
Q1:您似乎没有从您发布的引用中得到任何线索。 MSI 由 PCI 根主机处理,它将中断作为消息传递到特定的内存地址。此地址对您隐藏。 Q2:因此,您根本不必关心这些。 Q3:如果您的向量很少,您需要在 PCI 配置空间中正确定义它们。您需要使用
_msi_range()类型的函数来处理 MSI。在请求 IRQ 中,您必须从一组中选择正确的 IRQ 行号。
标签: linux linux-device-driver interrupt dma pci