summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <mark.kettenis@xs4all.nl>2011-11-06 17:34:29 +0000
committerMatthieu Herrb <matthieu.herrb@laas.fr>2011-11-19 15:44:43 +0100
commit2601ddd02d608c16b0022fe342e0a3f4bf6cadeb (patch)
tree3106a0206fe3d8ae5b668947cbdc4190f7990105
parente64ee4ee2b23dba147d144aacead3cb61c744854 (diff)
Add VGA Arbiter support for OpenBSD.
Signed-off-by: Matthieu Herrb <matthieu.herrb@laas.fr>
-rw-r--r--src/Makefile.am10
-rw-r--r--src/openbsd_pci.c134
2 files changed, 139 insertions, 5 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 6757a6f..13a7d94 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,38 +25,38 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
AM_CFLAGS = $(CWARNFLAGS) @PCIACCESS_CFLAGS@
lib_LTLIBRARIES = libpciaccess.la
if LINUX
OS_SUPPORT = linux_sysfs.c linux_devmem.c linux_devmem.h
+VGA_ARBITER = common_vgaarb.c
endif
if FREEBSD
OS_SUPPORT = freebsd_pci.c
+VGA_ARBITER = common_vgaarb_stub.c
endif
if NETBSD
OS_SUPPORT = netbsd_pci.c
+VGA_ARBITER = common_vgaarb_stub.c
endif
if OPENBSD
OS_SUPPORT = openbsd_pci.c
+# VGA Arbiter code is included in openbsd_pci.c
endif
if SOLARIS
OS_SUPPORT = solx_devfs.c pci_tools.h
-endif
-
-if LINUX
-VGA_ARBITER = common_vgaarb.c
-else
VGA_ARBITER = common_vgaarb_stub.c
endif
if GNU
OS_SUPPORT = x86_pci.c
+VGA_ARBITER = common_vgaarb_stub.c
endif
libpciaccess_la_SOURCES = common_bridge.c \
common_iterator.c \
common_init.c \
common_interface.c \
diff --git a/src/openbsd_pci.c b/src/openbsd_pci.c
index b5559ad..219aba7 100644
--- a/src/openbsd_pci.c
+++ b/src/openbsd_pci.c
@@ -520,6 +520,140 @@ pci_system_openbsd_create(void)
void
pci_system_openbsd_init_dev_mem(int fd)
{
aperturefd = fd;
}
+
+int
+pci_device_vgaarb_init(void)
+{
+ struct pci_device *dev = pci_sys->vga_target;
+ struct pci_device_iterator *iter;
+ struct pci_id_match vga_match = {
+ PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY,
+ (PCI_CLASS_DISPLAY << 16) | (PCI_SUBCLASS_DISPLAY_VGA << 8),
+ 0x00ffff00
+ };
+ struct pci_vga pv;
+ int err;
+
+ pv.pv_sel.pc_bus = 0;
+ pv.pv_sel.pc_dev = 0;
+ pv.pv_sel.pc_func = 0;
+ err = ioctl(pcifd[0], PCIOCGETVGA, &pv);
+ if (err)
+ return err;
+
+ pci_sys->vga_target = pci_device_find_by_slot(0, pv.pv_sel.pc_bus,
+ pv.pv_sel.pc_dev, pv.pv_sel.pc_func);
+
+ /* Count the number of VGA devices in domain 0. */
+ iter = pci_id_match_iterator_create(&vga_match);
+ if (iter == NULL)
+ return -1;
+ pci_sys->vga_count = 0;
+ while ((dev = pci_device_next(iter)) != NULL) {
+ if (dev->domain == 0)
+ pci_sys->vga_count++;
+ }
+ pci_iterator_destroy(iter);
+
+ return 0;
+}
+
+void
+pci_device_vgaarb_fini(void)
+{
+ struct pci_device *dev;
+ struct pci_vga pv;
+
+ if (pci_sys == NULL)
+ return;
+ dev = pci_sys->vga_target;
+ if (dev == NULL)
+ return;
+
+ pv.pv_sel.pc_bus = dev->bus;
+ pv.pv_sel.pc_dev = dev->dev;
+ pv.pv_sel.pc_func = dev->func;
+ pv.pv_lock = PCI_VGA_UNLOCK;
+ ioctl(pcifd[dev->domain], PCIOCSETVGA, &pv);
+}
+
+int
+pci_device_vgaarb_set_target(struct pci_device *dev)
+{
+ pci_sys->vga_target = dev;
+}
+
+int
+pci_device_vgaarb_lock(void)
+{
+ struct pci_device *dev = pci_sys->vga_target;
+ struct pci_vga pv;
+
+ if (dev == NULL)
+ return -1;
+
+#if 0
+ if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
+ return 0;
+#else
+ if (pci_sys->vga_count == 1)
+ return 0;
+#endif
+
+ pv.pv_sel.pc_bus = dev->bus;
+ pv.pv_sel.pc_dev = dev->dev;
+ pv.pv_sel.pc_func = dev->func;
+ pv.pv_lock = PCI_VGA_LOCK;
+ return ioctl(pcifd[dev->domain], PCIOCSETVGA, &pv);
+}
+
+int
+pci_device_vgaarb_unlock(void)
+{
+ struct pci_device *dev = pci_sys->vga_target;
+ struct pci_vga pv;
+
+ if (dev == NULL)
+ return -1;
+
+#if 0
+ if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
+ return 0;
+#else
+ if (pci_sys->vga_count == 1)
+ return 0;
+#endif
+
+ pv.pv_sel.pc_bus = dev->bus;
+ pv.pv_sel.pc_dev = dev->dev;
+ pv.pv_sel.pc_func = dev->func;
+ pv.pv_lock = PCI_VGA_UNLOCK;
+ return ioctl(pcifd[dev->domain], PCIOCSETVGA, &pv);
+}
+
+int
+pci_device_vgaarb_get_info(struct pci_device *dev, int *vga_count,
+ int *rsrc_decodes)
+{
+ *vga_count = pci_sys->vga_count;
+
+ if (dev)
+ *rsrc_decodes = dev->vgaarb_rsrc;
+
+ return 0;
+}
+
+int
+pci_device_vgaarb_decodes(int rsrc_decodes)
+{
+ struct pci_device *dev = pci_sys->vga_target;
+
+ if (dev == NULL)
+ return -1;
+
+ dev->vgaarb_rsrc = rsrc_decodes;
+ return 0;
+}