Lines Matching +full:d +full:- +full:- +full:- +full:- +full:- +full:0

5  * the COPYING file in the top-level directory.
12 #include "hw/xen/xen-legacy-backend.h"
13 #include "hw/xen/xen-bus-helper.h"
14 #include "xen-host-pci-device.h"
17 ((PCIE_CONFIG_SPACE_SIZE - PCI_CONFIG_SPACE_SIZE) / (PCI_CAP_SIZEOF + 4))
22 # define XEN_HOST_PCI_LOG(f, a...) (void)0
29 #define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */
31 #define IORESOURCE_TYPE_BITS 0x00000f00 /* Resource type */
32 #define IORESOURCE_IO 0x00000100
33 #define IORESOURCE_MEM 0x00000200
35 #define IORESOURCE_PREFETCH 0x00001000 /* No side effects */
36 #define IORESOURCE_MEM_64 0x00100000
39 * Non-passthrough (dom0) accesses are local PCI devices and use the given BDF
41 * either have a BDF identical to the backend's BDF (xen-backend.passthrough=1)
42 * or a local virtual BDF (xen-backend.passthrough=0)
47 static void xen_host_pci_fill_local_addr(XenHostPCIDevice *d, Error **errp) in xen_host_pci_fill_local_addr() argument
54 be_path = qemu_xen_xs_read(xenstore, 0, "device/pci/0/backend", &len); in xen_host_pci_fill_local_addr()
56 error_setg(errp, "Failed to read device/pci/0/backend"); in xen_host_pci_fill_local_addr()
60 if (xs_node_scanf(xenstore, 0, be_path, "num_devs", NULL, in xen_host_pci_fill_local_addr()
61 "%d", &num_devs) != 1) { in xen_host_pci_fill_local_addr()
66 for (i = 0; i < num_devs; i++) { in xen_host_pci_fill_local_addr()
67 snprintf(path, sizeof(path), "dev-%d", i); in xen_host_pci_fill_local_addr()
68 if (xs_node_scanf(xenstore, 0, be_path, path, NULL, in xen_host_pci_fill_local_addr()
73 if (domain != d->domain || in xen_host_pci_fill_local_addr()
74 bus != d->bus || in xen_host_pci_fill_local_addr()
75 dev != d->dev || in xen_host_pci_fill_local_addr()
76 func != d->func) in xen_host_pci_fill_local_addr()
78 snprintf(path, sizeof(path), "vdev-%d", i); in xen_host_pci_fill_local_addr()
79 if (xs_node_scanf(xenstore, 0, be_path, path, NULL, in xen_host_pci_fill_local_addr()
84 d->local_domain = domain; in xen_host_pci_fill_local_addr()
85 d->local_bus = bus; in xen_host_pci_fill_local_addr()
86 d->local_dev = dev; in xen_host_pci_fill_local_addr()
87 d->local_func = func; in xen_host_pci_fill_local_addr()
91 d->domain, d->bus, d->dev, d->func); in xen_host_pci_fill_local_addr()
97 static void xen_host_pci_sysfs_path(const XenHostPCIDevice *d, in xen_host_pci_sysfs_path() argument
102 rc = snprintf(buf, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s", in xen_host_pci_sysfs_path()
103 d->local_domain, d->local_bus, d->local_dev, d->local_func, in xen_host_pci_sysfs_path()
105 assert(rc >= 0 && rc < size); in xen_host_pci_sysfs_path()
111 static void xen_host_pci_get_resource(XenHostPCIDevice *d, Error **errp) in xen_host_pci_get_resource() argument
120 xen_host_pci_sysfs_path(d, "resource", path, sizeof(path)); in xen_host_pci_get_resource()
123 if (fd == -1) { in xen_host_pci_get_resource()
129 rc = read(fd, &buf, sizeof(buf) - 1); in xen_host_pci_get_resource()
130 if (rc < 0 && errno != EINTR) { in xen_host_pci_get_resource()
134 } while (rc < 0); in xen_host_pci_get_resource()
135 buf[rc] = 0; in xen_host_pci_get_resource()
138 for (i = 0; i < PCI_NUM_REGIONS; i++) { in xen_host_pci_get_resource()
139 type = 0; in xen_host_pci_get_resource()
158 size = end - start + 1; in xen_host_pci_get_resource()
160 size = 0; in xen_host_pci_get_resource()
177 d->io_regions[i].base_addr = start; in xen_host_pci_get_resource()
178 d->io_regions[i].size = size; in xen_host_pci_get_resource()
179 d->io_regions[i].type = type; in xen_host_pci_get_resource()
180 d->io_regions[i].bus_flags = flags & IORESOURCE_BITS; in xen_host_pci_get_resource()
182 d->rom.base_addr = start; in xen_host_pci_get_resource()
183 d->rom.size = size; in xen_host_pci_get_resource()
184 d->rom.type = type; in xen_host_pci_get_resource()
185 d->rom.bus_flags = flags & IORESOURCE_BITS; in xen_host_pci_get_resource()
199 static void xen_host_pci_get_value(XenHostPCIDevice *d, const char *name, in xen_host_pci_get_value() argument
208 xen_host_pci_sysfs_path(d, name, path, sizeof(path)); in xen_host_pci_get_value()
211 if (fd == -1) { in xen_host_pci_get_value()
217 rc = read(fd, &buf, sizeof(buf) - 1); in xen_host_pci_get_value()
218 if (rc < 0 && errno != EINTR) { in xen_host_pci_get_value()
222 } while (rc < 0); in xen_host_pci_get_value()
224 buf[rc] = 0; in xen_host_pci_get_value()
230 error_setg_errno(errp, -rc, "failed to parse value '%s'", buf); in xen_host_pci_get_value()
237 static inline void xen_host_pci_get_hex_value(XenHostPCIDevice *d, in xen_host_pci_get_hex_value() argument
242 xen_host_pci_get_value(d, name, pvalue, 16, errp); in xen_host_pci_get_hex_value()
245 static inline void xen_host_pci_get_dec_value(XenHostPCIDevice *d, in xen_host_pci_get_dec_value() argument
250 xen_host_pci_get_value(d, name, pvalue, 10, errp); in xen_host_pci_get_dec_value()
253 static bool xen_host_pci_dev_is_virtfn(XenHostPCIDevice *d) in xen_host_pci_dev_is_virtfn() argument
258 xen_host_pci_sysfs_path(d, "physfn", path, sizeof(path)); in xen_host_pci_dev_is_virtfn()
263 static void xen_host_pci_config_open(XenHostPCIDevice *d, Error **errp) in xen_host_pci_config_open() argument
267 xen_host_pci_sysfs_path(d, "config", path, sizeof(path)); in xen_host_pci_config_open()
269 d->config_fd = open(path, O_RDWR); in xen_host_pci_config_open()
270 if (d->config_fd == -1) { in xen_host_pci_config_open()
275 static int xen_host_pci_config_read(XenHostPCIDevice *d, in xen_host_pci_config_read() argument
281 rc = pread(d->config_fd, buf, len, pos); in xen_host_pci_config_read()
282 } while (rc < 0 && (errno == EINTR || errno == EAGAIN)); in xen_host_pci_config_read()
284 return -errno; in xen_host_pci_config_read()
286 return 0; in xen_host_pci_config_read()
289 static int xen_host_pci_config_write(XenHostPCIDevice *d, in xen_host_pci_config_write() argument
295 rc = pwrite(d->config_fd, buf, len, pos); in xen_host_pci_config_write()
296 } while (rc < 0 && (errno == EINTR || errno == EAGAIN)); in xen_host_pci_config_write()
298 return -errno; in xen_host_pci_config_write()
300 return 0; in xen_host_pci_config_write()
304 int xen_host_pci_get_byte(XenHostPCIDevice *d, int pos, uint8_t *p) in xen_host_pci_get_byte() argument
307 int rc = xen_host_pci_config_read(d, pos, &buf, 1); in xen_host_pci_get_byte()
314 int xen_host_pci_get_word(XenHostPCIDevice *d, int pos, uint16_t *p) in xen_host_pci_get_word() argument
317 int rc = xen_host_pci_config_read(d, pos, &buf, 2); in xen_host_pci_get_word()
324 int xen_host_pci_get_long(XenHostPCIDevice *d, int pos, uint32_t *p) in xen_host_pci_get_long() argument
327 int rc = xen_host_pci_config_read(d, pos, &buf, 4); in xen_host_pci_get_long()
334 int xen_host_pci_get_block(XenHostPCIDevice *d, int pos, uint8_t *buf, int len) in xen_host_pci_get_block() argument
336 return xen_host_pci_config_read(d, pos, buf, len); in xen_host_pci_get_block()
339 int xen_host_pci_set_byte(XenHostPCIDevice *d, int pos, uint8_t data) in xen_host_pci_set_byte() argument
341 return xen_host_pci_config_write(d, pos, &data, 1); in xen_host_pci_set_byte()
344 int xen_host_pci_set_word(XenHostPCIDevice *d, int pos, uint16_t data) in xen_host_pci_set_word() argument
347 return xen_host_pci_config_write(d, pos, &data, 2); in xen_host_pci_set_word()
350 int xen_host_pci_set_long(XenHostPCIDevice *d, int pos, uint32_t data) in xen_host_pci_set_long() argument
353 return xen_host_pci_config_write(d, pos, &data, 4); in xen_host_pci_set_long()
356 int xen_host_pci_set_block(XenHostPCIDevice *d, int pos, uint8_t *buf, int len) in xen_host_pci_set_block() argument
358 return xen_host_pci_config_write(d, pos, buf, len); in xen_host_pci_set_block()
361 int xen_host_pci_find_ext_cap_offset(XenHostPCIDevice *d, uint32_t cap) in xen_host_pci_find_ext_cap_offset() argument
363 uint32_t header = 0; in xen_host_pci_find_ext_cap_offset()
368 if (xen_host_pci_get_long(d, pos, &header)) { in xen_host_pci_find_ext_cap_offset()
373 * cap version and next pointer all being 0. in xen_host_pci_find_ext_cap_offset()
375 if (header == 0) { in xen_host_pci_find_ext_cap_offset()
388 max_cap--; in xen_host_pci_find_ext_cap_offset()
389 } while (max_cap > 0); in xen_host_pci_find_ext_cap_offset()
391 return -1; in xen_host_pci_find_ext_cap_offset()
394 void xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain, in xen_host_pci_device_get() argument
401 d->config_fd = -1; in xen_host_pci_device_get()
402 d->domain = domain; in xen_host_pci_device_get()
403 d->bus = bus; in xen_host_pci_device_get()
404 d->dev = dev; in xen_host_pci_device_get()
405 d->func = func; in xen_host_pci_device_get()
408 xen_host_pci_fill_local_addr(d, errp); in xen_host_pci_device_get()
413 d->local_domain = d->domain; in xen_host_pci_device_get()
414 d->local_bus = d->bus; in xen_host_pci_device_get()
415 d->local_dev = d->dev; in xen_host_pci_device_get()
416 d->local_func = d->func; in xen_host_pci_device_get()
419 xen_host_pci_config_open(d, errp); in xen_host_pci_device_get()
424 xen_host_pci_get_resource(d, errp); in xen_host_pci_device_get()
429 xen_host_pci_get_hex_value(d, "vendor", &v, errp); in xen_host_pci_device_get()
433 d->vendor_id = v; in xen_host_pci_device_get()
435 xen_host_pci_get_hex_value(d, "device", &v, errp); in xen_host_pci_device_get()
439 d->device_id = v; in xen_host_pci_device_get()
441 xen_host_pci_get_dec_value(d, "irq", &v, errp); in xen_host_pci_device_get()
445 d->irq = v; in xen_host_pci_device_get()
447 xen_host_pci_get_hex_value(d, "class", &v, errp); in xen_host_pci_device_get()
451 d->class_code = v; in xen_host_pci_device_get()
453 d->is_virtfn = xen_host_pci_dev_is_virtfn(d); in xen_host_pci_device_get()
459 if (d->config_fd >= 0) { in xen_host_pci_device_get()
460 close(d->config_fd); in xen_host_pci_device_get()
461 d->config_fd = -1; in xen_host_pci_device_get()
465 bool xen_host_pci_device_closed(XenHostPCIDevice *d) in xen_host_pci_device_closed() argument
467 return d->config_fd == -1; in xen_host_pci_device_closed()
470 void xen_host_pci_device_put(XenHostPCIDevice *d) in xen_host_pci_device_put() argument
472 if (d->config_fd >= 0) { in xen_host_pci_device_put()
473 close(d->config_fd); in xen_host_pci_device_put()
474 d->config_fd = -1; in xen_host_pci_device_put()