我正在使用带有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标志,有没有办法在不破解驱动程序代码的情况下执行此操作?