summaryrefslogtreecommitdiffstats
path: root/perl-install/modalias.pm
diff options
context:
space:
mode:
authorDexter Morgan <dmorgan@mageia.org>2011-06-02 20:51:35 +0000
committerDexter Morgan <dmorgan@mageia.org>2011-06-02 20:51:35 +0000
commita9b2bdafaf625d10aef2f476aa4014fd36c846bc (patch)
tree2364afc0ee6739b59a25c44d68c9f003bcaf03d9 /perl-install/modalias.pm
downloaddrakx-a9b2bdafaf625d10aef2f476aa4014fd36c846bc.tar
drakx-a9b2bdafaf625d10aef2f476aa4014fd36c846bc.tar.gz
drakx-a9b2bdafaf625d10aef2f476aa4014fd36c846bc.tar.bz2
drakx-a9b2bdafaf625d10aef2f476aa4014fd36c846bc.tar.xz
drakx-a9b2bdafaf625d10aef2f476aa4014fd36c846bc.zip
Branch for updates
Diffstat (limited to 'perl-install/modalias.pm')
-rw-r--r--perl-install/modalias.pm104
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;