linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH part3 00/11] PCI, x86: pci root bus hotplug support - part3
@ 2012-09-02 21:52 Yinghai Lu
  2012-09-02 21:52 ` [PATCH part3 01/11] PCI: Separate out pci_assign_unassigned_bus_resources() Yinghai Lu
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Yinghai Lu @ 2012-09-02 21:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Taku Izumi, Jiang Liu, x86
  Cc: Andrew Morton, Linus Torvalds, Greg Kroah-Hartman, linux-pci,
	linux-kernel, linux-acpi, Yinghai Lu

pci bus rescan related changes.
So later root bus hotadd path could use pci_assign_unassigned_resource for root bus.

could get from
        git://git.kernel.org/pub/scm/linux/kernel/git/yinghai/linux-yinghai.git for-pci-root-bus-hotplug-part3

Yinghai Lu (11):
  PCI: Separate out pci_assign_unassigned_bus_resources()
  PCI: Move back pci_rescan_bus() to probe.c
  PCI: pci_bus_size_bridges() should not size own bridge
  PCI: Use __pci_bus_size_bridges() directly in pci_assign_unassigned_bus_resources()
  PCI, sysfs: Use device_type and attr_groups with pci dev
  PCI, sysfs: Create rescan_bridge under /sys/.../pci/devices/... for pci bridges
  PCI: Add pci_bus_add_single_device()
  PCI: Make pci_rescan_bus_bridge_resize() use pci_scan_bridge
  PCI: Clean up rescan_bus_bridge_resize()
  PCI: Rescan bus or bridge using callback method too
  PCI, sysfs: Clean up rescan/remove with scheule_callback

 Documentation/ABI/testing/sysfs-bus-pci |   10 +++
 drivers/pci/bus.c                       |   39 ++++++++++++
 drivers/pci/hotplug/acpiphp_glue.c      |    3 +-
 drivers/pci/pci-sysfs.c                 |  101 ++++++++++++++++++++++++++----
 drivers/pci/pci.h                       |    1 +
 drivers/pci/probe.c                     |   30 ++++++++-
 drivers/pci/setup-bus.c                 |   50 +++++----------
 include/linux/pci.h                     |    3 +
 8 files changed, 185 insertions(+), 52 deletions(-)

-- 
1.7.7


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH part3 01/11] PCI: Separate out pci_assign_unassigned_bus_resources()
  2012-09-02 21:52 [PATCH part3 00/11] PCI, x86: pci root bus hotplug support - part3 Yinghai Lu
@ 2012-09-02 21:52 ` Yinghai Lu
  2012-09-02 21:52 ` [PATCH part3 02/11] PCI: Move back pci_rescan_bus() to probe.c Yinghai Lu
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Yinghai Lu @ 2012-09-02 21:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Taku Izumi, Jiang Liu, x86
  Cc: Andrew Morton, Linus Torvalds, Greg Kroah-Hartman, linux-pci,
	linux-kernel, linux-acpi, Yinghai Lu

It is main portion of pci_rescan_bus().

Separate it out and need to use it for pci root bus hot add later.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/setup-bus.c |   32 ++++++++++++++++++--------------
 include/linux/pci.h     |    1 +
 2 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index f0e959c..e5c45c8 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1511,25 +1511,12 @@ enable_all:
 }
 EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);
 
-#ifdef CONFIG_HOTPLUG
-/**
- * pci_rescan_bus - scan a PCI bus for devices.
- * @bus: PCI bus to scan
- *
- * Scan a PCI bus and child buses for new devices, adds them,
- * and enables them.
- *
- * Returns the max number of subordinate bus discovered.
- */
-unsigned int __ref pci_rescan_bus(struct pci_bus *bus)
+void pci_assign_unassigned_bus_resources(struct pci_bus *bus)
 {
-	unsigned int max;
 	struct pci_dev *dev;
 	LIST_HEAD(add_list); /* list of resources that
 					want additional resources */
 
-	max = pci_scan_child_bus(bus);
-
 	down_read(&pci_bus_sem);
 	list_for_each_entry(dev, &bus->devices, bus_list)
 		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
@@ -1542,6 +1529,23 @@ unsigned int __ref pci_rescan_bus(struct pci_bus *bus)
 	BUG_ON(!list_empty(&add_list));
 
 	pci_enable_bridges(bus);
+}
+#ifdef CONFIG_HOTPLUG
+/**
+ * pci_rescan_bus - scan a PCI bus for devices.
+ * @bus: PCI bus to scan
+ *
+ * Scan a PCI bus and child buses for new devices, adds them,
+ * and enables them.
+ *
+ * Returns the max number of subordinate bus discovered.
+ */
+unsigned int __ref pci_rescan_bus(struct pci_bus *bus)
+{
+	unsigned int max;
+
+	max = pci_scan_child_bus(bus);
+	pci_assign_unassigned_bus_resources(bus);
 	pci_bus_add_devices(bus);
 
 	return max;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 29a4704..1bd7559 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -983,6 +983,7 @@ void pci_bus_size_bridges(struct pci_bus *bus);
 int pci_claim_resource(struct pci_dev *, int);
 void pci_assign_unassigned_resources(void);
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge);
+void pci_assign_unassigned_bus_resources(struct pci_bus *bus);
 void pdev_enable_device(struct pci_dev *);
 int pci_enable_resources(struct pci_dev *, int mask);
 void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *),
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH part3 02/11] PCI: Move back pci_rescan_bus() to probe.c
  2012-09-02 21:52 [PATCH part3 00/11] PCI, x86: pci root bus hotplug support - part3 Yinghai Lu
  2012-09-02 21:52 ` [PATCH part3 01/11] PCI: Separate out pci_assign_unassigned_bus_resources() Yinghai Lu
