diff options
Diffstat (limited to 'drivers/pci/access.c')
| -rw-r--r-- | drivers/pci/access.c | 42 | 
1 files changed, 42 insertions, 0 deletions
| diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 01b9d0a00abc..d11cdbb8fba3 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -275,6 +275,19 @@ ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void  }  EXPORT_SYMBOL(pci_write_vpd); +/** + * pci_set_vpd_size - Set size of Vital Product Data space + * @dev:	pci device struct + * @len:	size of vpd space + */ +int pci_set_vpd_size(struct pci_dev *dev, size_t len) +{ +	if (!dev->vpd || !dev->vpd->ops) +		return -ENODEV; +	return dev->vpd->ops->set_size(dev, len); +} +EXPORT_SYMBOL(pci_set_vpd_size); +  #define PCI_VPD_MAX_SIZE (PCI_VPD_ADDR_MASK + 1)  /** @@ -498,9 +511,23 @@ out:  	return ret ? ret : count;  } +static int pci_vpd_set_size(struct pci_dev *dev, size_t len) +{ +	struct pci_vpd *vpd = dev->vpd; + +	if (len == 0 || len > PCI_VPD_MAX_SIZE) +		return -EIO; + +	vpd->valid = 1; +	vpd->len = len; + +	return 0; +} +  static const struct pci_vpd_ops pci_vpd_ops = {  	.read = pci_vpd_read,  	.write = pci_vpd_write, +	.set_size = pci_vpd_set_size,  };  static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count, @@ -533,9 +560,24 @@ static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count,  	return ret;  } +static int pci_vpd_f0_set_size(struct pci_dev *dev, size_t len) +{ +	struct pci_dev *tdev = pci_get_slot(dev->bus, +					    PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); +	int ret; + +	if (!tdev) +		return -ENODEV; + +	ret = pci_set_vpd_size(tdev, len); +	pci_dev_put(tdev); +	return ret; +} +  static const struct pci_vpd_ops pci_vpd_f0_ops = {  	.read = pci_vpd_f0_read,  	.write = pci_vpd_f0_write, +	.set_size = pci_vpd_f0_set_size,  };  int pci_vpd_init(struct pci_dev *dev) | 
