Patchwork [3/9] PCI: add interface to set visible size of VPD (rev3)

login
register
mail settings
Submitter stephen hemminger
Date Sept. 25, 2008, 4:48 p.m.
Message ID <20080925165223.366942933@vyatta.com>
Download mbox | patch
Permalink /patch/1546/
State Deferred
Delegated to: Jeff Garzik
Headers show

Comments

stephen hemminger - Sept. 25, 2008, 4:48 p.m.
The VPD on all devices may not be 32K. Unfortunately, there is no
generic way to find the size, so this adds a simple API hook
to reset it.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
 drivers/pci/access.c |   23 +++++++++++++++++++++++
 include/linux/pci.h  |    1 +
 2 files changed, 24 insertions(+)
Jeff Garzik - Sept. 25, 2008, 5:22 p.m.
Stephen Hemminger wrote:
> The VPD on all devices may not be 32K. Unfortunately, there is no
> generic way to find the size, so this adds a simple API hook
> to reset it.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> 
> ---
>  drivers/pci/access.c |   23 +++++++++++++++++++++++
>  include/linux/pci.h  |    1 +
>  2 files changed, 24 insertions(+)
> 
> --- a/drivers/pci/access.c	2008-09-09 13:57:05.000000000 -0700
> +++ b/drivers/pci/access.c	2008-09-09 13:57:06.000000000 -0700
> @@ -340,6 +340,29 @@ int pci_vpd_pci22_init(struct pci_dev *d
>  }
>  
>  /**
> + * pci_vpd_truncate - Set available Vital Product Data size
> + * @dev:	pci device struct
> + * @size:	available memory in bytes
> + *
> + * Adjust size of available VPD area.
> + */
> +int pci_vpd_truncate(struct pci_dev *dev, size_t size)
> +{
> +	if (!dev->vpd)
> +		return -EINVAL;
> +
> +	/* limited by the access method */
> +	if (size > dev->vpd->len)
> +		return -EINVAL;
> +
> +	dev->vpd->len = size;
> +	dev->vpd->attr->size = size;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(pci_vpd_truncate);

What is the initial size?

It seems like a bad idea to start out assuming the max, and reduce once 
a knowledgeable driver appears.

It seems more safe to start out at zero, and let a driver increase it?

That way, by design, you eliminate the possibility (later, if not now) 
of someone assuming that the full 32k can be read as soon as the 
interface is available.

	Jeff



--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ben Hutchings - Sept. 25, 2008, 5:49 p.m.
On Thu, 2008-09-25 at 13:22 -0400, Jeff Garzik wrote:
[...]
> What is the initial size?
> 
> It seems like a bad idea to start out assuming the max, and reduce once 
> a knowledgeable driver appears.
> 
> It seems more safe to start out at zero, and let a driver increase it?

VPD is meant to be usable even without a driver - that's why it's a
(somewhat) standard capability and not device-specific.

> That way, by design, you eliminate the possibility (later, if not now) 
> of someone assuming that the full 32k can be read as soon as the 
> interface is available.

I believe that's generally true, though it may be slow.

Maybe we could read as much as we need to find the real length when the
sysfs file is first opened?

Ben.

Patch

--- a/drivers/pci/access.c	2008-09-09 13:57:05.000000000 -0700
+++ b/drivers/pci/access.c	2008-09-09 13:57:06.000000000 -0700
@@ -340,6 +340,29 @@  int pci_vpd_pci22_init(struct pci_dev *d
 }
 
 /**
+ * pci_vpd_truncate - Set available Vital Product Data size
+ * @dev:	pci device struct
+ * @size:	available memory in bytes
+ *
+ * Adjust size of available VPD area.
+ */
+int pci_vpd_truncate(struct pci_dev *dev, size_t size)
+{
+	if (!dev->vpd)
+		return -EINVAL;
+
+	/* limited by the access method */
+	if (size > dev->vpd->len)
+		return -EINVAL;
+
+	dev->vpd->len = size;
+	dev->vpd->attr->size = size;
+
+	return 0;
+}
+EXPORT_SYMBOL(pci_vpd_truncate);
+
+/**
  * pci_block_user_cfg_access - Block userspace PCI config reads/writes
  * @dev:	pci device struct
  *
--- a/include/linux/pci.h	2008-09-09 13:57:05.000000000 -0700
+++ b/include/linux/pci.h	2008-09-09 13:57:06.000000000 -0700
@@ -653,6 +653,7 @@  int pci_bus_find_capability(struct pci_b
 /* Vital product data routines */
 ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf);
 ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf);
+int pci_vpd_truncate(struct pci_dev *dev, size_t size);
 
 /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
 void pci_bus_assign_resources(struct pci_bus *bus);