OSDN Git Service

Import libvgaaccess (VGA Arbiter) implementation from C3SL repository:
authorTiago Vignatti <vignatti@freedesktop.org>
Wed, 13 May 2009 20:44:46 +0000 (17:44 -0300)
committerTiago Vignatti <vignatti@freedesktop.org>
Wed, 13 May 2009 20:44:46 +0000 (17:44 -0300)
    http://git.c3sl.ufpr.br/

include/pciaccess.h
src/common_vgaarb.c [new file with mode: 0644]

index 6413ae0..2f0bf9d 100644 (file)
  * 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
@@ -449,4 +474,54 @@ struct pci_pcmcia_bridge_info {
 
 };
 
+
+/**
+ * VGA Arbiter definitions, functions and related.
+ */
+
+typedef int VgaArbRsrcType;
+
+typedef struct {
+    int fd;
+    VgaArbRsrcType rsrc;
+} vga_arb_rec, *vga_arb_ptr;
+
+/* This is a mask that can be OR'ed */
+#define VGA_ARB_RSRC_NONE       0
+#define VGA_ARB_RSRC_LEGACY_IO  1
+#define VGA_ARB_RSRC_LEGACY_MEM 2
+#define VGA_ARB_RSRC_NORMAL_IO  4
+#define VGA_ARB_RSRC_NORMAL_MEM 8
+
+/*
+ * All functions, except vga_arb_trylock(), return 1 on success and 0 if
+ * something went wrong.
+ * vga_arb_trylock returns 1 on success, 0 if the lock failed and -1 if
+ * something went wrong.
+ *
+ * But I really don't think you should be checking the return values. The lib
+ * checks for these errors but they should never happen, and when they happen
+ * it will print error messages at stderr.
+ *
+ * To understand the way these functions work see test/test2lib.c.
+ */
+
+
+int vga_arb_set_target (vga_arb_ptr vgaDev, unsigned int domain,
+                        unsigned int bus, unsigned int dev, unsigned int fn);
+
+int vga_arb_read    (vga_arb_ptr vgaDev);
+
+int vga_arb_lock    (vga_arb_ptr vgaDev);
+
+int vga_arb_trylock (vga_arb_ptr vgaDev);
+
+int vga_arb_unlock  (vga_arb_ptr vgaDev);
+
+int vga_arb_decodes (vga_arb_ptr vgaDev);
+
+int vga_arb_init    (vga_arb_ptr *vgaDev);
+
+void vga_arb_fini   (vga_arb_ptr vgaDev);
+
 #endif /* PCIACCESS_H */
