summaryrefslogtreecommitdiffstats
path: root/tools/find-drivers-needing-nonfree-firmware
blob: e8068baee9467fe5a2bba36e256ac9c7507565b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/perl
use MDK::Common;
use Data::Dumper;
use Data::Dumper::Perltidy;

my $debug = member('--debug', @ARGV);

my $path = '../../cache';
my %cache = (
    version   => "$path/version.txt",
    modules   => "$path/modules.txt",
    firmwares => "$path/firmwares.txt",
    modinfo   => "$path/modinfo.",
    );

mkdir_p($path) if !-d $path;
# version of main kernel flavor:
my $kernel = chomp_(cat_($cache{version}));
if (!$kernel) {
    # get regular flavor:
    ($kernel) = split('\|', chomp_(`urpmq -f kernel-desktop-latest`));
    # get real package name:
    $kernel =~ s/-latest//;
    # drop arch as it confuses urpmq:
    $kernel =~ s/\.[^.]*$//;
    output($cache{version}, $kernel);
}
warn ">> GOT '$kernel'\n" if $debug;

# list of modules:
my @modules = cat_($cache{modules});
if (!@modules) {
    @modules = grep { /\.ko/ } `urpmq -l $kernel`;
    output($cache{modules}, @modules);
}
@modules = map { chomp; $_ } @modules;

# list of those module firmwares:
my %firmwares;
{
    my @firmwares = cat_($cache{firmwares});
    if (!@firmwares) {
	@firmwares = `urpmf --qf '%name-%version-%release.%arch:%files' /lib/firmware/ |sort -u`;
	output($cache{firmwares}, @firmwares);
    }
    %firmwares = map { chomp; s!^(.*):/lib/firmware/!!; $_ => $1 } @firmwares;
}

#warn Data::Dumper->Dump([ \@modules ], [ 'modules' ]);
warn Data::Dumper->Dump([ \%firmwares ], [ 'firmwares' ]) if $debug;

# compute list of module that needs nonfree firmwares:
my @non_free_fw_drivers;
foreach (uniq(@modules)) {
    my ($raw) = m!([^/]*)$!;
    my $cache = $cache{modinfo} . $raw;
    my @firmwares = cat_($cache);
    # speedup: cache might exists but being empty:
    if (!-e $cache) {
	#warn ">> run '/sbin/modinfo $_ | grep firmware:'\n" if $debug;
	@firmwares = `/sbin/modinfo $_ | grep firmware:`;
	output($cache, @firmwares);
    }
    @firmwares = map { chomp; s/^.*:\s+//; $_ } @firmwares;
    next if !@firmwares;
    warn Data::Dumper->Dump([ \@firmwares ], [ 'firmware' ]) if $debug;
    if (any { $firmwares{$_} && $firmwares{$_} =~ /nonfree/ } @firmwares) {
	push @non_free_fw_drivers, $_;
	#last;
    }
}

# cleaning:
@non_free_fw_drivers = sort map { s!.*/!!; s!\.ko.*$!!; $_ } @non_free_fw_drivers;

#$Data::Dumper::Perltidy::ARGV = '-it=2 -l 100';
#warn Dumper(\@non_free_fw_drivers) . "\n";

# Pretty dump:
my $sep = '    ';
my $s = $sep . 'qw(' . join(' ', @non_free_fw_drivers) . ')';
$s =~ s/(.{70}\S*)\s+/$1\n$sep/g;

output('list_firmwares.pm',
	"# generated using $kernel\n",
       q(# This list is autogenerated ; Do NOT alter manually.

package list_firmwares;

our @modules_with_nonfree_firmware = 
),
       $s, ";\n\n1;\n");