summaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2012-02-23 19:23:32 -0800
committerJesse Barnes <jbarnes@virtuousgeek.org>2012-02-24 09:38:59 -0800
commitb07f2ebc109b607789f648dedcff4b125f9afec6 (patch)
tree3868d50119a2ba1721914e9b53f12d996c5d45b4 /drivers/pci
parenteb572e7c76f154d75f90a783924f88afc34d5fec (diff)
PCI: add a PCI resource reallocation config option
Add a new config option, PCI_REALLOC_ENABLE_AUTO, which will automatically try to re-allocate PCI resources if PCI_IOV support is enabled and the SR-IOV resources are unassigned. Behavior can still be controlled using the pci=realloc= parameter. -v2: According to Jesse, adding one CONFIG option for distribution to disable it or enable it. -v3: update Kconfig text (jbarnes) Signed-off-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/Kconfig13
-rw-r--r--drivers/pci/setup-bus.c28
2 files changed, 41 insertions, 0 deletions
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 37856f7c778..848bfb84c04 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -31,6 +31,19 @@ config PCI_DEBUG
When in doubt, say N.
+config PCI_REALLOC_ENABLE_AUTO
+ bool "Enable PCI resource re-allocation detection"
+ depends on PCI
+ help
+ Say Y here if you want the PCI core to detect if PCI resource
+ re-allocation needs to be enabled. You can always use pci=realloc=on
+ or pci=realloc=off to override it. Note this feature is a no-op
+ unless PCI_IOV support is also enabled; in that case it will
+ automatically re-allocate PCI resources if SR-IOV BARs have not
+ been allocated by the BIOS.
+
+ When in doubt, say N.
+
config PCI_STUB
tristate "PCI Stub driver"
depends on PCI
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index e21e1c23730..c9214a14b49 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1294,6 +1294,31 @@ static bool __init pci_realloc_enabled(void)
return pci_realloc_enable >= user_enabled;
}
+static void __init pci_realloc_detect(void)
+{
+#if defined(CONFIG_PCI_IOV) && defined(CONFIG_PCI_REALLOC_ENABLE_AUTO)
+ struct pci_dev *dev = NULL;
+
+ if (pci_realloc_enable != undefined)
+ return;
+
+ for_each_pci_dev(dev) {
+ int i;
+
+ for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++) {
+ struct resource *r = &dev->resource[i];
+
+ /* Not assigned, or rejected by kernel ? */
+ if (r->flags && !r->start) {
+ pci_realloc_enable = auto_enabled;
+
+ return;
+ }
+ }
+ }
+#endif
+}
+
/*
* first try will not touch pci bridge res
* second and later try will clear small leaf bridge res
@@ -1315,6 +1340,7 @@ pci_assign_unassigned_resources(void)
int pci_try_num = 1;
/* don't realloc if asked to do so */
+ pci_realloc_detect();
if (pci_realloc_enabled()) {
int max_depth = pci_get_max_depth();
@@ -1349,6 +1375,8 @@ again:
if (tried_times >= pci_try_num) {
if (pci_realloc_enable == undefined)
printk(KERN_INFO "Some PCI device resources are unassigned, try booting with pci=realloc\n");
+ else if (pci_realloc_enable == auto_enabled)
+ printk(KERN_INFO "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n");
free_list(&fail_head);
goto enable_and_dump;