Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb All com devices have an issue that they sleep in...
details: https://anonhg.NetBSD.org/src/rev/5916a73eca99
branches: trunk
changeset: 345245:5916a73eca99
user: mlelstv <mlelstv%NetBSD.org@localhost>
date: Sat May 14 10:52:29 2016 +0000
description:
All com devices have an issue that they sleep in the final close
when they signal a hangup while still using the device. This allows
a concurrent open to succeed without proper locking because it
only checks the state of the tty layer.
This issue triggers an assertion in ucom due to a reused USB xfer,
but it can also cause misbehaviour in other com devices.
For now in ucom:
- make open block while close is in progress
- also serialize close operations
diffstat:
sys/dev/usb/ucom.c | 18 ++++++++++++++----
1 files changed, 14 insertions(+), 4 deletions(-)
diffs (68 lines):
diff -r 6cd8e0472e49 -r 5916a73eca99 sys/dev/usb/ucom.c
--- a/sys/dev/usb/ucom.c Sat May 14 10:07:52 2016 +0000
+++ b/sys/dev/usb/ucom.c Sat May 14 10:52:29 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ucom.c,v 1.112 2016/05/10 10:40:33 skrll Exp $ */
+/* $NetBSD: ucom.c,v 1.113 2016/05/14 10:52:29 mlelstv Exp $ */
/*
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.112 2016/05/10 10:40:33 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.113 2016/05/14 10:52:29 mlelstv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -174,6 +174,7 @@
int sc_swflags;
u_char sc_opening; /* lock during open */
+ u_char sc_closing; /* lock during close */
int sc_refcnt;
u_char sc_dying; /* disconnecting */
@@ -282,6 +283,7 @@
sc->sc_tx_stopped = 0;
sc->sc_swflags = 0;
sc->sc_opening = 0;
+ sc->sc_closing = 0;
sc->sc_refcnt = 0;
sc->sc_dying = 0;
@@ -542,9 +544,10 @@
}
/*
- * Do the following iff this is a first open.
+ * Wait while the device is initialized by the
+ * first opener or cleaned up by the last closer.
*/
- while (sc->sc_opening) {
+ while (sc->sc_opening || sc->sc_closing) {
error = cv_wait_sig(&sc->sc_opencv, &sc->sc_lock);
if (error) {
@@ -681,6 +684,10 @@
mutex_enter(&sc->sc_lock);
tp = sc->sc_tty;
+ while (sc->sc_closing)
+ cv_wait(&sc->sc_opencv, &sc->sc_lock);
+ sc->sc_closing = 1;
+
if (!ISSET(tp->t_state, TS_ISOPEN)) {
goto out;
}
@@ -706,6 +713,9 @@
usb_detach_broadcast(sc->sc_dev, &sc->sc_detachcv);
out:
+ sc->sc_closing = 0;
+ cv_signal(&sc->sc_opencv);
+
mutex_exit(&sc->sc_lock);
return 0;
Home |
Main Index |
Thread Index |
Old Index