[PATCH 4/5] Add implementation of read_vpd() method for sysfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux