Revoke the vnodes on detach. This avoids the crashes people have seen

when moused was still running when the mouse was detached.

Convert uhid to use make_dev while I am there. Ugen still needs to be
converted.
This commit is contained in:
n_hibma 1999-11-21 17:25:30 +00:00
parent d1dec864e4
commit 183c85e4b4
4 changed files with 48 additions and 17 deletions

View File

@ -149,9 +149,10 @@ static usb_config_descriptor_t *ugen_get_cdesc __P((struct ugen_softc *sc,
static usbd_status ugen_set_interface __P((struct ugen_softc *, int, int));
static int ugen_get_alt_index __P((struct ugen_softc *sc, int ifaceidx));
#define UGENENDPMAX 16 /* maximum number of endpoints, see usb spec */
#define UGENUNIT(n) ((minor(n) >> 4) & 0xf)
#define UGENENDPOINT(n) (minor(n) & 0xf)
#define UGENDEV(u, e) (makedev(0, ((u) << 4) | (e)))
#define UGENDEV(u, e) (makedev(UGEN_CDEV_MAJOR, ((u) << 4) | (e)))
USB_DECLARE_DRIVER(ugen);
@ -629,7 +630,13 @@ USB_DETACH(ugen)
int s;
#if defined(__NetBSD__) || defined(__OpenBSD__)
int maj, mn;
#elif defined(__FreeBSD__)
struct vnode *vp;
dev_t dev;
int endpt;
#endif
#if defined(__NetBSD__) || defined(__OpenBSD__)
DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc, flags));
#elif defined(__FreeBSD__)
DPRINTF(("ugen_detach: sc=%p\n", sc));
@ -665,7 +672,12 @@ USB_DETACH(ugen)
mn = self->dv_unit * USB_MAX_ENDPOINTS;
vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR);
#elif defined(__FreeBSD__)
/* XXX not implemented yet */
for (endpt = 0; endpt < UGENENDPMAX; endpt++) {
dev = UGENDEV(device_get_unit(self), endpt);
vp = SLIST_FIRST(&dev->si_hlist);
if (vp)
VOP_REVOKE(vp, REVOKEALL);
}
#endif
return (0);

View File

@ -110,6 +110,10 @@ struct uhid_softc {
int sc_refcnt;
u_char sc_dying;
#if defined(__FreeBSD__)
dev_t dev;
#endif
};
#define UHIDUNIT(dev) (minor(dev))
@ -232,16 +236,12 @@ USB_ATTACH(uhid)
sc->sc_repdesc = desc;
sc->sc_repdesc_size = size;
#ifdef __FreeBSD__
{
static int global_init_done = 0;
if (!global_init_done) {
cdevsw_add(&uhid_cdevsw);
global_init_done = 1;
}
}
#if defined(__FreeBSD__)
sc->dev = make_dev(&uhid_cdevsw, device_get_unit(self),
UID_ROOT, GID_OPERATOR,
0644, "uhid%d", device_get_unit(self));
#endif
USB_ATTACH_SUCCESS_RETURN;
}
@ -272,7 +272,11 @@ USB_DETACH(uhid)
int s;
#if defined(__NetBSD__) || defined(__OpenBSD__)
int maj, mn;
#elif defined(__FreeBSD__)
struct vnode *vp;
#endif
#if defined(__NetBSD__) || defined(__OpenBSD__)
DPRINTF(("uhid_detach: sc=%p flags=%d\n", sc, flags));
#else
DPRINTF(("uhid_detach: sc=%p\n", sc));
@ -303,7 +307,11 @@ USB_DETACH(uhid)
mn = self->dv_unit;
vdevgone(maj, mn, mn, VCHR);
#elif defined(__FreeBSD__)
/* XXX not implemented yet */
vp = SLIST_FIRST(&sc->dev->si_hlist);
if (vp)
VOP_REVOKE(vp, REVOKEALL);
destroy_dev(sc->dev);
#endif
free(sc->sc_repdesc, M_USBDEV);

View File

@ -298,7 +298,11 @@ USB_DETACH(ulpt)
int s;
#if defined(__NetBSD__) || defined(__OpenBSD__)
int maj, mn;
#elif defined(__FreeBSD__)
struct vnode *vp;
#endif
#if defined(__NetBSD__) || defined(__OpenBSD__)
DPRINTF(("ulpt_detach: sc=%p flags=%d\n", sc, flags));
#elif defined(__FreeBSD__)
DPRINTF(("ulpt_detach: sc=%p\n", sc));
@ -326,7 +330,12 @@ USB_DETACH(ulpt)
mn = self->dv_unit;
vdevgone(maj, mn, mn, VCHR);
#elif defined(__FreeBSD__)
/* XXX not implemented yet */
vp = SLIST_FIRST(&sc->dev->si_hlist);
if (vp)
VOP_REVOKE(vp, REVOKEALL);
vp = SLIST_FIRST(&sc->dev_noprime->si_hlist);
if (vp)
VOP_REVOKE(vp, REVOKEALL);
destroy_dev(sc->dev);
destroy_dev(sc->dev_noprime);

View File

@ -360,6 +360,7 @@ static int
ums_detach(device_t self)
{
struct ums_softc *sc = device_get_softc(self);
struct vnode *vp;
if (sc->sc_enabled)
ums_disable(sc);
@ -369,6 +370,11 @@ ums_detach(device_t self)
free(sc->sc_loc_btn, M_USB);
free(sc->sc_ibuf, M_USB);
vp = SLIST_FIRST(&sc->dev->si_hlist);
if (vp)
VOP_REVOKE(vp, REVOKEALL);
/* someone waiting for data */
/*
* XXX If we wakeup the process here, the device will be gone by
* the time the process gets a chance to notice. *_close and friends
@ -376,9 +382,6 @@ ums_detach(device_t self)
* Or we should do a delayed detach for this.
* Does this delay now force tsleep to exit with an error?
*/
#if 0
/* someone waiting for data */
if (sc->state & UMS_ASLEEP) {
sc->state &= ~UMS_ASLEEP;
wakeup(sc);
@ -387,7 +390,6 @@ ums_detach(device_t self)
sc->state &= ~UMS_SELECT;
selwakeup(&sc->rsel);
}
#endif
destroy_dev(sc->dev);