Subject: Re: Libretto L2 USB IRQ Mapping
To: None <lennart@augustsson.net>
From: Masanori Kanaoka <kanaoka@ann.hi-ho.ne.jp>
List: tech-kern
Date: 05/12/2002 01:19:48
----Next_Part(Sun_May_12_01:19:48_2002_155)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi,

       From: Lennart Augustsson <lennart@augustsson.net>
    Subject: Re: Libretto L2 USB IRQ Mapping
      Date : Mon, 22 Apr 2002 22:44:48 +0200
 Message-ID: <3CC47640.46BE4FA0@augustsson.net>

$ Here is my interrupt routing patch.
$     -- Lennart

I modify your first patch below:

 - Move pcibios_init() after ACPI attach.
 - Get PRT information by ACPI.
 - Make PIR table from the PRT information.
 - Fixup PCI irq routing by PCIBIOS_INTR_FXIP.

When my patch applied, ochi0, cbb0, fxp0, autri0 work fine for me.
I think this is workaround. The right way is only using ACPI.

I attach patch and dmesg message.
FYI. Regards
---
 Masanori Kanaoka	kanaoka@ann.hi-ho.ne.jp


----Next_Part(Sun_May_12_01:19:48_2002_155)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="dmesg.acpi-pci_intr_fixup"

NetBSD 1.5ZC (IDEA) #0: Sat May 11 10:28:07 JST 2002
    root@idea.k.vnop.net:/usr/src/sys/arch/i386/compile/IDEA
cpu0: Transmeta Crusoe (586-class), 597.77 MHz
cpu0: Processor revision 1.3.2.0
cpu0: Code Morphing Software Rev: 4.2.5-8-148
cpu0: 20010503 11:00 official release 4.2.5#1
cpu0: LongRun mode: 1  <600MHz 1600mV 100%>
cpu0: features 80893f<FPU,VME,DE,PSE,TSC,MSR,CX8,SEP>
cpu0: features 80893f<CMOV,MMX>
total memory = 110 MB
avail memory = 98 MB
using 1446 buffers containing 5784 KB of memory
BIOS32 rev. 0 found at 0xfb5bb
mainbus0 (root)
 tbxface-0207 [01] AcpiLoadTables        : ACPI Tables successfully loaded
Parsing Methods:.............................................................................................
93 Control Methods found and parsed (509 nodes total)
ACPI Namespace successfully loaded at root 0xc04b4dd4
acpi0 at mainbus0
evxfevnt-0179 [02] AcpiEnable            : Transition to ACPI mode successful
acpi0: SCI interrupting at irq 9
acpi0: fixed-feature power button present
acpi0: Get PCI Irq Routing Table
acpi_pir_get: start
	Bus: 0  Device: 4
		INTA: link 0x01 bitmap 0x0800
	Bus: 0  Device: 18
		INTA: link 0x02 bitmap 0x0cf8
	Bus: 0  Device: 14
		INTA: link 0x03 bitmap 0x0400
	Bus: 0  Device: 6
		INTA: link 0x08 bitmap 0x0cf8
	Bus: 0  Device: 20
		INTA: link 0x07 bitmap 0x0080

acpi0: HID PNP0C01 found in scope \134_SB_ level 1
       STA 0x0000000f
acpi0: HID PNP0A03 found in scope \134_SB_ level 1
       ADR 0x0000000000000000
       STA 0x0000000f
acpi0: HID PNP0C0F found in scope \134_SB_ level 3
       UID 1
       STA 0x0000000b
acpi0: HID PNP0C0F found in scope \134_SB_ level 3
       UID 2
       STA 0x00000009
acpi0: HID PNP0C0F found in scope \134_SB_ level 3
       UID 3
       STA 0x0000000b
acpi0: HID PNP0C0F found in scope \134_SB_ level 3
       UID 7
       STA 0x0000000b
acpi0: HID PNP0C0F found in scope \134_SB_ level 3
       UID 8
       STA 0x00000009
acpi0: HID PNP0200 found in scope \134_SB_ level 3
       STA 0x0000000f
acpi0: HID PNP0000 found in scope \134_SB_ level 3
       STA 0x0000000f
acpi0: HID PNP0100 found in scope \134_SB_ level 3
       STA 0x0000000f
acpi0: HID PNP0800 found in scope \134_SB_ level 3
       STA 0x0000000f
acpi0: HID PNP0C04 found in scope \134_SB_ level 3
       STA 0x0000000f
acpi0: HID PNP0303 found in scope \134_SB_ level 3
       STA 0x0000000f
