summaryrefslogtreecommitdiff
path: root/drivers/pci/pci-sysfs.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2014-10-01 12:31:46 -0600
committerBjorn Helgaas <bhelgaas@google.com>2014-10-01 12:31:46 -0600
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,
char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
+ struct pci_bus *subordinate = pdev->subordinate;
- if (!pdev->subordinate)
- return 0;
-
- return sprintf(buf, "%u\n",
- !(pdev->subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI));
+ return sprintf(buf, "%u\n", subordinate ?
+ !(subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI)
+ : !pdev->no_msi);
}
static ssize_t msi_bus_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct pci_dev *pdev = to_pci_dev(dev);
+ struct pci_bus *subordinate = pdev->subordinate;
unsigned long val;
if (kstrtoul(buf, 0, &val) < 0)
return -EINVAL;
- /*
- * Bad things may happen if the no_msi flag is changed
- * while drivers are loaded.
- */
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
/*
- * Maybe devices without subordinate buses shouldn't have this
- * attribute in the first place?
+ * "no_msi" and "bus_flags" only affect what happens when a driver
+ * requests MSI or MSI-X. They don't affect any drivers that have
+ * already requested MSI or MSI-X.
*/
- if (!pdev->subordinate)
+ if (!subordinate) {
+ pdev->no_msi = !val;
+ dev_info(&pdev->dev, "MSI/MSI-X %s for future drivers\n",
+ val ? "allowed" : "disallowed");
return count;
-
- /* Is the flag going to change, or keep the value it already had? */
- if (!(pdev->subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI) ^
- !!val) {
- pdev->subordinate->bus_flags ^= PCI_BUS_FLAGS_NO_MSI;
-
- dev_warn(&pdev->dev, "forced subordinate bus to%s support MSI, bad things could happen\n",
- val ? "" : " not");
}
+ if (val)
+ subordinate->bus_flags &= ~PCI_BUS_FLAGS_NO_MSI;
+ else
+ subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
+
+ dev_info(&subordinate->dev, "MSI/MSI-X %s for future drivers of devices on this bus\n",
+ val ? "allowed" : "disallowed");
return count;
}
static DEVICE_ATTR_RW(msi_bus);