patch-2.4.21 linux-2.4.21/arch/alpha/kernel/pci.c

Next file: linux-2.4.21/arch/alpha/kernel/pci_impl.h
Previous file: linux-2.4.21/arch/alpha/kernel/osf_sys.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.20/arch/alpha/kernel/pci.c linux-2.4.21/arch/alpha/kernel/pci.c
@@ -41,6 +41,8 @@
 
 const char pci_hae0_name[] = "HAE0";
 
+/* Indicate whether we respect the PCI setup left by console. */
+int __initdata pci_probe_only;
 
 /*
  * The PCI controller list.
@@ -66,17 +68,6 @@
 }
 
 static void __init
-quirk_ali_ide_ports(struct pci_dev *dev)
-{
-	if (dev->resource[0].end == 0xffff)
-		dev->resource[0].end = dev->resource[0].start + 7;
-	if (dev->resource[2].end == 0xffff)
-		dev->resource[2].end = dev->resource[2].start + 7;
-	if (dev->resource[3].end == 0xffff)
-		dev->resource[3].end = dev->resource[3].start + 7;
-}
-
-static void __init
 quirk_cypress(struct pci_dev *dev)
 {
 	/* The Notorious Cy82C693 chip.  */
@@ -114,8 +105,6 @@
 	  quirk_eisa_bridge },
 	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378,
 	  quirk_isa_bridge },
-	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229,
-	  quirk_ali_ide_ports },
 	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693,
 	  quirk_cypress },
 	{ 0 }
@@ -243,10 +232,25 @@
 	struct pci_dev *dev = bus->self;
 
 	if (!dev) {
-		/* Root bus */
+		/* Root bus. */
+		u32 pci_mem_end;
+		u32 sg_base = hose->sg_pci ? hose->sg_pci->dma_base : ~0;
+		unsigned long end;
+
 		bus->resource[0] = hose->io_space;
 		bus->resource[1] = hose->mem_space;
-	}
+
+		/* Adjust hose mem_space limit to prevent PCI allocations
+		   in the iommu windows. */
+		pci_mem_end = min((u32)__direct_map_base, sg_base) - 1;
+		end = hose->mem_space->start + pci_mem_end;
+		if (hose->mem_space->end > end)
+			hose->mem_space->end = end;
+ 	} else if (pci_probe_only &&
+ 		   (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+ 		pci_read_bridge_bases(bus);
+ 		pcibios_fixup_device_resources(dev, bus);
+	} 
 
 	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
 		struct pci_dev *dev = pci_dev_b(ln);
@@ -311,7 +315,7 @@
 			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
 			/* Move up the chain of bridges. */
 			dev = dev->bus->self;
-		} while (dev->bus->self);
+		} while (dev->bus->parent);
 		*pinp = pin;
 
 		/* The slot is the slot of the last bridge. */
@@ -359,6 +363,40 @@
 	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
 }
 
+static void __init
+pcibios_claim_one_bus(struct pci_bus *b)
+{
+	struct list_head *ld;
+	struct pci_bus *child_bus;
+
+	for (ld = b->devices.next; ld != &b->devices; ld = ld->next) {
+		struct pci_dev *dev = pci_dev_b(ld);
+		int i;
+
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			struct resource *r = &dev->resource[i];
+
+			if (r->parent || !r->start || !r->flags)
+				continue;
+			pci_claim_resource(dev, i);
+		}
+	}
+
+	list_for_each_entry(child_bus, &b->children, node)
+		pcibios_claim_one_bus(child_bus);
+}
+
+static void __init
+pcibios_claim_console_setup(void)
+{
+	struct list_head *lb;
+
+	for(lb = pci_root_buses.next; lb != &pci_root_buses; lb = lb->next) {
+		struct pci_bus *b = pci_bus_b(lb);
+		pcibios_claim_one_bus(b);
+	}
+}
+
 void __init
 common_init_pci(void)
 {
@@ -376,7 +414,12 @@
 		next_busno += 1;
 	}
 
-	pci_assign_unassigned_resources();
+	if (pci_probe_only)
+		pcibios_claim_console_setup();
+	else	/* FIXME: `else' will be removed when
+		   pci_assign_unassigned_resources() is able to work
+		   correctly with [partially] allocated PCI tree. */
+		pci_assign_unassigned_resources();
 	pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)