diff -ruN pciutils-3.0.3/ChangeLog pciutils-3.1.0/ChangeLog
--- pciutils-3.0.3/ChangeLog	2008-11-09 21:28:28.000000000 +0100
+++ pciutils-3.1.0/ChangeLog	2009-01-18 23:10:47.000000000 +0100
@@ -1,3 +1,51 @@
+2009-01-18  Martin Mares <mj@ucw.cz>
+
+	* Released as 3.1.0.
+
+	* Updated pci.ids to the current snapshot of the database.
+
+	* The Cygwin backend now works on Windows Vista. Thanks to Jonathan
+	Kotta.
+
+	* Fixed a bug in decoding of the SR-IOV capability. Patch by Yu Zhao.
+
+	* Details of some PCIe capabilities are displayed only with -vv.
+
+	* When a BAR is reported by the OS, but not by the device (i.e.,
+	it is marked as [virtual] in lspci), the [disabled] flag is
+	suppressed, because it does not make sense in such cases.
+	Patch by Yu Zhao.
+
+2008-12-13  Martin Mares <mj@ucw.cz>
+
+	* The source code of lspci has been split to multiple files, hopefully
+	making it easier to maintain.
+
+	* The library and lspci now know about physical slot names. So far,
+	they are provided by the sysfs back-end only. Thanks go to Alex Chiang.
+
+	* When a device has the VPD (Vital Product Data) capability and the
+	VPD data are supplied by the OS, they are decoded and printed in the
+	verbose mode. This currently works only on Linux with the sysfs
+	back-end. Thanks to Ben Hutchings of Solarflare for the patch.
+
+	* `setpci --version' now works properly.
+
+	* `setpci --dumpregs' prints a table of all known name of
+	registers and capabilities. This replaces the table of registers
+	in the setpci man page.
+
+	* The dry-run mode of setpci gives better feedback.
+
+	* The setpci utility is now able to address registers stored in PCI
+	capabilities (actually it allows a more general form of relative
+	addressing).
+
+	* The library has gained functions for working with PCI capabilities.
+
+	* Address Translation Services capability is now decoded. Patch by
+	Yu Zhao.
+
 2008-11-09  Martin Mares <mj@ucw.cz>
 
 	* Released as 3.0.3.
diff -ruN pciutils-3.0.3/Makefile pciutils-3.1.0/Makefile
--- pciutils-3.0.3/Makefile	2008-11-09 21:28:18.000000000 +0100
+++ pciutils-3.1.0/Makefile	2009-01-18 23:07:59.000000000 +0100
@@ -1,11 +1,11 @@
 # Makefile for The PCI Utilities
-# (c) 1998--2008 Martin Mares <mj@ucw.cz>
+# (c) 1998--2009 Martin Mares <mj@ucw.cz>
 
 OPT=-O2
 CFLAGS=$(OPT) -Wall -W -Wno-parentheses -Wstrict-prototypes -Wmissing-prototypes
 
-VERSION=3.0.3
-DATE=2008-11-09
+VERSION=3.1.0
+DATE=2009-01-18
 
 # Host OS and release (override if you are cross-compiling)
 HOST=
@@ -62,10 +62,18 @@
 lib/config.h lib/config.mk:
 	cd lib && ./configure
 
-lspci: lspci.o common.o lib/$(PCILIB)
+lspci: lspci.o ls-vpd.o ls-caps.o ls-ecaps.o ls-kernel.o ls-tree.o ls-map.o common.o lib/$(PCILIB)
 setpci: setpci.o common.o lib/$(PCILIB)
 
-lspci.o: lspci.c pciutils.h $(PCIINC)
+LSPCIINC=lspci.h pciutils.h $(PCIINC)
+lspci.o: lspci.c $(LSPCIINC)
+ls-vpd.o: ls-vpd.c $(LSPCIINC)
+ls-caps.o: ls-caps.c $(LSPCIINC)
+ls-ecaps.o: ls-ecaps.c $(LSPCIINC)
+ls-kernel.o: ls-kernel.c $(LSPCIINC)
+ls-tree.o: ls-tree.c $(LSPCIINC)
+ls-map.o: ls-map.c $(LSPCIINC)
+
 setpci.o: setpci.c pciutils.h $(PCIINC)
 common.o: common.c pciutils.h $(PCIINC)
 
diff -ruN pciutils-3.0.3/README pciutils-3.1.0/README
--- pciutils-3.0.3/README	2008-11-09 21:29:23.000000000 +0100
+++ pciutils-3.1.0/README	2009-01-18 23:12:51.000000000 +0100
@@ -1,6 +1,6 @@
-This package contains the PCI Utilities, version 3.0.3.
+This package contains the PCI Utilities, version 3.1.0.
 
-Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
+Copyright (c) 1997--2009 Martin Mares <mj@ucw.cz>
 
 All files in this package can be freely distributed and used according
 to the terms of the GNU General Public License, either version 2 or
diff -ruN pciutils-3.0.3/TODO pciutils-3.1.0/TODO
--- pciutils-3.0.3/TODO	2008-08-26 13:20:25.000000000 +0200
+++ pciutils-3.1.0/TODO	2008-11-11 11:45:50.000000000 +0100
@@ -1,5 +1,9 @@
 - review class names
 
+Setpci:
+- auto-width
+- extend the register table
+
 Capabilities with partial decoding:
 - PCIe 2nd set of control/status registers (have spec)
 - HyperTransport caps (have spec)
diff -ruN pciutils-3.0.3/common.c pciutils-3.1.0/common.c
--- pciutils-3.0.3/common.c	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/common.c	2008-11-11 00:11:51.000000000 +0100
@@ -44,6 +44,15 @@
   return p;
 }
 
+char *
+xstrdup(char *str)
+{
+  int len = strlen(str) + 1;
+  char *copy = xmalloc(len);
+  memcpy(copy, str, len);
+  return copy;
+}
+
 static void
 set_pci_method(struct pci_access *pacc, char *arg)
 {
diff -ruN pciutils-3.0.3/example.c pciutils-3.1.0/example.c
--- pciutils-3.0.3/example.c	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/example.c	2008-11-11 00:11:51.000000000 +0100
@@ -20,7 +20,7 @@
   /* Set all options you want -- here we stick with the defaults */
   pci_init(pacc);		/* Initialize the PCI library */
   pci_scan_bus(pacc);		/* We want to get the list of devices */
-  for(dev=pacc->devices; dev; dev=dev->next)	/* Iterate over all devices */
+  for (dev=pacc->devices; dev; dev=dev->next)	/* Iterate over all devices */
     {
       pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS);	/* Fill in header info we need */
       c = pci_read_byte(dev, PCI_INTERRUPT_PIN);				/* Read config register directly */
diff -ruN pciutils-3.0.3/lib/Makefile pciutils-3.1.0/lib/Makefile
--- pciutils-3.0.3/lib/Makefile	2008-08-26 17:08:03.000000000 +0200
+++ pciutils-3.1.0/lib/Makefile	2008-11-11 00:11:51.000000000 +0100
@@ -3,7 +3,7 @@
 
 # Expects to be invoked from the top-level Makefile and uses lots of its variables.
 
-OBJS=init access generic dump names filter names-hash names-parse names-net names-cache params
+OBJS=init access generic dump names filter names-hash names-parse names-net names-cache params caps
 INCL=internal.h pci.h config.h header.h sysdep.h types.h
 
 ifdef PCI_HAVE_PM_LINUX_SYSFS
diff -ruN pciutils-3.0.3/lib/access.c pciutils-3.1.0/lib/access.c
--- pciutils-3.0.3/lib/access.c	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/lib/access.c	2008-12-13 00:12:44.000000000 +0100
@@ -58,6 +58,8 @@
 {
   if (d->methods->cleanup_dev)
     d->methods->cleanup_dev(d);
+  pci_free_caps(d);
+  pci_mfree(d->phy_slot);
   pci_mfree(d);
 }
 
@@ -102,6 +104,12 @@
   return d->methods->read(d, pos, buf, len);
 }
 
+int
+pci_read_vpd(struct pci_dev *d, int pos, byte *buf, int len)
+{
+  return d->methods->read_vpd ? d->methods->read_vpd(d, pos, buf, len) : 0;
+}
+
 static inline int
 pci_write_data(struct pci_dev *d, void *buf, int pos, int len)
 {
@@ -144,18 +152,25 @@
 }
 
 int
-pci_fill_info(struct pci_dev *d, int flags)
+pci_fill_info_v31(struct pci_dev *d, int flags)
 {
   if (flags & PCI_FILL_RESCAN)
     {
       flags &= ~PCI_FILL_RESCAN;
       d->known_fields = 0;
+      pci_free_caps(d);
     }
   if (flags & ~d->known_fields)
     d->known_fields |= d->methods->fill_info(d, flags & ~d->known_fields);
   return d->known_fields;
 }
 
+/* In version 3.1, pci_fill_info got new flags => versioned alias */
+STATIC_ALIAS(int pci_fill_info(struct pci_dev *d, int flags), pci_fill_info_v31(d,flags));
+DEFINE_ALIAS(int pci_fill_info_v30(struct pci_dev *d, int flags), pci_fill_info_v31);
+SYMBOL_VERSION(pci_fill_info_v30, pci_fill_info@LIBPCI_3.0);
+SYMBOL_VERSION(pci_fill_info_v31, pci_fill_info@@LIBPCI_3.1);
+
 void
 pci_setup_cache(struct pci_dev *d, byte *cache, int len)
 {
diff -ruN pciutils-3.0.3/lib/aix-device.c pciutils-3.1.0/lib/aix-device.c
--- pciutils-3.0.3/lib/aix-device.c	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/lib/aix-device.c	2008-11-21 22:00:38.000000000 +0100
@@ -269,6 +269,7 @@
   pci_generic_fill_info,
   aix_read,
   aix_write,
+  NULL,                                 /* read_vpd */
   NULL,                                 /* dev_init */
   NULL                                  /* dev_cleanup */
 };
diff -ruN pciutils-3.0.3/lib/caps.c pciutils-3.1.0/lib/caps.c
--- pciutils-3.0.3/lib/caps.c	1970-01-01 01:00:00.000000000 +0100
+++ pciutils-3.1.0/lib/caps.c	2008-11-11 11:48:50.000000000 +0100
@@ -0,0 +1,114 @@
+/*
+ *	The PCI Library -- Capabilities
+ *
+ *	Copyright (c) 2008 Martin Mares <mj@ucw.cz>
+ *
+ *	Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <string.h>
+
+#include "internal.h"
+
+static void
+pci_add_cap(struct pci_dev *d, unsigned int addr, unsigned int id, unsigned int type)
+{
+  struct pci_cap *cap = pci_malloc(d->access, sizeof(*cap));
+
+  cap->next = d->first_cap;
+  d->first_cap = cap;
+  cap->addr = addr;
+  cap->id = id;
+  cap->type = type;
+  d->access->debug("%04x:%02x:%02x.%d: Found capability %04x of type %d at %04x\n",
+    d->domain, d->bus, d->dev, d->func, id, type, addr);
+}
+
+static void
+pci_scan_trad_caps(struct pci_dev *d)
+{
+  word status = pci_read_word(d, PCI_STATUS);
+  byte been_there[256];
+  int where;
+
+  if (!(status & PCI_STATUS_CAP_LIST))
+    return;
+
+  memset(been_there, 0, 256);
+  where = pci_read_byte(d, PCI_CAPABILITY_LIST) & ~3;
+  while (where)
+    {
+      byte id = pci_read_byte(d, where + PCI_CAP_LIST_ID);
+      byte next = pci_read_byte(d, where + PCI_CAP_LIST_NEXT) & ~3;
+      if (been_there[where]++)
+	break;
+      if (id == 0xff)
+	break;
+      pci_add_cap(d, where, id, PCI_CAP_NORMAL);
+      where = next;
+    }
+}
+
+static void
+pci_scan_ext_caps(struct pci_dev *d)
+{
+  byte been_there[0x1000];
+  int where = 0x100;
+
+  if (!pci_find_cap(d, PCI_CAP_ID_EXP, PCI_CAP_NORMAL))
+    return;
+
+  memset(been_there, 0, 0x1000);
+  do
+    {
+      u32 header;
+      int id;
+
+      header = pci_read_long(d, where);
+      if (!header || header == 0xffffffff)
+	break;
+      id = header & 0xffff;
+      if (been_there[where]++)
+	break;
+      pci_add_cap(d, where, id, PCI_CAP_EXTENDED);
+      where = header >> 20;
+    }
+  while (where);
+}
+
+unsigned int
+pci_scan_caps(struct pci_dev *d, unsigned int want_fields)
+{
+  if ((want_fields & PCI_FILL_EXT_CAPS) && !(d->known_fields & PCI_FILL_CAPS))
+    want_fields |= PCI_FILL_CAPS;
+
+  if (want_fields & PCI_FILL_CAPS)
+    pci_scan_trad_caps(d);
+  if (want_fields & PCI_FILL_EXT_CAPS)
+    pci_scan_ext_caps(d);
+  return want_fields;
+}
+
+void
+pci_free_caps(struct pci_dev *d)
+{
+  struct pci_cap *cap;
+
+  while (cap = d->first_cap)
+    {
+      d->first_cap = cap;
+      pci_mfree(d);
+    }
+}
+
+struct pci_cap *
+pci_find_cap(struct pci_dev *d, unsigned int id, unsigned int type)
+{
+  struct pci_cap *c;
+
+  pci_fill_info_v31(d, ((type == PCI_CAP_NORMAL) ? PCI_FILL_CAPS : PCI_FILL_EXT_CAPS));
+  for (c=d->first_cap; c; c=c->next)
+    if (c->type == type && c->id == id)
+      return c;
+  return NULL;
+}
diff -ruN pciutils-3.0.3/lib/configure pciutils-3.1.0/lib/configure
--- pciutils-3.0.3/lib/configure	2008-11-09 20:50:26.000000000 +0100
+++ pciutils-3.1.0/lib/configure	2009-01-16 20:05:57.000000000 +0100
@@ -32,7 +32,7 @@
 	then
 		sys=freebsd
 	fi
-	if [ "$sys" = "CYGWIN_NT-5.1" ]
+	if [ "$sys" = "CYGWIN_NT-5.1" -o "$sys" = "CYGWIN_NT-6.0" ]
 	then
 		sys=cygwin
 	fi
diff -ruN pciutils-3.0.3/lib/dump.c pciutils-3.1.0/lib/dump.c
--- pciutils-3.0.3/lib/dump.c	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/lib/dump.c	2008-11-21 22:00:38.000000000 +0100
@@ -173,6 +173,7 @@
   pci_generic_fill_info,
   dump_read,
   dump_write,
+  NULL,					/* read_vpd */
   NULL,					/* init_dev */
   dump_cleanup_dev
 };
diff -ruN pciutils-3.0.3/lib/fbsd-device.c pciutils-3.1.0/lib/fbsd-device.c
--- pciutils-3.0.3/lib/fbsd-device.c	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/lib/fbsd-device.c	2008-11-21 22:00:38.000000000 +0100
@@ -164,6 +164,7 @@
   pci_generic_fill_info,
   fbsd_read,
   fbsd_write,
+  NULL,                                 /* read_vpd */
   NULL,                                 /* dev_init */
   NULL                                  /* dev_cleanup */
 };
diff -ruN pciutils-3.0.3/lib/filter.c pciutils-3.1.0/lib/filter.c
--- pciutils-3.0.3/lib/filter.c	2008-08-26 13:23:18.000000000 +0200
+++ pciutils-3.1.0/lib/filter.c	2008-11-11 11:49:17.000000000 +0100
@@ -114,7 +114,7 @@
     return 0;
   if (f->device >= 0 || f->vendor >= 0)
     {
-      pci_fill_info(d, PCI_FILL_IDENT);
+      pci_fill_info_v31(d, PCI_FILL_IDENT);
       if ((f->device >= 0 && f->device != d->device_id) ||
 	  (f->vendor >= 0 && f->vendor != d->vendor_id))
 	return 0;
diff -ruN pciutils-3.0.3/lib/generic.c pciutils-3.1.0/lib/generic.c
--- pciutils-3.0.3/lib/generic.c	2007-02-06 13:00:05.000000000 +0100
+++ pciutils-3.1.0/lib/generic.c	2008-11-11 00:11:51.000000000 +0100
@@ -25,11 +25,11 @@
   busmap[bus] = 1;
   t = pci_alloc_dev(a);
   t->bus = bus;
-  for(dev=0; dev<32; dev++)
+  for (dev=0; dev<32; dev++)
     {
       t->dev = dev;
       multi = 0;
-      for(t->func=0; !t->func || multi && t->func<8; t->func++)
+      for (t->func=0; !t->func || multi && t->func<8; t->func++)
 	{
 	  u32 vd = pci_read_long(t, PCI_VENDOR_ID);
 	  struct pci_dev *d;
@@ -108,7 +108,7 @@
 	}
       if (cnt)
 	{
-	  for(i=0; i<cnt; i++)
+	  for (i=0; i<cnt; i++)
 	    {
 	      u32 x = pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4);
 	      if (!x || x == (u32) ~0)
@@ -157,6 +157,8 @@
 	    d->rom_base_addr = u;
 	}
     }
+  if (flags & (PCI_FILL_CAPS | PCI_FILL_EXT_CAPS))
+    flags |= pci_scan_caps(d, flags);
   return flags & ~PCI_FILL_SIZES;
 }
 
diff -ruN pciutils-3.0.3/lib/header.h pciutils-3.1.0/lib/header.h
--- pciutils-3.0.3/lib/header.h	2008-11-09 20:38:37.000000000 +0100
+++ pciutils-3.1.0/lib/header.h	2008-12-12 23:49:02.000000000 +0100
@@ -220,6 +220,7 @@
 #define PCI_EXT_CAP_ID_VNDR	0x0b	/* Vendor specific */
 #define PCI_EXT_CAP_ID_ACS	0x0d	/* Access Controls */
 #define PCI_EXT_CAP_ID_ARI	0x0e	/* Alternative Routing-ID Interpretation */
+#define PCI_EXT_CAP_ID_ATS	0x0f	/* Address Translation Service */
 #define PCI_EXT_CAP_ID_SRIOV	0x10	/* Single Root I/O Virtualization */
 
 /* Power Management Registers */
@@ -280,6 +281,13 @@
 #define  PCI_AGP_COMMAND_RATE1	0x0001	/* Use 1x rate (4x in AGP3 mode) */
 #define PCI_AGP_SIZEOF		12
 
+/* Vital Product Data */
+
+#define PCI_VPD_ADDR		2	/* Address to access (15 bits!) */
+#define  PCI_VPD_ADDR_MASK	0x7fff	/* Address mask */
+#define  PCI_VPD_ADDR_F		0x8000	/* Write 0, 1 indicates completion */
+#define PCI_VPD_DATA		4	/* 32-bits of data returned here */
+
 /* Slot Identification */
 
 #define PCI_SID_ESR		2	/* Expansion Slot Register */
@@ -953,6 +961,13 @@
 #define  PCI_ARI_CTRL_ACS	0x0002	/* ACS Function Groups Enable */
 #define  PCI_ARI_CTRL_FG(x)	(((x) >> 4) & 7) /* Function Group */
 
+/* Address Translation Service */
+#define PCI_ATS_CAP		0x04	/* ATS Capability Register */
+#define  PCI_ATS_CAP_IQD(x)	((x) & 0x1f) /* Invalidate Queue Depth */
+#define PCI_ATS_CTRL		0x06	/* ATS Control Register */
+#define  PCI_ATS_CTRL_STU(x)	((x) & 0x1f) /* Smallest Translation Unit */
+#define  PCI_ATS_CTRL_ENABLE	0x8000	/* ATS Enable */
+
 /* Single Root I/O Virtualization */
 #define PCI_IOV_CAP		0x04	/* SR-IOV Capability Register */
 #define  PCI_IOV_CAP_VFM	0x00000001 /* VF Migration Capable */
diff -ruN pciutils-3.0.3/lib/i386-ports.c pciutils-3.1.0/lib/i386-ports.c
--- pciutils-3.0.3/lib/i386-ports.c	2008-08-26 17:07:28.000000000 +0200
+++ pciutils-3.1.0/lib/i386-ports.c	2008-11-21 22:00:38.000000000 +0100
@@ -69,7 +69,7 @@
   a->debug("...sanity check");
   d.bus = 0;
   d.func = 0;
-  for(d.dev = 0; d.dev < 32; d.dev++)
+  for (d.dev = 0; d.dev < 32; d.dev++)
     {
       u16 class, vendor;
       if (m->read(&d, PCI_CLASS_DEVICE, (byte *) &class, sizeof(class)) &&
@@ -265,6 +265,7 @@
   pci_generic_fill_info,
   conf1_read,
   conf1_write,
+  NULL,					/* read_vpd */
   NULL,					/* init_dev */
   NULL					/* cleanup_dev */
 };
@@ -280,6 +281,7 @@
   pci_generic_fill_info,
   conf2_read,
   conf2_write,
+  NULL,					/* read_vpd */
   NULL,					/* init_dev */
   NULL					/* cleanup_dev */
 };
diff -ruN pciutils-3.0.3/lib/init.c pciutils-3.1.0/lib/init.c
--- pciutils-3.0.3/lib/init.c	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/lib/init.c	2008-11-11 00:11:51.000000000 +0100
@@ -158,7 +158,7 @@
   pci_define_param(a, "net.cache_name", "~/.pciids-cache", "Name of the ID cache file");
   a->id_lookup_mode = PCI_LOOKUP_CACHE;
 #endif
-  for(i=0; i<PCI_ACCESS_MAX; i++)
+  for (i=0; i<PCI_ACCESS_MAX; i++)
     if (pci_methods[i] && pci_methods[i]->config)
       pci_methods[i]->config(a);
   return a;
@@ -185,7 +185,7 @@
   else
     {
       unsigned int i;
-      for(i=0; i<PCI_ACCESS_MAX; i++)
+      for (i=0; i<PCI_ACCESS_MAX; i++)
 	if (pci_methods[i])
 	  {
 	    a->debug("Trying method %d...", i);
@@ -210,7 +210,7 @@
 {
   struct pci_dev *d, *e;
 
-  for(d=a->devices; d; d=e)
+  for (d=a->devices; d; d=e)
     {
       e = d->next;
       pci_free_dev(d);
diff -ruN pciutils-3.0.3/lib/internal.h pciutils-3.1.0/lib/internal.h
--- pciutils-3.0.3/lib/internal.h	2008-08-26 15:08:14.000000000 +0200
+++ pciutils-3.1.0/lib/internal.h	2008-11-21 22:00:38.000000000 +0100
@@ -10,6 +10,13 @@
 
 #ifdef PCI_SHARED_LIB
 #define PCI_ABI __attribute__((visibility("default")))
+#define STATIC_ALIAS(_decl, _for)
+#define DEFINE_ALIAS(_decl, _for) extern _decl __attribute__((alias(#_for)))
+#define SYMBOL_VERSION(_int, _ext) asm(".symver " #_int "," #_ext)
+#else
+#define STATIC_ALIAS(_decl, _for) _decl { return _for; }
+#define DEFINE_ALIAS(_decl, _for)
+#define SYMBOL_VERSION(_int, _ext)
 #endif
 
 #include "pci.h"
@@ -26,27 +33,39 @@
   int (*fill_info)(struct pci_dev *, int flags);
   int (*read)(struct pci_dev *, int pos, byte *buf, int len);
   int (*write)(struct pci_dev *, int pos, byte *buf, int len);
+  int (*read_vpd)(struct pci_dev *, int pos, byte *buf, int len);
   void (*init_dev)(struct pci_dev *);
   void (*cleanup_dev)(struct pci_dev *);
 };
 
+/* generic.c */
 void pci_generic_scan_bus(struct pci_access *, byte *busmap, int bus);
 void pci_generic_scan(struct pci_access *);
 int pci_generic_fill_info(struct pci_dev *, int flags);
 int pci_generic_block_read(struct pci_dev *, int pos, byte *buf, int len);
 int pci_generic_block_write(struct pci_dev *, int pos, byte *buf, int len);
 
+/* init.c */
 void *pci_malloc(struct pci_access *, int);
 void pci_mfree(void *);
 char *pci_strdup(struct pci_access *a, char *s);
 
+/* access.c */
 struct pci_dev *pci_alloc_dev(struct pci_access *);
 int pci_link_dev(struct pci_access *, struct pci_dev *);
 
+int pci_fill_info_v30(struct pci_dev *, int flags) PCI_ABI;
+int pci_fill_info_v31(struct pci_dev *, int flags) PCI_ABI;
+
+/* params.c */
 void pci_define_param(struct pci_access *acc, char *param, char *val, char *help);
 int pci_set_param_internal(struct pci_access *acc, char *param, char *val, int copy);
 void pci_free_params(struct pci_access *acc);
 
+/* caps.c */
+unsigned int pci_scan_caps(struct pci_dev *, unsigned int want_fields);
+void pci_free_caps(struct pci_dev *);
+
 extern struct pci_methods pm_intel_conf1, pm_intel_conf2, pm_linux_proc,
 	pm_fbsd_device, pm_aix_device, pm_nbsd_libpci, pm_obsd_device,
 	pm_dump, pm_linux_sysfs;
diff -ruN pciutils-3.0.3/lib/libpci.ver pciutils-3.1.0/lib/libpci.ver
--- pciutils-3.0.3/lib/libpci.ver	2008-04-10 21:17:37.000000000 +0200
+++ pciutils-3.1.0/lib/libpci.ver	2008-11-21 22:00:38.000000000 +0100
@@ -7,6 +7,43 @@
  */
 
 LIBPCI_3.0 {
-	global: pci_*;
+	global:
+		pci_alloc;
+		pci_cleanup;
+		pci_fill_info;
+		pci_filter_init;
+		pci_filter_match;
+		pci_filter_parse_id;
+		pci_filter_parse_slot;
+		pci_free_dev;
+		pci_free_name_list;
+		pci_get_dev;
+		pci_get_method_name;
+		pci_get_param;
+		pci_id_cache_flush;
+		pci_init;
+		pci_load_name_list;
+		pci_lookup_method;
+		pci_lookup_name;
+		pci_read_block;
+		pci_read_byte;
+		pci_read_long;
+		pci_read_word;
+		pci_scan_bus;
+		pci_set_name_list_path;
+		pci_set_param;
+		pci_setup_cache;
+		pci_walk_params;
+		pci_write_block;
+		pci_write_byte;
+		pci_write_long;
+		pci_write_word;
 	local: *;
 };
+
+LIBPCI_3.1 {
+	global:
+		pci_fill_info;
+		pci_find_cap;
+		pci_read_vpd;
+};
diff -ruN pciutils-3.0.3/lib/nbsd-libpci.c pciutils-3.1.0/lib/nbsd-libpci.c
--- pciutils-3.0.3/lib/nbsd-libpci.c	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/lib/nbsd-libpci.c	2008-11-21 22:00:38.000000000 +0100
@@ -151,6 +151,7 @@
   pci_generic_fill_info,
   nbsd_read,
   nbsd_write,
+  NULL,                                 /* read_vpd */
   NULL,                                 /* dev_init */
   NULL                                  /* dev_cleanup */
 };
diff -ruN pciutils-3.0.3/lib/obsd-device.c pciutils-3.1.0/lib/obsd-device.c
--- pciutils-3.0.3/lib/obsd-device.c	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/lib/obsd-device.c	2008-11-21 22:00:38.000000000 +0100
@@ -146,6 +146,7 @@
   pci_generic_fill_info,
   obsd_read,
   obsd_write,
+  NULL,                                 /* read_vpd */
   NULL,                                 /* dev_init */
   NULL                                  /* dev_cleanup */
 };
diff -ruN pciutils-3.0.3/lib/pci.h pciutils-3.1.0/lib/pci.h
--- pciutils-3.0.3/lib/pci.h	2008-08-26 15:07:06.000000000 +0200
+++ pciutils-3.1.0/lib/pci.h	2009-01-18 23:09:07.000000000 +0100
@@ -1,7 +1,7 @@
 /*
  *	The PCI Library
  *
- *	Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
+ *	Copyright (c) 1997--2009 Martin Mares <mj@ucw.cz>
  *
  *	Can be freely distributed and used under the terms of the GNU GPL.
  */
@@ -16,7 +16,7 @@
 #include "header.h"
 #include "types.h"
 
-#define PCI_LIB_VERSION 0x030000
+#define PCI_LIB_VERSION 0x030100
 
 #ifndef PCI_ABI
 #define PCI_ABI
@@ -72,10 +72,11 @@
   struct id_bucket *current_id_bucket;
   int id_load_failed;
   int id_cache_status;			/* 0=not read, 1=read, 2=dirty */
-  int fd;				/* proc: fd */
-  int fd_rw;				/* proc: fd opened read-write */
-  struct pci_dev *cached_dev;		/* proc: device the fd is for */
-  int fd_pos;				/* proc: current position */
+  int fd;				/* proc/sys: fd for config space */
+  int fd_rw;				/* proc/sys: fd opened read-write */
+  int fd_pos;				/* proc/sys: current position */
+  int fd_vpd;				/* sys: fd for VPD */
+  struct pci_dev *cached_dev;		/* proc/sys: device the fds are for */
 };
 
 /* Initialize PCI access */
@@ -127,6 +128,8 @@
   pciaddr_t size[6];			/* Region sizes */
   pciaddr_t rom_base_addr;		/* Expansion ROM base address */
   pciaddr_t rom_size;			/* Expansion ROM size */
+  struct pci_cap *first_cap;		/* List of capabilities */
+  char *phy_slot;			/* Physical slot */
 
   /* Fields used internally: */
   struct pci_access *access;
@@ -139,11 +142,13 @@
 
 #define PCI_ADDR_IO_MASK (~(pciaddr_t) 0x3)
 #define PCI_ADDR_MEM_MASK (~(pciaddr_t) 0xf)
+#define PCI_ADDR_FLAG_MASK 0xf
 
 u8 pci_read_byte(struct pci_dev *, int pos) PCI_ABI; /* Access to configuration space */
 u16 pci_read_word(struct pci_dev *, int pos) PCI_ABI;
 u32 pci_read_long(struct pci_dev *, int pos) PCI_ABI;
 int pci_read_block(struct pci_dev *, int pos, u8 *buf, int len) PCI_ABI;
+int pci_read_vpd(struct pci_dev *d, int pos, u8 *buf, int len) PCI_ABI;
 int pci_write_byte(struct pci_dev *, int pos, u8 data) PCI_ABI;
 int pci_write_word(struct pci_dev *, int pos, u16 data) PCI_ABI;
 int pci_write_long(struct pci_dev *, int pos, u32 data) PCI_ABI;
@@ -157,11 +162,30 @@
 #define PCI_FILL_ROM_BASE	8
 #define PCI_FILL_SIZES		16
 #define PCI_FILL_CLASS		32
+#define PCI_FILL_CAPS		64
+#define PCI_FILL_EXT_CAPS	128
+#define PCI_FILL_PHYS_SLOT	256
 #define PCI_FILL_RESCAN		0x10000
 
 void pci_setup_cache(struct pci_dev *, u8 *cache, int len) PCI_ABI;
 
 /*
+ *	Capabilities
+ */
+
+struct pci_cap {
+  struct pci_cap *next;
+  u16 id;				/* PCI_CAP_ID_xxx */
+  u16 type;				/* PCI_CAP_xxx */
+  unsigned int addr;			/* Position in the config space */
+};
+
+#define PCI_CAP_NORMAL		1	/* Traditional PCI capabilities */
+#define PCI_CAP_EXTENDED	2	/* PCIe extended capabilities */
+
+struct pci_cap *pci_find_cap(struct pci_dev *, unsigned int id, unsigned int type) PCI_ABI;
+
+/*
  *	Filters
  */
 
diff -ruN pciutils-3.0.3/lib/proc.c pciutils-3.1.0/lib/proc.c
--- pciutils-3.0.3/lib/proc.c	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/lib/proc.c	2009-01-18 22:57:20.000000000 +0100
@@ -97,10 +97,10 @@
       d->func = PCI_FUNC(dfn & 0xff);
       d->vendor_id = vend >> 16U;
       d->device_id = vend & 0xffff;
-      known = PCI_FILL_IDENT;
+      known = 0;
       if (!a->buscentric)
 	{
-	  known |= PCI_FILL_IRQ | PCI_FILL_BASES;
+	  known |= PCI_FILL_IDENT | PCI_FILL_IRQ | PCI_FILL_BASES;
 	  if (cnt >= 10)
 	    known |= PCI_FILL_ROM_BASE;
 	  if (cnt >= 17)
@@ -197,6 +197,7 @@
   pci_generic_fill_info,
   proc_read,
   proc_write,
+  NULL,					/* read_vpd */
   NULL,					/* init_dev */
   proc_cleanup_dev
 };
diff -ruN pciutils-3.0.3/lib/sysfs.c pciutils-3.1.0/lib/sysfs.c
--- pciutils-3.0.3/lib/sysfs.c	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/lib/sysfs.c	2008-12-30 12:01:33.000000000 +0100
@@ -1,7 +1,7 @@
 /*
  *	The PCI Library -- Configuration Access via /sys/bus/pci
  *
- * 	Copyright (c) 2003 Matthew Wilcox <willy@fc.hp.com>
+ *	Copyright (c) 2003 Matthew Wilcox <matthew@wil.cx>
  *	Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
  *
  *	Can be freely distributed and used under the terms of the GNU GPL.
@@ -50,16 +50,29 @@
 sysfs_init(struct pci_access *a)
 {
   a->fd = -1;
+  a->fd_vpd = -1;
 }
 
 static void
-sysfs_cleanup(struct pci_access *a)
+sysfs_flush_cache(struct pci_access *a)
 {
   if (a->fd >= 0)
     {
       close(a->fd);
       a->fd = -1;
     }
+  if (a->fd_vpd >= 0)
+    {
+      close(a->fd_vpd);
+      a->fd_vpd = -1;
+    }
+  a->cached_dev = NULL;
+}
+
+static void
+sysfs_cleanup(struct pci_access *a)
+{
+  sysfs_flush_cache(a);
 }
 
 #define OBJNAMELEN 1024
@@ -107,23 +120,24 @@
     a->error("Cannot open %s: %s", namebuf, strerror(errno));
   for (i = 0; i < 7; i++)
     {
-      unsigned long long start, end, size;
+      unsigned long long start, end, size, flags;
       if (!fgets(buf, sizeof(buf), file))
 	break;
-      if (sscanf(buf, "%llx %llx", &start, &end) != 2)
+      if (sscanf(buf, "%llx %llx %llx", &start, &end, &flags) != 3)
 	a->error("Syntax error in %s", namebuf);
       if (start)
 	size = end - start + 1;
       else
 	size = 0;
+      flags &= PCI_ADDR_FLAG_MASK;
       if (i < 6)
 	{
-	  d->base_addr[i] = start;
+	  d->base_addr[i] = start | flags;
 	  d->size[i] = size;
 	}
       else
 	{
-	  d->rom_base_addr = start;
+	  d->rom_base_addr = start | flags;
 	  d->rom_size = size;
 	}
     }
@@ -177,22 +191,110 @@
   closedir(dir);
 }
 
+static void
+sysfs_fill_slots(struct pci_access *a)
+{
+  char dirname[1024];
+  DIR *dir;
+  struct dirent *entry;
+  int n;
+
+  n = snprintf(dirname, sizeof(dirname), "%s/slots", sysfs_name(a));
+  if (n < 0 || n >= (int) sizeof(dirname))
+    a->error("Directory name too long");
+  dir = opendir(dirname);
+  if (!dir)
+    return;
+
+  while (entry = readdir(dir))
+    {
+      char namebuf[OBJNAMELEN], buf[16];
+      FILE *file;
+      unsigned int dom, bus, dev;
+      struct pci_dev *d;
+
+      /* ".", ".." or a special non-device perhaps */
+      if (entry->d_name[0] == '.')
+	continue;
+
+      n = snprintf(namebuf, OBJNAMELEN, "%s/%s/%s", dirname, entry->d_name, "address");
+      if (n < 0 || n >= OBJNAMELEN)
+	a->error("File name too long");
+      file = fopen(namebuf, "r");
+      if (!file)
+	{
+	  a->warning("sysfs_fill_slots: Cannot open %s: %s", namebuf, strerror(errno));
+	  continue;
+	}
+
+      if (!fgets(buf, sizeof(buf), file) || sscanf(buf, "%x:%x:%x", &dom, &bus, &dev) < 3)
+	a->warning("sysfs_fill_slots: Couldn't parse entry address %s", buf);
+      else
+	{
+	  for (d = a->devices; d; d = d->next)
+	    if (dom == d->domain && bus == d->bus && dev == d->dev && !d->phy_slot)
+	      {
+		d->phy_slot = pci_malloc(a, strlen(entry->d_name) + 1);
+		strcpy(d->phy_slot, entry->d_name);
+		break;
+	      }
+	}
+      fclose(file);
+    }
+  closedir(dir);
+}
+
+static int
+sysfs_fill_info(struct pci_dev *d, int flags)
+{
+  if ((flags & PCI_FILL_PHYS_SLOT) && !(d->known_fields & PCI_FILL_PHYS_SLOT))
+    {
+      struct pci_dev *pd;
+      sysfs_fill_slots(d->access);
+      for (pd = d->access->devices; pd; pd = pd->next)
+	pd->known_fields |= PCI_FILL_PHYS_SLOT;
+    }
+  return pci_generic_fill_info(d, flags);
+}
+
+/* Intent of the sysfs_setup() caller */
+enum
+  {
+    SETUP_READ_CONFIG = 0,
+    SETUP_WRITE_CONFIG = 1,
+    SETUP_READ_VPD = 2
+  };
+
 static int
-sysfs_setup(struct pci_dev *d, int rw)
+sysfs_setup(struct pci_dev *d, int intent)
 {
   struct pci_access *a = d->access;
+  char namebuf[OBJNAMELEN];
+
+  if (a->cached_dev != d || (intent == SETUP_WRITE_CONFIG && !a->fd_rw))
+    {
+      sysfs_flush_cache(a);
+      a->cached_dev = d;
+    }
+
+  if (intent == SETUP_READ_VPD)
+    {
+      if (a->fd_vpd < 0)
+	{
+	  sysfs_obj_name(d, "vpd", namebuf);
+	  a->fd_vpd = open(namebuf, O_RDONLY);
+	  /* No warning on error; vpd may be absent or accessible only to root */
+	}
+      return a->fd_vpd;
+    }
 
-  if (a->cached_dev != d || a->fd_rw < rw)
+  if (a->fd < 0)
     {
-      char namebuf[OBJNAMELEN];
-      if (a->fd >= 0)
-	close(a->fd);
       sysfs_obj_name(d, "config", namebuf);
-      a->fd_rw = a->writeable || rw;
+      a->fd_rw = a->writeable || intent == SETUP_WRITE_CONFIG;
       a->fd = open(namebuf, a->fd_rw ? O_RDWR : O_RDONLY);
       if (a->fd < 0)
 	a->warning("Cannot open %s", namebuf);
-      a->cached_dev = d;
       a->fd_pos = 0;
     }
   return a->fd;
@@ -200,7 +302,7 @@
 
 static int sysfs_read(struct pci_dev *d, int pos, byte *buf, int len)
 {
-  int fd = sysfs_setup(d, 0);
+  int fd = sysfs_setup(d, SETUP_READ_CONFIG);
   int res;
 
   if (fd < 0)
@@ -218,7 +320,7 @@
 
 static int sysfs_write(struct pci_dev *d, int pos, byte *buf, int len)
 {
-  int fd = sysfs_setup(d, 1);
+  int fd = sysfs_setup(d, SETUP_WRITE_CONFIG);
   int res;
 
   if (fd < 0)
@@ -237,16 +339,43 @@
   return 1;
 }
 
+#ifdef PCI_HAVE_DO_READ
+
+/* pread() is not available and do_read() only works for a single fd, so we
+ * cannot implement read_vpd properly. */
+static int sysfs_read_vpd(struct pci_dev *d, int pos, byte *buf, int len)
+{
+  return 0;
+}
+
+#else /* !PCI_HAVE_DO_READ */
+
+static int sysfs_read_vpd(struct pci_dev *d, int pos, byte *buf, int len)
+{
+  int fd = sysfs_setup(d, SETUP_READ_VPD);
+  int res;
+
+  if (fd < 0)
+    return 0;
+  res = pread(fd, buf, len, pos);
+  if (res < 0)
+    {
+      d->access->warning("sysfs_read_vpd: read failed: %s", strerror(errno));
+      return 0;
+    }
+  else if (res != len)
+    return 0;
+  return 1;
+}
+
+#endif /* PCI_HAVE_DO_READ */
+
 static void sysfs_cleanup_dev(struct pci_dev *d)
 {
   struct pci_access *a = d->access;
 
   if (a->cached_dev == d)
-    {
-      a->cached_dev = NULL;
-      close(a->fd);
-      a->fd = -1;
-    }
+    sysfs_flush_cache(a);
 }
 
 struct pci_methods pm_linux_sysfs = {
@@ -257,9 +386,10 @@
   sysfs_init,
   sysfs_cleanup,
   sysfs_scan,
-  pci_generic_fill_info,
+  sysfs_fill_info,
   sysfs_read,
   sysfs_write,
+  sysfs_read_vpd,
   NULL,					/* init_dev */
   sysfs_cleanup_dev
 };
diff -ruN pciutils-3.0.3/ls-caps.c pciutils-3.1.0/ls-caps.c
--- pciutils-3.0.3/ls-caps.c	1970-01-01 01:00:00.000000000 +0100
+++ pciutils-3.1.0/ls-caps.c	2008-12-12 23:50:54.000000000 +0100
@@ -0,0 +1,1250 @@
+/*
+ *	The PCI Utilities -- Show Capabilities
+ *
+ *	Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
+ *
+ *	Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "lspci.h"
+
+static void
+cap_pm(struct device *d, int where, int cap)
+{
+  int t, b;
+  static int pm_aux_current[8] = { 0, 55, 100, 160, 220, 270, 320, 375 };
+
+  printf("Power Management version %d\n", cap & PCI_PM_CAP_VER_MASK);
+  if (verbose < 2)
+    return;
+  printf("\t\tFlags: PMEClk%c DSI%c D1%c D2%c AuxCurrent=%dmA PME(D0%c,D1%c,D2%c,D3hot%c,D3cold%c)\n",
+	 FLAG(cap, PCI_PM_CAP_PME_CLOCK),
+	 FLAG(cap, PCI_PM_CAP_DSI),
+	 FLAG(cap, PCI_PM_CAP_D1),
+	 FLAG(cap, PCI_PM_CAP_D2),
+	 pm_aux_current[(cap >> 6) & 7],
+	 FLAG(cap, PCI_PM_CAP_PME_D0),
+	 FLAG(cap, PCI_PM_CAP_PME_D1),
+	 FLAG(cap, PCI_PM_CAP_PME_D2),
+	 FLAG(cap, PCI_PM_CAP_PME_D3_HOT),
+	 FLAG(cap, PCI_PM_CAP_PME_D3_COLD));
+  if (!config_fetch(d, where + PCI_PM_CTRL, PCI_PM_SIZEOF - PCI_PM_CTRL))
+    return;
+  t = get_conf_word(d, where + PCI_PM_CTRL);
+  printf("\t\tStatus: D%d PME-Enable%c DSel=%d DScale=%d PME%c\n",
+	 t & PCI_PM_CTRL_STATE_MASK,
+	 FLAG(t, PCI_PM_CTRL_PME_ENABLE),
+	 (t & PCI_PM_CTRL_DATA_SEL_MASK) >> 9,
+	 (t & PCI_PM_CTRL_DATA_SCALE_MASK) >> 13,
+	 FLAG(t, PCI_PM_CTRL_PME_STATUS));
+  b = get_conf_byte(d, where + PCI_PM_PPB_EXTENSIONS);
+  if (b)
+    printf("\t\tBridge: PM%c B3%c\n",
+	   FLAG(t, PCI_PM_BPCC_ENABLE),
+	   FLAG(~t, PCI_PM_PPB_B2_B3));
+}
+
+static void
+format_agp_rate(int rate, char *buf, int agp3)
+{
+  char *c = buf;
+  int i;
+
+  for (i=0; i<=2; i++)
+    if (rate & (1 << i))
+      {
+	if (c != buf)
+	  *c++ = ',';
+	c += sprintf(c, "x%d", 1 << (i + 2*agp3));
+      }
+  if (c != buf)
+    *c = 0;
+  else
+    strcpy(buf, "<none>");
+}
+
+static void
+cap_agp(struct device *d, int where, int cap)
+{
+  u32 t;
+  char rate[16];
+  int ver, rev;
+  int agp3 = 0;
+
+  ver = (cap >> 4) & 0x0f;
+  rev = cap & 0x0f;
+  printf("AGP version %x.%x\n", ver, rev);
+  if (verbose < 2)
+    return;
+  if (!config_fetch(d, where + PCI_AGP_STATUS, PCI_AGP_SIZEOF - PCI_AGP_STATUS))
+    return;
+  t = get_conf_long(d, where + PCI_AGP_STATUS);
+  if (ver >= 3 && (t & PCI_AGP_STATUS_AGP3))
+    agp3 = 1;
+  format_agp_rate(t & 7, rate, agp3);
+  printf("\t\tStatus: RQ=%d Iso%c ArqSz=%d Cal=%d SBA%c ITACoh%c GART64%c HTrans%c 64bit%c FW%c AGP3%c Rate=%s\n",
+	 ((t & PCI_AGP_STATUS_RQ_MASK) >> 24U) + 1,
+	 FLAG(t, PCI_AGP_STATUS_ISOCH),
+	 ((t & PCI_AGP_STATUS_ARQSZ_MASK) >> 13),
+	 ((t & PCI_AGP_STATUS_CAL_MASK) >> 10),
+	 FLAG(t, PCI_AGP_STATUS_SBA),
+	 FLAG(t, PCI_AGP_STATUS_ITA_COH),
+	 FLAG(t, PCI_AGP_STATUS_GART64),
+	 FLAG(t, PCI_AGP_STATUS_HTRANS),
+	 FLAG(t, PCI_AGP_STATUS_64BIT),
+	 FLAG(t, PCI_AGP_STATUS_FW),
+	 FLAG(t, PCI_AGP_STATUS_AGP3),
+	 rate);
+  t = get_conf_long(d, where + PCI_AGP_COMMAND);
+  format_agp_rate(t & 7, rate, agp3);
+  printf("\t\tCommand: RQ=%d ArqSz=%d Cal=%d SBA%c AGP%c GART64%c 64bit%c FW%c Rate=%s\n",
+	 ((t & PCI_AGP_COMMAND_RQ_MASK) >> 24U) + 1,
+	 ((t & PCI_AGP_COMMAND_ARQSZ_MASK) >> 13),
+	 ((t & PCI_AGP_COMMAND_CAL_MASK) >> 10),
+	 FLAG(t, PCI_AGP_COMMAND_SBA),
+	 FLAG(t, PCI_AGP_COMMAND_AGP),
+	 FLAG(t, PCI_AGP_COMMAND_GART64),
+	 FLAG(t, PCI_AGP_COMMAND_64BIT),
+	 FLAG(t, PCI_AGP_COMMAND_FW),
+	 rate);
+}
+
+static void
+cap_pcix_nobridge(struct device *d, int where)
+{
+  u16 command;
+  u32 status;
+  static const byte max_outstanding[8] = { 1, 2, 3, 4, 8, 12, 16, 32 };
+
+  printf("PCI-X non-bridge device\n");
+
+  if (verbose < 2)
+    return;
+
+  if (!config_fetch(d, where + PCI_PCIX_STATUS, 4))
+    return;
+
+  command = get_conf_word(d, where + PCI_PCIX_COMMAND);
+  status = get_conf_long(d, where + PCI_PCIX_STATUS);
+  printf("\t\tCommand: DPERE%c ERO%c RBC=%d OST=%d\n",
+	 FLAG(command, PCI_PCIX_COMMAND_DPERE),
+	 FLAG(command, PCI_PCIX_COMMAND_ERO),
+	 1 << (9 + ((command & PCI_PCIX_COMMAND_MAX_MEM_READ_BYTE_COUNT) >> 2U)),
+	 max_outstanding[(command & PCI_PCIX_COMMAND_MAX_OUTSTANDING_SPLIT_TRANS) >> 4U]);
+  printf("\t\tStatus: Dev=%02x:%02x.%d 64bit%c 133MHz%c SCD%c USC%c DC=%s DMMRBC=%u DMOST=%u DMCRS=%u RSCEM%c 266MHz%c 533MHz%c\n",
+	 ((status >> 8) & 0xff),
+	 ((status >> 3) & 0x1f),
+	 (status & PCI_PCIX_STATUS_FUNCTION),
+	 FLAG(status, PCI_PCIX_STATUS_64BIT),
+	 FLAG(status, PCI_PCIX_STATUS_133MHZ),
+	 FLAG(status, PCI_PCIX_STATUS_SC_DISCARDED),
+	 FLAG(status, PCI_PCIX_STATUS_UNEXPECTED_SC),
+	 ((status & PCI_PCIX_STATUS_DEVICE_COMPLEXITY) ? "bridge" : "simple"),
+	 1 << (9 + ((status >> 21) & 3U)),
+	 max_outstanding[(status >> 23) & 7U],
+	 1 << (3 + ((status >> 26) & 7U)),
+	 FLAG(status, PCI_PCIX_STATUS_RCVD_SC_ERR_MESS),
+	 FLAG(status, PCI_PCIX_STATUS_266MHZ),
+	 FLAG(status, PCI_PCIX_STATUS_533MHZ));
+}
+
+static void
+cap_pcix_bridge(struct device *d, int where)
+{
+  static const char * const sec_clock_freq[8] = { "conv", "66MHz", "100MHz", "133MHz", "?4", "?5", "?6", "?7" };
+  u16 secstatus;
+  u32 status, upstcr, downstcr;
+
+  printf("PCI-X bridge device\n");
+
+  if (verbose < 2)
+    return;
+
+  if (!config_fetch(d, where + PCI_PCIX_BRIDGE_STATUS, 12))
+    return;
+
+  secstatus = get_conf_word(d, where + PCI_PCIX_BRIDGE_SEC_STATUS);
+  printf("\t\tSecondary Status: 64bit%c 133MHz%c SCD%c USC%c SCO%c SRD%c Freq=%s\n",
+	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_64BIT),
+	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_133MHZ),
+	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_SC_DISCARDED),
+	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_UNEXPECTED_SC),
+	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_SC_OVERRUN),
+	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_SPLIT_REQUEST_DELAYED),
+	 sec_clock_freq[(secstatus >> 6) & 7]);
+  status = get_conf_long(d, where + PCI_PCIX_BRIDGE_STATUS);
+  printf("\t\tStatus: Dev=%02x:%02x.%d 64bit%c 133MHz%c SCD%c USC%c SCO%c SRD%c\n",
+	 ((status >> 8) & 0xff),
+	 ((status >> 3) & 0x1f),
+	 (status & PCI_PCIX_BRIDGE_STATUS_FUNCTION),
+	 FLAG(status, PCI_PCIX_BRIDGE_STATUS_64BIT),
+	 FLAG(status, PCI_PCIX_BRIDGE_STATUS_133MHZ),
+	 FLAG(status, PCI_PCIX_BRIDGE_STATUS_SC_DISCARDED),
+	 FLAG(status, PCI_PCIX_BRIDGE_STATUS_UNEXPECTED_SC),
+	 FLAG(status, PCI_PCIX_BRIDGE_STATUS_SC_OVERRUN),
+	 FLAG(status, PCI_PCIX_BRIDGE_STATUS_SPLIT_REQUEST_DELAYED));
+  upstcr = get_conf_long(d, where + PCI_PCIX_BRIDGE_UPSTREAM_SPLIT_TRANS_CTRL);
+  printf("\t\tUpstream: Capacity=%u CommitmentLimit=%u\n",
+	 (upstcr & PCI_PCIX_BRIDGE_STR_CAPACITY),
+	 (upstcr >> 16) & 0xffff);
+  downstcr = get_conf_long(d, where + PCI_PCIX_BRIDGE_DOWNSTREAM_SPLIT_TRANS_CTRL);
+  printf("\t\tDownstream: Capacity=%u CommitmentLimit=%u\n",
+	 (downstcr & PCI_PCIX_BRIDGE_STR_CAPACITY),
+	 (downstcr >> 16) & 0xffff);
+}
+
+static void
+cap_pcix(struct device *d, int where)
+{
+  switch (get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f)
+    {
+    case PCI_HEADER_TYPE_NORMAL:
+      cap_pcix_nobridge(d, where);
+      break;
+    case PCI_HEADER_TYPE_BRIDGE:
+      cap_pcix_bridge(d, where);
+      break;
+    }
+}
+
+static inline char *
+ht_link_width(unsigned width)
+{
+  static char * const widths[8] = { "8bit", "16bit", "[2]", "32bit", "2bit", "4bit", "[6]", "N/C" };
+  return widths[width];
+}
+
+static inline char *
+ht_link_freq(unsigned freq)
+{
+  static char * const freqs[16] = { "200MHz", "300MHz", "400MHz", "500MHz", "600MHz", "800MHz", "1.0GHz", "1.2GHz",
+				    "1.4GHz", "1.6GHz", "[a]", "[b]", "[c]", "[d]", "[e]", "Vend" };
+  return freqs[freq];
+}
+
+static void
+cap_ht_pri(struct device *d, int where, int cmd)
+{
+  u16 lctr0, lcnf0, lctr1, lcnf1, eh;
+  u8 rid, lfrer0, lfcap0, ftr, lfrer1, lfcap1, mbu, mlu, bn;
+  char *fmt;
+
+  printf("HyperTransport: Slave or Primary Interface\n");
+  if (verbose < 2)
+    return;
+
+  if (!config_fetch(d, where + PCI_HT_PRI_LCTR0, PCI_HT_PRI_SIZEOF - PCI_HT_PRI_LCTR0))
+    return;
+  rid = get_conf_byte(d, where + PCI_HT_PRI_RID);
+  if (rid < 0x22 && rid > 0x11)
+    printf("\t\t!!! Possibly incomplete decoding\n");
+
+  if (rid >= 0x22)
+    fmt = "\t\tCommand: BaseUnitID=%u UnitCnt=%u MastHost%c DefDir%c DUL%c\n";
+  else
+    fmt = "\t\tCommand: BaseUnitID=%u UnitCnt=%u MastHost%c DefDir%c\n";
+  printf(fmt,
+	 (cmd & PCI_HT_PRI_CMD_BUID),
+	 (cmd & PCI_HT_PRI_CMD_UC) >> 5,
+	 FLAG(cmd, PCI_HT_PRI_CMD_MH),
+	 FLAG(cmd, PCI_HT_PRI_CMD_DD),
+	 FLAG(cmd, PCI_HT_PRI_CMD_DUL));
+  lctr0 = get_conf_word(d, where + PCI_HT_PRI_LCTR0);
+  if (rid >= 0x22)
+    fmt = "\t\tLink Control 0: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x IsocEn%c LSEn%c ExtCTL%c 64b%c\n";
+  else
+    fmt = "\t\tLink Control 0: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x\n";
+  printf(fmt,
+	 FLAG(lctr0, PCI_HT_LCTR_CFLE),
+	 FLAG(lctr0, PCI_HT_LCTR_CST),
+	 FLAG(lctr0, PCI_HT_LCTR_CFE),
+	 FLAG(lctr0, PCI_HT_LCTR_LKFAIL),
+	 FLAG(lctr0, PCI_HT_LCTR_INIT),
+	 FLAG(lctr0, PCI_HT_LCTR_EOC),
+	 FLAG(lctr0, PCI_HT_LCTR_TXO),
+	 (lctr0 & PCI_HT_LCTR_CRCERR) >> 8,
+	 FLAG(lctr0, PCI_HT_LCTR_ISOCEN),
+	 FLAG(lctr0, PCI_HT_LCTR_LSEN),
+	 FLAG(lctr0, PCI_HT_LCTR_EXTCTL),
+	 FLAG(lctr0, PCI_HT_LCTR_64B));
+  lcnf0 = get_conf_word(d, where + PCI_HT_PRI_LCNF0);
+  if (rid >= 0x22)
+    fmt = "\t\tLink Config 0: MLWI=%1$s DwFcIn%5$c MLWO=%2$s DwFcOut%6$c LWI=%3$s DwFcInEn%7$c LWO=%4$s DwFcOutEn%8$c\n";
+  else
+    fmt = "\t\tLink Config 0: MLWI=%s MLWO=%s LWI=%s LWO=%s\n";
+  printf(fmt,
+	 ht_link_width(lcnf0 & PCI_HT_LCNF_MLWI),
+	 ht_link_width((lcnf0 & PCI_HT_LCNF_MLWO) >> 4),
+	 ht_link_width((lcnf0 & PCI_HT_LCNF_LWI) >> 8),
+	 ht_link_width((lcnf0 & PCI_HT_LCNF_LWO) >> 12),
+	 FLAG(lcnf0, PCI_HT_LCNF_DFI),
+	 FLAG(lcnf0, PCI_HT_LCNF_DFO),
+	 FLAG(lcnf0, PCI_HT_LCNF_DFIE),
+	 FLAG(lcnf0, PCI_HT_LCNF_DFOE));
+  lctr1 = get_conf_word(d, where + PCI_HT_PRI_LCTR1);
+  if (rid >= 0x22)
+    fmt = "\t\tLink Control 1: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x IsocEn%c LSEn%c ExtCTL%c 64b%c\n";
+  else
+    fmt = "\t\tLink Control 1: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x\n";
+  printf(fmt,
+	 FLAG(lctr1, PCI_HT_LCTR_CFLE),
+	 FLAG(lctr1, PCI_HT_LCTR_CST),
+	 FLAG(lctr1, PCI_HT_LCTR_CFE),
+	 FLAG(lctr1, PCI_HT_LCTR_LKFAIL),
+	 FLAG(lctr1, PCI_HT_LCTR_INIT),
+	 FLAG(lctr1, PCI_HT_LCTR_EOC),
+	 FLAG(lctr1, PCI_HT_LCTR_TXO),
+	 (lctr1 & PCI_HT_LCTR_CRCERR) >> 8,
+	 FLAG(lctr1, PCI_HT_LCTR_ISOCEN),
+	 FLAG(lctr1, PCI_HT_LCTR_LSEN),
+	 FLAG(lctr1, PCI_HT_LCTR_EXTCTL),
+	 FLAG(lctr1, PCI_HT_LCTR_64B));
+  lcnf1 = get_conf_word(d, where + PCI_HT_PRI_LCNF1);
+  if (rid >= 0x22)
+    fmt = "\t\tLink Config 1: MLWI=%1$s DwFcIn%5$c MLWO=%2$s DwFcOut%6$c LWI=%3$s DwFcInEn%7$c LWO=%4$s DwFcOutEn%8$c\n";
+  else
+    fmt = "\t\tLink Config 1: MLWI=%s MLWO=%s LWI=%s LWO=%s\n";
+  printf(fmt,
+	 ht_link_width(lcnf1 & PCI_HT_LCNF_MLWI),
+	 ht_link_width((lcnf1 & PCI_HT_LCNF_MLWO) >> 4),
+	 ht_link_width((lcnf1 & PCI_HT_LCNF_LWI) >> 8),
+	 ht_link_width((lcnf1 & PCI_HT_LCNF_LWO) >> 12),
+	 FLAG(lcnf1, PCI_HT_LCNF_DFI),
+	 FLAG(lcnf1, PCI_HT_LCNF_DFO),
+	 FLAG(lcnf1, PCI_HT_LCNF_DFIE),
+	 FLAG(lcnf1, PCI_HT_LCNF_DFOE));
+  printf("\t\tRevision ID: %u.%02u\n",
+	 (rid & PCI_HT_RID_MAJ) >> 5, (rid & PCI_HT_RID_MIN));
+  if (rid < 0x22)
+    return;
+  lfrer0 = get_conf_byte(d, where + PCI_HT_PRI_LFRER0);
+  printf("\t\tLink Frequency 0: %s\n", ht_link_freq(lfrer0 & PCI_HT_LFRER_FREQ));
+  printf("\t\tLink Error 0: <Prot%c <Ovfl%c <EOC%c CTLTm%c\n",
+	 FLAG(lfrer0, PCI_HT_LFRER_PROT),
+	 FLAG(lfrer0, PCI_HT_LFRER_OV),
+	 FLAG(lfrer0, PCI_HT_LFRER_EOC),
+	 FLAG(lfrer0, PCI_HT_LFRER_CTLT));
+  lfcap0 = get_conf_byte(d, where + PCI_HT_PRI_LFCAP0);
+  printf("\t\tLink Frequency Capability 0: 200MHz%c 300MHz%c 400MHz%c 500MHz%c 600MHz%c 800MHz%c 1.0GHz%c 1.2GHz%c 1.4GHz%c 1.6GHz%c Vend%c\n",
+	 FLAG(lfcap0, PCI_HT_LFCAP_200),
+	 FLAG(lfcap0, PCI_HT_LFCAP_300),
+	 FLAG(lfcap0, PCI_HT_LFCAP_400),
+	 FLAG(lfcap0, PCI_HT_LFCAP_500),
+	 FLAG(lfcap0, PCI_HT_LFCAP_600),
+	 FLAG(lfcap0, PCI_HT_LFCAP_800),
+	 FLAG(lfcap0, PCI_HT_LFCAP_1000),
+	 FLAG(lfcap0, PCI_HT_LFCAP_1200),
+	 FLAG(lfcap0, PCI_HT_LFCAP_1400),
+	 FLAG(lfcap0, PCI_HT_LFCAP_1600),
+	 FLAG(lfcap0, PCI_HT_LFCAP_VEND));
+  ftr = get_conf_byte(d, where + PCI_HT_PRI_FTR);
+  printf("\t\tFeature Capability: IsocFC%c LDTSTOP%c CRCTM%c ECTLT%c 64bA%c UIDRD%c\n",
+	 FLAG(ftr, PCI_HT_FTR_ISOCFC),
+	 FLAG(ftr, PCI_HT_FTR_LDTSTOP),
+	 FLAG(ftr, PCI_HT_FTR_CRCTM),
+	 FLAG(ftr, PCI_HT_FTR_ECTLT),
+	 FLAG(ftr, PCI_HT_FTR_64BA),
+	 FLAG(ftr, PCI_HT_FTR_UIDRD));
+  lfrer1 = get_conf_byte(d, where + PCI_HT_PRI_LFRER1);
+  printf("\t\tLink Frequency 1: %s\n", ht_link_freq(lfrer1 & PCI_HT_LFRER_FREQ));
+  printf("\t\tLink Error 1: <Prot%c <Ovfl%c <EOC%c CTLTm%c\n",
+	 FLAG(lfrer1, PCI_HT_LFRER_PROT),
+	 FLAG(lfrer1, PCI_HT_LFRER_OV),
+	 FLAG(lfrer1, PCI_HT_LFRER_EOC),
+	 FLAG(lfrer1, PCI_HT_LFRER_CTLT));
+  lfcap1 = get_conf_byte(d, where + PCI_HT_PRI_LFCAP1);
+  printf("\t\tLink Frequency Capability 1: 200MHz%c 300MHz%c 400MHz%c 500MHz%c 600MHz%c 800MHz%c 1.0GHz%c 1.2GHz%c 1.4GHz%c 1.6GHz%c Vend%c\n",
+	 FLAG(lfcap1, PCI_HT_LFCAP_200),
+	 FLAG(lfcap1, PCI_HT_LFCAP_300),
+	 FLAG(lfcap1, PCI_HT_LFCAP_400),
+	 FLAG(lfcap1, PCI_HT_LFCAP_500),
+	 FLAG(lfcap1, PCI_HT_LFCAP_600),
+	 FLAG(lfcap1, PCI_HT_LFCAP_800),
+	 FLAG(lfcap1, PCI_HT_LFCAP_1000),
+	 FLAG(lfcap1, PCI_HT_LFCAP_1200),
+	 FLAG(lfcap1, PCI_HT_LFCAP_1400),
+	 FLAG(lfcap1, PCI_HT_LFCAP_1600),
+	 FLAG(lfcap1, PCI_HT_LFCAP_VEND));
+  eh = get_conf_word(d, where + PCI_HT_PRI_EH);
+  printf("\t\tError Handling: PFlE%c OFlE%c PFE%c OFE%c EOCFE%c RFE%c CRCFE%c SERRFE%c CF%c RE%c PNFE%c ONFE%c EOCNFE%c RNFE%c CRCNFE%c SERRNFE%c\n",
+	 FLAG(eh, PCI_HT_EH_PFLE),
+	 FLAG(eh, PCI_HT_EH_OFLE),
+	 FLAG(eh, PCI_HT_EH_PFE),
+	 FLAG(eh, PCI_HT_EH_OFE),
+	 FLAG(eh, PCI_HT_EH_EOCFE),
+	 FLAG(eh, PCI_HT_EH_RFE),
+	 FLAG(eh, PCI_HT_EH_CRCFE),
+	 FLAG(eh, PCI_HT_EH_SERRFE),
+	 FLAG(eh, PCI_HT_EH_CF),
+	 FLAG(eh, PCI_HT_EH_RE),
+	 FLAG(eh, PCI_HT_EH_PNFE),
+	 FLAG(eh, PCI_HT_EH_ONFE),
+	 FLAG(eh, PCI_HT_EH_EOCNFE),
+	 FLAG(eh, PCI_HT_EH_RNFE),
+	 FLAG(eh, PCI_HT_EH_CRCNFE),
+	 FLAG(eh, PCI_HT_EH_SERRNFE));
+  mbu = get_conf_byte(d, where + PCI_HT_PRI_MBU);
+  mlu = get_conf_byte(d, where + PCI_HT_PRI_MLU);
+  printf("\t\tPrefetchable memory behind bridge Upper: %02x-%02x\n", mbu, mlu);
+  bn = get_conf_byte(d, where + PCI_HT_PRI_BN);
+  printf("\t\tBus Number: %02x\n", bn);
+}
+
+static void
+cap_ht_sec(struct device *d, int where, int cmd)
+{
+  u16 lctr, lcnf, ftr, eh;
+  u8 rid, lfrer, lfcap, mbu, mlu;
+  char *fmt;
+
+  printf("HyperTransport: Host or Secondary Interface\n");
+  if (verbose < 2)
+    return;
+
+  if (!config_fetch(d, where + PCI_HT_SEC_LCTR, PCI_HT_SEC_SIZEOF - PCI_HT_SEC_LCTR))
+    return;
+  rid = get_conf_byte(d, where + PCI_HT_SEC_RID);
+  if (rid < 0x22 && rid > 0x11)
+    printf("\t\t!!! Possibly incomplete decoding\n");
+
+  if (rid >= 0x22)
+    fmt = "\t\tCommand: WarmRst%c DblEnd%c DevNum=%u ChainSide%c HostHide%c Slave%c <EOCErr%c DUL%c\n";
+  else
+    fmt = "\t\tCommand: WarmRst%c DblEnd%c\n";
+  printf(fmt,
+	 FLAG(cmd, PCI_HT_SEC_CMD_WR),
+	 FLAG(cmd, PCI_HT_SEC_CMD_DE),
+	 (cmd & PCI_HT_SEC_CMD_DN) >> 2,
+	 FLAG(cmd, PCI_HT_SEC_CMD_CS),
+	 FLAG(cmd, PCI_HT_SEC_CMD_HH),
+	 FLAG(cmd, PCI_HT_SEC_CMD_AS),
+	 FLAG(cmd, PCI_HT_SEC_CMD_HIECE),
+	 FLAG(cmd, PCI_HT_SEC_CMD_DUL));
+  lctr = get_conf_word(d, where + PCI_HT_SEC_LCTR);
+  if (rid >= 0x22)
+    fmt = "\t\tLink Control: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x IsocEn%c LSEn%c ExtCTL%c 64b%c\n";
+  else
+    fmt = "\t\tLink Control: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x\n";
+  printf(fmt,
+	 FLAG(lctr, PCI_HT_LCTR_CFLE),
+	 FLAG(lctr, PCI_HT_LCTR_CST),
+	 FLAG(lctr, PCI_HT_LCTR_CFE),
+	 FLAG(lctr, PCI_HT_LCTR_LKFAIL),
+	 FLAG(lctr, PCI_HT_LCTR_INIT),
+	 FLAG(lctr, PCI_HT_LCTR_EOC),
+	 FLAG(lctr, PCI_HT_LCTR_TXO),
+	 (lctr & PCI_HT_LCTR_CRCERR) >> 8,
+	 FLAG(lctr, PCI_HT_LCTR_ISOCEN),
+	 FLAG(lctr, PCI_HT_LCTR_LSEN),
+	 FLAG(lctr, PCI_HT_LCTR_EXTCTL),
+	 FLAG(lctr, PCI_HT_LCTR_64B));
+  lcnf = get_conf_word(d, where + PCI_HT_SEC_LCNF);
+  if (rid >= 0x22)
+    fmt = "\t\tLink Config: MLWI=%1$s DwFcIn%5$c MLWO=%2$s DwFcOut%6$c LWI=%3$s DwFcInEn%7$c LWO=%4$s DwFcOutEn%8$c\n";
+  else
+    fmt = "\t\tLink Config: MLWI=%s MLWO=%s LWI=%s LWO=%s\n";
+  printf(fmt,
+	 ht_link_width(lcnf & PCI_HT_LCNF_MLWI),
+	 ht_link_width((lcnf & PCI_HT_LCNF_MLWO) >> 4),
+	 ht_link_width((lcnf & PCI_HT_LCNF_LWI) >> 8),
+	 ht_link_width((lcnf & PCI_HT_LCNF_LWO) >> 12),
+	 FLAG(lcnf, PCI_HT_LCNF_DFI),
+	 FLAG(lcnf, PCI_HT_LCNF_DFO),
+	 FLAG(lcnf, PCI_HT_LCNF_DFIE),
+	 FLAG(lcnf, PCI_HT_LCNF_DFOE));
+  printf("\t\tRevision ID: %u.%02u\n",
+	 (rid & PCI_HT_RID_MAJ) >> 5, (rid & PCI_HT_RID_MIN));
+  if (rid < 0x22)
+    return;
+  lfrer = get_conf_byte(d, where + PCI_HT_SEC_LFRER);
+  printf("\t\tLink Frequency: %s\n", ht_link_freq(lfrer & PCI_HT_LFRER_FREQ));
+  printf("\t\tLink Error: <Prot%c <Ovfl%c <EOC%c CTLTm%c\n",
+	 FLAG(lfrer, PCI_HT_LFRER_PROT),
+	 FLAG(lfrer, PCI_HT_LFRER_OV),
+	 FLAG(lfrer, PCI_HT_LFRER_EOC),
+	 FLAG(lfrer, PCI_HT_LFRER_CTLT));
+  lfcap = get_conf_byte(d, where + PCI_HT_SEC_LFCAP);
+  printf("\t\tLink Frequency Capability: 200MHz%c 300MHz%c 400MHz%c 500MHz%c 600MHz%c 800MHz%c 1.0GHz%c 1.2GHz%c 1.4GHz%c 1.6GHz%c Vend%c\n",
+	 FLAG(lfcap, PCI_HT_LFCAP_200),
+	 FLAG(lfcap, PCI_HT_LFCAP_300),
+	 FLAG(lfcap, PCI_HT_LFCAP_400),
+	 FLAG(lfcap, PCI_HT_LFCAP_500),
+	 FLAG(lfcap, PCI_HT_LFCAP_600),
+	 FLAG(lfcap, PCI_HT_LFCAP_800),
+	 FLAG(lfcap, PCI_HT_LFCAP_1000),
+	 FLAG(lfcap, PCI_HT_LFCAP_1200),
+	 FLAG(lfcap, PCI_HT_LFCAP_1400),
+	 FLAG(lfcap, PCI_HT_LFCAP_1600),
+	 FLAG(lfcap, PCI_HT_LFCAP_VEND));
+  ftr = get_conf_word(d, where + PCI_HT_SEC_FTR);
+  printf("\t\tFeature Capability: IsocFC%c LDTSTOP%c CRCTM%c ECTLT%c 64bA%c UIDRD%c ExtRS%c UCnfE%c\n",
+	 FLAG(ftr, PCI_HT_FTR_ISOCFC),
+	 FLAG(ftr, PCI_HT_FTR_LDTSTOP),
+	 FLAG(ftr, PCI_HT_FTR_CRCTM),
+	 FLAG(ftr, PCI_HT_FTR_ECTLT),
+	 FLAG(ftr, PCI_HT_FTR_64BA),
+	 FLAG(ftr, PCI_HT_FTR_UIDRD),
+	 FLAG(ftr, PCI_HT_SEC_FTR_EXTRS),
+	 FLAG(ftr, PCI_HT_SEC_FTR_UCNFE));
+  if (ftr & PCI_HT_SEC_FTR_EXTRS)
+    {
+      eh = get_conf_word(d, where + PCI_HT_SEC_EH);
+      printf("\t\tError Handling: PFlE%c OFlE%c PFE%c OFE%c EOCFE%c RFE%c CRCFE%c SERRFE%c CF%c RE%c PNFE%c ONFE%c EOCNFE%c RNFE%c CRCNFE%c SERRNFE%c\n",
+	     FLAG(eh, PCI_HT_EH_PFLE),
+	     FLAG(eh, PCI_HT_EH_OFLE),
+	     FLAG(eh, PCI_HT_EH_PFE),
+	     FLAG(eh, PCI_HT_EH_OFE),
+	     FLAG(eh, PCI_HT_EH_EOCFE),
+	     FLAG(eh, PCI_HT_EH_RFE),
+	     FLAG(eh, PCI_HT_EH_CRCFE),
+	     FLAG(eh, PCI_HT_EH_SERRFE),
+	     FLAG(eh, PCI_HT_EH_CF),
+	     FLAG(eh, PCI_HT_EH_RE),
+	     FLAG(eh, PCI_HT_EH_PNFE),
+	     FLAG(eh, PCI_HT_EH_ONFE),
+	     FLAG(eh, PCI_HT_EH_EOCNFE),
+	     FLAG(eh, PCI_HT_EH_RNFE),
+	     FLAG(eh, PCI_HT_EH_CRCNFE),
+	     FLAG(eh, PCI_HT_EH_SERRNFE));
+      mbu = get_conf_byte(d, where + PCI_HT_SEC_MBU);
+      mlu = get_conf_byte(d, where + PCI_HT_SEC_MLU);
+      printf("\t\tPrefetchable memory behind bridge Upper: %02x-%02x\n", mbu, mlu);
+    }
+}
+
+static void
+cap_ht(struct device *d, int where, int cmd)
+{
+  int type;
+
+  switch (cmd & PCI_HT_CMD_TYP_HI)
+    {
+    case PCI_HT_CMD_TYP_HI_PRI:
+      cap_ht_pri(d, where, cmd);
+      return;
+    case PCI_HT_CMD_TYP_HI_SEC:
+      cap_ht_sec(d, where, cmd);
+      return;
+    }
+
+  type = cmd & PCI_HT_CMD_TYP;
+  switch (type)
+    {
+    case PCI_HT_CMD_TYP_SW:
+      printf("HyperTransport: Switch\n");
+      break;
+    case PCI_HT_CMD_TYP_IDC:
+      printf("HyperTransport: Interrupt Discovery and Configuration\n");
+      break;
+    case PCI_HT_CMD_TYP_RID:
+      printf("HyperTransport: Revision ID: %u.%02u\n",
+	     (cmd & PCI_HT_RID_MAJ) >> 5, (cmd & PCI_HT_RID_MIN));
+      break;
+    case PCI_HT_CMD_TYP_UIDC:
+      printf("HyperTransport: UnitID Clumping\n");
+      break;
+    case PCI_HT_CMD_TYP_ECSA:
+      printf("HyperTransport: Extended Configuration Space Access\n");
+      break;
+    case PCI_HT_CMD_TYP_AM:
+      printf("HyperTransport: Address Mapping\n");
+      break;
+    case PCI_HT_CMD_TYP_MSIM:
+      printf("HyperTransport: MSI Mapping Enable%c Fixed%c\n",
+	     FLAG(cmd, PCI_HT_MSIM_CMD_EN),
+	     FLAG(cmd, PCI_HT_MSIM_CMD_FIXD));
+      if (verbose >= 2 && !(cmd & PCI_HT_MSIM_CMD_FIXD))
+	{
+	  u32 offl, offh;
+	  if (!config_fetch(d, where + PCI_HT_MSIM_ADDR_LO, 8))
+	    break;
+	  offl = get_conf_long(d, where + PCI_HT_MSIM_ADDR_LO);
+	  offh = get_conf_long(d, where + PCI_HT_MSIM_ADDR_HI);
+	  printf("\t\tMapping Address Base: %016llx\n", ((unsigned long long)offh << 32) | (offl & ~0xfffff));
+	}
+      break;
+    case PCI_HT_CMD_TYP_DR:
+      printf("HyperTransport: DirectRoute\n");
+      break;
+    case PCI_HT_CMD_TYP_VCS:
+      printf("HyperTransport: VCSet\n");
+      break;
+    case PCI_HT_CMD_TYP_RM:
+      printf("HyperTransport: Retry Mode\n");
+      break;
+    case PCI_HT_CMD_TYP_X86:
+      printf("HyperTransport: X86 (reserved)\n");
+      break;
+    default:
+      printf("HyperTransport: #%02x\n", type >> 11);
+    }
+}
+
+static void
+cap_msi(struct device *d, int where, int cap)
+{
+  int is64;
+  u32 t;
+  u16 w;
+
+  printf("MSI: Mask%c 64bit%c Count=%d/%d Enable%c\n",
+         FLAG(cap, PCI_MSI_FLAGS_MASK_BIT),
+	 FLAG(cap, PCI_MSI_FLAGS_64BIT),
+	 1 << ((cap & PCI_MSI_FLAGS_QSIZE) >> 4),
+	 1 << ((cap & PCI_MSI_FLAGS_QMASK) >> 1),
+	 FLAG(cap, PCI_MSI_FLAGS_ENABLE));
+  if (verbose < 2)
+    return;
+  is64 = cap & PCI_MSI_FLAGS_64BIT;
+  if (!config_fetch(d, where + PCI_MSI_ADDRESS_LO, (is64 ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32) + 2 - PCI_MSI_ADDRESS_LO))
+    return;
+  printf("\t\tAddress: ");
+  if (is64)
+    {
+      t = get_conf_long(d, where + PCI_MSI_ADDRESS_HI);
+      w = get_conf_word(d, where + PCI_MSI_DATA_64);
+      printf("%08x", t);
+    }
+  else
+    w = get_conf_word(d, where + PCI_MSI_DATA_32);
+  t = get_conf_long(d, where + PCI_MSI_ADDRESS_LO);
+  printf("%08x  Data: %04x\n", t, w);
+  if (cap & PCI_MSI_FLAGS_MASK_BIT)
+    {
+      u32 mask, pending;
+
+      if (is64)
+	{
+	  if (!config_fetch(d, where + PCI_MSI_MASK_BIT_64, 8))
+	    return;
+	  mask = get_conf_long(d, where + PCI_MSI_MASK_BIT_64);
+	  pending = get_conf_long(d, where + PCI_MSI_PENDING_64);
+	}
+      else
+        {
+	  if (!config_fetch(d, where + PCI_MSI_MASK_BIT_32, 8))
+	    return;
+	  mask = get_conf_long(d, where + PCI_MSI_MASK_BIT_32);
+	  pending = get_conf_long(d, where + PCI_MSI_PENDING_32);
+	}
+      printf("\t\tMasking: %08x  Pending: %08x\n", mask, pending);
+    }
+}
+
+static float power_limit(int value, int scale)
+{
+  static const float scales[4] = { 1.0, 0.1, 0.01, 0.001 };
+  return value * scales[scale];
+}
+
+static const char *latency_l0s(int value)
+{
+  static const char *latencies[] = { "<64ns", "<128ns", "<256ns", "<512ns", "<1us", "<2us", "<4us", "unlimited" };
+  return latencies[value];
+}
+
+static const char *latency_l1(int value)
+{
+  static const char *latencies[] = { "<1us", "<2us", "<4us", "<8us", "<16us", "<32us", "<64us", "unlimited" };
+  return latencies[value];
+}
+
+static void cap_express_dev(struct device *d, int where, int type)
+{
+  u32 t;
+  u16 w;
+
+  t = get_conf_long(d, where + PCI_EXP_DEVCAP);
+  printf("\t\tDevCap:\tMaxPayload %d bytes, PhantFunc %d, Latency L0s %s, L1 %s\n",
+	128 << (t & PCI_EXP_DEVCAP_PAYLOAD),
+	(1 << ((t & PCI_EXP_DEVCAP_PHANTOM) >> 3)) - 1,
+	latency_l0s((t & PCI_EXP_DEVCAP_L0S) >> 6),
+	latency_l1((t & PCI_EXP_DEVCAP_L1) >> 9));
+  printf("\t\t\tExtTag%c", FLAG(t, PCI_EXP_DEVCAP_EXT_TAG));
+  if ((type == PCI_EXP_TYPE_ENDPOINT) || (type == PCI_EXP_TYPE_LEG_END) ||
+      (type == PCI_EXP_TYPE_UPSTREAM) || (type == PCI_EXP_TYPE_PCI_BRIDGE))
+    printf(" AttnBtn%c AttnInd%c PwrInd%c",
+	FLAG(t, PCI_EXP_DEVCAP_ATN_BUT),
+	FLAG(t, PCI_EXP_DEVCAP_ATN_IND), FLAG(t, PCI_EXP_DEVCAP_PWR_IND));
+  printf(" RBE%c FLReset%c",
+	FLAG(t, PCI_EXP_DEVCAP_RBE),
+	FLAG(t, PCI_EXP_DEVCAP_FLRESET));
+  if (type == PCI_EXP_TYPE_UPSTREAM)
+    printf("SlotPowerLimit %fW",
+	power_limit((t & PCI_EXP_DEVCAP_PWR_VAL) >> 18,
+		    (t & PCI_EXP_DEVCAP_PWR_SCL) >> 26));
+  printf("\n");
+
+  w = get_conf_word(d, where + PCI_EXP_DEVCTL);
+  printf("\t\tDevCtl:\tReport errors: Correctable%c Non-Fatal%c Fatal%c Unsupported%c\n",
+	FLAG(w, PCI_EXP_DEVCTL_CERE),
+	FLAG(w, PCI_EXP_DEVCTL_NFERE),
+	FLAG(w, PCI_EXP_DEVCTL_FERE),
+	FLAG(w, PCI_EXP_DEVCTL_URRE));
+  printf("\t\t\tRlxdOrd%c ExtTag%c PhantFunc%c AuxPwr%c NoSnoop%c",
+	FLAG(w, PCI_EXP_DEVCTL_RELAXED),
+	FLAG(w, PCI_EXP_DEVCTL_EXT_TAG),
+	FLAG(w, PCI_EXP_DEVCTL_PHANTOM),
+	FLAG(w, PCI_EXP_DEVCTL_AUX_PME),
+	FLAG(w, PCI_EXP_DEVCTL_NOSNOOP));
+  if (type == PCI_EXP_TYPE_PCI_BRIDGE || type == PCI_EXP_TYPE_PCIE_BRIDGE)
+    printf(" BrConfRtry%c", FLAG(w, PCI_EXP_DEVCTL_BCRE));
+  if (type == PCI_EXP_TYPE_ENDPOINT && (t & PCI_EXP_DEVCAP_FLRESET))
+    printf(" FLReset%c", FLAG(w, PCI_EXP_DEVCTL_FLRESET));
+  printf("\n\t\t\tMaxPayload %d bytes, MaxReadReq %d bytes\n",
+	128 << ((w & PCI_EXP_DEVCTL_PAYLOAD) >> 5),
+	128 << ((w & PCI_EXP_DEVCTL_READRQ) >> 12));
+
+  w = get_conf_word(d, where + PCI_EXP_DEVSTA);
+  printf("\t\tDevSta:\tCorrErr%c UncorrErr%c FatalErr%c UnsuppReq%c AuxPwr%c TransPend%c\n",
+	FLAG(w, PCI_EXP_DEVSTA_CED),
+	FLAG(w, PCI_EXP_DEVSTA_NFED),
+	FLAG(w, PCI_EXP_DEVSTA_FED),
+	FLAG(w, PCI_EXP_DEVSTA_URD),
+	FLAG(w, PCI_EXP_DEVSTA_AUXPD),
+	FLAG(w, PCI_EXP_DEVSTA_TRPND));
+}
+
+static char *link_speed(int speed)
+{
+  switch (speed)
+    {
+      case 1:
+	return "2.5GT/s";
+      case 2:
+	return "5GT/s";
+      default:
+	return "unknown";
+    }
+}
+
+static char *aspm_support(int code)
+{
+  switch (code)
+    {
+      case 1:
+	return "L0s";
+      case 3:
+	return "L0s L1";
+      default:
+	return "unknown";
+    }
+}
+
+static const char *aspm_enabled(int code)
+{
+  static const char *desc[] = { "Disabled", "L0s Enabled", "L1 Enabled", "L0s L1 Enabled" };
+  return desc[code];
+}
+
+static void cap_express_link(struct device *d, int where, int type)
+{
+  u32 t;
+  u16 w;
+
+  t = get_conf_long(d, where + PCI_EXP_LNKCAP);
+  printf("\t\tLnkCap:\tPort #%d, Speed %s, Width x%d, ASPM %s, Latency L0 %s, L1 %s\n",
+	t >> 24,
+	link_speed(t & PCI_EXP_LNKCAP_SPEED), (t & PCI_EXP_LNKCAP_WIDTH) >> 4,
+	aspm_support((t & PCI_EXP_LNKCAP_ASPM) >> 10),
+	latency_l0s((t & PCI_EXP_LNKCAP_L0S) >> 12),
+	latency_l1((t & PCI_EXP_LNKCAP_L1) >> 15));
+  printf("\t\t\tClockPM%c Surprise%c LLActRep%c BwNot%c\n",
+	FLAG(t, PCI_EXP_LNKCAP_CLOCKPM),
+	FLAG(t, PCI_EXP_LNKCAP_SURPRISE),
+	FLAG(t, PCI_EXP_LNKCAP_DLLA),
+	FLAG(t, PCI_EXP_LNKCAP_LBNC));
+
+  w = get_conf_word(d, where + PCI_EXP_LNKCTL);
+  printf("\t\tLnkCtl:\tASPM %s;", aspm_enabled(w & PCI_EXP_LNKCTL_ASPM));
+  if ((type == PCI_EXP_TYPE_ROOT_PORT) || (type == PCI_EXP_TYPE_ENDPOINT) ||
+      (type == PCI_EXP_TYPE_LEG_END))
+    printf(" RCB %d bytes", w & PCI_EXP_LNKCTL_RCB ? 128 : 64);
+  printf(" Disabled%c Retrain%c CommClk%c\n\t\t\tExtSynch%c ClockPM%c AutWidDis%c BWInt%c AutBWInt%c\n",
+	FLAG(w, PCI_EXP_LNKCTL_DISABLE),
+	FLAG(w, PCI_EXP_LNKCTL_RETRAIN),
+	FLAG(w, PCI_EXP_LNKCTL_CLOCK),
+	FLAG(w, PCI_EXP_LNKCTL_XSYNCH),
+	FLAG(w, PCI_EXP_LNKCTL_CLOCKPM),
+	FLAG(w, PCI_EXP_LNKCTL_HWAUTWD),
+	FLAG(w, PCI_EXP_LNKCTL_BWMIE),
+	FLAG(w, PCI_EXP_LNKCTL_AUTBWIE));
+
+  w = get_conf_word(d, where + PCI_EXP_LNKSTA);
+  printf("\t\tLnkSta:\tSpeed %s, Width x%d, TrErr%c Train%c SlotClk%c DLActive%c BWMgmt%c ABWMgmt%c\n",
+	link_speed(w & PCI_EXP_LNKSTA_SPEED),
+	(w & PCI_EXP_LNKSTA_WIDTH) >> 4,
+	FLAG(w, PCI_EXP_LNKSTA_TR_ERR),
+	FLAG(w, PCI_EXP_LNKSTA_TRAIN),
+	FLAG(w, PCI_EXP_LNKSTA_SL_CLK),
+	FLAG(w, PCI_EXP_LNKSTA_DL_ACT),
+	FLAG(w, PCI_EXP_LNKSTA_BWMGMT),
+	FLAG(w, PCI_EXP_LNKSTA_AUTBW));
+}
+
+static const char *indicator(int code)
+{
+  static const char *names[] = { "Unknown", "On", "Blink", "Off" };
+  return names[code];
+}
+
+static void cap_express_slot(struct device *d, int where)
+{
+  u32 t;
+  u16 w;
+
+  t = get_conf_long(d, where + PCI_EXP_SLTCAP);
+  printf("\t\tSltCap:\tAttnBtn%c PwrCtrl%c MRL%c AttnInd%c PwrInd%c HotPlug%c Surpise%c\n",
+	FLAG(t, PCI_EXP_SLTCAP_ATNB),
+	FLAG(t, PCI_EXP_SLTCAP_PWRC),
+	FLAG(t, PCI_EXP_SLTCAP_MRL),
+	FLAG(t, PCI_EXP_SLTCAP_ATNI),
+	FLAG(t, PCI_EXP_SLTCAP_PWRI),
+	FLAG(t, PCI_EXP_SLTCAP_HPC),
+	FLAG(t, PCI_EXP_SLTCAP_HPS));
+  printf("\t\t\tSlot #%3x, PowerLimit %f; Interlock%c NoCompl%c\n",
+	t >> 19,
+	power_limit((t & PCI_EXP_SLTCAP_PWR_VAL) >> 7, (t & PCI_EXP_SLTCAP_PWR_SCL) >> 15),
+	FLAG(t, PCI_EXP_SLTCAP_INTERLOCK),
+	FLAG(t, PCI_EXP_SLTCAP_NOCMDCOMP));
+
+  w = get_conf_word(d, where + PCI_EXP_SLTCTL);
+  printf("\t\tSltCtl:\tEnable: AttnBtn%c PwrFlt%c MRL%c PresDet%c CmdCplt%c HPIrq%c LinkChg%c\n",
+	FLAG(w, PCI_EXP_SLTCTL_ATNB),
+	FLAG(w, PCI_EXP_SLTCTL_PWRF),
+	FLAG(w, PCI_EXP_SLTCTL_MRLS),
+	FLAG(w, PCI_EXP_SLTCTL_PRSD),
+	FLAG(w, PCI_EXP_SLTCTL_CMDC),
+	FLAG(w, PCI_EXP_SLTCTL_HPIE),
+	FLAG(w, PCI_EXP_SLTCTL_LLCHG));
+  printf("\t\t\tControl: AttnInd %s, PwrInd %s, Power%c Interlock%c\n",
+	indicator((w & PCI_EXP_SLTCTL_ATNI) >> 6),
+	indicator((w & PCI_EXP_SLTCTL_PWRI) >> 8),
+	FLAG(w, PCI_EXP_SLTCTL_PWRC),
+	FLAG(w, PCI_EXP_SLTCTL_INTERLOCK));
+
+  w = get_conf_word(d, where + PCI_EXP_SLTSTA);
+  printf("\t\tSltSta:\tStatus: AttnBtn%c PowerFlt%c MRL%c CmdCplt%c PresDet%c Interlock%c\n",
+	FLAG(w, PCI_EXP_SLTSTA_ATNB),
+	FLAG(w, PCI_EXP_SLTSTA_PWRF),
+	FLAG(w, PCI_EXP_SLTSTA_MRL_ST),
+	FLAG(w, PCI_EXP_SLTSTA_CMDC),
+	FLAG(w, PCI_EXP_SLTSTA_PRES),
+	FLAG(w, PCI_EXP_SLTSTA_INTERLOCK));
+  printf("\t\t\tChanged: MRL%c PresDet%c LinkState%c\n",
+	FLAG(w, PCI_EXP_SLTSTA_MRLS),
+	FLAG(w, PCI_EXP_SLTSTA_PRSD),
+	FLAG(w, PCI_EXP_SLTSTA_LLCHG));
+}
+
+static void cap_express_root(struct device *d, int where)
+{
+  u32 w = get_conf_word(d, where + PCI_EXP_RTCTL);
+  printf("\t\tRootCtl: ErrCorrectable%c ErrNon-Fatal%c ErrFatal%c PMEIntEna%c CRSVisible%c\n",
+	FLAG(w, PCI_EXP_RTCTL_SECEE),
+	FLAG(w, PCI_EXP_RTCTL_SENFEE),
+	FLAG(w, PCI_EXP_RTCTL_SEFEE),
+	FLAG(w, PCI_EXP_RTCTL_PMEIE),
+	FLAG(w, PCI_EXP_RTCTL_CRSVIS));
+
+  w = get_conf_word(d, where + PCI_EXP_RTCAP);
+  printf("\t\tRootCap: CRSVisible%c\n",
+	FLAG(w, PCI_EXP_RTCAP_CRSVIS));
+
+  w = get_conf_word(d, where + PCI_EXP_RTSTA);
+  printf("\t\tRootSta: PME ReqID %04x, PMEStatus%c PMEPending%c\n",
+	w & PCI_EXP_RTSTA_PME_REQID,
+	FLAG(w, PCI_EXP_RTSTA_PME_STATUS),
+	FLAG(w, PCI_EXP_RTSTA_PME_PENDING));
+}
+
+static const char *cap_express_dev2_timeout_range(int type)
+{
+  /* Decode Completion Timeout Ranges. */
+  switch (type)
+    {
+      case 0:
+	return "Not Supported";
+      case 1:
+	return "Range A";
+      case 2:
+	return "Range B";
+      case 3:
+	return "Range AB";
+      case 6:
+	return "Range BC";
+      case 7:
+	return "Range ABC";
+      case 14:
+	return "Range BCD";
+      case 15:
+	return "Range ABCD";
+      default:
+	return "Unknown";
+    }
+}
+
+static const char *cap_express_dev2_timeout_value(int type)
+{
+  /* Decode Completion Timeout Value. */
+  switch (type)
+    {
+      case 0:
+	return "50us to 50ms";
+      case 1:
+	return "50us to 100us";
+      case 2:
+	return "1ms to 10ms";
+      case 5:
+	return "16ms to 55ms";
+      case 6:
+	return "65ms to 210ms";
+      case 9:
+	return "260ms to 900ms";
+      case 10:
+	return "1s to 3.5s";
+      case 13:
+	return "4s to 13s";
+      case 14:
+	return "17s to 64s";
+      default:
+	return "Unknown";
+    }
+}
+
+static void cap_express_dev2(struct device *d, int where, int type)
+{
+  u32 l;
+  u16 w;
+
+  l = get_conf_long(d, where + PCI_EXP_DEVCAP2);
+  printf("\t\tDevCap2: Completion Timeout: %s, TimeoutDis%c",
+	cap_express_dev2_timeout_range(PCI_EXP_DEV2_TIMEOUT_RANGE(l)),
+	FLAG(l, PCI_EXP_DEV2_TIMEOUT_DIS));
+  if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_DOWNSTREAM)
+    printf(" ARIFwd%c\n", FLAG(l, PCI_EXP_DEV2_ARI));
+  else
+    printf("\n");
+
+  w = get_conf_word(d, where + PCI_EXP_DEVCTL2);
+  printf("\t\tDevCtl2: Completion Timeout: %s, TimeoutDis%c",
+	cap_express_dev2_timeout_value(PCI_EXP_DEV2_TIMEOUT_VALUE(w)),
+	FLAG(w, PCI_EXP_DEV2_TIMEOUT_DIS));
+  if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_DOWNSTREAM)
+    printf(" ARIFwd%c\n", FLAG(w, PCI_EXP_DEV2_ARI));
+  else
+    printf("\n");
+}
+
+static const char *cap_express_link2_speed(int type)
+{
+  switch (type)
+    {
+      case 0: /* hardwire to 0 means only the 2.5GT/s is supported */
+      case 1:
+	return "2.5GT/s";
+      case 2:
+	return "5GT/s";
+      default:
+	return "Unknown";
+    }
+}
+
+static const char *cap_express_link2_deemphasis(int type)
+{
+  switch (type)
+    {
+      case 0:
+	return "-6dB";
+      case 1:
+	return "-3.5dB";
+      default:
+	return "Unknown";
+    }
+}
+
+static const char *cap_express_link2_transmargin(int type)
+{
+  switch (type)
+    {
+      case 0:
+	return "Normal Operating Range";
+      case 1:
+	return "800-1200mV(full-swing)/400-700mV(half-swing)";
+      case 2:
+      case 3:
+      case 4:
+      case 5:
+	return "200-400mV(full-swing)/100-200mV(half-swing)";
+      default:
+	return "Unknown";
+    }
+}
+
+static void cap_express_link2(struct device *d, int where, int type UNUSED)
+{
+  u16 w;
+
+  w = get_conf_word(d, where + PCI_EXP_LNKCTL2);
+  printf("\t\tLnkCtl2: Target Link Speed: %s, EnterCompliance%c SpeedDis%c, Selectable De-emphasis: %s\n"
+	"\t\t\t Transmit Margin: %s, EnterModifiedCompliance%c ComplianceSOS%c\n"
+	"\t\t\t Compliance De-emphasis: %s\n",
+	cap_express_link2_speed(PCI_EXP_LNKCTL2_SPEED(w)),
+	FLAG(w, PCI_EXP_LNKCTL2_CMPLNC),
+	FLAG(w, PCI_EXP_LNKCTL2_SPEED_DIS),
+	cap_express_link2_deemphasis(PCI_EXP_LNKCTL2_DEEMPHASIS(w)),
+	cap_express_link2_transmargin(PCI_EXP_LNKCTL2_MARGIN(w)),
+	FLAG(w, PCI_EXP_LNKCTL2_MOD_CMPLNC),
+	FLAG(w, PCI_EXP_LNKCTL2_CMPLNC_SOS),
+	cap_express_link2_deemphasis(PCI_EXP_LNKCTL2_COM_DEEMPHASIS(w)));
+
+  w = get_conf_word(d, where + PCI_EXP_LNKSTA2);
+  printf("\t\tLnkSta2: Current De-emphasis Level: %s\n",
+	cap_express_link2_deemphasis(PCI_EXP_LINKSTA2_DEEMPHASIS(w)));
+}
+
+static void cap_express_slot2(struct device *d UNUSED, int where UNUSED)
+{
+  /* No capabilities that require this field in PCIe rev2.0 spec. */
+}
+
+static void
+cap_express(struct device *d, int where, int cap)
+{
+  int type = (cap & PCI_EXP_FLAGS_TYPE) >> 4;
+  int size;
+  int slot = 0;
+
+  printf("Express ");
+  if (verbose >= 2)
+    printf("(v%d) ", cap & PCI_EXP_FLAGS_VERS);
+  switch (type)
+    {
+    case PCI_EXP_TYPE_ENDPOINT:
+      printf("Endpoint");
+      break;
+    case PCI_EXP_TYPE_LEG_END:
+      printf("Legacy Endpoint");
+      break;
+    case PCI_EXP_TYPE_ROOT_PORT:
+      slot = cap & PCI_EXP_FLAGS_SLOT;
+      printf("Root Port (Slot%c)", FLAG(cap, PCI_EXP_FLAGS_SLOT));
+      break;
+    case PCI_EXP_TYPE_UPSTREAM:
+      printf("Upstream Port");
+      break;
+    case PCI_EXP_TYPE_DOWNSTREAM:
+      slot = cap & PCI_EXP_FLAGS_SLOT;
+      printf("Downstream Port (Slot%c)", FLAG(cap, PCI_EXP_FLAGS_SLOT));
+      break;
+    case PCI_EXP_TYPE_PCI_BRIDGE:
+      printf("PCI/PCI-X Bridge");
+      break;
+    case PCI_EXP_TYPE_PCIE_BRIDGE:
+      printf("PCI/PCI-X to PCI-Express Bridge");
+      break;
+    case PCI_EXP_TYPE_ROOT_INT_EP:
+      printf("Root Complex Integrated Endpoint");
+      break;
+    case PCI_EXP_TYPE_ROOT_EC:
+      printf("Root Complex Event Collector");
+      break;
+    default:
+      printf("Unknown type %d", type);
+  }
+  printf(", MSI %02x\n", (cap & PCI_EXP_FLAGS_IRQ) >> 9);
+  if (verbose < 2)
+    return;
+
+  size = 16;
+  if (slot)
+    size = 24;
+  if (type == PCI_EXP_TYPE_ROOT_PORT)
+    size = 32;
+  if (!config_fetch(d, where + PCI_EXP_DEVCAP, size))
+    return;
+
+  cap_express_dev(d, where, type);
+  cap_express_link(d, where, type);
+  if (slot)
+    cap_express_slot(d, where);
+  if (type == PCI_EXP_TYPE_ROOT_PORT)
+    cap_express_root(d, where);
+
+  if ((cap & PCI_EXP_FLAGS_VERS) < 2)
+    return;
+
+  size = 16;
+  if (slot)
+    size = 24;
+  if (!config_fetch(d, where + PCI_EXP_DEVCAP2, size))
+    return;
+
+  cap_express_dev2(d, where, type);
+  cap_express_link2(d, where, type);
+  if (slot)
+    cap_express_slot2(d, where);
+}
+
+static void
+cap_msix(struct device *d, int where, int cap)
+{
+  u32 off;
+
+  printf("MSI-X: Enable%c Mask%c TabSize=%d\n",
+	 FLAG(cap, PCI_MSIX_ENABLE),
+	 FLAG(cap, PCI_MSIX_MASK),
+	 (cap & PCI_MSIX_TABSIZE) + 1);
+  if (verbose < 2 || !config_fetch(d, where + PCI_MSIX_TABLE, 8))
+    return;
+
+  off = get_conf_long(d, where + PCI_MSIX_TABLE);
+  printf("\t\tVector table: BAR=%d offset=%08x\n",
+	 off & PCI_MSIX_BIR, off & ~PCI_MSIX_BIR);
+  off = get_conf_long(d, where + PCI_MSIX_PBA);
+  printf("\t\tPBA: BAR=%d offset=%08x\n",
+	 off & PCI_MSIX_BIR, off & ~PCI_MSIX_BIR);
+}
+
+static void
+cap_slotid(int cap)
+{
+  int esr = cap & 0xff;
+  int chs = cap >> 8;
+
+  printf("Slot ID: %d slots, First%c, chassis %02x\n",
+	 esr & PCI_SID_ESR_NSLOTS,
+	 FLAG(esr, PCI_SID_ESR_FIC),
+	 chs);
+}
+
+static void
+cap_ssvid(struct device *d, int where)
+{
+  u16 subsys_v, subsys_d;
+  char ssnamebuf[256];
+
+  if (!config_fetch(d, where, 8))
+    return;
+  subsys_v = get_conf_word(d, where + PCI_SSVID_VENDOR);
+  subsys_d = get_conf_word(d, where + PCI_SSVID_DEVICE);
+  printf("Subsystem: %s\n",
+	   pci_lookup_name(pacc, ssnamebuf, sizeof(ssnamebuf),
+			   PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,
+			   d->dev->vendor_id, d->dev->device_id, subsys_v, subsys_d));
+}
+
+static void
+cap_debug_port(int cap)
+{
+  int bar = cap >> 13;
+  int pos = cap & 0x1fff;
+  printf("Debug port: BAR=%d offset=%04x\n", bar, pos);
+}
+
+void
+show_caps(struct device *d)
+{
+  int can_have_ext_caps = 0;
+
+  if (get_conf_word(d, PCI_STATUS) & PCI_STATUS_CAP_LIST)
+    {
+      int where = get_conf_byte(d, PCI_CAPABILITY_LIST) & ~3;
+      byte been_there[256];
+      memset(been_there, 0, 256);
+      while (where)
+	{
+	  int id, next, cap;
+	  printf("\tCapabilities: ");
+	  if (!config_fetch(d, where, 4))
+	    {
+	      puts("<access denied>");
+	      break;
+	    }
+	  id = get_conf_byte(d, where + PCI_CAP_LIST_ID);
+	  next = get_conf_byte(d, where + PCI_CAP_LIST_NEXT) & ~3;
+	  cap = get_conf_word(d, where + PCI_CAP_FLAGS);
+	  printf("[%02x] ", where);
+	  if (been_there[where]++)
+	    {
+	      printf("<chain looped>\n");
+	      break;
+	    }
+	  if (id == 0xff)
+	    {
+	      printf("<chain broken>\n");
+	      break;
+	    }
+	  switch (id)
+	    {
+	    case PCI_CAP_ID_PM:
+	      cap_pm(d, where, cap);
+	      break;
+	    case PCI_CAP_ID_AGP:
+	      cap_agp(d, where, cap);
+	      break;
+	    case PCI_CAP_ID_VPD:
+	      cap_vpd(d);
+	      break;
+	    case PCI_CAP_ID_SLOTID:
+	      cap_slotid(cap);
+	      break;
+	    case PCI_CAP_ID_MSI:
+	      cap_msi(d, where, cap);
+	      break;
+	    case PCI_CAP_ID_CHSWP:
+	      printf("CompactPCI hot-swap <?>\n");
+	      break;
+	    case PCI_CAP_ID_PCIX:
+	      cap_pcix(d, where);
+	      can_have_ext_caps = 1;
+	      break;
+	    case PCI_CAP_ID_HT:
+	      cap_ht(d, where, cap);
+	      break;
+	    case PCI_CAP_ID_VNDR:
+	      printf("Vendor Specific Information <?>\n");
+	      break;
+	    case PCI_CAP_ID_DBG:
+	      cap_debug_port(cap);
+	      break;
+	    case PCI_CAP_ID_CCRC:
+	      printf("CompactPCI central resource control <?>\n");
+	      break;
+	    case PCI_CAP_ID_HOTPLUG:
+	      printf("Hot-plug capable\n");
+	      break;
+	    case PCI_CAP_ID_SSVID:
+	      cap_ssvid(d, where);
+	      break;
+	    case PCI_CAP_ID_AGP3:
+	      printf("AGP3 <?>\n");
+	      break;
+	    case PCI_CAP_ID_SECURE:
+	      printf("Secure device <?>\n");
+	      break;
+	    case PCI_CAP_ID_EXP:
+	      cap_express(d, where, cap);
+	      can_have_ext_caps = 1;
+	      break;
+	    case PCI_CAP_ID_MSIX:
+	      cap_msix(d, where, cap);
+	      break;
+	    case PCI_CAP_ID_SATA:
+	      printf("SATA HBA <?>\n");
+	      break;
+	    case PCI_CAP_ID_AF:
+	      printf("PCIe advanced features <?>\n");
+	      break;
+	    default:
+	      printf("#%02x [%04x]\n", id, cap);
+	    }
+	  where = next;
+	}
+    }
+  if (can_have_ext_caps)
+    show_ext_caps(d);
+}
diff -ruN pciutils-3.0.3/ls-ecaps.c pciutils-3.1.0/ls-ecaps.c
--- pciutils-3.0.3/ls-ecaps.c	1970-01-01 01:00:00.000000000 +0100
+++ pciutils-3.1.0/ls-ecaps.c	2009-01-18 22:58:08.000000000 +0100
@@ -0,0 +1,262 @@
+/*
+ *	The PCI Utilities -- Show Extended Capabilities
+ *
+ *	Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
+ *
+ *	Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "lspci.h"
+
+static void
+cap_dsn(struct device *d, int where)
+{
+  u32 t1, t2;
+  if (!config_fetch(d, where + 4, 8))
+    return;
+  t1 = get_conf_long(d, where + 4);
+  t2 = get_conf_long(d, where + 8);
+  printf("Device Serial Number %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n",
+	t1 & 0xff, (t1 >> 8) & 0xff, (t1 >> 16) & 0xff, t1 >> 24,
+	t2 & 0xff, (t2 >> 8) & 0xff, (t2 >> 16) & 0xff, t2 >> 24);
+}
+
+static void
+cap_aer(struct device *d, int where)
+{
+  u32 l;
+
+  printf("Advanced Error Reporting\n");
+  if (verbose < 2)
+    return;
+
+  if (!config_fetch(d, where + PCI_ERR_UNCOR_STATUS, 24))
+    return;
+
+  l = get_conf_long(d, where + PCI_ERR_UNCOR_STATUS);
+  printf("\t\tUESta:\tDLP%c SDES%c TLP%c FCP%c CmpltTO%c CmpltAbrt%c UnxCmplt%c RxOF%c "
+	"MalfTLP%c ECRC%c UnsupReq%c ACSViol%c\n",
+	FLAG(l, PCI_ERR_UNC_DLP), FLAG(l, PCI_ERR_UNC_SDES), FLAG(l, PCI_ERR_UNC_POISON_TLP),
+	FLAG(l, PCI_ERR_UNC_FCP), FLAG(l, PCI_ERR_UNC_COMP_TIME), FLAG(l, PCI_ERR_UNC_COMP_ABORT),
+	FLAG(l, PCI_ERR_UNC_UNX_COMP), FLAG(l, PCI_ERR_UNC_RX_OVER), FLAG(l, PCI_ERR_UNC_MALF_TLP),
+	FLAG(l, PCI_ERR_UNC_ECRC), FLAG(l, PCI_ERR_UNC_UNSUP), FLAG(l, PCI_ERR_UNC_ACS_VIOL));
+  l = get_conf_long(d, where + PCI_ERR_UNCOR_MASK);
+  printf("\t\tUEMsk:\tDLP%c SDES%c TLP%c FCP%c CmpltTO%c CmpltAbrt%c UnxCmplt%c RxOF%c "
+	"MalfTLP%c ECRC%c UnsupReq%c ACSViol%c\n",
+	FLAG(l, PCI_ERR_UNC_DLP), FLAG(l, PCI_ERR_UNC_SDES), FLAG(l, PCI_ERR_UNC_POISON_TLP),
+	FLAG(l, PCI_ERR_UNC_FCP), FLAG(l, PCI_ERR_UNC_COMP_TIME), FLAG(l, PCI_ERR_UNC_COMP_ABORT),
+	FLAG(l, PCI_ERR_UNC_UNX_COMP), FLAG(l, PCI_ERR_UNC_RX_OVER), FLAG(l, PCI_ERR_UNC_MALF_TLP),
+	FLAG(l, PCI_ERR_UNC_ECRC), FLAG(l, PCI_ERR_UNC_UNSUP), FLAG(l, PCI_ERR_UNC_ACS_VIOL));
+  l = get_conf_long(d, where + PCI_ERR_UNCOR_SEVER);
+  printf("\t\tUESvrt:\tDLP%c SDES%c TLP%c FCP%c CmpltTO%c CmpltAbrt%c UnxCmplt%c RxOF%c "
+	"MalfTLP%c ECRC%c UnsupReq%c ACSViol%c\n",
+	FLAG(l, PCI_ERR_UNC_DLP), FLAG(l, PCI_ERR_UNC_SDES), FLAG(l, PCI_ERR_UNC_POISON_TLP),
+	FLAG(l, PCI_ERR_UNC_FCP), FLAG(l, PCI_ERR_UNC_COMP_TIME), FLAG(l, PCI_ERR_UNC_COMP_ABORT),
+	FLAG(l, PCI_ERR_UNC_UNX_COMP), FLAG(l, PCI_ERR_UNC_RX_OVER), FLAG(l, PCI_ERR_UNC_MALF_TLP),
+	FLAG(l, PCI_ERR_UNC_ECRC), FLAG(l, PCI_ERR_UNC_UNSUP), FLAG(l, PCI_ERR_UNC_ACS_VIOL));
+  l = get_conf_long(d, where + PCI_ERR_COR_STATUS);
+  printf("\t\tCESta:\tRxErr%c BadTLP%c BadDLLP%c Rollover%c Timeout%c NonFatalErr%c\n",
+	FLAG(l, PCI_ERR_COR_RCVR), FLAG(l, PCI_ERR_COR_BAD_TLP), FLAG(l, PCI_ERR_COR_BAD_DLLP),
+	FLAG(l, PCI_ERR_COR_REP_ROLL), FLAG(l, PCI_ERR_COR_REP_TIMER), FLAG(l, PCI_ERR_COR_REP_ANFE));
+  l = get_conf_long(d, where + PCI_ERR_COR_MASK);
+  printf("\t\tCEMsk:\tRxErr%c BadTLP%c BadDLLP%c Rollover%c Timeout%c NonFatalErr%c\n",
+	FLAG(l, PCI_ERR_COR_RCVR), FLAG(l, PCI_ERR_COR_BAD_TLP), FLAG(l, PCI_ERR_COR_BAD_DLLP),
+	FLAG(l, PCI_ERR_COR_REP_ROLL), FLAG(l, PCI_ERR_COR_REP_TIMER), FLAG(l, PCI_ERR_COR_REP_ANFE));
+  l = get_conf_long(d, where + PCI_ERR_CAP);
+  printf("\t\tAERCap:\tFirst Error Pointer: %02x, GenCap%c CGenEn%c ChkCap%c ChkEn%c\n",
+	PCI_ERR_CAP_FEP(l), FLAG(l, PCI_ERR_CAP_ECRC_GENC), FLAG(l, PCI_ERR_CAP_ECRC_GENE),
+	FLAG(l, PCI_ERR_CAP_ECRC_CHKC), FLAG(l, PCI_ERR_CAP_ECRC_CHKE));
+
+}
+
+static void
+cap_acs(struct device *d, int where)
+{
+  u16 w;
+
+  printf("Access Control Services\n");
+  if (verbose < 2)
+    return;
+
+  if (!config_fetch(d, where + PCI_ACS_CAP, 4))
+    return;
+
+  w = get_conf_word(d, where + PCI_ACS_CAP);
+  printf("\t\tACSCap:\tSrcValid%c TransBlk%c ReqRedir%c CmpltRedir%c UpstreamFwd%c EgressCtrl%c "
+	"DirectTrans%c\n",
+	FLAG(w, PCI_ACS_CAP_VALID), FLAG(w, PCI_ACS_CAP_BLOCK), FLAG(w, PCI_ACS_CAP_REQ_RED),
+	FLAG(w, PCI_ACS_CAP_CMPLT_RED), FLAG(w, PCI_ACS_CAP_FORWARD), FLAG(w, PCI_ACS_CAP_EGRESS),
+	FLAG(w, PCI_ACS_CAP_TRANS));
+  w = get_conf_word(d, where + PCI_ACS_CTRL);
+  printf("\t\tACSCtl:\tSrcValid%c TransBlk%c ReqRedir%c CmpltRedir%c UpstreamFwd%c EgressCtrl%c "
+	"DirectTrans%c\n",
+	FLAG(w, PCI_ACS_CTRL_VALID), FLAG(w, PCI_ACS_CTRL_BLOCK), FLAG(w, PCI_ACS_CTRL_REQ_RED),
+	FLAG(w, PCI_ACS_CTRL_CMPLT_RED), FLAG(w, PCI_ACS_CTRL_FORWARD), FLAG(w, PCI_ACS_CTRL_EGRESS),
+	FLAG(w, PCI_ACS_CTRL_TRANS));
+}
+
+static void
+cap_ari(struct device *d, int where)
+{
+  u16 w;
+
+  printf("Alternative Routing-ID Interpretation (ARI)\n");
+  if (verbose < 2)
+    return;
+
+  if (!config_fetch(d, where + PCI_ARI_CAP, 4))
+    return;
+
+  w = get_conf_word(d, where + PCI_ARI_CAP);
+  printf("\t\tARICap:\tMFVC%c ACS%c, Next Function: %d\n",
+	FLAG(w, PCI_ARI_CAP_MFVC), FLAG(w, PCI_ARI_CAP_ACS),
+	PCI_ARI_CAP_NFN(w));
+  w = get_conf_word(d, where + PCI_ARI_CTRL);
+  printf("\t\tARICtl:\tMFVC%c ACS%c, Function Group: %d\n",
+	FLAG(w, PCI_ARI_CTRL_MFVC), FLAG(w, PCI_ARI_CTRL_ACS),
+	PCI_ARI_CTRL_FG(w));
+}
+
+static void
+cap_ats(struct device *d, int where)
+{
+  u16 w;
+
+  printf("Address Translation Service (ATS)\n");
+  if (verbose < 2)
+    return;
+
+  if (!config_fetch(d, where + PCI_ATS_CAP, 4))
+    return;
+
+  w = get_conf_word(d, where + PCI_ATS_CAP);
+  printf("\t\tATSCap:\tInvalidate Queue Depth: %02x\n", PCI_ATS_CAP_IQD(w));
+  w = get_conf_word(d, where + PCI_ATS_CTRL);
+  printf("\t\tATSCtl:\tEnable%c, Smallest Translation Unit: %02x\n",
+	FLAG(w, PCI_ATS_CTRL_ENABLE), PCI_ATS_CTRL_STU(w));
+}
+
+static void
+cap_sriov(struct device *d, int where)
+{
+  u16 b;
+  u16 w;
+  u32 l;
+
+  printf("Single Root I/O Virtualization (SR-IOV)\n");
+  if (verbose < 2)
+    return;
+
+  if (!config_fetch(d, where + PCI_IOV_CAP, 0x3c))
+    return;
+
+  l = get_conf_long(d, where + PCI_IOV_CAP);
+  printf("\t\tIOVCap:\tMigration%c, Interrupt Message Number: %03x\n",
+	FLAG(l, PCI_IOV_CAP_VFM), PCI_IOV_CAP_IMN(l));
+  w = get_conf_word(d, where + PCI_IOV_CTRL);
+  printf("\t\tIOVCtl:\tEnable%c Migration%c Interrupt%c MSE%c ARIHierarchy%c\n",
+	FLAG(w, PCI_IOV_CTRL_VFE), FLAG(w, PCI_IOV_CTRL_VFME),
+	FLAG(w, PCI_IOV_CTRL_VFMIE), FLAG(w, PCI_IOV_CTRL_MSE),
+	FLAG(w, PCI_IOV_CTRL_ARI));
+  w = get_conf_word(d, where + PCI_IOV_STATUS);
+  printf("\t\tIOVSta:\tMigration%c\n", FLAG(w, PCI_IOV_STATUS_MS));
+  w = get_conf_word(d, where + PCI_IOV_INITIALVF);
+  printf("\t\tInitial VFs: %d, ", w);
+  w = get_conf_word(d, where + PCI_IOV_TOTALVF);
+  printf("Total VFs: %d, ", w);
+  w = get_conf_word(d, where + PCI_IOV_NUMVF);
+  printf("Number of VFs: %d, ", w);
+  b = get_conf_byte(d, where + PCI_IOV_FDL);
+  printf("Function Dependency Link: %02x\n", b);
+  w = get_conf_word(d, where + PCI_IOV_OFFSET);
+  printf("\t\tVF offset: %d, ", w);
+  w = get_conf_word(d, where + PCI_IOV_STRIDE);
+  printf("stride: %d, ", w);
+  w = get_conf_word(d, where + PCI_IOV_DID);
+  printf("Device ID: %04x\n", w);
+  l = get_conf_long(d, where + PCI_IOV_SUPPS);
+  printf("\t\tSupported Page Size: %08x, ", l);
+  l = get_conf_long(d, where + PCI_IOV_SYSPS);
+  printf("System Page Size: %08x\n", l);
+  l = get_conf_long(d, where + PCI_IOV_MSAO);
+  printf("\t\tVF Migration: offset: %08x, BIR: %x\n", PCI_IOV_MSA_OFFSET(l),
+	PCI_IOV_MSA_BIR(l));
+}
+
+void
+show_ext_caps(struct device *d)
+{
+  int where = 0x100;
+  char been_there[0x1000];
+  memset(been_there, 0, 0x1000);
+  do
+    {
+      u32 header;
+      int id;
+
+      if (!config_fetch(d, where, 4))
+	break;
+      header = get_conf_long(d, where);
+      if (!header)
+	break;
+      id = header & 0xffff;
+      printf("\tCapabilities: [%03x] ", where);
+      if (been_there[where]++)
+	{
+	  printf("<chain looped>\n");
+	  break;
+	}
+      switch (id)
+	{
+	  case PCI_EXT_CAP_ID_AER:
+	    cap_aer(d, where);
+	    break;
+	  case PCI_EXT_CAP_ID_VC:
+	    printf("Virtual Channel <?>\n");
+	    break;
+	  case PCI_EXT_CAP_ID_DSN:
+	    cap_dsn(d, where);
+	    break;
+	  case PCI_EXT_CAP_ID_PB:
+	    printf("Power Budgeting <?>\n");
+	    break;
+	  case PCI_EXT_CAP_ID_RCLINK:
+	    printf("Root Complex Link <?>\n");
+	    break;
+	  case PCI_EXT_CAP_ID_RCILINK:
+	    printf("Root Complex Internal Link <?>\n");
+	    break;
+	  case PCI_EXT_CAP_ID_RCECOLL:
+	    printf("Root Complex Event Collector <?>\n");
+	    break;
+	  case PCI_EXT_CAP_ID_MFVC:
+	    printf("Multi-Function Virtual Channel <?>\n");
+	    break;
+	  case PCI_EXT_CAP_ID_RBCB:
+	    printf("Root Bridge Control Block <?>\n");
+	    break;
+	  case PCI_EXT_CAP_ID_VNDR:
+	    printf("Vendor Specific Information <?>\n");
+	    break;
+	  case PCI_EXT_CAP_ID_ACS:
+	    cap_acs(d, where);
+	    break;
+	  case PCI_EXT_CAP_ID_ARI:
+	    cap_ari(d, where);
+	    break;
+	  case PCI_EXT_CAP_ID_ATS:
+	    cap_ats(d, where);
+	    break;
+	  case PCI_EXT_CAP_ID_SRIOV:
+	    cap_sriov(d, where);
+	    break;
+	  default:
+	    printf("#%02x\n", id);
+	    break;
+	}
+      where = header >> 20;
+    } while (where);
+}
diff -ruN pciutils-3.0.3/ls-kernel.c pciutils-3.1.0/ls-kernel.c
--- pciutils-3.0.3/ls-kernel.c	1970-01-01 01:00:00.000000000 +0100
+++ pciutils-3.1.0/ls-kernel.c	2008-11-21 22:28:24.000000000 +0100
@@ -0,0 +1,194 @@
+/*
+ *	The PCI Utilities -- Show Kernel Drivers
+ *
+ *	Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
+ *
+ *	Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "lspci.h"
+
+#ifdef PCI_OS_LINUX
+
+#include <sys/utsname.h>
+
+struct pcimap_entry {
+  struct pcimap_entry *next;
+  unsigned int vendor, device;
+  unsigned int subvendor, subdevice;
+  unsigned int class, class_mask;
+  char module[1];
+};
+
+static struct pcimap_entry *pcimap_head;
+
+static void
+load_pcimap(void)
+{
+  static int tried_pcimap;
+  struct utsname uts;
+  char *name, line[1024];
+  FILE *f;
+
+  if (tried_pcimap)
+    return;
+  tried_pcimap = 1;
+
+  if (name = opt_pcimap)
+    {
+      f = fopen(name, "r");
+      if (!f)
+	die("Cannot open pcimap file %s: %m", name);
+    }
+  else
+    {
+      if (uname(&uts) < 0)
+	die("uname() failed: %m");
+      name = alloca(64 + strlen(uts.release));
+      sprintf(name, "/lib/modules/%s/modules.pcimap", uts.release);
+      f = fopen(name, "r");
+      if (!f)
+	return;
+    }
+
+  while (fgets(line, sizeof(line), f))
+    {
+      char *c = strchr(line, '\n');
+      struct pcimap_entry *e;
+
+      if (!c)
+	die("Unterminated or too long line in %s", name);
+      *c = 0;
+      if (!line[0] || line[0] == '#')
+	continue;
+
+      c = line;
+      while (*c && *c != ' ' && *c != '\t')
+	c++;
+      if (!*c)
+	continue;	/* FIXME: Emit warnings! */
+      *c++ = 0;
+
+      e = xmalloc(sizeof(*e) + strlen(line));
+      if (sscanf(c, "%i%i%i%i%i%i",
+		 &e->vendor, &e->device,
+		 &e->subvendor, &e->subdevice,
+		 &e->class, &e->class_mask) != 6)
+	continue;
+      e->next = pcimap_head;
+      pcimap_head = e;
+      strcpy(e->module, line);
+    }
+  fclose(f);
+}
+
+static int
+match_pcimap(struct device *d, struct pcimap_entry *e)
+{
+  struct pci_dev *dev = d->dev;
+  unsigned int class = get_conf_long(d, PCI_REVISION_ID) >> 8;
+  word subv, subd;
+
+#define MATCH(x, y) ((y) > 0xffff || (x) == (y))
+  get_subid(d, &subv, &subd);
+  return
+    MATCH(dev->vendor_id, e->vendor) &&
+    MATCH(dev->device_id, e->device) &&
+    MATCH(subv, e->subvendor) &&
+    MATCH(subd, e->subdevice) &&
+    (class & e->class_mask) == e->class;
+#undef MATCH
+}
+
+#define DRIVER_BUF_SIZE 1024
+
+static char *
+find_driver(struct device *d, char *buf)
+{
+  struct pci_dev *dev = d->dev;
+  char name[1024], *drv, *base;
+  int n;
+
+  if (dev->access->method != PCI_ACCESS_SYS_BUS_PCI)
+    return NULL;
+
+  base = pci_get_param(dev->access, "sysfs.path");
+  if (!base || !base[0])
+    return NULL;
+
+  n = snprintf(name, sizeof(name), "%s/devices/%04x:%02x:%02x.%d/driver",
+	       base, dev->domain, dev->bus, dev->dev, dev->func);
+  if (n < 0 || n >= (int)sizeof(name))
+    die("show_driver: sysfs device name too long, why?");
+
+  n = readlink(name, buf, DRIVER_BUF_SIZE);
+  if (n < 0)
+    return NULL;
+  if (n >= DRIVER_BUF_SIZE)
+    return "<name-too-long>";
+  buf[n] = 0;
+
+  if (drv = strrchr(buf, '/'))
+    return drv+1;
+  else
+    return buf;
+}
+
+void
+show_kernel(struct device *d)
+{
+  char buf[DRIVER_BUF_SIZE];
+  char *driver;
+  struct pcimap_entry *e, *last = NULL;
+
+  if (driver = find_driver(d, buf))
+    printf("\tKernel driver in use: %s\n", driver);
+
+  load_pcimap();
+  for (e=pcimap_head; e; e=e->next)
+    if (match_pcimap(d, e) && (!last || strcmp(last->module, e->module)))
+      {
+	printf("%s %s", (last ? "," : "\tKernel modules:"), e->module);
+	last = e;
+      }
+  if (last)
+    putchar('\n');
+}
+
+void
+show_kernel_machine(struct device *d)
+{
+  char buf[DRIVER_BUF_SIZE];
+  char *driver;
+  struct pcimap_entry *e, *last = NULL;
+
+  if (driver = find_driver(d, buf))
+    printf("Driver:\t%s\n", driver);
+
+  load_pcimap();
+  for (e=pcimap_head; e; e=e->next)
+    if (match_pcimap(d, e) && (!last || strcmp(last->module, e->module)))
+      {
+	printf("Module:\t%s\n", e->module);
+	last = e;
+      }
+}
+
+#else
+
+void
+show_kernel(struct device *d UNUSED)
+{
+}
+
+void
+show_kernel_machine(struct device *d UNUSED)
+{
+}
+
+#endif
+
diff -ruN pciutils-3.0.3/ls-map.c pciutils-3.1.0/ls-map.c
--- pciutils-3.0.3/ls-map.c	1970-01-01 01:00:00.000000000 +0100
+++ pciutils-3.1.0/ls-map.c	2008-11-21 22:32:56.000000000 +0100
@@ -0,0 +1,180 @@
+/*
+ *	The PCI Utilities -- Bus Mapping Mode
+ *
+ *	Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
+ *
+ *	Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "lspci.h"
+
+struct bus_bridge {
+  struct bus_bridge *next;
+  byte this, dev, func, first, last, bug;
+};
+
+struct bus_info {
+  byte exists;
+  byte guestbook;
+  struct bus_bridge *bridges, *via;
+};
+
+static struct bus_info *bus_info;
+
+static void
+map_bridge(struct bus_info *bi, struct device *d, int np, int ns, int nl)
+{
+  struct bus_bridge *b = xmalloc(sizeof(struct bus_bridge));
+  struct pci_dev *p = d->dev;
+
+  b->next = bi->bridges;
+  bi->bridges = b;
+  b->this = get_conf_byte(d, np);
+  b->dev = p->dev;
+  b->func = p->func;
+  b->first = get_conf_byte(d, ns);
+  b->last = get_conf_byte(d, nl);
+  printf("## %02x.%02x:%d is a bridge from %02x to %02x-%02x\n",
+	 p->bus, p->dev, p->func, b->this, b->first, b->last);
+  if (b->this != p->bus)
+    printf("!!! Bridge points to invalid primary bus.\n");
+  if (b->first > b->last)
+    {
+      printf("!!! Bridge points to invalid bus range.\n");
+      b->last = b->first;
+    }
+}
+
+static void
+do_map_bus(int bus)
+{
+  int dev, func;
+  int verbose = pacc->debugging;
+  struct bus_info *bi = bus_info + bus;
+  struct device *d;
+
+  if (verbose)
+    printf("Mapping bus %02x\n", bus);
+  for (dev = 0; dev < 32; dev++)
+    if (filter.slot < 0 || filter.slot == dev)
+      {
+	int func_limit = 1;
+	for (func = 0; func < func_limit; func++)
+	  if (filter.func < 0 || filter.func == func)
+	    {
+	      /* XXX: Bus mapping supports only domain 0 */
+	      struct pci_dev *p = pci_get_dev(pacc, 0, bus, dev, func);
+	      u16 vendor = pci_read_word(p, PCI_VENDOR_ID);
+	      if (vendor && vendor != 0xffff)
+		{
+		  if (!func && (pci_read_byte(p, PCI_HEADER_TYPE) & 0x80))
+		    func_limit = 8;
+		  if (verbose)
+		    printf("Discovered device %02x:%02x.%d\n", bus, dev, func);
+		  bi->exists = 1;
+		  if (d = scan_device(p))
+		    {
+		      show_device(d);
+		      switch (get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f)
+			{
+			case PCI_HEADER_TYPE_BRIDGE:
+			  map_bridge(bi, d, PCI_PRIMARY_BUS, PCI_SECONDARY_BUS, PCI_SUBORDINATE_BUS);
+			  break;
+			case PCI_HEADER_TYPE_CARDBUS:
+			  map_bridge(bi, d, PCI_CB_PRIMARY_BUS, PCI_CB_CARD_BUS, PCI_CB_SUBORDINATE_BUS);
+			  break;
+			}
+		      free(d);
+		    }
+		  else if (verbose)
+		    printf("But it was filtered out.\n");
+		}
+	      pci_free_dev(p);
+	    }
+      }
+}
+
+static void
+do_map_bridges(int bus, int min, int max)
+{
+  struct bus_info *bi = bus_info + bus;
+  struct bus_bridge *b;
+
+  bi->guestbook = 1;
+  for (b=bi->bridges; b; b=b->next)
+    {
+      if (bus_info[b->first].guestbook)
+	b->bug = 1;
+      else if (b->first < min || b->last > max)
+	b->bug = 2;
+      else
+	{
+	  bus_info[b->first].via = b;
+	  do_map_bridges(b->first, b->first, b->last);
+	}
+    }
+}
+
+static void
+map_bridges(void)
+{
+  int i;
+
+  printf("\nSummary of buses:\n\n");
+  for (i=0; i<256; i++)
+    if (bus_info[i].exists && !bus_info[i].guestbook)
+      do_map_bridges(i, 0, 255);
+  for (i=0; i<256; i++)
+    {
+      struct bus_info *bi = bus_info + i;
+      struct bus_bridge *b = bi->via;
+
+      if (bi->exists)
+	{
+	  printf("%02x: ", i);
+	  if (b)
+	    printf("Entered via %02x:%02x.%d\n", b->this, b->dev, b->func);
+	  else if (!i)
+	    printf("Primary host bus\n");
+	  else
+	    printf("Secondary host bus (?)\n");
+	}
+      for (b=bi->bridges; b; b=b->next)
+	{
+	  printf("\t%02x.%d Bridge to %02x-%02x", b->dev, b->func, b->first, b->last);
+	  switch (b->bug)
+	    {
+	    case 1:
+	      printf(" <overlap bug>");
+	      break;
+	    case 2:
+	      printf(" <crossing bug>");
+	      break;
+	    }
+	  putchar('\n');
+	}
+    }
+}
+
+void
+map_the_bus(void)
+{
+  if (pacc->method == PCI_ACCESS_PROC_BUS_PCI ||
+      pacc->method == PCI_ACCESS_DUMP)
+    printf("WARNING: Bus mapping can be reliable only with direct hardware access enabled.\n\n");
+  bus_info = xmalloc(sizeof(struct bus_info) * 256);
+  memset(bus_info, 0, sizeof(struct bus_info) * 256);
+  if (filter.bus >= 0)
+    do_map_bus(filter.bus);
+  else
+    {
+      int bus;
+      for (bus=0; bus<256; bus++)
+	do_map_bus(bus);
+    }
+  map_bridges();
+}
diff -ruN pciutils-3.0.3/ls-tree.c pciutils-3.1.0/ls-tree.c
--- pciutils-3.0.3/ls-tree.c	1970-01-01 01:00:00.000000000 +0100
+++ pciutils-3.1.0/ls-tree.c	2008-11-21 22:30:11.000000000 +0100
@@ -0,0 +1,256 @@
+/*
+ *	The PCI Utilities -- Show Bus Tree
+ *
+ *	Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
+ *
+ *	Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "lspci.h"
+
+struct bridge {
+  struct bridge *chain;			/* Single-linked list of bridges */
+  struct bridge *next, *child;		/* Tree of bridges */
+  struct bus *first_bus;		/* List of buses connected to this bridge */
+  unsigned int domain;
+  unsigned int primary, secondary, subordinate;	/* Bus numbers */
+  struct device *br_dev;
+};
+
+struct bus {
+  unsigned int domain;
+  unsigned int number;
+  struct bus *sibling;
+  struct device *first_dev, **last_dev;
+};
+
+static struct bridge host_bridge = { NULL, NULL, NULL, NULL, 0, ~0, 0, ~0, NULL };
+
+static struct bus *
+find_bus(struct bridge *b, unsigned int domain, unsigned int n)
+{
+  struct bus *bus;
+
+  for (bus=b->first_bus; bus; bus=bus->sibling)
+    if (bus->domain == domain && bus->number == n)
+      break;
+  return bus;
+}
+
+static struct bus *
+new_bus(struct bridge *b, unsigned int domain, unsigned int n)
+{
+  struct bus *bus = xmalloc(sizeof(struct bus));
+  bus->domain = domain;
+  bus->number = n;
+  bus->sibling = b->first_bus;
+  bus->first_dev = NULL;
+  bus->last_dev = &bus->first_dev;
+  b->first_bus = bus;
+  return bus;
+}
+
+static void
+insert_dev(struct device *d, struct bridge *b)
+{
+  struct pci_dev *p = d->dev;
+  struct bus *bus;
+
+  if (! (bus = find_bus(b, p->domain, p->bus)))
+    {
+      struct bridge *c;
+      for (c=b->child; c; c=c->next)
+	if (c->domain == p->domain && c->secondary <= p->bus && p->bus <= c->subordinate)
+          {
+            insert_dev(d, c);
+            return;
+          }
+      bus = new_bus(b, p->domain, p->bus);
+    }
+  /* Simple insertion at the end _does_ guarantee the correct order as the
+   * original device list was sorted by (domain, bus, devfn) lexicographically
+   * and all devices on the new list have the same bus number.
+   */
+  *bus->last_dev = d;
+  bus->last_dev = &d->next;
+  d->next = NULL;
+}
+
+static void
+grow_tree(void)
+{
+  struct device *d, *d2;
+  struct bridge **last_br, *b;
+
+  /* Build list of bridges */
+
+  last_br = &host_bridge.chain;
+  for (d=first_dev; d; d=d->next)
+    {
+      word class = d->dev->device_class;
+      byte ht = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f;
+      if (class == PCI_CLASS_BRIDGE_PCI &&
+	  (ht == PCI_HEADER_TYPE_BRIDGE || ht == PCI_HEADER_TYPE_CARDBUS))
+	{
+	  b = xmalloc(sizeof(struct bridge));
+	  b->domain = d->dev->domain;
+	  if (ht == PCI_HEADER_TYPE_BRIDGE)
+	    {
+	      b->primary = get_conf_byte(d, PCI_PRIMARY_BUS);
+	      b->secondary = get_conf_byte(d, PCI_SECONDARY_BUS);
+	      b->subordinate = get_conf_byte(d, PCI_SUBORDINATE_BUS);
+	    }
+	  else
+	    {
+	      b->primary = get_conf_byte(d, PCI_CB_PRIMARY_BUS);
+	      b->secondary = get_conf_byte(d, PCI_CB_CARD_BUS);
+	      b->subordinate = get_conf_byte(d, PCI_CB_SUBORDINATE_BUS);
+	    }
+	  *last_br = b;
+	  last_br = &b->chain;
+	  b->next = b->child = NULL;
+	  b->first_bus = NULL;
+	  b->br_dev = d;
+	}
+    }
+  *last_br = NULL;
+
+  /* Create a bridge tree */
+
+  for (b=&host_bridge; b; b=b->chain)
+    {
+      struct bridge *c, *best;
+      best = NULL;
+      for (c=&host_bridge; c; c=c->chain)
+	if (c != b && (c == &host_bridge || b->domain == c->domain) &&
+	    b->primary >= c->secondary && b->primary <= c->subordinate &&
+	    (!best || best->subordinate - best->primary > c->subordinate - c->primary))
+	  best = c;
+      if (best)
+	{
+	  b->next = best->child;
+	  best->child = b;
+	}
+    }
+
+  /* Insert secondary bus for each bridge */
+
+  for (b=&host_bridge; b; b=b->chain)
+    if (!find_bus(b, b->domain, b->secondary))
+      new_bus(b, b->domain, b->secondary);
+
+  /* Create bus structs and link devices */
+
+  for (d=first_dev; d;)
+    {
+      d2 = d->next;
+      insert_dev(d, &host_bridge);
+      d = d2;
+    }
+}
+
+static void
+print_it(char *line, char *p)
+{
+  *p++ = '\n';
+  *p = 0;
+  fputs(line, stdout);
+  for (p=line; *p; p++)
+    if (*p == '+' || *p == '|')
+      *p = '|';
+    else
+      *p = ' ';
+}
+
+static void show_tree_bridge(struct bridge *, char *, char *);
+
+static void
+show_tree_dev(struct device *d, char *line, char *p)
+{
+  struct pci_dev *q = d->dev;
+  struct bridge *b;
+  char namebuf[256];
+
+  p += sprintf(p, "%02x.%x", q->dev, q->func);
+  for (b=&host_bridge; b; b=b->chain)
+    if (b->br_dev == d)
+      {
+	if (b->secondary == b->subordinate)
+	  p += sprintf(p, "-[%04x:%02x]-", b->domain, b->secondary);
+	else
+	  p += sprintf(p, "-[%04x:%02x-%02x]-", b->domain, b->secondary, b->subordinate);
+        show_tree_bridge(b, line, p);
+        return;
+      }
+  if (verbose)
+    p += sprintf(p, "  %s",
+		 pci_lookup_name(pacc, namebuf, sizeof(namebuf),
+				 PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,
+				 q->vendor_id, q->device_id));
+  print_it(line, p);
+}
+
+static void
+show_tree_bus(struct bus *b, char *line, char *p)
+{
+  if (!b->first_dev)
+    print_it(line, p);
+  else if (!b->first_dev->next)
+    {
+      *p++ = '-';
+      *p++ = '-';
+      show_tree_dev(b->first_dev, line, p);
+    }
+  else
+    {
+      struct device *d = b->first_dev;
+      while (d->next)
+	{
+	  p[0] = '+';
+	  p[1] = '-';
+	  show_tree_dev(d, line, p+2);
+	  d = d->next;
+	}
+      p[0] = '\\';
+      p[1] = '-';
+      show_tree_dev(d, line, p+2);
+    }
+}
+
+static void
+show_tree_bridge(struct bridge *b, char *line, char *p)
+{
+  *p++ = '-';
+  if (!b->first_bus->sibling)
+    {
+      if (b == &host_bridge)
+        p += sprintf(p, "[%04x:%02x]-", b->domain, b->first_bus->number);
+      show_tree_bus(b->first_bus, line, p);
+    }
+  else
+    {
+      struct bus *u = b->first_bus;
+      char *k;
+
+      while (u->sibling)
+        {
+          k = p + sprintf(p, "+-[%04x:%02x]-", u->domain, u->number);
+          show_tree_bus(u, line, k);
+          u = u->sibling;
+        }
+      k = p + sprintf(p, "\\-[%04x:%02x]-", u->domain, u->number);
+      show_tree_bus(u, line, k);
+    }
+}
+
+void
+show_forest(void)
+{
+  char line[256];
+
+  grow_tree();
+  show_tree_bridge(&host_bridge, line, line);
+}
diff -ruN pciutils-3.0.3/ls-vpd.c pciutils-3.1.0/ls-vpd.c
--- pciutils-3.0.3/ls-vpd.c	1970-01-01 01:00:00.000000000 +0100
+++ pciutils-3.1.0/ls-vpd.c	2008-11-22 22:21:32.000000000 +0100
@@ -0,0 +1,217 @@
+/*
+ *	The PCI Utilities -- Show Vital Product Data
+ *
+ *	Copyright (c) 2008 Solarflare Communications
+ *
+ *	Written by Ben Hutchings <bhutchings@solarflare.com>
+ *	Improved by Martin Mares <mj@ucw.cz>
+ *
+ *	Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <stdio.h>
+
+#include "lspci.h"
+
+/*
+ *  The list of all known VPD items and their formats.
+ *  Technically, this belongs to the pci.ids file, but the VPD does not seem
+ *  to be developed any longer, so we have chosen the easier way.
+ */
+
+enum vpd_format {
+  F_BINARY,
+  F_TEXT,
+  F_RESVD,
+  F_RDWR,
+};
+
+static const struct vpd_item {
+  byte id1, id2;
+  byte format;
+  const char *name;
+} vpd_items[] = {
+  { 'C','P', F_BINARY,	"Extended capability" },
+  { 'E','C', F_TEXT,	"Engineering changes" },
+  { 'M','N', F_BINARY,	"Manufacture ID" },
+  { 'P','N', F_TEXT,	"Part number" },
+  { 'R','V', F_RESVD,	"Reserved" },
+  { 'R','W', F_RDWR,	"Read-write area" },
+  { 'S','N', F_TEXT,	"Serial number" },
+  { 'Y','A', F_TEXT,	"Asset tag" },
+  { 'V', 0 , F_TEXT,	"Vendor specific" },
+  { 'Y', 0 , F_TEXT,	"System specific" },
+  {  0,  0 , F_BINARY,	NULL }
+};
+
+static void
+print_vpd_string(const byte *buf, word len)
+{
+  while (len--)
+    {
+      byte ch = *buf++;
+      if (ch == '\\')
+        printf("\\\\");
+      else if (!ch && !len)
+        ;  /* Cards with null-terminated strings have been observed */
+      else if (ch < 32 || ch == 127)
+        printf("\\x%02x", ch);
+      else
+        putchar(ch);
+    }
+}
+
+static void
+print_vpd_binary(const byte *buf, word len)
+{
+  int i;
+  for (i = 0; i < len; i++)
+    {
+      if (i)
+        putchar(' ');
+      printf("%02x", buf[i]);
+    }
+}
+
+static int
+read_vpd(struct device *d, int pos, byte *buf, int len, byte *csum)
+{
+  if (!pci_read_vpd(d->dev, pos, buf, len))
+    return 0;
+  while (len--)
+    *csum += *buf++;
+  return 1;
+}
+
+void
+cap_vpd(struct device *d)
+{
+  word res_addr = 0, res_len, part_pos, part_len;
+  byte buf[256];
+  byte tag;
+  byte csum = 0;
+
+  printf("Vital Product Data\n");
+  if (verbose < 2)
+    return;
+
+  while (res_addr <= PCI_VPD_ADDR_MASK)
+    {
+      if (!read_vpd(d, res_addr, &tag, 1, &csum))
+	break;
+      if (tag & 0x80)
+	{
+	  if (res_addr > PCI_VPD_ADDR_MASK + 1 - 3)
+	    break;
+	  if (!read_vpd(d, res_addr + 1, buf, 2, &csum))
+	    break;
+	  res_len = buf[0] + (buf[1] << 8);
+	  res_addr += 3;
+	}
+      else
+	{
+	  res_len = tag & 7;
+	  tag >>= 3;
+	  res_addr += 1;
+	}
+      if (res_len > PCI_VPD_ADDR_MASK + 1 - res_addr)
+	break;
+
+      part_pos = 0;
+
+      switch (tag)
+	{
+	case 0x0f:
+	  printf("\t\tEnd\n");
+	  return;
+
+	case 0x82:
+	  printf("\t\tProduct Name: ");
+	  while (part_pos < res_len)
+	    {
+	      part_len = res_len - part_pos;
+	      if (part_len > sizeof(buf))
+		part_len = sizeof(buf);
+	      if (!read_vpd(d, res_addr + part_pos, buf, part_len, &csum))
+		break;
+	      print_vpd_string(buf, part_len);
+	      part_pos += part_len;
+	    }
+	  printf("\n");
+	  break;
+
+	case 0x90:
+	case 0x91:
+	  printf("\t\t%s fields:\n",
+		 (tag == 0x90) ? "Read-only" : "Read/write");
+
+	  while (part_pos + 3 <= res_len)
+	    {
+	      word read_len;
+	      const struct vpd_item *item;
+	      struct vpd_item unknown_item;
+
+	      if (!read_vpd(d, res_addr + part_pos, buf, 3, &csum))
+		break;
+	      part_pos += 3;
+	      part_len = buf[2];
+	      if (part_len > res_len - part_pos)
+		break;
+
+	      /* Is this item known? */
+	      for (item=vpd_items; item->id1 && item->id1 != buf[0] ||
+				   item->id2 && item->id2 != buf[1]; item++)
+		;
+	      if (!item->id1 && !item->id2)
+	        {
+		  unknown_item.id1 = buf[0];
+		  unknown_item.id2 = buf[1];
+		  unknown_item.format = F_BINARY;
+		  unknown_item.name = "Unknown";
+		  item = &unknown_item;
+	        }
+
+	      /* Only read the first byte of the RV field because the
+	       * remaining bytes are not included in the checksum. */
+	      read_len = (item->format == F_RESVD) ? 1 : part_len;
+	      if (!read_vpd(d, res_addr + part_pos, buf, read_len, &csum))
+		break;
+
+	      printf("\t\t\t[%c%c] %s: ", item->id1, item->id2, item->name);
+
+	      switch (item->format)
+	        {
+		case F_TEXT:
+		  print_vpd_string(buf, part_len);
+		  printf("\n");
+		  break;
+		case F_BINARY:
+		  print_vpd_binary(buf, part_len);
+		  printf("\n");
+		  break;
+		case F_RESVD:
+		  printf("checksum %s, %d byte(s) reserved\n", csum ? "bad" : "good", part_len - 1);
+		  break;
+		case F_RDWR:
+		  printf("%d byte(s) free\n", part_len);
+		  break;
+		}
+
+	      part_pos += part_len;
+	    }
+	  break;
+
+	default:
+	  printf("\t\tUnknown %s resource type %02x\n",
+		 (tag & 0x80) ? "large" : "small", tag & ~0x80);
+	  break;
+	}
+
+      res_addr += res_len;
+    }
+
+  if (res_addr == 0)
+    printf("\t\tNot readable\n");
+  else
+    printf("\t\tNo end tag found\n");
+}
diff -ruN pciutils-3.0.3/lspci.c pciutils-3.1.0/lspci.c
--- pciutils-3.0.3/lspci.c	2008-11-09 21:05:06.000000000 +0100
+++ pciutils-3.1.0/lspci.c	2009-01-18 22:58:01.000000000 +0100
@@ -12,15 +12,13 @@
 #include <stdarg.h>
 #include <unistd.h>
 
-#define PCIUTILS_LSPCI
-#include "pciutils.h"
+#include "lspci.h"
 
 /* Options */
 
-static int verbose;			/* Show detailed information */
-static int opt_buscentric;		/* Show bus addresses/IRQ's instead of CPU-visible ones */
+int verbose;				/* Show detailed information */
 static int opt_hex;			/* Show contents of config space as hexadecimal numbers */
-static struct pci_filter filter;	/* Device filter */
+struct pci_filter filter;		/* Device filter */
 static int opt_tree;			/* Show bus tree */
 static int opt_machine;			/* Generate machine-readable output */
 static int opt_map_mode;		/* Bus mapping mode enabled */
@@ -28,7 +26,7 @@
 static int opt_kernel;			/* Show kernel drivers */
 static int opt_query_dns;		/* Query the DNS (0=disabled, 1=enabled, 2=refresh cache) */
 static int opt_query_all;		/* Query the DNS for all entries */
-static char *opt_pcimap;		/* Override path to Linux modules.pcimap */
+char *opt_pcimap;			/* Override path to Linux modules.pcimap */
 
 const char program_name[] = "lspci";
 
@@ -76,38 +74,13 @@
 GENERIC_HELP
 ;
 
-/*** Communication with libpci ***/
-
-static struct pci_access *pacc;
-
-/*
- *  If we aren't being compiled by GCC, use xmalloc() instead of alloca().
- *  This increases our memory footprint, but only slightly since we don't
- *  use alloca() much.
- */
-#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__DragonFly__)
-/* alloca() is defined in stdlib.h */
-#elif defined(__GNUC__) && !defined(PCI_OS_WINDOWS)
-#include <alloca.h>
-#else
-#undef alloca
-#define alloca xmalloc
-#endif
-
 /*** Our view of the PCI bus ***/
 
-struct device {
-  struct device *next;
-  struct pci_dev *dev;
-  unsigned int config_cached, config_bufsize;
-  byte *config;				/* Cached configuration space data */
-  byte *present;			/* Maps which configuration bytes are present */
-};
-
-static struct device *first_dev;
+struct pci_access *pacc;
+struct device *first_dev;
 static int seen_errors;
 
-static int
+int
 config_fetch(struct device *d, unsigned int pos, unsigned int len)
 {
   unsigned int end = pos+len;
@@ -135,7 +108,7 @@
   return result;
 }
 
-static struct device *
+struct device *
 scan_device(struct pci_dev *p)
 {
   struct device *d;
@@ -166,7 +139,7 @@
 	d->config_cached += 64;
     }
   pci_setup_cache(p, d->config, d->config_cached);
-  pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_CLASS | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES);
+  pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_CLASS | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES | PCI_FILL_PHYS_SLOT);
   return d;
 }
 
@@ -177,7 +150,7 @@
   struct pci_dev *p;
 
   pci_scan_bus(pacc);
-  for(p=pacc->devices; p; p=p->next)
+  for (p=pacc->devices; p; p=p->next)
     if (d = scan_device(p))
       {
 	d->next = first_dev;
@@ -197,21 +170,21 @@
       pos++, len--;
 }
 
-static inline byte
+byte
 get_conf_byte(struct device *d, unsigned int pos)
 {
   check_conf_range(d, pos, 1);
   return d->config[pos];
 }
 
-static word
+word
 get_conf_word(struct device *d, unsigned int pos)
 {
   check_conf_range(d, pos, 2);
   return d->config[pos] | (d->config[pos+1] << 8);
 }
 
-static u32
+u32
 get_conf_long(struct device *d, unsigned int pos)
 {
   check_conf_range(d, pos, 4);
@@ -249,1748 +222,109 @@
 }
 
 static void
-sort_them(void)
-{
-  struct device **index, **h, **last_dev;
-  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;
-}
-
-/*** Normal output ***/
-
-#define FLAG(x,y) ((x & y) ? '+' : '-')
-
-static void
-show_slot_name(struct device *d)
-{
-  struct pci_dev *p = d->dev;
-
-  if (!opt_machine ? opt_domains : (p->domain || opt_domains >= 2))
-    printf("%04x:", p->domain);
-  printf("%02x:%02x.%d", p->bus, p->dev, p->func);
-}
-
-static void
-get_subid(struct device *d, word *subvp, word *subdp)
-{
-  byte htype = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f;
-
-  if (htype == PCI_HEADER_TYPE_NORMAL)
-    {
-      *subvp = get_conf_word(d, PCI_SUBSYSTEM_VENDOR_ID);
-      *subdp = get_conf_word(d, PCI_SUBSYSTEM_ID);
-    }
-  else if (htype == PCI_HEADER_TYPE_CARDBUS && d->config_cached >= 128)
-    {
-      *subvp = get_conf_word(d, PCI_CB_SUBSYSTEM_VENDOR_ID);
-      *subdp = get_conf_word(d, PCI_CB_SUBSYSTEM_ID);
-    }
-  else
-    *subvp = *subdp = 0xffff;
-}
-
-static void
-show_terse(struct device *d)
-{
-  int c;
-  struct pci_dev *p = d->dev;
-  char classbuf[128], devbuf[128];
-
-  show_slot_name(d);
-  printf(" %s: %s",
-	 pci_lookup_name(pacc, classbuf, sizeof(classbuf),
-			 PCI_LOOKUP_CLASS,
-			 p->device_class),
-	 pci_lookup_name(pacc, devbuf, sizeof(devbuf),
-			 PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,
-			 p->vendor_id, p->device_id));
-  if (c = get_conf_byte(d, PCI_REVISION_ID))
-    printf(" (rev %02x)", c);
-  if (verbose)
-    {
-      char *x;
-      c = get_conf_byte(d, PCI_CLASS_PROG);
-      x = pci_lookup_name(pacc, devbuf, sizeof(devbuf),
-			  PCI_LOOKUP_PROGIF | PCI_LOOKUP_NO_NUMBERS,
-			  p->device_class, c);
-      if (c || x)
-	{
-	  printf(" (prog-if %02x", c);
-	  if (x)
-	    printf(" [%s]", x);
-	  putchar(')');
-	}
-    }
-  putchar('\n');
-
-  if (verbose || opt_kernel)
-    {
-      word subsys_v, subsys_d;
-      char ssnamebuf[256];
-
-      get_subid(d, &subsys_v, &subsys_d);
-      if (subsys_v && subsys_v != 0xffff)
-	printf("\tSubsystem: %s\n",
-		pci_lookup_name(pacc, ssnamebuf, sizeof(ssnamebuf),
-			PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,
-			p->vendor_id, p->device_id, subsys_v, subsys_d));
-    }
-}
-
-/*** Capabilities ***/
-
-static void
-cap_pm(struct device *d, int where, int cap)
-{
-  int t, b;
-  static int pm_aux_current[8] = { 0, 55, 100, 160, 220, 270, 320, 375 };
-
-  printf("Power Management version %d\n", cap & PCI_PM_CAP_VER_MASK);
-  if (verbose < 2)
-    return;
-  printf("\t\tFlags: PMEClk%c DSI%c D1%c D2%c AuxCurrent=%dmA PME(D0%c,D1%c,D2%c,D3hot%c,D3cold%c)\n",
-	 FLAG(cap, PCI_PM_CAP_PME_CLOCK),
-	 FLAG(cap, PCI_PM_CAP_DSI),
-	 FLAG(cap, PCI_PM_CAP_D1),
-	 FLAG(cap, PCI_PM_CAP_D2),
-	 pm_aux_current[(cap >> 6) & 7],
-	 FLAG(cap, PCI_PM_CAP_PME_D0),
-	 FLAG(cap, PCI_PM_CAP_PME_D1),
-	 FLAG(cap, PCI_PM_CAP_PME_D2),
-	 FLAG(cap, PCI_PM_CAP_PME_D3_HOT),
-	 FLAG(cap, PCI_PM_CAP_PME_D3_COLD));
-  if (!config_fetch(d, where + PCI_PM_CTRL, PCI_PM_SIZEOF - PCI_PM_CTRL))
-    return;
-  t = get_conf_word(d, where + PCI_PM_CTRL);
-  printf("\t\tStatus: D%d PME-Enable%c DSel=%d DScale=%d PME%c\n",
-	 t & PCI_PM_CTRL_STATE_MASK,
-	 FLAG(t, PCI_PM_CTRL_PME_ENABLE),
-	 (t & PCI_PM_CTRL_DATA_SEL_MASK) >> 9,
-	 (t & PCI_PM_CTRL_DATA_SCALE_MASK) >> 13,
-	 FLAG(t, PCI_PM_CTRL_PME_STATUS));
-  b = get_conf_byte(d, where + PCI_PM_PPB_EXTENSIONS);
-  if (b)
-    printf("\t\tBridge: PM%c B3%c\n",
-	   FLAG(t, PCI_PM_BPCC_ENABLE),
-	   FLAG(~t, PCI_PM_PPB_B2_B3));
-}
-
-static void
-format_agp_rate(int rate, char *buf, int agp3)
-{
-  char *c = buf;
-  int i;
-
-  for(i=0; i<=2; i++)
-    if (rate & (1 << i))
-      {
-	if (c != buf)
-	  *c++ = ',';
-	c += sprintf(c, "x%d", 1 << (i + 2*agp3));
-      }
-  if (c != buf)
-    *c = 0;
-  else
-    strcpy(buf, "<none>");
-}
-
-static void
-cap_agp(struct device *d, int where, int cap)
-{
-  u32 t;
-  char rate[16];
-  int ver, rev;
-  int agp3 = 0;
-
-  ver = (cap >> 4) & 0x0f;
-  rev = cap & 0x0f;
-  printf("AGP version %x.%x\n", ver, rev);
-  if (verbose < 2)
-    return;
-  if (!config_fetch(d, where + PCI_AGP_STATUS, PCI_AGP_SIZEOF - PCI_AGP_STATUS))
-    return;
-  t = get_conf_long(d, where + PCI_AGP_STATUS);
-  if (ver >= 3 && (t & PCI_AGP_STATUS_AGP3))
-    agp3 = 1;
-  format_agp_rate(t & 7, rate, agp3);
-  printf("\t\tStatus: RQ=%d Iso%c ArqSz=%d Cal=%d SBA%c ITACoh%c GART64%c HTrans%c 64bit%c FW%c AGP3%c Rate=%s\n",
-	 ((t & PCI_AGP_STATUS_RQ_MASK) >> 24U) + 1,
-	 FLAG(t, PCI_AGP_STATUS_ISOCH),
-	 ((t & PCI_AGP_STATUS_ARQSZ_MASK) >> 13),
-	 ((t & PCI_AGP_STATUS_CAL_MASK) >> 10),
-	 FLAG(t, PCI_AGP_STATUS_SBA),
-	 FLAG(t, PCI_AGP_STATUS_ITA_COH),
-	 FLAG(t, PCI_AGP_STATUS_GART64),
-	 FLAG(t, PCI_AGP_STATUS_HTRANS),
-	 FLAG(t, PCI_AGP_STATUS_64BIT),
-	 FLAG(t, PCI_AGP_STATUS_FW),
-	 FLAG(t, PCI_AGP_STATUS_AGP3),
-	 rate);
-  t = get_conf_long(d, where + PCI_AGP_COMMAND);
-  format_agp_rate(t & 7, rate, agp3);
-  printf("\t\tCommand: RQ=%d ArqSz=%d Cal=%d SBA%c AGP%c GART64%c 64bit%c FW%c Rate=%s\n",
-	 ((t & PCI_AGP_COMMAND_RQ_MASK) >> 24U) + 1,
-	 ((t & PCI_AGP_COMMAND_ARQSZ_MASK) >> 13),
-	 ((t & PCI_AGP_COMMAND_CAL_MASK) >> 10),
-	 FLAG(t, PCI_AGP_COMMAND_SBA),
-	 FLAG(t, PCI_AGP_COMMAND_AGP),
-	 FLAG(t, PCI_AGP_COMMAND_GART64),
-	 FLAG(t, PCI_AGP_COMMAND_64BIT),
-	 FLAG(t, PCI_AGP_COMMAND_FW),
-	 rate);
-}
-
-static void
-cap_pcix_nobridge(struct device *d, int where)
-{
-  u16 command;
-  u32 status;
-  static const byte max_outstanding[8] = { 1, 2, 3, 4, 8, 12, 16, 32 };
-
-  printf("PCI-X non-bridge device\n");
-
-  if (verbose < 2)
-    return;
-
-  if (!config_fetch(d, where + PCI_PCIX_STATUS, 4))
-    return;
-
-  command = get_conf_word(d, where + PCI_PCIX_COMMAND);
-  status = get_conf_long(d, where + PCI_PCIX_STATUS);
-  printf("\t\tCommand: DPERE%c ERO%c RBC=%d OST=%d\n",
-	 FLAG(command, PCI_PCIX_COMMAND_DPERE),
-	 FLAG(command, PCI_PCIX_COMMAND_ERO),
-	 1 << (9 + ((command & PCI_PCIX_COMMAND_MAX_MEM_READ_BYTE_COUNT) >> 2U)),
-	 max_outstanding[(command & PCI_PCIX_COMMAND_MAX_OUTSTANDING_SPLIT_TRANS) >> 4U]);
-  printf("\t\tStatus: Dev=%02x:%02x.%d 64bit%c 133MHz%c SCD%c USC%c DC=%s DMMRBC=%u DMOST=%u DMCRS=%u RSCEM%c 266MHz%c 533MHz%c\n",
-	 ((status >> 8) & 0xff),
-	 ((status >> 3) & 0x1f),
-	 (status & PCI_PCIX_STATUS_FUNCTION),
-	 FLAG(status, PCI_PCIX_STATUS_64BIT),
-	 FLAG(status, PCI_PCIX_STATUS_133MHZ),
-	 FLAG(status, PCI_PCIX_STATUS_SC_DISCARDED),
-	 FLAG(status, PCI_PCIX_STATUS_UNEXPECTED_SC),
-	 ((status & PCI_PCIX_STATUS_DEVICE_COMPLEXITY) ? "bridge" : "simple"),
-	 1 << (9 + ((status >> 21) & 3U)),
-	 max_outstanding[(status >> 23) & 7U],
-	 1 << (3 + ((status >> 26) & 7U)),
-	 FLAG(status, PCI_PCIX_STATUS_RCVD_SC_ERR_MESS),
-	 FLAG(status, PCI_PCIX_STATUS_266MHZ),
-	 FLAG(status, PCI_PCIX_STATUS_533MHZ));
-}
-
-static void
-cap_pcix_bridge(struct device *d, int where)
-{
-  static const char * const sec_clock_freq[8] = { "conv", "66MHz", "100MHz", "133MHz", "?4", "?5", "?6", "?7" };
-  u16 secstatus;
-  u32 status, upstcr, downstcr;
-
-  printf("PCI-X bridge device\n");
-
-  if (verbose < 2)
-    return;
-
-  if (!config_fetch(d, where + PCI_PCIX_BRIDGE_STATUS, 12))
-    return;
-
-  secstatus = get_conf_word(d, where + PCI_PCIX_BRIDGE_SEC_STATUS);
-  printf("\t\tSecondary Status: 64bit%c 133MHz%c SCD%c USC%c SCO%c SRD%c Freq=%s\n",
-	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_64BIT),
-	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_133MHZ),
-	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_SC_DISCARDED),
-	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_UNEXPECTED_SC),
-	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_SC_OVERRUN),
-	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_SPLIT_REQUEST_DELAYED),
-	 sec_clock_freq[(secstatus >> 6) & 7]);
-  status = get_conf_long(d, where + PCI_PCIX_BRIDGE_STATUS);
-  printf("\t\tStatus: Dev=%02x:%02x.%d 64bit%c 133MHz%c SCD%c USC%c SCO%c SRD%c\n",
-	 ((status >> 8) & 0xff),
-	 ((status >> 3) & 0x1f),
-	 (status & PCI_PCIX_BRIDGE_STATUS_FUNCTION),
-	 FLAG(status, PCI_PCIX_BRIDGE_STATUS_64BIT),
-	 FLAG(status, PCI_PCIX_BRIDGE_STATUS_133MHZ),
-	 FLAG(status, PCI_PCIX_BRIDGE_STATUS_SC_DISCARDED),
-	 FLAG(status, PCI_PCIX_BRIDGE_STATUS_UNEXPECTED_SC),
-	 FLAG(status, PCI_PCIX_BRIDGE_STATUS_SC_OVERRUN),
-	 FLAG(status, PCI_PCIX_BRIDGE_STATUS_SPLIT_REQUEST_DELAYED));
-  upstcr = get_conf_long(d, where + PCI_PCIX_BRIDGE_UPSTREAM_SPLIT_TRANS_CTRL);
-  printf("\t\tUpstream: Capacity=%u CommitmentLimit=%u\n",
-	 (upstcr & PCI_PCIX_BRIDGE_STR_CAPACITY),
-	 (upstcr >> 16) & 0xffff);
-  downstcr = get_conf_long(d, where + PCI_PCIX_BRIDGE_DOWNSTREAM_SPLIT_TRANS_CTRL);
-  printf("\t\tDownstream: Capacity=%u CommitmentLimit=%u\n",
-	 (downstcr & PCI_PCIX_BRIDGE_STR_CAPACITY),
-	 (downstcr >> 16) & 0xffff);
-}
-
-static void
-cap_pcix(struct device *d, int where)
-{
-  switch (get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f)
-    {
-    case PCI_HEADER_TYPE_NORMAL:
-      cap_pcix_nobridge(d, where);
-      break;
-    case PCI_HEADER_TYPE_BRIDGE:
-      cap_pcix_bridge(d, where);
-      break;
-    }
-}
-
-static inline char *
-ht_link_width(unsigned width)
-{
-  static char * const widths[8] = { "8bit", "16bit", "[2]", "32bit", "2bit", "4bit", "[6]", "N/C" };
-  return widths[width];
-}
-
-static inline char *
-ht_link_freq(unsigned freq)
-{
-  static char * const freqs[16] = { "200MHz", "300MHz", "400MHz", "500MHz", "600MHz", "800MHz", "1.0GHz", "1.2GHz",
-				    "1.4GHz", "1.6GHz", "[a]", "[b]", "[c]", "[d]", "[e]", "Vend" };
-  return freqs[freq];
-}
-
-static void
-cap_ht_pri(struct device *d, int where, int cmd)
-{
-  u16 lctr0, lcnf0, lctr1, lcnf1, eh;
-  u8 rid, lfrer0, lfcap0, ftr, lfrer1, lfcap1, mbu, mlu, bn;
-  char *fmt;
-
-  printf("HyperTransport: Slave or Primary Interface\n");
-  if (verbose < 2)
-    return;
-
-  if (!config_fetch(d, where + PCI_HT_PRI_LCTR0, PCI_HT_PRI_SIZEOF - PCI_HT_PRI_LCTR0))
-    return;
-  rid = get_conf_byte(d, where + PCI_HT_PRI_RID);
-  if (rid < 0x22 && rid > 0x11)
-    printf("\t\t!!! Possibly incomplete decoding\n");
-
-  if (rid >= 0x22)
-    fmt = "\t\tCommand: BaseUnitID=%u UnitCnt=%u MastHost%c DefDir%c DUL%c\n";
-  else
-    fmt = "\t\tCommand: BaseUnitID=%u UnitCnt=%u MastHost%c DefDir%c\n";
-  printf(fmt,
-	 (cmd & PCI_HT_PRI_CMD_BUID),
-	 (cmd & PCI_HT_PRI_CMD_UC) >> 5,
-	 FLAG(cmd, PCI_HT_PRI_CMD_MH),
-	 FLAG(cmd, PCI_HT_PRI_CMD_DD),
-	 FLAG(cmd, PCI_HT_PRI_CMD_DUL));
-  lctr0 = get_conf_word(d, where + PCI_HT_PRI_LCTR0);
-  if (rid >= 0x22)
-    fmt = "\t\tLink Control 0: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x IsocEn%c LSEn%c ExtCTL%c 64b%c\n";
-  else
-    fmt = "\t\tLink Control 0: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x\n";
-  printf(fmt,
-	 FLAG(lctr0, PCI_HT_LCTR_CFLE),
-	 FLAG(lctr0, PCI_HT_LCTR_CST),
-	 FLAG(lctr0, PCI_HT_LCTR_CFE),
-	 FLAG(lctr0, PCI_HT_LCTR_LKFAIL),
-	 FLAG(lctr0, PCI_HT_LCTR_INIT),
-	 FLAG(lctr0, PCI_HT_LCTR_EOC),
-	 FLAG(lctr0, PCI_HT_LCTR_TXO),
-	 (lctr0 & PCI_HT_LCTR_CRCERR) >> 8,
-	 FLAG(lctr0, PCI_HT_LCTR_ISOCEN),
-	 FLAG(lctr0, PCI_HT_LCTR_LSEN),
-	 FLAG(lctr0, PCI_HT_LCTR_EXTCTL),
-	 FLAG(lctr0, PCI_HT_LCTR_64B));
-  lcnf0 = get_conf_word(d, where + PCI_HT_PRI_LCNF0);
-  if (rid >= 0x22)
-    fmt = "\t\tLink Config 0: MLWI=%1$s DwFcIn%5$c MLWO=%2$s DwFcOut%6$c LWI=%3$s DwFcInEn%7$c LWO=%4$s DwFcOutEn%8$c\n";
-  else
-    fmt = "\t\tLink Config 0: MLWI=%s MLWO=%s LWI=%s LWO=%s\n";
-  printf(fmt,
-	 ht_link_width(lcnf0 & PCI_HT_LCNF_MLWI),
-	 ht_link_width((lcnf0 & PCI_HT_LCNF_MLWO) >> 4),
-	 ht_link_width((lcnf0 & PCI_HT_LCNF_LWI) >> 8),
-	 ht_link_width((lcnf0 & PCI_HT_LCNF_LWO) >> 12),
-	 FLAG(lcnf0, PCI_HT_LCNF_DFI),
-	 FLAG(lcnf0, PCI_HT_LCNF_DFO),
-	 FLAG(lcnf0, PCI_HT_LCNF_DFIE),
-	 FLAG(lcnf0, PCI_HT_LCNF_DFOE));
-  lctr1 = get_conf_word(d, where + PCI_HT_PRI_LCTR1);
-  if (rid >= 0x22)
-    fmt = "\t\tLink Control 1: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x IsocEn%c LSEn%c ExtCTL%c 64b%c\n";
-  else
-    fmt = "\t\tLink Control 1: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x\n";
-  printf(fmt,
-	 FLAG(lctr1, PCI_HT_LCTR_CFLE),
-	 FLAG(lctr1, PCI_HT_LCTR_CST),
-	 FLAG(lctr1, PCI_HT_LCTR_CFE),
-	 FLAG(lctr1, PCI_HT_LCTR_LKFAIL),
-	 FLAG(lctr1, PCI_HT_LCTR_INIT),
-	 FLAG(lctr1, PCI_HT_LCTR_EOC),
-	 FLAG(lctr1, PCI_HT_LCTR_TXO),
-	 (lctr1 & PCI_HT_LCTR_CRCERR) >> 8,
-	 FLAG(lctr1, PCI_HT_LCTR_ISOCEN),
-	 FLAG(lctr1, PCI_HT_LCTR_LSEN),
-	 FLAG(lctr1, PCI_HT_LCTR_EXTCTL),
-	 FLAG(lctr1, PCI_HT_LCTR_64B));
-  lcnf1 = get_conf_word(d, where + PCI_HT_PRI_LCNF1);
-  if (rid >= 0x22)
-    fmt = "\t\tLink Config 1: MLWI=%1$s DwFcIn%5$c MLWO=%2$s DwFcOut%6$c LWI=%3$s DwFcInEn%7$c LWO=%4$s DwFcOutEn%8$c\n";
-  else
-    fmt = "\t\tLink Config 1: MLWI=%s MLWO=%s LWI=%s LWO=%s\n";
-  printf(fmt,
-	 ht_link_width(lcnf1 & PCI_HT_LCNF_MLWI),
-	 ht_link_width((lcnf1 & PCI_HT_LCNF_MLWO) >> 4),
-	 ht_link_width((lcnf1 & PCI_HT_LCNF_LWI) >> 8),
-	 ht_link_width((lcnf1 & PCI_HT_LCNF_LWO) >> 12),
-	 FLAG(lcnf1, PCI_HT_LCNF_DFI),
-	 FLAG(lcnf1, PCI_HT_LCNF_DFO),
-	 FLAG(lcnf1, PCI_HT_LCNF_DFIE),
-	 FLAG(lcnf1, PCI_HT_LCNF_DFOE));
-  printf("\t\tRevision ID: %u.%02u\n",
-	 (rid & PCI_HT_RID_MAJ) >> 5, (rid & PCI_HT_RID_MIN));
-  if (rid < 0x22)
-    return;
-  lfrer0 = get_conf_byte(d, where + PCI_HT_PRI_LFRER0);
-  printf("\t\tLink Frequency 0: %s\n", ht_link_freq(lfrer0 & PCI_HT_LFRER_FREQ));
-  printf("\t\tLink Error 0: <Prot%c <Ovfl%c <EOC%c CTLTm%c\n",
-	 FLAG(lfrer0, PCI_HT_LFRER_PROT),
-	 FLAG(lfrer0, PCI_HT_LFRER_OV),
-	 FLAG(lfrer0, PCI_HT_LFRER_EOC),
-	 FLAG(lfrer0, PCI_HT_LFRER_CTLT));
-  lfcap0 = get_conf_byte(d, where + PCI_HT_PRI_LFCAP0);
-  printf("\t\tLink Frequency Capability 0: 200MHz%c 300MHz%c 400MHz%c 500MHz%c 600MHz%c 800MHz%c 1.0GHz%c 1.2GHz%c 1.4GHz%c 1.6GHz%c Vend%c\n",
-	 FLAG(lfcap0, PCI_HT_LFCAP_200),
-	 FLAG(lfcap0, PCI_HT_LFCAP_300),
-	 FLAG(lfcap0, PCI_HT_LFCAP_400),
-	 FLAG(lfcap0, PCI_HT_LFCAP_500),
-	 FLAG(lfcap0, PCI_HT_LFCAP_600),
-	 FLAG(lfcap0, PCI_HT_LFCAP_800),
-	 FLAG(lfcap0, PCI_HT_LFCAP_1000),
-	 FLAG(lfcap0, PCI_HT_LFCAP_1200),
-	 FLAG(lfcap0, PCI_HT_LFCAP_1400),
-	 FLAG(lfcap0, PCI_HT_LFCAP_1600),
-	 FLAG(lfcap0, PCI_HT_LFCAP_VEND));
-  ftr = get_conf_byte(d, where + PCI_HT_PRI_FTR);
-  printf("\t\tFeature Capability: IsocFC%c LDTSTOP%c CRCTM%c ECTLT%c 64bA%c UIDRD%c\n",
-	 FLAG(ftr, PCI_HT_FTR_ISOCFC),
-	 FLAG(ftr, PCI_HT_FTR_LDTSTOP),
-	 FLAG(ftr, PCI_HT_FTR_CRCTM),
-	 FLAG(ftr, PCI_HT_FTR_ECTLT),
-	 FLAG(ftr, PCI_HT_FTR_64BA),
-	 FLAG(ftr, PCI_HT_FTR_UIDRD));
-  lfrer1 = get_conf_byte(d, where + PCI_HT_PRI_LFRER1);
-  printf("\t\tLink Frequency 1: %s\n", ht_link_freq(lfrer1 & PCI_HT_LFRER_FREQ));
-  printf("\t\tLink Error 1: <Prot%c <Ovfl%c <EOC%c CTLTm%c\n",
-	 FLAG(lfrer1, PCI_HT_LFRER_PROT),
-	 FLAG(lfrer1, PCI_HT_LFRER_OV),
-	 FLAG(lfrer1, PCI_HT_LFRER_EOC),
-	 FLAG(lfrer1, PCI_HT_LFRER_CTLT));
-  lfcap1 = get_conf_byte(d, where + PCI_HT_PRI_LFCAP1);
-  printf("\t\tLink Frequency Capability 1: 200MHz%c 300MHz%c 400MHz%c 500MHz%c 600MHz%c 800MHz%c 1.0GHz%c 1.2GHz%c 1.4GHz%c 1.6GHz%c Vend%c\n",
-	 FLAG(lfcap1, PCI_HT_LFCAP_200),
-	 FLAG(lfcap1, PCI_HT_LFCAP_300),
-	 FLAG(lfcap1, PCI_HT_LFCAP_400),
-	 FLAG(lfcap1, PCI_HT_LFCAP_500),
-	 FLAG(lfcap1, PCI_HT_LFCAP_600),
-	 FLAG(lfcap1, PCI_HT_LFCAP_800),
-	 FLAG(lfcap1, PCI_HT_LFCAP_1000),
-	 FLAG(lfcap1, PCI_HT_LFCAP_1200),
-	 FLAG(lfcap1, PCI_HT_LFCAP_1400),
-	 FLAG(lfcap1, PCI_HT_LFCAP_1600),
-	 FLAG(lfcap1, PCI_HT_LFCAP_VEND));
-  eh = get_conf_word(d, where + PCI_HT_PRI_EH);
-  printf("\t\tError Handling: PFlE%c OFlE%c PFE%c OFE%c EOCFE%c RFE%c CRCFE%c SERRFE%c CF%c RE%c PNFE%c ONFE%c EOCNFE%c RNFE%c CRCNFE%c SERRNFE%c\n",
-	 FLAG(eh, PCI_HT_EH_PFLE),
-	 FLAG(eh, PCI_HT_EH_OFLE),
-	 FLAG(eh, PCI_HT_EH_PFE),
-	 FLAG(eh, PCI_HT_EH_OFE),
-	 FLAG(eh, PCI_HT_EH_EOCFE),
-	 FLAG(eh, PCI_HT_EH_RFE),
-	 FLAG(eh, PCI_HT_EH_CRCFE),
-	 FLAG(eh, PCI_HT_EH_SERRFE),
-	 FLAG(eh, PCI_HT_EH_CF),
-	 FLAG(eh, PCI_HT_EH_RE),
-	 FLAG(eh, PCI_HT_EH_PNFE),
-	 FLAG(eh, PCI_HT_EH_ONFE),
-	 FLAG(eh, PCI_HT_EH_EOCNFE),
-	 FLAG(eh, PCI_HT_EH_RNFE),
-	 FLAG(eh, PCI_HT_EH_CRCNFE),
-	 FLAG(eh, PCI_HT_EH_SERRNFE));
-  mbu = get_conf_byte(d, where + PCI_HT_PRI_MBU);
-  mlu = get_conf_byte(d, where + PCI_HT_PRI_MLU);
-  printf("\t\tPrefetchable memory behind bridge Upper: %02x-%02x\n", mbu, mlu);
-  bn = get_conf_byte(d, where + PCI_HT_PRI_BN);
-  printf("\t\tBus Number: %02x\n", bn);
-}
-
-static void
-cap_ht_sec(struct device *d, int where, int cmd)
-{
-  u16 lctr, lcnf, ftr, eh;
-  u8 rid, lfrer, lfcap, mbu, mlu;
-  char *fmt;
-
-  printf("HyperTransport: Host or Secondary Interface\n");
-  if (verbose < 2)
-    return;
-
-  if (!config_fetch(d, where + PCI_HT_SEC_LCTR, PCI_HT_SEC_SIZEOF - PCI_HT_SEC_LCTR))
-    return;
-  rid = get_conf_byte(d, where + PCI_HT_SEC_RID);
-  if (rid < 0x22 && rid > 0x11)
-    printf("\t\t!!! Possibly incomplete decoding\n");
-
-  if (rid >= 0x22)
-    fmt = "\t\tCommand: WarmRst%c DblEnd%c DevNum=%u ChainSide%c HostHide%c Slave%c <EOCErr%c DUL%c\n";
-  else
-    fmt = "\t\tCommand: WarmRst%c DblEnd%c\n";
-  printf(fmt,
-	 FLAG(cmd, PCI_HT_SEC_CMD_WR),
-	 FLAG(cmd, PCI_HT_SEC_CMD_DE),
-	 (cmd & PCI_HT_SEC_CMD_DN) >> 2,
-	 FLAG(cmd, PCI_HT_SEC_CMD_CS),
-	 FLAG(cmd, PCI_HT_SEC_CMD_HH),
-	 FLAG(cmd, PCI_HT_SEC_CMD_AS),
-	 FLAG(cmd, PCI_HT_SEC_CMD_HIECE),
-	 FLAG(cmd, PCI_HT_SEC_CMD_DUL));
-  lctr = get_conf_word(d, where + PCI_HT_SEC_LCTR);
-  if (rid >= 0x22)
-    fmt = "\t\tLink Control: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x IsocEn%c LSEn%c ExtCTL%c 64b%c\n";
-  else
-    fmt = "\t\tLink Control: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x\n";
-  printf(fmt,
-	 FLAG(lctr, PCI_HT_LCTR_CFLE),
-	 FLAG(lctr, PCI_HT_LCTR_CST),
-	 FLAG(lctr, PCI_HT_LCTR_CFE),
-	 FLAG(lctr, PCI_HT_LCTR_LKFAIL),
-	 FLAG(lctr, PCI_HT_LCTR_INIT),
-	 FLAG(lctr, PCI_HT_LCTR_EOC),
-	 FLAG(lctr, PCI_HT_LCTR_TXO),
-	 (lctr & PCI_HT_LCTR_CRCERR) >> 8,
-	 FLAG(lctr, PCI_HT_LCTR_ISOCEN),
-	 FLAG(lctr, PCI_HT_LCTR_LSEN),
-	 FLAG(lctr, PCI_HT_LCTR_EXTCTL),
-	 FLAG(lctr, PCI_HT_LCTR_64B));
-  lcnf = get_conf_word(d, where + PCI_HT_SEC_LCNF);
-  if (rid >= 0x22)
-    fmt = "\t\tLink Config: MLWI=%1$s DwFcIn%5$c MLWO=%2$s DwFcOut%6$c LWI=%3$s DwFcInEn%7$c LWO=%4$s DwFcOutEn%8$c\n";
-  else
-    fmt = "\t\tLink Config: MLWI=%s MLWO=%s LWI=%s LWO=%s\n";
-  printf(fmt,
-	 ht_link_width(lcnf & PCI_HT_LCNF_MLWI),
-	 ht_link_width((lcnf & PCI_HT_LCNF_MLWO) >> 4),
-	 ht_link_width((lcnf & PCI_HT_LCNF_LWI) >> 8),
-	 ht_link_width((lcnf & PCI_HT_LCNF_LWO) >> 12),
-	 FLAG(lcnf, PCI_HT_LCNF_DFI),
-	 FLAG(lcnf, PCI_HT_LCNF_DFO),
-	 FLAG(lcnf, PCI_HT_LCNF_DFIE),
-	 FLAG(lcnf, PCI_HT_LCNF_DFOE));
-  printf("\t\tRevision ID: %u.%02u\n",
-	 (rid & PCI_HT_RID_MAJ) >> 5, (rid & PCI_HT_RID_MIN));
-  if (rid < 0x22)
-    return;
-  lfrer = get_conf_byte(d, where + PCI_HT_SEC_LFRER);
-  printf("\t\tLink Frequency: %s\n", ht_link_freq(lfrer & PCI_HT_LFRER_FREQ));
-  printf("\t\tLink Error: <Prot%c <Ovfl%c <EOC%c CTLTm%c\n",
-	 FLAG(lfrer, PCI_HT_LFRER_PROT),
-	 FLAG(lfrer, PCI_HT_LFRER_OV),
-	 FLAG(lfrer, PCI_HT_LFRER_EOC),
-	 FLAG(lfrer, PCI_HT_LFRER_CTLT));
-  lfcap = get_conf_byte(d, where + PCI_HT_SEC_LFCAP);
-  printf("\t\tLink Frequency Capability: 200MHz%c 300MHz%c 400MHz%c 500MHz%c 600MHz%c 800MHz%c 1.0GHz%c 1.2GHz%c 1.4GHz%c 1.6GHz%c Vend%c\n",
-	 FLAG(lfcap, PCI_HT_LFCAP_200),
-	 FLAG(lfcap, PCI_HT_LFCAP_300),
-	 FLAG(lfcap, PCI_HT_LFCAP_400),
-	 FLAG(lfcap, PCI_HT_LFCAP_500),
-	 FLAG(lfcap, PCI_HT_LFCAP_600),
-	 FLAG(lfcap, PCI_HT_LFCAP_800),
-	 FLAG(lfcap, PCI_HT_LFCAP_1000),
-	 FLAG(lfcap, PCI_HT_LFCAP_1200),
-	 FLAG(lfcap, PCI_HT_LFCAP_1400),
-	 FLAG(lfcap, PCI_HT_LFCAP_1600),
-	 FLAG(lfcap, PCI_HT_LFCAP_VEND));
-  ftr = get_conf_word(d, where + PCI_HT_SEC_FTR);
-  printf("\t\tFeature Capability: IsocFC%c LDTSTOP%c CRCTM%c ECTLT%c 64bA%c UIDRD%c ExtRS%c UCnfE%c\n",
-	 FLAG(ftr, PCI_HT_FTR_ISOCFC),
-	 FLAG(ftr, PCI_HT_FTR_LDTSTOP),
-	 FLAG(ftr, PCI_HT_FTR_CRCTM),
-	 FLAG(ftr, PCI_HT_FTR_ECTLT),
-	 FLAG(ftr, PCI_HT_FTR_64BA),
-	 FLAG(ftr, PCI_HT_FTR_UIDRD),
-	 FLAG(ftr, PCI_HT_SEC_FTR_EXTRS),
-	 FLAG(ftr, PCI_HT_SEC_FTR_UCNFE));
-  if (ftr & PCI_HT_SEC_FTR_EXTRS)
-    {
-      eh = get_conf_word(d, where + PCI_HT_SEC_EH);
-      printf("\t\tError Handling: PFlE%c OFlE%c PFE%c OFE%c EOCFE%c RFE%c CRCFE%c SERRFE%c CF%c RE%c PNFE%c ONFE%c EOCNFE%c RNFE%c CRCNFE%c SERRNFE%c\n",
-	     FLAG(eh, PCI_HT_EH_PFLE),
-	     FLAG(eh, PCI_HT_EH_OFLE),
-	     FLAG(eh, PCI_HT_EH_PFE),
-	     FLAG(eh, PCI_HT_EH_OFE),
-	     FLAG(eh, PCI_HT_EH_EOCFE),
-	     FLAG(eh, PCI_HT_EH_RFE),
-	     FLAG(eh, PCI_HT_EH_CRCFE),
-	     FLAG(eh, PCI_HT_EH_SERRFE),
-	     FLAG(eh, PCI_HT_EH_CF),
-	     FLAG(eh, PCI_HT_EH_RE),
-	     FLAG(eh, PCI_HT_EH_PNFE),
-	     FLAG(eh, PCI_HT_EH_ONFE),
-	     FLAG(eh, PCI_HT_EH_EOCNFE),
-	     FLAG(eh, PCI_HT_EH_RNFE),
-	     FLAG(eh, PCI_HT_EH_CRCNFE),
-	     FLAG(eh, PCI_HT_EH_SERRNFE));
-      mbu = get_conf_byte(d, where + PCI_HT_SEC_MBU);
-      mlu = get_conf_byte(d, where + PCI_HT_SEC_MLU);
-      printf("\t\tPrefetchable memory behind bridge Upper: %02x-%02x\n", mbu, mlu);
-    }
-}
-
-static void
-cap_ht(struct device *d, int where, int cmd)
-{
-  int type;
-
-  switch (cmd & PCI_HT_CMD_TYP_HI)
-    {
-    case PCI_HT_CMD_TYP_HI_PRI:
-      cap_ht_pri(d, where, cmd);
-      return;
-    case PCI_HT_CMD_TYP_HI_SEC:
-      cap_ht_sec(d, where, cmd);
-      return;
-    }
-
-  type = cmd & PCI_HT_CMD_TYP;
-  switch (type)
-    {
-    case PCI_HT_CMD_TYP_SW:
-      printf("HyperTransport: Switch\n");
-      break;
-    case PCI_HT_CMD_TYP_IDC:
-      printf("HyperTransport: Interrupt Discovery and Configuration\n");
-      break;
-    case PCI_HT_CMD_TYP_RID:
-      printf("HyperTransport: Revision ID: %u.%02u\n",
-	     (cmd & PCI_HT_RID_MAJ) >> 5, (cmd & PCI_HT_RID_MIN));
-      break;
-    case PCI_HT_CMD_TYP_UIDC:
-      printf("HyperTransport: UnitID Clumping\n");
-      break;
-    case PCI_HT_CMD_TYP_ECSA:
-      printf("HyperTransport: Extended Configuration Space Access\n");
-      break;
-    case PCI_HT_CMD_TYP_AM:
-      printf("HyperTransport: Address Mapping\n");
-      break;
-    case PCI_HT_CMD_TYP_MSIM:
-      printf("HyperTransport: MSI Mapping Enable%c Fixed%c\n",
-	     FLAG(cmd, PCI_HT_MSIM_CMD_EN),
-	     FLAG(cmd, PCI_HT_MSIM_CMD_FIXD));
-      if (verbose >= 2 && !(cmd & PCI_HT_MSIM_CMD_FIXD))
-	{
-	  u32 offl, offh;
-	  if (!config_fetch(d, where + PCI_HT_MSIM_ADDR_LO, 8))
-	    break;
-	  offl = get_conf_long(d, where + PCI_HT_MSIM_ADDR_LO);
-	  offh = get_conf_long(d, where + PCI_HT_MSIM_ADDR_HI);
-	  printf("\t\tMapping Address Base: %016llx\n", ((unsigned long long)offh << 32) | (offl & ~0xfffff));
-	}
-      break;
-    case PCI_HT_CMD_TYP_DR:
-      printf("HyperTransport: DirectRoute\n");
-      break;
-    case PCI_HT_CMD_TYP_VCS:
-      printf("HyperTransport: VCSet\n");
-      break;
-    case PCI_HT_CMD_TYP_RM:
-      printf("HyperTransport: Retry Mode\n");
-      break;
-    case PCI_HT_CMD_TYP_X86:
-      printf("HyperTransport: X86 (reserved)\n");
-      break;
-    default:
-      printf("HyperTransport: #%02x\n", type >> 11);
-    }
-}
-
-static void
-cap_msi(struct device *d, int where, int cap)
-{
-  int is64;
-  u32 t;
-  u16 w;
-
-  printf("MSI: Mask%c 64bit%c Count=%d/%d Enable%c\n",
-         FLAG(cap, PCI_MSI_FLAGS_MASK_BIT),
-	 FLAG(cap, PCI_MSI_FLAGS_64BIT),
-	 1 << ((cap & PCI_MSI_FLAGS_QSIZE) >> 4),
-	 1 << ((cap & PCI_MSI_FLAGS_QMASK) >> 1),
-	 FLAG(cap, PCI_MSI_FLAGS_ENABLE));
-  if (verbose < 2)
-    return;
-  is64 = cap & PCI_MSI_FLAGS_64BIT;
-  if (!config_fetch(d, where + PCI_MSI_ADDRESS_LO, (is64 ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32) + 2 - PCI_MSI_ADDRESS_LO))
-    return;
-  printf("\t\tAddress: ");
-  if (is64)
-    {
-      t = get_conf_long(d, where + PCI_MSI_ADDRESS_HI);
-      w = get_conf_word(d, where + PCI_MSI_DATA_64);
-      printf("%08x", t);
-    }
-  else
-    w = get_conf_word(d, where + PCI_MSI_DATA_32);
-  t = get_conf_long(d, where + PCI_MSI_ADDRESS_LO);
-  printf("%08x  Data: %04x\n", t, w);
-  if (cap & PCI_MSI_FLAGS_MASK_BIT)
-    {
-      u32 mask, pending;
-
-      if (is64)
-	{
-	  if (!config_fetch(d, where + PCI_MSI_MASK_BIT_64, 8))
-	    return;
-	  mask = get_conf_long(d, where + PCI_MSI_MASK_BIT_64);
-	  pending = get_conf_long(d, where + PCI_MSI_PENDING_64);
-	}
-      else
-        {
-	  if (!config_fetch(d, where + PCI_MSI_MASK_BIT_32, 8))
-	    return;
-	  mask = get_conf_long(d, where + PCI_MSI_MASK_BIT_32);
-	  pending = get_conf_long(d, where + PCI_MSI_PENDING_32);
-	}
-      printf("\t\tMasking: %08x  Pending: %08x\n", mask, pending);
-    }
-}
-
-static float power_limit(int value, int scale)
-{
-  static const float scales[4] = { 1.0, 0.1, 0.01, 0.001 };
-  return value * scales[scale];
-}
-
-static const char *latency_l0s(int value)
-{
-  static const char *latencies[] = { "<64ns", "<128ns", "<256ns", "<512ns", "<1us", "<2us", "<4us", "unlimited" };
-  return latencies[value];
-}
-
-static const char *latency_l1(int value)
-{
-  static const char *latencies[] = { "<1us", "<2us", "<4us", "<8us", "<16us", "<32us", "<64us", "unlimited" };
-  return latencies[value];
-}
-
-static void cap_express_dev(struct device *d, int where, int type)
-{
-  u32 t;
-  u16 w;
-
-  t = get_conf_long(d, where + PCI_EXP_DEVCAP);
-  printf("\t\tDevCap:\tMaxPayload %d bytes, PhantFunc %d, Latency L0s %s, L1 %s\n",
-	128 << (t & PCI_EXP_DEVCAP_PAYLOAD),
-	(1 << ((t & PCI_EXP_DEVCAP_PHANTOM) >> 3)) - 1,
-	latency_l0s((t & PCI_EXP_DEVCAP_L0S) >> 6),
-	latency_l1((t & PCI_EXP_DEVCAP_L1) >> 9));
-  printf("\t\t\tExtTag%c", FLAG(t, PCI_EXP_DEVCAP_EXT_TAG));
-  if ((type == PCI_EXP_TYPE_ENDPOINT) || (type == PCI_EXP_TYPE_LEG_END) ||
-      (type == PCI_EXP_TYPE_UPSTREAM) || (type == PCI_EXP_TYPE_PCI_BRIDGE))
-    printf(" AttnBtn%c AttnInd%c PwrInd%c",
-	FLAG(t, PCI_EXP_DEVCAP_ATN_BUT),
-	FLAG(t, PCI_EXP_DEVCAP_ATN_IND), FLAG(t, PCI_EXP_DEVCAP_PWR_IND));
-  printf(" RBE%c FLReset%c",
-	FLAG(t, PCI_EXP_DEVCAP_RBE),
-	FLAG(t, PCI_EXP_DEVCAP_FLRESET));
-  if (type == PCI_EXP_TYPE_UPSTREAM)
-    printf("SlotPowerLimit %fW",
-	power_limit((t & PCI_EXP_DEVCAP_PWR_VAL) >> 18,
-		    (t & PCI_EXP_DEVCAP_PWR_SCL) >> 26));
-  printf("\n");
-
-  w = get_conf_word(d, where + PCI_EXP_DEVCTL);
-  printf("\t\tDevCtl:\tReport errors: Correctable%c Non-Fatal%c Fatal%c Unsupported%c\n",
-	FLAG(w, PCI_EXP_DEVCTL_CERE),
-	FLAG(w, PCI_EXP_DEVCTL_NFERE),
-	FLAG(w, PCI_EXP_DEVCTL_FERE),
-	FLAG(w, PCI_EXP_DEVCTL_URRE));
-  printf("\t\t\tRlxdOrd%c ExtTag%c PhantFunc%c AuxPwr%c NoSnoop%c",
-	FLAG(w, PCI_EXP_DEVCTL_RELAXED),
-	FLAG(w, PCI_EXP_DEVCTL_EXT_TAG),
-	FLAG(w, PCI_EXP_DEVCTL_PHANTOM),
-	FLAG(w, PCI_EXP_DEVCTL_AUX_PME),
-	FLAG(w, PCI_EXP_DEVCTL_NOSNOOP));
-  if (type == PCI_EXP_TYPE_PCI_BRIDGE || type == PCI_EXP_TYPE_PCIE_BRIDGE)
-    printf(" BrConfRtry%c", FLAG(w, PCI_EXP_DEVCTL_BCRE));
-  if (type == PCI_EXP_TYPE_ENDPOINT && (t & PCI_EXP_DEVCAP_FLRESET))
-    printf(" FLReset%c", FLAG(w, PCI_EXP_DEVCTL_FLRESET));
-  printf("\n\t\t\tMaxPayload %d bytes, MaxReadReq %d bytes\n",
-	128 << ((w & PCI_EXP_DEVCTL_PAYLOAD) >> 5),
-	128 << ((w & PCI_EXP_DEVCTL_READRQ) >> 12));
-
-  w = get_conf_word(d, where + PCI_EXP_DEVSTA);
-  printf("\t\tDevSta:\tCorrErr%c UncorrErr%c FatalErr%c UnsuppReq%c AuxPwr%c TransPend%c\n",
-	FLAG(w, PCI_EXP_DEVSTA_CED),
-	FLAG(w, PCI_EXP_DEVSTA_NFED),
-	FLAG(w, PCI_EXP_DEVSTA_FED),
-	FLAG(w, PCI_EXP_DEVSTA_URD),
-	FLAG(w, PCI_EXP_DEVSTA_AUXPD),
-	FLAG(w, PCI_EXP_DEVSTA_TRPND));
-}
-
-static char *link_speed(int speed)
-{
-  switch (speed)
-    {
-      case 1:
-	return "2.5GT/s";
-      case 2:
-	return "5GT/s";
-      default:
-	return "unknown";
-    }
-}
-
-static char *aspm_support(int code)
-{
-  switch (code)
-    {
-      case 1:
-	return "L0s";
-      case 3:
-	return "L0s L1";
-      default:
-	return "unknown";
-    }
-}
-
-static const char *aspm_enabled(int code)
-{
-  static const char *desc[] = { "Disabled", "L0s Enabled", "L1 Enabled", "L0s L1 Enabled" };
-  return desc[code];
-}
-
-static void cap_express_link(struct device *d, int where, int type)
-{
-  u32 t;
-  u16 w;
-
-  t = get_conf_long(d, where + PCI_EXP_LNKCAP);
-  printf("\t\tLnkCap:\tPort #%d, Speed %s, Width x%d, ASPM %s, Latency L0 %s, L1 %s\n",
-	t >> 24,
-	link_speed(t & PCI_EXP_LNKCAP_SPEED), (t & PCI_EXP_LNKCAP_WIDTH) >> 4,
-	aspm_support((t & PCI_EXP_LNKCAP_ASPM) >> 10),
-	latency_l0s((t & PCI_EXP_LNKCAP_L0S) >> 12),
-	latency_l1((t & PCI_EXP_LNKCAP_L1) >> 15));
-  printf("\t\t\tClockPM%c Suprise%c LLActRep%c BwNot%c\n",
-	FLAG(t, PCI_EXP_LNKCAP_CLOCKPM),
-	FLAG(t, PCI_EXP_LNKCAP_SURPRISE),
-	FLAG(t, PCI_EXP_LNKCAP_DLLA),
-	FLAG(t, PCI_EXP_LNKCAP_LBNC));
-
-  w = get_conf_word(d, where + PCI_EXP_LNKCTL);
-  printf("\t\tLnkCtl:\tASPM %s;", aspm_enabled(w & PCI_EXP_LNKCTL_ASPM));
-  if ((type == PCI_EXP_TYPE_ROOT_PORT) || (type == PCI_EXP_TYPE_ENDPOINT) ||
-      (type == PCI_EXP_TYPE_LEG_END))
-    printf(" RCB %d bytes", w & PCI_EXP_LNKCTL_RCB ? 128 : 64);
-  printf(" Disabled%c Retrain%c CommClk%c\n\t\t\tExtSynch%c ClockPM%c AutWidDis%c BWInt%c AutBWInt%c\n",
-	FLAG(w, PCI_EXP_LNKCTL_DISABLE),
-	FLAG(w, PCI_EXP_LNKCTL_RETRAIN),
-	FLAG(w, PCI_EXP_LNKCTL_CLOCK),
-	FLAG(w, PCI_EXP_LNKCTL_XSYNCH),
-	FLAG(w, PCI_EXP_LNKCTL_CLOCKPM),
-	FLAG(w, PCI_EXP_LNKCTL_HWAUTWD),
-	FLAG(w, PCI_EXP_LNKCTL_BWMIE),
-	FLAG(w, PCI_EXP_LNKCTL_AUTBWIE));
-
-  w = get_conf_word(d, where + PCI_EXP_LNKSTA);
-  printf("\t\tLnkSta:\tSpeed %s, Width x%d, TrErr%c Train%c SlotClk%c DLActive%c BWMgmt%c ABWMgmt%c\n",
-	link_speed(w & PCI_EXP_LNKSTA_SPEED),
-	(w & PCI_EXP_LNKSTA_WIDTH) >> 4,
-	FLAG(w, PCI_EXP_LNKSTA_TR_ERR),
-	FLAG(w, PCI_EXP_LNKSTA_TRAIN),
-	FLAG(w, PCI_EXP_LNKSTA_SL_CLK),
-	FLAG(w, PCI_EXP_LNKSTA_DL_ACT),
-	FLAG(w, PCI_EXP_LNKSTA_BWMGMT),
-	FLAG(w, PCI_EXP_LNKSTA_AUTBW));
-}
-
-static const char *indicator(int code)
-{
-  static const char *names[] = { "Unknown", "On", "Blink", "Off" };
-  return names[code];
-}
-
-static void cap_express_slot(struct device *d, int where)
-{
-  u32 t;
-  u16 w;
-
-  t = get_conf_long(d, where + PCI_EXP_SLTCAP);
-  printf("\t\tSltCap:\tAttnBtn%c PwrCtrl%c MRL%c AttnInd%c PwrInd%c HotPlug%c Surpise%c\n",
-	FLAG(t, PCI_EXP_SLTCAP_ATNB),
-	FLAG(t, PCI_EXP_SLTCAP_PWRC),
-	FLAG(t, PCI_EXP_SLTCAP_MRL),
-	FLAG(t, PCI_EXP_SLTCAP_ATNI),
-	FLAG(t, PCI_EXP_SLTCAP_PWRI),
-	FLAG(t, PCI_EXP_SLTCAP_HPC),
-	FLAG(t, PCI_EXP_SLTCAP_HPS));
-  printf("\t\t\tSlot #%3x, PowerLimit %f; Interlock%c NoCompl%c\n",
-	t >> 19,
-	power_limit((t & PCI_EXP_SLTCAP_PWR_VAL) >> 7, (t & PCI_EXP_SLTCAP_PWR_SCL) >> 15),
-	FLAG(t, PCI_EXP_SLTCAP_INTERLOCK),
-	FLAG(t, PCI_EXP_SLTCAP_NOCMDCOMP));
-
-  w = get_conf_word(d, where + PCI_EXP_SLTCTL);
-  printf("\t\tSltCtl:\tEnable: AttnBtn%c PwrFlt%c MRL%c PresDet%c CmdCplt%c HPIrq%c LinkChg%c\n",
-	FLAG(w, PCI_EXP_SLTCTL_ATNB),
-	FLAG(w, PCI_EXP_SLTCTL_PWRF),
-	FLAG(w, PCI_EXP_SLTCTL_MRLS),
-	FLAG(w, PCI_EXP_SLTCTL_PRSD),
-	FLAG(w, PCI_EXP_SLTCTL_CMDC),
-	FLAG(w, PCI_EXP_SLTCTL_HPIE),
-	FLAG(w, PCI_EXP_SLTCTL_LLCHG));
-  printf("\t\t\tControl: AttnInd %s, PwrInd %s, Power%c Interlock%c\n",
-	indicator((w & PCI_EXP_SLTCTL_ATNI) >> 6),
-	indicator((w & PCI_EXP_SLTCTL_PWRI) >> 8),
-	FLAG(w, PCI_EXP_SLTCTL_PWRC),
-	FLAG(w, PCI_EXP_SLTCTL_INTERLOCK));
-
-  w = get_conf_word(d, where + PCI_EXP_SLTSTA);
-  printf("\t\tSltSta:\tStatus: AttnBtn%c PowerFlt%c MRL%c CmdCplt%c PresDet%c Interlock%c\n",
-	FLAG(w, PCI_EXP_SLTSTA_ATNB),
-	FLAG(w, PCI_EXP_SLTSTA_PWRF),
-	FLAG(w, PCI_EXP_SLTSTA_MRL_ST),
-	FLAG(w, PCI_EXP_SLTSTA_CMDC),
-	FLAG(w, PCI_EXP_SLTSTA_PRES),
-	FLAG(w, PCI_EXP_SLTSTA_INTERLOCK));
-  printf("\t\t\tChanged: MRL%c PresDet%c LinkState%c\n",
-	FLAG(w, PCI_EXP_SLTSTA_MRLS),
-	FLAG(w, PCI_EXP_SLTSTA_PRSD),
-	FLAG(w, PCI_EXP_SLTSTA_LLCHG));
-}
-
-static void cap_express_root(struct device *d, int where)
-{
-  u32 w = get_conf_word(d, where + PCI_EXP_RTCTL);
-  printf("\t\tRootCtl: ErrCorrectable%c ErrNon-Fatal%c ErrFatal%c PMEIntEna%c CRSVisible%c\n",
-	FLAG(w, PCI_EXP_RTCTL_SECEE),
-	FLAG(w, PCI_EXP_RTCTL_SENFEE),
-	FLAG(w, PCI_EXP_RTCTL_SEFEE),
-	FLAG(w, PCI_EXP_RTCTL_PMEIE),
-	FLAG(w, PCI_EXP_RTCTL_CRSVIS));
-
-  w = get_conf_word(d, where + PCI_EXP_RTCAP);
-  printf("\t\tRootCap: CRSVisible%c\n",
-	FLAG(w, PCI_EXP_RTCAP_CRSVIS));
-
-  w = get_conf_word(d, where + PCI_EXP_RTSTA);
-  printf("\t\tRootSta: PME ReqID %04x, PMEStatus%c PMEPending%c\n",
-	w & PCI_EXP_RTSTA_PME_REQID,
-	FLAG(w, PCI_EXP_RTSTA_PME_STATUS),
-	FLAG(w, PCI_EXP_RTSTA_PME_PENDING));
-}
-
-static const char *cap_express_dev2_timeout_range(int type)
-{
-  /* Decode Completion Timeout Ranges. */
-  switch (type)
-    {
-      case 0:
-	return "Not Supported";
-      case 1:
-	return "Range A";
-      case 2:
-	return "Range B";
-      case 3:
-	return "Range AB";
-      case 6:
-	return "Range BC";
-      case 7:
-	return "Range ABC";
-      case 14:
-	return "Range BCD";
-      case 15:
-	return "Range ABCD";
-      default:
-	return "Unknown";
-    }
-}
-
-static const char *cap_express_dev2_timeout_value(int type)
-{
-  /* Decode Completion Timeout Value. */
-  switch (type)
-    {
-      case 0:
-	return "50us to 50ms";
-      case 1:
-	return "50us to 100us";
-      case 2:
-	return "1ms to 10ms";
-      case 5:
-	return "16ms to 55ms";
-      case 6:
-	return "65ms to 210ms";
-      case 9:
-	return "260ms to 900ms";
-      case 10:
-	return "1s to 3.5s";
-      case 13:
-	return "4s to 13s";
-      case 14:
-	return "17s to 64s";
-      default:
-	return "Unknown";
-    }
-}
-
-static void cap_express_dev2(struct device *d, int where, int type)
-{
-  u32 l;
-  u16 w;
-
-  l = get_conf_long(d, where + PCI_EXP_DEVCAP2);
-  printf("\t\tDevCap2: Completion Timeout: %s, TimeoutDis%c",
-	cap_express_dev2_timeout_range(PCI_EXP_DEV2_TIMEOUT_RANGE(l)),
-	FLAG(l, PCI_EXP_DEV2_TIMEOUT_DIS));
-  if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_DOWNSTREAM)
-    printf(" ARIFwd%c\n", FLAG(l, PCI_EXP_DEV2_ARI));
-  else
-    printf("\n");
-
-  w = get_conf_word(d, where + PCI_EXP_DEVCTL2);
-  printf("\t\tDevCtl2: Completion Timeout: %s, TimeoutDis%c",
-	cap_express_dev2_timeout_value(PCI_EXP_DEV2_TIMEOUT_VALUE(w)),
-	FLAG(w, PCI_EXP_DEV2_TIMEOUT_DIS));
-  if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_DOWNSTREAM)
-    printf(" ARIFwd%c\n", FLAG(w, PCI_EXP_DEV2_ARI));
-  else
-    printf("\n");
-}
-
-static const char *cap_express_link2_speed(int type)
-{
-  switch (type)
-    {
-      case 0: /* hardwire to 0 means only the 2.5GT/s is supported */
-      case 1:
-	return "2.5GT/s";
-      case 2:
-	return "5GT/s";
-      default:
-	return "Unknown";
-    }
-}
-
-static const char *cap_express_link2_deemphasis(int type)
-{
-  switch (type)
-    {
-      case 0:
-	return "-6dB";
-      case 1:
-	return "-3.5dB";
-      default:
-	return "Unknown";
-    }
-}
-
-static const char *cap_express_link2_transmargin(int type)
-{
-  switch (type)
-    {
-      case 0:
-	return "Normal Operating Range";
-      case 1:
-	return "800-1200mV(full-swing)/400-700mV(half-swing)";
-      case 2:
-      case 3:
-      case 4:
-      case 5:
-	return "200-400mV(full-swing)/100-200mV(half-swing)";
-      default:
-	return "Unknown";
-    }
-}
-
-static void cap_express_link2(struct device *d, int where, int type UNUSED)
-{
-  u16 w;
-
-  w = get_conf_word(d, where + PCI_EXP_LNKCTL2);
-  printf("\t\tLnkCtl2: Target Link Speed: %s, EnterCompliance%c SpeedDis%c, Selectable De-emphasis: %s\n"
-	"\t\t\t Transmit Margin: %s, EnterModifiedCompliance%c ComplianceSOS%c\n"
-	"\t\t\t Compliance De-emphasis: %s\n",
-	cap_express_link2_speed(PCI_EXP_LNKCTL2_SPEED(w)),
-	FLAG(w, PCI_EXP_LNKCTL2_CMPLNC),
-	FLAG(w, PCI_EXP_LNKCTL2_SPEED_DIS),
-	cap_express_link2_deemphasis(PCI_EXP_LNKCTL2_DEEMPHASIS(w)),
-	cap_express_link2_transmargin(PCI_EXP_LNKCTL2_MARGIN(w)),
-	FLAG(w, PCI_EXP_LNKCTL2_MOD_CMPLNC),
-	FLAG(w, PCI_EXP_LNKCTL2_CMPLNC_SOS),
-	cap_express_link2_deemphasis(PCI_EXP_LNKCTL2_COM_DEEMPHASIS(w)));
-
-  w = get_conf_word(d, where + PCI_EXP_LNKSTA2);
-  printf("\t\tLnkSta2: Current De-emphasis Level: %s\n",
-	cap_express_link2_deemphasis(PCI_EXP_LINKSTA2_DEEMPHASIS(w)));
-}
-
-static void cap_express_slot2(struct device *d UNUSED, int where UNUSED)
-{
-  /* No capabilities that require this field in PCIe rev2.0 spec. */
-}
-
-static void
-cap_express(struct device *d, int where, int cap)
-{
-  int type = (cap & PCI_EXP_FLAGS_TYPE) >> 4;
-  int size;
-  int slot = 0;
-
-  printf("Express ");
-  if (verbose >= 2)
-    printf("(v%d) ", cap & PCI_EXP_FLAGS_VERS);
-  switch (type)
-    {
-    case PCI_EXP_TYPE_ENDPOINT:
-      printf("Endpoint");
-      break;
-    case PCI_EXP_TYPE_LEG_END:
-      printf("Legacy Endpoint");
-      break;
-    case PCI_EXP_TYPE_ROOT_PORT:
-      slot = cap & PCI_EXP_FLAGS_SLOT;
-      printf("Root Port (Slot%c)", FLAG(cap, PCI_EXP_FLAGS_SLOT));
-      break;
-    case PCI_EXP_TYPE_UPSTREAM:
-      printf("Upstream Port");
-      break;
-    case PCI_EXP_TYPE_DOWNSTREAM:
-      slot = cap & PCI_EXP_FLAGS_SLOT;
-      printf("Downstream Port (Slot%c)", FLAG(cap, PCI_EXP_FLAGS_SLOT));
-      break;
-    case PCI_EXP_TYPE_PCI_BRIDGE:
-      printf("PCI/PCI-X Bridge");
-      break;
-    case PCI_EXP_TYPE_PCIE_BRIDGE:
-      printf("PCI/PCI-X to PCI-Express Bridge");
-      break;
-    case PCI_EXP_TYPE_ROOT_INT_EP:
-      printf("Root Complex Integrated Endpoint");
-      break;
-    case PCI_EXP_TYPE_ROOT_EC:
-      printf("Root Complex Event Collector");
-      break;
-    default:
-      printf("Unknown type %d", type);
-  }
-  printf(", MSI %02x\n", (cap & PCI_EXP_FLAGS_IRQ) >> 9);
-  if (verbose < 2)
-    return;
-
-  size = 16;
-  if (slot)
-    size = 24;
-  if (type == PCI_EXP_TYPE_ROOT_PORT)
-    size = 32;
-  if (!config_fetch(d, where + PCI_EXP_DEVCAP, size))
-    return;
-
-  cap_express_dev(d, where, type);
-  cap_express_link(d, where, type);
-  if (slot)
-    cap_express_slot(d, where);
-  if (type == PCI_EXP_TYPE_ROOT_PORT)
-    cap_express_root(d, where);
-
-  if ((cap & PCI_EXP_FLAGS_VERS) < 2)
-    return;
-
-  size = 16;
-  if (slot)
-    size = 24;
-  if (!config_fetch(d, where + PCI_EXP_DEVCAP2, size))
-    return;
-
-  cap_express_dev2(d, where, type);
-  cap_express_link2(d, where, type);
-  if (slot)
-    cap_express_slot2(d, where);
-}
-
-static void
-cap_msix(struct device *d, int where, int cap)
-{
-  u32 off;
-
-  printf("MSI-X: Enable%c Mask%c TabSize=%d\n",
-	 FLAG(cap, PCI_MSIX_ENABLE),
-	 FLAG(cap, PCI_MSIX_MASK),
-	 (cap & PCI_MSIX_TABSIZE) + 1);
-  if (verbose < 2 || !config_fetch(d, where + PCI_MSIX_TABLE, 8))
-    return;
-
-  off = get_conf_long(d, where + PCI_MSIX_TABLE);
-  printf("\t\tVector table: BAR=%d offset=%08x\n",
-	 off & PCI_MSIX_BIR, off & ~PCI_MSIX_BIR);
-  off = get_conf_long(d, where + PCI_MSIX_PBA);
-  printf("\t\tPBA: BAR=%d offset=%08x\n",
-	 off & PCI_MSIX_BIR, off & ~PCI_MSIX_BIR);
-}
-
-static void
-cap_slotid(int cap)
-{
-  int esr = cap & 0xff;
-  int chs = cap >> 8;
-
-  printf("Slot ID: %d slots, First%c, chassis %02x\n",
-	 esr & PCI_SID_ESR_NSLOTS,
-	 FLAG(esr, PCI_SID_ESR_FIC),
-	 chs);
-}
-
-static void
-cap_ssvid(struct device *d, int where)
-{
-  u16 subsys_v, subsys_d;
-  char ssnamebuf[256];
-
-  if (!config_fetch(d, where, 8))
-    return;
-  subsys_v = get_conf_word(d, where + PCI_SSVID_VENDOR);
-  subsys_d = get_conf_word(d, where + PCI_SSVID_DEVICE);
-  printf("Subsystem: %s\n",
-	   pci_lookup_name(pacc, ssnamebuf, sizeof(ssnamebuf),
-			   PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,
-			   d->dev->vendor_id, d->dev->device_id, subsys_v, subsys_d));
-}
-
-static void
-cap_dsn(struct device *d, int where)
-{
-  u32 t1, t2;
-  if (!config_fetch(d, where + 4, 8))
-    return;
-  t1 = get_conf_long(d, where + 4);
-  t2 = get_conf_long(d, where + 8);
-  printf("Device Serial Number %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n",
-	t1 & 0xff, (t1 >> 8) & 0xff, (t1 >> 16) & 0xff, t1 >> 24,
-	t2 & 0xff, (t2 >> 8) & 0xff, (t2 >> 16) & 0xff, t2 >> 24);
-}
-
-static void
-cap_debug_port(int cap)
-{
-  int bar = cap >> 13;
-  int pos = cap & 0x1fff;
-  printf("Debug port: BAR=%d offset=%04x\n", bar, pos);
-}
-
-static void
-cap_aer(struct device *d, int where)
-{
-  u32 l;
-
-  printf("Advanced Error Reporting\n");
-  if (!config_fetch(d, where + PCI_ERR_UNCOR_STATUS, 24))
-    return;
-
-  l = get_conf_long(d, where + PCI_ERR_UNCOR_STATUS);
-  printf("\t\tUESta:\tDLP%c SDES%c TLP%c FCP%c CmpltTO%c CmpltAbrt%c UnxCmplt%c RxOF%c "
-	"MalfTLP%c ECRC%c UnsupReq%c ACSViol%c\n",
-	FLAG(l, PCI_ERR_UNC_DLP), FLAG(l, PCI_ERR_UNC_SDES), FLAG(l, PCI_ERR_UNC_POISON_TLP),
-	FLAG(l, PCI_ERR_UNC_FCP), FLAG(l, PCI_ERR_UNC_COMP_TIME), FLAG(l, PCI_ERR_UNC_COMP_ABORT),
-	FLAG(l, PCI_ERR_UNC_UNX_COMP), FLAG(l, PCI_ERR_UNC_RX_OVER), FLAG(l, PCI_ERR_UNC_MALF_TLP),
-	FLAG(l, PCI_ERR_UNC_ECRC), FLAG(l, PCI_ERR_UNC_UNSUP), FLAG(l, PCI_ERR_UNC_ACS_VIOL));
-  l = get_conf_long(d, where + PCI_ERR_UNCOR_MASK);
-  printf("\t\tUEMsk:\tDLP%c SDES%c TLP%c FCP%c CmpltTO%c CmpltAbrt%c UnxCmplt%c RxOF%c "
-	"MalfTLP%c ECRC%c UnsupReq%c ACSViol%c\n",
-	FLAG(l, PCI_ERR_UNC_DLP), FLAG(l, PCI_ERR_UNC_SDES), FLAG(l, PCI_ERR_UNC_POISON_TLP),
-	FLAG(l, PCI_ERR_UNC_FCP), FLAG(l, PCI_ERR_UNC_COMP_TIME), FLAG(l, PCI_ERR_UNC_COMP_ABORT),
-	FLAG(l, PCI_ERR_UNC_UNX_COMP), FLAG(l, PCI_ERR_UNC_RX_OVER), FLAG(l, PCI_ERR_UNC_MALF_TLP),
-	FLAG(l, PCI_ERR_UNC_ECRC), FLAG(l, PCI_ERR_UNC_UNSUP), FLAG(l, PCI_ERR_UNC_ACS_VIOL));
-  l = get_conf_long(d, where + PCI_ERR_UNCOR_SEVER);
-  printf("\t\tUESvrt:\tDLP%c SDES%c TLP%c FCP%c CmpltTO%c CmpltAbrt%c UnxCmplt%c RxOF%c "
-	"MalfTLP%c ECRC%c UnsupReq%c ACSViol%c\n",
-	FLAG(l, PCI_ERR_UNC_DLP), FLAG(l, PCI_ERR_UNC_SDES), FLAG(l, PCI_ERR_UNC_POISON_TLP),
-	FLAG(l, PCI_ERR_UNC_FCP), FLAG(l, PCI_ERR_UNC_COMP_TIME), FLAG(l, PCI_ERR_UNC_COMP_ABORT),
-	FLAG(l, PCI_ERR_UNC_UNX_COMP), FLAG(l, PCI_ERR_UNC_RX_OVER), FLAG(l, PCI_ERR_UNC_MALF_TLP),
-	FLAG(l, PCI_ERR_UNC_ECRC), FLAG(l, PCI_ERR_UNC_UNSUP), FLAG(l, PCI_ERR_UNC_ACS_VIOL));
-  l = get_conf_long(d, where + PCI_ERR_COR_STATUS);
-  printf("\t\tCESta:\tRxErr%c BadTLP%c BadDLLP%c Rollover%c Timeout%c NonFatalErr%c\n",
-	FLAG(l, PCI_ERR_COR_RCVR), FLAG(l, PCI_ERR_COR_BAD_TLP), FLAG(l, PCI_ERR_COR_BAD_DLLP),
-	FLAG(l, PCI_ERR_COR_REP_ROLL), FLAG(l, PCI_ERR_COR_REP_TIMER), FLAG(l, PCI_ERR_COR_REP_ANFE));
-  l = get_conf_long(d, where + PCI_ERR_COR_MASK);
-  printf("\t\tCEMsk:\tRxErr%c BadTLP%c BadDLLP%c Rollover%c Timeout%c NonFatalErr%c\n",
-	FLAG(l, PCI_ERR_COR_RCVR), FLAG(l, PCI_ERR_COR_BAD_TLP), FLAG(l, PCI_ERR_COR_BAD_DLLP),
-	FLAG(l, PCI_ERR_COR_REP_ROLL), FLAG(l, PCI_ERR_COR_REP_TIMER), FLAG(l, PCI_ERR_COR_REP_ANFE));
-  l = get_conf_long(d, where + PCI_ERR_CAP);
-  printf("\t\tAERCap:\tFirst Error Pointer: %02x, GenCap%c CGenEn%c ChkCap%c ChkEn%c\n",
-	PCI_ERR_CAP_FEP(l), FLAG(l, PCI_ERR_CAP_ECRC_GENC), FLAG(l, PCI_ERR_CAP_ECRC_GENE),
-	FLAG(l, PCI_ERR_CAP_ECRC_CHKC), FLAG(l, PCI_ERR_CAP_ECRC_CHKE));
-
-}
-
-static void
-cap_acs(struct device *d, int where)
-{
-  u16 w;
-
-  printf("Access Control Services\n");
-  if (!config_fetch(d, where + PCI_ACS_CAP, 4))
-    return;
-
-  w = get_conf_word(d, where + PCI_ACS_CAP);
-  printf("\t\tACSCap:\tSrcValid%c TransBlk%c ReqRedir%c CmpltRedir%c UpstreamFwd%c EgressCtrl%c "
-	"DirectTrans%c\n",
-	FLAG(w, PCI_ACS_CAP_VALID), FLAG(w, PCI_ACS_CAP_BLOCK), FLAG(w, PCI_ACS_CAP_REQ_RED),
-	FLAG(w, PCI_ACS_CAP_CMPLT_RED), FLAG(w, PCI_ACS_CAP_FORWARD), FLAG(w, PCI_ACS_CAP_EGRESS),
-	FLAG(w, PCI_ACS_CAP_TRANS));
-  w = get_conf_word(d, where + PCI_ACS_CTRL);
-  printf("\t\tACSCtl:\tSrcValid%c TransBlk%c ReqRedir%c CmpltRedir%c UpstreamFwd%c EgressCtrl%c "
-	"DirectTrans%c\n",
-	FLAG(w, PCI_ACS_CTRL_VALID), FLAG(w, PCI_ACS_CTRL_BLOCK), FLAG(w, PCI_ACS_CTRL_REQ_RED),
-	FLAG(w, PCI_ACS_CTRL_CMPLT_RED), FLAG(w, PCI_ACS_CTRL_FORWARD), FLAG(w, PCI_ACS_CTRL_EGRESS),
-	FLAG(w, PCI_ACS_CTRL_TRANS));
-}
-
-static void
-cap_ari(struct device *d, int where)
-{
-  u16 w;
-
-  printf("Alternative Routing-ID Interpretation (ARI)\n");
-  if (!config_fetch(d, where + PCI_ARI_CAP, 4))
-    return;
-
-  w = get_conf_word(d, where + PCI_ARI_CAP);
-  printf("\t\tARICap:\tMFVC%c ACS%c, Next Function: %d\n",
-	FLAG(w, PCI_ARI_CAP_MFVC), FLAG(w, PCI_ARI_CAP_ACS),
-	PCI_ARI_CAP_NFN(w));
-  w = get_conf_word(d, where + PCI_ARI_CTRL);
-  printf("\t\tARICtl:\tMFVC%c ACS%c, Function Group: %d\n",
-	FLAG(w, PCI_ARI_CTRL_MFVC), FLAG(w, PCI_ARI_CTRL_ACS),
-	PCI_ARI_CTRL_FG(w));
-}
-
-static void
-cap_sriov(struct device *d, int where)
-{
-  u16 b;
-  u16 w;
-  u32 l;
-
-  printf("Single Root I/O Virtualization (SR-IOV)\n");
-  if (!config_fetch(d, where + PCI_IOV_CAP, 0x3c))
-    return;
-
-  l = get_conf_long(d, where + PCI_IOV_CAP);
-  printf("\t\tIOVCap:\tMigration%c, Interrupt Message Number: %03x\n",
-	FLAG(l, PCI_IOV_CAP_VFM), PCI_IOV_CAP_IMN(l));
-  w = get_conf_word(d, where + PCI_IOV_CTRL);
-  printf("\t\tIOVCtl:\tEnable%c Migration%c Interrupt%c MSE%c ARIHierarchy%c\n",
-	FLAG(w, PCI_IOV_CTRL_VFE), FLAG(w, PCI_IOV_CTRL_VFME),
-	FLAG(w, PCI_IOV_CTRL_VFMIE), FLAG(w, PCI_IOV_CTRL_MSE),
-	FLAG(w, PCI_IOV_CTRL_ARI));
-  w = get_conf_word(d, where + PCI_IOV_STATUS);
-  printf("\t\tIOVSta:\tMigration%c\n", FLAG(w, PCI_IOV_STATUS_MS));
-  w = get_conf_word(d, where + PCI_IOV_INITIALVF);
-  printf("\t\tInitial VFs: %d, ", w);
-  w = get_conf_word(d, where + PCI_IOV_TOTALVF);
-  printf("Total VFs: %d, ", w);
-  w = get_conf_word(d, where + PCI_IOV_NUMVF);
-  printf("Number of VFs: %d, ", w);
-  b = get_conf_byte(d, where + PCI_IOV_FDL);
-  printf("Function Dependency Link: %02x\n", b);
-  w = get_conf_word(d, where + PCI_IOV_OFFSET);
-  printf("\t\tVF offset: %d, ", w);
-  w = get_conf_word(d, where + PCI_IOV_STRIDE);
-  printf("stride: %d, ", w);
-  w = get_conf_word(d, where + PCI_IOV_DID);
-  printf("Device ID: %04x\n", w);
-  l = get_conf_long(d, where + PCI_IOV_SUPPS);
-  printf("\t\tSupported Page Size: %08x, ", l);
-  l = get_conf_long(d, where + PCI_IOV_SYSPS);
-  printf("System Page Size: %08x\n", l);
-  printf("\t\tVF Migration: offset: %08x, BIR: %x\n", PCI_IOV_MSA_OFFSET(l),
-	PCI_IOV_MSA_BIR(l));
-}
-
-static void
-show_ext_caps(struct device *d)
-{
-  int where = 0x100;
-  char been_there[0x1000];
-  memset(been_there, 0, 0x1000);
-  do
-    {
-      u32 header;
-      int id;
-
-      if (!config_fetch(d, where, 4))
-	break;
-      header = get_conf_long(d, where);
-      if (!header)
-	break;
-      id = header & 0xffff;
-      printf("\tCapabilities: [%03x] ", where);
-      if (been_there[where]++)
-	{
-	  printf("<chain looped>\n");
-	  break;
-	}
-      switch (id)
-	{
-	  case PCI_EXT_CAP_ID_AER:
-	    cap_aer(d, where);
-	    break;
-	  case PCI_EXT_CAP_ID_VC:
-	    printf("Virtual Channel <?>\n");
-	    break;
-	  case PCI_EXT_CAP_ID_DSN:
-	    cap_dsn(d, where);
-	    break;
-	  case PCI_EXT_CAP_ID_PB:
-	    printf("Power Budgeting <?>\n");
-	    break;
-	  case PCI_EXT_CAP_ID_RCLINK:
-	    printf("Root Complex Link <?>\n");
-	    break;
-	  case PCI_EXT_CAP_ID_RCILINK:
-	    printf("Root Complex Internal Link <?>\n");
-	    break;
-	  case PCI_EXT_CAP_ID_RCECOLL:
-	    printf("Root Complex Event Collector <?>\n");
-	    break;
-	  case PCI_EXT_CAP_ID_MFVC:
-	    printf("Multi-Function Virtual Channel <?>\n");
-	    break;
-	  case PCI_EXT_CAP_ID_RBCB:
-	    printf("Root Bridge Control Block <?>\n");
-	    break;
-	  case PCI_EXT_CAP_ID_VNDR:
-	    printf("Vendor Specific Information <?>\n");
-	    break;
-	  case PCI_EXT_CAP_ID_ACS:
-	    cap_acs(d, where);
-	    break;
-	  case PCI_EXT_CAP_ID_ARI:
-	    cap_ari(d, where);
-	    break;
-	  case PCI_EXT_CAP_ID_SRIOV:
-	    cap_sriov(d, where);
-	    break;
-	  default:
-	    printf("#%02x\n", id);
-	    break;
-	}
-      where = header >> 20;
-    } while (where);
-}
-
-static void
-show_caps(struct device *d)
-{
-  int can_have_ext_caps = 0;
-
-  if (get_conf_word(d, PCI_STATUS) & PCI_STATUS_CAP_LIST)
-    {
-      int where = get_conf_byte(d, PCI_CAPABILITY_LIST) & ~3;
-      byte been_there[256];
-      memset(been_there, 0, 256);
-      while (where)
-	{
-	  int id, next, cap;
-	  printf("\tCapabilities: ");
-	  if (!config_fetch(d, where, 4))
-	    {
-	      puts("<access denied>");
-	      break;
-	    }
-	  id = get_conf_byte(d, where + PCI_CAP_LIST_ID);
-	  next = get_conf_byte(d, where + PCI_CAP_LIST_NEXT) & ~3;
-	  cap = get_conf_word(d, where + PCI_CAP_FLAGS);
-	  printf("[%02x] ", where);
-	  if (been_there[where]++)
-	    {
-	      printf("<chain looped>\n");
-	      break;
-	    }
-	  if (id == 0xff)
-	    {
-	      printf("<chain broken>\n");
-	      break;
-	    }
-	  switch (id)
-	    {
-	    case PCI_CAP_ID_PM:
-	      cap_pm(d, where, cap);
-	      break;
-	    case PCI_CAP_ID_AGP:
-	      cap_agp(d, where, cap);
-	      break;
-	    case PCI_CAP_ID_VPD:
-	      printf("Vital Product Data <?>\n");
-	      break;
-	    case PCI_CAP_ID_SLOTID:
-	      cap_slotid(cap);
-	      break;
-	    case PCI_CAP_ID_MSI:
-	      cap_msi(d, where, cap);
-	      break;
-	    case PCI_CAP_ID_CHSWP:
-	      printf("CompactPCI hot-swap <?>\n");
-	      break;
-	    case PCI_CAP_ID_PCIX:
-	      cap_pcix(d, where);
-	      can_have_ext_caps = 1;
-	      break;
-	    case PCI_CAP_ID_HT:
-	      cap_ht(d, where, cap);
-	      break;
-	    case PCI_CAP_ID_VNDR:
-	      printf("Vendor Specific Information <?>\n");
-	      break;
-	    case PCI_CAP_ID_DBG:
-	      cap_debug_port(cap);
-	      break;
-	    case PCI_CAP_ID_CCRC:
-	      printf("CompactPCI central resource control <?>\n");
-	      break;
-	    case PCI_CAP_ID_HOTPLUG:
-	      printf("Hot-plug capable\n");
-	      break;
-	    case PCI_CAP_ID_SSVID:
-	      cap_ssvid(d, where);
-	      break;
-	    case PCI_CAP_ID_AGP3:
-	      printf("AGP3 <?>\n");
-	      break;
-	    case PCI_CAP_ID_SECURE:
-	      printf("Secure device <?>\n");
-	      break;
-	    case PCI_CAP_ID_EXP:
-	      cap_express(d, where, cap);
-	      can_have_ext_caps = 1;
-	      break;
-	    case PCI_CAP_ID_MSIX:
-	      cap_msix(d, where, cap);
-	      break;
-	    case PCI_CAP_ID_SATA:
-	      printf("SATA HBA <?>\n");
-	      break;
-	    case PCI_CAP_ID_AF:
-	      printf("PCIe advanced features <?>\n");
-	      break;
-	    default:
-	      printf("#%02x [%04x]\n", id, cap);
-	    }
-	  where = next;
-	}
-    }
-  if (can_have_ext_caps)
-    show_ext_caps(d);
-}
-
-/*** Kernel drivers ***/
-
-#ifdef PCI_OS_LINUX
-
-#include <sys/utsname.h>
-
-struct pcimap_entry {
-  struct pcimap_entry *next;
-  unsigned int vendor, device;
-  unsigned int subvendor, subdevice;
-  unsigned int class, class_mask;
-  char module[1];
-};
-
-static struct pcimap_entry *pcimap_head;
-
-static void
-load_pcimap(void)
+sort_them(void)
 {
-  static int tried_pcimap;
-  struct utsname uts;
-  char *name, line[1024];
-  FILE *f;
-
-  if (tried_pcimap)
-    return;
-  tried_pcimap = 1;
+  struct device **index, **h, **last_dev;
+  int cnt;
+  struct device *d;
 
-  if (name = opt_pcimap)
-    {
-      f = fopen(name, "r");
-      if (!f)
-	die("Cannot open pcimap file %s: %m", name);
-    }
-  else
+  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--)
     {
-      if (uname(&uts) < 0)
-	die("uname() failed: %m");
-      name = alloca(64 + strlen(uts.release));
-      sprintf(name, "/lib/modules/%s/modules.pcimap", uts.release);
-      f = fopen(name, "r");
-      if (!f)
-	return;
-    }
-
-  while (fgets(line, sizeof(line), f))
-    {
-      char *c = strchr(line, '\n');
-      struct pcimap_entry *e;
-
-      if (!c)
-	die("Unterminated or too long line in %s", name);
-      *c = 0;
-      if (!line[0] || line[0] == '#')
-	continue;
-
-      c = line;
-      while (*c && *c != ' ' && *c != '\t')
-	c++;
-      if (!*c)
-	continue;	/* FIXME: Emit warnings! */
-      *c++ = 0;
-
-      e = xmalloc(sizeof(*e) + strlen(line));
-      if (sscanf(c, "%i%i%i%i%i%i",
-		 &e->vendor, &e->device,
-		 &e->subvendor, &e->subdevice,
-		 &e->class, &e->class_mask) != 6)
-	continue;
-      e->next = pcimap_head;
-      pcimap_head = e;
-      strcpy(e->module, line);
+      *last_dev = *h;
+      last_dev = &(*h)->next;
+      h++;
     }
-  fclose(f);
+  *last_dev = NULL;
 }
 
-static int
-match_pcimap(struct device *d, struct pcimap_entry *e)
+/*** Normal output ***/
+
+static void
+show_slot_name(struct device *d)
 {
-  struct pci_dev *dev = d->dev;
-  unsigned int class = get_conf_long(d, PCI_REVISION_ID) >> 8;
-  word subv, subd;
+  struct pci_dev *p = d->dev;
 
-#define MATCH(x, y) ((y) > 0xffff || (x) == (y))
-  get_subid(d, &subv, &subd);
-  return
-    MATCH(dev->vendor_id, e->vendor) &&
-    MATCH(dev->device_id, e->device) &&
-    MATCH(subv, e->subvendor) &&
-    MATCH(subd, e->subdevice) &&
-    (class & e->class_mask) == e->class;
-#undef MATCH
+  if (!opt_machine ? opt_domains : (p->domain || opt_domains >= 2))
+    printf("%04x:", p->domain);
+  printf("%02x:%02x.%d", p->bus, p->dev, p->func);
 }
 
-#define DRIVER_BUF_SIZE 1024
-
-static char *
-find_driver(struct device *d, char *buf)
+void
+get_subid(struct device *d, word *subvp, word *subdp)
 {
-  struct pci_dev *dev = d->dev;
-  char name[1024], *drv, *base;
-  int n;
-
-  if (dev->access->method != PCI_ACCESS_SYS_BUS_PCI)
-    return NULL;
-
-  base = pci_get_param(dev->access, "sysfs.path");
-  if (!base || !base[0])
-    return NULL;
-
-  n = snprintf(name, sizeof(name), "%s/devices/%04x:%02x:%02x.%d/driver",
-	       base, dev->domain, dev->bus, dev->dev, dev->func);
-  if (n < 0 || n >= (int)sizeof(name))
-    die("show_driver: sysfs device name too long, why?");
-
-  n = readlink(name, buf, DRIVER_BUF_SIZE);
-  if (n < 0)
-    return NULL;
-  if (n >= DRIVER_BUF_SIZE)
-    return "<name-too-long>";
-  buf[n] = 0;
+  byte htype = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f;
 
-  if (drv = strrchr(buf, '/'))
-    return drv+1;
+  if (htype == PCI_HEADER_TYPE_NORMAL)
+    {
+      *subvp = get_conf_word(d, PCI_SUBSYSTEM_VENDOR_ID);
+      *subdp = get_conf_word(d, PCI_SUBSYSTEM_ID);
+    }
+  else if (htype == PCI_HEADER_TYPE_CARDBUS && d->config_cached >= 128)
+    {
+      *subvp = get_conf_word(d, PCI_CB_SUBSYSTEM_VENDOR_ID);
+      *subdp = get_conf_word(d, PCI_CB_SUBSYSTEM_ID);
+    }
   else
-    return buf;
-}
-
-static void
-show_kernel(struct device *d)
-{
-  char buf[DRIVER_BUF_SIZE];
-  char *driver;
-  struct pcimap_entry *e, *last = NULL;
-
-  if (driver = find_driver(d, buf))
-    printf("\tKernel driver in use: %s\n", driver);
-
-  load_pcimap();
-  for (e=pcimap_head; e; e=e->next)
-    if (match_pcimap(d, e) && (!last || strcmp(last->module, e->module)))
-      {
-	printf("%s %s", (last ? "," : "\tKernel modules:"), e->module);
-	last = e;
-      }
-  if (last)
-    putchar('\n');
+    *subvp = *subdp = 0xffff;
 }
 
 static void
-show_kernel_machine(struct device *d)
+show_terse(struct device *d)
 {
-  char buf[DRIVER_BUF_SIZE];
-  char *driver;
-  struct pcimap_entry *e, *last = NULL;
-
-  if (driver = find_driver(d, buf))
-    printf("Driver:\t%s\n", driver);
-
-  load_pcimap();
-  for (e=pcimap_head; e; e=e->next)
-    if (match_pcimap(d, e) && (!last || strcmp(last->module, e->module)))
-      {
-	printf("Module:\t%s\n", e->module);
-	last = e;
-      }
-}
+  int c;
+  struct pci_dev *p = d->dev;
+  char classbuf[128], devbuf[128];
 
-#else
+  show_slot_name(d);
+  printf(" %s: %s",
+	 pci_lookup_name(pacc, classbuf, sizeof(classbuf),
+			 PCI_LOOKUP_CLASS,
+			 p->device_class),
+	 pci_lookup_name(pacc, devbuf, sizeof(devbuf),
+			 PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,
+			 p->vendor_id, p->device_id));
+  if (c = get_conf_byte(d, PCI_REVISION_ID))
+    printf(" (rev %02x)", c);
+  if (verbose)
+    {
+      char *x;
+      c = get_conf_byte(d, PCI_CLASS_PROG);
+      x = pci_lookup_name(pacc, devbuf, sizeof(devbuf),
+			  PCI_LOOKUP_PROGIF | PCI_LOOKUP_NO_NUMBERS,
+			  p->device_class, c);
+      if (c || x)
+	{
+	  printf(" (prog-if %02x", c);
+	  if (x)
+	    printf(" [%s]", x);
+	  putchar(')');
+	}
+    }
+  putchar('\n');
 
-static void
-show_kernel(struct device *d UNUSED)
-{
-}
+  if (verbose || opt_kernel)
+    {
+      word subsys_v, subsys_d;
+      char ssnamebuf[256];
 
-static void
-show_kernel_machine(struct device *d UNUSED)
-{
+      get_subid(d, &subsys_v, &subsys_d);
+      if (subsys_v && subsys_v != 0xffff)
+	printf("\tSubsystem: %s\n",
+		pci_lookup_name(pacc, ssnamebuf, sizeof(ssnamebuf),
+			PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,
+			p->vendor_id, p->device_id, subsys_v, subsys_d));
+    }
 }
 
-#endif
-
 /*** Verbose output ***/
 
 static void
@@ -2016,8 +350,9 @@
   struct pci_dev *p = d->dev;
   word cmd = get_conf_word(d, PCI_COMMAND);
   int i;
+  int virtual = 0;
 
-  for(i=0; i<cnt; i++)
+  for (i=0; i<cnt; i++)
     {
       pciaddr_t pos = p->base_addr[i];
       pciaddr_t len = (p->known_fields & PCI_FILL_SIZES) ? p->size[i] : 0;
@@ -2034,6 +369,7 @@
 	{
 	  printf("[virtual] ");
 	  flg = pos;
+	  virtual = 1;
 	}
       if (flg & PCI_BASE_ADDRESS_SPACE_IO)
 	{
@@ -2045,7 +381,7 @@
 	    printf("<ignored>");
 	  else
 	    printf("<unassigned>");
-	  if (!(cmd & PCI_COMMAND_IO))
+	  if (!virtual && !(cmd & PCI_COMMAND_IO))
 	    printf(" [disabled]");
 	}
       else
@@ -2067,15 +403,6 @@
 		{
 		  i++;
 		  z = get_conf_long(d, PCI_BASE_ADDRESS_0 + 4*i);
-		  if (opt_buscentric)
-		    {
-		      u32 y = a & 0xffffffff;
-		      if (a || z)
-			printf("%08x%08x", z, y);
-		      else
-			printf("<unassigned>");
-		      done = 1;
-		    }
 		}
 	    }
 	  if (!done)
@@ -2090,7 +417,7 @@
 		 (t == PCI_BASE_ADDRESS_MEM_TYPE_64) ? "64-bit" :
 		 (t == PCI_BASE_ADDRESS_MEM_TYPE_1M) ? "low-1M" : "type 3",
 		 (flg & PCI_BASE_ADDRESS_MEM_PREFETCH) ? "" : "non-");
-	  if (!(cmd & PCI_COMMAND_MEMORY))
+	  if (!virtual && !(cmd & PCI_COMMAND_MEMORY))
 	    printf(" [disabled]");
 	}
       show_size(len);
@@ -2106,6 +433,7 @@
   pciaddr_t len = (p->known_fields & PCI_FILL_SIZES) ? p->rom_size : 0;
   u32 flg = get_conf_long(d, reg);
   word cmd = get_conf_word(d, PCI_COMMAND);
+  int virtual = 0;
 
   if (!rom && !flg && !len)
     return;
@@ -2114,6 +442,7 @@
     {
       printf("[virtual] ");
       flg = rom;
+      virtual = 1;
     }
   printf("Expansion ROM at ");
   if (rom & PCI_ROM_ADDRESS_MASK)
@@ -2124,7 +453,7 @@
     printf("<unassigned>");
   if (!(flg & PCI_ROM_ADDRESS_ENABLE))
     printf(" [disabled]");
-  else if (!(cmd & PCI_COMMAND_MEMORY))
+  else if (!virtual && !(cmd & PCI_COMMAND_MEMORY))
     printf(" [disabled by cmd]");
   show_size(len);
   putchar('\n');
@@ -2259,7 +588,7 @@
 	 get_conf_byte(d, PCI_CB_CARD_BUS),
 	 get_conf_byte(d, PCI_CB_SUBORDINATE_BUS),
 	 get_conf_byte(d, PCI_CB_LATENCY_TIMER));
-  for(i=0; i<2; i++)
+  for (i=0; i<2; i++)
     {
       int p = 8*i;
       u32 base = get_conf_long(d, PCI_CB_MEMORY_BASE_0 + p);
@@ -2269,7 +598,7 @@
 	       (cmd & PCI_COMMAND_MEMORY) ? "" : " [disabled]",
 	       (brc & (PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 << i)) ? " (prefetchable)" : "");
     }
-  for(i=0; i<2; i++)
+  for (i=0; i<2; i++)
     {
       int p = 8*i;
       u32 base = get_conf_long(d, PCI_CB_IO_BASE_0 + p);
@@ -2350,6 +679,9 @@
       return;
     }
 
+  if (p->phy_slot)
+    printf("\tPhysical Slot: %s\n", p->phy_slot);
+
   if (verbose > 1)
     {
       printf("\tControl: I/O%c Mem%c BusMaster%c SpecCycle%c MemWINV%c VGASnoop%c ParErr%c Stepping%c SERR%c FastB2B%c DisINTx%c\n",
@@ -2464,7 +796,7 @@
 	cnt = 4096;
     }
 
-  for(i=0; i<cnt; i++)
+  for (i=0; i<cnt; i++)
     {
       if (! (i & 15))
 	printf("%02x:", i);
@@ -2515,6 +847,8 @@
 	  printf("SDevice:\t%s\n",
 		 pci_lookup_name(pacc, sdbuf, sizeof(sdbuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id, sv_id, sd_id));
 	}
+      if (p->phy_slot)
+	printf("PhySlot:\t%s\n", p->phy_slot);
       if (c = get_conf_byte(d, PCI_REVISION_ID))
 	printf("Rev:\t%02x\n", c);
       if (c = get_conf_byte(d, PCI_CLASS_PROG))
@@ -2545,7 +879,7 @@
 
 /*** Main show function ***/
 
-static void
+void
 show_device(struct device *d)
 {
   if (opt_machine)
@@ -2570,425 +904,10 @@
 {
   struct device *d;
 
-  for(d=first_dev; d; d=d->next)
+  for (d=first_dev; d; d=d->next)
     show_device(d);
 }
 
-/*** Tree output ***/
-
-struct bridge {
-  struct bridge *chain;			/* Single-linked list of bridges */
-  struct bridge *next, *child;		/* Tree of bridges */
-  struct bus *first_bus;		/* List of buses connected to this bridge */
-  unsigned int domain;
-  unsigned int primary, secondary, subordinate;	/* Bus numbers */
-  struct device *br_dev;
-};
-
-struct bus {
-  unsigned int domain;
-  unsigned int number;
-  struct bus *sibling;
-  struct device *first_dev, **last_dev;
-};
-
-static struct bridge host_bridge = { NULL, NULL, NULL, NULL, 0, ~0, 0, ~0, NULL };
-
-static struct bus *
-find_bus(struct bridge *b, unsigned int domain, unsigned int n)
-{
-  struct bus *bus;
-
-  for(bus=b->first_bus; bus; bus=bus->sibling)
-    if (bus->domain == domain && bus->number == n)
-      break;
-  return bus;
-}
-
-static struct bus *
-new_bus(struct bridge *b, unsigned int domain, unsigned int n)
-{
-  struct bus *bus = xmalloc(sizeof(struct bus));
-  bus->domain = domain;
-  bus->number = n;
-  bus->sibling = b->first_bus;
-  bus->first_dev = NULL;
-  bus->last_dev = &bus->first_dev;
-  b->first_bus = bus;
-  return bus;
-}
-
-static void
-insert_dev(struct device *d, struct bridge *b)
-{
-  struct pci_dev *p = d->dev;
-  struct bus *bus;
-
-  if (! (bus = find_bus(b, p->domain, p->bus)))
-    {
-      struct bridge *c;
-      for(c=b->child; c; c=c->next)
-	if (c->domain == p->domain && c->secondary <= p->bus && p->bus <= c->subordinate)
-          {
-            insert_dev(d, c);
-            return;
-          }
-      bus = new_bus(b, p->domain, p->bus);
-    }
-  /* Simple insertion at the end _does_ guarantee the correct order as the
-   * original device list was sorted by (domain, bus, devfn) lexicographically
-   * and all devices on the new list have the same bus number.
-   */
-  *bus->last_dev = d;
-  bus->last_dev = &d->next;
-  d->next = NULL;
-}
-
-static void
-grow_tree(void)
-{
-  struct device *d, *d2;
-  struct bridge **last_br, *b;
-
-  /* Build list of bridges */
-
-  last_br = &host_bridge.chain;
-  for(d=first_dev; d; d=d->next)
-    {
-      word class = d->dev->device_class;
-      byte ht = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f;
-      if (class == PCI_CLASS_BRIDGE_PCI &&
-	  (ht == PCI_HEADER_TYPE_BRIDGE || ht == PCI_HEADER_TYPE_CARDBUS))
-	{
-	  b = xmalloc(sizeof(struct bridge));
-	  b->domain = d->dev->domain;
-	  if (ht == PCI_HEADER_TYPE_BRIDGE)
-	    {
-	      b->primary = get_conf_byte(d, PCI_PRIMARY_BUS);
-	      b->secondary = get_conf_byte(d, PCI_SECONDARY_BUS);
-	      b->subordinate = get_conf_byte(d, PCI_SUBORDINATE_BUS);
-	    }
-	  else
-	    {
-	      b->primary = get_conf_byte(d, PCI_CB_PRIMARY_BUS);
-	      b->secondary = get_conf_byte(d, PCI_CB_CARD_BUS);
-	      b->subordinate = get_conf_byte(d, PCI_CB_SUBORDINATE_BUS);
-	    }
-	  *last_br = b;
-	  last_br = &b->chain;
-	  b->next = b->child = NULL;
-	  b->first_bus = NULL;
-	  b->br_dev = d;
-	}
-    }
-  *last_br = NULL;
-
-  /* Create a bridge tree */
-
-  for(b=&host_bridge; b; b=b->chain)
-    {
-      struct bridge *c, *best;
-      best = NULL;
-      for(c=&host_bridge; c; c=c->chain)
-	if (c != b && (c == &host_bridge || b->domain == c->domain) &&
-	    b->primary >= c->secondary && b->primary <= c->subordinate &&
-	    (!best || best->subordinate - best->primary > c->subordinate - c->primary))
-	  best = c;
-      if (best)
-	{
-	  b->next = best->child;
-	  best->child = b;
-	}
-    }
-
-  /* Insert secondary bus for each bridge */
-
-  for(b=&host_bridge; b; b=b->chain)
-    if (!find_bus(b, b->domain, b->secondary))
-      new_bus(b, b->domain, b->secondary);
-
-  /* Create bus structs and link devices */
-
-  for(d=first_dev; d;)
-    {
-      d2 = d->next;
-      insert_dev(d, &host_bridge);
-      d = d2;
-    }
-}
-
-static void
-print_it(char *line, char *p)
-{
-  *p++ = '\n';
-  *p = 0;
-  fputs(line, stdout);
-  for(p=line; *p; p++)
-    if (*p == '+' || *p == '|')
-      *p = '|';
-    else
-      *p = ' ';
-}
-
-static void show_tree_bridge(struct bridge *, char *, char *);
-
-static void
-show_tree_dev(struct device *d, char *line, char *p)
-{
-  struct pci_dev *q = d->dev;
-  struct bridge *b;
-  char namebuf[256];
-
-  p += sprintf(p, "%02x.%x", q->dev, q->func);
-  for(b=&host_bridge; b; b=b->chain)
-    if (b->br_dev == d)
-      {
-	if (b->secondary == b->subordinate)
-	  p += sprintf(p, "-[%04x:%02x]-", b->domain, b->secondary);
-	else
-	  p += sprintf(p, "-[%04x:%02x-%02x]-", b->domain, b->secondary, b->subordinate);
-        show_tree_bridge(b, line, p);
-        return;
-      }
-  if (verbose)
-    p += sprintf(p, "  %s",
-		 pci_lookup_name(pacc, namebuf, sizeof(namebuf),
-				 PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,
-				 q->vendor_id, q->device_id));
-  print_it(line, p);
-}
-
-static void
-show_tree_bus(struct bus *b, char *line, char *p)
-{
-  if (!b->first_dev)
-    print_it(line, p);
-  else if (!b->first_dev->next)
-    {
-      *p++ = '-';
-      *p++ = '-';
-      show_tree_dev(b->first_dev, line, p);
-    }
-  else
-    {
-      struct device *d = b->first_dev;
-      while (d->next)
-	{
-	  p[0] = '+';
-	  p[1] = '-';
-	  show_tree_dev(d, line, p+2);
-	  d = d->next;
-	}
-      p[0] = '\\';
-      p[1] = '-';
-      show_tree_dev(d, line, p+2);
-    }
-}
-
-static void
-show_tree_bridge(struct bridge *b, char *line, char *p)
-{
-  *p++ = '-';
-  if (!b->first_bus->sibling)
-    {
-      if (b == &host_bridge)
-        p += sprintf(p, "[%04x:%02x]-", b->domain, b->first_bus->number);
-      show_tree_bus(b->first_bus, line, p);
-    }
-  else
-    {
-      struct bus *u = b->first_bus;
-      char *k;
-
-      while (u->sibling)
-        {
-          k = p + sprintf(p, "+-[%04x:%02x]-", u->domain, u->number);
-          show_tree_bus(u, line, k);
-          u = u->sibling;
-        }
-      k = p + sprintf(p, "\\-[%04x:%02x]-", u->domain, u->number);
-      show_tree_bus(u, line, k);
-    }
-}
-
-static void
-show_forest(void)
-{
-  char line[256];
-
-  grow_tree();
-  show_tree_bridge(&host_bridge, line, line);
-}
-
-/*** Bus mapping mode ***/
-
-struct bus_bridge {
-  struct bus_bridge *next;
-  byte this, dev, func, first, last, bug;
-};
-
-struct bus_info {
-  byte exists;
-  byte guestbook;
-  struct bus_bridge *bridges, *via;
-};
-
-static struct bus_info *bus_info;
-
-static void
-map_bridge(struct bus_info *bi, struct device *d, int np, int ns, int nl)
-{
-  struct bus_bridge *b = xmalloc(sizeof(struct bus_bridge));
-  struct pci_dev *p = d->dev;
-
-  b->next = bi->bridges;
-  bi->bridges = b;
-  b->this = get_conf_byte(d, np);
-  b->dev = p->dev;
-  b->func = p->func;
-  b->first = get_conf_byte(d, ns);
-  b->last = get_conf_byte(d, nl);
-  printf("## %02x.%02x:%d is a bridge from %02x to %02x-%02x\n",
-	 p->bus, p->dev, p->func, b->this, b->first, b->last);
-  if (b->this != p->bus)
-    printf("!!! Bridge points to invalid primary bus.\n");
-  if (b->first > b->last)
-    {
-      printf("!!! Bridge points to invalid bus range.\n");
-      b->last = b->first;
-    }
-}
-
-static void
-do_map_bus(int bus)
-{
-  int dev, func;
-  int verbose = pacc->debugging;
-  struct bus_info *bi = bus_info + bus;
-  struct device *d;
-
-  if (verbose)
-    printf("Mapping bus %02x\n", bus);
-  for(dev = 0; dev < 32; dev++)
-    if (filter.slot < 0 || filter.slot == dev)
-      {
-	int func_limit = 1;
-	for(func = 0; func < func_limit; func++)
-	  if (filter.func < 0 || filter.func == func)
-	    {
-	      /* XXX: Bus mapping supports only domain 0 */
-	      struct pci_dev *p = pci_get_dev(pacc, 0, bus, dev, func);
-	      u16 vendor = pci_read_word(p, PCI_VENDOR_ID);
-	      if (vendor && vendor != 0xffff)
-		{
-		  if (!func && (pci_read_byte(p, PCI_HEADER_TYPE) & 0x80))
-		    func_limit = 8;
-		  if (verbose)
-		    printf("Discovered device %02x:%02x.%d\n", bus, dev, func);
-		  bi->exists = 1;
-		  if (d = scan_device(p))
-		    {
-		      show_device(d);
-		      switch (get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f)
-			{
-			case PCI_HEADER_TYPE_BRIDGE:
-			  map_bridge(bi, d, PCI_PRIMARY_BUS, PCI_SECONDARY_BUS, PCI_SUBORDINATE_BUS);
-			  break;
-			case PCI_HEADER_TYPE_CARDBUS:
-			  map_bridge(bi, d, PCI_CB_PRIMARY_BUS, PCI_CB_CARD_BUS, PCI_CB_SUBORDINATE_BUS);
-			  break;
-			}
-		      free(d);
-		    }
-		  else if (verbose)
-		    printf("But it was filtered out.\n");
-		}
-	      pci_free_dev(p);
-	    }
-      }
-}
-
-static void
-do_map_bridges(int bus, int min, int max)
-{
-  struct bus_info *bi = bus_info + bus;
-  struct bus_bridge *b;
-
-  bi->guestbook = 1;
-  for(b=bi->bridges; b; b=b->next)
-    {
-      if (bus_info[b->first].guestbook)
-	b->bug = 1;
-      else if (b->first < min || b->last > max)
-	b->bug = 2;
-      else
-	{
-	  bus_info[b->first].via = b;
-	  do_map_bridges(b->first, b->first, b->last);
-	}
-    }
-}
-
-static void
-map_bridges(void)
-{
-  int i;
-
-  printf("\nSummary of buses:\n\n");
-  for(i=0; i<256; i++)
-    if (bus_info[i].exists && !bus_info[i].guestbook)
-      do_map_bridges(i, 0, 255);
-  for(i=0; i<256; i++)
-    {
-      struct bus_info *bi = bus_info + i;
-      struct bus_bridge *b = bi->via;
-
-      if (bi->exists)
-	{
-	  printf("%02x: ", i);
-	  if (b)
-	    printf("Entered via %02x:%02x.%d\n", b->this, b->dev, b->func);
-	  else if (!i)
-	    printf("Primary host bus\n");
-	  else
-	    printf("Secondary host bus (?)\n");
-	}
-      for(b=bi->bridges; b; b=b->next)
-	{
-	  printf("\t%02x.%d Bridge to %02x-%02x", b->dev, b->func, b->first, b->last);
-	  switch (b->bug)
-	    {
-	    case 1:
-	      printf(" <overlap bug>");
-	      break;
-	    case 2:
-	      printf(" <crossing bug>");
-	      break;
-	    }
-	  putchar('\n');
-	}
-    }
-}
-
-static void
-map_the_bus(void)
-{
-  if (pacc->method == PCI_ACCESS_PROC_BUS_PCI ||
-      pacc->method == PCI_ACCESS_DUMP)
-    printf("WARNING: Bus mapping can be reliable only with direct hardware access enabled.\n\n");
-  bus_info = xmalloc(sizeof(struct bus_info) * 256);
-  memset(bus_info, 0, sizeof(struct bus_info) * 256);
-  if (filter.bus >= 0)
-    do_map_bus(filter.bus);
-  else
-    {
-      int bus;
-      for(bus=0; bus<256; bus++)
-	do_map_bus(bus);
-    }
-  map_bridges();
-}
-
 /* Main */
 
 int
@@ -3018,7 +937,6 @@
 	break;
       case 'b':
 	pacc->buscentric = 1;
-	opt_buscentric = 1;
 	break;
       case 's':
 	if (msg = pci_filter_parse_slot(&filter, optarg))
diff -ruN pciutils-3.0.3/lspci.h pciutils-3.1.0/lspci.h
--- pciutils-3.0.3/lspci.h	1970-01-01 01:00:00.000000000 +0100
+++ pciutils-3.1.0/lspci.h	2008-11-21 22:33:22.000000000 +0100
@@ -0,0 +1,80 @@
+/*
+ *	The PCI Utilities -- List All PCI Devices
+ *
+ *	Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
+ *
+ *	Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#define PCIUTILS_LSPCI
+#include "pciutils.h"
+
+/*
+ *  If we aren't being compiled by GCC, use xmalloc() instead of alloca().
+ *  This increases our memory footprint, but only slightly since we don't
+ *  use alloca() much.
+ */
+#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__DragonFly__)
+/* alloca() is defined in stdlib.h */
+#elif defined(__GNUC__) && !defined(PCI_OS_WINDOWS)
+#include <alloca.h>
+#else
+#undef alloca
+#define alloca xmalloc
+#endif
+
+/*** Options ***/
+
+extern int verbose;
+extern struct pci_filter filter;
+extern char *opt_pcimap;
+
+/*** PCI devices and access to their config space ***/
+
+struct device {
+  struct device *next;
+  struct pci_dev *dev;
+  unsigned int config_cached, config_bufsize;
+  byte *config;				/* Cached configuration space data */
+  byte *present;			/* Maps which configuration bytes are present */
+};
+
+extern struct device *first_dev;
+extern struct pci_access *pacc;
+
+struct device *scan_device(struct pci_dev *p);
+void show_device(struct device *d);
+
+int config_fetch(struct device *d, unsigned int pos, unsigned int len);
+u32 get_conf_long(struct device *d, unsigned int pos);
+word get_conf_word(struct device *d, unsigned int pos);
+byte get_conf_byte(struct device *d, unsigned int pos);
+
+void get_subid(struct device *d, word *subvp, word *subdp);
+
+#define FLAG(x,y) ((x & y) ? '+' : '-')
+
+/* ls-vpd.c */
+
+void cap_vpd(struct device *d);
+
+/* ls-caps.c */
+
+void show_caps(struct device *d);
+
+/* ls-ecaps.c */
+
+void show_ext_caps(struct device *d);
+
+/* ls-kernel.c */
+
+void show_kernel_machine(struct device *d UNUSED);
+void show_kernel(struct device *d UNUSED);
+
+/* ls-tree.c */
+
+void show_forest(void);
+
+/* ls-map.c */
+
+void map_the_bus(void);
diff -ruN pciutils-3.0.3/lspci.man pciutils-3.1.0/lspci.man
--- pciutils-3.0.3/lspci.man	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/lspci.man	2008-12-13 00:12:44.000000000 +0100
@@ -286,6 +286,10 @@
 Name of the subsystem (optional).
 
 .TP
+.B PhySlot
+The physical slot where the device resides (optional, Linux only).
+
+.TP
 .B Rev
 Revision number (optional).
 
diff -ruN pciutils-3.0.3/maint/release pciutils-3.1.0/maint/release
--- pciutils-3.0.3/maint/release	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/maint/release	2008-11-11 00:11:51.000000000 +0100
@@ -15,7 +15,7 @@
 print "API version is $apiver ... <confirm> "; <STDIN>;
 
 print "Updating public GIT tree\n";
-`cg-push public`; die if $?;
+`git push --tags public`; die if $?;
 
 my $r = new UCW::Release("pciutils");
 my $ver = $r->GetVersionFromFile("Makefile", "VERSION=(.*)");
diff -ruN pciutils-3.0.3/pci.ids pciutils-3.1.0/pci.ids
--- pciutils-3.0.3/pci.ids	2008-11-09 21:18:24.000000000 +0100
+++ pciutils-3.1.0/pci.ids	2009-01-13 03:15:01.000000000 +0100
@@ -1,8 +1,8 @@
 #
 #	List of PCI ID's
 #
-#	Version: 2008.11.09
-#	Date:    2008-11-09 21:16:52
+#	Version: 2009.01.13
+#	Date:    2009-01-13 03:15:01
 #
 #	Maintained by Martin Mares <mj@ucw.cz> and other volunteers from the
 #	PCI ID Project at http://pciids.sf.net/.
@@ -1047,6 +1047,7 @@
 		1028 0223  PowerEdge R905 Embedded ATI ES1000
 		1028 0225  PowerEdge T105 Embedded ATI ES1000
 		1028 023c  PowerEdge R200 Embedded ATI ES1000
+		103c 1304  Integrity iLO2 Advanced KVM VGA [AD307A]
 		15d9 8680  X7DVL-E-O motherboard
 		8086 3476  S5000PSLSATA Server Board
 	515f  ES1000
@@ -1113,6 +1114,7 @@
 	554b  R423 UK [Radeon X800SE (PCIE)]
 	554c  Radeon X800 XTP (R430) (PCIE)
 	554d  R430 [Radeon X800 XL] (PCIe)
+		1458 2124  GV-R80L256V-B (AGP)
 	554e  Radeon X800 SE (R430) (PCIE)
 	554f  R430 [Radeon X800 (PCIE)]
 	5550  R423 [FireGL V7100]
@@ -1123,6 +1125,7 @@
 	5569  R423 UI [Radeon X800PRO (PCIE)] (Secondary)
 	556b  Radeon R423 UK (PCIE) [X800 SE] (Secondary)
 	556d  R430 [Radeon X800 XL] (PCIe) (Secondary)
+		1458 2125  GV-R80L256V-B (AGP)
 	556f  R430 [Radeon X800] (PCIE) (Secondary)
 	5571  R423GL-SE [FireGL V5100 (PCIE)] (Secondary)
 	564a  M26 [Mobility FireGL V5000]
@@ -1382,6 +1385,7 @@
 	71c4  M56GL [Mobility FireGL V5200]
 		17aa 2007  ThinkPad T60p
 	71c5  M56P [Radeon Mobility X1600]
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a3  Compaq NW8440
 		1043 10b2  A6J-Q008
 		106b 0080  MacBook Pro
@@ -1474,8 +1478,10 @@
 	944c  RV770 LE [Radeon HD 4800 Series]
 	945a  M98 XT [Mobility Radeon HD 4870]
 	9480  M96 [Mobility Radeon HD 4650]
+	9489  M96 XT [Mobility FireGL V5725]
 	9490  RV730XT [Radeon HD 4670]
 	9498  RV730 PRO [Radeon HD 4650]
+	949f  RV730 [FirePro V5700]
 	94c1  RV610 [Radeon HD 2400 XT]
 		1028 0211  Optiplex 755
 		1028 0d02  Optiplex 755
@@ -1499,6 +1505,7 @@
 	9519  RV670 [FireStream 9170]
 	9540  RV710 [Radeon HD 4550]
 	954f  RV710 [Radeon HD 4350]
+	9552  M92 LP [Mobility Radeon HD 4300 Series]
 	9553  M92 [Mobility Radeon HD 4500 Series]
 	9559  Mobility Radeon HD 3600 Series
 	9581  M76 [Radeon Mobility HD 2600 Series]
@@ -1533,6 +1540,7 @@
 	9612  RS780M/RS780MN [Radeon HD 3200 Graphics]
 	9613  RS780MC [Radeon HD 3100 Graphics]
 	9614  Radeon HD 3300 Graphics
+	9616  760G [Radeon 3000]
 	aa00  R600 Audio Device [Radeon HD 2900 Series]
 	aa08  RV630/M76 audio device [Radeon HD 2600 Series]
 	aa10  RV610 audio device [Radeon HD 2400 PRO]
@@ -2407,7 +2415,8 @@
 		102b 1030  Parhelia 256 MB Dual DVI
 		102b 14e1  Parhelia PCI 256MB
 		102b 2021  QID Pro
-	0532  MGA G200eW WPCM450 [Hermon] - Winbond/Nuvoton
+	0532  MGA G200eW WPCM450
+		1028 0287  PowerEdge M610 MGA G200eW WPCM450
 	0540  M91XX
 		102b 2080  M9140 LP PCIe x16
 		102b 2100  M9120 PCIe x16
@@ -2527,6 +2536,8 @@
 	002d  PCI to C-bus Bridge
 	0035  USB
 		1033 0035  Hama USB 2.0 CardBus
+		103c 1293  USB add-in card
+		103c 1294  USB 2.0 add-in card
 		1179 0001  USB
 		12ee 7000  Root Hub
 		14c2 0105  PTI-205N USB 2.0 Host Controller
@@ -2836,6 +2847,8 @@
 		103c 3245  Smart Array P410i
 		103c 3247  Smart Array P411
 		103c 3249  Smart Array P812
+		103c 324a  HP Smart Array 712m (Mezzanine RAID controller)
+		103c 324b  Smart Array P711m (Mezzanine RAID controller)
 # Will present virtual install media as mass storage, keyboard/mouse from console session, etc.
 	3300  Proliant iLO2 virtual USB controller
 	3301  iLO3 Serial Port
@@ -3097,7 +3110,7 @@
 	8036  PCI6515 Cardbus Controller
 	8038  PCI6515 SmartCard Controller
 	8039  PCIxx12 Cardbus Controller
-		103c 309f  nx9420
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a1  NC2400
 		103c 30a3  Compaq nw8440
 	803a  PCIxx12 OHCI Compliant IEEE 1394 Host Controller
@@ -3111,7 +3124,7 @@
 		103c 309f  nx9420
 		103c 30a3  Compaq nw8440
 	803d  PCIxx12 GemCore based SmartCard controller
-		103c 309f  nx9420
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a1  NC2400
 		103c 30a3  nc8430
 		103c 30aa  nc6310
@@ -3281,6 +3294,7 @@
 	3012  ColdFusion 3e Chipset Memory Controller Hub
 	3017  Unassigned Hitachi Shared FC Device 3017
 	301d  PCIe-to-PCIe Bridge with Virtualization IO Assist Feature
+	3020  FIVE-EX based Fibre Channel to PCIe HBA
 	3505  SH7751 PCI Controller (PCIC)
 	350e  SH7751R PCI Controller (PCIC)
 1055  Efar Microsystems
@@ -3451,7 +3465,10 @@
 		105a 8603  SuperTrak EX8658
 		105a 8604  SuperTrak EX8650
 		105a 8610  SuperTrak EX8650M
+		105a a600  SuperTrak EX12650
 		105a b600  SuperTrak EX16650
+		105a b601  SuperTrak EX16654
+		105a b602  SuperTrak EX16658
 	c350  80333 [SuperTrak EX12350]
 	e350  80333 [SuperTrak EX24350]
 105b  Foxconn International, Inc.
@@ -5072,6 +5089,7 @@
 		105b 0c43  Winfast NF3250K8AA
 		1462 7030  K8N Neo-FSR v2.0
 		147b 1c0b  NF8 Mainboard
+		f849 00e5  Motherboard (one of many)
 	00e6  CK8S Ethernet Controller
 	00e7  CK8S USB Controller
 		1043 813f  K8N-E
@@ -5582,6 +5600,7 @@
 	0366  MCP55 LPC Bridge
 	0367  MCP55 LPC Bridge
 	0368  MCP55 SMBus
+		1028 020c  PowerEdge M605 MCP55 SMBus
 		1028 0221  PowerEdge R805 MCP55 SMBus
 		147b 12c4  KN9-Ultra Mainboard
 	0369  MCP55 Memory Controller
@@ -5589,9 +5608,11 @@
 	036a  MCP55 Memory Controller
 	036b  MCP55 SMU
 	036c  MCP55 USB Controller
+		1028 020c  PowerEdge M605 MCP55 USB Controller
 		1028 0221  PowerEdge R805 MCP55 USB Controller
 		147b 12c4  KN9-Ultra Mainboard
 	036d  MCP55 USB Controller
+		1028 020c  PowerEdge M605 MCP55 USB Controller
 		1028 0221  PowerEdge R805 MCP55 USB Controller
 		147b 12c4  KN9-Ultra Mainboard
 	036e  MCP55 IDE
@@ -5810,6 +5831,7 @@
 	0600  GeForce 8800 GTS 512
 	0602  GeForce 8800 GT 512
 	0604  GeForce 9800 GX2
+	0605  GeForce 9800 GT
 	0606  GeForce 8800 GS
 	0609  GeForce 8800M GTS
 	060c  GeForce 8800M GTX
@@ -5819,7 +5841,9 @@
 		107d 2ab0  Winfast PX8800 GT PCI-E
 		19da 1040  ZT-88TES2P-FSP
 	0612  GeForce 9800 GTX
+	0613  GeForce 9800 GTX+
 	0614  GeForce 9800 GT
+	0617  GeForce 9800M GTX
 	061a  Quadro FX 3700
 	061c  Quadro FX 3600M
 	0622  G94 [GeForce 9600 GT]
@@ -5827,6 +5851,7 @@
 	0623  GeForce 9600 GS
 	063a  Quadro FX 2700M
 	0640  GeForce 9500 GT
+	0641  D9M-20 [GeForce 9400 GT]
 	0647  GeForce 9600M GT
 	0648  GeForce 9600M GS
 	0649  GeForce 9600M GT
@@ -5916,6 +5941,7 @@
 	07e2  GeForce 7050 / nForce 630i
 	07e3  GeForce 7050/nForce 610i
 	07e5  GeForce 7100 / nForce 620i
+	07f0  MCP73 IDE
 	07f4  GeForce 7100/nForce 630i
 	07f8  MCP73 SATA RAID Controller
 	07fc  MCP73 High Definition Audio
@@ -5923,6 +5949,7 @@
 	07fe  GeForce 7100/nForce 630i
 		1afa 7150  JW-IN7150-HD
 	0844  GeForce 9100M G
+	0845  GeForce 8200M G
 	0848  GeForce 8300
 	0849  GeForce 8200
 		1849 0849  K10N78FullHD-hSLI R3.0 GeForce 8200
@@ -5998,6 +6025,7 @@
 		1849 0ad0  K10N78FullHD-hSLI R3.0 IDE
 	0ad4  MCP78S [GeForce 8200] AHCI Controller
 		1849 0ad4  K10N78FullHD-hSLI R3.0 AHCI Controller
+	10de  GeForce 9800M GTX
 	21c3  nVidia Corporation G73 [GeForce 7600 GS] (rev a2)
 	c615  G70 [GeForce 7600 GT]
 10df  Emulex Corporation
@@ -6199,6 +6227,7 @@
 		1458 e000  GA-EP45-DS5 Motherboard
 		1462 238c  Onboard RTL8111b on MSI P965 Platinum Mainboard
 		1462 368c  K9AG Neo2
+		1849 8168  A770CrossFire motherboard
 	8169  RTL-8169 Gigabit Ethernet
 		1025 0079  Aspire 5024WLMi
 		1259 c107  CG-LAPCIGT
@@ -6244,6 +6273,7 @@
 10f0  Peritek Corporation
 10f1  Tyan Computer
 	2865  Tyan Thunder K8E S2865
+	5300  Tyan S5380 Mainboard
 10f2  Achme Computer, Inc.
 10f3  Alaris, Inc.
 10f4  S-MOS Systems, Inc.
@@ -6295,6 +6325,7 @@
 		1102 8061  SBLive! Player 5.1
 		1102 8064  SBLive! 5.1 Model SB0100
 		1102 8065  SBLive! 5.1 Digital Model SB0220
+		1102 8066  Live! 5.1 Digital [SB0228]
 		1102 8067  SBLive! 5.1 eMicro 28028
 	0004  SB Audigy
 		1102 0051  SB0090 Audigy Player
@@ -6310,7 +6341,7 @@
 		1102 002c  X-Fi XtremeGamer FATAL1TY PRO
 		1102 1003  X-Fi XtremeMusic
 	0006  [SB Live! Value] EMU10k1X
-	0007  SB Audigy LS
+	0007  CA0106 Soundblaster
 		1102 0007  SBLive! 24bit
 		1102 1001  SB0310 Audigy LS
 		1102 1002  SB0312 Audigy LS
@@ -6873,6 +6904,7 @@
 	e238  K8T890 PCI to PCI Bridge Controller
 	e340  PT900 PCI to PCI Bridge Controller
 	e353  VX800/VX820 PCI Express Root Port
+	e721  VT1708B 8-channel High Definition Audio CODEC
 	f208  PT890 PCI to PCI Bridge Controller
 	f238  K8T890 PCI to PCI Bridge Controller
 	f340  PT900 PCI to PCI Bridge Controller
@@ -6953,6 +6985,9 @@
 	0026  DT3005
 	0027  DT3001-PGL
 	0028  DT3003-PGL
+	0051  DT322
+	0060  DT340
+	0069  DT332
 1117  Datacube, Inc
 	9500  Max-1C SVGA card
 	9501  Max-1C image processing
@@ -7090,6 +7125,7 @@
 	8061  PES12T3G2 PCI Express Gen2 Switch
 	8068  PES6T6G2 PCI Express Gen2 Switch
 	806a  PES24T3G2 PCI Express Gen2 Switch
+		14c1 000c  10G-PCIE2-8B2
 	806c  PES16T4A/4T4G2 PCI Express Gen2 Switch
 	806e  PES24T6G2 PCI Express Gen2 Switch
 	806f  HIO524G2 PCI Express Gen2 Switch
@@ -7412,6 +7448,9 @@
 	f013  NinjaSCSI-32 Logitec
 	f015  NinjaSCSI-32 Melco
 	f020  NinjaSCSI-32 Sony PCGA-DVD51
+	f021  NinjaPATA-32 Delkin Cardbus UDMA
+	f024  NinjaPATA-32 Delkin Cardbus UDMA
+	f103  NinjaPATA-32 Delkin Cardbus UDMA
 1146  Force Computers
 1147  Interface Corp
 # Nee Schneider & Koch
@@ -9972,9 +10011,9 @@
 	1001  7xxx/8xxx-series PATA/SATA-RAID
 		13c1 1001  7xxx/8xxx-series PATA/SATA-RAID
 	1002  9xxx-series SATA-RAID
-	1003  9550SX SATA-RAID
-	1004  9650SE SATA-II RAID
-	1005  9690SA SAS-RAID
+	1003  9550SX SATA-II RAID PCI-X
+	1004  9650SE SATA-II RAID PCIe
+	1005  9690SA SAS/SATA-II RAID PCIe
 13c2  Technotrend Systemtechnik GmbH
 	000e  Technotrend/Hauppauge DVB card rev2.3
 	1019  TTechnoTrend-budget DVB S2-3200
@@ -10341,11 +10380,11 @@
 	000b  T210 Protocol Engine
 	000c  T204 Protocol Engine
 	0022  10GbE Ethernet Adapter
-	0030  T310 10GbE Single Port Protocol Engine Ethernet Adapter
+	0030  T310 10GbE Single Port Adapter
 		103c 705e  PCIe 10GBase-SR [AD386A]
-	0031  T320 10GbE Dual Port Protocol Engine Ethernet Adapter
-	0032  T302 1GbE Dual Port Protocol Engine Ethernet adapter
-	0033  T304 1GbE Quad Port Protocol Engine Ethernet adapter
+	0031  T320 10GbE Dual Port Adapter
+	0032  T302 1GbE Dual Port Adapter
+	0033  T304 1GbE Quad Port Adapter
 1426  Storage Technology Corp.
 1427  Better On-Line Solutions
 1428  Edec Co Ltd
@@ -10494,6 +10533,7 @@
 1480  SCII Telecom
 1481  BIOPAC Systems Inc
 1482  ISYTEC - Integrierte Systemtechnik GmBH
+	0001  PCI-16 Host Interface for ITC-16
 1483  LABWAY Corporation
 1484  Logic Corporation
 1485  ERMA - Electronic GmBH
@@ -10593,6 +10633,8 @@
 		14c1 0008  10G-PCIE-8A
 		14c1 0009  10G-PCIE-8A (MSI-X firmware)
 		14c1 000a  10G-PCIE-8B
+		14c1 000b  10G-PCIE-8B2
+		14c1 000c  10G-PCIE2-8B2
 	8043  Myrinet 2000 Scalable Cluster Interconnect
 		103c 1240  Myrinet M2L-PCI64/2-3.0 LANai 7.4 (HP OEM)
 14c2  DTK Computer
@@ -10688,9 +10730,11 @@
 		103c 7059  NC382T PCI Express Dual Port Multifunction Gigabit Server Adapter
 		10a9 8027  Quad port Gigabit Ethernet Controller
 	163a  NetXtreme II BCM5709S Gigabit Ethernet
+		1028 027b  PowerEdge M610 Broadcom NetXtreme II BCM5709S
 		103c 171d  NC382m Dual Port 1GbE Multifunction BL-c Adapter
 		103c 7056  NC382i Integrated Quad Port PCI Express Gigabit Server Adapter
 	163b  NetXtreme II BCM5716 Gigabit Ethernet
+	163c  NetXtreme II BCM5716S Gigabit Ethernet
 	1644  NetXtreme BCM5700 Gigabit Ethernet
 		1014 0277  Broadcom Vigil B5700 1000Base-T
 		1028 00d1  Broadcom BCM5700
@@ -10768,6 +10812,7 @@
 	164a  NetXtreme II BCM5706 Gigabit Ethernet
 		103c 3070  NC380T PCI Express Dual Port Multifunction Gigabit Server Adapter
 		103c 3101  NC370T MultifuNCtion Gigabit Server Adapter
+		103c 3106  NC370i Multifunction Gigabit Server Adapter
 	164c  NetXtreme II BCM5708 Gigabit Ethernet
 		1028 01f0  PowerEdge R900 Broadcom NetXtreme II BCM5708
 		1028 0205  PowerEdge 2970 Broadcom NetXtreme II BCM5708
@@ -10888,6 +10933,7 @@
 		14e4 000b  NetXtreme BCM5703 1000Base-T
 		14e4 800a  NetXtreme BCM5703 1000Base-T
 	16a8  NetXtreme BCM5704S Gigabit Ethernet
+		103c 132b  PCI-X 1000Mbps Dual-port Built-in
 		10a9 8014  Dual Port Gigabit Ethernet (PCI-X,Fiber)
 		10a9 801c  Quad Port Gigabit Ethernet (PCI-E,Fiber)
 		10b7 2001  3C998-SX Dual Port 1000-SX PCI-X
@@ -10896,6 +10942,7 @@
 	16ac  NetXtreme II BCM5708S Gigabit Ethernet
 		1014 0304  NetXtreme II BCM5708S Gigabit Ethernet
 		1028 01bb  PowerEdge 1955 Broadcom NetXtreme II BCM5708S
+		1028 020c  PowerEdge M605 Broadcom NetXtreme II BCM5708S
 		103c 1706  NC373m Multifunction Gigabit Server Adapter
 		103c 7038  NC373i PCI Express Multifunction Gigabit Server Adapter
 		103c 703b  NC373i Integrated Multifunction Gigabit Server Adapter
@@ -10914,6 +10961,7 @@
 	16dd  NetLink BCM5781 Gigabit Ethernet PCI Express
 	16f7  NetXtreme BCM5753 Gigabit Ethernet PCI Express
 	16fd  NetXtreme BCM5753M Gigabit Ethernet PCI Express
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a3  Compaq nw8440
 	16fe  NetXtreme BCM5753F Fast Ethernet PCI Express
 	170c  BCM4401-B0 100Base-TX
@@ -10934,6 +10982,7 @@
 	1713  NetLink BCM5906M Fast Ethernet PCI Express
 		1028 01f3  Inspiron 1420
 		1028 0209  XPS M1330
+		103c 30c0  Compaq 6710b
 	3352  BCM3352
 	3360  BCM3360
 	4210  BCM4210 iLine10 HomePNA 2.0
@@ -11632,6 +11681,7 @@
 1587  Konica Corp
 1588  Solidum Systems Corp
 1589  Atlantek Microsystems Pty Ltd
+	0008  Leutron Vision PicPortExpress CL
 	0009  Leutron Vision PicPortExpress CL Stereo
 158a  Digalog Systems Inc
 158b  Allied Data Technologies
@@ -11687,6 +11737,8 @@
 	0740  Virtual Machine Communication Interface
 	0770  Abstract USB2 EHCI Controller
 	0790  PCI bridge
+	07b0  VMXNET3 Ethernet Adapter
+	07c0  PVSCSI SCSI Controller
 	0801  Virtual Machine Interface
 		15ad 0800  Hypervisor ROM Interface
 15ae  Amersham Pharmacia Biotech
@@ -11704,13 +11756,12 @@
 	6274  MT25204 [InfiniHost III Lx HCA]
 	6278  MT25208 InfiniHost III Ex (Tavor compatibility mode)
 	6279  MT25208 [InfiniHost III Ex HCA Flash Recovery]
-	6282  MT25208 InfiniHost III Ex
-	6340  MT25408 [ConnectX IB SDR]
-	634a  MT25418 [ConnectX IB DDR, PCIe 2.0 2.5GT/s]
-	6354  MT25428 [ConnectX IB QDR]
+	6282  MT25208 [InfiniHost III Ex]
+	6340  MT25408 [ConnectX VPI - IB SDR / 10GigE]
+	634a  MT25418 [ConnectX VPI PCIe 2.0 2.5GT/s - IB DDR / 10GigE]
 	6368  MT25448 [ConnectX EN 10GigE, PCIe 2.0 2.5GT/s]
-	6732  MT26418 [ConnectX IB DDR, PCIe 2.0 5GT/s]
-	673c  MT26428 [ConnectX IB QDR, PCIe 2.0 5GT/s]
+	6732  MT26418 [ConnectX VPI PCIe 2.0 5GT/s - IB DDR / 10GigE]
+	673c  MT26428 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE]
 	6750  MT26448 [ConnectX EN 10GigE, PCIe 2.0 5GT/s]
 15b4  CCI/TRIAD
 15b5  Cimetrics Inc
@@ -11970,6 +12021,7 @@
 	0027  AR9160 802.11abgn Wireless PCI Adapter
 	0029  AR922X Wireless Network Adapter
 	002a  AR928X Wireless Network Adapter (PCI-Express)
+	002b  AR9285 Wireless Network Adapter (PCI-Express)
 	0033  11a/b/g/n Wireless LAN Mini-PCI Express Adapter
 	0207  AR5210
 	1014  AR5212 802.11abg NIC
@@ -12048,6 +12100,7 @@
 	5602  PMC-VLX110 Reconfigurable Virtex-5 FPGA with plug-in I/O
 	5603  PMC-VSX95 Reconfigurable Virtex-5 FPGA with plug-in I/O
 	5604  PMC-VLX155 Reconfigurable Virtex-5 FPGA with plug-in I/O
+	5605  PMC-VFX70 Reconfigurable Virtex-5 FPGA with plug-in I/O
 16da  Advantech Co., Ltd.
 	0011  INES GPIB-PCI
 16df  PIKA Technologies Inc.
@@ -12158,6 +12211,7 @@
 179c  Data Patterns
 	0557  DP-PCI-557 [PCI 1553B]
 	0566  DP-PCI-566 [Intelligent PCI 1553B]
+	1152  DP-cPCI-1152 (8–channel Isolated ADC Module)
 	5031  DP-CPCI-5031-Synchro Module
 	5121  DP-CPCI-5121-IP Carrier
 	5211  DP-CPCI-5211-IP Carrier
@@ -12277,6 +12331,7 @@
 	0601  RT2800 802.11n PCI
 	0681  RT2860 Wireless 802.11n PCIe
 	0701  RT2760 Wireless 802.11n 1T/2R Cardbus
+	0781  RT2860
 	e932  RT2560F 802.11 b/g PCI
 1815  Devolo AG
 1820  InfiniCon Systems Inc.
@@ -12451,6 +12506,7 @@
 		1924 0500  SFE4005-A0
 		1924 5102  SFN4111T-A2
 		1924 5103  SFN4111T-R3
+		1924 5104  SFN4111T-R4
 	6703  SFC4000 rev A iSCSI/Onload [Solarstorm]
 		10b8 0102  SMC10GPCIe-10BT (A2) [TigerCard]
 		10b8 0103  SMC10GPCIe-10BT (A3) [TigerCard]
@@ -12534,9 +12590,12 @@
 1966  Orad Hi-Tec Systems
 	1975  DVG64 family
 1969  Attansic Technology Corp.
-	1026  L1 Gigabit Ethernet Adapter
+	1026  L1e Gigabit Ethernet Adapter
+		1043 8304  P5KPL-CM Motherboard
 	1048  L1 Gigabit Ethernet Adapter
 		1043 8226  P5KPL-VM Motherboard
+	1066  L2c Gigabit Ethernet Adapter
+	1067  L1c Gigabit Ethernet Adapter
 	2048  L2 100 Mbit Ethernet Adapter
 196a  Sensory Networks Inc.
 	0101  NodalCore C-1000 Content Classification Accelerator
@@ -12565,6 +12624,10 @@
 	2382  SD/MMC Host Controller
 	2383  MS Host Controller
 	2384  xD Host Controller
+	2386  Standard SD Host Controller
+	2387  SD/MMC Host Controller
+	2388  MS Host Controller
+	2389  xD Host Controller
 1982  Distant Early Warning Communications Inc
 	1600  OX16C954 HOST-A
 	16ff  OX16C954 HOST-B
@@ -12590,6 +12653,8 @@
 19da  ZOTAC International (MCO) Ltd.
 19de  Pico Computing
 19e2  Vector Informatik GmbH
+19e3  DDRdrive LLC
+	dd52  DDRdrive X1
 19e7  NET (Network Equipment Technologies)
 	1001  STIX DSP Card
 	1002  STIX - 1 Port T1/E1 Card
@@ -12598,7 +12663,7 @@
 	1005  STIX - 4 Port FXS Card
 19ee  Netronome Systems, Inc.
 1a03  ASPEED Technology, Inc.
-	2000  AST2000
+	2000  ASPEED Graphics Family
 1a07  Kvaser AB
 	0006  CAN interface PC104+ HS/HS
 	0007  CAN interface PCIcanx II HS or HS/HS
@@ -12608,6 +12673,8 @@
 	0000  SC15064
 1a0e  DekTec Digital Video B.V.
 	0069  DTA-105
+1a17  Force10 Networks, Inc.
+	8002  PB-10GE-2P 10GbE Security Card
 1a1d  GFaI e.V.
 	1a17  Meta Networks MTP-1G IDPS NIC
 1a1e  3Leaf Systems, Inc.
@@ -12668,6 +12735,7 @@
 	1fa8  BYNET BIC2SE/X
 		1b3e 00a3  BYNET BIC2SX
 		1b3e 00c3  BYNET BIC2SE
+1b40  Schooner Information Technology, Inc.
 1b55  NetUP Inc.
 	2a2c  Dual DVB-S2-CI card
 1c1c  Symphony
@@ -12836,6 +12904,10 @@
 4143  Digital Equipment Corp
 4144  Alpha Data
 	0044  ADM-XRCIIPro
+4150  ONA Electroerosion
+	0001  PCI32TLITE FILSTRUP1 PCI to VME Bridge Controller
+	0006  PCI32TLITE UART 16550 Opencores
+	0007  PCI32TLITE CAN Controller Opencores
 415a  Auzentech, Inc.
 416c  Aladdin Knowledge Systems
 	0100  AladdinCARD
@@ -12925,6 +12997,8 @@
 	0b02  BU-65569I2 MIL-STD-1553 Data Bus
 	0b03  BU-65569I3 MIL-STD-1553 Data Bus
 	0b04  BU-65569I4 MIL-STD-1553 Data Bus
+5045  University of Toronto
+	4243  BLASTbus PCI Interface Card v1
 5046  GemTek Technology Corporation
 	1001  PCI Radio
 5053  Voyetra Technologies
@@ -13136,6 +13210,14 @@
 	0041  Auburndale/Havendale PCI Express x16 Root Port
 	0042  Auburndale/Havendale Integrated Graphics Controller
 	0050  Auburndale/Havendale Thermal Management Controller
+	0082  WiFi Link 6000 Series
+	0083  WiFi Link 100 Series
+	0084  WiFi Link 100 Series
+	0085  WiFi Link 6000 Series
+	0086  WiMAX/WiFi Link 6050 Series
+	0087  WiMAX/WiFi Link 6050 Series
+	0088  WiMAX/WiFi Link 6050 Series
+	0089  WiMAX/WiFi Link 6050 Series
 	0122  82437FX
 	0309  80303 I/O Processor PCI-to-PCI Bridge
 	030d  80312 I/O Companion Chip PCI-to-PCI Bridge
@@ -13561,6 +13643,9 @@
 		8086 a10c  10 Gigabit AT Server Adapter
 		8086 a11c  10 Gigabit AT Server Adapter
 		8086 a12c  10 Gigabit AT Server Adapter
+	10c9  82576 Gigabit Network Connection
+		8086 a01c  Gigabit ET Dual Port Server Adapter
+		8086 a03c  Gigabit ET Dual Port Server Adapter
 	10cb  82567V Gigabit Network Connection
 	10cc  82567LM-2 Gigabit Network Connection
 	10cd  82567LF-2 Gigabit Network Connection
@@ -13571,21 +13656,33 @@
 	10d6  82575GB Gigabit Network Connection
 		8086 10d6  Gigabit VT Quad Port Server Adapter
 		8086 145a  Gigabit VT Quad Port Server Adapter
+		8086 147a  Gigabit VT Quad Port Server Adapter
 	10d9  82571EB Dual Port Gigabit Mezzanine Adapter
 		103c 1716  NC360m Dual Port 1GbE BL-c Adapter
 	10da  82571EB Quad Port Gigabit Mezzanine Adapter
 		103c 1717  NC364m Quad Port 1GbE BL-c Adapter
+	10db  82598EB 10-Gigabit Dual Port Network Connection
 	10dd  82598EB 10 Gigabit AT CX4 Network Connection
 	10de  82567LM-3 Gigabit Network Connection
 	10df  82567LF-3 Gigabit Network Connection
+	10e1  82598EB 10-Gigabit AT Dual Port Network Connection
+		8086 a15f  10-Gigabit SR Dual Port Express Module
 	10e2  82575GB Gigabit Network Connection
 		8086 10e2  Gigabit VT Quad Port Server Adapter
 	10e5  82567LM-4 Gigabit Network Connection
-	10ec  10 Gigabit AT CX4 Network Connection
+	10e6  82576 Gigabit Network Connection
+		8086 a01f  Gigabit EF Dual Port Server Adapter
+		8086 a02f  Gigabit EF Dual Port Server Adapter
+	10e7  82576 Gigabit Network Connection
+	10ec  82598EB 10-Gigabit AT CX4 Network Connection
 		8086 a01f  10 Gigabit CX4 Dual Port Server Adapter
 		8086 a11f  10 Gigabit CX4 Dual Port Server Adapter
-	10f4  10 Gigabit AT Network Connection
+	10f1  82598EB 10-Gigabit AT Dual Port Network Connection
+		8086 a20f  10-Gigabit AF DA Dual Port Server Adapter
+		8086 a21f  10-Gigabit AF DA Dual Port Server Adapter
+	10f4  82598EB 10-Gigabit AT Network Connection
 		8086 106f  10 Gigabit XF LR Server Adapter
+		8086 a06f  10-Gigabit XF LR Server Adapter
 	10f5  82567LM Gigabit Network Connection
 	1107  PRO/1000 MF Server Adapter (LX)
 	1130  82815 815 Chipset Host Bridge and Memory Controller Hub
@@ -13928,7 +14025,7 @@
 # (rev d3) (prog-if (rev d3) (prog-if 01 [Subtractive decode])
 		103c 0934  HP Compaq nw8240 Mobile Workstation
 		103c 099c  NX6110/NC6120
-		103c 309f  HP Compaq nx9420
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a3  Compaq nw8440
 		103c 30c1  Compaq 6910p
 		144d c00c  P30 notebook
@@ -14870,16 +14967,19 @@
 	27a0  Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub
 		1025 006c  9814 WKMI
 		1028 01d7  XPS M1210
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a1  NC2400
 		103c 30a3  Compaq nw8440
 		1043 1237  A6J-Q008
 		17aa 2015  ThinkPad T60
 		17aa 2017  ThinkPad T60/R60 series
 	27a1  Mobile 945GM/PM/GMS, 943/940GML and 945GT Express PCI Express Root Port
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a3  Compaq nw8440
 	27a2  Mobile 945GM/GMS, 943/940GML Express Integrated Graphics Controller
 		103c 30a1  NC2400
 		17aa 201a  ThinkPad T60/R60 series
+		9902 1584  CCE MPL-D10H120F
 	27a6  Mobile 945GM/GMS/GME, 943/940GML Express Integrated Graphics Controller
 		103c 30a1  NC2400
 		17aa 201a  ThinkPad T60/R60 series
@@ -14895,7 +14995,7 @@
 		8086 544e  DeskTop Board D945GTP
 	27b9  82801GBM (ICH7-M) LPC Interface Bridge
 		1028 01d7  XPS M1210
-		103c 309f  HP Compaq nx9420
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a1  NC2400
 		103c 30a3  Compaq nw8440
 		10f7 8338  Panasonic CF-Y5 laptop
@@ -14921,6 +15021,7 @@
 		1028 01d7  XPS M1210
 		17aa 200e  Thinkpad T60 model 2007
 	27c5  82801GBM/GHM (ICH7 Family) SATA AHCI Controller
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a3  Compaq nw8440
 		17aa 200d  ThinkPad T60/R60 series
 	27c6  82801GHM (ICH7-M DH) SATA RAID Controller
@@ -14930,6 +15031,7 @@
 		1028 01d7  XPS M1210
 		1028 01df  PowerEdge SC440
 		1028 01e6  PowerEdge 860
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a1  NC2400
 		103c 30a3  Compaq nw8440
 		1043 1237  A6J-Q008
@@ -14943,6 +15045,7 @@
 		1028 01d7  XPS M1210
 		1028 01df  PowerEdge SC440
 		1028 01e6  PowerEdge 860
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a1  NC2400
 		103c 30a3  Compaq nw8440
 		1043 1237  A6J-Q008
@@ -14956,6 +15059,7 @@
 		1028 01d7  XPS M1210
 		1028 01df  PowerEdge SC440
 		1028 01e6  PowerEdge 860
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a1  NC2400
 		103c 30a3  Compaq nw8440
 		1043 1237  A6J-Q008
@@ -14968,6 +15072,7 @@
 		1028 01ad  OptiPlex GX620
 		1028 01d7  XPS M1210
 		1028 01df  PowerEdge SC440
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a1  NC2400
 		103c 30a3  Compaq nw8440
 		1043 1237  A6J-Q008
@@ -14981,6 +15086,7 @@
 		1028 01d7  XPS M1210
 		1028 01df  PowerEdge SC440
 		1028 01e6  PowerEdge 860
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a1  NC2400
 		103c 30a3  Compaq nw8440
 		1043 1237  A6J-Q008
@@ -14988,8 +15094,10 @@
 		17aa 200b  ThinkPad T60/R60 series
 		8086 544e  DeskTop Board D945GTP
 	27d0  82801G (ICH7 Family) PCI Express Port 1
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a3  Compaq nw8440
 	27d2  82801G (ICH7 Family) PCI Express Port 2
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a3  Compaq nw8440
 	27d4  82801G (ICH7 Family) PCI Express Port 3
 	27d6  82801G (ICH7 Family) PCI Express Port 4
@@ -14997,11 +15105,13 @@
 	27d8  82801G (ICH7 Family) High Definition Audio Controller
 		1025 006c  9814 WKMI
 		1028 01d7  XPS M1210
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a1  NC2400
 		103c 30a3  Compaq nw8440
 		1043 1123  A6J-Q008
 		1043 13c4  Asus G2P
 		1043 8290  P5KPL-VM Motherboard
+		1043 82ea  P5KPL-CM Motherboard
 		107b 5048  E4500
 		10f7 8338  Panasonic CF-Y5 laptop
 		1179 ff10  Toshiba Satellite A100-796 audio (Realtek ALC861)
@@ -15034,6 +15144,7 @@
 	27df  82801G (ICH7 Family) IDE Controller
 		1028 01df  PowerEdge SC440
 		1028 01e6  PowerEdge 860
+		103c 309f  Compaq nx9420 Notebook
 		103c 30a1  NC2400
 		103c 30a3  Compaq nw8440
 		1043 1237  A6J-Q008
@@ -15261,11 +15372,13 @@
 		1028 023c  PowerEdge R200 onboard UHCI
 	2937  82801I (ICH9 Family) USB UHCI Controller #4
 		1028 0211  Optiplex 755
+		1028 0287  PowerEdge M610 onboard UHCI
 		1028 2011  Optiplex 755
 		8086 2937  Optiplex 755
 		8086 2942  828011 (ICH9 Family ) USB UHCI Controller
 	2938  82801I (ICH9 Family) USB UHCI Controller #5
 		1028 0211  Optiplex 755
+		1028 0287  PowerEdge M610 onboard UHCI
 		8086 2938  Optiplex 755
 	2939  82801I (ICH9 Family) USB UHCI Controller #6
 		1028 0210  PowerEdge T300 onboard UHCI
@@ -15276,6 +15389,7 @@
 		1028 023c  PowerEdge R200 onboard EHCI
 	293c  82801I (ICH9 Family) USB2 EHCI Controller #2
 		1028 0211  Optiplex 755
+		1028 0287  PowerEdge M610 onboard EHCI
 		8086 293c  Optiplex 755
 	293e  82801I (ICH9 Family) HD Audio Controller
 		1028 0211  Optiplex 755
@@ -15427,28 +15541,29 @@
 	2a51  Cantiga MEI Controller
 	2a52  Cantiga PT IDER Controller
 	2a53  Cantiga AMT SOL Redirection
-	2c01  QuickPath Architecture System Address Decoder
-	2c10  QPI Link 0
-	2c11  QPI Physical 0
-	2c14  QPI Link 1
-	2c15  QPI Physical 1
-	2c18  QuickPath Memory Controller
-	2c19  QuickPath Memory Controller Target Address Decoder
-	2c1a  QuickPath Memory Controller RAS Registers
-	2c1c  QuickPath Memory Controller Test Registers
-	2c20  QuickPath Memory Controller Channel 0 Control Registers
-	2c21  QuickPath Memory Controller Channel 0 Address Registers
-	2c22  QuickPath Memory Controller Channel 0 Rank Registers
-	2c23  QuickPath Memory Controller Channel 0 Thermal Control Registers
-	2c28  QuickPath Memory Controller Channel 1 Control Registers
-	2c29  QuickPath Memory Controller Channel 1 Address Registers
-	2c2a  QuickPath Memory Controller Channel 1 Rank Registers
-	2c2b  QuickPath Memory Controller Channel 1 Thermal Control Registers
-	2c30  QuickPath Memory Controller Channel 2 Control Registers
-	2c31  QuickPath Memory Controller Channel 2 Address Registers
-	2c32  QuickPath Memory Controller Channel 2 Rank Registers
-	2c33  QuickPath Memory Controller Channel 2 Thermal Control Registers
-	2c40  QuickPath Architecture Generic Non-Core Registers
+	2c01  Core i7 QuickPath Architecture System Address Decoder
+	2c10  Core i7 QPI Link 0
+	2c11  Core i7 QPI Physical 0
+	2c14  Core i7 QPI Link 1
+	2c15  Core i7 QPI Physical 1
+	2c18  Core i7 Integrated Memory Controller
+	2c19  Core i7 Integrated Memory Controller Target Address Decoder
+	2c1a  Core i7 Integrated Memory Controller RAS Registers
+	2c1c  Core i7 Integrated Memory Controller Test Registers
+	2c20  Core i7 Integrated Memory Controller Channel 0 Control Registers
+	2c21  Core i7 Integrated Memory Controller Channel 0 Address Registers
+	2c22  Core i7 Integrated Memory Controller Channel 0 Rank Registers
+	2c23  Core i7 Integrated Memory Controller Channel 0 Thermal Control Registers
+	2c28  Core i7 Integrated Memory Controller Channel 1 Control Registers
+	2c29  Core i7 Integrated Memory Controller Channel 1 Address Registers
+	2c2a  Core i7 Integrated Memory Controller Channel 1 Rank Registers
+	2c2b  Core i7 Integrated Memory Controller Channel 1 Thermal Control Registers
+	2c30  Core i7 Integrated Memory Controller Channel 2 Control Registers
+	2c31  Core i7 Integrated Memory Controller Channel 2 Address Registers
+	2c32  Core i7 Integrated Memory Controller Channel 2 Rank Registers
+	2c33  Core i7 Integrated Memory Controller Channel 2 Thermal Control Registers
+	2c40  Core i7 QuickPath Architecture Generic Non-Core Registers
+	2c41  QuickPath Architecture Generic Non-Core Registers
 	2c50  QuickPath Architecture Generic Non-Core Registers
 	2c51  QuickPath Architecture Generic Non-Core Registers
 	2c52  QuickPath Architecture Generic Non-Core Registers
@@ -15540,46 +15655,47 @@
 	3382  81342 [Chevelon] I/O Processor (ATUe)
 	33c3  IOP348 I/O Processor (SL8De) in IOC Mode SAS/SATA
 	33cb  IOP348 I/O Processor (SL8Dx) in IOC Mode SAS/SATA
-	3400  QuickPath Architecture I/O Hub to ESI Port
-	3401  QuickPath Architecture I/O Hub to ESI Port
-	3402  QuickPath Architecture I/O Hub to ESI Port
-	3403  QuickPath Architecture I/O Hub to ESI Port
-	3404  QuickPath Architecture I/O Hub to ESI Port
-	3405  QuickPath Architecture I/O Hub to ESI Port
-	3406  QuickPath Architecture I/O Hub to ESI Port
-	3407  QuickPath Architecture I/O Hub to ESI Port
-	3408  QuickPath Architecture I/O Hub PCI Express Root Port 1
-	3409  QuickPath Architecture I/O Hub PCI Express Root Port 2
-	340a  QuickPath Architecture I/O Hub PCI Express Root Port 3
-	340b  QuickPath Architecture I/O Hub PCI Express Root Port 4
-	340c  QuickPath Architecture I/O Hub PCI Express Root Port 5
-	340d  QuickPath Architecture I/O Hub PCI Express Root Port 6
-	340e  QuickPath Architecture I/O Hub PCI Express Root Port 7
-	340f  QuickPath Architecture I/O Hub PCI Express Root Port 8
-	3410  QuickPath Architecture I/O Hub PCI Express Root Port 9
-	3411  QuickPath Architecture I/O Hub PCI Express Root Port 10
-	3418  Quickpath Interconnect Physical Layer Port 0
+	3400  X58 I/O Hub to ESI Port
+	3401  X58 I/O Hub to ESI Port
+	3402  X58 I/O Hub to ESI Port
+	3403  X58 I/O Hub to ESI Port
+		1028 0287  PowerEdge M610 I/O Hub to ESI Port
+	3404  X58 I/O Hub to ESI Port
+	3405  X58 I/O Hub to ESI Port
+	3406  X58 I/O Hub to ESI Port
+	3407  X58 I/O Hub to ESI Port
+	3408  X58 I/O Hub PCI Express Root Port 1
+	3409  X58 I/O Hub PCI Express Root Port 2
+	340a  X58 I/O Hub PCI Express Root Port 3
+	340b  X58 I/O Hub PCI Express Root Port 4
+	340c  X58 I/O Hub PCI Express Root Port 5
+	340d  X58 I/O Hub PCI Express Root Port 6
+	340e  X58 I/O Hub PCI Express Root Port 7
+	340f  X58 I/O Hub PCI Express Root Port 8
+	3410  X58 I/O Hub PCI Express Root Port 9
+	3411  X58 I/O Hub PCI Express Root Port 10
+	3418  X58 Physical Layer Port 0
 	3419  Quickpath Interconnect Physical Layer Port 1
-	3420  QuickPath Architecture I/O Hub PCI Express Root Port 0
-	3421  QuickPath Architecture I/O Hub PCI Express Root Port 0
-	3422  QuickPath Architecture I/O Hub GPIO and Scratch Pad Registers
-	3423  QuickPath Architecture I/O Hub Control Status and RAS Registers
-	3425  QuickPath Interconnect Physical and Link Layer Registers Port 0
-	3426  QuickPath Interconnect Routing and Protocol Layer Registers Port 0
+	3420  X58 I/O Hub PCI Express Root Port 0
+	3421  X58 I/O Hub PCI Express Root Port 0
+	3422  X58 I/O Hub GPIO and Scratch Pad Registers
+	3423  X58 I/O Hub Control Status and RAS Registers
+	3425  X58 Physical and Link Layer Registers Port 0
+	3426  X58 Routing and Protocol Layer Registers Port 0
 	3427  QuickPath Interconnect Physical and Link Layer Registers Port 1
 	3428  QuickPath Interconnect Routing and Protocol Layer Registers Port 1
-	3429  DMA Engine
-	342a  DMA Engine
-	342b  DMA Engine
+	3429  X58 Chipset QuickData Technology Device
+	342a  X58 Chipset QuickData Technology Device
+	342b  X58 Chipset QuickData Technology Device
 	342c  DMA Engine
-	342d  QuickPath Architecture I/O Hub I/OxAPIC Interrupt Controller
-	342e  QuickPath Architecture I/O Hub System Management Registers
-	342f  Trusted Execution Technology Registers
-	3430  DMA Engine
-	3431  DMA Engine
-	3432  DMA Engine
-	3433  DMA Engine
-	3438  QuickPath Architecture I/O Hub Throttle Registers
+	342d  X58 I/O Hub I/OxAPIC Interrupt Controller
+	342e  X58 I/O Hub System Management Registers
+	342f  X58 Trusted Execution Technology Registers
+	3430  X58 Chipset QuickData Technology Device
+	3431  X58 Chipset QuickData Technology Device
+	3432  X58 Chipset QuickData Technology Device
+	3433  X58 Chipset QuickData Technology Device
+	3438  X58 I/O Hub Throttle Registers
 	3500  6311ESB/6321ESB PCI Express Upstream Port
 	3501  6310ESB PCI Express Upstream Port
 	3504  6311ESB/6321ESB I/OxAPIC Interrupt Controller
@@ -15721,6 +15837,7 @@
 	3a1a  82801JD (ICH10D) LPC Interface Controller
 	3a20  82801JI (ICH10 Family) 4 port SATA IDE Controller
 	3a22  82801JI (ICH10 Family) SATA AHCI Controller
+		1043 82d4  P5Q Deluxe Motherboard
 		1458 b005  GA-EP45-DS5 Motherboard
 	3a25  82801JIR (ICH10R) SATA RAID Controller
 	3a26  82801JI (ICH10 Family) 2 port SATA IDE Controller
@@ -15878,8 +15995,7 @@
 		8086 2722  Dell Latitude D600
 		8086 2731  Samsung P35 integrated WLAN
 	4222  PRO/Wireless 3945ABG [Golan] Network Connection
-		103c 135c  Compaq 6710b
-		103c 30c0  Compaq 6710b
+		103c 135c  Compaq 6710b or nx9420 Notebook
 		8086 1000  PRO/Wireless 3945ABG Network Connection
 		8086 1001  PRO/Wireless 3945ABG Network Connection
 		8086 1005  PRO/Wireless 3945BG Network Connection
@@ -15897,6 +16013,7 @@
 		8086 1011  ThinkPad R60e/X60s
 		8086 1014  PRO/Wireless 3945BG Network Connection
 	4229  PRO/Wireless 4965 AG or AGN [Kedron] Network Connection
+	422b  WiFi Link 6000 Series
 	4230  PRO/Wireless 4965 AG or AGN [Kedron] Network Connection
 		8086 1110  Lenovo ThinkPad T51
 		8086 1111  Lenovo ThinkPad T61
@@ -15906,11 +16023,16 @@
 		8086 1216  PRO/Wireless 5100ABG Network Connection
 		8086 1305  PRO/Wireless 5100BG Network Connection
 		8086 1306  PRO/Wireless 5100ABG Network Connection
+		8086 1321  Wireless WiFi Link 5100
 		8086 1326  PRO/Wireless 5100ABG Network Connection
 	4235  PRO/Wireless 5300 AGN [Shiloh] Network Connection
-	4236  Wireless WiFi Link 5100
+	4236  Wireless WiFi Link 5300
 	4237  PRO/Wireless 5100 AGN [Shiloh] Network Connection
+	4238  WiFi Link 6000 Series
 	423a  PRO/Wireless 5350 AGN [Echo Peak] Network Connection
+	423b  PRO/Wireless 5350 AGN [Echo Peak] Network Connection
+	423c  WiMAX/WiFi Link 5050 Series
+	423d  WiMAX/WiFi Link 5050 Series
 	444e  Turbo Memory Controller
 	5001  LE80578
 	5002  LE80578 Graphics Processor Unit
@@ -16685,6 +16807,8 @@
 	efac  Xena SD-MM/SD-22-MM
 	facd  Xena HD-MM
 f5f5  F5 Networks, Inc.
+# Subsystem ID for PATA controller on nForce motherboard
+f849  ASRock Incorporation (Wrong ID)
 fa57  Interagon AS
 	0001  PMC [Pattern Matching Chip]
 fab7  Fabric7 Systems, Inc.
diff -ruN pciutils-3.0.3/pcilib.man pciutils-3.1.0/pcilib.man
--- pciutils-3.0.3/pcilib.man	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/pcilib.man	2008-12-13 00:14:24.000000000 +0100
@@ -21,8 +21,9 @@
 The
 .B /sys
 filesystem on Linux 2.6 and newer. The standard header of the config space is available
-to all users, the rest only to root. Supports extended configuration space, PCI domains
-and information on attached kernel drivers.
+to all users, the rest only to root. Supports extended configuration space, PCI domains,
+VPD (from Linux 2.6.26), physical slots (also since Linux 2.6.26) and information on attached
+kernel drivers.
 .TP
 .B linux-proc
 The
diff -ruN pciutils-3.0.3/pciutils.h pciutils-3.1.0/pciutils.h
--- pciutils-3.0.3/pciutils.h	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/pciutils.h	2008-11-11 00:11:51.000000000 +0100
@@ -20,6 +20,7 @@
 void die(char *msg, ...) NONRET PCI_PRINTF(1,2);
 void *xmalloc(unsigned int howmuch);
 void *xrealloc(void *ptr, unsigned int howmuch);
+char *xstrdup(char *str);
 int parse_generic_option(int i, struct pci_access *pacc, char *optarg);
 
 #ifdef PCI_HAVE_PM_INTEL_CONF
diff -ruN pciutils-3.0.3/pciutils.lsm pciutils-3.1.0/pciutils.lsm
--- pciutils-3.0.3/pciutils.lsm	2008-11-09 21:29:23.000000000 +0100
+++ pciutils-3.1.0/pciutils.lsm	2009-01-18 23:12:51.000000000 +0100
@@ -1,14 +1,14 @@
 Begin3
 Title:          The PCI Utilities
-Version:        3.0.3
-Entered-date:   081109
+Version:        3.1.0
+Entered-date:   090118
 Description:    This package contains various utilities for inspecting and
 		setting of devices connected to the PCI bus.
 Keywords:       kernel, pci, lspci, setpci, libpci
 Author:         mj@ucw.cz (Martin Mares)
 Maintained-by:  mj@ucw.cz (Martin Mares)
-Primary-site:   atrey.karlin.mff.cuni.cz pub/linux/pci/pciutils-3.0.3.tar.gz
-Alternate-site: ftp.kernel.org pub/software/utils/pciutils/pciutils-3.0.3.tar.gz
-Alternate-site: metalab.unc.edu pub/Linux/hardware/pciutils-3.0.3.tar.gz
+Primary-site:   atrey.karlin.mff.cuni.cz pub/linux/pci/pciutils-3.1.0.tar.gz
+Alternate-site: ftp.kernel.org pub/software/utils/pciutils/pciutils-3.1.0.tar.gz
+Alternate-site: metalab.unc.edu pub/Linux/hardware/pciutils-3.1.0.tar.gz
 Copying-policy: GPL
 End
diff -ruN pciutils-3.0.3/pciutils.spec pciutils-3.1.0/pciutils.spec
--- pciutils-3.0.3/pciutils.spec	2008-11-09 21:29:24.000000000 +0100
+++ pciutils-3.1.0/pciutils.spec	2009-01-18 23:12:51.000000000 +0100
@@ -1,5 +1,5 @@
 Name:		pciutils
-Version:	3.0.3
+Version:	3.1.0
 Release: 	1
 Source:		ftp://atrey.karlin.mff.cuni.cz/pub/linux/pci/%{name}-%{version}.tar.gz
 Copyright:	GNU GPL
diff -ruN pciutils-3.0.3/setpci.c pciutils-3.1.0/setpci.c
--- pciutils-3.0.3/setpci.c	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/setpci.c	2008-11-21 22:12:31.000000000 +0100
@@ -11,6 +11,7 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <unistd.h>
+#include <errno.h>
 
 #define PCIUTILS_SETPCI
 #include "pciutils.h"
@@ -31,9 +32,11 @@
 struct op {
   struct op *next;
   struct pci_dev **dev_vector;
+  u16 cap_type;				/* PCI_CAP_xxx or 0 */
+  u16 cap_id;
   unsigned int addr;
   unsigned int width;			/* Byte width of the access */
-  int num_values;			/* Number of values to write; <0=read */
+  unsigned int num_values;		/* Number of values to write; 0=read */
   struct value values[0];
 };
 
@@ -46,41 +49,66 @@
   struct pci_dev *z, **a, **b;
   int cnt = 1;
 
-  for(z=pacc->devices; z; z=z->next)
+  for (z=pacc->devices; z; z=z->next)
     if (pci_filter_match(filt, z))
       cnt++;
   a = b = xmalloc(sizeof(struct device *) * cnt);
-  for(z=pacc->devices; z; z=z->next)
+  for (z=pacc->devices; z; z=z->next)
     if (pci_filter_match(filt, z))
       *a++ = z;
   *a = NULL;
   return b;
 }
 
+static void PCI_PRINTF(1,2)
+trace(const char *fmt, ...)
+{
+  va_list args;
+  va_start(args, fmt);
+  if (verbose)
+    vprintf(fmt, args);
+  va_end(args);
+}
+
 static void
 exec_op(struct op *op, struct pci_dev *dev)
 {
-  char *formats[] = { NULL, "%02x", "%04x", NULL, "%08x" };
-  char *mask_formats[] = { NULL, "%02x->(%02x:%02x)->%02x", "%04x->(%04x:%04x)->%04x", NULL, "%08x->(%08x:%08x)->%08x" };
-  unsigned int x, y;
-  int i, addr;
+  const char * const formats[] = { NULL, " %02x", " %04x", NULL, " %08x" };
+  const char * const mask_formats[] = { NULL, " %02x->(%02x:%02x)->%02x", " %04x->(%04x:%04x)->%04x", NULL, " %08x->(%08x:%08x)->%08x" };
+  unsigned int i, x, y;
+  int addr = 0;
   int width = op->width;
+  char slot[16];
 
-  if (verbose)
-    printf("%02x:%02x.%x:%02x", dev->bus, dev->dev, dev->func, op->addr);
-  addr = op->addr;
-  if (op->num_values >= 0)
+  sprintf(slot, "%04x:%02x:%02x.%x", dev->domain, dev->bus, dev->dev, dev->func);
+  trace("%s ", slot);
+  if (op->cap_type)
+    {
+      struct pci_cap *cap;
+      cap = pci_find_cap(dev, op->cap_id, op->cap_type);
+      if (cap)
+	addr = cap->addr;
+      else
+	die("%s: %s %04x not found", slot, ((op->cap_type == PCI_CAP_NORMAL) ? "Capability" : "Extended capability"), op->cap_id);
+      trace(((op->cap_type == PCI_CAP_NORMAL) ? "(cap %02x @%02x) " : "(ecap %04x @%03x) "), op->cap_id, addr);
+    }
+  addr += op->addr;
+  trace("@%02x", addr);
+
+  /* We have already checked it when parsing, but addressing relative to capabilities can change the address. */
+  if (addr & (width-1))
+    die("%s: Unaligned access of width %d to register %04x", slot, width, addr);
+  if (addr + width > 0x1000)
+    die("%s: Access of width %d to register %04x out of range", slot, width, addr);
+
+  if (op->num_values)
     {
-      for(i=0; i<op->num_values; i++)
+      for (i=0; i<op->num_values; i++)
 	{
 	  if ((op->values[i].mask & max_values[width]) == max_values[width])
 	    {
 	      x = op->values[i].value;
-	      if (verbose)
-		{
-		  putchar(' ');
-		  printf(formats[width], op->values[i].value);
-		}
+	      trace(formats[width], op->values[i].value);
 	    }
 	  else
 	    {
@@ -97,11 +125,7 @@
 		  break;
 		}
 	      x = (y & ~op->values[i].mask) | op->values[i].value;
-	      if (verbose)
-		{
-		  putchar(' ');
-		  printf(mask_formats[width], y, op->values[i].value, op->values[i].mask, x);
-		}
+	      trace(mask_formats[width], y, op->values[i].value, op->values[i].mask, x);
 	    }
 	  if (!demo_mode)
 	    {
@@ -120,13 +144,11 @@
 	    }
 	  addr += width;
 	}
-      if (verbose)
-	putchar('\n');
+      trace("\n");
     }
   else
     {
-      if (verbose)
-	printf(" = ");
+      trace(" = ");
       switch (width)
 	{
 	case 1:
@@ -139,7 +161,7 @@
 	  x = pci_read_long(dev, addr);
 	  break;
 	}
-      printf(formats[width], x);
+      printf(formats[width]+1, x);
       putchar('\n');
     }
 }
@@ -155,7 +177,7 @@
     {
       pdev = vec = op->dev_vector;
       while (dev = *pdev++)
-	for(oops=op; oops && oops->dev_vector == vec; oops=oops->next)
+	for (oops=op; oops && oops->dev_vector == vec; oops=oops->next)
 	  exec_op(oops, dev);
       while (op && op->dev_vector == vec)
 	op = op->next;
@@ -165,99 +187,145 @@
 static void
 scan_ops(struct op *op)
 {
+  if (demo_mode)
+    return;
   while (op)
     {
-      if (op->num_values >= 0)
+      if (op->num_values)
 	pacc->writeable = 1;
       op = op->next;
     }
 }
 
 struct reg_name {
+  unsigned int cap;
   unsigned int offset;
   unsigned int width;
   const char *name;
 };
 
 static const struct reg_name pci_reg_names[] = {
-  { 0x00, 2, "VENDOR_ID", },
-  { 0x02, 2, "DEVICE_ID", },
-  { 0x04, 2, "COMMAND", },
-  { 0x06, 2, "STATUS", },
-  { 0x08, 1, "REVISION", },
-  { 0x09, 1, "CLASS_PROG", },
-  { 0x0a, 2, "CLASS_DEVICE", },
-  { 0x0c, 1, "CACHE_LINE_SIZE", },
-  { 0x0d, 1, "LATENCY_TIMER", },
-  { 0x0e, 1, "HEADER_TYPE", },
-  { 0x0f, 1, "BIST", },
-  { 0x10, 4, "BASE_ADDRESS_0", },
-  { 0x14, 4, "BASE_ADDRESS_1", },
-  { 0x18, 4, "BASE_ADDRESS_2", },
-  { 0x1c, 4, "BASE_ADDRESS_3", },
-  { 0x20, 4, "BASE_ADDRESS_4", },
-  { 0x24, 4, "BASE_ADDRESS_5", },
-  { 0x28, 4, "CARDBUS_CIS", },
-  { 0x2c, 4, "SUBSYSTEM_VENDOR_ID", },
-  { 0x2e, 2, "SUBSYSTEM_ID", },
-  { 0x30, 4, "ROM_ADDRESS", },
-  { 0x3c, 1, "INTERRUPT_LINE", },
-  { 0x3d, 1, "INTERRUPT_PIN", },
-  { 0x3e, 1, "MIN_GNT", },
-  { 0x3f, 1, "MAX_LAT", },
-  { 0x18, 1, "PRIMARY_BUS", },
-  { 0x19, 1, "SECONDARY_BUS", },
-  { 0x1a, 1, "SUBORDINATE_BUS", },
-  { 0x1b, 1, "SEC_LATENCY_TIMER", },
-  { 0x1c, 1, "IO_BASE", },
-  { 0x1d, 1, "IO_LIMIT", },
-  { 0x1e, 2, "SEC_STATUS", },
-  { 0x20, 2, "MEMORY_BASE", },
-  { 0x22, 2, "MEMORY_LIMIT", },
-  { 0x24, 2, "PREF_MEMORY_BASE", },
-  { 0x26, 2, "PREF_MEMORY_LIMIT", },
-  { 0x28, 4, "PREF_BASE_UPPER32", },
-  { 0x2c, 4, "PREF_LIMIT_UPPER32", },
-  { 0x30, 2, "IO_BASE_UPPER16", },
-  { 0x32, 2, "IO_LIMIT_UPPER16", },
-  { 0x38, 4, "BRIDGE_ROM_ADDRESS", },
-  { 0x3e, 2, "BRIDGE_CONTROL", },
-  { 0x10, 4, "CB_CARDBUS_BASE", },
-  { 0x14, 2, "CB_CAPABILITIES", },
-  { 0x16, 2, "CB_SEC_STATUS", },
-  { 0x18, 1, "CB_BUS_NUMBER", },
-  { 0x19, 1, "CB_CARDBUS_NUMBER", },
-  { 0x1a, 1, "CB_SUBORDINATE_BUS", },
-  { 0x1b, 1, "CB_CARDBUS_LATENCY", },
-  { 0x1c, 4, "CB_MEMORY_BASE_0", },
-  { 0x20, 4, "CB_MEMORY_LIMIT_0", },
-  { 0x24, 4, "CB_MEMORY_BASE_1", },
-  { 0x28, 4, "CB_MEMORY_LIMIT_1", },
-  { 0x2c, 2, "CB_IO_BASE_0", },
-  { 0x2e, 2, "CB_IO_BASE_0_HI", },
-  { 0x30, 2, "CB_IO_LIMIT_0", },
-  { 0x32, 2, "CB_IO_LIMIT_0_HI", },
-  { 0x34, 2, "CB_IO_BASE_1", },
-  { 0x36, 2, "CB_IO_BASE_1_HI", },
-  { 0x38, 2, "CB_IO_LIMIT_1", },
-  { 0x3a, 2, "CB_IO_LIMIT_1_HI", },
-  { 0x40, 2, "CB_SUBSYSTEM_VENDOR_ID", },
-  { 0x42, 2, "CB_SUBSYSTEM_ID", },
-  { 0x44, 4, "CB_LEGACY_MODE_BASE", },
-  { 0x00, 0, NULL }
+  {       0, 0x00, 2, "VENDOR_ID" },
+  {       0, 0x02, 2, "DEVICE_ID" },
+  {       0, 0x04, 2, "COMMAND" },
+  {       0, 0x06, 2, "STATUS" },
+  {       0, 0x08, 1, "REVISION" },
+  {       0, 0x09, 1, "CLASS_PROG" },
+  {       0, 0x0a, 2, "CLASS_DEVICE" },
+  {       0, 0x0c, 1, "CACHE_LINE_SIZE" },
+  {       0, 0x0d, 1, "LATENCY_TIMER" },
+  {       0, 0x0e, 1, "HEADER_TYPE" },
+  {       0, 0x0f, 1, "BIST" },
+  {       0, 0x10, 4, "BASE_ADDRESS_0" },
+  {       0, 0x14, 4, "BASE_ADDRESS_1" },
+  {       0, 0x18, 4, "BASE_ADDRESS_2" },
+  {       0, 0x1c, 4, "BASE_ADDRESS_3" },
+  {       0, 0x20, 4, "BASE_ADDRESS_4" },
+  {       0, 0x24, 4, "BASE_ADDRESS_5" },
+  {       0, 0x28, 4, "CARDBUS_CIS" },
+  {       0, 0x2c, 4, "SUBSYSTEM_VENDOR_ID" },
+  {       0, 0x2e, 2, "SUBSYSTEM_ID" },
+  {       0, 0x30, 4, "ROM_ADDRESS" },
+  {       0, 0x3c, 1, "INTERRUPT_LINE" },
+  {       0, 0x3d, 1, "INTERRUPT_PIN" },
+  {       0, 0x3e, 1, "MIN_GNT" },
+  {       0, 0x3f, 1, "MAX_LAT" },
+  {       0, 0x18, 1, "PRIMARY_BUS" },
+  {       0, 0x19, 1, "SECONDARY_BUS" },
+  {       0, 0x1a, 1, "SUBORDINATE_BUS" },
+  {       0, 0x1b, 1, "SEC_LATENCY_TIMER" },
+  {       0, 0x1c, 1, "IO_BASE" },
+  {       0, 0x1d, 1, "IO_LIMIT" },
+  {       0, 0x1e, 2, "SEC_STATUS" },
+  {       0, 0x20, 2, "MEMORY_BASE" },
+  {       0, 0x22, 2, "MEMORY_LIMIT" },
+  {       0, 0x24, 2, "PREF_MEMORY_BASE" },
+  {       0, 0x26, 2, "PREF_MEMORY_LIMIT" },
+  {       0, 0x28, 4, "PREF_BASE_UPPER32" },
+  {       0, 0x2c, 4, "PREF_LIMIT_UPPER32" },
+  {       0, 0x30, 2, "IO_BASE_UPPER16" },
+  {       0, 0x32, 2, "IO_LIMIT_UPPER16" },
+  {       0, 0x38, 4, "BRIDGE_ROM_ADDRESS" },
+  {       0, 0x3e, 2, "BRIDGE_CONTROL" },
+  {       0, 0x10, 4, "CB_CARDBUS_BASE" },
+  {       0, 0x14, 2, "CB_CAPABILITIES" },
+  {       0, 0x16, 2, "CB_SEC_STATUS" },
+  {       0, 0x18, 1, "CB_BUS_NUMBER" },
+  {       0, 0x19, 1, "CB_CARDBUS_NUMBER" },
+  {       0, 0x1a, 1, "CB_SUBORDINATE_BUS" },
+  {       0, 0x1b, 1, "CB_CARDBUS_LATENCY" },
+  {       0, 0x1c, 4, "CB_MEMORY_BASE_0" },
+  {       0, 0x20, 4, "CB_MEMORY_LIMIT_0" },
+  {       0, 0x24, 4, "CB_MEMORY_BASE_1" },
+  {       0, 0x28, 4, "CB_MEMORY_LIMIT_1" },
+  {       0, 0x2c, 2, "CB_IO_BASE_0" },
+  {       0, 0x2e, 2, "CB_IO_BASE_0_HI" },
+  {       0, 0x30, 2, "CB_IO_LIMIT_0" },
+  {       0, 0x32, 2, "CB_IO_LIMIT_0_HI" },
+  {       0, 0x34, 2, "CB_IO_BASE_1" },
+  {       0, 0x36, 2, "CB_IO_BASE_1_HI" },
+  {       0, 0x38, 2, "CB_IO_LIMIT_1" },
+  {       0, 0x3a, 2, "CB_IO_LIMIT_1_HI" },
+  {       0, 0x40, 2, "CB_SUBSYSTEM_VENDOR_ID" },
+  {       0, 0x42, 2, "CB_SUBSYSTEM_ID" },
+  {       0, 0x44, 4, "CB_LEGACY_MODE_BASE" },
+  { 0x10001,    0, 0, "CAP_PM" },
+  { 0x10002,    0, 0, "CAP_AGP" },
+  { 0x10003,    0, 0, "CAP_VPD" },
+  { 0x10004,    0, 0, "CAP_SLOTID" },
+  { 0x10005,    0, 0, "CAP_MSI" },
+  { 0x10006,    0, 0, "CAP_CHSWP" },
+  { 0x10007,    0, 0, "CAP_PCIX" },
+  { 0x10008,    0, 0, "CAP_HT" },
+  { 0x10009,    0, 0, "CAP_VNDR" },
+  { 0x1000a,    0, 0, "CAP_DBG" },
+  { 0x1000b,    0, 0, "CAP_CCRC" },
+  { 0x1000c,    0, 0, "CAP_HOTPLUG" },
+  { 0x1000d,    0, 0, "CAP_SSVID" },
+  { 0x1000e,    0, 0, "CAP_AGP3" },
+  { 0x1000f,    0, 0, "CAP_SECURE" },
+  { 0x10010,    0, 0, "CAP_EXP" },
+  { 0x10011,    0, 0, "CAP_MSIX" },
+  { 0x10012,    0, 0, "CAP_SATA" },
+  { 0x10013,    0, 0, "CAP_AF" },
+  { 0x20001,	0, 0, "ECAP_AER" },
+  { 0x20002,	0, 0, "ECAP_VC" },
+  { 0x20003,	0, 0, "ECAP_DSN" },
+  { 0x20004,	0, 0, "ECAP_PB" },
+  { 0x20005,	0, 0, "ECAP_RCLINK" },
+  { 0x20006,	0, 0, "ECAP_RCILINK" },
+  { 0x20007,	0, 0, "ECAP_RCECOLL" },
+  { 0x20008,	0, 0, "ECAP_MFVC" },
+  { 0x2000a,	0, 0, "ECAP_RBCB" },
+  { 0x2000b,	0, 0, "ECAP_VNDR" },
+  { 0x2000d,	0, 0, "ECAP_ACS" },
+  { 0x2000e,	0, 0, "ECAP_ARI" },
+  { 0x2000f,	0, 0, "ECAP_ATS" },
+  { 0x20010,	0, 0, "ECAP_SRIOV" },
+  {       0,    0, 0, NULL }
 };
 
-static void NONRET PCI_PRINTF(1,2)
-usage(char *msg, ...)
+static void
+dump_registers(void)
 {
-  va_list args;
-  va_start(args, msg);
-  if (msg)
+  const struct reg_name *r;
+
+  printf("cap pos w name\n");
+  for (r = pci_reg_names; r->name; r++)
     {
-      fprintf(stderr, "setpci: ");
-      vfprintf(stderr, msg, args);
-      fprintf(stderr, "\n\n");
+      if (r->cap >= 0x20000)
+	printf("%04x", r->cap - 0x20000);
+      else if (r->cap)
+	printf("  %02x", r->cap - 0x10000);
+      else
+	printf("    ");
+      printf(" %02x %c %s\n", r->offset, "-BW?L"[r->width], r->name);
     }
+}
+
+static void NONRET
+usage(void)
+{
   fprintf(stderr,
 "Usage: setpci [<options>] (<device>+ <reg>[=<values>]*)*\n"
 "\n"
@@ -265,48 +333,68 @@
 "-f\t\tDon't complain if there's nothing to do\n"
 "-v\t\tBe verbose\n"
 "-D\t\tList changes, don't commit them\n"
+"--dumpregs\tDump all known register names and exit\n"
 "\n"
 "PCI access options:\n"
 GENERIC_HELP
 "\n"
 "Setting commands:\n"
 "<device>:\t-s [[[<domain>]:][<bus>]:][<slot>][.[<func>]]\n"
-"\t|\t-d [<vendor>]:[<device>]\n"
-"<reg>:\t\t<number>[.(B|W|L)]\n"
-"     |\t\t<name>\n"
+"\t\t-d [<vendor>]:[<device>]\n"
+"<reg>:\t\t<base>[+<offset>][.(B|W|L)]\n"
+"<base>:\t\t<address>\n"
+"\t\t<named-register>\n"
+"\t\t[E]CAP_<capability-name>\n"
+"\t\t[E]CAP<capability-number>\n"
 "<values>:\t<value>[,<value>...]\n"
 "<value>:\t<hex>\n"
-"       |\t<hex>:<mask>\n");
+"\t\t<hex>:<mask>\n");
+  exit(0);
+}
+
+static void NONRET PCI_PRINTF(1,2)
+parse_err(const char *msg, ...)
+{
+  va_list args;
+  va_start(args, msg);
+  fprintf(stderr, "setpci: ");
+  vfprintf(stderr, msg, args);
+  fprintf(stderr, ".\nTry `setpci --help' for more information.\n");
   exit(1);
 }
 
-int
-main(int argc, char **argv)
+static int
+parse_options(int argc, char **argv)
 {
-  enum { STATE_INIT, STATE_GOT_FILTER, STATE_GOT_OP } state = STATE_INIT;
-  struct pci_filter filter;
-  struct pci_dev **selected_devices = NULL;
-  char *opts = GENERIC_OPTIONS ;
+  const char opts[] = GENERIC_OPTIONS;
+  int i=1;
 
-  if (argc == 2 && !strcmp(argv[1], "--version"))
+  if (argc == 2)
     {
-      puts("setpci version " PCIUTILS_VERSION);
-      return 0;
+      if (!strcmp(argv[1], "--help"))
+	usage();
+      if (!strcmp(argv[1], "--version"))
+	{
+	  puts("setpci version " PCIUTILS_VERSION);
+	  exit(0);
+	}
+      if (!strcmp(argv[1], "--dumpregs"))
+	{
+	  dump_registers();
+	  exit(0);
+	}
     }
-  argc--;
-  argv++;
 
-  pacc = pci_alloc();
-  pacc->error = die;
-
-  while (argc && argv[0][0] == '-')
+  while (i < argc && argv[i][0] == '-')
     {
-      char *c = argv[0]+1;
+      char *c = argv[i++] + 1;
       char *d = c;
       char *e;
       while (*c)
 	switch (*c)
 	  {
+	  case 0:
+	    break;
 	  case 'v':
 	    verbose++;
 	    c++;
@@ -319,8 +407,6 @@
 	    demo_mode++;
 	    c++;
 	    break;
-	  case 0:
-	    break;
 	  default:
 	    if (e = strchr(opts, *c))
 	      {
@@ -330,182 +416,291 @@
 		  {
 		    if (*c)
 		      arg = c;
-		    else if (argc > 1)
-		      {
-			arg = argv[1];
-			argc--; argv++;
-		      }
+		    else if (i < argc)
+		      arg = argv[i++];
 		    else
-		      usage(NULL);
+		      parse_err("Option -%c requires an argument", *e);
 		    c = "";
 		  }
 		else
 		  arg = NULL;
 		if (!parse_generic_option(*e, pacc, arg))
-		  usage(NULL);
+		  parse_err("Unable to parse option -%c", *e);
 	      }
 	    else
 	      {
 		if (c != d)
-		  usage(NULL);
-		goto next;
+		  parse_err("Invalid or misplaced option -%c", *c);
+		return i-1;
 	      }
 	  }
-      argc--;
-      argv++;
     }
-next:
 
-  pci_init(pacc);
-  pci_scan_bus(pacc);
+  return i;
+}
+
+static int parse_filter(int argc, char **argv, int i, struct pci_filter *filter)
+{
+  char *c = argv[i++];
+  char *d;
+
+  if (!c[1] || !strchr("sd", c[1]))
+    parse_err("Invalid option -%c", c[1]);
+  if (c[2])
+    d = (c[2] == '=') ? c+3 : c+2;
+  else if (i < argc)
+    d = argv[i++];
+  else
+    parse_err("Option -%c requires an argument", c[1]);
+  switch (c[1])
+    {
+    case 's':
+      if (d = pci_filter_parse_slot(filter, d))
+	parse_err("Unable to parse filter -s %s", d);
+      break;
+    case 'd':
+      if (d = pci_filter_parse_id(filter, d))
+	parse_err("Unable to parse filter -d %s", d);
+      break;
+    default:
+      parse_err("Unknown filter option -%c", c[1]);
+    }
+
+  return i;
+}
+
+static const struct reg_name *parse_reg_name(char *name)
+{
+  const struct reg_name *r;
+
+  for (r = pci_reg_names; r->name; r++)
+    if (!strcasecmp(r->name, name))
+      return r;
+  return NULL;
+}
+
+static int parse_x32(char *c, char **stopp, unsigned int *resp)
+{
+  char *stop;
+
+  if (!*c)
+    return -1;
+  errno = 0;
+  unsigned long int l = strtoul(c, &stop, 16);
+  if (errno)
+    return -1;
+  if ((l & ~0U) != l)
+    return -1;
+  *resp = l;
+  if (*stop)
+    {
+      if (stopp)
+	*stopp = stop;
+      return 0;
+    }
+  else
+    return 1;
+}
+
+static void parse_register(struct op *op, char *base)
+{
+  const struct reg_name *r;
+  unsigned int cap;
+
+  op->cap_type = op->cap_id = 0;
+  if (parse_x32(base, NULL, &op->addr) > 0)
+    return;
+  else if (r = parse_reg_name(base))
+    {
+      switch (r->cap & 0xff0000)
+	{
+	case 0x10000:
+	  op->cap_type = PCI_CAP_NORMAL;
+	  break;
+	case 0x20000:
+	  op->cap_type = PCI_CAP_EXTENDED;
+	  break;
+	}
+      op->cap_id = r->cap & 0xffff;
+      op->addr = r->offset;
+      if (r->width && !op->width)
+	op->width = r->width;
+      return;
+    }
+  else if (!strncasecmp(base, "CAP", 3))
+    {
+      if (parse_x32(base+3, NULL, &cap) > 0 && cap < 0x100)
+	{
+	  op->cap_type = PCI_CAP_NORMAL;
+	  op->cap_id = cap;
+	  op->addr = 0;
+	  return;
+	}
+    }
+  else if (!strncasecmp(base, "ECAP", 4))
+    {
+      if (parse_x32(base+4, NULL, &cap) > 0 && cap < 0x1000)
+	{
+	  op->cap_type = PCI_CAP_EXTENDED;
+	  op->cap_id = cap;
+	  op->addr = 0;
+	  return;
+	}
+    }
+  parse_err("Unknown register \"%s\"", base);
+}
+
+static void parse_op(char *c, struct pci_dev **selected_devices)
+{
+  char *base, *offset, *width, *value;
+  char *e, *f;
+  int n, j;
+  struct op *op;
+
+  /* Split the argument */
+  base = xstrdup(c);
+  if (value = strchr(base, '='))
+    *value++ = 0;
+  if (width = strchr(base, '.'))
+    *width++ = 0;
+  if (offset = strchr(base, '+'))
+    *offset++ = 0;
+
+  /* Look for setting of values and count how many */
+  n = 0;
+  if (value)
+    {
+      if (!*value)
+	parse_err("Missing value");
+      n++;
+      for (e=value; *e; e++)
+	if (*e == ',')
+	  n++;
+    }
 
-  while (argc)
+  /* Allocate the operation */
+  op = xmalloc(sizeof(struct op) + n*sizeof(struct value));
+  op->dev_vector = selected_devices;
+  op->num_values = n;
+
+  /* What is the width suffix? */
+  if (width)
     {
-      char *c = argv[0];
-      char *d, *e, *f;
-      int n, i;
-      struct op *op;
-      unsigned long ll;
-      unsigned int lim;
+      if (width[1])
+	parse_err("Invalid width \"%s\"", width);
+      switch (*width & 0xdf)
+	{
+	case 'B':
+	  op->width = 1; break;
+	case 'W':
+	  op->width = 2; break;
+	case 'L':
+	  op->width = 4; break;
+	default:
+	  parse_err("Invalid width \"%c\"", *width);
+	}
+    }
+  else
+    op->width = 0;
+
+  /* Find the register */
+  parse_register(op, base);
+  if (!op->width)
+    parse_err("Missing width");
+
+  /* Add offset */
+  if (offset)
+    {
+      unsigned int off;
+      if (parse_x32(offset, NULL, &off) <= 0 || off >= 0x1000)
+	parse_err("Invalid offset \"%s\"", offset);
+      op->addr += off;
+    }
+
+  /* Check range */
+  if (op->addr >= 0x1000 || op->addr + op->width*(n ? n : 1) > 0x1000)
+    parse_err("Register number %02x out of range", op->addr);
+  if (op->addr & (op->width - 1))
+    parse_err("Unaligned register address %02x", op->addr);
+
+  /* Parse the values */
+  for (j=0; j<n; j++)
+    {
+      unsigned int ll, lim;
+      e = strchr(value, ',');
+      if (e)
+	*e++ = 0;
+      if (parse_x32(value, &f, &ll) < 0 || *f && *f != ':')
+	parse_err("Invalid value \"%s\"", value);
+      lim = max_values[op->width];
+      if (ll > lim && ll < ~0UL - lim)
+	parse_err("Value \"%s\" is out of range", value);
+      op->values[j].value = ll;
+      if (*f == ':')
+	{
+	  if (parse_x32(f+1, NULL, &ll) <= 0)
+	    parse_err("Invalid mask \"%s\"", f+1);
+	  if (ll > lim && ll < ~0UL - lim)
+	    parse_err("Mask \"%s\" is out of range", f+1);
+	  op->values[j].mask = ll;
+	  op->values[j].value &= ll;
+	}
+      else
+	op->values[j].mask = ~0U;
+      value = e;
+    }
+
+  *last_op = op;
+  last_op = &op->next;
+  op->next = NULL;
+}
+
+static void parse_ops(int argc, char **argv, int i)
+{
+  enum { STATE_INIT, STATE_GOT_FILTER, STATE_GOT_OP } state = STATE_INIT;
+  struct pci_filter filter;
+  struct pci_dev **selected_devices = NULL;
+
+  while (i < argc)
+    {
+      char *c = argv[i++];
 
       if (*c == '-')
 	{
-	  if (!c[1] || !strchr("sd", c[1]))
-	    usage(NULL);
-	  if (c[2])
-	    d = (c[2] == '=') ? c+3 : c+2;
-	  else if (argc > 1)
-	    {
-	      argc--;
-	      argv++;
-	      d = argv[0];
-	    }
-	  else
-	    usage(NULL);
 	  if (state != STATE_GOT_FILTER)
-	    {
-	      pci_filter_init(pacc, &filter);
-	      state = STATE_GOT_FILTER;
-	    }
-	  switch (c[1])
-	    {
-	    case 's':
-	      if (d = pci_filter_parse_slot(&filter, d))
-		die("-s: %s", d);
-	      break;
-	    case 'd':
-	      if (d = pci_filter_parse_id(&filter, d))
-		die("-d: %s", d);
-	      break;
-	    default:
-	      usage(NULL);
-	    }
+	    pci_filter_init(pacc, &filter);
+	  i = parse_filter(argc, argv, i-1, &filter);
+	  state = STATE_GOT_FILTER;
 	}
-      else if (state == STATE_INIT)
-	usage(NULL);
       else
 	{
+	  if (state == STATE_INIT)
+	    parse_err("Filter specification expected");
 	  if (state == STATE_GOT_FILTER)
 	    selected_devices = select_devices(&filter);
 	  if (!selected_devices[0] && !force)
-	    fprintf(stderr, "setpci: Warning: No devices selected for `%s'.\n", c);
+	    fprintf(stderr, "setpci: Warning: No devices selected for \"%s\".\n", c);
+	  parse_op(c, selected_devices);
 	  state = STATE_GOT_OP;
-	  /* look for setting of values and count how many */
-	  d = strchr(c, '=');
-	  if (d)
-	    {
-	      *d++ = 0;
-	      if (!*d)
-		usage("Missing value");
-	      for(e=d, n=1; *e; e++)
-		if (*e == ',')
-		  n++;
-	      op = xmalloc(sizeof(struct op) + n*sizeof(struct value));
-	    }
-	  else
-	    {
-	      n = -1;
-	      op = xmalloc(sizeof(struct op));
-	    }
-	  op->dev_vector = selected_devices;
-	  op->num_values = n;
-	  e = strchr(c, '.');
-	  if (e)
-	    {
-	      *e++ = 0;
-	      if (e[1])
-		usage("Missing width");
-	      switch (*e & 0xdf)
-		{
-		case 'B':
-		  op->width = 1; break;
-		case 'W':
-		  op->width = 2; break;
-		case 'L':
-		  op->width = 4; break;
-		default:
-		  usage("Invalid width \"%c\"", *e);
-		}
-	    }
-	  else
-	    op->width = 1;
-	  ll = strtol(c, &f, 16);
-	  if (f && *f)
-	    {
-	      const struct reg_name *r;
-	      for(r = pci_reg_names; r->name; r++)
-		if (!strcasecmp(r->name, c))
-		  break;
-	      if (!r->name)
-		usage("Unknown register \"%s\"", c);
-	      if (e && op->width != r->width)
-		usage("Explicit width doesn't correspond with the named register \"%s\"", c);
-	      ll = r->offset;
-	      op->width = r->width;
-	    }
-	  if (ll > 0x1000 || ll + op->width*((n < 0) ? 1 : n) > 0x1000)
-	    die("Register number out of range!");
-	  if (ll & (op->width - 1))
-	    die("Unaligned register address!");
-	  op->addr = ll;
-	  /* read in all the values to be set */
-	  for(i=0; i<n; i++)
-	    {
-	      e = strchr(d, ',');
-	      if (e)
-		*e++ = 0;
-	      ll = strtoul(d, &f, 16);
-	      lim = max_values[op->width];
-	      if (f && *f && *f != ':')
-		usage("Invalid value \"%s\"", d);
-	      if (ll > lim && ll < ~0UL - lim)
-		usage("Value \"%s\" is out of range", d);
-	      op->values[i].value = ll;
-	      if (f && *f == ':')
-		{
-		  d = ++f;
-		  ll = strtoul(d, &f, 16);
-		  if (f && *f)
-		    usage("Invalid mask \"%s\"", d);
-		  if (ll > lim && ll < ~0UL - lim)
-		    usage("Mask \"%s\" is out of range", d);
-		  op->values[i].mask = ll;
-		  op->values[i].value &= ll;
-		}
-	      else
-		op->values[i].mask = ~0U;
-	      d = e;
-	    }
-	  *last_op = op;
-	  last_op = &op->next;
-	  op->next = NULL;
 	}
-      argc--;
-      argv++;
     }
   if (state == STATE_INIT)
-    usage("No operation specified");
+    parse_err("No operation specified");
+}
+
+int
+main(int argc, char **argv)
+{
+  int i;
+
+  pacc = pci_alloc();
+  pacc->error = die;
+  i = parse_options(argc, argv);
+
+  pci_init(pacc);
+  pci_scan_bus(pacc);
 
+  parse_ops(argc, argv, i);
   scan_ops(first_op);
   execute(first_op);
 
diff -ruN pciutils-3.0.3/setpci.man pciutils-3.1.0/setpci.man
--- pciutils-3.0.3/setpci.man	2008-04-10 21:15:47.000000000 +0200
+++ pciutils-3.1.0/setpci.man	2008-11-11 11:20:14.000000000 +0100
@@ -42,14 +42,21 @@
 `Demo mode' -- don't write anything to the configuration registers.
 It's useful to try
 .B setpci -vD
-to see what your complex sequence of
+to verify that your complex sequence of
 .B setpci
-operations does before you actually execute it.
+operations does what you think it should do.
 .TP
 .B --version
-Shows
+Show
 .I setpci
 version. This option should be used stand-alone.
+.TP
+.B --help
+Show detailed help on available options. This option should be used stand-alone.
+.TP
+.B --dumpregs
+Show a list of all known PCI registers and capabilities. This option should be
+used stand-alone.
 
 .SS PCI access options
 .PP
@@ -85,119 +92,86 @@
 operation to affect.
 .TP
 .B -s [[[[<domain>]:]<bus>]:][<slot>][.[<func>]]
-Show only devices in the specified domain (in case your machine has several host bridges,
+Consider only devices in the specified domain (in case your machine has several host bridges,
 they can either share a common bus number space or each of them can address a PCI domain
 of its own; domains are numbered from 0 to ffff), bus (0 to ff), slot (0 to 1f) and function (0 to 7).
 Each component of the device address can be omitted or set to "*", both meaning "any value". All numbers are
 hexadecimal.  E.g., "0:" means all devices on bus 0, "0" means all functions of device 0
-on any bus, "0.3" selects third function of device 0 on all buses and ".4" shows only
+on any bus, "0.3" selects third function of device 0 on all buses and ".4" matches only
 the fourth function of each device.
 .TP
 .B -d [<vendor>]:[<device>]
 Select devices with specified vendor and device ID. Both ID's are given in
 hexadecimal and may be omitted or given as "*", both meaning "any value".
-
-.SH OPERATIONS
 .PP
-To query value of a configuration register, just name it (either by typing its name or
-by typing register address with optional
-.BR .B ,
-.B .W
-or
-.B .L
-suffix specifying register width as byte, word or longword).
-.PP
-To set a register, write
-.BR reg = values
-where
-.B reg
-is the same as you would use to query the register and
-.B values
-is a comma-separated list of values you want to write starting with the given
-address. Each value to be written can be specified either as a hexadecimal number
-or as a
-.BR bits : mask
-pair which causes the bits corresponding to binary ones in the
-.B mask
-to be changed to values of the corresponding bits in the
-.B bits
-.
+When
+.B -s
+and
+.B -d
+are combined, only devices that match both criteria are selected. When multiple
+options of the same kind are specified, the rightmost one overrides the others.
 
-.SH REGISTER NAMES
+.SH OPERATIONS
 .PP
-.B setpci
-knows the following configuration register names. See PCI bus specifications for their precise
-meaning or consult
-.B header.h
-or
-.B /usr/include/linux/pci.h
-for a couple of comments.
-.PP
-.nf
-VENDOR_ID
-DEVICE_ID
-COMMAND
-STATUS
-REVISION
-CLASS_PROG
-CLASS_DEVICE
-CACHE_LINE_SIZE
-LATENCY_TIMER
-HEADER_TYPE
-BIST
-BASE_ADDRESS_0
-BASE_ADDRESS_1
-BASE_ADDRESS_2
-BASE_ADDRESS_3
-BASE_ADDRESS_4
-BASE_ADDRESS_5
-CARDBUS_CIS
-SUBSYSTEM_VENDOR_ID
-SUBSYSTEM_ID
-ROM_ADDRESS
-INTERRUPT_LINE
-INTERRUPT_PIN
-MIN_GNT
-MAX_LAT
-PRIMARY_BUS
-SECONDARY_BUS
-SUBORDINATE_BUS
-SEC_LATENCY_TIMER
-IO_BASE
-IO_LIMIT
-SEC_STATUS
-MEMORY_BASE
-MEMORY_LIMIT
-PREF_MEMORY_BASE
-PREF_MEMORY_LIMIT
-PREF_BASE_UPPER32
-PREF_LIMIT_UPPER32
-IO_BASE_UPPER16
-IO_LIMIT_UPPER16
-BRIDGE_ROM_ADDRESS
-BRIDGE_CONTROL
-CB_CARDBUS_BASE
-CB_CAPABILITIES
-CB_SEC_STATUS
-CB_BUS_NUMBER
-CB_CARDBUS_NUMBER
-CB_SUBORDINATE_BUS
-CB_CARDBUS_LATENCY
-CB_MEMORY_BASE_0
-CB_MEMORY_LIMIT_0
-CB_MEMORY_BASE_1
-CB_MEMORY_LIMIT_1
-CB_IO_BASE_0
-CB_IO_BASE_0_HI
-CB_IO_LIMIT_0
-CB_IO_LIMIT_0_HI
-CB_IO_BASE_1
-CB_IO_BASE_1_HI
-CB_IO_LIMIT_1
-CB_IO_LIMIT_1_HI
-CB_SUBSYSTEM_VENDOR_ID
-CB_SUBSYSTEM_ID
-CB_LEGACY_MODE_BASE
+There are two kinds of operations: reads and writes. To read a register, just specify
+its name. Writes have the form
+.IR name = value , value ...
+where each
+.I value
+is either a hexadecimal number or an expression of type
+.IR data : mask
+where both
+.I data
+and
+.I mask
+are hexdecimal numbers. In the latter case, only the bits corresponding to binary
+ones in the \fImask\fP are changed (technically, this is a read-modify-write operation).
+
+.PP
+There are several ways how to identity a register:
+.IP \(bu
+Tell its address in hexadecimal.
+.IP \(bu
+Spell its name. Setpci knows the names of all registers in the standard configuration
+headers. Use `\fBsetpci --dumpregs\fP' to get the complete list.
+See PCI bus specifications for the precise meaning of these registers or consult
+\fBheader.h\fP or \fB/usr/include/pci/pci.h\fP for a brief sketch.
+.IP \(bu
+If the register is a part of a PCI capability, you can specify the name of the
+capability to get the address of its first register. See the names starting with
+`CAP_' or `ECAP_' in the \fB--dumpregs\fP output.
+.IP \(bu
+If the name of the capability is not known to \fBsetpci\fP, you can refer to it
+by its number in the form CAP\fBid\fP or ECAP\fBid\fP, where \fBid\fP is the numeric
+identifier of the capability in hexadecimal.
+.IP \(bu
+Each of the previous formats can be followed by \fB+offset\fP to add an offset
+(a hex number) to the address. This feature can be useful for addressing of registers
+living within a capability, or to modify parts of standard registers.
+\IP \(bu
+Finally, you should append a width specifier \fB.B\fP, \fB.W\fP, or \fB.L\fP to choose
+how many bytes (1, 2, or 4) should be transferred. The width can be omitted if you are
+accessing a named register whose width is well known.
+
+.PP
+All names of registers and width specifiers are case-insensitive.
+
+.SH
+EXAMPLES
+
+.IP COMMAND
+asks for the word-sized command register.
+.IP 4.w
+is a numeric address of the same register.
+.IP COMMAND.l
+asks for a 32-bit word starting at the location of the command register,
+i.e., the command and status registers together.
+.IP VENDOR_ID+1.b
+specifies the upper byte of the vendor ID register (remember, PCI is little-endian).
+.IP CAP_PM+2.w
+corresponds to the second word of the power management capability.
+.IP ECAP108.l
+asks for the first 32-bit word of the extended capability with ID 0x108.
 
 .SH SEE ALSO
 .BR lspci (8),
diff -ruN pciutils-3.0.3/tests/cap-address-xlation pciutils-3.1.0/tests/cap-address-xlation
--- pciutils-3.0.3/tests/cap-address-xlation	1970-01-01 01:00:00.000000000 +0100
+++ pciutils-3.1.0/tests/cap-address-xlation	2008-12-12 23:50:54.000000000 +0100
@@ -0,0 +1,298 @@
+02:00.0 Ethernet controller: MYRICOM Inc. Myri-10G Dual-Protocol NIC
+	Subsystem: MYRICOM Inc. 10G-PCIE-8A (MSI-X firmware)
+	Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
+	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
+	Latency: 0, Cache Line Size: 64 bytes
+	Interrupt: pin A routed to IRQ 11
+	Region 0: Memory at 50000000 (64-bit, prefetchable) [size=16M]
+	Region 2: Memory at 53100000 (64-bit, non-prefetchable) [size=1M]
+	Expansion ROM at <ignored> [disabled]
+	Capabilities: [44] MSI: Mask- 64bit+ Count=1/1 Enable-
+		Address: 0000000000000000  Data: 0000
+	Capabilities: [54] Power Management version 3
+		Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
+		Status: D0 PME-Enable- DSel=0 DScale=1 PME-
+	Capabilities: [5c] Express (v1) Endpoint, MSI 00
+		DevCap:	MaxPayload 4096 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
+			ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
+		DevCtl:	Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
+			RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
+			MaxPayload 128 bytes, MaxReadReq 512 bytes
+		DevSta:	CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
+		LnkCap:	Port #0, Speed 2.5GT/s, Width x8, ASPM L0s, Latency L0 unlimited, L1 unlimited
+			ClockPM- Surprise- LLActRep- BwNot-
+		LnkCtl:	ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk-
+			ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
+		LnkSta:	Speed 2.5GT/s, Width x8, TrErr- Train- SlotClk- DLActive- BWMgmt- ABWMgmt-
+	Capabilities: [88] Vendor Specific Information <?>
+	Capabilities: [d0] MSI-X: Enable- Mask- TabSize=128
+		Vector table: BAR=2 offset=000f0000
+		PBA: BAR=2 offset=000f9000
+	Capabilities: [100] Advanced Error Reporting
+		UESta:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
+		UEMsk:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
+		UESvrt:	DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
+		CESta:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
+		CEMsk:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
+		AERCap:	First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
+	Capabilities: [1a8] Device Serial Number 00-60-dd-ff-ff-47-15-13
+	Capabilities: [1c4] Address Translation Service (ATS)
+		ATSCap:	Invalidate Queue Depth: 00
+		ATSCtl:	Enable-, Smallest Translation Unit: 00
+00: c1 14 08 00 06 00 10 00 00 00 00 02 10 00 00 00
+10: 0c 00 00 50 00 00 00 00 04 00 10 53 00 00 00 00
+20: 00 00 00 00 00 00 00 00 00 00 00 00 c1 14 09 00
+30: 00 00 f8 ff 44 00 00 00 00 00 00 00 0b 01 00 00
+40: 00 00 00 00 05 54 80 00 00 00 00 00 00 00 00 00
+50: 00 00 00 00 01 5c 03 00 00 20 00 64 10 88 01 00
+60: 05 80 00 00 10 28 00 00 81 f4 03 00 00 00 81 00
+70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+80: 1e 00 00 00 00 00 00 00 09 d0 20 00 00 00 00 00
+90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d0: 11 00 7f 00 02 00 0f 00 02 90 0f 00 00 00 00 00
+e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+100: 01 00 81 1a 00 00 00 00 00 00 00 00 10 20 06 00
+110: 00 00 00 00 00 20 00 00 a0 00 00 00 00 00 00 00
+120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1a0: 00 00 00 00 00 00 00 00 03 00 41 1c 00 60 dd ff
+1b0: ff 47 15 13 00 00 00 00 00 00 00 00 00 00 00 00
+1c0: 00 00 00 00 0f 00 01 00 00 00 00 00 00 00 00 00
+1d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+1f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+2f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+4f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+540: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+5f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+610: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+620: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+650: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+6a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+6b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+6c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+6d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+6e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+6f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+720: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+7f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+870: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+8f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+950: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+9f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+a90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+aa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ab0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ac0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ad0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ae0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+af0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+b90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ba0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+be0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+bf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+c90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ca0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ce0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+cf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+d90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+da0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+db0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+dc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+dd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+de0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+df0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+e10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+e20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+e30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+e40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+e50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+e60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+e70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+e90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ea0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+eb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ec0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ed0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ee0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ef0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+f10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+f20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+f30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+f40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+f50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+f60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+f70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
diff -ruN pciutils-3.0.3/tests/cap-pcie-1 pciutils-3.1.0/tests/cap-pcie-1
--- pciutils-3.0.3/tests/cap-pcie-1	2008-11-09 20:38:37.000000000 +0100
+++ pciutils-3.1.0/tests/cap-pcie-1	2008-12-30 17:11:48.000000000 +0100
@@ -1,68 +1,72 @@
-00:01.0 Class 0604: Device 8086:3408 (rev 10)
-	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx+
+00:01.0 PCI bridge: Intel Corporation QuickPath Architecture I/O Hub PCI Express Root Port 1 (rev 12) (prog-if 00 [Normal decode])
+	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
 	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
-	Latency: 0
+	Latency: 0, Cache Line Size: 64 bytes
 	Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
-	I/O behind bridge: 0000f000-00000fff
-	Memory behind bridge: fff00000-000fffff
-	Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff
+	I/O behind bridge: 00001000-00001fff
+	Memory behind bridge: e0000000-e09fffff
+	Prefetchable memory behind bridge: 00000000c7800000-00000000c7ffffff
 	Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
 	BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
 		PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
-	Capabilities: [40] Subsystem: Device 8086:0000
-	Capabilities: [60] MSI: Mask+ 64bit- Count=1/2 Enable+
-		Address: fee00000  Data: 40b0
-		Masking: 00000003  Pending: 00000000
-	Capabilities: [90] Express (v2) Root Port (Slot-), MSI 00
+	Capabilities: [40] Subsystem: Intel Corporation Device 4f53
+	Capabilities: [60] MSI: Mask+ 64bit- Count=1/2 Enable-
+		Address: 00000020  Data: 0000
+		Masking: 00000000  Pending: 00000000
+	Capabilities: [90] Express (v2) Root Port (Slot+), MSI 00
 		DevCap:	MaxPayload 256 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
 			ExtTag+ RBE+ FLReset-
 		DevCtl:	Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
 			RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
-			MaxPayload 128 bytes, MaxReadReq 128 bytes
+			MaxPayload 256 bytes, MaxReadReq 128 bytes
 		DevSta:	CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
-		LnkCap:	Port #1, Speed 5GT/s, Width x4, ASPM unknown, Latency L0 <512ns, L1 <4us
+		LnkCap:	Port #1, Speed 5GT/s, Width x4, ASPM L0s L1, Latency L0 <512ns, L1 <4us
 			ClockPM- Suprise+ LLActRep+ BwNot+
-		LnkCtl:	ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+
+		LnkCtl:	ASPM L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
 			ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
-		LnkSta:	Speed 2.5GT/s, Width x0, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
-		RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible+
+		LnkSta:	Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive+ BWMgmt+ ABWMgmt-
+		SltCap:	AttnBtn+ PwrCtrl+ MRL+ AttnInd+ PwrInd+ HotPlug- Surpise-
+			Slot # 40, PowerLimit 0.000000; Interlock+ NoCompl-
+		SltCtl:	Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
+			Control: AttnInd Off, PwrInd Off, Power+ Interlock-
+		SltSta:	Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
+			Changed: MRL- PresDet+ LinkState+
+		RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible-
 		RootCap: CRSVisible-
 		RootSta: PME ReqID 0000, PMEStatus- PMEPending-
 		DevCap2: Completion Timeout: Range BCD, TimeoutDis+ ARIFwd+
 		DevCtl2: Completion Timeout: 260ms to 900ms, TimeoutDis+ ARIFwd+
-		LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-, Selectable De-emphasis: -3.5dB
+		LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance+ SpeedDis-, Selectable De-emphasis: -6dB
 			 Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
 			 Compliance De-emphasis: -6dB
-		LnkSta2: Current De-emphasis Level: -3.5dB
+		LnkSta2: Current De-emphasis Level: -6dB
 	Capabilities: [e0] Power Management version 3
 		Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 		Status: D0 PME-Enable- DSel=0 DScale=0 PME-
 	Capabilities: [100] Advanced Error Reporting
-		UESta:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSVoil-
-		UEMsk:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSVoil-
-		UESvrt:	DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSVoil-
+		UESta:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
+		UEMsk:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
+		UESvrt:	DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
 		CESta:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
-		CESta:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
+		CEMsk:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
 		AERCap:	First Error Pointer: 00, GenCap- CGenEn- ChkCap- ChkEn-
 	Capabilities: [150] Access Control Services
 		ACSCap:	SrcValid+ TransBlk+ ReqRedir+ CmpltRedir+ UpstreamFwd+ EgressCtrl- DirectTrans-
 		ACSCtl:	SrcValid- TransBlk- ReqRedir- CmpltRedir- UpstreamFwd- EgressCtrl- DirectTrans-
 	Capabilities: [160] Vendor Specific Information <?>
-	Kernel driver in use: pcieport-driver
-	Kernel modules: shpchp
-00: 86 80 08 34 47 05 10 00 10 00 04 06 00 00 01 00
-10: 00 00 00 00 00 00 00 00 00 01 01 00 f0 00 00 00
-20: f0 ff 00 00 f1 ff 01 00 00 00 00 00 00 00 00 00
+00: 86 80 08 34 47 01 10 00 12 00 04 06 10 00 01 00
+10: 00 00 00 00 00 00 00 00 00 01 01 00 10 10 00 00
+20: 00 e0 90 e0 81 c7 f1 c7 00 00 00 00 00 00 00 00
 30: 00 00 00 00 40 00 00 00 00 00 00 00 0b 01 00 00
-40: 0d 60 00 00 86 80 00 00 00 00 00 00 00 00 00 00
+40: 0d 60 00 00 86 80 53 4f 00 00 00 00 00 00 00 00
 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-60: 05 90 03 01 00 00 e0 fe b0 40 00 00 03 00 00 00
+60: 05 90 02 01 20 00 00 00 00 00 00 00 00 00 00 00
 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-90: 10 e0 42 00 21 80 00 00 00 00 00 00 42 30 39 01
-a0: 40 00 01 10 00 00 00 00 00 00 48 00 10 00 01 00
+90: 10 e0 42 01 21 80 00 00 20 00 00 00 42 3c 39 01
+a0: 42 00 41 70 1f 00 02 02 c0 07 48 01 00 00 01 00
 b0: 00 00 00 00 3e 00 00 00 39 00 00 00 00 00 00 00
-c0: 42 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00
+c0: 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 e0: 01 00 03 c8 00 00 00 00 00 00 00 00 00 00 00 00
 f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
@@ -74,16 +78,16 @@
 150: 0d 00 01 16 1f 00 00 00 03 69 00 00 00 00 00 00
 160: 0b 00 00 00 02 00 c0 00 00 00 00 00 00 00 00 00
 170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-180: 0c 30 18 00 00 00 00 00 00 10 00 20 00 00 00 00
-190: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+180: 00 30 18 00 00 00 00 00 00 10 00 20 00 00 00 00
+190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 1a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 1b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 1c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 1d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 1e0: 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00
 1f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-210: 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+200: 01 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00
+210: 02 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00
 220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff -ruN pciutils-3.0.3/tests/cap-pcie-2 pciutils-3.1.0/tests/cap-pcie-2
--- pciutils-3.0.3/tests/cap-pcie-2	2008-11-09 20:38:37.000000000 +0100
+++ pciutils-3.1.0/tests/cap-pcie-2	2008-12-30 17:11:44.000000000 +0100
@@ -1,17 +1,18 @@
-09:00.0 Class 0200: Device 8086:10c9 (rev 01)
+01:00.0 Ethernet controller: Intel Corporation Device 10c9 (rev 01)
+	Subsystem: Intel Corporation Device a03c
 	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
 	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
 	Latency: 0, Cache Line Size: 64 bytes
 	Interrupt: pin A routed to IRQ 16
-	Region 0: Memory at b1a60000 (32-bit, non-prefetchable) [size=128K]
-	Region 1: Memory at b1a40000 (32-bit, non-prefetchable) [size=128K]
-	Region 2: I/O ports at 2020 [size=32]
-	Region 3: Memory at b1b04000 (32-bit, non-prefetchable) [size=16K]
-	Expansion ROM at f7f00000 [disabled] [size=128K]
+	Region 0: Memory at e0800000 (32-bit, non-prefetchable) [size=128K]
+	Region 1: Memory at e0000000 (32-bit, non-prefetchable) [size=4M]
+	Region 2: I/O ports at 1020 [size=32]
+	Region 3: Memory at e0840000 (32-bit, non-prefetchable) [size=16K]
+	Expansion ROM at c7800000 [disabled] [size=4M]
 	Capabilities: [40] Power Management version 3
 		Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 		Status: D0 PME-Enable- DSel=0 DScale=1 PME-
-	Capabilities: [50] MSI: Mask+ 64bit+ Count=0/1 Enable-
+	Capabilities: [50] MSI: Mask+ 64bit+ Count=1/1 Enable-
 		Address: 0000000000000000  Data: 0000
 		Masking: 00000000  Pending: 00000000
 	Capabilities: [70] MSI-X: Enable+ Mask- TabSize=10
@@ -24,9 +25,9 @@
 			RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+ FLReset-
 			MaxPayload 256 bytes, MaxReadReq 512 bytes
 		DevSta:	CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr+ TransPend-
-		LnkCap:	Port #2, Speed 2.5GT/s, Width x4, ASPM L0s L1, Latency L0 <4us, L1 <64us
+		LnkCap:	Port #0, Speed 2.5GT/s, Width x4, ASPM L0s L1, Latency L0 <4us, L1 <64us
 			ClockPM- Suprise- LLActRep- BwNot-
-		LnkCtl:	ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+
+		LnkCtl:	ASPM L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
 			ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 		LnkSta:	Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
 		DevCap2: Completion Timeout: Range ABCD, TimeoutDis+
@@ -36,38 +37,37 @@
 			 Compliance De-emphasis: -6dB
 		LnkSta2: Current De-emphasis Level: -6dB
 	Capabilities: [100] Advanced Error Reporting
-		UESta:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSVoil-
-		UEMsk:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSVoil-
-		UESvrt:	DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSVoil-
-		CESta:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
+		UESta:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
+		UEMsk:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
+		UESvrt:	DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
 		CESta:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
+		CEMsk:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
 		AERCap:	First Error Pointer: 00, GenCap- CGenEn- ChkCap- ChkEn-
-	Capabilities: [140] Device Serial Number 4c-17-12-ff-ff-21-1b-00
+	Capabilities: [140] Device Serial Number e0-46-2b-ff-ff-21-1b-00
 	Capabilities: [150] Alternative Routing-ID Interpretation (ARI)
 		ARICap:	MFVC- ACS-, Next Function: 1
 		ARICtl:	MFVC- ACS-, Function Group: 0
 	Capabilities: [160] Single Root I/O Virtualization (SR-IOV)
 		IOVCap:	Migration-, Interrupt Message Number: 000
-		IOVCtl:	Enable+ Migration- Interrupt- MSE+ ARIHierarchy+
+		IOVCtl:	Enable+ Migration- Interrupt- MSE+ ARIHierarchy-
 		IOVSta:	Migration-
-		Initial VFs: 8, Total VFs: 8, Number of VFs: 4, Function Dependency Link: 00
-		VF offset: 128, stride: 2, Device ID: 10ca
+		Initial VFs: 8, Total VFs: 8, Number of VFs: 1, Function Dependency Link: 00
+		VF offset: 384, stride: 2, Device ID: 10ca
 		Supported Page Size: 00000553, System Page Size: 00000001
-		VF Migration: offset: 00000000, BIR: 1
+		VF Migration: offset: 00000000, BIR: 0
 	Kernel driver in use: igb
-	Kernel modules: ipmi_si
 00: 86 80 c9 10 07 04 10 00 01 00 00 02 10 00 80 00
-10: 00 00 a6 b1 00 00 a4 b1 21 20 00 00 00 40 b0 b1
-20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-30: 00 00 fe ff 40 00 00 00 00 00 00 00 0b 01 00 00
+10: 00 00 80 e0 00 00 00 e0 21 10 00 00 00 00 84 e0
+20: 00 00 00 00 00 00 00 00 00 00 00 00 86 80 3c a0
+30: 00 00 80 c7 40 00 00 00 00 00 00 00 0b 01 00 00
 40: 01 50 23 c8 00 20 00 1a 00 00 00 00 00 00 00 00
 50: 05 70 80 01 00 00 00 00 00 00 00 00 00 00 00 00
 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 70: 11 a0 09 80 03 00 00 00 03 20 00 00 00 00 00 00
 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-a0: 10 00 02 00 c2 8c 00 10 30 28 19 00 41 6c 03 02
-b0: 40 00 41 10 00 00 00 00 00 00 00 00 00 00 00 00
+a0: 10 00 02 00 c2 8c 00 10 30 28 19 00 41 6c 03 00
+b0: 42 00 41 10 00 00 00 00 00 00 00 00 00 00 00 00
 c0: 00 00 00 00 1f 00 00 00 00 00 00 00 00 00 00 00
 d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 e0: 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
@@ -76,12 +76,12 @@
 110: 00 20 00 00 00 20 00 00 00 00 00 00 00 00 00 00
 120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-140: 03 00 01 15 4c 17 12 ff ff 21 1b 00 00 00 00 00
+140: 03 00 01 15 e0 46 2b ff ff 21 1b 00 00 00 00 00
 150: 0e 00 01 16 00 01 00 00 00 00 00 00 00 00 00 00
-160: 10 00 01 00 00 00 00 00 19 00 00 00 08 00 08 00
-170: 04 00 00 00 80 00 02 00 00 00 ca 10 53 05 00 00
-180: 01 00 00 00 04 00 a8 b1 00 00 00 00 00 00 00 00
-190: 04 00 a9 b1 00 00 00 00 00 00 00 00 00 00 00 00
+160: 10 00 01 00 00 00 00 00 09 00 00 00 08 00 08 00
+170: 01 00 00 00 80 01 02 00 00 00 ca 10 53 05 00 00
+180: 01 00 00 00 04 00 84 d2 00 00 00 00 00 00 00 00
+190: 04 00 86 d2 00 00 00 00 00 00 00 00 00 00 00 00
 1a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 1b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 1c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff -ruN pciutils-3.0.3/win32/config.h pciutils-3.1.0/win32/config.h
--- pciutils-3.0.3/win32/config.h	2008-11-09 21:29:24.000000000 +0100
+++ pciutils-3.1.0/win32/config.h	2009-01-18 23:12:51.000000000 +0100
@@ -3,4 +3,4 @@
 #define PCI_HAVE_PM_INTEL_CONF
 #define PCI_IDS "pci.ids"
 #define PCI_PATH_IDS_DIR "."
-#define PCILIB_VERSION "3.0.3"
+#define PCILIB_VERSION "3.1.0"
