]> err.no Git - linux-2.6/blobdiff - arch/x86/pci/common.c
Merge branch 'for-2.6.26' of master.kernel.org:/pub/scm/linux/kernel/git/jwboyer...
[linux-2.6] / arch / x86 / pci / common.c
index 52deabc72a6facaf7975436a7bba1cf5c99d403f..2a4d751818b731fd1ae0007ed2f1f9a94cdf12d1 100644 (file)
@@ -26,16 +26,37 @@ int pcibios_last_bus = -1;
 unsigned long pirq_table_addr;
 struct pci_bus *pci_root_bus;
 struct pci_raw_ops *raw_pci_ops;
+struct pci_raw_ops *raw_pci_ext_ops;
+
+int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
+                                               int reg, int len, u32 *val)
+{
+       if (reg < 256 && raw_pci_ops)
+               return raw_pci_ops->read(domain, bus, devfn, reg, len, val);
+       if (raw_pci_ext_ops)
+               return raw_pci_ext_ops->read(domain, bus, devfn, reg, len, val);
+       return -EINVAL;
+}
+
+int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
+                                               int reg, int len, u32 val)
+{
+       if (reg < 256 && raw_pci_ops)
+               return raw_pci_ops->write(domain, bus, devfn, reg, len, val);
+       if (raw_pci_ext_ops)
+               return raw_pci_ext_ops->write(domain, bus, devfn, reg, len, val);
+       return -EINVAL;
+}
 
 static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
 {
-       return raw_pci_ops->read(pci_domain_nr(bus), bus->number,
+       return raw_pci_read(pci_domain_nr(bus), bus->number,
                                 devfn, where, size, value);
 }
 
 static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
 {
-       return raw_pci_ops->write(pci_domain_nr(bus), bus->number,
+       return raw_pci_write(pci_domain_nr(bus), bus->number,
                                  devfn, where, size, value);
 }
 
@@ -56,59 +77,6 @@ int pcibios_scanned;
  */
 DEFINE_SPINLOCK(pci_config_lock);
 
-/*
- * Several buggy motherboards address only 16 devices and mirror
- * them to next 16 IDs. We try to detect this `feature' on all
- * primary buses (those containing host bridges as they are
- * expected to be unique) and remove the ghost devices.
- */
-
-static void __devinit pcibios_fixup_ghosts(struct pci_bus *b)
-{
-       struct list_head *ln, *mn;
-       struct pci_dev *d, *e;
-       int mirror = PCI_DEVFN(16,0);
-       int seen_host_bridge = 0;
-       int i;
-
-       DBG("PCI: Scanning for ghost devices on bus %d\n", b->number);
-       list_for_each(ln, &b->devices) {
-               d = pci_dev_b(ln);
-               if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST)
-                       seen_host_bridge++;
-               for (mn=ln->next; mn != &b->devices; mn=mn->next) {
-                       e = pci_dev_b(mn);
-                       if (e->devfn != d->devfn + mirror ||
-                           e->vendor != d->vendor ||
-                           e->device != d->device ||
-                           e->class != d->class)
-                               continue;
-                       for(i=0; i<PCI_NUM_RESOURCES; i++)
-                               if (e->resource[i].start != d->resource[i].start ||
-                                   e->resource[i].end != d->resource[i].end ||
-                                   e->resource[i].flags != d->resource[i].flags)
-                                       continue;
-                       break;
-               }
-               if (mn == &b->devices)
-                       return;
-       }
-       if (!seen_host_bridge)
-               return;
-       printk(KERN_WARNING "PCI: Ignoring ghost devices on bus %02x\n", b->number);
-
-       ln = &b->devices;
-       while (ln->next != &b->devices) {
-               d = pci_dev_b(ln->next);
-               if (d->devfn >= mirror) {
-                       list_del(&d->global_list);
-                       list_del(&d->bus_list);
-                       kfree(d);
-               } else
-                       ln = ln->next;
-       }
-}
-
 static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
 {
        struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
@@ -131,7 +99,6 @@ void __devinit  pcibios_fixup_bus(struct pci_bus *b)
 {
        struct pci_dev *dev;
 
-       pcibios_fixup_ghosts(b);
        pci_read_bridge_bases(b);
        list_for_each_entry(dev, &b->devices, bus_list)
                pcibios_fixup_device_resources(dev);
@@ -375,9 +342,14 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
                return NULL;
        }
 
+       sd->node = get_mp_bus_to_node(busnum);
+
        printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
+       bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd);
+       if (!bus)
+               kfree(sd);
 
-       return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd);
+       return bus;
 }
 
 extern u8 pci_cache_line_size;
@@ -406,10 +378,6 @@ static int __init pcibios_init(void)
 
        if (pci_bf_sort >= pci_force_bf)
                pci_sort_breadthfirst();
-#ifdef CONFIG_PCI_BIOS
-       if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
-               pcibios_sort();
-#endif
        return 0;
 }
 
@@ -434,9 +402,6 @@ char * __devinit  pcibios_setup(char *str)
        } else if (!strcmp(str, "nobios")) {
                pci_probe &= ~PCI_PROBE_BIOS;
                return NULL;
-       } else if (!strcmp(str, "nosort")) {
-               pci_probe |= PCI_NO_SORT;
-               return NULL;
        } else if (!strcmp(str, "biosirq")) {
                pci_probe |= PCI_BIOS_IRQ_SCAN;
                return NULL;
@@ -460,6 +425,10 @@ char * __devinit  pcibios_setup(char *str)
                pci_probe &= ~PCI_PROBE_MMCONF;
                return NULL;
        }
+       else if (!strcmp(str, "check_enable_amd_mmconf")) {
+               pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF;
+               return NULL;
+       }
 #endif
        else if (!strcmp(str, "noacpi")) {
                acpi_noirq_set();
@@ -506,7 +475,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
        int err;
 
-       if ((err = pcibios_enable_resources(dev, mask)) < 0)
+       if ((err = pci_enable_resources(dev, mask)) < 0)
                return err;
 
        if (!dev->msi_enabled)
@@ -520,7 +489,7 @@ void pcibios_disable_device (struct pci_dev *dev)
                pcibios_disable_irq(dev);
 }
 
-struct pci_bus *pci_scan_bus_with_sysdata(int busno)
+struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node)
 {
        struct pci_bus *bus = NULL;
        struct pci_sysdata *sd;
@@ -535,10 +504,15 @@ struct pci_bus *pci_scan_bus_with_sysdata(int busno)
                printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busno);
                return NULL;
        }
-       sd->node = -1;
-       bus = pci_scan_bus(busno, &pci_root_ops, sd);
+       sd->node = node;
+       bus = pci_scan_bus(busno, ops, sd);
        if (!bus)
                kfree(sd);
 
        return bus;
 }
+
+struct pci_bus *pci_scan_bus_with_sysdata(int busno)
+{
+       return pci_scan_bus_on_node(busno, &pci_root_ops, -1);
+}