+static ssize_t
+pci_read_vpd(struct kobject *kobj, struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct pci_dev *dev =
+ to_pci_dev(container_of(kobj, struct device, kobj));
+ int end;
+ int ret;
+
+ if (off > bin_attr->size)
+ count = 0;
+ else if (count > bin_attr->size - off)
+ count = bin_attr->size - off;
+ end = off + count;
+
+ while (off < end) {
+ ret = dev->vpd->ops->read(dev, off, end - off, buf);
+ if (ret < 0)
+ return ret;
+ buf += ret;
+ off += ret;
+ }
+
+ return count;
+}
+
+static ssize_t
+pci_write_vpd(struct kobject *kobj, struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct pci_dev *dev =
+ to_pci_dev(container_of(kobj, struct device, kobj));
+ int end;
+ int ret;
+
+ if (off > bin_attr->size)
+ count = 0;
+ else if (count > bin_attr->size - off)
+ count = bin_attr->size - off;
+ end = off + count;
+
+ while (off < end) {
+ ret = dev->vpd->ops->write(dev, off, end - off, buf);
+ if (ret < 0)
+ return ret;
+ buf += ret;
+ off += ret;
+ }
+
+ return count;
+}
+