Signed-off-by: Ben Hutchings <bhutchings@xxxxxxxxxxxxxx> --- lib/sysfs.c | 39 +++++++++++++++++++++++++++++++++------ 1 files changed, 33 insertions(+), 6 deletions(-) diff --git a/lib/sysfs.c b/lib/sysfs.c index 671fc25..90bd4be 100644 --- a/lib/sysfs.c +++ b/lib/sysfs.c @@ -22,6 +22,11 @@ #include "internal.h" #include "pread.h" +enum { + FD_RW = 1, /* opened read-write, else read-only */ + FD_VPD = 2, /* opened VPD, else config */ +}; + static void sysfs_config(struct pci_access *a) { @@ -178,18 +183,22 @@ static void sysfs_scan(struct pci_access *a) } static int -sysfs_setup(struct pci_dev *d, int rw) +sysfs_setup(struct pci_dev *d, int flags) { struct pci_access *a = d->access; - if (a->cached_dev != d || a->fd_flags < rw) + if (a->cached_dev != d || + (flags ^ a->fd_flags) & FD_VPD || + (flags & FD_RW) && !(a->fd_flags & FD_RW)) { char namebuf[OBJNAMELEN]; if (a->fd >= 0) close(a->fd); - sysfs_obj_name(d, "config", namebuf); - a->fd_flags = a->writeable || rw; - a->fd = open(namebuf, a->fd_flags ? O_RDWR : O_RDONLY); + if (a->writeable) + flags |= FD_RW; + sysfs_obj_name(d, (flags & FD_VPD) ? "vpd" : "config", namebuf); + a->fd_flags = flags; + a->fd = open(namebuf, (flags & FD_RW) ? O_RDWR : O_RDONLY); if (a->fd < 0) a->warning("Cannot open %s", namebuf); a->cached_dev = d; @@ -216,6 +225,24 @@ static int sysfs_read(struct pci_dev *d, int pos, byte *buf, int len) return 1; } +static int sysfs_read_vpd(struct pci_dev *d, int pos, byte *buf, int len) +{ + int fd = sysfs_setup(d, FD_VPD); + int res; + + if (fd < 0) + return 0; + res = do_read(d, fd, buf, len, pos); + if (res < 0) + { + d->access->warning("sysfs_read_vpd: read failed: %s", strerror(errno)); + return 0; + } + else if (res != len) + return 0; + return 1; +} + static int sysfs_write(struct pci_dev *d, int pos, byte *buf, int len) { int fd = sysfs_setup(d, 1); @@ -259,7 +286,7 @@ struct pci_methods pm_linux_sysfs = { sysfs_scan, pci_generic_fill_info, sysfs_read, - NULL, + sysfs_read_vpd, sysfs_write, NULL, /* init_dev */ sysfs_cleanup_dev -- Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job. They asked us to note that Solarflare product names are trademarked. -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html