diff --git a/src/common_vgaarb.c b/src/common_vgaarb.c
new file mode 100644 (file)
index 0000000..729998d
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * 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.
+ *
+ */
+
+/* vgaaccess.c */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "vgaaccess.h"
+
+/* ALL messages *should* fit in this buffer */
+#define BUFSIZE 128
+
+#define ARBITER_DEVICE "/dev/vga_arbiter"
+
+/*
+ * Writes the message on the device.
+ *
+ * Returns: 0 if something went wrong
+ *      1 if everything is ok
+ *      2 if the device returned EBUSY (used ONLY by trylock)
+ */
+static int
+vga_arb_write(int fd, char *buf, int len)
+{
+    int ret;
+   
+    /* Just to make sure... */
+    buf[len] = '\0';
+
+    ret = write(fd, buf, len);
+
+    if (ret == -1) {
+    /* Check for EBUSY: the user may have called "trylock" and didn't get
+     * the lock. */
+    if (errno == EBUSY)
+        return 2;
+        perror("[libvgaaccess] write error");
+    return 0;
+    }
+    else if (ret != len) {
+    /* The VGA arbiter implementation shouldn't recive less than one
+     * single message. It also shouldn't recive more. */
+    fprintf(stderr, "[libvgaaccess] write error: "
+            "wrote less than expected!\n");
+    return 0;
+    }
+
+#ifdef DEBUG
+    fprintf(stderr, "[libvgaaccess] successfully wrote: '%s'.\n", buf);
+#endif
+
+    return 1;
+}
+
+/* Convert "integer rsrc" in "string rsrc" */
+static const char *
+rsrc_to_str(VgaArbRsrcType 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";
+}
+
+#ifndef STUB
+int
+vga_arb_read(vga_arb_ptr vgaDev)
+{
+    int ret;
+    char buf[BUFSIZE];
+
+
+    ret = read (vgaDev->fd, buf, BUFSIZE);
+
+    /* Just to make sure... */
+    buf[ret]='\0';
+
+    if (ret == 0) {
+    /* It always has something to be read. */
+    fprintf(stderr, "[libvgaaccess] error: there is nothing to read!\n");
+    return 0;
+    }
+    else if (ret == -1) {
+    perror("[libvgaaccess] read error");
+    return 0;
+    }
+
+#ifdef DEBUG    
+    fprintf(stderr, "[libvgaaccess]: sucessfully read: '%s'.\n", buf);
+#endif
+    return 1;
+}
+
+int
+vga_arb_set_target(vga_arb_ptr vgaDev, unsigned int domain, unsigned int bus,
+               unsigned int dev, unsigned int fn)
+{
+    int len;
+    char buf[BUFSIZE];
+
+    len = snprintf(buf, BUFSIZE, "target PCI:%d:%d:%d.%d",
+                   domain, bus, dev, fn);
+
+    return vga_arb_write(vgaDev->fd, buf, len);
+}
+
+int
+vga_arb_lock(vga_arb_ptr vgaDev)
+{
+    int len;
+    char buf[BUFSIZE];
+
+    len = snprintf(buf, BUFSIZE, "lock %s", rsrc_to_str(vgaDev->rsrc));
+
+    return vga_arb_write(vgaDev->fd, buf, len);
+}
+
+int
+vga_arb_trylock(vga_arb_ptr vgaDev)
+{
+    int len, write_ret;
+    char buf[BUFSIZE];
+
+    len = snprintf(buf, BUFSIZE, "trylock %s", rsrc_to_str(vgaDev->rsrc));
+
+    write_ret = vga_arb_write(vgaDev->fd, buf, len);
+
+    if (write_ret == 0)
+        return -1;
+    else if (write_ret == 1)
+        return 1;
+    else
+        /* write_ret == 2 and the lock failed */
+        return 0;
+}
+
+int
+vga_arb_unlock(vga_arb_ptr vgaDev)
+{
+    int len;
+    char buf[BUFSIZE];
+
+    len = snprintf(buf, BUFSIZE, "unlock %s", rsrc_to_str(vgaDev->rsrc));
+
+    return vga_arb_write(vgaDev->fd, buf, len);
+}
+
+int
+vga_arb_decodes(vga_arb_ptr vgaDev)
+{
+    int len;
+    char buf[BUFSIZE];
+
+    len = snprintf(buf, BUFSIZE, "decodes %s", rsrc_to_str(vgaDev->rsrc));
+
+    return vga_arb_write(vgaDev->fd, buf, len);
+}
+
+int
+vga_arb_init(vga_arb_ptr *vgaDev)
+{
+    *vgaDev = malloc (sizeof(vga_arb_ptr *));
+    if (vgaDev == NULL) {
+    fprintf(stderr, "[libvgaaccess] malloc: couldn't allocate memory!\n");
+    return 0;
+    }
+
+    (*vgaDev)->rsrc = 0;
+
+    if (((*vgaDev)->fd = open (ARBITER_DEVICE, O_RDWR)) < 0) {
+        perror("[libvgaaccess] device open failed");
+        return 0;
+    }
+
+    return (*vgaDev)->fd;
+}
+
+void
+vga_arb_fini(vga_arb_ptr vgaDev)
+{
+    if (close(vgaDev->fd) == -1)
+    perror("[libvgaaccess] device close failed");
+}
+
+#else /* STUB */
+int
+vga_arb_read(vga_arb_ptr vgaDev)
+{
+    return 1;
+}
+
+int
+vga_arb_set_target(vga_arb_ptr vgaDev, unsigned int domain, unsigned int bus,
+                   unsigned int dev,    unsigned int fn)
+{
+    return 1;
+}
+
+int
+vga_arb_lock(vga_arb_ptr vgaDev)
+{
+    return 1;
+}
+
+int
+vga_arb_trylock(vga_arb_ptr vgaDev)
+{
+    return 1;
+}
+
+int
+vga_arb_unlock(vga_arb_ptr vgaDev)
+{
+    return 1;
+}
+
+int
+vga_arb_decodes(vga_arb_ptr vgaDev)
+{
+    return 1;
+}
+
+int
+vga_arb_init(vga_arb_ptr *vgaDev)
+{
+    fprintf(stderr, "[libvgaaccess] YOU'RE USING THE STUB FUNCTIONS!\n");
+    return 1;
+}
+
+void
+vga_arb_fini(vga_arb_ptr vgaDev)
+{
+}
+#endif /* END OF STUB */