@ 2012-09-02 21:52 ` Yinghai Lu
  2012-09-02 21:52 ` [PATCH part3 03/11] PCI: pci_bus_size_bridges() should not size own bridge Yinghai Lu
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Yinghai Lu @ 2012-09-02 21:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Taku Izumi, Jiang Liu, x86
  Cc: Andrew Morton, Linus Torvalds, Greg Kroah-Hartman, linux-pci,
	linux-kernel, linux-acpi, Yinghai Lu

We have pci_assign_unassigned_bus_resources() in as global function now.

So could move back pci_rescan_bus to probe.c where it should be.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/probe.c     |   21 +++++++++++++++++++++
 drivers/pci/setup-bus.c |   22 ----------------------
 2 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index d8f513b..bc22308 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1890,6 +1890,27 @@ unsigned int __ref pci_rescan_bus_bridge_resize(struct pci_dev *bridge)
 	return max;
 }
 
+/**
+ * pci_rescan_bus - scan a PCI bus for devices.
+ * @bus: PCI bus to scan
+ *
+ * Scan a PCI bus and child buses for new devices, adds them,
+ * and enables them.
+ *
+ * Returns the max number of subordinate bus discovered.
+ */
+unsigned int __ref pci_rescan_bus(struct pci_bus *bus)
+{
+	unsigned int max;
+
+	max = pci_scan_child_bus(bus);
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
+
+	return max;
+}
+EXPORT_SYMBOL_GPL(pci_rescan_bus);
+
 EXPORT_SYMBOL(pci_add_new_bus);
 EXPORT_SYMBOL(pci_scan_slot);
 EXPORT_SYMBOL(pci_scan_bridge);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index e5c45c8..1dc22b3 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1530,25 +1530,3 @@ void pci_assign_unassigned_bus_resources(struct pci_bus *bus)
 
 	pci_enable_bridges(bus);
 }
-#ifdef CONFIG_HOTPLUG
-/**
- * pci_rescan_bus - scan a PCI bus for devices.
- * @bus: PCI bus to scan
- *
- * Scan a PCI bus and child buses for new devices, adds them,
- * and enables them.
- *
- * Returns the max number of subordinate bus discovered.
- */
-unsigned int __ref pci_rescan_bus(struct pci_bus *bus)
-{
-	unsigned int max;
-
-	max = pci_scan_child_bus(bus);
-	pci_assign_unassigned_bus_resources(bus);
-	pci_bus_add_devices(bus);
-
-	return max;
-}
-EXPORT_SYMBOL_GPL(pci_rescan_bus);
-#endif
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH part3 03/11] PCI: pci_bus_size_bridges() should not size own bridge
  2012-09-02 21:52 [PATCH part3 00/11] PCI, x86: pci root bus hotplug support - part3 Yinghai Lu
  2012-09-02 21:52 ` [PATCH part3 01/11] PCI: Separate out pci_assign_unassigned_bus_resources() Yinghai Lu
  2012-09-02 21:52 ` [PATCH part3 02/11] PCI: Move back pci_rescan_bus() to probe.c Yinghai Lu
@ 2012-09-02 21:52 ` Yinghai Lu
  2012-09-02 21:52 ` [PATCH part3 04/11] PCI: Use __pci_bus_size_bridges() directly in pci_assign_unassigned_bus_resources() Yinghai Lu
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Yinghai Lu @ 2012-09-02 21:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Taku Izumi, Jiang Liu, x86
  Cc: Andrew Morton, Linus Torvalds, Greg Kroah-Hartman, linux-pci,
	linux-kernel, linux-acpi, Yinghai Lu

During checking acpiphp code, found following sequence:
        pci_bus_size_bridges(bus);
        pci_bus_assign_resources(bus);
	pci_enable_bridges(bus);

