pci: introduce helpers for device name parsing/update
[dpdk.git] / lib / librte_eal / linuxapp / eal / eal_pci.c
index 77d70d9..62da4d4 100644 (file)
@@ -66,8 +66,8 @@ pci_unbind_kernel_driver(struct rte_pci_device *dev)
 
        /* open /sys/bus/pci/devices/AAAA:BB:CC.D/driver */
        snprintf(filename, sizeof(filename),
-                SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/driver/unbind",
-                loc->domain, loc->bus, loc->devid, loc->function);
+               "%s/" PCI_PRI_FMT "/driver/unbind", pci_get_sysfs_path(),
+               loc->domain, loc->bus, loc->devid, loc->function);
 
        f = fopen(filename, "w");
        if (f == NULL) /* device was not bound */
@@ -190,12 +190,13 @@ pci_find_max_end_va(void)
        return RTE_PTR_ADD(last->addr, last->len);
 }
 
-/* parse the "resource" sysfs file */
-static int
-pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
+/* parse one line of the "resource" sysfs file (note that the 'line'
+ * string is modified)
+ */
+int
+pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
+       uint64_t *end_addr, uint64_t *flags)
 {
-       FILE *f;
-       char buf[BUFSIZ];
        union pci_resource_info {
                struct {
                        char *phys_addr;
@@ -204,6 +205,31 @@ pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
                };
                char *ptrs[PCI_RESOURCE_FMT_NVAL];
        } res_info;
+
+       if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) {
+               RTE_LOG(ERR, EAL,
+                       "%s(): bad resource format\n", __func__);
+               return -1;
+       }
+       errno = 0;
+       *phys_addr = strtoull(res_info.phys_addr, NULL, 16);
+       *end_addr = strtoull(res_info.end_addr, NULL, 16);
+       *flags = strtoull(res_info.flags, NULL, 16);
+       if (errno != 0) {
+               RTE_LOG(ERR, EAL,
+                       "%s(): bad resource format\n", __func__);
+               return -1;
+       }
+
+       return 0;
+}
+
+/* parse the "resource" sysfs file */
+static int
+pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
+{
+       FILE *f;
+       char buf[BUFSIZ];
        int i;
        uint64_t phys_addr, end_addr, flags;
 
@@ -220,21 +246,9 @@ pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
                                "%s(): cannot read resource\n", __func__);
                        goto error;
                }
-
-               if (rte_strsplit(buf, sizeof(buf), res_info.ptrs, 3, ' ') != 3) {
-                       RTE_LOG(ERR, EAL,
-                               "%s(): bad resource format\n", __func__);
+               if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
+                               &end_addr, &flags) < 0)
                        goto error;
-               }
-               errno = 0;
-               phys_addr = strtoull(res_info.phys_addr, NULL, 16);
-               end_addr = strtoull(res_info.end_addr, NULL, 16);
-               flags = strtoull(res_info.flags, NULL, 16);
-               if (errno != 0) {
-                       RTE_LOG(ERR, EAL,
-                               "%s(): bad resource format\n", __func__);
-                       goto error;
-               }
 
                if (flags & IORESOURCE_MEM) {
                        dev->mem_resource[i].phys_addr = phys_addr;
@@ -306,6 +320,16 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
        }
        dev->id.subsystem_device_id = (uint16_t)tmp;
 
+       /* get class_id */
+       snprintf(filename, sizeof(filename), "%s/class",
+                dirname);
+       if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+               free(dev);
+               return -1;
+       }
+       /* the least 24 bits are valid: class, subclass, program interface */
+       dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID;
+
        /* get max_vfs */
        dev->max_vfs = 0;
        snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
@@ -393,6 +417,19 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
        return 0;
 }
 
+int
+pci_update_device(const struct rte_pci_addr *addr)
+{
+       char filename[PATH_MAX];
+
+       snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT,
+                pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
+                addr->function);
+
+       return pci_scan_one(filename, addr->domain, addr->bus, addr->devid,
+                               addr->function);
+}
+
 /*
  * split up a pci address into its constituent parts.
  */
@@ -453,7 +490,7 @@ rte_eal_pci_scan(void)
        uint16_t domain;
        uint8_t bus, devid, function;
 
-       dir = opendir(SYSFS_PCI_DEVICES);
+       dir = opendir(pci_get_sysfs_path());
        if (dir == NULL) {
                RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
                        __func__, strerror(errno));
@@ -468,8 +505,8 @@ rte_eal_pci_scan(void)
                                &bus, &devid, &function) != 0)
                        continue;
 
