diff options
author | Marcus Glocker <mglocker@cvs.openbsd.org> | 2009-03-29 16:45:36 +0000 |
---|---|---|
committer | Marcus Glocker <mglocker@cvs.openbsd.org> | 2009-03-29 16:45:36 +0000 |
commit | 388119e64aa8692eb907041b048836dfa912ee66 (patch) | |
tree | 4e3595a6d582c14aebf542d27bd1831da6ff635c /sys | |
parent | 219278b23d55767a19508bfbf816a59aff614d25 (diff) |
Finally fix kernel crash (page fault) when closing bulk devices.
Help from kettenis@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/usb/uvideo.c | 16 |
1 files changed, 6 insertions, 10 deletions
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c index 6fa9763df9e..b73ec910e5c 100644 --- a/sys/dev/usb/uvideo.c +++ b/sys/dev/usb/uvideo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvideo.c,v 1.123 2009/03/28 09:18:28 mglocker Exp $ */ +/* $OpenBSD: uvideo.c,v 1.124 2009/03/29 16:45:35 mglocker Exp $ */ /* * Copyright (c) 2008 Robert Nagy <robert@openbsd.org> @@ -1726,15 +1726,10 @@ uvideo_vs_open(struct uvideo_softc *sc) void uvideo_vs_close(struct uvideo_softc *sc) { - /* - * XXX - * A bulk device will crash the kernel here, because in almost all - * cases we close the pipe before sc->sc_vs_cur->bulk_running = 0 - * gets noticed in the thread loop of uvideo_vs_start_bulk_thread(), - * which make it access a closed pipe. We need to fix this - * properly. - */ - sc->sc_vs_cur->bulk_running = 0; + if (sc->sc_vs_cur->bulk_running == 1) { + sc->sc_vs_cur->bulk_running = 0; + (void)tsleep(&sc->sc_vs_cur->bulk_running, 0, "vid_close", 0); + } if (sc->sc_vs_cur->pipeh) { usbd_abort_pipe(sc->sc_vs_cur->pipeh); @@ -1829,6 +1824,7 @@ uvideo_vs_start_bulk_thread(void *arg) (void)sc->sc_decode_stream_header(sc, sc->sc_vs_cur->bxfer.buf, size); } + wakeup(&sc->sc_vs_cur->bulk_running); kthread_exit(0); } |