diff options
author | Takashi Iwai <tiwai@suse.de> | 2006-03-27 09:40:49 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-03-31 10:58:59 -0500 |
commit | 3bf75f9b90c981f18f27a0d35a44f488ab68c8ea (patch) | |
tree | 9284c90f09ce38fc3bb2ebc46624ddf3db09b526 /sound/core/pcm_native.c | |
parent | bf1bbb5a49eec51c30d341606885507b501b37e8 (diff) |
[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>
Diffstat (limited to 'sound/core/pcm_native.c')
-rw-r--r-- | sound/core/pcm_native.c | 108 |
1 files changed, 57 insertions, 51 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 13efe39e4cc..964e4c47a7f 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -1995,28 +1995,63 @@ static void snd_pcm_remove_file(struct snd_pcm_str *str, | |||
1995 | } | 1995 | } |
1996 | } | 1996 | } |
1997 | 1997 | ||
1998 | static int snd_pcm_release_file(struct snd_pcm_file * pcm_file) | 1998 | static void pcm_release_private(struct snd_pcm_substream *substream) |
1999 | { | 1999 | { |
2000 | struct snd_pcm_substream *substream; | 2000 | struct snd_pcm_file *pcm_file = substream->file; |
2001 | struct snd_pcm_runtime *runtime; | ||
2002 | struct snd_pcm_str * str; | ||
2003 | 2001 | ||
2004 | snd_assert(pcm_file != NULL, return -ENXIO); | ||
2005 | substream = pcm_file->substream; | ||
2006 | snd_assert(substream != NULL, return -ENXIO); | ||
2007 | runtime = substream->runtime; | ||
2008 | str = substream->pstr; | ||
2009 | snd_pcm_unlink(substream); | 2002 | snd_pcm_unlink(substream); |
2010 | if (substream->ffile != NULL) { | 2003 | snd_pcm_remove_file(substream->pstr, pcm_file); |
2004 | kfree(pcm_file); | ||
2005 | } | ||
2006 | |||
2007 | void snd_pcm_release_substream(struct snd_pcm_substream *substream) | ||
2008 | { | ||
2009 | snd_pcm_drop(substream); | ||
2010 | if (substream->pcm_release) | ||
2011 | substream->pcm_release(substream); | ||
2012 | if (substream->hw_opened) { | ||
2011 | if (substream->ops->hw_free != NULL) | 2013 | if (substream->ops->hw_free != NULL) |
2012 | substream->ops->hw_free(substream); | 2014 | substream->ops->hw_free(substream); |
2013 | substream->ops->close(substream); | 2015 | substream->ops->close(substream); |
2014 | substream->ffile = NULL; | 2016 | substream->hw_opened = 0; |
2015 | } | 2017 | } |
2016 | snd_pcm_remove_file(str, pcm_file); | 2018 | snd_pcm_detach_substream(substream); |
2017 | snd_pcm_release_substream(substream); | 2019 | } |
2018 | kfree(pcm_file); | 2020 | |
2021 | int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, | ||
2022 | struct file *file, | ||
2023 | struct snd_pcm_substream **rsubstream) | ||
2024 | { | ||
2025 | struct snd_pcm_substream *substream; | ||
2026 | int err; | ||
2027 | |||
2028 | err = snd_pcm_attach_substream(pcm, stream, file, &substream); | ||
2029 | if (err < 0) | ||
2030 | return err; | ||
2031 | substream->no_mmap_ctrl = 0; | ||
2032 | err = snd_pcm_hw_constraints_init(substream); | ||
2033 | if (err < 0) { | ||
2034 | snd_printd("snd_pcm_hw_constraints_init failed\n"); | ||
2035 | goto error; | ||
2036 | } | ||
2037 | |||
2038 | if ((err = substream->ops->open(substream)) < 0) | ||
2039 | goto error; | ||
2040 | |||
2041 | substream->hw_opened = 1; | ||
2042 | |||
2043 | err = snd_pcm_hw_constraints_complete(substream); | ||
2044 | if (err < 0) { | ||
2045 | snd_printd("snd_pcm_hw_constraints_complete failed\n"); | ||
2046 | goto error; | ||
2047 | } | ||
2048 | |||
2049 | *rsubstream = substream; | ||
2019 | return 0; | 2050 | return 0; |
2051 | |||
2052 | error: | ||
2053 | snd_pcm_release_substream(substream); | ||
2054 | return err; | ||
2020 | } | 2055 | } |
2021 | 2056 | ||
2022 | static int snd_pcm_open_file(struct file *file, | 2057 | static int snd_pcm_open_file(struct file *file, |
@@ -2024,52 +2059,29 @@ static int snd_pcm_open_file(struct file *file, | |||
2024 | int stream, | 2059 | int stream, |
2025 | struct snd_pcm_file **rpcm_file) | 2060 | struct snd_pcm_file **rpcm_file) |
2026 | { | 2061 | { |
2027 | int err = 0; | ||
2028 | struct snd_pcm_file *pcm_file; | 2062 | struct snd_pcm_file *pcm_file; |
2029 | struct snd_pcm_substream *substream; | 2063 | struct snd_pcm_substream *substream; |
2030 | struct snd_pcm_str *str; | 2064 | struct snd_pcm_str *str; |
2065 | int err; | ||
2031 | 2066 | ||
2032 | snd_assert(rpcm_file != NULL, return -EINVAL); | 2067 | snd_assert(rpcm_file != NULL, return -EINVAL); |
2033 | *rpcm_file = NULL; | 2068 | *rpcm_file = NULL; |
2034 | 2069 | ||
2070 | err = snd_pcm_open_substream(pcm, stream, file, &substream); | ||
2071 | if (err < 0) | ||
2072 | return err; | ||
2073 | |||
2035 | pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL); | 2074 | pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL); |
2036 | if (pcm_file == NULL) { | 2075 | if (pcm_file == NULL) { |
2076 | snd_pcm_release_substream(substream); | ||
2037 | return -ENOMEM; | 2077 | return -ENOMEM; |
2038 | } | 2078 | } |
2039 | |||
2040 | if ((err = snd_pcm_open_substream(pcm, stream, &substream)) < 0) { | ||
2041 | kfree(pcm_file); | ||
2042 | return err; | ||
2043 | } | ||
2044 | |||
2045 | str = substream->pstr; | 2079 | str = substream->pstr; |
2046 | substream->file = pcm_file; | 2080 | substream->file = pcm_file; |
2047 | substream->no_mmap_ctrl = 0; | 2081 | substream->pcm_release = pcm_release_private; |
2048 | |||
2049 | pcm_file->substream = substream; | 2082 | pcm_file->substream = substream; |
2050 | |||
2051 | snd_pcm_add_file(str, pcm_file); | 2083 | snd_pcm_add_file(str, pcm_file); |
2052 | 2084 | ||
2053 | err = snd_pcm_hw_constraints_init(substream); | ||
2054 | if (err < 0) { | ||
2055 | snd_printd("snd_pcm_hw_constraints_init failed\n"); | ||
2056 | snd_pcm_release_file(pcm_file); | ||
2057 | return err; | ||
2058 | } | ||
2059 | |||
2060 | if ((err = substream->ops->open(substream)) < 0) { | ||
2061 | snd_pcm_release_file(pcm_file); | ||
2062 | return err; | ||
2063 | } | ||
2064 | substream->ffile = file; | ||
2065 | |||
2066 | err = snd_pcm_hw_constraints_complete(substream); | ||
2067 | if (err < 0) { | ||
2068 | snd_printd("snd_pcm_hw_constraints_complete failed\n"); | ||
2069 | snd_pcm_release_file(pcm_file); | ||
2070 | return err; | ||
2071 | } | ||
2072 | |||
2073 | file->private_data = pcm_file; | 2085 | file->private_data = pcm_file; |
2074 | *rpcm_file = pcm_file; | 2086 | *rpcm_file = pcm_file; |
2075 | return 0; | 2087 | return 0; |
@@ -2158,10 +2170,9 @@ static int snd_pcm_release(struct inode *inode, struct file *file) | |||
2158 | snd_assert(substream != NULL, return -ENXIO); | 2170 | snd_assert(substream != NULL, return -ENXIO); |
2159 | snd_assert(!atomic_read(&substream->runtime->mmap_count), ); | 2171 | snd_assert(!atomic_read(&substream->runtime->mmap_count), ); |
2160 | pcm = substream->pcm; | 2172 | pcm = substream->pcm; |
2161 | snd_pcm_drop(substream); | ||
2162 | fasync_helper(-1, file, 0, &substream->runtime->fasync); | 2173 | fasync_helper(-1, file, 0, &substream->runtime->fasync); |
2163 | mutex_lock(&pcm->open_mutex); | 2174 | mutex_lock(&pcm->open_mutex); |
2164 | snd_pcm_release_file(pcm_file); | 2175 | snd_pcm_release_substream(substream); |
2165 | mutex_unlock(&pcm->open_mutex); | 2176 | mutex_unlock(&pcm->open_mutex); |
2166 | wake_up(&pcm->open_wait); | 2177 | wake_up(&pcm->open_wait); |
2167 | module_put(pcm->card->module); | 2178 | module_put(pcm->card->module); |
@@ -2480,11 +2491,6 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream, | |||
2480 | return 0; | 2491 | return 0; |
2481 | } | 2492 | } |
2482 | 2493 | ||
2483 | static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream, | ||
2484 | unsigned int cmd, void __user *arg); | ||
2485 | static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream, | ||
2486 | unsigned int cmd, void __user *arg); | ||
2487 | |||
2488 | static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream, | 2494 | static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream, |
2489 | unsigned int cmd, void __user *arg) | 2495 | unsigned int cmd, void __user *arg) |
2490 | { | 2496 | { |