1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Gaëtan Rivet 3 */ 4 5 #include "rte_ethdev.h" 6 #include "rte_ethdev_driver.h" 7 #include "ethdev_private.h" 8 9 uint16_t 10 eth_dev_to_id(const struct rte_eth_dev *dev) 11 { 12 if (dev == NULL) 13 return RTE_MAX_ETHPORTS; 14 return dev - rte_eth_devices; 15 } 16 17 struct rte_eth_dev * 18 eth_find_device(const struct rte_eth_dev *start, rte_eth_cmp_t cmp, 19 const void *data) 20 { 21 struct rte_eth_dev *edev; 22 ptrdiff_t idx; 23 24 /* Avoid Undefined Behaviour */ 25 if (start != NULL && 26 (start < &rte_eth_devices[0] || 27 start > &rte_eth_devices[RTE_MAX_ETHPORTS])) 28 return NULL; 29 if (start != NULL) 30 idx = eth_dev_to_id(start) + 1; 31 else 32 idx = 0; 33 for (; idx < RTE_MAX_ETHPORTS; idx++) { 34 edev = &rte_eth_devices[idx]; 35 if (cmp(edev, data) == 0) 36 return edev; 37 } 38 return NULL; 39 } 40 41 int 42 rte_eth_devargs_parse_list(char *str, rte_eth_devargs_callback_t callback, 43 void *data) 44 { 45 char *str_start; 46 int state; 47 int result; 48 49 if (*str != '[') 50 /* Single element, not a list */ 51 return callback(str, data); 52 53 /* Sanity check, then strip the brackets */ 54 str_start = &str[strlen(str) - 1]; 55 if (*str_start != ']') { 56 RTE_LOG(ERR, EAL, "(%s): List does not end with ']'\n", str); 57 return -EINVAL; 58 } 59 str++; 60 *str_start = '\0'; 61 62 /* Process list elements */ 63 state = 0; 64 while (1) { 65 if (state == 0) { 66 if (*str == '\0') 67 break; 68 if (*str != ',') { 69 str_start = str; 70 state = 1; 71 } 72 } else if (state == 1) { 73 if (*str == ',' || *str == '\0') { 74 if (str > str_start) { 75 /* Non-empty string fragment */ 76 *str = '\0'; 77 result = callback(str_start, data); 78 if (result < 0) 79 return result; 80 } 81 state = 0; 82 } 83 } 84 str++; 85 } 86 return 0; 87 } 88 89 static int 90 rte_eth_devargs_process_range(char *str, uint16_t *list, uint16_t *len_list, 91 const uint16_t max_list) 92 { 93 uint16_t lo, hi, val; 94 int result; 95 96 result = sscanf(str, "%hu-%hu", &lo, &hi); 97 if (result == 1) { 98 if (*len_list >= max_list) 99 return -ENOMEM; 100 list[(*len_list)++] = lo; 101 } else if (result == 2) { 102 if (lo >= hi || lo > RTE_MAX_ETHPORTS || hi > RTE_MAX_ETHPORTS) 103 return -EINVAL; 104 for (val = lo; val <= hi; val++) { 105 if (*len_list >= max_list) 106 return -ENOMEM; 107 list[(*len_list)++] = val; 108 } 109 } else 110 return -EINVAL; 111 return 0; 112 } 113 114 int 115 rte_eth_devargs_parse_representor_ports(char *str, void *data) 116 { 117 struct rte_eth_devargs *eth_da = data; 118 119 return rte_eth_devargs_process_range(str, eth_da->representor_ports, 120 ð_da->nb_representor_ports, RTE_MAX_ETHPORTS); 121 } 122