1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Intel Corporation 3 */ 4 5 /** 6 * @file 7 * 8 * Device specific vhost lib 9 */ 10 11 #include <stdbool.h> 12 13 #include <rte_malloc.h> 14 #include "rte_vdpa.h" 15 #include "vhost.h" 16 17 static struct rte_vdpa_device *vdpa_devices[MAX_VHOST_DEVICE]; 18 static uint32_t vdpa_device_num; 19 20 static bool 21 is_same_vdpa_device(struct rte_vdpa_dev_addr *a, 22 struct rte_vdpa_dev_addr *b) 23 { 24 bool ret = true; 25 26 if (a->type != b->type) 27 return false; 28 29 switch (a->type) { 30 case PCI_ADDR: 31 if (a->pci_addr.domain != b->pci_addr.domain || 32 a->pci_addr.bus != b->pci_addr.bus || 33 a->pci_addr.devid != b->pci_addr.devid || 34 a->pci_addr.function != b->pci_addr.function) 35 ret = false; 36 break; 37 default: 38 break; 39 } 40 41 return ret; 42 } 43 44 int 45 rte_vdpa_register_device(struct rte_vdpa_dev_addr *addr, 46 struct rte_vdpa_dev_ops *ops) 47 { 48 struct rte_vdpa_device *dev; 49 char device_name[MAX_VDPA_NAME_LEN]; 50 int i; 51 52 if (vdpa_device_num >= MAX_VHOST_DEVICE || addr == NULL || ops == NULL) 53 return -1; 54 55 for (i = 0; i < MAX_VHOST_DEVICE; i++) { 56 dev = vdpa_devices[i]; 57 if (dev && is_same_vdpa_device(&dev->addr, addr)) 58 return -1; 59 } 60 61 for (i = 0; i < MAX_VHOST_DEVICE; i++) { 62 if (vdpa_devices[i] == NULL) 63 break; 64 } 65 66 if (i == MAX_VHOST_DEVICE) 67 return -1; 68 69 snprintf(device_name, sizeof(device_name), "vdpa-dev-%d", i); 70 dev = rte_zmalloc(device_name, sizeof(struct rte_vdpa_device), 71 RTE_CACHE_LINE_SIZE); 72 if (!dev) 73 return -1; 74 75 memcpy(&dev->addr, addr, sizeof(struct rte_vdpa_dev_addr)); 76 dev->ops = ops; 77 vdpa_devices[i] = dev; 78 vdpa_device_num++; 79 80 return i; 81 } 82 83 int 84 rte_vdpa_unregister_device(int did) 85 { 86 if (did < 0 || did >= MAX_VHOST_DEVICE || vdpa_devices[did] == NULL) 87 return -1; 88 89 rte_free(vdpa_devices[did]); 90 vdpa_devices[did] = NULL; 91 vdpa_device_num--; 92 93 return did; 94 } 95 96 int 97 rte_vdpa_find_device_id(struct rte_vdpa_dev_addr *addr) 98 { 99 struct rte_vdpa_device *dev; 100 int i; 101 102 if (addr == NULL) 103 return -1; 104 105 for (i = 0; i < MAX_VHOST_DEVICE; ++i) { 106 dev = vdpa_devices[i]; 107 if (dev && is_same_vdpa_device(&dev->addr, addr)) 108 return i; 109 } 110 111 return -1; 112 } 113 114 struct rte_vdpa_device * 115 rte_vdpa_get_device(int did) 116 { 117 if (did < 0 || did >= MAX_VHOST_DEVICE) 118 return NULL; 119 120 return vdpa_devices[did]; 121 } 122 123 int 124 rte_vdpa_get_device_num(void) 125 { 126 return vdpa_device_num; 127 } 128