2 * The PCI Utilities -- Show Vital Product Data
4 * Copyright (c) 2008 Solarflare Communications
6 * Written by Ben Hutchings <bhutchings@solarflare.com>
8 * Can be freely distributed and used under the terms of the GNU GPL.
16 print_vpd_string(const byte *buf, word len)
23 else if (ch < 32 || ch == 127)
24 printf("\\x%02x", ch);
31 read_vpd(struct device *d, int pos, byte *buf, int len, byte *csum)
33 if (!pci_read_vpd(d->dev, pos, buf, len))
41 cap_vpd(struct device *d)
43 word res_addr = 0, res_len, part_pos, part_len;
44 byte key[2], buf[256];
48 printf("Vital Product Data\n");
52 while (res_addr <= PCI_VPD_ADDR_MASK)
54 if (!read_vpd(d, res_addr, &tag, 1, &csum))
58 if (res_addr > PCI_VPD_ADDR_MASK + 1 - 3)
60 if (!read_vpd(d, res_addr + 1, buf, 2, &csum))
62 res_len = buf[0] + (buf[1] << 8);
71 if (res_len > PCI_VPD_ADDR_MASK + 1 - res_addr)
83 printf("\t\tProduct Name: ");
84 while (part_pos < res_len)
86 part_len = res_len - part_pos;
87 if (part_len > sizeof(buf))
88 part_len = sizeof(buf);
89 if (!read_vpd(d, res_addr + part_pos, buf, part_len, &csum))
91 print_vpd_string(buf, part_len);
99 printf("\t\t%s fields:\n",
100 (tag == 0x90) ? "Read-only" : "Read/write");
102 while (part_pos + 3 <= res_len)
106 if (!read_vpd(d, res_addr + part_pos, buf, 3, &csum))
112 if (part_len > res_len - part_pos)
115 /* Only read the first byte of the RV field because the
116 * remaining bytes are not included in the checksum. */
117 read_len = (key[0] == 'R' && key[1] == 'V') ? 1 : part_len;
118 if (!read_vpd(d, res_addr + part_pos, buf, read_len, &csum))
121 if ((key[0] == 'E' && key[1] == 'C') ||
122 (key[0] == 'P' && key[1] == 'N') ||
123 (key[0] == 'S' && key[1] == 'N') ||
127 /* Alphanumeric content */
128 printf("\t\t\t%c%c: ", key[0], key[1]);
129 print_vpd_string(buf, part_len);
132 else if (key[0] == 'R' && key[1] == 'V')
134 /* Reserved and checksum */
135 printf("\t\t\tRV: checksum %s, %d byte(s) reserved\n",
136 csum ? "bad" : "good", part_len - 1);
138 else if (key[0] == 'R' && key[1] == 'W')
140 /* Read-write area */
141 printf("\t\t\tRW: %d byte(s) free\n", part_len);
145 /* Binary or unknown content */
147 printf("\t\t\t%c%c:", key[0], key[1]);
148 for (i = 0; i < part_len; i++)
149 printf(" %02x", buf[i]);
153 part_pos += part_len;
158 printf("\t\tUnknown %s resource type %02x\n",
159 (tag & 0x80) ? "large" : "small", tag & ~0x80);
167 printf("\t\tNot readable\n");
169 printf("\t\tNo end tag found\n");