42a4693bd9eea6c3bd30ccb7683247cca4593ff2
[dpdk.git] / lib / dmadev / rte_dmadev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2021 HiSilicon Limited
3  * Copyright(c) 2021 Intel Corporation
4  */
5
6 #include <inttypes.h>
7
8 #include <rte_eal.h>
9 #include <rte_lcore.h>
10 #include <rte_log.h>
11 #include <rte_malloc.h>
12 #include <rte_memzone.h>
13 #include <rte_string_fns.h>
14
15 #include "rte_dmadev.h"
16 #include "rte_dmadev_pmd.h"
17
18 static int16_t dma_devices_max;
19
20 struct rte_dma_dev *rte_dma_devices;
21
22 RTE_LOG_REGISTER_DEFAULT(rte_dma_logtype, INFO);
23 #define RTE_DMA_LOG(level, ...) \
24         rte_log(RTE_LOG_ ## level, rte_dma_logtype, RTE_FMT("dma: " \
25                 RTE_FMT_HEAD(__VA_ARGS__,) "\n", RTE_FMT_TAIL(__VA_ARGS__,)))
26
27 int
28 rte_dma_dev_max(size_t dev_max)
29 {
30         /* This function may be called before rte_eal_init(), so no rte library
31          * function can be called in this function.
32          */
33         if (dev_max == 0 || dev_max > INT16_MAX)
34                 return -EINVAL;
35
36         if (dma_devices_max > 0)
37                 return -EINVAL;
38
39         dma_devices_max = dev_max;
40
41         return 0;
42 }
43
44 static int
45 dma_check_name(const char *name)
46 {
47         size_t name_len;
48
49         if (name == NULL) {
50                 RTE_DMA_LOG(ERR, "Name can't be NULL");
51                 return -EINVAL;
52         }
53
54         name_len = strnlen(name, RTE_DEV_NAME_MAX_LEN);
55         if (name_len == 0) {
56                 RTE_DMA_LOG(ERR, "Zero length DMA device name");
57                 return -EINVAL;
58         }
59         if (name_len >= RTE_DEV_NAME_MAX_LEN) {
60                 RTE_DMA_LOG(ERR, "DMA device name is too long");
61                 return -EINVAL;
62         }
63
64         return 0;
65 }
66
67 static int16_t
68 dma_find_free_id(void)
69 {
70         int16_t i;
71
72         if (rte_dma_devices == NULL)
73                 return -1;
74
75         for (i = 0; i < dma_devices_max; i++) {
76                 if (rte_dma_devices[i].state == RTE_DMA_DEV_UNUSED)
77                         return i;
78         }
79
80         return -1;
81 }
82
83 static struct rte_dma_dev*
84 dma_find_by_name(const char *name)
85 {
86         int16_t i;
87
88         if (rte_dma_devices == NULL)
89                 return NULL;
90
91         for (i = 0; i < dma_devices_max; i++) {
92                 if ((rte_dma_devices[i].state != RTE_DMA_DEV_UNUSED) &&
93                     (!strcmp(name, rte_dma_devices[i].dev_name)))
94                         return &rte_dma_devices[i];
95         }
96
97         return NULL;
98 }
99
100 static int
101 dma_dev_data_prepare(void)
102 {
103         size_t size;
104
105         if (rte_dma_devices != NULL)
106                 return 0;
107
108         size = dma_devices_max * sizeof(struct rte_dma_dev);
109         rte_dma_devices = malloc(size);
110         if (rte_dma_devices == NULL)
111                 return -ENOMEM;
112         memset(rte_dma_devices, 0, size);
113
114         return 0;
115 }
116
117 static int
118 dma_data_prepare(void)
119 {
120         if (dma_devices_max == 0)
121                 dma_devices_max = RTE_DMADEV_DEFAULT_MAX;
122         return dma_dev_data_prepare();
123 }
124
125 static struct rte_dma_dev *
126 dma_allocate(const char *name, int numa_node, size_t private_data_size)
127 {
128         struct rte_dma_dev *dev;
129         void *dev_private;
130         int16_t dev_id;
131         int ret;
132
133         ret = dma_data_prepare();
134         if (ret < 0) {
135                 RTE_DMA_LOG(ERR, "Cannot initialize dmadevs data");
136                 return NULL;
137         }
138
139         dev = dma_find_by_name(name);
140         if (dev != NULL) {
141                 RTE_DMA_LOG(ERR, "DMA device already allocated");
142                 return NULL;
143         }
144
145         dev_private = rte_zmalloc_socket(name, private_data_size,
146                                          RTE_CACHE_LINE_SIZE, numa_node);
147         if (dev_private == NULL) {
148                 RTE_DMA_LOG(ERR, "Cannot allocate private data");
149                 return NULL;
150         }
151
152         dev_id = dma_find_free_id();
153         if (dev_id < 0) {
154                 RTE_DMA_LOG(ERR, "Reached maximum number of DMA devices");
155                 rte_free(dev_private);
156                 return NULL;
157         }
158
159         dev = &rte_dma_devices[dev_id];
160         rte_strscpy(dev->dev_name, name, sizeof(dev->dev_name));
161         dev->dev_id = dev_id;
162         dev->numa_node = numa_node;
163         dev->dev_private = dev_private;
164
165         return dev;
166 }
167
168 static void
169 dma_release(struct rte_dma_dev *dev)
170 {
171         rte_free(dev->dev_private);
172         memset(dev, 0, sizeof(struct rte_dma_dev));
173 }
174
175 struct rte_dma_dev *
176 rte_dma_pmd_allocate(const char *name, int numa_node, size_t private_data_size)
177 {
178         struct rte_dma_dev *dev;
179
180         if (dma_check_name(name) != 0 || private_data_size == 0)
181                 return NULL;
182
183         dev = dma_allocate(name, numa_node, private_data_size);
184         if (dev == NULL)
185                 return NULL;
186
187         dev->state = RTE_DMA_DEV_REGISTERED;
188
189         return dev;
190 }
191
192 int
193 rte_dma_pmd_release(const char *name)
194 {
195         struct rte_dma_dev *dev;
196
197         if (dma_check_name(name) != 0)
198                 return -EINVAL;
199
200         dev = dma_find_by_name(name);
201         if (dev == NULL)
202                 return -EINVAL;
203
204         dma_release(dev);
205         return 0;
206 }
207
208 int
209 rte_dma_get_dev_id_by_name(const char *name)
210 {
211         struct rte_dma_dev *dev;
212
213         if (dma_check_name(name) != 0)
214                 return -EINVAL;
215
216         dev = dma_find_by_name(name);
217         if (dev == NULL)
218                 return -EINVAL;
219
220         return dev->dev_id;
221 }
222
223 bool
224 rte_dma_is_valid(int16_t dev_id)
225 {
226         return (dev_id >= 0) && (dev_id < dma_devices_max) &&
227                 rte_dma_devices != NULL &&
228                 rte_dma_devices[dev_id].state != RTE_DMA_DEV_UNUSED;
229 }
230
231 uint16_t
232 rte_dma_count_avail(void)
233 {
234         uint16_t count = 0;
235         uint16_t i;
236
237         if (rte_dma_devices == NULL)
238                 return count;
239
240         for (i = 0; i < dma_devices_max; i++) {
241                 if (rte_dma_devices[i].state != RTE_DMA_DEV_UNUSED)
242                         count++;
243         }
244
245         return count;
246 }