8f44f093592529cf5c92677ce0e60db03167635d
[dpdk.git] / lib / librte_eal / linuxapp / eal / eal_pci.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <string.h>
35 #include <dirent.h>
36 #include <sys/mman.h>
37
38 #include <rte_log.h>
39 #include <rte_pci.h>
40 #include <rte_tailq.h>
41 #include <rte_eal_memconfig.h>
42 #include <rte_malloc.h>
43 #include <rte_devargs.h>
44 #include <rte_memcpy.h>
45
46 #include "rte_pci_dev_ids.h"
47 #include "eal_filesystem.h"
48 #include "eal_private.h"
49 #include "eal_pci_init.h"
50
51 /**
52  * @file
53  * PCI probing under linux
54  *
55  * This code is used to simulate a PCI probe by parsing information in sysfs.
56  * When a registered device matches a driver, it is then initialized with
57  * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
58  */
59
60 struct mapped_pci_res_list *pci_res_list = NULL;
61
62 /* unbind kernel driver for this device */
63 static int
64 pci_unbind_kernel_driver(struct rte_pci_device *dev)
65 {
66         int n;
67         FILE *f;
68         char filename[PATH_MAX];
69         char buf[BUFSIZ];
70         struct rte_pci_addr *loc = &dev->addr;
71
72         /* open /sys/bus/pci/devices/AAAA:BB:CC.D/driver */
73         snprintf(filename, sizeof(filename),
74                  SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/driver/unbind",
75                  loc->domain, loc->bus, loc->devid, loc->function);
76
77         f = fopen(filename, "w");
78         if (f == NULL) /* device was not bound */
79                 return 0;
80
81         n = snprintf(buf, sizeof(buf), PCI_PRI_FMT "\n",
82                      loc->domain, loc->bus, loc->devid, loc->function);
83         if ((n < 0) || (n >= (int)sizeof(buf))) {
84                 RTE_LOG(ERR, EAL, "%s(): snprintf failed\n", __func__);
85                 goto error;
86         }
87         if (fwrite(buf, n, 1, f) == 0) {
88                 RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
89                                 filename);
90                 goto error;
91         }
92
93         fclose(f);
94         return 0;
95
96 error:
97         fclose(f);
98         return -1;
99 }
100
101 static int
102 pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
103 {
104         int count;
105         char path[PATH_MAX];
106         char *name;
107
108         if (!filename || !dri_name)
109                 return -1;
110
111         count = readlink(filename, path, PATH_MAX);
112         if (count >= PATH_MAX)
113                 return -1;
114
115         /* For device does not have a driver */
116         if (count < 0)
117                 return 1;
118
119         path[count] = '\0';
120
121         name = strrchr(path, '/');
122         if (name) {
123                 strncpy(dri_name, name + 1, strlen(name + 1) + 1);
124                 return 0;
125         }
126
127         return -1;
128 }
129
130 void *
131 pci_find_max_end_va(void)
132 {
133         const struct rte_memseg *seg = rte_eal_get_physmem_layout();
134         const struct rte_memseg *last = seg;
135         unsigned i = 0;
136
137         for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
138                 if (seg->addr == NULL)
139                         break;
140
141                 if (seg->addr > last->addr)
142                         last = seg;
143
144         }
145         return RTE_PTR_ADD(last->addr, last->len);
146 }
147
148
149 /* map a particular resource from a file */
150 void *
151 pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
152                  int additional_flags)
153 {
154         void *mapaddr;
155
156         /* Map the PCI memory resource of device */
157         mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
158                         MAP_SHARED | additional_flags, fd, offset);
159         if (mapaddr == MAP_FAILED) {
160                 RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
161                         __func__, fd, requested_addr,
162                         (unsigned long)size, (unsigned long)offset,
163                         strerror(errno), mapaddr);
164         } else {
165                 RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
166         }
167
168         return mapaddr;
169 }
170
171 /* unmap a particular resource */
172 void
173 pci_unmap_resource(void *requested_addr, size_t size)
174 {
175         if (requested_addr == NULL)
176                 return;
177
178         /* Unmap the PCI memory resource of device */
179         if (munmap(requested_addr, size)) {
180                 RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
181                         __func__, requested_addr, (unsigned long)size,
182                         strerror(errno));
183         } else
184                 RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
185                                 requested_addr);
186 }
187
188 /* parse the "resource" sysfs file */
189 static int
190 pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
191 {
192         FILE *f;
193         char buf[BUFSIZ];
194         union pci_resource_info {
195                 struct {
196                         char *phys_addr;
197                         char *end_addr;
198                         char *flags;
199                 };
200                 char *ptrs[PCI_RESOURCE_FMT_NVAL];
201         } res_info;
202         int i;
203         uint64_t phys_addr, end_addr, flags;
204
205         f = fopen(filename, "r");
206         if (f == NULL) {
207                 RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n");
208                 return -1;
209         }
210
211         for (i = 0; i<PCI_MAX_RESOURCE; i++) {
212
213                 if (fgets(buf, sizeof(buf), f) == NULL) {
214                         RTE_LOG(ERR, EAL,
215                                 "%s(): cannot read resource\n", __func__);
216                         goto error;
217                 }
218
219                 if (rte_strsplit(buf, sizeof(buf), res_info.ptrs, 3, ' ') != 3) {
220                         RTE_LOG(ERR, EAL,
221                                 "%s(): bad resource format\n", __func__);
222                         goto error;
223                 }
224                 errno = 0;
225                 phys_addr = strtoull(res_info.phys_addr, NULL, 16);
226                 end_addr = strtoull(res_info.end_addr, NULL, 16);
227                 flags = strtoull(res_info.flags, NULL, 16);
228                 if (errno != 0) {
229                         RTE_LOG(ERR, EAL,
230                                 "%s(): bad resource format\n", __func__);
231                         goto error;
232                 }
233
234                 if (flags & IORESOURCE_MEM) {
235                         dev->mem_resource[i].phys_addr = phys_addr;
236                         dev->mem_resource[i].len = end_addr - phys_addr + 1;
237                         /* not mapped for now */
238                         dev->mem_resource[i].addr = NULL;
239                 }
240         }
241         fclose(f);
242         return 0;
243
244 error:
245         fclose(f);
246         return -1;
247 }
248
249 /* Scan one pci sysfs entry, and fill the devices list from it. */
250 static int
251 pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
252              uint8_t devid, uint8_t function)
253 {
254         char filename[PATH_MAX];
255         unsigned long tmp;
256         struct rte_pci_device *dev;
257         char driver[PATH_MAX];
258         int ret;
259
260         dev = malloc(sizeof(*dev));
261         if (dev == NULL)
262                 return -1;
263
264         memset(dev, 0, sizeof(*dev));
265         dev->addr.domain = domain;
266         dev->addr.bus = bus;
267         dev->addr.devid = devid;
268         dev->addr.function = function;
269
270         /* get vendor id */
271         snprintf(filename, sizeof(filename), "%s/vendor", dirname);
272         if (eal_parse_sysfs_value(filename, &tmp) < 0) {
273                 free(dev);
274                 return -1;
275         }
276         dev->id.vendor_id = (uint16_t)tmp;
277
278         /* get device id */
279         snprintf(filename, sizeof(filename), "%s/device", dirname);
280         if (eal_parse_sysfs_value(filename, &tmp) < 0) {
281                 free(dev);
282                 return -1;
283         }
284         dev->id.device_id = (uint16_t)tmp;
285
286         /* get subsystem_vendor id */
287         snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
288                  dirname);
289         if (eal_parse_sysfs_value(filename, &tmp) < 0) {
290                 free(dev);
291                 return -1;
292         }
293         dev->id.subsystem_vendor_id = (uint16_t)tmp;
294
295         /* get subsystem_device id */
296         snprintf(filename, sizeof(filename), "%s/subsystem_device",
297                  dirname);
298         if (eal_parse_sysfs_value(filename, &tmp) < 0) {
299                 free(dev);
300                 return -1;
301         }
302         dev->id.subsystem_device_id = (uint16_t)tmp;
303
304         /* get max_vfs */
305         dev->max_vfs = 0;
306         snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
307         if (!access(filename, F_OK) &&
308             eal_parse_sysfs_value(filename, &tmp) == 0)
309                 dev->max_vfs = (uint16_t)tmp;
310         else {
311                 /* for non igb_uio driver, need kernel version >= 3.8 */
312                 snprintf(filename, sizeof(filename),
313                          "%s/sriov_numvfs", dirname);
314                 if (!access(filename, F_OK) &&
315                     eal_parse_sysfs_value(filename, &tmp) == 0)
316                         dev->max_vfs = (uint16_t)tmp;
317         }
318
319         /* get numa node */
320         snprintf(filename, sizeof(filename), "%s/numa_node",
321                  dirname);
322         if (access(filename, R_OK) != 0) {
323                 /* if no NUMA support just set node to -1 */
324                 dev->numa_node = -1;
325         } else {
326                 if (eal_parse_sysfs_value(filename, &tmp) < 0) {
327                         free(dev);
328                         return -1;
329                 }
330                 dev->numa_node = tmp;
331         }
332
333         /* parse resources */
334         snprintf(filename, sizeof(filename), "%s/resource", dirname);
335         if (pci_parse_sysfs_resource(filename, dev) < 0) {
336                 RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__);
337                 free(dev);
338                 return -1;
339         }
340
341         /* parse driver */
342         snprintf(filename, sizeof(filename), "%s/driver", dirname);
343         ret = pci_get_kernel_driver_by_path(filename, driver);
344         if (!ret) {
345                 if (!strcmp(driver, "vfio-pci"))
346                         dev->pt_driver = RTE_PT_VFIO;
347                 else if (!strcmp(driver, "igb_uio"))
348                         dev->pt_driver = RTE_PT_IGB_UIO;
349                 else if (!strcmp(driver, "uio_pci_generic"))
350                         dev->pt_driver = RTE_PT_UIO_GENERIC;
351                 else
352                         dev->pt_driver = RTE_PT_UNKNOWN;
353         } else if (ret < 0) {
354                 RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
355                 free(dev);
356                 return -1;
357         } else
358                 dev->pt_driver = RTE_PT_UNKNOWN;
359
360         /* device is valid, add in list (sorted) */
361         if (TAILQ_EMPTY(&pci_device_list)) {
362                 TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
363         }
364         else {
365                 struct rte_pci_device *dev2 = NULL;
366                 int ret;
367
368                 TAILQ_FOREACH(dev2, &pci_device_list, next) {
369                         ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
370                         if (ret > 0)
371                                 continue;
372                         else if (ret < 0) {
373                                 TAILQ_INSERT_BEFORE(dev2, dev, next);
374                                 return 0;
375                         } else { /* already registered */
376                                 /* update pt_driver */
377                                 dev2->pt_driver = dev->pt_driver;
378                                 dev2->max_vfs = dev->max_vfs;
379                                 memmove(dev2->mem_resource,
380                                         dev->mem_resource,
381                                         sizeof(dev->mem_resource));
382                                 free(dev);
383                                 return 0;
384                         }
385                 }
386                 TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
387         }
388
389         return 0;
390 }
391
392 /*
393  * split up a pci address into its constituent parts.
394  */
395 static int
396 parse_pci_addr_format(const char *buf, int bufsize, uint16_t *domain,
397                 uint8_t *bus, uint8_t *devid, uint8_t *function)
398 {
399         /* first split on ':' */
400         union splitaddr {
401                 struct {
402                         char *domain;
403                         char *bus;
404                         char *devid;
405                         char *function;
406                 };
407                 char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */
408         } splitaddr;
409
410         char *buf_copy = strndup(buf, bufsize);
411         if (buf_copy == NULL)
412                 return -1;
413
414         if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':')
415                         != PCI_FMT_NVAL - 1)
416                 goto error;
417         /* final split is on '.' between devid and function */
418         splitaddr.function = strchr(splitaddr.devid,'.');
419         if (splitaddr.function == NULL)
420                 goto error;
421         *splitaddr.function++ = '\0';
422
423         /* now convert to int values */
424         errno = 0;
425         *domain = (uint16_t)strtoul(splitaddr.domain, NULL, 16);
426         *bus = (uint8_t)strtoul(splitaddr.bus, NULL, 16);
427         *devid = (uint8_t)strtoul(splitaddr.devid, NULL, 16);
428         *function = (uint8_t)strtoul(splitaddr.function, NULL, 10);
429         if (errno != 0)
430                 goto error;
431
432         free(buf_copy); /* free the copy made with strdup */
433         return 0;
434 error:
435         free(buf_copy);
436         return -1;
437 }
438
439 /*
440  * Scan the content of the PCI bus, and the devices in the devices
441  * list
442  */
443 int
444 rte_eal_pci_scan(void)
445 {
446         struct dirent *e;
447         DIR *dir;
448         char dirname[PATH_MAX];
449         uint16_t domain;
450         uint8_t bus, devid, function;
451
452         dir = opendir(SYSFS_PCI_DEVICES);
453         if (dir == NULL) {
454                 RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
455                         __func__, strerror(errno));
456                 return -1;
457         }
458
459         while ((e = readdir(dir)) != NULL) {
460                 if (e->d_name[0] == '.')
461                         continue;
462
463                 if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &domain,
464                                 &bus, &devid, &function) != 0)
465                         continue;
466
467                 snprintf(dirname, sizeof(dirname), "%s/%s", SYSFS_PCI_DEVICES,
468                          e->d_name);
469                 if (pci_scan_one(dirname, domain, bus, devid, function) < 0)
470                         goto error;
471         }
472         closedir(dir);
473         return 0;
474
475 error:
476         closedir(dir);
477         return -1;
478 }
479
480 #ifdef RTE_PCI_CONFIG
481 static int
482 pci_config_extended_tag(struct rte_pci_device *dev)
483 {
484         struct rte_pci_addr *loc = &dev->addr;
485         char filename[PATH_MAX];
486         char buf[BUFSIZ];
487         FILE *f;
488
489         /* not configured, let it as is */
490         if (strncmp(RTE_PCI_EXTENDED_TAG, "on", 2) != 0 &&
491                 strncmp(RTE_PCI_EXTENDED_TAG, "off", 3) != 0)
492                 return 0;
493
494         snprintf(filename, sizeof(filename),
495                 SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/" "extended_tag",
496                 loc->domain, loc->bus, loc->devid, loc->function);
497         f = fopen(filename, "rw+");
498         if (!f)
499                 return -1;
500
501         fgets(buf, sizeof(buf), f);
502         if (strncmp(RTE_PCI_EXTENDED_TAG, "on", 2) == 0) {
503                 /* enable Extended Tag*/
504                 if (strncmp(buf, "on", 2) != 0) {
505                         fseek(f, 0, SEEK_SET);
506                         fputs("on", f);
507                 }
508         } else {
509                 /* disable Extended Tag */
510                 if (strncmp(buf, "off", 3) != 0) {
511                         fseek(f, 0, SEEK_SET);
512                         fputs("off", f);
513                 }
514         }
515         fclose(f);
516
517         return 0;
518 }
519
520 static int
521 pci_config_max_read_request_size(struct rte_pci_device *dev)
522 {
523         struct rte_pci_addr *loc = &dev->addr;
524         char filename[PATH_MAX];
525         char buf[BUFSIZ], param[BUFSIZ];
526         FILE *f;
527         /* size can be 128, 256, 512, 1024, 2048, 4096 */
528         uint32_t max_size = RTE_PCI_MAX_READ_REQUEST_SIZE;
529
530         /* not configured, let it as is */
531         if (!max_size)
532                 return 0;
533
534         snprintf(filename, sizeof(filename),
535                 SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/" "max_read_request_size",
536                         loc->domain, loc->bus, loc->devid, loc->function);
537         f = fopen(filename, "rw+");
538         if (!f)
539                 return -1;
540
541         fgets(buf, sizeof(buf), f);
542         snprintf(param, sizeof(param), "%d", max_size);
543
544         /* check if the size to be set is the same as current */
545         if (strcmp(buf, param) == 0) {
546                 fclose(f);
547                 return 0;
548         }
549         fseek(f, 0, SEEK_SET);
550         fputs(param, f);
551         fclose(f);
552
553         return 0;
554 }
555
556 static void
557 pci_config_space_set(struct rte_pci_device *dev)
558 {
559         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
560                 return;
561
562         /* configure extended tag */
563         pci_config_extended_tag(dev);
564
565         /* configure max read request size */
566         pci_config_max_read_request_size(dev);
567 }
568 #endif
569
570 static int
571 pci_map_device(struct rte_pci_device *dev)
572 {
573         int ret = -1;
574
575         /* try mapping the NIC resources using VFIO if it exists */
576         switch (dev->pt_driver) {
577         case RTE_PT_VFIO:
578 #ifdef VFIO_PRESENT
579                 if (pci_vfio_is_enabled())
580                         ret = pci_vfio_map_resource(dev);
581 #endif
582                 break;
583         case RTE_PT_IGB_UIO:
584         case RTE_PT_UIO_GENERIC:
585                 /* map resources for devices that use uio */
586                 ret = pci_uio_map_resource(dev);
587                 break;
588         default:
589                 RTE_LOG(DEBUG, EAL, "  Not managed by known pt driver,"
590                         " skipped\n");
591                 ret = 1;
592                 break;
593         }
594
595         return ret;
596 }
597
598 #ifdef RTE_LIBRTE_EAL_HOTPLUG
599 static void
600 pci_unmap_device(struct rte_pci_device *dev)
601 {
602         if (dev == NULL)
603                 return;
604
605         /* try unmapping the NIC resources using VFIO if it exists */
606         switch (dev->pt_driver) {
607         case RTE_PT_VFIO:
608                 RTE_LOG(ERR, EAL, "Hotplug doesn't support vfio yet\n");
609                 break;
610         case RTE_PT_IGB_UIO:
611         case RTE_PT_UIO_GENERIC:
612                 /* unmap resources for devices that use uio */
613                 pci_uio_unmap_resource(dev);
614                 break;
615         default:
616                 RTE_LOG(DEBUG, EAL, "  Not managed by known pt driver,"
617                         " skipped\n");
618                 break;
619         }
620 }
621 #endif /* RTE_LIBRTE_EAL_HOTPLUG */
622
623 /*
624  * If vendor/device ID match, call the devinit() function of the
625  * driver.
626  */
627 int
628 rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *dev)
629 {
630         int ret;
631         struct rte_pci_id *id_table;
632
633         for (id_table = dr->id_table ; id_table->vendor_id != 0; id_table++) {
634
635                 /* check if device's identifiers match the driver's ones */
636                 if (id_table->vendor_id != dev->id.vendor_id &&
637                                 id_table->vendor_id != PCI_ANY_ID)
638                         continue;
639                 if (id_table->device_id != dev->id.device_id &&
640                                 id_table->device_id != PCI_ANY_ID)
641                         continue;
642                 if (id_table->subsystem_vendor_id != dev->id.subsystem_vendor_id &&
643                                 id_table->subsystem_vendor_id != PCI_ANY_ID)
644                         continue;
645                 if (id_table->subsystem_device_id != dev->id.subsystem_device_id &&
646                                 id_table->subsystem_device_id != PCI_ANY_ID)
647                         continue;
648
649                 struct rte_pci_addr *loc = &dev->addr;
650
651                 RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
652                                 loc->domain, loc->bus, loc->devid, loc->function,
653                                 dev->numa_node);
654
655                 RTE_LOG(DEBUG, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
656                                 dev->id.device_id, dr->name);
657
658                 /* no initialization when blacklisted, return without error */
659                 if (dev->devargs != NULL &&
660                         dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI) {
661                         RTE_LOG(DEBUG, EAL, "  Device is blacklisted, not initializing\n");
662                         return 1;
663                 }
664
665                 if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
666 #ifdef RTE_PCI_CONFIG
667                         /*
668                          * Set PCIe config space for high performance.
669                          * Return value can be ignored.
670                          */
671                         pci_config_space_set(dev);
672 #endif
673                         /* map resources for devices that use igb_uio */
674                         ret = pci_map_device(dev);
675                         if (ret != 0)
676                                 return ret;
677                 } else if (dr->drv_flags & RTE_PCI_DRV_FORCE_UNBIND &&
678                            rte_eal_process_type() == RTE_PROC_PRIMARY) {
679                         /* unbind current driver */
680                         if (pci_unbind_kernel_driver(dev) < 0)
681                                 return -1;
682                 }
683
684                 /* reference driver structure */
685                 dev->driver = dr;
686
687                 /* call the driver devinit() function */
688                 return dr->devinit(dr, dev);
689         }
690         /* return positive value if driver is not found */
691         return 1;
692 }
693
694 #ifdef RTE_LIBRTE_EAL_HOTPLUG
695 /*
696  * If vendor/device ID match, call the devuninit() function of the
697  * driver.
698  */
699 int
700 rte_eal_pci_close_one_driver(struct rte_pci_driver *dr,
701                 struct rte_pci_device *dev)
702 {
703         struct rte_pci_id *id_table;
704
705         if ((dr == NULL) || (dev == NULL))
706                 return -EINVAL;
707
708         for (id_table = dr->id_table ; id_table->vendor_id != 0; id_table++) {
709
710                 /* check if device's identifiers match the driver's ones */
711                 if (id_table->vendor_id != dev->id.vendor_id &&
712                     id_table->vendor_id != PCI_ANY_ID)
713                         continue;
714                 if (id_table->device_id != dev->id.device_id &&
715                     id_table->device_id != PCI_ANY_ID)
716                         continue;
717                 if (id_table->subsystem_vendor_id !=
718                     dev->id.subsystem_vendor_id &&
719                     id_table->subsystem_vendor_id != PCI_ANY_ID)
720                         continue;
721                 if (id_table->subsystem_device_id !=
722                     dev->id.subsystem_device_id &&
723                     id_table->subsystem_device_id != PCI_ANY_ID)
724                         continue;
725
726                 struct rte_pci_addr *loc = &dev->addr;
727
728                 RTE_LOG(DEBUG, EAL,
729                                 "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
730                                 loc->domain, loc->bus, loc->devid,
731                                 loc->function, dev->numa_node);
732
733                 RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n",
734                                 dev->id.vendor_id, dev->id.device_id,
735                                 dr->name);
736
737                 /* call the driver devuninit() function */
738                 if (dr->devuninit && (dr->devuninit(dev) < 0))
739                         return -1;      /* negative value is an error */
740
741                 /* clear driver structure */
742                 dev->driver = NULL;
743
744                 if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
745                         /* unmap resources for devices that use igb_uio */
746                         pci_unmap_device(dev);
747
748                 return 0;
749         }
750         /* return positive value if driver is not found */
751         return 1;
752 }
753 #else /* RTE_LIBRTE_EAL_HOTPLUG */
754 int
755 rte_eal_pci_close_one_driver(struct rte_pci_driver *dr __rte_unused,
756                 struct rte_pci_device *dev __rte_unused)
757 {
758         RTE_LOG(ERR, EAL, "Hotplug support isn't enabled\n");
759         return -1;
760 }
761 #endif /* RTE_LIBRTE_EAL_HOTPLUG */
762
763 /* Init the PCI EAL subsystem */
764 int
765 rte_eal_pci_init(void)
766 {
767         TAILQ_INIT(&pci_driver_list);
768         TAILQ_INIT(&pci_device_list);
769         pci_res_list = RTE_TAILQ_LOOKUP_BY_IDX(RTE_TAILQ_PCI,
770                                                mapped_pci_res_list);
771
772         /* for debug purposes, PCI can be disabled */
773         if (internal_config.no_pci)
774                 return 0;
775
776         if (rte_eal_pci_scan() < 0) {
777                 RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
778                 return -1;
779         }
780 #ifdef VFIO_PRESENT
781         pci_vfio_enable();
782
783         if (pci_vfio_is_enabled()) {
784
785                 /* if we are primary process, create a thread to communicate with
786                  * secondary processes. the thread will use a socket to wait for
787                  * requests from secondary process to send open file descriptors,
788                  * because VFIO does not allow multiple open descriptors on a group or
789                  * VFIO container.
790                  */
791                 if (internal_config.process_type == RTE_PROC_PRIMARY &&
792                                 pci_vfio_mp_sync_setup() < 0)
793                         return -1;
794         }
795 #endif
796         return 0;
797 }