patch-2.4.27 linux-2.4.27/arch/i386/kernel/mpparse.c

Next file: linux-2.4.27/arch/i386/kernel/mtrr.c
Previous file: linux-2.4.27/arch/i386/kernel/io_apic.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.26/arch/i386/kernel/mpparse.c linux-2.4.27/arch/i386/kernel/mpparse.c
@@ -1104,6 +1104,20 @@
 }
 
 
+/* allocate mp_irqs[] for ACPI parsing table parsing */
+int __init mp_irqs_alloc()
+{
+	int size = (MAX_IRQ_SOURCES * sizeof(int)) * 4;
+
+	mp_irqs = (struct mpc_config_intsrc *)alloc_bootmem(size);
+	if (!mp_irqs) {
+		printk(KERN_ERR "mp_irqs_alloc(): alloc_bootmem(%d) failed!\n", size);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+
 void __init mp_override_legacy_irq (
 	u8			bus_irq,
 	u8			polarity, 
@@ -1111,8 +1125,6 @@
 	u32			global_irq)
 {
 	struct mpc_config_intsrc intsrc;
-	int			i = 0;
-	int			found = 0;
 	int			ioapic = -1;
 	int			pin = -1;
 
@@ -1145,23 +1157,9 @@
 		(intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, 
 		intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, intsrc.mpc_dstirq);
 
-	/* 
-	 * If an existing [IOAPIC.PIN -> IRQ] routing entry exists we override it.
-	 * Otherwise create a new entry (e.g. global_irq == 2).
-	 */
-	for (i = 0; i < mp_irq_entries; i++) {
-		if ((mp_irqs[i].mpc_srcbus == intsrc.mpc_srcbus) 
-			&& (mp_irqs[i].mpc_srcbusirq == intsrc.mpc_srcbusirq)) {
-			mp_irqs[i] = intsrc;
-			found = 1;
-			break;
-		}
-	}
-	if (!found) {
-		mp_irqs[mp_irq_entries] = intsrc;
-		if (++mp_irq_entries == MAX_IRQ_SOURCES)
-			panic("Max # of irq sources exceeded!\n");
-	}
+	mp_irqs[mp_irq_entries] = intsrc;
+	if (++mp_irq_entries == MAX_IRQ_SOURCES)
+		panic("Max # of irq sources exceeded!\n");
 
 	return;
 }
@@ -1179,7 +1177,6 @@
 	int count;
 
 	count = (MAX_MP_BUSSES * sizeof(int)) * 4;
-	count += (MAX_IRQ_SOURCES * sizeof(int)) * 4;
 	bus_data = alloc_bootmem(count);
 	if (!bus_data) {
 		panic("Fatal: can't allocate bus memory for ACPI legacy IRQ!");
@@ -1188,7 +1185,7 @@
 	mp_bus_id_to_node = (int *)&bus_data[(MAX_MP_BUSSES * sizeof(int))];
 	mp_bus_id_to_local = (int *)&bus_data[(MAX_MP_BUSSES * sizeof(int)) * 2];
 	mp_bus_id_to_pci_bus = (int *)&bus_data[(MAX_MP_BUSSES * sizeof(int)) * 3];
-	mp_irqs = (struct mpc_config_intsrc *)&bus_data[(MAX_MP_BUSSES * sizeof(int)) * 4];
+
 	for (i = 0; i < MAX_MP_BUSSES; ++i)
 	  mp_bus_id_to_pci_bus[i] = -1;
 
@@ -1206,13 +1203,20 @@
 		return;
 
 	/* 
-	 * Use the default configuration for the IRQs 0-15.  These may be
+	 * Use the default configuration for the IRQs 0-15.  Unless
 	 * overriden by (MADT) interrupt source override entries.
 	 */
 	for (i = 0; i < 16; i++) {
+		int idx;
 
-		if (i == 2)
-			continue;			/* Don't connect IRQ2 */
+		for (idx = 0; idx < mp_irq_entries; idx++)
+			if (mp_irqs[idx].mpc_srcbus == MP_ISA_BUS &&
+				(mp_irqs[idx].mpc_dstapic == mp_ioapics[ioapic].mpc_apicid) &&
+				(mp_irqs[idx].mpc_srcbusirq == i ||
+				mp_irqs[idx].mpc_dstirq == i))
+					break;
+		if (idx != mp_irq_entries)
+			continue;			  /* IRQ already used */
 
 		mp_irqs[mp_irq_entries].mpc_type = MP_INTSRC;
 		mp_irqs[mp_irq_entries].mpc_irqflag = 0;	/* Conforming */
@@ -1308,11 +1312,13 @@
 		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",
-			entry->id.segment, entry->id.bus, 
-			entry->id.device, ('A' + entry->pin), 
-			mp_ioapic_routing[ioapic].apic_id, ioapic_pin, 
-			entry->irq);
+                printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d"
+                        " -> IRQ %d %s %s\n", entry->id.segment, entry->id.bus,
+                        entry->id.device, ('A' + entry->pin),
+                        mp_ioapic_routing[ioapic].apic_id, ioapic_pin,
+                        entry->irq, edge_level ? "level" : "edge",
+                        active_high_low ? "low" : "high");
+
 	}
 	
 	print_IO_APIC();

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)