All of lore.kernel.org
 help / color / mirror / Atom feed
* RE: [PATCH] IRQ params patch#4
@ 2003-07-23  7:53 Grover, Andrew
       [not found] ` <F760B14C9561B941B89469F59BA3A8470255EEA0-sBd4vmA9Se4Lll3ZsUKC9FDQ4js95KgL@public.gmane.org>
  0 siblings, 1 reply; 7+ messages in thread
From: Grover, Andrew @ 2003-07-23  7:53 UTC (permalink / raw)
  To: Andrew de Quincey, acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

Andrew,

You still hacking on this?

Just got another bug report (completely different HW) that I think might
be the same problem.

Regards -- Andy G.

> From: Andrew de Quincey [mailto:adq_dvb-fmPXVN3awWJAJAzL26g0SA@public.gmane.org] 
> Sent: Tuesday, July 15, 2003 3:42 AM
> To: acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> Subject: [ACPI] [PATCH] IRQ params patch#4
> 
> 
> OK, patch#3 is way too strict... thought a bit more about it, 
> and I suppose 
> the BIOS not allocating some devices an IRQ is actually OK....
> 
> Anyway, patch#4 now just warns the user if an attempt to set 
> an IRQ results in 
> a different IRQ than expected, and attempts to abort ACPI irq 
> routing. 
> Unfortunately, it isn't able to undo the changes it has made 
> to the routing 
> as it would have to call the _SRS method to do it... and its 
> just found out 
> that that is buggy. So at the moment it probably won't be able to 
> automatically "fix" devices already programmed when dropping 
> back to a 
> different method (it can't on my board). Sigh.
> 
> Anyway, the warning should at least help find which boards 
> have bad ACPI IRQ 
> routing.
> 


-------------------------------------------------------
This SF.net email is sponsored by: VM Ware
With VMware you can run multiple operating systems on a single machine.
WITHOUT REBOOTING! Mix Linux / Windows / Novell virtual machines at the
same time. Free trial click here: http://www.vmware.com/wl/offer/345/0

^ permalink raw reply	[flat|nested] 7+ messages in thread
* [PATCH] IRQ params patch#4
@ 2003-07-15 10:42 Andrew de Quincey
       [not found] ` <200307151142.12738.adq_dvb-fmPXVN3awWJAJAzL26g0SA@public.gmane.org>
  0 siblings, 1 reply; 7+ messages in thread
From: Andrew de Quincey @ 2003-07-15 10:42 UTC (permalink / raw)
  To: acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

[-- Attachment #1: Type: text/plain, Size: 721 bytes --]

OK, patch#3 is way too strict... thought a bit more about it, and I suppose 
the BIOS not allocating some devices an IRQ is actually OK....

Anyway, patch#4 now just warns the user if an attempt to set an IRQ results in 
a different IRQ than expected, and attempts to abort ACPI irq routing. 
Unfortunately, it isn't able to undo the changes it has made to the routing 
as it would have to call the _SRS method to do it... and its just found out 
that that is buggy. So at the moment it probably won't be able to 
automatically "fix" devices already programmed when dropping back to a 
different method (it can't on my board). Sigh.

Anyway, the warning should at least help find which boards have bad ACPI IRQ 
routing.

[-- Attachment #2: linux-2.5.75-acpi-irqparams-4.patch --]
[-- Type: text/x-diff, Size: 8836 bytes --]

diff -Naurb linux-2.5.75.orig/arch/i386/kernel/io_apic.c linux-2.5.75/arch/i386/kernel/io_apic.c
--- linux-2.5.75.orig/arch/i386/kernel/io_apic.c	2003-07-10 21:07:34.000000000 +0100
+++ linux-2.5.75/arch/i386/kernel/io_apic.c	2003-07-13 23:53:12.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;
@@ -2336,18 +2336,22 @@
 	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;
 
 	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]);
 
diff -Naurb linux-2.5.75.orig/arch/i386/kernel/mpparse.c linux-2.5.75/arch/i386/kernel/mpparse.c
--- linux-2.5.75.orig/arch/i386/kernel/mpparse.c	2003-07-10 21:06:59.000000000 +0100
+++ linux-2.5.75/arch/i386/kernel/mpparse.c	2003-07-14 22:31:00.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",
diff -Naurb linux-2.5.75.orig/drivers/acpi/pci_irq.c linux-2.5.75/drivers/acpi/pci_irq.c
--- linux-2.5.75.orig/drivers/acpi/pci_irq.c	2003-07-10 21:08:54.000000000 +0100
+++ linux-2.5.75/drivers/acpi/pci_irq.c	2003-07-15 02:56:11.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. */
diff -Naurb linux-2.5.75.orig/drivers/acpi/pci_link.c linux-2.5.75/drivers/acpi/pci_link.c
--- linux-2.5.75.orig/drivers/acpi/pci_link.c	2003-07-10 21:04:58.000000000 +0100
+++ linux-2.5.75/drivers/acpi/pci_link.c	2003-07-15 12:28:08.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,12 +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.edge_level = link->irq.edge_level;
+		resource.res.data.irq.active_high_low = link->irq.active_high_low;
 		resource.res.data.irq.shared_exclusive = ACPI_SHARED;
 		resource.res.data.irq.number_of_interrupts = 1;
 		resource.res.data.irq.interrupts[0] = irq;
@@ -324,8 +332,8 @@
 		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.edge_level = link->irq.edge_level;
+		resource.res.data.extended_irq.active_high_low = link->irq.active_high_low;
 		resource.res.data.extended_irq.shared_exclusive = ACPI_SHARED;
 		resource.res.data.extended_irq.number_of_interrupts = 1;
 		resource.res.data.extended_irq.interrupts[0] = irq;
@@ -333,6 +341,7 @@
 	}
 	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"));
@@ -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);
 }

diff -Naurb linux-2.5.75.orig/include/acpi/acpi_drivers.h linux-2.5.75/include/acpi/acpi_drivers.h
--- linux-2.5.75.orig/include/acpi/acpi_drivers.h	2003-07-10 21:12:26.000000000 +0100
+++ linux-2.5.75/include/acpi/acpi_drivers.h	2003-07-13 22:21:05.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) */

diff -Naurb linux-2.5.75.orig/include/asm-i386/io_apic.h linux-2.5.75/include/asm-i386/io_apic.h
--- linux-2.5.75.orig/include/asm-i386/io_apic.h	2003-07-10 21:12:15.000000000 +0100
+++ linux-2.5.75/include/asm-i386/io_apic.h	2003-07-13 22:21:05.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 */

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2003-07-24 13:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-07-23  7:53 [PATCH] IRQ params patch#4 Grover, Andrew
     [not found] ` <F760B14C9561B941B89469F59BA3A8470255EEA0-sBd4vmA9Se4Lll3ZsUKC9FDQ4js95KgL@public.gmane.org>
2003-07-23 17:52   ` Rob North
2003-07-24  9:13   ` Andrew de Quincey
     [not found]     ` <200307241013.34507.adq_dvb-fmPXVN3awWJAJAzL26g0SA@public.gmane.org>
2003-07-24 12:58       ` Rob North
2003-07-24 13:31         ` Andrew de Quincey
  -- strict thread matches above, loose matches on Subject: below --
2003-07-15 10:42 Andrew de Quincey
     [not found] ` <200307151142.12738.adq_dvb-fmPXVN3awWJAJAzL26g0SA@public.gmane.org>
2003-07-19 10:49   ` Rob North

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.