[RFC] Xorg VGA arbitration (again!) (libpciaccess-vgaarbiter.diff)
Tiago Vignatti
vignatti at freedesktop.org
Thu May 14 16:59:47 PDT 2009
diff --git a/include/pciaccess.h b/include/pciaccess.h
index 6413ae0..fa6787f 100644
--- a/include/pciaccess.h
+++ b/include/pciaccess.h
@@ -21,6 +21,31 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
+/*
+ * Copyright (c) 2007 Paulo R. Zanoni, Tiago Vignatti
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
/**
* \file pciaccess.h
@@ -350,6 +375,12 @@ struct pci_device {
* the \c pci_device structure.
*/
intptr_t user_data;
+
+ /**
+ * Used by the VGA arbiter. Type of resource decoded by the device and
+ * the file descriptor (/dev/vga_arbiter). */
+ int vgaarb_rsrc;
+ int vgaarb_fd;
};
@@ -449,4 +480,25 @@ struct pci_pcmcia_bridge_info {
};
+
+/**
+ * VGA Arbiter definitions, functions and related.
+ */
+
+/* Legacy VGA regions */
+#define VGA_ARB_RSRC_NONE 0x00
+#define VGA_ARB_RSRC_LEGACY_IO 0x01
+#define VGA_ARB_RSRC_LEGACY_MEM 0x02
+/* Non-legacy access */
+#define VGA_ARB_RSRC_NORMAL_IO 0x04
+#define VGA_ARB_RSRC_NORMAL_MEM 0x08
+
+int pci_device_vgaarb_init (struct pci_device *dev);
+void pci_device_vgaarb_fini (struct pci_device *dev);
+int pci_device_vgaarb_set_target (struct pci_device *dev);
+int pci_device_vgaarb_decodes (struct pci_device *dev);
+int pci_device_vgaarb_lock (struct pci_device *dev);
+int pci_device_vgaarb_trylock (struct pci_device *dev);
+int pci_device_vgaarb_unlock (struct pci_device *dev);
+
#endif /* PCIACCESS_H */
diff --git a/src/Makefile.am b/src/Makefile.am
index 14f2e48..0de6894 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -45,6 +45,12 @@ 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
+
libpciaccess_la_SOURCES = common_bridge.c \
common_iterator.c \
common_init.c \
@@ -53,6 +59,7 @@ libpciaccess_la_SOURCES = common_bridge.c \
common_device_name.c \
common_map.c \
pciaccess_private.h \
+ $(VGA_ARBITER) \
$(OS_SUPPORT)
INCLUDES = -I$(top_srcdir)/include
diff --git a/src/common_vgaarb.c b/src/common_vgaarb.c
new file mode 100644
index 0000000..f75257e
--- /dev/null
+++ b/src/common_vgaarb.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2007 Paulo R. Zanoni, Tiago Vignatti
+ * 2009 Tiago Vignatti
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "pciaccess.h"
+
+#define BUFSIZE 32
+
+int
+pci_device_vgaarb_init(struct pci_device *dev)
+{
+ dev->vgaarb_rsrc = VGA_ARB_RSRC_NONE;
+
+ if ((dev->vgaarb_fd = open ("/dev/vga_arbiter", O_RDWR)) < 0) {
+ fprintf(stderr, "device open failed");
+ return errno;
+ }
+
+ return 0;
+}
+
+void
+pci_device_vgaarb_fini(struct pci_device *dev)
+{
+ if (close(dev->vgaarb_fd) != 0)
+ fprintf(stderr, "device close failed");
+}
+
+/**
+ * Writes message on vga device. The messages are defined by the kernel
+ * implementation.
+ *
+ * \param fd vga arbiter device.
+ * \param buf message itself.
+ * \param len message length.
+ *
+ * \return
+ * Zero on success, 1 if something gets wrong and 2 if fd is busy (only for
+ * 'trylock')
+ */
+static int
+vgaarb_write(int fd, char *buf, int len)
+{
+ int ret;
+
+
+ buf[len] = '\0';
+
+ ret = write(fd, buf, len);
+ if (ret == -1) {
+ /* the user may have called "trylock" and didn't get the lock */
+ if (errno == EBUSY)
+ return 2;
+
+ fprintf(stderr, "write error");
+ return 1;
+ }
+ else if (ret != len) {
+ /* it's need to receive the exactly amount required. */
+ fprintf(stderr, "write error: wrote different than expected\n");
+ return 1;
+ }
+
+#ifdef DEBUG
+ fprintf(stderr, "%s: successfully wrote: '%s'\n", __FUNCTION__, buf);
+#endif
+
+ return 0;
+}
+
+static const char *
+rsrc_to_str(int iostate)
+{
+ switch (iostate) {
+ case VGA_ARB_RSRC_LEGACY_IO | VGA_ARB_RSRC_LEGACY_MEM:
+ return "io+mem";
+ case VGA_ARB_RSRC_LEGACY_IO:
+ return "io";
+ case VGA_ARB_RSRC_LEGACY_MEM:
+ return "mem";
+ }
+
+ return "none";
+}
+
+int
+pci_device_vgaarb_set_target(struct pci_device *dev)
+{
+ int len;
+ char buf[BUFSIZE];
+
+ len = snprintf(buf, BUFSIZE, "target PCI:%d:%d:%d.%d",
+ dev->domain, dev->bus, dev->dev, dev->func);
+
+ return vgaarb_write(dev->vgaarb_fd, buf, len);
+}
+
+int
+pci_device_vgaarb_decodes(struct pci_device *dev)
+{
+ int len;
+ char buf[BUFSIZE];
+
+ len = snprintf(buf, BUFSIZE, "decodes %s", rsrc_to_str(dev->vgaarb_rsrc));
+
+ return vgaarb_write(dev->vgaarb_fd, buf, len);
+}
+
+int
+pci_device_vgaarb_lock(struct pci_device *dev)
+{
+ int len;
+ char buf[BUFSIZE];
+
+ len = snprintf(buf, BUFSIZE, "lock %s", rsrc_to_str(dev->vgaarb_rsrc));
+
+ return vgaarb_write(dev->vgaarb_fd, buf, len);
+}
+
+int
+pci_device_vgaarb_trylock(struct pci_device *dev)
+{
+ int len;
+ char buf[BUFSIZE];
+
+ len = snprintf(buf, BUFSIZE, "trylock %s", rsrc_to_str(dev->vgaarb_rsrc));
+
+ return vgaarb_write(dev->vgaarb_fd, buf, len);
+}
+
+int
+pci_device_vgaarb_unlock(struct pci_device *dev)
+{
+ int len;
+ char buf[BUFSIZE];
+
+ len = snprintf(buf, BUFSIZE, "unlock %s", rsrc_to_str(dev->vgaarb_rsrc));
+
+ return vgaarb_write(dev->vgaarb_fd, buf, len);
+}
diff --git a/src/common_vgaarb_stub.c b/src/common_vgaarb_stub.c
new file mode 100644
index 0000000..5fc5dfe
--- /dev/null
+++ b/src/common_vgaarb_stub.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2009 Tiago Vignatti
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include "pciaccess.h"
+
+int
+pci_device_vgaarb_init(struct pci_device *dev)
+{
+#ifdef DEBUG
+ fprintf(stderr, "%s: You're using VGA arbiter stub functions!\n",
+ __FUNCTION__);
+#endif
+ return 0;
+}
+
+void
+pci_device_vgaarb_fini(struct pci_device *dev)
+{
+}
+
+int
+pci_device_vgaarb_set_target(struct pci_device *dev)
+{
+ return 0;
+}
+
+int
+pci_device_vgaarb_decodes(struct pci_device *dev)
+{
+ return 0;
+}
+
+int
+pci_device_vgaarb_lock(struct pci_device *dev)
+{
+ return 0;
+}
+
+int
+pci_device_vgaarb_trylock(struct pci_device *dev)
+{
+ return 0;
+}
+
+int
+pci_device_vgaarb_unlock(struct pci_device *dev)
+{
+ return 0;
+}
More information about the xorg-devel
mailing list