aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArjan van de Ven <arjan@linux.intel.com>2006-04-29 04:59:08 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-21 14:59:59 -0400
commit9f125d30487cea72542a84b4835c037163c7f3d5 (patch)
tree268a4592aaf2e6a43c82571dde4aae2cd2938100
parent75acfecaa031c0e1bc412cee4fe58ba49ff3406c (diff)
[PATCH] PCI: Add a "enable" sysfs attribute to the pci devices to allow userspace (Xorg) to enable devices without doing foul direct access
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>
-rw-r--r--drivers/pci/pci-sysfs.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 56ac2bc003c7..37897a8c95e0 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -43,6 +43,7 @@ pci_config_attr(subsystem_vendor, "0x%04x\n");
43pci_config_attr(subsystem_device, "0x%04x\n"); 43pci_config_attr(subsystem_device, "0x%04x\n");
44pci_config_attr(class, "0x%06x\n"); 44pci_config_attr(class, "0x%06x\n");
45pci_config_attr(irq, "%u\n"); 45pci_config_attr(irq, "%u\n");
46pci_config_attr(is_enabled, "%u\n");
46 47
47static ssize_t local_cpus_show(struct device *dev, 48static ssize_t local_cpus_show(struct device *dev,
48 struct device_attribute *attr, char *buf) 49 struct device_attribute *attr, char *buf)
@@ -90,6 +91,25 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
90 (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8), 91 (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8),
91 (u8)(pci_dev->class)); 92 (u8)(pci_dev->class));
92} 93}
94static ssize_t
95is_enabled_store(struct device *dev, struct device_attribute *attr,
96 const char *buf, size_t count)
97{
98 struct pci_dev *pdev = to_pci_dev(dev);
99
100 /* this can crash the machine when done on the "wrong" device */
101 if (!capable(CAP_SYS_ADMIN))
102 return count;
103
104 if (*buf == '0')
105 pci_disable_device(pdev);
106
107 if (*buf == '1')
108 pci_enable_device(pdev);
109
110 return count;
111}
112
93 113
94struct device_attribute pci_dev_attrs[] = { 114struct device_attribute pci_dev_attrs[] = {
95 __ATTR_RO(resource), 115 __ATTR_RO(resource),
@@ -101,6 +121,7 @@ struct device_attribute pci_dev_attrs[] = {
101 __ATTR_RO(irq), 121 __ATTR_RO(irq),
102 __ATTR_RO(local_cpus), 122 __ATTR_RO(local_cpus),
103 __ATTR_RO(modalias), 123 __ATTR_RO(modalias),
124 __ATTR(enable, 0600, is_enabled_show, is_enabled_store),
104 __ATTR_NULL, 125 __ATTR_NULL,
105}; 126};
106 127