diff options
Diffstat (limited to 'drivers/pci/vpd.c')
| -rw-r--r-- | drivers/pci/vpd.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c index a4fc4d0690fe..153394a652d3 100644 --- a/drivers/pci/vpd.c +++ b/drivers/pci/vpd.c @@ -9,7 +9,7 @@ #include <linux/delay.h> #include <linux/export.h> #include <linux/sched/signal.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "pci.h" #define PCI_VPD_LRDT_TAG_SIZE 3 @@ -271,31 +271,61 @@ void pci_vpd_init(struct pci_dev *dev) } static ssize_t vpd_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, char *buf, loff_t off, - size_t count) + const struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj)); + struct pci_dev *vpd_dev = dev; + ssize_t ret; + + if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) { + vpd_dev = pci_get_func0_dev(dev); + if (!vpd_dev) + return -ENODEV; + } + + pci_config_pm_runtime_get(vpd_dev); + ret = pci_read_vpd(vpd_dev, off, count, buf); + pci_config_pm_runtime_put(vpd_dev); + + if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) + pci_dev_put(vpd_dev); - return pci_read_vpd(dev, off, count, buf); + return ret; } static ssize_t vpd_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, char *buf, loff_t off, - size_t count) + const struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) { struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj)); + struct pci_dev *vpd_dev = dev; + ssize_t ret; + + if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) { + vpd_dev = pci_get_func0_dev(dev); + if (!vpd_dev) + return -ENODEV; + } + + pci_config_pm_runtime_get(vpd_dev); + ret = pci_write_vpd(vpd_dev, off, count, buf); + pci_config_pm_runtime_put(vpd_dev); + + if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) + pci_dev_put(vpd_dev); - return pci_write_vpd(dev, off, count, buf); + return ret; } -static BIN_ATTR(vpd, 0600, vpd_read, vpd_write, 0); +static const BIN_ATTR(vpd, 0600, vpd_read, vpd_write, 0); -static struct bin_attribute *vpd_attrs[] = { +static const struct bin_attribute *const vpd_attrs[] = { &bin_attr_vpd, NULL, }; static umode_t vpd_attr_is_visible(struct kobject *kobj, - struct bin_attribute *a, int n) + const struct bin_attribute *a, int n) { struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); |