acpi0: HID PNP0F13 found in scope \134_SB_ level 3
       STA 0x0000000f
acpi0: HID PNP0B00 found in scope \134_SB_ level 3
       STA 0x0000000f
acpi0: HID PNP0C02 found in scope \134_SB_ level 3
       STA 0x0000000f
acpi0: HID PNP0C0D found in scope \134_SB_ level 1
       STA 0x0000000f
acpi0: HID PNP0C0A found in scope \134_SB_ level 1
       UID 1
       STA 0x0000001f
acpi0: HID ACPI0003 found in scope \134_SB_ level 1
       STA 0x0000000f
acpi0: HID TOS6200 found in scope \134_SB_ level 1
       STA 0x0000000b
acpi0: HID TOS6201 found in scope \134_SB_ level 1
       STA 0x0000000b
PNP0C01 at acpi0 not configured
PNP0A03 at acpi0 not configured
PNP0200 at acpi0 not configured
PNP0000 at acpi0 not configured
PNP0100 at acpi0 not configured
PNP0800 at acpi0 not configured
PNP0C04 at acpi0 not configured
PNP0303 at acpi0 not configured
PNP0F13 at acpi0 not configured
PNP0B00 at acpi0 not configured
PNP0C02 at acpi0 not configured
acpilid0 at acpi0: ACPI Lid Switch
PNP0C0A at acpi0 not configured
acpiacad0 at acpi0: ACPI AC Adapter
acpiacad0: AC adapter connected
acpi0: HID PNP0C0B found in scope \134_TZ_ level 1
       UID 1
       STA 0x0000000f
acpi0: HID PNP0C0B found in scope \134_TZ_ level 1
       UID 2
       STA 0x0000000f
PNP0C0B at acpi0 not configured
PNP0C0B at acpi0 not configured
PCI BIOS rev. 2.1 found at 0xfcd73
pcibios: config mechanism [1][x], special cycles [x][x], last bus 1

Using ACPI PRT information.
PIR Entry 0:
	Bus: 0  Device: 20
		INTA: link 0x07 bitmap 0x0080
		INTB: link 0x00 bitmap 0x0000
		INTC: link 0x00 bitmap 0x0000
		INTD: link 0x00 bitmap 0x0000
PIR Entry 1:
	Bus: 0  Device: 6
		INTA: link 0x08 bitmap 0x0cf8
		INTB: link 0x00 bitmap 0x0000
		INTC: link 0x00 bitmap 0x0000
		INTD: link 0x00 bitmap 0x0000
PIR Entry 2:
	Bus: 0  Device: 14
		INTA: link 0x03 bitmap 0x0400
		INTB: link 0x00 bitmap 0x0000
		INTC: link 0x00 bitmap 0x0000
		INTD: link 0x00 bitmap 0x0000
PIR Entry 3:
	Bus: 0  Device: 18
		INTA: link 0x02 bitmap 0x0cf8
		INTB: link 0x00 bitmap 0x0000
		INTC: link 0x00 bitmap 0x0000
		INTD: link 0x00 bitmap 0x0000
PIR Entry 4:
	Bus: 0  Device: 4
		INTA: link 0x01 bitmap 0x0800
		INTB: link 0x00 bitmap 0x0000
		INTC: link 0x00 bitmap 0x0000
		INTD: link 0x00 bitmap 0x0000
pciintr_link_fixup: PIRQ 0x00 already connected to IRQ 11
pciintr_link_fixup: PIRQ 0x01 not connected
pciintr_link_fixup: PIRQ 0x02 already connected to IRQ 10
pciintr_link_fixup: PIRQ 0x06 not connected, assigning IRQ 7
pciintr_link_fixup: PIRQ 0x07 not connected
pciintr_link_fixup (stage 2): assigning IRQ 7 to PIRQ 0x01
pciintr_link_fixup (stage 2): assigning IRQ 7 to PIRQ 0x07
pciintr_link_route: route of PIRQ 0x00 -> IRQ 11 preserved BIOS setting
pciintr_link_route: route of PIRQ 0x02 -> IRQ 10 preserved BIOS setting
------------------------------------------
  device vendor product pin PIRQ IRQ stage
