public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* USB + PCI - IRQ = kernel bug??
@ 2001-12-11  3:29 Jonathan Stanford
  2001-12-11 12:49 ` Alan Cox
  0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Stanford @ 2001-12-11  3:29 UTC (permalink / raw)
  To: linux-kernel

Got a problem usb subsystem......
it's not seeing anything past the root hub....
when a device is connected the following error pops up....

USB device not accepting new address=2 (error=-110)
see for yourself here --> http://quail.no-ip.com/bootmsg.txt

what i find interesting is that no interrupts are being sent
see for yourself here --> http://quail.no-ip.com/interrupts.txt

i've removed just about all devices from the system.... and there is no 
change....

here's a list of the PCI bus......
http://quail.no-ip.com/lspci.txt

this problem appears on everything from 2.4.7 (RH7.2 kern)  to the 
latest and greatest (2.4.17-pre8) and probably earlier kernels as well....

the southbridge/usb controler is the VIA Technologies, Inc. VT82C686b chip as you can see in 

http://quail.no-ip.com/lspci.txt


Let me know what else you need to make sence of this.......

-Jonathan Stanford
<jomast@mindspring.com>




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: USB + PCI - IRQ = kernel bug??
       [not found] <mailman.1008041221.4721.linux-kernel2news@redhat.com>
@ 2001-12-11  3:42 ` Pete Zaitcev
  2001-12-11  4:01   ` Jonathan Stanford
  0 siblings, 1 reply; 5+ messages in thread
From: Pete Zaitcev @ 2001-12-11  3:42 UTC (permalink / raw)
  To: jomast, linux-kernel

> what i find interesting is that no interrupts are being sent
> see for yourself here --> http://quail.no-ip.com/interrupts.txt

Your BIOS is broken.

> i've removed just about all devices from the system.... and there is no 
> change....

You should have posted the log as it looks _after_ pulling
the SCSI card.

Another thing to try is to use a 2.7.9-x kernel from RH updates
for 7.2 and use "apic" parameter. See if that helps.

-- Pete

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: USB + PCI - IRQ = kernel bug??
  2001-12-11  3:42 ` Pete Zaitcev
@ 2001-12-11  4:01   ` Jonathan Stanford
  0 siblings, 0 replies; 5+ messages in thread
From: Jonathan Stanford @ 2001-12-11  4:01 UTC (permalink / raw)
  To: Pete Zaitcev; +Cc: linux-kernel

>
>
>>what i find interesting is that no interrupts are being sent
>>see for yourself here --> http://quail.no-ip.com/interrupts.txt
>>
>
>Your BIOS is broken.
>
it's got the latest flash........
and as much as i dont like saying this out loud......  it all works in 
win2k.....

>
>
>>i've removed just about all devices from the system.... and there is no 
>>change....
>>
>
>You should have posted the log as it looks _after_ pulling
>the SCSI card.
>
>Another thing to try is to use a 2.7.9-x kernel from RH updates
>for 7.2 and use "apic" parameter. See if that helps.
>
i've try'd that kernel...... same results.....

"apic" ??

>
>-- Pete
>




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: USB + PCI - IRQ = kernel bug??
  2001-12-11  3:29 USB + PCI - IRQ = kernel bug?? Jonathan Stanford
@ 2001-12-11 12:49 ` Alan Cox
  2001-12-11 21:00   ` Jonathan Stanford
  0 siblings, 1 reply; 5+ messages in thread
From: Alan Cox @ 2001-12-11 12:49 UTC (permalink / raw)
  To: Jonathan Stanford; +Cc: linux-kernel

> this problem appears on everything from 2.4.7 (RH7.2 kern)  to the 
> latest and greatest (2.4.17-pre8) and probably earlier kernels as well....
> 
> the southbridge/usb controler is the VIA Technologies, Inc. VT82C686b chip as you can see in 

Seems to be a lot of stuff where the pci routing and Linux isnt getting on
when it comes to VIA and USB. Dunno if its wrong BIOS tables but the
following previous patch might help you

Let Manfred and co know if it does

Alan


>From manfred@colorfullife.com Sun Nov 04 22:07:34 2001
To: Alan Cox <alan@lxorguk.ukuu.org.uk>
CC: jgarzik@mandrakesoft.com
Subject: pci-irq.c
Status: RO

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


--- 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]++;


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: USB + PCI - IRQ = kernel bug??
  2001-12-11 12:49 ` Alan Cox
@ 2001-12-11 21:00   ` Jonathan Stanford
  0 siblings, 0 replies; 5+ messages in thread
From: Jonathan Stanford @ 2001-12-11 21:00 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel, manfred, Pete Zaitcev

Looks like this patch did the trick guys!
Thanks!

(patch was applied to 2.4.17-pre8)

-Jonathan Stanford


Alan Cox wrote:

>>this problem appears on everything from 2.4.7 (RH7.2 kern)  to the 
>>latest and greatest (2.4.17-pre8) and probably earlier kernels as well....
>>
>>the southbridge/usb controler is the VIA Technologies, Inc. VT82C686b chip as you can see in 
>>
>
>Seems to be a lot of stuff where the pci routing and Linux isnt getting on
>when it comes to VIA and USB. Dunno if its wrong BIOS tables but the
>following previous patch might help you
>
>Let Manfred and co know if it does
>
>Alan
>
>
>>From manfred@colorfullife.com Sun Nov 04 22:07:34 2001
>To: Alan Cox <alan@lxorguk.ukuu.org.uk>
>CC: jgarzik@mandrakesoft.com
>Subject: pci-irq.c
>Status: RO
>
>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
>
>
>--- 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]++;
>
>




^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2001-12-11 20:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-12-11  3:29 USB + PCI - IRQ = kernel bug?? Jonathan Stanford
2001-12-11 12:49 ` Alan Cox
2001-12-11 21:00   ` Jonathan Stanford
     [not found] <mailman.1008041221.4721.linux-kernel2news@redhat.com>
2001-12-11  3:42 ` Pete Zaitcev
2001-12-11  4:01   ` Jonathan Stanford

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox