Re: 2.6.10-rc2 doesn't boot (if no floppy device)

From: Linus Torvalds
Date: Tue Nov 23 2004 - 00:06:39 EST




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@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/