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
- Lines: 134
- Date:
2003-06-13 07:51:32.000000000 -0700
- Orig file:
linux-2.4.20/arch/ppc64/kernel/pci.c
- Orig date:
2002-11-28 15:53:11.000000000 -0800
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)