| 667 | } |
| 668 | |
| 669 | static int |
| 670 | ccp_setup_interrupts(struct ccp_softc *sc) |
| 671 | { |
| 672 | uint32_t nvec; |
| 673 | int rid, error, n, ridcopy; |
| 674 | |
| 675 | n = pci_msix_count(sc->dev); |
| 676 | if (n < 1) { |
| 677 | device_printf(sc->dev, "%s: msix_count: %d\n", __func__, n); |
| 678 | return (ENXIO); |
| 679 | } |
| 680 | |
| 681 | nvec = n; |
| 682 | error = pci_alloc_msix(sc->dev, &nvec); |
| 683 | if (error != 0) { |
| 684 | device_printf(sc->dev, "%s: alloc_msix error: %d\n", __func__, |
| 685 | error); |
| 686 | return (error); |
| 687 | } |
| 688 | if (nvec < 1) { |
| 689 | device_printf(sc->dev, "%s: alloc_msix: 0 vectors\n", |
| 690 | __func__); |
| 691 | return (ENXIO); |
| 692 | } |
| 693 | if (nvec > nitems(sc->intr_res)) { |
| 694 | device_printf(sc->dev, "%s: too many vectors: %u\n", __func__, |
| 695 | nvec); |
| 696 | nvec = nitems(sc->intr_res); |
| 697 | } |
| 698 | |
| 699 | for (rid = 1; rid < 1 + nvec; rid++) { |
| 700 | ridcopy = rid; |
| 701 | sc->intr_res[rid - 1] = bus_alloc_resource_any(sc->dev, |
| 702 | SYS_RES_IRQ, &ridcopy, RF_ACTIVE); |
| 703 | if (sc->intr_res[rid - 1] == NULL) { |
| 704 | device_printf(sc->dev, "%s: Failed to alloc IRQ resource\n", |
| 705 | __func__); |
| 706 | return (ENXIO); |
| 707 | } |
| 708 | |
| 709 | sc->intr_tag[rid - 1] = NULL; |
| 710 | error = bus_setup_intr(sc->dev, sc->intr_res[rid - 1], |
| 711 | INTR_MPSAFE | INTR_TYPE_MISC, ccp_intr_filter, |
| 712 | ccp_intr_handler, sc, &sc->intr_tag[rid - 1]); |
| 713 | if (error != 0) |
| 714 | device_printf(sc->dev, "%s: setup_intr: %d\n", |
| 715 | __func__, error); |
| 716 | } |
| 717 | sc->intr_count = nvec; |
| 718 | |
| 719 | return (error); |
| 720 | } |
| 721 | |
| 722 | static void |
| 723 | ccp_release_interrupts(struct ccp_softc *sc) |
no test coverage detected