运行Debian linux的CompactPCI系统:lspci显示错误的IRQ导致gen_irq标志不匹配和IRQ冲突

时间:2017-02-01 21:52:47

标签: linux-kernel linux-device-driver

我正在使用带有Advantec MIC3325处理器manufacturer site的3U compactPCI系统和几个插件卡,其中一个是8端口串行卡datasheet。此序列卡公开了2个Oxford OX16PCI954,每个模拟4个16C950。

我正在从linux 4.9.4源代码构建内核,但我描述的问题在Debian 8安装(内核3.16)中是相同的

通过手动配置linux tty serial 8250驱动程序,我可以使所有8个端口都能正常工作,但我需要解决2个问题。

第一个问题正在检测IRQ。在过去,我使用了 lspci 并解析了输出。但我发现这个IRQ并不总是正确的。例如:

05:0c.0 Serial controller: Tenta Technology Device 0800 (prog-if 06 [16950])
 Interrupt: pin A routed to IRQ 18
 Region 0: I/O ports at ec00 [size=32]
05:0c.1 Bridge: Tenta Technology Device a801
 Interrupt: pin B routed to IRQ 10
 Region 0: I/O ports at e800 [size=32]

我试过关闭APIC,通过内核选项直接在BIOS中我已经尝试了所有ACPI配置的组合,而IRQ在某些情况下改变了它仍然不可靠正确,通常我运行到在这两种情况下都会出现问我使用设备树,当MSIX打开时,此设备不支持MSI,所以这似乎无关紧要。该板可以处理轮询中断,但是我丢失了串行线上的数据,所以这不是一个解决方案。

我已经阅读了很多关于中断路由如何工作以及如何从PCI引脚编号到IRQ编号的链接的讨论,但我找不到有关如何更改或调试配置的任何文档。例如,由于第一个芯片充当第二个芯片的PCI桥接器,可能会有额外的混乱,但我不太了解深度。

在代码中使用pci_dev结构并通过导航虚拟文件系统 / proc / bus / pci 找到相同的(错误的IRQ)。其他插槽和不同机箱(背板)中的其他cPCI插件卡会出现此问题。

此时您可能想知道我是如何知道IRQ不正确的。我有2个案例,一个是有另一个设备使用正确的IRQ而另一个是没有。第二种情况是最简单的,端口根本不起作用。

在第一种情况当端口收到数据时最终在 dmesg 中,我会看到:

[57.301692] irq 19: nobody cared
...
[57.302684] Disabling IRQ #19

使用 cat / proc / interrupts 我看到IRQ 19已注册到某个USB端口

19:      24987      25004      25000      25009   IO-APIC  19-fasteoi   uhci_hcd:usb2

我使用 setserial / dev / ttyS6端口exe800 irq 19 autoconfig 强制串口使用IRQ 19而不是lspci中显示的IRQ 10.

这会导致第二个问题,即:

[40.875178] genirq: Flags mismatch irq 19. 00000000 (serial) vs. 00000080 (uhci_hcd:usb2)

我设法在BIOS中禁用USB端口,并使串口在IRQ 19上正常工作。我知道它正在工作,因为在发送(和接收)数据时,/ proc /中断的IRQ19中断数增加了在港口。

我检查了8250_core.c中的代码并交叉引用我的内核编译标志,看起来驱动程序设置为共享中断:

CONFIG_SERIAL_8250_SHARE_IRQ=y

作为最后的手段,我攻击了8250_core.c以强制总是使用共享中断:

ret = request_irq(up->port.irq, serial8250_interrupt,
                              IRQF_SHARED, "serial", i);

这实际上解决了genirq标志不匹配问题。但我不明白为什么现有的代码没有设置UPD_SHARE_IRQ位 使用 setserial 手动配置端口时的uart_port.port.flags。

总结一下我的问题,任何人都可以提供帮助:

1)为什么lspci显示错误的IRQ? (在我的情况下是10而不是19)?

2)为什么8250_core内核驱动程序在手动配置端口时没有设置UPD_SHARE_IRQ标志,有没有办法在不破解驱动程序代码的情况下执行此操作?

0 个答案:

没有答案