| 1409 | } |
| 1410 | |
| 1411 | int |
| 1412 | intr_alloc_msix(device_t pci, device_t child, intptr_t xref, int *irq) |
| 1413 | { |
| 1414 | struct iommu_domain *domain; |
| 1415 | struct intr_irqsrc *isrc; |
| 1416 | struct intr_pic *pic; |
| 1417 | device_t pdev; |
| 1418 | struct intr_map_data_msi *msi; |
| 1419 | int err; |
| 1420 | |
| 1421 | pic = pic_lookup(NULL, xref, FLAG_MSI); |
| 1422 | if (pic == NULL) |
| 1423 | return (ESRCH); |
| 1424 | |
| 1425 | KASSERT((pic->pic_flags & FLAG_TYPE_MASK) == FLAG_MSI, |
| 1426 | ("%s: Found a non-MSI controller: %s", __func__, |
| 1427 | device_get_name(pic->pic_dev))); |
| 1428 | |
| 1429 | /* |
| 1430 | * If this is the first time we have used this context ask the |
| 1431 | * interrupt controller to map memory the msi source will need. |
| 1432 | */ |
| 1433 | err = MSI_IOMMU_INIT(pic->pic_dev, child, &domain); |
| 1434 | if (err != 0) |
| 1435 | return (err); |
| 1436 | |
| 1437 | err = MSI_ALLOC_MSIX(pic->pic_dev, child, &pdev, &isrc); |
| 1438 | if (err != 0) |
| 1439 | return (err); |
| 1440 | |
| 1441 | isrc->isrc_iommu = domain; |
| 1442 | msi = (struct intr_map_data_msi *)intr_alloc_map_data( |
| 1443 | INTR_MAP_DATA_MSI, sizeof(*msi), M_WAITOK | M_ZERO); |
| 1444 | msi->isrc = isrc; |
| 1445 | *irq = intr_map_irq(pic->pic_dev, xref, (struct intr_map_data *)msi); |
| 1446 | return (0); |
| 1447 | } |
| 1448 | |
| 1449 | int |
| 1450 | intr_release_msix(device_t pci, device_t child, intptr_t xref, int irq) |
no test coverage detected