The problem is that when bus is not root bus, pci_bus_size_bridges would also size
own pci bridge bus->self if that bridge resource is not inserted before.
but later pci_bus_assign_resources will not allocate those size bridge res.

So try make it less confusing, let it does not include self sizing.
and add with_self parameter info __pci_bus_size_bridge()

Fixes caller in pci hotplug componets.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/hotplug/acpiphp_glue.c |    3 ++-
 drivers/pci/setup-bus.c            |   24 +++++++++++++++---------
 include/linux/pci.h                |    1 +
 3 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 085eec7..6cb1923 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -842,7 +842,8 @@ static int __ref enable_device(struct acpiphp_slot *slot)
 				max = pci_scan_bridge(bus, dev, max, pass);
 				if (pass && dev->subordinate) {
 					check_hotplug_bridge(slot, dev);
-					pci_bus_size_bridges(dev->subordinate);
+					pci_bus_size_bridges_with_self(
+							dev->subordinate);
 				}
 			}
 		}
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 1dc22b3..70d6292 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1005,8 +1005,8 @@ handle_done:
 	;
 }
 
-void __ref __pci_bus_size_bridges(struct pci_bus *bus,
-			struct list_head *realloc_head)
+static void __ref __pci_bus_size_bridges(struct pci_bus *bus,
+			struct list_head *realloc_head, bool with_self)
 {
 	struct pci_dev *dev;
 	unsigned long mask, prefmask;
@@ -1024,13 +1024,13 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus,
 
 		case PCI_CLASS_BRIDGE_PCI:
 		default:
-			__pci_bus_size_bridges(b, realloc_head);
+			__pci_bus_size_bridges(b, realloc_head, true);
 			break;
 		}
 	}
 
-	/* The root bus? */
-	if (!bus->self)
+	/* Is root bus or not wanted? */
+	if (!bus->self || !with_self)
 		return;
 
 	switch (bus->self->class >> 8) {
@@ -1070,9 +1070,15 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus,
 	}
 }
 
+void __ref pci_bus_size_bridges_with_self(struct pci_bus *bus)
+{
+	__pci_bus_size_bridges(bus, NULL, true);
+}
+EXPORT_SYMBOL(pci_bus_size_bridges_with_self);
+
 void __ref pci_bus_size_bridges(struct pci_bus *bus)
 {
-	__pci_bus_size_bridges(bus, NULL);
+	__pci_bus_size_bridges(bus, NULL, false);
 }
 EXPORT_SYMBOL(pci_bus_size_bridges);
 
@@ -1385,7 +1391,7 @@ again:
 	/* Depth first, calculate sizes and alignments of all
 	   subordinate buses. */
 	list_for_each_entry(bus, &pci_root_buses, node)
-		__pci_bus_size_bridges(bus, add_list);
+		__pci_bus_size_bridges(bus, add_list, false);
 
 	/* Depth last, allocate resources and update the hardware. */
 	list_for_each_entry(bus, &pci_root_buses, node)
@@ -1462,7 +1468,7 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
 				  IORESOURCE_PREFETCH;
 
 again:
-	__pci_bus_size_bridges(parent, &add_list);
+	__pci_bus_size_bridges(parent, &add_list, true);
 	__pci_bridge_assign_resources(bridge, &add_list, &fail_head);
 	BUG_ON(!list_empty(&add_list));
 	tried_times++;
@@ -1523,7 +1529,7 @@ void pci_assign_unassigned_bus_resources(struct pci_bus *bus)
 		    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
 			if (dev->subordinate)
 				__pci_bus_size_bridges(dev->subordinate,
-							 &add_list);
+						 &add_list, true);
 	up_read(&pci_bus_sem);
 	__pci_bus_assign_resources(bus, &add_list, NULL);
 	BUG_ON(!list_empty(&add_list));
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1bd7559..f994e93 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -980,6 +980,7 @@ int pci_vpd_truncate(struct pci_dev *dev, size_t size);
 resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx);
 void pci_bus_assign_resources(const struct pci_bus *bus);
 void pci_bus_size_bridges(struct pci_bus *bus);
+void pci_bus_size_bridges_with_self(struct pci_bus *bus);
 int pci_claim_resource(struct pci_dev *, int);
 void pci_assign_unassigned_resources(void);
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge);
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH part3 04/11] PCI: Use __pci_bus_size_bridges() directly in pci_assign_unassigned_bus_resources()
  2012-09-02 21:52 [PATCH part3 00/11] PCI, x86: pci root bus hotplug support - part3 Yinghai Lu
                   ` (2 preceding siblings ...)
  2012-09-02 21:52 ` [PATCH part3 03/11] PCI: pci_bus_size_bridges() should not size own bridge Yinghai Lu
