pccard 56k preventing suspend

Mitsuru IWASAKI iwasaki at jp.FreeBSD.org
Fri Sep 12 16:41:04 PDT 2003


Hi,

> > From: Jesse Guardiani <jesse at wingnet.net>
> > Date: Fri, 12 Sep 2003 18:49:31 -0400
> > Sender: owner-freebsd-mobile at freebsd.org
> > 
> > Kevin Oberman wrote:
> > 
> > >> From: Jesse Guardiani <jesse at wingnet.net>
> > >> Date: Fri, 12 Sep 2003 18:29:57 -0400
> > >> Sender: owner-freebsd-mobile at freebsd.org
> > >> 
> > >> Hmmmm....
> > >> 
> > >> Just when I thought I had everything working:
> > >> 
> > >> I bought a remanufactured 56k 3Com Megahertz 3CXM756.
> > >> 
> > >> The modem works great, but now I've found that I
> > >> can't suspend my laptop unless I remove the card.
> > >> 
> > >> Nothing bad happens if I try to suspend with the
> > >> card plugged in - it just goes into standby mode,
> > >> and I can come out of standby with no ill side-
> > >> effects, but it's a bit inconvenient having to
> > >> remove my shiny new pccard everytime I want to
> > >> suspend.
> > >> 
> > >> Any ideas?
> > >> 
> > >> I tried using pccardc to power down the slot, but
> > >> I'm not running pccardd, and /dev/card* doesn't
> > >> exist...
> > > 
> > > This seems to be an IBM BIOS issue that I've never tracked down. I
> > > seldom use a PCcard with my T30 as it has WiFi and Ethernet built in,
> > > but I believe that it suspends OK when I disconnect the AC line.
> > 
> > Wow. You're right. That works. Wierd.
> > 
> > 
> > > I
> > > might also get there by switching from X to a vty. I did this a lot on
> > > my old 600E.
> > 
> > I automatically switch to a vty from my rc.suspend script. Otherwise
> > the laptop never comes back on-line on resume.
> > 
> > Anyway, I'm a big fan of scripting. If I add:
> > 
> > device card 1 # pccard bus
> > 
> > Do you think I'll then be able to power down the card slot with:
> > 
> > pccardc power 1 0
> > 
> > And then do a successful suspend even with the AC plugged?
> > 
> > Also, do I have to add that device line to my kernel? Or is there a
> > dynamic way to do it using the hints file?
> 
> I don't think that this will work. imp can say for sure, but I think
> you would need to completely switch to OLDCARD to use pccardc and that
> won't work with CardBus cards. I think your stuck with pulling the
> plug before suspending. (You can plug it right back in. It will sty
> suspended.) 

I have a patch for pccardc power command for NEWCARD. Enjoy!

Index: pccbb.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/pccbb/pccbb.c,v
retrieving revision 1.95
diff -u -r1.95 pccbb.c
--- pccbb.c	22 Aug 2003 08:49:56 -0000	1.95
+++ pccbb.c	4 Sep 2003 23:33:55 -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>
@@ -221,6 +223,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);
@@ -275,6 +284,90 @@
 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;
+
+#if __FreeBSD_version < 500000
+#define CDEV_MAJOR 50
+#else
+#define CDEV_MAJOR MAJOR_AUTO
+#endif
+
+static struct cdevsw crd_cdevsw = {
+	/* open */	.d_open =	crdopen,
+	/* close */	.d_close =	crdclose,
+	/* ioctl */	.d_ioctl =	crdioctl,
+	/* name */	.d_name =	"crd",
+	/* maj */	.d_maj =	CDEV_MAJOR,
+};
+
+#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
@@ -677,6 +770,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");
@@ -795,6 +890,10 @@
 	/* reset interrupt */
 	cbb_set(sc, CBB_SOCKET_EVENT, cbb_get(sc, CBB_SOCKET_EVENT));
 
+	if (cbb_boot_deactivated) {
+		sc->flags |= CBB_INACTIVATE;
+	}
+
 	if (bootverbose)
 		cbb_print_config(brdev);
 
@@ -805,6 +904,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)
@@ -1001,6 +1104,7 @@
 		DPRINTF(("Status is 0x%x\n", status));
 		if (!CBB_CARD_PRESENT(status)) {
 			not_a_card = 0;		/* We know card type */
+			sc->flags &= ~CBB_INACTIVATE;
 			cbb_removal(sc);
 		} else if (status & CBB_STATE_NOT_A_CARD) {
 			/*
@@ -1017,7 +1121,9 @@
 			}
 		} else {
 			not_a_card = 0;		/* We know card type */
-			cbb_insert(sc);
+			if (!(sc->flags & CBB_INACTIVATE)) {
+				cbb_insert(sc);
+			}
 		}
 		mtx_unlock(&Giant);
 
@@ -1098,6 +1204,7 @@
 			CARD_DETACH_CARD(sc->cbdev);
 	}
 	cbb_destroy_res(sc);
+	sc->flags &= ~CBB_CARD_OK;
 }
 
 /************************************************************************/
Index: pccbbvar.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/pccbb/pccbbvar.h,v
retrieving revision 1.19
diff -u -r1.19 pccbbvar.h
--- pccbbvar.h	12 Jun 2003 03:37:28 -0000	1.19
+++ pccbbvar.h	4 Sep 2003 22:48:01 -0000
@@ -66,6 +66,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


More information about the freebsd-mobile mailing list