]> xenbits.xensource.com Git - xenclient/kernel.git/commitdiff
imported patch pci-ignore disable-free_init_pages-on-x86_64.patch
authort_jeang <devnull@localhost>
Tue, 6 Jan 2009 12:05:56 +0000 (12:05 +0000)
committert_jeang <devnull@localhost>
Tue, 6 Jan 2009 12:05:56 +0000 (12:05 +0000)
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/probe.c

index 619f6224f80b69ad438f6ad7c7bc321e69b644b9..8810a69a6c5ae2093302825d0decb93a3d87d3c2 100644 (file)
@@ -21,6 +21,9 @@
 
 unsigned int pci_pm_d3_delay = 10;
 
+struct pci_ignore pci_ignore_list[512] __devinit = {{-1,-1,-1},};
+int pci_ignore_count __devinit = 0;
+
 /**
  * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
  * @bus: pointer to PCI bus structure to search
@@ -1376,6 +1379,33 @@ static int __devinit pci_init(void)
        return 0;
 }
 
+static int __devinit pci_ignore(char *str)
+{
+       unsigned int bus = -1u, dev = -1u, fn = -1u;
+       int fields;
+
+       fields = sscanf(str, "ignore-%x-%x-%x", &bus, &dev, &fn);
+       if (fields < 1 || fields > 3) 
+               return 0;
+
+       if (pci_ignore_count >= 512) 
+               return 0;
+
+       printk(KERN_INFO "PCI: Ignoring %2.2x", bus);
+       if (dev != -1u)
+               printk(".%2.2x", dev);
+       if (fn != -1u)
+               printk(".%2.2x", dev);
+       printk("\n");
+
+       pci_ignore_list[pci_ignore_count].bus = bus;
+       pci_ignore_list[pci_ignore_count].dev = dev;
+       pci_ignore_list[pci_ignore_count].fn = fn;
+       pci_ignore_count++;
+
+       return 1;
+}
+
 static int __devinit pci_setup(char *str)
 {
        while (str) {
@@ -1385,7 +1415,7 @@ static int __devinit pci_setup(char *str)
                if (*str && (str = pcibios_setup(str)) && *str) {
                        if (!strcmp(str, "nomsi")) {
                                pci_no_msi();
-                       } else {
+                       } else if (!pci_ignore(str)) {
                                printk(KERN_ERR "PCI: Unknown option `%s'\n",
                                                str);
                        }
index 2bfea99997238f2a05d0dc45fd2e5f1a2de36b0d..c5312646aeb2687976a4377655e523f7d5383f05 100644 (file)
@@ -100,3 +100,28 @@ pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
        return NULL;
 }
 
+/* Linked list of pci bus/dev/fn combinations not to touch */
+struct pci_ignore {
+       unsigned int bus, dev, fn; /* what to ignore; -1u means wildcard */
+};
+
+extern struct pci_ignore pci_ignore_list[] __devinit;;
+extern int pci_ignore_count __devinit;
+
+static inline int __devinit pci_ignore_chk(unsigned int bus, 
+                                          unsigned int dev, 
+                                          unsigned int fn)
+{
+       int i;
+       struct pci_ignore *ig = pci_ignore_list;
+       for (i = 0; i < pci_ignore_count; i++)
+               if (ig[i].bus == bus 
+                   && (ig[i].dev == dev || ig[i].dev == -1u)
+                   && (ig[i].fn == fn || ig[i].fn == -1u))
+                       return 1;
+       return 0;
+}
+
+#define pci_ignore_bus(_b)     pci_ignore_chk((_b), -1u, -1u)
+#define pci_ignore_dev(_b, _d) pci_ignore_chk((_b), (_d), -1u)
+#define pci_ignore_fn(_b, _f)  pci_ignore_chk((_b), PCI_SLOT(_f), PCI_FUNC(_f))
index d409acac85191c2a04d742c8bb4829da7ea64aee..9006ef00f4d7ea9d77f30f1c6fe6813daf0ee32e 100644 (file)
@@ -786,6 +786,13 @@ pci_scan_device(struct pci_bus *bus, int devfn)
        u8 hdr_type;
        int delay = 1;
 
+       if (pci_ignore_fn(bus->number, devfn)) {
+               pr_debug("PCI: skipping dev/fn %04x:%02x:%02x:%02x\n",
+                        pci_domain_nr(bus), bus->number,
+                        PCI_SLOT(devfn), PCI_SLOT(devfn));
+               return NULL;
+       }
+
        if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l))
                return NULL;
 
@@ -891,6 +898,12 @@ int __devinit pci_scan_slot(struct pci_bus *bus, int devfn)
        int func, nr = 0;
        int scan_all_fns;
 
+       if (pci_ignore_dev(bus->number, PCI_SLOT(devfn))) {
+               pr_debug("PCI: skipping dev %04x:%02x:%02x\n",
+                        pci_domain_nr(bus), bus->number, PCI_SLOT(devfn));
+               return nr;
+       }
+
        scan_all_fns = pcibios_scan_all_fns(bus, devfn);
 
        for (func = 0; func < 8; func++, devfn++) {
@@ -929,6 +942,12 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
         */
        pcibios_fix_bus_scan_quirk(bus);
 
+       if (pci_ignore_bus(bus->number)) {
+               pr_debug("PCI: skipping bus %04x:%02x\n",
+                        pci_domain_nr(bus), bus->number);
+               return max;
+       }
+
        pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(bus), bus->number);
 
        /* Go find them, Rover! */