diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-10 07:28:51 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-10 07:28:51 -0700 |
commit | 2169ce92ca996bdbb0baa8b99f928eb5e9a8f3ab (patch) | |
tree | b3569e3c80e9b92042d4e750438ade54320fe4a6 | |
parent | 7fc7693627f363820c0e95d1e082f73c197f83c4 (diff) | |
parent | f483d3923dc3a6394c483e28ccb3fe700bdf399e (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6:
PCI: conditional resource-reallocation through kernel parameter pci=realloc
-rw-r--r-- | Documentation/kernel-parameters.txt | 2 | ||||
-rw-r--r-- | drivers/pci/pci.c | 2 | ||||
-rw-r--r-- | drivers/pci/pci.h | 2 | ||||
-rw-r--r-- | drivers/pci/setup-bus.c | 15 |
4 files changed, 21 insertions, 0 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index fd248a31821..aa47be71df4 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2015,6 +2015,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. the default. off: Turn ECRC off on: Turn ECRC on. + realloc reallocate PCI resources if allocations done by BIOS + are erroneous. pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power Management. diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 2c5b9b99127..692671b1166 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3483,6 +3483,8 @@ static int __init pci_setup(char *str) pci_no_msi(); } else if (!strcmp(str, "noaer")) { pci_no_aer(); + } else if (!strncmp(str, "realloc", 7)) { + pci_realloc(); } else if (!strcmp(str, "nodomains")) { pci_no_domains(); } else if (!strncmp(str, "cbiosize=", 9)) { diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 731e20265ac..3a39bf1f1e2 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -146,6 +146,8 @@ static inline void pci_no_msi(void) { } static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } #endif +extern void pci_realloc(void); + static inline int pci_no_d1d2(struct pci_dev *dev) { unsigned int parent_dstates = 0; diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 1e9e5a5b8c8..9995842e45b 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -47,6 +47,13 @@ struct resource_list_x { (head)->next = NULL; \ } while (0) +int pci_realloc_enable = 0; +#define pci_realloc_enabled() pci_realloc_enable +void pci_realloc(void) +{ + pci_realloc_enable = 1; +} + /** * add_to_list() - add a new resource tracker to the list * @head: Head of the list @@ -1025,6 +1032,7 @@ static int __init pci_get_max_depth(void) return depth; } + /* * first try will not touch pci bridge res * second and later try will clear small leaf bridge res @@ -1068,6 +1076,13 @@ again: /* any device complain? */ if (!head.next) goto enable_and_dump; + + /* don't realloc if asked to do so */ + if (!pci_realloc_enabled()) { + free_list(resource_list_x, &head); + goto enable_and_dump; + } + failed_type = 0; for (list = head.next; list;) { failed_type |= list->flags; |