------------------------------------------
000:04:0 0x5333 0x8c12   A  0x00  11  0    already assigned
000:06:0 0x10b9 0x5451   A  0x07   7  2    fixed up
000:14:0 0x8086 0x1229   A  0x02  10  0    already assigned
000:18:0 0x1179 0x0617   A  0x01   7  2    fixed up
000:20:0 0x10b9 0x5237   A  0x06   7  1    already assigned
------------------------------------------
PCI fixup examining 1279:395
PCI fixup examining 1279:396
PCI fixup examining 1279:397
PCI fixup examining 5333:8c12
PCI fixup examining 10b9:5451
PCI fixup examining 10b9:1533
PCI fixup examining 8086:1229
PCI fixup examining 10b9:5229
PCI fixup examining 10b9:7101
PCI fixup examining 1179:617
PCI bridge 0: primary 0, secondary 1, subordinate 1
PCI fixup examining 10b9:5237
PCI bus #1 is the last bus
[System BIOS Setting]-----------------------
  device vendor product
  register space address    size
--------------------------------------------
000:00:0 0x1279 0x0395 
	10h mem  0xefd00000 0x00100000
		[OK]
000:00:1 0x1279 0x0396 
		[OK]
000:00:2 0x1279 0x0397 
		[OK]
000:04:0 0x5333 0x8c12 
	10h mem  0xe0000000 0x08000000
		[OK]
000:06:0 0x10b9 0x5451 
	10h port 0x00000000 0x00000100
	14h mem  0x00000000 0x00001000
		[NG]
000:07:0 0x10b9 0x1533 
		[OK]
000:14:0 0x8086 0x1229 
	10h mem  0xdffff000 0x00001000
	14h port 0x0000edc0 0x00000040
	18h mem  0xdfe00000 0x00100000
		[OK]
000:16:0 0x10b9 0x5229 
	20h port 0x0000edb0 0x00000010
		[OK]
000:17:0 0x10b9 0x7101 
		[OK]
000:18:0 0x1179 0x0617 
	10h mem  0x00000000 0x00001000
		[NG]
000:20:0 0x10b9 0x5237 
	10h mem  0xdfdfe000 0x00001000
		[OK]
--------------------------[  2 devices bogus]
 Physical memory end: 0x06f58000
 PCI memory mapped I/O space start: 0x07000000
[PCIBIOS fixup stage]-----------------------
  device vendor product
  register space address    size
--------------------------------------------
000:00:0 0x1279 0x0395 
	10h mem  0xefd00000 0x00100000
		[OK]
000:00:1 0x1279 0x0396 
		[OK]
000:00:2 0x1279 0x0397 
		[OK]
000:04:0 0x5333 0x8c12 
	10h mem  0xe0000000 0x08000000
		[OK]
000:06:0 0x10b9 0x5451 
	10h port 0x00005800 0x00000100
	14h mem  0x07000000 0x00001000
		[OK]
000:07:0 0x10b9 0x1533 
		[OK]
000:14:0 0x8086 0x1229 
	10h mem  0xdffff000 0x00001000
	14h port 0x0000edc0 0x00000040
	18h mem  0xdfe00000 0x00100000
		[OK]
000:16:0 0x10b9 0x5229 
	20h port 0x0000edb0 0x00000010
		[OK]
000:17:0 0x10b9 0x7101 
		[OK]
000:18:0 0x1179 0x0617 
	10h mem  0x07001000 0x00001000
		[OK]
000:20:0 0x10b9 0x5237 
	10h mem  0xdfdfe000 0x00001000
		[OK]
