Skip to contentSkip to conversation

PCI core learns hotplug

RFC PATCH Superseded Alex Chiang 1 participant 13 messages Feb 13, 2009

Subsystems (2)

v2 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v2 cover PCI core learns hotplug

Hi all,

Jesse asked me to send out some updated bits on this series to get more early review. He notes that there is at least one patch out there (Yuji Shimada's memory resource alignment) that would really like this.

Original discussion here:

	http://thread.gmane.org/gmane.linux.kernel.pci/2914

This is still a work-in-progress.

Known to work:
- remove any device in PCI tree once, rescan to get it back
- device seems to be functional. :)
- can repeat above multiple times on non PCIe machines

Known to not work:
- can't remove/rescan multiple times when PCIe port driver is loaded
- hotplug drivers using pci_do_scan_bus may blow up

TODO:
- fix known PCIe port driver bug
- clean up hotplug drivers using pci_do_scan_bus
- incorporate one more of Trent's patches, will probably replace "Introduce /sys/bus/pci/rescan" since his implementation was nicer
- remove ASPM patch once jbarnes's linux-next tree gets rebased ;)

Comments welcom.

Thanks.

/ac

v1 -> v2:
- incorporated lots of Trent Piepho's work
- beefed up pci_do_scan_bus as heavy lifter for rescanning
- small bugfixes folded into earlier patches to get everything working
---

Alex Chiang (8):
PCI: more whitespace cleanups
PCI Hotplug: schedule fakephp for feature removal PCI Hotplug: rename legacy_fakephp to fakephp
PCI: Introduce /sys/bus/pci/devices/.../rescan
PCI: Introduce /sys/bus/pci/rescan
PCI: beef up pci_do_scan_bus()
PCI: properly clean up ASPM link state on device remove
PCI: always scan child buses

Trent Piepho (4):
PCI Hotplug: restore fakephp interface with complete reimplementation
PCI: Introduce /sys/bus/pci/devices/.../remove
PCI: pci_scan_slot() returns newly found devices
PCI: don't scan existing devices

 Documentation/ABI/testing/sysfs-bus-pci    |   27 ++
 Documentation/feature-removal-schedule.txt |   32 ++
 Documentation/filesystems/sysfs-pci.txt    |    9 +
 drivers/pci/hotplug-pci.c                  |   16 +
 drivers/pci/hotplug/fakephp.c              |  443 +++++++---------------------
 drivers/pci/pci-sysfs.c                    |   96 +++++-
 drivers/pci/pcie/aspm.c                    |    4 
 drivers/pci/probe.c                        |   90 +++---
 drivers/pci/remove.c                       |    4 
 9 files changed, 323 insertions(+), 398 deletions(-)
#1 lore raw

RFC PATCH v2 1/12 PCI: don't scan existing devices

From: Trent Piepho <[email protected]>

pci_scan_single_device is supposed to add newly discovered devices to pci_bus->devices, but doesn't check to see if the device has already been added. This can cause problems if we ever want to use this interface to rescan the PCI bus.

If the device is already added, just return it.

---

 drivers/pci/probe.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)
drivers/pci/probe.c +6 -0
index 55ec44a..66b5d1c 100644
@@ -1006,6 +1006,12 @@ struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn)
 {
 	struct pci_dev *dev;
 
+	dev = pci_get_slot(bus, devfn);
+	if (dev) {
+		pci_dev_put(dev);
+		return dev;
+	}
+
 	dev = pci_scan_device(bus, devfn);
 	if (!dev)
 		return NULL;
#2 lore raw

RFC PATCH v2 2/12 PCI: pci_scan_slot() returns newly found devices

In reply to Alex Chiang

From: Trent Piepho <[email protected]>

pci_scan_slot() has been rewritten to be less complex and will now return the number of *new* devices found.

Existing callers need not worry because they already assume that they can't call pci_scan_slot() on an already-scanned slot.

Thus, there is no semantic change for existing callers: returning newly found devices (this patch) is exactly equal to returning all found devices (before this patch).

This patch adds some more groundwork to allow us to rescan the PCI bus during runtime to discover newly added devices.

---

 drivers/pci/probe.c |   35 +++++++++++++----------------------
 1 files changed, 13 insertions(+), 22 deletions(-)
drivers/pci/probe.c +13 -22
index 66b5d1c..d392813 100644
@@ -1030,35 +1030,26 @@ EXPORT_SYMBOL(pci_scan_single_device);
  * Scan a PCI slot on the specified PCI bus for devices, adding
  * discovered devices to the @bus->devices list.  New devices
  * will not have is_added set.
+ *
+ * Returns the number of new devices found.
  */
 int pci_scan_slot(struct pci_bus *bus, int devfn)
 {
-	int func, nr = 0;
-	int scan_all_fns;
-
-	scan_all_fns = pcibios_scan_all_fns(bus, devfn);
-
-	for (func = 0; func < 8; func++, devfn++) {
-		struct pci_dev *dev;
+	int fn, nr = 0;
+	struct pci_dev *dev;
 
-		dev = pci_scan_single_device(bus, devfn);
-		if (dev) {
+	if ((dev = pci_scan_single_device(bus, devfn)))
+		if (!dev->is_added)	/* new device? */
 			nr++;
 
-			/*
-		 	 * If this is a single function device,
-		 	 * don't scan past the first function.
-		 	 */
-			if (!dev->multifunction) {
-				if (func > 0) {
-					dev->multifunction = 1;
-				} else {
- 					break;
-				}
+	if ((dev && dev->multifunction) ||
+	    (!dev && pcibios_scan_all_fns(bus, devfn))) {
+		for (fn = 1; fn < 8; fn++) {
+			if ((dev = pci_scan_single_device(bus, devfn + fn))) {
+				if (!dev->is_added)
+					nr++;
+				dev->multifunction = 1;
 			}
-		} else {
-			if (func == 0 && !scan_all_fns)
-				break;
 		}
 	}
 
#3 lore raw

RFC PATCH v2 3/12 PCI: always scan child buses

In reply to Alex Chiang

While scanning bridges, we stop our scan if we encounter a bus that we've seen before, to work around some buggy chipsets. This is a good idea, but prevents us from fully scanning the PCI bus at a future time (to find newly hot-added devices, for example).

Change the logic so that we skip _re-adding_ an existing bus that we've seen before, but also allow the scan to descend to all child buses.

Now that we're potentially scanning our child buses again, we also need to be sure not to attempt re-initializing their BARs so we avoid that.

This patch lays the groundwork to allow the user to issue a rescan of the PCI bus at any time.

---

 drivers/pci/probe.c |   33 +++++++++++++++++++--------------
 1 files changed, 19 insertions(+), 14 deletions(-)
drivers/pci/probe.c +19 -14
index d392813..d2bd1b0 100644
@@ -511,21 +511,21 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
 
 		/*
 		 * If we already got to this bus through a different bridge,
-		 * ignore it.  This can happen with the i450NX chipset.
+		 * don't re-add it. This can happen with the i450NX chipset.
+		 *
+		 * However, we continue to descend down the hierarchy and
+		 * scan remaining child buses.
 		 */
-		if (pci_find_bus(pci_domain_nr(bus), busnr)) {
-			dev_info(&dev->dev, "bus %04x:%02x already known\n",
-				 pci_domain_nr(bus), busnr);
-			goto out;
+		child = pci_find_bus(pci_domain_nr(bus), busnr);
+		if (!child) {
+			child = pci_add_new_bus(bus, dev, busnr);
+			if (!child)
+				goto out;
+			child->primary = buses & 0xFF;
+			child->subordinate = (buses >> 16) & 0xFF;
+			child->bridge_ctl = bctl;
 		}
 
-		child = pci_add_new_bus(bus, dev, busnr);
-		if (!child)
-			goto out;
-		child->primary = buses & 0xFF;
-		child->subordinate = (buses >> 16) & 0xFF;
-		child->bridge_ctl = bctl;
-
 		cmax = pci_scan_child_bus(child);
 		if (cmax > max)
 			max = cmax;
@@ -1075,8 +1075,13 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
 	 * After performing arch-dependent fixup of the bus, look behind
 	 * all PCI-to-PCI bridges on this bus.
 	 */
-	pr_debug("PCI: Fixups for bus %04x:%02x\n", pci_domain_nr(bus), bus->number);
-	pcibios_fixup_bus(bus);
+	if (!bus->is_added) {
+		pr_debug("PCI: Fixups for bus %04x:%02x\n", pci_domain_nr(bus), bus->number);
+		pcibios_fixup_bus(bus);
+		if (bus->parent == NULL)
+			bus->is_added = 1;
+	}
+
 	for (pass=0; pass < 2; pass++)
 		list_for_each_entry(dev, &bus->devices, bus_list) {
 			if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
#4 lore raw

RFC PATCH v2 4/12 PCI: properly clean up ASPM link state on device remove

In reply to Alex Chiang

We only want to disable ASPM when the last function is removed from the parent's device list. We determine this by checking to see if the parent's device list is completely empty.

Unfortunately, we never hit that code because the parent is considered an upstream port, and never had an ASPM link_state associated with it.

The early check for !link_state causes us to return early, we never discover that our device list is empty, and thus we never remove the downstream ports' link_state nodes.

Instead of checking to see if the parent's device list is empty, we can check to see if we are the last device on the list, and if so, then we know that we can clean up properly.

---

 drivers/pci/pcie/aspm.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/pci/pcie/aspm.c +2 -2
index 586b6f7..b0367f1 100644
@@ -718,9 +718,9 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
 
 	/*
 	 * All PCIe functions are in one slot, remove one function will remove
-	 * the the whole slot, so just wait
+	 * the whole slot, so just wait until we are the last function left.
 	 */
-	if (!list_empty(&parent->subordinate->devices))
+	if (!list_is_last(&pdev->bus_list, &parent->subordinate->devices))
 		goto out;
 
 	/* All functions are removed, so just disable ASPM for the link */
#5 lore raw

RFC PATCH v2 5/12 PCI: beef up pci_do_scan_bus()

In reply to Alex Chiang

We have a nice interface for re-scanning a PCI bus which will discover newly added devices, add them to the device tree, and enable them properly.

Ensure that the bridge resources are properly sized and assigned during the rescan.

---

 drivers/pci/hotplug-pci.c |   16 ++++++++++++----
 1 files changed, 12 insertions(+), 4 deletions(-)
drivers/pci/hotplug-pci.c +12 -4
index 4d4a644..33ab2d2 100644
@@ -6,13 +6,21 @@
 
 unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus)
 {
-	unsigned int max;
+	unsigned int max, pass;
+	struct pci_dev *dev;
 
 	max = pci_scan_child_bus(bus);
 
-	/*
-	 * Make the discovered devices available.
-	 */
+	for (pass=0; pass < 2; pass++)
+		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 (pass && dev->subordinate)
+					pci_bus_size_bridges(dev->subordinate);
+		}
+
+	pci_bus_assign_resources(bus);
+	pci_enable_bridges(bus);
 	pci_bus_add_devices(bus);
 
 	return max;
#6 lore raw

RFC PATCH v2 6/12 PCI: Introduce /sys/bus/pci/rescan

In reply to Alex Chiang

This interface allows the user to force a rescan of all PCI buses in system, and rediscover devices that have been removed earlier.

---

 Documentation/ABI/testing/sysfs-bus-pci |    9 +++++++++
 drivers/pci/pci-sysfs.c                 |   26 ++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 0 deletions(-)
Documentation/ABI/testing/sysfs-bus-pci +9 -0
index ceddcff..ba15e2e 100644
@@ -1,3 +1,12 @@
+What:		/sys/bus/pci/rescan
+Date:		January 2009
+Contact:	Linux PCI developers <[email protected]>
+Description:
+		Writing a non-zero value to this attribute will
+		force a rescan of all PCI buses in the system, and
+		re-discover previously removed devices.
+		Depends on CONFIG_HOTPLUG.
+
 What:		/sys/bus/pci/devices/.../vpd
 Date:		February 2008
 Contact:	Ben Hutchings <[email protected]>
drivers/pci/pci-sysfs.c +26 -0
index db7ec14..a2d85f6 100644
@@ -956,12 +956,38 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
 	}
 }
 
+#ifdef CONFIG_HOTPLUG
+static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf, size_t count)
+{
+	unsigned long val;
+	struct pci_bus *b = NULL;
+
+	if (strict_strtoul(buf, 0, &val) < 0)
+		return -EINVAL;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (val)
+		while ((b = pci_find_next_bus(b)) != NULL)
+			pci_do_scan_bus(b);
+
+	return count;
+}
+static BUS_ATTR(rescan, S_IWUSR, NULL, bus_rescan_store);
+#endif
+
 static int __init pci_sysfs_init(void)
 {
 	struct pci_dev *pdev = NULL;
 	int retval;
 
 	sysfs_initialized = 1;
+#ifdef CONFIG_HOTPLUG
+	retval = bus_create_file(&pci_bus_type, &bus_attr_rescan);
+	if (retval)
+		return retval;
+#endif
 	for_each_pci_dev(pdev) {
 		retval = pci_create_sysfs_dev_files(pdev);
 		if (retval) {
#7 lore raw

RFC PATCH v2 7/12 PCI: Introduce /sys/bus/pci/devices/.../remove

In reply to Alex Chiang

From: Trent Piepho <[email protected]>

This patch adds an attribute named "remove" to a PCI device's sysfs directory. Writing a non-zero value to this attribute will remove the PCI device and any children of it.

[[email protected]: document in Documentation/ABI]
[[email protected]: add #ifdef CONFIG_HOTPLUG]
[[email protected]: need final pci_dev_put in remove_callback]

---

 Documentation/ABI/testing/sysfs-bus-pci |    8 ++++++++
 Documentation/filesystems/sysfs-pci.txt |    9 +++++++++
 drivers/pci/pci-sysfs.c                 |   32 +++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 0 deletions(-)
Documentation/ABI/testing/sysfs-bus-pci +8 -0
index ba15e2e..8c0abc7 100644
@@ -7,6 +7,14 @@ Description:
 		re-discover previously removed devices.
 		Depends on CONFIG_HOTPLUG.
 
+What:		/sys/bus/pci/devices/.../remove
+Date:		January 2009
+Contact:	Linux PCI developers <[email protected]>
+Description:
+		Writing a non-zero value to this attribute will
+		hot-remove the PCI device and any of its children.
+		Depends on CONFIG_HOTPLUG.
+
 What:		/sys/bus/pci/devices/.../vpd
 Date:		February 2008
 Contact:	Ben Hutchings <[email protected]>
Documentation/filesystems/sysfs-pci.txt +9 -0
index 68ef488..54e014f 100644
@@ -11,6 +11,7 @@ that support it.  For example, a given bus might look like this:
      |   |-- device
      |   |-- irq
      |   |-- local_cpus
+     |   |-- remove
      |   |-- resource
      |   |-- resource0
      |   |-- resource1
@@ -34,6 +35,7 @@ files, each with their own function.
        device		   PCI device (ascii, ro)
        irq		   IRQ number (ascii, ro)
        local_cpus	   nearby CPU mask (cpumask, ro)
+       remove		   remove device from kernel's list (ascii, wo)
        resource		   PCI resource host addresses (ascii, ro)
        resource0..N	   PCI resource N, if present (binary, mmap)
        resource0_wc..N_wc  PCI WC map resource N, if prefetchable (binary, mmap)
@@ -44,6 +46,7 @@ files, each with their own function.
 
   ro - read only file
   rw - file is readable and writable
+  wo - write only file
   mmap - file is mmapable
   ascii - file contains ascii text
   binary - file contains binary data
@@ -62,6 +65,12 @@ ROM file, if available.  It's disabled by default, however, so applications
 should write the string "1" to the file to enable it before attempting a read
 call, and disable it following the access by writing "0" to the file.
 
+The 'remove' file is used to remove the PCI device, by writing a non-zero
+integer to the file.  This does not involve any kind of hot-plug functionality,
+e.g. powering off the device.  The device is removed from the kernel's list of
+PCI devices, the sysfs directory for it removed, and the device will be removed
+from any drivers attached to it.
+
 Accessing legacy resources through sysfs
 ----------------------------------------
 
drivers/pci/pci-sysfs.c +32 -0
index a2d85f6..e4d2c0d 100644
@@ -219,6 +219,35 @@ msi_bus_store(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
+#ifdef CONFIG_HOTPLUG
+static void remove_callback(void *data)
+{
+	struct pci_dev *pdev = (struct pci_dev *)data;
+	pci_remove_bus_device(pdev);
+	pci_dev_put(pdev);
+}
+
+static ssize_t
+remove_store(struct device *dev, struct device_attribute *dummy,
+	     const char *buf, size_t count)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	unsigned long val;
+
+	if (strict_strtoul(buf, 0, &val) < 0)
+		return -EINVAL;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (val)
+		sysfs_schedule_callback(&dev->kobj, remove_callback, pdev,
+		                        THIS_MODULE);
+
+	return count;
+}
+#endif
+
 struct device_attribute pci_dev_attrs[] = {
 	__ATTR_RO(resource),
 	__ATTR_RO(vendor),
@@ -237,6 +266,9 @@ struct device_attribute pci_dev_attrs[] = {
 	__ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
 		broken_parity_status_show,broken_parity_status_store),
 	__ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),
+#ifdef CONFIG_HOTPLUG
+	__ATTR(remove, S_IWUSR, NULL, remove_store),
+#endif
 	__ATTR_NULL,
 };
 
#8 lore raw

RFC PATCH v2 8/12 PCI: Introduce /sys/bus/pci/devices/.../rescan

In reply to Alex Chiang

This interface allows the user to force a rescan of the device's parent bus and all subordinate buses, and rediscover devices removed earlier from this part of the device tree.

---

 Documentation/ABI/testing/sysfs-bus-pci |   10 ++++++++++
 drivers/pci/pci-sysfs.c                 |   20 ++++++++++++++++++++
 2 files changed, 30 insertions(+), 0 deletions(-)
Documentation/ABI/testing/sysfs-bus-pci +10 -0
index 8c0abc7..f59e963 100644
@@ -15,6 +15,16 @@ Description:
 		hot-remove the PCI device and any of its children.
 		Depends on CONFIG_HOTPLUG.
 
+What:		/sys/bus/pci/devices/.../rescan
+Date:		January 2009
+Contact:	Linux PCI developers <[email protected]>
+Description:
+		Writing a non-zero value to this attribute will
+		force a rescan of the device's parent bus 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/.../vpd
 Date:		February 2008
 Contact:	Ben Hutchings <[email protected]>
drivers/pci/pci-sysfs.c +20 -0
index e4d2c0d..6e5f141 100644
@@ -220,6 +220,25 @@ msi_bus_store(struct device *dev, struct device_attribute *attr,
 }
 
 #ifdef CONFIG_HOTPLUG
+static ssize_t
+dev_rescan_store(struct device *dev, struct device_attribute *attr,
+	      const char *buf, size_t count)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	unsigned long val;
+
+	if (strict_strtoul(buf, 0, &val) < 0)
+		return -EINVAL;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (val)
+		pci_do_scan_bus(pdev->bus);
+
+	return count;
+}
+
 static void remove_callback(void *data)
 {
 	struct pci_dev *pdev = (struct pci_dev *)data;
@@ -268,6 +287,7 @@ struct device_attribute pci_dev_attrs[] = {
 	__ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),
 #ifdef CONFIG_HOTPLUG
 	__ATTR(remove, S_IWUSR, NULL, remove_store),
+	__ATTR(rescan, S_IWUSR, NULL, dev_rescan_store),
 #endif
 	__ATTR_NULL,
 };
#9 lore raw

RFC PATCH v2 9/12 PCI Hotplug: restore fakephp interface with complete reimplementation

In reply to Alex Chiang

From: Trent Piepho <[email protected]>

A complete re-implementation of fakephp is necessary if it is to present its former interface (pre-2.6.27, when it broke). The reason is that PCI hotplug drivers call pci_hp_register(), which enforces the rule that only one /sys/bus/pci/slots/ file may be created per physical slot.

The change breaks the old fakephp's assumption that it could create a file per function. So we re-implement fakephp to avoid using the standard PCI hotplug API so that we can restore the old fakephp user interface.

It puts entries in /sys/bus/pci/slots with the names of all PCI devices/functions, exactly symmetrical to what is shown in /sys/bus/pci/devices. Each slots/ entry has a "power" attribute, which works the same way as the fakephp driver's power attribute has worked.

There are a few improvements over old fakephp, which couldn't handle PCI devices being added or removed via a means outside of fakephp's knowledge. If a device was added another way, old fakephp didn't notice and didn't create the fake slot for it. If a device was removed another way, old fakephp didn't delete the fake slot for it (and accessing the stale slot caused an oops).

The new implementation overcomes these limitations. As a consequence, removing a bridge with other devices behind it now works as well, which is something else old fakephp couldn't do previously.

This duplicates a tiny bit of the code in the PCI core that does this same function. Re-using that code ends up being more complex than duplicating it, and it makes code in the PCI core more ugly just to support this legacy fakephp interface compatibility layer.

---

 drivers/pci/hotplug/Makefile         |    2 
 drivers/pci/hotplug/fakephp.c        |  395 ----------------------------------
 drivers/pci/hotplug/legacy_fakephp.c |  162 ++++++++++++++
 3 files changed, 163 insertions(+), 396 deletions(-)
 delete mode 100644 drivers/pci/hotplug/fakephp.c
 create mode 100644 drivers/pci/hotplug/legacy_fakephp.c
drivers/pci/hotplug/Makefile +1 -1
index 2aa117c..3314fe8 100644
@@ -20,7 +20,7 @@ obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR)	+= rpadlpar_io.o
 obj-$(CONFIG_HOTPLUG_PCI_SGI)		+= sgi_hotplug.o
 
 # Link this last so it doesn't claim devices that have a real hotplug driver
-obj-$(CONFIG_HOTPLUG_PCI_FAKE)		+= fakephp.o
+obj-$(CONFIG_HOTPLUG_PCI_FAKE)		+= legacy_fakephp.o
 
 pci_hotplug-objs	:=	pci_hotplug_core.o
 
drivers/pci/hotplug/fakephp.c deleted +0 -395

395 lines not on this page · raw message

drivers/pci/hotplug/legacy_fakephp.c new file +162 -0

162 lines not on this page · raw message

#10 lore raw

RFC PATCH v2 10/12 PCI Hotplug: rename legacy_fakephp to fakephp

In reply to Alex Chiang

We wanted to replace fakephp wholesale, so rename legacy_fakephp back to fakephp. Yes, this is a silly commit, but it produces a much easier patch to read and review.

---

 drivers/pci/hotplug/Makefile         |    2 
 drivers/pci/hotplug/fakephp.c        |  162 ++++++++++++++++++++++++++++++++++
 drivers/pci/hotplug/legacy_fakephp.c |  162 ----------------------------------
 3 files changed, 163 insertions(+), 163 deletions(-)
 create mode 100644 drivers/pci/hotplug/fakephp.c
 delete mode 100644 drivers/pci/hotplug/legacy_fakephp.c
drivers/pci/hotplug/Makefile +1 -1
index 3314fe8..2aa117c 100644
@@ -20,7 +20,7 @@ obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR)	+= rpadlpar_io.o
 obj-$(CONFIG_HOTPLUG_PCI_SGI)		+= sgi_hotplug.o
 
 # Link this last so it doesn't claim devices that have a real hotplug driver
-obj-$(CONFIG_HOTPLUG_PCI_FAKE)		+= legacy_fakephp.o
+obj-$(CONFIG_HOTPLUG_PCI_FAKE)		+= fakephp.o
 
 pci_hotplug-objs	:=	pci_hotplug_core.o
 
drivers/pci/hotplug/fakephp.c new file +162 -0

162 lines not on this page · raw message

drivers/pci/hotplug/legacy_fakephp.c deleted +0 -162

162 lines not on this page · raw message

#11 lore raw

RFC PATCH v2 11/12 PCI Hotplug: schedule fakephp for feature removal

In reply to Alex Chiang

Now that the PCI core is capable of function-level remove and rescan as well as bus-level rescan, there's no functional need to keep fakephp anymore.

We keep it around for userspace compatibility reasons, schedule removal in three years.

---

 Documentation/feature-removal-schedule.txt |   32 ++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)
Documentation/feature-removal-schedule.txt +32 -0
index 5ddbe35..fc3505b 100644
@@ -335,3 +335,35 @@ Why:	In 2.6.18 the Secmark concept was introduced to replace the "compat_net"
 	Secmark, it is time to deprecate the older mechanism and start the
 	process of removing the old code.
 Who:	Paul Moore <[email protected]>
+
+---------------------------
+
+What:	fakephp and associated sysfs files in /sys/bus/pci/slots/
+When:	2011
+Why:	In 2.6.27, the semantics of /sys/bus/pci/slots was redefined to
+	represent a machine's physical PCI slots. The change in semantics
+	had userspace implications, as the hotplug core no longer allowed
+	drivers to create multiple sysfs files per physical slot (required
+	for multi-function devices, e.g.). fakephp was seen as a developer's
+	tool only, and its interface changed. Too late, we learned that
+	there were some users of the fakephp interface.
+
+	In 2.6.30, the original fakephp interface was restored. At the same
+	time, the PCI core gained the ability that fakephp provided, namely
+	function-level hot-remove and hot-add.
+
+	Since the PCI core now provides the same functionality, exposed in:
+
+		/sys/bus/pci/rescan
+		/sys/bus/pci/devices/.../remove
+		/sys/bus/pci/devices/.../rescan
+
+	there is no functional reason to maintain fakephp as well.
+
+	We will keep the existing module so that 'modprobe fakephp' will
+	present the old /sys/bus/pci/slots/... interface for compatibility,
+	but users are urged to migrate their applications to the API above.
+
+	After a reasonable transition period, we will remove the legacy
+	fakephp interface.
+Who:	Alex Chiang <[email protected]>
#12 lore raw

RFC PATCH v2 12/12 PCI: more whitespace cleanups

In reply to Alex Chiang

Clean up some stray whitespace issues.

---

 drivers/pci/pci-sysfs.c |   18 +++++++++---------
 drivers/pci/probe.c     |   16 +++++++++-------
 drivers/pci/remove.c    |    4 ++--
 3 files changed, 20 insertions(+), 18 deletions(-)
drivers/pci/pci-sysfs.c +9 -9
index 6e5f141..42121ec 100644
@@ -10,7 +10,7 @@
  *
  * File attributes for PCI devices
  *
- * Modeled after usb's driverfs.c 
+ * Modeled after usb's driverfs.c
  *
  */
 
@@ -70,7 +70,7 @@ static ssize_t broken_parity_status_store(struct device *dev,
 
 static ssize_t local_cpus_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
-{		
+{
 	const struct cpumask *mask;
 	int len;
 
@@ -380,13 +380,13 @@ pci_write_config(struct kobject *kobj, struct bin_attribute *bin_attr,
 		size = dev->cfg_size - off;
 		count = size;
 	}
-	
+
 	if ((off & 1) && size) {
 		pci_user_write_config_byte(dev, off, data[off - init_off]);
 		off++;
 		size--;
 	}
-	
+
 	if ((off & 3) && size > 2) {
 		u16 val = data[off - init_off];
 		val |= (u16) data[off - init_off + 1] << 8;
@@ -404,7 +404,7 @@ pci_write_config(struct kobject *kobj, struct bin_attribute *bin_attr,
 		off += 4;
 		size -= 4;
 	}
-	
+
 	if (size >= 2) {
 		u16 val = data[off - init_off];
 		val |= (u16) data[off - init_off + 1] << 8;
@@ -818,21 +818,21 @@ pci_read_rom(struct kobject *kobj, struct bin_attribute *bin_attr,
 
 	if (!pdev->rom_attr_enabled)
 		return -EINVAL;
-	
+
 	rom = pci_map_rom(pdev, &size);	/* size starts out as PCI window size */
 	if (!rom)
 		return 0;
-		
+
 	if (off >= size)
 		count = 0;
 	else {
 		if (off + count > size)
 			count = size - off;
-		
+
 		memcpy_fromio(buf, rom + off, count);
 	}
 	pci_unmap_rom(pdev, rom);
-		
+
 	return count;
 }
 
drivers/pci/probe.c +9 -7
index d2bd1b0..d853abe 100644
@@ -494,7 +494,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
 	}
 
 	/* Disable MasterAbortMode during probing to avoid reporting
-	   of bus errors (in some architectures) */ 
+	   of bus errors (in some architectures) */
 	pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bctl);
 	pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
 			      bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
@@ -570,7 +570,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
 			buses &= ~0xff000000;
 			buses |= CARDBUS_LATENCY_TIMER << 24;
 		}
-			
+
 		/*
 		 * We need to blast all three values with a single write.
 		 */
@@ -680,7 +680,7 @@ static void pci_read_irq(struct pci_dev *dev)
  * pci_setup_device - fill in class and map information of a device
  * @dev: the device structure to fill
  *
- * Initialize the device structure with information about the device's 
+ * Initialize the device structure with information about the device's
  * vendor,class,memory and IO-space addresses,IRQ lines etc.
  * Called at initialisation of the PCI subsystem and by CardBus services.
  * Returns 0 on success and -1 if unknown type of device (not normal, bridge
@@ -720,8 +720,8 @@ static int pci_setup_device(struct pci_dev * dev)
 		pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device);
 
 		/*
-		 *	Do the ugly legacy mode stuff here rather than broken chip
-		 *	quirk code. Legacy mode ATA controllers have fixed
+		 *	Do the ugly legacy mode stuff here rather than broken
+		 *	chip quirk code. Legacy mode ATA controllers have fixed
 		 *	addresses. These are not always echoed in BAR0-3, and
 		 *	BAR0-3 in a few cases contain junk!
 		 */
@@ -752,7 +752,7 @@ static int pci_setup_device(struct pci_dev * dev)
 			goto bad;
 		/* The PCI-to-PCI bridge spec requires that subtractive
 		   decoding (i.e. transparent) bridge must have programming
-		   interface code of 0x01. */ 
+		   interface code of 0x01. */
 		pci_read_irq(dev);
 		dev->transparent = ((dev->class & 0xff) == 1);
 		pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
@@ -1126,7 +1126,9 @@ struct pci_bus * pci_create_bus(struct device *parent,
 	b->ops = ops;
 
 	if (pci_find_bus(pci_domain_nr(b), bus)) {
-		/* If we already got to this bus through a different bridge, ignore it */
+		/* If we already got to this bus through a different bridge,
+		 * ignore it
+		 */
 		pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);
 		goto err_out;
 	}
drivers/pci/remove.c +2 -2
index 042e089..ba58128 100644
@@ -7,7 +7,7 @@ static void pci_free_resources(struct pci_dev *dev)
 {
 	int i;
 
- 	msi_remove_pci_irq_vectors(dev);
+	msi_remove_pci_irq_vectors(dev);
 
 	pci_cleanup_rom(dev);
 	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
@@ -49,7 +49,7 @@ static void pci_destroy_dev(struct pci_dev *dev)
  * pci_remove_device_safe - remove an unused hotplug device
  * @dev: the device to remove
  *
- * Delete the device structure from the device lists and 
+ * Delete the device structure from the device lists and
  * notify userspace (/sbin/hotplug), but only if the device
  * in question is not being used by a driver.
  * Returns 0 on success.