@ 2012-09-02 21:52 ` Yinghai Lu
  2012-09-02 21:52 ` [PATCH part3 05/11] PCI, sysfs: Use device_type and attr_groups with pci dev Yinghai Lu
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Yinghai Lu @ 2012-09-02 21:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Taku Izumi, Jiang Liu, x86
  Cc: Andrew Morton, Linus Torvalds, Greg Kroah-Hartman, linux-pci,
	linux-kernel, linux-acpi, Yinghai Lu

Now __pci_bus_size_bridges() will not include self bridge.
So we don't need to have our own version in
 pci_assign_unassigned_bus_resources anymore.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/setup-bus.c |    8 +-------
 1 files changed, 1 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 70d6292..054d54b 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1519,17 +1519,11 @@ EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);
 
 void pci_assign_unassigned_bus_resources(struct pci_bus *bus)
 {
-	struct pci_dev *dev;
 	LIST_HEAD(add_list); /* list of resources that
 					want additional resources */
 
 	down_read(&pci_bus_sem);
-	list_for_each_entry(dev, &bus->devices, bus_list)
-		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
-		    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
-			if (dev->subordinate)
-				__pci_bus_size_bridges(dev->subordinate,
-						 &add_list, true);
+	__pci_bus_size_bridges(bus, &add_list, false);
 	up_read(&pci_bus_sem);
 	__pci_bus_assign_resources(bus, &add_list, NULL);
 	BUG_ON(!list_empty(&add_list));
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH part3 05/11] PCI, sysfs: Use device_type and attr_groups with pci dev
  2012-09-02 21:52 [PATCH part3 00/11] PCI, x86: pci root bus hotplug support - part3 Yinghai Lu
                   ` (3 preceding siblings ...)
  2012-09-02 21:52 ` [PATCH part3 04/11] PCI: Use __pci_bus_size_bridges() directly in pci_assign_unassigned_bus_resources() Yinghai Lu
@ 2012-09-02 21:52 ` Yinghai Lu
  2012-09-02 21:52 ` [PATCH part3 06/11] PCI, sysfs: Create rescan_bridge under /sys/.../pci/devices/... for pci bridges Yinghai Lu
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Yinghai Lu @ 2012-09-02 21:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Taku Izumi, Jiang Liu, x86
  Cc: Andrew Morton, Linus Torvalds, Greg Kroah-Hartman, linux-pci,
	linux-kernel, linux-acpi, Yinghai Lu

We want to create rescan in sys only for pci bridge instead of all pci dev.

We could use attribute_groups/is_visible method to do that.

Now pci dev does not use device type yet. So add pci_dev_type to take
attr_groups with it.

Add pci_dev_bridge_attrs_are_visible() to control attr_bridge_group only create
attr for bridge.

This is the framework related change, later could attr to bridge_attr_group,
to make those attr only show up on pci bridge device.

Also We could add more attr groups with is_visible to reduce messness in
	pci_create_sysfs_dev_files. ( at least for boot_vga one )

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/pci-sysfs.c |   30 ++++++++++++++++++++++++++++++
 drivers/pci/pci.h       |    1 +
 drivers/pci/probe.c     |    1 +
 3 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 6869009..e37a0e0 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1369,3 +1369,33 @@ static int __init pci_sysfs_init(void)
 }
 
 late_initcall(pci_sysfs_init);
+
+static struct attribute *pci_dev_bridge_attrs[] = {
+	NULL,
+};
+
+static umode_t pci_dev_bridge_attrs_are_visible(struct kobject *kobj,
+						struct attribute *a, int n)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	if (!pdev->subordinate)
+		return 0;
+
+	return a->mode;
+}
+
+static struct attribute_group pci_dev_bridge_attr_group = {
+	.attrs = pci_dev_bridge_attrs,
+	.is_visible = pci_dev_bridge_attrs_are_visible,
+};
+
+static const struct attribute_group *pci_dev_attr_groups[] = {
+	&pci_dev_bridge_attr_group,
+	NULL,
+};
+
+struct device_type pci_dev_type = {
+	.groups = pci_dev_attr_groups,
+};
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index bacbcba..6f6cd14 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -157,6 +157,7 @@ static inline int pci_no_d1d2(struct pci_dev *dev)
 }
 extern struct device_attribute pci_dev_attrs[];
 extern struct device_attribute pcibus_dev_attrs[];
+extern struct device_type pci_dev_type;
 #ifdef CONFIG_HOTPLUG
 extern struct bus_attribute pci_bus_attrs[];
 #else
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index bc22308..d1796fe 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -970,6 +970,7 @@ int pci_setup_device(struct pci_dev *dev)
 	dev->sysdata = dev->bus->sysdata;
 	dev->dev.parent = dev->bus->bridge;
 	dev->dev.bus = &pci_bus_type;
