Module Name: src Committed By: skrll Date: Tue Sep 6 11:55:07 UTC 2022
Modified Files: src/sys/arch/arm/fdt: pcihost_fdt.c pcihost_fdtvar.h Log Message: pcihost: Track MSI/MSI-X interrupt handlers. Track the MSI/MSI-X interrupt handlers so that fdtbus_intr_disestablish doesn't get called for them. This avoids a KASSERT firing when using 'drvctl -d' on a pci device that uses MSI/MSI-X interrupts. To generate a diff of this commit: cvs rdiff -u -r1.30 -r1.31 src/sys/arch/arm/fdt/pcihost_fdt.c cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/fdt/pcihost_fdtvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/fdt/pcihost_fdt.c diff -u src/sys/arch/arm/fdt/pcihost_fdt.c:1.30 src/sys/arch/arm/fdt/pcihost_fdt.c:1.31 --- src/sys/arch/arm/fdt/pcihost_fdt.c:1.30 Sun Sep 4 16:01:25 2022 +++ src/sys/arch/arm/fdt/pcihost_fdt.c Tue Sep 6 11:55:07 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: pcihost_fdt.c,v 1.30 2022/09/04 16:01:25 skrll Exp $ */ +/* $NetBSD: pcihost_fdt.c,v 1.31 2022/09/06 11:55:07 skrll Exp $ */ /*- * Copyright (c) 2018 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pcihost_fdt.c,v 1.30 2022/09/04 16:01:25 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pcihost_fdt.c,v 1.31 2022/09/06 11:55:07 skrll Exp $"); #include <sys/param.h> @@ -101,6 +101,12 @@ static const struct device_compatible_en DEVICE_COMPAT_EOL }; +struct pcihost_msi_handler { + LIST_ENTRY(pcihost_msi_handler) pmh_next; + void *pmh_ih; +}; + + static int pcihost_match(device_t parent, cfdata_t cf, void *aux) { @@ -178,6 +184,8 @@ pcihost_init2(struct pcihost_softc *sc) if (of_getprop_uint32(sc->sc_phandle, "linux,pci-domain", &sc->sc_seg)) sc->sc_seg = pcihost_segment++; + mutex_init(&sc->sc_msi_handlers_mutex, MUTEX_DEFAULT, IPL_NONE); + if (pcihost_config(sc) != 0) return; @@ -601,18 +609,30 @@ pcihost_intr_setattr(void *v, pci_intr_h } static void * -pcihost_intr_establish(void *v, pci_intr_handle_t ih, int ipl, +pcihost_intr_establish(void *v, pci_intr_handle_t pih, int ipl, int (*callback)(void *), void *arg, const char *xname) { struct pcihost_softc *sc = v; - const int flags = (ih & ARM_PCI_INTR_MPSAFE) ? FDT_INTR_MPSAFE : 0; + const int flags = (pih & ARM_PCI_INTR_MPSAFE) ? FDT_INTR_MPSAFE : 0; const u_int *specifier; int ihandle; - if ((ih & (ARM_PCI_INTR_MSI | ARM_PCI_INTR_MSIX)) != 0) - return arm_pci_msi_intr_establish(&sc->sc_pc, ih, ipl, callback, arg, xname); + if ((pih & (ARM_PCI_INTR_MSI | ARM_PCI_INTR_MSIX)) != 0) { + void *ih = arm_pci_msi_intr_establish(&sc->sc_pc, pih, ipl, + callback, arg, xname); + + if (ih) { + struct pcihost_msi_handler * const pmh = + kmem_alloc(sizeof(*pmh), KM_SLEEP); + pmh->pmh_ih = ih; + mutex_enter(&sc->sc_msi_handlers_mutex); + LIST_INSERT_HEAD(&sc->sc_msi_handlers, pmh, pmh_next); + mutex_exit(&sc->sc_msi_handlers_mutex); + } + return ih; + } - specifier = pcihost_find_intr(sc, ih & ARM_PCI_INTR_IRQ, &ihandle); + specifier = pcihost_find_intr(sc, pih & ARM_PCI_INTR_IRQ, &ihandle); if (specifier == NULL) return NULL; @@ -625,6 +645,18 @@ pcihost_intr_disestablish(void *v, void { struct pcihost_softc *sc = v; + mutex_enter(&sc->sc_msi_handlers_mutex); + struct pcihost_msi_handler *pmh; + LIST_FOREACH(pmh, &sc->sc_msi_handlers, pmh_next) { + if (pmh->pmh_ih == vih) { + LIST_REMOVE(pmh, pmh_next); + mutex_exit(&sc->sc_msi_handlers_mutex); + kmem_free(pmh, sizeof(*pmh)); + return; + } + } + mutex_exit(&sc->sc_msi_handlers_mutex); + fdtbus_intr_disestablish(sc->sc_phandle, vih); } Index: src/sys/arch/arm/fdt/pcihost_fdtvar.h diff -u src/sys/arch/arm/fdt/pcihost_fdtvar.h:1.4 src/sys/arch/arm/fdt/pcihost_fdtvar.h:1.5 --- src/sys/arch/arm/fdt/pcihost_fdtvar.h:1.4 Mon Sep 6 14:03:17 2021 +++ src/sys/arch/arm/fdt/pcihost_fdtvar.h Tue Sep 6 11:55:07 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: pcihost_fdtvar.h,v 1.4 2021/09/06 14:03:17 jmcneill Exp $ */ +/* $NetBSD: pcihost_fdtvar.h,v 1.5 2022/09/06 11:55:07 skrll Exp $ */ /*- * Copyright (c) 2018 Jared D. McNeill <jmcne...@invisible.ca> @@ -47,6 +47,8 @@ enum pcihost_type { PCIHOST_ECAM, }; +struct pcihost_msi_handlers; + struct pcih_bus_space { struct bus_space bst; @@ -85,6 +87,10 @@ struct pcihost_softc { const u_int *sc_pci_ranges; u_int sc_pci_ranges_cells; + + kmutex_t sc_msi_handlers_mutex; + LIST_HEAD(, pcihost_msi_handler) + sc_msi_handlers; }; void pcihost_init2(struct pcihost_softc *);