*/
#include <stdio.h>
+#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
+#include <stdlib.h>
+#include <limits.h>
#include "pciaccess.h"
+#include "pciaccess_private.h"
-#define BUFSIZE 32
+#define BUFSIZE 64
int
-pci_device_vgaarb_init(struct pci_device *dev)
+pci_device_vgaarb_init(void)
{
- dev->vgaarb_rsrc = VGA_ARB_RSRC_NONE;
-
- if ((dev->vgaarb_fd = open ("/dev/vga_arbiter", O_RDWR)) < 0) {
- fprintf(stderr, "device open failed");
+ if ((pci_sys->vgaarb_fd = open ("/dev/vga_arbiter", O_RDWR)) < 0) {
return errno;
}
}
void
-pci_device_vgaarb_fini(struct pci_device *dev)
+pci_device_vgaarb_fini(void)
{
- if (close(dev->vgaarb_fd) != 0)
- fprintf(stderr, "device close failed");
+ close(pci_sys->vgaarb_fd);
}
/**
if (errno == EBUSY)
return 2;
+#ifdef DEBUG
fprintf(stderr, "write error");
+#endif
return 1;
}
else if (ret != len) {
/* it's need to receive the exactly amount required. */
+#ifdef DEBUG
fprintf(stderr, "write error: wrote different than expected\n");
+#endif
return 1;
}
return 0;
}
+static int
+parse_string_to_decodes_rsrc(char *input, int *vga_count)
+{
+ char *tok;
+ char count[16];
+
+ strncpy(count, input, 10);
+ count[11] = 0;
+
+ tok = strtok(count,":");
+ if (!tok)
+ goto fail;
+ tok = strtok(NULL, "");
+ if (!tok)
+ goto fail;
+
+ *vga_count = strtoul(tok, NULL, 10);
+ if (*vga_count == LONG_MAX)
+ goto fail;
+
+#ifdef DEBUG
+ fprintf(stderr,"vga count is %d\n", *vga_count);
+#endif
+
+ tok = strtok(input, ",");
+ if (!tok)
+ goto fail;
+
+ tok = strtok(NULL, ",");
+ if (!tok)
+ goto fail;
+ tok = strtok(tok, "=");
+ if (!tok)
+ goto fail;
+ tok = strtok(NULL, "=");
+ if (!tok)
+ goto fail;
+
+ if (!strncmp(tok, "io+mem", 6))
+ return VGA_ARB_RSRC_LEGACY_IO | VGA_ARB_RSRC_LEGACY_MEM;
+ if (!strncmp(tok, "io", 2))
+ return VGA_ARB_RSRC_LEGACY_IO;
+ if (!strncmp(tok, "mem", 3))
+ return VGA_ARB_RSRC_LEGACY_MEM;
+fail:
+ return VGA_ARB_RSRC_NONE;
+}
+
static const char *
rsrc_to_str(int iostate)
{
{
int len;
char buf[BUFSIZE];
+ int ret;
+ int rsrc;
- len = snprintf(buf, BUFSIZE, "target PCI:%d:%d:%d.%d",
- dev->domain, dev->bus, dev->dev, dev->func);
+ if (!dev)
+ len = snprintf(buf, BUFSIZE, "default");
+ else
+ 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);
+ ret = vgaarb_write(pci_sys->vgaarb_fd, buf, len);
+ if (ret)
+ return ret;
+
+ ret = read(pci_sys->vgaarb_fd, buf, BUFSIZE);
+ if (ret <= 0)
+ return -1;
+
+ rsrc = parse_string_to_decodes_rsrc(buf, &pci_sys->vga_count);
+ if (dev)
+ dev->vgaarb_rsrc = rsrc;
+ return 0;
}
int
-pci_device_vgaarb_decodes(struct pci_device *dev)
+pci_device_vgaarb_decodes(struct pci_device *dev, int new_vgaarb_rsrc)
{
int len;
char buf[BUFSIZE];
+ int ret;
- len = snprintf(buf, BUFSIZE, "decodes %s", rsrc_to_str(dev->vgaarb_rsrc));
+ if (dev->vgaarb_rsrc == new_vgaarb_rsrc)
+ return 0;
- return vgaarb_write(dev->vgaarb_fd, buf, len);
+ len = snprintf(buf, BUFSIZE, "decodes %s", rsrc_to_str(dev->vgaarb_rsrc));
+ ret = vgaarb_write(pci_sys->vgaarb_fd, buf, len);
+ if (ret == 0)
+ dev->vgaarb_rsrc = new_vgaarb_rsrc;
+ return ret;
}
int
int len;
char buf[BUFSIZE];
+ if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
+ return 0;
+
len = snprintf(buf, BUFSIZE, "lock %s", rsrc_to_str(dev->vgaarb_rsrc));
- return vgaarb_write(dev->vgaarb_fd, buf, len);
+ return vgaarb_write(pci_sys->vgaarb_fd, buf, len);
}
int
int len;
char buf[BUFSIZE];
+ if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
+ return 0;
+
len = snprintf(buf, BUFSIZE, "trylock %s", rsrc_to_str(dev->vgaarb_rsrc));
- return vgaarb_write(dev->vgaarb_fd, buf, len);
+ return vgaarb_write(pci_sys->vgaarb_fd, buf, len);
}
int
int len;
char buf[BUFSIZE];
+ if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
+ return 0;
+
len = snprintf(buf, BUFSIZE, "unlock %s", rsrc_to_str(dev->vgaarb_rsrc));
- return vgaarb_write(dev->vgaarb_fd, buf, len);
+ return vgaarb_write(pci_sys->vgaarb_fd, buf, len);
}