+	dev->dev.type = &pci_dev_type;
 	dev->hdr_type = hdr_type & 0x7f;
 	dev->multifunction = !!(hdr_type & 0x80);
 	dev->error_state = pci_channel_io_normal;
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH part3 06/11] PCI, sysfs: Create rescan_bridge under /sys/.../pci/devices/... for pci bridges
  2012-09-02 21:52 [PATCH part3 00/11] PCI, x86: pci root bus hotplug support - part3 Yinghai Lu
                   ` (4 preceding siblings ...)
  2012-09-02 21:52 ` [PATCH part3 05/11] PCI, sysfs: Use device_type and attr_groups with pci dev Yinghai Lu
@ 2012-09-02 21:52 ` Yinghai Lu
  2012-09-02 21:52 ` [PATCH part3 07/11] PCI: Add pci_bus_add_single_device() Yinghai Lu
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Yinghai Lu @ 2012-09-02 21:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Taku Izumi, Jiang Liu, x86
  Cc: Andrew Morton, Linus Torvalds, Greg Kroah-Hartman, linux-pci,
	linux-kernel, linux-acpi, Yinghai Lu, Randy Dunlap

Current code will create rescan for every pci device under parent bus.
that is not right. The device is already there, there is no reason to rescan it.

We could have rescan for pci bridges. less confusing.

Need to move rescan attr to pci dev bridge attribute group.
And we should rescan bridge's secondary bus instead of primary bus.

-v3: Use device_type for pci dev.
-v4: Seperate pci device type change out
-v5: add rescan_bridge for bridge type, and still keep the old rescan.
	may remove the old rescan later.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Randy Dunlap <rdunlap@xenotime.net>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Documentation/ABI/testing/sysfs-bus-pci |   10 ++++++++++
 drivers/pci/pci-sysfs.c                 |   24 ++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci
index 34f5110..95f0f37 100644
--- a/Documentation/ABI/testing/sysfs-bus-pci
+++ b/Documentation/ABI/testing/sysfs-bus-pci
@@ -111,6 +111,16 @@ Description:
 		from this part of the device tree.
 		Depends on CONFIG_HOTPLUG.
 
+What:		/sys/bus/pci/devices/.../rescan_bridge
+Date:		February 2012
+Contact:	Linux PCI developers <linux-pci@vger.kernel.org>
+Description:
+		Writing a non-zero value to this attribute will
+		force a rescan of the bridge and all child buses, and
+		re-discover devices removed earlier from this part of
+		the device tree.
+		Depends on CONFIG_HOTPLUG.
+
 What:		/sys/bus/pci/devices/.../reset
 Date:		July 2009
 Contact:	Michael S. Tsirkin <mst@redhat.com>
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index e37a0e0..2100c04 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -327,6 +327,27 @@ dev_rescan_store(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
+static ssize_t
+dev_bridge_rescan_store(struct device *dev, struct device_attribute *attr,
+		 const char *buf, size_t count)
+{
+	unsigned long val;
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	if (kstrtoul(buf, 0, &val) < 0)
+		return -EINVAL;
+
+	if (val) {
+		mutex_lock(&pci_remove_rescan_mutex);
+		pci_rescan_bus(pdev->subordinate);
+		mutex_unlock(&pci_remove_rescan_mutex);
+	}
+	return count;
+}
+
+static struct device_attribute pci_dev_bridge_rescan_attr =
+	__ATTR(rescan_bridge, (S_IWUSR|S_IWGRP), NULL, dev_bridge_rescan_store);
+
 static void remove_callback(struct device *dev)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
@@ -1371,6 +1392,9 @@ static int __init pci_sysfs_init(void)
 late_initcall(pci_sysfs_init);
 
 static struct attribute *pci_dev_bridge_attrs[] = {
+#ifdef CONFIG_HOTPLUG
+	&pci_dev_bridge_rescan_attr.attr,
+#endif
 	NULL,
 };
 
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH part3 07/11] PCI: Add pci_bus_add_single_device()
  2012-09-02 21:52 [PATCH part3 00/11] PCI, x86: pci root bus hotplug support - part3 Yinghai Lu
                   ` (5 preceding siblings ...)
  2012-09-02 21:52 ` [PATCH part3 06/11] PCI, sysfs: Create rescan_bridge under /sys/.../pci/devices/... for pci bridges Yinghai Lu
@ 2012-09-02 21:52 ` Yinghai Lu
  2012-09-02 21:52 ` [PATCH part3 08/11] PCI: Make pci_rescan_bus_bridge_resize() use pci_scan_bridge Yinghai Lu
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Yinghai Lu @ 2012-09-02 21:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Taku Izumi, Jiang Liu, x86
  Cc: Andrew Morton, Linus Torvalds, Greg Kroah-Hartman, linux-pci,
	linux-kernel, linux-acpi, Yinghai Lu

