From: Andrew de Quincey <adq_dvb@lidskialf.net>
To: Mika Liljeberg <mika.liljeberg@welho.com>,
Felipe Alfaro Solana <felipe_alfaro@linuxmail.org>
Cc: linux-kernel@vger.kernel.org
Subject: Re: 2.6.0-test1: irq18 nobody cared! on Intel D865PERL motherboard
Date: Sat, 26 Jul 2003 23:13:08 +0100 [thread overview]
Message-ID: <200307262313.08819.adq_dvb@lidskialf.net> (raw)
In-Reply-To: <1059256372.8484.9.camel@hades>
[-- Attachment #1: Type: text/plain, Size: 964 bytes --]
On Saturday 26 July 2003 22:52, Mika Liljeberg wrote:
> On Mon, 2003-07-14 at 16:12, Felipe Alfaro Solana wrote:
> > I'm having problems with an Intel D865PERL motherboard and Serial ATA
> > support. Everytime I boot my RHL9 box using 2.6.0-test1, I get an
> > "irq18 nobody cared!" error and then "Disabling IRQ #18". Any attempt
> > to access any of the SATA controllers makes the system hang and
> > spitting out problems with timings on the "hde" interface.
>
> I have the same problem with Abit IS7-E, which also has the i865PE
> chipset.
>
> Add "noirqdebug" to the kernel command line and you should be able to
> boot, although the irq will be firing continously until the device
> driver gets initialized and catches it.
Out of interest, do these boxes have an IO-APIC and are you using ACPI? If so,
can you tell me if the attached patch helps?
These are exactly the symptoms I got without the attached patch (it fixes an
IO-APIC setup bug with ACPI).
[-- Attachment #2: linux-2.5.75-acpi-irqparams-final.patch --]
[-- Type: text/x-diff, Size: 8685 bytes --]
--- linux-2.5.75.orig/arch/i386/kernel/io_apic.c 2003-07-10 21:07:34.000000000 +0100
+++ linux-2.5.75-noprocfs/arch/i386/kernel/io_apic.c 2003-07-26 21:21:18.000000000 +0100
@@ -2313,7 +2313,7 @@
}
-int io_apic_set_pci_routing (int ioapic, int pin, int irq)
+int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low)
{
struct IO_APIC_route_entry entry;
unsigned long flags;
@@ -2335,19 +2335,23 @@
entry.delivery_mode = INT_DELIVERY_MODE;
entry.dest_mode = INT_DEST_MODE;
entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
- entry.mask = 1; /* Disabled (masked) */
- entry.trigger = 1; /* Level sensitive */
- entry.polarity = 1; /* Low active */
+ entry.trigger = edge_level;
+ entry.polarity = active_high_low;
+ entry.mask = 1;
add_pin_to_irq(irq, ioapic, pin);
entry.vector = assign_irq_vector(irq);
printk(KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> "
- "IRQ %d)\n", ioapic,
- mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq);
+ "IRQ %d Mode:%i Active:%i)\n", ioapic,
+ mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, edge_level, active_high_low);
+ if (edge_level) {
irq_desc[irq].handler = &ioapic_level_irq_type;
+ } else {
+ irq_desc[irq].handler = &ioapic_edge_irq_type;
+ }
set_intr_gate(entry.vector, interrupt[irq]);
--- linux-2.5.75.orig/arch/i386/kernel/mpparse.c 2003-07-10 21:06:59.000000000 +0100
+++ linux-2.5.75-noprocfs/arch/i386/kernel/mpparse.c 2003-07-26 21:02:26.000000000 +0100
@@ -1065,7 +1065,7 @@
ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
- io_apic_set_pci_routing(ioapic, ioapic_pin, irq);
+ io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 1, 1); // Active low, edge triggered
}
#endif /*CONFIG_ACPI_HT_ONLY*/
@@ -1080,6 +1080,8 @@
int ioapic_pin = 0;
int irq = 0;
int idx, bit = 0;
+ int edge_level = 0;
+ int active_high_low = 0;
/*
* Parsing through the PCI Interrupt Routing Table (PRT) and program
@@ -1090,7 +1092,7 @@
/* Need to get irq for dynamic entry */
if (entry->link.handle) {
- irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index);
+ irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low);
if (!irq)
continue;
}
@@ -1130,7 +1132,7 @@
mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
- if (!io_apic_set_pci_routing(ioapic, ioapic_pin, irq))
+ if (!io_apic_set_pci_routing(ioapic, ioapic_pin, irq, edge_level, active_high_low))
entry->irq = irq;
printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n",
--- linux-2.5.75.orig/drivers/acpi/pci_irq.c 2003-07-10 21:08:54.000000000 +0100
+++ linux-2.5.75-noprocfs/drivers/acpi/pci_irq.c 2003-07-26 21:05:19.000000000 +0100
@@ -249,7 +249,7 @@
}
if (!entry->irq && entry->link.handle) {
- entry->irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index);
+ entry->irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, NULL, NULL);
if (!entry->irq) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
return_VALUE(0);
@@ -389,7 +389,9 @@
}
/* Make sure all link devices have a valid IRQ. */
- acpi_pci_link_check();
+ if (acpi_pci_link_check()) {
+ return_VALUE(-ENODEV);
+ }
#ifdef CONFIG_X86_IO_APIC
/* Program IOAPICs using data from PRT entries. */
--- linux-2.5.75.orig/drivers/acpi/pci_link.c 2003-07-10 21:04:58.000000000 +0100
+++ linux-2.5.75-noprocfs/drivers/acpi/pci_link.c 2003-07-26 21:12:52.000000000 +0100
@@ -69,6 +69,8 @@
struct acpi_pci_link_irq {
u8 active; /* Current IRQ */
+ u8 edge_level; /* All IRQs */
+ u8 active_high_low; /* All IRQs */
u8 possible_count;
u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
};
@@ -118,6 +120,8 @@
link->irq.possible[i] = p->interrupts[i];
link->irq.possible_count++;
}
+ link->irq.edge_level = p->edge_level;
+ link->irq.active_high_low = p->active_high_low;
break;
}
case ACPI_RSTYPE_EXT_IRQ:
@@ -136,6 +140,8 @@
link->irq.possible[i] = p->interrupts[i];
link->irq.possible_count++;
}
+ link->irq.edge_level = p->edge_level;
+ link->irq.active_high_low = p->active_high_low;
break;
}
default:
@@ -310,13 +316,14 @@
memset(&resource, 0, sizeof(resource));
- /* NOTE: PCI interrupts are always level / active_low / shared. */
+ /* NOTE: PCI interrupts are always level / active_low / shared. But not all
+ interrupts > 15 are PCI interrupts. Rely on the ACPI IRQ definition for
+ parameters */
if (irq <= 15) {
resource.res.id = ACPI_RSTYPE_IRQ;
resource.res.length = sizeof(struct acpi_resource);
- resource.res.data.irq.edge_level = ACPI_LEVEL_SENSITIVE;
- resource.res.data.irq.active_high_low = ACPI_ACTIVE_LOW;
- resource.res.data.irq.shared_exclusive = ACPI_SHARED;
+ resource.res.data.irq.edge_level = link->irq.edge_level;
+ resource.res.data.irq.active_high_low = link->irq.active_high_low;
resource.res.data.irq.number_of_interrupts = 1;
resource.res.data.irq.interrupts[0] = irq;
}
@@ -324,15 +331,15 @@
resource.res.id = ACPI_RSTYPE_EXT_IRQ;
resource.res.length = sizeof(struct acpi_resource);
resource.res.data.extended_irq.producer_consumer = ACPI_CONSUMER;
- resource.res.data.extended_irq.edge_level = ACPI_LEVEL_SENSITIVE;
- resource.res.data.extended_irq.active_high_low = ACPI_ACTIVE_LOW;
- resource.res.data.extended_irq.shared_exclusive = ACPI_SHARED;
+ resource.res.data.extended_irq.edge_level = link->irq.edge_level;
+ resource.res.data.extended_irq.active_high_low = link->irq.active_high_low;
resource.res.data.extended_irq.number_of_interrupts = 1;
resource.res.data.extended_irq.interrupts[0] = irq;
/* ignore resource_source, it's optional */
}
resource.end.id = ACPI_RSTYPE_END_TAG;
+ /* Attempt to set the resource */
status = acpi_set_current_resources(link->handle, &buffer);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SRS\n"));
@@ -355,11 +362,13 @@
if (result) {
return_VALUE(result);
}
+
if (link->irq.active != irq) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Attempt to enable at IRQ %d resulted in IRQ %d\n",
irq, link->irq.active));
link->irq.active = 0;
+ acpi_ut_evaluate_object (link->handle, "__DIS", 0, NULL);
return_VALUE(-ENODEV);
}
@@ -455,15 +464,20 @@
irq = link->irq.possible[i];
}
- /* Enable the link device at this IRQ. */
- acpi_pci_link_set(link, irq);
-
+ /* Attempt to enable the link device at this IRQ. */
+ if (acpi_pci_link_set(link, irq)) {
+ printk(PREFIX "Unable to set IRQ for %s [%s] (likely buggy ACPI BIOS). Aborting ACPI-based IRQ routing. Try pci=noacpi or acpi=off\n",
+ acpi_device_name(link->device),
+ acpi_device_bid(link->device));
+ return_VALUE(-ENODEV);
+ } else {
acpi_irq_penalty[link->irq.active] += 100;
printk(PREFIX "%s [%s] enabled at IRQ %d\n",
acpi_device_name(link->device),
acpi_device_bid(link->device), link->irq.active);
}
+ }
return_VALUE(0);
}
@@ -472,7 +486,9 @@
int
acpi_pci_link_get_irq (
acpi_handle handle,
- int index)
+ int index,
+ int* edge_level,
+ int* active_high_low)
{
int result = 0;
struct acpi_device *device = NULL;
@@ -503,6 +519,8 @@
return_VALUE(0);
}
+ if (edge_level) *edge_level = link->irq.edge_level;
+ if (active_high_low) *active_high_low = link->irq.active_high_low;
return_VALUE(link->irq.active);
}
--- linux-2.5.75.orig/include/acpi/acpi_drivers.h 2003-07-10 21:12:26.000000000 +0100
+++ linux-2.5.75-noprocfs/include/acpi/acpi_drivers.h 2003-07-26 20:59:45.000000000 +0100
@@ -60,7 +60,7 @@
/* ACPI PCI Interrupt Link (pci_link.c) */
int acpi_pci_link_check (void);
-int acpi_pci_link_get_irq (acpi_handle handle, int index);
+int acpi_pci_link_get_irq (acpi_handle handle, int index, int* edge_level, int* active_high_low);
/* ACPI PCI Interrupt Routing (pci_irq.c) */
--- linux-2.5.75.orig/include/asm-i386/io_apic.h 2003-07-10 21:12:15.000000000 +0100
+++ linux-2.5.75-noprocfs/include/asm-i386/io_apic.h 2003-07-26 21:01:16.000000000 +0100
@@ -170,7 +170,7 @@
extern int io_apic_get_unique_id (int ioapic, int apic_id);
extern int io_apic_get_version (int ioapic);
extern int io_apic_get_redir_entries (int ioapic);
-extern int io_apic_set_pci_routing (int ioapic, int pin, int irq);
+extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low);
#endif /*CONFIG_ACPI_BOOT*/
#else /* !CONFIG_X86_IO_APIC */
next prev parent reply other threads:[~2003-07-26 21:58 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-07-14 13:12 2.6.0-test1: irq18 nobody cared! on Intel D865PERL motherboard Felipe Alfaro Solana
2003-07-26 21:52 ` Mika Liljeberg
2003-07-26 22:13 ` Andrew de Quincey [this message]
2003-07-26 23:01 ` Mika Liljeberg
2003-07-26 23:23 ` Andrew de Quincey
2003-07-27 0:17 ` 2.6.0-test1: irq18 nobody cared! on Intel D865PERL motherboard -- found it! Andrew de Quincey
2003-07-27 19:09 ` 2.6.0-test1: irq18 nobody cared! on Intel D865PERL motherboard Felipe Alfaro Solana
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200307262313.08819.adq_dvb@lidskialf.net \
--to=adq_dvb@lidskialf.net \
--cc=felipe_alfaro@linuxmail.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mika.liljeberg@welho.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).