diff options
| author | riastradh <riastradh@NetBSD.org> | 2020-08-16 02:34:20 +0000 |
|---|---|---|
| committer | riastradh <riastradh@NetBSD.org> | 2020-08-16 02:34:20 +0000 |
| commit | ef1cd0c8a4502baabb073d9de35cdd67a2362474 (patch) | |
| tree | 0116b597700b404984369d24af158df0616a1a7e /sys/dev/usb/ugen.c | |
| parent | 52256d390e992733f1b27711c995133988b3218d (diff) | |
Hold the lock over access to the data structures it covers.
Still not MPSAFE, but progress.
Diffstat (limited to 'sys/dev/usb/ugen.c')
| -rw-r--r-- | sys/dev/usb/ugen.c | 90 |
1 files changed, 53 insertions, 37 deletions
diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c index 6dcb2b479e2..07a71145d17 100644 --- a/sys/dev/usb/ugen.c +++ b/sys/dev/usb/ugen.c @@ -1,4 +1,4 @@ -/* $NetBSD: ugen.c,v 1.152 2020/08/16 02:33:17 riastradh Exp $ */ +/* $NetBSD: ugen.c,v 1.153 2020/08/16 02:34:20 riastradh Exp $ */ /* * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.152 2020/08/16 02:33:17 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.153 2020/08/16 02:34:20 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -1964,12 +1964,18 @@ filt_ugenread_intr(struct knote *kn, long hint) { struct ugen_endpoint *sce = kn->kn_hook; struct ugen_softc *sc = sce->sc; + int ret; - if (sc->sc_dying) - return 0; + mutex_enter(&sc->sc_lock); + if (sc->sc_dying) { + ret = 0; + } else { + kn->kn_data = sce->q.c_cc; + ret = kn->kn_data > 0; + } + mutex_exit(&sc->sc_lock); - kn->kn_data = sce->q.c_cc; - return kn->kn_data > 0; + return ret; } static int @@ -1977,20 +1983,24 @@ filt_ugenread_isoc(struct knote *kn, long hint) { struct ugen_endpoint *sce = kn->kn_hook; struct ugen_softc *sc = sce->sc; + int ret; - if (sc->sc_dying) - return 0; - - if (sce->cur == sce->fill) - return 0; - - if (sce->cur < sce->fill) + mutex_enter(&sc->sc_lock); + if (sc->sc_dying) { + ret = 0; + } else if (sce->cur == sce->fill) { + ret = 0; + } else if (sce->cur < sce->fill) { kn->kn_data = sce->fill - sce->cur; - else + ret = 1; + } else { kn->kn_data = (sce->limit - sce->cur) + (sce->fill - sce->ibuf); + ret = 1; + } + mutex_exit(&sc->sc_lock); - return 1; + return ret; } static int @@ -1998,24 +2008,27 @@ filt_ugenread_bulk(struct knote *kn, long hint) { struct ugen_endpoint *sce = kn->kn_hook; struct ugen_softc *sc = sce->sc; + int ret; - if (sc->sc_dying) - return 0; - - if (!(sce->state & UGEN_BULK_RA)) + mutex_enter(&sc->sc_lock); + if (sc->sc_dying) { + ret = 0; + } else if (!(sce->state & UGEN_BULK_RA)) { /* * We have no easy way of determining if a read will * yield any data or a write will happen. * So, emulate "seltrue". */ - return filt_seltrue(kn, hint); - - if (sce->ra_wb_used == 0) - return 0; - - kn->kn_data = sce->ra_wb_used; + ret = filt_seltrue(kn, hint); + } else if (sce->ra_wb_used == 0) { + ret = 0; + } else { + kn->kn_data = sce->ra_wb_used; + ret = 1; + } + mutex_exit(&sc->sc_lock); - return 1; + return ret; } static int @@ -2023,24 +2036,27 @@ filt_ugenwrite_bulk(struct knote *kn, long hint) { struct ugen_endpoint *sce = kn->kn_hook; struct ugen_softc *sc = sce->sc; + int ret; - if (sc->sc_dying) - return 0; - - if (!(sce->state & UGEN_BULK_WB)) + mutex_enter(&sc->sc_lock); + if (sc->sc_dying) { + ret = 0; + } else if (!(sce->state & UGEN_BULK_WB)) { /* * We have no easy way of determining if a read will * yield any data or a write will happen. * So, emulate "seltrue". */ - return filt_seltrue(kn, hint); - - if (sce->ra_wb_used == sce->limit - sce->ibuf) - return 0; - - kn->kn_data = (sce->limit - sce->ibuf) - sce->ra_wb_used; + ret = filt_seltrue(kn, hint); + } else if (sce->ra_wb_used == sce->limit - sce->ibuf) { + ret = 0; + } else { + kn->kn_data = (sce->limit - sce->ibuf) - sce->ra_wb_used; + ret = 1; + } + mutex_exit(&sc->sc_lock); - return 1; + return ret; } static const struct filterops ugenread_intr_filtops = { |
