Module Name:    src
Committed By:   jdc
Date:           Sun Jan 17 11:57:29 UTC 2010

Modified Files:
        src/sys/dev/pci: if_cas.c

Log Message:
Mask out (disable) cas interrupts on detach and suspend.
(Re-)enable interrupts on resume.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/pci/if_cas.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/if_cas.c
diff -u src/sys/dev/pci/if_cas.c:1.2 src/sys/dev/pci/if_cas.c:1.3
--- src/sys/dev/pci/if_cas.c:1.2	Sat Jan  9 13:34:33 2010
+++ src/sys/dev/pci/if_cas.c	Sun Jan 17 11:57:29 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_cas.c,v 1.2 2010/01/09 13:34:33 martin Exp $	*/
+/*	$NetBSD: if_cas.c,v 1.3 2010/01/17 11:57:29 jdc Exp $	*/
 /*	$OpenBSD: if_cas.c,v 1.29 2009/11/29 16:19:38 kettenis Exp $	*/
 
 /*
@@ -44,7 +44,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_cas.c,v 1.2 2010/01/09 13:34:33 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_cas.c,v 1.3 2010/01/17 11:57:29 jdc Exp $");
 
 #include "opt_inet.h"
 #include "bpfilter.h"
@@ -115,7 +115,7 @@
 
 #define TRIES	10000
 
-static bool	cas_estintr(struct cas_softc *sc);
+static bool	cas_estintr(struct cas_softc *sc, int);
 bool		cas_shutdown(device_t, int);
 static bool	cas_suspend(device_t, pmf_qual_t);
 static bool	cas_resume(device_t, pmf_qual_t);
@@ -385,7 +385,7 @@
 		return;
 	}
 	sc->sc_pc = pa->pa_pc;
-	if (!cas_estintr(sc)) {
+	if (!cas_estintr(sc, CAS_INTR_PCI)) {
 		bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_size);
 		aprint_error_dev(sc->sc_dev, "unable to establish interrupt\n");
 		return;
@@ -657,6 +657,8 @@
 {
 	int i;
 	struct cas_softc *sc = device_private(self);
+	bus_space_tag_t t = sc->sc_memt;
+	bus_space_handle_t h = sc->sc_memh;
 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 
 	/*
@@ -665,6 +667,7 @@
 	 */
 	switch (sc->sc_att_stage) {
 	case CAS_ATT_FINISHED:
+		bus_space_write_4(t, h, CAS_INTMASK, ~(uint32_t)0);
 		pmf_device_deregister(self);
 		cas_stop(&sc->sc_ethercom.ec_if, 1);
 		evcnt_detach(&sc->sc_ev_intr);
@@ -695,7 +698,7 @@
 		for (i = 0; i < CAS_NRXDESC; i++) {
 			if (sc->sc_rxsoft[i].rxs_dmamap != NULL)
 				bus_dmamap_unload(sc->sc_dmatag,
-		   		    sc->sc_rxsoft[i].rxs_dmamap);
+				    sc->sc_rxsoft[i].rxs_dmamap);
 			if (sc->sc_rxsoft[i].rxs_dmamap != NULL)
 				bus_dmamap_destroy(sc->sc_dmatag,
 				    sc->sc_rxsoft[i].rxs_dmamap);
@@ -1139,18 +1142,7 @@
 	}
 
 	/* step 8. Global Configuration & Interrupt Mask */
-	bus_space_write_4(t, h, CAS_INTMASK,
-		      ~(CAS_INTR_TX_INTME|CAS_INTR_TX_EMPTY|
-			CAS_INTR_TX_TAG_ERR|
-			CAS_INTR_RX_DONE|CAS_INTR_RX_NOBUF|
-			CAS_INTR_RX_TAG_ERR|
-			CAS_INTR_RX_COMP_FULL|CAS_INTR_PCS|
-			CAS_INTR_MAC_CONTROL|CAS_INTR_MIF|
-			CAS_INTR_BERR));
-	bus_space_write_4(t, h, CAS_MAC_RX_MASK,
-	    CAS_MAC_RX_DONE|CAS_MAC_RX_FRAME_CNT);
-	bus_space_write_4(t, h, CAS_MAC_TX_MASK, CAS_MAC_TX_XMIT_DONE);
-	bus_space_write_4(t, h, CAS_MAC_CONTROL_MASK, 0); /* XXXX */
+	cas_estintr(sc, CAS_INTR_REG);
 
 	/* step 9. ETX Configuration: use mostly default values */
 
@@ -1240,7 +1232,7 @@
 
 		/* Secondary MAC addresses set to 0:0:0:0:0:0 */
 		for (r = CAS_MAC_ADDR3; r < CAS_MAC_ADDR42; r += 4)
