#include <stdlib.h>
#include <limits.h>
+#include "config.h"
#include "pciaccess.h"
#include "pciaccess_private.h"
parse_string_to_decodes_rsrc(char *input, int *vga_count, struct pci_slot_match *match)
{
char *tok;
- char count[16];
+ char *input_sp = NULL, *count_sp, *pci_sp;
+ char tmp[32];
- strncpy(count, input, 10);
- count[11] = 0;
+ tok = strtok_r(input,",",&input_sp);
+ if (!tok)
+ goto fail;
+
+ strncpy(tmp, input, 15);
+ tmp[15] = 0;
- tok = strtok(count,":");
+ tok = strtok_r(tmp,":",&count_sp);
if (!tok)
- goto fail;
- tok = strtok(NULL, "");
+ goto fail;
+ tok = strtok_r(NULL, ":",&count_sp);
if (!tok)
- goto fail;
+ goto fail;
*vga_count = strtoul(tok, NULL, 10);
if (*vga_count == LONG_MAX)
- goto fail;
+ goto fail;
#ifdef DEBUG
fprintf(stderr,"vga count is %d\n", *vga_count);
#endif
- tok = strtok(input, ",");
+ tok = strtok_r(NULL, ",",&input_sp);
if (!tok)
- goto fail;
+ goto fail;
if (match) {
- tok = strtok(NULL, ":");
- if (!tok)
- goto fail;
- match->domain = strtoul(tok, NULL, 16);
-
- tok = strtok(NULL, ":");
- if (!tok)
- goto fail;
- match->bus = strtoul(tok, NULL, 16);
-
- tok = strtok(NULL, ".");
- if (!tok)
- goto fail;
- match->dev = strtoul(tok, NULL, 16);
-
- tok = strtok(NULL, ".");
- if (!tok)
- goto fail;
- match->func = strtoul(tok, NULL, 16);
+ strncpy(tmp, tok, 32);
+ tmp[31] = 0;
+ tok = strtok_r(tmp, ":", &pci_sp);
+ if (!tok)
+ goto fail;
+ tok = strtok_r(NULL, ":", &pci_sp);
+ if (!tok)
+ goto fail;
+ match->domain = strtoul(tok, NULL, 16);
+
+ tok = strtok_r(NULL, ":", &pci_sp);
+ if (!tok)
+ goto fail;
+ match->bus = strtoul(tok, NULL, 16);
+
+ tok = strtok_r(NULL, ".", &pci_sp);
+ if (!tok)
+ goto fail;
+ match->dev = strtoul(tok, NULL, 16);
+
+ tok = strtok_r(NULL, ".", &pci_sp);
+ if (!tok)
+ goto fail;
+ match->func = strtoul(tok, NULL, 16);
}
- tok = strtok(NULL, ",");
+ tok = strtok_r(NULL, ",",&input_sp);
if (!tok)
- goto fail;
- tok = strtok(tok, "=");
+ goto fail;
+ tok = strtok_r(tok, "=", &input_sp);
if (!tok)
- goto fail;
- tok = strtok(NULL, "=");
+ goto fail;
+ tok = strtok_r(NULL, "=", &input_sp);
if (!tok)
- goto fail;
+ goto fail;
if (!strncmp(tok, "io+mem", 6))
- return VGA_ARB_RSRC_LEGACY_IO | VGA_ARB_RSRC_LEGACY_MEM;
+ return VGA_ARB_RSRC_LEGACY_IO | VGA_ARB_RSRC_LEGACY_MEM;
if (!strncmp(tok, "io", 2))
- return VGA_ARB_RSRC_LEGACY_IO;
+ return VGA_ARB_RSRC_LEGACY_IO;
if (!strncmp(tok, "mem", 3))
- return VGA_ARB_RSRC_LEGACY_MEM;
+ return VGA_ARB_RSRC_LEGACY_MEM;
fail:
return VGA_ARB_RSRC_NONE;
}
struct pci_slot_match match;
char buf[BUFSIZE];
int ret, rsrc;
+
+ if (!pci_sys)
+ return -1;
+
if ((pci_sys->vgaarb_fd = open ("/dev/vga_arbiter", O_RDWR)) < 0) {
return errno;
}
ret = read(pci_sys->vgaarb_fd, buf, BUFSIZE);
if (ret <= 0)
- return -1;
+ return -1;
memset(&match, 0xff, sizeof(match));
/* need to find the device to go back to and what it was decoding */
rsrc = parse_string_to_decodes_rsrc(buf, &pci_sys->vga_count, &match);
-
+
pci_sys->vga_default_dev = pci_device_find_by_slot(match.domain, match.bus, match.dev, match.func);
-
+
if (pci_sys->vga_default_dev)
pci_sys->vga_default_dev->vgaarb_rsrc = rsrc;
return 0;
void
pci_device_vgaarb_fini(void)
{
+ if (!pci_sys)
+ return;
+
close(pci_sys->vgaarb_fd);
}
int ret;
if (!dev)
- dev = pci_sys->vga_default_dev;
+ dev = pci_sys->vga_default_dev;
if (!dev)
- return -1;
+ return -1;
- len = snprintf(buf, BUFSIZE, "target PCI:%d:%d:%d.%d",
+ len = snprintf(buf, BUFSIZE, "target PCI:%04x:%02x:%02x.%x",
dev->domain, dev->bus, dev->dev, dev->func);
ret = vgaarb_write(pci_sys->vgaarb_fd, buf, len);
if (ret)
- return ret;
+ return ret;
ret = read(pci_sys->vgaarb_fd, buf, BUFSIZE);
if (ret <= 0)
- return -1;
+ return -1;
dev->vgaarb_rsrc = parse_string_to_decodes_rsrc(buf, &pci_sys->vga_count, NULL);
pci_sys->vga_target = dev;
struct pci_device *dev = pci_sys->vga_target;
if (!dev)
- return -1;
+ return -1;
if (dev->vgaarb_rsrc == new_vgaarb_rsrc)
- return 0;
+ return 0;
- len = snprintf(buf, BUFSIZE, "decodes %s", rsrc_to_str(dev->vgaarb_rsrc));
+ len = snprintf(buf, BUFSIZE, "decodes %s", rsrc_to_str(new_vgaarb_rsrc));
ret = vgaarb_write(pci_sys->vgaarb_fd, buf, len);
if (ret == 0)
dev->vgaarb_rsrc = new_vgaarb_rsrc;
+
+ ret = read(pci_sys->vgaarb_fd, buf, BUFSIZE);
+ if (ret <= 0)
+ return -1;
+
+ parse_string_to_decodes_rsrc(buf, &pci_sys->vga_count, NULL);
+
return ret;
}
struct pci_device *dev = pci_sys->vga_target;
if (!dev)
- return -1;
+ return -1;
if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
return 0;
struct pci_device *dev = pci_sys->vga_target;
if (!dev)
- return -1;
+ return -1;
if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
return 0;
return vgaarb_write(pci_sys->vgaarb_fd, buf, len);
}
+
+int pci_device_vgaarb_get_info(struct pci_device *dev, int *vga_count, int *rsrc_decodes)
+{
+ *vga_count = pci_sys->vga_count;
+ if (!dev)
+ return 0;
+
+ *rsrc_decodes = dev->vgaarb_rsrc;
+ return 0;
+}