389 lines
11 KiB
Perl
389 lines
11 KiB
Perl
#!/usr/bin/perl
|
|
|
|
# $XdotOrg$
|
|
|
|
# Automatically generate the data structures for PCI vendor/device lists
|
|
# from the pci.ids file.
|
|
#
|
|
# It should be run as:
|
|
#
|
|
# perl pciid2c.pl ../common/xf86PciInfo.h < pci.ids > xf86PciStdIds.h
|
|
#
|
|
#
|
|
# Copyright © 2002 by The XFree86 Project, Inc.
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
# copy of this software and associated documentation files (the "Software"),
|
|
# to deal in the Software without restriction, including without limitation
|
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
# and/or sell copies of the Software, and to permit persons to whom the
|
|
# Software is furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in
|
|
# all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
# OTHER DEALINGS IN THE SOFTWARE.
|
|
#
|
|
# Except as contained in this notice, the name of the copyright holder(s)
|
|
# and author(s) shall not be used in advertising or otherwise to promote
|
|
# the sale, use or other dealings in this Software without prior written
|
|
# authorization from the copyright holder(s) and author(s).
|
|
#
|
|
|
|
#
|
|
# Author: David Dawes
|
|
#
|
|
# $XFree86: xc/programs/Xserver/hw/xfree86/scanpci/pciid2c.pl,v 1.3 2003/08/24 17:37:10 dawes Exp $
|
|
#
|
|
|
|
if (@ARGV[0]) {
|
|
$infofile = @ARGV[0];
|
|
}
|
|
|
|
#
|
|
# The basic pci.ids format is:
|
|
# - Vendor lines start with four (lower case) hex digits
|
|
# - Device lines start with one tab followed by four hex digits
|
|
# - Subsystem lines start with two tabs followed by two sets of four
|
|
# hex digits.
|
|
# - Class overrides for devices start with two tabs followed by a "C",
|
|
# followed by four hex digits with the class/subclass value.
|
|
# - Class lines start with a "C".
|
|
# - Comment lines start with a '#'.
|
|
# - Blank lines are ignored.
|
|
#
|
|
# We allow for extra lines to be appended to modify existing entries or
|
|
# add new ones. To add/modify Device entries without modifying the
|
|
# Vendor name, a special vendor name of '"' is used (mnemonic: "ditto").
|
|
# Similarly for adding subsystem names without modifying (or adding)
|
|
# a corresponding device entry. To rename an existing entry, simply
|
|
# provide the new name. To remove an existing entry, use the special
|
|
# name '-'.
|
|
#
|
|
|
|
while (<STDIN>) {
|
|
# Process data lines
|
|
if (/^([0-9a-f]{4})\s+(.*)/) {
|
|
$vendor = $1;
|
|
if ($2 eq '-') {
|
|
delete($vendors{$vendor});
|
|
} elsif ($2 ne '"') {
|
|
$vendors{$vendor} = $2;
|
|
# Remove " characters
|
|
$vendors{$vendor} =~ s/"//g;
|
|
# Remove multiple "?" sequences to avoid trigraphs
|
|
$vendors{$vendor} =~ s/\?+/\?/g;
|
|
}
|
|
} elsif (/^\t([0-9a-f]{4})\s+(.*)/) {
|
|
$device = $1;
|
|
if ($2 eq '-') {
|
|
delete($devices{$vendor}{$device});
|
|
} elsif ($2 ne '"') {
|
|
$devices{$vendor}{$device} = $2;
|
|
# Remove " characters
|
|
$devices{$vendor}{$device} =~ s/"//g;
|
|
# Remove multiple "?" sequences to avoid trigraphs
|
|
$devices{$vendor}{$device} =~ s/\?+/\?/g;
|
|
}
|
|
} elsif (/^\t\t([0-9a-f]{4})\s+([0-9a-f]{4})\s+(.*)/) {
|
|
$v = $1;
|
|
$s = $2;
|
|
if ($3 eq '-') {
|
|
delete($subsystems{$v}{$s});
|
|
delete($devsubsystems{$vendor}{$device}{"$v-$s"});
|
|
} elsif ($3 ne '"') {
|
|
if ($subsystems{$v}{$s}) {
|
|
#print STDERR "Duplicate subsytem: $v, $s, \"$subsystems{$v}{$s}\", \"$3\"\n";
|
|
}
|
|
$subsystems{$v}{$s} = $3;
|
|
# Remove " characters
|
|
$subsystems{$v}{$s} =~ s/"//g;
|
|
# Remove multiple "?" sequences to avoid trigraphs
|
|
$subsystems{$v}{$s} =~ s/\?+/\?/g;
|
|
$devsubsystems{$vendor}{$device}{"$v-$s"} = $subsystems{$v}{$s};
|
|
}
|
|
} elsif (/^\t\tC\s+([0-9a-f]{4})/) {
|
|
$classes{$vendor}{$device} = $1;
|
|
}
|
|
# Ignore all other lines.
|
|
}
|
|
|
|
# Find which vendors are "video" vendors.
|
|
if ($infofile) {
|
|
open(INFO, "<$infofile") || die "Can't open $infofile";
|
|
while (<INFO>) {
|
|
if (/^#define\s+PCI_VENDOR_.*0x([0-9a-fA-F]{4})/) {
|
|
$vendor = $1;
|
|
$vendor =~ tr/A-F/a-f/;
|
|
$video{$vendor} = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# This layout is quite different from that used in the old xf86PciInfo.h
|
|
# file. One main difference is that the list is initialised at runtime.
|
|
# It's currently a flat list. This could be improved.
|
|
#
|
|
|
|
# Print out header information.
|
|
|
|
$proj = "XdotOrg";
|
|
print "
|
|
/*
|
|
* THIS FILE IS AUTOMATICALLY GENERATED -- DO NOT EDIT
|
|
*
|
|
* It is generated by pciid2c.pl using data from the following files:
|
|
*
|
|
* ../etc/pci.ids
|
|
* ../etc/extrapci.ids
|
|
* ../common/xf86PciInfo.h
|
|
*/
|
|
|
|
/*
|
|
* Copyright © 2002 by the XFree86 Project, Inc.
|
|
*
|
|
* The pci.ids file and the data it contains are from the Linux PCI ID's
|
|
* Project (http://pciids.sf.net/). It is maintained by Martin Mares
|
|
* <mj\@ucw.cz> and other volunteers. The pci.ids file is licensed under
|
|
* the BSD 3-clause or GPL version 2 or later licenses.
|
|
*/
|
|
|
|
#include \"xf86PciInfo.h\"
|
|
#ifndef NULL
|
|
#define NULL (void *)0
|
|
#endif
|
|
|
|
";
|
|
|
|
# The following #ifdefs are used:
|
|
# - INIT_SUBSYS_INFO -- initialise subsystem data
|
|
# - INIT_VENDOR_SUBSYS_INFO -- initialise a vendor<->subsystem table.
|
|
# - VENDOR_INCLUDE_NONVIDEO -- include data for non-video vendors.
|
|
|
|
# Define static variables with all of the strings.
|
|
|
|
foreach $vendor (sort keys %vendors) {
|
|
if ($infofile && !$video{$vendor}) {
|
|
print "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
|
|
}
|
|
print "static const char pci_vendor_${vendor}[] = \"$vendors{$vendor}\";\n";
|
|
foreach $device (sort keys %{$devices{$vendor}}) {
|
|
print "static const char pci_device_${vendor}_${device}[] = " .
|
|
"\"$devices{$vendor}{$device}\";\n";
|
|
foreach $subsys (sort keys %{$devsubsystems{$vendor}{$device}}) {
|
|
$s = $subsys;
|
|
($v) = split /-/, $s;
|
|
if ($infofile && !$video{$vendor} && $video{$v}) {
|
|
print "#endif\n";
|
|
}
|
|
$s =~ s/-/_/;
|
|
print "#ifdef INIT_SUBSYS_INFO\n";
|
|
print "static const char pci_subsys_${vendor}_${device}_${s}[] = " .
|
|
"\"$devsubsystems{$vendor}{$device}{$subsys}\";\n";
|
|
print "#endif\n";
|
|
if ($infofile && !$video{$vendor} && $video{$v}) {
|
|
print "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
|
|
}
|
|
}
|
|
}
|
|
if ($infofile && !$video{$vendor}) {
|
|
print "#endif\n";
|
|
}
|
|
}
|
|
|
|
|
|
# Pre-initialise the table structures (from the inner to the outer).
|
|
|
|
# First, the subsys structures.
|
|
|
|
print "#ifdef INIT_SUBSYS_INFO\n";
|
|
foreach $vendor (sort keys %vendors) {
|
|
if ($infofile && !$video{$vendor}) {
|
|
$pre = "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
|
|
} else {
|
|
undef($pre);
|
|
undef($post);
|
|
}
|
|
foreach $device (sort keys %{$devices{$vendor}}) {
|
|
foreach $subsys (sort keys %{$devsubsystems{$vendor}{$device}}) {
|
|
$s = $subsys;
|
|
$s =~ tr/-/_/;
|
|
($vid, $sid) = split /_/, $s;
|
|
if ($pre) {
|
|
print $pre;
|
|
undef($pre);
|
|
$post = "#endif\n";
|
|
}
|
|
if ($infofile && !$video{$vendor} && $video{$vid}) {
|
|
print "#endif\n";
|
|
}
|
|
print "static const pciSubsystemInfo " .
|
|
"pci_ss_info_${vendor}_${device}_$s =\n";
|
|
print "\t{0x$vid, 0x$sid, pci_subsys_${vendor}_${device}_$s, 0};\n";
|
|
print "#undef pci_ss_info_$s\n";
|
|
print "#define pci_ss_info_$s pci_ss_info_${vendor}_${device}_$s\n";
|
|
if ($infofile && !$video{$vendor} && $video{$vid}) {
|
|
print "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
|
|
}
|
|
}
|
|
}
|
|
if ($post) {
|
|
print $post;
|
|
undef($post);
|
|
}
|
|
}
|
|
|
|
# Next, the list of per vendor+device subsystem arrays
|
|
|
|
foreach $vendor (sort keys %vendors) {
|
|
if ($infofile && !$video{$vendor}) {
|
|
$pre = "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
|
|
} else {
|
|
undef($pre);
|
|
undef($post);
|
|
}
|
|
foreach $device (sort keys %{$devices{$vendor}}) {
|
|
if (scalar(keys %{$devsubsystems{$vendor}{$device}}) > 0) {
|
|
if ($pre) {
|
|
print $pre;
|
|
undef($pre);
|
|
$post = "#endif\n";
|
|
}
|
|
print "static const pciSubsystemInfo *pci_ss_list_${vendor}_${device}[] = {\n";
|
|
foreach $sub (sort keys %{$devsubsystems{$vendor}{$device}}) {
|
|
$sub =~ s/-/_/;
|
|
print "\t&pci_ss_info_${vendor}_${device}_${sub},\n";
|
|
}
|
|
print "\tNULL\n};\n";
|
|
} else {
|
|
print "#define pci_ss_list_${vendor}_${device} NULL\n";
|
|
}
|
|
}
|
|
if ($post) {
|
|
print $post;
|
|
undef($post);
|
|
}
|
|
}
|
|
|
|
# Next, the list of per vendor subsystem arrays
|
|
|
|
print "#ifdef INIT_VENDOR_SUBSYS_INFO\n";
|
|
foreach $vendor (sort keys %vendors) {
|
|
if (scalar(keys %{$subsystems{$vendor}}) > 0) {
|
|
if ($infofile && !$video{$vendor}) {
|
|
print "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
|
|
}
|
|
print "static const pciSubsystemInfo *pci_ss_list_${vendor}[] = {\n";
|
|
foreach $sub (sort keys %{$subsystems{$vendor}}) {
|
|
print "\t&pci_ss_info_${vendor}_${sub},\n";
|
|
}
|
|
print "\tNULL\n};\n";
|
|
if ($infofile && !$video{$vendor}) {
|
|
print "#endif\n";
|
|
}
|
|
} else {
|
|
print "#define pci_ss_list_${vendor} NULL\n";
|
|
}
|
|
}
|
|
print "#endif /* INIT_VENDOR_SUBSYS_INFO */\n";
|
|
print "#endif /* INIT_SUBSYS_INFO */\n";
|
|
|
|
# Next the device structures
|
|
|
|
foreach $vendor (sort keys %vendors) {
|
|
if ($infofile && !$video{$vendor}) {
|
|
$pre = "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
|
|
} else {
|
|
undef($pre);
|
|
undef($post);
|
|
}
|
|
foreach $device (sort keys %{$devices{$vendor}}) {
|
|
if ($pre) {
|
|
print $pre;
|
|
undef($pre);
|
|
$post = "#endif\n";
|
|
}
|
|
if ($classes{$vendor}{$device}) {
|
|
$class = "0x$classes{$vendor}{$device}";
|
|
} else {
|
|
$class = "0";
|
|
}
|
|
print "static const pciDeviceInfo " .
|
|
"pci_dev_info_${vendor}_${device} = {\n";
|
|
print "\t0x$device, pci_device_${vendor}_${device},\n";
|
|
print "#ifdef INIT_SUBSYS_INFO\n";
|
|
print "\tpci_ss_list_${vendor}_${device},\n";
|
|
print "#else\n";
|
|
print "\tNULL,\n";
|
|
print "#endif\n";
|
|
print "\t$class\n};\n";
|
|
}
|
|
if ($post) {
|
|
print $post;
|
|
undef($post);
|
|
}
|
|
}
|
|
|
|
# Next, the list of per vendor device arrays
|
|
|
|
foreach $vendor (sort keys %vendors) {
|
|
if (scalar(keys %{$devices{$vendor}}) > 0) {
|
|
if ($infofile && !$video{$vendor}) {
|
|
print "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
|
|
}
|
|
print "static const pciDeviceInfo *pci_dev_list_${vendor}[] = {\n";
|
|
foreach $device (sort keys %{$devices{$vendor}}) {
|
|
print "\t&pci_dev_info_${vendor}_${device},\n";
|
|
}
|
|
print "\tNULL\n};\n";
|
|
if ($infofile && !$video{$vendor}) {
|
|
print "#endif\n";
|
|
}
|
|
} else {
|
|
print "#define pci_dev_list_${vendor} NULL\n";
|
|
}
|
|
}
|
|
|
|
# Next, the main vendor list
|
|
|
|
print "
|
|
static const pciVendorInfo pciVendorInfoList[] = {
|
|
";
|
|
|
|
foreach $vendor (sort keys %vendors) {
|
|
if ($infofile && !$video{$vendor}) {
|
|
print "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
|
|
}
|
|
print "\t{0x$vendor, pci_vendor_$vendor, pci_dev_list_$vendor},\n";
|
|
if ($infofile && !$video{$vendor}) {
|
|
print "#endif\n";
|
|
}
|
|
}
|
|
print "\t{0x0000, NULL, NULL}\n};\n";
|
|
|
|
# Finally, the main vendor/subsystem list
|
|
|
|
print "
|
|
#if defined(INIT_VENDOR_SUBSYS_INFO) && defined(INIT_SUBSYS_INFO)
|
|
static const pciVendorSubsysInfo pciVendorSubsysInfoList[] = {
|
|
";
|
|
|
|
foreach $vendor (sort keys %vendors) {
|
|
if ($infofile && !$video{$vendor}) {
|
|
print "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
|
|
}
|
|
print "\t{0x$vendor, pci_vendor_$vendor, pci_ss_list_$vendor},\n";
|
|
if ($infofile && !$video{$vendor}) {
|
|
print "#endif\n";
|
|
}
|
|
}
|
|
print "\t{0x0000, NULL, NULL}\n};\n";
|
|
print "#endif\n";
|