1diff -Nur pciutils-3.2.0/lib/Makefile pciutils-3.2.0-darwin/lib/Makefile
2--- pciutils-3.2.0/lib/Makefile	2011-01-07 13:04:28.000000000 -0800
3+++ pciutils-3.2.0-darwin/lib/Makefile	2013-10-31 18:17:24.000000000 -0700
4@@ -42,6 +42,10 @@
5 OBJS += nbsd-libpci
6 endif
7
8+ifdef PCI_HAVE_PM_DARWIN_DEVICE
9+OBJS += darwin-device
10+endif
11+
12 all: $(PCILIB) $(PCILIBPC)
13
14 ifeq ($(SHARED),no)
15diff -Nur pciutils-3.2.0/lib/configure pciutils-3.2.0-darwin/lib/configure
16--- pciutils-3.2.0/lib/configure	2013-04-01 12:47:38.000000000 -0700
17+++ pciutils-3.2.0-darwin/lib/configure	2013-10-31 18:17:24.000000000 -0700
18@@ -100,6 +100,14 @@
19 		echo >>$c '#define PCI_PATH_OBSD_DEVICE "/dev/pci"'
20 		LIBRESOLV=
21 		;;
22+
23+        darwin)
24+	        echo_n " darwin-device"
25+		echo >>$c '#define PCI_HAVE_PM_DARWIN_DEVICE'
26+		echo >>$m 'WITH_LIBS+=-lresolv -framework CoreFoundation -framework IOKit'
27+		echo >>$c '#define PCI_HAVE_64BIT_ADDRESS'
28+		LIBRESOLV=
29+		;;
30 	aix)
31 		echo_n " aix-device"
32 		echo >>$c '#define PCI_HAVE_PM_AIX_DEVICE'
33diff -Nur pciutils-3.2.0/lib/darwin-device.c pciutils-3.2.0-darwin/lib/darwin-device.c
34--- pciutils-3.2.0/lib/darwin-device.c	1969-12-31 16:00:00.000000000 -0800
35+++ pciutils-3.2.0-darwin/lib/darwin-device.c	2013-11-01 13:46:41.000000000 -0700
36@@ -0,0 +1,166 @@
37+/*
38+ */
39+
40+#include <errno.h>
41+#include <fcntl.h>
42+#include <stdio.h>
43+#include <string.h>
44+#include <unistd.h>
45+#include <stdint.h>
46+
47+#include "internal.h"
48+
49+
50+#include <CoreFoundation/CoreFoundation.h>
51+#include <mach/mach_error.h>
52+#include <IOKit/IOKitLib.h>
53+#include <IOKit/IOKitKeys.h>
54+#include <IOKit/pci/IOPCIDevice.h>
55+#include <IOKit/pci/IOPCIPrivate.h>
56+
57+
58+static void
59+darwin_config(struct pci_access *a UNUSED)
60+{
61+}
62+
63+static int
64+darwin_detect(struct pci_access *a)
65+{
66+	io_registry_entry_t    service;
67+	io_connect_t           connect;
68+	kern_return_t          status;
69+
70+	service = IOServiceGetMatchingService(kIOMasterPortDefault,
71+																					IOServiceMatching("IOPCIBridge"));
72+	if (service)
73+	{
74+		status = IOServiceOpen(service, mach_task_self(), kIOPCIDiagnosticsClientType, &connect);
75+		IOObjectRelease(service);
76+	}
77+
78+  if (!service || (kIOReturnSuccess != status))
79+	{
80+		a->warning("Cannot open IOPCIBridge (add boot arg debug=0x144 & run as root)");
81+		return 0;
82+	}
83+  a->debug("...using IOPCIBridge");
84+  a->fd = connect;
85+  return 1;
86+}
87+
88+static void
89+darwin_init(struct pci_access *a UNUSED)
90+{
91+}
92+
93+static void
94+darwin_cleanup(struct pci_access *a UNUSED)
95+{
96+}
97+
98+static int
99+darwin_read(struct pci_dev *d, int pos, byte *buf, int len)
100+{
101+  if (!(len == 1 || len == 2 || len == 4))
102+    return pci_generic_block_read(d, pos, buf, len);
103+
104+    IOPCIDiagnosticsParameters param;
105+    kern_return_t              status;
106+
107+    param.spaceType = kIOPCIConfigSpace;
108+    param.bitWidth  = len * 8;
109+    param.options   = 0;
110+
111+	param.address.pci.offset   = pos;
112+	param.address.pci.function = d->func;
113+	param.address.pci.device   = d->dev;
114+	param.address.pci.bus      = d->bus;
115+	param.address.pci.segment  = d->domain;
116+	param.address.pci.reserved = 0;
117+	param.value                = -1ULL;
118+
119+	size_t outSize = sizeof(param);
120+	status = IOConnectCallStructMethod(d->access->fd, kIOPCIDiagnosticsMethodRead,
121+																					&param, sizeof(param),
122+																					&param, &outSize);
123+  if ((kIOReturnSuccess != status))
124+	{
125+		d->access->error("darwin_read: kIOPCIDiagnosticsMethodRead failed: %s",
126+							mach_error_string(status));
127+	}
128+
129+  switch (len)
130+	{
131+    case 1:
132+      buf[0] = (u8) param.value;
133+      break;
134+    case 2:
135+      ((u16 *) buf)[0] = cpu_to_le16((u16) param.value);
136+      break;
137+    case 4:
138+      ((u32 *) buf)[0] = cpu_to_le32((u32) param.value);
139+      break;
140+	}
141+  return 1;
142+}
143+
144+static int
145+darwin_write(struct pci_dev *d, int pos, byte *buf, int len)
146+{
147+  if (!(len == 1 || len == 2 || len == 4))
148+    return pci_generic_block_write(d, pos, buf, len);
149+
150+    IOPCIDiagnosticsParameters param;
151+    kern_return_t              status;
152+
153+    param.spaceType = kIOPCIConfigSpace;
154+    param.bitWidth  = len * 8;
155+    param.options   = 0;
156+    param.address.pci.offset   = pos;
157+    param.address.pci.function = d->func;
158+    param.address.pci.device   = d->dev;
159+    param.address.pci.bus      = d->bus;
160+    param.address.pci.segment  = d->domain;
161+    param.address.pci.reserved = 0;
162+  switch (len)
163+	{
164+    case 1:
165+      param.value = buf[0];
166+      break;
167+    case 2:
168+      param.value = le16_to_cpu(((u16 *) buf)[0]);
169+      break;
170+    case 4:
171+      param.value = le32_to_cpu(((u32 *) buf)[0]);
172+      break;
173+	}
174+
175+	size_t outSize = 0;
176+	status = IOConnectCallStructMethod(d->access->fd, kIOPCIDiagnosticsMethodWrite,
177+																					&param, sizeof(param),
178+																					NULL, &outSize);
179+  if ((kIOReturnSuccess != status))
180+	{
181+		d->access->error("darwin_read: kIOPCIDiagnosticsMethodWrite failed: %s",
182+							mach_error_string(status));
183+	}
184+
185+  return 1;
186+}
187+
188+struct pci_methods pm_darwin_device = {
189+  "darwin-device",
190+  "Darwin device",
191+  darwin_config,
192+  darwin_detect,
193+  darwin_init,
194+  darwin_cleanup,
195+  pci_generic_scan,
196+  pci_generic_fill_info,
197+  darwin_read,
198+  darwin_write,
199+  NULL,                                 /* read_vpd */
200+  NULL,                                 /* dev_init */
201+  NULL                                  /* dev_cleanup */
202+};
203diff -Nur pciutils-3.2.0/lib/init.c pciutils-3.2.0-darwin/lib/init.c
204--- pciutils-3.2.0/lib/init.c	2011-01-07 13:04:28.000000000 -0800
205+++ pciutils-3.2.0-darwin/lib/init.c	2013-10-31 18:17:24.000000000 -0700
206@@ -57,6 +57,11 @@
207 #else
208   NULL,
209 #endif
210+#ifdef PCI_HAVE_PM_DARWIN_DEVICE
211+  &pm_darwin_device,
212+#else
213+  NULL,
214+#endif
215 };
216
217 void *
218diff -Nur pciutils-3.2.0/lib/internal.h pciutils-3.2.0-darwin/lib/internal.h
219--- pciutils-3.2.0/lib/internal.h	2013-04-01 06:36:18.000000000 -0700
220+++ pciutils-3.2.0-darwin/lib/internal.h	2013-10-31 18:17:24.000000000 -0700
221@@ -69,4 +69,4 @@
222
223 extern struct pci_methods pm_intel_conf1, pm_intel_conf2, pm_linux_proc,
224 	pm_fbsd_device, pm_aix_device, pm_nbsd_libpci, pm_obsd_device,
225-	pm_dump, pm_linux_sysfs;
226+	pm_dump, pm_linux_sysfs, pm_darwin_device;
227diff -Nur pciutils-3.2.0/lib/pci.h pciutils-3.2.0-darwin/lib/pci.h
228--- pciutils-3.2.0/lib/pci.h	2013-04-01 06:35:24.000000000 -0700
229+++ pciutils-3.2.0-darwin/lib/pci.h	2013-10-31 18:17:24.000000000 -0700
230@@ -39,7 +39,8 @@
231   PCI_ACCESS_AIX_DEVICE,		/* /dev/pci0, /dev/bus0, etc. */
232   PCI_ACCESS_NBSD_LIBPCI,		/* NetBSD libpci */
233   PCI_ACCESS_OBSD_DEVICE,		/* OpenBSD /dev/pci */
234-  PCI_ACCESS_DUMP,			/* Dump file */
235+  PCI_ACCESS_DUMP,			    /* Dump file */
236+  PCI_ACCESS_DARWIN,			/* Darwin */
237   PCI_ACCESS_MAX
238 };
239
240