]>
git.ipfire.org Git - ipfire-2.x.git/blob - src/hwinfo/src/ids/convert_hd
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,
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",
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 ]
122 $opt_sort_reverse = 0;
123 $opt_sort_random = 0; # for testing
125 $opt_with_source = 0;
128 $opt_internal_dtd = 0;
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,
156 if(/^\s*\<\?xml\s/) {
161 if(/^#\s+pci\s+module\s+vendor\s+device\s+subvendor\s+subdevice\s+class\s+class_mask\s+driver_data\s*$/) {
166 if(/^#\s+usb\s+module\s+match_flags\s+idVendor\s+idProduct\s+/) {
171 if(/^\s*alias\s+(pci|pnp|usb):\S+\s+\S+$/) {
176 if(/^\s*alias:\s+(pci|pnp|usb):\S+\s*$/) {
184 $i = join "|", map "\Q$_", @ent_names;
186 if(/^\s*[+&|]?($i)\s/) {
202 $format = 'names' if !$format;
204 if($format eq 'names') {
206 print STDERR
"====== \"$f\": name info ======\n";
207 read_name_file
$f, \
@f;
210 elsif($format eq 'drivers') {
212 print STDERR
"====== \"$f\": driver info ======\n";
213 read_driver_file
$f, \
@f;
216 elsif($format eq 'xml') {
218 print STDERR
"====== \"$f\": xml info ======\n";
219 $xmlp = new XML
::Parser
(Style
=> 'Tree', ParseParamEnt
=> 1);
220 get_xml_data
$xmlp->parsefile($f);
223 elsif($format eq 'ids') {
225 print STDERR
"====== \"$f\": id info ======\n";
226 read_id_file
$f, \
@f;
229 elsif($format eq 'pcimap') {
231 print STDERR
"====== \"$f\": pcimap info ======\n";
232 read_pcimap_file
$f, \
@f;
235 elsif($format eq 'usbmap') {
237 print STDERR
"====== \"$f\": usbmap info ======\n";
238 read_usbmap_file
$f, \
@f;
241 elsif($format eq 'alias') {
243 print STDERR
"====== \"$f\": alias info ======\n";
244 read_alias_file
$f, \
@f;
247 elsif($format eq 'modinfo') {
249 print STDERR
"====== \"$f\": module info ======\n";
250 read_modinfo_file
$f, \
@f;
259 print STDERR
"removing unnecessary items\n";
262 print STDERR
"got ${\scalar @hd} items\n";
264 if($opt_fix_driver) {
269 print STDERR
"splitting items\n";
271 push @hd_new, split_item
($_);
278 print STDERR
"sorting\n";
279 if($opt_sort_random) {
280 @hd = sort { $cmp_item_cnt++, rand() <=> rand() } @hd;
282 elsif($opt_sort_reverse) {
283 @hd = sort { cmp_item
$b, $a } @hd;
286 @hd = sort { cmp_item
$a, $b } @hd;
291 print STDERR
"writing \"hd.ids\"\n";
296 print STDERR
"writing \"hd.xml\"\n";
300 print STDERR
"cmps: $cmp_item_cnt\n" if $cmp_item_cnt;
302 # $dump->dumpValue( \@hd );
305 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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";
324 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
327 return $_[0] =~ /^0/ ?
oct $_[0] : return $_[0] + 0;
331 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
333 # read file with name/class info
335 # (either pciutils or SaX/SaX2 format)
340 my ( $file_name, $file, $line, $sax_version, $tag, $id, $val, $ent );
341 my ( @id0, @id1, @id2, @id3, @id4, $raw, $opt, $ext, $srv, $str );
344 my $rnf_add_id0 = sub
346 my ( $id0, $name0, $ent_id0, $ent_name0, $id, $val );
348 # note: $tag belongs to read_name_file()
349 ( $ent_id0, $ent_name0, $tag, $id0, $name0 ) = @_;
353 @id0 = ( $flag_id, $tag, $id0 );
354 undef @id1; undef @id2; undef @id3;
356 $id->[$ent_id0] = [ @id0 ];
357 $val->[$ent_name0] = [ $flag_string, $name0 ];
359 push @hd, [ "$file_name($line)", [ $id ], $val ];
362 my $rnf_add_bus = sub
364 $rnf_add_id0->($he_bus_id, $he_bus_name, 0, @_);
367 my $rnf_add_baseclass = sub
369 $rnf_add_id0->($he_baseclass_id, $he_baseclass_name, 0, @_);
372 my $rnf_add_vendor = sub
374 $rnf_add_id0->($he_vendor_id, $he_vendor_name, @_);
377 my $rnf_add_subdevice = sub
379 my ( $id2, $id3, $range, $name, $class, $id, $val );
381 ( $id2, $id3, $range, $name, $class ) = @_;
383 @id2 = ( $flag_id, $tag, $id2 );
384 @id3 = ( $flag_id, $tag, $id3 );
385 $id3[3] = $range if defined $range;
387 if($ent == $he_device_id || $ent == $he_subdevice_id) {
388 $ent = $he_subdevice_id;
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 ];
396 $val->[$he_baseclass_id] = [ $flag_id, $tag_none, $class >> 8 ];
397 $val->[$he_subclass_id] = [ $flag_id, $tag_none, $class & 0xff ];
401 die "oops $file_name($line): subdevice id expected\n";
404 push @hd, [ "$file_name($line)", [ $id ], $val ];
407 ( $file_name, $file ) = @_;
420 if(/^NAME=(.+?)§DEVICE=(.+?)§VID=0x([0-9a-fA-F]+?)§DID=0x([0-9a-fA-F]+?)§SERVER=([^§]+)(§EXT=([^§]*))?(§OPT=([^§]*))?(§RAW=([^§]*))?$/) {
421 # 1 2 3 4 5 6 7 8 9 10 11
423 $rnf_add_vendor->($tag_pci, hex($3), $1);
425 @id0 = ( $flag_id, $tag, hex($3) );
426 @id1 = ( $flag_id, $tag, hex($4) );
427 @id3 = ( $flag_string, $2 );
432 $id->[$he_vendor_id] = [ @id0 ];
433 $id->[$he_device_id] = [ @id1 ];
434 $val->[$he_device_name] = [ @id3 ];
436 push @hd, [ "$file_name($line)", [ $id ], $val ];
438 ( $srv, $ext, $opt, $raw ) = ( $5, $7, $9, $11 );
439 $sax_tmp = $srv =~ /^3DLABS|MACH64|P9000|RUSH|S3|SVGA|TGA$/ ?
1 : 2;
440 $sax_version = $sax_tmp unless defined $sax_version;
441 die "line has SaX$sax_tmp format (expected SaX$sax_version): $file_name($line)\n" if $sax_tmp != $sax_version;
446 $id->[$he_vendor_id] = [ @id0 ];
447 $id->[$he_device_id] = [ @id1 ];
450 $str = join "|", ( $sax_version == 1 ?
3 : 4, $srv, undef, undef, $ext, $opt );
453 $str = join "|", ( $sax_version == 1 ?
3 : 4, $srv, undef, undef, $ext );
456 $str = join "|", ( $sax_version == 1 ?
3 : 4, $srv );
459 @id4 = ( "x\t$str" );
461 for $str (split /,/, $raw) { $id4[0] .= "\x00X\t$str" }
464 $val->[$he_driver] = [ $flag_string, @id4 ];
466 push @hd, [ "$file_name($line)", [ $id ], $val ];
469 elsif(/^B\s+([0-9a-fA-F]+)\s+(.*?)\s*$/) {
471 $rnf_add_bus->(hex($1), $2);
475 elsif(/^C\s+([0-9a-fA-F]+)\s+(.*?)\s*$/) {
477 $rnf_add_baseclass->(hex($1), $2);
481 elsif(/^([0-9a-fA-F]{4})(\s+(.*?))?\s*$/) {
483 $rnf_add_vendor->($tag_pci, hex($1), $3);
487 elsif(/^u([0-9a-fA-F]{4})(\s+(.*?))?\s*$/) {
489 $rnf_add_vendor->($tag_usb, hex($1), $3);
493 elsif(/^s([0-9a-fA-F]{4})(\s+(.*?))?\s*$/) {
495 $rnf_add_vendor->($tag_special, hex($1), $3);
499 elsif(/^([A-Z_@]{3})(\s+(.*?))?\s*$/) {
501 $rnf_add_vendor->($tag_eisa, eisa_id
($1), $3);
505 elsif(/^\t([0-9a-fA-F]{1,4})(\+([0-9a-fA-F]+))?(\.([0-9a-fA-F]+))?(\s+(.*?))?\s*$/) {
507 $range = $3 ?
hex($3) : undef;
508 $class = $5 ?
hex($5) : undef;
510 @id1 = ( $flag_id, $tag, hex($1) );
511 $id1[3] = $range if defined $range;
512 undef @id2; undef @id3;
517 if($ent == $he_baseclass_id || $ent == $he_subclass_id) {
518 $ent = $he_subclass_id;
520 $id->[$he_baseclass_id] = [ @id0 ];
521 $id->[$he_subclass_id] = [ @id1 ];
522 $val->[$he_subclass_name] = [ $flag_string, $7 ];
524 elsif($ent == $he_vendor_id || $ent == $he_device_id || $ent == $he_subdevice_id) {
525 $ent = $he_device_id;
527 $id->[$he_vendor_id] = [ @id0 ];
528 $id->[$he_device_id] = [ @id1 ];
529 $val->[$he_device_name] = [ $flag_string, $7 ];
531 $val->[$he_baseclass_id] = [ $flag_id, $tag_none, $class >> 8 ];
532 $val->[$he_subclass_id] = [ $flag_id, $tag_none, $class & 0xff ];
536 die "oops $file_name($line): device id expected\n";
539 push @hd, [ "$file_name($line)", [ $id ], $val ];
543 elsif($ent == $he_subclass_id && /^\t\t([0-9a-fA-F]+)\s+(.*?)\s*$/) {
545 @id2 = ( $flag_id, $tag, hex($1) );
551 $id->[$he_baseclass_id] = [ @id0 ];
552 $id->[$he_subclass_id] = [ @id1 ];
553 $id->[$he_progif_id] = [ @id2 ];
554 $val->[$he_progif_name] = [ $flag_string, $2 ];
556 push @hd, [ "$file_name($line)", [ $id ], $val ];
560 elsif(/^\t\t([0-9a-fA-F]{4})\s+([0-9a-fA-F]{4})(\+([0-9a-fA-F]+))?(\.([0-9a-fA-F]+))?(\s+(.*?))?\s*$/) {
562 $rnf_add_subdevice->(hex($1), hex($2), $4 ?
hex($4) : undef, $8, $6 ?
hex($6) : undef);
566 elsif(/^\t\t([A-Z_@]{3})\s+([0-9a-fA-F]{4})(\+([0-9a-fA-F]+))?(\.([0-9a-fA-F]+))?(\s+(.*?))?\s*$/) {
568 $rnf_add_subdevice->(eisa_id
($1), hex($2), $4 ?
hex($4) : undef, $8, $6 ?
hex($6) : undef);
572 elsif(/^\t\t([0-9a-fA-F]{4})([0-9a-fA-F]{4})\s+(.*?)\s*$/) {
574 # NOTE: subvendor & subdevice ids are reversed!
575 $rnf_add_subdevice->(hex($2), hex($1), undef, $3);
580 die "invalid line: $file_name($line)\n";
586 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
588 # read file with driver info
593 my ( $line, @drv, $file, $file_name, $drv_type, $tag );
596 my $rdf_save_drv = sub
599 push @hd, [ @drv ] if defined @drv;
600 @drv = ( "$file_name($line)" );
601 $drv[2][$he_driver] = [ $flag_string ];
608 my ( $tag, $id0, $id1, $range1, $id2, $id3, $range3, $id );
610 ( $tag, $id0, $id1, $range1, $id2, $id3, $range3 ) = @_;
616 @id0 = ( $flag_id, $tag, $id0 );
617 @id1 = ( $flag_id, $tag, $id1 );
618 $id1[3] = $range1 if defined $range1;
620 $id->[$he_vendor_id] = [ @id0 ];
621 $id->[$he_device_id] = [ @id1 ];
624 @id2 = ( $flag_id, $tag, $id2 );
625 @id3 = ( $flag_id, $tag, $id3 );
626 $id3[3] = $range3 if defined $range3;
628 $id->[$he_subvendor_id] = [ @id2 ];
629 $id->[$he_subdevice_id] = [ @id3 ];
631 push @
{$drv[1]}, $id;
634 ( $file_name, $file ) = @_;
645 if(/^([us]?)([0-9a-fA-F]{4})\s+([0-9a-fA-F]{4})(\+([0-9a-fA-F]+))?\s*$/) {
648 $tag = $tag_usb if $1 eq 'u';
649 $tag = $tag_special if $1 eq 's';
651 $rdf_add_id->($tag, hex($2), hex($3), $5 ?
hex($5) : undef);
655 elsif(/^([A-Z_@]{3})\s+([0-9a-fA-F]{4})(\+([0-9a-fA-F]+))?\s*$/) {
657 $rdf_add_id->($tag_eisa, eisa_id
($1), hex($2), $4 ?
hex($4) : undef);
661 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*$/) {
664 $tag = $tag_usb if $1 eq 'u';
665 $tag = $tag_special if $1 eq 's';
667 $rdf_add_id->($tag, hex($2), hex($3), $5 ?
hex($5) : undef, hex($7), hex($8), $10 ?
hex($10) : undef);
671 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*$/) {
673 $rdf_add_id->($tag_eisa, eisa_id
($1), hex($2), $4 ?
hex($4) : undef, eisa_id
($5), hex($6), $8 ?
hex($8) : undef);
677 elsif(/^\t([a-z])\s+(.*?)\s*$/) {
679 push @
{$drv[2][$he_driver]}, "$1\t$2";
684 elsif($drv_type && /^\t\t\s*(.*)$/) {
686 $drv_type = "X" if $drv_type eq "x";
687 $drv_type = "M" if $drv_type eq "m";
688 $drv[2][$he_driver][-1] .= "\x00$drv_type\t$1";
693 die "invalid line: $file_name($line)\n";
703 return $_[0] =~ /^0/ ?
oct $_[0] : return $_[0] + 0;
706 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
708 # read file with id info
713 my ( $line, $file, $file_name, $tag, $pre, $fields, @item, @id, $state, $keyid );
717 my $rif_save_item = sub
722 @item = ( "$file_name($line)" );
728 my ($val, $id, $tag, $mask, $range, @id);
732 if($val =~ s/^(${\join '|', @tag_name})\s+//o) {
733 die "internal oops: $file_name($line)\n" unless exists $tag_values{$1};
734 $tag = $tag_values{$1};
740 if($val =~ /^\s*(\S+)\s*([&+])\s*(\S+)\s*$/) {
754 if($range =~ /^(0x[0-9a-zA-Z]+|\d+)$/) {
758 die "$file_name($line): invalid range\n"
763 if($mask =~ /^(0x[0-9a-zA-Z]+|\d+)$/) {
767 die "$file_name($line): invalid mask\n"
771 if($id =~ /^(0x[0-9a-zA-Z]+|\d+)$/) {
774 elsif(($tag == $tag_none || $tag == $tag_eisa) && $id =~ /^[A-Z_@]{3}$/) {
779 die "$file_name($line): invalid id\n"
782 @id = ( $flag_id, $tag, $id );
783 $id[3] = $range if defined $range;
784 $id[4] = $mask if defined $mask;
789 ( $file_name, $file ) = @_;
791 $fields = join "|", map "\Q$_", @ent_names;
804 if(/^\s*([+&|]?)($fields)\s+(.+)/) {
805 ($pre, $key, $val) = ($1, $2, $3);
806 # print ">$pre< $is_id>$key< >$val<\n";
807 die "internal oops: $file_name($line)\n" unless exists $ent_values{$key};
808 $keyid = $ent_values{$key};
809 $is_id = $keyid < $he_nomask && $key =~ /\.id$/ ?
1 : 0;
812 die "invalid line: $file_name($line)\n";
816 die "invalid line: $file_name($line)\n" unless $state == 0 || $state == 2;
825 die "invalid line: $file_name($line)\n" unless $state == 1;
826 push @
{$item[1]}, [ @id ];
830 die "invalid line: $file_name($line)\n" unless $state == 1;
833 die "invalid line: $file_name($line)\n" unless $state == 1 || $state == 2;
835 push @
{$item[1]}, [ @id ];
841 die "internal oops: $file_name($line)\n";
845 $id[$keyid] = $str2id->($val);
847 elsif($keyid < $he_nomask) {
848 $id[$keyid] = [ $flag_string, $val ];
850 elsif($keyid == $he_class_id) {
851 $i = ${$str2id->($val)}[2];
852 $id[$he_baseclass_id] = [ $flag_id, $tag_none, $i >> 8 ];
853 $id[$he_subclass_id] = [ $flag_id, $tag_none, $i & 0xff ];
857 if($keyid == $he_driver_module_insmod) {
860 elsif($keyid == $he_driver_module_modprobe) {
863 elsif($keyid == $he_driver_module_config) {
866 elsif($keyid == $he_driver_xfree) {
869 elsif($keyid == $he_driver_xfree_config) {
872 elsif($keyid == $he_driver_mouse) {
875 elsif($keyid == $he_driver_display) {
878 elsif($keyid == $he_driver_any) {
882 die "unhandled entry: $file_name($line)\n"
885 if(!defined $id[$he_driver]) {
886 $id[$he_driver] = [ $flag_string ];
888 if($i eq "X" || $i eq "M") {
889 $id[$he_driver]->[-1] .= "\x00$val"
892 push @
{$id[$he_driver]}, $val;
906 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
913 my (@l, $id, $n, $key, $val, $mask);
916 ( $file_name, $file ) = @_;
927 die "invalid line: $file_name($line)\n" unless @l == 8;
931 $val->[$he_driver] = [ $flag_string, "m\t$l[0]" ];
935 $key->[$he_vendor_id] = [ $flag_id, $tag_pci, $n ] if ($n = num
$l[1]) != 0xffffffff;
936 $key->[$he_device_id] = [ $flag_id, $tag_pci, $n ] if ($n = num
$l[2]) != 0xffffffff;
937 $key->[$he_subvendor_id] = [ $flag_id, $tag_pci, $n ] if ($n = num
$l[3]) != 0xffffffff;
938 $key->[$he_subdevice_id] = [ $flag_id, $tag_pci, $n ] if ($n = num
$l[4]) != 0xffffffff;
942 if($mask = ($n >> 16) & 0xff) {
943 $key->[$he_baseclass_id] = [ $flag_id, $tag_none, (num
($l[5]) >> 16) & 0xff ];
945 $key->[$he_baseclass_id][4] = (~$mask & 0xff);
949 if($mask = ($n >> 8) & 0xff) {
950 $key->[$he_subclass_id] = [ $flag_id, $tag_none, (num
($l[5]) >> 8) & 0xff ];
952 $key->[$he_subclass_id][4] = (~$mask & 0xff);
956 if($mask = $n & 0xff) {
957 $key->[$he_progif_id] = [ $flag_id, $tag_none, num
($l[5]) & 0xff ];
959 $key->[$he_progif_id][4] = (~$mask & 0xff);
963 push @hd, [ "$file_name($line)", [ $key ], $val ];
968 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
975 my (@l, $id, $n, $key, $val, $mask);
978 ( $file_name, $file ) = @_;
989 die "invalid line: $file_name($line)\n" unless @l == 13;
991 next if num
($l[1]) != 3; # match_flags != 3
997 $key->[$he_vendor_id] = [ $flag_id, $tag_usb, num
($l[2]) ];
998 $key->[$he_device_id] = [ $flag_id, $tag_usb, num
($l[3]) ];
1000 $val->[$he_driver] = [ $flag_string, "m\t$l[0]" ];
1002 if($usbmod2class{$l[0]}) {
1003 $val->[$he_baseclass_id] = [ $flag_id, $tag_none, $usbmod2class{$l[0]}[0] ] if defined $usbmod2class{$l[0]}[0];
1004 $val->[$he_subclass_id] = [ $flag_id, $tag_none, $usbmod2class{$l[0]}[1] ] if defined $usbmod2class{$l[0]}[1];
1007 push @hd, [ "$file_name($line)", [ $key ], $val ];
1012 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1019 my ($f, $id, $n, $key, $val, $mask, $tag, $module, $spec, $t1, $t2);
1024 ( $file_name, $file ) = @_;
1033 next unless /^\s*alias\s+(pci|pnp|usb):(\S+)\s+(\S+)/;
1035 $tag = $tag_pci if $1 eq 'pci';
1036 $tag = $tag_eisa if $1 eq 'pnp';
1037 $tag = $tag_usb if $1 eq 'usb';
1044 $val->[$he_driver] = [ $flag_string, "m\t$module" ];
1048 if($spec =~ /^v($f)d($f)sv($f)sd($f)bc($f)sc($f)i($f)$/ ) {
1049 $key->[$he_vendor_id] = [ $flag_id, $tag, hex $1 ] if $1 ne '*';
1050 $key->[$he_device_id] = [ $flag_id, $tag, hex $2 ] if $2 ne '*';
1051 $key->[$he_subvendor_id] = [ $flag_id, $tag, hex $3 ] if $3 ne '*';
1052 $key->[$he_subdevice_id] = [ $flag_id, $tag, hex $4 ] if $4 ne '*';
1053 $key->[$he_baseclass_id] = [ $flag_id, $tag_none, hex $5 ] if $5 ne '*';
1054 $key->[$he_subclass_id] = [ $flag_id, $tag_none, hex $6 ] if $6 ne '*';
1055 $key->[$he_progif_id] = [ $flag_id, $tag_none, hex $7 ] if $7 ne '*';
1057 push @hd, [ "$file_name($line)", [ $key ], $val ];
1059 elsif($spec =~ /^v($f)p($f)dl($f)dh($f)dc($f)dsc($f)dp($f)ic($f)isc($f)ip($f)$/ ) {
1062 $3 == '*' && $4 == '*' && $5 == '*' &&
1063 $6 == '*' && $7 == '*' && $8 == '*' &&
1064 $9 == '*' && $10 == '*'
1066 $key->[$he_vendor_id] = [ $flag_id, $tag, hex $1 ] if $1 ne '*';
1067 $key->[$he_device_id] = [ $flag_id, $tag, hex $2 ] if $2 ne '*';
1069 push @hd, [ "$file_name($line)", [ $key ], $val ];
1072 elsif($spec =~ /^[c|d](\S{3})([0-9a-fA-FX]{4})/ ) {
1076 if($t1 =~ /[\@A-Z\[\\\]\^_]{3}/ && $t2 ne 'XXXX') {
1077 $key->[$he_vendor_id] = [ $flag_id, $tag, eisa_id
$t1 ];
1078 $key->[$he_device_id] = [ $flag_id, $tag, hex $t2 ];
1080 push @hd, [ "$file_name($line)", [ $key ], $val ];
1084 die "invalid line: $file_name($line)\n"
1090 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1095 sub read_modinfo_file
1097 my ($f, $id, $n, $key, $val, $mask, $tag, $module, $spec, $t1, $t2);
1102 ( $file_name, $file ) = @_;
1111 if(m
#([^/]+)\.ko:$#) {
1116 next unless /^\s*alias:\s+(pci|pnp|usb):(\S+)\s*$/;
1118 $tag = $tag_pci if $1 eq 'pci';
1119 $tag = $tag_eisa if $1 eq 'pnp';
1120 $tag = $tag_usb if $1 eq 'usb';
1126 $val->[$he_driver] = [ $flag_string, "m\t$module" ];
1130 if($spec =~ /^v($f)d($f)sv($f)sd($f)bc($f)sc($f)i($f)$/ ) {
1131 $key->[$he_vendor_id] = [ $flag_id, $tag, hex $1 ] if $1 ne '*';
1132 $key->[$he_device_id] = [ $flag_id, $tag, hex $2 ] if $2 ne '*';
1133 $key->[$he_subvendor_id] = [ $flag_id, $tag, hex $3 ] if $3 ne '*';
1134 $key->[$he_subdevice_id] = [ $flag_id, $tag, hex $4 ] if $4 ne '*';
1135 $key->[$he_baseclass_id] = [ $flag_id, $tag_none, hex $5 ] if $5 ne '*';
1136 $key->[$he_subclass_id] = [ $flag_id, $tag_none, hex $6 ] if $6 ne '*';
1137 $key->[$he_progif_id] = [ $flag_id, $tag_none, hex $7 ] if $7 ne '*';
1139 push @hd, [ "$file_name($line)", [ $key ], $val ];
1141 elsif($spec =~ /^v($f)p($f)dl($f)dh($f)dc($f)dsc($f)dp($f)ic($f)isc($f)ip($f)$/ ) {
1144 $3 == '*' && $4 == '*' && $5 == '*' &&
1145 $6 == '*' && $7 == '*' && $8 == '*' &&
1146 $9 == '*' && $10 == '*'
1148 $key->[$he_vendor_id] = [ $flag_id, $tag, hex $1 ] if $1 ne '*';
1149 $key->[$he_device_id] = [ $flag_id, $tag, hex $2 ] if $2 ne '*';
1151 push @hd, [ "$file_name($line)", [ $key ], $val ];
1154 elsif($spec =~ /^[c|d](\S{3})([0-9a-fA-FX]{4})/ ) {
1158 if($t1 =~ /[\@A-Z\[\\\]\^_]{3}/ && $t2 ne 'XXXX') {
1159 $key->[$he_vendor_id] = [ $flag_id, $tag, eisa_id
$t1 ];
1160 $key->[$he_device_id] = [ $flag_id, $tag, hex $t2 ];
1162 push @hd, [ "$file_name($line)", [ $key ], $val ];
1166 die "invalid line: $file_name($line)\n"
1172 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1174 # convert 3-letter eisa id to number
1179 my ( $str, $id, $i, $j );
1184 die "internal oops" unless length($str) == 3;
1185 for($i = 0; $i < 3; $i++) {
1187 $j = ord substr $str, $i, 1;
1189 die "internal oops" unless $j >= 0 && $j <= 0x1f;
1197 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1199 # convert numerical eisa id to 3-letter string
1208 die "internal oops: eisa id \"$id\"" unless $id >= 0 && $id <= 0x7fff;
1210 $str = chr((($id >> 10) & 0x1f) + ord('A') - 1);
1211 $str .= chr((($id >> 5) & 0x1f) + ord('A') - 1);
1212 $str .= chr(( $id & 0x1f) + ord('A') - 1);
1218 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1220 # remove entries that have no effect
1225 my ($hd, $id, $f, $i, $cf);
1229 if(!defined($hd->[1]) || !@
{$hd->[1]} || !defined($hd->[2]) || !@
{$hd->[2]}) {
1233 for $id (@
{$hd->[1]}, $hd->[2]) {
1239 if(@
$f == 2 && $f->[0] == $flag_string && $f->[1] eq "") {
1248 if(!defined($hd->[1]) || !@
{$hd->[1]} || !defined($hd->[2]) || !@
{$hd->[2]}) {
1249 print STDERR
"$hd->[0] has no info, dropped\n";
1255 @hd = grep { defined } @hd;
1259 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1261 # remove duplicate entries
1264 sub remove_duplicates
1266 my ($hd, $hd0, $hd1, $len, $i, $j, $m, $v, $buf, $errors, $drop);
1271 for($j = 0; $j < $len; $j++) {
1272 print STDERR
">> $j\r";
1274 for($i = $j + 1; $i < $len; $i++) {
1276 $m = match_item
$$hd0, $$hd1;
1277 # print "$$hd0->[0] -- $$hd1->[0]: $m\n";
1279 $drop = cmp_item
$$hd0, $$hd1;
1280 $drop = !$drop || abs($drop) == 2 ?
", dropped" : undef;
1282 # print STDERR "j: $$hd0->[0], $$hd1->[0]\n";
1283 $v = join_skey
$$hd0->[2], $$hd1->[2], \
$buf, \
$errors;
1285 print STDERR
"$$hd1->[0] conflicts with $$hd0->[0]$drop:\n$buf\n";
1286 $$hd1 = undef if $drop;
1290 print STDERR
"$$hd1->[0] added to $$hd0->[0] and dropped\n";
1295 print STDERR
"$$hd1->[0] shadowed by $$hd0->[0]\n";
1303 @hd = grep { defined } @hd;
1307 !defined($hd->[2]) ||
1308 !defined($hd->[2][$he_driver]) ||
1309 !(defined($hd->[2][$he_device_name]) || defined($hd->[2][$he_subdevice_name]))
1316 @hd = grep { defined } @hd;
1321 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1323 # remove duplicate entries
1326 sub remove_duplicatesx
1328 my ($hd0, $hd1, $len, $i, $j, $m, $v, $buf, $errors, $drop);
1333 for($j = 0; $j < $len; $j++) {
1334 print STDERR
">> $j\r";
1336 for($i = $j + 1; $i < $len; $i++) {
1338 $m = match_item
$$hd0, $$hd1;
1339 # print "$$hd0->[0] -- $$hd1->[0]: $m\n";
1341 $drop = cmp_item
$$hd0, $$hd1;
1342 $drop = !$drop || abs($drop) == 2 ?
", dropped" : undef;
1344 $v = join_skey
$$hd0->[2], $$hd1->[2], \
$buf, \
$errors;
1346 print STDERR
"$$hd1->[0] conflicts with $$hd0->[0]$drop:\n$buf\n";
1347 $$hd1 = undef if $drop;
1351 print STDERR
"$$hd1->[0] added to $$hd0->[0] and dropped\n";
1356 print STDERR
"$$hd1->[0] shadowed by $$hd0->[0]\n";
1363 @hd = grep { defined } @hd;
1367 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1374 my ($hd, $hid, $drv, $i, @i, @info, @req, %req);
1378 !defined($hd->[2]) ||
1379 !defined($hd->[2][$he_driver])
1383 $hid = $hd->[2][$he_driver];
1384 next unless $hid->[0] == $flag_string;
1388 for $drv (@
$hid[1 .. @
$hid - 1]) {
1389 @i = split /\x00/, $drv;
1391 next if $i =~ /^[MX]\t/;
1393 next unless $i =~ /^x\t/;
1394 @info = split /\|/, $i;
1395 # remove leasding 'XF86_' from server name
1396 $info[1] =~ s/^XF86_// if $info[1];
1397 # sort package, extension and option lists
1398 push @req, split /,/, $info[3] if $info[3];
1399 # $info[3] = join ',', sort split /,/, $info[3] if $info[3];
1400 $info[3] = undef if $info[3];
1401 $info[4] = join ',', sort split /,/, $info[4] if $info[4];
1402 $info[5] = join ',', sort split /,/, $info[5] if $info[5];
1403 $info[6] = join ',', sort { $a <=> $b } split /,/, $info[6] if $info[6];
1404 $i = join '|', @info;
1406 $drv = join "\x00", @i;
1411 $hid = $hd->[2][$he_requires];
1413 if($hid->[0] != $flag_string) {
1414 die "oops, invalid data"
1416 push @req, split /\|/, $hid->[1];
1417 $hid->[1] = join '|', @req;
1420 $hd->[2][$he_requires] = [ $flag_string, join('|', @req) ];
1427 !defined($hd->[2]) ||
1428 !defined($hd->[2][$he_requires])
1432 $hid = $hd->[2][$he_requires];
1433 next unless $hid->[0] == $flag_string;
1438 @req = split /\|/, $hid->[1];
1441 $hid->[1] = join '|', sort keys %req;
1446 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1448 # hd: [ "source", [ skey, skey, ... ], [ val ] ]
1449 # skey/val: [ ... , id, ..., id, ... ]
1450 # id: [ $flag_id, $tag, $value, $range, $mask ]
1451 # id: [ $flag_string, "str", "str", ... ]
1455 my ($id0, $id1, $len0, $len1, $len, $i, $k);
1459 return 0 if !defined($id0) && !defined($id1);
1460 return -1 if !defined($id0);
1461 return 1 if !defined($id1);
1463 if($id0->[0] != $id1->[0]) {
1464 return $id0->[0] <=> $id1->[0];
1469 $len = $len0 < $len1 ?
$len0 : $len1;
1471 if($id0->[0] == $flag_string) {
1472 for($i = 1; $i < $len; $i++) {
1473 $k = $id0->[$i] cmp $id1->[$i];
1476 return $len0 <=> $len1;
1479 if($id0->[0] == $flag_id) {
1480 $k = $id0->[1] <=> $id1->[1];
1482 $k = $id0->[2] <=> $id1->[2];
1484 $k = $len0 <=> $len1;
1485 return $k if $k || $len <= 3;
1487 # $dump->dumpValue( $id0 );
1488 # $dump->dumpValue( $id1 );
1489 # die "internal oops: strange id" if $len < 4;
1491 return -1 if !defined($id0->[$i]);
1492 return 1 if !defined($id1->[$i]);
1493 return $id0->[$i] <=> $id1->[$i];
1496 die "internal oops: can't compare that!";
1500 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1504 my ($skey0, $skey1, $len0, $len1, $len, $i, $k);
1506 ($skey0, $skey1) = @_;
1508 return 0 if !defined($skey0) && !defined($skey1);
1509 return -1 if !defined($skey0);
1510 return 1 if !defined($skey1);
1514 $len = $len0 < $len1 ?
$len0 : $len1;
1516 # $dump->dumpValue( $skey0 );
1517 # $dump->dumpValue( $skey1 );
1519 for($i = 0; $i < $len; $i++) {
1520 next unless defined($skey0->[$i]) || defined($skey1->[$i]);
1522 # note: this looks reversed, but is intentional!
1523 return 1 if !defined($skey0->[$i]);
1524 return -1 if !defined($skey1->[$i]);
1526 $k = cmp_id
$skey0->[$i], $skey1->[$i];
1531 return $len0 <=> $len1;
1535 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1538 # +-1: differing keys
1539 # +-2: differing values
1543 my ($item0, $item1, $len0, $len1, $len, $i, $k);
1545 ($item0, $item1) = @_;
1549 return 0 if !defined($item0) && !defined($item1);
1550 return -1 if !defined($item0);
1551 return 1 if !defined($item1);
1553 $len0 = @
{$item0->[1]};
1554 $len1 = @
{$item1->[1]};
1555 $len = $len0 < $len1 ?
$len0 : $len1;
1557 # $dump->dumpValue( $item0 );
1559 for($i = 0; $i < $len; $i++) {
1560 return -1 if !defined($item0->[1][$i]);
1561 return 1 if !defined($item1->[1][$i]);
1562 $k = cmp_skey
$item0->[1][$i], $item1->[1][$i];
1563 # print " skey: $k\n";
1566 $k = $len0 <=> $len1;
1569 return 0 if !defined($item0->[2]) && !defined($item1->[2]);
1570 return -2 if !defined($item0->[2]);
1571 return 2 if !defined($item1->[2]);
1573 $k = cmp_skey
$item0->[2], $item1->[2];
1574 # print " val: $k\n";
1579 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1581 # check if id1 is part of id0
1588 # hd: [ "source", [ skey, skey, ... ], [ val ] ]
1589 # skey/val: [ ... , id, ..., id, ... ]
1590 # id: [ $flag_id, $tag, $value, $range, $mask ]
1591 # id: [ $flag_string, "str", "str", ... ]
1595 my ($id0, $id1, $len0, $len1, $len, $i, $k);
1599 return 0 if !defined($id0) || !defined($id1);
1601 return 0 if $id0->[0] != $id1->[0];
1605 $len = $len0 < $len1 ?
$len0 : $len1;
1607 if($id0->[0] == $flag_string) {
1608 for($i = 1; $i < $len; $i++) {
1609 return 0 if $id0->[$i] cmp $id1->[$i];
1611 return $len0 != $len1 ?
0 : 1;
1614 if($id0->[0] == $flag_id) {
1615 return 0 if $id0->[1] != $id1->[1];
1618 return $id0->[2] != $id1->[2] ?
0 : 1;
1621 return $id1->[2] >= $id0->[2] && $id1->[2] < $id0->[2] + $id0->[3] ?
1 : 0;
1624 return ($id1->[2] & ~$id0->[4]) == $id0->[2] ?
1 : 0;
1641 die "internal oops: can't match that!";
1645 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1647 # skey1 part of skey0?
1651 my ($skey0, $skey1, $len0, $len1, $len, $i, $k);
1653 ($skey0, $skey1) = @_;
1655 return 0 if !defined($skey0) || !defined($skey1);
1660 $len = $len0 > $len1 ?
$len0 : $len1;
1662 # $dump->dumpValue( $skey0 );
1663 # $dump->dumpValue( $skey1 );
1665 for($i = 0; $i < $len; $i++) {
1666 next unless defined($skey1->[$i]);
1668 return 0 if !defined($skey0->[$i]) && defined($skey1->[$i]);
1670 $k = match_id
$skey0->[$i], $skey1->[$i];
1679 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1681 # item1 part of item0?
1685 my ($item0, $item1, $len0, $len1, $i, $j, $k, $m);
1687 ($item0, $item1) = @_;
1691 return 0 if !defined($item0) || !defined($item1);
1693 $len0 = @
{$item0->[1]};
1694 $len1 = @
{$item1->[1]};
1696 for($j = 0; $j < $len1; $j++) {
1697 for($i = 0; $i < $len0; $i++) {
1698 $k = match_skey
$item0->[1][$i], $item1->[1][$j];
1699 $m = $k if defined $k;
1708 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1710 # add skey1 to skey0
1714 my ($skey0, $skey1, $len, $i, $k, $n, $buf, $err);
1716 ($skey0, $skey1, $buf, $errors) = @_;
1720 return undef if !defined($skey0) && !defined($skey1);
1721 return [ @
$skey0 ] if !defined($skey1);
1722 return [ @
$skey1 ] if !defined($skey0);
1728 for($i = 0; $i < $len; $i++) {
1729 next unless defined $skey1->[$i];
1731 $n->[$i] = $skey1->[$i];
1733 next unless defined $skey0->[$i];
1735 $k = cmp_id
$skey0->[$i], $skey1->[$i];
1739 if($i != $he_driver) {
1740 $$buf .= ent_name_pr
(" 0:", $ent_names[$i]);
1741 $$buf .= id_dump
($i, $skey0->[$i]) . "\n";
1742 $$buf .= ent_name_pr
(" 1:", $ent_names[$i]);
1743 $$buf .= id_dump
($i, $skey1->[$i]) . "\n";
1746 $$buf .= drv_dump
(" 0:", $skey0->[$i]);
1747 $$buf =~ s/\n&/\n 0:/;
1748 $$buf .= drv_dump
(" 1:", $skey1->[$i]);
1749 $$buf =~ s/\n&/\n 1:/;
1752 $$errors++ if defined $errors;
1761 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1767 my ($item, @items, $tmp);
1772 return $item if !defined($item) || !defined($item->[1]);
1774 for (@
{$item->[1]}) {
1784 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1792 if($xml->[0] ne 'hwdata') {
1793 die "invalid XML root element (expected 'hwdata')\n"
1796 for($i = 1; $i < @
{$xml->[1]}; $i += 2) {
1797 if($xml->[1][$i] eq 'item') {
1798 push @hd, parse_xml_item
($xml->[1][$i + 1]);
1806 my (@xml, %attr, $i, $item);
1809 %attr = %{shift @xml};
1811 for($i = 0; $i < @xml; $i += 2) {
1812 if($xml[$i] eq 'key') {
1813 push @
{$item->[1]}, parse_xml_key
($xml[$i + 1]);
1816 $item->[2] = parse_xml_key
($_[0]);
1826 my (@xml, %attr, $i, @key, $val, $id, $is_id, $keyid, $keyid2, $tmp);
1829 %attr = %{shift @xml};
1831 for($i = 0; $i < @xml; $i += 2) {
1832 next if $xml[$i] eq '0' || $xml[$i] eq 'key';
1834 $keyid = $xml_values{$xml[$i]};
1835 $is_id = $keyid < $he_nomask && $ent_names[$keyid] =~ /\.(id|name)$/ ?
1 : 0;
1837 if(!defined($keyid)) {
1838 die "invalid key element \"$xml[$i]\"\n";
1841 if($keyid == $he_driver) {
1842 $id = parse_xml_driver
($xml[$i + 1]);
1843 if(!defined($key[$keyid])) {
1847 push @
{$key[$keyid]}, $id->[1];
1851 $id = parse_xml_id
($xml[$i + 1]);
1852 if($id->[0] == $flag_id) {
1853 $tmp = $ent_names[$keyid];
1854 $tmp =~ s/\.name$/.id/;
1855 $keyid2 = $ent_values{$tmp};
1856 if(!defined($keyid2)) {
1857 die "oops, no .id for $xml[$i]?";
1861 $tmp = $ent_names[$keyid];
1862 $tmp =~ s/\.id$/.name/;
1863 $keyid2 = $ent_values{$tmp};
1864 if(!defined($keyid2)) {
1865 die "oops, no .name for $xml[$i]?";
1868 $key[$keyid2] = $id;
1871 $val = parse_xml_cdata
($xml[$i + 1]);
1872 if(defined($key[$keyid]) && $keyid == $he_requires) {
1873 $key[$keyid][1] .= "|$val";
1876 $key[$keyid] = [ $flag_string, $val ];
1887 my (@xml, %attr, $i, $id, $val);
1890 %attr = %{shift @xml};
1892 for($i = 0; $i < @xml; $i += 2) {
1893 next if $xml[$i] eq '0';
1895 if($xml[$i] eq 'id') {
1896 $id = parse_xml_id_id
($xml[$i + 1]);
1898 elsif($xml[$i] eq 'idrange') {
1899 $id = parse_xml_id_range
($xml[$i + 1]);
1901 elsif($xml[$i] eq 'idmask') {
1902 $id = parse_xml_id_mask
($xml[$i + 1]);
1904 elsif($xml[$i] eq 'name') {
1905 $val = parse_xml_cdata
($xml[$i + 1]);
1906 $id = [ $flag_string, $val ];
1909 die "invalid id element \"$xml[$i]\"\n";
1919 my (@xml, %attr, $i, $tag, $value);
1922 %attr = %{shift @xml};
1924 $tag = $tag_values{$attr{type
}};
1926 if(!defined($tag)) {
1927 die "missing/unsupported id attribute \"$attr{type}\"\n";
1930 for($i = 0; $i < @xml; $i += 2) {
1931 if($xml[$i] eq '0') {
1932 $value = idstr2value
$tag, $xml[$i + 1];
1935 die "cdata expected, got \"$xml[$i]\"\n";
1939 return [ $flag_id, $tag, $value ];
1943 sub parse_xml_id_range
1945 my (@xml, %attr, $i, $tag, $value, $range);
1948 %attr = %{shift @xml};
1950 $tag = $tag_values{$attr{type
}};
1952 if(!defined($tag)) {
1953 die "missing/unsupported id attribute \"$attr{type}\"\n";
1956 for($i = 0; $i < @xml; $i += 2) {
1957 next if $xml[$i] eq '0';
1958 if($xml[$i] eq 'first') {
1959 $value = idstr2value
$tag, parse_xml_cdata
($xml[$i + 1]);
1961 elsif($xml[$i] eq 'last') {
1962 $range = idstr2value
$tag, parse_xml_cdata
($xml[$i + 1]);
1965 die "invalid idrange element \"$xml[$i]\"\n";
1969 if(!defined($value) || !defined($range)) {
1970 die "invalid idrange\n";
1973 return [ $flag_id, $tag, $value, $range - $value + 1 ];
1977 sub parse_xml_id_mask
1979 my (@xml, %attr, $i, $tag, $value, $mask);
1982 %attr = %{shift @xml};
1984 $tag = $tag_values{$attr{type
}};
1986 if(!defined($tag)) {
1987 die "missing/unsupported id attribute \"$attr{type}\"\n";
1990 for($i = 0; $i < @xml; $i += 2) {
1991 next if $xml[$i] eq '0';
1992 if($xml[$i] eq 'value') {
1993 $value = idstr2value
$tag, parse_xml_cdata
($xml[$i + 1]);
1995 elsif($xml[$i] eq 'mask') {
1996 $mask = idstr2value
$tag, parse_xml_cdata
($xml[$i + 1]);
1999 die "invalid idmask element \"$xml[$i]\"\n";
2003 if(!defined($value) || !defined($mask)) {
2004 die "invalid idmask\n";
2007 return [ $flag_id, $tag, $value, undef, $mask ];
2011 sub parse_xml_driver
2013 my (@xml, %attr, $i, $val);
2016 %attr = %{shift @xml};
2018 for($i = 0; $i < @xml; $i += 2) {
2019 next if $xml[$i] eq '0';
2021 if($xml[$i] eq 'any') {
2022 $val = "a\t" . parse_xml_cdata
($xml[$i + 1]);
2024 elsif($xml[$i] eq 'display') {
2025 $val = parse_xml_driver_display
($xml[$i + 1]);
2027 elsif($xml[$i] eq 'module') {
2028 $val = parse_xml_driver_module
($xml[$i + 1]);
2030 elsif($xml[$i] eq 'mouse') {
2031 $val = parse_xml_driver_mouse
($xml[$i + 1]);
2033 elsif($xml[$i] eq 'xfree') {
2034 $val = parse_xml_driver_xfree
($xml[$i + 1]);
2037 die "invalid driver element \"$xml[$i]\"\n";
2041 return [ $flag_string, $val ];
2045 sub parse_xml_driver_display
2047 my (@xml, %attr, $i, @val);
2050 %attr = %{shift @xml};
2052 for($i = 0; $i < @xml; $i += 2) {
2053 next if $xml[$i] eq '0';
2055 if($xml[$i] eq 'resolution') {
2056 $val[0] = join('x', parse_xml_pair
($xml[$i + 1], 'width', 'height'));
2058 elsif($xml[$i] eq 'vsync') {
2059 $val[1] = join('-', parse_xml_pair
($xml[$i + 1], 'min', 'max'));
2061 elsif($xml[$i] eq 'hsync') {
2062 $val[2] = join('-', parse_xml_pair
($xml[$i + 1], 'min', 'max'));
2064 elsif($xml[$i] eq 'bandwidth') {
2065 $val[3] = parse_xml_cdata
($xml[$i + 1]);
2068 die "invalid display element \"$xml[$i]\"\n";
2073 die "invalid display info\n";
2076 return "d\t" . join('|', @val);
2080 sub parse_xml_driver_module
2082 my (@xml, %attr, $i, $val, $type, @conf, @mods);
2085 %attr = %{shift @xml};
2087 for($i = 0; $i < @xml; $i += 2) {
2088 next if $xml[$i] eq '0';
2090 $val = parse_xml_cdata
($xml[$i + 1]);
2092 if($xml[$i] eq 'modprobe') {
2093 if($type && $type ne 'm') {
2094 die "invalid module info: \"$xml[$i]\"\n";
2099 elsif($xml[$i] eq 'insmod') {
2100 if($type && $type ne 'i') {
2101 die "invalid module info: \"$xml[$i]\"\n";
2106 elsif($xml[$i] eq 'modconf') {
2107 if($type && $type ne 'm') {
2108 die "invalid module info: \"$xml[$i]\"\n";
2110 push @conf, "\x00M\t$val";
2113 die "invalid module element \"$xml[$i]\"\n";
2117 if(!$type && !@mods) {
2118 die "invalid module info\n";
2121 $val = "$type\t" . join('|', @mods);
2124 $val .= join('', @conf);
2131 sub parse_xml_driver_mouse
2133 my (@xml, %attr, $i, $val, @val);
2136 %attr = %{shift @xml};
2138 for($i = 0; $i < @xml; $i += 2) {
2139 next if $xml[$i] eq '0';
2141 $val = parse_xml_cdata
($xml[$i + 1]);
2143 if($xml[$i] eq 'xf86') {
2146 elsif($xml[$i] eq 'gpm') {
2149 elsif($xml[$i] eq 'buttons') {
2152 elsif($xml[$i] eq 'wheels') {
2156 die "invalid mouse element \"$xml[$i]\"\n";
2161 die "invalid mouse info\n";
2164 return "p\t" . join('|', @val);
2168 sub parse_xml_driver_xfree
2170 my (@xml, %attr, $i, $val, @val, @conf);
2173 %attr = %{shift @xml};
2175 for($i = 0; $i < @xml; $i += 2) {
2176 next if $xml[$i] eq '0';
2178 if($xml[$i] eq 'has3d') {
2182 $val = parse_xml_cdata
($xml[$i + 1]);
2184 if($xml[$i] eq 'version') {
2187 elsif($xml[$i] eq 'server') {
2190 elsif($xml[$i] eq 'extension') {
2191 $val[4] .= "," if defined $val[4];
2194 elsif($xml[$i] eq 'option') {
2195 $val[5] .= "," if defined $val[5];
2198 elsif($xml[$i] eq 'bpp') {
2199 $val[6] .= "," if defined $val[6];
2202 elsif($xml[$i] eq 'dacspeed') {
2205 elsif($xml[$i] eq 'script') {
2208 elsif($xml[$i] eq 'xf86conf') {
2209 push @conf, "\x00X\t$val";
2212 die "invalid xfree element \"$xml[$i]\"\n";
2218 die "invalid xfree info\n";
2221 $val = "x\t" . join('|', @val);
2224 $val .= join('', @conf);
2233 my (@xml, %attr, $i, $val0, $val1, $elem0, $elem1);
2239 %attr = %{shift @xml};
2241 for($i = 0; $i < @xml; $i += 2) {
2242 next if $xml[$i] eq '0';
2243 if($xml[$i] eq $elem0) {
2244 $val0 = parse_xml_cdata
($xml[$i + 1]);
2246 elsif($xml[$i] eq $elem1) {
2247 $val1 = parse_xml_cdata
($xml[$i + 1]);
2250 die "invalid element \"$xml[$i]\"\n";
2254 if(!defined($val0) || !defined($val1)) {
2255 die "invalid element\n";
2258 return ($val0, $val1);
2264 my (@xml, %attr, $i);
2267 %attr = %{shift @xml};
2269 for($i = 0; $i < @xml; $i += 2) {
2270 if($xml[$i] eq '0') {
2281 ($tag, $value) = @_;
2283 if($tag == $tag_eisa && length($value) == 3 && $value !~ /^[0-9]/) {
2284 $value = eisa_id
$value;
2287 $value = num
$value;
2293 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2299 $str = $_[0] . $_[1];
2304 $len = ($len & ~7) + 8;
2305 $str .= "\t" x
((24 - $len)/8) if $len < 24;
2313 my ($id, $ent, $str, $tag, $format);
2317 if($id->[0] == $flag_id) {
2319 if($tag == $tag_eisa && ($ent == $he_vendor_id || $ent == $he_subvendor_id)) {
2320 $str = eisa_str
$id->[2];
2323 $str .= $tag_name[$tag];
2324 $str .= " " if $tag;
2326 $format = "0x%02x" if $ent == $he_bus_id || $ent == $he_subclass_id || $ent == $he_progif_id;
2327 $format = "0x%03x" if $ent == $he_baseclass_id;
2328 $str .= sprintf $format, $id->[2];
2330 if(defined $id->[3]) {
2331 $str .= sprintf "+0x%04x", $id->[3];
2333 elsif(defined $id->[4]) {
2334 $str .= sprintf "&0x%04x", $id->[4];
2337 elsif($id->[0] == $flag_string) {
2338 if(defined($id->[2])) {
2339 die "oops: strage string data\n";
2344 die "oops: unknown id flag\n"
2353 my ($id, $str, $i, $pre, $type, $drv, $buf);
2357 die "oops: invalid driver data\n" if $id->[0] != $flag_string;
2359 for($i = 1; $i < @
{$id}; $i++) {
2360 for $drv (split /\x00/, $id->[$i]) {
2361 $type = substr $drv, 0, 2;
2363 if($type eq "x\t") {
2364 $buf .= ent_name_pr
($pre, $ent_names[$he_driver_xfree]);
2365 $buf .= substr($drv, 2) . "\n";
2367 elsif($type eq "X\t") {
2368 $buf .= ent_name_pr
($pre, $ent_names[$he_driver_xfree_config]);
2369 $buf .= substr($drv, 2) . "\n";
2371 elsif($type eq "i\t") {
2372 $buf .= ent_name_pr
($pre, $ent_names[$he_driver_module_insmod]);
2373 $buf .= substr($drv, 2) . "\n";
2375 elsif($type eq "m\t") {
2376 $buf .= ent_name_pr
($pre, $ent_names[$he_driver_module_modprobe]);
2377 $buf .= substr($drv, 2) . "\n";
2379 elsif($type eq "M\t") {
2380 $buf .= ent_name_pr
($pre, $ent_names[$he_driver_module_config]);
2381 $buf .= substr($drv, 2) . "\n";
2383 elsif($type eq "p\t") {
2384 $buf .= ent_name_pr
($pre, $ent_names[$he_driver_mouse]);
2385 $buf .= substr($drv, 2) . "\n";
2387 elsif($type eq "d\t") {
2388 $buf .= ent_name_pr
($pre, $ent_names[$he_driver_display]);
2389 $buf .= substr($drv, 2) . "\n";
2391 elsif($type eq "a\t") {
2392 $buf .= ent_name_pr
($pre, $ent_names[$he_driver_any]);
2393 $buf .= substr($drv, 2) . "\n";
2396 die "oops: unhandled driver info type: $drv\n";
2399 $pre = "&" if $pre ne "+";
2409 my ($pre, $id, $ent, $buf);
2411 ($buf, $pre, $id) = @_;
2413 $pre = defined($pre) ?
"|" : " " if $pre ne "+";
2414 for($ent = 0; $ent < @
{$id}; $ent++) {
2415 if(defined $id->[$ent]) {
2416 if($ent != $he_driver) {
2417 $$buf .= ent_name_pr
($pre, $ent_names[$ent]);
2418 $$buf .= id_dump
($ent, $id->[$ent]);
2422 $$buf .= drv_dump
($pre, $id->[$ent]);
2424 $pre = "&" if $pre ne "+";
2434 my ($item, $id, $ent, $pre, $buf);
2436 # $dump->dumpValue( \@hd );
2443 print F
"# $item->[0]\n" if $opt_with_source;
2444 for $id (@
{$item->[1]}) {
2445 $pre = ent_dump \
$buf, $pre, $id;
2448 ent_dump \
$buf, $pre, $item->[2];
2458 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2464 if($opt_internal_dtd) {
2465 $dtd = hd_dtd_internal
;
2468 $dtd = "<!DOCTYPE hwdata SYSTEM \"hd.dtd\">\n";
2471 $xml_file = new IO
::File
(">hd.xml");
2472 $xml = new XML
::Writer
(OUTPUT
=> $xml_file, DATA_MODE
=> 1, DATA_INDENT
=> 2);
2474 $xml->xmlDecl("utf-8");
2476 print $xml_file "\n$dtd";
2478 $xml->startTag("hwdata");
2480 print $xml_file "\n";
2483 dump_xml_item
$item;
2486 $xml->endTag("hwdata");
2489 if(!$opt_internal_dtd) {
2490 print STDERR
"writing \"hd.dtd\"\n";
2491 open DTD
, ">hd.dtd";
2500 my ($ent, $id, $i, $tag, $str, $format, $range, $mask);
2504 $i = $xml_names[$ent];
2506 die "oops: entry $ent not allowed here\n" unless $i;
2508 if($ent == $he_requires) {
2509 if($id->[0] == $flag_string) {
2510 die "oops: strange string data\n" if defined $id->[2];
2511 for $str (split /\|/, $id->[1]) {
2512 $xml->dataElement("requires", $str);
2516 die "oops: requires _id_???\n"
2522 if($ent == $he_serial) {
2523 if($id->[0] == $flag_string) {
2524 die "oops: strange string data\n" if defined $id->[2];
2525 $xml->characters($id->[1]);
2528 die "oops: serial _id_???\n"
2532 if($id->[0] == $flag_id) {
2534 if($tag == $tag_eisa && ($ent == $he_vendor_id || $ent == $he_subvendor_id)) {
2535 $str = eisa_str
$id->[2];
2539 $format = "0x%02x" if $ent == $he_bus_id || $ent == $he_subclass_id || $ent == $he_progif_id;
2540 $format = "0x%03x" if $ent == $he_baseclass_id;
2541 $str = sprintf $format, $id->[2];
2543 if(defined $id->[3]) {
2544 if($tag == $tag_eisa && ($ent == $he_vendor_id || $ent == $he_subvendor_id)) {
2545 $range = eisa_str
$id->[2] + $id->[3] - 1;
2548 $range = sprintf "0x%04x", $id->[2] + $id->[3] - 1;
2551 elsif(defined $id->[4]) {
2552 $mask = sprintf "0x%04x", $id->[4];
2554 $tag = $tag_name[$tag];
2556 if(defined $range) {
2558 $xml->startTag("idrange", "type" => $tag);
2561 $xml->startTag("idrange");
2563 $xml->dataElement("first", $str);
2564 $xml->dataElement("last", $range);
2567 elsif(defined $mask) {
2569 $xml->startTag("idmask", "type" => $tag);
2572 $xml->startTag("idmask");
2574 $xml->dataElement("value", $str);
2575 $xml->dataElement("mask", $mask);
2580 $xml->dataElement("id", $str, "type" => $tag);
2583 $xml->dataElement("id", $str);
2587 elsif($id->[0] == $flag_string) {
2588 die "oops: strage string data\n" if defined $id->[2];
2589 $xml->dataElement("name", $id->[1]);
2592 die "oops: unknown id flag\n"
2603 my ($id, $str, $i, $j, $k, $type, $drv, $info, @info, $current);
2607 die "oops: invalid driver data\n" if $id->[0] != $flag_string;
2609 for($i = 1; $i < @
{$id}; $i++) {
2611 $xml->startTag('driver');
2615 for $drv (split /\x00/, $id->[$i]) {
2616 $type = substr $drv, 0, 2;
2617 $info = substr $drv, 2;
2618 @info = split /\|/, $info;
2620 if($type eq "i\t") {
2621 $xml->endTag() if $current; $current = $type;
2622 $xml->startTag('module');
2624 $xml->dataElement('insmod', $j);
2627 elsif($type eq "m\t") {
2628 $xml->endTag() if $current; $current = $type;
2629 $xml->startTag('module');
2631 $xml->dataElement('modprobe', $j);
2634 elsif($type eq "M\t") {
2635 die "oops: incorrect driver info: $drv\n" unless $current eq "m\t";
2636 $xml->dataElement('modconf', $info);
2638 elsif($type eq "a\t") {
2639 $xml->endTag() if $current; $current = undef;;
2640 $xml->dataElement('any', $info);
2642 elsif($type eq "d\t") {
2643 $xml->endTag() if $current; $current = undef;
2644 $xml->startTag('display');
2645 if($info[0] =~ /^(\d+)x(\d+)$/) {
2646 ($j, $k) = ($1, $2);
2647 $xml->startTag('resolution');
2648 $xml->dataElement('width', $j);
2649 $xml->dataElement('height', $k);
2650 $xml->endTag('resolution');
2652 if($info[1] =~ /^(\d+)-(\d+)$/) {
2653 ($j, $k) = ($1, $2);
2654 $xml->startTag('vsync');
2655 $xml->dataElement('min', $j);
2656 $xml->dataElement('max', $k);
2657 $xml->endTag('vsync');
2659 if($info[2] =~ /^(\d+)-(\d+)$/) {
2660 ($j, $k) = ($1, $2);
2661 $xml->startTag('hsync');
2662 $xml->dataElement('min', $j);
2663 $xml->dataElement('max', $k);
2664 $xml->endTag('hsync');
2666 if($info[3] =~ /^\d+$/) {
2667 $xml->dataElement('bandwidth', $info[3]);
2669 $xml->endTag('display');
2671 elsif($type eq "x\t") {
2672 $xml->endTag() if $current; $current = $type;
2673 $xml->startTag('xfree');
2674 if(defined $info[0]) {
2675 $xml->dataElement('version', $info[0]);
2678 $xml->dataElement('server', $info[1]);
2681 $xml->emptyTag('has3d');
2684 # for $j (split /,/, $info[3]) {
2685 # $xml->dataElement('package', $j);
2689 for $j (split /,/, $info[4]) {
2690 $xml->dataElement('extension', $j);
2694 for $j (split /,/, $info[5]) {
2695 $xml->dataElement('option', $j);
2699 for $j (split /,/, $info[6]) {
2700 $xml->dataElement('bpp', $j);
2703 if($info[7] =~ /^\d+$/) {
2704 $xml->dataElement('dacspeed', $info[7]);
2707 $xml->dataElement('script', $info[8]);
2710 elsif($type eq "X\t") {
2711 die "oops: incorrect driver info: $drv\n" unless $current eq "x\t";
2712 $xml->dataElement('xf86conf', $info);
2714 elsif($type eq "p\t") {
2715 $xml->endTag() if $current; $current = undef;
2716 $xml->startTag('mouse');
2718 $xml->dataElement('xf86', $info[0]);
2721 $xml->dataElement('gpm', $info[1]);
2723 if($info[2] ne "") {
2724 $xml->dataElement('buttons', $info[2]);
2726 if($info[3] ne "") {
2727 $xml->dataElement('wheels', $info[3]);
2729 $xml->endTag('mouse');
2732 $xml->endTag() if $current; $current = undef;
2733 # die "oops: unhandled driver info type: $drv\n";
2737 $xml->endTag() if $current;
2739 $xml->endTag('driver');
2751 for($ent = 0; $ent < @
{$id}; $ent++) {
2752 if(defined $id->[$ent]) {
2753 if($ent != $he_driver) {
2754 dump_xml_id
$ent, $id->[$ent];
2757 dump_xml_drv
$id->[$ent];
2771 $xml->startTag('item');
2773 for $id (@
{$item->[1]}) {
2774 $xml->startTag('key');
2776 $xml->endTag('key');
2779 dump_xml_ent
$item->[2];
2781 $xml->endTag('item');
2782 print $xml_file "\n";
2789 <!-- libhd DTD V0.2 -->
2791 <!ENTITY % keyfields "bus|baseclass|subclass|progif|vendor|device|subvendor|subdevice|revision|serial|driver|requires">
2792 <!ENTITY % idelements "id|idrange|idmask|name">
2793 <!ENTITY % idtypes "none|pci|eisa|usb|pcmcia|special">
2795 <!ELEMENT hwdata (item*)>
2797 <!ELEMENT item (key+,(%keyfields;)*)>
2799 <!ELEMENT key (%keyfields;)+>
2801 <!ELEMENT bus (%idelements;)>
2802 <!ELEMENT baseclass (%idelements;)>
2803 <!ELEMENT subclass (%idelements;)>
2804 <!ELEMENT progif (%idelements;)>
2805 <!ELEMENT vendor (%idelements;)>
2806 <!ELEMENT device (%idelements;)>
2807 <!ELEMENT subvendor (%idelements;)>
2808 <!ELEMENT subdevice (%idelements;)>
2809 <!ELEMENT revision (%idelements;)>
2810 <!ELEMENT serial (#PCDATA)>
2811 <!ELEMENT requires (#PCDATA)>
2812 <!ELEMENT id (#PCDATA)>
2813 <!ELEMENT idrange (first,last)>
2814 <!ELEMENT first (#PCDATA)>
2815 <!ELEMENT last (#PCDATA)>
2816 <!ELEMENT idmask (value,mask)>
2817 <!ELEMENT value (#PCDATA)>
2818 <!ELEMENT mask (#PCDATA)>
2819 <!ATTLIST id type (%idtypes;) "none">
2820 <!ATTLIST idrange type (%idtypes;) "none">
2821 <!ATTLIST idmask type (%idtypes;) "none">
2822 <!ELEMENT name (#PCDATA)>
2824 <!ELEMENT driver (any|display|module|mouse|xfree)?>
2826 <!ELEMENT any (#PCDATA)>
2828 <!ELEMENT display (resolution?,vsync?,hsync?,bandwidth?)>
2829 <!ELEMENT resolution (width,height)>
2830 <!ELEMENT width (#PCDATA)>
2831 <!ELEMENT height (#PCDATA)>
2832 <!ELEMENT vsync (min,max)>
2833 <!ELEMENT hsync (min,max)>
2834 <!ELEMENT min (#PCDATA)>
2835 <!ELEMENT max (#PCDATA)>
2836 <!ELEMENT bandwidth (#PCDATA)>
2838 <!ELEMENT module (insmod+|(modprobe+,modconf*))>
2839 <!ELEMENT insmod (#PCDATA)>
2840 <!ELEMENT modprobe (#PCDATA)>
2841 <!ELEMENT modconf (#PCDATA)>
2843 <!ELEMENT mouse (xf86?,gpm?,buttons?,wheels?)>
2844 <!ELEMENT xf86 (#PCDATA)>
2845 <!ELEMENT gpm (#PCDATA)>
2846 <!ELEMENT buttons (#PCDATA)>
2847 <!ELEMENT wheels (#PCDATA)>
2849 <!ELEMENT xfree (version,server?,has3d?,extension*,option*,bpp*,dacspeed?,script?,xf86conf*)>
2850 <!ELEMENT version (#PCDATA)>
2851 <!ELEMENT server (#PCDATA)>
2852 <!ELEMENT has3d EMPTY>
2853 <!ELEMENT extension (#PCDATA)>
2854 <!ELEMENT option (#PCDATA)>
2855 <!ELEMENT bpp (#PCDATA)>
2856 <!ELEMENT dacspeed (#PCDATA)>
2857 <!ELEMENT script (#PCDATA)>
2858 <!ELEMENT xf86conf (#PCDATA)>
2870 <!ELEMENT hwdata (item*)>
2871 <!ELEMENT item (key+,(bus|baseclass|subclass|progif|vendor|device|subvendor|subdevice|revision|serial|driver|requires)*)>
2872 <!ELEMENT key (bus|baseclass|subclass|progif|vendor|device|subvendor|subdevice|revision|serial|driver|requires)+>
2873 <!ELEMENT bus (id|idrange|idmask|name)>
2874 <!ELEMENT baseclass (id|idrange|idmask|name)>
2875 <!ELEMENT subclass (id|idrange|idmask|name)>
2876 <!ELEMENT progif (id|idrange|idmask|name)>
2877 <!ELEMENT vendor (id|idrange|idmask|name)>
2878 <!ELEMENT device (id|idrange|idmask|name)>
2879 <!ELEMENT subvendor (id|idrange|idmask|name)>
2880 <!ELEMENT subdevice (id|idrange|idmask|name)>
2881 <!ELEMENT revision (id|idrange|idmask|name)>
2882 <!ELEMENT serial (#PCDATA)>
2883 <!ELEMENT requires (#PCDATA)>
2884 <!ELEMENT id (#PCDATA)>
2885 <!ELEMENT idrange (first,last)>
2886 <!ELEMENT first (#PCDATA)>
2887 <!ELEMENT last (#PCDATA)>
2888 <!ELEMENT idmask (value,mask)>
2889 <!ELEMENT value (#PCDATA)>
2890 <!ELEMENT mask (#PCDATA)>
2891 <!ATTLIST id type (none|pci|eisa|usb|pcmcia|special) "none">
2892 <!ATTLIST idrange type (none|pci|eisa|usb|special) "none">
2893 <!ATTLIST idmask type (none|pci|eisa|usb|special) "none">
2894 <!ELEMENT name (#PCDATA)>
2895 <!ELEMENT driver (any|display|module|mouse|xfree)?>
2896 <!ELEMENT any (#PCDATA)>
2897 <!ELEMENT display (resolution?,vsync?,hsync?,bandwidth?)>
2898 <!ELEMENT resolution (width,height)>
2899 <!ELEMENT width (#PCDATA)>
2900 <!ELEMENT height (#PCDATA)>
2901 <!ELEMENT vsync (min,max)>
2902 <!ELEMENT hsync (min,max)>
2903 <!ELEMENT min (#PCDATA)>
2904 <!ELEMENT max (#PCDATA)>
2905 <!ELEMENT bandwidth (#PCDATA)>
2906 <!ELEMENT module (insmod+|(modprobe+,modconf*))>
2907 <!ELEMENT insmod (#PCDATA)>
2908 <!ELEMENT modprobe (#PCDATA)>
2909 <!ELEMENT modconf (#PCDATA)>
2910 <!ELEMENT mouse (xf86?,gpm?,buttons?,wheels?)>
2911 <!ELEMENT xf86 (#PCDATA)>
2912 <!ELEMENT gpm (#PCDATA)>
2913 <!ELEMENT buttons (#PCDATA)>
2914 <!ELEMENT wheels (#PCDATA)>
2915 <!ELEMENT xfree (version,server?,has3d?,extension*,option*,bpp*,dacspeed?,script?,xf86conf*)>
2916 <!ELEMENT version (#PCDATA)>
2917 <!ELEMENT server (#PCDATA)>
2918 <!ELEMENT has3d EMPTY>
2919 <!ELEMENT extension (#PCDATA)>
2920 <!ELEMENT option (#PCDATA)>
2921 <!ELEMENT bpp (#PCDATA)>
2922 <!ELEMENT dacspeed (#PCDATA)>
2923 <!ELEMENT script (#PCDATA)>
2924 <!ELEMENT xf86conf (#PCDATA)>