diff options
author | Antoine Ginies <aginies@mandriva.com> | 2011-01-19 10:44:49 +0000 |
---|---|---|
committer | Antoine Ginies <aginies@mandriva.com> | 2011-01-19 10:44:49 +0000 |
commit | 530a16ec071db0e24e6e949e265a96848864967c (patch) | |
tree | fe40cacd28d67b98186754c551b7fd339ebc7e17 /perl-install/modalias.pm | |
download | drakx-530a16ec071db0e24e6e949e265a96848864967c.tar drakx-530a16ec071db0e24e6e949e265a96848864967c.tar.gz drakx-530a16ec071db0e24e6e949e265a96848864967c.tar.bz2 drakx-530a16ec071db0e24e6e949e265a96848864967c.tar.xz drakx-530a16ec071db0e24e6e949e265a96848864967c.zip |
add mes5-2.6.33 branch
Diffstat (limited to 'perl-install/modalias.pm')
-rw-r--r-- | perl-install/modalias.pm | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/perl-install/modalias.pm b/perl-install/modalias.pm new file mode 100644 index 000000000..e1b61edc0 --- /dev/null +++ b/perl-install/modalias.pm @@ -0,0 +1,104 @@ +package modalias; + +# TODO: +# - be faster (Elapsed time: lspcidrake.pl ~ 0.28s instead of 0.12s for old lspcidrake + +use strict; +use MDK::Common; +use c; + +my @config_groups = ( + [ + "/lib/module-init-tools/modprobe.default", + "/etc/modprobe.conf", + "/etc/modprobe.d", + ], +); +my @system_groups = ( + [ + "/lib/module-init-tools/ldetect-lst-modules.alias", + ], + [ + "/lib/modules/" . c::kernel_version() . "/modules.alias", + ], +); +my @classes = qw(ide ieee1394 input pci pcmcia pnp serio usb); +my @alias_groups; + +my $alias_re = qr/^\s*alias\s+(([^:]+):\S+)\s+(\S+)$/; + +sub alias_to_ids { + my ($alias) = @_; + my ($vendor, $device); + # returns (vendor, device) + if (($vendor, $device) = $alias =~ /:v([0-9A-F]{4})[dp]([0-9A-F]{4})/) { + return ($vendor, $device); + } elsif (($vendor, $device) = $alias =~ /:v0{4}([0-9A-F]{4})[dp]0{4}([0-9A-F]{4})/) { + return ($vendor, $device); + } +} + +sub parse_path { + my ($group, $path) = @_; + if (-d $path) { + parse_path($group, "$path/$_") foreach all($path); + } elsif (-f $path) { + foreach (cat_($path)) { + if (my ($alias, $class, $module) = $_ =~ $alias_re) { + if (member($class, @classes)) { + my ($vendor, $device) = alias_to_ids($alias); + if ($vendor) { + $group->{$class} ||= {}; + $group->{$class}{$vendor} ||= {}; + $group->{$class}{$vendor}{$device} ||= []; + push @{$group->{$class}{$vendor}{$device}}, $alias, $module; + } else { + push @{$group->{$class}{other}}, $alias, $module; + } + } + } + } + } +} + +sub parse_file_modules { + my ($path) = @_; + my %modules; + foreach (cat_($path)) { + if (my ($alias, undef, $module) = $_ =~ $alias_re) { + push @{$modules{$module}}, $alias; + } + } + \%modules; +} + +sub get_alias_groups { + my ($o_skip_config) = @_; + #- FIXME: only o_skip_config from the first call is considered + @alias_groups = map { + my $group = {}; + parse_path($group, $_) foreach @$_; + $group; + } if_(!$o_skip_config, @config_groups), @system_groups unless @alias_groups; + @alias_groups; +} + +sub get_modules { + my ($modalias, $o_skip_config) = @_; + my ($class) = $modalias =~ /^([^:]+):\S+$/; + my ($vendor, $device) = alias_to_ids($modalias); + $class && member($class, @classes) or return; + + require File::FnMatch; + foreach my $group (get_alias_groups($o_skip_config)) { + my @aliases; + foreach my $subgroup ($group->{$class}{$vendor}{$device}, $group->{$class}{other}) { + foreach (group_by2(@$subgroup)) { + File::FnMatch::fnmatch($_->[0], $modalias) and push @aliases, $_->[1]; + } + } + return uniq(@aliases) if @aliases; + } +} + +1; |