Created
June 15, 2015 16:21
-
-
Save nonakap/32a245f50f5be7bc2742 to your computer and use it in GitHub Desktop.
hdaudio(4): Use MSI instead of legacy INTx, if available.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/sys/dev/pci/hdaudio_pci.c b/sys/dev/pci/hdaudio_pci.c | |
| index 12ab15b..0b68cf7 100644 | |
| --- a/sys/dev/pci/hdaudio_pci.c | |
| +++ b/sys/dev/pci/hdaudio_pci.c | |
| @@ -58,6 +58,9 @@ struct hdaudio_pci_softc { | |
| pci_chipset_tag_t sc_pc; | |
| void *sc_ih; | |
| pcireg_t sc_id; | |
| +#ifdef __HAVE_PCI_MSI_MSIX | |
| + pci_intr_handle_t *sc_pihp; | |
| +#endif | |
| }; | |
| static int hdaudio_pci_match(device_t, cfdata_t, void *); | |
| @@ -105,7 +108,9 @@ hdaudio_pci_attach(device_t parent, device_t self, void *opaque) | |
| { | |
| struct hdaudio_pci_softc *sc = device_private(self); | |
| struct pci_attach_args *pa = opaque; | |
| +#ifndef __HAVE_PCI_MSI_MSIX | |
| pci_intr_handle_t ih; | |
| +#endif | |
| const char *intrstr; | |
| pcireg_t csr; | |
| int err; | |
| @@ -140,6 +145,22 @@ hdaudio_pci_attach(device_t parent, device_t self, void *opaque) | |
| sc->sc_hdaudio.sc_dmat = pa->pa_dmat; | |
| /* Map interrupt and establish handler */ | |
| +#ifdef __HAVE_PCI_MSI_MSIX | |
| + int error = ENODEV; | |
| + if (pci_msi_count(pa) > 0) { | |
| + error = pci_msi_alloc_exact(pa, &sc->sc_pihp, 1); | |
| + } | |
| + if (error != 0) { | |
| + if (pci_intx_alloc(pa, &sc->sc_pihp)) { | |
| + aprint_error_dev(self, "couldn't map interrupt\n"); | |
| + return; | |
| + } | |
| + } | |
| + intrstr = pci_intr_string(pa->pa_pc, sc->sc_pihp[0], intrbuf, | |
| + sizeof(intrbuf)); | |
| + sc->sc_ih = pci_intr_establish(pa->pa_pc, sc->sc_pihp[0], IPL_AUDIO, | |
| + hdaudio_pci_intr, sc); | |
| +#else | |
| err = pci_intr_map(pa, &ih); | |
| if (err) { | |
| aprint_error_dev(self, "couldn't map interrupt\n"); | |
| @@ -148,6 +169,7 @@ hdaudio_pci_attach(device_t parent, device_t self, void *opaque) | |
| intrstr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf)); | |
| sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, | |
| hdaudio_pci_intr, sc); | |
| +#endif | |
| if (sc->sc_ih == NULL) { | |
| aprint_error_dev(self, "couldn't establish interrupt"); | |
| if (intrstr) | |
| @@ -165,6 +187,9 @@ hdaudio_pci_attach(device_t parent, device_t self, void *opaque) | |
| /* Attach bus-independent HD audio layer */ | |
| if (hdaudio_attach(self, &sc->sc_hdaudio)) { | |
| pci_intr_disestablish(sc->sc_pc, sc->sc_ih); | |
| +#ifdef __HAVE_PCI_MSI_MSIX | |
| + pci_intr_release(sc->sc_pc, sc->sc_pihp, 1); | |
| +#endif | |
| sc->sc_ih = NULL; | |
| bus_space_unmap(sc->sc_hdaudio.sc_memt, | |
| sc->sc_hdaudio.sc_memh, | |
| @@ -173,6 +198,7 @@ hdaudio_pci_attach(device_t parent, device_t self, void *opaque) | |
| csr = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG); | |
| csr &= ~(PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_BACKTOBACK_ENABLE); | |
| pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG, csr); | |
| + pmf_device_deregister(self); | |
| } | |
| } | |
| @@ -202,6 +228,9 @@ hdaudio_pci_detach(device_t self, int flags) | |
| if (sc->sc_ih != NULL) { | |
| pci_intr_disestablish(sc->sc_pc, sc->sc_ih); | |
| +#ifdef __HAVE_PCI_MSI_MSIX | |
| + pci_intr_release(sc->sc_pc, sc->sc_pihp, 1); | |
| +#endif | |
| sc->sc_ih = NULL; | |
| } | |
| if (sc->sc_hdaudio.sc_memvalid == true) { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment