virtio: move left PCI stuff in the right file
authorYuanhan Liu <yuanhan.liu@linux.intel.com>
Tue, 2 Feb 2016 13:48:15 +0000 (21:48 +0800)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Wed, 3 Feb 2016 15:07:49 +0000 (16:07 +0100)
virtio_pci.c is a more proper place for pci stuff; virtio_ethdev is not.

Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Tested-by: Qian Xu <qian.q.xu@intel.com>
Reviewed-by: Tetsuya Mukawa <mukawa@igel.co.jp>
Tested-by: Tetsuya Mukawa <mukawa@igel.co.jp>
Acked-by: Huawei Xie <huawei.xie@intel.com>
drivers/net/virtio/virtio_ethdev.c
drivers/net/virtio/virtio_pci.c

index 6c1d3a0..b57224d 100644 (file)
 #include <stdio.h>
 #include <errno.h>
 #include <unistd.h>
-#ifdef RTE_EXEC_ENV_LINUXAPP
-#include <dirent.h>
-#include <fcntl.h>
-#endif
 
 #include <rte_ethdev.h>
 #include <rte_memcpy.h>
@@ -955,260 +951,6 @@ virtio_negotiate_features(struct virtio_hw *hw)
                hw->guest_features);
 }
 
-#ifdef RTE_EXEC_ENV_LINUXAPP
-static int
-parse_sysfs_value(const char *filename, unsigned long *val)
-{
-       FILE *f;
-       char buf[BUFSIZ];
-       char *end = NULL;
-
-       f = fopen(filename, "r");
-       if (f == NULL) {
-               PMD_INIT_LOG(ERR, "%s(): cannot open sysfs value %s",
-                            __func__, filename);
-               return -1;
-       }
-
-       if (fgets(buf, sizeof(buf), f) == NULL) {
-               PMD_INIT_LOG(ERR, "%s(): cannot read sysfs value %s",
-                            __func__, filename);
-               fclose(f);
-               return -1;
-       }
-       *val = strtoul(buf, &end, 0);
-       if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) {
-               PMD_INIT_LOG(ERR, "%s(): cannot parse sysfs value %s",
-                            __func__, filename);
-               fclose(f);
-               return -1;
-       }
-       fclose(f);
-       return 0;
-}
-
-static int get_uio_dev(struct rte_pci_addr *loc, char *buf, unsigned int buflen,
-                       unsigned int *uio_num)
-{
-       struct dirent *e;
-       DIR *dir;
-       char dirname[PATH_MAX];
-
-       /* depending on kernel version, uio can be located in uio/uioX
-        * or uio:uioX */
-       snprintf(dirname, sizeof(dirname),
-                    SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/uio",
-                    loc->domain, loc->bus, loc->devid, loc->function);
-       dir = opendir(dirname);
-       if (dir == NULL) {
-               /* retry with the parent directory */
-               snprintf(dirname, sizeof(dirname),
-                            SYSFS_PCI_DEVICES "/" PCI_PRI_FMT,
-                            loc->domain, loc->bus, loc->devid, loc->function);
-               dir = opendir(dirname);
-
-               if (dir == NULL) {
-                       PMD_INIT_LOG(ERR, "Cannot opendir %s", dirname);
-                       return -1;
-               }
-       }
-
-       /* take the first file starting with "uio" */
-       while ((e = readdir(dir)) != NULL) {
-               /* format could be uio%d ...*/
-               int shortprefix_len = sizeof("uio") - 1;
-               /* ... or uio:uio%d */
-               int longprefix_len = sizeof("uio:uio") - 1;
-               char *endptr;
-
-               if (strncmp(e->d_name, "uio", 3) != 0)
-                       continue;
-
-               /* first try uio%d */
-               errno = 0;
-               *uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
-               if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
-                       snprintf(buf, buflen, "%s/uio%u", dirname, *uio_num);
-                       break;
-               }
-
-               /* then try uio:uio%d */
-               errno = 0;
-               *uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
-               if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
-                       snprintf(buf, buflen, "%s/uio:uio%u", dirname,
-                                    *uio_num);
-                       break;
-               }
-       }
-       closedir(dir);
-
-       /* No uio resource found */
-       if (e == NULL) {
-               PMD_INIT_LOG(ERR, "Could not find uio resource");
-               return -1;
-       }
-
-       return 0;
-}
-
-static int
-virtio_has_msix(const struct rte_pci_addr *loc)
-{
-       DIR *d;
-       char dirname[PATH_MAX];
-
-       snprintf(dirname, sizeof(dirname),
-                    SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/msi_irqs",
-                    loc->domain, loc->bus, loc->devid, loc->function);
-
-       d = opendir(dirname);
-       if (d)
-               closedir(d);
-
-       return (d != NULL);
-}
-
-/* Extract I/O port numbers from sysfs */
-static int virtio_resource_init_by_uio(struct rte_pci_device *pci_dev)
-{
-       char dirname[PATH_MAX];
-       char filename[PATH_MAX];
-       unsigned long start, size;
-       unsigned int uio_num;
-
-       if (get_uio_dev(&pci_dev->addr, dirname, sizeof(dirname), &uio_num) < 0)
-               return -1;
-
-       /* get portio size */
-       snprintf(filename, sizeof(filename),
-                    "%s/portio/port0/size", dirname);
-       if (parse_sysfs_value(filename, &size) < 0) {
-               PMD_INIT_LOG(ERR, "%s(): cannot parse size",
-                            __func__);
-               return -1;
-       }
-
-       /* get portio start */
-       snprintf(filename, sizeof(filename),
-                "%s/portio/port0/start", dirname);
-       if (parse_sysfs_value(filename, &start) < 0) {
-               PMD_INIT_LOG(ERR, "%s(): cannot parse portio start",
-                            __func__);
-               return -1;
-       }
-       pci_dev->mem_resource[0].addr = (void *)(uintptr_t)start;
-       pci_dev->mem_resource[0].len =  (uint64_t)size;
-       PMD_INIT_LOG(DEBUG,
-                    "PCI Port IO found start=0x%lx with size=0x%lx",
-                    start, size);
-
-       /* save fd */
-       memset(dirname, 0, sizeof(dirname));
-       snprintf(dirname, sizeof(dirname), "/dev/uio%u", uio_num);
-       pci_dev->intr_handle.fd = open(dirname, O_RDWR);
-       if (pci_dev->intr_handle.fd < 0) {
-               PMD_INIT_LOG(ERR, "Cannot open %s: %s\n",
-                       dirname, strerror(errno));
-               return -1;
-       }
-
-       pci_dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-       pci_dev->driver->drv_flags |= RTE_PCI_DRV_INTR_LSC;
-
-       return 0;
-}
-
-/* Extract port I/O numbers from proc/ioports */
-static int virtio_resource_init_by_ioports(struct rte_pci_device *pci_dev)
-{
-       uint16_t start, end;
-       int size;
-       FILE *fp;
-       char *line = NULL;
-       char pci_id[16];
-       int found = 0;
-       size_t linesz;
-
-       snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
-                pci_dev->addr.domain,
-                pci_dev->addr.bus,
-                pci_dev->addr.devid,
-                pci_dev->addr.function);
-
-       fp = fopen("/proc/ioports", "r");
-       if (fp == NULL) {
-               PMD_INIT_LOG(ERR, "%s(): can't open ioports", __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);
-                       size = end - start + 1;
-
-                       break;
-               }
-       }
-
-       free(line);
-       fclose(fp);
-
-       if (!found)
-               return -1;
-
-       pci_dev->mem_resource[0].addr = (void *)(uintptr_t)(uint32_t)start;
-       pci_dev->mem_resource[0].len =  (uint64_t)size;
-       PMD_INIT_LOG(DEBUG,
-               "PCI Port IO found start=0x%x with size=0x%x",
-               start, size);
-
-       /* can't support lsc interrupt without uio */
-       pci_dev->driver->drv_flags &= ~RTE_PCI_DRV_INTR_LSC;
-
-       return 0;
-}
-
-/* Extract I/O port numbers from sysfs */
-static int virtio_resource_init(struct rte_pci_device *pci_dev)
-{
-       if (virtio_resource_init_by_uio(pci_dev) == 0)
-               return 0;
-       else
-               return virtio_resource_init_by_ioports(pci_dev);
-}
-
-#else
-static int
-virtio_has_msix(const struct rte_pci_addr *loc __rte_unused)
-{
-       /* nic_uio does not enable interrupts, return 0 (false). */
-       return 0;
-}
-
-static int virtio_resource_init(struct rte_pci_device *pci_dev __rte_unused)
-{
-       /* no setup required */
-       return 0;
-}
-#endif
-
 /*
  * Process Virtio Config changed interrupt and call the callback
  * if link state changed.
@@ -1279,14 +1021,9 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 
        pci_dev = eth_dev->pci_dev;
 
-       vtpci_init(pci_dev, hw);
-
-       if (virtio_resource_init(pci_dev) < 0)
+       if (vtpci_init(pci_dev, hw) < 0)
                return -1;
 
-       hw->use_msix = virtio_has_msix(&pci_dev->addr);
-       hw->io_base = (uint32_t)(uintptr_t)pci_dev->mem_resource[0].addr;
-
        /* Reset the device although not necessary at startup */
        vtpci_reset(hw);
 
