> uhci chipsets. As I said previously, I know a "special" UHCI driver was
> released by Microsoft/VIA that corrected a lot of problems that were being
> had with VIA's chipset. I would persue a fix for it myself, but I don't
The old VIA random bit stuff is covered in the Linux USB
> know enough about the host controller code to be able to talk one-to-one
> to a VIA representative. If the maintainer of one of the *uhci.c drivers
> were to look into it, I think it definitely be worth doing.
Lots of VIA boards have what appear to be incorrect $PIR IRQ routing tables.
Windows uses other methods for IRQ routing so generally works out, Linux
uses the $PIR table so does not.
-- this hack tends to fix most of them ->
>From [EMAIL PROTECTED] Sun Nov 04 22:07:34 2001
Return-path: <[EMAIL PROTECTED]>
Envelope-to: [EMAIL PROTECTED]
Delivery-date: Sun, 04 Nov 2001 22:07:34 +0000
Received: from colorfullife.com ([216.156.138.34])
by the-village.bc.nu with esmtp (Exim 3.22 #1)
id 160VQT-0003Du-00
for [EMAIL PROTECTED]; Sun, 04 Nov 2001 22:07:33 +0000
Received: from dbl.localdomain (localhost [127.0.0.1])
by colorfullife.com (8.11.6/8.11.6) with ESMTP id fA4M1CL25528;
Sun, 4 Nov 2001 17:01:13 -0500
Received: from colorfullife.com (IDENT:[EMAIL PROTECTED] [172.17.4.1])
by dbl.localdomain (8.11.2/8.11.2) with ESMTP id fA4LxvU12362;
Sun, 4 Nov 2001 23:00:03 +0100
Sender: [EMAIL PROTECTED]
Message-ID: <[EMAIL PROTECTED]>
Date: Sun, 04 Nov 2001 22:59:57 +0100
From: Manfred Spraul <[EMAIL PROTECTED]>
X-Mailer: Mozilla 4.76 [en] (X11; U; Linux 2.4.13-ac7 i686)
X-Accept-Language: en, de
MIME-Version: 1.0
To: Alan Cox <[EMAIL PROTECTED]>
CC: [EMAIL PROTECTED]
Subject: pci-irq.c
Content-Type: multipart/mixed;
boundary="------------7B3CDC07A9A97CDC876B3336"
Status: RO
This is a multi-part message in MIME format.
--------------7B3CDC07A9A97CDC876B3336
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Hi Alan,
attached is my cleanup of pci-irq.c.
It works with all my mobos (piix, ali, via) and should fix the vaio
problem.
The main change is a code cleanup (do not scan first for a good irq,
and then discard the result and use what's currently installed in
the irq router, etc) and documentation.
Actual changes:
* if r->set exists, then always write our idea of the irq number
into the irq router, even if we use the bios supplied dev->irq number.
* ignore 'dev2->irq' mismatches - if they exist (e.g. Toms vaio),
then we must solve them by either using 'dev->irq' or 'dev2->irq'.
Just looking away means that one device won't work.
* bounds checking in pirq_via_set. I think I saw pirq=0x58 with my
ali board, I must check the docu if that can be right.
But I doubt that this solves your via sound problems.
via sound interrupts are handled with special code in via_quirks,
and that code is not pirq compatible. Do you have lspci -vxx /
dump_pirq output?
--
Manfred
--------------7B3CDC07A9A97CDC876B3336
Content-Type: text/plain; charset=us-ascii;
name="patch-pciirq-experimental"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="patch-pciirq-experimental"
--- 2.4/arch/i386/kernel/pci-irq.c Sat Nov 3 19:51:08 2001
+++ build-2.4/arch/i386/kernel/pci-irq.c Sun Nov 4 22:47:22 2001
@@ -197,13 +197,24 @@
*/
static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
{
- return read_config_nybble(router, 0x55, pirq);
+ /* the internal devices (APCI, MC97, AC97, USB port 1 and 2
+ * are handled by quirk_via_acpi and quirk_via_irqpic
+ */
+ if (pirq < 6)
+ return read_config_nybble(router, 0x55, pirq);
+ return 0;
}
static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int
irq)
{
- write_config_nybble(router, 0x55, pirq, irq);
- return 1;
+ /* the internal devices (APCI, MC97, AC97, USB port 1 and 2
+ * are handled by quirk_via_acpi and quirk_via_irqpic
+ */
+ if (pirq < 6) {
+ write_config_nybble(router, 0x55, pirq, irq);
+ return 1;
+ }
+ return 0;
}
/*
@@ -536,8 +547,8 @@
{
u8 pin;
struct irq_info *info;
- int i, pirq, newirq;
- int irq = 0;
+ int i, pirq;
+ int irq;
u32 mask;
struct irq_router *r = pirq_router;
struct pci_dev *dev2;
@@ -570,48 +581,65 @@
mask &= pcibios_irq_mask;
/*
- * Find the best IRQ to assign: use the one
- * reported by the device if possible.
+ * Find the best IRQ to assign:
+ * 1) hardcoded into pirq 0xf?
+ * 2) dev->irq.
+ * There are 2 sources for dev->irq:
+ * a) stored by the bios into PCI_INTERRUPT_LINE
+ * b) multiple devices share one pirq, then the loop
+ * at the end of this function writes to dev->irq
+ * 3) stored by the bios into the irq router
+ * 4) only if assign is set: search for a low penalty irq
*/
- newirq = dev->irq;
- if (!newirq && assign) {
- for (i = 0; i < 16; i++) {
- if (!(mask & (1 << i)))
- continue;
- if (pirq_penalty[i] < pirq_penalty[newirq] &&
- !request_irq(i, pcibios_test_irq_handler, SA_SHIRQ,
"pci-test", dev)) {
- free_irq(i, dev);
- newirq = i;
- }
- }
- }
- DBG(" -> newirq=%d", newirq);
-
- /* Check if it is hardcoded */
if ((pirq & 0xf0) == 0xf0) {
irq = pirq & 0xf;
DBG(" -> hardcoded IRQ %d\n", irq);
msg = "Hardcoded";
+ } else if (dev->irq) {
+ irq = dev->irq;
+ DBG(" -> preselected IRQ %d\n", irq);
+ msg = "Preselected";
+ if (!(mask & (1<<irq)))
+ printk(KERN_INFO "PCI: pirq table doesn't match preselected
+IRQ for %s, using preselected irq.\n", dev->slot_name);
} else if (r->get && (irq = r->get(pirq_router_dev, dev, pirq))) {
DBG(" -> got IRQ %d\n", irq);
msg = "Found";
- } else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
- DBG(" -> assigning IRQ %d", newirq);
- if (r->set(pirq_router_dev, dev, pirq, newirq)) {
- eisa_set_level_irq(newirq);
- DBG(" ... OK\n");
- msg = "Assigned";
- irq = newirq;
+ if (!(mask & (1<<irq)))
+ printk(KERN_INFO "PCI: pirq table doesn't match IRQ router
+setting for %s, using irq router setting.\n", dev->slot_name);
+ } else if (assign) {
+ for (i = 0; i < 16; i++) {
+ if (!(mask & (1 << i)))
+ continue;
+ if (pirq_penalty[i] < pirq_penalty[irq] &&
+ !request_irq(i, pcibios_test_irq_handler, SA_SHIRQ,
+"pci-test", dev)) {
+ free_irq(i, dev);
+ irq = i;
+ }
}
- }
+ DBG(" -> assigning irq=%d\n", irq);
+ msg = "Assigned";
+ } else
+ return 0;
+ if (!irq)
+ return 0;
- if (!irq) {
- DBG(" ... failed\n");
- if (newirq && mask == (1 << newirq)) {
- msg = "Guessed";
- irq = newirq;
- } else
- return 0;
+ if ((pirq & 0xf0) != 0xf0 && r->set && (dev->class >> 8) !=
+PCI_CLASS_DISPLAY_VGA) {
+ /* always rewrite our idea of the interrupt routing back into
+ * the irq router
+ */
+ if (r->set(pirq_router_dev, dev, pirq, irq)) {
+ DBG("Set succeeded\n");
+ eisa_set_level_irq(irq);
+ } else {
+ DBG("Set failed\n");
+ /* We ignore this error unless there is no way
+ * the irq routing could work without a successful
+ * r->set().
+ */
+ if (!strcmp(msg, "Assigned") && mask != (1<<irq)) {
+ return 0;
+ }
+ }
}
printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, dev->slot_name);
@@ -625,11 +653,13 @@
if (!info)
continue;
if (info->irq[pin].link == pirq) {
- /* We refuse to override the dev->irq information. Give a
warning! */
+ /* Give a warning if we have to overwrite dev->irq information.
+ * This only happens when multiple devices share one pirq, and
+ * the bios claims that it routes them to different irq
+numbers.
+ */
if (dev2->irq && dev2->irq != irq) {
printk(KERN_INFO "IRQ routing conflict for %s, have
irq %d, want irq %d\n",
dev2->slot_name, dev2->irq, irq);
- continue;
}
dev2->irq = irq;
pirq_penalty[irq]++;
--------------7B3CDC07A9A97CDC876B3336--
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel