| 588 | } |
| 589 | |
| 590 | int |
| 591 | ppt_setup_msix(struct vm *vm, int vcpu, int bus, int slot, int func, |
| 592 | int idx, uint64_t addr, uint64_t msg, uint32_t vector_control) |
| 593 | { |
| 594 | struct pptdev *ppt; |
| 595 | struct pci_devinfo *dinfo; |
| 596 | int numvec, alloced, rid, error; |
| 597 | size_t res_size, cookie_size, arg_size; |
| 598 | |
| 599 | error = ppt_find(vm, bus, slot, func, &ppt); |
| 600 | if (error) |
| 601 | return (error); |
| 602 | |
| 603 | /* Reject attempts to enable MSI-X while MSI is active. */ |
| 604 | if (ppt->msi.num_msgs != 0) |
| 605 | return (EBUSY); |
| 606 | |
| 607 | dinfo = device_get_ivars(ppt->dev); |
| 608 | if (!dinfo) |
| 609 | return (ENXIO); |
| 610 | |
| 611 | /* |
| 612 | * First-time configuration: |
| 613 | * Allocate the MSI-X table |
| 614 | * Allocate the IRQ resources |
| 615 | * Set up some variables in ppt->msix |
| 616 | */ |
| 617 | if (ppt->msix.num_msgs == 0) { |
| 618 | numvec = pci_msix_count(ppt->dev); |
| 619 | if (numvec <= 0) |
| 620 | return (EINVAL); |
| 621 | |
| 622 | ppt->msix.startrid = 1; |
| 623 | ppt->msix.num_msgs = numvec; |
| 624 | |
| 625 | res_size = numvec * sizeof(ppt->msix.res[0]); |
| 626 | cookie_size = numvec * sizeof(ppt->msix.cookie[0]); |
| 627 | arg_size = numvec * sizeof(ppt->msix.arg[0]); |
| 628 | |
| 629 | ppt->msix.res = malloc(res_size, M_PPTMSIX, M_WAITOK | M_ZERO); |
| 630 | ppt->msix.cookie = malloc(cookie_size, M_PPTMSIX, |
| 631 | M_WAITOK | M_ZERO); |
| 632 | ppt->msix.arg = malloc(arg_size, M_PPTMSIX, M_WAITOK | M_ZERO); |
| 633 | |
| 634 | rid = dinfo->cfg.msix.msix_table_bar; |
| 635 | ppt->msix.msix_table_res = bus_alloc_resource_any(ppt->dev, |
| 636 | SYS_RES_MEMORY, &rid, RF_ACTIVE); |
| 637 | |
| 638 | if (ppt->msix.msix_table_res == NULL) { |
| 639 | ppt_teardown_msix(ppt); |
| 640 | return (ENOSPC); |
| 641 | } |
| 642 | ppt->msix.msix_table_rid = rid; |
| 643 | |
| 644 | if (dinfo->cfg.msix.msix_table_bar != |
| 645 | dinfo->cfg.msix.msix_pba_bar) { |
| 646 | rid = dinfo->cfg.msix.msix_pba_bar; |
| 647 | ppt->msix.msix_pba_res = bus_alloc_resource_any( |
no test coverage detected