]>
git.ipfire.org Git - thirdparty/pciutils.git/blob - ls-vpd.c
2 * The PCI Utilities -- Show Vital Product Data
4 * Copyright (c) 2008 Solarflare Communications
6 * Written by Ben Hutchings <bhutchings@solarflare.com>
7 * Improved by Martin Mares <mj@ucw.cz>
9 * Can be freely distributed and used under the terms of the GNU GPL v2+.
11 * SPDX-License-Identifier: GPL-2.0-or-later
20 * The list of all known VPD items and their formats.
21 * Technically, this belongs to the pci.ids file, but the VPD does not seem
22 * to be developed any longer, so we have chosen the easier way.
32 static const struct vpd_item
{
37 { 'C','P', F_BINARY
, "Extended capability" },
38 { 'E','C', F_TEXT
, "Engineering changes" },
39 { 'M','N', F_TEXT
, "Manufacture ID" },
40 { 'P','N', F_TEXT
, "Part number" },
41 { 'R','V', F_RESVD
, "Reserved" },
42 { 'R','W', F_RDWR
, "Read-write area" },
43 { 'S','N', F_TEXT
, "Serial number" },
44 { 'Y','A', F_TEXT
, "Asset tag" },
45 { 'V', 0 , F_TEXT
, "Vendor specific" },
46 { 'Y', 0 , F_TEXT
, "System specific" },
47 /* Non-standard extensions */
48 { 'C','C', F_TEXT
, "CCIN" },
49 { 'F','C', F_TEXT
, "Feature code" },
50 { 'F','N', F_TEXT
, "FRU" },
51 { 'N','A', F_TEXT
, "Network address" },
52 { 'R','M', F_TEXT
, "Firmware version" },
53 { 'Z', 0 , F_TEXT
, "Product specific" },
54 { 0, 0 , F_BINARY
, "Unknown" }
58 print_vpd_string(const byte
*buf
, word len
)
66 ; /* Cards with null-terminated strings have been observed */
67 else if (ch
< 32 || ch
== 127)
68 printf("\\x%02x", ch
);
75 print_vpd_binary(const byte
*buf
, word len
)
78 for (i
= 0; i
< len
; i
++)
82 printf("%02x", buf
[i
]);
87 read_vpd(struct device
*d
, int pos
, byte
*buf
, int len
, byte
*csum
)
89 if (!pci_read_vpd(d
->dev
, pos
, buf
, len
))
97 cap_vpd(struct device
*d
)
99 word res_addr
= 0, res_len
, part_pos
, part_len
;
104 printf("Vital Product Data\n");
108 while (res_addr
<= PCI_VPD_ADDR_MASK
)
110 if (!read_vpd(d
, res_addr
, &tag
, 1, &csum
))
114 if (res_addr
> PCI_VPD_ADDR_MASK
+ 1 - 3)
116 if (!read_vpd(d
, res_addr
+ 1, buf
, 2, &csum
))
118 res_len
= buf
[0] + (buf
[1] << 8);
127 if (res_len
> PCI_VPD_ADDR_MASK
+ 1 - res_addr
)
139 printf("\t\tProduct Name: ");
140 while (part_pos
< res_len
)
142 part_len
= res_len
- part_pos
;
143 if (part_len
> sizeof(buf
))
144 part_len
= sizeof(buf
);
145 if (!read_vpd(d
, res_addr
+ part_pos
, buf
, part_len
, &csum
))
147 print_vpd_string(buf
, part_len
);
148 part_pos
+= part_len
;
155 printf("\t\t%s fields:\n",
156 (tag
== 0x90) ? "Read-only" : "Read/write");
158 while (part_pos
+ 3 <= res_len
)
161 const struct vpd_item
*item
;
162 byte id
[2], id1
, id2
;
164 if (!read_vpd(d
, res_addr
+ part_pos
, buf
, 3, &csum
))
171 if (part_len
> res_len
- part_pos
)
174 /* Is this item known? */
175 for (item
=vpd_items
; item
->id1
&& item
->id1
!= id1
||
176 item
->id2
&& item
->id2
!= id2
; item
++)
179 /* Only read the first byte of the RV field because the
180 * remaining bytes are not included in the checksum. */
181 read_len
= (item
->format
== F_RESVD
) ? 1 : part_len
;
182 if (!read_vpd(d
, res_addr
+ part_pos
, buf
, read_len
, &csum
))
186 print_vpd_string(id
, 2);
187 printf("] %s: ", item
->name
);
189 switch (item
->format
)
192 print_vpd_string(buf
, part_len
);
196 print_vpd_binary(buf
, part_len
);
200 printf("checksum %s, %d byte(s) reserved\n", csum
? "bad" : "good", part_len
- 1);
203 printf("%d byte(s) free\n", part_len
);
207 part_pos
+= part_len
;
212 printf("\t\tUnknown %s resource type %02x, will not decode more.\n",
213 (tag
& 0x80) ? "large" : "small", tag
& ~0x80);
221 printf("\t\tNot readable\n");
223 printf("\t\tNo end tag found\n");