--------------------------[  0 devices bogus]
pci0 at mainbus0 bus 0: configuration mode 1
pci0: i/o space, memory space enabled, rd/line, rd/mult, wr/inv ok
pchb0 at pci0 dev 0 function 0
pchb0: Transmeta Corp LongRun Northbridge (rev. 0x01)
Transmeta Corp SDRAM Controller (RAM memory) at pci0 dev 0 function 1 not configured
Transmeta Corp BIOS Scratchpad (RAM memory) at pci0 dev 0 function 2 not configured
vga1 at pci0 dev 4 function 0: S3 Savage/IX+MV (rev. 0x13)
wsdisplay0 at vga1 kbdmux 1: console (80x25, vt100 emulation)
wsmux1: connecting to wsdisplay0
wsdisplay0: screen 1-3 added (80x25, vt100 emulation)
autri0 at pci0 dev 6 function 0: Acer Labs M5451 AC-Link Controller Audio Device (rev. 0x01)
autri0: interrupting at irq 7
autri0: Asahi Kasei AK4543 codec; headphone, 18 bit DAC, 18 bit ADC, AKM 3D
audio0 at autri0: full duplex, mmap, independent
midi0 at autri0: 4DWAVE MIDI UART
pcib0 at pci0 dev 7 function 0
pcib0: Acer Labs M1543 PCI-ISA Bridge (rev. 0x00)
fxp0 at pci0 dev 14 function 0: i82559 Ethernet, rev 8
fxp0: interrupting at irq 10
fxp0: Ethernet address 00:00:39:fa:d6:d1
inphy0 at fxp0 phy 1: i82555 10/100 media interface, rev. 4
inphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
pciide0 at pci0 dev 16 function 0: Acer Labs M5229 UDMA IDE Controller (rev. 0xc3)
pciide0: bus-master DMA support present
pciide0: primary channel wired to compatibility mode
wd0 at pciide0 channel 0 drive 0: <TOSHIBA MK2018GAP>
wd0: drive supports 16-sector PIO transfers, LBA addressing
wd0: 19077 MB, 16383 cyl, 16 head, 63 sec, 512 bytes/sect x 39070080 sectors
wd0: 32-bit data port
wd0: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 5 (Ultra/100)
pciide0: primary channel interrupting at irq 14
wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 2 (Ultra/33) (using DMA data transfers)
pciide0: secondary channel wired to compatibility mode
pciide0: secondary channel ignored (disabled)
Acer Labs M7101 Power Management Controller (miscellaneous bridge) at pci0 dev 17 function 0 not configured
cbb0 at pci0 dev 18 function 0: Toshiba ToPIC100 CardBus-PCI Bridge (rev. 0x32)
ohci0 at pci0 dev 20 function 0: Acer Labs M5237 USB Host Controller (rev. 0x03)
ohci0: interrupting at irq 7
ohci0: OHCI version 1.0, legacy support
usb0 at ohci0: USB revision 1.0
uhub0 at usb0
uhub0: Acer Labs OHCI root hub, class 9/0, rev 1.00/1.00, addr 1
uhub0: 2 ports with 2 removable, self powered
isa0 at pcib0
pckbc0 at isa0 port 0x60-0x64
pckbd0 at pckbc0 (kbd slot)
pckbc0: using irq 1 for kbd slot
wskbd0 at pckbd0: console keyboard, using wsdisplay0
pms0 at pckbc0 (aux slot)
pckbc0: using irq 12 for aux slot
wsmouse0 at pms0 mux 0
pcppi0 at isa0 port 0x61
midi1 at pcppi0: PC speaker
sysbeep0 at pcppi0
npx0 at isa0 port 0xf0-0xff: using exception 16
cbb0: interrupting at irq 7
cardslot0 at cbb0 slot 0 flags 0
cardbus0 at cardslot0: bus 1 device 0
pcmcia0 at cardslot0
biomask e9fd netmask edfd ttymask fdff
ACPI: WARNING: Callback scheduled before thread present.
ex0 at cardbus0 dev 0 function 0: 3Com 3c575CT Ethernet
ex0: MAC address 00:50:04:b6:85:bf
tqphy0 at ex0 phy 0: 78Q2120 10/100 media interface, rev. 11
tqphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
boot device: wd0
root on wd0a dumps on wd0b
root file system type: ffs
ex0: interrupting at 7
uhidev0 at uhub0 port 1 configuration 1 interface 0
uhidev0: Logitech N48, rev 1.00/4.00, addr 2, iclass 3/1
ums0 at uhidev0: 3 buttons and Z dir.
wsmouse1 at ums0 mux 0
uhidev0: at uhub0 port 1 (addr 2) disconnected
wsmouse1 detached
ums0 detached
uhidev0 detached
acpiacad0: AC adapter not connected
acpiacad0: AC adapter connected

----Next_Part(Sun_May_12_01:19:48_2002_155)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="acpi-pci_intr_fixup.diff"

Index: arch/i386/i386/autoconf.c
===================================================================
RCS file: /ftp/cvs/syssrc/sys/arch/i386/i386/autoconf.c,v
retrieving revision 1.60
diff -u -r1.60 autoconf.c
--- arch/i386/i386/autoconf.c	2002/01/07 21:47:00	1.60
+++ arch/i386/i386/autoconf.c	2002/05/10 08:58:44
@@ -84,13 +84,6 @@
 #include <machine/bios32.h>
 #endif
 
-#include "opt_pcibios.h"
-#ifdef PCIBIOS
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcivar.h>
-#include <i386/pci/pcibios.h>
-#endif
-
 struct device *booted_device;
 int booted_partition;
 
@@ -105,9 +98,6 @@
 
 #if NBIOS32 > 0
 	bios32_init();
-#endif
-#ifdef PCIBIOS
-	pcibios_init();
 #endif
 
 	if (config_rootfound("mainbus", NULL) == NULL)
