As we know, the uacce driver (e.g. hisi_acc DMA driver) reads the API of the hardware device (through /sysfs/class/uacce/xxx/api) and compares it with the API supported by the driver to match the corresponding hardware device.
Hardware devices will continue to evolve, which means their APIs will change, but business requirements demand that they support old programming interfaces as much as possible. To adapt to this situation, this commit supports forward compatibility of driver APIs. For example, if the driver supports the hisi_qm_v5 API, it can drive the hardware device that supports the hisi_qm_v6 or hisi_qm_v7 API. In addition, a driver flag (RTE_UACCE_DRV_FORWARD_COMPATIBILITY_DEV) is introduced. The driver supports forward compatibility of APIs only when this flag is defined. Signed-off-by: Chengwen Feng <[email protected]> --- drivers/bus/uacce/bus_uacce_driver.h | 5 +++ drivers/bus/uacce/uacce.c | 51 ++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/drivers/bus/uacce/bus_uacce_driver.h b/drivers/bus/uacce/bus_uacce_driver.h index 618e0f9b76..c7445778a6 100644 --- a/drivers/bus/uacce/bus_uacce_driver.h +++ b/drivers/bus/uacce/bus_uacce_driver.h @@ -50,6 +50,7 @@ struct rte_uacce_device { char dev_root[RTE_UACCE_DEV_PATH_SIZE]; /**< Sysfs path with device name. */ char cdev_path[RTE_UACCE_DEV_PATH_SIZE]; /**< Device path in devfs. */ char api[RTE_UACCE_API_NAME_SIZE]; /**< Device context type. */ + uint32_t api_ver; /**< Device api version used for compatibility. */ char algs[RTE_UACCE_ALGS_NAME_SIZE]; /**< Device supported algorithms. */ uint32_t flags; /**< Device flags. */ int numa_node; /**< NUMA node connection, -1 if unknown. */ @@ -100,8 +101,12 @@ struct rte_uacce_driver { rte_uacce_probe_t *probe; /**< Device probe function. */ rte_uacce_remove_t *remove; /**< Device remove function. */ const struct rte_uacce_id *id_table; /**< ID table, NULL terminated. */ + uint32_t drv_flags; /**< Flags RTE_UACCE_DRV_*. */ }; +/** Device driver supports forward compatibility device */ +#define RTE_UACCE_DRV_FORWARD_COMPATIBILITY_DEV 0x1 + /** * Get available queue number. * diff --git a/drivers/bus/uacce/uacce.c b/drivers/bus/uacce/uacce.c index 79f990c54c..a471edcad0 100644 --- a/drivers/bus/uacce/uacce.c +++ b/drivers/bus/uacce/uacce.c @@ -2,6 +2,7 @@ * Copyright(c) 2024 HiSilicon Limited */ +#include <ctype.h> #include <dirent.h> #include <errno.h> #include <fcntl.h> @@ -324,19 +325,62 @@ uacce_scan(void) return -1; } +static uint32_t +uacce_calc_api_ver(const char *api, int *offset) +{ + int len = strlen(api); + int end = len - 1; + unsigned long ver; + + while (end >= 0 && isdigit(api[end])) + end--; + + if (end <= 0 || end == len - 1 || api[end] != 'v') + return 0; + + ver = strtoul(api + end + 1, NULL, 10); + if (ver > UINT32_MAX) + return 0; + + if (offset != NULL) + *offset = end + 1; + return (uint32_t)ver; +} + +static bool +uacce_match_api(const struct rte_uacce_device *dev, bool forward_compat, + const struct rte_uacce_id *id_table) +{ + int dev_ver_off = 0, id_ver_off = 0; + uint32_t dev_ver, id_ver; + + if (!forward_compat) + return strcmp(id_table->dev_api, dev->api) == 0; + + dev_ver = uacce_calc_api_ver(dev->api, &dev_ver_off); + id_ver = uacce_calc_api_ver(id_table->dev_api, &id_ver_off); + return dev_ver > 0 && id_ver > 0 && dev_ver_off == id_ver_off && + strncmp(id_table->dev_api, dev->api, dev_ver_off) == 0 && + dev_ver >= id_ver; +} + static bool -uacce_match(const struct rte_uacce_driver *dr, const struct rte_uacce_device *dev) +uacce_match(const struct rte_uacce_driver *dr, struct rte_uacce_device *dev) { + bool forward_compat = !!(dr->drv_flags & RTE_UACCE_DRV_FORWARD_COMPATIBILITY_DEV); + uint32_t api_ver = uacce_calc_api_ver(dev->api, NULL); const struct rte_uacce_id *id_table; const char *map; uint32_t len; for (id_table = dr->id_table; id_table->dev_api != NULL; id_table++) { - if (strcmp(id_table->dev_api, dev->api) != 0) + if (!uacce_match_api(dev, forward_compat, id_table)) continue; - if (id_table->dev_alg == NULL) + if (id_table->dev_alg == NULL) { + dev->api_ver = api_ver; return true; + } /* The dev->algs's algrothims is separated by new line, for * example: dev->algs could be: aaa\nbbbb\ncc, which has three @@ -352,6 +396,7 @@ uacce_match(const struct rte_uacce_driver *dr, const struct rte_uacce_device *de if (map[len] != '\0' && map[len] != '\n') continue; + dev->api_ver = api_ver; return true; } -- 2.17.1

