properly protect uhid's sc_q member with sc_lock. should fix PR#49728.
while here, remove D_MPSAFE from uhid* and all uhid users, as it really needs all the callers to be safe and they're not. XXX: pullup-7
This commit is contained in:
parent
ebbed00d76
commit
d9406a725c
@ -1,4 +1,4 @@
|
|||||||
$NetBSD: TODO.usbmp,v 1.8 2014/08/02 15:50:16 skrll Exp $
|
$NetBSD: TODO.usbmp,v 1.9 2015/03/07 20:20:55 mrg Exp $
|
||||||
|
|
||||||
|
|
||||||
the majority of the USB MP device interface is documented in usbdivar.h.
|
the majority of the USB MP device interface is documented in usbdivar.h.
|
||||||
@ -41,8 +41,8 @@ convert uhidev users to MPSAFE:
|
|||||||
- own cdevsw that isn't D_MPSAFE; need to check intr handlers
|
- own cdevsw that isn't D_MPSAFE; need to check intr handlers
|
||||||
|
|
||||||
uhid(4)
|
uhid(4)
|
||||||
- needs some locking here (not completely tested changes)
|
- D_MPSAFE not set as all users need it first.
|
||||||
- done
|
- mostly done
|
||||||
|
|
||||||
ukbd(4)
|
ukbd(4)
|
||||||
ums(4)
|
ums(4)
|
||||||
@ -135,7 +135,7 @@ driver testing: STATUS
|
|||||||
- ral
|
- ral
|
||||||
- rum
|
- rum
|
||||||
- run
|
- run
|
||||||
- urtw
|
- urtw working
|
||||||
- urtwn
|
- urtwn
|
||||||
- upgt
|
- upgt
|
||||||
- zyd
|
- zyd
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: uatp.c,v 1.10 2014/07/17 17:11:12 riastradh Exp $ */
|
/* $NetBSD: uatp.c,v 1.11 2015/03/07 20:20:55 mrg Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
|
* Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
|
||||||
@ -146,7 +146,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.10 2014/07/17 17:11:12 riastradh Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.11 2015/03/07 20:20:55 mrg Exp $");
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -1350,8 +1350,7 @@ geyser34_initialize(struct uatp_softc *sc)
|
|||||||
|
|
||||||
DPRINTF(sc, UATP_DEBUG_MISC, ("initializing\n"));
|
DPRINTF(sc, UATP_DEBUG_MISC, ("initializing\n"));
|
||||||
geyser34_enable_raw_mode(sc);
|
geyser34_enable_raw_mode(sc);
|
||||||
usb_init_task(&sc->sc_reset_task, &geyser34_reset_task, sc,
|
usb_init_task(&sc->sc_reset_task, &geyser34_reset_task, sc, 0);
|
||||||
USB_TASKQ_MPSAFE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -2012,7 +2011,7 @@ tap_debug(struct uatp_softc *sc, const char *caller, const char *prefix)
|
|||||||
static void
|
static void
|
||||||
tap_initialize(struct uatp_softc *sc)
|
tap_initialize(struct uatp_softc *sc)
|
||||||
{
|
{
|
||||||
callout_init(&sc->sc_untap_callout, CALLOUT_MPSAFE);
|
callout_init(&sc->sc_untap_callout, 0);
|
||||||
callout_setfunc(&sc->sc_untap_callout, untap_callout, sc);
|
callout_setfunc(&sc->sc_untap_callout, untap_callout, sc);
|
||||||
mutex_init(&sc->sc_tap_mutex, MUTEX_DEFAULT, IPL_USB);
|
mutex_init(&sc->sc_tap_mutex, MUTEX_DEFAULT, IPL_USB);
|
||||||
cv_init(&sc->sc_tap_cv, "uatptap");
|
cv_init(&sc->sc_tap_cv, "uatptap");
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: ucycom.c,v 1.41 2014/11/15 19:26:37 christos Exp $ */
|
/* $NetBSD: ucycom.c,v 1.42 2015/03/07 20:20:55 mrg Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005 The NetBSD Foundation, Inc.
|
* Copyright (c) 2005 The NetBSD Foundation, Inc.
|
||||||
@ -38,7 +38,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: ucycom.c,v 1.41 2014/11/15 19:26:37 christos Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: ucycom.c,v 1.42 2015/03/07 20:20:55 mrg Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
@ -1124,9 +1124,14 @@ ucycom_get_cfg(struct ucycom_softc *sc)
|
|||||||
Static void
|
Static void
|
||||||
ucycom_cleanup(struct ucycom_softc *sc)
|
ucycom_cleanup(struct ucycom_softc *sc)
|
||||||
{
|
{
|
||||||
|
uint8_t *obuf;
|
||||||
|
|
||||||
DPRINTF(("ucycom_cleanup: closing uhidev\n"));
|
DPRINTF(("ucycom_cleanup: closing uhidev\n"));
|
||||||
|
|
||||||
if (sc->sc_obuf !=NULL)
|
obuf = sc->sc_obuf;
|
||||||
free (sc->sc_obuf, M_USBDEV);
|
sc->sc_obuf = NULL;
|
||||||
uhidev_close(&sc->sc_hdev);
|
uhidev_close(&sc->sc_hdev);
|
||||||
|
|
||||||
|
if (obuf != NULL)
|
||||||
|
free (obuf, M_USBDEV);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: uhid.c,v 1.92 2014/07/25 08:10:39 dholland Exp $ */
|
/* $NetBSD: uhid.c,v 1.93 2015/03/07 20:20:55 mrg Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2004, 2008, 2012 The NetBSD Foundation, Inc.
|
* Copyright (c) 1998, 2004, 2008, 2012 The NetBSD Foundation, Inc.
|
||||||
@ -35,7 +35,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.92 2014/07/25 08:10:39 dholland Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.93 2015/03/07 20:20:55 mrg Exp $");
|
||||||
|
|
||||||
#ifdef _KERNEL_OPT
|
#ifdef _KERNEL_OPT
|
||||||
#include "opt_compat_netbsd.h"
|
#include "opt_compat_netbsd.h"
|
||||||
@ -91,7 +91,7 @@ struct uhid_softc {
|
|||||||
|
|
||||||
u_char *sc_obuf;
|
u_char *sc_obuf;
|
||||||
|
|
||||||
struct clist sc_q;
|
struct clist sc_q; /* protected by sc_lock */
|
||||||
struct selinfo sc_rsel;
|
struct selinfo sc_rsel;
|
||||||
proc_t *sc_async; /* process that wants SIGIO */
|
proc_t *sc_async; /* process that wants SIGIO */
|
||||||
void *sc_sih;
|
void *sc_sih;
|
||||||
@ -127,7 +127,7 @@ const struct cdevsw uhid_cdevsw = {
|
|||||||
.d_mmap = nommap,
|
.d_mmap = nommap,
|
||||||
.d_kqfilter = uhidkqfilter,
|
.d_kqfilter = uhidkqfilter,
|
||||||
.d_discard = nodiscard,
|
.d_discard = nodiscard,
|
||||||
.d_flag = D_OTHER | D_MPSAFE
|
.d_flag = D_OTHER
|
||||||
};
|
};
|
||||||
|
|
||||||
Static void uhid_intr(struct uhidev *, void *, u_int len);
|
Static void uhid_intr(struct uhidev *, void *, u_int len);
|
||||||
@ -154,9 +154,9 @@ uhid_match(device_t parent, cfdata_t match, void *aux)
|
|||||||
DPRINTF(("uhid_match: report=%d\n", uha->reportid));
|
DPRINTF(("uhid_match: report=%d\n", uha->reportid));
|
||||||
|
|
||||||
if (match->cf_flags & 1)
|
if (match->cf_flags & 1)
|
||||||
return (UMATCH_HIGHEST);
|
return UMATCH_HIGHEST;
|
||||||
else
|
else
|
||||||
return (UMATCH_IFACECLASS_GENERIC);
|
return UMATCH_IFACECLASS_GENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -172,7 +172,7 @@ uhid_attach(device_t parent, device_t self, void *aux)
|
|||||||
sc->sc_hdev.sc_intr = uhid_intr;
|
sc->sc_hdev.sc_intr = uhid_intr;
|
||||||
sc->sc_hdev.sc_parent = uha->parent;
|
sc->sc_hdev.sc_parent = uha->parent;
|
||||||
sc->sc_hdev.sc_report_id = uha->reportid;
|
sc->sc_hdev.sc_report_id = uha->reportid;
|
||||||
sc->sc_sih = softint_establish(SOFTINT_MPSAFE | SOFTINT_CLOCK,
|
sc->sc_sih = softint_establish(SOFTINT_CLOCK,
|
||||||
uhid_softintr, sc);
|
uhid_softintr, sc);
|
||||||
|
|
||||||
uhidev_get_report_desc(uha->parent, &desc, &size);
|
uhidev_get_report_desc(uha->parent, &desc, &size);
|
||||||
@ -253,7 +253,7 @@ uhid_detach(device_t self, int flags)
|
|||||||
seldestroy(&sc->sc_rsel);
|
seldestroy(&sc->sc_rsel);
|
||||||
softint_disestablish(sc->sc_sih);
|
softint_disestablish(sc->sc_sih);
|
||||||
|
|
||||||
return (0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -314,22 +314,31 @@ uhidopen(dev_t dev, int flag, int mode, struct lwp *l)
|
|||||||
DPRINTF(("uhidopen: sc=%p\n", sc));
|
DPRINTF(("uhidopen: sc=%p\n", sc));
|
||||||
|
|
||||||
if (sc->sc_dying)
|
if (sc->sc_dying)
|
||||||
return (ENXIO);
|
return ENXIO;
|
||||||
|
|
||||||
mutex_enter(&sc->sc_access_lock);
|
mutex_enter(&sc->sc_access_lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* uhid interrupts aren't enabled yet, so setup sc_q now, as
|
||||||
|
* long as they're not already allocated.
|
||||||
|
*/
|
||||||
|
if (sc->sc_hdev.sc_state & UHIDEV_OPEN) {
|
||||||
|
mutex_exit(&sc->sc_access_lock);
|
||||||
|
return EBUSY;
|
||||||
|
}
|
||||||
|
if (clalloc(&sc->sc_q, UHID_BSIZE, 0) == -1) {
|
||||||
|
mutex_exit(&sc->sc_access_lock);
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
error = uhidev_open(&sc->sc_hdev);
|
error = uhidev_open(&sc->sc_hdev);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
clfree(&sc->sc_q);
|
||||||
mutex_exit(&sc->sc_access_lock);
|
mutex_exit(&sc->sc_access_lock);
|
||||||
return (error);
|
return error;
|
||||||
}
|
}
|
||||||
mutex_exit(&sc->sc_access_lock);
|
mutex_exit(&sc->sc_access_lock);
|
||||||
|
|
||||||
if (clalloc(&sc->sc_q, UHID_BSIZE, 0) == -1) {
|
|
||||||
mutex_enter(&sc->sc_access_lock);
|
|
||||||
uhidev_close(&sc->sc_hdev);
|
|
||||||
mutex_exit(&sc->sc_access_lock);
|
|
||||||
return (ENOMEM);
|
|
||||||
}
|
|
||||||
sc->sc_obuf = malloc(sc->sc_osize, M_USBDEV, M_WAITOK);
|
sc->sc_obuf = malloc(sc->sc_osize, M_USBDEV, M_WAITOK);
|
||||||
sc->sc_state &= ~UHID_IMMED;
|
sc->sc_state &= ~UHID_IMMED;
|
||||||
|
|
||||||
@ -337,7 +346,7 @@ uhidopen(dev_t dev, int flag, int mode, struct lwp *l)
|
|||||||
sc->sc_async = NULL;
|
sc->sc_async = NULL;
|
||||||
mutex_exit(proc_lock);
|
mutex_exit(proc_lock);
|
||||||
|
|
||||||
return (0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -349,18 +358,24 @@ uhidclose(dev_t dev, int flag, int mode, struct lwp *l)
|
|||||||
|
|
||||||
DPRINTF(("uhidclose: sc=%p\n", sc));
|
DPRINTF(("uhidclose: sc=%p\n", sc));
|
||||||
|
|
||||||
clfree(&sc->sc_q);
|
|
||||||
free(sc->sc_obuf, M_USBDEV);
|
|
||||||
|
|
||||||
mutex_enter(proc_lock);
|
mutex_enter(proc_lock);
|
||||||
sc->sc_async = NULL;
|
sc->sc_async = NULL;
|
||||||
mutex_exit(proc_lock);
|
mutex_exit(proc_lock);
|
||||||
|
|
||||||
mutex_enter(&sc->sc_access_lock);
|
mutex_enter(&sc->sc_access_lock);
|
||||||
|
|
||||||
|
mutex_enter(&sc->sc_lock);
|
||||||
|
uhidev_stop(&sc->sc_hdev);
|
||||||
|
mutex_exit(&sc->sc_lock);
|
||||||
|
|
||||||
|
clfree(&sc->sc_q);
|
||||||
|
free(sc->sc_obuf, M_USBDEV);
|
||||||
|
|
||||||
uhidev_close(&sc->sc_hdev);
|
uhidev_close(&sc->sc_hdev);
|
||||||
|
|
||||||
mutex_exit(&sc->sc_access_lock);
|
mutex_exit(&sc->sc_access_lock);
|
||||||
|
|
||||||
return (0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -379,15 +394,15 @@ uhid_do_read(struct uhid_softc *sc, struct uio *uio, int flag)
|
|||||||
err = uhidev_get_report(&sc->sc_hdev, UHID_INPUT_REPORT,
|
err = uhidev_get_report(&sc->sc_hdev, UHID_INPUT_REPORT,
|
||||||
buffer, sc->sc_isize + extra);
|
buffer, sc->sc_isize + extra);
|
||||||
if (err)
|
if (err)
|
||||||
return (EIO);
|
return EIO;
|
||||||
return (uiomove(buffer+extra, sc->sc_isize, uio));
|
return uiomove(buffer+extra, sc->sc_isize, uio);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_enter(&sc->sc_lock);
|
mutex_enter(&sc->sc_lock);
|
||||||
while (sc->sc_q.c_cc == 0) {
|
while (sc->sc_q.c_cc == 0) {
|
||||||
if (flag & IO_NDELAY) {
|
if (flag & IO_NDELAY) {
|
||||||
mutex_exit(&sc->sc_lock);
|
mutex_exit(&sc->sc_lock);
|
||||||
return (EWOULDBLOCK);
|
return EWOULDBLOCK;
|
||||||
}
|
}
|
||||||
sc->sc_state |= UHID_ASLP;
|
sc->sc_state |= UHID_ASLP;
|
||||||
DPRINTFN(5, ("uhidread: sleep on %p\n", &sc->sc_q));
|
DPRINTFN(5, ("uhidread: sleep on %p\n", &sc->sc_q));
|
||||||
@ -400,7 +415,6 @@ uhid_do_read(struct uhid_softc *sc, struct uio *uio, int flag)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_exit(&sc->sc_lock);
|
|
||||||
|
|
||||||
/* Transfer as many chunks as possible. */
|
/* Transfer as many chunks as possible. */
|
||||||
while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0 && !error) {
|
while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0 && !error) {
|
||||||
@ -413,11 +427,14 @@ uhid_do_read(struct uhid_softc *sc, struct uio *uio, int flag)
|
|||||||
DPRINTFN(5, ("uhidread: got %lu chars\n", (u_long)length));
|
DPRINTFN(5, ("uhidread: got %lu chars\n", (u_long)length));
|
||||||
|
|
||||||
/* Copy the data to the user process. */
|
/* Copy the data to the user process. */
|
||||||
|
mutex_exit(&sc->sc_lock);
|
||||||
if ((error = uiomove(buffer, length, uio)) != 0)
|
if ((error = uiomove(buffer, length, uio)) != 0)
|
||||||
break;
|
return error;
|
||||||
|
mutex_enter(&sc->sc_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (error);
|
mutex_exit(&sc->sc_lock);
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -440,7 +457,7 @@ uhidread(dev_t dev, struct uio *uio, int flag)
|
|||||||
if (--sc->sc_refcnt < 0)
|
if (--sc->sc_refcnt < 0)
|
||||||
usb_detach_broadcast(sc->sc_hdev.sc_dev, &sc->sc_detach_cv);
|
usb_detach_broadcast(sc->sc_hdev.sc_dev, &sc->sc_detach_cv);
|
||||||
mutex_exit(&sc->sc_lock);
|
mutex_exit(&sc->sc_lock);
|
||||||
return (error);
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -453,12 +470,12 @@ uhid_do_write(struct uhid_softc *sc, struct uio *uio, int flag)
|
|||||||
DPRINTFN(1, ("uhidwrite\n"));
|
DPRINTFN(1, ("uhidwrite\n"));
|
||||||
|
|
||||||
if (sc->sc_dying)
|
if (sc->sc_dying)
|
||||||
return (EIO);
|
return EIO;
|
||||||
|
|
||||||
size = sc->sc_osize;
|
size = sc->sc_osize;
|
||||||
error = 0;
|
error = 0;
|
||||||
if (uio->uio_resid != size)
|
if (uio->uio_resid != size)
|
||||||
return (EINVAL);
|
return EINVAL;
|
||||||
error = uiomove(sc->sc_obuf, size, uio);
|
error = uiomove(sc->sc_obuf, size, uio);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
err = uhidev_set_report(&sc->sc_hdev, UHID_OUTPUT_REPORT,
|
err = uhidev_set_report(&sc->sc_hdev, UHID_OUTPUT_REPORT,
|
||||||
@ -467,7 +484,7 @@ uhid_do_write(struct uhid_softc *sc, struct uio *uio, int flag)
|
|||||||
error = EIO;
|
error = EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (error);
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -490,7 +507,7 @@ uhidwrite(dev_t dev, struct uio *uio, int flag)
|
|||||||
if (--sc->sc_refcnt < 0)
|
if (--sc->sc_refcnt < 0)
|
||||||
usb_detach_broadcast(sc->sc_hdev.sc_dev, &sc->sc_detach_cv);
|
usb_detach_broadcast(sc->sc_hdev.sc_dev, &sc->sc_detach_cv);
|
||||||
mutex_exit(&sc->sc_lock);
|
mutex_exit(&sc->sc_lock);
|
||||||
return (error);
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -507,7 +524,7 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, void *addr,
|
|||||||
DPRINTFN(2, ("uhidioctl: cmd=%lx\n", cmd));
|
DPRINTFN(2, ("uhidioctl: cmd=%lx\n", cmd));
|
||||||
|
|
||||||
if (sc->sc_dying)
|
if (sc->sc_dying)
|
||||||
return (EIO);
|
return EIO;
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case FIONBIO:
|
case FIONBIO:
|
||||||
@ -518,7 +535,7 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, void *addr,
|
|||||||
mutex_enter(proc_lock);
|
mutex_enter(proc_lock);
|
||||||
if (*(int *)addr) {
|
if (*(int *)addr) {
|
||||||
if (sc->sc_async != NULL)
|
if (sc->sc_async != NULL)
|
||||||
return (EBUSY);
|
return EBUSY;
|
||||||
sc->sc_async = l->l_proc;
|
sc->sc_async = l->l_proc;
|
||||||
DPRINTF(("uhid_do_ioctl: FIOASYNC %p\n", l->l_proc));
|
DPRINTF(("uhid_do_ioctl: FIOASYNC %p\n", l->l_proc));
|
||||||
} else
|
} else
|
||||||
@ -531,11 +548,11 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, void *addr,
|
|||||||
mutex_enter(proc_lock);
|
mutex_enter(proc_lock);
|
||||||
if (sc->sc_async == NULL) {
|
if (sc->sc_async == NULL) {
|
||||||
mutex_exit(proc_lock);
|
mutex_exit(proc_lock);
|
||||||
return (EINVAL);
|
return EINVAL;
|
||||||
}
|
}
|
||||||
if (*(int *)addr != sc->sc_async->p_pgid) {
|
if (*(int *)addr != sc->sc_async->p_pgid) {
|
||||||
mutex_exit(proc_lock);
|
mutex_exit(proc_lock);
|
||||||
return (EPERM);
|
return EPERM;
|
||||||
}
|
}
|
||||||
mutex_exit(proc_lock);
|
mutex_exit(proc_lock);
|
||||||
break;
|
break;
|
||||||
@ -544,12 +561,12 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, void *addr,
|
|||||||
mutex_enter(proc_lock);
|
mutex_enter(proc_lock);
|
||||||
if (sc->sc_async == NULL) {
|
if (sc->sc_async == NULL) {
|
||||||
mutex_exit(proc_lock);
|
mutex_exit(proc_lock);
|
||||||
return (EINVAL);
|
return EINVAL;
|
||||||
}
|
}
|
||||||
if (-*(int *)addr != sc->sc_async->p_pgid
|
if (-*(int *)addr != sc->sc_async->p_pgid
|
||||||
&& *(int *)addr != sc->sc_async->p_pid) {
|
&& *(int *)addr != sc->sc_async->p_pid) {
|
||||||
mutex_exit(proc_lock);
|
mutex_exit(proc_lock);
|
||||||
return (EPERM);
|
return EPERM;
|
||||||
}
|
}
|
||||||
mutex_exit(proc_lock);
|
mutex_exit(proc_lock);
|
||||||
break;
|
break;
|
||||||
@ -568,7 +585,7 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, void *addr,
|
|||||||
err = uhidev_get_report(&sc->sc_hdev, UHID_INPUT_REPORT,
|
err = uhidev_get_report(&sc->sc_hdev, UHID_INPUT_REPORT,
|
||||||
buffer, sc->sc_isize + extra);
|
buffer, sc->sc_isize + extra);
|
||||||
if (err)
|
if (err)
|
||||||
return (EOPNOTSUPP);
|
return EOPNOTSUPP;
|
||||||
|
|
||||||
sc->sc_state |= UHID_IMMED;
|
sc->sc_state |= UHID_IMMED;
|
||||||
} else
|
} else
|
||||||
@ -588,7 +605,7 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, void *addr,
|
|||||||
size = sc->sc_fsize;
|
size = sc->sc_fsize;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return (EINVAL);
|
return EINVAL;
|
||||||
}
|
}
|
||||||
extra = sc->sc_hdev.sc_report_id != 0;
|
extra = sc->sc_hdev.sc_report_id != 0;
|
||||||
err = uhidev_get_report(&sc->sc_hdev, re->ucr_report,
|
err = uhidev_get_report(&sc->sc_hdev, re->ucr_report,
|
||||||
@ -596,7 +613,7 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, void *addr,
|
|||||||
if (extra)
|
if (extra)
|
||||||
memcpy(re->ucr_data, re->ucr_data+1, size);
|
memcpy(re->ucr_data, re->ucr_data+1, size);
|
||||||
if (err)
|
if (err)
|
||||||
return (EIO);
|
return EIO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USB_SET_REPORT:
|
case USB_SET_REPORT:
|
||||||
@ -612,12 +629,12 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, void *addr,
|
|||||||
size = sc->sc_fsize;
|
size = sc->sc_fsize;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return (EINVAL);
|
return EINVAL;
|
||||||
}
|
}
|
||||||
err = uhidev_set_report(&sc->sc_hdev, re->ucr_report,
|
err = uhidev_set_report(&sc->sc_hdev, re->ucr_report,
|
||||||
re->ucr_data, size);
|
re->ucr_data, size);
|
||||||
if (err)
|
if (err)
|
||||||
return (EIO);
|
return EIO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USB_GET_REPORT_ID:
|
case USB_GET_REPORT_ID:
|
||||||
@ -647,14 +664,14 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, void *addr,
|
|||||||
si->usd_string_index,
|
si->usd_string_index,
|
||||||
si->usd_language_id, &si->usd_desc, &size);
|
si->usd_language_id, &si->usd_desc, &size);
|
||||||
if (err)
|
if (err)
|
||||||
return (EINVAL);
|
return EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (EINVAL);
|
return EINVAL;
|
||||||
}
|
}
|
||||||
return (0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -682,7 +699,7 @@ uhidioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
|
|||||||
if (--sc->sc_refcnt < 0)
|
if (--sc->sc_refcnt < 0)
|
||||||
usb_detach_broadcast(sc->sc_hdev.sc_dev, &sc->sc_detach_cv);
|
usb_detach_broadcast(sc->sc_hdev.sc_dev, &sc->sc_detach_cv);
|
||||||
mutex_exit(&sc->sc_lock);
|
mutex_exit(&sc->sc_lock);
|
||||||
return (error);
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -709,7 +726,7 @@ uhidpoll(dev_t dev, int events, struct lwp *l)
|
|||||||
}
|
}
|
||||||
mutex_exit(&sc->sc_lock);
|
mutex_exit(&sc->sc_lock);
|
||||||
|
|
||||||
return (revents);
|
return revents;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -746,7 +763,7 @@ uhidkqfilter(dev_t dev, struct knote *kn)
|
|||||||
sc = device_lookup_private(&uhid_cd, UHIDUNIT(dev));
|
sc = device_lookup_private(&uhid_cd, UHIDUNIT(dev));
|
||||||
|
|
||||||
if (sc->sc_dying)
|
if (sc->sc_dying)
|
||||||
return (ENXIO);
|
return ENXIO;
|
||||||
|
|
||||||
switch (kn->kn_filter) {
|
switch (kn->kn_filter) {
|
||||||
case EVFILT_READ:
|
case EVFILT_READ:
|
||||||
@ -760,7 +777,7 @@ uhidkqfilter(dev_t dev, struct knote *kn)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (EINVAL);
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
kn->kn_hook = sc;
|
kn->kn_hook = sc;
|
||||||
@ -769,5 +786,5 @@ uhidkqfilter(dev_t dev, struct knote *kn)
|
|||||||
SLIST_INSERT_HEAD(klist, kn, kn_selnext);
|
SLIST_INSERT_HEAD(klist, kn, kn_selnext);
|
||||||
mutex_exit(&sc->sc_lock);
|
mutex_exit(&sc->sc_lock);
|
||||||
|
|
||||||
return (0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: uhidev.c,v 1.62 2015/02/08 19:22:45 jmcneill Exp $ */
|
/* $NetBSD: uhidev.c,v 1.63 2015/03/07 20:20:55 mrg Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
|
* Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
|
||||||
@ -35,7 +35,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.62 2015/02/08 19:22:45 jmcneill Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.63 2015/03/07 20:20:55 mrg Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
@ -647,6 +647,30 @@ out1:
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uhidev_stop(struct uhidev *scd)
|
||||||
|
{
|
||||||
|
struct uhidev_softc *sc = scd->sc_parent;
|
||||||
|
|
||||||
|
/* Disable interrupts. */
|
||||||
|
if (sc->sc_opipe != NULL) {
|
||||||
|
usbd_abort_pipe(sc->sc_opipe);
|
||||||
|
usbd_close_pipe(sc->sc_opipe);
|
||||||
|
sc->sc_opipe = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sc->sc_ipipe != NULL) {
|
||||||
|
usbd_abort_pipe(sc->sc_ipipe);
|
||||||
|
usbd_close_pipe(sc->sc_ipipe);
|
||||||
|
sc->sc_ipipe = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sc->sc_ibuf != NULL) {
|
||||||
|
free(sc->sc_ibuf, M_USBDEV);
|
||||||
|
sc->sc_ibuf = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uhidev_close(struct uhidev *scd)
|
uhidev_close(struct uhidev *scd)
|
||||||
{
|
{
|
||||||
@ -671,23 +695,8 @@ uhidev_close(struct uhidev *scd)
|
|||||||
sc->sc_oxfer = NULL;
|
sc->sc_oxfer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable interrupts. */
|
/* Possibly redundant, but properly handled */
|
||||||
if (sc->sc_opipe != NULL) {
|
uhidev_stop(scd);
|
||||||
usbd_abort_pipe(sc->sc_opipe);
|
|
||||||
usbd_close_pipe(sc->sc_opipe);
|
|
||||||
sc->sc_opipe = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sc->sc_ipipe != NULL) {
|
|
||||||
usbd_abort_pipe(sc->sc_ipipe);
|
|
||||||
usbd_close_pipe(sc->sc_ipipe);
|
|
||||||
sc->sc_ipipe = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sc->sc_ibuf != NULL) {
|
|
||||||
free(sc->sc_ibuf, M_USBDEV);
|
|
||||||
sc->sc_ibuf = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usbd_status
|
usbd_status
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: uhidev.h,v 1.16 2015/02/08 19:22:45 jmcneill Exp $ */
|
/* $NetBSD: uhidev.h,v 1.17 2015/03/07 20:20:55 mrg Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||||
@ -82,6 +82,7 @@ struct uhidev_attach_arg {
|
|||||||
|
|
||||||
void uhidev_get_report_desc(struct uhidev_softc *, void **, int *);
|
void uhidev_get_report_desc(struct uhidev_softc *, void **, int *);
|
||||||
int uhidev_open(struct uhidev *);
|
int uhidev_open(struct uhidev *);
|
||||||
|
void uhidev_stop(struct uhidev *);
|
||||||
void uhidev_close(struct uhidev *);
|
void uhidev_close(struct uhidev *);
|
||||||
usbd_status uhidev_set_report(struct uhidev *, int, void *, int);
|
usbd_status uhidev_set_report(struct uhidev *, int, void *, int);
|
||||||
usbd_status uhidev_get_report(struct uhidev *, int, void *, int);
|
usbd_status uhidev_get_report(struct uhidev *, int, void *, int);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: ukbd.c,v 1.129 2013/09/26 07:25:31 skrll Exp $ */
|
/* $NetBSD: ukbd.c,v 1.130 2015/03/07 20:20:55 mrg Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||||
@ -35,7 +35,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.129 2013/09/26 07:25:31 skrll Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.130 2015/03/07 20:20:55 mrg Exp $");
|
||||||
|
|
||||||
#ifdef _KERNEL_OPT
|
#ifdef _KERNEL_OPT
|
||||||
#include "opt_ukbd.h"
|
#include "opt_ukbd.h"
|
||||||
@ -478,8 +478,7 @@ ukbd_attach(device_t parent, device_t self, void *aux)
|
|||||||
|
|
||||||
callout_init(&sc->sc_delay, 0);
|
callout_init(&sc->sc_delay, 0);
|
||||||
|
|
||||||
usb_init_task(&sc->sc_ledtask, ukbd_set_leds_task, sc,
|
usb_init_task(&sc->sc_ledtask, ukbd_set_leds_task, sc, 0);
|
||||||
USB_TASKQ_MPSAFE);
|
|
||||||
|
|
||||||
/* Flash the leds; no real purpose, just shows we're alive. */
|
/* Flash the leds; no real purpose, just shows we're alive. */
|
||||||
ukbd_set_leds(sc, WSKBD_LED_SCROLL | WSKBD_LED_NUM | WSKBD_LED_CAPS
|
ukbd_set_leds(sc, WSKBD_LED_SCROLL | WSKBD_LED_NUM | WSKBD_LED_CAPS
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: uyurex.c,v 1.9 2013/01/05 23:34:21 christos Exp $ */
|
/* $NetBSD: uyurex.c,v 1.10 2015/03/07 20:20:55 mrg Exp $ */
|
||||||
/* $OpenBSD: uyurex.c,v 1.3 2010/03/04 03:47:22 deraadt Exp $ */
|
/* $OpenBSD: uyurex.c,v 1.3 2010/03/04 03:47:22 deraadt Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -22,7 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: uyurex.c,v 1.9 2013/01/05 23:34:21 christos Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: uyurex.c,v 1.10 2015/03/07 20:20:55 mrg Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
@ -150,6 +150,10 @@ uyurex_attach(device_t parent, device_t self, void *aux)
|
|||||||
aprint_normal("\n");
|
aprint_normal("\n");
|
||||||
aprint_naive("\n");
|
aprint_naive("\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX uhidev_open enables the interrupt, so we should do it as
|
||||||
|
* one of the final things here.
|
||||||
|
*/
|
||||||
err = uhidev_open(&sc->sc_hdev);
|
err = uhidev_open(&sc->sc_hdev);
|
||||||
if (err) {
|
if (err) {
|
||||||
aprint_error_dev(self, "uyurex_open: uhidev_open %d\n", err);
|
aprint_error_dev(self, "uyurex_open: uhidev_open %d\n", err);
|
||||||
|
Loading…
Reference in New Issue
Block a user