Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb since we have to drop locks to call into the usb...
details: https://anonhg.NetBSD.org/src/rev/b569e5a2668e
branches: trunk
changeset: 773736:b569e5a2668e
user: mrg <mrg%NetBSD.org@localhost>
date: Tue Feb 14 19:28:22 2012 +0000
description:
since we have to drop locks to call into the usb code, we need to make
sure that only one caller ends up doing something in close_out_jack().
add a "closing" member that is set when closing and error out in various
places.
with this in place i can read and write from umidi without triggering
any locking or other obvious issues, though the writing is currently
broken (it worked in 5.99.60-era.) it runs the correct time, but no
output occurs no the synth itself. more work needed here.
diffstat:
sys/dev/usb/umidi.c | 38 ++++++++++++++++++++++++--------------
sys/dev/usb/umidivar.h | 3 ++-
2 files changed, 26 insertions(+), 15 deletions(-)
diffs (146 lines):
diff -r 221453c13df8 -r b569e5a2668e sys/dev/usb/umidi.c
--- a/sys/dev/usb/umidi.c Tue Feb 14 18:57:35 2012 +0000
+++ b/sys/dev/usb/umidi.c Tue Feb 14 19:28:22 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: umidi.c,v 1.58 2012/02/13 17:36:18 mrg Exp $ */
+/* $NetBSD: umidi.c,v 1.59 2012/02/14 19:28:22 mrg Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umidi.c,v 1.58 2012/02/13 17:36:18 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umidi.c,v 1.59 2012/02/14 19:28:22 mrg Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -341,6 +341,7 @@
return EIO;
mididev->opened = 1;
+ mididev->closing = 0;
mididev->flags = flags;
if ((mididev->flags & FWRITE) && mididev->out_jack) {
err = open_out_jack(mididev->out_jack, arg, ointr);
@@ -367,6 +368,8 @@
struct umidi_mididev *mididev = addr;
/* XXX SMP */
+ mididev->closing = 1;
+
KERNEL_LOCK(1, curlwp);
mutex_spin_exit(&mididev->sc->sc_lock);
@@ -374,11 +377,12 @@
close_out_jack(mididev->out_jack);
if ((mididev->flags & FREAD) && mididev->in_jack)
close_in_jack(mididev->in_jack);
- mididev->opened = 0;
/* XXX SMP */
mutex_spin_enter(&mididev->sc->sc_lock);
KERNEL_UNLOCK_ONE(curlwp);
+
+ mididev->opened = 0;
}
int
@@ -387,7 +391,7 @@
{
struct umidi_mididev *mididev = addr;
- if (!mididev->out_jack || !mididev->opened)
+ if (!mididev->out_jack || !mididev->opened || !mididev->closing)
return EIO;
return out_jack_output(mididev->out_jack, msg, len, (status>>4)&0xf);
@@ -399,7 +403,7 @@
struct umidi_mididev *mididev = addr;
int cin;
- if (!mididev->out_jack || !mididev->opened)
+ if (!mididev->out_jack || !mididev->opened || !mididev->closing)
return EIO;
switch ( len ) {
@@ -418,7 +422,7 @@
struct umidi_mididev *mididev = addr;
int cin;
- if (!mididev->out_jack || !mididev->opened)
+ if (!mididev->out_jack || !mididev->opened || !mididev->closing)
return EIO;
switch ( len ) {
@@ -437,7 +441,7 @@
struct umidi_mididev *mididev = addr;
u_char msg = d;
- if (!mididev->out_jack || !mididev->opened)
+ if (!mididev->out_jack || !mididev->opened || !mididev->closing)
return EIO;
return out_jack_output(mididev->out_jack, &msg, 1, 0xf);
@@ -1154,11 +1158,10 @@
u_int16_t mask;
int err;
-
if (jack->opened) {
ep = jack->endpoint;
sc = ep->sc;
- KASSERT(mutex_owned(&sc->sc_lock));
+ mutex_spin_enter(&sc->sc_lock);
mask = 1 << (jack->cable_number);
while (mask & (ep->this_schedule | ep->next_schedule)) {
err = cv_timedwait_sig(&sc->sc_cv, &sc->sc_lock,
@@ -1166,10 +1169,17 @@
if (err)
break;
}
- jack->opened = 0;
- jack->endpoint->num_open--;
- ep->this_schedule &= ~mask;
- ep->next_schedule &= ~mask;
+ /*
+ * We can re-enter this function from both close() and
+ * detach(). Make sure only one of them does this part.
+ */
+ if (jack->opened) {
+ jack->opened = 0;
+ jack->endpoint->num_open--;
+ ep->this_schedule &= ~mask;
+ ep->next_schedule &= ~mask;
+ }
+ mutex_spin_exit(&sc->sc_lock);
}
}
@@ -1179,7 +1189,7 @@
if (jack->opened) {
jack->opened = 0;
if (--jack->endpoint->num_open == 0) {
- usbd_abort_pipe(jack->endpoint->pipe);
+ usbd_abort_pipe(jack->endpoint->pipe);
}
}
}
diff -r 221453c13df8 -r b569e5a2668e sys/dev/usb/umidivar.h
--- a/sys/dev/usb/umidivar.h Tue Feb 14 18:57:35 2012 +0000
+++ b/sys/dev/usb/umidivar.h Tue Feb 14 19:28:22 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: umidivar.h,v 1.17 2011/11/26 13:22:09 mrg Exp $ */
+/* $NetBSD: umidivar.h,v 1.18 2012/02/14 19:28:23 mrg Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -51,6 +51,7 @@
size_t label_len;
/* */
int opened;
+ int closing;
int flags;
};
Home |
Main Index |
Thread Index |
Old Index