Re: Realtek 8139 problem on 486.
From: Arnd Bergmann <arnd@kernel.org>
Date: 2021-06-22 13:25:25
On Tue, Jun 22, 2021 at 2:32 PM Nikolai Zhubr [off-list ref] wrote:
21.06.2021 14:22, Arnd Bergmann: [...]quoted
I looked some more through the git history and found at least one time that the per-chipset ELCR fixup came up for discussion[1], and this appears to have resulted in generalizing an ALI specific fixup into common code into common code[2], so we should already be doing exactly this in many cases. If Nikolai can boot the system with debugging enabled for arch/x86/pci/irq.c, we should be able to see exactly which code path is his in his case, and why it doesn't go through setting that register at the moment.Here is my dmesg with debugging (hopefully) added to irq.c: https://pastebin.com/tnC2rRDM
Ok, so it's getting roughly through the right code path:
dev_dbg(&dev->dev, "PCI INT %c -> PIRQ %02x, mask %04x, excl %04x",
'A' + pin - 1, pirq, mask, pirq_table->exclusive_irqs);
...
dev_dbg(&dev->dev, "PCI INT %c -> newirq %d", 'A' + pin - 1, newirq);
/* Check if it is hardcoded */
if ((pirq & 0xf0) == 0xf0) {
irq = pirq & 0xf;
msg = "hardcoded";
} else if (r->get && (irq = r->get(pirq_router_dev, dev, pirq)) && \
((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask))) {
msg = "found";
elcr_set_level_irq(irq);
} else if (newirq && r->set &&
(dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
if (r->set(pirq_router_dev, dev, pirq, newirq)) {
elcr_set_level_irq(newirq);
msg = "assigned";
irq = newirq;
}
}
if (!irq) {
if (newirq && mask == (1 << newirq)) {
msg = "guessed";
irq = newirq;
} else {
dev_dbg(&dev->dev, "can't route interrupt\n");
return 0;
}
}
dev_info(&dev->dev, "%s PCI INT %c -> IRQ %d\n", msg, 'A' +
pin - 1, irq);
with the corresponding output from that one being
[ 0.761546] 8139too 0000:00:0d.0: runtime IRQ mapping not provided by arch
[ 0.761546] 8139too: 8139too Fast Ethernet driver 0.9.28
[ 0.761546] 8139too 0000:00:0d.0: PCI INT A -> PIRQ 02, mask 1eb8, excl 0001
[ 0.765817] 8139too 0000:00:0d.0: PCI INT A -> newirq 9
[ 0.765817] 8139too 0000:00:0d.0: can't route interrupt
[ 0.777546] 8139too 0000:00:0d.0 eth0: RealTek RTL8139 at
0xc4804000, 00:11:6b:32:85:74, IRQ 9
From what I can tell, this means that there is no chipset specific
get/set function,
the irq is not hardcoded but the 'mask' value in the irq_info table (0x1eb8)
lists a number of options.
In this case, the function gives up with the "can't route interrupt\n"
output and does not call elcr_set_level_irq(newirq). Adding the call
to elcr_set_level_irq() in that code path as well probably makes it
set the irq to level mode:
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c@@ -984,6 +984,7 @@ static int pcibios_lookup_irq(struct pci_dev *dev,int assign)
irq = newirq;
} else {
dev_dbg(&dev->dev, "can't route interrupt\n");
+ elcr_set_level_irq(newirq);
return 0;
}
}
No idea if doing this is a good idea though, in particular I have no clue
about whether this is a common scenario or not.
Arnd