-               snprintf(dirname, sizeof(dirname), "%s/%s", SYSFS_PCI_DEVICES,
-                        e->d_name);
+               snprintf(dirname, sizeof(dirname), "%s/%s",
+                               pci_get_sysfs_path(), e->d_name);
                if (pci_scan_one(dirname, domain, bus, devid, function) < 0)
                        goto error;
        }
@@ -481,18 +518,6 @@ error:
        return -1;
 }
 
-#ifdef RTE_PCI_CONFIG
-/*
- * It is deprecated, all its configurations have been moved into
- * each PMD respectively.
- */
-void
-pci_config_space_set(__rte_unused struct rte_pci_device *dev)
-{
-       RTE_LOG(DEBUG, EAL, "Nothing here, as it is deprecated\n");
-}
-#endif
-
 /* Read PCI config space. */
 int rte_eal_pci_read_config(const struct rte_pci_device *device,
                            void *buf, size_t len, off_t offset)
@@ -617,8 +642,14 @@ rte_eal_pci_ioport_map(struct rte_pci_device *dev, int bar,
                break;
 #endif
        case RTE_KDRV_IGB_UIO:
+               ret = pci_uio_ioport_map(dev, bar, p);
+               break;
        case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+               ret = pci_ioport_map(dev, bar, p);
+#else
                ret = pci_uio_ioport_map(dev, bar, p);
+#endif
                break;
        case RTE_KDRV_NONE:
 #if defined(RTE_ARCH_X86)
@@ -646,15 +677,18 @@ rte_eal_pci_ioport_read(struct rte_pci_ioport *p,
                break;
 #endif
        case RTE_KDRV_IGB_UIO:
+               pci_uio_ioport_read(p, data, len, offset);
+               break;
        case RTE_KDRV_UIO_GENERIC:
                pci_uio_ioport_read(p, data, len, offset);
                break;
-       default:
+       case RTE_KDRV_NONE:
 #if defined(RTE_ARCH_X86)
-               /* special case for x86 ... */
                pci_uio_ioport_read(p, data, len, offset);
 #endif
                break;
+       default:
+               break;
        }
 }
 
@@ -669,15 +703,18 @@ rte_eal_pci_ioport_write(struct rte_pci_ioport *p,
                break;
 #endif
        case RTE_KDRV_IGB_UIO:
+               pci_uio_ioport_write(p, data, len, offset);
+               break;
        case RTE_KDRV_UIO_GENERIC:
                pci_uio_ioport_write(p, data, len, offset);
                break;
-       default:
+       case RTE_KDRV_NONE:
 #if defined(RTE_ARCH_X86)
-               /* special case for x86 ... */
                pci_uio_ioport_write(p, data, len, offset);
 #endif
                break;
+       default:
+               break;
        }
 }
 
@@ -694,15 +731,22 @@ rte_eal_pci_ioport_unmap(struct rte_pci_ioport *p)
                break;
 #endif
        case RTE_KDRV_IGB_UIO:
+               ret = pci_uio_ioport_unmap(p);
+               break;
        case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+               ret = 0;
+#else
                ret = pci_uio_ioport_unmap(p);
+#endif
                break;
-       default:
+       case RTE_KDRV_NONE:
 #if defined(RTE_ARCH_X86)
-               /* special case for x86 ... nothing to do */
                ret = 0;
 #endif
                break;
+       default:
+               break;
        }
 
        return ret;
@@ -712,9 +756,6 @@ rte_eal_pci_ioport_unmap(struct rte_pci_ioport *p)
 int
 rte_eal_pci_init(void)
 {
-       TAILQ_INIT(&pci_driver_list);
-       TAILQ_INIT(&pci_device_list);
-
        /* for debug purposes, PCI can be disabled */
        if (internal_config.no_pci)
                return 0;
@@ -723,21 +764,6 @@ rte_eal_pci_init(void)
                RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
                return -1;
        }
-#ifdef VFIO_PRESENT
-       pci_vfio_enable();
-
-       if (pci_vfio_is_enabled()) {
-
-               /* if we are primary process, create a thread to communicate with
-                * secondary processes. the thread will use a socket to wait for
-                * requests from secondary process to send open file descriptors,
-                * because VFIO does not allow multiple open descriptors on a group or
-                * VFIO container.
-                */
-               if (internal_config.process_type == RTE_PROC_PRIMARY &&
-                               pci_vfio_mp_sync_setup() < 0)
-                       return -1;
-       }
-#endif
+
        return 0;
 }