PCI: Allow additional bus numbers for hotplug bridges
A user may hot add a switch requiring more than one bus to enumerate. This previously required a system reboot if BIOS did not sufficiently pad the bus resource, which they frequently don't do. Add a kernel parameter so a user can specify the minimum number of bus numbers to reserve for a hotplug bridge's subordinate buses so rebooting won't be necessary. The default is 1, which is equivalent to previous behavior. Signed-off-by: Keith Busch <keith.busch@intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
af8c34ce6a
commit
e16b466059
|
@ -3016,6 +3016,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||||
hpmemsize=nn[KMG] The fixed amount of bus space which is
|
hpmemsize=nn[KMG] The fixed amount of bus space which is
|
||||||
reserved for hotplug bridge's memory window.
|
reserved for hotplug bridge's memory window.
|
||||||
Default size is 2 megabytes.
|
Default size is 2 megabytes.
|
||||||
|
hpbussize=nn The minimum amount of additional bus numbers
|
||||||
|
reserved for buses below a hotplug bridge.
|
||||||
|
Default is 1.
|
||||||
realloc= Enable/disable reallocating PCI bridge resources
|
realloc= Enable/disable reallocating PCI bridge resources
|
||||||
if allocations done by BIOS are too small to
|
if allocations done by BIOS are too small to
|
||||||
accommodate resources required by all child
|
accommodate resources required by all child
|
||||||
|
|
|
@ -81,6 +81,9 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE;
|
||||||
unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE;
|
unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE;
|
||||||
unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE;
|
unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE;
|
||||||
|
|
||||||
|
#define DEFAULT_HOTPLUG_BUS_SIZE 1
|
||||||
|
unsigned long pci_hotplug_bus_size = DEFAULT_HOTPLUG_BUS_SIZE;
|
||||||
|
|
||||||
enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_DEFAULT;
|
enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_DEFAULT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -5021,6 +5024,11 @@ static int __init pci_setup(char *str)
|
||||||
pci_hotplug_io_size = memparse(str + 9, &str);
|
pci_hotplug_io_size = memparse(str + 9, &str);
|
||||||
} else if (!strncmp(str, "hpmemsize=", 10)) {
|
} else if (!strncmp(str, "hpmemsize=", 10)) {
|
||||||
pci_hotplug_mem_size = memparse(str + 10, &str);
|
pci_hotplug_mem_size = memparse(str + 10, &str);
|
||||||
|
} else if (!strncmp(str, "hpbussize=", 10)) {
|
||||||
|
pci_hotplug_bus_size =
|
||||||
|
simple_strtoul(str + 10, &str, 0);
|
||||||
|
if (pci_hotplug_bus_size > 0xff)
|
||||||
|
pci_hotplug_bus_size = DEFAULT_HOTPLUG_BUS_SIZE;
|
||||||
} else if (!strncmp(str, "pcie_bus_tune_off", 17)) {
|
} else if (!strncmp(str, "pcie_bus_tune_off", 17)) {
|
||||||
pcie_bus_config = PCIE_BUS_TUNE_OFF;
|
pcie_bus_config = PCIE_BUS_TUNE_OFF;
|
||||||
} else if (!strncmp(str, "pcie_bus_safe", 13)) {
|
} else if (!strncmp(str, "pcie_bus_safe", 13)) {
|
||||||
|
|
|
@ -2076,6 +2076,15 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus)
|
||||||
max = pci_scan_bridge(bus, dev, max, pass);
|
max = pci_scan_bridge(bus, dev, max, pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure a hotplug bridge has at least the minimum requested
|
||||||
|
* number of buses.
|
||||||
|
*/
|
||||||
|
if (bus->self && bus->self->is_hotplug_bridge && pci_hotplug_bus_size) {
|
||||||
|
if (max - bus->busn_res.start < pci_hotplug_bus_size - 1)
|
||||||
|
max = bus->busn_res.start + pci_hotplug_bus_size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We've scanned the bus and so we know all about what's on
|
* We've scanned the bus and so we know all about what's on
|
||||||
* the other side of any bridges that may be on this bus plus
|
* the other side of any bridges that may be on this bus plus
|
||||||
|
|
|
@ -1706,6 +1706,7 @@ extern u8 pci_cache_line_size;
|
||||||
|
|
||||||
extern unsigned long pci_hotplug_io_size;
|
extern unsigned long pci_hotplug_io_size;
|
||||||
extern unsigned long pci_hotplug_mem_size;
|
extern unsigned long pci_hotplug_mem_size;
|
||||||
|
extern unsigned long pci_hotplug_bus_size;
|
||||||
|
|
||||||
/* Architecture-specific versions may override these (weak) */
|
/* Architecture-specific versions may override these (weak) */
|
||||||
void pcibios_disable_device(struct pci_dev *dev);
|
void pcibios_disable_device(struct pci_dev *dev);
|
||||||
|
|
Loading…
Reference in New Issue