eal: enable hotplug on multi-process
[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 #include <rte_string_fns.h>
23
24 #include "eal_private.h"
25 #include "hotplug_mp.h"
26
27 /**
28  * The device event callback description.
29  *
30  * It contains callback address to be registered by user application,
31  * the pointer to the parameters for callback, and the device name.
32  */
33 struct dev_event_callback {
34         TAILQ_ENTRY(dev_event_callback) next; /**< Callbacks list */
35         rte_dev_event_cb_fn cb_fn;            /**< Callback address */
36         void *cb_arg;                         /**< Callback parameter */
37         char *dev_name;  /**< Callback device name, NULL is for all device */
38         uint32_t active;                      /**< Callback is executing */
39 };
40
41 /** @internal Structure to keep track of registered callbacks */
42 TAILQ_HEAD(dev_event_cb_list, dev_event_callback);
43
44 /* The device event callback list for all registered callbacks. */
45 static struct dev_event_cb_list dev_event_cbs;
46
47 /* spinlock for device callbacks */
48 static rte_spinlock_t dev_event_lock = RTE_SPINLOCK_INITIALIZER;
49
50 struct dev_next_ctx {
51         struct rte_dev_iterator *it;
52         const char *bus_str;
53         const char *cls_str;
54 };
55
56 #define CTX(it, bus_str, cls_str) \
57         (&(const struct dev_next_ctx){ \
58                 .it = it, \
59                 .bus_str = bus_str, \
60                 .cls_str = cls_str, \
61         })
62
63 #define ITCTX(ptr) \
64         (((struct dev_next_ctx *)(intptr_t)ptr)->it)
65
66 #define BUSCTX(ptr) \
67         (((struct dev_next_ctx *)(intptr_t)ptr)->bus_str)
68
69 #define CLSCTX(ptr) \
70         (((struct dev_next_ctx *)(intptr_t)ptr)->cls_str)
71
72 static int cmp_dev_name(const struct rte_device *dev, const void *_name)
73 {
74         const char *name = _name;
75
76         return strcmp(dev->name, name);
77 }
78
79 int rte_eal_dev_attach(const char *name, const char *devargs)
80 {
81         struct rte_bus *bus;
82
83         if (name == NULL || devargs == NULL) {
84                 RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
85                 return -EINVAL;
86         }
87
88         bus = rte_bus_find_by_device_name(name);
89         if (bus == NULL) {
90                 RTE_LOG(ERR, EAL, "Unable to find a bus for the device '%s'\n",
91                         name);
92                 return -EINVAL;
93         }
94         if (strcmp(bus->name, "pci") == 0 || strcmp(bus->name, "vdev") == 0)
95                 return rte_eal_hotplug_add(bus->name, name, devargs);
96
97         RTE_LOG(ERR, EAL,
98                 "Device attach is only supported for PCI and vdev devices.\n");
99
100         return -ENOTSUP;
101 }
102
103 int rte_eal_dev_detach(struct rte_device *dev)
104 {
105         struct rte_bus *bus;
106         int ret;
107
108         if (dev == NULL) {
109                 RTE_LOG(ERR, EAL, "Invalid device provided.\n");
110                 return -EINVAL;
111         }
112
113         bus = rte_bus_find_by_device(dev);
114         if (bus == NULL) {
115                 RTE_LOG(ERR, EAL, "Cannot find bus for device (%s)\n",
116                         dev->name);
117                 return -EINVAL;
118         }
119
120         if (bus->unplug == NULL) {
121                 RTE_LOG(ERR, EAL, "Bus function not supported\n");
122                 return -ENOTSUP;
123         }
124
125         ret = bus->unplug(dev);
126         if (ret)
127                 RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n",
128                         dev->name);
129         return ret;
130 }
131
132 /* helper function to build devargs, caller should free the memory */
133 static int
134 build_devargs(const char *busname, const char *devname,
135               const char *drvargs, char **devargs)
136 {
137         int length;
138
139         length = snprintf(NULL, 0, "%s:%s,%s", busname, devname, drvargs);
140         if (length < 0)
141                 return -EINVAL;
142
143         *devargs = malloc(length + 1);
144         if (*devargs == NULL)
145                 return -ENOMEM;
146
147         length = snprintf(*devargs, length + 1, "%s:%s,%s",
148                         busname, devname, drvargs);
149         if (length < 0) {
150                 free(*devargs);
151                 return -EINVAL;
152         }
153
154         return 0;
155 }
156
157 int
158 rte_eal_hotplug_add(const char *busname, const char *devname,
159                     const char *drvargs)
160 {
161
162         char *devargs;
163         int ret;
164
165         ret = build_devargs(busname, devname, drvargs, &devargs);
166         if (ret != 0)
167                 return ret;
168
169         ret = rte_dev_probe(devargs);
170         free(devargs);
171
172         return ret;
173 }
174
175 /* probe device at local process. */
176 int
177 local_dev_probe(const char *devargs, struct rte_device **new_dev)
178 {
179         struct rte_device *dev;
180         struct rte_devargs *da;
181         int ret;
182
183         *new_dev = NULL;
184         da = calloc(1, sizeof(*da));
185         if (da == NULL)
186                 return -ENOMEM;
187
188         ret = rte_devargs_parse(da, devargs);
189         if (ret)
190                 goto err_devarg;
191
192         if (da->bus->plug == NULL) {
193                 RTE_LOG(ERR, EAL, "Function plug not supported by bus (%s)\n",
194                         da->bus->name);
195                 ret = -ENOTSUP;
196                 goto err_devarg;
197         }
198
199         ret = rte_devargs_insert(da);
200         if (ret)
201                 goto err_devarg;
202
203         ret = da->bus->scan();
204         if (ret)
205                 goto err_devarg;
206
207         dev = da->bus->find_device(NULL, cmp_dev_name, da->name);
208         if (dev == NULL) {
209                 RTE_LOG(ERR, EAL, "Cannot find device (%s)\n",
210                         da->name);
211                 ret = -ENODEV;
212                 goto err_devarg;
213         }
214
215         if (dev->driver != NULL) {
216                 RTE_LOG(ERR, EAL, "Device is already plugged\n");
217                 return -EEXIST;
218         }
219
220         ret = dev->bus->plug(dev);
221         if (ret) {
222                 RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
223                         dev->name);
224                 goto err_devarg;
225         }
226
227         *new_dev = dev;
228         return 0;
229
230 err_devarg:
231         if (rte_devargs_remove(da) != 0) {
232                 free(da->args);
233                 free(da);
234         }
235         return ret;
236 }
237
238 int __rte_experimental
239 rte_dev_probe(const char *devargs)
240 {
241         struct eal_dev_mp_req req;
242         struct rte_device *dev;
243         int ret;
244
245         memset(&req, 0, sizeof(req));
246         req.t = EAL_DEV_REQ_TYPE_ATTACH;
247         strlcpy(req.devargs, devargs, EAL_DEV_MP_DEV_ARGS_MAX_LEN);
248
249         if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
250                 /**
251                  * If in secondary process, just send IPC request to
252                  * primary process.
253                  */
254                 ret = eal_dev_hotplug_request_to_primary(&req);
255                 if (ret != 0) {
256                         RTE_LOG(ERR, EAL,
257                                 "Failed to send hotplug request to primary\n");
258                         return -ENOMSG;
259                 }
260                 if (req.result != 0)
261                         RTE_LOG(ERR, EAL,
262                                 "Failed to hotplug add device\n");
263                 return req.result;
264         }
265
266         /* attach a shared device from primary start from here: */
267
268         /* primary attach the new device itself. */
269         ret = local_dev_probe(devargs, &dev);
270
271         if (ret != 0) {
272                 RTE_LOG(ERR, EAL,
273                         "Failed to attach device on primary process\n");
274
275                 /**
276                  * it is possible that secondary process failed to attached a
277                  * device that primary process have during initialization,
278                  * so for -EEXIST case, we still need to sync with secondary
279                  * process.
280                  */
281                 if (ret != -EEXIST)
282                         return ret;
283         }
284
285         /* primary send attach sync request to secondary. */
286         ret = eal_dev_hotplug_request_to_secondary(&req);
287
288         /* if any communication error, we need to rollback. */
289         if (ret != 0) {
290                 RTE_LOG(ERR, EAL,
291                         "Failed to send hotplug add request to secondary\n");
292                 ret = -ENOMSG;
293                 goto rollback;
294         }
295
296         /**
297          * if any secondary failed to attach, we need to consider if rollback
298          * is necessary.
299          */
300         if (req.result != 0) {
301                 RTE_LOG(ERR, EAL,
302                         "Failed to attach device on secondary process\n");
303                 ret = req.result;
304
305                 /* for -EEXIST, we don't need to rollback. */
306                 if (ret == -EEXIST)
307                         return ret;
308                 goto rollback;
309         }
310
311         return 0;
312
313 rollback:
314         req.t = EAL_DEV_REQ_TYPE_ATTACH_ROLLBACK;
315
316         /* primary send rollback request to secondary. */
317         if (eal_dev_hotplug_request_to_secondary(&req) != 0)
318                 RTE_LOG(WARNING, EAL,
319                         "Failed to rollback device attach on secondary."
320                         "Devices in secondary may not sync with primary\n");
321
322         /* primary rollback itself. */
323         if (local_dev_remove(dev) != 0)
324                 RTE_LOG(WARNING, EAL,
325                         "Failed to rollback device attach on primary."
326                         "Devices in secondary may not sync with primary\n");
327
328         return ret;
329 }
330
331 int
332 rte_eal_hotplug_remove(const char *busname, const char *devname)
333 {
334         struct rte_device *dev;
335         struct rte_bus *bus;
336
337         bus = rte_bus_find_by_name(busname);
338         if (bus == NULL) {
339                 RTE_LOG(ERR, EAL, "Cannot find bus (%s)\n", busname);
340                 return -ENOENT;
341         }
342
343         dev = bus->find_device(NULL, cmp_dev_name, devname);
344         if (dev == NULL) {
345                 RTE_LOG(ERR, EAL, "Cannot find plugged device (%s)\n", devname);
346                 return -EINVAL;
347         }
348
349         return rte_dev_remove(dev);
350 }
351
352 /* remove device at local process. */
353 int
354 local_dev_remove(struct rte_device *dev)
355 {
356         int ret;
357
358         if (dev->driver == NULL) {
359                 RTE_LOG(ERR, EAL, "Device is already unplugged\n");
360                 return -ENOENT;
361         }
362
363         if (dev->bus->unplug == NULL) {
364                 RTE_LOG(ERR, EAL, "Function unplug not supported by bus (%s)\n",
365                         dev->bus->name);
366                 return -ENOTSUP;
367         }
368
369         ret = dev->bus->unplug(dev);
370         if (ret) {
371                 RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n",
372                         dev->name);
373                 return ret;
374         }
375
376         rte_devargs_remove(dev->devargs);
377
378         return 0;
379 }
380
381 int __rte_experimental
382 rte_dev_remove(struct rte_device *dev)
383 {
384         struct eal_dev_mp_req req;
385         char *devargs;
386         int ret;
387
388         ret = build_devargs(dev->devargs->bus->name, dev->name, "", &devargs);
389         if (ret != 0)
390                 return ret;
391
392         memset(&req, 0, sizeof(req));
393         req.t = EAL_DEV_REQ_TYPE_DETACH;
394         strlcpy(req.devargs, devargs, EAL_DEV_MP_DEV_ARGS_MAX_LEN);
395         free(devargs);
396
397         if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
398                 /**
399                  * If in secondary process, just send IPC request to
400                  * primary process.
401                  */
402                 ret = eal_dev_hotplug_request_to_primary(&req);
403                 if (ret != 0) {
404                         RTE_LOG(ERR, EAL,
405                                 "Failed to send hotplug request to primary\n");
406                         return -ENOMSG;
407                 }
408                 if (req.result != 0)
409                         RTE_LOG(ERR, EAL,
410                                 "Failed to hotplug remove device\n");
411                 return req.result;
412         }
413
414         /* detach a device from primary start from here: */
415
416         /* primary send detach sync request to secondary */
417         ret = eal_dev_hotplug_request_to_secondary(&req);
418
419         /**
420          * if communication error, we need to rollback, because it is possible
421          * part of the secondary processes still detached it successfully.
422          */
423         if (ret != 0) {
424                 RTE_LOG(ERR, EAL,
425                         "Failed to send device detach request to secondary\n");
426                 ret = -ENOMSG;
427                 goto rollback;
428         }
429
430         /**
431          * if any secondary failed to detach, we need to consider if rollback
432          * is necessary.
433          */
434         if (req.result != 0) {
435                 RTE_LOG(ERR, EAL,
436                         "Failed to detach device on secondary process\n");
437                 ret = req.result;
438                 /**
439                  * if -ENOENT, we don't need to rollback, since devices is
440                  * already detached on secondary process.
441                  */
442                 if (ret != -ENOENT)
443                         goto rollback;
444         }
445
446         /* primary detach the device itself. */
447         ret = local_dev_remove(dev);
448
449         /* if primary failed, still need to consider if rollback is necessary */
450         if (ret != 0) {
451                 RTE_LOG(ERR, EAL,
452                         "Failed to detach device on primary process\n");
453                 /* if -ENOENT, we don't need to rollback */
454                 if (ret == -ENOENT)
455                         return ret;
456                 goto rollback;
457         }
458
459         return 0;
460
461 rollback:
462         req.t = EAL_DEV_REQ_TYPE_DETACH_ROLLBACK;
463
464         /* primary send rollback request to secondary. */
465         if (eal_dev_hotplug_request_to_secondary(&req) != 0)
466                 RTE_LOG(WARNING, EAL,
467                         "Failed to rollback device detach on secondary."
468                         "Devices in secondary may not sync with primary\n");
469
470         return ret;
471 }
472
473 int __rte_experimental
474 rte_dev_event_callback_register(const char *device_name,
475                                 rte_dev_event_cb_fn cb_fn,
476                                 void *cb_arg)
477 {
478         struct dev_event_callback *event_cb;
479         int ret;
480
481         if (!cb_fn)
482                 return -EINVAL;
483
484         rte_spinlock_lock(&dev_event_lock);
485
486         if (TAILQ_EMPTY(&dev_event_cbs))
487                 TAILQ_INIT(&dev_event_cbs);
488
489         TAILQ_FOREACH(event_cb, &dev_event_cbs, next) {
490                 if (event_cb->cb_fn == cb_fn && event_cb->cb_arg == cb_arg) {
491                         if (device_name == NULL && event_cb->dev_name == NULL)
492                                 break;
493                         if (device_name == NULL || event_cb->dev_name == NULL)
494                                 continue;
495                         if (!strcmp(event_cb->dev_name, device_name))
496                                 break;
497                 }
498         }
499
500         /* create a new callback. */
501         if (event_cb == NULL) {
502                 event_cb = malloc(sizeof(struct dev_event_callback));
503                 if (event_cb != NULL) {
504                         event_cb->cb_fn = cb_fn;
505                         event_cb->cb_arg = cb_arg;
506                         event_cb->active = 0;
507                         if (!device_name) {
508                                 event_cb->dev_name = NULL;
509                         } else {
510                                 event_cb->dev_name = strdup(device_name);
511                                 if (event_cb->dev_name == NULL) {
512                                         ret = -ENOMEM;
513                                         goto error;
514                                 }
515                         }
516                         TAILQ_INSERT_TAIL(&dev_event_cbs, event_cb, next);
517                 } else {
518                         RTE_LOG(ERR, EAL,
519                                 "Failed to allocate memory for device "
520                                 "event callback.");
521                         ret = -ENOMEM;
522                         goto error;
523                 }
524         } else {
525                 RTE_LOG(ERR, EAL,
526                         "The callback is already exist, no need "
527                         "to register again.\n");
528                 ret = -EEXIST;
529         }
530
531         rte_spinlock_unlock(&dev_event_lock);
532         return 0;
533 error:
534         free(event_cb);
535         rte_spinlock_unlock(&dev_event_lock);
536         return ret;
537 }
538
539 int __rte_experimental
540 rte_dev_event_callback_unregister(const char *device_name,
541                                   rte_dev_event_cb_fn cb_fn,
542                                   void *cb_arg)
543 {
544         int ret = 0;
545         struct dev_event_callback *event_cb, *next;
546
547         if (!cb_fn)
548                 return -EINVAL;
549
550         rte_spinlock_lock(&dev_event_lock);
551         /*walk through the callbacks and remove all that match. */
552         for (event_cb = TAILQ_FIRST(&dev_event_cbs); event_cb != NULL;
553              event_cb = next) {
554
555                 next = TAILQ_NEXT(event_cb, next);
556
557                 if (device_name != NULL && event_cb->dev_name != NULL) {
558                         if (!strcmp(event_cb->dev_name, device_name)) {
559                                 if (event_cb->cb_fn != cb_fn ||
560                                     (cb_arg != (void *)-1 &&
561                                     event_cb->cb_arg != cb_arg))
562                                         continue;
563                         }
564                 } else if (device_name != NULL) {
565                         continue;
566                 }
567
568                 /*
569                  * if this callback is not executing right now,
570                  * then remove it.
571                  */
572                 if (event_cb->active == 0) {
573                         TAILQ_REMOVE(&dev_event_cbs, event_cb, next);
574                         free(event_cb);
575                         ret++;
576                 } else {
577                         continue;
578                 }
579         }
580         rte_spinlock_unlock(&dev_event_lock);
581         return ret;
582 }
583
584 void __rte_experimental
585 rte_dev_event_callback_process(const char *device_name,
586                                enum rte_dev_event_type event)
587 {
588         struct dev_event_callback *cb_lst;
589
590         if (device_name == NULL)
591                 return;
592
593         rte_spinlock_lock(&dev_event_lock);
594
595         TAILQ_FOREACH(cb_lst, &dev_event_cbs, next) {
596                 if (cb_lst->dev_name) {
597                         if (strcmp(cb_lst->dev_name, device_name))
598                                 continue;
599                 }
600                 cb_lst->active = 1;
601                 rte_spinlock_unlock(&dev_event_lock);
602                 cb_lst->cb_fn(device_name, event,
603                                 cb_lst->cb_arg);
604                 rte_spinlock_lock(&dev_event_lock);
605                 cb_lst->active = 0;
606         }
607         rte_spinlock_unlock(&dev_event_lock);
608 }
609
610 __rte_experimental
611 int
612 rte_dev_iterator_init(struct rte_dev_iterator *it,
613                       const char *dev_str)
614 {
615         struct rte_devargs devargs;
616         struct rte_class *cls = NULL;
617         struct rte_bus *bus = NULL;
618
619         /* Having both bus_str and cls_str NULL is illegal,
620          * marking this iterator as invalid unless
621          * everything goes well.
622          */
623         it->bus_str = NULL;
624         it->cls_str = NULL;
625
626         devargs.data = dev_str;
627         if (rte_devargs_layers_parse(&devargs, dev_str))
628                 goto get_out;
629
630         bus = devargs.bus;
631         cls = devargs.cls;
632         /* The string should have at least
633          * one layer specified.
634          */
635         if (bus == NULL && cls == NULL) {
636                 RTE_LOG(ERR, EAL,
637                         "Either bus or class must be specified.\n");
638                 rte_errno = EINVAL;
639                 goto get_out;
640         }
641         if (bus != NULL && bus->dev_iterate == NULL) {
642                 RTE_LOG(ERR, EAL, "Bus %s not supported\n", bus->name);
643                 rte_errno = ENOTSUP;
644                 goto get_out;
645         }
646         if (cls != NULL && cls->dev_iterate == NULL) {
647                 RTE_LOG(ERR, EAL, "Class %s not supported\n", cls->name);
648                 rte_errno = ENOTSUP;
649                 goto get_out;
650         }
651         it->bus_str = devargs.bus_str;
652         it->cls_str = devargs.cls_str;
653         it->dev_str = dev_str;
654         it->bus = bus;
655         it->cls = cls;
656         it->device = NULL;
657         it->class_device = NULL;
658 get_out:
659         return -rte_errno;
660 }
661
662 static char *
663 dev_str_sane_copy(const char *str)
664 {
665         size_t end;
666         char *copy;
667
668         end = strcspn(str, ",/");
669         if (str[end] == ',') {
670                 copy = strdup(&str[end + 1]);
671         } else {
672                 /* '/' or '\0' */
673                 copy = strdup("");
674         }
675         if (copy == NULL) {
676                 rte_errno = ENOMEM;
677         } else {
678                 char *slash;
679
680                 slash = strchr(copy, '/');
681                 if (slash != NULL)
682                         slash[0] = '\0';
683         }
684         return copy;
685 }
686
687 static int
688 class_next_dev_cmp(const struct rte_class *cls,
689                    const void *ctx)
690 {
691         struct rte_dev_iterator *it;
692         const char *cls_str = NULL;
693         void *dev;
694
695         if (cls->dev_iterate == NULL)
696                 return 1;
697         it = ITCTX(ctx);
698         cls_str = CLSCTX(ctx);
699         dev = it->class_device;
700         /* it->cls_str != NULL means a class
701          * was specified in the devstr.
702          */
703         if (it->cls_str != NULL && cls != it->cls)
704                 return 1;
705         /* If an error occurred previously,
706          * no need to test further.
707          */
708         if (rte_errno != 0)
709                 return -1;
710         dev = cls->dev_iterate(dev, cls_str, it);
711         it->class_device = dev;
712         return dev == NULL;
713 }
714
715 static int
716 bus_next_dev_cmp(const struct rte_bus *bus,
717                  const void *ctx)
718 {
719         struct rte_device *dev = NULL;
720         struct rte_class *cls = NULL;
721         struct rte_dev_iterator *it;
722         const char *bus_str = NULL;
723
724         if (bus->dev_iterate == NULL)
725                 return 1;
726         it = ITCTX(ctx);
727         bus_str = BUSCTX(ctx);
728         dev = it->device;
729         /* it->bus_str != NULL means a bus
730          * was specified in the devstr.
731          */
732         if (it->bus_str != NULL && bus != it->bus)
733                 return 1;
734         /* If an error occurred previously,
735          * no need to test further.
736          */
737         if (rte_errno != 0)
738                 return -1;
739         if (it->cls_str == NULL) {
740                 dev = bus->dev_iterate(dev, bus_str, it);
741                 goto end;
742         }
743         /* cls_str != NULL */
744         if (dev == NULL) {
745 next_dev_on_bus:
746                 dev = bus->dev_iterate(dev, bus_str, it);
747                 it->device = dev;
748         }
749         if (dev == NULL)
750                 return 1;
751         if (it->cls != NULL)
752                 cls = TAILQ_PREV(it->cls, rte_class_list, next);
753         cls = rte_class_find(cls, class_next_dev_cmp, ctx);
754         if (cls != NULL) {
755                 it->cls = cls;
756                 goto end;
757         }
758         goto next_dev_on_bus;
759 end:
760         it->device = dev;
761         return dev == NULL;
762 }
763 __rte_experimental
764 struct rte_device *
765 rte_dev_iterator_next(struct rte_dev_iterator *it)
766 {
767         struct rte_bus *bus = NULL;
768         int old_errno = rte_errno;
769         char *bus_str = NULL;
770         char *cls_str = NULL;
771
772         rte_errno = 0;
773         if (it->bus_str == NULL && it->cls_str == NULL) {
774                 /* Invalid iterator. */
775                 rte_errno = EINVAL;
776                 return NULL;
777         }
778         if (it->bus != NULL)
779                 bus = TAILQ_PREV(it->bus, rte_bus_list, next);
780         if (it->bus_str != NULL) {
781                 bus_str = dev_str_sane_copy(it->bus_str);
782                 if (bus_str == NULL)
783                         goto out;
784         }
785         if (it->cls_str != NULL) {
786                 cls_str = dev_str_sane_copy(it->cls_str);
787                 if (cls_str == NULL)
788                         goto out;
789         }
790         while ((bus = rte_bus_find(bus, bus_next_dev_cmp,
791                                    CTX(it, bus_str, cls_str)))) {
792                 if (it->device != NULL) {
793                         it->bus = bus;
794                         goto out;
795                 }
796                 if (it->bus_str != NULL ||
797                     rte_errno != 0)
798                         break;
799         }
800         if (rte_errno == 0)
801                 rte_errno = old_errno;
802 out:
803         free(bus_str);
804         free(cls_str);
805         return it->device;
806 }