Module Name: src Committed By: jdolecek Date: Wed May 5 19:30:51 UTC 2021
Modified Files: src/sys/dev/pci: siisata_pci.c Log Message: disable MSI for SiI3124 - interrupts don't seem to work on this old board when MSI is enabled, maybe because it's behind a PCI bridge PR kern/55115 by John D. Baker To generate a diff of this commit: cvs rdiff -u -r1.20 -r1.21 src/sys/dev/pci/siisata_pci.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/siisata_pci.c diff -u src/sys/dev/pci/siisata_pci.c:1.20 src/sys/dev/pci/siisata_pci.c:1.21 --- src/sys/dev/pci/siisata_pci.c:1.20 Thu Oct 25 21:03:19 2018 +++ src/sys/dev/pci/siisata_pci.c Wed May 5 19:30:51 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata_pci.c,v 1.20 2018/10/25 21:03:19 jdolecek Exp $ */ +/* $NetBSD: siisata_pci.c,v 1.21 2021/05/05 19:30:51 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -51,7 +51,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: siisata_pci.c,v 1.20 2018/10/25 21:03:19 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata_pci.c,v 1.21 2021/05/05 19:30:51 jdolecek Exp $"); #include <sys/types.h> #include <sys/malloc.h> @@ -82,14 +82,22 @@ struct siisata_pci_board { pci_product_id_t spb_prod; uint16_t spb_port; uint16_t spb_chip; + uint8_t sbp_flags; }; +#define SIISATA_BROKEN_MSI 0x01 + static const struct siisata_pci_board siisata_pci_boards[] = { { .spb_vend = PCI_VENDOR_CMDTECH, .spb_prod = PCI_PRODUCT_CMDTECH_3124, .spb_port = 4, .spb_chip = 3124, + /* + * SiI3124 seems to be PCI/PCI-X chip behind PCI-e bridge, + * claims MSI support but interrups don't work with MSI on. + */ + .sbp_flags = SIISATA_BROKEN_MSI, }, { .spb_vend = PCI_VENDOR_CMDTECH, @@ -157,6 +165,9 @@ siisata_pci_attach(device_t parent, devi bus_size_t grsize, prsize; char intrbuf[PCI_INTRSTR_LEN]; + spbp = siisata_pci_lookup(pa); + KASSERT(spbp != NULL); + sc->sc_atac.atac_dev = self; psc->sc_pc = pa->pa_pc; @@ -210,8 +221,19 @@ siisata_pci_attach(device_t parent, devi else sc->sc_dmat = pa->pa_dmat; + int counts[PCI_INTR_TYPE_SIZE] = { + [PCI_INTR_TYPE_INTX] = 1, + [PCI_INTR_TYPE_MSI] = 1, + [PCI_INTR_TYPE_MSIX] = 1, + }; + int max_type = PCI_INTR_TYPE_MSIX; + + if (spbp->sbp_flags & SIISATA_BROKEN_MSI) { + max_type = PCI_INTR_TYPE_INTX; + } + /* map interrupt */ - if (pci_intr_alloc(pa, &psc->sc_pihp, NULL, 0) != 0) { + if (pci_intr_alloc(pa, &psc->sc_pihp, counts, max_type) != 0) { bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize); bus_space_unmap(sc->sc_prt, sc->sc_prh, prsize); aprint_error_dev(self, "couldn't map interrupt\n"); @@ -235,8 +257,6 @@ siisata_pci_attach(device_t parent, devi intrstr ? intrstr : "unknown interrupt"); /* fill in number of ports on this device */ - spbp = siisata_pci_lookup(pa); - KASSERT(spbp != NULL); sc->sc_atac.atac_nchannels = spbp->spb_port; /* set the necessary bits in case the firmware didn't */