Will use it to pci_bus_bridge_scan_resize() to make bridge will
have pci_bus directory created correctly.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/bus.c   |   39 +++++++++++++++++++++++++++++++++++++++
 include/linux/pci.h |    1 +
 2 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 2882d01..950b786 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -259,6 +259,45 @@ void pci_bus_add_devices(const struct pci_bus *bus)
 	}
 }
 
+void pci_bus_add_single_device(struct pci_dev *dev)
+{
+	struct pci_bus *child;
+	int retval;
+
+	/* Skip already-added devices */
+	if (!dev->is_added) {
+		retval = pci_bus_add_device(dev);
+		if (retval)
+			dev_err(&dev->dev, "Error adding device, continuing\n");
+	}
+
+	BUG_ON(!dev->is_added);
+
+	child = dev->subordinate;
+	/*
+	 * If there is an unattached subordinate bus, attach
+	 * it and then scan for unattached PCI devices.
+	 */
+	if (child) {
+		if (list_empty(&child->node)) {
+			down_write(&pci_bus_sem);
+			list_add_tail(&child->node, &dev->bus->children);
+			up_write(&pci_bus_sem);
+		}
+		pci_bus_add_devices(child);
+
+		/*
+		 * register the bus with sysfs as the parent is now
+		 * properly registered.
+		 */
+		if (!child->is_added) {
+			retval = pci_bus_add_child(child);
+			if (retval)
+				dev_err(&dev->dev, "Error adding bus, continuing\n");
+		}
+	}
+}
+
 void pci_enable_bridges(struct pci_bus *bus)
 {
 	struct pci_dev *dev;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index f994e93..4446448 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -700,6 +700,7 @@ void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
 void pcibios_scan_specific_bus(int busn);
 extern struct pci_bus *pci_find_bus(int domain, int busnr);
 void pci_bus_add_devices(const struct pci_bus *bus);
+void pci_bus_add_single_device(struct pci_dev *dev);
 struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
 				      struct pci_ops *ops, void *sysdata);
 struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH part3 08/11] PCI: Make pci_rescan_bus_bridge_resize() use pci_scan_bridge
  2012-09-02 21:52 [PATCH part3 00/11] PCI, x86: pci root bus hotplug support - part3 Yinghai Lu
                   ` (6 preceding siblings ...)
  2012-09-02 21:52 ` [PATCH part3 07/11] PCI: Add pci_bus_add_single_device() Yinghai Lu
@ 2012-09-02 21:52 ` Yinghai Lu
  2012-09-02 21:52 ` [PATCH part3 09/11] PCI: Clean up rescan_bus_bridge_resize() Yinghai Lu
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Yinghai Lu @ 2012-09-02 21:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Taku Izumi, Jiang Liu, x86
  Cc: Andrew Morton, Linus Torvalds, Greg Kroah-Hartman, linux-pci,
	linux-kernel, linux-acpi, Yinghai Lu

So after remove all children and then using setpci change bus register and
rescan bridge could use new set bus number.

Otherwise need to rescan parent bus, it would have too much overhead.

also need to use pci_bus_add_single_device to make sure new change bus have
directory /sys/../.../pci_bus.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/probe.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index d1796fe..59345ac 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1879,14 +1879,16 @@ EXPORT_SYMBOL(pci_scan_bus);
  */
 unsigned int __ref pci_rescan_bus_bridge_resize(struct pci_dev *bridge)
 {
-	unsigned int max;
-	struct pci_bus *bus = bridge->subordinate;
+	unsigned int max = 0;
+	int pass;
+	struct pci_bus *bus = bridge->bus;
 
-	max = pci_scan_child_bus(bus);
+	for (pass = 0; pass < 2; pass++)
+		max = pci_scan_bridge(bus, bridge, max, pass);
 
 	pci_assign_unassigned_bridge_resources(bridge);
 
-	pci_bus_add_devices(bus);
+	pci_bus_add_single_device(bridge);
 
 	return max;
 }
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH part3 09/11] PCI: Clean up rescan_bus_bridge_resize()
  2012-09-02 21:52 [PATCH part3 00/11] PCI, x86: pci root bus hotplug support - part3 Yinghai Lu
                   ` (7 preceding siblings ...)
  2012-09-02 21:52 ` [PATCH part3 08/11] PCI: Make pci_rescan_bus_bridge_resize() use pci_scan_bridge Yinghai Lu
