[ALSA] Clean up PCM codes (take 2)

- Clean up initialization and destruction of substream instance
  Now snd_pcm_open_substream() alone does most initialization jobs.
  Add pcm_release callback for cleaning up at snd_pcm_release_substream()
- Tidy up PCM oss code

Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2006-03-27 16:40:49 +02:00 committed by Jaroslav Kysela
parent bf1bbb5a49
commit 3bf75f9b90
6 changed files with 114 additions and 219 deletions

View file

@ -1995,28 +1995,63 @@ static void snd_pcm_remove_file(struct snd_pcm_str *str,
}
}
static int snd_pcm_release_file(struct snd_pcm_file * pcm_file)
static void pcm_release_private(struct snd_pcm_substream *substream)
{
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
struct snd_pcm_str * str;
struct snd_pcm_file *pcm_file = substream->file;
snd_assert(pcm_file != NULL, return -ENXIO);
substream = pcm_file->substream;
snd_assert(substream != NULL, return -ENXIO);
runtime = substream->runtime;
str = substream->pstr;
snd_pcm_unlink(substream);
if (substream->ffile != NULL) {
snd_pcm_remove_file(substream->pstr, pcm_file);
kfree(pcm_file);
}
void snd_pcm_release_substream(struct snd_pcm_substream *substream)
{
snd_pcm_drop(substream);
if (substream->pcm_release)
substream->pcm_release(substream);
if (substream->hw_opened) {
if (substream->ops->hw_free != NULL)
substream->ops->hw_free(substream);
substream->ops->close(substream);
substream->ffile = NULL;
substream->hw_opened = 0;
}
snd_pcm_remove_file(str, pcm_file);
snd_pcm_release_substream(substream);
kfree(pcm_file);
snd_pcm_detach_substream(substream);
}
int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
struct file *file,
struct snd_pcm_substream **rsubstream)
{
struct snd_pcm_substream *substream;
int err;
err = snd_pcm_attach_substream(pcm, stream, file, &substream);
if (err < 0)
return err;
substream->no_mmap_ctrl = 0;
err = snd_pcm_hw_constraints_init(substream);
if (err < 0) {
snd_printd("snd_pcm_hw_constraints_init failed\n");
goto error;
}
if ((err = substream->ops->open(substream)) < 0)
goto error;
substream->hw_opened = 1;
err = snd_pcm_hw_constraints_complete(substream);
if (err < 0) {
snd_printd("snd_pcm_hw_constraints_complete failed\n");
goto error;
}
*rsubstream = substream;
return 0;
error:
snd_pcm_release_substream(substream);
return err;
}
static int snd_pcm_open_file(struct file *file,
@ -2024,52 +2059,29 @@ static int snd_pcm_open_file(struct file *file,
int stream,
struct snd_pcm_file **rpcm_file)
{
int err = 0;
struct snd_pcm_file *pcm_file;
struct snd_pcm_substream *substream;
struct snd_pcm_str *str;
int err;
snd_assert(rpcm_file != NULL, return -EINVAL);
*rpcm_file = NULL;
err = snd_pcm_open_substream(pcm, stream, file, &substream);
if (err < 0)
return err;
pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL);
if (pcm_file == NULL) {
snd_pcm_release_substream(substream);
return -ENOMEM;
}
if ((err = snd_pcm_open_substream(pcm, stream, &substream)) < 0) {
kfree(pcm_file);
return err;
}
str = substream->pstr;
substream->file = pcm_file;
substream->no_mmap_ctrl = 0;
substream->pcm_release = pcm_release_private;
pcm_file->substream = substream;
snd_pcm_add_file(str, pcm_file);
err = snd_pcm_hw_constraints_init(substream);
if (err < 0) {
snd_printd("snd_pcm_hw_constraints_init failed\n");
snd_pcm_release_file(pcm_file);
return err;
}
if ((err = substream->ops->open(substream)) < 0) {
snd_pcm_release_file(pcm_file);
return err;
}
substream->ffile = file;
err = snd_pcm_hw_constraints_complete(substream);
if (err < 0) {
snd_printd("snd_pcm_hw_constraints_complete failed\n");
snd_pcm_release_file(pcm_file);
return err;
}
file->private_data = pcm_file;
*rpcm_file = pcm_file;
return 0;
@ -2158,10 +2170,9 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
snd_assert(substream != NULL, return -ENXIO);
snd_assert(!atomic_read(&substream->runtime->mmap_count), );
pcm = substream->pcm;
snd_pcm_drop(substream);
fasync_helper(-1, file, 0, &substream->runtime->fasync);
mutex_lock(&pcm->open_mutex);
snd_pcm_release_file(pcm_file);
snd_pcm_release_substream(substream);
mutex_unlock(&pcm->open_mutex);
wake_up(&pcm->open_wait);
module_put(pcm->card->module);
@ -2480,11 +2491,6 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
return 0;
}
static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream,
unsigned int cmd, void __user *arg);
static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream,
unsigned int cmd, void __user *arg);
static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream,
unsigned int cmd, void __user *arg)
{