Subject: port-macppc/26341: some cards in pci1 ( behind a PCI-PCI bridge ) in S900 boxes don't get an IRQ assigned
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <macallan18@earthlink.net>
List: netbsd-bugs
Date: 07/15/2004 20:45:43
>Number:         26341
>Category:       port-macppc
>Synopsis:       some cards in pci1 ( behind a PCI-PCI bridge ) in S900 boxes don't get an IRQ assigned
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-macppc-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jul 15 23:10:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Michael Loreny
>Release:        2.0G
>Organization:
>Environment:
NetBSD Macallan 2.0G NetBSD 2.0G (MACALLAN) #66: Thu Jul 15 18:29:54 EDT 2004  ml@Macallan:/usr/src/sys/arch/macppc/compile/MACALLAN macppc

>Description:
Some cards - in my case a yds and a ohci card - don't get an interrupt
assigned when plugged into one of the lower 4 PCI slots of a UMAX S900.
These slots are controlled by a PCI-PCI bridge. 
They worked fine in 1.6.2 so I compared the code in question and added
support for the configuration method used in 1.6.2 as a fallback which 
leads to all cards in pci1 sharing the same interrupt - inherited from
the bridge - but it seems to work fine.
>How-To-Repeat:
plug a few PCI cards that need interrupts into the lower 4 PCI slots of a S900
>Fix:
Index: src/sys/arch/macppc/pci/pci_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/pci/pci_machdep.c,v
retrieving revision 1.25
diff --context -r1.25 pci_machdep.c
*** src/sys/arch/macppc/pci/pci_machdep.c       8 Apr 2004 23:58:24 -0000       
1.25
--- src/sys/arch/macppc/pci/pci_machdep.c       15 Jul 2004 22:54:17 -0000
***************
*** 369,375 ****
--- 388,406 ----
                        intr &= ~PCI_INTERRUPT_LINE_MASK;
                        intr |= irqs[0] & PCI_INTERRUPT_LINE_MASK;
                        pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr);
+               } else
+               {
+               #ifdef DEBUG_PCI
+                       printf("fixing interrupt...\n");
+               #endif
+                       if(find_node_intr(node, &addr[0].phys_hi, irqs) == -1)
+                               continue;
+                       intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
+                       intr &= ~PCI_INTERRUPT_LINE_MASK;
+                       intr |= irqs[0] & PCI_INTERRUPT_LINE_MASK;
+                       pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr);       
                }
+                       
        }
  }

>Release-Note:
>Audit-Trail:
>Unformatted: