Page MenuHomeFreeBSD

D32499.diff
No OneTemporary

D32499.diff

diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h
--- a/sys/dev/sound/pcm/channel.h
+++ b/sys/dev/sound/pcm/channel.h
@@ -166,7 +166,8 @@
struct pcmchan_matrix matrix;
struct pcmchan_matrix matrix_scratch;
- int volume[SND_VOL_C_MAX][SND_CHN_T_VOL_MAX];
+ int16_t volume[SND_VOL_C_MAX][SND_CHN_T_VOL_MAX];
+ int8_t muted[SND_VOL_C_MAX][SND_CHN_T_VOL_MAX];
void *data1, *data2;
};
@@ -271,6 +272,9 @@
int center);
int chn_setvolume_matrix(struct pcm_channel *c, int vc, int vt, int val);
int chn_getvolume_matrix(struct pcm_channel *c, int vc, int vt);
+int chn_setmute_multi(struct pcm_channel *c, int vc, int mute);
+int chn_setmute_matrix(struct pcm_channel *c, int vc, int vt, int mute);
+int chn_getmute_matrix(struct pcm_channel *c, int vc, int vt);
void chn_vpc_reset(struct pcm_channel *c, int vc, int force);
int chn_setparam(struct pcm_channel *c, uint32_t format, uint32_t speed);
int chn_setspeed(struct pcm_channel *c, uint32_t speed);
@@ -307,6 +311,8 @@
#define CHN_GETVOLUME(x, y, z) ((x)->volume[y][z])
#endif
+#define CHN_GETMUTE(x, y, z) ((x)->muted[y][z])
+
#ifdef OSSV4_EXPERIMENT
int chn_getpeaks(struct pcm_channel *c, int *lpeak, int *rpeak);
#endif
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -1223,6 +1223,8 @@
c->volume[SND_VOL_C_MASTER][SND_CHN_T_VOL_0DB] = SND_VOL_0DB_MASTER;
c->volume[SND_VOL_C_PCM][SND_CHN_T_VOL_0DB] = chn_vol_0db_pcm;
+ memset(c->muted, 0, sizeof(c->muted));
+
chn_vpc_reset(c, SND_VOL_C_PCM, 1);
ret = ENODEV;
@@ -1394,6 +1396,75 @@
return (c->volume[vc][vt]);
}
+int
+chn_setmute_multi(struct pcm_channel *c, int vc, int mute)
+{
+ int i, ret;
+
+ ret = 0;
+
+ for (i = 0; i < SND_CHN_T_MAX; i++) {
+ if ((1 << i) & SND_CHN_LEFT_MASK)
+ ret |= chn_setmute_matrix(c, vc, i, mute);
+ else if ((1 << i) & SND_CHN_RIGHT_MASK)
+ ret |= chn_setmute_matrix(c, vc, i, mute) << 8;
+ else
+ ret |= chn_setmute_matrix(c, vc, i, mute) << 16;
+ }
+ return (ret);
+}
+
+int
+chn_setmute_matrix(struct pcm_channel *c, int vc, int vt, int mute)
+{
+ int i;
+
+ KASSERT(c != NULL && vc >= SND_VOL_C_MASTER && vc < SND_VOL_C_MAX &&
+ (vc == SND_VOL_C_MASTER || (vc & 1)) &&
+ (vt == SND_CHN_T_VOL_0DB || (vt >= SND_CHN_T_BEGIN && vt <= SND_CHN_T_END)),
+ ("%s(): invalid mute matrix c=%p vc=%d vt=%d mute=%d",
+ __func__, c, vc, vt, mute));
+
+ CHN_LOCKASSERT(c);
+
+ mute = (mute != 0);
+
+ c->muted[vc][vt] = mute;
+
+ /*
+ * Do relative calculation here and store it into class + 1
+ * to ease the job of feeder_volume.
+ */
+ if (vc == SND_VOL_C_MASTER) {
+ for (vc = SND_VOL_C_BEGIN; vc <= SND_VOL_C_END;
+ vc += SND_VOL_C_STEP)
+ c->muted[SND_VOL_C_VAL(vc)][vt] = mute;
+ } else if (vc & 1) {
+ if (vt == SND_CHN_T_VOL_0DB) {
+ for (i = SND_CHN_T_BEGIN; i <= SND_CHN_T_END;
+ i += SND_CHN_T_STEP) {
+ c->muted[SND_VOL_C_VAL(vc)][i] = mute;
+ }
+ } else {
+ c->muted[SND_VOL_C_VAL(vc)][vt] = mute;
+ }
+ }
+ return (mute);
+}
+
+int
+chn_getmute_matrix(struct pcm_channel *c, int vc, int vt)
+{
+ KASSERT(c != NULL && vc >= SND_VOL_C_MASTER && vc < SND_VOL_C_MAX &&
+ (vt == SND_CHN_T_VOL_0DB ||
+ (vt >= SND_CHN_T_BEGIN && vt <= SND_CHN_T_END)),
+ ("%s(): invalid mute matrix c=%p vc=%d vt=%d",
+ __func__, c, vc, vt));
+ CHN_LOCKASSERT(c);
+
+ return (c->muted[vc][vt]);
+}
+
struct pcmchan_matrix *
chn_getmatrix(struct pcm_channel *c)
{
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -965,6 +965,7 @@
struct snddev_info *d;
struct pcm_channel *rdch, *wrch;
int j, devtype, ret;
+ int left, right, center, mute;
d = dsp_get_info(dev);
if (!PCM_REGISTERED(d) || !(dsp_get_flags(dev) & SD_F_VPC))
@@ -1003,67 +1004,95 @@
}
/* Final validation */
- if (volch != NULL) {
- CHN_LOCK(volch);
- if (!(volch->feederflags & (1 << FEEDER_VOLUME))) {
- CHN_UNLOCK(volch);
- return (-1);
- }
- if (volch->direction == PCMDIR_PLAY)
- wrch = volch;
- else
- rdch = volch;
- }
-
- ret = EINVAL;
+ if (volch == NULL)
+ return (EINVAL);
- if (volch != NULL &&
- ((j == SOUND_MIXER_PCM && volch->direction == PCMDIR_PLAY) ||
- (j == SOUND_MIXER_RECLEV && volch->direction == PCMDIR_REC))) {
- if ((cmd & ~0xff) == MIXER_WRITE(0)) {
- int left, right, center;
+ CHN_LOCK(volch);
+ if (!(volch->feederflags & (1 << FEEDER_VOLUME))) {
+ CHN_UNLOCK(volch);
+ return (EINVAL);
+ }
+ switch (cmd & ~0xff) {
+ case MIXER_WRITE(0):
+ switch (j) {
+ case SOUND_MIXER_MUTE:
+ if (volch->direction == PCMDIR_REC) {
+ chn_setmute_multi(volch, SND_VOL_C_PCM, (*(int *)arg & SOUND_MASK_RECLEV) != 0);
+ } else {
+ chn_setmute_multi(volch, SND_VOL_C_PCM, (*(int *)arg & SOUND_MASK_PCM) != 0);
+ }
+ break;
+ case SOUND_MIXER_PCM:
+ if (volch->direction != PCMDIR_PLAY)
+ break;
left = *(int *)arg & 0x7f;
right = ((*(int *)arg) >> 8) & 0x7f;
center = (left + right) >> 1;
- chn_setvolume_multi(volch, SND_VOL_C_PCM, left, right,
- center);
- } else if ((cmd & ~0xff) == MIXER_READ(0)) {
- *(int *)arg = CHN_GETVOLUME(volch,
- SND_VOL_C_PCM, SND_CHN_T_FL);
- *(int *)arg |= CHN_GETVOLUME(volch,
- SND_VOL_C_PCM, SND_CHN_T_FR) << 8;
+ chn_setvolume_multi(volch, SND_VOL_C_PCM,
+ left, right, center);
+ break;
+ case SOUND_MIXER_RECLEV:
+ if (volch->direction != PCMDIR_REC)
+ break;
+ left = *(int *)arg & 0x7f;
+ right = ((*(int *)arg) >> 8) & 0x7f;
+ center = (left + right) >> 1;
+ chn_setvolume_multi(volch, SND_VOL_C_PCM,
+ left, right, center);
+ break;
+ default:
+ /* ignore all other mixer writes */
+ break;
}
- ret = 0;
- } else if (rdch != NULL || wrch != NULL) {
+ break;
+
+ case MIXER_READ(0):
switch (j) {
+ case SOUND_MIXER_MUTE:
+ mute = CHN_GETMUTE(volch, SND_VOL_C_PCM, SND_CHN_T_FL) ||
+ CHN_GETMUTE(volch, SND_VOL_C_PCM, SND_CHN_T_FR);
+ if (volch->direction == PCMDIR_REC) {
+ *(int *)arg = mute << SOUND_MIXER_RECLEV;
+ } else {
+ *(int *)arg = mute << SOUND_MIXER_PCM;
+ }
+ break;
+ case SOUND_MIXER_PCM:
+ if (volch->direction != PCMDIR_PLAY)
+ break;
+ *(int *)arg = CHN_GETVOLUME(volch,
+ SND_VOL_C_PCM, SND_CHN_T_FL);
+ *(int *)arg |= CHN_GETVOLUME(volch,
+ SND_VOL_C_PCM, SND_CHN_T_FR) << 8;
+ break;
+ case SOUND_MIXER_RECLEV:
+ if (volch->direction != PCMDIR_REC)
+ break;
+ *(int *)arg = CHN_GETVOLUME(volch,
+ SND_VOL_C_PCM, SND_CHN_T_FL);
+ *(int *)arg |= CHN_GETVOLUME(volch,
+ SND_VOL_C_PCM, SND_CHN_T_FR) << 8;
+ break;
case SOUND_MIXER_DEVMASK:
case SOUND_MIXER_CAPS:
case SOUND_MIXER_STEREODEVS:
- if ((cmd & ~0xff) == MIXER_READ(0)) {
- *(int *)arg = 0;
- if (rdch != NULL)
- *(int *)arg |= SOUND_MASK_RECLEV;
- if (wrch != NULL)
- *(int *)arg |= SOUND_MASK_PCM;
- }
- ret = 0;
- break;
- case SOUND_MIXER_RECMASK:
- case SOUND_MIXER_RECSRC:
- if ((cmd & ~0xff) == MIXER_READ(0))
- *(int *)arg = 0;
- ret = 0;
+ if (volch->direction == PCMDIR_REC)
+ *(int *)arg = SOUND_MASK_RECLEV;
+ else
+ *(int *)arg = SOUND_MASK_PCM;
break;
default:
+ *(int *)arg = 0;
break;
}
- }
-
- if (volch != NULL)
- CHN_UNLOCK(volch);
+ break;
- return (ret);
+ default:
+ break;
+ }
+ CHN_UNLOCK(volch);
+ return (0);
}
static int
@@ -2294,8 +2323,7 @@
size_t len;
len = strlen(namep);
-
- if (bcmp(name, namep, len) != 0)
+ if (strncmp(name, namep, len) != 0)
return (ENODEV);
name += len;
diff --git a/sys/dev/sound/pcm/feeder_volume.c b/sys/dev/sound/pcm/feeder_volume.c
--- a/sys/dev/sound/pcm/feeder_volume.c
+++ b/sys/dev/sound/pcm/feeder_volume.c
@@ -237,10 +237,13 @@
feed_volume_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
uint32_t count, void *source)
{
+ int temp_vol[SND_CHN_T_VOL_MAX];
struct feed_volume_info *info;
uint32_t j, align;
- int i, *vol, *matrix;
+ int i, *matrix;
uint8_t *dst;
+ const int16_t *vol;
+ const int8_t *muted;
/*
* Fetch filter data operation.
@@ -251,6 +254,7 @@
return (FEEDER_FEED(f->source, c, b, count, source));
vol = c->volume[SND_VOL_C_VAL(info->volume_class)];
+ muted = c->muted[SND_VOL_C_VAL(info->volume_class)];
matrix = info->matrix;
/*
@@ -258,17 +262,22 @@
*/
j = 0;
i = info->channels;
- do {
- if (vol[matrix[--i]] != SND_VOL_FLAT) {
+ while (i--) {
+ if (vol[matrix[i]] != SND_VOL_FLAT ||
+ muted[matrix[i]] != 0) {
j = 1;
break;
}
- } while (i != 0);
+ }
/* Nope, just bypass entirely. */
if (j == 0)
return (FEEDER_FEED(f->source, c, b, count, source));
+ /* Check if any controls are muted. */
+ for (j = 0; j != SND_CHN_T_VOL_MAX; j++)
+ temp_vol[j] = muted[j] ? 0 : vol[j];
+
dst = b;
align = info->bps * info->channels;
@@ -281,7 +290,7 @@
if (j == 0)
break;
- info->apply(vol, matrix, info->channels, dst, j);
+ info->apply(temp_vol, matrix, info->channels, dst, j);
j *= align;
dst += j;
diff --git a/sys/dev/sound/pcm/mixer.h b/sys/dev/sound/pcm/mixer.h
--- a/sys/dev/sound/pcm/mixer.h
+++ b/sys/dev/sound/pcm/mixer.h
@@ -60,8 +60,10 @@
void mix_setdevs(struct snd_mixer *m, u_int32_t v);
void mix_setrecdevs(struct snd_mixer *m, u_int32_t v);
+void mix_setmutedevs(struct snd_mixer *m, u_int32_t v);
u_int32_t mix_getdevs(struct snd_mixer *m);
u_int32_t mix_getrecdevs(struct snd_mixer *m);
+u_int32_t mix_getmutedevs(struct snd_mixer *m);
void mix_setparentchild(struct snd_mixer *m, u_int32_t parent, u_int32_t childs);
void mix_setrealdev(struct snd_mixer *m, u_int32_t dev, u_int32_t realdev);
u_int32_t mix_getparent(struct snd_mixer *m, u_int32_t dev);
diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c
--- a/sys/dev/sound/pcm/mixer.c
+++ b/sys/dev/sound/pcm/mixer.c
@@ -51,16 +51,16 @@
KOBJ_FIELDS;
void *devinfo;
int busy;
- int hwvol_muted;
int hwvol_mixer;
int hwvol_step;
int type;
device_t dev;
- u_int32_t hwvol_mute_level;
u_int32_t devs;
+ u_int32_t mutedevs;
u_int32_t recdevs;
u_int32_t recsrc;
u_int16_t level[32];
+ u_int16_t level_muted[32];
u_int8_t parent[32];
u_int32_t child[32];
u_int8_t realdev[32];
@@ -244,7 +244,7 @@
}
static int
-mixer_set(struct snd_mixer *m, u_int dev, u_int lev)
+mixer_set(struct snd_mixer *m, u_int dev, u_int32_t muted, u_int lev)
{
struct snddev_info *d;
u_int l, r, tl, tr;
@@ -254,7 +254,7 @@
if (m == NULL || dev >= SOUND_MIXER_NRDEVICES ||
(0 == (m->devs & (1 << dev))))
- return -1;
+ return (-1);
l = min((lev & 0x00ff), 100);
r = min(((lev & 0xff00) >> 8), 100);
@@ -262,7 +262,7 @@
d = device_get_softc(m->dev);
if (d == NULL)
- return -1;
+ return (-1);
/* It is safe to drop this mutex due to Giant. */
if (!(d->flags & SD_F_MPSAFE) && mtx_owned(m->lock) != 0)
@@ -270,6 +270,11 @@
else
dropmtx = 0;
+ /* Allow the volume to be "changed" while muted. */
+ if (muted & (1 << dev)) {
+ m->level_muted[dev] = l | (r << 8);
+ return (0);
+ }
MIXER_SET_UNLOCK(m, dropmtx);
/* TODO: recursive handling */
@@ -287,7 +292,7 @@
else if (realdev != SOUND_MIXER_NONE &&
MIXER_SET(m, realdev, tl, tr) < 0) {
MIXER_SET_LOCK(m, dropmtx);
- return -1;
+ return (-1);
}
} else if (child != 0) {
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
@@ -305,8 +310,8 @@
realdev = m->realdev[dev];
if (realdev != SOUND_MIXER_NONE &&
MIXER_SET(m, realdev, l, r) < 0) {
- MIXER_SET_LOCK(m, dropmtx);
- return -1;
+ MIXER_SET_LOCK(m, dropmtx);
+ return (-1);
}
} else {
if (dev == SOUND_MIXER_PCM && (d->flags & SD_F_SOFTPCMVOL))
@@ -317,7 +322,7 @@
else if (realdev != SOUND_MIXER_NONE &&
MIXER_SET(m, realdev, l, r) < 0) {
MIXER_SET_LOCK(m, dropmtx);
- return -1;
+ return (-1);
}
}
@@ -326,16 +331,42 @@
m->level[dev] = l | (r << 8);
m->modify_counter++;
- return 0;
+ return (0);
}
static int
mixer_get(struct snd_mixer *mixer, int dev)
{
- if ((dev < SOUND_MIXER_NRDEVICES) && (mixer->devs & (1 << dev)))
- return mixer->level[dev];
- else
- return -1;
+ if ((dev < SOUND_MIXER_NRDEVICES) && (mixer->devs & (1 << dev))) {
+ if (mixer->mutedevs & (1 << dev))
+ return (mixer->level_muted[dev]);
+ else
+ return (mixer->level[dev]);
+ } else {
+ return (-1);
+ }
+}
+
+void
+mix_setmutedevs(struct snd_mixer *mixer, u_int32_t mutedevs)
+{
+ u_int32_t delta;
+
+ /* Filter out invalid values. */
+ mutedevs &= mixer->devs;
+ delta = (mixer->mutedevs ^ mutedevs) & mixer->devs;
+ mixer->mutedevs = mutedevs;
+
+ for (int i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
+ if (!(delta & (1 << i)))
+ continue;
+ if (mutedevs & (1 << i)) {
+ mixer->level_muted[i] = mixer->level[i];
+ mixer_set(mixer, i, 0, 0);
+ } else {
+ mixer_set(mixer, i, 0, mixer->level_muted[i]);
+ }
+ }
}
static int
@@ -598,6 +629,12 @@
return m->devs;
}
+u_int32_t
+mix_getmutedevs(struct snd_mixer *m)
+{
+ return m->mutedevs;
+}
+
u_int32_t
mix_getrecdevs(struct snd_mixer *m)
{
@@ -721,7 +758,7 @@
}
}
- mixer_set(m, i, v | (v << 8));
+ mixer_set(m, i, 0, v | (v << 8));
}
mixer_setrecsrc(m, 0); /* Set default input. */
@@ -799,7 +836,7 @@
snd_mtxlock(m->lock);
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- mixer_set(m, i, 0);
+ mixer_set(m, i, 0, 0);
mixer_setrecsrc(m, SOUND_MASK_MIC);
@@ -836,8 +873,12 @@
return i;
}
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- mixer_set(m, i, m->level[i]);
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
+ if (m->mutedevs & (1 << i))
+ mixer_set(m, i, 0, 0);
+ else
+ mixer_set(m, i, 0, m->level[i]);
+ }
mixer_setrecsrc(m, m->recsrc);
snd_mtxunlock(m->lock);
@@ -863,10 +904,8 @@
if (dev == -1) {
snd_mtxunlock(m->lock);
return EINVAL;
- }
- else if (dev != m->hwvol_mixer) {
+ } else {
m->hwvol_mixer = dev;
- m->hwvol_muted = 0;
}
}
snd_mtxunlock(m->lock);
@@ -897,14 +936,7 @@
void
mixer_hwvol_mute_locked(struct snd_mixer *m)
{
- if (m->hwvol_muted) {
- m->hwvol_muted = 0;
- mixer_set(m, m->hwvol_mixer, m->hwvol_mute_level);
- } else {
- m->hwvol_muted++;
- m->hwvol_mute_level = mixer_get(m, m->hwvol_mixer);
- mixer_set(m, m->hwvol_mixer, 0);
- }
+ mix_setmutedevs(m, m->mutedevs ^ (1 << m->hwvol_mixer));
}
void
@@ -925,11 +957,8 @@
{
int level, left, right;
- if (m->hwvol_muted) {
- m->hwvol_muted = 0;
- level = m->hwvol_mute_level;
- } else
- level = mixer_get(m, m->hwvol_mixer);
+ level = mixer_get(m, m->hwvol_mixer);
+
if (level != -1) {
left = level & 0xff;
right = (level >> 8) & 0xff;
@@ -943,7 +972,8 @@
right = 0;
else if (right > 100)
right = 100;
- mixer_set(m, m->hwvol_mixer, left | right << 8);
+
+ mixer_set(m, m->hwvol_mixer, m->mutedevs, left | right << 8);
}
}
@@ -976,7 +1006,7 @@
KASSERT(m != NULL, ("NULL snd_mixer"));
snd_mtxlock(m->lock);
- ret = mixer_set(m, dev, left | (right << 8));
+ ret = mixer_set(m, dev, m->mutedevs, left | (right << 8));
snd_mtxunlock(m->lock);
return ((ret != 0) ? ENXIO : 0);
@@ -1304,10 +1334,18 @@
goto done;
}
if ((cmd & ~0xff) == MIXER_WRITE(0)) {
- if (j == SOUND_MIXER_RECSRC)
+ switch (j) {
+ case SOUND_MIXER_RECSRC:
ret = mixer_setrecsrc(m, *arg_i);
- else
- ret = mixer_set(m, j, *arg_i);
+ break;
+ case SOUND_MIXER_MUTE:
+ mix_setmutedevs(m, *arg_i);
+ ret = 0;
+ break;
+ default:
+ ret = mixer_set(m, j, m->mutedevs, *arg_i);
+ break;
+ }
snd_mtxunlock(m->lock);
return ((ret == 0) ? 0 : ENXIO);
}
@@ -1318,6 +1356,9 @@
case SOUND_MIXER_STEREODEVS:
v = mix_getdevs(m);
break;
+ case SOUND_MIXER_MUTE:
+ v = mix_getmutedevs(m);
+ break;
case SOUND_MIXER_RECMASK:
v = mix_getrecdevs(m);
break;
@@ -1326,6 +1367,7 @@
break;
default:
v = mixer_get(m, j);
+ break;
}
*arg_i = v;
snd_mtxunlock(m->lock);
@@ -1554,5 +1596,5 @@
level = (left & 0xFF) | ((right & 0xFF) << 8);
- return (mixer_set(m, dev, level));
+ return (mixer_set(m, dev, m->mutedevs, level));
}
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -411,6 +411,10 @@
void sound_oss_sysinfo(oss_sysinfo *);
int sound_oss_card_info(oss_card_info *);
+#define PCM_MODE_MIXER 0x01
+#define PCM_MODE_PLAY 0x02
+#define PCM_MODE_REC 0x04
+
#define PCM_LOCKOWNED(d) mtx_owned((d)->lock)
#define PCM_LOCK(d) mtx_lock((d)->lock)
#define PCM_UNLOCK(d) mtx_unlock((d)->lock)
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
--- a/sys/dev/sound/pcm/sound.c
+++ b/sys/dev/sound/pcm/sound.c
@@ -1015,12 +1015,30 @@
"global clone garbage collector");
#endif
+static u_int8_t
+pcm_mode_init(struct snddev_info *d)
+{
+ u_int8_t mode = 0;
+
+ if (d->playcount > 0)
+ mode |= PCM_MODE_PLAY;
+ if (d->reccount > 0)
+ mode |= PCM_MODE_REC;
+ if (d->mixer_dev != NULL)
+ mode |= PCM_MODE_MIXER;
+
+ return (mode);
+}
+
static void
pcm_sysinit(device_t dev)
{
struct snddev_info *d = device_get_softc(dev);
+ u_int8_t mode;
+
+ mode = pcm_mode_init(d);
- /* XXX: an user should be able to set this with a control tool, the
+ /* XXX: a user should be able to set this with a control tool, the
sysadmin then needs min+max sysctls for this */
SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
@@ -1030,6 +1048,11 @@
"bitperfect", CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, d,
sizeof(d), sysctl_dev_pcm_bitperfect, "I",
"bit-perfect playback/recording (0=disable, 1=enable)");
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "mode", CTLFLAG_RD, NULL, mode,
+ "mode (1=mixer, 2=play, 4=rec. The values are OR'ed if more than one"
+ "mode is supported)");
#ifdef SND_DEBUG
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
@@ -1133,7 +1156,7 @@
sysctl_ctx_init(&d->rec_sysctl_ctx);
d->rec_sysctl_tree = SYSCTL_ADD_NODE(&d->rec_sysctl_ctx,
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "rec",
- CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "record channels node");
+ CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "recording channels node");
if (numplay > 0 || numrec > 0)
d->flags |= SD_F_AUTOVCHAN;

File Metadata

Mime Type
text/plain
Expires
Sat, Jan 11, 9:32 AM (20 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15751867
Default Alt Text
D32499.diff (18 KB)

Event Timeline