aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/pcm_native.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2006-03-27 09:40:49 -0500
committerJaroslav Kysela <perex@suse.cz>2006-03-31 10:58:59 -0500
commit3bf75f9b90c981f18f27a0d35a44f488ab68c8ea (patch)
tree9284c90f09ce38fc3bb2ebc46624ddf3db09b526 /sound/core/pcm_native.c
parentbf1bbb5a49eec51c30d341606885507b501b37e8 (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.c108
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
1998static int snd_pcm_release_file(struct snd_pcm_file * pcm_file) 1998static 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
2007void 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
2021int 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
2022static int snd_pcm_open_file(struct file *file, 2057static 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
2483static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream,
2484 unsigned int cmd, void __user *arg);
2485static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream,
2486 unsigned int cmd, void __user *arg);
2487
2488static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream, 2494static 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{