xref: /f-stack/dpdk/lib/librte_vhost/vdpa.c (revision 16d80a6d)
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