@ 2012-09-02 21:52 ` Yinghai Lu
  2012-09-02 21:52 ` [PATCH part3 10/11] PCI: Rescan bus or bridge using callback method too Yinghai Lu
  2012-09-02 21:52 ` [PATCH part3 11/11] PCI, sysfs: Clean up rescan/remove with scheule_callback Yinghai Lu
  10 siblings, 0 replies; 12+ messages in thread
From: Yinghai Lu @ 2012-09-02 21:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Taku Izumi, Jiang Liu, x86
  Cc: Andrew Morton, Linus Torvalds, Greg Kroah-Hartman, linux-pci,
	linux-kernel, linux-acpi, Yinghai Lu

Should only use it with bridge instead of bus.
It could get new subordinate. so can not use it with reguar bus.

In that case, user may need to make sure all children devices get removed
already before rescan.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/pci-sysfs.c |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 2100c04..60cb06b 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -339,7 +339,7 @@ dev_bridge_rescan_store(struct device *dev, struct device_attribute *attr,
 
 	if (val) {
 		mutex_lock(&pci_remove_rescan_mutex);
-		pci_rescan_bus(pdev->subordinate);
+		pci_rescan_bus_bridge_resize(pdev);
 		mutex_unlock(&pci_remove_rescan_mutex);
 	}
 	return count;
@@ -389,10 +389,7 @@ dev_bus_rescan_store(struct device *dev, struct device_attribute *attr,
 
 	if (val) {
 		mutex_lock(&pci_remove_rescan_mutex);
-		if (!pci_is_root_bus(bus) && list_empty(&bus->devices))
-			pci_rescan_bus_bridge_resize(bus->self);
-		else
-			pci_rescan_bus(bus);
+		pci_rescan_bus(bus);
 		mutex_unlock(&pci_remove_rescan_mutex);
 	}
 	return count;
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH part3 10/11] PCI: Rescan bus or bridge using callback method too
  2012-09-02 21:52 [PATCH part3 00/11] PCI, x86: pci root bus hotplug support - part3 Yinghai Lu
                   ` (8 preceding siblings ...)
  2012-09-02 21:52 ` [PATCH part3 09/11] PCI: Clean up rescan_bus_bridge_resize() Yinghai Lu
@ 2012-09-02 21:52 ` Yinghai Lu
  2012-09-02 21:52 ` [PATCH part3 11/11] PCI, sysfs: Clean up rescan/remove with scheule_callback Yinghai Lu
  10 siblings, 0 replies; 12+ messages in thread
From: Yinghai Lu @ 2012-09-02 21:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Taku Izumi, Jiang Liu, x86
  Cc: Andrew Morton, Linus Torvalds, Greg Kroah-Hartman, linux-pci,
	linux-kernel, linux-acpi, Yinghai Lu

Just like removal.

Because We could add new bus under the bridges...

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/pci-sysfs.c |   43 +++++++++++++++++++++++++++++++------------
 1 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 60cb06b..7ebc764 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -327,21 +327,31 @@ dev_rescan_store(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
+static void bridge_rescan_callback(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	mutex_lock(&pci_remove_rescan_mutex);
+	pci_rescan_bus_bridge_resize(pdev);
+	mutex_unlock(&pci_remove_rescan_mutex);
+}
+
 static ssize_t
 dev_bridge_rescan_store(struct device *dev, struct device_attribute *attr,
 		 const char *buf, size_t count)
 {
+	int ret = 0;
 	unsigned long val;
-	struct pci_dev *pdev = to_pci_dev(dev);
 
 	if (kstrtoul(buf, 0, &val) < 0)
 		return -EINVAL;
 
-	if (val) {
-		mutex_lock(&pci_remove_rescan_mutex);
-		pci_rescan_bus_bridge_resize(pdev);
-		mutex_unlock(&pci_remove_rescan_mutex);
-	}
+	if (val)
+		ret = device_schedule_callback(dev, bridge_rescan_callback);
+
+	if (ret)
+		count = ret;
+
 	return count;
 }
 
@@ -377,21 +387,30 @@ remove_store(struct device *dev, struct device_attribute *dummy,
 	return count;
 }
 
+static void bus_rescan_callback(struct device *dev)
+{
+	struct pci_bus *bus = to_pci_bus(dev);
+
+	mutex_lock(&pci_remove_rescan_mutex);
+	pci_rescan_bus(bus);
+	mutex_unlock(&pci_remove_rescan_mutex);
+}
 static ssize_t
 dev_bus_rescan_store(struct device *dev, struct device_attribute *attr,
 		 const char *buf, size_t count)
 {
+	int ret = 0;
 	unsigned long val;
-	struct pci_bus *bus = to_pci_bus(dev);
 
 	if (strict_strtoul(buf, 0, &val) < 0)
 		return -EINVAL;
 
-	if (val) {
-		mutex_lock(&pci_remove_rescan_mutex);
-		pci_rescan_bus(bus);
-		mutex_unlock(&pci_remove_rescan_mutex);
-	}
+	if (val)
+		ret = device_schedule_callback(dev, bus_rescan_callback);
+
+	if (ret)
+		count = ret;
+
 	return count;
 }
 
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH part3 11/11] PCI, sysfs: Clean up rescan/remove with scheule_callback
  2012-09-02 21:52 [PATCH part3 00/11] PCI, x86: pci root bus hotplug support - part3 Yinghai Lu
                   ` (9 preceding siblings ...)
  2012-09-02 21:52 ` [PATCH part3 10/11] PCI: Rescan bus or bridge using callback method too Yinghai Lu
@ 2012-09-02 21:52 ` Yinghai Lu
  10 siblings, 0 replies; 12+ messages in thread
