1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2018 Gaëtan Rivet 3 */ 4 5 #include <rte_bus.h> 6 #include <rte_bus_pci.h> 7 #include <rte_dev.h> 8 #include <rte_errno.h> 9 #include <rte_kvargs.h> 10 #include <rte_pci.h> 11 12 #include "private.h" 13 14 enum pci_params { 15 RTE_PCI_PARAMS_ID, 16 RTE_PCI_PARAMS_MAX, 17 }; 18 19 static const char * const pci_params_keys[] = { 20 [RTE_PCI_PARAMS_ID] = "id", 21 [RTE_PCI_PARAMS_MAX] = NULL, 22 }; 23 24 static int 25 pci_addr_kv_cmp(const char *key __rte_unused, 26 const char *value, 27 void *_addr2) 28 { 29 struct rte_pci_addr _addr1; 30 struct rte_pci_addr *addr1 = &_addr1; 31 struct rte_pci_addr *addr2 = _addr2; 32 33 if (rte_pci_addr_parse(value, addr1)) 34 return -1; 35 return -abs(rte_pci_addr_cmp(addr1, addr2)); 36 } 37 38 static int 39 pci_dev_match(const struct rte_device *dev, 40 const void *_kvlist) 41 { 42 const struct rte_kvargs *kvlist = _kvlist; 43 const struct rte_pci_device *pdev; 44 45 if (kvlist == NULL) 46 /* Empty string matches everything. */ 47 return 0; 48 pdev = RTE_DEV_TO_PCI_CONST(dev); 49 /* if any field does not match. */ 50 if (rte_kvargs_process(kvlist, "id", 51 &pci_addr_kv_cmp, 52 (void *)(intptr_t)&pdev->addr)) 53 return 1; 54 return 0; 55 } 56 57 void * 58 rte_pci_dev_iterate(const void *start, 59 const char *str, 60 const struct rte_dev_iterator *it __rte_unused) 61 { 62 rte_bus_find_device_t find_device; 63 struct rte_kvargs *kvargs = NULL; 64 struct rte_device *dev; 65 66 if (str != NULL) { 67 kvargs = rte_kvargs_parse(str, pci_params_keys); 68 if (kvargs == NULL) { 69 RTE_LOG(ERR, EAL, "cannot parse argument list\n"); 70 rte_errno = EINVAL; 71 return NULL; 72 } 73 } 74 find_device = rte_pci_bus.bus.find_device; 75 dev = find_device(start, pci_dev_match, kvargs); 76 rte_kvargs_free(kvargs); 77 return dev; 78 } 79