]> git.openfabrics.org - ~adrianc/mstflint.git/commitdiff
+ Added support to read VPD in new way from FileSystem path that support concurrency...
authorAdham Masarwah <adham@mellanox.com>
Mon, 12 May 2014 12:57:18 +0000 (15:57 +0300)
committerAdham Masarwah <adham@mellanox.com>
Mon, 12 May 2014 12:57:18 +0000 (15:57 +0300)
+ Fix some coding styles.
+ Change some variables' names.

small_utils/vpd.c

index 54620e81ed59b0dfe3fc694dcaa7919152dfd965..9257b2d13cdc7d008d138826d5e5e5718e3c833d 100644 (file)
@@ -128,53 +128,81 @@ enum {
 #define VPD_FIELD_CHECKSUM "RV"
 #define VPD_FIELD_RW       "RW"
 
-int pci_find_capability(int device, int cap_id)
+int pci_find_capability(int fd, int cap_id)
 {
        unsigned offset;
        unsigned char visited[256] = {}; /* Prevent infinite loops */
        unsigned char data[2];
        int ret;
 
-       ret = pread(device, data, 1, PCI_CAP_PTR);
-       if (ret != 1)
+       ret = pread(fd, data, 1, PCI_CAP_PTR);
+       if (ret != 1) {
                return 0;
+       }
        offset = data[0];
 
        for(;;) {
-               if (offset < PCI_HDR_SIZE)
+               if (offset < PCI_HDR_SIZE) {
                        return 0;
+               }
 
-               ret = pread(device, data, sizeof data, offset);
-               if (ret != sizeof data)
+               ret = pread(fd, data, sizeof data, offset);
+               if (ret != sizeof data) {
                        return 0;
+               }
 
                visited[offset] = 1;
 
-               if (data[0] == cap_id)
+               if (data[0] == cap_id) {
                        return offset;
+               }
 
                offset = data[1];
-               if (visited[offset])
+               if (visited[offset]) {
                        return 0;
+               }
        }
+       return 0;
 }
 
-int pci_read_vpd_dword(int device, int vpd_cap_offset, unsigned offset, unsigned char data[4])
+int pci_read_vpd_dword_file(int fd, unsigned offset, unsigned char data[4])
+{
+    unsigned char addr_flag[2];
+    int ret;
+    if (offset >= VPD_MAX_SIZE || (offset & 0x3)) {
+        return -1;
+    }
+
+    if (lseek(fd, offset, SEEK_SET) < 0)
+    {
+        fprintf(stderr, "Reached End Of VPD region: %s\n", strerror(errno));
+        return errno;
+    }
+    if (read(fd, data, 0x4) != 4) {
+        fprintf(stderr, "Failed to read VPD: %s\n", strerror(errno));
+        return errno;
+    }
+    return 0;
+}
+
+int pci_read_vpd_dword_gw(int fd, int vpd_cap_offset, unsigned offset, unsigned char data[4])
 {
        unsigned char addr_flag[2];
        int ret;
 
-       if (offset >= VPD_MAX_SIZE || (offset & 0x3))
+       if (offset >= VPD_MAX_SIZE || (offset & 0x3)) {
                return -1;
+       }
 
        addr_flag[0] = (offset) & ~0x3;
        addr_flag[1] = ((offset) >> 8) | VPD_FLAG_READ_START;
 
-       ret = pwrite(device, addr_flag, sizeof addr_flag,
+       ret = pwrite(fd, addr_flag, sizeof addr_flag,
                     vpd_cap_offset + VPD_ADDR_OFFSET);
 
-       if (ret != sizeof addr_flag)
+       if (ret != sizeof addr_flag) {
                return ret;
+       }
 
        start_t = times(NULL);
        while((addr_flag[1] & VPD_FLAG) != VPD_FLAG_READ_READY) {
@@ -184,35 +212,49 @@ int pci_read_vpd_dword(int device, int vpd_cap_offset, unsigned offset, unsigned
                        return -EIO;
                }
 
-               ret = pread(device, addr_flag, sizeof addr_flag,
+               ret = pread(fd, addr_flag, sizeof addr_flag,
                             vpd_cap_offset + VPD_ADDR_OFFSET);
-               if (ret != sizeof addr_flag)
+               if (ret != sizeof addr_flag) {
                        return ret;
+               }
        }
 
-       ret = pread(device, data, sizeof data, vpd_cap_offset + VPD_DATA_OFFSET);
-       if (ret != sizeof data)
+       ret = pread(fd, data, sizeof data, vpd_cap_offset + VPD_DATA_OFFSET);
+       if (ret != sizeof data) {
                return ret;
+       }
 
        return 0;
 }
 
-int vpd_read(int device, vpd_t vpd)
+int vpd_read(int fd, vpd_t vpd, int vpd_path_exists)
 {
-       unsigned offset;
-       int ret;
-       int vpd_cap_offset;
-       vpd_cap_offset = pci_find_capability(device, VPD_CAP_ID);
-       if (!vpd_cap_offset)
-               return -1;
-
-       for (offset = 0; offset < VPD_MAX_SIZE; offset += 0x4) {
-               ret = pci_read_vpd_dword(device, vpd_cap_offset, offset, vpd + offset);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
+    if (vpd_path_exists) {
+        unsigned offset;
+        int ret;
+        for (offset = 0; offset < VPD_MAX_SIZE; offset += 0x4) {
+            ret = pci_read_vpd_dword_file(fd, offset, vpd + offset);
+            if (ret) {
+                return ret;
+            }
+        }
+    } else {
+        unsigned offset;
+        int ret;
+        int vpd_cap_offset;
+        vpd_cap_offset = pci_find_capability(fd, VPD_CAP_ID);
+        if (!vpd_cap_offset) {
+            return -1;
+        }
+
+        for (offset = 0; offset < VPD_MAX_SIZE; offset += 0x4) {
+            ret = pci_read_vpd_dword_gw(fd, vpd_cap_offset, offset, vpd + offset);
+            if (ret) {
+                return ret;
+            }
+        }
+    }
+    return 0;
 }
 
 /* Verify that keywords in R and W sections fit in length. */
@@ -245,8 +287,9 @@ void vpd_checksum_length(union vpd_data_type *d, unsigned offset, unsigned *chec
        unsigned i;
        struct vpd_field *field;
 
-       if (VPD_TAG_NAME(d) != VPD_TAG_R)
+       if (VPD_TAG_NAME(d) != VPD_TAG_R) {
                return;
+       }
 
        for (i = 0; i < VPD_TAG_LENGTH(d); i += 0x3 + field->length) {
                field = (struct vpd_field *)(VPD_TAG_DATA(d)->bytes + i);
@@ -262,14 +305,16 @@ void vpd_show_field(FILE *f, struct vpd_field *field)
        int i;
 
        if (!memcmp(VPD_FIELD_CHECKSUM, field->keyword, sizeof field->keyword) ||
-               !memcmp(VPD_FIELD_RW      , field->keyword, sizeof field->keyword))
+               !memcmp(VPD_FIELD_RW      , field->keyword, sizeof field->keyword)) {
                return;
+       }
        fputc(field->keyword[0], f);
        fputc(field->keyword[1], f);
        fputs(": ", f);
        for (i = 0; i < field->length; ++i) {
-               if (!field->data[i])
+               if (!field->data[i]) {
                        break;
+               }
                fputc(field->data[i], f);
        }
        fputc('\n', f);
@@ -283,8 +328,9 @@ void vpd_show_fields(FILE *f, union vpd_data_type *d, const char *keyword)
        for (i = 0; i < VPD_TAG_LENGTH(d); i += 0x3 + field->length) {
                field = (struct vpd_field *)(VPD_TAG_DATA(d)->bytes + i);
                if (!keyword ||
-                       !memcmp(keyword, field->keyword, sizeof field->keyword))
+                       !memcmp(keyword, field->keyword, sizeof field->keyword)) {
                                vpd_show_field(f, field);
+               }
        }
 }
 
@@ -293,8 +339,9 @@ void vpd_show_id(FILE *f, union vpd_data_type *d)
        unsigned i;
 
        fputs("ID: ", f);
-       for (i = 0; i < VPD_TAG_LENGTH(d); ++i)
+       for (i = 0; i < VPD_TAG_LENGTH(d); ++i) {
                fputc(VPD_TAG_DATA(d)->bytes[i], f);
+       }
        fputc('\n', f);
 }
 
@@ -302,8 +349,9 @@ void vpd_show_one(FILE *f, union vpd_data_type* d, const char *keyword)
 {
        switch(VPD_TAG_NAME(d)) {
        case VPD_TAG_ID:
-               if (!keyword || !memcmp("ID", keyword, 2))
+               if (!keyword || !memcmp("ID", keyword, 2)) {
                        vpd_show_id(f, d);
+               }
                break;
        case VPD_TAG_R:
                vpd_show_fields(f, d, keyword);
@@ -314,8 +362,9 @@ void vpd_show_one(FILE *f, union vpd_data_type* d, const char *keyword)
        case VPD_TAG_F:
                break;
        default:
-               if (!keyword)
+               if (!keyword) {
                        fprintf(f, "??: 0x%x\n", VPD_TAG_NAME(d));
+               }
        }
 }
 
@@ -334,8 +383,9 @@ int vpd_check(vpd_t vpd, int checksum, int ignore_w)
 
                if (!(VPD_TAG_NAME(d) == VPD_TAG_W && ignore_w)) {
                        rc = vpd_check_one(d, offset);
-                       if (rc)
+                       if (rc) {
                                return rc;
+                       }
                }
 
                vpd_checksum_length(d, offset, &checksum_len);
@@ -346,8 +396,9 @@ int vpd_check(vpd_t vpd, int checksum, int ignore_w)
                return 1;
        }
 
-       if (!checksum)
+       if (!checksum) {
                return 0;
+       }
 
        if (!checksum_len) {
                fprintf(stderr, "-E- Mandatory checksum(RV) field not found.\n");
@@ -355,8 +406,9 @@ int vpd_check(vpd_t vpd, int checksum, int ignore_w)
        }
 
        b = 0;
-       for (i = 0; i < checksum_len; ++i)
+       for (i = 0; i < checksum_len; ++i) {
                b+= vpd[i];
+       }
 
        if (b) {
                fprintf(stderr, "-E- Len 0x%x: checksum mismatch: 0x%x\n",
@@ -379,7 +431,23 @@ void vpd_show(FILE *f, vpd_t vpd, const char *keyword, int ignore_w)
        }
 }
 
-int pci_parse_name(const char *name, char buf[4096])
+int is_file_exist(const char *fname)
+{
+    int fd = open(fname, O_RDONLY);
+    if (fd > 0) {
+        u_int8_t data[4];
+        if (read(fd, data, 0x4) != 4){
+            close(fd);
+            return 0;
+        } else {
+            close(fd);
+            return 1;
+        }
+    }
+    return 0;
+}
+
+int pci_parse_name(const char *name, char buf[4096], int* vpd_path_exists)
 {
        int domain, bus, dev, func, tmp;
        struct stat dummybuf;
@@ -410,37 +478,47 @@ int pci_parse_name(const char *name, char buf[4096])
                }
 
                base = basename(pbuf);
-               if (!base)
+               if (!base) {
                        return 1;
-               if (sscanf(base, "%x:%x:%x.%x", &domain, &bus, &dev, &func) != 4)
+               }
+               if (sscanf(base, "%x:%x:%x.%x", &domain, &bus, &dev, &func) != 4) {
                        return 1;
+               }
        } else if (sscanf(name, "%x:%x:%x.%x", &domain, &bus, &dev, &func) != 4) {
                domain = 0;
                if (sscanf(name, "%x:%x.%x", &bus, &dev, &func) != 3)
                        return -2;
        }
        
