diff options
| author | Ariff Abdullah <ariff@FreeBSD.org> | 2005-10-26 21:18:41 +0000 |
|---|---|---|
| committer | Ariff Abdullah <ariff@FreeBSD.org> | 2005-10-26 21:18:41 +0000 |
| commit | 22ff0d37bed858c18d98a96dc3036a048a04110c (patch) | |
| tree | 93c79424134a2b31bd50f32a168ec80d0e64203e /sys/dev | |
| parent | f66ce35e97a3129c988b81ed0ce5f6f57465b89f (diff) | |
Notes
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/sound/pcm/vchan.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/sys/dev/sound/pcm/vchan.c b/sys/dev/sound/pcm/vchan.c index 91a114e65706..9b9e102f8f92 100644 --- a/sys/dev/sound/pcm/vchan.c +++ b/sys/dev/sound/pcm/vchan.c @@ -251,7 +251,8 @@ vchan_create(struct pcm_channel *parent) struct snddev_info *d = parent->parentsnddev; struct pcmchan_children *pce; struct pcm_channel *child; - int err, first; + struct pcmchan_caps *parent_caps; + int err, first, speed; CHN_UNLOCK(parent); @@ -295,7 +296,20 @@ vchan_create(struct pcm_channel *parent) err = chn_reset(parent, AFMT_STEREO | AFMT_S16_LE); if (err) printf("chn_reset: %d\n", err); - err = chn_setspeed(parent, 44100); + speed = 44100; + parent_caps = chn_getcaps(parent); + if (parent_caps != NULL) { + /* + * Limit speed based on driver caps. + * This is supposed to help fixed rate, non-VRA + * AC97 cards. + */ + if (speed < parent_caps->minspeed) + speed = parent_caps->minspeed; + if (speed > parent_caps->maxspeed) + speed = parent_caps->maxspeed; + } + err = chn_setspeed(parent, speed); if (err) printf("chn_setspeed: %d\n", err); } @@ -309,6 +323,7 @@ vchan_destroy(struct pcm_channel *c) struct pcm_channel *parent = c->parentchannel; struct snddev_info *d = parent->parentsnddev; struct pcmchan_children *pce; + struct snddev_channel *sce; int err, last; CHN_LOCK(parent); @@ -329,6 +344,19 @@ vchan_destroy(struct pcm_channel *c) CHN_UNLOCK(parent); return EINVAL; gotch: + SLIST_FOREACH(sce, &d->channels, link) { + if (sce->channel == c) { + if (sce->dsp_devt) + destroy_dev(sce->dsp_devt); + if (sce->dspW_devt) + destroy_dev(sce->dspW_devt); + if (sce->audio_devt) + destroy_dev(sce->audio_devt); + if (sce->dspr_devt) + destroy_dev(sce->dspr_devt); + break; + } + } SLIST_REMOVE(&parent->children, pce, pcmchan_children, link); free(pce, M_DEVBUF); |
