Update data
[oweals/hwids.git] / udev-hwdb-update.pl
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 sub usb_vendor {
7         my $vendor;
8
9         open(IN, "<", "usb.ids");
10         open(OUT, ">", "20-usb-vendor-model.hwdb");
11         print(OUT "# This file is part of systemd.\n" .
12                   "#\n" .
13                   "# Data imported from: http://www.linux-usb.org/usb.ids\n");
14
15         while (my $line = <IN>) {
16                 $line =~ s/\s+$//;
17                 $line =~ m/^([0-9a-f]{4})\s*(.+)$/;
18                 if (defined $1) {
19                         $vendor = uc $1;
20                         my $text = $2;
21                         print(OUT "\n");
22                         print(OUT "usb:v" . $vendor . "*\n");
23                         print(OUT " ID_VENDOR_FROM_DATABASE=" . $text . "\n");
24                         next;
25                 }
26
27                 $line =~ m/^\t([0-9a-f]{4})\s*(.+)$/;
28                 if (defined $1) {
29                         my $model = uc $1;
30                         my $text = $2;
31                         print(OUT "\n");
32                         print(OUT "usb:v" . $vendor . "p" . $model . "*\n");
33                         print(OUT " ID_MODEL_FROM_DATABASE=" . $text . "\n");
34                 }
35         }
36
37         close(IN);
38         close(OUT);
39 }
40
41 sub usb_classes {
42         my $class;
43         my $subclass;
44         my $protocol;
45
46         open(IN, "<", "usb.ids");
47         open(OUT, ">", "20-usb-classes.hwdb");
48         print(OUT "# This file is part of systemd.\n" .
49                   "#\n" .
50                   "# Data imported from: http://www.linux-usb.org/usb.ids\n");
51
52         while (my $line = <IN>) {
53                 $line =~ s/\s+$//;
54
55                 $line =~ m/^C\ ([0-9a-f]{2})\s*(.+)$/;
56                 if (defined $1) {
57                         $class = uc $1;
58                         if ($class =~ m/^00$/) {
59                                 next;
60                         }
61                         my $text = $2;
62                         print(OUT "\n");
63                         print(OUT "usb:v*p*d*dc" . $class . "*\n");
64                         print(OUT " ID_USB_CLASS_FROM_DATABASE=" . $text . "\n");
65                         next;
66                 }
67
68                 if (not defined $class) {
69                         next;
70                 } elsif ($line =~ m/^$/) {
71                         last;
72                 }
73
74                 $line =~ m/^\t([0-9a-f]{2})\s*(.+)$/;
75                 if (defined $1) {
76                         $subclass = uc $1;
77                         if ($subclass =~ m/^00$/) {
78                                 next;
79                         }
80                         my $text = $2;
81                         if ($text =~ m/^(\?|None|Unused)$/) {
82                                 next;
83                         }
84                         print(OUT "\n");
85                         print(OUT "usb:v*p*d*dc" . $class . "dsc" . $subclass . "*\n");
86                         print(OUT " ID_USB_SUBCLASS_FROM_DATABASE=" . $text . "\n");
87                         next;
88                 }
89
90                 $line =~ m/^\t\t([0-9a-f]{2})\s*(.+)$/;
91                 if (defined $1) {
92                         $protocol = uc $1;
93                         my $text = $2;
94                         if ($text =~ m/^(\?|None|Unused)$/) {
95                                 next;
96                         }
97                         print(OUT "\n");
98                         print(OUT "usb:v*p*d*dc" .  $class . "dsc" . $subclass . "dp" . $protocol . "*\n");
99                         print(OUT " ID_USB_PROTOCOL_FROM_DATABASE=" . $text . "\n");
100                 }
101         }
102
103         close(IN);
104         close(OUT);
105 }
106
107 sub pci_vendor {
108         my $vendor;
109         my $device;
110         my $device_text;
111
112         open(IN, "<", "pci.ids");
113         open(OUT, ">", "20-pci-vendor-model.hwdb");
114         print(OUT "# This file is part of systemd.\n" .
115                   "#\n" .
116                   "# Data imported from: http://pci-ids.ucw.cz/v2.2/pci.ids\n");
117
118         while (my $line = <IN>) {
119                 $line =~ s/\s+$//;
120                 $line =~ m/^([0-9a-f]{4})\s*(.+)$/;
121
122                 if (defined $1) {
123                         $vendor = uc $1;
124                         my $text = $2;
125                         print(OUT "\n");
126                         print(OUT "pci:v0000" . $vendor . "*\n");
127                         print(OUT " ID_VENDOR_FROM_DATABASE=" . $text . "\n");
128                         next;
129                 }
130
131                 $line =~ m/^\t([0-9a-f]{4})\s*(.+)$/;
132                 if (defined $1) {
133                         $device = uc $1;
134                         $device_text = $2;
135                         print(OUT "\n");
136                         print(OUT "pci:v0000" . $vendor . "d0000" . $device . "*\n");
137                         print(OUT " ID_MODEL_FROM_DATABASE=" . $device_text . "\n");
138                         next;
139                 }
140
141                 $line =~ m/^\t\t([0-9a-f]{4})\s*([0-9a-f]{4})\s*(.*)$/;
142                 if (defined $1) {
143                         my $sub_vendor = uc $1;
144                         my $sub_device = uc $2;
145                         my $sub_text = $3;
146                         $sub_text =~ s/^\Q$device_text\E\s*//;
147                         $sub_text =~ s/(.+)/\ ($1)/;
148                         print(OUT "\n");
149                         print(OUT "pci:v0000" . $vendor . "d0000" . $device . "sv0000" . $sub_vendor . "sd0000" . $sub_device . "*\n");
150                         print(OUT " ID_MODEL_FROM_DATABASE=" . $device_text . $sub_text . "\n");
151                 }
152         }
153
154         close(IN);
155         close(OUT);
156 }
157
158 sub pci_classes {
159         my $class;
160         my $subclass;
161         my $interface;
162
163         open(IN, "<", "pci.ids");
164         open(OUT, ">", "20-pci-classes.hwdb");
165         print(OUT "# This file is part of systemd.\n" .
166                   "#\n" .
167                   "# Data imported from: http://pci-ids.ucw.cz/v2.2/pci.ids\n");
168
169         while (my $line = <IN>) {
170                 $line =~ s/\s+$//;
171
172                 $line =~ m/^C\ ([0-9a-f]{2})\s*(.+)$/;
173                 if (defined $1) {
174                         $class = uc $1;
175                         my $text = $2;
176                         print(OUT "\n");
177                         print(OUT "pci:v*d*sv*sd*bc" . $class . "*\n");
178                         print(OUT " ID_PCI_CLASS_FROM_DATABASE=" . $text . "\n");
179                         next;
180                 }
181
182                 if (not defined $class) {
183                         next;
184                 } elsif ($line =~ m/^$/) {
185                         last;
186                 }
187
188                 $line =~ m/^\t([0-9a-f]{2})\s*(.+)$/;
189                 if (defined $1) {
190                         $subclass = uc $1;
191                         my $text = $2;
192                         print(OUT "\n");
193                         print(OUT "pci:v*d*sv*sd*bc" . $class . "sc" . $subclass . "*\n");
194                         print(OUT " ID_PCI_SUBCLASS_FROM_DATABASE=" . $text . "\n");
195                         next;
196                 }
197
198                 $line =~ m/^\t\t([0-9a-f]{2})\s*(.+)$/;
199                 if (defined $1) {
200                         $interface = uc $1;
201                         my $text = $2;
202                         print(OUT "\n");
203                         print(OUT "pci:v*d*sv*sd*bc" .  $class . "sc" . $subclass . "i" . $interface . "*\n");
204                         print(OUT " ID_PCI_INTERFACE_FROM_DATABASE=" . $text . "\n");
205                 }
206         }
207
208         close(IN);
209         close(OUT);
210 }
211
212 sub sdio_vendor {
213         my $vendor;
214         my $device;
215
216         open(IN, "<", "sdio.ids");
217         open(OUT, ">", "20-sdio-vendor-model.hwdb");
218         print(OUT "# This file is part of systemd.\n" .
219                   "#\n" .
220                   "# Data imported from: hwdb/sdio.ids\n");
221
222         while (my $line = <IN>) {
223                 $line =~ s/\s+$//;
224                 $line =~ m/^([0-9a-f]{4})\s*(.+)$/;
225
226                 if (defined $1) {
227                         $vendor = uc $1;
228                         my $text = $2;
229                         print(OUT "\n");
230                         print(OUT "sdio:c*v" . $vendor . "*\n");
231                         print(OUT " ID_VENDOR_FROM_DATABASE=" . $text . "\n");
232                         next;
233                 }
234
235                 $line =~ m/^\t([0-9a-f]{4})\s*(.+)$/;
236                 if (defined $1) {
237                         $device = uc $1;
238                         my $text = $2;
239                         print(OUT "\n");
240                         print(OUT "sdio:c*v" . $vendor . "d" . $device . "*\n");
241                         print(OUT " ID_MODEL_FROM_DATABASE=" . $text . "\n");
242                         next;
243                 }
244         }
245
246         close(IN);
247         close(OUT);
248 }
249
250 sub sdio_classes {
251         my $class;
252         my $subclass;
253         my $interface;
254
255         open(IN, "<", "sdio.ids");
256         open(OUT, ">", "20-sdio-classes.hwdb");
257         print(OUT "# This file is part of systemd.\n" .
258                   "#\n" .
259                   "# Data imported from: hwdb/sdio.ids\n");
260
261         while (my $line = <IN>) {
262                 $line =~ s/\s+$//;
263
264                 $line =~ m/^C\ ([0-9a-f]{2})\s*(.+)$/;
265                 if (defined $1) {
266                         $class = uc $1;
267                         my $text = $2;
268                         print(OUT "\n");
269                         print(OUT "sdio:c" . $class . "v*d*\n");
270                         print(OUT " ID_SDIO_CLASS_FROM_DATABASE=" . $text . "\n");
271                         next;
272                 }
273         }
274
275         close(IN);
276         close(OUT);
277 }
278
279 # MAC Address Block Large/Medium/Small
280 # Large  MA-L 24/24 bit (OUI)
281 # Medium MA-M 28/20 bit (OUI prefix owned by IEEE)
282 # Small  MA-S 36/12 bit (OUI prefix owned by IEEE)
283 sub oui {
284         my $prefix;
285         my %ieee_prefixes = ();
286
287         open(OUT, ">", "20-OUI.hwdb");
288         print(OUT "# This file is part of systemd.\n" .
289                   "#\n" .
290                   "# Data imported from:\n" .
291                   "#   https://services13.ieee.org/RST/standards-ra-web/rest/assignments/download/?registry=MA-L&format=txt\n" .
292                   "#   https://services13.ieee.org/RST/standards-ra-web/rest/assignments/download/?registry=MA-M&format=txt\n" .
293                   "#   https://services13.ieee.org/RST/standards-ra-web/rest/assignments/download/?registry=MA-S&format=txt\n");
294
295         open(IN, "<", "ma-small.txt");
296         while (my $line = <IN>) {
297                 $line =~ s/^ +//;
298                 $line =~ s/\s+$//;
299                 $line =~ m/^([0-9A-F]{2})-([0-9A-F]{2})-([0-9A-F]{2})\s*\(hex\)\s*.+$/;
300                 if (defined $1) {
301                         $prefix = $1 . $2 . $3;
302                         $ieee_prefixes{ $prefix } = 1;
303                         next;
304                 }
305
306                 $line =~ m/^([0-9A-F]{3})000-\g1FFF\s*\(base 16\)\s*(.+)$/;
307                 if (defined $1) {
308                         my $vendor = uc $1;
309                         my $text = $2;
310
311                         print(OUT "\n");
312                         print(OUT "OUI:" . $prefix . $vendor . "*\n");
313                         print(OUT " ID_OUI_FROM_DATABASE=" . $text . "\n");
314                 }
315         }
316         close(IN);
317
318         open(IN, "<", "ma-medium.txt");
319         while (my $line = <IN>) {
320                 $line =~ s/^ +//;
321                 $line =~ s/\s+$//;
322                 $line =~ m/^([0-9A-F]{2})-([0-9A-F]{2})-([0-9A-F]{2})\s*\(hex\)\s*.+$/;
323                 if (defined $1) {
324                         $prefix = $1 . $2 . $3;
325                         $ieee_prefixes{ $prefix } = 1;
326                         next;
327                 }
328
329                 $line =~ m/^([0-9A-F])00000-\g1FFFFF\s*\(base 16\)\s*(.+)$/;
330                 if (defined $1) {
331                         my $vendor = uc $1;
332                         my $text = $2;
333
334                         print(OUT "\n");
335                         print(OUT "OUI:" . $prefix . $vendor . "*\n");
336                         print(OUT " ID_OUI_FROM_DATABASE=" . $text . "\n");
337                 }
338         }
339
340         open(IN, "<", "ma-large.txt");
341         while (my $line = <IN>) {
342                 $line =~ s/^ +//;
343                 $line =~ s/\s+$//;
344                 $line =~ m/^([0-9A-F]{6})\s*\(base 16\)\s*(.+)$/;
345                 if (defined $1) {
346                         my $vendor = uc $1;
347                         my $text = $2;
348
349                         if ($text =~ m/^IEEE REGISTRATION AUTHORITY/) {
350                                 next;
351                         }
352
353                         # skip the IEEE owned prefixes
354                         if (! exists $ieee_prefixes{ $vendor }) {
355                                 print(OUT "\n");
356                                 print(OUT "OUI:" . $vendor . "*\n");
357                                 print(OUT " ID_OUI_FROM_DATABASE=" . $text . "\n");
358                         }
359                 }
360         }
361         close(IN);
362
363         close(OUT);
364 }
365
366 usb_vendor();
367 usb_classes();
368
369 pci_vendor();
370 pci_classes();
371
372 sdio_vendor();
373 sdio_classes();
374
375 oui();