17
sub read_modinfo_file;
22
sub remove_duplicates;
42
sub parse_xml_id_range;
43
sub parse_xml_id_mask;
45
sub parse_xml_driver_display;
46
sub parse_xml_driver_module;
47
sub parse_xml_driver_mouse;
48
sub parse_xml_driver_xfree;
63
$dump = new Dumpvalue();
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, $he_hwclass,
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
76
$he_class_id = $he_nomask;
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", "hwclass",
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"
88
@ent_values{@ent_names} = ( 0 .. 100 );
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"
97
@xml_values{@xml_names} = ( 0 .. 100 );
99
( $tag_none, $tag_pci, $tag_eisa, $tag_usb, $tag_special, $tag_pcmcia ) = ( 0 .. 5 );
101
@tag_name = ( "", "pci", "eisa", "usb", "special", "pcmcia" );
102
@tag_values{@tag_name} = ( 0 .. 5 );
103
$tag_values{none} = 0;
105
( $flag_id, $flag_range, $flag_mask, $flag_string, $flag_regexp ) = ( 0 .. 4 );
108
# map usb modules to device classes
110
'ov511' => [ 0x10f, 0 ],
111
'pwc' => [ 0x10f, 0 ],
112
'hpusbscsi' => [ 0x10c, 0 ],
113
'microtek' => [ 0x10c, 0 ],
114
'scanner' => [ 0x10c, 0 ]
118
undef, "system", "cpu", "keyboard", "braille", "mouse", "joystick",
119
"printer", "scanner", "chipcard", "monitor", "tv card", "graphics card",
120
"framebuffer", "camera", "sound", "storage", "network", "isdn adapter",
121
"modem", "network interface", "disk", "partition", "cdrom", "floppy",
122
"manual", "usb controller", "usb", "bios", "pci", "isapnp", "bridge",
123
"hub", "scsi", "ide", "memory", "dvb card", "pcmcia", "pcmcia controller",
124
"firewire", "firewire controller", "hotplug", "hotplug controller", "zip",
125
"pppoe", "wlan card", "redasd", "dsl adapter", "block device", "tape",
126
"vesa bios", "bluetooth", "unknown"
128
@hwclass_values{@hwclass_names} = ( 0 .. 255 );
135
$opt_sort_reverse = 0;
136
$opt_sort_random = 0; # for testing
138
$opt_with_source = 0;
141
$opt_internal_dtd = 0;
143
$opt_ok = GetOptions(
144
'ids' => \$opt_write_ids,
145
'no-ids' => sub { $opt_write_ids = 0 },
146
'xml' => \$opt_write_xml,
147
'no-xml' => sub { $opt_write_xml = 0 },
148
'sort' => \$opt_sort,
149
'reverse' => \$opt_sort_reverse,
150
'random' => \$opt_sort_random,
151
'split' => \$opt_split,
152
'with-source' => \$opt_with_source,
153
'fix-driver' => \$opt_fix_driver,
154
'no-fix-driver' => sub { $opt_fix_driver = 0 },
155
'internal-dtd' => \$opt_internal_dtd,
169
if(/^\s*\<\?xml\s/) {
174
if(/^#\s+pci\s+module\s+vendor\s+device\s+subvendor\s+subdevice\s+class\s+class_mask\s+driver_data\s*$/) {
179
if(/^#\s+usb\s+module\s+match_flags\s+idVendor\s+idProduct\s+/) {
184
if(/^\s*alias\s+(pci|pnp|usb):\S+\s+\S+$/) {
189
if(/^\s*alias:\s+(pci|pnp|usb):\S+\s*$/) {
197
$i = join "|", map "\Q$_", @ent_names;
199
if(/^\s*[+&|]?($i)\s/) {
215
$format = 'names' if !$format;
217
if($format eq 'names') {
219
print STDERR "====== \"$f\": name info ======\n";
220
read_name_file $f, \@f;
223
elsif($format eq 'drivers') {
225
print STDERR "====== \"$f\": driver info ======\n";
226
read_driver_file $f, \@f;
229
elsif($format eq 'xml') {
231
print STDERR "====== \"$f\": xml info ======\n";
232
$xmlp = new XML::Parser(Style => 'Tree', ParseParamEnt => 1);
233
get_xml_data $xmlp->parsefile($f);
236
elsif($format eq 'ids') {
238
print STDERR "====== \"$f\": id info ======\n";
239
read_id_file $f, \@f;
242
elsif($format eq 'pcimap') {
244
print STDERR "====== \"$f\": pcimap info ======\n";
245
read_pcimap_file $f, \@f;
248
elsif($format eq 'usbmap') {
250
print STDERR "====== \"$f\": usbmap info ======\n";
251
read_usbmap_file $f, \@f;
254
elsif($format eq 'alias') {
256
print STDERR "====== \"$f\": alias info ======\n";
257
read_alias_file $f, \@f;
260
elsif($format eq 'modinfo') {
262
print STDERR "====== \"$f\": module info ======\n";
263
read_modinfo_file $f, \@f;
272
print STDERR "removing unnecessary items\n";
275
print STDERR "got ${\scalar @hd} items\n";
277
if($opt_fix_driver) {
282
print STDERR "splitting items\n";
284
push @hd_new, split_item($_);
291
print STDERR "sorting\n";
292
if($opt_sort_random) {
293
@hd = sort { $cmp_item_cnt++, rand() <=> rand() } @hd;
295
elsif($opt_sort_reverse) {
296
@hd = sort { cmp_item $b, $a } @hd;
299
@hd = sort { cmp_item $a, $b } @hd;
304
print STDERR "writing \"hd.ids\"\n";
309
print STDERR "writing \"hd.xml\"\n";
313
print STDERR "cmps: $cmp_item_cnt\n" if $cmp_item_cnt;
315
# $dump->dumpValue( \@hd );
318
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
323
"Usage: convert_hd [options] files\n" .
324
"Convert various hardware info to libhd/hwinfo internal format or to XML.\n" .
325
" --ids write internal format (default) to \"hd.ids\"\n" .
326
" --no-ids do not write internal format\n" .
327
" --xml write XML to \"hd.xml\", DTD to \"hd.dtd\"\n" .
328
" --no-xml do not write XML (default)\n" .
329
" --with-source add comment to each item indicating info source\n" .
330
" --internal-dtd generate internal dtd\n\n" .
331
" Note: for more sophisticated operations on hardware data use check_hd.\n";
337
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
340
return $_[0] =~ /^0/ ? oct $_[0] : return $_[0] + 0;
344
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
346
# read file with name/class info
348
# (either pciutils or SaX/SaX2 format)
353
my ( $file_name, $file, $line, $sax_version, $tag, $id, $val, $ent );
354
my ( @id0, @id1, @id2, @id3, @id4, $raw, $opt, $ext, $srv, $str );
357
my $rnf_add_id0 = sub
359
my ( $id0, $name0, $ent_id0, $ent_name0, $id, $val );
361
# note: $tag belongs to read_name_file()
362
( $ent_id0, $ent_name0, $tag, $id0, $name0 ) = @_;
366
@id0 = ( $flag_id, $tag, $id0 );
367
undef @id1; undef @id2; undef @id3;
369
$id->[$ent_id0] = [ @id0 ];
370
$val->[$ent_name0] = [ $flag_string, $name0 ];
372
push @hd, [ "$file_name($line)", [ $id ], $val ];
375
my $rnf_add_bus = sub
377
$rnf_add_id0->($he_bus_id, $he_bus_name, 0, @_);
380
my $rnf_add_baseclass = sub
382
$rnf_add_id0->($he_baseclass_id, $he_baseclass_name, 0, @_);
385
my $rnf_add_vendor = sub
387
$rnf_add_id0->($he_vendor_id, $he_vendor_name, @_);
390
my $rnf_add_subdevice = sub
392
my ( $id2, $id3, $range, $name, $class, $id, $val );
394
( $id2, $id3, $range, $name, $class ) = @_;
396
@id2 = ( $flag_id, $tag, $id2 );
397
@id3 = ( $flag_id, $tag, $id3 );
398
$id3[3] = $range if defined $range;
400
if($ent == $he_device_id || $ent == $he_subdevice_id) {
401
$ent = $he_subdevice_id;
403
$id->[$he_vendor_id] = [ @id0 ];
404
$id->[$he_device_id] = [ @id1 ];
405
$id->[$he_subvendor_id] = [ @id2 ];
406
$id->[$he_subdevice_id] = [ @id3 ];
407
$val->[$he_subdevice_name] = [ $flag_string, $name ];
409
$val->[$he_baseclass_id] = [ $flag_id, $tag_none, $class >> 8 ];
410
$val->[$he_subclass_id] = [ $flag_id, $tag_none, $class & 0xff ];
414
die "oops $file_name($line): subdevice id expected\n";
417
push @hd, [ "$file_name($line)", [ $id ], $val ];
420
( $file_name, $file ) = @_;
433
if(/^NAME=(.+?)�DEVICE=(.+?)�VID=0x([0-9a-fA-F]+?)�DID=0x([0-9a-fA-F]+?)�SERVER=([^�]+)(�EXT=([^�]*))?(�OPT=([^�]*))?(�RAW=([^�]*))?$/) {
434
# 1 2 3 4 5 6 7 8 9 10 11
436
$rnf_add_vendor->($tag_pci, hex($3), $1);
438
@id0 = ( $flag_id, $tag, hex($3) );
439
@id1 = ( $flag_id, $tag, hex($4) );
440
@id3 = ( $flag_string, $2 );
445
$id->[$he_vendor_id] = [ @id0 ];
446
$id->[$he_device_id] = [ @id1 ];
447
$val->[$he_device_name] = [ @id3 ];
449
push @hd, [ "$file_name($line)", [ $id ], $val ];
451
( $srv, $ext, $opt, $raw ) = ( $5, $7, $9, $11 );
452
$sax_tmp = $srv =~ /^3DLABS|MACH64|P9000|RUSH|S3|SVGA|TGA$/ ? 1 : 2;
453
$sax_version = $sax_tmp unless defined $sax_version;
454
die "line has SaX$sax_tmp format (expected SaX$sax_version): $file_name($line)\n" if $sax_tmp != $sax_version;
459
$id->[$he_vendor_id] = [ @id0 ];
460
$id->[$he_device_id] = [ @id1 ];
463
$str = join "|", ( $sax_version == 1 ? 3 : 4, $srv, undef, undef, $ext, $opt );
466
$str = join "|", ( $sax_version == 1 ? 3 : 4, $srv, undef, undef, $ext );
469
$str = join "|", ( $sax_version == 1 ? 3 : 4, $srv );
472
@id4 = ( "x\t$str" );
474
for $str (split /,/, $raw) { $id4[0] .= "\x00X\t$str" }
477
$val->[$he_driver] = [ $flag_string, @id4 ];
479
push @hd, [ "$file_name($line)", [ $id ], $val ];
482
elsif(/^B\s+([0-9a-fA-F]+)\s+(.*?)\s*$/) {
484
$rnf_add_bus->(hex($1), $2);
488
elsif(/^C\s+([0-9a-fA-F]+)\s+(.*?)\s*$/) {
490
$rnf_add_baseclass->(hex($1), $2);
494
elsif(/^([0-9a-fA-F]{4})(\s+(.*?))?\s*$/) {
496
$rnf_add_vendor->($tag_pci, hex($1), $3);
500
elsif(/^u([0-9a-fA-F]{4})(\s+(.*?))?\s*$/) {
502
$rnf_add_vendor->($tag_usb, hex($1), $3);
506
elsif(/^s([0-9a-fA-F]{4})(\s+(.*?))?\s*$/) {
508
$rnf_add_vendor->($tag_special, hex($1), $3);
512
elsif(/^([A-Z_@]{3})(\s+(.*?))?\s*$/) {
514
$rnf_add_vendor->($tag_eisa, eisa_id($1), $3);
518
elsif(/^\t([0-9a-fA-F]{1,4})(\+([0-9a-fA-F]+))?(\.([0-9a-fA-F]+))?(\s+(.*?))?\s*$/) {
520
$range = $3 ? hex($3) : undef;
521
$class = $5 ? hex($5) : undef;
523
@id1 = ( $flag_id, $tag, hex($1) );
524
$id1[3] = $range if defined $range;
525
undef @id2; undef @id3;
530
if($ent == $he_baseclass_id || $ent == $he_subclass_id) {
531
$ent = $he_subclass_id;
533
$id->[$he_baseclass_id] = [ @id0 ];
534
$id->[$he_subclass_id] = [ @id1 ];
535
$val->[$he_subclass_name] = [ $flag_string, $7 ];
537
elsif($ent == $he_vendor_id || $ent == $he_device_id || $ent == $he_subdevice_id) {
538
$ent = $he_device_id;
540
$id->[$he_vendor_id] = [ @id0 ];
541
$id->[$he_device_id] = [ @id1 ];
542
$val->[$he_device_name] = [ $flag_string, $7 ];
544
$val->[$he_baseclass_id] = [ $flag_id, $tag_none, $class >> 8 ];
545
$val->[$he_subclass_id] = [ $flag_id, $tag_none, $class & 0xff ];
549
die "oops $file_name($line): device id expected\n";
552
push @hd, [ "$file_name($line)", [ $id ], $val ];
556
elsif($ent == $he_subclass_id && /^\t\t([0-9a-fA-F]+)\s+(.*?)\s*$/) {
558
@id2 = ( $flag_id, $tag, hex($1) );
564
$id->[$he_baseclass_id] = [ @id0 ];
565
$id->[$he_subclass_id] = [ @id1 ];
566
$id->[$he_progif_id] = [ @id2 ];
567
$val->[$he_progif_name] = [ $flag_string, $2 ];
569
push @hd, [ "$file_name($line)", [ $id ], $val ];
573
elsif(/^\t\t([0-9a-fA-F]{4})\s+([0-9a-fA-F]{4})(\+([0-9a-fA-F]+))?(\.([0-9a-fA-F]+))?(\s+(.*?))?\s*$/) {
575
$rnf_add_subdevice->(hex($1), hex($2), $4 ? hex($4) : undef, $8, $6 ? hex($6) : undef);
579
elsif(/^\t\t([A-Z_@]{3})\s+([0-9a-fA-F]{4})(\+([0-9a-fA-F]+))?(\.([0-9a-fA-F]+))?(\s+(.*?))?\s*$/) {
581
$rnf_add_subdevice->(eisa_id($1), hex($2), $4 ? hex($4) : undef, $8, $6 ? hex($6) : undef);
585
elsif(/^\t\t([0-9a-fA-F]{4})([0-9a-fA-F]{4})\s+(.*?)\s*$/) {
587
# NOTE: subvendor & subdevice ids are reversed!
588
$rnf_add_subdevice->(hex($2), hex($1), undef, $3);
593
die "invalid line: $file_name($line)\n";
599
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
601
# read file with driver info
606
my ( $line, @drv, $file, $file_name, $drv_type, $tag );
609
my $rdf_save_drv = sub
612
push @hd, [ @drv ] if defined @drv;
613
@drv = ( "$file_name($line)" );
614
$drv[2][$he_driver] = [ $flag_string ];
621
my ( $tag, $id0, $id1, $range1, $id2, $id3, $range3, $id );
623
( $tag, $id0, $id1, $range1, $id2, $id3, $range3 ) = @_;
629
@id0 = ( $flag_id, $tag, $id0 );
630
@id1 = ( $flag_id, $tag, $id1 );
631
$id1[3] = $range1 if defined $range1;
633
$id->[$he_vendor_id] = [ @id0 ];
634
$id->[$he_device_id] = [ @id1 ];
637
@id2 = ( $flag_id, $tag, $id2 );
638
@id3 = ( $flag_id, $tag, $id3 );
639
$id3[3] = $range3 if defined $range3;
641
$id->[$he_subvendor_id] = [ @id2 ];
642
$id->[$he_subdevice_id] = [ @id3 ];
644
push @{$drv[1]}, $id;
647
( $file_name, $file ) = @_;
658
if(/^([us]?)([0-9a-fA-F]{4})\s+([0-9a-fA-F]{4})(\+([0-9a-fA-F]+))?\s*$/) {
661
$tag = $tag_usb if $1 eq 'u';
662
$tag = $tag_special if $1 eq 's';
664
$rdf_add_id->($tag, hex($2), hex($3), $5 ? hex($5) : undef);
668
elsif(/^([A-Z_@]{3})\s+([0-9a-fA-F]{4})(\+([0-9a-fA-F]+))?\s*$/) {
670
$rdf_add_id->($tag_eisa, eisa_id($1), hex($2), $4 ? hex($4) : undef);
674
elsif(/^([us]?)([0-9a-fA-F]{4})\s+([0-9a-fA-F]{4})(\+([0-9a-fA-F]+))?\s+([us]?)([0-9a-fA-F]{4})\s+([0-9a-fA-F]{4})(\+([0-9a-fA-F]+))?\s*$/) {
677
$tag = $tag_usb if $1 eq 'u';
678
$tag = $tag_special if $1 eq 's';
680
$rdf_add_id->($tag, hex($2), hex($3), $5 ? hex($5) : undef, hex($7), hex($8), $10 ? hex($10) : undef);
684
elsif(/^([A-Z_@]{3})\s+([0-9a-fA-F]{4})(\+([0-9a-fA-F]+))?\s+([A-Z_@]{3})\s+([0-9a-fA-F]{4})(\+([0-9a-fA-F]+))?\s*$/) {
686
$rdf_add_id->($tag_eisa, eisa_id($1), hex($2), $4 ? hex($4) : undef, eisa_id($5), hex($6), $8 ? hex($8) : undef);
690
elsif(/^\t([a-z])\s+(.*?)\s*$/) {
692
push @{$drv[2][$he_driver]}, "$1\t$2";
697
elsif($drv_type && /^\t\t\s*(.*)$/) {
699
$drv_type = "X" if $drv_type eq "x";
700
$drv_type = "M" if $drv_type eq "m";
701
$drv[2][$he_driver][-1] .= "\x00$drv_type\t$1";
706
die "invalid line: $file_name($line)\n";
716
return $_[0] =~ /^0/ ? oct $_[0] : return $_[0] + 0;
719
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
721
# read file with id info
726
my ( $line, $file, $file_name, $tag, $pre, $fields, @item, @id, $state, $keyid );
727
my ( $is_id, $i, $j );
730
my $rif_save_item = sub
735
@item = ( "$file_name($line)" );
741
my ($val, $id, $tag, $mask, $range, @id);
745
if($val =~ s/^(${\join '|', @tag_name})\s+//o) {
746
die "internal oops: $file_name($line)\n" unless exists $tag_values{$1};
747
$tag = $tag_values{$1};
753
if($val =~ /^\s*(\S+)\s*([&+])\s*(\S+)\s*$/) {
767
if($range =~ /^(0x[0-9a-zA-Z]+|\d+)$/) {
771
die "$file_name($line): invalid range\n"
776
if($mask =~ /^(0x[0-9a-zA-Z]+|\d+)$/) {
780
die "$file_name($line): invalid mask\n"
784
if($id =~ /^(0x[0-9a-zA-Z]+|\d+)$/) {
787
elsif(($tag == $tag_none || $tag == $tag_eisa) && $id =~ /^[A-Z_@]{3}$/) {
792
die "$file_name($line): invalid id\n"
795
@id = ( $flag_id, $tag, $id );
796
$id[3] = $range if defined $range;
797
$id[4] = $mask if defined $mask;
802
( $file_name, $file ) = @_;
804
$fields = join "|", map "\Q$_", @ent_names;
817
if(/^\s*([+&|]?)($fields)\s+(.+)/) {
818
($pre, $key, $val) = ($1, $2, $3);
819
# print ">$pre< $is_id>$key< >$val<\n";
820
die "internal oops: $file_name($line)\n" unless exists $ent_values{$key};
821
$keyid = $ent_values{$key};
822
$is_id = $keyid < $he_nomask && $key =~ /\.id$/ ? 1 : 0;
825
die "invalid line: $file_name($line)\n";
829
die "invalid line: $file_name($line)\n" unless $state == 0 || $state == 2;
838
die "invalid line: $file_name($line)\n" unless $state == 1;
839
push @{$item[1]}, [ @id ];
843
die "invalid line: $file_name($line)\n" unless $state == 1;
846
die "invalid line: $file_name($line)\n" unless $state == 1 || $state == 2;
848
push @{$item[1]}, [ @id ];
854
die "internal oops: $file_name($line)\n";
858
$id[$keyid] = $str2id->($val);
860
elsif($keyid == $he_hwclass) {
862
for $j (reverse split /\|/, $val) {
863
$i = ($i << 8) + $hwclass_values{$j} if $hwclass_values{$j};
866
$id[$keyid] = [ $flag_id, 0, $i ] if $i;
868
elsif($keyid < $he_nomask) {
869
$id[$keyid] = [ $flag_string, $val ];
871
elsif($keyid == $he_class_id) {
872
$i = ${$str2id->($val)}[2];
873
$id[$he_baseclass_id] = [ $flag_id, $tag_none, $i >> 8 ];
874
$id[$he_subclass_id] = [ $flag_id, $tag_none, $i & 0xff ];
878
if($keyid == $he_driver_module_insmod) {
881
elsif($keyid == $he_driver_module_modprobe) {
884
elsif($keyid == $he_driver_module_config) {
887
elsif($keyid == $he_driver_xfree) {
890
elsif($keyid == $he_driver_xfree_config) {
893
elsif($keyid == $he_driver_mouse) {
896
elsif($keyid == $he_driver_display) {
899
elsif($keyid == $he_driver_any) {
903
die "unhandled entry: $file_name($line)\n"
906
if(!defined $id[$he_driver]) {
907
$id[$he_driver] = [ $flag_string ];
909
if($i eq "X" || $i eq "M") {
910
$id[$he_driver]->[-1] .= "\x00$val"
913
push @{$id[$he_driver]}, $val;
927
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
934
my (@l, $id, $n, $key, $val, $mask);
937
( $file_name, $file ) = @_;
948
die "invalid line: $file_name($line)\n" unless @l == 8;
952
$val->[$he_driver] = [ $flag_string, "m\t$l[0]" ];
956
$key->[$he_vendor_id] = [ $flag_id, $tag_pci, $n ] if ($n = num $l[1]) != 0xffffffff;
957
$key->[$he_device_id] = [ $flag_id, $tag_pci, $n ] if ($n = num $l[2]) != 0xffffffff;
958
$key->[$he_subvendor_id] = [ $flag_id, $tag_pci, $n ] if ($n = num $l[3]) != 0xffffffff;
959
$key->[$he_subdevice_id] = [ $flag_id, $tag_pci, $n ] if ($n = num $l[4]) != 0xffffffff;
963
if($mask = ($n >> 16) & 0xff) {
964
$key->[$he_baseclass_id] = [ $flag_id, $tag_none, (num($l[5]) >> 16) & 0xff ];
966
$key->[$he_baseclass_id][4] = (~$mask & 0xff);
970
if($mask = ($n >> 8) & 0xff) {
971
$key->[$he_subclass_id] = [ $flag_id, $tag_none, (num($l[5]) >> 8) & 0xff ];
973
$key->[$he_subclass_id][4] = (~$mask & 0xff);
977
if($mask = $n & 0xff) {
978
$key->[$he_progif_id] = [ $flag_id, $tag_none, num($l[5]) & 0xff ];
980
$key->[$he_progif_id][4] = (~$mask & 0xff);
984
push @hd, [ "$file_name($line)", [ $key ], $val ];
989
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
996
my (@l, $id, $n, $key, $val, $mask);
999
( $file_name, $file ) = @_;
1010
die "invalid line: $file_name($line)\n" unless @l == 13;
1012
next if num($l[1]) != 3; # match_flags != 3
1018
$key->[$he_vendor_id] = [ $flag_id, $tag_usb, num($l[2]) ];
1019
$key->[$he_device_id] = [ $flag_id, $tag_usb, num($l[3]) ];
1021
$val->[$he_driver] = [ $flag_string, "m\t$l[0]" ];
1023
if($usbmod2class{$l[0]}) {
1024
$val->[$he_baseclass_id] = [ $flag_id, $tag_none, $usbmod2class{$l[0]}[0] ] if defined $usbmod2class{$l[0]}[0];
1025
$val->[$he_subclass_id] = [ $flag_id, $tag_none, $usbmod2class{$l[0]}[1] ] if defined $usbmod2class{$l[0]}[1];
1028
push @hd, [ "$file_name($line)", [ $key ], $val ];
1033
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1040
my ($f, $id, $n, $key, $val, $mask, $tag, $module, $spec, $t1, $t2);
1045
( $file_name, $file ) = @_;
1054
next unless /^\s*alias\s+(pci|pnp|usb):(\S+)\s+(\S+)/;
1056
$tag = $tag_pci if $1 eq 'pci';
1057
$tag = $tag_eisa if $1 eq 'pnp';
1058
$tag = $tag_usb if $1 eq 'usb';
1065
$val->[$he_driver] = [ $flag_string, "m\t$module" ];
1069
if($spec =~ /^v($f)d($f)sv($f)sd($f)bc($f)sc($f)i($f)$/ ) {
1070
$key->[$he_vendor_id] = [ $flag_id, $tag, hex $1 ] if $1 ne '*';
1071
$key->[$he_device_id] = [ $flag_id, $tag, hex $2 ] if $2 ne '*';
1072
$key->[$he_subvendor_id] = [ $flag_id, $tag, hex $3 ] if $3 ne '*';
1073
$key->[$he_subdevice_id] = [ $flag_id, $tag, hex $4 ] if $4 ne '*';
1074
$key->[$he_baseclass_id] = [ $flag_id, $tag_none, hex $5 ] if $5 ne '*';
1075
$key->[$he_subclass_id] = [ $flag_id, $tag_none, hex $6 ] if $6 ne '*';
1076
$key->[$he_progif_id] = [ $flag_id, $tag_none, hex $7 ] if $7 ne '*';
1078
push @hd, [ "$file_name($line)", [ $key ], $val ];
1080
elsif($spec =~ /^v($f)p($f)dl($f)dh($f)dc($f)dsc($f)dp($f)ic($f)isc($f)ip($f)$/ ) {
1083
$3 == '*' && $4 == '*' && $5 == '*' &&
1084
$6 == '*' && $7 == '*' && $8 == '*' &&
1085
$9 == '*' && $10 == '*'
1087
$key->[$he_vendor_id] = [ $flag_id, $tag, hex $1 ] if $1 ne '*';
1088
$key->[$he_device_id] = [ $flag_id, $tag, hex $2 ] if $2 ne '*';
1090
push @hd, [ "$file_name($line)", [ $key ], $val ];
1093
elsif($spec =~ /^[c|d](\S{3})([0-9a-fA-FX]{4})/ ) {
1097
if($t1 =~ /[\@A-Z\[\\\]\^_]{3}/ && $t2 ne 'XXXX') {
1098
$key->[$he_vendor_id] = [ $flag_id, $tag, eisa_id $t1 ];
1099
$key->[$he_device_id] = [ $flag_id, $tag, hex $t2 ];
1101
push @hd, [ "$file_name($line)", [ $key ], $val ];
1105
die "invalid line: $file_name($line)\n"
1111
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1116
sub read_modinfo_file
1118
my ($f, $id, $n, $key, $val, $mask, $tag, $module, $spec, $t1, $t2);
1123
( $file_name, $file ) = @_;
1132
if(m#([^/]+)\.ko:$#) {
1137
next unless /^\s*alias:\s+(pci|pnp|usb):(\S+)\s*$/;
1139
$tag = $tag_pci if $1 eq 'pci';
1140
$tag = $tag_eisa if $1 eq 'pnp';
1141
$tag = $tag_usb if $1 eq 'usb';
1147
$val->[$he_driver] = [ $flag_string, "m\t$module" ];
1151
if($spec =~ /^v($f)d($f)sv($f)sd($f)bc($f)sc($f)i($f)$/ ) {
1152
$key->[$he_vendor_id] = [ $flag_id, $tag, hex $1 ] if $1 ne '*';
1153
$key->[$he_device_id] = [ $flag_id, $tag, hex $2 ] if $2 ne '*';
1154
$key->[$he_subvendor_id] = [ $flag_id, $tag, hex $3 ] if $3 ne '*';
1155
$key->[$he_subdevice_id] = [ $flag_id, $tag, hex $4 ] if $4 ne '*';
1156
$key->[$he_baseclass_id] = [ $flag_id, $tag_none, hex $5 ] if $5 ne '*';
1157
$key->[$he_subclass_id] = [ $flag_id, $tag_none, hex $6 ] if $6 ne '*';
1158
$key->[$he_progif_id] = [ $flag_id, $tag_none, hex $7 ] if $7 ne '*';
1160
push @hd, [ "$file_name($line)", [ $key ], $val ];
1162
elsif($spec =~ /^v($f)p($f)dl($f)dh($f)dc($f)dsc($f)dp($f)ic($f)isc($f)ip($f)$/ ) {
1165
$3 == '*' && $4 == '*' && $5 == '*' &&
1166
$6 == '*' && $7 == '*' && $8 == '*' &&
1167
$9 == '*' && $10 == '*'
1169
$key->[$he_vendor_id] = [ $flag_id, $tag, hex $1 ] if $1 ne '*';
1170
$key->[$he_device_id] = [ $flag_id, $tag, hex $2 ] if $2 ne '*';
1172
push @hd, [ "$file_name($line)", [ $key ], $val ];
1175
elsif($spec =~ /^[c|d](\S{3})([0-9a-fA-FX]{4})/ ) {
1179
if($t1 =~ /[\@A-Z\[\\\]\^_]{3}/ && $t2 ne 'XXXX') {
1180
$key->[$he_vendor_id] = [ $flag_id, $tag, eisa_id $t1 ];
1181
$key->[$he_device_id] = [ $flag_id, $tag, hex $t2 ];
1183
push @hd, [ "$file_name($line)", [ $key ], $val ];
1187
die "invalid line: $file_name($line)\n"
1193
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1195
# convert 3-letter eisa id to number
1200
my ( $str, $id, $i, $j );
1205
die "internal oops" unless length($str) == 3;
1206
for($i = 0; $i < 3; $i++) {
1208
$j = ord substr $str, $i, 1;
1210
die "internal oops" unless $j >= 0 && $j <= 0x1f;
1218
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1220
# convert numerical eisa id to 3-letter string
1229
die "internal oops: eisa id \"$id\"" unless $id >= 0 && $id <= 0x7fff;
1231
$str = chr((($id >> 10) & 0x1f) + ord('A') - 1);
1232
$str .= chr((($id >> 5) & 0x1f) + ord('A') - 1);
1233
$str .= chr(( $id & 0x1f) + ord('A') - 1);
1239
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1241
# remove entries that have no effect
1246
my ($hd, $id, $f, $i, $cf);
1250
if(!defined($hd->[1]) || !@{$hd->[1]} || !defined($hd->[2]) || !@{$hd->[2]}) {
1254
for $id (@{$hd->[1]}, $hd->[2]) {
1260
if(@$f == 2 && $f->[0] == $flag_string && $f->[1] eq "") {
1269
if(!defined($hd->[1]) || !@{$hd->[1]} || !defined($hd->[2]) || !@{$hd->[2]}) {
1270
print STDERR "$hd->[0] has no info, dropped\n";
1276
@hd = grep { defined } @hd;
1280
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1282
# remove duplicate entries
1285
sub remove_duplicates
1287
my ($hd, $hd0, $hd1, $len, $i, $j, $m, $v, $buf, $errors, $drop);
1292
for($j = 0; $j < $len; $j++) {
1293
print STDERR ">> $j\r";
1295
for($i = $j + 1; $i < $len; $i++) {
1297
$m = match_item $$hd0, $$hd1;
1298
# print "$$hd0->[0] -- $$hd1->[0]: $m\n";
1300
$drop = cmp_item $$hd0, $$hd1;
1301
$drop = !$drop || abs($drop) == 2 ? ", dropped" : undef;
1303
# print STDERR "j: $$hd0->[0], $$hd1->[0]\n";
1304
$v = join_skey $$hd0->[2], $$hd1->[2], \$buf, \$errors;
1306
print STDERR "$$hd1->[0] conflicts with $$hd0->[0]$drop:\n$buf\n";
1307
$$hd1 = undef if $drop;
1311
print STDERR "$$hd1->[0] added to $$hd0->[0] and dropped\n";
1316
print STDERR "$$hd1->[0] shadowed by $$hd0->[0]\n";
1324
@hd = grep { defined } @hd;
1328
!defined($hd->[2]) ||
1329
!defined($hd->[2][$he_driver]) ||
1330
!(defined($hd->[2][$he_device_name]) || defined($hd->[2][$he_subdevice_name]))
1337
@hd = grep { defined } @hd;
1342
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1344
# remove duplicate entries
1347
sub remove_duplicatesx
1349
my ($hd0, $hd1, $len, $i, $j, $m, $v, $buf, $errors, $drop);
1354
for($j = 0; $j < $len; $j++) {
1355
print STDERR ">> $j\r";
1357
for($i = $j + 1; $i < $len; $i++) {
1359
$m = match_item $$hd0, $$hd1;
1360
# print "$$hd0->[0] -- $$hd1->[0]: $m\n";
1362
$drop = cmp_item $$hd0, $$hd1;
1363
$drop = !$drop || abs($drop) == 2 ? ", dropped" : undef;
1365
$v = join_skey $$hd0->[2], $$hd1->[2], \$buf, \$errors;
1367
print STDERR "$$hd1->[0] conflicts with $$hd0->[0]$drop:\n$buf\n";
1368
$$hd1 = undef if $drop;
1372
print STDERR "$$hd1->[0] added to $$hd0->[0] and dropped\n";
1377
print STDERR "$$hd1->[0] shadowed by $$hd0->[0]\n";
1384
@hd = grep { defined } @hd;
1388
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1395
my ($hd, $hid, $drv, $i, @i, @info, @req, %req);
1399
!defined($hd->[2]) ||
1400
!defined($hd->[2][$he_driver])
1404
$hid = $hd->[2][$he_driver];
1405
next unless $hid->[0] == $flag_string;
1409
for $drv (@$hid[1 .. @$hid - 1]) {
1410
@i = split /\x00/, $drv;
1412
next if $i =~ /^[MX]\t/;
1414
next unless $i =~ /^x\t/;
1415
@info = split /\|/, $i;
1416
# remove leasding 'XF86_' from server name
1417
$info[1] =~ s/^XF86_// if $info[1];
1418
# sort package, extension and option lists
1419
push @req, split /,/, $info[3] if $info[3];
1420
# $info[3] = join ',', sort split /,/, $info[3] if $info[3];
1421
$info[3] = undef if $info[3];
1422
$info[4] = join ',', sort split /,/, $info[4] if $info[4];
1423
$info[5] = join ',', sort split /,/, $info[5] if $info[5];
1424
$info[6] = join ',', sort { $a <=> $b } split /,/, $info[6] if $info[6];
1425
$i = join '|', @info;
1427
$drv = join "\x00", @i;
1432
$hid = $hd->[2][$he_requires];
1434
if($hid->[0] != $flag_string) {
1435
die "oops, invalid data"
1437
push @req, split /\|/, $hid->[1];
1438
$hid->[1] = join '|', @req;
1441
$hd->[2][$he_requires] = [ $flag_string, join('|', @req) ];
1448
!defined($hd->[2]) ||
1449
!defined($hd->[2][$he_requires])
1453
$hid = $hd->[2][$he_requires];
1454
next unless $hid->[0] == $flag_string;
1459
@req = split /\|/, $hid->[1];
1462
$hid->[1] = join '|', sort keys %req;
1467
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1469
# hd: [ "source", [ skey, skey, ... ], [ val ] ]
1470
# skey/val: [ ... , id, ..., id, ... ]
1471
# id: [ $flag_id, $tag, $value, $range, $mask ]
1472
# id: [ $flag_string, "str", "str", ... ]
1476
my ($id0, $id1, $len0, $len1, $len, $i, $k);
1480
return 0 if !defined($id0) && !defined($id1);
1481
return -1 if !defined($id0);
1482
return 1 if !defined($id1);
1484
if($id0->[0] != $id1->[0]) {
1485
return $id0->[0] <=> $id1->[0];
1490
$len = $len0 < $len1 ? $len0 : $len1;
1492
if($id0->[0] == $flag_string) {
1493
for($i = 1; $i < $len; $i++) {
1494
$k = $id0->[$i] cmp $id1->[$i];
1497
return $len0 <=> $len1;
1500
if($id0->[0] == $flag_id) {
1501
$k = $id0->[1] <=> $id1->[1];
1503
$k = $id0->[2] <=> $id1->[2];
1505
$k = $len0 <=> $len1;
1506
return $k if $k || $len <= 3;
1508
# $dump->dumpValue( $id0 );
1509
# $dump->dumpValue( $id1 );
1510
# die "internal oops: strange id" if $len < 4;
1512
return -1 if !defined($id0->[$i]);
1513
return 1 if !defined($id1->[$i]);
1514
return $id0->[$i] <=> $id1->[$i];
1517
die "internal oops: can't compare that!";
1521
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1525
my ($skey0, $skey1, $len0, $len1, $len, $i, $k);
1527
($skey0, $skey1) = @_;
1529
return 0 if !defined($skey0) && !defined($skey1);
1530
return -1 if !defined($skey0);
1531
return 1 if !defined($skey1);
1535
$len = $len0 < $len1 ? $len0 : $len1;
1537
# $dump->dumpValue( $skey0 );
1538
# $dump->dumpValue( $skey1 );
1540
for($i = 0; $i < $len; $i++) {
1541
next unless defined($skey0->[$i]) || defined($skey1->[$i]);
1543
# note: this looks reversed, but is intentional!
1544
return 1 if !defined($skey0->[$i]);
1545
return -1 if !defined($skey1->[$i]);
1547
$k = cmp_id $skey0->[$i], $skey1->[$i];
1552
return $len0 <=> $len1;
1556
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1559
# +-1: differing keys
1560
# +-2: differing values
1564
my ($item0, $item1, $len0, $len1, $len, $i, $k);
1566
($item0, $item1) = @_;
1570
return 0 if !defined($item0) && !defined($item1);
1571
return -1 if !defined($item0);
1572
return 1 if !defined($item1);
1574
$len0 = @{$item0->[1]};
1575
$len1 = @{$item1->[1]};
1576
$len = $len0 < $len1 ? $len0 : $len1;
1578
# $dump->dumpValue( $item0 );
1580
for($i = 0; $i < $len; $i++) {
1581
return -1 if !defined($item0->[1][$i]);
1582
return 1 if !defined($item1->[1][$i]);
1583
$k = cmp_skey $item0->[1][$i], $item1->[1][$i];
1584
# print " skey: $k\n";
1587
$k = $len0 <=> $len1;
1590
return 0 if !defined($item0->[2]) && !defined($item1->[2]);
1591
return -2 if !defined($item0->[2]);
1592
return 2 if !defined($item1->[2]);
1594
$k = cmp_skey $item0->[2], $item1->[2];
1595
# print " val: $k\n";
1600
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1602
# check if id1 is part of id0
1609
# hd: [ "source", [ skey, skey, ... ], [ val ] ]
1610
# skey/val: [ ... , id, ..., id, ... ]
1611
# id: [ $flag_id, $tag, $value, $range, $mask ]
1612
# id: [ $flag_string, "str", "str", ... ]
1616
my ($id0, $id1, $len0, $len1, $len, $i, $k);
1620
return 0 if !defined($id0) || !defined($id1);
1622
return 0 if $id0->[0] != $id1->[0];
1626
$len = $len0 < $len1 ? $len0 : $len1;
1628
if($id0->[0] == $flag_string) {
1629
for($i = 1; $i < $len; $i++) {
1630
return 0 if $id0->[$i] cmp $id1->[$i];
1632
return $len0 != $len1 ? 0 : 1;
1635
if($id0->[0] == $flag_id) {
1636
return 0 if $id0->[1] != $id1->[1];
1639
return $id0->[2] != $id1->[2] ? 0 : 1;
1642
return $id1->[2] >= $id0->[2] && $id1->[2] < $id0->[2] + $id0->[3] ? 1 : 0;
1645
return ($id1->[2] & ~$id0->[4]) == $id0->[2] ? 1 : 0;
1662
die "internal oops: can't match that!";
1666
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1668
# skey1 part of skey0?
1672
my ($skey0, $skey1, $len0, $len1, $len, $i, $k);
1674
($skey0, $skey1) = @_;
1676
return 0 if !defined($skey0) || !defined($skey1);
1681
$len = $len0 > $len1 ? $len0 : $len1;
1683
# $dump->dumpValue( $skey0 );
1684
# $dump->dumpValue( $skey1 );
1686
for($i = 0; $i < $len; $i++) {
1687
next unless defined($skey1->[$i]);
1689
return 0 if !defined($skey0->[$i]) && defined($skey1->[$i]);
1691
$k = match_id $skey0->[$i], $skey1->[$i];
1700
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1702
# item1 part of item0?
1706
my ($item0, $item1, $len0, $len1, $i, $j, $k, $m);
1708
($item0, $item1) = @_;
1712
return 0 if !defined($item0) || !defined($item1);
1714
$len0 = @{$item0->[1]};
1715
$len1 = @{$item1->[1]};
1717
for($j = 0; $j < $len1; $j++) {
1718
for($i = 0; $i < $len0; $i++) {
1719
$k = match_skey $item0->[1][$i], $item1->[1][$j];
1720
$m = $k if defined $k;
1729
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1731
# add skey1 to skey0
1735
my ($skey0, $skey1, $len, $i, $k, $n, $buf, $err);
1737
($skey0, $skey1, $buf, $errors) = @_;
1741
return undef if !defined($skey0) && !defined($skey1);
1742
return [ @$skey0 ] if !defined($skey1);
1743
return [ @$skey1 ] if !defined($skey0);
1749
for($i = 0; $i < $len; $i++) {
1750
next unless defined $skey1->[$i];
1752
$n->[$i] = $skey1->[$i];
1754
next unless defined $skey0->[$i];
1756
$k = cmp_id $skey0->[$i], $skey1->[$i];
1760
if($i != $he_driver) {
1761
$$buf .= ent_name_pr(" 0:", $ent_names[$i]);
1762
$$buf .= id_dump($i, $skey0->[$i]) . "\n";
1763
$$buf .= ent_name_pr(" 1:", $ent_names[$i]);
1764
$$buf .= id_dump($i, $skey1->[$i]) . "\n";
1767
$$buf .= drv_dump(" 0:", $skey0->[$i]);
1768
$$buf =~ s/\n&/\n 0:/;
1769
$$buf .= drv_dump(" 1:", $skey1->[$i]);
1770
$$buf =~ s/\n&/\n 1:/;
1773
$$errors++ if defined $errors;
1782
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1788
my ($item, @items, $tmp);
1793
return $item if !defined($item) || !defined($item->[1]);
1795
for (@{$item->[1]}) {
1805
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1813
if($xml->[0] ne 'hwdata') {
1814
die "invalid XML root element (expected 'hwdata')\n"
1817
for($i = 1; $i < @{$xml->[1]}; $i += 2) {
1818
if($xml->[1][$i] eq 'item') {
1819
push @hd, parse_xml_item($xml->[1][$i + 1]);
1827
my (@xml, %attr, $i, $item);
1830
%attr = %{shift @xml};
1832
for($i = 0; $i < @xml; $i += 2) {
1833
if($xml[$i] eq 'key') {
1834
push @{$item->[1]}, parse_xml_key($xml[$i + 1]);
1837
$item->[2] = parse_xml_key($_[0]);
1847
my (@xml, %attr, $i, @key, $val, $id, $is_id, $keyid, $keyid2, $tmp);
1850
%attr = %{shift @xml};
1852
for($i = 0; $i < @xml; $i += 2) {
1853
next if $xml[$i] eq '0' || $xml[$i] eq 'key';
1855
$keyid = $xml_values{$xml[$i]};
1856
$is_id = $keyid < $he_nomask && $ent_names[$keyid] =~ /\.(id|name)$/ ? 1 : 0;
1858
if(!defined($keyid)) {
1859
die "invalid key element \"$xml[$i]\"\n";
1862
if($keyid == $he_driver) {
1863
$id = parse_xml_driver($xml[$i + 1]);
1864
if(!defined($key[$keyid])) {
1868
push @{$key[$keyid]}, $id->[1];
1872
$id = parse_xml_id($xml[$i + 1]);
1873
if($id->[0] == $flag_id) {
1874
$tmp = $ent_names[$keyid];
1875
$tmp =~ s/\.name$/.id/;
1876
$keyid2 = $ent_values{$tmp};
1877
if(!defined($keyid2)) {
1878
die "oops, no .id for $xml[$i]?";
1882
$tmp = $ent_names[$keyid];
1883
$tmp =~ s/\.id$/.name/;
1884
$keyid2 = $ent_values{$tmp};
1885
if(!defined($keyid2)) {
1886
die "oops, no .name for $xml[$i]?";
1889
$key[$keyid2] = $id;
1892
$val = parse_xml_cdata($xml[$i + 1]);
1893
if(defined($key[$keyid]) && $keyid == $he_requires) {
1894
$key[$keyid][1] .= "|$val";
1897
$key[$keyid] = [ $flag_string, $val ];
1908
my (@xml, %attr, $i, $id, $val);
1911
%attr = %{shift @xml};
1913
for($i = 0; $i < @xml; $i += 2) {
1914
next if $xml[$i] eq '0';
1916
if($xml[$i] eq 'id') {
1917
$id = parse_xml_id_id($xml[$i + 1]);
1919
elsif($xml[$i] eq 'idrange') {
1920
$id = parse_xml_id_range($xml[$i + 1]);
1922
elsif($xml[$i] eq 'idmask') {
1923
$id = parse_xml_id_mask($xml[$i + 1]);
1925
elsif($xml[$i] eq 'name') {
1926
$val = parse_xml_cdata($xml[$i + 1]);
1927
$id = [ $flag_string, $val ];
1930
die "invalid id element \"$xml[$i]\"\n";
1940
my (@xml, %attr, $i, $tag, $value);
1943
%attr = %{shift @xml};
1945
$tag = $tag_values{$attr{type}};
1947
if(!defined($tag)) {
1948
die "missing/unsupported id attribute \"$attr{type}\"\n";
1951
for($i = 0; $i < @xml; $i += 2) {
1952
if($xml[$i] eq '0') {
1953
$value = idstr2value $tag, $xml[$i + 1];
1956
die "cdata expected, got \"$xml[$i]\"\n";
1960
return [ $flag_id, $tag, $value ];
1964
sub parse_xml_id_range
1966
my (@xml, %attr, $i, $tag, $value, $range);
1969
%attr = %{shift @xml};
1971
$tag = $tag_values{$attr{type}};
1973
if(!defined($tag)) {
1974
die "missing/unsupported id attribute \"$attr{type}\"\n";
1977
for($i = 0; $i < @xml; $i += 2) {
1978
next if $xml[$i] eq '0';
1979
if($xml[$i] eq 'first') {
1980
$value = idstr2value $tag, parse_xml_cdata($xml[$i + 1]);
1982
elsif($xml[$i] eq 'last') {
1983
$range = idstr2value $tag, parse_xml_cdata($xml[$i + 1]);
1986
die "invalid idrange element \"$xml[$i]\"\n";
1990
if(!defined($value) || !defined($range)) {
1991
die "invalid idrange\n";
1994
return [ $flag_id, $tag, $value, $range - $value + 1 ];
1998
sub parse_xml_id_mask
2000
my (@xml, %attr, $i, $tag, $value, $mask);
2003
%attr = %{shift @xml};
2005
$tag = $tag_values{$attr{type}};
2007
if(!defined($tag)) {
2008
die "missing/unsupported id attribute \"$attr{type}\"\n";
2011
for($i = 0; $i < @xml; $i += 2) {
2012
next if $xml[$i] eq '0';
2013
if($xml[$i] eq 'value') {
2014
$value = idstr2value $tag, parse_xml_cdata($xml[$i + 1]);
2016
elsif($xml[$i] eq 'mask') {
2017
$mask = idstr2value $tag, parse_xml_cdata($xml[$i + 1]);
2020
die "invalid idmask element \"$xml[$i]\"\n";
2024
if(!defined($value) || !defined($mask)) {
2025
die "invalid idmask\n";
2028
return [ $flag_id, $tag, $value, undef, $mask ];
2032
sub parse_xml_driver
2034
my (@xml, %attr, $i, $val);
2037
%attr = %{shift @xml};
2039
for($i = 0; $i < @xml; $i += 2) {
2040
next if $xml[$i] eq '0';
2042
if($xml[$i] eq 'any') {
2043
$val = "a\t" . parse_xml_cdata($xml[$i + 1]);
2045
elsif($xml[$i] eq 'display') {
2046
$val = parse_xml_driver_display($xml[$i + 1]);
2048
elsif($xml[$i] eq 'module') {
2049
$val = parse_xml_driver_module($xml[$i + 1]);
2051
elsif($xml[$i] eq 'mouse') {
2052
$val = parse_xml_driver_mouse($xml[$i + 1]);
2054
elsif($xml[$i] eq 'xfree') {
2055
$val = parse_xml_driver_xfree($xml[$i + 1]);
2058
die "invalid driver element \"$xml[$i]\"\n";
2062
return [ $flag_string, $val ];
2066
sub parse_xml_driver_display
2068
my (@xml, %attr, $i, @val);
2071
%attr = %{shift @xml};
2073
for($i = 0; $i < @xml; $i += 2) {
2074
next if $xml[$i] eq '0';
2076
if($xml[$i] eq 'resolution') {
2077
$val[0] = join('x', parse_xml_pair($xml[$i + 1], 'width', 'height'));
2079
elsif($xml[$i] eq 'vsync') {
2080
$val[1] = join('-', parse_xml_pair($xml[$i + 1], 'min', 'max'));
2082
elsif($xml[$i] eq 'hsync') {
2083
$val[2] = join('-', parse_xml_pair($xml[$i + 1], 'min', 'max'));
2085
elsif($xml[$i] eq 'bandwidth') {
2086
$val[3] = parse_xml_cdata($xml[$i + 1]);
2089
die "invalid display element \"$xml[$i]\"\n";
2094
die "invalid display info\n";
2097
return "d\t" . join('|', @val);
2101
sub parse_xml_driver_module
2103
my (@xml, %attr, $i, $val, $type, @conf, @mods);
2106
%attr = %{shift @xml};
2108
for($i = 0; $i < @xml; $i += 2) {
2109
next if $xml[$i] eq '0';
2111
$val = parse_xml_cdata($xml[$i + 1]);
2113
if($xml[$i] eq 'modprobe') {
2114
if($type && $type ne 'm') {
2115
die "invalid module info: \"$xml[$i]\"\n";
2120
elsif($xml[$i] eq 'insmod') {
2121
if($type && $type ne 'i') {
2122
die "invalid module info: \"$xml[$i]\"\n";
2127
elsif($xml[$i] eq 'modconf') {
2128
if($type && $type ne 'm') {
2129
die "invalid module info: \"$xml[$i]\"\n";
2131
push @conf, "\x00M\t$val";
2134
die "invalid module element \"$xml[$i]\"\n";
2138
if(!$type && !@mods) {
2139
die "invalid module info\n";
2142
$val = "$type\t" . join('|', @mods);
2145
$val .= join('', @conf);
2152
sub parse_xml_driver_mouse
2154
my (@xml, %attr, $i, $val, @val);
2157
%attr = %{shift @xml};
2159
for($i = 0; $i < @xml; $i += 2) {
2160
next if $xml[$i] eq '0';
2162
$val = parse_xml_cdata($xml[$i + 1]);
2164
if($xml[$i] eq 'xf86') {
2167
elsif($xml[$i] eq 'gpm') {
2170
elsif($xml[$i] eq 'buttons') {
2173
elsif($xml[$i] eq 'wheels') {
2177
die "invalid mouse element \"$xml[$i]\"\n";
2182
die "invalid mouse info\n";
2185
return "p\t" . join('|', @val);
2189
sub parse_xml_driver_xfree
2191
my (@xml, %attr, $i, $val, @val, @conf);
2194
%attr = %{shift @xml};
2196
for($i = 0; $i < @xml; $i += 2) {
2197
next if $xml[$i] eq '0';
2199
if($xml[$i] eq 'has3d') {
2203
$val = parse_xml_cdata($xml[$i + 1]);
2205
if($xml[$i] eq 'version') {
2208
elsif($xml[$i] eq 'server') {
2211
elsif($xml[$i] eq 'extension') {
2212
$val[4] .= "," if defined $val[4];
2215
elsif($xml[$i] eq 'option') {
2216
$val[5] .= "," if defined $val[5];
2219
elsif($xml[$i] eq 'bpp') {
2220
$val[6] .= "," if defined $val[6];
2223
elsif($xml[$i] eq 'dacspeed') {
2226
elsif($xml[$i] eq 'script') {
2229
elsif($xml[$i] eq 'xf86conf') {
2230
push @conf, "\x00X\t$val";
2233
die "invalid xfree element \"$xml[$i]\"\n";
2239
die "invalid xfree info\n";
2242
$val = "x\t" . join('|', @val);
2245
$val .= join('', @conf);
2254
my (@xml, %attr, $i, $val0, $val1, $elem0, $elem1);
2260
%attr = %{shift @xml};
2262
for($i = 0; $i < @xml; $i += 2) {
2263
next if $xml[$i] eq '0';
2264
if($xml[$i] eq $elem0) {
2265
$val0 = parse_xml_cdata($xml[$i + 1]);
2267
elsif($xml[$i] eq $elem1) {
2268
$val1 = parse_xml_cdata($xml[$i + 1]);
2271
die "invalid element \"$xml[$i]\"\n";
2275
if(!defined($val0) || !defined($val1)) {
2276
die "invalid element\n";
2279
return ($val0, $val1);
2285
my (@xml, %attr, $i);
2288
%attr = %{shift @xml};
2290
for($i = 0; $i < @xml; $i += 2) {
2291
if($xml[$i] eq '0') {
2302
($tag, $value) = @_;
2304
if($tag == $tag_eisa && length($value) == 3 && $value !~ /^[0-9]/) {
2305
$value = eisa_id $value;
2308
$value = num $value;
2314
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2320
$str = $_[0] . $_[1];
2325
$len = ($len & ~7) + 8;
2326
$str .= "\t" x ((24 - $len)/8) if $len < 24;
2334
my ($id, $ent, $str, $tag, $format, $u, $s);
2338
if($id->[0] == $flag_id) {
2340
if($ent == $he_hwclass) {
2342
for($u = $id->[2] & 0xffffff; $u; $u >>= 8) {
2343
if(defined $hwclass_names[$u & 0xff]) {
2344
$str .= $hwclass_names[$u & 0xff];
2345
$str .= "|" if $u > 0x100;
2349
elsif($tag == $tag_eisa && ($ent == $he_vendor_id || $ent == $he_subvendor_id)) {
2350
$str = eisa_str $id->[2];
2353
$str .= $tag_name[$tag];
2354
$str .= " " if $tag;
2356
$format = "0x%02x" if $ent == $he_bus_id || $ent == $he_subclass_id || $ent == $he_progif_id;
2357
$format = "0x%03x" if $ent == $he_baseclass_id;
2358
$str .= sprintf $format, $id->[2];
2360
if(defined $id->[3]) {
2361
$str .= sprintf "+0x%04x", $id->[3];
2363
elsif(defined $id->[4]) {
2364
$str .= sprintf "&0x%04x", $id->[4];
2367
elsif($id->[0] == $flag_string) {
2368
if(defined($id->[2])) {
2369
die "oops: strage string data\n";
2374
die "oops: unknown id flag\n"
2383
my ($id, $str, $i, $pre, $type, $drv, $buf);
2387
die "oops: invalid driver data\n" if $id->[0] != $flag_string;
2389
for($i = 1; $i < @{$id}; $i++) {
2390
for $drv (split /\x00/, $id->[$i]) {
2391
$type = substr $drv, 0, 2;
2393
if($type eq "x\t") {
2394
$buf .= ent_name_pr($pre, $ent_names[$he_driver_xfree]);
2395
$buf .= substr($drv, 2) . "\n";
2397
elsif($type eq "X\t") {
2398
$buf .= ent_name_pr($pre, $ent_names[$he_driver_xfree_config]);
2399
$buf .= substr($drv, 2) . "\n";
2401
elsif($type eq "i\t") {
2402
$buf .= ent_name_pr($pre, $ent_names[$he_driver_module_insmod]);
2403
$buf .= substr($drv, 2) . "\n";
2405
elsif($type eq "m\t") {
2406
$buf .= ent_name_pr($pre, $ent_names[$he_driver_module_modprobe]);
2407
$buf .= substr($drv, 2) . "\n";
2409
elsif($type eq "M\t") {
2410
$buf .= ent_name_pr($pre, $ent_names[$he_driver_module_config]);
2411
$buf .= substr($drv, 2) . "\n";
2413
elsif($type eq "p\t") {
2414
$buf .= ent_name_pr($pre, $ent_names[$he_driver_mouse]);
2415
$buf .= substr($drv, 2) . "\n";
2417
elsif($type eq "d\t") {
2418
$buf .= ent_name_pr($pre, $ent_names[$he_driver_display]);
2419
$buf .= substr($drv, 2) . "\n";
2421
elsif($type eq "a\t") {
2422
$buf .= ent_name_pr($pre, $ent_names[$he_driver_any]);
2423
$buf .= substr($drv, 2) . "\n";
2426
die "oops: unhandled driver info type: $drv\n";
2429
$pre = "&" if $pre ne "+";
2439
my ($pre, $id, $ent, $buf);
2441
($buf, $pre, $id) = @_;
2443
$pre = defined($pre) ? "|" : " " if $pre ne "+";
2444
for($ent = 0; $ent < @{$id}; $ent++) {
2445
if(defined $id->[$ent]) {
2446
if($ent != $he_driver) {
2447
$$buf .= ent_name_pr($pre, $ent_names[$ent]);
2448
$$buf .= id_dump($ent, $id->[$ent]);
2452
$$buf .= drv_dump($pre, $id->[$ent]);
2454
$pre = "&" if $pre ne "+";
2464
my ($item, $id, $ent, $pre, $buf);
2466
# $dump->dumpValue( \@hd );
2473
print F "# $item->[0]\n" if $opt_with_source;
2474
for $id (@{$item->[1]}) {
2475
$pre = ent_dump \$buf, $pre, $id;
2478
ent_dump \$buf, $pre, $item->[2];
2488
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2494
if($opt_internal_dtd) {
2495
$dtd = hd_dtd_internal;
2498
$dtd = "<!DOCTYPE hwdata SYSTEM \"hd.dtd\">\n";
2501
$xml_file = new IO::File(">hd.xml");
2502
$xml = new XML::Writer(OUTPUT => $xml_file, DATA_MODE => 1, DATA_INDENT => 2);
2504
$xml->xmlDecl("utf-8");
2506
print $xml_file "\n$dtd";
2508
$xml->startTag("hwdata");
2510
print $xml_file "\n";
2513
dump_xml_item $item;
2516
$xml->endTag("hwdata");
2519
if(!$opt_internal_dtd) {
2520
print STDERR "writing \"hd.dtd\"\n";
2521
open DTD, ">hd.dtd";
2530
my ($ent, $id, $i, $tag, $str, $format, $range, $mask);
2534
$i = $xml_names[$ent];
2536
die "oops: entry $ent not allowed here\n" unless $i;
2538
if($ent == $he_requires) {
2539
if($id->[0] == $flag_string) {
2540
die "oops: strange string data\n" if defined $id->[2];
2541
for $str (split /\|/, $id->[1]) {
2542
$xml->dataElement("requires", $str);
2546
die "oops: requires _id_???\n"
2552
if($ent == $he_serial) {
2553
if($id->[0] == $flag_string) {
2554
die "oops: strange string data\n" if defined $id->[2];
2555
$xml->characters($id->[1]);
2558
die "oops: serial _id_???\n"
2562
if($id->[0] == $flag_id) {
2564
if($tag == $tag_eisa && ($ent == $he_vendor_id || $ent == $he_subvendor_id)) {
2565
$str = eisa_str $id->[2];
2569
$format = "0x%02x" if $ent == $he_bus_id || $ent == $he_subclass_id || $ent == $he_progif_id;
2570
$format = "0x%03x" if $ent == $he_baseclass_id;
2571
$str = sprintf $format, $id->[2];
2573
if(defined $id->[3]) {
2574
if($tag == $tag_eisa && ($ent == $he_vendor_id || $ent == $he_subvendor_id)) {
2575
$range = eisa_str $id->[2] + $id->[3] - 1;
2578
$range = sprintf "0x%04x", $id->[2] + $id->[3] - 1;
2581
elsif(defined $id->[4]) {
2582
$mask = sprintf "0x%04x", $id->[4];
2584
$tag = $tag_name[$tag];
2586
if(defined $range) {
2588
$xml->startTag("idrange", "type" => $tag);
2591
$xml->startTag("idrange");
2593
$xml->dataElement("first", $str);
2594
$xml->dataElement("last", $range);
2597
elsif(defined $mask) {
2599
$xml->startTag("idmask", "type" => $tag);
2602
$xml->startTag("idmask");
2604
$xml->dataElement("value", $str);
2605
$xml->dataElement("mask", $mask);
2610
$xml->dataElement("id", $str, "type" => $tag);
2613
$xml->dataElement("id", $str);
2617
elsif($id->[0] == $flag_string) {
2618
die "oops: strage string data\n" if defined $id->[2];
2619
$xml->dataElement("name", $id->[1]);
2622
die "oops: unknown id flag\n"
2633
my ($id, $str, $i, $j, $k, $type, $drv, $info, @info, $current);
2637
die "oops: invalid driver data\n" if $id->[0] != $flag_string;
2639
for($i = 1; $i < @{$id}; $i++) {
2641
$xml->startTag('driver');
2645
for $drv (split /\x00/, $id->[$i]) {
2646
$type = substr $drv, 0, 2;
2647
$info = substr $drv, 2;
2648
@info = split /\|/, $info;
2650
if($type eq "i\t") {
2651
$xml->endTag() if $current; $current = $type;
2652
$xml->startTag('module');
2654
$xml->dataElement('insmod', $j);
2657
elsif($type eq "m\t") {
2658
$xml->endTag() if $current; $current = $type;
2659
$xml->startTag('module');
2661
$xml->dataElement('modprobe', $j);
2664
elsif($type eq "M\t") {
2665
die "oops: incorrect driver info: $drv\n" unless $current eq "m\t";
2666
$xml->dataElement('modconf', $info);
2668
elsif($type eq "a\t") {
2669
$xml->endTag() if $current; $current = undef;;
2670
$xml->dataElement('any', $info);
2672
elsif($type eq "d\t") {
2673
$xml->endTag() if $current; $current = undef;
2674
$xml->startTag('display');
2675
if($info[0] =~ /^(\d+)x(\d+)$/) {
2676
($j, $k) = ($1, $2);
2677
$xml->startTag('resolution');
2678
$xml->dataElement('width', $j);
2679
$xml->dataElement('height', $k);
2680
$xml->endTag('resolution');
2682
if($info[1] =~ /^(\d+)-(\d+)$/) {
2683
($j, $k) = ($1, $2);
2684
$xml->startTag('vsync');
2685
$xml->dataElement('min', $j);
2686
$xml->dataElement('max', $k);
2687
$xml->endTag('vsync');
2689
if($info[2] =~ /^(\d+)-(\d+)$/) {
2690
($j, $k) = ($1, $2);
2691
$xml->startTag('hsync');
2692
$xml->dataElement('min', $j);
2693
$xml->dataElement('max', $k);
2694
$xml->endTag('hsync');
2696
if($info[3] =~ /^\d+$/) {
2697
$xml->dataElement('bandwidth', $info[3]);
2699
$xml->endTag('display');
2701
elsif($type eq "x\t") {
2702
$xml->endTag() if $current; $current = $type;
2703
$xml->startTag('xfree');
2704
if(defined $info[0]) {
2705
$xml->dataElement('version', $info[0]);
2708
$xml->dataElement('server', $info[1]);
2711
$xml->emptyTag('has3d');
2714
# for $j (split /,/, $info[3]) {
2715
# $xml->dataElement('package', $j);
2719
for $j (split /,/, $info[4]) {
2720
$xml->dataElement('extension', $j);
2724
for $j (split /,/, $info[5]) {
2725
$xml->dataElement('option', $j);
2729
for $j (split /,/, $info[6]) {
2730
$xml->dataElement('bpp', $j);
2733
if($info[7] =~ /^\d+$/) {
2734
$xml->dataElement('dacspeed', $info[7]);
2737
$xml->dataElement('script', $info[8]);
2740
elsif($type eq "X\t") {
2741
die "oops: incorrect driver info: $drv\n" unless $current eq "x\t";
2742
$xml->dataElement('xf86conf', $info);
2744
elsif($type eq "p\t") {
2745
$xml->endTag() if $current; $current = undef;
2746
$xml->startTag('mouse');
2748
$xml->dataElement('xf86', $info[0]);
2751
$xml->dataElement('gpm', $info[1]);
2753
if($info[2] ne "") {
2754
$xml->dataElement('buttons', $info[2]);
2756
if($info[3] ne "") {
2757
$xml->dataElement('wheels', $info[3]);
2759
$xml->endTag('mouse');
2762
$xml->endTag() if $current; $current = undef;
2763
# die "oops: unhandled driver info type: $drv\n";
2767
$xml->endTag() if $current;
2769
$xml->endTag('driver');
2781
for($ent = 0; $ent < @{$id}; $ent++) {
2782
if(defined $id->[$ent]) {
2783
if($ent != $he_driver) {
2784
dump_xml_id $ent, $id->[$ent];
2787
dump_xml_drv $id->[$ent];
2801
$xml->startTag('item');
2803
for $id (@{$item->[1]}) {
2804
$xml->startTag('key');
2806
$xml->endTag('key');
2809
dump_xml_ent $item->[2];
2811
$xml->endTag('item');
2812
print $xml_file "\n";
2819
<!-- libhd DTD V0.2 -->
2821
<!ENTITY % keyfields "bus|baseclass|subclass|progif|vendor|device|subvendor|subdevice|revision|serial|driver|requires">
2822
<!ENTITY % idelements "id|idrange|idmask|name">
2823
<!ENTITY % idtypes "none|pci|eisa|usb|pcmcia|special">
2825
<!ELEMENT hwdata (item*)>
2827
<!ELEMENT item (key+,(%keyfields;)*)>
2829
<!ELEMENT key (%keyfields;)+>
2831
<!ELEMENT bus (%idelements;)>
2832
<!ELEMENT baseclass (%idelements;)>
2833
<!ELEMENT subclass (%idelements;)>
2834
<!ELEMENT progif (%idelements;)>
2835
<!ELEMENT vendor (%idelements;)>
2836
<!ELEMENT device (%idelements;)>
2837
<!ELEMENT subvendor (%idelements;)>
2838
<!ELEMENT subdevice (%idelements;)>
2839
<!ELEMENT revision (%idelements;)>
2840
<!ELEMENT serial (#PCDATA)>
2841
<!ELEMENT requires (#PCDATA)>
2842
<!ELEMENT id (#PCDATA)>
2843
<!ELEMENT idrange (first,last)>
2844
<!ELEMENT first (#PCDATA)>
2845
<!ELEMENT last (#PCDATA)>
2846
<!ELEMENT idmask (value,mask)>
2847
<!ELEMENT value (#PCDATA)>
2848
<!ELEMENT mask (#PCDATA)>
2849
<!ATTLIST id type (%idtypes;) "none">
2850
<!ATTLIST idrange type (%idtypes;) "none">
2851
<!ATTLIST idmask type (%idtypes;) "none">
2852
<!ELEMENT name (#PCDATA)>
2854
<!ELEMENT driver (any|display|module|mouse|xfree)?>
2856
<!ELEMENT any (#PCDATA)>
2858
<!ELEMENT display (resolution?,vsync?,hsync?,bandwidth?)>
2859
<!ELEMENT resolution (width,height)>
2860
<!ELEMENT width (#PCDATA)>
2861
<!ELEMENT height (#PCDATA)>
2862
<!ELEMENT vsync (min,max)>
2863
<!ELEMENT hsync (min,max)>
2864
<!ELEMENT min (#PCDATA)>
2865
<!ELEMENT max (#PCDATA)>
2866
<!ELEMENT bandwidth (#PCDATA)>
2868
<!ELEMENT module (insmod+|(modprobe+,modconf*))>
2869
<!ELEMENT insmod (#PCDATA)>
2870
<!ELEMENT modprobe (#PCDATA)>
2871
<!ELEMENT modconf (#PCDATA)>
2873
<!ELEMENT mouse (xf86?,gpm?,buttons?,wheels?)>
2874
<!ELEMENT xf86 (#PCDATA)>
2875
<!ELEMENT gpm (#PCDATA)>
2876
<!ELEMENT buttons (#PCDATA)>
2877
<!ELEMENT wheels (#PCDATA)>
2879
<!ELEMENT xfree (version,server?,has3d?,extension*,option*,bpp*,dacspeed?,script?,xf86conf*)>
2880
<!ELEMENT version (#PCDATA)>
2881
<!ELEMENT server (#PCDATA)>
2882
<!ELEMENT has3d EMPTY>
2883
<!ELEMENT extension (#PCDATA)>
2884
<!ELEMENT option (#PCDATA)>
2885
<!ELEMENT bpp (#PCDATA)>
2886
<!ELEMENT dacspeed (#PCDATA)>
2887
<!ELEMENT script (#PCDATA)>
2888
<!ELEMENT xf86conf (#PCDATA)>
2900
<!ELEMENT hwdata (item*)>
2901
<!ELEMENT item (key+,(bus|baseclass|subclass|progif|vendor|device|subvendor|subdevice|revision|serial|driver|requires)*)>
2902
<!ELEMENT key (bus|baseclass|subclass|progif|vendor|device|subvendor|subdevice|revision|serial|driver|requires)+>
2903
<!ELEMENT bus (id|idrange|idmask|name)>
2904
<!ELEMENT baseclass (id|idrange|idmask|name)>
2905
<!ELEMENT subclass (id|idrange|idmask|name)>
2906
<!ELEMENT progif (id|idrange|idmask|name)>
2907
<!ELEMENT vendor (id|idrange|idmask|name)>
2908
<!ELEMENT device (id|idrange|idmask|name)>
2909
<!ELEMENT subvendor (id|idrange|idmask|name)>
2910
<!ELEMENT subdevice (id|idrange|idmask|name)>
2911
<!ELEMENT revision (id|idrange|idmask|name)>
2912
<!ELEMENT serial (#PCDATA)>
2913
<!ELEMENT requires (#PCDATA)>
2914
<!ELEMENT id (#PCDATA)>
2915
<!ELEMENT idrange (first,last)>
2916
<!ELEMENT first (#PCDATA)>
2917
<!ELEMENT last (#PCDATA)>
2918
<!ELEMENT idmask (value,mask)>
2919
<!ELEMENT value (#PCDATA)>
2920
<!ELEMENT mask (#PCDATA)>
2921
<!ATTLIST id type (none|pci|eisa|usb|pcmcia|special) "none">
2922
<!ATTLIST idrange type (none|pci|eisa|usb|special) "none">
2923
<!ATTLIST idmask type (none|pci|eisa|usb|special) "none">
2924
<!ELEMENT name (#PCDATA)>
2925
<!ELEMENT driver (any|display|module|mouse|xfree)?>
2926
<!ELEMENT any (#PCDATA)>
2927
<!ELEMENT display (resolution?,vsync?,hsync?,bandwidth?)>
2928
<!ELEMENT resolution (width,height)>
2929
<!ELEMENT width (#PCDATA)>
2930
<!ELEMENT height (#PCDATA)>
2931
<!ELEMENT vsync (min,max)>
2932
<!ELEMENT hsync (min,max)>
2933
<!ELEMENT min (#PCDATA)>
2934
<!ELEMENT max (#PCDATA)>
2935
<!ELEMENT bandwidth (#PCDATA)>
2936
<!ELEMENT module (insmod+|(modprobe+,modconf*))>
2937
<!ELEMENT insmod (#PCDATA)>
2938
<!ELEMENT modprobe (#PCDATA)>
2939
<!ELEMENT modconf (#PCDATA)>
2940
<!ELEMENT mouse (xf86?,gpm?,buttons?,wheels?)>
2941
<!ELEMENT xf86 (#PCDATA)>
2942
<!ELEMENT gpm (#PCDATA)>
2943
<!ELEMENT buttons (#PCDATA)>
2944
<!ELEMENT wheels (#PCDATA)>
2945
<!ELEMENT xfree (version,server?,has3d?,extension*,option*,bpp*,dacspeed?,script?,xf86conf*)>
2946
<!ELEMENT version (#PCDATA)>
2947
<!ELEMENT server (#PCDATA)>
2948
<!ELEMENT has3d EMPTY>
2949
<!ELEMENT extension (#PCDATA)>
2950
<!ELEMENT option (#PCDATA)>
2951
<!ELEMENT bpp (#PCDATA)>
2952
<!ELEMENT dacspeed (#PCDATA)>
2953
<!ELEMENT script (#PCDATA)>
2954
<!ELEMENT xf86conf (#PCDATA)>