[PATCH] PCI: Add a "enable" sysfs attribute to the pci devices to allow userspace...
authorArjan van de Ven <arjan@linux.intel.com>
Sat, 29 Apr 2006 08:59:08 +0000 (10:59 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 21 Jun 2006 18:59:59 +0000 (11:59 -0700)
This patch adds an "enable" sysfs attribute to each PCI device. When read it
shows the "enabled-ness" of the device, but you can write a "0" into it to
disable a device, and a "1" to enable it.

This later is needed for X and other cases where userspace wants to enable
the BARs on a device (typical example: to run the video bios on a secundary
head). Right now X does all this "by hand" via bitbanging, that's just evil.
This allows X to no longer do that but to just let the kernel do this.

Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
CC: Peter Jones <pjones@redhat.com>
Acked-by: Dave Airlie <airlied@linux.ie>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/pci/pci-sysfs.c

index 56ac2bc003c7fdae7ab2fe47d00b7a1e2670229a..37897a8c95e0ec4a5d9d59a970a9a10e5a566eb2 100644 (file)
@@ -43,6 +43,7 @@ pci_config_attr(subsystem_vendor, "0x%04x\n");
 pci_config_attr(subsystem_device, "0x%04x\n");
 pci_config_attr(class, "0x%06x\n");
 pci_config_attr(irq, "%u\n");
+pci_config_attr(is_enabled, "%u\n");
 
 static ssize_t local_cpus_show(struct device *dev,
                        struct device_attribute *attr, char *buf)
@@ -90,6 +91,25 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
                       (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8),
                       (u8)(pci_dev->class));
 }
+static ssize_t
+is_enabled_store(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t count)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+
+       /* this can crash the machine when done on the "wrong" device */
+       if (!capable(CAP_SYS_ADMIN))
+               return count;
+
+       if (*buf == '0')
+               pci_disable_device(pdev);
+
+       if (*buf == '1')
+               pci_enable_device(pdev);
+
+       return count;
+}
+
 
 struct device_attribute pci_dev_attrs[] = {
        __ATTR_RO(resource),
@@ -101,6 +121,7 @@ struct device_attribute pci_dev_attrs[] = {
        __ATTR_RO(irq),
        __ATTR_RO(local_cpus),
        __ATTR_RO(modalias),
+       __ATTR(enable, 0600, is_enabled_show, is_enabled_store),
        __ATTR_NULL,
 };