#!/usr/bin/perl use FileHandle; my %depend = (); my %minver = (); my %config = (); my %intopt = (); my %tristate = (); my $version, $level, $sublevel; my $force_kconfig=shift; sub add_bool($) { my $arg=shift; exists $config{$arg} or die "Adding unknown boolean '$arg'"; $tristate{$arg}="bool"; # printf "Boolean:%s\n",$arg; } sub add_tristate($) { my $arg=shift; exists $config{$arg} or die "Adding unknown tristate '$arg'"; $tristate{$arg}="tristate"; # printf "Tristate:%s\n",$arg; } sub add_int($) { my $arg=shift; exists $config{$arg} or die "Adding unknown int/hex '$arg'"; $intopt{$arg} = 0; } sub set_int_value($$) { my $key = shift; my $val = shift; exists $intopt{$key} or die "Default for unknown int/hex option '$key'"; $intopt{$key} = $val; } sub add_config($) { my $arg=shift; if ($arg =~ m/^(\w+)/) { # Have option default to 'on' $config{$1} = 1; } else { die "Do not understand config variable '$arg'"; } } # Turn option off, iff it already exists sub disable_config($) { my $key = shift; $config{$key} = 0 if (exists $config{$key}); } sub check_deps($) { my $arg=shift; $arg=$arg." "; while ($arg ne "") { if ($arg =~ m/^([A-Z0-9_]+) /) { my $val=$1; my $prev=$depend{$val}; $depend { $val } = 1+$prev; } $arg =~ s/^[^ ]+ //; } } sub open_kconfig($$) { my ($dir,$file)=@_; my $in = new FileHandle; my $disabled=0; my $key; #print "opening $file\n"; open $in,"$file"; while (<$in>) { # if (m;^\s*source[\s\"]+drivers/media/(video|dvb)/Kconfig;) { # next; # } # start of a new stanza, reset if (m/^\w/) { $disabled = 0; $default_seen = 0; $key = undef; } if (m|^\s*source\s+"([^"]+)"\s*$| || m|^\s*source\s+(\S+)\s*$|) { open_kconfig($dir,"$dir/$1"); next; } if (m|^\s+depends on\s+(.*)\n|) { check_deps ($1); } if (m|^\s+select\s+(.*)\n|) { check_deps ($1); } if (m|^\s+bool(ean)?\s|) { add_bool($key); } if (m|^\s+tristate\s|) { add_tristate($key); } if (m|^\s+int\s|) { add_int($key); } if (m|^\s+hex\s|) { add_int($key); } # Get default for int options if (m|^\s+default "([[:xdigit:]]+)"| && exists $intopt{$key}) { set_int_value($key, $1); } # Override default for disabled tri/bool options if (m/^\s+default (y|n|m|"yes"|"no")\s+(if .*)?$/ && exists $tristate{$key} && $disabled) { $default_seen = 1; $_ = "\tdefault n\n"; } # check for end of config definition for disabled drivers # we need to make sure we've disabled it, and add a bit # to the help text if (m|^\s*(---)?help(---)?\s*$| && $disabled) { if(exists $tristate{$key} && !$default_seen) { print OUT "\tdefault n\n"; } print OUT <<"EOF"; depends on VIDEO_KERNEL_VERSION help WARNING! This driver needs at least kernel $minver{$key}! It may not compile or work correctly on your kernel, which is too old. EOF next; } if (m|^\s*config (\w+)\s*$|) { $key=$1; add_config ($1); my $min=$minver { $key }; my $minversion, $minlevel, $minsublevel; if ($min =~ m/(\d+)\.(\d+)\.(\d+)/) { $minversion=$1; $minlevel=$2; $minsublevel=$3; } else { die "Minimum version for $key not found at versions.txt"; } if ( ($version < $minversion) || ($level < $minlevel) || ($sublevel < $minsublevel) ) { $disabled=1; disable_config ($key); print "$key requires version $minversion.$minlevel.$minsublevel\n"; print OUT "# $key disabled for insufficient kernel version\n"; } else { # print "OK: $key requires version $minversion.$minlevel.$minsublevel\n"; $disabled=0; } } s/^main(menu\s\"[^\"]+)/\1 - DON'T CHANGE IT!/; print OUT $_; } close $in; } sub parse_versions () { my $in = new FileHandle; my $ver; open $in,"versions.txt"; while (<$in>) { if (m/\[([\d.]*)\]/) { $ver=$1; next; } s/\n//; if (m/^\s*([\w\d_]+)/) { $minver { $1 } = $ver; # printf ("%s=%s\n",$1,$ver); } } close $in; } parse_versions; open IN,".version"; while () { if (m/KERNELRELEASE\s*[:]*[=]+\s*(\d+)\.(\d+)\.(\d+)/) { $version=$1; $level=$2; $sublevel=$3; } } close IN; printf "Preparing to compile for kernel version %d.%d.%d\n",$version,$level,$sublevel; open OUT,">Kconfig"; print OUT <<"EOF"; mainmenu "V4L/DVB menu" source Kconfig.kern config VIDEO_KERNEL_VERSION bool "Enable drivers not supported by this kernel" default n ---help--- Normally drivers that require a kernel newer $version.$level.$sublevel, the kernel you are compiling for now, will be disabled. Turning this switch on will let you enabled them, but be warned they may not work properly or even compile. They may also work fine, and the only reason they are listed as requiring a newer kernel is that no one has tested them with an older one yet. If the driver works, please post a report at V4L mailing list: video4linux-list\@redhat.com. Unless you know what you are doing, you should answer N. EOF open_kconfig ("../linux","../linux/drivers/media/Kconfig"); close OUT; while ( my ($key, $value) = each(%config) ) { delete $depend{$key}; } open OUT,">Kconfig.kern"; print OUT "config MODULES\n\tboolean\n\tdefault y\n\n"; add_config('MODULES'); add_bool('MODULES'); while ( my ($key, $value) = each(%depend) ) { print OUT "# $key with $value refs\nconfig $key\n\ttristate\n\tdefault m\n\n"; } close OUT; # These options should default to off disable_config('DVB_AV7110_FIRMWARE'); disable_config('DVB_CINERGYT2_TUNING'); # Produce a .config file if it's forced or one doesn't already exist if (($force_kconfig eq 1) || !open IN,".config") { open OUT,">.config"; while ( my ($key,$value) = each(%tristate) ) { if (!$config{$key}) { print OUT "CONFIG_$key=n\n"; } elsif ($value eq 'tristate') { print OUT "CONFIG_$key=m\n"; } else { # must be 'bool' print OUT "CONFIG_$key=y\n"; } } while ( my ($key,$value) = each(%intopt) ) { print OUT "CONFIG_$key=$value\n"; } close OUT; }