Index: arch/i386/i386/mainbus.c
===================================================================
RCS file: /ftp/cvs/syssrc/sys/arch/i386/i386/mainbus.c,v
retrieving revision 1.37
diff -u -r1.37 mainbus.c
--- arch/i386/i386/mainbus.c	2002/02/28 21:48:05	1.37
+++ arch/i386/i386/mainbus.c	2002/05/10 09:35:42
@@ -53,6 +53,13 @@
 #include "pnpbios.h"
 #include "acpi.h"
 
+#include "opt_pcibios.h"
+#ifdef PCIBIOS
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <i386/pci/pcibios.h>
+#endif
+
 #if NAPM > 0
 #include <machine/bioscall.h>
 #include <machine/apmvar.h>
@@ -184,6 +191,9 @@
 	}
 #endif
 
+#ifdef PCIBIOS
+	pcibios_init();
+#endif
 	/*
 	 * XXX Note also that the presence of a PCI bus should
 	 * XXX _always_ be checked, and if present the bus should be
Index: dev/acpi/acpi.c
===================================================================
RCS file: /ftp/cvs/syssrc/sys/dev/acpi/acpi.c,v
retrieving revision 1.7
diff -u -r1.7 acpi.c
--- dev/acpi/acpi.c	2002/03/24 03:32:14	1.7
+++ dev/acpi/acpi.c	2002/05/10 17:29:26
@@ -53,6 +53,9 @@
 #include <dev/acpi/acpivar.h>
 #include <dev/acpi/acpi_osd.h>
 
+#include <dev/acpi/acpica/Subsystem/acresrc.h>
+#include <dev/acpi/acpica/Subsystem/acnamesp.h>
+
 #ifdef ENABLE_DEBUGGER
 #define	ACPI_DBGR_INIT		0x01
 #define	ACPI_DBGR_TABLES	0x02
@@ -94,6 +97,21 @@
 
 void		acpi_enable_fixed_events(struct acpi_softc *);
 
+#ifndef ACPI_PIR_GET
+#define ACPI_PIR_GET
+#endif
+
+#ifdef ACPI_PIR_GET
+void			acpi_pir_get(struct acpi_softc *);
+static ACPI_HANDLE	acpi_get_node(char *);
+static ACPI_STATUS	acpi_run_with_buf(
+			    ACPI_STATUS (*)(ACPI_HANDLE, ACPI_BUFFER *),
+			    ACPI_BUFFER *, ACPI_HANDLE);
+static UINT16		acpi_get_bitmap(ACPI_HANDLE);
+static ACPI_STATUS	acpi_pir_get_bus(ACPI_HANDLE, UINT32, void *,
+			    void **);
+#endif
+
 /*
  * acpi_probe:
  *
@@ -254,11 +272,20 @@
 	/* Our current state is "awake". */
 	sc->sc_sleepstate = ACPI_STATE_S0;
 
+	/* Show SCI interrupt. */
+	if (AcpiGbl_FADT != NULL)
+		printf("%s: SCI interrupting at irq %d\n",
+			sc->sc_dev.dv_xname, AcpiGbl_FADT->SciInt);
 	/*
 	 * Check for fixed-hardware features.
 	 */
 	acpi_enable_fixed_events(sc);
 
+	acpi_pir_info = NULL;
+#ifdef ACPI_PIR_GET
+	/* Get PCI Routing Table. */
+	acpi_pir_get(sc);
+#endif
 	/*
 	 * Scan the namespace and build our device tree.
 	 */
@@ -709,3 +736,187 @@
 
 	return ((*getit)(handle, buf));
 }
