diff -urN pciutils-2.2.9.orig/lib/access.c pciutils-2.2.9/lib/access.c
--- pciutils-2.2.9.orig/lib/access.c	2007-02-06 11:59:43.000000000 +0000
+++ pciutils-2.2.9/lib/access.c	2008-06-30 19:07:09.713187000 +0100
@@ -57,6 +57,11 @@
 #else
   NULL,
 #endif
+#ifdef PCI_OS_MINIOS
+  &pm_minios,
+#else
+  NULL,
+#endif
 };
 
 struct pci_access *
--- pciutils-2.2.9.orig/lib/pci.h	2006-09-09 13:46:06.000000000 +0100
+++ pciutils-2.2.9/lib/pci.h	2008-06-30 18:56:15.350111000 +0100
@@ -33,6 +33,7 @@
   PCI_ACCESS_NBSD_LIBPCI,		/* NetBSD libpci */
   PCI_ACCESS_OBSD_DEVICE,		/* OpenBSD /dev/pci */
   PCI_ACCESS_DUMP,			/* Dump file (params: filename) */
+  PCI_ACCESS_MINIOS,			/* MiniOS */
   PCI_ACCESS_MAX
 };
 
--- pciutils-2.2.9.orig/lib/internal.h	2006-09-09 11:52:47.000000000 +0100
+++ pciutils-2.2.9/lib/internal.h	2008-07-01 10:46:24.968202000 +0100
@@ -37,4 +37,4 @@
 
 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;
+	pm_dump, pm_linux_sysfs, pm_minios;
--- pciutils-2.2.9.orig/lib/Makefile	2007-10-19 13:41:34.000000000 +0100
+++ pciutils-2.2.9/lib/Makefile	2008-07-01 12:13:14.400525000 +0100
@@ -46,6 +46,12 @@
 PCILIB=libpciutils.a
 endif
 
+ifdef PCI_OS_MINIOS
+XEN_ROOT=$(CURDIR)/../../..
+include $(XEN_ROOT)/Config.mk
+OBJS += minios.o
+endif
+
 all: $(PCILIB) $(PCILIBPC)
 
 $(PCILIB): $(OBJS)
--- pciutils-2.2.9.orig/lib/types.h    2009-07-14 18:18:59.000000000 +0200
+++ pciutils-2.2.9/lib/types.h 2009-07-14 18:19:16.000000000 +0200
@@ -20,10 +20,12 @@ typedef DWORD u32;
 typedef uint8_t u8;
 typedef uint16_t u16;
 typedef uint32_t u32;
+typedef uint64_t u64;
 #else
 typedef u_int8_t u8;
 typedef u_int16_t u16;
 typedef u_int32_t u32;
+typedef u_int64_t u64;
 #endif

 #ifdef PCI_HAVE_64BIT_ADDRESS
 
--- pciutils-2.2.9.orig/lib/minios.c	1970-01-01 01:00:00.000000000 +0100
+++ pciutils-2.2.9/lib/minios.c	2008-07-01 12:31:40.554260000 +0100
@@ -0,0 +1,106 @@
+/*
+ *	The PCI Library -- MiniOS PCI frontend access
+ *
+ *	Samuel Thibault <samuel.thibault@eu.citrix.com>, 2008
+ *
+ *	Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <os.h>
+#include <pcifront.h>
+#include <xenbus.h>
+#include "internal.h"
+
+static int
+minios_detect(struct pci_access *a)
+{
+  return 1;
+}
+
+static void
+minios_init(struct pci_access *a)
+{
+}
+
+static void
+minios_cleanup(struct pci_access *a)
+{
+  shutdown_pcifront(NULL);
+}
+
+static void
+minios_scan(struct pci_access *a)
+{
+  void func(unsigned int domain, unsigned int bus, unsigned int slot, unsigned int fun)
+  {
+    struct pci_dev *d = pci_alloc_dev(a);
+
+    d->domain = domain;
+    d->bus = bus;
+    d->dev = slot;
+    d->func = fun;
+
+    pci_link_dev(a, d);
+  }
+
+  pcifront_scan(NULL, func);
+}
+
+static int
+minios_read(struct pci_dev *d, int pos, byte *buf, int len)
+{
+  unsigned int val;
+  switch (len) {
+    case 1:
+      if (pcifront_conf_read(NULL, d->domain, d->bus, d->dev, d->func, pos, len, &val))
+        return 0;
+      * buf = val;
+      return 1;
+    case 2:
+      if (pcifront_conf_read(NULL, d->domain, d->bus, d->dev, d->func, pos, len, &val))
+        return 0;
+      *(u16 *) buf = cpu_to_le16((u16) val);
+      return 1;
+    case 4:
+      if (pcifront_conf_read(NULL, d->domain, d->bus, d->dev, d->func, pos, len, &val))
+        return 0;
+      *(u32 *) buf = cpu_to_le32((u32) val);
+      return 1;
+    default:
+      return pci_generic_block_read(d, pos, buf, len);
+  }
+}
+
+static int
+minios_write(struct pci_dev *d, int pos, byte *buf, int len)
+{
+  unsigned int val;
+  switch (len) {
+    case 1:
+      val = * buf;
+      break;
+    case 2:
+      val = le16_to_cpu(*(u16 *) buf);
+      break;
+    case 4:
+      val = le32_to_cpu(*(u32 *) buf);
+      break;
+    default:
+      return pci_generic_block_write(d, pos, buf, len);
+  }
+  return !pcifront_conf_write(NULL, d->domain, d->bus, d->dev, d->func, pos, len, val);
+}
+
+struct pci_methods pm_minios = {
+  "MiniOS-device",
+  NULL,                                 /* config */
+  minios_detect,
+  minios_init,
+  minios_cleanup,
+  minios_scan,
+  pci_generic_fill_info,
+  minios_read,
+  minios_write,
+  NULL,                                 /* dev_init */
+  NULL                                  /* dev_cleanup */
+};
--- pciutils-2.2.9/lib/generic.c	2007-02-06 12:00:05.000000000 +0000
+++ pciutils-2.2.9-mine/lib/generic.c	2008-07-01 19:13:52.289949000 +0100
@@ -74,6 +74,19 @@
   pci_generic_scan_bus(a, busmap, 0);
 }
 
