diff options
author | Mark Kettenis <mark.kettenis@xs4all.nl> | 2011-11-06 17:34:29 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu.herrb@laas.fr> | 2011-11-19 15:44:43 +0100 |
commit | 2601ddd02d608c16b0022fe342e0a3f4bf6cadeb (patch) | |
tree | 3106a0206fe3d8ae5b668947cbdc4190f7990105 | |
parent | e64ee4ee2b23dba147d144aacead3cb61c744854 (diff) |
Add VGA Arbiter support for OpenBSD.
Signed-off-by: Matthieu Herrb <matthieu.herrb@laas.fr>
-rw-r--r-- | src/Makefile.am | 10 | ||||
-rw-r--r-- | src/openbsd_pci.c | 134 |
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 @@ -28,32 +28,32 @@ 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 \ 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 @@ -523,3 +523,137 @@ 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; +} |