ACPI Problems: IRQ conflicts on USB controllers and SATA
controller
John Baldwin
jhb at freebsd.org
Fri Oct 13 18:49:52 UTC 2006
On Friday 13 October 2006 12:58, Erik Norgaard wrote:
> Thanks, I tried but no luck... :(
>
> John Baldwin wrote:
>
> > Ok, so get vmstat -i output. There's not much flexibility here though as
all
> > the APIC IRQ's are hardcoded, so to guess which ones are routed
incorrectly
> > will be a pain.
>
> For boot-v with empty loader.conf:
>
> interrupt total rate
> irq1: atkbd0 410 1
> irq9: acpi0 17173212 50959
> irq14: ata0 1296 3
> irq15: ata1 47 0
> irq18: uhci0 uhci+ 2 0
> irq22: fwohci0+ 1 0
> cpu0: timer 673315 1997
> Total 17848283 52962
So whatever is storming is storming on IRQ 9. Can you figure out which device
is causing the interrupt? That is, see what triggers it starting, or hack
drivers to selectively disable devices to help narrow things down.
> >> I will try to see if I can get the debugger when apic is disabled and
> >> pci_link enabled.
> >
> > Actually, I think I know what that is already.
>
> Didn't get that...
When you disable pci_link two of your USB devices don't have interrupts
assigned at all so they are just going to cause storms.
> >>>> boot -v, acpi disabled:
> >>> Doesn't detect APIC. BIOS is too dumb to provide $PIR. That's a new
> >>> low for incompetence on the part of BIOS writers.
> >> Strange - is ACPI required on this box to find APIC? Sounds wierd when
> >> they are both enabled they each seem to fight for control over the
> >> devices...
> >
> > ACPI and APIC are two _entirely_ different things. On your box, yes, ACPI
is
> > required to find APICs.
>
> That's what I understood from the documentation, but if both handles
> IRQs then I don't understand how they can coexist.
Interrupt controllers (APIC and 8259A) are hardware devices with pins that
you hook interrupt lines from other devices up to. They then alert the CPU
when there is an interrupt. BIOS tables (ACPI, MPTable, $PIR, etc.) provide
information to tell you what the interrupt line for a given device is hooked
up to. On x86 it is complicated since you have two sets of interrupt
controllers and the OS can use either one (though not all machines have
APIC).
> > You really shouldn't use that hint, you should route an entire link
> > (hw.pci.link.LNKD.irq = 5 for example) when using links. First try just
> > fixing your ASL w/o using any settings in loader.conf.
> >
> > Hmm, you can also try just doing this w/o having to hack your ASL which
might
> > fix things:
> >
> > hw.pci.link.LNKB.irq=10
> > hw.pci.link.LNKD.irq=10
> > hw.pci.link.LNKF.irq=10
> >
> > It will emit warnings about the IRQs not being valid but still use them,
and
> > this matches what your BIOS used.
>
> Tried that but no change. I have added the dmesg etc to the same path as
> the previous: http://www.locolomo.org/src/acpi/
Ah, I didn't MFC the patch to let you specify invalid links. Try the patch
below (MFC of 1.54 of acpi_pci_link.c):
Index: acpi_pci_link.c
===================================================================
RCS file: /usr/cvs/src/sys/dev/acpica/acpi_pci_link.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -r1.53 -r1.54
--- acpi_pci_link.c 6 Jan 2006 16:14:32 -0000 1.53
+++ acpi_pci_link.c 7 Aug 2006 19:52:30 -0000 1.54
@@ -941,19 +941,27 @@
KASSERT(!PCI_INTERRUPT_VALID(link->l_irq),
("%s: link already has an IRQ", __func__));
- /* Check for a tunable override and use it if it is valid. */
+ /* Check for a tunable override. */
if (ACPI_SUCCESS(acpi_short_name(acpi_get_handle(dev), link_name,
sizeof(link_name)))) {
snprintf(tunable_buffer, sizeof(tunable_buffer),
"hw.pci.link.%s.%d.irq", link_name, link->l_res_index);
- if (getenv_int(tunable_buffer, &i) &&
- PCI_INTERRUPT_VALID(i) && link_valid_irq(link, i))
+ if (getenv_int(tunable_buffer, &i) && PCI_INTERRUPT_VALID(i)) {
+ if (!link_valid_irq(link, i))
+ device_printf(dev,
+ "Warning, IRQ %d is not listed as valid\n",
+ i);
return (i);
+ }
snprintf(tunable_buffer, sizeof(tunable_buffer),
"hw.pci.link.%s.irq", link_name);
- if (getenv_int(tunable_buffer, &i) &&
- PCI_INTERRUPT_VALID(i) && link_valid_irq(link, i))
+ if (getenv_int(tunable_buffer, &i) && PCI_INTERRUPT_VALID(i)) {
+ if (!link_valid_irq(link, i))
+ device_printf(dev,
+ "Warning, IRQ %d is not listed as valid\n",
+ i);
return (i);
+ }
}
/*
--
John Baldwin
More information about the freebsd-mobile
mailing list