diff options
| -rw-r--r-- | Documentation/ABI/testing/sysfs-bus-pci | 8 | ||||
| -rw-r--r-- | Documentation/filesystems/sysfs-pci.txt | 10 | ||||
| -rw-r--r-- | drivers/pci/pci-sysfs.c | 36 |
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 | ||
| 69 | What: /sys/bus/pci/devices/.../remove | ||
| 70 | Date: January 2009 | ||
| 71 | Contact: Linux PCI developers <linux-pci@vger.kernel.org> | ||
| 72 | Description: | ||
| 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 | |||
| 69 | What: /sys/bus/pci/devices/.../vpd | 77 | What: /sys/bus/pci/devices/.../vpd |
| 70 | Date: February 2008 | 78 | Date: February 2008 |
| 71 | Contact: Ben Hutchings <bhutchings@solarflare.com> | 79 | Contact: 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. | |||
| 73 | In the event a driver is not bound to the device, it can be enabled using the | 76 | In 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 | ||
| 79 | The 'remove' file is used to remove the PCI device, by writing a non-zero | ||
| 80 | integer to the file. This does not involve any kind of hot-plug functionality, | ||
| 81 | e.g. powering off the device. The device is removed from the kernel's list of | ||
| 82 | PCI devices, the sysfs directory for it is removed, and the device will be | ||
| 83 | removed from any drivers attached to it. Removal of PCI root buses is | ||
| 84 | disallowed. | ||
| 85 | |||
| 76 | Accessing legacy resources through sysfs | 86 | Accessing 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 | |||
| 247 | static 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 | |||
| 256 | static ssize_t | ||
| 257 | remove_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 | ||
| 248 | struct device_attribute pci_dev_attrs[] = { | 281 | struct 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 | ||
