]> git.ipfire.org Git - ipfire-2.x.git/blame - src/hwinfo/src/ids/convert_hd
Kleiner netter neuer Versuch.
[ipfire-2.x.git] / src / hwinfo / src / ids / convert_hd
CommitLineData
a6316ce4
MT
1#! /usr/bin/perl
2
3use Getopt::Long;
4use XML::Writer;
5use XML::Parser;
6use IO;
7use Dumpvalue;
8
9sub help;
10
11sub read_name_file;
12sub read_driver_file;
13sub read_id_file;
14sub read_pcimap_file;
15sub read_usbmap_file;
16sub read_alias_file;
17sub read_modinfo_file;
18sub eisa_id;
19sub eisa_str;
20
21sub remove_nops;
22sub remove_duplicates;
23sub fix_driver_info;
24
25sub cmp_id;
26sub cmp_skey;
27sub cmp_item;
28
29sub match_id;
30sub match_skey;
31sub match_item;
32
33sub join_skey;
34
35sub split_item;
36
37sub get_xml_data;
38sub parse_xml_item;
39sub parse_xml_key;
40sub parse_xml_id;
41sub parse_xml_id_id;
42sub parse_xml_id_range;
43sub parse_xml_id_mask;
44sub parse_xml_driver;
45sub parse_xml_driver_display;
46sub parse_xml_driver_module;
47sub parse_xml_driver_mouse;
48sub parse_xml_driver_xfree;
49sub parse_xml_pair;
50sub parse_xml_cdata;
51sub idstr2value;
52
53sub dump2ids;
54sub dump2xml;
55sub dump_xml_item;
56sub dump_xml_names;
57sub dump_xml_drivers;
58sub id2xml;
59
60sub hd_dtd;
61sub hd_dtd_internal;
62
63$dump = new Dumpvalue();
64
65(
66 $he_other, $he_bus_id, $he_baseclass_id, $he_subclass_id, $he_progif_id,
67 $he_vendor_id, $he_device_id, $he_subvendor_id, $he_subdevice_id, $he_rev_id,
68 $he_bus_name, $he_baseclass_name, $he_subclass_name, $he_progif_name,
69 $he_vendor_name, $he_device_name, $he_subvendor_name, $he_subdevice_name,
70 $he_rev_name, $he_serial, $he_driver, $he_requires,
71 $he_nomask,
72 $he_driver_module_insmod, $he_driver_module_modprobe,
73 $he_driver_module_config, $he_driver_xfree, $he_driver_xfree_config,
74 $he_driver_mouse, $he_driver_display, $he_driver_any
75) = ( 0 .. 100 );
76$he_class_id = $he_nomask;
77
78@ent_names = (
79 "other", "bus.id", "baseclass.id", "subclass.id", "progif.id",
80 "vendor.id", "device.id", "subvendor.id", "subdevice.id", "rev.id",
81 "bus.name", "baseclass.name", "subclass.name", "progif.name",
82 "vendor.name", "device.name", "subvendor.name", "subdevice.name",
83 "rev.name", "serial", "driver", "requires",
84 "class.id", "driver.module.insmod", "driver.module.modprobe",
85 "driver.module.config", "driver.xfree", "driver.xfree.config",
86 "driver.mouse", "driver.display", "driver.any"
87);
88@ent_values{@ent_names} = ( 0 .. 100 );
89
90@xml_names = (
91 "other", "bus", "baseclass", "subclass", "progif",
92 "vendor", "device", "subvendor", "subdevice", "revision",
93 "bus", "baseclass", "subclass", "progif",
94 "vendor", "device", "subvendor", "subdevice",
95 "revision", "serial", "driver", "requires"
96);
97@xml_values{@xml_names} = ( 0 .. 100 );
98
99( $tag_none, $tag_pci, $tag_eisa, $tag_usb, $tag_special, $tag_pcmcia ) = ( 0 .. 5 );
100
101@tag_name = ( "", "pci", "eisa", "usb", "special", "pcmcia" );
102@tag_values{@tag_name} = ( 0 .. 5 );
103$tag_values{none} = 0;
104
105( $flag_id, $flag_range, $flag_mask, $flag_string, $flag_regexp ) = ( 0 .. 4 );
106$flag_cont = 8;
107
108# map usb modules to device classes
109%usbmod2class = (
110 'ov511' => [ 0x10f, 0 ],
111 'pwc' => [ 0x10f, 0 ],
112 'hpusbscsi' => [ 0x10c, 0 ],
113 'microtek' => [ 0x10c, 0 ],
114 'scanner' => [ 0x10c, 0 ]
115);
116
117
118# options
119$opt_write_ids = 1;
120$opt_write_xml = 0;
121$opt_sort_ids = 0;
122$opt_sort_reverse = 0;
123$opt_sort_random = 0; # for testing
124$opt_split = 0;
125$opt_with_source = 0;
126$opt_fix_driver = 1;
127$opt_help = 0;
128$opt_internal_dtd = 0;
129
130$opt_ok = GetOptions(
131 'ids' => \$opt_write_ids,
132 'no-ids' => sub { $opt_write_ids = 0 },
133 'xml' => \$opt_write_xml,
134 'no-xml' => sub { $opt_write_xml = 0 },
135 'sort' => \$opt_sort,
136 'reverse' => \$opt_sort_reverse,
137 'random' => \$opt_sort_random,
138 'split' => \$opt_split,
139 'with-source' => \$opt_with_source,
140 'fix-driver' => \$opt_fix_driver,
141 'no-fix-driver' => sub { $opt_fix_driver = 0 },
142 'internal-dtd' => \$opt_internal_dtd,
143 'help' => \&help
144) ;
145
146for $f (@ARGV) {
147 if(open F, $f) {
148 @f = (<F>);
149 close F;
150
151 # file format check
152
153 undef $format;
154
155 for (@f) {
156 if(/^\s*\<\?xml\s/) {
157 $format = 'xml';
158 last;
159 }
160
161 if(/^#\s+pci\s+module\s+vendor\s+device\s+subvendor\s+subdevice\s+class\s+class_mask\s+driver_data\s*$/) {
162 $format = 'pcimap';
163 last;
164 }
165
166 if(/^#\s+usb\s+module\s+match_flags\s+idVendor\s+idProduct\s+/) {
167 $format = 'usbmap';
168 last;
169 }
170
171 if(/^\s*alias\s+(pci|pnp|usb):\S+\s+\S+$/) {
172 $format = 'alias';
173 last;
174 }
175
176 if(/^\s*alias:\s+(pci|pnp|usb):\S+\s*$/) {
177 $format = 'modinfo';
178 last;
179 }
180
181 }
182
183 if(!$format) {
184 $i = join "|", map "\Q$_", @ent_names;
185 for (@f) {
186 if(/^\s*[+&|]?($i)\s/) {
187 $format = 'ids';
188 last;
189 }
190 }
191 }
192
193 if(!$format) {
194 for (@f) {
195 if(/^\t[a-z]\s/) {
196 $format = 'drivers';
197 last;
198 }
199 }
200 }
201
202 $format = 'names' if !$format;
203
204 if($format eq 'names') {
205
206 print STDERR "====== \"$f\": name info ======\n";
207 read_name_file $f, \@f;
208
209 }
210 elsif($format eq 'drivers') {
211
212 print STDERR "====== \"$f\": driver info ======\n";
213 read_driver_file $f, \@f;
214
215 }
216 elsif($format eq 'xml') {
217
218 print STDERR "====== \"$f\": xml info ======\n";
219 $xmlp = new XML::Parser(Style => 'Tree', ParseParamEnt => 1);
220 get_xml_data $xmlp->parsefile($f);
221
222 }
223 elsif($format eq 'ids') {
224
225 print STDERR "====== \"$f\": id info ======\n";
226 read_id_file $f, \@f;
227
228 }
229 elsif($format eq 'pcimap') {
230
231 print STDERR "====== \"$f\": pcimap info ======\n";
232 read_pcimap_file $f, \@f;
233
234 }
235 elsif($format eq 'usbmap') {
236
237 print STDERR "====== \"$f\": usbmap info ======\n";
238 read_usbmap_file $f, \@f;
239
240 }
241 elsif($format eq 'alias') {
242
243 print STDERR "====== \"$f\": alias info ======\n";
244 read_alias_file $f, \@f;
245
246 }
247 elsif($format eq 'modinfo') {
248
249 print STDERR "====== \"$f\": module info ======\n";
250 read_modinfo_file $f, \@f;
251
252 }
253 }
254 else {
255 die "$f: $!\n"
256 }
257}
258
259print STDERR "removing unnecessary items\n";
260remove_nops;
261
262print STDERR "got ${\scalar @hd} items\n";
263
264if($opt_fix_driver) {
265 fix_driver_info;
266}
267
268if($opt_split) {
269 print STDERR "splitting items\n";
270 for (@hd) {
271 push @hd_new, split_item($_);
272 }
273 @hd = @hd_new;
274 undef @hd_new;
275}
276
277if($opt_sort_ids) {
278 print STDERR "sorting\n";
279 if($opt_sort_random) {
280 @hd = sort { $cmp_item_cnt++, rand() <=> rand() } @hd;
281 }
282 elsif($opt_sort_reverse) {
283 @hd = sort { cmp_item $b, $a } @hd;
284 }
285 else {
286 @hd = sort { cmp_item $a, $b } @hd;
287 }
288}
289
290if($opt_write_ids) {
291 print STDERR "writing \"hd.ids\"\n";
292 dump2ids;
293}
294
295if($opt_write_xml) {
296 print STDERR "writing \"hd.xml\"\n";
297 dump2xml;
298}
299
300print STDERR "cmps: $cmp_item_cnt\n" if $cmp_item_cnt;
301
302# $dump->dumpValue( \@hd );
303
304
305# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
306
307sub help
308{
309 print STDERR
310 "Usage: convert_hd [options] files\n" .
311 "Convert various hardware info to libhd/hwinfo internal format or to XML.\n" .
312 " --ids write internal format (default) to \"hd.ids\"\n" .
313 " --no-ids do not write internal format\n" .
314 " --xml write XML to \"hd.xml\", DTD to \"hd.dtd\"\n" .
315 " --no-xml do not write XML (default)\n" .
316 " --with-source add comment to each item indicating info source\n" .
317 " --internal-dtd generate internal dtd\n\n" .
318 " Note: for more sophisticated operations on hardware data use check_hd.\n";
319
320 exit 0;
321}
322
323
324# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
325sub num
326{
327 return $_[0] =~ /^0/ ? oct $_[0] : return $_[0] + 0;
328}
329
330
331# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
332#
333# read file with name/class info
334#
335# (either pciutils or SaX/SaX2 format)
336#
337
338sub read_name_file
339{
340 my ( $file_name, $file, $line, $sax_version, $tag, $id, $val, $ent );
341 my ( @id0, @id1, @id2, @id3, @id4, $raw, $opt, $ext, $srv, $str );
342 local $_;
343
344 my $rnf_add_id0 = sub
345 {
346 my ( $id0, $name0, $ent_id0, $ent_name0, $id, $val );
347
348 # note: $tag belongs to read_name_file()
349 ( $ent_id0, $ent_name0, $tag, $id0, $name0 ) = @_;
350
351 $ent = $ent_id0;
352
353 @id0 = ( $flag_id, $tag, $id0 );
354 undef @id1; undef @id2; undef @id3;
355
356 $id->[$ent_id0] = [ @id0 ];
357 $val->[$ent_name0] = [ $flag_string, $name0 ];
358
359 push @hd, [ "$file_name($line)", [ $id ], $val ];
360 };
361
362 my $rnf_add_bus = sub
363 {
364 $rnf_add_id0->($he_bus_id, $he_bus_name, 0, @_);
365 };
366
367 my $rnf_add_baseclass = sub
368 {
369 $rnf_add_id0->($he_baseclass_id, $he_baseclass_name, 0, @_);
370 };
371
372 my $rnf_add_vendor = sub
373 {
374 $rnf_add_id0->($he_vendor_id, $he_vendor_name, @_);
375 };
376
377 my $rnf_add_subdevice = sub
378 {
379 my ( $id2, $id3, $range, $name, $class, $id, $val );
380
381 ( $id2, $id3, $range, $name, $class ) = @_;
382
383 @id2 = ( $flag_id, $tag, $id2 );
384 @id3 = ( $flag_id, $tag, $id3 );
385 $id3[3] = $range if defined $range;
386
387 if($ent == $he_device_id || $ent == $he_subdevice_id) {
388 $ent = $he_subdevice_id;
389
390 $id->[$he_vendor_id] = [ @id0 ];
391 $id->[$he_device_id] = [ @id1 ];
392 $id->[$he_subvendor_id] = [ @id2 ];
393 $id->[$he_subdevice_id] = [ @id3 ];
394 $val->[$he_subdevice_name] = [ $flag_string, $name ];
395 if(defined $class) {
396 $val->[$he_baseclass_id] = [ $flag_id, $tag_none, $class >> 8 ];
397 $val->[$he_subclass_id] = [ $flag_id, $tag_none, $class & 0xff ];
398 }
399 }
400 else {
401 die "oops $file_name($line): subdevice id expected\n";
402 }
403
404 push @hd, [ "$file_name($line)", [ $id ], $val ];
405 };
406
407 ( $file_name, $file ) = @_;
408
409 $line = 0;
410 undef $sax_version;
411
412 for (@$file) {
413 $line++;
414 chomp;
415 s/\s*$//;
416 next if /^\s*[#;]/;
417 next if /^$/;
418
419 # SaX Identity file
420