patch-2.4.5 linux/arch/sparc64/kernel/pci_sabre.c

Next file: linux/arch/sparc64/kernel/pci_schizo.c
Previous file: linux/arch/sparc64/kernel/pci_psycho.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/kernel/pci_sabre.c linux/arch/sparc64/kernel/pci_sabre.c
@@ -1,4 +1,4 @@
-/* $Id: pci_sabre.c,v 1.27 2001/04/24 05:14:12 davem Exp $
+/* $Id: pci_sabre.c,v 1.32 2001/05/15 11:10:01 davem Exp $
  * pci_sabre.c: Sabre specific PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -215,7 +215,7 @@
 	 ((unsigned long)(DEVFN) << 8)  |	\
 	 ((unsigned long)(REG)))
 
-static int apb_present;
+static int hummingbird_p;
 
 static void *sabre_pci_config_mkaddr(struct pci_pbm_info *pbm,
 				     unsigned char bus,
@@ -231,7 +231,7 @@
 
 static int sabre_out_of_range(unsigned char devfn)
 {
-	if (!apb_present)
+	if (hummingbird_p)
 		return 0;
 
 	return (((PCI_SLOT(devfn) == 0) && (PCI_FUNC(devfn) > 0)) ||
@@ -243,7 +243,7 @@
 				unsigned char bus,
 				unsigned char devfn)
 {
-	if (!apb_present)
+	if (hummingbird_p)
 		return 0;
 
 	return ((pbm->parent == 0) ||
@@ -1112,11 +1112,28 @@
 	}
 }
 
+static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm)
+{
+	struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
+
+	if (!cookie) {
+		prom_printf("SABRE: Critical allocation failure.\n");
+		prom_halt();
+	}
+
+	/* All we care about is the PBM. */
+	memset(cookie, 0, sizeof(*cookie));
+	cookie->pbm = pbm;
+
+	return cookie;
+}
+
 static void __init sabre_scan_bus(struct pci_controller_info *p)
 {
 	static int once = 0;
 	struct pci_bus *sabre_bus;
 	struct pci_pbm_info *pbm;
+	struct pcidev_cookie *cookie;
 	struct list_head *walk;
 	int sabres_scanned;
 
@@ -1142,10 +1159,15 @@
 	}
 	once++;
 
+	cookie = alloc_bridge_cookie(&p->pbm_A);
+
 	/* The pci_bus2pbm table has already been setup in sabre_init. */
 	sabre_bus = pci_scan_bus(p->pci_first_busno,
 				 p->pci_ops,
 				 &p->pbm_A);
+	pci_fixup_host_bridge_self(sabre_bus);
+	sabre_bus->self->sysdata = cookie;
+
 	apb_init(p, sabre_bus);
 
 	sabres_scanned = 0;
@@ -1161,6 +1183,9 @@
 		} else
 			continue;
 
+		cookie = alloc_bridge_cookie(pbm);
+		pbus->self->sysdata = cookie;
+
 		sabres_scanned++;
 
 		pbus->sysdata = pbm;
@@ -1444,6 +1469,11 @@
 			memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
 		}
 
+
+		sprintf(pbm->name, "SABRE%d PBM%c", p->index,
+			(pbm == &p->pbm_A ? 'A' : 'B'));
+		pbm->io_space.name = pbm->mem_space.name = pbm->name;
+
 		/* Hack up top-level resources. */
 		pbm->io_space.start = p->controller_regs + SABRE_IOSPACE;
 		pbm->io_space.end   = pbm->io_space.start + (1UL << 16) - 1UL;
@@ -1461,12 +1491,10 @@
 			prom_printf("Cannot register Hummingbird's MEM space.\n");
 			prom_halt();
 		}
-	} else {
-		apb_present = 1;
 	}
 }
 
-void __init sabre_init(int pnode)
+void __init sabre_init(int pnode, char *model_name)
 {
 	struct linux_prom64_registers pr_regs[2];
 	struct pci_controller_info *p;
@@ -1478,6 +1506,18 @@
 	u32 upa_portid, dma_mask;
 	int bus;
 
+	hummingbird_p = 0;
+	if (!strcmp(model_name, "pci108e,a001"))
+		hummingbird_p = 1;
+	else if (!strcmp(model_name, "SUNW,sabre")) {
+		char compat[64];
+
+		if (prom_getproperty(pnode, "compatible",
+				     compat, sizeof(compat)) > 0 &&
+		    !strcmp(compat, "pci108e,a001"))
+			hummingbird_p = 1;
+	}
+
 	p = kmalloc(sizeof(*p), GFP_ATOMIC);
 	if (!p) {
 		prom_printf("SABRE: Error, kmalloc(pci_controller_info) failed.\n");
@@ -1502,6 +1542,7 @@
 
 	p->portid = upa_portid;
 	p->index = pci_num_controllers++;
+	p->pbms_same_domain = 1;
 	p->scan_bus = sabre_scan_bus;
 	p->irq_build = sabre_irq_build;
 	p->base_address_update = sabre_base_address_update;

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