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

Next file: linux-2.4.21/arch/ppc64/kernel/pci.h
Previous file: linux-2.4.21/arch/ppc64/kernel/pacaData.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.20/arch/ppc64/kernel/pci.c linux-2.4.21/arch/ppc64/kernel/pci.c
@@ -1,6 +1,4 @@
 /*
- * 
- *
  * Port for PPC64 David Engebretsen, IBM Corp.
  *   Contains common pci routines for ppc64 platform, pSeries and iSeries brands. 
  * 
@@ -33,7 +31,6 @@
 #include <asm/naca.h>
 #include <asm/pci_dma.h>
 #include <asm/machdep.h>
-#include <asm/eeh.h>
 
 #include "pci.h"
 
@@ -123,12 +120,48 @@
 }
 
 
+/* Given an mmio phys address, find a pci device that implements
+ * this address.  This is of course expensive, but only used
+ * for device initialization or error paths.
+ * For io BARs it is assumed the pci_io_base has already been added
+ * into addr.
+ *
+ * Bridges are ignored although they could be used to optimize the search.
+ */
+struct pci_dev *pci_find_dev_by_addr(unsigned long addr)
+{
+	struct pci_dev *dev;
+	int i;
+	unsigned long ioaddr;
+
+	ioaddr = (addr > _IO_BASE) ? addr - _IO_BASE : 0;
+
+	pci_for_each_dev(dev) {
+		if ((dev->class >> 8) == PCI_BASE_CLASS_BRIDGE)
+			continue;
+		for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+			unsigned long start = pci_resource_start(dev,i);
+			unsigned long end = pci_resource_end(dev,i);
+			unsigned int flags = pci_resource_flags(dev,i);
+			if (start == 0 || ~start == 0 ||
+			    end == 0 || ~end == 0)
+				continue;
+			if ((flags & IORESOURCE_IO) &&
+			    (ioaddr >= start && ioaddr <= end))
+				return dev;
+			else if ((flags & IORESOURCE_MEM) &&
+				 (addr >= start && addr <= end))
+				return dev;
+		}
+	}
+	return NULL;
+}
+
 void pcibios_fixup_pbus_ranges(struct pci_bus *pbus,
 				struct pbus_set_ranges_data *pranges)
 {
 }
 
-
 void
 pcibios_update_resource(struct pci_dev *dev, struct resource *root,
 			     struct resource *res, int resource)
@@ -182,6 +215,7 @@
 void
 pcibios_align_resource(void *data, struct resource *res, unsigned long size,
 		       unsigned long align)
+
 {
 	struct pci_dev *dev = data;
 
@@ -200,7 +234,6 @@
 	}
 }
 
-
 /*
  *  Handle resources of PCI devices.  If the world were perfect, we could
  *  just allocate all the resource regions and do nothing more.  It isn't.
@@ -409,8 +442,10 @@
                 return NULL;
         }
         memset(hose, 0, sizeof(struct pci_controller));
-        if(strlen(model) < 8) strcpy(hose->what,model);
-        else                  memcpy(hose->what,model,7);
+        if(strlen(model) < 8)
+		strcpy(hose->what,model);
+        else
+		memcpy(hose->what,model,7);
         hose->type = controller_type;
         hose->global_number = global_phb_number;
 	phbtab[global_phb_number++] = hose;
@@ -469,7 +504,7 @@
 			next_busno = hose->last_busno+1;
 	}
 	pci_bus_count = next_busno;
-		
+
 	/* Call machine dependant fixup */
 	if (ppc_md.pcibios_fixup) {
 		ppc_md.pcibios_fixup();
@@ -549,21 +584,15 @@
 				/* Transparent resource -- don't try to "fix" it. */
 				continue;
 			}
-			if (is_eeh_implemented()) {
-				if (res->flags & (IORESOURCE_IO|IORESOURCE_MEM)) {
-					res->start = eeh_token(phb->global_number, bus->number, 0, 0);
-					res->end = eeh_token(phb->global_number, bus->number, 0xff, 0xffffffff);
-				}
-			} else {
-				if (res->flags & IORESOURCE_IO) {
-					res->start += (unsigned long)phb->io_base_virt;
-					res->end += (unsigned long)phb->io_base_virt;
-				} else if (phb->pci_mem_offset
-					   && (res->flags & IORESOURCE_MEM)) {
-					if (res->start < phb->pci_mem_offset) {
-						res->start += phb->pci_mem_offset;
-						res->end += phb->pci_mem_offset;
-					}
+			if (res->flags & IORESOURCE_IO) {
+				unsigned long offset = (unsigned long)phb->io_base_virt - pci_io_base;
+				res->start += offset;
+				res->end += offset;
+			} else if (phb->pci_mem_offset
+				   && (res->flags & IORESOURCE_MEM)) {
+				if (res->start < phb->pci_mem_offset) {
+					res->start += phb->pci_mem_offset;
+					res->end += phb->pci_mem_offset;
 				}
 			}
 		}

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