X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_eal%2Flinuxapp%2Feal%2Feal_pci.c;h=434697323c00a85d3e7b82fe3327f398681a4a4d;hb=756ce64b1ecdf107acfa45fc3f31359ca338649e;hp=db947da386dad00798b1208ece53c55c572b8095;hpb=962cf902e6ebcb035fedc61847041769894e5f4c;p=dpdk.git diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c index db947da386..434697323c 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c @@ -621,6 +621,176 @@ int rte_eal_pci_write_config(const struct rte_pci_device *device, } } +#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_I686) +static int +pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused, + struct rte_pci_ioport *p) +{ + uint16_t start, end; + FILE *fp; + char *line = NULL; + char pci_id[16]; + int found = 0; + size_t linesz; + + snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT, + dev->addr.domain, dev->addr.bus, + dev->addr.devid, dev->addr.function); + + fp = fopen("/proc/ioports", "r"); + if (fp == NULL) { + RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__); + return -1; + } + + while (getdelim(&line, &linesz, '\n', fp) > 0) { + char *ptr = line; + char *left; + int n; + + n = strcspn(ptr, ":"); + ptr[n] = 0; + left = &ptr[n + 1]; + + while (*left && isspace(*left)) + left++; + + if (!strncmp(left, pci_id, strlen(pci_id))) { + found = 1; + + while (*ptr && isspace(*ptr)) + ptr++; + + sscanf(ptr, "%04hx-%04hx", &start, &end); + + break; + } + } + + free(line); + fclose(fp); + + if (!found) + return -1; + + dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; + p->base = start; + RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start); + + return 0; +} +#endif + +int +rte_eal_pci_ioport_map(struct rte_pci_device *dev, int bar, + struct rte_pci_ioport *p) +{ + int ret; + + switch (dev->kdrv) { +#ifdef VFIO_PRESENT + case RTE_KDRV_VFIO: + ret = -1; + if (pci_vfio_is_enabled()) + ret = pci_vfio_ioport_map(dev, bar, p); + break; +#endif + case RTE_KDRV_IGB_UIO: + case RTE_KDRV_UIO_GENERIC: + ret = pci_uio_ioport_map(dev, bar, p); + break; + default: +#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_I686) + /* special case for x86 ... */ + ret = pci_ioport_map(dev, bar, p); +#else + ret = -1; +#endif + break; + } + + if (!ret) + p->dev = dev; + + return ret; +} + +void +rte_eal_pci_ioport_read(struct rte_pci_ioport *p, + void *data, size_t len, off_t offset) +{ + switch (p->dev->kdrv) { +#ifdef VFIO_PRESENT + case RTE_KDRV_VFIO: + pci_vfio_ioport_read(p, data, len, offset); + break; +#endif + case RTE_KDRV_IGB_UIO: + case RTE_KDRV_UIO_GENERIC: + pci_uio_ioport_read(p, data, len, offset); + break; + default: +#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_I686) + /* special case for x86 ... */ + pci_uio_ioport_read(p, data, len, offset); +#endif + break; + } +} + +void +rte_eal_pci_ioport_write(struct rte_pci_ioport *p, + const void *data, size_t len, off_t offset) +{ + switch (p->dev->kdrv) { +#ifdef VFIO_PRESENT + case RTE_KDRV_VFIO: + pci_vfio_ioport_write(p, data, len, offset); + break; +#endif + case RTE_KDRV_IGB_UIO: + case RTE_KDRV_UIO_GENERIC: + pci_uio_ioport_write(p, data, len, offset); + break; + default: +#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_I686) + /* special case for x86 ... */ + pci_uio_ioport_write(p, data, len, offset); +#endif + break; + } +} + +int +rte_eal_pci_ioport_unmap(struct rte_pci_ioport *p) +{ + int ret; + + switch (p->dev->kdrv) { +#ifdef VFIO_PRESENT + case RTE_KDRV_VFIO: + ret = -1; + if (pci_vfio_is_enabled()) + ret = pci_vfio_ioport_unmap(p); + break; +#endif + case RTE_KDRV_IGB_UIO: + case RTE_KDRV_UIO_GENERIC: + ret = pci_uio_ioport_unmap(p); + break; + default: +#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_I686) + /* special case for x86 ... nothing to do */ + ret = 0; +#else + ret = -1; +#endif + break; + } + + return ret; +} + /* Init the PCI EAL subsystem */ int rte_eal_pci_init(void)