/* * Detach a keyboard. To keep track of users of the softc we keep * a reference count that's incremented while inside, e.g., read. * If the keyboard is active and the reference count is > 0 (0 is the * normal state) we post an event and then wait for the process * that had the reference to wake us up again. Then we blow away the * vnode and return (which will deallocate the softc). */ int wskbd_detach(struct device *self, int flags) { struct wskbd_softc *sc = (struct wskbd_softc *)self; struct wseventvar *evar; int maj, mn; int s; #if NWSMUX > 0 /* Tell parent mux we're leaving. */ if (sc->sc_base.me_parent != NULL) wsmux_detach_sc(&sc->sc_base); #endif #if NWSDISPLAY > 0 if (sc->sc_repeating) { sc->sc_repeating = 0; timeout_del(&sc->sc_repeat_ch); } #endif if (sc->sc_isconsole) { KASSERT(wskbd_console_device == sc); wskbd_console_device = NULL; } evar = sc->sc_base.me_evp; if (evar != NULL && evar->io != NULL) { s = spltty(); if (--sc->sc_refcnt >= 0) { /* Wake everyone by generating a dummy event. */ if (++evar->put >= WSEVENT_QSIZE) evar->put = 0; WSEVENT_WAKEUP(evar); /* Wait for processes to go away. */ if (tsleep(sc, PZERO, "wskdet", hz * 60)) printf("wskbd_detach: %s didn't detach\n", sc->sc_base.me_dv.dv_xname); } splx(s); } /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == wskbdopen) break; /* Nuke the vnodes for any open instances. */ mn = self->dv_unit; vdevgone(maj, mn, mn, VCHR); return (0); }
/* * Detach a keyboard. To keep track of users of the softc we keep * a reference count that's incremented while inside, e.g., read. * If the keyboard is active and the reference count is > 0 (0 is the * normal state) we post an event and then wait for the process * that had the reference to wake us up again. Then we blow away the * vnode and return (which will deallocate the softc). */ int wskbd_detach(device_t self, int flags) { struct wskbd_softc *sc = device_private(self); struct wseventvar *evar; int maj, mn; int s; #if NWSMUX > 0 /* Tell parent mux we're leaving. */ if (sc->sc_base.me_parent != NULL) wsmux_detach_sc(&sc->sc_base); #endif callout_halt(&sc->sc_repeat_ch, NULL); callout_destroy(&sc->sc_repeat_ch); if (sc->sc_isconsole) { KASSERT(wskbd_console_device == sc); wskbd_console_device = NULL; } pmf_device_deregister(self); evar = sc->sc_base.me_evp; if (evar != NULL && evar->io != NULL) { s = spltty(); if (--sc->sc_refcnt >= 0) { struct wscons_event event; /* Wake everyone by generating a dummy event. */ event.type = 0; event.value = 0; if (wsevent_inject(evar, &event, 1) != 0) wsevent_wakeup(evar); /* Wait for processes to go away. */ if (tsleep(sc, PZERO, "wskdet", hz * 60)) aprint_error("wskbd_detach: %s didn't detach\n", device_xname(self)); } splx(s); } /* locate the major number */ maj = cdevsw_lookup_major(&wskbd_cdevsw); /* Nuke the vnodes for any open instances. */ mn = device_unit(self); vdevgone(maj, mn, mn, VCHR); return (0); }
int wskbdopen(dev_t dev, int flags, int mode, struct proc *p) { struct wskbd_softc *sc; struct wseventvar *evar; int unit, error; unit = minor(dev); if (unit >= wskbd_cd.cd_ndevs || /* make sure it was attached */ (sc = wskbd_cd.cd_devs[unit]) == NULL) return (ENXIO); #if NWSMUX > 0 DPRINTF(("wskbdopen: %s mux=%p p=%p\n", sc->sc_base.me_dv.dv_xname, sc->sc_base.me_parent, p)); #endif if (sc->sc_dying) return (EIO); if ((flags & (FREAD | FWRITE)) == FWRITE) { /* Not opening for read, only ioctl is available. */ return (0); } #if NWSMUX > 0 if (sc->sc_base.me_parent != NULL) { /* Grab the keyboard out of the greedy hands of the mux. */ DPRINTF(("wskbdopen: detach\n")); wsmux_detach_sc(&sc->sc_base); } #endif if (sc->sc_base.me_evp != NULL) return (EBUSY); evar = &sc->sc_base.me_evar; wsevent_init(evar); evar->io = p->p_p; error = wskbd_do_open(sc, evar); if (error) { DPRINTF(("wskbdopen: %s open failed\n", sc->sc_base.me_dv.dv_xname)); sc->sc_base.me_evp = NULL; wsevent_fini(evar); } return (error); }
int wsmouseopen(dev_t dev, int flags, int mode, struct proc *p) { struct wsmouse_softc *sc; struct wseventvar *evar; int error, unit; unit = minor(dev); if (unit >= wsmouse_cd.cd_ndevs || /* make sure it was attached */ (sc = wsmouse_cd.cd_devs[unit]) == NULL) return (ENXIO); #if NWSMUX > 0 DPRINTF(("wsmouseopen: %s mux=%p p=%p\n", sc->sc_base.me_dv.dv_xname, sc->sc_base.me_parent, p)); #endif if (sc->sc_dying) return (EIO); if ((flags & (FREAD | FWRITE)) == FWRITE) return (0); /* always allow open for write so ioctl() is possible. */ #if NWSMUX > 0 if (sc->sc_base.me_parent != NULL) { /* Grab the mouse out of the greedy hands of the mux. */ DPRINTF(("wsmouseopen: detach\n")); wsmux_detach_sc(&sc->sc_base); } #endif if (sc->sc_base.me_evp != NULL) return (EBUSY); evar = &sc->sc_base.me_evar; wsevent_init(evar); evar->io = p->p_p; error = wsmousedoopen(sc, evar); if (error) { DPRINTF(("wsmouseopen: %s open failed\n", sc->sc_base.me_dv.dv_xname)); sc->sc_base.me_evp = NULL; wsevent_fini(evar); } return (error); }
/* * Detach a mouse. To keep track of users of the softc we keep * a reference count that's incremented while inside, e.g., read. * If the mouse is active and the reference count is > 0 (0 is the * normal state) we post an event and then wait for the process * that had the reference to wake us up again. Then we blow away the * vnode and return (which will deallocate the softc). */ int wsmouse_detach(device_t self, int flags) { struct wsmouse_softc *sc = device_private(self); struct wseventvar *evar; int maj, mn; int s; #if NWSMUX > 0 /* Tell parent mux we're leaving. */ if (sc->sc_base.me_parent != NULL) { DPRINTF(("wsmouse_detach:\n")); wsmux_detach_sc(&sc->sc_base); } #endif /* If we're open ... */ evar = sc->sc_base.me_evp; if (evar != NULL && evar->io != NULL) { s = spltty(); if (--sc->sc_refcnt >= 0) { struct wscons_event event; /* Wake everyone by generating a dummy event. */ event.type = 0; event.value = 0; if (wsevent_inject(evar, &event, 1) != 0) wsevent_wakeup(evar); /* Wait for processes to go away. */ if (tsleep(sc, PZERO, "wsmdet", hz * 60)) printf("wsmouse_detach: %s didn't detach\n", device_xname(self)); } splx(s); } /* locate the major number */ maj = cdevsw_lookup_major(&wsmouse_cdevsw); /* Nuke the vnodes for any open instances (calls close). */ mn = device_unit(self); vdevgone(maj, mn, mn, VCHR); return (0); }
int wskbdopen(dev_t dev, int flags, int mode, struct lwp *l) { struct wskbd_softc *sc = device_lookup_private(&wskbd_cd, minor(dev)); struct wseventvar *evar; int error; if (sc == NULL) return (ENXIO); #if NWSMUX > 0 DPRINTF(("wskbdopen: %s mux=%p l=%p\n", device_xname(sc->sc_base.me_dv), sc->sc_base.me_parent, l)); #endif if (sc->sc_dying) return (EIO); if ((flags & (FREAD | FWRITE)) == FWRITE) /* Not opening for read, only ioctl is available. */ return (0); #if NWSMUX > 0 if (sc->sc_base.me_parent != NULL) { /* Grab the keyboard out of the greedy hands of the mux. */ DPRINTF(("wskbdopen: detach\n")); wsmux_detach_sc(&sc->sc_base); } #endif if (sc->sc_base.me_evp != NULL) return (EBUSY); evar = &sc->sc_base.me_evar; wsevent_init(evar, l->l_proc); error = wskbd_do_open(sc, evar); if (error) { DPRINTF(("wskbdopen: %s open failed\n", device_xname(sc->sc_base.me_dv))); sc->sc_base.me_evp = NULL; wsevent_fini(evar); } return (error); }
/* * Detach a mouse. To keep track of users of the softc we keep * a reference count that's incremented while inside, e.g., read. * If the mouse is active and the reference count is > 0 (0 is the * normal state) we post an event and then wait for the process * that had the reference to wake us up again. Then we blow away the * vnode and return (which will deallocate the softc). */ int wsmouse_detach(struct device *self, int flags) { struct wsmouse_softc *sc = (struct wsmouse_softc *)self; struct wseventvar *evar; int maj, mn; int s; #if NWSMUX > 0 /* Tell parent mux we're leaving. */ if (sc->sc_base.me_parent != NULL) { DPRINTF(("wsmouse_detach:\n")); wsmux_detach_sc(&sc->sc_base); } #endif /* If we're open ... */ evar = sc->sc_base.me_evp; if (evar != NULL && evar->io != NULL) { s = spltty(); if (--sc->sc_refcnt >= 0) { /* Wake everyone by generating a dummy event. */ if (++evar->put >= WSEVENT_QSIZE) evar->put = 0; WSEVENT_WAKEUP(evar); /* Wait for processes to go away. */ if (tsleep(sc, PZERO, "wsmdet", hz * 60)) printf("wsmouse_detach: %s didn't detach\n", sc->sc_base.me_dv.dv_xname); } splx(s); } /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == wsmouseopen) break; /* Nuke the vnodes for any open instances (calls close). */ mn = self->dv_unit; vdevgone(maj, mn, mn, VCHR); return (0); }