|
@@ -499,6 +499,45 @@ static struct device_attribute sriov_numvfs_attr =
|
|
|
sriov_numvfs_show, sriov_numvfs_store);
|
|
|
#endif /* CONFIG_PCI_IOV */
|
|
|
|
|
|
+static ssize_t driver_override_store(struct device *dev,
|
|
|
+ struct device_attribute *attr,
|
|
|
+ const char *buf, size_t count)
|
|
|
+{
|
|
|
+ struct pci_dev *pdev = to_pci_dev(dev);
|
|
|
+ char *driver_override, *old = pdev->driver_override, *cp;
|
|
|
+
|
|
|
+ if (count > PATH_MAX)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ driver_override = kstrndup(buf, count, GFP_KERNEL);
|
|
|
+ if (!driver_override)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ cp = strchr(driver_override, '\n');
|
|
|
+ if (cp)
|
|
|
+ *cp = '\0';
|
|
|
+
|
|
|
+ if (strlen(driver_override)) {
|
|
|
+ pdev->driver_override = driver_override;
|
|
|
+ } else {
|
|
|
+ kfree(driver_override);
|
|
|
+ pdev->driver_override = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ kfree(old);
|
|
|
+
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t driver_override_show(struct device *dev,
|
|
|
+ struct device_attribute *attr, char *buf)
|
|
|
+{
|
|
|
+ struct pci_dev *pdev = to_pci_dev(dev);
|
|
|
+
|
|
|
+ return sprintf(buf, "%s\n", pdev->driver_override);
|
|
|
+}
|
|
|
+static DEVICE_ATTR_RW(driver_override);
|
|
|
+
|
|
|
static struct attribute *pci_dev_attrs[] = {
|
|
|
&dev_attr_resource.attr,
|
|
|
&dev_attr_vendor.attr,
|
|
@@ -521,6 +560,7 @@ static struct attribute *pci_dev_attrs[] = {
|
|
|
#if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI)
|
|
|
&dev_attr_d3cold_allowed.attr,
|
|
|
#endif
|
|
|
+ &dev_attr_driver_override.attr,
|
|
|
NULL,
|
|
|
};
|
|
|
|