1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #include <string.h> 6 #include <dirent.h> 7 8 #include <rte_log.h> 9 #include <rte_pci.h> 10 #include <rte_bus_pci.h> 11 #include <rte_malloc.h> 12 #include <rte_devargs.h> 13 #include <rte_memcpy.h> 14 #include <rte_vfio.h> 15 16 #include "eal_filesystem.h" 17 18 #include "private.h" 19 #include "pci_init.h" 20 21 /** 22 * @file 23 * PCI probing using Linux sysfs. 24 */ 25 26 static int 27 pci_get_kernel_driver_by_path(const char *filename, char *dri_name, 28 size_t len) 29 { 30 int count; 31 char path[PATH_MAX]; 32 char *name; 33 34 if (!filename || !dri_name) 35 return -1; 36 37 count = readlink(filename, path, PATH_MAX); 38 if (count >= PATH_MAX) 39 return -1; 40 41 /* For device does not have a driver */ 42 if (count < 0) 43 return 1; 44 45 path[count] = '\0'; 46 47 name = strrchr(path, '/'); 48 if (name) { 49 strlcpy(dri_name, name + 1, len); 50 return 0; 51 } 52 53 return -1; 54 } 55 56 /* Map pci device */ 57 int 58 rte_pci_map_device(struct rte_pci_device *dev) 59 { 60 int ret = -1; 61 62 /* try mapping the NIC resources using VFIO if it exists */ 63 switch (dev->kdrv) { 64 case RTE_PCI_KDRV_VFIO: 65 #ifdef VFIO_PRESENT 66 if (pci_vfio_is_enabled()) 67 ret = pci_vfio_map_resource(dev); 68 #endif 69 break; 70 case RTE_PCI_KDRV_IGB_UIO: 71 case RTE_PCI_KDRV_UIO_GENERIC: 72 if (rte_eal_using_phys_addrs()) { 73 /* map resources for devices that use uio */ 74 ret = pci_uio_map_resource(dev); 75 } 76 break; 77 default: 78 PCI_LOG(DEBUG, " Not managed by a supported kernel driver, skipped"); 79 ret = 1; 80 break; 81 } 82 83 return ret; 84 } 85 86 /* Unmap pci device */ 87 void 88 rte_pci_unmap_device(struct rte_pci_device *dev) 89 { 90 /* try unmapping the NIC resources using VFIO if it exists */ 91 switch (dev->kdrv) { 92 case RTE_PCI_KDRV_VFIO: 93 #ifdef VFIO_PRESENT 94 if (pci_vfio_is_enabled()) 95 pci_vfio_unmap_resource(dev); 96 #endif 97 break; 98 case RTE_PCI_KDRV_IGB_UIO: 99 case RTE_PCI_KDRV_UIO_GENERIC: 100 /* unmap resources for devices that use uio */ 101 pci_uio_unmap_resource(dev); 102 break; 103 default: 104 PCI_LOG(DEBUG, " Not managed by a supported kernel driver, skipped"); 105 break; 106 } 107 } 108 109 static int 110 find_max_end_va(const struct rte_memseg_list *msl, void *arg) 111 { 112 size_t sz = msl->len; 113 void *end_va = RTE_PTR_ADD(msl->base_va, sz); 114 void **max_va = arg; 115 116 if (*max_va < end_va) 117 *max_va = end_va; 118 return 0; 119 } 120 121 void * 122 pci_find_max_end_va(void) 123 { 124 void *va = NULL; 125 126 rte_memseg_list_walk(find_max_end_va, &va); 127 return va; 128 } 129 130 131 /* parse one line of the "resource" sysfs file (note that the 'line' 132 * string is modified) 133 */ 134 int 135 pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr, 136 uint64_t *end_addr, uint64_t *flags) 137 { 138 union pci_resource_info { 139 struct { 140 char *phys_addr; 141 char *end_addr; 142 char *flags; 143 }; 144 char *ptrs[PCI_RESOURCE_FMT_NVAL]; 145 } res_info; 146 147 if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) { 148 PCI_LOG(ERR, "%s(): bad resource format", __func__); 149 return -1; 150 } 151 errno = 0; 152 *phys_addr = strtoull(res_info.phys_addr, NULL, 16); 153 *end_addr = strtoull(res_info.end_addr, NULL, 16); 154 *flags = strtoull(res_info.flags, NULL, 16); 155 if (errno != 0) { 156 PCI_LOG(ERR, "%s(): bad resource format", __func__); 157 return -1; 158 } 159 160 return 0; 161 } 162 163 /* parse the "resource" sysfs file */ 164 static int 165 pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev) 166 { 167 FILE *f; 168 char buf[BUFSIZ]; 169 int i; 170 uint64_t phys_addr, end_addr, flags; 171 172 f = fopen(filename, "r"); 173 if (f == NULL) { 174 PCI_LOG(ERR, "Cannot open sysfs resource"); 175 return -1; 176 } 177 178 for (i = 0; i<PCI_MAX_RESOURCE; i++) { 179 180 if (fgets(buf, sizeof(buf), f) == NULL) { 181 PCI_LOG(ERR, "%s(): cannot read resource", __func__); 182 goto error; 183 } 184 if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr, 185 &end_addr, &flags) < 0) 186 goto error; 187 188 if (flags & IORESOURCE_MEM) { 189 dev->mem_resource[i].phys_addr = phys_addr; 190 dev->mem_resource[i].len = end_addr - phys_addr + 1; 191 /* not mapped for now */ 192 dev->mem_resource[i].addr = NULL; 193 } 194 } 195 fclose(f); 196 return 0; 197 198 error: 199 fclose(f); 200 return -1; 201 } 202 203 /* Scan one pci sysfs entry, and fill the devices list from it. */ 204 static int 205 pci_scan_one(const char *dirname, const struct rte_pci_addr *addr) 206 { 207 char filename[PATH_MAX]; 208 unsigned long tmp; 209 struct rte_pci_device_internal *pdev; 210 struct rte_pci_device *dev; 211 char driver[PATH_MAX]; 212 int ret; 213 214 pdev = malloc(sizeof(*pdev)); 215 if (pdev == NULL) { 216 PCI_LOG(ERR, "Cannot allocate memory for internal pci device"); 217 return -1; 218 } 219 220 memset(pdev, 0, sizeof(*pdev)); 221 dev = &pdev->device; 222 dev->device.bus = &rte_pci_bus.bus; 223 dev->addr = *addr; 224 225 /* get vendor id */ 226 snprintf(filename, sizeof(filename), "%s/vendor", dirname); 227 if (eal_parse_sysfs_value(filename, &tmp) < 0) { 228 pci_free(pdev); 229 return -1; 230 } 231 dev->id.vendor_id = (uint16_t)tmp; 232 233 /* get device id */ 234 snprintf(filename, sizeof(filename), "%s/device", dirname); 235 if (eal_parse_sysfs_value(filename, &tmp) < 0) { 236 pci_free(pdev); 237 return -1; 238 } 239 dev->id.device_id = (uint16_t)tmp; 240 241 /* get subsystem_vendor id */ 242 snprintf(filename, sizeof(filename), "%s/subsystem_vendor", 243 dirname); 244 if (eal_parse_sysfs_value(filename, &tmp) < 0) { 245 pci_free(pdev); 246 return -1; 247 } 248 dev->id.subsystem_vendor_id = (uint16_t)tmp; 249 250 /* get subsystem_device id */ 251 snprintf(filename, sizeof(filename), "%s/subsystem_device", 252 dirname); 253 if (eal_parse_sysfs_value(filename, &tmp) < 0) { 254 pci_free(pdev); 255 return -1; 256 } 257 dev->id.subsystem_device_id = (uint16_t)tmp; 258 259 /* get class_id */ 260 snprintf(filename, sizeof(filename), "%s/class", 261 dirname); 262 if (eal_parse_sysfs_value(filename, &tmp) < 0) { 263 pci_free(pdev); 264 return -1; 265 } 266 /* the least 24 bits are valid: class, subclass, program interface */ 267 dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID; 268 269 /* get max_vfs */ 270 dev->max_vfs = 0; 271 snprintf(filename, sizeof(filename), "%s/max_vfs", dirname); 272 if (!access(filename, F_OK) && 273 eal_parse_sysfs_value(filename, &tmp) == 0) 274 dev->max_vfs = (uint16_t)tmp; 275 else { 276 /* for non igb_uio driver, need kernel version >= 3.8 */ 277 snprintf(filename, sizeof(filename), 278 "%s/sriov_numvfs", dirname); 279 if (!access(filename, F_OK) && 280 eal_parse_sysfs_value(filename, &tmp) == 0) 281 dev->max_vfs = (uint16_t)tmp; 282 } 283 284 /* get numa node, default to 0 if not present */ 285 snprintf(filename, sizeof(filename), "%s/numa_node", dirname); 286 287 if (access(filename, F_OK) == 0 && 288 eal_parse_sysfs_value(filename, &tmp) == 0) 289 dev->device.numa_node = tmp; 290 else 291 dev->device.numa_node = SOCKET_ID_ANY; 292 293 pci_common_set(dev); 294 295 /* parse resources */ 296 snprintf(filename, sizeof(filename), "%s/resource", dirname); 297 if (pci_parse_sysfs_resource(filename, dev) < 0) { 298 PCI_LOG(ERR, "%s(): cannot parse resource", __func__); 299 pci_free(pdev); 300 return -1; 301 } 302 303 /* parse driver */ 304 snprintf(filename, sizeof(filename), "%s/driver", dirname); 305 ret = pci_get_kernel_driver_by_path(filename, driver, sizeof(driver)); 306 if (ret < 0) { 307 PCI_LOG(ERR, "Fail to get kernel driver"); 308 pci_free(pdev); 309 return -1; 310 } 311 312 if (!ret) { 313 if (!strcmp(driver, "vfio-pci")) 314 dev->kdrv = RTE_PCI_KDRV_VFIO; 315 else if (!strcmp(driver, "igb_uio")) 316 dev->kdrv = RTE_PCI_KDRV_IGB_UIO; 317 else if (!strcmp(driver, "uio_pci_generic")) 318 dev->kdrv = RTE_PCI_KDRV_UIO_GENERIC; 319 else 320 dev->kdrv = RTE_PCI_KDRV_UNKNOWN; 321 } else { 322 pci_free(pdev); 323 return 0; 324 } 325 /* device is valid, add in list (sorted) */ 326 if (TAILQ_EMPTY(&rte_pci_bus.device_list)) { 327 rte_pci_add_device(dev); 328 } else { 329 struct rte_pci_device *dev2; 330 int ret; 331 332 TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) { 333 ret = rte_pci_addr_cmp(&dev->addr, &dev2->addr); 334 if (ret > 0) 335 continue; 336 337 if (ret < 0) { 338 rte_pci_insert_device(dev2, dev); 339 } else { /* already registered */ 340 if (!rte_dev_is_probed(&dev2->device)) { 341 dev2->kdrv = dev->kdrv; 342 dev2->max_vfs = dev->max_vfs; 343 dev2->id = dev->id; 344 pci_common_set(dev2); 345 memmove(dev2->mem_resource, 346 dev->mem_resource, 347 sizeof(dev->mem_resource)); 348 } else { 349 /** 350 * If device is plugged and driver is 351 * probed already, (This happens when 352 * we call rte_dev_probe which will 353 * scan all device on the bus) we don't 354 * need to do anything here unless... 355 **/ 356 if (dev2->kdrv != dev->kdrv || 357 dev2->max_vfs != dev->max_vfs || 358 memcmp(&dev2->id, &dev->id, sizeof(dev2->id))) 359 /* 360 * This should not happens. 361 * But it is still possible if 362 * we unbind a device from 363 * vfio or uio before hotplug 364 * remove and rebind it with 365 * a different configure. 366 * So we just print out the 367 * error as an alarm. 368 */ 369 PCI_LOG(ERR, "Unexpected device scan at %s!", 370 filename); 371 else if (dev2->device.devargs != 372 dev->device.devargs) { 373 rte_devargs_remove(dev2->device.devargs); 374 pci_common_set(dev2); 375 } 376 } 377 pci_free(pdev); 378 } 379 return 0; 380 } 381 382 rte_pci_add_device(dev); 383 } 384 385 return 0; 386 } 387 388 /* 389 * split up a pci address into its constituent parts. 390 */ 391 static int 392 parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr) 393 { 394 /* first split on ':' */ 395 union splitaddr { 396 struct { 397 char *domain; 398 char *bus; 399 char *devid; 400 char *function; 401 }; 402 char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */ 403 } splitaddr; 404 405 char *buf_copy = strndup(buf, bufsize); 406 if (buf_copy == NULL) 407 return -1; 408 409 if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':') 410 != PCI_FMT_NVAL - 1) 411 goto error; 412 /* final split is on '.' between devid and function */ 413 splitaddr.function = strchr(splitaddr.devid,'.'); 414 if (splitaddr.function == NULL) 415 goto error; 416 *splitaddr.function++ = '\0'; 417 418 /* now convert to int values */ 419 errno = 0; 420 addr->domain = strtoul(splitaddr.domain, NULL, 16); 421 addr->bus = strtoul(splitaddr.bus, NULL, 16); 422 addr->devid = strtoul(splitaddr.devid, NULL, 16); 423 addr->function = strtoul(splitaddr.function, NULL, 10); 424 if (errno != 0) 425 goto error; 426 427 free(buf_copy); /* free the copy made with strdup */ 428 return 0; 429 error: 430 free(buf_copy); 431 return -1; 432 } 433 434 /* 435 * Scan the content of the PCI bus, and the devices in the devices 436 * list 437 */ 438 int 439 rte_pci_scan(void) 440 { 441 struct dirent *e; 442 DIR *dir; 443 char dirname[PATH_MAX]; 444 struct rte_pci_addr addr; 445 446 /* for debug purposes, PCI can be disabled */ 447 if (!rte_eal_has_pci()) 448 return 0; 449 450 dir = opendir(rte_pci_get_sysfs_path()); 451 if (dir == NULL) { 452 PCI_LOG(ERR, "%s(): opendir failed: %s", __func__, strerror(errno)); 453 return -1; 454 } 455 456 while ((e = readdir(dir)) != NULL) { 457 if (e->d_name[0] == '.') 458 continue; 459 460 if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0) 461 continue; 462 463 if (rte_pci_ignore_device(&addr)) 464 continue; 465 466 snprintf(dirname, sizeof(dirname), "%s/%s", 467 rte_pci_get_sysfs_path(), e->d_name); 468 469 if (pci_scan_one(dirname, &addr) < 0) 470 goto error; 471 } 472 closedir(dir); 473 return 0; 474 475 error: 476 closedir(dir); 477 return -1; 478 } 479 480 #if defined(RTE_ARCH_X86) 481 bool 482 pci_device_iommu_support_va(const struct rte_pci_device *dev) 483 { 484 #define VTD_CAP_MGAW_SHIFT 16 485 #define VTD_CAP_MGAW_MASK (0x3fULL << VTD_CAP_MGAW_SHIFT) 486 const struct rte_pci_addr *addr = &dev->addr; 487 char filename[PATH_MAX]; 488 FILE *fp; 489 uint64_t mgaw, vtd_cap_reg = 0; 490 491 snprintf(filename, sizeof(filename), 492 "%s/" PCI_PRI_FMT "/iommu/intel-iommu/cap", 493 rte_pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid, 494 addr->function); 495 496 fp = fopen(filename, "r"); 497 if (fp == NULL) { 498 /* We don't have an Intel IOMMU, assume VA supported */ 499 if (errno == ENOENT) 500 return true; 501 502 PCI_LOG(ERR, "%s(): can't open %s: %s", 503 __func__, filename, strerror(errno)); 504 return false; 505 } 506 507 /* We have an Intel IOMMU */ 508 if (fscanf(fp, "%" PRIx64, &vtd_cap_reg) != 1) { 509 PCI_LOG(ERR, "%s(): can't read %s", __func__, filename); 510 fclose(fp); 511 return false; 512 } 513 514 fclose(fp); 515 516 mgaw = ((vtd_cap_reg & VTD_CAP_MGAW_MASK) >> VTD_CAP_MGAW_SHIFT) + 1; 517 518 /* 519 * Assuming there is no limitation by now. We can not know at this point 520 * because the memory has not been initialized yet. Setting the dma mask 521 * will force a check once memory initialization is done. We can not do 522 * a fallback to IOVA PA now, but if the dma check fails, the error 523 * message should advice for using '--iova-mode pa' if IOVA VA is the 524 * current mode. 525 */ 526 rte_mem_set_dma_mask(mgaw); 527 return true; 528 } 529 #elif defined(RTE_ARCH_PPC_64) 530 bool 531 pci_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev) 532 { 533 /* 534 * All POWER systems support an IOMMU, but only IOMMUv2 supports 535 * IOVA = VA in DPDK. Check contents of /proc/cpuinfo to find the 536 * system. 537 * 538 * Platform | Model | IOMMU | VA? | Comment 539 * ---------+-------+---------+-----+--------------------------------- 540 * PowerNV | N/A | IOMMUv2 | Yes | OpenPOWER (Bare Metal) 541 * pSeries | ~qemu | IOMMUv2 | Yes | PowerVM Logical Partition (LPAR) 542 * pSeries | qemu | IOMMUv1 | No | QEMU Virtual Machine 543 */ 544 545 char *line = NULL; 546 size_t len = 0; 547 char filename[PATH_MAX] = "/proc/cpuinfo"; 548 FILE *fp = fopen(filename, "r"); 549 bool pseries = false, powernv = false, qemu = false; 550 bool ret = false; 551 552 if (fp == NULL) { 553 PCI_LOG(ERR, "%s(): can't open %s: %s", 554 __func__, filename, strerror(errno)); 555 return ret; 556 } 557 558 /* Check the "platform" and "model" fields */ 559 while (getline(&line, &len, fp) != -1) { 560 if (strstr(line, "platform") != NULL) { 561 if (strstr(line, "PowerNV") != NULL) { 562 PCI_LOG(DEBUG, "Running on a PowerNV platform"); 563 powernv = true; 564 } else if (strstr(line, "pSeries") != NULL) { 565 PCI_LOG(DEBUG, "Running on a pSeries platform"); 566 pseries = true; 567 } 568 } else if (strstr(line, "model") != NULL) { 569 if (strstr(line, "qemu") != NULL) { 570 PCI_LOG(DEBUG, "Found qemu emulation"); 571 qemu = true; 572 } 573 } 574 } 575 576 free(line); 577 fclose(fp); 578 579 if (powernv || (pseries && !qemu)) 580 ret = true; 581 return ret; 582 } 583 #else 584 bool 585 pci_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev) 586 { 587 return true; 588 } 589 #endif 590 591 enum rte_iova_mode 592 pci_device_iova_mode(const struct rte_pci_driver *pdrv, 593 const struct rte_pci_device *pdev) 594 { 595 enum rte_iova_mode iova_mode = RTE_IOVA_DC; 596 597 switch (pdev->kdrv) { 598 case RTE_PCI_KDRV_VFIO: { 599 #ifdef VFIO_PRESENT 600 static int is_vfio_noiommu_enabled = -1; 601 602 if (is_vfio_noiommu_enabled == -1) { 603 if (rte_vfio_noiommu_is_enabled() == 1) 604 is_vfio_noiommu_enabled = 1; 605 else 606 is_vfio_noiommu_enabled = 0; 607 } 608 if (is_vfio_noiommu_enabled != 0) 609 iova_mode = RTE_IOVA_PA; 610 else if ((pdrv->drv_flags & RTE_PCI_DRV_NEED_IOVA_AS_VA) != 0) 611 iova_mode = RTE_IOVA_VA; 612 #endif 613 break; 614 } 615 616 case RTE_PCI_KDRV_IGB_UIO: 617 case RTE_PCI_KDRV_UIO_GENERIC: 618 iova_mode = RTE_IOVA_PA; 619 break; 620 621 default: 622 if ((pdrv->drv_flags & RTE_PCI_DRV_NEED_IOVA_AS_VA) != 0) 623 iova_mode = RTE_IOVA_VA; 624 break; 625 } 626 return iova_mode; 627 } 628 629 /* Read PCI config space. */ 630 int rte_pci_read_config(const struct rte_pci_device *device, 631 void *buf, size_t len, off_t offset) 632 { 633 char devname[RTE_DEV_NAME_MAX_LEN] = ""; 634 const struct rte_intr_handle *intr_handle = device->intr_handle; 635 636 switch (device->kdrv) { 637 case RTE_PCI_KDRV_IGB_UIO: 638 case RTE_PCI_KDRV_UIO_GENERIC: 639 return pci_uio_read_config(intr_handle, buf, len, offset); 640 #ifdef VFIO_PRESENT 641 case RTE_PCI_KDRV_VFIO: 642 return pci_vfio_read_config(device, buf, len, offset); 643 #endif 644 default: 645 rte_pci_device_name(&device->addr, devname, 646 RTE_DEV_NAME_MAX_LEN); 647 PCI_LOG(ERR, "Unknown driver type for %s", devname); 648 return -1; 649 } 650 } 651 652 /* Write PCI config space. */ 653 int rte_pci_write_config(const struct rte_pci_device *device, 654 const void *buf, size_t len, off_t offset) 655 { 656 char devname[RTE_DEV_NAME_MAX_LEN] = ""; 657 const struct rte_intr_handle *intr_handle = device->intr_handle; 658 659 switch (device->kdrv) { 660 case RTE_PCI_KDRV_IGB_UIO: 661 case RTE_PCI_KDRV_UIO_GENERIC: 662 return pci_uio_write_config(intr_handle, buf, len, offset); 663 #ifdef VFIO_PRESENT 664 case RTE_PCI_KDRV_VFIO: 665 return pci_vfio_write_config(device, buf, len, offset); 666 #endif 667 default: 668 rte_pci_device_name(&device->addr, devname, 669 RTE_DEV_NAME_MAX_LEN); 670 PCI_LOG(ERR, "Unknown driver type for %s", devname); 671 return -1; 672 } 673 } 674 675 /* Read PCI MMIO space. */ 676 int rte_pci_mmio_read(const struct rte_pci_device *device, int bar, 677 void *buf, size_t len, off_t offset) 678 { 679 char devname[RTE_DEV_NAME_MAX_LEN] = ""; 680 681 switch (device->kdrv) { 682 case RTE_PCI_KDRV_IGB_UIO: 683 case RTE_PCI_KDRV_UIO_GENERIC: 684 return pci_uio_mmio_read(device, bar, buf, len, offset); 685 #ifdef VFIO_PRESENT 686 case RTE_PCI_KDRV_VFIO: 687 return pci_vfio_mmio_read(device, bar, buf, len, offset); 688 #endif 689 default: 690 rte_pci_device_name(&device->addr, devname, 691 RTE_DEV_NAME_MAX_LEN); 692 PCI_LOG(ERR, "Unknown driver type for %s", devname); 693 return -1; 694 } 695 } 696 697 /* Write PCI MMIO space. */ 698 int rte_pci_mmio_write(const struct rte_pci_device *device, int bar, 699 const void *buf, size_t len, off_t offset) 700 { 701 char devname[RTE_DEV_NAME_MAX_LEN] = ""; 702 703 switch (device->kdrv) { 704 case RTE_PCI_KDRV_IGB_UIO: 705 case RTE_PCI_KDRV_UIO_GENERIC: 706 return pci_uio_mmio_write(device, bar, buf, len, offset); 707 #ifdef VFIO_PRESENT 708 case RTE_PCI_KDRV_VFIO: 709 return pci_vfio_mmio_write(device, bar, buf, len, offset); 710 #endif 711 default: 712 rte_pci_device_name(&device->addr, devname, 713 RTE_DEV_NAME_MAX_LEN); 714 PCI_LOG(ERR, "Unknown driver type for %s", devname); 715 return -1; 716 } 717 } 718 719 int 720 rte_pci_ioport_map(struct rte_pci_device *dev, int bar, 721 struct rte_pci_ioport *p) 722 { 723 int ret = -1; 724 725 switch (dev->kdrv) { 726 #ifdef VFIO_PRESENT 727 case RTE_PCI_KDRV_VFIO: 728 if (pci_vfio_is_enabled()) 729 ret = pci_vfio_ioport_map(dev, bar, p); 730 break; 731 #endif 732 case RTE_PCI_KDRV_IGB_UIO: 733 case RTE_PCI_KDRV_UIO_GENERIC: 734 ret = pci_uio_ioport_map(dev, bar, p); 735 break; 736 default: 737 break; 738 } 739 740 if (!ret) 741 p->dev = dev; 742 743 return ret; 744 } 745 746 void 747 rte_pci_ioport_read(struct rte_pci_ioport *p, 748 void *data, size_t len, off_t offset) 749 { 750 switch (p->dev->kdrv) { 751 #ifdef VFIO_PRESENT 752 case RTE_PCI_KDRV_VFIO: 753 pci_vfio_ioport_read(p, data, len, offset); 754 break; 755 #endif 756 case RTE_PCI_KDRV_IGB_UIO: 757 case RTE_PCI_KDRV_UIO_GENERIC: 758 pci_uio_ioport_read(p, data, len, offset); 759 break; 760 default: 761 break; 762 } 763 } 764 765 void 766 rte_pci_ioport_write(struct rte_pci_ioport *p, 767 const void *data, size_t len, off_t offset) 768 { 769 switch (p->dev->kdrv) { 770 #ifdef VFIO_PRESENT 771 case RTE_PCI_KDRV_VFIO: 772 pci_vfio_ioport_write(p, data, len, offset); 773 break; 774 #endif 775 case RTE_PCI_KDRV_IGB_UIO: 776 case RTE_PCI_KDRV_UIO_GENERIC: 777 pci_uio_ioport_write(p, data, len, offset); 778 break; 779 default: 780 break; 781 } 782 } 783 784 int 785 rte_pci_ioport_unmap(struct rte_pci_ioport *p) 786 { 787 int ret = -1; 788 789 switch (p->dev->kdrv) { 790 #ifdef VFIO_PRESENT 791 case RTE_PCI_KDRV_VFIO: 792 if (pci_vfio_is_enabled()) 793 ret = pci_vfio_ioport_unmap(p); 794 break; 795 #endif 796 case RTE_PCI_KDRV_IGB_UIO: 797 case RTE_PCI_KDRV_UIO_GENERIC: 798 ret = pci_uio_ioport_unmap(p); 799 break; 800 default: 801 break; 802 } 803 804 return ret; 805 } 806