Skip to contentSkip to conversation

2.6.0-test1: irq18 nobody cared! on Intel D865PERL motherboard

DISCUSSION Felipe Alfaro Solana 3 participants 7 messages Jul 14, 2003 – Jul 28, 2003

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

Hi,

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 tried compiling without ACPI, APIC and SMP, but the result is nearly the same. Attached to this message are the output of "lspci -vvv", a "dmesg" and the "config" used to compile the kernel.

Any ideas? Should I report this to IDE mantainers? Thanks!

Signature · 5 lines
______________________________________________
http://www.linuxmail.org/
Now with e-mail forwarding for only US$5.95/yr

Powered by Outblaze
#1 lore raw
Quoted 5 lines · Felipe Alfaro Solana

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.

MikaL

#2 lore raw
Quoted 7 lines · Mika Liljeberg
Quoted 5 lines · Felipe Alfaro Solana

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.

Quoted 6 lines

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).

arch/i386/kernel/io_apic.c +10 -6
@@ -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]);
 
arch/i386/kernel/mpparse.c +5 -3
@@ -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",
drivers/acpi/pci_irq.c +4 -2
@@ -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. */
drivers/acpi/pci_link.c +29 -11
@@ -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);
 }
 
include/acpi/acpi_drivers.h +1 -1
@@ -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) */
 
include/asm-i386/io_apic.h +1 -1
@@ -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 */
#3 lore raw
Quoted 2 lines · Andrew de Quincey

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?

Yes, yes, nope. I tried your patch but the SATA driver now hangs during boot waiting for an irq that never arrives.

MikaL

#4 lore raw
Quoted 6 lines · Mika Liljeberg
Quoted 2 lines · Andrew de Quincey

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?

Yes, yes, nope. I tried your patch but the SATA driver now hangs during boot waiting for an irq that never arrives.

This sounds very familiar. As I said, the patch fixes the IO-APIC so IRQ polarities and mode is it is now setup as per ACPI... its obviously doing _something_ for you.

However, there is a second problem which I do not yet have a resolution for.

On my board, it manifests itself with PCI addon cards.. I never see any IRQs from them because the IO-APIC is configured (as per ACPI) for active high IRQs, yet the PCI standard is active low IRQs.

I am fairly certain that the IO-APIC is now configured correctly, and that the PCI routing is correct, because Windows XP sets everything up in exactly the same way, and everything works fine under it.

There is something else that is not being done by linux. I'd assumed this was an nforce2-specific issue, but your results hint that it may be larger than this.

#5 lore raw

Re: 2.6.0-test1: irq18 nobody cared! on Intel D865PERL motherboard -- found it!

Quoted 4 lines

There is something else that is not being done by linux. I'd assumed this was an nforce2-specific issue, but your results hint that it may be larger than this.

Yay! I've found it. What seems to be happening is the PIC is left connected to the PCI IRQ lines, and is causing problems.. I assume pulling the lines up/down incorrectly.

My BIOS lets me define which PIC IRQs are allocated to PCI and which are "reserved". I set them all to reserved, effectively disabling any IRQs < 15 being allocated to PCI. Now everything works perfectly.

I've downloaded the manual for your motherboard, but I can't see anything like that for your board.. all you can do is the standard choose IRQ, or auto.

Anyway, now I know what is causing this, expect a patch soon.

#6 lore raw
In reply to Andrew de Quincey
Quoted 7 lines · Andrew de Quincey
Quoted 6 lines

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.

Quoted 5 lines

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).

I won't have access to those machines until August, 3th. I will give your patch a try then :-)
Thanks!