Re: Powering down / 'stop'ing cards under NEWCARD?

Mark Santcroos <[email protected]>
Newsgroups gmane.os.freebsd.devel.mobile
Message-ID <[email protected]>
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
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-mobile
To unsubscribe, send any mail to "[email protected]"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.