Subject: kern/22728: fix for irq slot allocation problem
To: None <gnats-bugs@gnats.netbsd.org>
From: Stephen Degler <stephen@degler.net>
List: netbsd-bugs
Date: 09/09/2003 00:27:38
>Number:         22728
>Category:       kern
>Synopsis:       fix for irq slot allocation problem
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Sep 09 04:28:01 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     Stephen Degler
>Release:        NetBSD 1.6Z
>Organization:
	Very Little, At Best
>Environment:
	
	
System: NetBSD kashmir.degler.net 1.6Z NetBSD 1.6Z (KASHMIR) #96: Mon Sep 8 23:10:47 EDT 2003 sdegler@kashmir.degler.net:/vol1/NetBSD/kernels/KASHMIR i386
Architecture: i386
Machine: i386
>Description:
	I am using a VIA KT600 motherboard, and a -current kernel
	with ACPI and the ioapic enabled.  The bios configures the usb
	controllers in a silly fashion:
	
	uhci0: interrupting at ioapic0 pin 21 (irq 5)
	uhci1: interrupting at ioapic0 pin 21 (irq 5)
	uhci2: interrupting at ioapic0 pin 21 (irq 9)
	uhci2: interrupting at ioapic0 pin 21 (irq 9)
	ehci0: interrupting at ioapic0 pin 21 (irq 11)

	Note that all the irq's are in the "legacy" range, and they differ.
	The current code for allocating irq's ends up mapping some of
	these inputs to different interrupt slots and then programming
	ioapic pin 21 reptitively for the different slots.  Only the
	last slot for a given pin will get interrupt service.
	
	
>How-To-Repeat:
	Using an Asus A7V600, bios version 1005, build a -current kernel
	with acpi and the ioapic enabled.  Note that the usb ports do not
	work.  Booting a kernel witout the ioapic will work fine.

>Fix:
	With the attached patch, all devices with identical pins for a
	given pic will be mapped to the same slot.  The "non-legacy"
	and multiprocessor logic already seems to do this.

Index: sys/arch/x86/x86/intr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/intr.c,v
retrieving revision 1.6
diff -u -r1.6 intr.c
--- sys/arch/x86/x86/intr.c	2003/09/06 17:44:40	1.6
+++ sys/arch/x86/x86/intr.c	2003/09/09 03:47:10
@@ -262,6 +262,14 @@
 	 */
 	if (legacy_irq != -1) {
 		ci = &cpu_info_primary;
+		/* must check for duplicate pic + pin first */
+		for ( slot = 0 ; slot < MAX_INTR_SOURCES ; slot++) {
+			isp = ci->ci_isources[slot];
+			if ( isp != NULL && isp->is_pic == pic &&
+			     isp->is_pin == pin ) {
+				goto duplicate;
+			}
+		}
 		slot = legacy_irq;
 		isp = ci->ci_isources[slot];
 		if (isp == NULL) {
@@ -284,7 +292,7 @@
 				goto other;
 			}
 		}
-
+duplicate:
 		if (pic == &i8259_pic)
 			idtvec = ICU_OFFSET + legacy_irq;
 		else {
>Release-Note:
>Audit-Trail:
>Unformatted: