Hi, I've implemented pccardc power and boot_deactivated support code for NEWCARD. They are needed for some mobile users including me.
- Add pccardc power support code. Yes, it's OLDCARD compatible. - Add new loader tunable hw.cbb.boot_deactivated to prevent pccards from attaching automatically. Some people want to keep pccards in slots all the time even if they don't want to use the pccard. They can power pccard on via pccardc command now (and in OLDCARD days) when it's required, so automatic attaching pccards at boot time is not desired behavior for them. This is quick hack actually (took about 1 hour), so it's not clean at all. But it's good enough for prototype, working great for me actually :) Enjoy! 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 To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message