Skip to contentSkip to conversation

pci_child_fixup()

PATCH William Lee Irwin III 2 participants 3 messages Jan 20, 2003 PCI

lore
Share & tools
lore
#0 lore raw

Adds a fresh pci_fixup_child() hook for physical bus numbers in bus number registers that don't match the bus numbers in the MP tables. It basically allows for arbitrary bus number twiddling for children.

vs. 2.5.59-mm1

 arch/i386/pci/numa.c   |    9 +++++++++
 drivers/pci/probe.c    |    5 +----
 include/asm-i386/pci.h |   11 +++++++++++
 3 files changed, 21 insertions(+), 4 deletions(-)
arch/i386/pci/numa.c +9 -0
diff -urpN mpc-2.5.59-1/arch/i386/pci/numa.c mpc-2.5.59-2/arch/i386/pci/numa.c
@@ -88,6 +88,15 @@ static struct pci_ops pci_direct_conf1_m
 	.write	= pci_conf1_mq_write
 };
 
+void pci_child_fixup(struct pci_bus *parent, struct pci_bus *child, int buses)
+{
+	int quad = BUS2QUAD(parent->number);
+	child->primary		= QUADLOCAL2BUS(quad, buses         & 0xFF);
+	child->secondary	= QUADLOCAL2BUS(quad, (buses >> 8)  & 0xFF);
+	child->subordinate	= QUADLOCAL2BUS(quad, (buses >> 16) & 0xFF);
+	child->number		= child->secondary;
+}
+
 
 static void __devinit pci_fixup_i450nx(struct pci_dev *d)
 {
drivers/pci/probe.c +1 -4
diff -urpN mpc-2.5.59-1/drivers/pci/probe.c mpc-2.5.59-2/drivers/pci/probe.c
@@ -271,10 +271,7 @@ int __devinit pci_scan_bridge(struct pci
 		if (pass)
 			return max;
 		child = pci_add_new_bus(bus, dev, 0);
-		child->primary = buses & 0xFF;
-		child->secondary = (buses >> 8) & 0xFF;
-		child->subordinate = (buses >> 16) & 0xFF;
-		child->number = child->secondary;
+		pci_child_fixup(bus, child, buses);
 		cmax = pci_do_scan_bus(child);
 		if (cmax > max) max = cmax;
 	} else {
include/asm-i386/pci.h +11 -0
diff -urpN mpc-2.5.59-1/include/asm-i386/pci.h mpc-2.5.59-2/include/asm-i386/pci.h
@@ -100,6 +100,17 @@ static inline int pci_controller_num(str
 extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 			       enum pci_mmap_state mmap_state, int write_combine);
 
+#ifdef CONFIG_X86_NUMAQ
+void pci_child_fixup(struct pci_bus *, struct pci_bus *, int);
+#else
+static inline void pci_child_fixup(struct pci_bus *parent, struct pci_bus *child, int buses)
+{
+	child->primary		= buses & 0xFF;
+	child->secondary	= (buses >> 8) & 0xFF;
+	child->subordinate	= (buses >> 16) & 0xFF;
+	child->number		= child->secondary;
+}
+#endif
 #endif /* __KERNEL__ */
 
 /* implement the pci_ DMA API in terms of the generic device dma_ one */
#1 lore raw

drivers/pci/probe.c int __devinit pci_scan_bridge(struct pci · line 274

Quoted 6 lines · William Lee Irwin III
drivers/pci/probe.c +1 -4
 		child = pci_add_new_bus(bus, dev, 0);
-		child->primary = buses & 0xFF;
-		child->secondary = (buses >> 8) & 0xFF;
-		child->subordinate = (buses >> 16) & 0xFF;
-		child->number = child->secondary;
+		pci_child_fixup(bus, child, buses);

The "bus" argument seems to be redundant. Why not use "child->parent" just filled in by pci_add_new_bus() instead?

Ivan.

#2 lore raw
Quoted 6 lines · William Lee Irwin III
Quoted 6 lines
(quoted diff) +1 -4
 		child = pci_add_new_bus(bus, dev, 0);
-		child->primary = buses & 0xFF;
-		child->secondary = (buses >> 8) & 0xFF;
-		child->subordinate = (buses >> 16) & 0xFF;
-		child->number = child->secondary;
+		pci_child_fixup(bus, child, buses);
Quoted 3 lines · Ivan Kokshaysky

The "bus" argument seems to be redundant. Why not use "child->parent" just filled in by pci_add_new_bus() instead?
Ivan.

Good point. Here's an adjusted patch. I added gregkh to the cc: list in case he's interested (he generally seems to be wrt. PCI).

Thanks,
Bill

The NUMA-Q BIOS reports bus numbers different from the physical ones programmed into PCI-PCI bridges etc. PCI config cycles (and almost everything else) are meant to use translation tables handed to us by the BIOS. No other extant i386 port has such a beast, and there's currently no way to override bus numbers gotten from bus number registers in a meaningful way; bus number conflicts error out prior to any call into arch code. All of the IRQ routing, interrupt assignment, IO-APIC, PCI bus, etc. etc. MP table entries use these numbers, so we're stuck with them.

This provides a fixup hook so it's possible to override the standard interpretation of the bus number registers in PCI-PCI bridges.

 arch/i386/pci/numa.c   |    9 +++++++++
 drivers/pci/probe.c    |    5 +----
 include/asm-i386/pci.h |   11 +++++++++++
 3 files changed, 21 insertions(+), 4 deletions(-)
arch/i386/pci/numa.c +9 -0
diff -urpN mpc-2.5.59-1/arch/i386/pci/numa.c mpc-2.5.59-2/arch/i386/pci/numa.c
@@ -88,6 +88,15 @@ static struct pci_ops pci_direct_conf1_m
 	.write	= pci_conf1_mq_write
 };
 
+void pci_child_fixup(struct pci_bus *child, int buses)
+{
+	int quad = BUS2QUAD(child->parent->number);
+	child->primary		= QUADLOCAL2BUS(quad, buses         & 0xFF);
+	child->secondary	= QUADLOCAL2BUS(quad, (buses >> 8)  & 0xFF);
+	child->subordinate	= QUADLOCAL2BUS(quad, (buses >> 16) & 0xFF);
+	child->number		= child->secondary;
+}
+
 
 static void __devinit pci_fixup_i450nx(struct pci_dev *d)
 {
drivers/pci/probe.c +1 -4
diff -urpN mpc-2.5.59-1/drivers/pci/probe.c mpc-2.5.59-2/drivers/pci/probe.c
@@ -271,10 +271,7 @@ int __devinit pci_scan_bridge(struct pci
 		if (pass)
 			return max;
 		child = pci_add_new_bus(bus, dev, 0);
-		child->primary = buses & 0xFF;
-		child->secondary = (buses >> 8) & 0xFF;
-		child->subordinate = (buses >> 16) & 0xFF;
-		child->number = child->secondary;
+		pci_child_fixup(child, buses);
 		cmax = pci_do_scan_bus(child);
 		if (cmax > max) max = cmax;
 	} else {
include/asm-i386/pci.h +11 -0
diff -urpN mpc-2.5.59-1/include/asm-i386/pci.h mpc-2.5.59-2/include/asm-i386/pci.h
@@ -100,6 +100,17 @@ static inline int pci_controller_num(str
 extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 			       enum pci_mmap_state mmap_state, int write_combine);
 
+#ifdef CONFIG_X86_NUMAQ
+void pci_child_fixup(struct pci_bus *, int);
+#else
+static inline void pci_child_fixup(struct pci_bus *child, int buses)
+{
+	child->primary		= buses & 0xFF;
+	child->secondary	= (buses >> 8) & 0xFF;
+	child->subordinate	= (buses >> 16) & 0xFF;
+	child->number		= child->secondary;
+}
+#endif
 #endif /* __KERNEL__ */
 
 /* implement the pci_ DMA API in terms of the generic device dma_ one */