Messages in this thread Patch in this message | | | Date | Mon, 22 Nov 2004 20:57:20 -0800 (PST) | From | Linus Torvalds <> | Subject | Re: 2.6.10-rc2 doesn't boot (if no floppy device) |
| |
On Mon, 22 Nov 2004, Linus Torvalds wrote: > > So what's the right way to get ELCR into a useful state? I'm starting to > lean towards your "just clear it all" after all, but that does the wrong > thing for SCI (which is _usually_ level-triggered), and I worry that there > are other cases too. > > Any reasonably simple patch that likely gets it right?
Len, how about this patch - it re-enables the link disable and then re-codes the ELCR setting to match.
Basically it just computes the new ELCR: if acpi_noirq is set, it leaves it at the old value, otherwise it zeroes it - and in both cases it fixes the SCI entry.
Your argument for doing this ended up being convincing, so the only difference between this and your debug patch is really just the obvious organizational ones, and the test for "acpi_noirq", which I think is needed (since if acpi_noirq is set, we're not going to disable and re-enable the PCI interrupts, so we'll just have to trust ELCR).
Linus
---- ===== arch/i386/kernel/acpi/boot.c 1.75 vs edited ===== --- 1.75/arch/i386/kernel/acpi/boot.c 2004-11-11 16:08:40 -08:00 +++ edited/arch/i386/kernel/acpi/boot.c 2004-11-22 20:55:57 -08:00 @@ -409,28 +409,38 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) { - unsigned char mask = 1 << (irq & 7); - unsigned int port = 0x4d0 + (irq >> 3); - unsigned char val = inb(port); + unsigned int mask = 1 << irq; + unsigned int old, new; - - printk(PREFIX "IRQ%d SCI:", irq); - if (!(val & mask)) { - printk(" Edge"); + /* Real old ELCR mask */ + old = inb(0x4d0) | (inb(0x4d1) << 8); - if (trigger == 3) { - printk(" set to Level"); - outb(val | mask, port); - } - } else { - printk(" Level"); + /* + * If we use ACPI to set PCI irq's, then we should clear ELCR + * since we will set it correctly as we enable the PCI irq + * routing. + */ + new = acpi_noirq ? old : 0; - if (trigger == 1) { - printk(" set to Edge"); - outb(val & ~mask, port); - } + /* + * Update SCI information in the ELCR, it isn't in the PCI + * routing tables.. + */ + switch (trigger) { + case 1: /* Edge - clear */ + new &= ~mask; + break; + case 3: /* Level - set */ + new |= mask; + break; } - printk(" Trigger.\n"); + + if (old == new) + return; + + printk(PREFIX "setting ELCR to %04x (from %04x)\n", new, old); + outb(new, 0x4d0); + outb(new >> 8, 0x4d1); } ===== drivers/acpi/pci_link.c 1.35 vs edited ===== --- 1.35/drivers/acpi/pci_link.c 2004-11-22 10:41:11 -08:00 +++ edited/drivers/acpi/pci_link.c 2004-11-22 20:02:53 -08:00 @@ -685,6 +685,9 @@ acpi_link.count++; end: + /* disable all links -- to be activated on use */ + acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL); + if (result) kfree(link); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |