From: t_jeang Date: Tue, 6 Jan 2009 12:05:56 +0000 (+0000) Subject: imported patch pci-ignore X-Git-Tag: disable-free_init_pages-on-x86_64.patch X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=6a8a3b860cc11a505086741cd91557e6b62d0d28;p=xenclient%2Fkernel.git imported patch pci-ignore --- diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 619f6224..8810a69a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -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); } diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 2bfea999..c5312646 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -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)) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index d409acac..9006ef00 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -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! */