+
+
+#ifdef ACPI_PIR_GET
+
+static ACPI_HANDLE
+acpi_get_node(char *name)
+{
+	ACPI_NAMESPACE_NODE *ObjDesc;
+	ACPI_STATUS Status;
+
+	Status = AcpiNsGetNode(name, NULL, &ObjDesc);
+	if (ACPI_FAILURE (Status)) {
+		printf("Could not find: %s\n", AcpiFormatException (Status));
+		return NULL;
+	}
+	return ObjDesc;
+}
+
+
+static ACPI_STATUS
+acpi_run_with_buf(ACPI_STATUS (*fun)(ACPI_HANDLE, ACPI_BUFFER *),
+		  ACPI_BUFFER *buf, ACPI_HANDLE handle)
+{
+	ACPI_STATUS rv;
+
+	buf->Pointer = NULL;
+	buf->Length = 0;
+	rv = (*fun)(handle, buf);
+	if (rv != AE_BUFFER_OVERFLOW)
+		return (rv);
+	buf->Pointer = malloc(buf->Length, M_DEVBUF, M_WAITOK);
+	rv = (*fun)(handle, buf);
+	if (ACPI_FAILURE(rv))
+		free(buf->Pointer, M_DEVBUF);
+	return (rv);
+}
+
+static UINT16 
+acpi_get_bitmap(ACPI_HANDLE handle)
+{
+	ACPI_BUFFER bufp, bufc;
+	ACPI_RESOURCE *resp, *resc;
+	ACPI_RESOURCE_IRQ *irq;
+	ACPI_STATUS rv;
+	UINT16 i, bitmap = 0;
+
+	rv = acpi_run_with_buf(AcpiGetPossibleResources, &bufp, handle);
+	if (ACPI_FAILURE(rv)) 
+		goto out;
+	rv = acpi_run_with_buf(AcpiGetCurrentResources, &bufc, handle);
+	if (ACPI_FAILURE(rv)) 
+		goto out1;
+	
+	resp = bufp.Pointer;
+	resc = bufc.Pointer;
+
+	/*
+	 * If current NumberOfInterrupts is 1, we use current.
+	 * Else, we use possible.
+	 */  
+	irq = (ACPI_RESOURCE_IRQ *)&resc->Data;
+	if (irq->NumberOfInterrupts != 1)
+		irq = (ACPI_RESOURCE_IRQ *)&resp->Data;
+
+	for (i = 0; i < irq->NumberOfInterrupts; i++)
+		bitmap |= (1 << irq->Interrupts[i]);
+
+	free(bufc.Pointer, M_DEVBUF);
+out1:
+	free(bufp.Pointer, M_DEVBUF);
+out:
+	return (bitmap);
+}
+
+static ACPI_STATUS
+acpi_pir_get_bus(ACPI_HANDLE handle, UINT32 level, void *context,
+		   void **status)
+{
+	struct acpi_softc *sc = context;
+	ACPI_STATUS rv;
+	ACPI_BUFFER buf;
+	UINT8 *Buffer;
+	PCI_ROUTING_TABLE *PrtElement;
+	ACPI_HANDLE link;
+	char LastChar;
+	UINT16 bitmap;
+	struct acpi_intr *ai;
+
+	rv = acpi_run_with_buf(AcpiGetIrqRoutingTable, &buf, handle);
+	if (ACPI_FAILURE(rv))
+		return (AE_OK);
+
+	acpi_pir_info = malloc(sizeof(struct acpi_pir), M_DEVBUF, M_NOWAIT);
+	if (acpi_pir_info == NULL) {
+		printf("No memory for acpi_pir_info\n");
+		return (AE_OK);
+	}
+	acpi_pir_info->api_intr = NULL;
+	acpi_pir_info->api_nentries = 0;
+	acpi_pir_info->api_sci_irq = AcpiGbl_FADT->SciInt;
+	
+        for (Buffer = buf.Pointer; ; Buffer += PrtElement->Length) {
+		PrtElement = (PCI_ROUTING_TABLE *)Buffer;
+		if (PrtElement->Length == 0)
+			break;
+		if (PrtElement->Source == NULL)
+			continue;
+
+		link = acpi_get_node(PrtElement->Source);
+		LastChar = PrtElement->Source[strlen(PrtElement->Source)-1];
+		if (LastChar >= 'A' && LastChar <= 'Z') 
+			LastChar -= '@';
+		else if (LastChar >= '0' && LastChar <= '9')
+			LastChar -= '0';
+		if (link == NULL)
+			continue;
+		bitmap = acpi_get_bitmap(link);
+
+#ifdef ACPI_DEBUG
+		printf("\tBus: %d  Device: %d\n", sc->sc_pci_bus,
+	 	    (unsigned)PrtElement->Address >> 16);
+		printf("\t\tINT%c: link 0x%02x bitmap 0x%04x\n",
+		    PrtElement->Pin + 1 + '@', LastChar, bitmap);
+#endif
+
+		/* XXX: set pcibios Interface */
+
+		ai = malloc(sizeof(*ai), M_DEVBUF,M_NOWAIT);
+		ai->ai_next = acpi_pir_info->api_intr;
+		ai->ai_bus = sc->sc_pci_bus;
+		ai->ai_dev = (unsigned)PrtElement->Address >> 16;
+		ai->ai_pin = PrtElement->Pin;
+		ai->ai_link = LastChar;
+		ai->ai_bitmap = bitmap;
+		acpi_pir_info->api_intr = ai;
+		acpi_pir_info->api_nentries++;
+
+	}
+#ifdef ACPI_DEBUG
+	printf("\n");
+#endif
+	sc->sc_pci_bus++;
+
+	free(buf.Pointer, M_DEVBUF);
+	return (AE_OK);
+}
+
+/*
+ * acpi_pir_get:
+ */
+void
+acpi_pir_get(struct acpi_softc *sc)
+{
+	ACPI_HANDLE parent;
+
+	printf("%s: Get PCI Irq Routing Table\n", sc->sc_dev.dv_xname);
+
+#ifdef ACPI_DEBUG
+	printf("acpi_pir_get: start\n");
+#endif
+	if (AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &parent) != AE_OK)
+		return;
+	sc->sc_pci_bus = 0;
+	AcpiWalkNamespace(ACPI_TYPE_DEVICE, parent, 100,
+	    acpi_pir_get_bus, sc, NULL);
+#if 0
+	{
+		struct acpi_intr *ai;
+		for (ai = acpi_pir_info->api_intr; 
+		    ai ; 
+		    ai = ai->ai_next) {
+			printf("\tBus: %d Device: %d\n", 
+			    ai->ai_bus, ai->ai_dev);
+			printf("\t\tINT%c: link 0x%02x bitmap 0x%04x\n",
+		    	    ai->ai_pin + 1 +'@', ai->ai_link, ai->ai_bitmap);
+		}
+		printf("acpi_pir_info->api_nentries %d\n",
+		    acpi_pir_info->api_nentries);
+		printf("%s: SCI interrupting at irq %d\n",
+		    sc->sc_dev.dv_xname, acpi_pir_info->api_sci_irq);
+	}
+#endif
+}
+#endif /* ACPI_PIR_GET */
Index: dev/acpi/acpivar.h
===================================================================
RCS file: /ftp/cvs/syssrc/sys/dev/acpi/acpivar.h,v
retrieving revision 1.4
diff -u -r1.4 acpivar.h
--- dev/acpi/acpivar.h	2002/03/24 03:32:14	1.4
+++ dev/acpi/acpivar.h	2002/05/10 16:47:55
@@ -107,6 +107,7 @@
 	bus_space_tag_t sc_memt;	/* PCI MEM space tag */
 	pci_chipset_tag_t sc_pc;	/* PCI chipset tag */
 	int sc_pciflags;		/* PCI bus flags */
