diff options
-rw-r--r-- | include/pciaccess.h | 5 | ||||
-rw-r--r-- | src/common_vgaarb.c | 61 | ||||
-rw-r--r-- | src/pciaccess_private.h | 1 |
3 files changed, 53 insertions, 14 deletions
diff --git a/include/pciaccess.h b/include/pciaccess.h index fa6787f..2230b27 100644 --- a/include/pciaccess.h +++ b/include/pciaccess.h @@ -380,7 +380,6 @@ struct pci_device { * 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; }; @@ -493,8 +492,8 @@ struct pci_pcmcia_bridge_info { #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_init (void); +void pci_device_vgaarb_fini (void); 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); diff --git a/src/common_vgaarb.c b/src/common_vgaarb.c index f75257e..232d4ac 100644 --- a/src/common_vgaarb.c +++ b/src/common_vgaarb.c @@ -26,20 +26,20 @@ */ #include <stdio.h> +#include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include "pciaccess.h" +#include "pciaccess_private.h" #define BUFSIZE 32 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) { + if ((pci_sys->vgaarb_fd = open ("/dev/vga_arbiter", O_RDWR)) < 0) { fprintf(stderr, "device open failed"); return errno; } @@ -48,9 +48,9 @@ pci_device_vgaarb_init(struct pci_device *dev) } void -pci_device_vgaarb_fini(struct pci_device *dev) +pci_device_vgaarb_fini(void) { - if (close(dev->vgaarb_fd) != 0) + if (close(pci_sys->vgaarb_fd) != 0) fprintf(stderr, "device close failed"); } @@ -96,6 +96,35 @@ vgaarb_write(int fd, char *buf, int len) return 0; } +static int +parse_string_to_decodes_rsrc(char *input) +{ + char *tok; + + 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) { @@ -116,11 +145,21 @@ pci_device_vgaarb_set_target(struct pci_device *dev) { int len; char buf[BUFSIZE]; + int ret; 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; + + dev->vgaarb_rsrc = parse_string_to_decodes_rsrc(buf); + return 0; } int @@ -131,7 +170,7 @@ pci_device_vgaarb_decodes(struct pci_device *dev) len = snprintf(buf, BUFSIZE, "decodes %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 @@ -142,7 +181,7 @@ pci_device_vgaarb_lock(struct pci_device *dev) 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 @@ -153,7 +192,7 @@ pci_device_vgaarb_trylock(struct pci_device *dev) 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 @@ -164,5 +203,5 @@ pci_device_vgaarb_unlock(struct pci_device *dev) 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); } diff --git a/src/pciaccess_private.h b/src/pciaccess_private.h index 769e181..220673d 100644 --- a/src/pciaccess_private.h +++ b/src/pciaccess_private.h @@ -131,6 +131,7 @@ struct pci_system { #ifdef HAVE_MTRR int mtrr_fd; #endif + int vgaarb_fd; }; extern struct pci_system * pci_sys; |