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