]> mj.ucw.cz Git - pciutils.git/commitdiff
Beginning of the history.
authorMartin Mares <mj@ucw.cz>
Fri, 5 May 2006 12:03:58 +0000 (14:03 +0200)
committerMartin Mares <mj@ucw.cz>
Fri, 5 May 2006 12:03:58 +0000 (14:03 +0200)
Makefile [new file with mode: 0644]
lspci.c [new file with mode: 0644]
names.c [new file with mode: 0644]
pci.ids [new file with mode: 0644]
pciutils.h [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..3960efb
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,22 @@
+# $Id: Makefile,v 1.1 1997/12/23 10:29:18 mj Exp $
+# Makefile for Linux PCI Utilities
+# (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+
+OPT=-O2 -m486 -malign-loops=0 -malign-jumps=0 -malign-functions=2 -fno-strength-reduce
+#-fomit-frame-pointer
+#LOPT=-s
+#DEBUG=-ggdb
+#LDEBUG=-lefence
+CFLAGS=$(OPT) $(DEBUG) -Wall -W -Wno-parentheses -Wstrict-prototypes -Wno-unused -Werror
+LDFLAGS=$(LOPT) $(LDEBUG)
+
+all: lspci
+
+lspci: lspci.o names.o
+
+lspci.o: lspci.c pciutils.h
+names.o: names.c pciutils.h
+
+clean:
+       rm -f `find . -name "*~" -or -name "*.[oa]" -or -name "\#*\#" -or -name TAGS -or -name core`
+       rm -f lspci
diff --git a/lspci.c b/lspci.c
new file mode 100644 (file)
index 0000000..c2a986d
--- /dev/null
+++ b/lspci.c
@@ -0,0 +1,630 @@
+/*
+ *     $Id: lspci.c,v 1.1 1997/12/23 10:29:18 mj Exp $
+ *
+ *     Linux PCI Utilities -- List All PCI Devices
+ *
+ *     Copyright (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *
+ *     Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <linux/pci.h>
+
+#include "pciutils.h"
+
+/* Options */
+
+static int verbose;                    /* Show detailed information */
+static int buscentric_view;            /* Show bus addresses/IRQ's instead of CPU-visible ones */
+static int show_hex;                   /* Show contents of config space as hexadecimal numbers */
+static int bus_filter = -1;            /* Bus, slot, function, vendor and device ID filtering */
+static int slot_filter = -1;
+static int func_filter = -1;
+static int vend_filter = -1;
+static int dev_filter = -1;
+
+static char options[] = "nvbxB:S:F:V:D:";
+
+static char help_msg[] = "\
+Usage: lspci [<switches>]\n\
+\n\
+-v\tBe verbose\n\
+-n\tShow numeric ID's\n\
+-b\tBus-centric view (PCI addresses and IRQ's instead of those seen by the CPU)\n\
+-x\tShow hex-dump of config space (-xx shows full 256 bytes)\n\
+-B <bus>, -S <slot>, -F <func>, -V <vendor>, -D <device>  Show only selected devices\n\
+";
+
+/* Our view of the PCI bus */
+
+struct device {
+  struct device *next;
+  byte bus, devfn;
+  word vendid, devid;
+  unsigned int kernel_irq;
+  unsigned long kernel_base_addr[6];
+  byte config[256];
+};
+
+static struct device *first_dev, **last_dev = &first_dev;
+
+/* Miscellaneous routines */
+
+void *
+xmalloc(unsigned int howmuch)
+{
+  void *p = malloc(howmuch);
+  if (!p)
+    {
+      fprintf(stderr, "lspci: Unable to allocate %d bytes of memory\n", howmuch);
+      exit(1);
+    }
+  return p;
+}
+
+/* Filtering */
+
+static inline int
+filter_out(struct device *d)
+{
+  return (bus_filter >= 0 && d->bus != bus_filter ||
+         slot_filter >= 0 && PCI_SLOT(d->devfn) != slot_filter ||
+         func_filter >= 0 && PCI_FUNC(d->devfn) != func_filter ||
+         vend_filter >= 0 && d->vendid != vend_filter ||
+         dev_filter >= 0 && d->devid != dev_filter);
+}
+
+/* Interface for /proc/bus/pci */
+
+static void
+scan_dev_list(void)
+{
+  FILE *f;
+  byte line[256];
+
+  if (! (f = fopen(PROC_BUS_PCI "/devices", "r")))
+    {
+      perror("Unable to open " PROC_BUS_PCI "/devices");
+      exit(1);
+    }
+  while (fgets(line, sizeof(line), f))
+    {
+      struct device *d = xmalloc(sizeof(struct device));
+      unsigned int dfn, vend;
+
+      sscanf(line, "%x %x %x %lx %lx %lx %lx %lx %lx",
+            &dfn,
+            &vend,
+            &d->kernel_irq,
+            &d->kernel_base_addr[0],
+            &d->kernel_base_addr[1],
+            &d->kernel_base_addr[2],
+            &d->kernel_base_addr[3],
+            &d->kernel_base_addr[4],
+            &d->kernel_base_addr[5]);
+      d->bus = dfn >> 8U;
+      d->devfn = dfn & 0xff;
+      d->vendid = vend >> 16U;
+      d->devid = vend & 0xffff;
+      if (!filter_out(d))
+       {
+         *last_dev = d;
+         last_dev = &d->next;
+         d->next = NULL;
+       }
+    }
+  fclose(f);
+}
+
+static inline void
+make_proc_pci_name(struct device *d, char *p)
+{
+  sprintf(p, PROC_BUS_PCI "/%02x/%02x.%x",
+         d->bus, PCI_SLOT(d->devfn), PCI_FUNC(d->devfn));
+}
+
+static void
+scan_config(void)
+{
+  struct device *d;
+  char name[64];
+  int fd;
+  int how_much = (show_hex > 1) ? 256 : 64;
+
+  for(d=first_dev; d; d=d->next)
+    {
+      make_proc_pci_name(d, name);
+      if ((fd = open(name, O_RDONLY)) < 0)
+       {
+         fprintf(stderr, "lspci: Unable to open %s: %m\n", name);
+         exit(1);
+       }
+      if (read(fd, d->config, how_much) != how_much)
+       {
+         fprintf(stderr, "lspci: Error reading %s: %m\n", name);
+         exit(1);
+       }
+      close(fd);
+    }
+}
+
+static void
+scan_proc(void)
+{
+  scan_dev_list();
+  scan_config();
+}
+
+/* Config space accesses */
+
+static inline byte
+get_conf_byte(struct device *d, unsigned int pos)
+{
+  return d->config[pos];
+}
+
+static word
+get_conf_word(struct device *d, unsigned int pos)
+{
+  return d->config[pos] | (d->config[pos+1] << 8);
+}
+
+static u32
+get_conf_long(struct device *d, unsigned int pos)
+{
+  return d->config[pos] |
+    (d->config[pos+1] << 8) |
+    (d->config[pos+2] << 16) |
+    (d->config[pos+3] << 24);
+}
+
+/* Sorting */
+
+static int
+compare_them(const void *A, const void *B)
+{
+  const struct device *a = *(const struct device **)A;
+  const struct device *b = *(const struct device **)B;
+
+  if (a->bus < b->bus)
+    return -1;
+  if (a->bus > b->bus)
+    return 1;
+  if (a->devfn < b->devfn)
+    return -1;
+  if (a->devfn > b->devfn)
+    return 1;
+  return 0;
+}
+
+static void
+sort_them(void)
+{
+  struct device **index, **h;
+  int cnt;
+  struct device *d;
+
+  cnt = 0;
+  for(d=first_dev; d; d=d->next)
+    cnt++;
+  h = index = alloca(sizeof(struct device *) * cnt);
+  for(d=first_dev; d; d=d->next)
+    *h++ = d;
+  qsort(index, cnt, sizeof(struct device *), compare_them);
+  last_dev = &first_dev;
+  h = index;
+  while (cnt--)
+    {
+      *last_dev = *h;
+      last_dev = &(*h)->next;
+      h++;
+    }
+  *last_dev = NULL;
+}
+
+/* Output */
+
+static void
+show_terse(struct device *d)
+{
+  int c;
+
+  printf("%02x:%02x.%x %s: %s",
+        d->bus,
+        PCI_SLOT(d->devfn),
+        PCI_FUNC(d->devfn),
+        lookup_class(get_conf_word(d, PCI_CLASS_DEVICE)),
+        lookup_device_full(d->vendid, d->devid));
+  if (c = get_conf_byte(d, PCI_REVISION_ID))
+    printf(" (rev %02x)", c);
+  if (verbose && (c = get_conf_byte(d, PCI_CLASS_PROG)))
+    printf(" (prog-if %02x)", c);
+  putchar('\n');
+}
+
+static void
+show_bases(struct device *d, int cnt)
+{
+  word cmd = get_conf_word(d, PCI_COMMAND);
+  int i;
+
+  for(i=0; i<6; i++)
+    {
+      unsigned long pos;
+      unsigned int flg = get_conf_long(d, PCI_BASE_ADDRESS_0 + 4*i);
+      if (buscentric_view)
+       pos = flg;
+      else
+       pos = d->kernel_base_addr[i];
+      if (!pos || pos == 0xffffffff)
+       continue;
+      if (verbose > 1)
+       printf("\tRegion %d: ", i);
+      else
+       putchar('\t');
+      if (flg & PCI_BASE_ADDRESS_SPACE_IO)
+       printf("I/O ports at %04lx%s\n",
+              pos & PCI_BASE_ADDRESS_IO_MASK,
+              (cmd & PCI_COMMAND_IO) ? "" : " [disabled]");
+      else
+       {
+         int t = flg & PCI_BASE_ADDRESS_MEM_TYPE_MASK;
+         printf("Memory at ");
+         if (t == PCI_BASE_ADDRESS_MEM_TYPE_64)
+           {
+             if (i < cnt - 1)
+               {
+                 i++;
+                 if (!buscentric_view)
+                   printf("%08x", get_conf_long(d, PCI_BASE_ADDRESS_0 + 4*i));
+               }
+             else
+               printf("????????");
+           }
+         printf("%08lx (%s, %sprefetchable)%s\n",
+                pos & PCI_BASE_ADDRESS_MEM_MASK,
+                (t == PCI_BASE_ADDRESS_MEM_TYPE_32) ? "32-bit" :
+                (t == PCI_BASE_ADDRESS_MEM_TYPE_64) ? "64-bit" :
+                (t == PCI_BASE_ADDRESS_MEM_TYPE_1M) ? "low-1M 32-bit" : "???",
+                (flg & PCI_BASE_ADDRESS_MEM_PREFETCH) ? "" : "non-",
+                (cmd & PCI_COMMAND_MEMORY) ? "" : " [disabled]");
+       }
+    }
+}
+
+static void
+show_htype0(struct device *d)
+{
+  u32 rom = get_conf_long(d, PCI_ROM_ADDRESS);
+
+  show_bases(d, 6);
+
+  if (rom & 1)
+    {
+      word cmd = get_conf_word(d, PCI_COMMAND);
+      printf("\tExpansion ROM at %08x%s\n", rom & ~0xfff,
+            (cmd & PCI_COMMAND_MEMORY) ? "" : " [disabled]");
+    }
+}
+
+static void
+show_htype1(struct device *d)
+{
+  u32 io_base = get_conf_byte(d, PCI_IO_BASE);
+  u32 io_limit = get_conf_byte(d, PCI_IO_LIMIT);
+  u32 io_type = io_base & PCI_IO_RANGE_TYPE_MASK;
+  u32 mem_base = get_conf_word(d, PCI_MEMORY_BASE);
+  u32 mem_limit = get_conf_word(d, PCI_MEMORY_LIMIT);
+  u32 mem_type = mem_base & PCI_MEMORY_RANGE_TYPE_MASK;
+  u32 pref_base = get_conf_word(d, PCI_PREF_MEMORY_BASE);
+  u32 pref_limit = get_conf_word(d, PCI_PREF_MEMORY_LIMIT);
+  u32 pref_type = pref_base & PCI_PREF_RANGE_TYPE_MASK;
+  u32 rom = get_conf_long(d, PCI_ROM_ADDRESS1);
+  word brc = get_conf_word(d, PCI_BRIDGE_CONTROL);
+
+  show_bases(d, 2);
+  printf("\tBus: primary=%02x, secondary=%02x, subordinate=%02x, sec-latency=%d\n",
+        get_conf_byte(d, PCI_PRIMARY_BUS),
+        get_conf_byte(d, PCI_SECONDARY_BUS),
+        get_conf_byte(d, PCI_SUBORDINATE_BUS),
+        get_conf_byte(d, PCI_SEC_LATENCY_TIMER));
+
+  if (io_type != (io_limit & PCI_IO_RANGE_TYPE_MASK) ||
+      (io_type != PCI_IO_RANGE_TYPE_16 && io_type != PCI_IO_RANGE_TYPE_32))
+    printf("\t!!! Unknown I/O range types %x/%x\n", io_base, io_limit);
+  else
+    {
+      io_base = (io_base & PCI_IO_RANGE_MASK) << 8;
+      io_limit = (io_limit & PCI_IO_RANGE_MASK) << 8;
+      if (io_type == PCI_IO_RANGE_TYPE_32)
+       {
+         io_base |= (get_conf_word(d, PCI_IO_BASE_UPPER16) << 16);
+         io_limit |= (get_conf_word(d, PCI_IO_LIMIT_UPPER16) << 16);
+       }
+      if (io_base)
+       printf("\tI/O behind bridge: %08x-%08x\n", io_base, io_limit+0xfff);
+    }
+
+  if (mem_type != (mem_limit & PCI_MEMORY_RANGE_TYPE_MASK) ||
+      mem_type)
+    printf("\t!!! Unknown memory range types %x/%x\n", mem_base, mem_limit);
+  else if (mem_base)
+    {
+      mem_base = (mem_base & PCI_MEMORY_RANGE_MASK) << 16;
+      mem_limit = (mem_limit & PCI_MEMORY_RANGE_MASK) << 16;
+      printf("\tMemory behind bridge: %08x-%08x\n", mem_base, mem_limit + 0xfffff);
+    }
+
+  if (pref_type != (pref_limit & PCI_PREF_RANGE_TYPE_MASK) ||
+      (pref_type != PCI_PREF_RANGE_TYPE_32 && pref_type != PCI_PREF_RANGE_TYPE_64))
+    printf("\t!!! Unknown prefetchable memory range types %x/%x\n", pref_base, pref_limit);
+  else if (pref_base)
+    {
+      pref_base = (pref_base & PCI_PREF_RANGE_MASK) << 16;
+      pref_limit = (pref_limit & PCI_PREF_RANGE_MASK) << 16;
+      if (pref_type == PCI_PREF_RANGE_TYPE_32)
+       printf("\tPrefetchable memory behind bridge: %08x-%08x\n", pref_base, pref_limit);
+      else
+       printf("\tPrefetchable memory behind bridge: %08x%08x-%08x%08x\n",
+              get_conf_long(d, PCI_PREF_BASE_UPPER32),
+              pref_base,
+              get_conf_long(d, PCI_PREF_LIMIT_UPPER32),
+              pref_limit);
+    }
+
+  if (get_conf_word(d, PCI_SEC_STATUS) & PCI_STATUS_SIG_SYSTEM_ERROR)
+    printf("\tSecondary status: SERR\n");
+
+  if (rom & 1)
+    {
+      word cmd = get_conf_word(d, PCI_COMMAND);
+      printf("\tExpansion ROM at %08x%s\n", rom & ~0xfff,
+            (cmd & PCI_COMMAND_MEMORY) ? "" : " [disabled]");
+    }
+
+  if (verbose > 1)
+    printf("\tBridgeCtl: Parity%c SERR%c NoISA%c VGA%c MAbort%c >Reset%c FastB2B%c\n",
+          (brc & PCI_BRIDGE_CTL_PARITY) ? '+' : '-',
+          (brc & PCI_BRIDGE_CTL_SERR) ? '+' : '-',
+          (brc & PCI_BRIDGE_CTL_NO_ISA) ? '+' : '-',
+          (brc & PCI_BRIDGE_CTL_VGA) ? '+' : '-',
+          (brc & PCI_BRIDGE_CTL_MASTER_ABORT) ? '+' : '-',
+          (brc & PCI_BRIDGE_CTL_BUS_RESET) ? '+' : '-',
+          (brc & PCI_BRIDGE_CTL_FAST_BACK) ? '+' : '-');
+}
+
+static void
+show_verbose(struct device *d)
+{
+  word status = get_conf_word(d, PCI_STATUS);
+  word cmd = get_conf_word(d, PCI_COMMAND);
+  word class = get_conf_word(d, PCI_CLASS_DEVICE);
+  byte bist = get_conf_byte(d, PCI_BIST);
+  byte htype = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f;
+  byte latency = get_conf_byte(d, PCI_LATENCY_TIMER);
+  byte cache_line = get_conf_byte(d, PCI_CACHE_LINE_SIZE);
+  byte max_lat, min_gnt;
+  byte int_pin = get_conf_byte(d, PCI_INTERRUPT_PIN);
+  byte int_line = get_conf_byte(d, PCI_INTERRUPT_LINE);
+  unsigned int irq, ex_htype;
+  word subsys_v, subsys_d;
+
+  show_terse(d);
+
+  switch (class)
+    {
+    case PCI_CLASS_BRIDGE_PCI:
+      ex_htype = 1;
+      break;
+    default:
+      ex_htype = 0;
+    }
+  if (ex_htype != htype)
+    {
+      printf("\t!!! Header type %02x doesn't match class code %04x\n", htype, class);
+      return;
+    }
+
+  switch (htype)
+    {
+    case 0:
+      max_lat = get_conf_byte(d, PCI_MAX_LAT);
+      min_gnt = get_conf_byte(d, PCI_MIN_GNT);
+      subsys_v = get_conf_word(d, PCI_SUBSYSTEM_VENDOR_ID);
+      subsys_d = get_conf_word(d, PCI_SUBSYSTEM_ID);
+      break;
+    case 1:
+      irq = int_line = int_pin = min_gnt = max_lat = 0;
+      subsys_v = subsys_d = 0;
+      break;
+    default:
+      printf("\t!!! Unknown header type %02x\n", htype);
+      return;
+    }
+
+  if (buscentric_view)
+    irq = int_line;
+  else
+    irq = d->kernel_irq;
+
+  if (verbose > 1)
+    {
+      if (subsys_v)
+       printf("\tSubsystem ID: %04x:%04x\n", subsys_v, subsys_d);
+      printf("\tControl: I/O%c Mem%c BusMaster%c SpecCycle%c MemWINV%c VGASnoop%c ParErr%c Stepping%c SERR%c FastB2B%c\n",
+            (cmd & PCI_COMMAND_IO) ? '+' : '-',
+            (cmd & PCI_COMMAND_MEMORY) ? '+' : '-',
+            (cmd & PCI_COMMAND_MASTER) ? '+' : '-',
+            (cmd & PCI_COMMAND_SPECIAL) ? '+' : '-',
+            (cmd & PCI_COMMAND_INVALIDATE) ? '+' : '-',
+            (cmd & PCI_COMMAND_VGA_PALETTE) ? '+' : '-',
+            (cmd & PCI_COMMAND_PARITY) ? '+' : '-',
+            (cmd & PCI_COMMAND_WAIT) ? '+' : '-',
+            (cmd & PCI_COMMAND_SERR) ? '+' : '-',
+            (cmd & PCI_COMMAND_FAST_BACK) ? '+' : '-');
+      printf("\tStatus: 66Mhz%c UDF%c FastB2B%c ParErr%c DEVSEL=%s >TAbort%c <TAbort%c <MAbort%c >SERR%c <PERR%c\n",
+            (status & PCI_STATUS_66MHZ) ? '+' : '-',
+            (status & PCI_STATUS_UDF) ? '+' : '-',
+            (status & PCI_STATUS_FAST_BACK) ? '+' : '-',
+            (status & PCI_STATUS_PARITY) ? '+' : '-',
+            ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_SLOW) ? "slow" :
+            ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_MEDIUM) ? "medium" :
+            ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_FAST) ? "fast" : "??",
+            (status & PCI_STATUS_SIG_TARGET_ABORT) ? '+' : '-',
+            (status & PCI_STATUS_REC_TARGET_ABORT) ? '+' : '-',
+            (status & PCI_STATUS_REC_MASTER_ABORT) ? '+' : '-',
+            (status & PCI_STATUS_SIG_SYSTEM_ERROR) ? '+' : '-',
+            (status & PCI_STATUS_DETECTED_PARITY) ? '+' : '-');
+      if (cmd & PCI_COMMAND_MASTER)
+       {
+         printf("\tLatency: ");
+         if (min_gnt)
+           printf("%d min, ", min_gnt);
+         if (max_lat)
+           printf("%d max, ", max_lat);
+         printf("%d set", latency);
+         if (cache_line)
+           printf(", cache line size %02x", cache_line);
+         putchar('\n');
+       }
+      if (int_pin)
+       printf("\tInterrupt: pin %c routed to IRQ %d\n", 'A' + int_pin - 1, irq);
+    }
+  else
+    {
+      printf("\tFlags: ");
+      if (cmd & PCI_COMMAND_MASTER)
+       printf("bus master, ");
+      if (cmd & PCI_COMMAND_VGA_PALETTE)
+       printf("VGA palette snoop, ");
+      if (cmd & PCI_COMMAND_WAIT)
+       printf("stepping, ");
+      if (cmd & PCI_COMMAND_FAST_BACK)
+       printf("fast Back2Back, ");
+      if (status & PCI_STATUS_66MHZ)
+       printf("66Mhz, ");
+      if (status & PCI_STATUS_UDF)
+       printf("user-definable features, ");
+      printf("%s devsel",
+            ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_SLOW) ? "slow" :
+            ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_MEDIUM) ? "medium" :
+            ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_FAST) ? "fast" : "??");
+      if (cmd & PCI_COMMAND_MASTER)
+       printf(", latency %d", latency);
+      if (int_pin)
+       if (d->kernel_irq)
+         printf(", IRQ %d", irq);
+       else
+         printf(", IRQ ?");
+      putchar('\n');
+    }
+
+  if (bist & PCI_BIST_CAPABLE)
+    {
+      if (bist & PCI_BIST_START)
+       printf("\tBIST is running\n");
+      else
+       printf("\tBIST result: %02x\n", bist & PCI_BIST_CODE_MASK);
+    }
+
+  switch (htype)
+    {
+    case 0:
+      show_htype0(d);
+      break;
+    case 1:
+      show_htype1(d);
+      break;
+    }
+}
+
+static void
+show_hex_dump(struct device *d)
+{
+  int i;
+  int limit = (show_hex > 1) ? 256 : 64;
+
+  for(i=0; i<limit; i++)
+    {
+      if (! (i & 15))
+       printf("%02x:", i);
+      printf(" %02x", get_conf_byte(d, i));
+      if ((i & 15) == 15)
+       putchar('\n');
+    }
+}
+
+static void
+show(void)
+{
+  struct device *d;
+
+  for(d=first_dev; d; d=d->next)
+    {
+      if (verbose)
+       show_verbose(d);
+      else
+       show_terse(d);
+      if (show_hex)
+       show_hex_dump(d);
+      if (verbose || show_hex)
+       putchar('\n');
+    }
+}
+
+/* Main */
+
+int
+main(int argc, char **argv)
+{
+  int i;
+
+  while ((i = getopt(argc, argv, options)) != -1)
+    switch (i)
+      {
+      case 'n':
+       show_numeric_ids = 1;
+       break;
+      case 'v':
+       verbose++;
+       break;
+      case 'b':
+       buscentric_view = 1;
+       break;
+      case 'B':
+       bus_filter = strtol(optarg, NULL, 16);
+       break;
+      case 'S':
+       slot_filter = strtol(optarg, NULL, 16);
+       break;
+      case 'F':
+       func_filter = strtol(optarg, NULL, 16);
+       break;
+      case 'V':
+       vend_filter = strtol(optarg, NULL, 16);
+       break;
+      case 'D':
+       dev_filter = strtol(optarg, NULL, 16);
+       break;
+      case 'x':
+       show_hex++;
+       break;
+      default:
+      bad:
+       fprintf(stderr, help_msg);
+       return 1;
+      }
+  if (optind < argc)
+    goto bad;
+
+  scan_proc();
+  sort_them();
+  show();
+
+  return 0;
+}
diff --git a/names.c b/names.c
new file mode 100644 (file)
index 0000000..485050f
--- /dev/null
+++ b/names.c
@@ -0,0 +1,282 @@
+/*
+ *     $Id: names.c,v 1.1 1997/12/23 10:29:18 mj Exp $
+ *
+ *     Linux PCI Utilities -- Device ID to Name Translation
+ *
+ *     Copyright (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *
+ *     Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <linux/pci.h>
+
+#include "pciutils.h"
+
+int show_numeric_ids;
+
+static byte *name_list;
+static int name_list_loaded;
+
+struct nl_entry {
+  struct nl_entry *next;
+  int id1, id2;
+  byte *name;
+};
+
+#define ID1_VENDOR -1
+#define ID1_CLASS -2
+#define ID1_SUBCLASS -3
+#define ID1_ERROR -4
+
+#define HASH_SIZE 1024
+
+static struct nl_entry *nl_hash[HASH_SIZE];
+
+static inline unsigned int nl_calc_hash(int id1, int id2)
+{
+  unsigned int h;
+
+  h = id1 ^ id2;
+  h ^= (h >> 6);
+  return h & (HASH_SIZE-1);
+}
+
+static struct nl_entry *nl_lookup(int id1, int id2)
+{
+  unsigned int h = nl_calc_hash(id1, id2);
+  struct nl_entry *n = nl_hash[h];
+
+  while (n && (n->id1 != id1 || n->id2 != id2))
+    n = n->next;
+  return n;
+}
+
+static int nl_add(int id1, int id2, byte *text)
+{
+  unsigned int h = nl_calc_hash(id1, id2);
+  struct nl_entry *n = nl_hash[h];
+
+  while (n && (n->id1 != id1 || n->id2 != id2))
+    n = n->next;
+  if (n)
+    return 1;
+  n = xmalloc(sizeof(struct nl_entry));
+  n->id1 = id1;
+  n->id2 = id2;
+  n->name = text;
+  n->next = nl_hash[h];
+  nl_hash[h] = n;
+  return 0;
+}
+
+static void
+err_name_list(char *msg)
+{
+  fprintf(stderr, ETC_PCI_IDS ": %s: %m\n", msg);
+  exit(1);
+}
+
+static void
+parse_name_list(void)
+{
+  byte *p = name_list;
+  byte *q, *r, *s;
+  int lino = 0;
+  int id1 = ID1_ERROR;
+  int id2 = 0;
+  int i, j;
+
+  while (*p)
+    {
+      lino++;
+      q = p;
+      while (*p && *p != '\n')
+       {
+         if (*p == '#')
+           {
+             *p++ = 0;
+             while (*p && *p != '\n')
+               p++;
+             break;
+           }
+         if (*p == '\t')
+           *p = ' ';
+         p++;
+       }
+      if (*p == '\n')
+       *p++ = 0;
+      if (!*q)
+       continue;
+      r = p;
+      while (r > q && r[-1] == ' ')
+       *--r = 0;
+      r = q;
+      while (*q == ' ')
+       q++;
+      if (strlen(q) < 5 || q[4] != ' ')
+       goto parserr;
+      if (r == q)
+       {
+         if (q[0] == 'C' && q[1] == ' ')
+           {
+             if (sscanf(q+2, "%x", &j) != 1)
+               goto parserr;
+             i = ID1_CLASS;
+           }
+         else
+           {
+             if (sscanf(q, "%x", &j) != 1)
+               goto parserr;
+             i = ID1_VENDOR;
+           }
+         id1 = i;
+         id2 = j;
+       }
+      else
+       {
+         if (sscanf(q, "%x", &j) != 1)
+           goto parserr;
+         if (id1 == ID1_ERROR)
+           goto parserr;
+         if (id1 == ID1_CLASS)
+           {
+             i = ID1_SUBCLASS;
+             j |= (id2 << 8);
+           }
+         else
+           i = id2;
+       }
+      q += 4;
+      while (*q == ' ')
+       q++;
+      if (!*q)
+       goto parserr;
+      if (nl_add(i, j, q))
+       {
+         fprintf(stderr, ETC_PCI_IDS ", line %d: duplicate entry\n", lino);
+         exit(1);
+       }
+    }
+  return;
+
+parserr:
+  fprintf(stderr, ETC_PCI_IDS ", line %d: parse error\n", lino);
+  exit(1);
+}
+
+static void
+load_name_list(void)
+{
+  int fd;
+  struct stat st;
+
+  fd = open(ETC_PCI_IDS, O_RDONLY);
+  if (fd < 0)
+    {
+      show_numeric_ids = 1;
+      return;
+    }
+  if (fstat(fd, &st) < 0)
+    err_name_list("stat");
+  name_list = xmalloc(st.st_size + 1);
+  if (read(fd, name_list, st.st_size) != st.st_size)
+    err_name_list("read");
+  name_list[st.st_size] = 0;
+  parse_name_list();
+  close(fd);
+  name_list_loaded = 1;
+}
+
+char *
+lookup_vendor(word i)
+{
+  static char vendbuf[6];
+
+  if (!show_numeric_ids)
+    {
+      struct nl_entry *e;
+
+      if (!name_list_loaded)
+       load_name_list();
+      e = nl_lookup(ID1_VENDOR, i);
+      if (e)
+       return e->name;
+    }
+  sprintf(vendbuf, "%04x", i);
+  return vendbuf;
+}
+
+char *
+lookup_device(word v, word i)
+{
+  static char devbuf[6];
+
+  if (!show_numeric_ids)
+    {
+      struct nl_entry *e;
+
+      if (!name_list_loaded)
+       load_name_list();
+      e = nl_lookup(v, i);
+      if (e)
+       return e->name;
+    }
+  sprintf(devbuf, "%04x", i);
+  return devbuf;
+}
+
+char *
+lookup_device_full(word v, word i)
+{
+  static char fullbuf[256];
+
+  if (!show_numeric_ids)
+    {
+      struct nl_entry *e, *e2;
+
+      if (!name_list_loaded)
+       load_name_list();
+      e = nl_lookup(ID1_VENDOR, v);
+      e2 = nl_lookup(v, i);
+      if (!e)
+       sprintf(fullbuf, "Unknown device %04x:%04x", v, i);
+      else if (!e2)
+       sprintf(fullbuf, "%s: Unknown device %04x", e->name, i);
+      else
+       sprintf(fullbuf, "%s %s", e->name, e2->name);
+    }
+  else
+    sprintf(fullbuf, "%04x:%04x", v, i);
+  return fullbuf;
+}
+
+char *
+lookup_class(word c)
+{
+  static char classbuf[80];
+
+  if (!show_numeric_ids)
+    {
+      struct nl_entry *e;
+
+      if (!name_list_loaded)
+       load_name_list();
+      e = nl_lookup(ID1_SUBCLASS, c);
+      if (e)
+       return e->name;
+      e = nl_lookup(ID1_CLASS, c);
+      if (e)
+       sprintf(classbuf, "%s [%04x]", e->name, c);
+      else
+       sprintf(classbuf, "Unknown class [%04x]", c);
+    }
+  else
+    sprintf(classbuf, "Class %04x", c);
+  return classbuf;
+}
diff --git a/pci.ids b/pci.ids
new file mode 100644 (file)
index 0000000..b73a7b2
--- /dev/null
+++ b/pci.ids
@@ -0,0 +1,585 @@
+#
+#      List of PCI ID's
+#
+#      Maintained by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+#      If you have any new entries, send them to the maintainer.
+#
+#      $Id: pci.ids,v 1.1 1997/12/23 10:29:18 mj Exp $
+#
+
+# Vendors and devices. Please keep sorted.
+
+0e11  Compaq
+       3033  QVision 1280/p
+       ae10  Smart-2/P RAID Controller
+       ae32  Netelligent 10/100
+       ae34  Netelligent 10
+       ae35  NetFlex 3
+       ae40  Netelligent 10/100 Dual
+       ae43  Netelligent 10/100 ProLiant
+       b011  Netelligent 10/100 Integrated
+       f130  ThunderLAN
+       f150  NetFlex 3 BNC
+1000  NCR
+       0001  53c810
+       0002  53c820
+       0003  53c825
+       0004  53c815
+       0006  53c860
+       000b  53c896
+       000c  53c895
+       000d  53c885
+       000f  53c875
+       008f  53c876
+1002  ATI
+       4158  68800AX
+       4354  215CT222
+       4358  210888CX
+       4742  Mach64 GB
+       4750  Mach64 GP (Rage Pro)
+       4754  Mach64 GT (Rage II)
+       4755  Mach64 GT (Rage II)
+       4758  210888GX
+       5654  Mach64 VT
+1004  VLSI
+       0005  82C592-FC1
+       0006  82C593-FC1
+       0007  82C594-AFC2
+       0009  82C597-AFC2
+       000c  82C541 Lynx
+       000d  82C543 Lynx ISA
+       0702  VAS96011 (Golden Gate II)
+1005  Avance Logic
+       2301  2301
+100b  NS
+       0002  87415
+       d001  87410
+100c  Tseng'Lab
+       3202  ET4000W32P
+       3205  ET4000W32P rev B
+       3206  ET4000W32P rev C
+       3207  ET4000W32P rev D
+       3208  ET6000
+100e  Weitek
+       9001  P9000
+       9100  P9100
+1011  DEC
+       0001  DC21050
+       0002  DC21040
+       0004  TGA
+       0009  DC21140
+       000D  TGA2
+       000F  DEFPA
+       0014  DC21041
+       0019  DC21142
+       0021  DC21052
+       0024  DC21152
+1013  Cirrus Logic
+       0038  GD 7548
+       00a0  GD 5430
+       00a4  GD 5434
+       00a8  GD 5434
+       00ac  GD 5436
+       00b8  GD 5446
+       00bc  GD 5480
+       00d4  GD 5464
+       00d6  GD 5465
+       1100  CL 6729
+       1110  PD 6832
+       1200  CL 7542
+       1202  CL 7543
+       1204  CL 7541
+1014  IBM
+       000a  Fire Coral
+       0018  Token Ring
+       001d  82G2675
+       0022  82351
+101c  Western Digital
+       3296  WD 7197
+1022  AMD
+       2000  79C970
+       2020  53C974
+1023  Trident
+       9420  TG 9420
+       9440  TG 9440
+       9660  TG 9660
+       9750  Image 975
+1025  Acer Incorporated
+       1435  M1435
+102B  Matrox
+       0518  Atlas PX2085
+       0519  Millennium
+       051A  Mystique
+       051b  Millennium II
+       0d10  MGA Impression
+102c  Chips & Technologies
+       00d8  65545
+       00dc  65548
+       00e0  65550
+       00e4  65554
+1031  Miro
+       5601  ZR36050
+1033  NEC
+       0046  PowerVR PCX2
+1036  Future Domain
+       0000  TMC-18C30
+1039  Silicon Integrated Systems
+       0001  6201
+       0002  6202
+       0008  85C503
+       0205  6205
+       0406  85C501
+       0496  85C496
+       0601  85C601
+       5107  5107
+       5511  85C5511
+       5513  85C5513
+       5571  5571
+       5597  5597
+       7001  7001
+103c  Hewlett Packard
+       1030  J2585A
+       1031  J2585B (Lassen)
+1042  PCTECH
+       1000  RZ1000 (buggy)
+       1001  RZ1001 (buggy?)
+1044  DPT
+       a400  SmartCache/Raid
+1045  OPTi
+       c178  92C178
+       c557  82C557
+       c558  82C558
+       c621  82C621
+       c700  82C700
+       c701  82C701 FireStar Plus
+       c814  82C814 Firebridge 1
+       c822  82C822
+104B  BusLogic
+       0140  MultiMaster NC
+       1040  MultiMaster
+       8130  FlashPoint
+104a  SGS Thomson
+       0008  STG 2000X
+       0009  STG 1764X
+104c  Texas Instruments
+       3d04  TVP4010 Permedia
+       3d07  TVP4020 Permedia 2
+       ac12  PCI1130
+       ac15  PCI1131
+104e  OAK
+       0107  OTI107
+1050  Winbond
+       0940  NE2000-PCI
+1057  Motorola
+       0001  MPC105 Eagle
+       0002  MPC106 Grackle
+       4801  Raven
+105a  Promise Technology
+       4d33  IDE UltraDMA/33
+       5300  DC5030
+105d  Number Nine
+       2309  Imagine 128
+       2339  Imagine 128v2
+1060  UMC
+       0101  UM8673F
+       0891  UM8891A
+       673a  UM8886BF
+       886a  UM8886A
+       8881  UM8881F
+       8886  UM8886F
+       9017  UM9017F
+       e886  UM8886N
+       e891  UM8891N
+1061  X TECHNOLOGY
+       0001  ITT AGX016
+1066  PicoPower
+       0001  PT86C52x Vesuvius
+106b  Apple
+       0001  Bandit
+       0002  Grand Central
+       000e  Hydra
+1074  Nexgen
+       4e78  82C501
+1077  Q Logic
+       1020  ISP1020
+       1022  ISP1022
+107d  Leadtek Research
+       0000  S3 805
+1080  Contaq
+       0600  82C599
+1083  Forex
+108d  Olicom
+       0001  OC-3136/3137
+       0011  OC-2315
+       0012  OC-2325
+       0013  OC-2183/2185
+       0014  OC-2326
+       0021  OC-6151/6152
+108e  Sun Microsystems
+       1000  EBUS
+       1001  Happy Meal
+       8000  PCI Bus Module
+1095  CMD
+       0640  640 (buggy)
+       0643  643
+       0646  646
+       0670  670
+1098  Vision
+       0001  QD-8500
+       0002  QD-8580
+109e  Brooktree
+       0350  Bt848
+10a8  Sierra
+       0000  STB Horizon 64
+10aa  ACC MICROELECTRONICS
+       0000  2056
+10ad  Winbond
+       0001  W83769F
+       0105  SL82C105
+       0565  W83C553
+10b3  Databook
+       b106  DB87144
+10b7  3Com
+       5900  3C590 10bT
+       5950  3C595 100bTX
+       5951  3C595 100bT4
+       5952  3C595 100b-MII
+       9000  3C900 10bTPO
+       9001  3C900 10b Combo
+       9050  3C905 100bTX
+10b8  SMC
+       0005  9432 TX
+10b9  Acer Labs
+       1445  M1445
+       1449  M1449
+       1451  M1451
+       1461  M1461
+       1489  M1489
+       1511  M1511
+       1513  M1513
+       1521  M1521
+       1523  M1523
+       1531  M1531 Aladdin IV
+       1533  M1533 Aladdin IV
+       5215  M4803
+       5219  M5219
+       5229  M5229 TXpro
+10ba  Mitsubishi
+10bd  Surecom
+       0e34  NE-34PCI LAN
+10c8  Neomagic
+       0001  MagicGraph NM2070
+       0002  MagicGraph 128V
+       0003  MagicGraph 128ZV
+       0004  MagicGraph NM2160
+10cd  Advanced System Products
+       1200  ABP940
+       1300  ABP940U
+10dc  CERN
+       0001  STAR/RD24 SCI-PCI (PMC)
+       0002  STAR/RD24 SCI-PCI (PMC)
+10de  NVidia
+10e0  IMS
+       8849  8849
+10e1  Tekram
+       690c  DC690c
+10e3  Tundra
+       0000  CA91C042 Universe
+10e8  AMCC
+       8043  Myrinet PCI (M2-PCI-32)
+       807d  S5933
+10ea  Intergraphics
+       1680  IGA-1680
+       1682  IGA-1682
+10ec  Realtek
+       8029  8029
+       8129  8129
+10fa  Truevision
+       000c  TARGA 1000
+1101  Initio Corp
+       9100  320 P
+1106  VIA Technologies
+       0505  VT 82C505
+       0561  VT 82C561
+       0571  VT 82C586 Apollo IDE
+       0576  VT 82C576 3V
+       0585  VT 82C585 Apollo VP1/VPX
+       0586  VT 82C586 Apollo ISA
+       0595  VT 82C595 Apollo VP2
+       0926  VT 82C926 Amazon
+       1571  VT 82C416MV
+       1595  VT 82C595 Apollo VP2/97
+       3038  VT 82C586 Apollo USB
+       3040  VT 82C586B Apollo ACPI
+1119  VORTEX
+       0000  GDT 60
+       0001  GDT 6000b
+       0002  GDT 6110/6510
+       0003  GDT 6120/6520
+       0004  GDT 6530
+       0005  GDT 6550
+       0006  GDT 6117/6517
+       0007  GDT 6127/6527
+       0008  GDT 6537
+       0009  GDT 6557
+       000a  GDT 6115/6515
+       000b  GDT 6125/6525
+       000c  GDT 6535
+       000d  GDT 6555
+       0100  GDT 6117RP/6517RP
+       0101  GDT 6127RP/6527RP
+       0102  GDT 6537RP
+       0103  GDT 6557RP
+       0104  GDT 6111RP/6511RP
+       0105  GDT 6121RP/6521RP
+       0110  GDT 6117RP1/6517RP1
+       0111  GDT 6127RP1/6527RP1
+       0112  GDT 6537RP1
+       0113  GDT 6557RP1
+       0114  GDT 6111RP1/6511RP1
+       0115  GDT 6121RP1/6521RP1
+       0120  GDT 6117RP2/6517RP2
+       0121  GDT 6127RP2/6527RP2
+       0122  GDT 6537RP2
+       0123  GDT 6557RP2
+       0124  GDT 6111RP2/6511RP2
+       0125  GDT 6121RP2/6521RP2
+111a  Efficient Networks
+       0000  155P-MF1 (FPGA)
+       0002  155P-MF1 (ASIC)
+1127  Fore Systems
+       0210  PCA-200PC
+       0300  PCA-200E
+112f  Imaging Technology
+       0000  MVC IC-PCI
+1131  Philips
+       7146  SAA7146
+113c  PLX
+       0001  PCI9060 i960 bridge
+1142  Alliance
+       3210  Promotion-6410
+       6422  Provideo
+       6424  AT24
+       643d  AT3D
+114a  VMIC
+       7587  VMIVME-7587
+114f  Digi Intl.
+       0003  RightSwitch SE-6
+1159  Mutech
+       0001  MV-1000
+1163  Rendition
+       0001  Verite 1000
+1179  Toshiba
+       0601  Laptop
+1180  Ricoh
+       0466  RL5C466
+1193  ZeitNet
+       0001  1221
+       0002  1225
+119b  Omega Micro
+       1221  82C092G
+11ad  LiteOn
+       0002  LNE100TX
+11bc  Network Peripherals
+       0001  NP-PCI
+11cb  Specialix
+       4000  XIO/SIO host
+       8000  RIO host
+11d1  Auravision
+       01f7  VXP524
+11d5  Ikon
+       0115  10115 Greensheet
+       0117  10117 Greensheet
+11de  Zoran
+       6057  ZR36057
+       6120  ZR36120
+11f6  Compex
+       0112  Readylink ENET100-VG4
+       1401  ReadyLink 2000
+11fe  Comtrol
+       0001  RocketPort 8 Oct
+       0002  RocketPort 8 Intf
+       0003  RocketPort 16 Intf
+       0004  RocketPort 32 Intf
+120e  Cyclades
+       0100  Cyclom-Y below 1Mbyte
+       0101  Cyclom-Y above 1Mbyte
+       0200  Cyclom-Z below 1Mbyte
+       0201  Cyclom-Z above 1Mbyte
+121a  3Dfx
+       0001  Voodoo
+1236  Sigma Designs
+       6401  REALmagic64/GX
+1255  Optibase
+       1110  MPEG Forge
+       1210  MPEG Fusion
+       2110  VideoPlex
+       2120  VideoPlex CC
+       2130  VideoQuest
+1274  Ensoniq
+       5000  AudioPCI
+12c5  Picture Elements
+       0081  PCIVST
+12d2  NVidia/SGS Thomson
+       0018  Riva 128
+1c1c  Symphony
+       0001  82C101
+1de1  Tekram
+       dc29  DC-290
+3d3d  3Dlabs
+       0001  GLINT 300SX
+       0002  GLINT 500TX
+       0003  GLINT Delta
+       0004  PERMEDIA
+4005  Avance
+       2064  ALG2064i
+       2302  ALG-2302
+4a14  NetVin
+       5000  NV5000
+5333  S3 Inc.
+       0551  PLATO/PX (system)
+       5631  ViRGE
+       8811  Trio32/Trio64
+       8812  Aurora64V+
+       8814  Trio64UV+
+       883d  ViRGE/VX
+       8880  Vision 868
+       88b0  Vision 928-P
+       88c0  Vision 864-P
+       88c1  Vision 864-P
+       88d0  Vision 964-P
+       88d1  Vision 964-P
+       88f0  Vision 968
+       8901  Trio64V2/DX or /GX
+       8902  PLATO/PX (graphics)
+       8a01  ViRGE/DX or /GX
+       8a10  ViRGE/GX2
+8086  Intel
+       0482  82375EB
+       0483  82424ZX Saturn
+       0484  82378IB
+       0486  82430ZX Aries
+       04a3  82434LX Mercury/Neptune
+       1221  82092AA PCMCIA bridge
+       1222  82092AA EIDE
+       1223  SAA7116
+       1226  82596
+       1227  82865
+       1229  82557
+       122d  82437
+       122e  82371 Triton PIIX
+       1230  82371 Triton PIIX
+       1234  430MX - 82371MX MPIIX
+       1235  430MX - 82437MX MTSC
+       1237  82441FX Natoma
+       1250  82439HX Triton II
+       7000  82371SB Natoma/Triton II PIIX3
+       7010  82371SB Natoma/Triton II PIIX3
+       7020  82371SB Natoma/Triton II PIIX3
+       7030  82437VX Triton II
+       7100  82439TX
+       7110  82371AB PIIX4 ISA
+       7111  82371AB PIIX4 IDE
+       7112  82371AB PIIX4 USB
+       7113  82371AB PIIX4 ACPI
+       7180  440LX - 82443LX PAC Host
+       7181  440LX - 82443LX PAC AGP
+       84c4  Orion P6
+       84c5  82450GX Orion P6
+8e2e  KTI
+       3000  ET32P2
+9004  Adaptec
+       5078  AIC-7850
+       5578  AIC-7855
+       5800  AIC-5800
+       6078  AIC-7860
+       6178  AIC-7861
+       7078  AIC-7870
+       7178  AIC-7871
+       7278  AIC-7872
+       7378  AIC-7873
+       7478  AIC-7874
+       7895  AIC-7895U
+       8078  AIC-7880U
+       8178  AIC-7881U
+       8278  AIC-7882U
+       8378  AIC-7883U
+       8478  AIC-7884U
+907f  Atronics
+       2015  IDE-2015PL
+edd8  ARK Logic
+       a091  Stingray
+       a099  Stingray ARK 2000PV
+       a0a1  2000MT
+
+# List of known device classes and subclasses
+
+C 00  Unclassified device
+       0000  Non-VGA unclassified device
+       0001  VGA compatible unclassified device
+C 01  Mass storage controller
+       0000  SCSI storage controller
+       0001  IDE interface
+       0002  Floppy disk controller
+       0003  IPI bus controller
+       0004  RAID bus controller
+       0080  Unknown mass storage controller
+C 02  Network controller
+       0000  Ethernet controller
+       0001  Token ring network controller
+       0002  FDDI network controller
+       0003  ATM network controller
+       0080  Network controller
+C 03  Display controller
+       0000  VGA compatible controller
+       0001  XGA compatible controller
+       0080  Display controller
+C 04  Multimedia controller
+       0000  Multimedia video controller
+       0001  Multimedia audio controller
+       0080  Multimedia controller
+C 05  Memory controller
+       0000  RAM memory
+       0001  FLASH memory
+       0080  Memory
+C 06  Bridge
+       0000  Host bridge
+       0001  ISA bridge
+       0002  EISA bridge
+       0003  MicroChannel bridge
+       0004  PCI bridge
+       0005  PCMCIA bridge
+       0006  NuBus bridge
+       0007  CardBus bridge
+       0080  Bridge
+C 07  Communication controller
+       0000  Serial controller
+       0001  Parallel controller
+       0080  Communication controller
+C 08  Generic system peripheral
+       0000  PIC
+       0001  DMA controller
+       0002  Timer
+       0003  RTC
+       0080  System peripheral
+C 09  Input device controller
+       0000  Keyboard controller
+       0001  Digitizer Pen
+       0002  Mouse controller
+       0080  Input device controller
+C 0A  Docking station
+       0000  Generic Docking Station
+       0080  Docking Station
+C 0B  Processor
+       0000  386
+       0001  486
+       0002  Pentium
+       0010  Alpha
+       0020  Power PC
+       0040  Co-processor
+C 0C  Serial bus controller
+       0000  FireWire (IEEE 1394)
+       0001  ACCESS Bus
+       0002  SSA
+       0003  USB Controller
+       0004  Fiber Channel
diff --git a/pciutils.h b/pciutils.h
new file mode 100644 (file)
index 0000000..fe0388d
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *     $Id: pciutils.h,v 1.1 1997/12/23 10:29:18 mj Exp $
+ *
+ *     Linux PCI Utilities -- Declarations
+ *
+ *     Copyright (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *
+ *     Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <linux/types.h>
+
+#if 1
+#define PROC_BUS_PCI "/proc/bus/pci"
+#define ETC_PCI_IDS "/etc/pci.ids"
+#else
+#define PROC_BUS_PCI "/tmp/bus/pci"
+#define ETC_PCI_IDS "pci.ids"
+#endif
+
+/* Types */
+
+typedef __u8 byte;
+typedef __u16 word;
+typedef __u32 u32;
+
+/* lspci.c */
+
+void *xmalloc(unsigned int);
+
+/* names.c */
+
+extern int show_numeric_ids;
+
+char *lookup_vendor(word);
+char *lookup_device(word, word);
+char *lookup_device_full(word, word);
+char *lookup_class(word);