-		  	bus_space_write_4(t, h, r, 0);
+			bus_space_write_4(t, h, r, 0);
 
 		/* MAC control addr set to 0:1:c2:0:1:80 */
 		bus_space_write_4(t, h, CAS_MAC_ADDR42, 0x0001);
@@ -1515,9 +1507,9 @@
 	if (status & CAS_INTR_RX_MAC) {
 		int rxstat = bus_space_read_4(t, seb, CAS_MAC_RX_STATUS);
 #ifdef CAS_DEBUG
- 		if (rxstat & ~CAS_MAC_RX_DONE)
- 			printf("%s: MAC rx fault, status %x\n",
- 			    device_xname(sc->sc_dev), rxstat);
+		if (rxstat & ~CAS_MAC_RX_DONE)
+			printf("%s: MAC rx fault, status %x\n",
+			    device_xname(sc->sc_dev), rxstat);
 #endif
 		/*
 		 * On some chip revisions CAS_MAC_RX_OVERFLOW happen often
@@ -1833,11 +1825,6 @@
 		}
 	}
 
-	/* Try to get things going again */
-/*
-	if (ifp->if_flags & IFF_UP)
-		cas_start(ifp);
-*/
 	splx(s);
 	return (error);
 }
@@ -1846,7 +1833,10 @@
 cas_suspend(device_t self, pmf_qual_t qual)
 {
 	struct cas_softc *sc = device_private(self);
+	bus_space_tag_t t = sc->sc_memt;
+	bus_space_handle_t h = sc->sc_memh;
 
+	bus_space_write_4(t, h, CAS_INTMASK, ~(uint32_t)0);
 	if (sc->sc_ih != NULL) {
 		pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
 		sc->sc_ih = NULL;
@@ -1860,26 +1850,48 @@
 {
 	struct cas_softc *sc = device_private(self);
 
-	return cas_estintr(sc);
+	return cas_estintr(sc, CAS_INTR_PCI | CAS_INTR_REG);
 }
 
 static bool
-cas_estintr(struct cas_softc *sc)
+cas_estintr(struct cas_softc *sc, int what)
 {
+	bus_space_tag_t t = sc->sc_memt;
+	bus_space_handle_t h = sc->sc_memh;
 	const char *intrstr = NULL;
 
-	intrstr = pci_intr_string(sc->sc_pc, sc->sc_handle);
-	sc->sc_ih = pci_intr_establish(sc->sc_pc, sc->sc_handle,
-	    IPL_NET, cas_intr, sc);
-	if (sc->sc_ih == NULL) {
-		aprint_error_dev(sc->sc_dev, "unable to establish interrupt");
-		if (intrstr != NULL)
-			aprint_error(" at %s", intrstr);
-		aprint_error("\n");
-		return false;
+	/* PCI interrupts */
+	if (what & CAS_INTR_PCI) {
+		intrstr = pci_intr_string(sc->sc_pc, sc->sc_handle);
+		sc->sc_ih = pci_intr_establish(sc->sc_pc, sc->sc_handle,
+		    IPL_NET, cas_intr, sc);
+		if (sc->sc_ih == NULL) {
+			aprint_error_dev(sc->sc_dev,
+			    "unable to establish interrupt");
+			if (intrstr != NULL)
+				aprint_error(" at %s", intrstr);
+			aprint_error("\n");
+			return false;
+		}
+
+		aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);
 	}
 
-	aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);
+	/* Interrupt register */
+	if (what & CAS_INTR_REG) {
+		bus_space_write_4(t, h, CAS_INTMASK,
+		    ~(CAS_INTR_TX_INTME|CAS_INTR_TX_EMPTY|
+		    CAS_INTR_TX_TAG_ERR|
+		    CAS_INTR_RX_DONE|CAS_INTR_RX_NOBUF|
+		    CAS_INTR_RX_TAG_ERR|
+		    CAS_INTR_RX_COMP_FULL|CAS_INTR_PCS|
+		    CAS_INTR_MAC_CONTROL|CAS_INTR_MIF|
+		    CAS_INTR_BERR));
+		bus_space_write_4(t, h, CAS_MAC_RX_MASK,
+		    CAS_MAC_RX_DONE|CAS_MAC_RX_FRAME_CNT);
+		bus_space_write_4(t, h, CAS_MAC_TX_MASK, CAS_MAC_TX_XMIT_DONE);
+		bus_space_write_4(t, h, CAS_MAC_CONTROL_MASK, 0); /* XXXX */
+	}
 	return true;
 }
 

Reply via email to