1diff -urN pciutils-2.2.9.orig/lib/access.c pciutils-2.2.9/lib/access.c
2--- pciutils-2.2.9.orig/lib/access.c	2007-02-06 11:59:43.000000000 +0000
3+++ pciutils-2.2.9/lib/access.c	2008-06-30 19:07:09.713187000 +0100
4@@ -57,6 +57,11 @@
5 #else
6   NULL,
7 #endif
8+#ifdef PCI_OS_MINIOS
9+  &pm_minios,
10+#else
11+  NULL,
12+#endif
13 };
14
15 struct pci_access *
16--- pciutils-2.2.9.orig/lib/pci.h	2006-09-09 13:46:06.000000000 +0100
17+++ pciutils-2.2.9/lib/pci.h	2008-06-30 18:56:15.350111000 +0100
18@@ -33,6 +33,7 @@
19   PCI_ACCESS_NBSD_LIBPCI,		/* NetBSD libpci */
20   PCI_ACCESS_OBSD_DEVICE,		/* OpenBSD /dev/pci */
21   PCI_ACCESS_DUMP,			/* Dump file (params: filename) */
22+  PCI_ACCESS_MINIOS,			/* MiniOS */
23   PCI_ACCESS_MAX
24 };
25
26--- pciutils-2.2.9.orig/lib/internal.h	2006-09-09 11:52:47.000000000 +0100
27+++ pciutils-2.2.9/lib/internal.h	2008-07-01 10:46:24.968202000 +0100
28@@ -37,4 +37,4 @@
29
30 extern struct pci_methods pm_intel_conf1, pm_intel_conf2, pm_linux_proc,
31 	pm_fbsd_device, pm_aix_device, pm_nbsd_libpci, pm_obsd_device,
32-	pm_dump, pm_linux_sysfs;
33+	pm_dump, pm_linux_sysfs, pm_minios;
34--- pciutils-2.2.9.orig/lib/Makefile	2007-10-19 13:41:34.000000000 +0100
35+++ pciutils-2.2.9/lib/Makefile	2008-07-01 12:13:14.400525000 +0100
36@@ -46,6 +46,12 @@
37 PCILIB=libpciutils.a
38 endif
39
40+ifdef PCI_OS_MINIOS
41+XEN_ROOT=$(CURDIR)/../../..
42+include $(XEN_ROOT)/Config.mk
43+OBJS += minios.o
44+endif
45+
46 all: $(PCILIB) $(PCILIBPC)
47
48 $(PCILIB): $(OBJS)
49--- pciutils-2.2.9.orig/lib/types.h    2009-07-14 18:18:59.000000000 +0200
50+++ pciutils-2.2.9/lib/types.h 2009-07-14 18:19:16.000000000 +0200
51@@ -20,10 +20,12 @@ typedef DWORD u32;
52 typedef uint8_t u8;
53 typedef uint16_t u16;
54 typedef uint32_t u32;
55+typedef uint64_t u64;
56 #else
57 typedef u_int8_t u8;
58 typedef u_int16_t u16;
59 typedef u_int32_t u32;
60+typedef u_int64_t u64;
61 #endif
62
63 #ifdef PCI_HAVE_64BIT_ADDRESS
64
65--- pciutils-2.2.9.orig/lib/minios.c	1970-01-01 01:00:00.000000000 +0100
66+++ pciutils-2.2.9/lib/minios.c	2008-07-01 12:31:40.554260000 +0100
67@@ -0,0 +1,106 @@
68+/*
69+ *	The PCI Library -- MiniOS PCI frontend access
70+ *
71+ *	Samuel Thibault <samuel.thibault@eu.citrix.com>, 2008
72+ *
73+ *	Can be freely distributed and used under the terms of the GNU GPL.
74+ */
75+
76+#include <os.h>
77+#include <pcifront.h>
78+#include <xenbus.h>
79+#include "internal.h"
80+
81+static int
82+minios_detect(struct pci_access *a)
83+{
84+  return 1;
85+}
86+
87+static void
88+minios_init(struct pci_access *a)
89+{
90+}
91+
92+static void
93+minios_cleanup(struct pci_access *a)
94+{
95+  shutdown_pcifront(NULL);
96+}
97+
98+static void
99+minios_scan(struct pci_access *a)
100+{
101+  void func(unsigned int domain, unsigned int bus, unsigned int slot, unsigned int fun)
102+  {
103+    struct pci_dev *d = pci_alloc_dev(a);
104+
105+    d->domain = domain;
106+    d->bus = bus;
107+    d->dev = slot;
108+    d->func = fun;
109+
110+    pci_link_dev(a, d);
111+  }
112+
113+  pcifront_scan(NULL, func);
114+}
115+
116+static int
117+minios_read(struct pci_dev *d, int pos, byte *buf, int len)
118+{
119+  unsigned int val;
120+  switch (len) {
121+    case 1:
122+      if (pcifront_conf_read(NULL, d->domain, d->bus, d->dev, d->func, pos, len, &val))
123+        return 0;
124+      * buf = val;
125+      return 1;
126+    case 2:
127+      if (pcifront_conf_read(NULL, d->domain, d->bus, d->dev, d->func, pos, len, &val))
128+        return 0;
129+      *(u16 *) buf = cpu_to_le16((u16) val);
130+      return 1;
131+    case 4:
132+      if (pcifront_conf_read(NULL, d->domain, d->bus, d->dev, d->func, pos, len, &val))
133+        return 0;
134+      *(u32 *) buf = cpu_to_le32((u32) val);
135+      return 1;
136+    default:
137+      return pci_generic_block_read(d, pos, buf, len);
138+  }
139+}
140+
141+static int
142+minios_write(struct pci_dev *d, int pos, byte *buf, int len)
143+{
144+  unsigned int val;
145+  switch (len) {
146+    case 1:
147+      val = * buf;
148+      break;
149+    case 2:
150+      val = le16_to_cpu(*(u16 *) buf);
151+      break;
152+    case 4:
153+      val = le32_to_cpu(*(u32 *) buf);
154+      break;
155+    default:
156+      return pci_generic_block_write(d, pos, buf, len);
157+  }
158+  return !pcifront_conf_write(NULL, d->domain, d->bus, d->dev, d->func, pos, len, val);
159+}
160+
161+struct pci_methods pm_minios = {
162+  "MiniOS-device",
163+  NULL,                                 /* config */
164+  minios_detect,
165+  minios_init,
166+  minios_cleanup,
167+  minios_scan,
168+  pci_generic_fill_info,
169+  minios_read,
170+  minios_write,
171+  NULL,                                 /* dev_init */
172+  NULL                                  /* dev_cleanup */
173+};
174--- pciutils-2.2.9/lib/generic.c	2007-02-06 12:00:05.000000000 +0000
175+++ pciutils-2.2.9-mine/lib/generic.c	2008-07-01 19:13:52.289949000 +0100
176@@ -74,6 +74,19 @@
177   pci_generic_scan_bus(a, busmap, 0);
178 }
179
180+static u32 pci_size(u32 base, u32 maxbase, u32 mask)
181+{
182+  u32 size = mask & maxbase;
183+  if (!size)
184+    return 0;
185+  size = (size & ~(size-1)) - 1;
186+
187+  if (base == maxbase && ((base | size) & mask) != mask)
188+    return 0;
189+
190+  return size + 1;
191+}
192+
193 int
194 pci_generic_fill_info(struct pci_dev *d, int flags)
195 {
196@@ -114,23 +127,61 @@
197 	      if (!x || x == (u32) ~0)
198 		continue;
199 	      if ((x & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
200-		d->base_addr[i] = x;
201-	      else
202+                {
203+                  d->base_addr[i] = x & PCI_BASE_ADDRESS_IO_MASK;
204+                  if (flags & PCI_FILL_SIZES)
205+                    {
206+                      u32 size;
207+                      pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, ~0);
208+                      d->size[i] = pci_size(x, pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4), PCI_BASE_ADDRESS_IO_MASK);
209+                      pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, x);
210+                    }
211+                }
212+              else
213 		{
214 		  if ((x & PCI_BASE_ADDRESS_MEM_TYPE_MASK) != PCI_BASE_ADDRESS_MEM_TYPE_64)
215-		    d->base_addr[i] = x;
216+                    {
217+                      d->base_addr[i] = x & PCI_BASE_ADDRESS_MEM_MASK;
218+                      if (flags & PCI_FILL_SIZES)
219+                        {
220+                          u32 size;
221+                          pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, ~0);
222+                          d->size[i] = pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4);
223+                          d->size[i] = pci_size(x, pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4), PCI_BASE_ADDRESS_MEM_MASK);
224+                          pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, x);
225+                        }
226+                    }
227 		  else if (i >= cnt-1)
228 		    a->warning("%04x:%02x:%02x.%d: Invalid 64-bit address seen for BAR %d.", d->domain, d->bus, d->dev, d->func, i);
229 		  else
230 		    {
231 		      u32 y = pci_read_long(d, PCI_BASE_ADDRESS_0 + (++i)*4);
232 #ifdef PCI_HAVE_64BIT_ADDRESS
233-		      d->base_addr[i-1] = x | (((pciaddr_t) y) << 32);
234+		      d->base_addr[i-1] = (x | (((pciaddr_t) y) << 32)) & PCI_BASE_ADDRESS_MEM_MASK;
235+                      if (flags & PCI_FILL_SIZES)
236+                        {
237+                          u32 size;
238+                          pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, ~0);
239+                          pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, ~0);
240+                          d->size[i-1] = pci_size(y, pci_read_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4) |
241+                                         pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4), 0xffffffff );
242+                          pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, x);
243+                          pci_write_long(d, PCI_BASE_ADDRESS_0 + i*4, y);
244+                        }
245 #else
246 		      if (y)
247 			a->warning("%04x:%02x:%02x.%d 64-bit device address ignored.", d->domain, d->bus, d->dev, d->func);
248 		      else
249-			d->base_addr[i-1] = x;
250+                        {
251+                          d->base_addr[i-1] = x & PCI_BASE_ADDRESS_MEM_MASK;
252+                          if (flags & PCI_FILL_SIZES)
253+                            {
254+                              u32 size;
255+                              pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, ~0);
256+                              d->size[i-1] = pci_size(x, pci_read_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4), PCI_BASE_ADDRESS_MEM_MASK);
257+                              pci_write_long(d, PCI_BASE_ADDRESS_0 + (i-1)*4, x);
258+                            }
259+                        }
260 #endif
261 		    }
262 		}
263@@ -154,10 +205,19 @@
264 	{
265 	  u32 u = pci_read_long(d, reg);
266 	  if (u != 0xffffffff)
267-	    d->rom_base_addr = u;
268+            {
269+              d->rom_base_addr = u;
270+              if (flags & PCI_FILL_SIZES)
271+                {
272+                  u32 size;
273+                  pci_write_long(d, reg, ~0);
274+                  d->rom_size = pci_read_long(d, reg);
275+                  pci_write_long(d, reg, u);
276+                }
277+            }
278 	}
279     }
280-  return flags & ~PCI_FILL_SIZES;
281+  return flags;
282 }
283
284 static int
285diff -uNpbE -uNpbEr pciutils-2.2.9.orig/lib/sysdep.h pciutils-2.2.9/lib/sysdep.h
286--- pciutils-2.2.9.orig/lib/sysdep.h	2007-02-06 12:00:18.000000000 +0000
287+++ pciutils-2.2.9/lib/sysdep.h	2009-07-22 16:26:30.000000000 +0100
288@@ -32,6 +32,10 @@ typedef u16 word;
289
290 #else
291
292+#ifdef PCI_OS_MINIOS
293+#include <machine/endian.h>
294+#endif
295+
296 #ifdef PCI_OS_LINUX
297 #include <endian.h>
298 #define BYTE_ORDER __BYTE_ORDER
299