diff -upr sys.org/dev/pccbb/pccbb.c sys/dev/pccbb/pccbb.c --- sys.org/dev/pccbb/pccbb.c Thu Jun 12 15:06:14 2003 +++ sys/dev/pccbb/pccbb.c Wed Jun 25 17:49:28 2003 @@ -86,6 +86,8 @@ #include #include #include +#include +#include #include #include #include @@ -193,6 +195,12 @@ SYSCTL_ULONG(_hw_cbb, OID_AUTO, start_me &cbb_start_mem, CBB_START_MEM, "Starting address for memory allocations"); +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."); + u_long cbb_start_16_io = CBB_START_16_IO; TUNABLE_INT("hw.cbb.start_16_io", (int *)&cbb_start_16_io); SYSCTL_ULONG(_hw_cbb, OID_AUTO, start_16_io, CTLFLAG_RW, @@ -264,6 +272,86 @@ static uint32_t cbb_read_config(device_t 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 MAJOR_AUTO +static struct cdevsw crd_cdevsw = { + .d_open = crdopen, + .d_close = crdclose, + .d_ioctl = crdioctl, + .d_name = "crd", + .d_maj = CDEV_MAJOR, + .d_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 @@ -629,6 +717,8 @@ cbb_attach(device_t brdev) { 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"); @@ -751,6 +841,10 @@ cbb_attach(device_t brdev) if (bootverbose) cbb_print_config(brdev); + 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(brdev), device_get_unit(brdev))) { @@ -758,6 +852,10 @@ cbb_attach(device_t brdev) 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) @@ -1034,6 +1132,7 @@ cbb_removal(struct cbb_softc *sc) CARD_DETACH_CARD(sc->cbdev); } cbb_destroy_res(sc); + sc->flags &= ~CBB_CARD_OK; } /************************************************************************/ diff -upr sys.org/dev/pccbb/pccbbvar.h sys/dev/pccbb/pccbbvar.h --- sys.org/dev/pccbb/pccbbvar.h Thu Jun 12 12:37:28 2003 +++ sys/dev/pccbb/pccbbvar.h Wed Jun 25 17:49:28 2003 @@ -66,6 +66,7 @@ struct cbb_softc { 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