2 * Copyright (c) 2007 Paulo R. Zanoni, Tiago Vignatti
5 * Permission is hereby granted, free of charge, to any person
6 * obtaining a copy of this software and associated documentation
7 * files (the "Software"), to deal in the Software without
8 * restriction, including without limitation the rights to use,
9 * copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
36 #include "pciaccess.h"
37 #include "pciaccess_private.h"
42 parse_string_to_decodes_rsrc(char *input, int *vga_count, struct pci_slot_match *match)
47 strncpy(count, input, 10);
50 tok = strtok(count,":");
53 tok = strtok(NULL, "");
57 *vga_count = strtoul(tok, NULL, 10);
58 if (*vga_count == LONG_MAX)
62 fprintf(stderr,"vga count is %d\n", *vga_count);
65 tok = strtok(input, ",");
70 tok = strtok(NULL, ":");
73 match->domain = strtoul(tok, NULL, 16);
75 tok = strtok(NULL, ":");
78 match->bus = strtoul(tok, NULL, 16);
80 tok = strtok(NULL, ".");
83 match->dev = strtoul(tok, NULL, 16);
85 tok = strtok(NULL, ".");
88 match->func = strtoul(tok, NULL, 16);
91 tok = strtok(NULL, ",");
94 tok = strtok(tok, "=");
97 tok = strtok(NULL, "=");
101 if (!strncmp(tok, "io+mem", 6))
102 return VGA_ARB_RSRC_LEGACY_IO | VGA_ARB_RSRC_LEGACY_MEM;
103 if (!strncmp(tok, "io", 2))
104 return VGA_ARB_RSRC_LEGACY_IO;
105 if (!strncmp(tok, "mem", 3))
106 return VGA_ARB_RSRC_LEGACY_MEM;
108 return VGA_ARB_RSRC_NONE;
112 pci_device_vgaarb_init(void)
114 struct pci_slot_match match;
117 if ((pci_sys->vgaarb_fd = open ("/dev/vga_arbiter", O_RDWR)) < 0) {
121 ret = read(pci_sys->vgaarb_fd, buf, BUFSIZE);
125 memset(&match, 0xff, sizeof(match));
126 /* need to find the device to go back to and what it was decoding */
127 rsrc = parse_string_to_decodes_rsrc(buf, &pci_sys->vga_count, &match);
129 pci_sys->vga_default_dev = pci_device_find_by_slot(match.domain, match.bus, match.dev, match.func);
131 if (pci_sys->vga_default_dev)
132 pci_sys->vga_default_dev->vgaarb_rsrc = rsrc;
137 pci_device_vgaarb_fini(void)
139 close(pci_sys->vgaarb_fd);
143 * Writes message on vga device. The messages are defined by the kernel
146 * \param fd vga arbiter device.
147 * \param buf message itself.
148 * \param len message length.
151 * Zero on success, 1 if something gets wrong and 2 if fd is busy (only for
155 vgaarb_write(int fd, char *buf, int len)
162 ret = write(fd, buf, len);
164 /* the user may have called "trylock" and didn't get the lock */
169 fprintf(stderr, "write error");
173 else if (ret != len) {
174 /* it's need to receive the exactly amount required. */
176 fprintf(stderr, "write error: wrote different than expected\n");
182 fprintf(stderr, "%s: successfully wrote: '%s'\n", __FUNCTION__, buf);
190 rsrc_to_str(int iostate)
193 case VGA_ARB_RSRC_LEGACY_IO | VGA_ARB_RSRC_LEGACY_MEM:
195 case VGA_ARB_RSRC_LEGACY_IO:
197 case VGA_ARB_RSRC_LEGACY_MEM:
205 pci_device_vgaarb_set_target(struct pci_device *dev)
212 dev = pci_sys->vga_default_dev;
216 len = snprintf(buf, BUFSIZE, "target PCI:%d:%d:%d.%d",
217 dev->domain, dev->bus, dev->dev, dev->func);
219 ret = vgaarb_write(pci_sys->vgaarb_fd, buf, len);
223 ret = read(pci_sys->vgaarb_fd, buf, BUFSIZE);
227 dev->vgaarb_rsrc = parse_string_to_decodes_rsrc(buf, &pci_sys->vga_count, NULL);
228 pci_sys->vga_target = dev;
233 pci_device_vgaarb_decodes(int new_vgaarb_rsrc)
238 struct pci_device *dev = pci_sys->vga_target;
242 if (dev->vgaarb_rsrc == new_vgaarb_rsrc)
245 len = snprintf(buf, BUFSIZE, "decodes %s", rsrc_to_str(dev->vgaarb_rsrc));
246 ret = vgaarb_write(pci_sys->vgaarb_fd, buf, len);
248 dev->vgaarb_rsrc = new_vgaarb_rsrc;
253 pci_device_vgaarb_lock(void)
257 struct pci_device *dev = pci_sys->vga_target;
262 if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
265 len = snprintf(buf, BUFSIZE, "lock %s", rsrc_to_str(dev->vgaarb_rsrc));
267 return vgaarb_write(pci_sys->vgaarb_fd, buf, len);
271 pci_device_vgaarb_trylock(void)
275 struct pci_device *dev = pci_sys->vga_target;
280 if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
283 len = snprintf(buf, BUFSIZE, "trylock %s", rsrc_to_str(dev->vgaarb_rsrc));
285 return vgaarb_write(pci_sys->vgaarb_fd, buf, len);
289 pci_device_vgaarb_unlock(void)
293 struct pci_device *dev = pci_sys->vga_target;
298 if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
301 len = snprintf(buf, BUFSIZE, "unlock %s", rsrc_to_str(dev->vgaarb_rsrc));
303 return vgaarb_write(pci_sys->vgaarb_fd, buf, len);