diff mbox

[3/3] pci: Make rescan bus could increase bridge resource size if needed

Message ID 4DBF3AF0.4000804@kernel.org (mailing list archive)
State Superseded, archived
Headers show

Commit Message

Yinghai Lu May 2, 2011, 11:14 p.m. UTC
Current rescan will not touch bridge MMIO and IO.

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

only do that for bridges that all children get removed before. So do not release resources
that could already be used by drivers of child devices.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>

---
 drivers/pci/pci-sysfs.c |    5 ++++-
 drivers/pci/probe.c     |   24 ++++++++++++++++++++++++
 include/linux/pci.h     |    1 +
 3 files changed, 29 insertions(+), 1 deletion(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Jesse Barnes May 9, 2011, 8:56 p.m. UTC | #1
On Mon, 02 May 2011 16:14:56 -0700
Yinghai Lu <yinghai@kernel.org> wrote:

> 
> Current rescan will not touch bridge MMIO and IO.
> 
> Try to reuse pci_assign_unassigned_bridge_resources(bridge) to update bridge resource,
> if child devices need more resource.
> 
> only do that for bridges that all children get removed before. So do not release resources
> that could already be used by drivers of child devices.
> 
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> 
> ---
>  drivers/pci/pci-sysfs.c |    5 ++++-
>  drivers/pci/probe.c     |   24 ++++++++++++++++++++++++
>  include/linux/pci.h     |    1 +
>  3 files changed, 29 insertions(+), 1 deletion(-)
> 
> Index: linux-2.6/drivers/pci/pci-sysfs.c
> ===================================================================
> --- linux-2.6.orig/drivers/pci/pci-sysfs.c
> +++ linux-2.6/drivers/pci/pci-sysfs.c
> @@ -313,7 +313,10 @@ dev_bus_rescan_store(struct device *dev,
>  
>  	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;
> Index: linux-2.6/drivers/pci/probe.c
> ===================================================================
> --- linux-2.6.orig/drivers/pci/probe.c
> +++ linux-2.6/drivers/pci/probe.c
> @@ -1518,6 +1518,30 @@ EXPORT_SYMBOL(pci_scan_bus_parented);
>  
>  #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, adds them,
> + * and enables them, it will resize bridge mmio/io resource if it is possible
> + * for safe, caller should make sure that children get removed already.
> + *
> + * 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;
> +}
> +
> +/**

Why return anything if the value will never be used?
diff mbox

Patch

Index: linux-2.6/drivers/pci/pci-sysfs.c
===================================================================
--- linux-2.6.orig/drivers/pci/pci-sysfs.c
+++ linux-2.6/drivers/pci/pci-sysfs.c
@@ -313,7 +313,10 @@  dev_bus_rescan_store(struct device *dev,
 
 	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;
Index: linux-2.6/drivers/pci/probe.c
===================================================================
--- linux-2.6.orig/drivers/pci/probe.c
+++ linux-2.6/drivers/pci/probe.c
@@ -1518,6 +1518,30 @@  EXPORT_SYMBOL(pci_scan_bus_parented);
 
 #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, adds them,
+ * and enables them, it will resize bridge mmio/io resource if it is possible
+ * for safe, caller should make sure that children get removed already.
+ *
+ * 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
  *
Index: linux-2.6/include/linux/pci.h
===================================================================
--- linux-2.6.orig/include/linux/pci.h
+++ linux-2.6/include/linux/pci.h
@@ -835,6 +835,7 @@  void set_pcie_hotplug_bridge(struct pci_
 /* 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