Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev Ensure proper use of sc_opens (play back) and sc_rec...



details:   https://anonhg.NetBSD.org/src/rev/ed43e0149cef
branches:  trunk
changeset: 356530:ed43e0149cef
user:      nat <nat%NetBSD.org@localhost>
date:      Sun Oct 01 21:49:20 2017 +0000

description:
Ensure proper use of sc_opens (play back) and sc_recopens (recording).
Fix logic for /dev/sound so audiosetinfo is only called once.

These changes are to ensure that init_output/input is only called once for
the respective function play back or recording.  For multiple recording or
plack back streams init_input/output is only called once fot the first
play/rec stream.

This addresses PR kern/52580, PR kern/52581 and PR kern/52582 analyzed and
reported by isaki@.

diffstat:

 sys/dev/audio.c |  42 ++++++++++++++++++++++--------------------
 1 files changed, 22 insertions(+), 20 deletions(-)

diffs (168 lines):

diff -r 1ab459025aa5 -r ed43e0149cef sys/dev/audio.c
--- a/sys/dev/audio.c   Sun Oct 01 20:49:24 2017 +0000
+++ b/sys/dev/audio.c   Sun Oct 01 21:49:20 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: audio.c,v 1.409 2017/09/30 05:37:55 isaki Exp $        */
+/*     $NetBSD: audio.c,v 1.410 2017/10/01 21:49:20 nat Exp $  */
 
 /*-
  * Copyright (c) 2016 Nathanial Sloss <nathanialsloss%yahoo.com.au@localhost>
@@ -148,7 +148,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.409 2017/09/30 05:37:55 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.410 2017/10/01 21:49:20 nat Exp $");
 
 #ifdef _KERNEL_OPT
 #include "audio.h"
@@ -2027,7 +2027,7 @@
                ((vc->sc_open & AUOPEN_READ) || vc == sc->sc_hwvc)) {
                audio_init_ringbuffer(sc, &vc->sc_mrr,
                    AUMODE_RECORD);
-               if (sc->sc_opens == 0 && (vc->sc_mode & AUMODE_RECORD)) {
+               if (sc->sc_recopens == 0 && (vc->sc_open & AUOPEN_READ)) {
                        if (hw->init_input) {
                                error = hw->init_input(sc->hw_hdl,
                                    vc->sc_mrr.s.start,
@@ -2043,7 +2043,7 @@
                audio_init_ringbuffer(sc, &vc->sc_mpr,
                    AUMODE_PLAY);
                vc->sc_sil_count = 0;
-               if (sc->sc_opens == 0 && (vc->sc_mode & AUMODE_PLAY)) {
+               if (sc->sc_opens == 0 && (vc->sc_open & AUOPEN_WRITE)) {
                        if (hw->init_output) {
                                error = hw->init_output(sc->hw_hdl,
                                    vc->sc_mpr.s.start,
@@ -2157,7 +2157,7 @@
        if (error)
                goto bad;
 
-       if (sc->sc_opens == 0) {
+       if (sc->sc_opens + sc->sc_recopens == 0) {
                sc->sc_credentials = kauth_cred_get();
                kauth_cred_hold(sc->sc_credentials);
                if (hw->open != NULL) {
@@ -2216,13 +2216,13 @@
         * The /dev/audio is always (re)set to 8-bit MU-Law mono
         * For the other devices, you get what they were last set to.
         */
-       error = audio_set_defaults(sc, mode, vc);
-       if (!error && ISDEVSOUND(dev) && sc->sc_aivalid == true) {
+       if (ISDEVSOUND(dev) && sc->sc_aivalid == true) {
                sc->sc_ai.mode = mode;
                sc->sc_ai.play.port = ~0;
                sc->sc_ai.record.port = ~0;
                error = audiosetinfo(sc, &sc->sc_ai, true, vc);
-       }
+       } else
+               error = audio_set_defaults(sc, mode, vc);
        if (error)
                goto bad;
 
@@ -2250,7 +2250,8 @@
        grow_mixer_states(sc, 2);
        if (flags & FREAD)
                sc->sc_recopens++;