+static u32 pci_size(u32 base, u32 maxbase, u32 mask)
+{
+  u32 size = mask & maxbase;
+  if (!size)
+    return 0;
+  size = (size & ~(size-1)) - 1;
+
+  if (base == maxbase && ((base | size) & mask) != mask)
+    return 0;
+
+  return size + 1;
+}
+
 int
 pci_generic_fill_info(struct pci_dev *d, int flags)
 {
@@ -114,23 +127,61 @@
 	      if (!x || x == (u32) ~0)
 		continue;
 	      if ((x & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
-		d->base_addr[i] = x;
-	      else
+                {
+                  d->base_addr[i] = x & PCI_BASE_ADDRESS_IO_MASK;
+                  if (flags & PCI_FILL_SIZES)
+                    {
+                      u32 size;
+                      pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, ~0);
+                      d->size[i] = pci_size(x, pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4), PCI_BASE_ADDRESS_IO_MASK);
+                      pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, x);
+                    }
+                }
+              else
 		{
 		  if ((x & PCI_BASE_ADDRESS_MEM_TYPE_MASK) != PCI_BASE_ADDRESS_MEM_TYPE_64)
-		    d->base_addr[i] = x;
+                    {
+                      d->base_addr[i] = x & PCI_BASE_ADDRESS_MEM_MASK;
+                      if (flags & PCI_FILL_SIZES)
+                        {
+                          u32 size;
+                          pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, ~0);
+                          d->size[i] = pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4);
+                          d->size[i] = pci_size(x, pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4), PCI_BASE_ADDRESS_MEM_MASK);
+                          pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, x);
+                        }
+                    }
 		  else if (i >= cnt-1)
 		    a->warning("%04x:%02x:%02x.%d: Invalid 64-bit address seen for BAR %d.", d->domain, d->bus, d->dev, d->func, i);
 		  else
 		    {
 		      u32 y = pci_read_long(d, PCI_BASE_ADDRESS_0 + (++i)*4);
 #ifdef PCI_HAVE_64BIT_ADDRESS
-		      d->base_addr[i-1] = x | (((pciaddr_t) y) << 32);
+		      d->base_addr[i-1] = (x | (((pciaddr_t) y) << 32)) & PCI_BASE_ADDRESS_MEM_MASK;
+                      if (flags & PCI_FILL_SIZES)
+                        {
+                          u32 size;
+                          pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, ~0);
+                          pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, ~0);
+                          d->size[i-1] = pci_size(y, pci_read_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4) | 
+                                         pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4), 0xffffffff );
+                          pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, x);
+                          pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, y);
+                        }
 #else
 		      if (y)
 			a->warning("%04x:%02x:%02x.%d 64-bit device address ignored.", d->domain, d->bus, d->dev, d->func);
 		      else
-			d->base_addr[i-1] = x;
+                        {
+                          d->base_addr[i-1] = x & PCI_BASE_ADDRESS_MEM_MASK;
+                          if (flags & PCI_FILL_SIZES)
+                            {
+                              u32 size;
+                              pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, ~0);
+                              d->size[i-1] = pci_size(x, pci_read_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4), PCI_BASE_ADDRESS_MEM_MASK);
+                              pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, x);
+                            }
+                        }
 #endif
 		    }
 		}
@@ -154,10 +205,19 @@
 	{
 	  u32 u = pci_read_long(d, reg);
 	  if (u != 0xffffffff)
-	    d->rom_base_addr = u;
+            {
+              d->rom_base_addr = u;
+              if (flags & PCI_FILL_SIZES)
+                {
+                  u32 size;
+                  pci_write_long(d, reg, ~0);
+                  d->rom_size = pci_read_long(d, reg);
+                  pci_write_long(d, reg, u);
+                }
+            }
 	}
     }
-  return flags & ~PCI_FILL_SIZES;
+  return flags;
 }
 
 static int
diff -uNpbE -uNpbEr pciutils-2.2.9.orig/lib/sysdep.h pciutils-2.2.9/lib/sysdep.h
--- pciutils-2.2.9.orig/lib/sysdep.h	2007-02-06 12:00:18.000000000 +0000
+++ pciutils-2.2.9/lib/sysdep.h	2009-07-22 16:26:30.000000000 +0100
@@ -32,6 +32,10 @@ typedef u16 word;
 
 #else
 
+#ifdef PCI_OS_MINIOS
+#include <machine/endian.h>
+#endif
+
 #ifdef PCI_OS_LINUX
 #include <endian.h>
 #define BYTE_ORDER __BYTE_ORDER
