summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2016-06-13 19:45:08 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2016-06-13 19:45:08 +0000
commit5017ea6b1e69b2161f471ad48323fe6e3f5a01b7 (patch)
tree1a250bd372e8a4400813b3ba581e3d6f0ccac31a
parent97552bdfaa2f1d61e34d926cbb5b271c1d24f39c (diff)
* Start/stop audio bulk thread as consumer opens/closes device.
And as a result get rid of a few defines/flags. * Fix _as_close() to and audio bulk thread exit. * Change sc->sc_as_running into a flag; save an int. From Patrick Keshishian ok mpi
-rw-r--r--sys/dev/usb/utvfu.c80
-rw-r--r--sys/dev/usb/utvfu.h8
2 files changed, 44 insertions, 44 deletions
diff --git a/sys/dev/usb/utvfu.c b/sys/dev/usb/utvfu.c
index d9e24348b9e..6f986fd227a 100644
--- a/sys/dev/usb/utvfu.c
+++ b/sys/dev/usb/utvfu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: utvfu.c,v 1.3 2016/06/02 17:39:37 mglocker Exp $ */
+/* $OpenBSD: utvfu.c,v 1.4 2016/06/13 19:45:07 mglocker Exp $ */
/*
* Copyright (c) 2013 Lubomir Rintel
* Copyright (c) 2013 Federico Simoncelli
@@ -456,9 +456,11 @@ int
utvfu_start_capture(struct utvfu_softc *sc)
{
usbd_status error;
+ int restart_au;
DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
+ restart_au = ISSET(sc->sc_flags, UTVFU_FLAG_AS_RUNNING);
utvfu_audio_stop(sc);
/* default video stream interface */
@@ -474,7 +476,8 @@ utvfu_start_capture(struct utvfu_softc *sc)
if (error != USBD_NORMAL_COMPLETION)
return (EINVAL);
- utvfu_audio_start(sc);
+ if (restart_au)
+ utvfu_audio_start(sc);
return (0);
}
@@ -790,10 +793,6 @@ int utvfu_audio_trigger_input(void *, void *, void *, int,
void utvfu_audio_get_default_params(void *, int,
struct audio_params *);
-#define UTVFU_AUDIO_HAS_CLIENT(sc) ((sc)->sc_flags & UTVFU_FLAG_AUDIO_CLI)
-#define UTVFU_VIDEO_HAS_CLIENT(sc) ((sc)->sc_flags & UTVFU_FLAG_VIDEO_CLI)
-
-
struct cfdriver utvfu_cd = {
NULL, "utvfu", DV_DULL
};
@@ -974,10 +973,11 @@ utvfu_detach(struct device *self, int flags)
if (sc->sc_audiodev != NULL)
rv += config_detach(sc->sc_audiodev, flags);
- sc->sc_flags = 0;
utvfu_as_free(sc);
utvfu_vs_free(sc);
+ sc->sc_flags = 0;
+
return (rv);
}
@@ -1042,7 +1042,7 @@ utvfu_open(void *addr, int flags, int *size, uint8_t *buffer,
if (usbd_is_dying(sc->sc_udev))
return (EIO);
- if ((rv = utvfu_vs_init(sc)) != 0 || (rv = utvfu_as_init(sc)) != 0)
+ if ((rv = utvfu_vs_init(sc)) != 0)
return (rv);
/* pointers to upper video layer */
@@ -1051,7 +1051,6 @@ utvfu_open(void *addr, int flags, int *size, uint8_t *buffer,
sc->sc_uplayer_fbuffer = buffer;
sc->sc_uplayer_intr = intr;
- sc->sc_flags |= UTVFU_FLAG_VIDEO_CLI;
sc->sc_flags &= ~UTVFU_FLAG_MMAP;
return (0);
@@ -1066,10 +1065,6 @@ utvfu_close(void *addr)
/* free & clean up video stream */
utvfu_vs_free(sc);
- sc->sc_flags &= ~UTVFU_FLAG_VIDEO_CLI;
-
- if (!UTVFU_AUDIO_HAS_CLIENT(sc))
- utvfu_as_free(sc);
return (0);
}
@@ -1161,8 +1156,15 @@ utvfu_vs_open(struct utvfu_softc *sc)
void
utvfu_as_close(struct utvfu_softc *sc)
{
+ DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
+
+ CLR(sc->sc_flags, UTVFU_FLAG_AS_RUNNING);
+
if (sc->sc_audio.iface.pipeh != NULL) {
usbd_abort_pipe(sc->sc_audio.iface.pipeh);
+
+ tsleep(&sc->sc_flags, 0, "audioclose", hz/2+1);
+
usbd_close_pipe(sc->sc_audio.iface.pipeh);
sc->sc_audio.iface.pipeh = NULL;
}
@@ -1205,15 +1207,15 @@ utvfu_as_start_bulk(struct utvfu_softc *sc)
{
int error;
- if (sc->sc_as_running == 1)
+ if (ISSET(sc->sc_flags, UTVFU_FLAG_AS_RUNNING))
return (0);
if (sc->sc_audio.iface.pipeh == NULL)
return (ENXIO);
- sc->sc_as_running = 1;
+ SET(sc->sc_flags, UTVFU_FLAG_AS_RUNNING);
error = kthread_create(utvfu_as_bulk_thread, sc, NULL, DEVNAME(sc));
if (error) {
- sc->sc_as_running = 0;
+ CLR(sc->sc_flags, UTVFU_FLAG_AS_RUNNING);
printf("%s: can't create kernel thread!", DEVNAME(sc));
}
@@ -1228,8 +1230,10 @@ utvfu_as_bulk_thread(void *arg)
usbd_status error;
uint32_t actlen;
+ DPRINTF(1, "%s %s\n", DEVNAME(sc), __func__);
+
iface = &sc->sc_audio.iface;
- while (sc->sc_as_running) {
+ while (ISSET(sc->sc_flags, UTVFU_FLAG_AS_RUNNING)) {
usbd_setup_xfer(
iface->xfer,
iface->pipeh,
@@ -1240,6 +1244,7 @@ utvfu_as_bulk_thread(void *arg)
0,
NULL);
error = usbd_transfer(iface->xfer);
+
if (error != USBD_NORMAL_COMPLETION) {
DPRINTF(1, "%s: error in bulk xfer: %s!\n",
DEVNAME(sc), usbd_errstr(error));
@@ -1250,14 +1255,13 @@ utvfu_as_bulk_thread(void *arg)
NULL);
DPRINTF(2, "%s: *** buffer len = %d\n", DEVNAME(sc), actlen);
- if (UTVFU_AUDIO_HAS_CLIENT(sc)) {
- rw_enter_read(&sc->sc_audio.rwlock);
- utvfu_audio_decode(sc, actlen);
- rw_exit_read(&sc->sc_audio.rwlock);
- }
+ rw_enter_read(&sc->sc_audio.rwlock);
+ utvfu_audio_decode(sc, actlen);
+ rw_exit_read(&sc->sc_audio.rwlock);
}
- sc->sc_as_running = 0;
+ CLR(sc->sc_flags, UTVFU_FLAG_AS_RUNNING);
+ wakeup(&sc->sc_flags);
DPRINTF(1, "%s %s: exiting\n", DEVNAME(sc), __func__);
@@ -1451,8 +1455,6 @@ utvfu_start_read(void *v)
void
utvfu_audio_clear_client(struct utvfu_softc *sc)
{
- sc->sc_flags &= ~UTVFU_FLAG_AUDIO_CLI;
-
rw_enter_write(&sc->sc_audio.rwlock);
sc->sc_audio.intr = NULL;
@@ -1855,7 +1857,7 @@ utvfu_audio_open(void *v, int flags)
if ((flags & FWRITE))
return (ENXIO);
- if (UTVFU_AUDIO_HAS_CLIENT(sc))
+ if (ISSET(sc->sc_flags, UTVFU_FLAG_AS_RUNNING))
return (EBUSY);
return utvfu_as_init(sc);
@@ -1866,10 +1868,9 @@ utvfu_audio_close(void *v)
{
struct utvfu_softc *sc = v;
- /* Leave the audio thread running if video is streaming */
- if (!UTVFU_VIDEO_HAS_CLIENT(sc))
- utvfu_as_free(sc);
+ DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
+ utvfu_audio_stop(sc);
utvfu_audio_clear_client(sc);
}
@@ -1937,9 +1938,7 @@ utvfu_audio_halt_in(void *v)
DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
- if (!UTVFU_VIDEO_HAS_CLIENT(sc))
- utvfu_audio_stop(sc);
-
+ utvfu_audio_stop(sc);
utvfu_audio_clear_client(sc);
return (0);
@@ -2069,8 +2068,6 @@ utvfu_audio_trigger_input(void *v, void *start, void *end, int blksize,
rw_exit_write(&sc->sc_audio.rwlock);
- sc->sc_flags |= UTVFU_FLAG_AUDIO_CLI;
-
DPRINTF(1, "%s %s: start=%p end=%p diff=%lu blksize=%d\n",
DEVNAME(sc), __func__, start, end,
((u_char *)end - (u_char *)start), blksize);
@@ -2081,11 +2078,15 @@ utvfu_audio_trigger_input(void *v, void *start, void *end, int blksize,
int
utvfu_audio_start(struct utvfu_softc *sc)
{
- if (sc->sc_as_running == 1)
+ DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
+
+ if (ISSET(sc->sc_flags, UTVFU_FLAG_AS_RUNNING))
return (0);
utvfu_audio_start_chip(sc);
+ if (utvfu_as_init(sc) != 0)
+ return (ENOMEM);
if (sc->sc_audio.iface.pipeh == NULL) {
if (utvfu_as_open(sc) != USBD_NORMAL_COMPLETION)
return (ENOMEM);
@@ -2097,9 +2098,10 @@ utvfu_audio_start(struct utvfu_softc *sc)
int
utvfu_audio_stop(struct utvfu_softc *sc)
{
- if (sc->sc_as_running == 1) {
- utvfu_audio_stop_chip(sc);
- utvfu_as_close(sc);
- }
+ DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
+
+ utvfu_audio_stop_chip(sc);
+ utvfu_as_free(sc);
+
return (0);
}
diff --git a/sys/dev/usb/utvfu.h b/sys/dev/usb/utvfu.h
index 20b83bd82ce..f71fd3d8c40 100644
--- a/sys/dev/usb/utvfu.h
+++ b/sys/dev/usb/utvfu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: utvfu.h,v 1.1 2016/06/01 09:48:20 mglocker Exp $ */
+/* $OpenBSD: utvfu.h,v 1.2 2016/06/13 19:45:07 mglocker Exp $ */
/*
* Copyright (c) 2013 Lubomir Rintel
* All rights reserved.
@@ -145,10 +145,9 @@ struct utvfu_softc {
struct device *sc_audiodev;
struct device *sc_videodev;
-#define UTVFU_FLAG_MMAP 0x01
-#define UTVFU_FLAG_AUDIO_CLI 0x02
-#define UTVFU_FLAG_VIDEO_CLI 0x04
int sc_flags;
+#define UTVFU_FLAG_MMAP 0x01
+#define UTVFU_FLAG_AS_RUNNING 0x02
int sc_normi;
int sc_nchunks;
@@ -159,7 +158,6 @@ struct utvfu_softc {
struct utvfu_vs_iface sc_iface;
struct utvfu_frame_buf sc_fb;
- int sc_as_running;
struct utvfu_audio_chan sc_audio;
/* mmap */