aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrice Goglin <brice@myri.com>2006-08-31 01:55:15 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-09-26 20:43:52 -0400
commitfe97064c2870e174a6ff4a93feb11a70c4b71cc5 (patch)
tree1ce4aff048e1b1a428444b7ae087dba8519854de
parent24334a12533e9ac70dcb467ccd629f190afc5361 (diff)
MSI: Export the PCI_BUS_FLAGS_NO_MSI flag in sysfs
Export the PCI_BUS_FLAGS_NO_MSI flag of a PCI bus in the sysfs files of its parent device and make it writable. Could be used to: * disable MSI on a device which has not been blacklisted yet * allow MSI when some setpci hacks enable MSI support (for instance on the ServerWorks HT2000 chipset where the MSI HT cap is disabled by default). Architecture where some bus have no parent chipset cannot use this strategy to change MSI support. If the chipset does not have a subordinate bus, its 'bus_msi' file is empty. Also document and warn about the possible danger of changing the flag. Signed-off-by: Brice Goglin <brice@myri.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/pci/pci-sysfs.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index fdefa7dcd156..010e01c4bd43 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -131,6 +131,46 @@ is_enabled_store(struct device *dev, struct device_attribute *attr,
131 return count; 131 return count;
132} 132}
133 133
134static ssize_t
135msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf)
136{
137 struct pci_dev *pdev = to_pci_dev(dev);
138
139 if (!pdev->subordinate)
140 return 0;
141
142 return sprintf (buf, "%u\n",
143 !(pdev->subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI));
144}
145
146static ssize_t
147msi_bus_store(struct device *dev, struct device_attribute *attr,
148 const char *buf, size_t count)
149{
150 struct pci_dev *pdev = to_pci_dev(dev);
151
152 /* bad things may happen if the no_msi flag is changed
153 * while some drivers are loaded */
154 if (!capable(CAP_SYS_ADMIN))
155 return count;
156
157 if (!pdev->subordinate)
158 return count;
159
160 if (*buf == '0') {
161 pdev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
162 dev_warn(&pdev->dev, "forced subordinate bus to not support MSI,"
163 " bad things could happen.\n");
164 }
165
166 if (*buf == '1') {
167 pdev->subordinate->bus_flags &= ~PCI_BUS_FLAGS_NO_MSI;
168 dev_warn(&pdev->dev, "forced subordinate bus to support MSI,"
169 " bad things could happen.\n");
170 }
171
172 return count;
173}
134 174
135struct device_attribute pci_dev_attrs[] = { 175struct device_attribute pci_dev_attrs[] = {
136 __ATTR_RO(resource), 176 __ATTR_RO(resource),
@@ -145,6 +185,7 @@ struct device_attribute pci_dev_attrs[] = {
145 __ATTR(enable, 0600, is_enabled_show, is_enabled_store), 185 __ATTR(enable, 0600, is_enabled_show, is_enabled_store),
146 __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR), 186 __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
147 broken_parity_status_show,broken_parity_status_store), 187 broken_parity_status_show,broken_parity_status_store),
188 __ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),
148 __ATTR_NULL, 189 __ATTR_NULL,
149}; 190};
150 191