From: Steven Smith Date: Tue, 30 Jun 2009 11:55:48 +0000 (+0100) Subject: patch pci-ignore X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=f113ad75fe1dad24ee2c29e29b0e88c7218f9dc9;p=people%2Fssmith%2Fnc2-2.6.27.git patch pci-ignore --- diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1964c670..cf0a00cb 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -23,6 +23,9 @@ unsigned int pci_pm_d3_delay = 10; +struct pci_ignore pci_ignore_list[512] __devinitdata = {{-1,-1,-1},}; +int pci_ignore_count __devinitdata = 0; + #ifdef CONFIG_PCI_DOMAINS int pci_domains_supported = 1; #endif @@ -1927,6 +1930,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) { @@ -1944,7 +1974,7 @@ static int __devinit pci_setup(char *str) pci_cardbus_io_size = memparse(str + 9, &str); } else if (!strncmp(str, "cbmemsize=", 10)) { pci_cardbus_mem_size = memparse(str + 10, &str); - } 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 9b7f9cc3..b7a59d7a 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -131,6 +131,31 @@ 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[]; +extern int pci_ignore_count; + +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)) struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev); /* PCI slot sysfs helper code */ diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index eb6c8d15..f12de80e 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -955,6 +955,13 @@ static struct pci_dev *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; @@ -1071,6 +1078,12 @@ int 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++) { @@ -1109,6 +1122,12 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) unsigned int devfn, pass, max = bus->secondary; struct pci_dev *dev; + 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! */