index 8d001e8..e89a044 100644 (file)
  */
 #include <stdint.h>
 
+#ifdef RTE_EXEC_ENV_LINUXAPP
+ #include <dirent.h>
+ #include <fcntl.h>
+#endif
+
 #include "virtio_pci.h"
 #include "virtio_logs.h"
 #include "virtqueue.h"
@@ -156,6 +161,266 @@ legacy_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
        VIRTIO_WRITE_REG_2(hw, VIRTIO_PCI_QUEUE_NOTIFY, vq->vq_queue_index);
 }
 
+#ifdef RTE_EXEC_ENV_LINUXAPP
+static int
+parse_sysfs_value(const char *filename, unsigned long *val)
+{
+       FILE *f;
+       char buf[BUFSIZ];
+       char *end = NULL;
+
+       f = fopen(filename, "r");
+       if (f == NULL) {
+               PMD_INIT_LOG(ERR, "%s(): cannot open sysfs value %s",
+                            __func__, filename);
+               return -1;
+       }
+
+       if (fgets(buf, sizeof(buf), f) == NULL) {
+               PMD_INIT_LOG(ERR, "%s(): cannot read sysfs value %s",
+                            __func__, filename);
+               fclose(f);
+               return -1;
+       }
+       *val = strtoul(buf, &end, 0);
+       if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) {
+               PMD_INIT_LOG(ERR, "%s(): cannot parse sysfs value %s",
+                            __func__, filename);
+               fclose(f);
+               return -1;
+       }
+       fclose(f);
+       return 0;
+}
+
+static int
+get_uio_dev(struct rte_pci_addr *loc, char *buf, unsigned int buflen,
+                       unsigned int *uio_num)
+{
+       struct dirent *e;
+       DIR *dir;
+       char dirname[PATH_MAX];
+
+       /*
+        * depending on kernel version, uio can be located in uio/uioX
+        * or uio:uioX
+        */
+       snprintf(dirname, sizeof(dirname),
+                    SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/uio",
+                    loc->domain, loc->bus, loc->devid, loc->function);
+       dir = opendir(dirname);
+       if (dir == NULL) {
+               /* retry with the parent directory */
+               snprintf(dirname, sizeof(dirname),
+                            SYSFS_PCI_DEVICES "/" PCI_PRI_FMT,
+                            loc->domain, loc->bus, loc->devid, loc->function);
+               dir = opendir(dirname);
+
+               if (dir == NULL) {
+                       PMD_INIT_LOG(ERR, "Cannot opendir %s", dirname);
+                       return -1;
+               }
+       }
+
+       /* take the first file starting with "uio" */
+       while ((e = readdir(dir)) != NULL) {
+               /* format could be uio%d ...*/
+               int shortprefix_len = sizeof("uio") - 1;
+               /* ... or uio:uio%d */
+               int longprefix_len = sizeof("uio:uio") - 1;
+               char *endptr;
+
+               if (strncmp(e->d_name, "uio", 3) != 0)
+                       continue;
+
+               /* first try uio%d */
+               errno = 0;
+               *uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
+               if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
+                       snprintf(buf, buflen, "%s/uio%u", dirname, *uio_num);
+                       break;
+               }
+
+               /* then try uio:uio%d */
+               errno = 0;
+               *uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
+               if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
+                       snprintf(buf, buflen, "%s/uio:uio%u", dirname,
+                                    *uio_num);
+                       break;
+               }
+       }
+       closedir(dir);
+
+       /* No uio resource found */
+       if (e == NULL) {
+               PMD_INIT_LOG(ERR, "Could not find uio resource");
+               return -1;
+       }
+
+       return 0;
+}
+
+static int
+legacy_virtio_has_msix(const struct rte_pci_addr *loc)
+{
+       DIR *d;
+       char dirname[PATH_MAX];
+
+       snprintf(dirname, sizeof(dirname),
+                    SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/msi_irqs",
+                    loc->domain, loc->bus, loc->devid, loc->function);
+
+       d = opendir(dirname);
+       if (d)
+               closedir(d);
+
+       return (d != NULL);
+}
+
+/* Extract I/O port numbers from sysfs */
+static int
+virtio_resource_init_by_uio(struct rte_pci_device *pci_dev)
+{
+       char dirname[PATH_MAX];
+       char filename[PATH_MAX];
+       unsigned long start, size;
+       unsigned int uio_num;
+
+       if (get_uio_dev(&pci_dev->addr, dirname, sizeof(dirname), &uio_num) < 0)
+               return -1;
+
+       /* get portio size */
+       snprintf(filename, sizeof(filename),
+                    "%s/portio/port0/size", dirname);
+       if (parse_sysfs_value(filename, &size) < 0) {
+               PMD_INIT_LOG(ERR, "%s(): cannot parse size",
+                            __func__);
+               return -1;
+       }
+
+       /* get portio start */
+       snprintf(filename, sizeof(filename),
+                "%s/portio/port0/start", dirname);
+       if (parse_sysfs_value(filename, &start) < 0) {
+               PMD_INIT_LOG(ERR, "%s(): cannot parse portio start",
+                            __func__);
+               return -1;
+       }
+       pci_dev->mem_resource[0].addr = (void *)(uintptr_t)start;
+       pci_dev->mem_resource[0].len =  (uint64_t)size;
+       PMD_INIT_LOG(DEBUG,
+                    "PCI Port IO found start=0x%lx with size=0x%lx",
+                    start, size);
+
+       /* save fd */
+       memset(dirname, 0, sizeof(dirname));
+       snprintf(dirname, sizeof(dirname), "/dev/uio%u", uio_num);
+       pci_dev->intr_handle.fd = open(dirname, O_RDWR);
+       if (pci_dev->intr_handle.fd < 0) {
+               PMD_INIT_LOG(ERR, "Cannot open %s: %s\n",
+                       dirname, strerror(errno));
+               return -1;
+       }
+
+       pci_dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+       pci_dev->driver->drv_flags |= RTE_PCI_DRV_INTR_LSC;
+
+       return 0;
+}
+
+/* Extract port I/O numbers from proc/ioports */
+static int
+virtio_resource_init_by_ioports(struct rte_pci_device *pci_dev)
+{
+       uint16_t start, end;
+       int size;
+       FILE *fp;
+       char *line = NULL;
+       char pci_id[16];
+       int found = 0;
+       size_t linesz;
+
+       snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
+                pci_dev->addr.domain,
+                pci_dev->addr.bus,
+                pci_dev->addr.devid,
+                pci_dev->addr.function);
+
+       fp = fopen("/proc/ioports", "r");
+       if (fp == NULL) {
+               PMD_INIT_LOG(ERR, "%s(): can't open ioports", __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);
+                       size = end - start + 1;
+
+                       break;
+               }
+       }
+
+       free(line);
+       fclose(fp);
+
+       if (!found)
+               return -1;
+
+       pci_dev->mem_resource[0].addr = (void *)(uintptr_t)(uint32_t)start;
+       pci_dev->mem_resource[0].len =  (uint64_t)size;
+       PMD_INIT_LOG(DEBUG,
+               "PCI Port IO found start=0x%x with size=0x%x",
+               start, size);
+
+       /* can't support lsc interrupt without uio */
+       pci_dev->driver->drv_flags &= ~RTE_PCI_DRV_INTR_LSC;
+
+       return 0;
+}
+
+/* Extract I/O port numbers from sysfs */
+static int
+legacy_virtio_resource_init(struct rte_pci_device *pci_dev)
+{
+       if (virtio_resource_init_by_uio(pci_dev) == 0)
+               return 0;
+       else
+               return virtio_resource_init_by_ioports(pci_dev);
+}
+
+#else
+static int
+legayc_virtio_has_msix(const struct rte_pci_addr *loc __rte_unused)
+{
+       /* nic_uio does not enable interrupts, return 0 (false). */
+       return 0;
+}
+
+static int
+legacy_virtio_resource_init(struct rte_pci_device *pci_dev __rte_unused)
+{
+       /* no setup required */
+       return 0;
+}
+#endif
 
 static const struct virtio_pci_ops legacy_ops = {
        .read_dev_cfg   = legacy_read_dev_config,
@@ -241,9 +506,14 @@ vtpci_irq_config(struct virtio_hw *hw, uint16_t vec)
 }
 
 int
-vtpci_init(struct rte_pci_device *dev __rte_unused, struct virtio_hw *hw)
+vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw)
 {
        hw->vtpci_ops = &legacy_ops;
 
+       if (legacy_virtio_resource_init(dev) < 0)
+               return -1;
+       hw->use_msix = legacy_virtio_has_msix(&dev->addr);
+       hw->io_base  = (uint32_t)(uintptr_t)dev->mem_resource[0].addr;
+
        return 0;
 }