aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorAlex Chiang <achiang@hp.com>2009-03-20 16:56:41 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-03-20 17:59:07 -0400
commit738a6396c223b486304dda778119dbbca563f019 (patch)
treeee5f2801ed439d9d969598621de7d2b3ba8f8d0a /drivers/pci
parent77c27c7b49d69d45ccb94e481653f024f1ac6650 (diff)
PCI: Introduce /sys/bus/pci/devices/.../rescan
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. Cc: Trent Piepho <xyzzy@speakeasy.org> Signed-off-by: Alex Chiang <achiang@hp.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pci-sysfs.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index e16990ecc024..e9a8706a6401 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -244,6 +244,24 @@ struct bus_attribute pci_bus_attrs[] = {
244 __ATTR_NULL 244 __ATTR_NULL
245}; 245};
246 246
247static ssize_t
248dev_rescan_store(struct device *dev, struct device_attribute *attr,
249 const char *buf, size_t count)
250{
251 unsigned long val;
252 struct pci_dev *pdev = to_pci_dev(dev);
253
254 if (strict_strtoul(buf, 0, &val) < 0)
255 return -EINVAL;
256
257 if (val) {
258 mutex_lock(&pci_remove_rescan_mutex);
259 pci_rescan_bus(pdev->bus);
260 mutex_unlock(&pci_remove_rescan_mutex);
261 }
262 return count;
263}
264
247static void remove_callback(struct device *dev) 265static void remove_callback(struct device *dev)
248{ 266{
249 struct pci_dev *pdev = to_pci_dev(dev); 267 struct pci_dev *pdev = to_pci_dev(dev);
@@ -298,6 +316,7 @@ struct device_attribute pci_dev_attrs[] = {
298 __ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store), 316 __ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),
299#ifdef CONFIG_HOTPLUG 317#ifdef CONFIG_HOTPLUG
300 __ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store), 318 __ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store),
319 __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_rescan_store),
301#endif 320#endif
302 __ATTR_NULL, 321 __ATTR_NULL,
303}; 322};