Module Name: src Committed By: msaitoh Date: Tue May 9 06:29:20 UTC 2017
Modified Files: src/sys/dev/pci: ppb.c Log Message: - Fix a bug that a device which has no PCIe capability incorrectly accessess the PCI config area in ppbdetach(). - Don't add event counters if slot interrupt isn't used. To generate a diff of this commit: cvs rdiff -u -r1.61 -r1.62 src/sys/dev/pci/ppb.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/ppb.c diff -u src/sys/dev/pci/ppb.c:1.61 src/sys/dev/pci/ppb.c:1.62 --- src/sys/dev/pci/ppb.c:1.61 Thu Apr 27 04:44:02 2017 +++ src/sys/dev/pci/ppb.c Tue May 9 06:29:20 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ppb.c,v 1.61 2017/04/27 04:44:02 msaitoh Exp $ */ +/* $NetBSD: ppb.c,v 1.62 2017/05/09 06:29:20 msaitoh Exp $ */ /* * Copyright (c) 1996, 1998 Christopher G. Demetriou. All rights reserved. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ppb.c,v 1.61 2017/04/27 04:44:02 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ppb.c,v 1.62 2017/05/09 06:29:20 msaitoh Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -257,7 +257,7 @@ ppbattach(device_t parent, device_t self sc->sc_pciecapoff + PCIE_SLCSR, reg); } #ifdef PPB_USEINTR -#if 0 +#if 0 /* notyet */ /* * XXX Initialize workqueue or something else for * HotPlug support. @@ -267,71 +267,88 @@ ppbattach(device_t parent, device_t self sc->sc_intrhand = pci_intr_establish_xname(pc, sc->sc_pihp[0], IPL_BIO, ppb_intr, sc, device_xname(sc->sc_dev)); +#endif + } + +#ifdef PPB_USEINTR + if (sc->sc_intrhand != NULL) { + pcireg_t slcap, slcsr, val; + + intrstr = pci_intr_string(pc, sc->sc_pihp[0], intrbuf, + sizeof(intrbuf)); + aprint_normal_dev(self, "%s\n", intrstr); - if (sc->sc_intrhand) { - pcireg_t slcap, slcsr, val; + /* Clear any pending events */ + slcsr = pci_conf_read(pc, pa->pa_tag, + sc->sc_pciecapoff + PCIE_SLCSR); + pci_conf_write(pc, pa->pa_tag, + sc->sc_pciecapoff + PCIE_SLCSR, slcsr); - intrstr = pci_intr_string(pc, sc->sc_pihp[0], intrbuf, - sizeof(intrbuf)); - aprint_normal_dev(self, "%s\n", intrstr); - - /* Clear any pending events */ - slcsr = pci_conf_read(pc, pa->pa_tag, - sc->sc_pciecapoff + PCIE_SLCSR); - pci_conf_write(pc, pa->pa_tag, - sc->sc_pciecapoff + PCIE_SLCSR, slcsr); - - /* Enable interrupt. */ - val = 0; - slcap = pci_conf_read(pc, pa->pa_tag, - sc->sc_pciecapoff + PCIE_SLCAP); - if (slcap & PCIE_SLCAP_ABP) - val |= PCIE_SLCSR_ABE; - if (slcap & PCIE_SLCAP_PCP) - val |= PCIE_SLCSR_PFE; - if (slcap & PCIE_SLCAP_MSP) - val |= PCIE_SLCSR_MSE; + /* Enable interrupt. */ + val = 0; + slcap = pci_conf_read(pc, pa->pa_tag, + sc->sc_pciecapoff + PCIE_SLCAP); + if (slcap & PCIE_SLCAP_ABP) + val |= PCIE_SLCSR_ABE; + if (slcap & PCIE_SLCAP_PCP) + val |= PCIE_SLCSR_PFE; + if (slcap & PCIE_SLCAP_MSP) + val |= PCIE_SLCSR_MSE; #if 0 + /* + * XXX Disable for a while because setting + * PCIE_SLCSR_CCE makes break device access on + * some environment. + */ + if ((slcap & PCIE_SLCAP_NCCS) == 0) + val |= PCIE_SLCSR_CCE; +#endif + /* Attention indicator off by default */ + if (slcap & PCIE_SLCAP_AIP) { + val |= __SHIFTIN(PCIE_SLCSR_IND_OFF, + PCIE_SLCSR_AIC); + } + /* Power indicator */ + if (slcap & PCIE_SLCAP_PIP) { /* - * XXX Disable for a while because setting - * PCIE_SLCSR_CCE makes break device access on - * some environment. + * Indicator off: + * a) card not present + * b) power fault + * c) MRL sensor off */ - if ((slcap & PCIE_SLCAP_NCCS) == 0) - val |= PCIE_SLCSR_CCE; -#endif - /* Attention indicator off by default */ - if (slcap & PCIE_SLCAP_AIP) { + if (((slcsr & PCIE_SLCSR_PDS) == 0) + || ((slcsr & PCIE_SLCSR_PFD) != 0) + || (((slcap & PCIE_SLCAP_MSP) != 0) + && ((slcsr & PCIE_SLCSR_MS) != 0))) val |= __SHIFTIN(PCIE_SLCSR_IND_OFF, - PCIE_SLCSR_AIC); - } - /* Power indicator */ - if (slcap & PCIE_SLCAP_PIP) { - /* - * Indicator off: - * a) card not present - * b) power fault - * c) MRL sensor off - */ - if (((slcsr & PCIE_SLCSR_PDS) == 0) - || ((slcsr & PCIE_SLCSR_PFD) != 0) - || (((slcap & PCIE_SLCAP_MSP) != 0) - && ((slcsr & PCIE_SLCSR_MS) != 0))) - val |= __SHIFTIN(PCIE_SLCSR_IND_OFF, - PCIE_SLCSR_PIC); - else - val |= __SHIFTIN(PCIE_SLCSR_IND_ON, - PCIE_SLCSR_PIC); - } - - val |= PCIE_SLCSR_DLLSCE | PCIE_SLCSR_HPE - | PCIE_SLCSR_PDE; - slcsr = val; - pci_conf_write(pc, pa->pa_tag, - sc->sc_pciecapoff + PCIE_SLCSR, slcsr); + PCIE_SLCSR_PIC); + else + val |= __SHIFTIN(PCIE_SLCSR_IND_ON, + PCIE_SLCSR_PIC); } -#endif /* PPB_USEINTR */ + + val |= PCIE_SLCSR_DLLSCE | PCIE_SLCSR_HPE | PCIE_SLCSR_PDE; + slcsr = val; + pci_conf_write(pc, pa->pa_tag, + sc->sc_pciecapoff + PCIE_SLCSR, slcsr); + + /* Attach event counters */ + evcnt_attach_dynamic(&sc->sc_ev_intr, EVCNT_TYPE_INTR, NULL, + device_xname(sc->sc_dev), "Interrupt"); + evcnt_attach_dynamic(&sc->sc_ev_abp, EVCNT_TYPE_MISC, NULL, + device_xname(sc->sc_dev), "Attention Button Pressed"); + evcnt_attach_dynamic(&sc->sc_ev_pfd, EVCNT_TYPE_MISC, NULL, + device_xname(sc->sc_dev), "Power Fault Detected"); + evcnt_attach_dynamic(&sc->sc_ev_msc, EVCNT_TYPE_MISC, NULL, + device_xname(sc->sc_dev), "MRL Sensor Changed"); + evcnt_attach_dynamic(&sc->sc_ev_pdc, EVCNT_TYPE_MISC, NULL, + device_xname(sc->sc_dev), "Presence Detect Changed"); + evcnt_attach_dynamic(&sc->sc_ev_cc, EVCNT_TYPE_MISC, NULL, + device_xname(sc->sc_dev), "Command Completed"); + evcnt_attach_dynamic(&sc->sc_ev_lacs, EVCNT_TYPE_MISC, NULL, + device_xname(sc->sc_dev), "Data Link Layer State Changed"); } +#endif /* PPB_USEINTR */ if (!pmf_device_register(self, ppb_suspend, ppb_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); @@ -354,24 +371,6 @@ ppbattach(device_t parent, device_t self pba.pba_intrswiz = pa->pa_intrswiz; pba.pba_intrtag = pa->pa_intrtag; -#ifdef PPB_USEINTR - /* Attach event counters */ - evcnt_attach_dynamic(&sc->sc_ev_intr, EVCNT_TYPE_INTR, NULL, - device_xname(sc->sc_dev), "Interrupt"); - evcnt_attach_dynamic(&sc->sc_ev_abp, EVCNT_TYPE_MISC, NULL, - device_xname(sc->sc_dev), "Attention Button Pressed"); - evcnt_attach_dynamic(&sc->sc_ev_pfd, EVCNT_TYPE_MISC, NULL, - device_xname(sc->sc_dev), "Power Fault Detected"); - evcnt_attach_dynamic(&sc->sc_ev_msc, EVCNT_TYPE_MISC, NULL, - device_xname(sc->sc_dev), "MRL Sensor Changed"); - evcnt_attach_dynamic(&sc->sc_ev_pdc, EVCNT_TYPE_MISC, NULL, - device_xname(sc->sc_dev), "Presence Detect Changed"); - evcnt_attach_dynamic(&sc->sc_ev_cc, EVCNT_TYPE_MISC, NULL, - device_xname(sc->sc_dev), "Command Completed"); - evcnt_attach_dynamic(&sc->sc_ev_lacs, EVCNT_TYPE_MISC, NULL, - device_xname(sc->sc_dev), "Data Link Layer State Changed"); -#endif - config_found_ia(self, "pcibus", &pba, pcibusprint); } @@ -388,24 +387,24 @@ ppbdetach(device_t self, int flags) return rc; #ifdef PPB_USEINTR - /* Detach event counters */ - evcnt_detach(&sc->sc_ev_intr); - evcnt_detach(&sc->sc_ev_abp); - evcnt_detach(&sc->sc_ev_pfd); - evcnt_detach(&sc->sc_ev_msc); - evcnt_detach(&sc->sc_ev_pdc); - evcnt_detach(&sc->sc_ev_cc); - evcnt_detach(&sc->sc_ev_lacs); - - /* Clear any pending events and disable interrupt */ - slcsr = pci_conf_read(sc->sc_pc, sc->sc_tag, - sc->sc_pciecapoff + PCIE_SLCSR); - slcsr &= ~PCIE_SLCSR_ENABLE_MASK; - pci_conf_write(sc->sc_pc, sc->sc_tag, - sc->sc_pciecapoff + PCIE_SLCSR, slcsr); - - /* Disestablish the interrupt handler */ if (sc->sc_intrhand != NULL) { + /* Detach event counters */ + evcnt_detach(&sc->sc_ev_intr); + evcnt_detach(&sc->sc_ev_abp); + evcnt_detach(&sc->sc_ev_pfd); + evcnt_detach(&sc->sc_ev_msc); + evcnt_detach(&sc->sc_ev_pdc); + evcnt_detach(&sc->sc_ev_cc); + evcnt_detach(&sc->sc_ev_lacs); + + /* Clear any pending events and disable interrupt */ + slcsr = pci_conf_read(sc->sc_pc, sc->sc_tag, + sc->sc_pciecapoff + PCIE_SLCSR); + slcsr &= ~PCIE_SLCSR_ENABLE_MASK; + pci_conf_write(sc->sc_pc, sc->sc_tag, + sc->sc_pciecapoff + PCIE_SLCSR, slcsr); + + /* Disestablish the interrupt handler */ pci_intr_disestablish(sc->sc_pc, sc->sc_intrhand); pci_intr_release(sc->sc_pc, sc->sc_pihp, 1); }