+	int sc_pci_bus;			/* internal PCI fixup */
 
 	void *sc_sdhook;		/* shutdown hook */
 
@@ -236,6 +237,23 @@
 	void	(*start_dep)(struct device *, void *, int);
 	void	(*end_dep)(struct device *, void *);
 };
+
+struct acpi_intr {
+	struct acpi_intr *ai_next;
+	u_int8_t	ai_bus;
+	u_int8_t	ai_dev;
+	u_int8_t	ai_pin;
+	u_int8_t	ai_link;
+	u_int16_t	ai_bitmap;
+};
+
+struct acpi_pir {
+	struct acpi_intr *api_intr;
+	int	api_nentries;
+	int	api_sci_irq;
+};
+
+struct acpi_pir *acpi_pir_info; 
 
 extern struct acpi_softc *acpi_softc;
 extern int acpi_active;
Index: arch/i386/pci/pci_intr_fixup.c
===================================================================
RCS file: /ftp/cvs/syssrc/sys/arch/i386/pci/pci_intr_fixup.c,v
retrieving revision 1.19
diff -u -r1.19 pci_intr_fixup.c
--- arch/i386/pci/pci_intr_fixup.c	2001/12/07 08:07:57	1.19
+++ arch/i386/pci/pci_intr_fixup.c	2002/05/11 00:29:49
@@ -576,10 +576,16 @@
 {
 	int i, bit;
 
+	/* XXX: Force set Level for some irq (such as ACPI SCI) */
+	*pciirq |= pcibios_force_level_bitmap;
+
 	for (i = 0, bit = 1; i < 16; i++, bit <<= 1) {
 		if ((*pciirq & bit) == 0)
 			(void) pciintr_icu_set_trigger(pciintr_icu_tag,
 			    pciintr_icu_handle, i, IST_EDGE);
+		else if ((pcibios_force_level_bitmap & bit) == 1)
+			(void) pciintr_icu_set_trigger(pciintr_icu_tag,
+			    pciintr_icu_handle, i, IST_LEVEL);
 	}
 
 	return (0);
Index: arch/i386/pci/pcibios.c
===================================================================
RCS file: /ftp/cvs/syssrc/sys/arch/i386/pci/pcibios.c,v
retrieving revision 1.9
diff -u -r1.9 pcibios.c
--- arch/i386/pci/pcibios.c	2002/01/28 23:53:08	1.9
+++ arch/i386/pci/pcibios.c	2002/05/11 01:21:01
@@ -83,6 +83,8 @@
 #include <dev/pci/pcivar.h>
 #include <dev/pci/pcidevs.h>
 
+#include <dev/acpi/acpivar.h>
+
 #include <i386/pci/pcibios.h>
 #ifdef PCIBIOS_INTR_FIXUP
 #include <i386/pci/pci_intr_fixup.h>
@@ -119,6 +121,8 @@
 int	pcibios_return_code __P((u_int16_t, const char *));
 
 void	pcibios_print_exclirq __P((void));
+
+
 #ifdef PCIINTR_DEBUG
 void	pcibios_print_pir_table __P((void));
 #endif
@@ -237,7 +241,51 @@
 	u_int16_t tablesize;
 	u_int8_t rev_maj, rev_min;
 	int i;
+	struct pcibios_intr_routing *pir;
+	struct acpi_intr *ai;
+
+	/*
+	 * At first, We try using ACPI PRT information.
+	 * ACPI_PIR_GET make ACPI PRT information.
+	 */
+	pcibios_force_level_bitmap = 0;
+	if (acpi_pir_info != NULL && acpi_pir_info->api_nentries != 0) {
+		pcibios_pir_table = malloc(acpi_pir_info->api_nentries * 16, 
+		    M_DEVBUF, M_NOWAIT);
+		if (pcibios_pir_table == NULL) {
+			printf("pcibios_pir_init: no memory for $PIR\n");
+			return;
+		}
+		for ( ai = acpi_pir_info->api_intr, pir = pcibios_pir_table ;
+		     ai; ai = ai->ai_next, pir++) {
+			pir->bus = ai->ai_bus;
+			pir->device = (ai->ai_dev & 0x1f) << 3;
+			for (i = 0; i < 4 ; i++) {
+				if (i == ai->ai_pin) {
+					pir->linkmap[i].link = ai->ai_link;
+					pir->linkmap[i].bitmap = ai->ai_bitmap;
+				} else {
+					pir->linkmap[i].link = 0;
+					pir->linkmap[i].bitmap = 0;
+				}
+			}
+			pir->slot = 0;
+			pir->reserved = 0;
+		}
+		pcibios_pir_table_nentries = acpi_pir_info->api_nentries;
+		pcibios_force_level_bitmap = (1 << acpi_pir_info->api_sci_irq);
+		printf("\nUsing ACPI PRT information.\n");
 
+#ifdef PCIINTR_DEBUG
+		pcibios_print_pir_table();
+#endif
+		return;
+	}
+
+	/*
+	 * If there were no ACPI pir table, we try using $PIR table. 
+	 * Get $PIR table.
+	 */
 	for (pa = PCI_IRQ_TABLE_START; pa < PCI_IRQ_TABLE_END; pa += 16) {
 		p = (caddr_t)ISA_HOLE_VADDR(pa);
 		if (*(int *)p != BIOS32_MAKESIG('$', 'P', 'I', 'R')) {
@@ -301,6 +349,7 @@
 		}
 		printf("\n");
 		pcibios_print_exclirq();
+
 #ifdef PCIINTR_DEBUG
 		pcibios_print_pir_table();
 #endif
@@ -333,6 +382,7 @@
 	printf("PCI BIOS has %d Interrupt Routing table entries\n",
 	    pcibios_pir_table_nentries);
 	pcibios_print_exclirq();
+
 #ifdef PCIINTR_DEBUG
 	pcibios_print_pir_table();
 #endif
@@ -477,6 +527,7 @@
 		printf("\n");
 	}
 }
+
 
 #ifdef PCIINTR_DEBUG
 void
Index: arch/i386/pci/pcibios.h
===================================================================
RCS file: /ftp/cvs/syssrc/sys/arch/i386/pci/pcibios.h,v
retrieving revision 1.5
diff -u -r1.5 pcibios.h
--- arch/i386/pci/pcibios.h	2002/01/22 15:07:27	1.5
+++ arch/i386/pci/pcibios.h	2002/05/10 17:21:24
@@ -100,6 +100,8 @@
 void pci_bridge_foreach(pci_chipset_tag_t, int, int,
     void (*) (pci_chipset_tag_t, pcitag_t, void *), void *);
 
+u_int16_t pcibios_force_level_bitmap;
+
 #ifdef PCIBIOSVERBOSE
 extern int pcibiosverbose;
 

----Next_Part(Sun_May_12_01:19:48_2002_155)----