From: Yinghai Lu @ 2012-09-02 21:52 UTC (permalink / raw)
  To: Bjorn Helgaas, Taku Izumi, Jiang Liu, x86
  Cc: Andrew Morton, Linus Torvalds, Greg Kroah-Hartman, linux-pci,
	linux-kernel, linux-acpi, Yinghai Lu

Change to use three return according to Bjorn.

Suggested-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/pci-sysfs.c |   37 ++++++++++++++++++++-----------------
 1 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 7ebc764..3601912 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -340,17 +340,17 @@ static ssize_t
 dev_bridge_rescan_store(struct device *dev, struct device_attribute *attr,
 		 const char *buf, size_t count)
 {
-	int ret = 0;
+	int err;
 	unsigned long val;
 
 	if (kstrtoul(buf, 0, &val) < 0)
 		return -EINVAL;
+	if (!val)
+		return count;
 
-	if (val)
-		ret = device_schedule_callback(dev, bridge_rescan_callback);
-
-	if (ret)
-		count = ret;
+	err = device_schedule_callback(dev, bridge_rescan_callback);
+	if (err)
+		return err;
 
 	return count;
 }
@@ -371,7 +371,7 @@ static ssize_t
 remove_store(struct device *dev, struct device_attribute *dummy,
 	     const char *buf, size_t count)
 {
-	int ret = 0;
+	int err;
 	unsigned long val;
 
 	if (strict_strtoul(buf, 0, &val) < 0)
@@ -380,10 +380,13 @@ remove_store(struct device *dev, struct device_attribute *dummy,
 	/* An attribute cannot be unregistered by one of its own methods,
 	 * so we have to use this roundabout approach.
 	 */
-	if (val)
-		ret = device_schedule_callback(dev, remove_callback);
-	if (ret)
-		count = ret;
+	if (!val)
+		return count;
+
+	err = device_schedule_callback(dev, remove_callback);
+	if (err)
+		return err;
+
 	return count;
 }
 
@@ -399,17 +402,17 @@ static ssize_t
 dev_bus_rescan_store(struct device *dev, struct device_attribute *attr,
 		 const char *buf, size_t count)
 {
-	int ret = 0;
+	int err;
 	unsigned long val;
 
 	if (strict_strtoul(buf, 0, &val) < 0)
 		return -EINVAL;
+	if (!val)
+		return count;
 
-	if (val)
-		ret = device_schedule_callback(dev, bus_rescan_callback);
-
-	if (ret)
-		count = ret;
+	err = device_schedule_callback(dev, bus_rescan_callback);
+	if (err)
+		return err;
 
 	return count;
 }
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2012-09-02 21:52 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-02 21:52 [PATCH part3 00/11] PCI, x86: pci root bus hotplug support - part3 Yinghai Lu
2012-09-02 21:52 ` [PATCH part3 01/11] PCI: Separate out pci_assign_unassigned_bus_resources() Yinghai Lu
2012-09-02 21:52 ` [PATCH part3 02/11] PCI: Move back pci_rescan_bus() to probe.c Yinghai Lu
2012-09-02 21:52 ` [PATCH part3 03/11] PCI: pci_bus_size_bridges() should not size own bridge Yinghai Lu
2012-09-02 21:52 ` [PATCH part3 04/11] PCI: Use __pci_bus_size_bridges() directly in pci_assign_unassigned_bus_resources() Yinghai Lu
2012-09-02 21:52 ` [PATCH part3 05/11] PCI, sysfs: Use device_type and attr_groups with pci dev Yinghai Lu
2012-09-02 21:52 ` [PATCH part3 06/11] PCI, sysfs: Create rescan_bridge under /sys/.../pci/devices/... for pci bridges Yinghai Lu
2012-09-02 21:52 ` [PATCH part3 07/11] PCI: Add pci_bus_add_single_device() Yinghai Lu
2012-09-02 21:52 ` [PATCH part3 08/11] PCI: Make pci_rescan_bus_bridge_resize() use pci_scan_bridge Yinghai Lu
2012-09-02 21:52 ` [PATCH part3 09/11] PCI: Clean up rescan_bus_bridge_resize() Yinghai Lu
2012-09-02 21:52 ` [PATCH part3 10/11] PCI: Rescan bus or bridge using callback method too Yinghai Lu
2012-09-02 21:52 ` [PATCH part3 11/11] PCI, sysfs: Clean up rescan/remove with scheule_callback Yinghai Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).