File: [local] / openbsd / fw_update / firmware_patterns.pl (download)
Revision 1.2, Wed Dec 22 03:05:48 2021 UTC (2 years, 9 months ago) by afresh1
Branch: MAIN
CVS Tags: HEAD Changes since 1.1: +1 -0 lines
Ignore devices with only a vendor
Not sure why they exist, but whatever.
|
#!/usr/bin/perl
use v5.30;
use warnings;
use File::Temp qw<>;
my %drivers = (
acx => undef,
amdgpu => { dir => 'sys/dev/pci/drm/amd/amdgpu/', type => 'amdgpu' },
athn => undef,
bwfm => undef,
bwi => undef,
intel => ['^cpu0: Intel'],
inteldrm => { dir => 'sys/dev/pci/drm/i915/', type => 'i915' },
ipw => undef,
iwi => undef,
iwm => undef,
iwn => undef,
iwx => undef,
malo => undef,
ogx => undef,
otus => undef,
pgt => undef,
radeondrm => { dir => 'sys/dev/pci/drm/radeon/', type => 'radeon' },
rsu => undef,
rtwn => undef,
uath => undef,
upgt => undef,
urtwn => undef,
uvideo => undef,
vmm => undef,
wpi => undef,
);
foreach my $driver (sort keys %drivers ) {
my $def = $drivers{$driver};
say "$driver";
next unless defined $def;
if ( ref $def eq 'ARRAY' ) {
say "$driver $_" for @{ $def };
}
elsif ( ref $def eq 'HASH' ) {
say qq{$driver $_} for products($def);
}
else { die "Unknown def for $driver!" }
}
sub products {
state $C = do { local $/; readline *DATA };
state $D = File::Temp->newdir("firmware_patterns-XXXXXXXXX");
my ($def) = @_;
my $type = $def->{type};
my $f = "$D/$type";
{
open my $fh, ">", "$f.c" or die "Unable to create $f.c: $!";
$fh->print( $C =~ s/%type%/$type/gr );
close $fh;
}
system(cc => '-o', $f, '-I', "/usr/src/$def->{dir}", "$f.c") == 0
or die "cc $f.c failed!";
open my $fh, '-|', $f or die "Unable to fork $f: $!";
my @patterns = $fh->getlines;
close $fh;
chomp @patterns;
my %seen;
return map { qq{"$_"} } grep { !$seen{$_}++ } sort
grep { ! /\s$/ } # ignore items with just a vendor
map { s/^\p{XDigit}+:\p{XDigit}+\s+//r } @patterns;
}
__DATA__
#include <sys/types.h>
#include <stdio.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
#include <dev/pci/pcidevs_data.h>
struct pci_matchid {
pci_vendor_id_t pm_vid;
pci_product_id_t pm_pid;
};
#include "%type%_devlist.h"
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
const char *
pci_findvendor(pci_vendor_id_t vendor)
{
const struct pci_known_vendor *kdp;
kdp = pci_known_vendors;
while (kdp->vendorname != NULL) { /* all have vendor name */
if (kdp->vendor == vendor)
break;
kdp++;
}
return (kdp->vendorname);
}
const char *
pci_findproduct(pci_vendor_id_t vendor, pci_product_id_t product)
{
const struct pci_known_product *pkp;
pkp = pci_known_products;
while (pkp->productname != NULL) { /* all have product name */
if (pkp->vendor == vendor && pkp->product == product)
break;
pkp++;
}
return (pkp->productname);
}
int
main(void)
{
int i;
const char *v, *p;
for (i = 0; i < nitems(%type%_devices); i++) {
v = pci_findvendor(%type%_devices[i].pm_vid);
p = pci_findproduct(%type%_devices[i].pm_vid,
%type%_devices[i].pm_pid);
printf("%04x:%04x", %type%_devices[i].pm_vid,
%type%_devices[i].pm_pid);
printf(" %s %s\n", v ? v : "", p ? p : "");
}
return 0;
}