-       sc->sc_opens++;
+       if (flags & FWRITE)
+               sc->sc_opens++;
        chan->dev = dev;
        chan->chan = n;
        chan->deschan = n;
@@ -2265,7 +2266,7 @@
 bad:
        audio_destroy_pfilters(vc);
        audio_destroy_rfilters(vc);
-       if (hw->close != NULL && sc->sc_opens == 0)
+       if (hw->close != NULL && sc->sc_opens == 0 && sc->sc_recopens == 0)
                hw->close(sc->hw_hdl);
        mutex_exit(sc->sc_lock);
        audio_free_ring(sc, &vc->sc_mpr);
@@ -2285,7 +2286,7 @@
 
        KASSERT(mutex_owned(sc->sc_lock));
        
-       if (sc->sc_opens != 0)
+       if (sc->sc_recopens != 0)
                return;
 
        mutex_enter(sc->sc_intr_lock);
@@ -2416,7 +2417,7 @@
 
        KASSERT(mutex_owned(sc->sc_lock));
        
-       if (sc->sc_opens == 0)
+       if (sc->sc_opens == 0 && sc->sc_recopens == 0)
                return ENXIO;
 
        vc = chan->vc;
@@ -2450,7 +2451,7 @@
                        audio_drain(sc, chan->vc);
                vc->sc_pbus = false;
        }
-       if (sc->sc_opens == 1) {
+       if ((flags & FWRITE) && (sc->sc_opens == 1)) {
                if (vc->sc_mpr.mmapped == false)
                        audio_drain(sc, sc->sc_hwvc);
                if (hw->drain)
@@ -2461,11 +2462,11 @@
        if ((flags & FREAD) && (sc->sc_recopens == 1))
                sc->sc_rec_started = false;
 
-       if (sc->sc_opens == 1 && hw->close != NULL)
+       if (sc->sc_opens + sc->sc_recopens == 1 && hw->close != NULL)
                hw->close(sc->hw_hdl);
        mutex_exit(sc->sc_intr_lock);
 
-       if (sc->sc_opens == 1) {
+       if (sc->sc_opens + sc->sc_recopens == 1) {
                sc->sc_async_audio = 0;
                kauth_cred_free(sc->sc_credentials);
        }
@@ -2479,7 +2480,8 @@
 
        if (flags & FREAD)
                sc->sc_recopens--;
-       sc->sc_opens--;
+       if (flags & FWRITE)
+               sc->sc_opens--;
        shrink_mixer_states(sc, 2);
        SIMPLEQ_REMOVE(&sc->sc_audiochan, chan, audio_chan, entries);
        mutex_exit(sc->sc_lock);
@@ -4710,7 +4712,7 @@
                }
        }
 
-       if (hw->commit_settings && sc->sc_opens == 0) {
+       if (hw->commit_settings && sc->sc_opens + sc->sc_recopens == 0) {
                error = hw->commit_settings(sc->hw_hdl);
                if (error)
                        goto cleanup;
@@ -5830,7 +5832,7 @@
        mutex_enter(sc->sc_lock);
 
        /* This may not change when a virtual channel is open */
-       if (sc->sc_opens) {
+       if (sc->sc_opens || sc->sc_recopens) {
                mutex_exit(sc->sc_lock);
                return EBUSY;
        }
@@ -5871,7 +5873,7 @@
        mutex_enter(sc->sc_lock);
 
        /* This may not change when a virtual channel is open */
-       if (sc->sc_opens) {
+       if (sc->sc_opens || sc->sc_recopens) {
                mutex_exit(sc->sc_lock);
                return EBUSY;
        }
@@ -5923,7 +5925,7 @@
        mutex_enter(sc->sc_lock);
 
        /* This may not change when a virtual channel is open */
-       if (sc->sc_opens) {
+       if (sc->sc_opens || sc->sc_recopens) {
                mutex_exit(sc->sc_lock);
                return EBUSY;
        }



Home | Main Index | Thread Index | Old Index