Powering down / 'stop'ing cards under NEWCARD?

Mark Santcroos marks at ripe.net
Tue May 6 01:12:13 PDT 2003


On Mon, May 05, 2003 at 11:31:24PM -0700, Cliff L. Biffle wrote:
> That specific problem I'll deal with another day, but for now, is there any 
> way to 'stop' a card under -current with NEWCARD?

The following patch was provided by Mitsuru IWASAKI:
(Find his original post at current@ Oct 29 2002)

Index: pccbb.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/pccbb/pccbb.c,v
retrieving revision 1.59
diff -u -r1.59 pccbb.c
--- pccbb.c	11 Oct 2002 04:30:59 -0000	1.59
+++ pccbb.c	29 Oct 2002 10:55:48 -0000
@@ -86,6 +86,8 @@
 #include <sys/sysctl.h>
 #include <sys/kthread.h>
 #include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/ioccom.h>
 #include <machine/bus.h>
 #include <sys/rman.h>
 #include <machine/resource.h>
@@ -210,6 +212,13 @@
 SYSCTL_ULONG(_hw_cbb, OID_AUTO, debug, CTLFLAG_RW, &cbb_debug, 0,
     "Verbose cardbus bridge debugging");
 
+int cbb_boot_deactivated = 0;
+TUNABLE_INT("hw.cbb.boot_deactivated", &cbb_boot_deactivated);
+SYSCTL_INT(_hw_cbb, OID_AUTO, boot_deactivated, CTLFLAG_RD,
+    &cbb_boot_deactivated, 0,
+    "Override the automatic powering up of pccards at boot.");
+
+
 static int	cbb_chipset(uint32_t pci_id, const char **namep);
 static int	cbb_probe(device_t brdev);
 static void	cbb_chipinit(struct cbb_softc *sc);
@@ -264,6 +273,93 @@
 static void	cbb_write_config(device_t brdev, int b, int s, int f,
 		    int reg, uint32_t val, int width);
 
+static d_open_t		crdopen;
+static d_close_t	crdclose;
+static d_ioctl_t	crdioctl;
+
+#define CDEV_MAJOR 50
+static struct cdevsw crd_cdevsw = {
+	/* open */	crdopen,
+	/* close */	crdclose,
+	/* read */	noread,
+	/* write */	nowrite,
+	/* ioctl */	crdioctl,
+	/* poll */	nopoll,
+	/* mmap */	nommap,
+	/* strategy */	nostrategy,
+	/* name */	"crd",
+	/* maj */	CDEV_MAJOR,
+	/* dump */	nodump,
+	/* psize */	nopsize,
+	/* flags */	0,
+};
+
+#define PIOCSVIR	_IOW('P', 10, int)	/* Virtual insert/remove */
+
+static  int
+crdopen(dev_t dev, int oflags, int devtype, d_thread_t *td)
+{
+	if (dev == NULL || dev->si_drv1 == NULL) {
+		return (ENXIO);
+	}
+
+	return (0);
+}
+
+static  int
+crdclose(dev_t dev, int fflag, int devtype, d_thread_t *td)
+{
+	return (0);
+}
+
+static  int
+crdioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, d_thread_t *td)
+{
+	struct cbb_softc *sc;
+	int		error;
+	int		pwval;
+
+	sc = dev->si_drv1;
+	error = 0;
+
+	switch(cmd) {
+	/*
+	 * Set power values.
+	 */
+	case PIOCSVIR:
+		pwval = *(int *)data;
+
+		switch (pwval) {
+		case 0:
+			if (!(sc->flags & CBB_CARD_OK)) {
+				error = EINVAL;
+				break;
+			}
+
+			sc->flags |= CBB_INACTIVATE;
+			cbb_removal(sc);
+			break;
+
+		case 1:
+			if (sc->flags & CBB_CARD_OK) {
+				error = EINVAL;
+				break;
+			}
+
+			sc->flags &= ~CBB_INACTIVATE;
+			cbb_insert(sc);
+			break;
+		}
+
+		break;
+
+	default:
+		error = ENOTTY;
+	}
+
+	return (error);
+}
+
 /*
  */
 static __inline void
@@ -560,6 +656,8 @@
 {
 	struct cbb_softc *sc = (struct cbb_softc *)device_get_softc(brdev);
 	int rid;
+	int unit;
+	dev_t cbb_dev_t;
 
 	mtx_init(&sc->mtx, device_get_nameunit(brdev), "cbb", MTX_DEF);
 	cv_init(&sc->cv, "cbb cv");
@@ -680,6 +778,10 @@
 	/* reset interrupt */
 	cbb_set(sc, CBB_SOCKET_EVENT, cbb_get(sc, CBB_SOCKET_EVENT));
 
+	if (cbb_boot_deactivated) {
+		sc->flags |= CBB_INACTIVATE;
+	}
+
 	/* Start the thread */
 	if (kthread_create(cbb_event_thread, sc, &sc->event_thread, 0, 0,
 		"%s%d", device_get_name(sc->dev), device_get_unit(sc->dev))) {
@@ -687,6 +789,10 @@
 		panic ("cbb_create_event_thread");
 	}
 
+	unit = device_get_unit(sc->dev);
+	cbb_dev_t = make_dev(&crd_cdevsw, unit, 0, 0, 0664, "card%d", unit);
+	cbb_dev_t->si_drv1 = sc;
+
 	return (0);
 err:
 	if (sc->irq_res)
@@ -913,10 +1019,14 @@
 
 		status = cbb_get(sc, CBB_SOCKET_STATE);
 		mtx_lock(&Giant);
-		if ((status & CBB_SOCKET_STAT_CD) == 0)
-			cbb_insert(sc);
-		else
+		if ((status & CBB_SOCKET_STAT_CD) == 0) {
+			if (!(sc->flags & CBB_INACTIVATE)) {
+				cbb_insert(sc);
+			}
+		} else {
+			sc->flags &= ~CBB_INACTIVATE;
 			cbb_removal(sc);
+		}
 		mtx_unlock(&Giant);
 
 		/*
@@ -995,6 +1105,7 @@
 	else if ((!(sc->flags & CBB_16BIT_CARD)) && sc->cbdev != NULL)
 		CARD_DETACH_CARD(sc->cbdev, DETACH_FORCE);
 	cbb_destroy_res(sc);
+	sc->flags &= ~CBB_CARD_OK;
 }
 
 /************************************************************************/
@@ -1918,7 +2029,10 @@
 	cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD);
 
 	/* Force us to go query the socket state */
-	cbb_setb(sc, CBB_SOCKET_FORCE, CBB_SOCKET_EVENT_CD);
+	mtx_lock(&sc->mtx);
+	sc->flags &= ~CBB_CARD_OK;
+	cv_signal(&sc->cv);
+	mtx_unlock(&sc->mtx);
 
 	error = bus_generic_resume(self);
 
Index: pccbbvar.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/pccbb/pccbbvar.h,v
retrieving revision 1.15
diff -u -r1.15 pccbbvar.h
--- pccbbvar.h	7 Oct 2002 23:11:29 -0000	1.15
+++ pccbbvar.h	28 Oct 2002 15:31:17 -0000
@@ -65,6 +65,7 @@
 	struct mtx	mtx;
 	struct cv	cv;
 	u_int32_t	flags;
+#define CBB_INACTIVATE		0x04000000
 #define CBB_CARD_OK		0x08000000
 #define	CBB_KLUDGE_ALLOC	0x10000000
 #define	CBB_16BIT_CARD		0x20000000

-- 
Mark Santcroos                    RIPE Network Coordination Centre
http://www.ripe.net/home/mark/    New Projects Group/TTM


More information about the freebsd-mobile mailing list