aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-sysfs.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2014-10-01 14:31:46 -0400
committerBjorn Helgaas <bhelgaas@google.com>2014-10-01 14:31:46 -0400
commit359c660e99d1431a9b08b240bfc31acc3d658efe (patch)
tree4cb575bf7873b767b6c269cd90bda5b0d7c7294d /drivers/pci/pci-sysfs.c
parent07a7cbd3b815ea77b44d4d5bb4260b37d03a358d (diff)
parent5ec094057c7df5ff80f5e7fe282f47ad205fb976 (diff)
Merge branch 'pci/msi' into next
* pci/msi: PCI/MSI: Remove unnecessary temporary variable PCI/MSI: Use __write_msi_msg() instead of write_msi_msg() MSI/powerpc: Use __read_msi_msg() instead of read_msi_msg() PCI/MSI: Use __get_cached_msi_msg() instead of get_cached_msi_msg() PCI/MSI: Add "msi_bus" sysfs MSI/MSI-X control for endpoints PCI/MSI: Remove "pos" from the struct msi_desc msi_attrib PCI/MSI: Remove unused kobject from struct msi_desc PCI/MSI: Rename pci_msi_check_device() to pci_msi_supported() PCI/MSI: Move D0 check into pci_msi_check_device() PCI/MSI: Remove arch_msi_check_device() irqchip: armada-370-xp: Remove arch_msi_check_device() PCI/MSI/PPC: Remove arch_msi_check_device() Conflicts: drivers/pci/host/pcie-designware.c
Diffstat (limited to 'drivers/pci/pci-sysfs.c')
-rw-r--r--drivers/pci/pci-sysfs.c39
1 files changed, 19 insertions, 20 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 76ef7914c9aa..92b6d9ab00e4 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -250,46 +250,45 @@ static ssize_t msi_bus_show(struct device *dev, struct device_attribute *attr,
250 char *buf) 250 char *buf)
251{ 251{
252 struct pci_dev *pdev = to_pci_dev(dev); 252 struct pci_dev *pdev = to_pci_dev(dev);
253 struct pci_bus *subordinate = pdev->subordinate;
253 254
254 if (!pdev->subordinate) 255 return sprintf(buf, "%u\n", subordinate ?
255 return 0; 256 !(subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI)
256 257 : !pdev->no_msi);
257 return sprintf(buf, "%u\n",
258 !(pdev->subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI));
259} 258}
260 259
261static ssize_t msi_bus_store(struct device *dev, struct device_attribute *attr, 260static ssize_t msi_bus_store(struct device *dev, struct device_attribute *attr,
262 const char *buf, size_t count) 261 const char *buf, size_t count)
263{ 262{
264 struct pci_dev *pdev = to_pci_dev(dev); 263 struct pci_dev *pdev = to_pci_dev(dev);
264 struct pci_bus *subordinate = pdev->subordinate;
265 unsigned long val; 265 unsigned long val;
266 266
267 if (kstrtoul(buf, 0, &val) < 0) 267 if (kstrtoul(buf, 0, &val) < 0)
268 return -EINVAL; 268 return -EINVAL;
269 269
270 /*
271 * Bad things may happen if the no_msi flag is changed
272 * while drivers are loaded.
273 */
274 if (!capable(CAP_SYS_ADMIN)) 270 if (!capable(CAP_SYS_ADMIN))
275 return -EPERM; 271 return -EPERM;
276 272
277 /* 273 /*
278 * Maybe devices without subordinate buses shouldn't have this 274 * "no_msi" and "bus_flags" only affect what happens when a driver
279 * attribute in the first place? 275 * requests MSI or MSI-X. They don't affect any drivers that have
276 * already requested MSI or MSI-X.
280 */ 277 */
281 if (!pdev->subordinate) 278 if (!subordinate) {
279 pdev->no_msi = !val;
280 dev_info(&pdev->dev, "MSI/MSI-X %s for future drivers\n",
281 val ? "allowed" : "disallowed");
282 return count; 282 return count;
283
284 /* Is the flag going to change, or keep the value it already had? */
285 if (!(pdev->subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI) ^
286 !!val) {
287 pdev->subordinate->bus_flags ^= PCI_BUS_FLAGS_NO_MSI;
288
289 dev_warn(&pdev->dev, "forced subordinate bus to%s support MSI, bad things could happen\n",
290 val ? "" : " not");
291 } 283 }
292 284
285 if (val)
286 subordinate->bus_flags &= ~PCI_BUS_FLAGS_NO_MSI;
287 else
288 subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
289
290 dev_info(&subordinate->dev, "MSI/MSI-X %s for future drivers of devices on this bus\n",
291 val ? "allowed" : "disallowed");
293 return count; 292 return count;
294} 293}
295static DEVICE_ATTR_RW(msi_bus); 294static DEVICE_ATTR_RW(msi_bus);