Page MenuHomeFreeBSD

D48335.id149647.diff
No OneTemporary

D48335.id149647.diff

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
@@ -237,8 +237,8 @@
struct mtx *lock;
struct cdev *mixer_dev;
struct cdev *dsp_dev;
- uint32_t pvchanrate, pvchanformat;
- uint32_t rvchanrate, rvchanformat;
+ uint32_t pvchanrate, pvchanformat, pvchanmode;
+ uint32_t rvchanrate, rvchanformat, rvchanmode;
int32_t eqpreamp;
struct sysctl_ctx_list play_sysctl_ctx, rec_sysctl_ctx;
struct sysctl_oid *play_sysctl_tree, *rec_sysctl_tree;
diff --git a/sys/dev/sound/pcm/vchan.c b/sys/dev/sound/pcm/vchan.c
--- a/sys/dev/sound/pcm/vchan.c
+++ b/sys/dev/sound/pcm/vchan.c
@@ -253,48 +253,6 @@
};
CHANNEL_DECLARE(vchan);
-static void
-vchan_getparentchannel(struct snddev_info *d,
- struct pcm_channel **wrch, struct pcm_channel **rdch)
-{
- struct pcm_channel **ch, *wch, *rch, *c;
-
- KASSERT(d != NULL, ("%s(): NULL snddev_info", __func__));
-
- PCM_BUSYASSERT(d);
- PCM_UNLOCKASSERT(d);
-
- wch = NULL;
- rch = NULL;
-
- CHN_FOREACH(c, d, channels.pcm) {
- CHN_LOCK(c);
- ch = (c->direction == PCMDIR_PLAY) ? &wch : &rch;
- if (c->flags & CHN_F_VIRTUAL) {
- /* Sanity check */
- if (*ch != NULL && *ch != c->parentchannel) {
- CHN_UNLOCK(c);
- *ch = NULL;
- break;
- }
- } else {
- /* No way!! */
- if (*ch != NULL) {
- CHN_UNLOCK(c);
- *ch = NULL;
- break;
- }
- *ch = c;
- }
- CHN_UNLOCK(c);
- }
-
- if (wrch != NULL)
- *wrch = wch;
- if (rdch != NULL)
- *rdch = rch;
-}
-
static int
sysctl_dev_pcm_vchans(SYSCTL_HANDLER_ARGS)
{
@@ -356,7 +314,7 @@
struct snddev_info *d;
struct pcm_channel *c;
uint32_t dflags;
- int direction, ret;
+ int *vchanmode, direction, ret;
char dtype[16];
d = devclass_get_softc(pcm_devclass, VCHAN_SYSCTL_UNIT(oidp->oid_arg1));
@@ -373,6 +331,7 @@
return (ENODEV);
}
direction = PCMDIR_PLAY;
+ vchanmode = &d->pvchanmode;
break;
case VCHAN_REC:
if ((d->flags & SD_F_RVCHANS) == 0) {
@@ -380,6 +339,7 @@
return (ENODEV);
}
direction = PCMDIR_REC;
+ vchanmode = &d->rvchanmode;
break;
default:
PCM_UNLOCK(d);
@@ -389,53 +349,42 @@
PCM_ACQUIRE(d);
PCM_UNLOCK(d);
- if (direction == PCMDIR_PLAY)
- vchan_getparentchannel(d, &c, NULL);
- else
- vchan_getparentchannel(d, NULL, &c);
-
- if (c == NULL) {
- PCM_RELEASE_QUICK(d);
- return (EINVAL);
- }
-
- KASSERT(direction == c->direction, ("%s(): invalid direction %d/%d",
- __func__, direction, c->direction));
-
- CHN_LOCK(c);
- if (c->flags & CHN_F_VCHAN_PASSTHROUGH)
+ if (*vchanmode & CHN_F_VCHAN_PASSTHROUGH)
strlcpy(dtype, "passthrough", sizeof(dtype));
- else if (c->flags & CHN_F_VCHAN_ADAPTIVE)
+ else if (*vchanmode & CHN_F_VCHAN_ADAPTIVE)
strlcpy(dtype, "adaptive", sizeof(dtype));
else
strlcpy(dtype, "fixed", sizeof(dtype));
- CHN_UNLOCK(c);
ret = sysctl_handle_string(oidp, dtype, sizeof(dtype), req);
- if (ret == 0 && req->newptr != NULL) {
- if (strcasecmp(dtype, "passthrough") == 0 ||
- strcmp(dtype, "1") == 0)
- dflags = CHN_F_VCHAN_PASSTHROUGH;
- else if (strcasecmp(dtype, "adaptive") == 0 ||
- strcmp(dtype, "2") == 0)
- dflags = CHN_F_VCHAN_ADAPTIVE;
- else if (strcasecmp(dtype, "fixed") == 0 ||
- strcmp(dtype, "0") == 0)
- dflags = 0;
- else {
- PCM_RELEASE_QUICK(d);
- return (EINVAL);
- }
+ if (ret != 0 || req->newptr == NULL) {
+ PCM_RELEASE_QUICK(d);
+ return (ret);
+ }
+
+ if (strcasecmp(dtype, "passthrough") == 0 || strcmp(dtype, "1") == 0)
+ dflags = CHN_F_VCHAN_PASSTHROUGH;
+ else if (strcasecmp(dtype, "adaptive") == 0 || strcmp(dtype, "2") == 0)
+ dflags = CHN_F_VCHAN_ADAPTIVE;
+ else if (strcasecmp(dtype, "fixed") == 0 || strcmp(dtype, "0") == 0)
+ dflags = 0;
+ else {
+ PCM_RELEASE_QUICK(d);
+ return (EINVAL);
+ }
+
+ CHN_FOREACH(c, d, channels.pcm.primary) {
CHN_LOCK(c);
- if (dflags == (c->flags & CHN_F_VCHAN_DYNAMIC) ||
+ if (c->direction != direction ||
+ dflags == (c->flags & CHN_F_VCHAN_DYNAMIC) ||
(c->flags & CHN_F_PASSTHROUGH)) {
CHN_UNLOCK(c);
- PCM_RELEASE_QUICK(d);
- return (0);
+ continue;
}
c->flags &= ~CHN_F_VCHAN_DYNAMIC;
c->flags |= dflags;
CHN_UNLOCK(c);
+ *vchanmode = dflags;
}
PCM_RELEASE_QUICK(d);
@@ -491,19 +440,6 @@
PCM_ACQUIRE(d);
PCM_UNLOCK(d);
- if (direction == PCMDIR_PLAY)
- vchan_getparentchannel(d, &c, NULL);
- else
- vchan_getparentchannel(d, NULL, &c);
-
- if (c == NULL) {
- PCM_RELEASE_QUICK(d);
- return (EINVAL);
- }
-
- KASSERT(direction == c->direction, ("%s(): invalid direction %d/%d",
- __func__, direction, c->direction));
-
newspd = *vchanrate;
ret = sysctl_handle_int(oidp, &newspd, 0, req);
@@ -517,40 +453,44 @@
return (EINVAL);
}
- CHN_LOCK(c);
-
- if (newspd != c->speed && VCHAN_ACCESSIBLE(c)) {
- if (CHN_STARTED(c)) {
- chn_abort(c);
- restart = 1;
- } else
- restart = 0;
-
- if (feeder_rate_round) {
- caps = chn_getcaps(c);
- RANGE(newspd, caps->minspeed, caps->maxspeed);
- newspd = CHANNEL_SETSPEED(c->methods,
- c->devinfo, newspd);
+ CHN_FOREACH(c, d, channels.pcm.primary) {
+ CHN_LOCK(c);
+ if (c->direction != direction) {
+ CHN_UNLOCK(c);
+ continue;
}
- *vchanrate = newspd;
-
- ret = chn_reset(c, c->format, newspd);
- if (ret == 0) {
- if (restart != 0) {
- CHN_FOREACH(ch, c, children.busy) {
- CHN_LOCK(ch);
- if (VCHAN_SYNC_REQUIRED(ch))
- vchan_sync(ch);
- CHN_UNLOCK(ch);
+ if (newspd != c->speed && VCHAN_ACCESSIBLE(c)) {
+ if (CHN_STARTED(c)) {
+ chn_abort(c);
+ restart = 1;
+ } else
+ restart = 0;
+
+ if (feeder_rate_round) {
+ caps = chn_getcaps(c);
+ RANGE(newspd, caps->minspeed, caps->maxspeed);
+ newspd = CHANNEL_SETSPEED(c->methods,
+ c->devinfo, newspd);
+ }
+ *vchanrate = newspd;
+
+ ret = chn_reset(c, c->format, newspd);
+ if (ret == 0) {
+ if (restart != 0) {
+ CHN_FOREACH(ch, c, children.busy) {
+ CHN_LOCK(ch);
+ if (VCHAN_SYNC_REQUIRED(ch))
+ vchan_sync(ch);
+ CHN_UNLOCK(ch);
+ }
+ c->flags |= CHN_F_DIRTY;
+ ret = chn_start(c, 1);
}
- c->flags |= CHN_F_DIRTY;
- ret = chn_start(c, 1);
}
}
+ CHN_UNLOCK(c);
}
- CHN_UNLOCK(c);
-
PCM_RELEASE_QUICK(d);
return (ret);
@@ -597,19 +537,6 @@
PCM_ACQUIRE(d);
PCM_UNLOCK(d);
- if (direction == PCMDIR_PLAY)
- vchan_getparentchannel(d, &c, NULL);
- else
- vchan_getparentchannel(d, NULL, &c);
-
- if (c == NULL) {
- PCM_RELEASE_QUICK(d);
- return (EINVAL);
- }
-
- KASSERT(direction == c->direction, ("%s(): invalid direction %d/%d",
- __func__, direction, c->direction));
-
bzero(fmtstr, sizeof(fmtstr));
if (snd_afmt2str(*vchanformat, fmtstr, sizeof(fmtstr)) != *vchanformat)
@@ -627,33 +554,37 @@
return (EINVAL);
}
- CHN_LOCK(c);
-
- if (newfmt != c->format && VCHAN_ACCESSIBLE(c)) {
- if (CHN_STARTED(c)) {
- chn_abort(c);
- restart = 1;
- } else
- restart = 0;
- *vchanformat = newfmt;
-
- ret = chn_reset(c, newfmt, c->speed);
- if (ret == 0) {
- if (restart != 0) {
- CHN_FOREACH(ch, c, children.busy) {
- CHN_LOCK(ch);
- if (VCHAN_SYNC_REQUIRED(ch))
- vchan_sync(ch);
- CHN_UNLOCK(ch);
+ CHN_FOREACH(c, d, channels.pcm.primary) {
+ CHN_LOCK(c);
+ if (c->direction != direction) {
+ CHN_UNLOCK(c);
+ continue;
+ }
+ if (newfmt != c->format && VCHAN_ACCESSIBLE(c)) {
+ if (CHN_STARTED(c)) {
+ chn_abort(c);
+ restart = 1;
+ } else
+ restart = 0;
+ *vchanformat = newfmt;
+
+ ret = chn_reset(c, newfmt, c->speed);
+ if (ret == 0) {
+ if (restart != 0) {
+ CHN_FOREACH(ch, c, children.busy) {
+ CHN_LOCK(ch);
+ if (VCHAN_SYNC_REQUIRED(ch))
+ vchan_sync(ch);
+ CHN_UNLOCK(ch);
+ }
+ c->flags |= CHN_F_DIRTY;
+ ret = chn_start(c, 1);
}
- c->flags |= CHN_F_DIRTY;
- ret = chn_start(c, 1);
}
}
+ CHN_UNLOCK(c);
}
- CHN_UNLOCK(c);
-
PCM_RELEASE_QUICK(d);
return (ret);

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 8, 7:26 PM (25 m, 52 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28488765
Default Alt Text
D48335.id149647.diff (7 KB)

Event Timeline