return count;
}
+static ssize_t
+msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ if (!pdev->subordinate)
+ return 0;
+
+ return sprintf (buf, "%u\n",
+ !(pdev->subordinate->bus_flags & PCI_BUS_FLAGS_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);
+
+ /* bad things may happen if the no_msi flag is changed
+ * while some drivers are loaded */
+ if (!capable(CAP_SYS_ADMIN))
+ return count;
+
+ if (!pdev->subordinate)
+ return count;
+
+ if (*buf == '0') {
+ pdev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
+ dev_warn(&pdev->dev, "forced subordinate bus to not support MSI,"
+ " bad things could happen.\n");
+ }
+
+ if (*buf == '1') {
+ pdev->subordinate->bus_flags &= ~PCI_BUS_FLAGS_NO_MSI;
+ dev_warn(&pdev->dev, "forced subordinate bus to support MSI,"
+ " bad things could happen.\n");
+ }
+
+ return count;
+}
struct device_attribute pci_dev_attrs[] = {
__ATTR_RO(resource),
__ATTR(enable, 0600, is_enabled_show, is_enabled_store),
__ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
broken_parity_status_show,broken_parity_status_store),
+ __ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),
__ATTR_NULL,
};