lkml.org 
[lkml]   [2004]   [Nov]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: 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/
    \
     
     \ /
      Last update: 2009-11-18 23:46    [W:4.757 / U:0.212 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site