On Thu, Oct 20, 2011 at 11:57, Stefano Stabellini <stefano.stabell...@eu.citrix.com> wrote: > On Wed, 19 Oct 2011, Anthony PERARD wrote: >> Signed-off-by: Anthony PERARD <anthony.per...@citrix.com> >> --- >> Makefile.target | 1 + >> hw/host-pci-device.c | 245 >> ++++++++++++++++++++++++++++++++++++++++++++++++++ >> hw/host-pci-device.h | 75 +++++++++++++++ >> 3 files changed, 321 insertions(+), 0 deletions(-) >> create mode 100644 hw/host-pci-device.c >> create mode 100644 hw/host-pci-device.h >> >> diff --git a/Makefile.target b/Makefile.target >> index c518103..ca3420d 100644 >> --- a/Makefile.target >> +++ b/Makefile.target >> @@ -209,6 +209,7 @@ obj-$(CONFIG_NO_XEN) += xen-stub.o >> obj-i386-$(CONFIG_XEN) += xen_platform.o >> >> # Xen PCI Passthrough >> +obj-i386-$(CONFIG_XEN_PCI_PASSTHROUGH) += host-pci-device.o >> >> # Inter-VM PCI shared memory >> CONFIG_IVSHMEM = >> diff --git a/hw/host-pci-device.c b/hw/host-pci-device.c >> new file mode 100644 >> index 0000000..0f25fcf >> --- /dev/null >> +++ b/hw/host-pci-device.c >> @@ -0,0 +1,245 @@ >> +/* >> + * Copyright (C) 2011 Citrix Ltd. >> + * >> + * This work is licensed under the terms of the GNU GPL, version 2. See >> + * the COPYING file in the top-level directory. >> + * >> + */ >> + >> +#include "qemu-common.h" >> +#include "host-pci-device.h" >> + >> +static int path_to(const HostPCIDevice *d, >> + const char *name, char *buf, ssize_t size) >> +{ >> + return snprintf(buf, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%x/%s", >> + d->domain, d->bus, d->dev, d->func, name); >> +} >> + >> +static int get_resource(HostPCIDevice *d) >> +{ >> + int i, rc = 0; >> + FILE *f; >> + char path[PATH_MAX]; >> + unsigned long long start, end, flags, size; >> + >> + path_to(d, "resource", path, sizeof (path)); >> + f = fopen(path, "r"); >> + if (!f) { >> + fprintf(stderr, "Error: Can't open %s: %s\n", path, >> strerror(errno)); >> + return -1; > > it would be better to return a proper error code, rather than just -1
probably -errno will do it. >> + } >> + >> + for (i = 0; i < PCI_NUM_REGIONS; i++) { >> + if (fscanf(f, "%llx %llx %llx", &start, &end, &flags) != 3) { >> + fprintf(stderr, "Error: Syntax error in %s\n", path); >> + rc = -1; > > Ditto probably 1 with a define on the top of the file. >> + break; >> + } >> + if (start) { >> + size = end - start + 1; >> + } else { >> + size = 0; >> + } >> + >> + if (i < PCI_ROM_SLOT) { >> + d->io_regions[i].base_addr = start; >> + d->io_regions[i].size = size; >> + d->io_regions[i].flags = flags; >> + } else { >> + d->rom.base_addr = start; >> + d->rom.size = size; >> + d->rom.flags = flags; >> + } >> + } >> + >> + fclose(f); >> + return rc; >> +} [...] >> + >> +uint32_t host_pci_find_ext_cap_offset(HostPCIDevice *d, uint32_t cap) >> +{ >> + uint32_t header = 0; >> + int max_cap = 480; >> + int pos = 0x100; > > could you used some defined constants here? Yes, I will. >> + do { >> + header = host_pci_get_long(d, pos); >> + /* >> + * If we have no capabilities, this is indicated by cap ID, >> + * cap version and next pointer all being 0. >> + */ >> + if (header == 0) { >> + break; >> + } >> + >> + if (PCI_EXT_CAP_ID(header) == cap) { >> + return pos; >> + } >> + >> + pos = PCI_EXT_CAP_NEXT(header); >> + if (pos < 0x100) { >> + break; >> + } >> + >> + max_cap--; >> + } while (max_cap > 0); >> + >> + return 0; >> +} -- Anthony PERARD