3 # Copyright (C) 2001 Sheldon Hearn. All rights reserved.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
8 # 1. Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # 2. Redistributions in binary form must reproduce the above copyright
11 # notice, this list of conditions and the following disclaimer in the
12 # documentation and/or other materials provided with the distribution.
14 # THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
15 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
18 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 # usage: mk_pci_vendors [-lq] [-p pcidevs.txt] [-v vendors.txt]
30 # Generate src/share/misc/pci_vendors from the Hart and Boemler lists,
31 # currently available at:
33 # Boemler: http://www.pcidatabase.com/reports.php?type=csv
34 # Hart: http://members.datafast.net.au/dft0802/downloads/pcidevs.txt
36 # -l Where an entry is found in both input lists, use the entry with
37 # the longest description. The default is for the Boemler file to
38 # override the Hart file.
39 # -q Do not print diagnostics.
40 # -p Specify the pathname of the Hart file. (Default ./pcidevs.txt)
41 # -v Specify the pathname of the Boemler file. (Default ./vendors.txt)
47 my $PROGNAME = 'mk_pci_vendors';
48 my $VENDORS_FILE = 'vendors.txt';
49 my $PCIDEVS_FILE = 'pcidevs.txt';
51 my ($cur_vendor, $vendorid, $pciid, $vendor);
55 my ($descr, $existing, $id, $line, $rv, $winner, $optlused);
66 sub vendors_parse($\$\$\$\$);
67 sub pcidevs_parse($\$\$);
69 if (not getopts('lp:qv:', \%opts) or @ARGV > 0) {
70 print STDERR "usage: $PROGNAME [-lq] [-p pcidevs.txt] [-v vendors.txt]\n";
74 if (not defined($opts{p})) {
75 $opts{p} = $PCIDEVS_FILE;
77 if (not defined($opts{v})) {
78 $opts{v} = $VENDORS_FILE;
80 foreach (('l', 'q')) {
81 if (not exists($opts{$_})) {
88 open(VENDORS, "< $opts{v}") or
89 die "$PROGNAME: $opts{v}: $!\n";
90 while ($line = <VENDORS>) {
92 $rv = vendors_parse($line, $vendorid, $pciid, $vendor, $descr);
94 if (defined $vendors{$vendorid}
95 && $vendors{$vendorid}[$W_VENDORS] ne $vendor) {
96 die "$PROGNAME: $vendorid: duplicate vendor ID\n";
98 $vendors{$vendorid}[$W_VENDORS] = $vendor;
99 $pciids{$vendorid}{$pciid}[$W_VENDORS] = $descr;
104 open(PCIDEVS, "< $opts{p}") or
105 die "$PROGNAME: $opts{p}: $!\n";
106 while ($line = <PCIDEVS>) {
108 $rv = pcidevs_parse($line, $id, $descr);
109 if ($rv == $IS_VENDOR) {
111 $vendors{$vendorid}[$W_PCIDEVS] = $descr;
112 } elsif ($rv == $IS_DEVICE) {
113 $pciids{$vendorid}{$id}[$W_PCIDEVS] = $descr;
118 foreach my $vid (keys(%vendors)) {
119 if (!defined $vendors{$vid}[$W_VENDORS]
120 && defined $vendors{$vid}[$W_PCIDEVS]) {
121 $vendors{$vid}[$W_FINAL] = $vendors{$vid}[$W_PCIDEVS];
122 } elsif (defined $vendors{$vid}[$W_VENDORS]
123 && !defined $vendors{$vid}[$W_PCIDEVS]) {
124 $vendors{$vid}[$W_FINAL] = $vendors{$vid}[$W_VENDORS];
125 } elsif (!$opts{l}) {
126 $vendors{$vid}[$W_FINAL] = $vendors{$vid}[$W_VENDORS];
128 if (length($vendors{$vid}[$W_VENDORS]) >
129 length($vendors{$vid}[$W_PCIDEVS])) {
130 $vendors{$vid}[$W_FINAL] = $vendors{$vid}[$W_VENDORS];
132 $vendors{$vid}[$W_FINAL] = $vendors{$vid}[$W_PCIDEVS];
136 foreach my $pciid (keys(%{$pciids{$vid}})) {
137 if (!defined $pciids{$vid}{$pciid}[$W_VENDORS]
138 && defined $pciids{$vid}{$pciid}[$W_PCIDEVS]) {
139 $pciids{$vid}{$pciid}[$W_FINAL] =
140 $pciids{$vid}{$pciid}[$W_PCIDEVS];
141 } elsif (defined $pciids{$vid}{$pciid}[$W_VENDORS]
142 && !defined $pciids{$vid}{$pciid}[$W_PCIDEVS]) {
143 $pciids{$vid}{$pciid}[$W_FINAL] =
144 $pciids{$vid}{$pciid}[$W_VENDORS];
145 } elsif (!$opts{l}) {
146 $pciids{$vid}{$pciid}[$W_FINAL] =
147 $pciids{$vid}{$pciid}[$W_VENDORS];
149 if (length($pciids{$vid}{$pciid}[$W_VENDORS]) >
150 length($pciids{$vid}{$pciid}[$W_PCIDEVS])) {
151 $pciids{$vid}{$pciid}[$W_FINAL] =
152 $pciids{$vid}{$pciid}[$W_VENDORS];
154 $pciids{$vid}{$pciid}[$W_FINAL] =
155 $pciids{$vid}{$pciid}[$W_PCIDEVS];
162 $optlused = $opts{l} ? "with" : "without";
166 ; Automatically generated by src/tools/tools/pciid/mk_pci_vendors.pl
167 ; ($optlused the -l option), using the following source lists:
169 ; http://www.pcidatabase.com/reports.php?type=csv
170 ; http://members.datafast.net.au/dft0802/downloads/pcidevs.txt
172 ; Manual edits on this file will be lost!
176 foreach my $vid (sort keys %vendors) {
177 $descr = $vendors{$vid}[0];
178 print "$vid\t$descr\n";
179 foreach $pciid (sort keys %{$pciids{$vid}}) {
180 $descr = $pciids{$vid}{$pciid}[0];
181 print "\t$pciid\t$descr\n";
187 # Parse a line from the Boemler CSV file and place the vendor id, pciid,
188 # vendor description and description in the scalars.
190 # Returns 0 if there is a problem.
192 sub vendors_parse($\$\$\$\$)
194 my ($line, $vendorid_ref, $pciid_ref, $vendor_ref, $descr_ref) = @_;
196 my @a = split(/","/, $line);
197 $a[0] =~ s/0x//; # 0x1234 -> 1234
200 $a[0] =~ s/^"//; # Remove starting or trailing "
203 $a[0] = uc($a[0]); # Some are lowercase hex-digits
206 # Length of the Vendor ID or PCI ID is not four hex-digits, ignore it
207 return 0 if (length($a[0]) != 4 || length($a[1]) != 4);
209 # If there is no description, see if the chip data exists and use that
219 $$vendorid_ref = $a[0];
221 $$vendor_ref = $a[2];
222 $$descr_ref = clean_descr($a[4]);
223 $$descr_ref .= clean_descr(" ($a[3])") if ($a[3] =~ /[a-zA-Z0-0]/);
227 # Parse a line from the Hart file and place the ID and description
228 # in the scalars referenced by $id_ref and $descr_ref.
230 # On success, returns $IS_VENDOR if the line represents a vendor entity
231 # or $IS_DEVICE if the line represents a device entity.
233 # Returns 0 on failure.
235 sub pcidevs_parse($\$\$)
237 my ($line, $id_ref, $descr_ref) = @_;
240 if ($line =~ /^V\t([A-Fa-f0-9]{4})\t([^\t].+?)\s*$/) {
241 ($$id_ref, $$descr_ref) = (uc($1), clean_descr($2));
243 } elsif ($line =~ /^D\t([A-Fa-f0-9]{4})\t([^\t].+?)\s*$/) {
244 ($$id_ref, $$descr_ref) = (uc($1), clean_descr($2));
246 } elsif (not $opts{q} and
247 $line !~ /^\s*$/ and $line !~ /^[;ORSX]/) {
248 print STDERR "$PROGNAME: ignored Hart: $line\n";
258 $descr =~ s/[^[:print:]]//g; # non-printable
259 $descr =~ s/\\//g; # escape of 's
260 $descr =~ s/\#/*/g; # pciconf(8) ignores data after this