]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - tools/tools/pciid/mk_pci_vendors.pl
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / tools / tools / pciid / mk_pci_vendors.pl
1 #!/usr/bin/perl -w
2 #
3 # Copyright (C) 2001 Sheldon Hearn.  All rights reserved.
4
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
7 # are met:
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.
13
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
24 # SUCH DAMAGE.
25
26 # $FreeBSD$
27 #
28 # usage: mk_pci_vendors [-lq] [-p pcidevs.txt] [-v vendors.txt]
29 #
30 # Generate src/share/misc/pci_vendors from the Hart and Boemler lists,
31 # currently available at:
32 #
33 # Boemler:      http://www.pcidatabase.com/reports.php?type=csv
34 # Hart:         http://members.datafast.net.au/dft0802/downloads/pcidevs.txt
35 #
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)
42 #
43 use strict;
44 use Getopt::Std;
45 use Data::Dumper;
46
47 my $PROGNAME = 'mk_pci_vendors';
48 my $VENDORS_FILE = 'vendors.txt';
49 my $PCIDEVS_FILE = 'pcidevs.txt';
50
51 my ($cur_vendor, $vendorid, $pciid, $vendor);
52 my %opts;
53 my %pciids = ();
54 my %vendors = ();
55 my ($descr, $existing, $id, $line, $rv, $winner, $optlused);
56
57 my $IS_VENDOR = 1;
58 my $IS_DEVICE = 2;
59 my $V_DESCR = 0;
60 my $V_DEVSL = 1;
61 my $W_FINAL = 0;
62 my $W_VENDORS = 1;
63 my $W_PCIDEVS = 2;
64
65 sub clean_descr($);
66 sub vendors_parse($\$\$\$\$);
67 sub pcidevs_parse($\$\$);
68
69 if (not getopts('lp:qv:', \%opts) or @ARGV > 0) {
70         print STDERR "usage: $PROGNAME [-lq] [-p pcidevs.txt] [-v vendors.txt]\n";
71         exit 1;
72 }
73
74 if (not defined($opts{p})) {
75         $opts{p} = $PCIDEVS_FILE;
76 }
77 if (not defined($opts{v})) {
78         $opts{v} = $VENDORS_FILE;
79 }
80 foreach (('l', 'q')) {
81         if (not exists($opts{$_})) {
82                 $opts{$_} = 0;
83         } else {
84                 $opts{$_} = 1;
85         }
86 }
87
88 open(VENDORS, "< $opts{v}") or
89     die "$PROGNAME: $opts{v}: $!\n";
90 while ($line = <VENDORS>) {
91         chomp($line);
92         $rv = vendors_parse($line, $vendorid, $pciid, $vendor, $descr);
93         if ($rv != 0) {
94                 if (defined $vendors{$vendorid}
95                  && $vendors{$vendorid}[$W_VENDORS] ne $vendor) {
96                         die "$PROGNAME: $vendorid: duplicate vendor ID\n";
97                 }
98                 $vendors{$vendorid}[$W_VENDORS] = $vendor;
99                 $pciids{$vendorid}{$pciid}[$W_VENDORS] = $descr;
100         }
101 }
102 close(VENDORS);
103
104 open(PCIDEVS, "< $opts{p}") or
105     die "$PROGNAME: $opts{p}: $!\n";
106 while ($line = <PCIDEVS>) {
107         chomp($line);
108         $rv = pcidevs_parse($line, $id, $descr);
109         if ($rv == $IS_VENDOR) {
110                 $vendorid = $id;
111                 $vendors{$vendorid}[$W_PCIDEVS] = $descr;
112         } elsif ($rv == $IS_DEVICE) {
113                 $pciids{$vendorid}{$id}[$W_PCIDEVS] = $descr;
114         }
115 }
116 close(PCIDEVS);
117
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];
127         } else {
128                 if (length($vendors{$vid}[$W_VENDORS]) >
129                     length($vendors{$vid}[$W_PCIDEVS])) {
130                         $vendors{$vid}[$W_FINAL] = $vendors{$vid}[$W_VENDORS];
131                 } else {
132                         $vendors{$vid}[$W_FINAL] = $vendors{$vid}[$W_PCIDEVS];
133                 }
134         }
135
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];
148                 } else {
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];
153                         } else {
154                                 $pciids{$vid}{$pciid}[$W_FINAL] =
155                                     $pciids{$vid}{$pciid}[$W_PCIDEVS];
156                         }
157                 }
158         }
159
160 }
161
162 $optlused = $opts{l} ? "with" : "without";
163 print <<HEADER_END;
164 ; \$FreeBSD\$
165 ;
166 ; Automatically generated by src/tools/tools/pciid/mk_pci_vendors.pl
167 ; ($optlused the -l option), using the following source lists:
168 ;
169 ;       http://www.pcidatabase.com/reports.php?type=csv
170 ;       http://members.datafast.net.au/dft0802/downloads/pcidevs.txt
171 ;
172 ; Manual edits on this file will be lost!
173 ;
174 HEADER_END
175
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";
182         }
183 }
184 exit 0;
185
186
187 # Parse a line from the Boemler CSV file and place the vendor id, pciid,
188 # vendor description and description in the scalars.
189 #
190 # Returns 0 if there is a problem.
191 #
192 sub vendors_parse($\$\$\$\$)
193 {
194         my ($line, $vendorid_ref, $pciid_ref, $vendor_ref, $descr_ref) = @_;
195
196         my @a = split(/","/, $line);
197         $a[0] =~ s/0x//;        # 0x1234 -> 1234
198         $a[1] =~ s/0x//;
199
200         $a[0] =~ s/^"//;        # Remove starting or trailing "
201         $a[4] =~ s/"$//;
202
203         $a[0] = uc($a[0]);      # Some are lowercase hex-digits
204         $a[1] = uc($a[1]);
205
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);
208
209         # If there is no description, see if the chip data exists and use that
210         if ($a[4] eq "") {
211                 if ($a[3] ne "") {
212                         $a[4] = $a[3];
213                         $a[3] = "";
214                 } else {
215                         $a[4] = "?";
216                 }
217         }
218
219         $$vendorid_ref = $a[0];
220         $$pciid_ref = $a[1];
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]/);
224         return 1;
225 }
226
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.
229 #
230 # On success, returns $IS_VENDOR if the line represents a vendor entity
231 # or $IS_DEVICE if the line represents a device entity.
232 #
233 # Returns 0 on failure.
234 #
235 sub pcidevs_parse($\$\$)
236 {
237         my ($line, $id_ref, $descr_ref) = @_;
238         my $descr;
239
240         if ($line =~ /^V\t([A-Fa-f0-9]{4})\t([^\t].+?)\s*$/) {
241                 ($$id_ref, $$descr_ref) = (uc($1), clean_descr($2));
242                 return $IS_VENDOR;
243         } elsif ($line =~ /^D\t([A-Fa-f0-9]{4})\t([^\t].+?)\s*$/) {
244                 ($$id_ref, $$descr_ref) = (uc($1), clean_descr($2));
245                 return $IS_DEVICE;
246         } elsif (not $opts{q} and
247             $line !~ /^\s*$/ and $line !~ /^[;ORSX]/) {
248                 print STDERR "$PROGNAME: ignored Hart: $line\n";
249         }
250
251         return 0;
252 }
253
254 sub clean_descr($)
255 {
256         my ($descr) = @_;
257
258         $descr =~ s/[^[:print:]]//g;    # non-printable
259         $descr =~ s/\\//g;      # escape of 's
260         $descr =~ s/\#/*/g;     # pciconf(8) ignores data after this
261
262         return $descr;
263 }