Date: Sat, 13 Sep 2003 08:40:30 +0900 (JST) From: Mitsuru IWASAKI <iwasaki@jp.FreeBSD.org> To: oberman@es.net Cc: freebsd-mobile@freebsd.org Subject: Re: pccard 56k preventing suspend Message-ID: <20030913.084030.21588099.iwasaki@jp.FreeBSD.org> In-Reply-To: <20030912225331.BEF1D5D08@ptavv.es.net> References: <jesse@wingnet.net> <20030912225331.BEF1D5D08@ptavv.es.net>
next in thread | previous in thread | raw e-mail | index | archive | help
Hi, > > From: Jesse Guardiani <jesse@wingnet.net> > > Date: Fri, 12 Sep 2003 18:49:31 -0400 > > Sender: owner-freebsd-mobile@freebsd.org > > > > Kevin Oberman wrote: > > > > >> From: Jesse Guardiani <jesse@wingnet.net> > > >> Date: Fri, 12 Sep 2003 18:29:57 -0400 > > >> Sender: owner-freebsd-mobile@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030913.084030.21588099.iwasaki>