New upstream version 18.08
[deb_dpdk.git] / lib / librte_eal / common / eal_common_dev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation.
3  * Copyright(c) 2014 6WIND S.A.
4  */
5
6 #include <stdio.h>
7 #include <string.h>
8 #include <inttypes.h>
9 #include <sys/queue.h>
10
11 #include <rte_compat.h>
12 #include <rte_bus.h>
13 #include <rte_class.h>
14 #include <rte_dev.h>
15 #include <rte_devargs.h>
16 #include <rte_debug.h>
17 #include <rte_errno.h>
18 #include <rte_kvargs.h>
19 #include <rte_log.h>
20 #include <rte_spinlock.h>
21 #include <rte_malloc.h>
22
23 #include "eal_private.h"
24
25 /**
26  * The device event callback description.
27  *
28  * It contains callback address to be registered by user application,
29  * the pointer to the parameters for callback, and the device name.
30  */
31 struct dev_event_callback {
32         TAILQ_ENTRY(dev_event_callback) next; /**< Callbacks list */
33         rte_dev_event_cb_fn cb_fn;            /**< Callback address */
34         void *cb_arg;                         /**< Callback parameter */
35         char *dev_name;  /**< Callback device name, NULL is for all device */
36         uint32_t active;                      /**< Callback is executing */
37 };
38
39 /** @internal Structure to keep track of registered callbacks */
40 TAILQ_HEAD(dev_event_cb_list, dev_event_callback);
41
42 /* The device event callback list for all registered callbacks. */
43 static struct dev_event_cb_list dev_event_cbs;
44
45 /* spinlock for device callbacks */
46 static rte_spinlock_t dev_event_lock = RTE_SPINLOCK_INITIALIZER;
47
48 struct dev_next_ctx {
49         struct rte_dev_iterator *it;
50         const char *bus_str;
51         const char *cls_str;
52 };
53
54 #define CTX(it, bus_str, cls_str) \
55         (&(const struct dev_next_ctx){ \
56                 .it = it, \
57                 .bus_str = bus_str, \
58                 .cls_str = cls_str, \
59         })
60
61 #define ITCTX(ptr) \
62         (((struct dev_next_ctx *)(intptr_t)ptr)->it)
63
64 #define BUSCTX(ptr) \
65         (((struct dev_next_ctx *)(intptr_t)ptr)->bus_str)
66
67 #define CLSCTX(ptr) \
68         (((struct dev_next_ctx *)(intptr_t)ptr)->cls_str)
69
70 static int cmp_dev_name(const struct rte_device *dev, const void *_name)
71 {
72         const char *name = _name;
73
74         return strcmp(dev->name, name);
75 }
76
77 int rte_eal_dev_attach(const char *name, const char *devargs)
78 {
79         struct rte_bus *bus;
80
81         if (name == NULL || devargs == NULL) {
82                 RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
83                 return -EINVAL;
84         }
85
86         bus = rte_bus_find_by_device_name(name);
87         if (bus == NULL) {
88                 RTE_LOG(ERR, EAL, "Unable to find a bus for the device '%s'\n",
89                         name);
90                 return -EINVAL;
91         }
92         if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") == 0)
93                 return rte_eal_hotplug_add(bus->name, name, devargs);
94
95         RTE_LOG(ERR, EAL,
96                 "Device attach is only supported for PCI and vdev devices.\n");
97
98         return -ENOTSUP;
99 }
100
101 int rte_eal_dev_detach(struct rte_device *dev)
102 {
103         struct rte_bus *bus;
104         int ret;
105
106         if (dev == NULL) {
107                 RTE_LOG(ERR, EAL, "Invalid device provided.\n");
108                 return -EINVAL;
109         }
110
111         bus = rte_bus_find_by_device(dev);
112         if (bus == NULL) {
113                 RTE_LOG(ERR, EAL, "Cannot find bus for device (%s)\n",
114                         dev->name);
115                 return -EINVAL;
116         }
117
118         if (bus->unplug == NULL) {
119                 RTE_LOG(ERR, EAL, "Bus function not supported\n");
120                 return -ENOTSUP;
121         }
122
123         ret = bus->unplug(dev);
124         if (ret)
125                 RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n",
126                         dev->name);
127         return ret;
128 }
129
130 int __rte_experimental rte_eal_hotplug_add(const char *busname, const char *devname,
131                         const char *devargs)
132 {
133         struct rte_bus *bus;
134         struct rte_device *dev;
135         struct rte_devargs *da;
136         int ret;
137
138         bus = rte_bus_find_by_name(busname);
139         if (bus == NULL) {
140                 RTE_LOG(ERR, EAL, "Cannot find bus (%s)\n", busname);
141                 return -ENOENT;
142         }
143
144         if (bus->plug == NULL) {
145                 RTE_LOG(ERR, EAL, "Function plug not supported by bus (%s)\n",
146                         bus->name);
147                 return -ENOTSUP;
148         }
149
150         da = calloc(1, sizeof(*da));
151         if (da == NULL)
152                 return -ENOMEM;
153
154         ret = rte_devargs_parsef(da, "%s:%s,%s",
155                                  busname, devname, devargs);
156         if (ret)
157                 goto err_devarg;
158
159         ret = rte_devargs_insert(da);
160         if (ret)
161                 goto err_devarg;
162
163         ret = bus->scan();
164         if (ret)
165                 goto err_devarg;
166
167         dev = bus->find_device(NULL, cmp_dev_name, devname);
168         if (dev == NULL) {
169                 RTE_LOG(ERR, EAL, "Cannot find device (%s)\n",
170                         devname);
171                 ret = -ENODEV;
172                 goto err_devarg;
173         }
174
175         if (dev->driver != NULL) {
176                 RTE_LOG(ERR, EAL, "Device is already plugged\n");
177                 return -EEXIST;
178         }
179
180         ret = bus->plug(dev);
181         if (ret) {
182                 RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
183                         dev->name);
184                 goto err_devarg;
185         }
186         return 0;
187
188 err_devarg:
189         if (rte_devargs_remove(busname, devname)) {
190                 free(da->args);
191                 free(da);
192         }
193         return ret;
194 }
195
196 int __rte_experimental
197 rte_eal_hotplug_remove(const char *busname, const char *devname)
198 {
199         struct rte_bus *bus;
200         struct rte_device *dev;
201         int ret;
202
203         bus = rte_bus_find_by_name(busname);
204         if (bus == NULL) {
205                 RTE_LOG(ERR, EAL, "Cannot find bus (%s)\n", busname);
206                 return -ENOENT;
207         }
208
209         if (bus->unplug == NULL) {
210                 RTE_LOG(ERR, EAL, "Function unplug not supported by bus (%s)\n",
211                         bus->name);
212                 return -ENOTSUP;
213         }
214
215         dev = bus->find_device(NULL, cmp_dev_name, devname);
216         if (dev == NULL) {
217                 RTE_LOG(ERR, EAL, "Cannot find plugged device (%s)\n", devname);
218                 return -EINVAL;
219         }
220
221         if (dev->driver == NULL) {
222                 RTE_LOG(ERR, EAL, "Device is already unplugged\n");
223                 return -ENOENT;
224         }
225
226         ret = bus->unplug(dev);
227         if (ret)
228                 RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n",
229                         dev->name);
230         rte_devargs_remove(busname, devname);
231         return ret;
232 }
233
234 int __rte_experimental
235 rte_dev_event_callback_register(const char *device_name,
236                                 rte_dev_event_cb_fn cb_fn,
237                                 void *cb_arg)
238 {
239         struct dev_event_callback *event_cb;
240         int ret;
241
242         if (!cb_fn)
243                 return -EINVAL;
244
245         rte_spinlock_lock(&dev_event_lock);
246
247         if (TAILQ_EMPTY(&dev_event_cbs))
248                 TAILQ_INIT(&dev_event_cbs);
249
250         TAILQ_FOREACH(event_cb, &dev_event_cbs, next) {
251                 if (event_cb->cb_fn == cb_fn && event_cb->cb_arg == cb_arg) {
252                         if (device_name == NULL && event_cb->dev_name == NULL)
253                                 break;
254                         if (device_name == NULL || event_cb->dev_name == NULL)
255                                 continue;
256                         if (!strcmp(event_cb->dev_name, device_name))
257                                 break;
258                 }
259         }
260
261         /* create a new callback. */
262         if (event_cb == NULL) {
263                 event_cb = malloc(sizeof(struct dev_event_callback));
264                 if (event_cb != NULL) {
265                         event_cb->cb_fn = cb_fn;
266                         event_cb->cb_arg = cb_arg;
267                         event_cb->active = 0;
268                         if (!device_name) {
269                                 event_cb->dev_name = NULL;
270                         } else {
271                                 event_cb->dev_name = strdup(device_name);
272                                 if (event_cb->dev_name == NULL) {
273                                         ret = -ENOMEM;
274                                         goto error;
275                                 }
276                         }
277                         TAILQ_INSERT_TAIL(&dev_event_cbs, event_cb, next);
278                 } else {
279                         RTE_LOG(ERR, EAL,
280                                 "Failed to allocate memory for device "
281                                 "event callback.");
282                         ret = -ENOMEM;
283                         goto error;
284                 }
285         } else {
286                 RTE_LOG(ERR, EAL,
287                         "The callback is already exist, no need "
288                         "to register again.\n");
289                 ret = -EEXIST;
290         }
291
292         rte_spinlock_unlock(&dev_event_lock);
293         return 0;
294 error:
295         free(event_cb);
296         rte_spinlock_unlock(&dev_event_lock);
297         return ret;
298 }
299
300 int __rte_experimental
301 rte_dev_event_callback_unregister(const char *device_name,
302                                   rte_dev_event_cb_fn cb_fn,
303                                   void *cb_arg)
304 {
305         int ret = 0;
306         struct dev_event_callback *event_cb, *next;
307
308         if (!cb_fn)
309                 return -EINVAL;
310
311         rte_spinlock_lock(&dev_event_lock);
312         /*walk through the callbacks and remove all that match. */
313         for (event_cb = TAILQ_FIRST(&dev_event_cbs); event_cb != NULL;
314              event_cb = next) {
315
316                 next = TAILQ_NEXT(event_cb, next);
317
318                 if (device_name != NULL && event_cb->dev_name != NULL) {
319                         if (!strcmp(event_cb->dev_name, device_name)) {
320                                 if (event_cb->cb_fn != cb_fn ||
321                                     (cb_arg != (void *)-1 &&
322                                     event_cb->cb_arg != cb_arg))
323                                         continue;
324                         }
325                 } else if (device_name != NULL) {
326                         continue;
327                 }
328
329                 /*
330                  * if this callback is not executing right now,
331                  * then remove it.
332                  */
333                 if (event_cb->active == 0) {
334                         TAILQ_REMOVE(&dev_event_cbs, event_cb, next);
335                         free(event_cb);
336                         ret++;
337                 } else {
338                         continue;
339                 }
340         }
341         rte_spinlock_unlock(&dev_event_lock);
342         return ret;
343 }
344
345 void
346 dev_callback_process(char *device_name, enum rte_dev_event_type event)
347 {
348         struct dev_event_callback *cb_lst;
349
350         if (device_name == NULL)
351                 return;
352
353         rte_spinlock_lock(&dev_event_lock);
354
355         TAILQ_FOREACH(cb_lst, &dev_event_cbs, next) {
356                 if (cb_lst->dev_name) {
357                         if (strcmp(cb_lst->dev_name, device_name))
358                                 continue;
359                 }
360                 cb_lst->active = 1;
361                 rte_spinlock_unlock(&dev_event_lock);
362                 cb_lst->cb_fn(device_name, event,
363                                 cb_lst->cb_arg);
364                 rte_spinlock_lock(&dev_event_lock);
365                 cb_lst->active = 0;
366         }
367         rte_spinlock_unlock(&dev_event_lock);
368 }
369
370 __rte_experimental
371 int
372 rte_dev_iterator_init(struct rte_dev_iterator *it,
373                       const char *dev_str)
374 {
375         struct rte_devargs devargs;
376         struct rte_class *cls = NULL;
377         struct rte_bus *bus = NULL;
378
379         /* Having both bus_str and cls_str NULL is illegal,
380          * marking this iterator as invalid unless
381          * everything goes well.
382          */
383         it->bus_str = NULL;
384         it->cls_str = NULL;
385
386         devargs.data = dev_str;
387         if (rte_devargs_layers_parse(&devargs, dev_str))
388                 goto get_out;
389
390         bus = devargs.bus;
391         cls = devargs.cls;
392         /* The string should have at least
393          * one layer specified.
394          */
395         if (bus == NULL && cls == NULL) {
396                 RTE_LOG(ERR, EAL,
397                         "Either bus or class must be specified.\n");
398                 rte_errno = EINVAL;
399                 goto get_out;
400         }
401         if (bus != NULL && bus->dev_iterate == NULL) {
402                 RTE_LOG(ERR, EAL, "Bus %s not supported\n", bus->name);
403                 rte_errno = ENOTSUP;
404                 goto get_out;
405         }
406         if (cls != NULL && cls->dev_iterate == NULL) {
407                 RTE_LOG(ERR, EAL, "Class %s not supported\n", cls->name);
408                 rte_errno = ENOTSUP;
409                 goto get_out;
410         }
411         it->bus_str = devargs.bus_str;
412         it->cls_str = devargs.cls_str;
413         it->dev_str = dev_str;
414         it->bus = bus;
415         it->cls = cls;
416         it->device = NULL;
417         it->class_device = NULL;
418 get_out:
419         return -rte_errno;
420 }
421
422 static char *
423 dev_str_sane_copy(const char *str)
424 {
425         size_t end;
426         char *copy;
427
428         end = strcspn(str, ",/");
429         if (str[end] == ',') {
430                 copy = strdup(&str[end + 1]);
431         } else {
432                 /* '/' or '\0' */
433                 copy = strdup("");
434         }
435         if (copy == NULL) {
436                 rte_errno = ENOMEM;
437         } else {
438                 char *slash;
439
440                 slash = strchr(copy, '/');
441                 if (slash != NULL)
442                         slash[0] = '\0';
443         }
444         return copy;
445 }
446
447 static int
448 class_next_dev_cmp(const struct rte_class *cls,
449                    const void *ctx)
450 {
451         struct rte_dev_iterator *it;
452         const char *cls_str = NULL;
453         void *dev;
454
455         if (cls->dev_iterate == NULL)
456                 return 1;
457         it = ITCTX(ctx);
458         cls_str = CLSCTX(ctx);
459         dev = it->class_device;
460         /* it->cls_str != NULL means a class
461          * was specified in the devstr.
462          */
463         if (it->cls_str != NULL && cls != it->cls)
464                 return 1;
465         /* If an error occurred previously,
466          * no need to test further.
467          */
468         if (rte_errno != 0)
469                 return -1;
470         dev = cls->dev_iterate(dev, cls_str, it);
471         it->class_device = dev;
472         return dev == NULL;
473 }
474
475 static int
476 bus_next_dev_cmp(const struct rte_bus *bus,
477                  const void *ctx)
478 {
479         struct rte_device *dev = NULL;
480         struct rte_class *cls = NULL;
481         struct rte_dev_iterator *it;
482         const char *bus_str = NULL;
483
484         if (bus->dev_iterate == NULL)
485                 return 1;
486         it = ITCTX(ctx);
487         bus_str = BUSCTX(ctx);
488         dev = it->device;
489         /* it->bus_str != NULL means a bus
490          * was specified in the devstr.
491          */
492         if (it->bus_str != NULL && bus != it->bus)
493                 return 1;
494         /* If an error occurred previously,
495          * no need to test further.
496          */
497         if (rte_errno != 0)
498                 return -1;
499         if (it->cls_str == NULL) {
500                 dev = bus->dev_iterate(dev, bus_str, it);
501                 goto end;
502         }
503         /* cls_str != NULL */
504         if (dev == NULL) {
505 next_dev_on_bus:
506                 dev = bus->dev_iterate(dev, bus_str, it);
507                 it->device = dev;
508         }
509         if (dev == NULL)
510                 return 1;
511         if (it->cls != NULL)
512                 cls = TAILQ_PREV(it->cls, rte_class_list, next);
513         cls = rte_class_find(cls, class_next_dev_cmp, ctx);
514         if (cls != NULL) {
515                 it->cls = cls;
516                 goto end;
517         }
518         goto next_dev_on_bus;
519 end:
520         it->device = dev;
521         return dev == NULL;
522 }
523 __rte_experimental
524 struct rte_device *
525 rte_dev_iterator_next(struct rte_dev_iterator *it)
526 {
527         struct rte_bus *bus = NULL;
528         int old_errno = rte_errno;
529         char *bus_str = NULL;
530         char *cls_str = NULL;
531
532         rte_errno = 0;
533         if (it->bus_str == NULL && it->cls_str == NULL) {
534                 /* Invalid iterator. */
535                 rte_errno = EINVAL;
536                 return NULL;
537         }
538         if (it->bus != NULL)
539                 bus = TAILQ_PREV(it->bus, rte_bus_list, next);
540         if (it->bus_str != NULL) {
541                 bus_str = dev_str_sane_copy(it->bus_str);
542                 if (bus_str == NULL)
543                         goto out;
544         }
545         if (it->cls_str != NULL) {
546                 cls_str = dev_str_sane_copy(it->cls_str);
547                 if (cls_str == NULL)
548                         goto out;
549         }
550         while ((bus = rte_bus_find(bus, bus_next_dev_cmp,
551                                    CTX(it, bus_str, cls_str)))) {
552                 if (it->device != NULL) {
553                         it->bus = bus;
554                         goto out;
555                 }
556                 if (it->bus_str != NULL ||
557                     rte_errno != 0)
558                         break;
559         }
560         if (rte_errno == 0)
561                 rte_errno = old_errno;
562 out:
563         free(bus_str);
564         free(cls_str);
565         return it->device;
566 }