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);
 	}

Reply via email to