Skip to content

Commit

Permalink
PCI: Make rescan bus increase bridge resource size if needed
Browse files Browse the repository at this point in the history
Current rescan will not touch bridge MMIO and IO.

Try to reuse pci_assign_unassigned_bridge_resources(bridge) to update bridge
resources, if child devices need more resources.

Only do that for bridges whose children are all removed already; i.e. don't
release resources that could already be in use by drivers on child devices.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
  • Loading branch information
Yinghai Lu authored and Jesse Barnes committed Feb 14, 2012
1 parent 8424d75 commit 2f32052
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 1 deletion.
5 changes: 4 additions & 1 deletion drivers/pci/pci-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,10 @@ dev_bus_rescan_store(struct device *dev, struct device_attribute *attr,

if (val) {
mutex_lock(&pci_remove_rescan_mutex);
pci_rescan_bus(bus);
if (!pci_is_root_bus(bus) && list_empty(&bus->devices))
pci_rescan_bus_bridge_resize(bus->self);
else
pci_rescan_bus(bus);
mutex_unlock(&pci_remove_rescan_mutex);
}
return count;
Expand Down
25 changes: 25 additions & 0 deletions drivers/pci/probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,31 @@ struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops,
EXPORT_SYMBOL(pci_scan_bus);

#ifdef CONFIG_HOTPLUG
/**
* pci_rescan_bus_bridge_resize - scan a PCI bus for devices.
* @bridge: PCI bridge for the bus to scan
*
* Scan a PCI bus and child buses for new devices, add them,
* and enable them, resizing bridge mmio/io resource if necessary
* and possible. The caller must ensure the child devices are already
* removed for resizing to occur.
*
* Returns the max number of subordinate bus discovered.
*/
unsigned int __ref pci_rescan_bus_bridge_resize(struct pci_dev *bridge)
{
unsigned int max;
struct pci_bus *bus = bridge->subordinate;

max = pci_scan_child_bus(bus);

pci_assign_unassigned_bridge_resources(bridge);

pci_bus_add_devices(bus);

return max;
}

/**
* pci_rescan_bus - scan a PCI bus for devices.
* @bus: PCI bus to scan
Expand Down
1 change: 1 addition & 0 deletions include/linux/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,7 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev);
/* Functions for PCI Hotplug drivers to use */
int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap);
#ifdef CONFIG_HOTPLUG
unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge);
unsigned int pci_rescan_bus(struct pci_bus *bus);
#endif

Expand Down

0 comments on commit 2f32052

Please sign in to comment.