diff --git a/sis33/drivers/sis33install.pl b/sis33/drivers/sis33install.pl new file mode 100755 index 0000000000000000000000000000000000000000..2bb988ebc937e5a5714da9ab41dcb92bdbcd6e46 --- /dev/null +++ b/sis33/drivers/sis33install.pl @@ -0,0 +1,131 @@ +#!/usr/bin/perl +# Install sis33 modules from a transfer.ref file +# +# first the transfer.ref file is parsed and then, after some sanity checks, +# insmod is called with the parameters extracted from transfer.ref. +# +# call with 'script.pl --type 00' to install sis3300 modules only. +# ditto for SIS33'20' modules. +# by default it tries to install all the modules it finds. + +use strict; +use warnings; +use Getopt::Long; + +# module types to be installed +my @types; + +# supported module types +my $supported = "(0|2)0"; + +GetOptions("type=s" => \@types) or die("Failed to parse arguments\n"); + +# allow comma-separated input +@types = split(/,/, join(',', @types)); + +# sanity check the input +for my $type (@types) { + die("Invalid type $type (valid: $supported\n") if $type !~ m/^$supported$/; +} + +# install all modules by default +if (!@types) { + @types = qw/00 20/; +} + +my $path = '/etc/transfer.ref'; +my @AoH; +my @keys = ('ln', 'mln', 'bus', 'mtno', 'module-type', 'lu', 'W1', 'AM1', + 'DPsz1', 'basaddr1', 'range1', 'W2', 'AM2', 'DPsz2', 'basaddr2', + 'range2', 'testoff', 'sz', 'sl', 'ss'); + +my %base_addrs; + +open(INPUT, "<$path") or die ("$path not found"); +# put all the described modules in an array of hashes (AoH) +LINE: while (<INPUT>) { + next LINE if $_ !~ m|^\#\+\#|; + + chomp; + my @values = split(/\s+/, $_); + # remove the first '#+#' + shift @values; + + my $href; + foreach (@keys) { + $href->{$_} = shift @values; + } + +# only add SIS33 modules to the AoH + next LINE if $href->{'module-type'} !~ m/^SIS33$supported$/; + +# don't add modules with index values that we have already picked up + if ($base_addrs{"$href->{'lu'}"}) { + print "warning: $href->{'module-type'}.$href->{'lu'} has an already taken index number and won't be installed\n"; + } else { + push @AoH, $href; + $base_addrs{$href->{'lu'}} = $href->{'basaddr1'}; + } +} +close(INPUT); + +# If we found at least a module, then sis33.ko should be installed +# But if the sis33 module is already there, we won't install it again +if (@AoH) { + if (!module_is_loaded('sis33')) { + system('insmod sis33.ko') == 0 or die("'insmod sis33.ko' failed"); + } +} else { + die "No SIS33$supported modules found in $path.\n"; +} + +# install the modules in @types, catching repeated entries. +my %installed; +for my $module_type (@types) { + if (!defined $installed{"$module_type"}) { + sis33_install($module_type, \@AoH); + $installed{"$module_type"} = 1; + } else { + print "warning: repeated type $module_type\n"; + } +} + +sub module_is_loaded { + my $module = shift; + + open(LSMOD, '/proc/modules') or die('Cannot open /proc/modules.\n'); + while (<LSMOD>) { + chomp; + my ($modname, $rest) = split(/\s+/, $_); + + if ($modname =~ m/^$module$/) { + close(LSMOD); + return 1; + } + } + close(LSMOD); + return 0; +} + +sub sis33_install { + my $type = shift; + my $AoHref = shift; + my $index_parm; + my $base_parm; + + ENTRY: foreach my $href (@{$AoHref}) { + next ENTRY if $href->{'module-type'} !~ m/SIS33$type/; + + if (defined $base_parm) { + $base_parm = $base_parm.',0x'.$href->{'basaddr1'}; + $index_parm = $index_parm.','.$href->{'lu'}; + } else { + $base_parm = '0x'.$href->{'basaddr1'}; + $index_parm = $href->{'lu'}; + } + } + if (defined $base_parm) { + my $insmod = "insmod sis33$type.ko base=$base_parm index=$index_parm"; + system($insmod) == 0 or die("$insmod failed"); + } +}