Re: PCI IRQ routing problem in 2.4.0 (fwd)

From: Martin Diehl (mdiehlcs@compuserve.de)
Date: Mon Jan 29 2001 - 13:09:11 EST


Apparantly this didn't get thru since my mailer was blocked due to
dialup-blacklists (never observed this bevor on l-k!)

so I try to resend it.

Martin

---------- Forwarded message ----------
Date: Mon, 29 Jan 2001 18:22:43 +0100 (CET)
From: Martin Diehl <mdiehlcs@compuserve.de>
To: Jeff Garzik <jgarzik@mandrakesoft.mandrakesoft.com>
Cc: Linus Torvalds <torvalds@transmeta.com>,
     Robert Siemer <siemer@panorama.hadiko.de>, linux-kernel@vger.kernel.org
Subject: Re: PCI IRQ routing problem in 2.4.0

On Mon, 29 Jan 2001, Jeff Garzik wrote:

> And what what we're seeing in this thread, it looks like there are
> two different types of SiS link values from two different BIOSen;
> or perhaps one BIOS is using some of the link value bits for other
> purposes.

Right, seems the 0x41/0x01 thing. I have the 0x01 case with SiS 85C503
router rev. 01. Hopefully the 0x41 boards have a different revision. My
fear however is, this is due to BIOS implementation of the routing table.

Using the docs of the 85C503 function from the SiS5595 southbridge
datasheet I've written a patch to get things right - at least for the 0x01
case. The mapping on my box appears as follows:

link/pirq value config-reg function
0x01/0x02/0x03/0x04 0x41/0x42/0x43/0x44 PCI INTA..D
0x61 0x61 5513 onboard IDE
0x62 0x62 onboard USB (OHCI)
0x6a 0x6a onboard ACPI
0x7e 0x7e onboard data acquisition

The patch below deals with the PCI INT and USB case and works fine on my
box. It will fail (printk) on the 0x41 case.
So please, everyone with SiS chipset (seems all of them using the same
router function): Test it - regardless whether having problems or not.
Probably we'll need a kernel parameter to specify which mapping to use.

More details as commented in the code.

Attached: dmesg/lspci/dump_pirq output with BIOS-setting PNP OS=yes and
USB (enabled, auto-irq) to see the router at work (PCI-DEBUG).

BTW: I was wondering, why we did not update the PCI_INTERRUPT_LINE in
config space when we re-route dev->irq. Well, documentation/pci.txt says
we should trust on dev->irq over config space, however stopping lspci
and friends to confuse us would be too bad either. So I've included a
one-liner to fix this.

------

--- linux-2.4.0/arch/i386/kernel/pci-irq.c.orig Mon Jan 8 14:45:35 2001
+++ linux-2.4.0/arch/i386/kernel/pci-irq.c Mon Jan 29 17:23:25 2001
@@ -234,22 +234,114 @@
         return 1;
 }
 
+/*
+ * PIRQ routing for SiS 85C503 router used in several SiS chipsets
+ * According to the SiS 5595 datasheet (preliminary V1.0, 12/24/1997)
+ * the related registers work as follows:
+ *
+ * general: one byte per re-routable IRQ,
+ * bit 7 IRQ mapping enabled (0) or disabled (1)
+ * bits [6:4] reserved
+ * bits [3:0] IRQ to map to
+ * allowed: 3-7, 9-12, 14-15
+ * reserved: 0, 1, 2, 8, 13
+ *
+ * individual registers in device config space:
+ *
+ * 0x41/0x42/0x43/0x44: PCI INT A/B/C/D - bits as in general case
+ *
+ * 0x61: IDEIRQ: bits as in general case - but:
+ * bits [6:5] must be written 01
+ * bit 4 channel-select primary (0), secondary (1)
+ *
+ * 0x62: USBIRQ: bits as in general case - but:
+ * bit 4 OHCI function disabled (0), enabled (1)
+ *
+ * 0x6a: ACPI/SCI IRQ - bits as in general case
+ *
+ * 0x7e: Data Acq. Module IRQ - bits as in general case
+ *
+ * Tested using SiS 5595 southbridge (vendor:device:rev=1039:0008:01)
+ * Testbox:
+ * BIOS Vendor: Award Software, Inc.
+ * BIOS Version: #401A0-0103xl-7
+ * BIOS Release: 06/12/98
+ * System Vendor: System Manufacturer.
+ * Product Name: System Name.
+ * Version System Version.
+ * Serial Number SYS-1234567890.
+ * Board Vendor: ASUSTeK Computer INC..
+ * Board Name: SP98AGP-X.
+ * Board Version: REV 1.XX.
+ * Asset Tag: Asset-1234567890.
+ *
+ * BIOS routing table uses link 0x01-0x04 for PCI IRQ A-D, but register
+ * offsets like 0x62 as link values for USBIRQ e.g. So there is no simple
+ * "register = offset + pirq" relation. To make things even more confusing,
+ * reading USB OHCI's PCI_INTERRUPT_PIN config register (at 0x3d) returns 1
+ * suggesting the USB OHCI were connected to PCI INTA, which is not the case.
+ * One can map USBIRQ to a value that differs from all PCI INTA..D!
+ * Same holds for the other onboard chipset IRQ's (IDE/ACPI/DAQ).
+ * The latter are currently unsupported (left untouched as set by BIOS).
+ */
+
 static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
 {
         u8 x;
- int reg = 0x41 + (pirq - 'A') ;
+ int reg = pirq;
 
- pci_read_config_byte(router, reg, &x);
+ switch(pirq) {
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ reg += 0x40;
+ case 0x62:
+ pci_read_config_byte(router, reg, &x);
+ if (reg != 0x62)
+ break;
+ if (!(x & 0x40))
+ return 0;
+ break;
+ case 0x61:
+ case 0x6a:
+ case 0x7e:
+ printk("SiS pirq: advanced IDE/ACPI/DAQ mapping not yet implemented\n");
+ return 0;
+ default:
+ printk("SiS router pirq escape (%d)\n", pirq);
+ return 0;
+ }
         return (x & 0x80) ? 0 : (x & 0x0f);
 }
 
 static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
 {
         u8 x;
- int reg = 0x41 + (pirq - 'A') ;
+ int reg = pirq;
 
- pci_read_config_byte(router, reg, &x);
- x = (pirq & 0x20) ? 0 : (irq & 0x0f);
+ switch(pirq) {
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ reg += 0x40;
+ case 0x62:
+ x = (irq&0x0f) ? (irq&0x0f) : 0x80;
+ if (reg != 0x62)
+ break;
+ /* always mark OHCI enabled, as nothing else knows about this */
+ x |= 0x40;
+ break;
+ case 0x61:
+ case 0x6a:
+ case 0x7e:
+ printk("advanced SiS pirq mapping not yet implemented\n");
+ return 0;
+ default:
+ printk("SiS router pirq escape (%d)\n", pirq);
+ return 0;
+ }
         pci_write_config_byte(router, reg, x);
 
         return 1;
@@ -505,6 +597,7 @@
                         continue;
                 if (info->irq[pin].link == pirq) {
                         dev2->irq = irq;
+ pci_write_config_byte(dev2, PCI_INTERRUPT_LINE, irq);
                         pirq_penalty[irq]++;
                         if (dev != dev2)
                                 printk("PCI: The same IRQ used for device %s\n", dev2->slot_name);







-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Jan 31 2001 - 21:00:33 EST