1592ffb21SWarner Losh#!/usr/bin/perl 2592ffb21SWarner Losh 3592ffb21SWarner Loshuse strict; 4592ffb21SWarner Loshuse warnings; 5592ffb21SWarner Loshuse utf8; 6592ffb21SWarner Losh 7592ffb21SWarner Loshuse File::Basename; 8592ffb21SWarner Losh 9592ffb21SWarner Loshmy $progname = basename($0); 10592ffb21SWarner Losh 11592ffb21SWarner Loshsub parse_linux_header ($) 12592ffb21SWarner Losh{ 13592ffb21SWarner Losh my ($header) = @_; 14592ffb21SWarner Losh 15592ffb21SWarner Losh open(my $fh, '<', $header) or die "Can't open Linux header: $!\n"; 16592ffb21SWarner Losh 17592ffb21SWarner Losh my $in_list = 0; 18592ffb21SWarner Losh 19592ffb21SWarner Losh my %pciids = (); 20592ffb21SWarner Losh 21592ffb21SWarner Losh my $current_vendor_define; 22592ffb21SWarner Losh 23592ffb21SWarner Losh while (my $line = <$fh>) { 24592ffb21SWarner Losh if ($line =~ /^#define +([^ ]+) +/) { 25592ffb21SWarner Losh $current_vendor_define = $1; 26592ffb21SWarner Losh $pciids{$current_vendor_define} = {}; 27592ffb21SWarner Losh } elsif ($line =~ /^\t\{0x([0-9a-fA-F]{4}), *0x([0-9a-fA-F]{4}),[^,]+,[^,]+,[^,]+,[^,]+, *([^}]+)\}/) { 28592ffb21SWarner Losh my $vendor_id = uc($1); 29592ffb21SWarner Losh my $device_id = uc($2); 30592ffb21SWarner Losh my $flags = $3; 31592ffb21SWarner Losh 32592ffb21SWarner Losh $pciids{$current_vendor_define}{$device_id} = { 33592ffb21SWarner Losh 'vendor_id' => $vendor_id, 34592ffb21SWarner Losh 'flags' => $flags 35592ffb21SWarner Losh }; 36592ffb21SWarner Losh } 37592ffb21SWarner Losh } 38592ffb21SWarner Losh 39592ffb21SWarner Losh close($fh); 40592ffb21SWarner Losh 41592ffb21SWarner Losh return %pciids; 42592ffb21SWarner Losh} 43592ffb21SWarner Losh 44592ffb21SWarner Loshsub parse_freebsd_header ($) { 45592ffb21SWarner Losh my ($header) = @_; 46592ffb21SWarner Losh 47592ffb21SWarner Losh open(my $fh, '<', $header) or die "Can't open FreeBSD header: $!\n"; 48592ffb21SWarner Losh 49592ffb21SWarner Losh my $in_list = 0; 50592ffb21SWarner Losh 51592ffb21SWarner Losh my %pciids = (); 52592ffb21SWarner Losh 53592ffb21SWarner Losh my $current_vendor_define; 54592ffb21SWarner Losh 55592ffb21SWarner Losh while (my $line = <$fh>) { 56592ffb21SWarner Losh if ($line =~ /^#define +([^ ]+) +/) { 57592ffb21SWarner Losh $current_vendor_define = $1; 58592ffb21SWarner Losh $pciids{$current_vendor_define} = {}; 59592ffb21SWarner Losh } elsif ($line =~ /^\t\{0x([0-9a-fA-F]{4}), *0x([0-9a-fA-F]{4}), *([^,]+), *"([^"]+)"\}/) { 60592ffb21SWarner Losh my $vendor_id = uc($1); 61592ffb21SWarner Losh my $device_id = uc($2); 62592ffb21SWarner Losh my $flags = $3; 63592ffb21SWarner Losh my $name = $4; 64592ffb21SWarner Losh 65592ffb21SWarner Losh $pciids{$current_vendor_define}{$device_id} = { 66592ffb21SWarner Losh 'vendor_id' => $vendor_id, 67592ffb21SWarner Losh 'flags' => $flags, 68592ffb21SWarner Losh 'name' => $name 69592ffb21SWarner Losh }; 70592ffb21SWarner Losh } 71592ffb21SWarner Losh } 72592ffb21SWarner Losh 73592ffb21SWarner Losh close($fh); 74592ffb21SWarner Losh 75592ffb21SWarner Losh return %pciids; 76592ffb21SWarner Losh} 77592ffb21SWarner Losh 78592ffb21SWarner Loshsub parse_pciids_db ($) { 79592ffb21SWarner Losh my ($header) = @_; 80592ffb21SWarner Losh 81592ffb21SWarner Losh open(my $fh, '<', $header) or die "Can't open PCI IDs database: $!\n"; 82592ffb21SWarner Losh 83592ffb21SWarner Losh my %pciids = (); 84592ffb21SWarner Losh 85592ffb21SWarner Losh my $current_vendor_id; 86592ffb21SWarner Losh 87592ffb21SWarner Losh while (my $line = <$fh>) { 88592ffb21SWarner Losh if (!$line || $line =~ /^#/) { 89592ffb21SWarner Losh next; 90592ffb21SWarner Losh } 91592ffb21SWarner Losh if ($line =~ /^([0-9a-fA-F]{4}) (.+)/) { 92592ffb21SWarner Losh # Vendor ID & name. 93592ffb21SWarner Losh my $vendor_id = uc($1); 94592ffb21SWarner Losh my $vendor_name = $2; 95592ffb21SWarner Losh $pciids{$vendor_id} = { 96592ffb21SWarner Losh 'name' => $vendor_name, 97592ffb21SWarner Losh 'devices' => {} 98592ffb21SWarner Losh }; 99592ffb21SWarner Losh 100592ffb21SWarner Losh $current_vendor_id = $vendor_id; 101592ffb21SWarner Losh } elsif ($line =~ /^\t([0-9a-fA-F]{4}) (.+)/) { 102592ffb21SWarner Losh # Device ID & name. 103592ffb21SWarner Losh my $device_id = uc($1); 104592ffb21SWarner Losh my $device_name = $2; 105592ffb21SWarner Losh $pciids{$current_vendor_id}{'devices'}{$device_id} = $device_name; 106592ffb21SWarner Losh } 107592ffb21SWarner Losh } 108592ffb21SWarner Losh 109592ffb21SWarner Losh close($fh); 110592ffb21SWarner Losh 111592ffb21SWarner Losh return %pciids; 112592ffb21SWarner Losh} 113592ffb21SWarner Losh 114592ffb21SWarner Loshif (scalar(@ARGV) != 3) { 115592ffb21SWarner Losh print STDERR "Syntax: $progname <linux_header> <freebsd_header> <pciids_db> [<vendor_define>]\n"; 116592ffb21SWarner Losh exit 1; 117592ffb21SWarner Losh} 118592ffb21SWarner Losh 119592ffb21SWarner Loshmy $linux_header = $ARGV[0]; 120592ffb21SWarner Loshmy $freebsd_header = $ARGV[1]; 121592ffb21SWarner Loshmy $pciids_db = $ARGV[2]; 122592ffb21SWarner Loshmy $only_vendor = $ARGV[3]; 123592ffb21SWarner Losh 124592ffb21SWarner Loshmy %linux_pciids = parse_linux_header($linux_header); 125592ffb21SWarner Loshmy %freebsd_pciids = parse_freebsd_header($freebsd_header); 126592ffb21SWarner Loshmy %pciids_db = parse_pciids_db($pciids_db); 127592ffb21SWarner Losh 128592ffb21SWarner Loshprint STDERR "Update FreeBSD's PCI IDs:\n"; 129592ffb21SWarner Loshforeach my $vendor_define (sort keys(%linux_pciids)) { 130592ffb21SWarner Losh if ($only_vendor && $vendor_define ne $only_vendor) { 131592ffb21SWarner Losh print STDERR "(skip unwanted define: $vendor_define)\n"; 132592ffb21SWarner Losh next; 133592ffb21SWarner Losh } elsif (!$only_vendor && !exists($freebsd_pciids{$vendor_define})) { 134592ffb21SWarner Losh print STDERR "(skip unsupport define: $vendor_define)\n"; 135592ffb21SWarner Losh next; 136592ffb21SWarner Losh } 137592ffb21SWarner Losh 138592ffb21SWarner Losh foreach my $device_id (sort keys(%{$linux_pciids{$vendor_define}})) { 139592ffb21SWarner Losh my $vendor_id = $linux_pciids{$vendor_define}{$device_id}{'vendor_id'}; 140592ffb21SWarner Losh 141592ffb21SWarner Losh if (exists($freebsd_pciids{$vendor_define}{$device_id})) { 142592ffb21SWarner Losh print STDERR " $vendor_define: $vendor_id:$device_id already in header\n"; 143592ffb21SWarner Losh next; 144592ffb21SWarner Losh } 145592ffb21SWarner Losh 146592ffb21SWarner Losh my $flags = $linux_pciids{$vendor_define}{$device_id}{'flags'}; 147592ffb21SWarner Losh my $name = $pciids_db{$vendor_id}{'devices'}{$device_id} || "Unknown device name"; 148592ffb21SWarner Losh print STDERR " $vendor_define: $vendor_id:$device_id is missing ($name)\n"; 149592ffb21SWarner Losh $freebsd_pciids{$vendor_define}{$device_id} = { 150592ffb21SWarner Losh 'vendor_id' => $vendor_id, 151592ffb21SWarner Losh 'flags' => $flags, 152592ffb21SWarner Losh 'name' => $name 153592ffb21SWarner Losh }; 154592ffb21SWarner Losh } 155592ffb21SWarner Losh} 156592ffb21SWarner Losh 157592ffb21SWarner Loshprint STDERR "\nWrite FreeBSD header to stdout...\n"; 158592ffb21SWarner Loshprint <<"EOF"; 159592ffb21SWarner Losh/* 160592ffb21SWarner Losh * Generated by $progname from: 161592ffb21SWarner Losh * o previous FreeBSD's drm_pciids.h 162592ffb21SWarner Losh * o Linux' drm_pciids.h 163592ffb21SWarner Losh * o the PCI ID repository (http://pciids.sourceforge.net/) 164592ffb21SWarner Losh * 165592ffb21SWarner Losh * See tools/tools/drm/$progname. 166592ffb21SWarner Losh */ 167592ffb21SWarner LoshEOF 168592ffb21SWarner Loshforeach my $vendor_define (sort keys(%freebsd_pciids)) { 169592ffb21SWarner Losh print "\n#define $vendor_define \\\n"; 170592ffb21SWarner Losh foreach my $device_id (sort keys(%{$freebsd_pciids{$vendor_define}})) { 171592ffb21SWarner Losh my $vendor_id = $freebsd_pciids{$vendor_define}{$device_id}{'vendor_id'}; 172592ffb21SWarner Losh my $flags = $freebsd_pciids{$vendor_define}{$device_id}{'flags'}; 173592ffb21SWarner Losh my $name = $freebsd_pciids{$vendor_define}{$device_id}{'name'}; 174592ffb21SWarner Losh 175592ffb21SWarner Losh print "\t{0x$vendor_id, 0x$device_id, $flags, \"$name\"}, \\\n"; 176592ffb21SWarner Losh } 177592ffb21SWarner Losh print "\t{0, 0, 0, NULL}\n"; 178592ffb21SWarner Losh} 179