From patchwork Thu Dec 22 00:01:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 121241 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id EF265A034C; Thu, 22 Dec 2022 01:01:24 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D6D2440A7F; Thu, 22 Dec 2022 01:01:24 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 976F540698 for ; Thu, 22 Dec 2022 01:01:23 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BLIGXoQ018295; Wed, 21 Dec 2022 16:01:22 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=EUWtMVoX7b3esX+Fkn6t5VPYJvs+2qa6ebdrqcIEdA8=; b=A/LQ++sJXjBKjUXwzH1QMKeAbSFFGd9g2RxXoNSLuMVlcDmatpM1DpzgU4L6yR9iklWf +zX9wGMnC6HNVZv0JY8ovkXMg/IlaR4zLSR+Dax+TU7llOwulpNAlkqTjSJe0cbirLpq JtK5DfsksEypfDVjLXJpVxSYJBvLjxsdbE4G/NqHP2OiqtBJPuLx1J1YKjQt/eZC422y KZvS+G2/S2kC8qKI1sygoT4enIxQ9yN2mG/B7L7J/KC8wGm37iTaWDWClhiFz8XEI/VG sfo90jvorA+30lve+Tlr0Iz8s/YAE4HwL/yJKHgbJnb48dUyF3s9hcplXY1oFREs+Zri +Q== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3mm79c1g8c-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 21 Dec 2022 16:01:22 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Wed, 21 Dec 2022 16:01:20 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.42 via Frontend Transport; Wed, 21 Dec 2022 16:01:20 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 0FF665B6948; Wed, 21 Dec 2022 16:01:18 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [RFC PATCH] bus/platform: add platform bus Date: Thu, 22 Dec 2022 01:01:06 +0100 Message-ID: <20221222000106.270619-1-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: 0fJZUNOkQQbCXFnxvAoHPqkkuYK3OhvQ X-Proofpoint-GUID: 0fJZUNOkQQbCXFnxvAoHPqkkuYK3OhvQ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-21_13,2022-12-21_01,2022-06-22_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Platform bus is a software bus under Linux that manages devices which generally do not have built-in discovery mechanisms. Linux normally learns about platform devices directly from device-tree during boot-up phase. Up to this point, whenever some userspace app needed control over platform device or a range of thereof some sort of driver being a mixture of vdev/rawdev was required. In order to simplify this task, provide an auto-probe experience and separate bus logic from the driver itself, add platform bus support. Signed-off-by: Tomasz Duszynski --- drivers/bus/meson.build | 1 + drivers/bus/platform/meson.build | 17 + drivers/bus/platform/platform.c | 394 ++++++++++++++++++++++++ drivers/bus/platform/platform_params.c | 70 +++++ drivers/bus/platform/private.h | 47 +++ drivers/bus/platform/rte_bus_platform.h | 165 ++++++++++ drivers/bus/platform/version.map | 10 + 7 files changed, 704 insertions(+) create mode 100644 drivers/bus/platform/meson.build create mode 100644 drivers/bus/platform/platform.c create mode 100644 drivers/bus/platform/platform_params.c create mode 100644 drivers/bus/platform/private.h create mode 100644 drivers/bus/platform/rte_bus_platform.h create mode 100644 drivers/bus/platform/version.map -- 2.25.1 diff --git a/drivers/bus/meson.build b/drivers/bus/meson.build index 45eab5233d..6d2520c543 100644 --- a/drivers/bus/meson.build +++ b/drivers/bus/meson.build @@ -7,6 +7,7 @@ drivers = [ 'fslmc', 'ifpga', 'pci', + 'platform', 'vdev', 'vmbus', ] diff --git a/drivers/bus/platform/meson.build b/drivers/bus/platform/meson.build new file mode 100644 index 0000000000..b51d757a07 --- /dev/null +++ b/drivers/bus/platform/meson.build @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(C) 2023 Marvell. +# + +if not is_linux + build = false + reason = 'only supported on Linux' +endif + +deps += ['kvargs'] +sources = files( + 'platform_params.c', + 'platform.c', +) +headers = files( + 'rte_bus_platform.h', +) diff --git a/drivers/bus/platform/platform.c b/drivers/bus/platform/platform.c new file mode 100644 index 0000000000..d489dde7ed --- /dev/null +++ b/drivers/bus/platform/platform.c @@ -0,0 +1,394 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2023 Marvell. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "eal_filesystem.h" +#include "private.h" + +#define PLATFORM_BUS_DEVICES_PATH "/sys/bus/platform/devices" + +void +rte_platform_register(struct rte_platform_driver *pdrv) +{ + TAILQ_INSERT_TAIL(&platform_bus.driver_list, pdrv, next); +} + +void +rte_platform_unregister(struct rte_platform_driver *pdrv) +{ + TAILQ_REMOVE(&platform_bus.driver_list, pdrv, next); +} + +static int +parse_sysfs_value(const char *path, unsigned long *val) +{ + if (access(path, F_OK)) + return -1; + + return eal_parse_sysfs_value(path, val); +} + +static struct rte_devargs * +device_devargs(const char *dev_name) +{ + struct rte_devargs *devargs; + + RTE_EAL_DEVARGS_FOREACH("platform", devargs) { + if (!strcmp(devargs->name, dev_name)) + return devargs; + } + + return NULL; +} + +static bool +device_allowed(const char *dev_name) +{ + struct rte_devargs *devargs; + + devargs = device_devargs(dev_name); + if (!devargs) + return true; + + switch (platform_bus.bus.conf.scan_mode) { + case RTE_BUS_SCAN_UNDEFINED: + case RTE_BUS_SCAN_ALLOWLIST: + if (devargs->policy == RTE_DEV_ALLOWED) + return true; + break; + case RTE_BUS_SCAN_BLOCKLIST: + if (devargs->policy == RTE_DEV_BLOCKED) + return false; + break; + } + + return true; +} + +static struct rte_platform_driver * +device_lookup_driver(const char *dev_name) +{ + struct rte_platform_driver *pdrv = NULL; + char buf[BUFSIZ] = { }; + char path[PATH_MAX]; + char *p; + int ret; + + snprintf(path, sizeof(path), PLATFORM_BUS_DEVICES_PATH "/%s/driver", dev_name); + /* save space for terminating null byte */ + ret = readlink(path, buf, sizeof(buf) - 1); + if (ret <= 0) + return NULL; + + /* last token is kernel driver name */ + p = strrchr(buf, '/'); + if (!p++) + return NULL; + + FOREACH_DRIVER_ON_PLATFORM_BUS(pdrv) { + /* match by driver name */ + if (!strcmp(p, pdrv->driver.name)) + break; + + /* match by driver alias */ + if (pdrv->driver.alias) { + if (!strcmp(p, pdrv->driver.alias)) + break; + } + + /* match by device name */ + if (!strcmp(dev_name, pdrv->driver.name)) + break; + } + + return pdrv; +} + +static int +device_add(const char *dev_name) +{ + struct rte_platform_device *pdev; + char path[PATH_MAX]; + unsigned long val; + + pdev = calloc(1, sizeof(*pdev)); + if (!pdev) + return -ENOMEM; + + strncpy(pdev->name, dev_name, RTE_DEV_NAME_MAX_LEN); + pdev->device.name = pdev->name; + pdev->device.bus = &platform_bus.bus; + + snprintf(path, sizeof(path), PLATFORM_BUS_DEVICES_PATH "/%s/numa_node", dev_name); + pdev->device.numa_node = parse_sysfs_value(path, &val) ? rte_socket_id() : val; + + TAILQ_INSERT_HEAD(&platform_bus.device_list, pdev, next); + + PLATFORM_LOG(INFO, "adding %s to the platform devices list\n", dev_name); + + return 0; +} + +static int +platform_bus_scan(void) +{ + const struct dirent *ent; + const char *name; + int ret = 0; + DIR *dp; + + if (!(dp = opendir(PLATFORM_BUS_DEVICES_PATH))) { + PLATFORM_LOG(INFO, "failed to open %s\n", PLATFORM_BUS_DEVICES_PATH); + + return -errno; + } + + while ((ent = readdir(dp))) { + name = ent->d_name; + + if (name[0] == '.') + continue; + + if (!device_allowed(name)) + continue; + + if (!device_lookup_driver(name)) + continue; + + ret = device_add(name); + if (ret) + break; + } + + closedir(dp); + + return ret; +} + +static int +platform_probe(struct rte_platform_device *pdev) +{ + struct rte_platform_driver *pdrv; + enum rte_iova_mode iova_mode; + int ret; + + if (!pdev) + return -EINVAL; + + pdrv = device_lookup_driver(pdev->name); + if (!pdrv) + return -ENODEV; + + iova_mode = rte_eal_iova_mode(); + if (pdrv->drv_flags & RTE_PLATFORM_DRV_NEED_IOVA_AS_VA && iova_mode != RTE_IOVA_VA) { + PLATFORM_LOG(ERR, "Driver %s expects VA IOVA mode but current mode is PA\n", + pdrv->driver.name); + + return -EINVAL; + } + + if (!pdrv->probe) + return -ENOTSUP; + + pdev->driver = pdrv; + + ret = pdrv->probe(pdev); + if (ret) + return ret; + + pdev->device.driver = &pdrv->driver; + + return 0; +} + +static int +platform_remove(struct rte_platform_device *pdev) +{ + struct rte_platform_driver *pdrv; + int ret; + + if (!pdev) + return -EINVAL; + + pdrv = pdev->driver; + if (pdrv->remove) { + ret = pdrv->remove(pdev); + if (ret) + return ret; + } + + pdev->driver = NULL; + pdev->device.driver = NULL; + + TAILQ_REMOVE(&platform_bus.device_list, pdev, next); + rte_devargs_remove(pdev->device.devargs); + free(pdrv); + + return 0; +} + +static int +platform_bus_probe(void) +{ + struct rte_platform_device *pdev; + int ret; + + FOREACH_DEVICE_ON_PLATFORM_BUS(pdev) { + ret = platform_probe(pdev); + if (ret) + PLATFORM_LOG(ERR, "failed to probe %s\n", pdev->name); + } + + return 0; +} + +static struct rte_device * +platform_bus_find_device(const struct rte_device *start, rte_dev_cmp_t cmp, const void *data) +{ + struct rte_platform_device *pdev; + + pdev = start ? RTE_TAILQ_NEXT(RTE_DEV_TO_PLATFORM_DEV_CONST(start), next) : + RTE_TAILQ_FIRST(&platform_bus.device_list); + while (pdev) { + if (cmp(&pdev->device, data) == 0) + return &pdev->device; + + pdev = RTE_TAILQ_NEXT(pdev, next); + } + + return NULL; +} + +static bool +device_exists(const char *dev_name) +{ + char path[PATH_MAX]; + + snprintf(path, sizeof(path), PLATFORM_BUS_DEVICES_PATH "/%s", dev_name); + + return access(path, R_OK) == 0; +} + +static int +platform_bus_plug(struct rte_device *dev) +{ + if (!device_exists(dev->name)) + return -ENODEV; + + if (device_allowed(dev->name)) { + PLATFORM_LOG(WARNING, "Device not allowed\n"); + + return -ENODEV; + } + + return platform_probe(RTE_DEV_TO_PLATFORM_DEV(dev)); +} + +static int +platform_bus_unplug(struct rte_device *dev) +{ + struct rte_platform_device *pdev = RTE_DEV_TO_PLATFORM_DEV(dev); + + return platform_remove(pdev); +} + +static int +platform_bus_parse(const char *name, void *addr) +{ + struct rte_platform_driver *pdrv; + const char **out = addr; + + pdrv = device_lookup_driver(name); + if (pdrv && addr) + *out = name; + + return pdrv ? 0 : -1; +} + +static int +platform_bus_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t len) +{ + struct rte_platform_device *pdev = RTE_DEV_TO_PLATFORM_DEV(dev); + + if (!pdev || !pdev->driver) { + rte_errno = EINVAL; + + return -1; + } + + if (!pdev->driver->dma_map) { + rte_errno = ENOTSUP; + + return -1; + } + + return pdev->driver->dma_map(pdev, addr, iova, len); +} + +static int +platform_bus_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, size_t len) +{ + + struct rte_platform_device *pdev = RTE_DEV_TO_PLATFORM_DEV(dev); + + if (!pdev || !pdev->driver) { + rte_errno = EINVAL; + + return -1; + } + + if (!pdev->driver->dma_unmap) { + rte_errno = ENOTSUP; + + return -1; + } + + return pdev->driver->dma_unmap(pdev, addr, iova, len); +} + +static enum rte_iova_mode +platform_bus_get_iommu_class(void) +{ + struct rte_platform_driver *pdrv; + + FOREACH_DRIVER_ON_PLATFORM_BUS(pdrv) { + if (pdrv->drv_flags & RTE_PLATFORM_DRV_NEED_IOVA_AS_VA) + return RTE_IOVA_VA; + } + + return RTE_IOVA_DC; +} + +struct rte_platform_bus platform_bus = { + .bus = { + .scan = platform_bus_scan, + .probe = platform_bus_probe, + .find_device = platform_bus_find_device, + .plug = platform_bus_plug, + .unplug = platform_bus_unplug, + .parse = platform_bus_parse, + .dma_map = platform_bus_dma_map, + .dma_unmap = platform_bus_dma_unmap, + .get_iommu_class = platform_bus_get_iommu_class, + .dev_iterate = platform_bus_dev_iterate, + }, + .device_list = TAILQ_HEAD_INITIALIZER(platform_bus.device_list), + .driver_list = TAILQ_HEAD_INITIALIZER(platform_bus.driver_list), +}; + +RTE_REGISTER_BUS(platform_bus, platform_bus.bus); +RTE_LOG_REGISTER_DEFAULT(platform_bus_logtype, NOTICE); diff --git a/drivers/bus/platform/platform_params.c b/drivers/bus/platform/platform_params.c new file mode 100644 index 0000000000..86e8587b82 --- /dev/null +++ b/drivers/bus/platform/platform_params.c @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2023 Marvell. + */ + +#include + +#include +#include +#include +#include +#include + +#include "private.h" +#include "rte_bus_platform.h" + +enum platform_params { + RTE_PLATFORM_PARAM_NAME, +}; + +static const char * const platform_params_keys[] = { + [RTE_PLATFORM_PARAM_NAME] = "name", + NULL +}; + +static int +platform_dev_match(const struct rte_device *dev, const void *_kvlist) +{ + const char *key = platform_params_keys[RTE_PLATFORM_PARAM_NAME]; + const struct rte_kvargs *kvlist = _kvlist; + const char *name; + + /* no kvlist arg, all devices match */ + if (!kvlist) + return 0; + + /* if key is present in kvlist and does not match, filter device */ + name = rte_kvargs_get(kvlist, key); + if (name && strcmp(name, dev->name)) + return -1; + + return 0; +} + +void * +platform_bus_dev_iterate(const void *start, const char *str, + const struct rte_dev_iterator *it __rte_unused) +{ + rte_bus_find_device_t find_device; + struct rte_kvargs *kvargs = NULL; + struct rte_device *dev; + + if (str) { + kvargs = rte_kvargs_parse(str, platform_params_keys); + if (!kvargs) { + PLATFORM_LOG(ERR, "cannot parse argument list %s", str); + rte_errno = EINVAL; + + return NULL; + } + } + + find_device = platform_bus.bus.find_device; + if (!find_device) + return NULL; + + dev = platform_bus.bus.find_device(start, platform_dev_match, kvargs); + rte_kvargs_free(kvargs); + + return dev; +} diff --git a/drivers/bus/platform/private.h b/drivers/bus/platform/private.h new file mode 100644 index 0000000000..988803080f --- /dev/null +++ b/drivers/bus/platform/private.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2023 Marvell. + */ + +#ifndef _RTE_BUS_PLATFORM_PRIVATE_H_ +#define _RTE_BUS_PLATFORM_PRIVATE_H_ + +#include +#include +#include +#include +#include + +#include "rte_bus_platform.h" + +extern struct rte_platform_bus platform_bus; +extern int platform_bus_logtype; + +/* Platform bus iterators. */ +#define FOREACH_DEVICE_ON_PLATFORM_BUS(p) \ + RTE_TAILQ_FOREACH(p, &(platform_bus.device_list), next) + +#define FOREACH_DRIVER_ON_PLATFORM_BUS(p) \ + RTE_TAILQ_FOREACH(p, &(platform_bus.driver_list), next) + +/* + * Structure describing platform bus. + */ +struct rte_platform_bus { + struct rte_bus bus; /* Core bus */ + RTE_TAILQ_HEAD(, rte_platform_device) device_list; /* List of bus devices */ + RTE_TAILQ_HEAD(, rte_platform_driver) driver_list; /* List of bus drivers */ +}; + +#define PLATFORM_LOG(level, ...) \ + rte_log(RTE_LOG_ ## level, platform_bus_logtype, \ + RTE_FMT("platform bus: " RTE_FMT_HEAD(__VA_ARGS__,) , \ + RTE_FMT_TAIL(__VA_ARGS__,))) + +/* + * Iterate registered platform devices and find one that matches provided string. + */ +void * +platform_bus_dev_iterate(const void *start, const char *str, + const struct rte_dev_iterator *it __rte_unused); + +#endif /* _RTE_BUS_PLATFORM_PRIVATE_H_ */ diff --git a/drivers/bus/platform/rte_bus_platform.h b/drivers/bus/platform/rte_bus_platform.h new file mode 100644 index 0000000000..5e5cdb166b --- /dev/null +++ b/drivers/bus/platform/rte_bus_platform.h @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2023 Marvell. + */ + +#ifndef _RTE_BUS_PLATFORM_H_ +#define _RTE_BUS_PLATFORM_H_ + +/** + * @file + * Platform bus interface. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#include +#include +#include + +/* Forward declarations */ +struct rte_platform_bus; +struct rte_platform_device; +struct rte_platform_driver; + +/** + * Initialization function for the driver called during platform device probing. + * + * @param pdev + * Pointer to the platform device. + * @return + * 0 on success, negative value otherwise. + */ +typedef int (rte_platform_probe_t)(struct rte_platform_device *pdev); + +/** + * Removal function for the driver called during platform device removal. + * + * @param pdev + * Pointer to the platform device. + * @return + * 0 on success, negative value otherwise. + */ +typedef int (rte_platform_remove_t)(struct rte_platform_device *pdev); + +/** + * Driver specific DMA mapping. + * + * @param pdev + * Pointer to the platform device. + * @param addr + * Starting virtual address of memory to be mapped. + * @param iova + * Starting IOVA address of memory to be mapped. + * @param len + * Length of memory segment being mapped. + * @return + * - 0 on success. + * - Negative value and rte_errno is set otherwise. + */ +typedef int (rte_platform_dma_map_t)(struct rte_platform_device *pdev, void *addr, uint64_t iova, + size_t len); + +/** + * Driver specific DMA unmapping. + * + * @param pdev + * Pointer to the platform device. + * @param addr + * Starting virtual address of memory to be mapped. + * @param iova + * Starting IOVA address of memory to be mapped. + * @param len + * Length of memory segment being mapped. + * @return + * - 0 on success. + * - Negative value and rte_errno is set otherwise. + */ +typedef int (rte_platform_dma_unmap_t)(struct rte_platform_device *pdev, void *addr, uint64_t iova, + size_t len); + +/** + * A structure describing a platform device. + */ +struct rte_platform_device { + RTE_TAILQ_ENTRY(rte_platform_device) next; /**< Next attached platform device */ + struct rte_device device; /**< Core device */ + struct rte_platform_driver *driver; /**< Matching device driver */ + char name[RTE_DEV_NAME_MAX_LEN + 1]; /**< Device name */ + void *driver_data; /**< Driver data */ +}; + +/** + * A structure describing a platform device driver. + */ +struct rte_platform_driver { + RTE_TAILQ_ENTRY(rte_platform_driver) next; /**< Next available platform driver */ + struct rte_driver driver; /**< Core driver */ + rte_platform_probe_t *probe; /**< Device probe function */ + rte_platform_remove_t *remove; /**< Device remove function */ + rte_platform_dma_map_t *dma_map; /**< Device DMA map function */ + rte_platform_dma_unmap_t *dma_unmap; /**< Device DMA unmap function */ + /** Device driver needs IOVA as VA and cannot work with IOVA as VA */ +#define RTE_PLATFORM_DRV_NEED_IOVA_AS_VA 0x0001 + uint32_t drv_flags; /**< Driver flags */ +}; + +/** + * @internal + * Helper macros used to convert core device to platform device. + */ +#define RTE_DEV_TO_PLATFORM_DEV(ptr) \ + container_of(ptr, struct rte_platform_device, device) + +#define RTE_DEV_TO_PLATFORM_DEV_CONST(ptr) \ + container_of(ptr, const struct rte_platform_device, device) + +/** + * Register a platform device driver. + * + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * @param pdrv + * A pointer to a rte_platform_driver structure describing driver to be registered. + */ +__rte_experimental +void rte_platform_register(struct rte_platform_driver *pdrv); + +/** Helper for platform driver registration. */ +#define RTE_PMD_REGISTER_PLATFORM(nm, platform_drv) \ +static const char *pdrvinit_ ## nm ## _alias; \ +RTE_INIT(pdrvinitfn_ ##nm) \ +{ \ + (platform_drv).driver.name = RTE_STR(nm); \ + (platform_drv).driver.alias = pdrvinit_ ## nm ## _alias; \ + rte_platform_register(&(platform_drv)); \ +} \ +RTE_PMD_EXPORT_NAME(nm, __COUNTER__) + +/** Helper for setting platform driver alias. */ +#define RTE_PMD_REGISTER_ALIAS(nm, alias) \ +static const char *pdrvinit_ ## nm ## _alias = RTE_STR(alias) + +/** + * Unregister a platform device driver. + * + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * @param pdrv + * A pointer to a rte_platform_driver structure describing driver to be unregistered. + */ +__rte_experimental +void rte_platform_unregister(struct rte_platform_driver *pdrv); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_BUS_PLATFORM_H_ */ diff --git a/drivers/bus/platform/version.map b/drivers/bus/platform/version.map new file mode 100644 index 0000000000..ee77a6beff --- /dev/null +++ b/drivers/bus/platform/version.map @@ -0,0 +1,10 @@ +DPDK_23 { + local: *; +}; + +EXPERIMENTAL { + global: + + rte_platform_register; + rte_platform_unregister; +};