+       snprintf(buf, 4096, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/vpd", domain, bus, dev, func);
+       if (is_file_exist(buf)) {
+           *vpd_path_exists = 1;
+           return 0;
+       }
+       *vpd_path_exists = 0;
+
        snprintf(buf, 4096, "/proc/bus/pci/%2.2x/%2.2x.%1.1x", bus, dev, func);
-       if (stat(buf, &dummybuf))
+       if (stat(buf, &dummybuf)) {
                snprintf(buf, 4096, "/proc/bus/pci/%4.4x:%2.2x/%2.2x.%1.1x",
                         domain, bus,dev,func);
+       }
 
-       if (stat(buf, &dummybuf))
+       if (stat(buf, &dummybuf)) {
                return -3;
+       }
 
        return 0;
 }
 
-int vpd_open(const char *name)
+int vpd_open(const char *name, int* vpd_path_exists)
 {
        int fd;
        char buf[4096];
 
-       if (pci_parse_name(name, buf)) {
+       if (pci_parse_name(name, buf, vpd_path_exists)) {
                fprintf(stderr, "-E- Unable to parse device name %s\n", name);
                return -1;
        }
-
        fd = open(buf, O_RDWR);
        if (fd < 0) {
                fprintf(stderr, "-E- Unable to open file %s: %s\n", buf, strerror(errno));
@@ -458,6 +536,7 @@ int main(int argc, char **argv)
        int m = 0;
        int n = 0;
        int ignore_w = 0;
+       int vpd_path_exists = 0;
 
        if (argc < 2) {
                rc = 1;
@@ -499,11 +578,11 @@ int main(int argc, char **argv)
                if (fread(d, VPD_MAX_SIZE, 1, stdin) != 1)
                        return 3;
        } else {
-               fd = vpd_open(name);
+               fd = vpd_open(name, &vpd_path_exists);
                if (fd < 0)
                        return 4;
 
-               if (vpd_read(fd, d))
+               if (vpd_read(fd, d, vpd_path_exists))
                        return 5;
        }