aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Chiang <achiang@hp.com>2009-03-20 16:56:36 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-03-20 17:58:48 -0400
commit77c27c7b49d69d45ccb94e481653f024f1ac6650 (patch)
tree8f2e7a6f3971e3630ad1d219bee1c673597158fe
parent705b1aaa823e800490f157cd9366ad8cff385f5f (diff)
PCI: Introduce /sys/bus/pci/devices/.../remove
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. Trent Piepho wrote the original implementation and documentation. Thanks to Vegard Nossum for testing under kmemcheck and finding locking issues with the sysfs interface. Cc: Trent Piepho <xyzzy@speakeasy.org> Tested-by: Vegard Nossum <vegard.nossum@gmail.com> Signed-off-by: Alex Chiang <achiang@hp.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r--Documentation/ABI/testing/sysfs-bus-pci8
-rw-r--r--Documentation/filesystems/sysfs-pci.txt10
-rw-r--r--drivers/pci/pci-sysfs.c36
3 files changed, 54 insertions, 0 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci
index e6ad047cb3c2..daa791a9e85e 100644
--- a/Documentation/ABI/testing/sysfs-bus-pci
+++ b/Documentation/ABI/testing/sysfs-bus-pci
@@ -66,6 +66,14 @@ Description:
66 re-discover previously removed devices. 66 re-discover previously removed devices.
67 Depends on CONFIG_HOTPLUG. 67 Depends on CONFIG_HOTPLUG.
68 68
69What: /sys/bus/pci/devices/.../remove
70Date: January 2009
71Contact: Linux PCI developers <linux-pci@vger.kernel.org>
72Description:
73 Writing a non-zero value to this attribute will
74 hot-remove the PCI device and any of its children.
75 Depends on CONFIG_HOTPLUG.
76
69What: /sys/bus/pci/devices/.../vpd 77What: /sys/bus/pci/devices/.../vpd
70Date: February 2008 78Date: February 2008
71Contact: Ben Hutchings <bhutchings@solarflare.com> 79Contact: Ben Hutchings <bhutchings@solarflare.com>
diff --git a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt
index 9f8740ca3f3b..26e4b8bc53ee 100644
--- a/Documentation/filesystems/sysfs-pci.txt
+++ b/Documentation/filesystems/sysfs-pci.txt
@@ -12,6 +12,7 @@ that support it. For example, a given bus might look like this:
12 | |-- enable 12 | |-- enable
13 | |-- irq 13 | |-- irq
14 | |-- local_cpus 14 | |-- local_cpus
15 | |-- remove
15 | |-- resource 16 | |-- resource
16 | |-- resource0 17 | |-- resource0
17 | |-- resource1 18 | |-- resource1
@@ -36,6 +37,7 @@ files, each with their own function.
36 enable Whether the device is enabled (ascii, rw) 37 enable Whether the device is enabled (ascii, rw)
37 irq IRQ number (ascii, ro) 38 irq IRQ number (ascii, ro)
38 local_cpus nearby CPU mask (cpumask, ro) 39 local_cpus nearby CPU mask (cpumask, ro)
40 remove remove device from kernel's list (ascii, wo)
39 resource PCI resource host addresses (ascii, ro) 41 resource PCI resource host addresses (ascii, ro)
40 resource0..N PCI resource N, if present (binary, mmap) 42 resource0..N PCI resource N, if present (binary, mmap)
41 resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap) 43 resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap)
@@ -46,6 +48,7 @@ files, each with their own function.
46 48
47 ro - read only file 49 ro - read only file
48 rw - file is readable and writable 50 rw - file is readable and writable
51 wo - write only file
49 mmap - file is mmapable 52 mmap - file is mmapable
50 ascii - file contains ascii text 53 ascii - file contains ascii text
51 binary - file contains binary data 54 binary - file contains binary data
@@ -73,6 +76,13 @@ that the device must be enabled for a rom read to return data succesfully.
73In the event a driver is not bound to the device, it can be enabled using the 76In the event a driver is not bound to the device, it can be enabled using the
74'enable' file, documented above. 77'enable' file, documented above.
75 78
79The 'remove' file is used to remove the PCI device, by writing a non-zero
80integer to the file. This does not involve any kind of hot-plug functionality,
81e.g. powering off the device. The device is removed from the kernel's list of
82PCI devices, the sysfs directory for it is removed, and the device will be
83removed from any drivers attached to it. Removal of PCI root buses is
84disallowed.
85
76Accessing legacy resources through sysfs 86Accessing legacy resources through sysfs
77---------------------------------------- 87----------------------------------------
78 88
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index be7468a5eb72..e16990ecc024 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -243,6 +243,39 @@ struct bus_attribute pci_bus_attrs[] = {
243 __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, bus_rescan_store), 243 __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, bus_rescan_store),
244 __ATTR_NULL 244 __ATTR_NULL
245}; 245};
246
247static void remove_callback(struct device *dev)
248{
249 struct pci_dev *pdev = to_pci_dev(dev);
250
251 mutex_lock(&pci_remove_rescan_mutex);
252 pci_remove_bus_device(pdev);
253 mutex_unlock(&pci_remove_rescan_mutex);
254}
255
256static ssize_t
257remove_store(struct device *dev, struct device_attribute *dummy,
258 const char *buf, size_t count)
259{
260 int ret = 0;
261 unsigned long val;
262 struct pci_dev *pdev = to_pci_dev(dev);
263
264 if (strict_strtoul(buf, 0, &val) < 0)
265 return -EINVAL;
266
267 if (pci_is_root_bus(pdev->bus))
268 return -EBUSY;
269
270 /* An attribute cannot be unregistered by one of its own methods,
271 * so we have to use this roundabout approach.
272 */
273 if (val)
274 ret = device_schedule_callback(dev, remove_callback);
275 if (ret)
276 count = ret;
277 return count;
278}
246#endif 279#endif
247 280
248struct device_attribute pci_dev_attrs[] = { 281struct device_attribute pci_dev_attrs[] = {
@@ -263,6 +296,9 @@ struct device_attribute pci_dev_attrs[] = {
263 __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR), 296 __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
264 broken_parity_status_show,broken_parity_status_store), 297 broken_parity_status_show,broken_parity_status_store),
265 __ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store), 298 __ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),
299#ifdef CONFIG_HOTPLUG
300 __ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store),
301#endif
266 __ATTR_NULL, 302 __ATTR_NULL,
267}; 303};
268 304