Re: Problem with New PCI IRQ routing code for pre9-2

From: Martin Mares (mj@suse.cz)
Date: Fri May 19 2000 - 04:56:50 EST


Hello!

> After our discussion regarding the IRQ being assigned to for my USB to be the
> same as the sound card, I tried this patch.
>
> Kernel version 99pre3 + pci patch
>
> Previously we got the correct IRQ assigned to the USB controller with Pre7 by
> adding pci-irqmask=0xff00
>
> Now what happens is lspci shows 0 with and without this option on boot.
>
> However when usb-uhci is loaded, it detects IRQ 6, without the pci= option, and
> irq 9 with it.

   This looks well, although it should better have avoided IRQ 6 since it's
used by the floppy controller. Here is an update to the yesterday's patch which
penalizes IRQ 6 and avoids "common ISA use" penalties for IRQ's which were
already assigned to PCI devices by the BIOS. Using the `pci=irqmask=...' switch
should be no longer necessary unless you have ISA cards && your BIOS doesn't
allow to set the PCI exclusive IRQ mask.

diff -uN /tmp/z/arch/i386/kernel/pci-irq.c arch/i386/kernel/pci-irq.c
--- /tmp/z/arch/i386/kernel/pci-irq.c Fri May 19 11:42:00 2000
+++ arch/i386/kernel/pci-irq.c Fri May 19 11:30:53 2000
@@ -27,12 +27,12 @@
 /*
  * Never use: 0, 1, 2 (timer, keyboard, and cascade)
  * Avoid using: 13, 14 and 15 (FP error and IDE).
- * Penalize: 3, 4, 7, 12 (known ISA uses: serial, parallel and mouse)
+ * Penalize: 3, 4, 6, 7, 12 (known ISA uses: serial, floppy, parallel and mouse)
  */
 unsigned int pcibios_irq_mask = 0xfff8;
 
-static unsigned pirq_penalty[16] = {
- 1000000, 1000000, 1000000, 1000, 1000, 0, 0, 1000,
+static int pirq_penalty[16] = {
+ 1000000, 1000000, 1000000, 1000, 1000, 0, 1000, 1000,
         0, 0, 0, 0, 1000, 100000, 100000, 100000
 };
 
@@ -415,6 +415,9 @@
                         DBG("%s: ignoring bogus IRQ %d\n", dev->slot_name, dev->irq);
                         dev->irq = 0;
                 }
+ /* If the IRQ is already assigned to a PCI device, ignore its ISA use penalty */
+ if (pirq_penalty[dev->irq] >= 100 && pirq_penalty[dev->irq] < 100000)
+ pirq_penalty[dev->irq] = 0;
                 pirq_penalty[dev->irq]++;
         }
 

> uhci refuses to load in both cases, compaining of IRQ not set.

It's a bug in the uhci driver -- it checks whether dev->irq is non-zero before
it gives pci_enable_device() a chance to assign it. Here is a patch which should
fix this problem in both uhci and usb-ohci.

To Randy: Should I send such patches to the HC maintainers or to you?

--- drivers/usb/uhci.c.mj Fri May 19 11:29:53 2000
+++ drivers/usb/uhci.c Fri May 19 11:35:20 2000
@@ -2325,30 +2325,29 @@
 {
         int i;
 
+ /* disable legacy emulation */
+ pci_write_config_word(dev, USBLEGSUP, USBLEGSUP_DEFAULT);
+
+ if (pci_enable_device(dev) < 0)
+ return -1;
+
+ if (!dev->irq) {
+ err("found UHCI device with no IRQ assigned. check BIOS settings!");
+ return -1;
+ }
+
         /* Search for the IO base address.. */
         for (i = 0; i < 6; i++) {
- unsigned int io_addr = dev->resource[i].start;
- unsigned int io_size =
- dev->resource[i].end - dev->resource[i].start + 1;
+ unsigned int io_addr = pci_resource_start(dev, i);
+ unsigned int io_size = pci_resource_len(dev, i);
 
                 /* IO address? */
- if (!(dev->resource[i].flags & IORESOURCE_IO))
+ if (!(pci_resource_flags(dev, i) & IORESOURCE_IO))
                         continue;
 
                 /* Is it already in use? */
                 if (check_region(io_addr, io_size))
                         break;
-
- if (!dev->irq) {
- err("found UHCI device with no IRQ assigned. check BIOS settings!");
- continue;
- }
-
- /* disable legacy emulation */
- pci_write_config_word(dev, USBLEGSUP, USBLEGSUP_DEFAULT);
-
- if (pci_enable_device(dev) < 0)
- continue;
 
                 return setup_uhci(dev, dev->irq, io_addr, io_size);
         }
--- drivers/usb/usb-ohci.c.mj Fri May 19 11:33:06 2000
+++ drivers/usb/usb-ohci.c Fri May 19 11:33:06 2000
@@ -1936,11 +1936,11 @@
 {
         unsigned long mem_base;
 
- mem_base = dev->resource[0].start;
         if (pci_enable_device(dev) < 0)
                 return -ENODEV;
         
         pci_set_master (dev);
+ mem_base = dev->resource[0].start;
         mem_base = (unsigned long) ioremap_nocache (mem_base, 4096);
 
         if (!mem_base) {

                                Have a nice fortnight

-- 
Martin `MJ' Mares <mj@ucw.cz> <mj@suse.cz> http://atrey.karlin.mff.cuni.cz/~mj/
"People disagree with me.  I just ignore them." -- Linus Torvalds

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



This archive was generated by hypermail 2b29 : Tue May 23 2000 - 21:00:17 EST