aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2006-07-31 10:51:51 -0400
committerJaroslav Kysela <perex@suse.cz>2006-09-23 04:39:50 -0400
commit548a648b98318e4b843b636dd2c7f42377e19a00 (patch)
treeaf08ffaaabd478080656a7fb8df149d37f66cdb8 /sound
parent1c3985580445ef9225c1ea7714d6d963f7626eeb (diff)
[ALSA] Fix control/status mmap with shared PCM substream
The flag to avoid 32bit-incompatible mmap for control/status records should be outside the pcm substream instance since a substream can be shared among multiple opens. Now it's flagged in pcm_file list that is directly assigned to file->private_data. Also, removed snd_pcm_add_file() and remove_file() functions and substream.files field that are not really used in the code. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/core/pcm_compat.c2
-rw-r--r--sound/core/pcm_native.c49
2 files changed, 11 insertions, 40 deletions
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 2b8aab6fd6cd..2b539799d23b 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -478,7 +478,7 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
478 * mmap of PCM status/control records because of the size 478 * mmap of PCM status/control records because of the size
479 * incompatibility. 479 * incompatibility.
480 */ 480 */
481 substream->no_mmap_ctrl = 1; 481 pcm_file->no_compat_mmap = 1;
482 482
483 switch (cmd) { 483 switch (cmd) {
484 case SNDRV_PCM_IOCTL_PVERSION: 484 case SNDRV_PCM_IOCTL_PVERSION:
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 439f047929e1..0224c70414f5 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1992,35 +1992,9 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
1992 return 0; 1992 return 0;
1993} 1993}
1994 1994
1995static void snd_pcm_add_file(struct snd_pcm_str *str,
1996 struct snd_pcm_file *pcm_file)
1997{
1998 pcm_file->next = str->files;
1999 str->files = pcm_file;
2000}
2001
2002static void snd_pcm_remove_file(struct snd_pcm_str *str,
2003 struct snd_pcm_file *pcm_file)
2004{
2005 struct snd_pcm_file * pcm_file1;
2006 if (str->files == pcm_file) {
2007 str->files = pcm_file->next;
2008 } else {
2009 pcm_file1 = str->files;
2010 while (pcm_file1 && pcm_file1->next != pcm_file)
2011 pcm_file1 = pcm_file1->next;
2012 if (pcm_file1 != NULL)
2013 pcm_file1->next = pcm_file->next;
2014 }
2015}
2016
2017static void pcm_release_private(struct snd_pcm_substream *substream) 1995static void pcm_release_private(struct snd_pcm_substream *substream)
2018{ 1996{
2019 struct snd_pcm_file *pcm_file = substream->file;
2020
2021 snd_pcm_unlink(substream); 1997 snd_pcm_unlink(substream);
2022 snd_pcm_remove_file(substream->pstr, pcm_file);
2023 kfree(pcm_file);
2024} 1998}
2025 1999
2026void snd_pcm_release_substream(struct snd_pcm_substream *substream) 2000void snd_pcm_release_substream(struct snd_pcm_substream *substream)
@@ -2060,7 +2034,6 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
2060 return 0; 2034 return 0;
2061 } 2035 }
2062 2036
2063 substream->no_mmap_ctrl = 0;
2064 err = snd_pcm_hw_constraints_init(substream); 2037 err = snd_pcm_hw_constraints_init(substream);
2065 if (err < 0) { 2038 if (err < 0) {
2066 snd_printd("snd_pcm_hw_constraints_init failed\n"); 2039 snd_printd("snd_pcm_hw_constraints_init failed\n");
@@ -2105,19 +2078,16 @@ static int snd_pcm_open_file(struct file *file,
2105 if (err < 0) 2078 if (err < 0)
2106 return err; 2079 return err;
2107 2080
2108 if (substream->ref_count > 1) 2081 pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL);
2109 pcm_file = substream->file; 2082 if (pcm_file == NULL) {
2110 else { 2083 snd_pcm_release_substream(substream);
2111 pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL); 2084 return -ENOMEM;
2112 if (pcm_file == NULL) { 2085 }
2113 snd_pcm_release_substream(substream); 2086 pcm_file->substream = substream;
2114 return -ENOMEM; 2087 if (substream->ref_count == 1) {
2115 }
2116 str = substream->pstr; 2088 str = substream->pstr;
2117 substream->file = pcm_file; 2089 substream->file = pcm_file;
2118 substream->pcm_release = pcm_release_private; 2090 substream->pcm_release = pcm_release_private;
2119 pcm_file->substream = substream;
2120 snd_pcm_add_file(str, pcm_file);
2121 } 2091 }
2122 file->private_data = pcm_file; 2092 file->private_data = pcm_file;
2123 *rpcm_file = pcm_file; 2093 *rpcm_file = pcm_file;
@@ -2209,6 +2179,7 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
2209 fasync_helper(-1, file, 0, &substream->runtime->fasync); 2179 fasync_helper(-1, file, 0, &substream->runtime->fasync);
2210 mutex_lock(&pcm->open_mutex); 2180 mutex_lock(&pcm->open_mutex);
2211 snd_pcm_release_substream(substream); 2181 snd_pcm_release_substream(substream);
2182 kfree(pcm_file);
2212 mutex_unlock(&pcm->open_mutex); 2183 mutex_unlock(&pcm->open_mutex);
2213 wake_up(&pcm->open_wait); 2184 wake_up(&pcm->open_wait);
2214 module_put(pcm->card->module); 2185 module_put(pcm->card->module);
@@ -3270,11 +3241,11 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
3270 offset = area->vm_pgoff << PAGE_SHIFT; 3241 offset = area->vm_pgoff << PAGE_SHIFT;
3271 switch (offset) { 3242 switch (offset) {
3272 case SNDRV_PCM_MMAP_OFFSET_STATUS: 3243 case SNDRV_PCM_MMAP_OFFSET_STATUS:
3273 if (substream->no_mmap_ctrl) 3244 if (pcm_file->no_compat_mmap)
3274 return -ENXIO; 3245 return -ENXIO;
3275 return snd_pcm_mmap_status(substream, file, area); 3246 return snd_pcm_mmap_status(substream, file, area);
3276 case SNDRV_PCM_MMAP_OFFSET_CONTROL: 3247 case SNDRV_PCM_MMAP_OFFSET_CONTROL:
3277 if (substream->no_mmap_ctrl) 3248 if (pcm_file->no_compat_mmap)
3278 return -ENXIO; 3249 return -ENXIO;
3279 return snd_pcm_mmap_control(substream, file, area); 3250 return snd_pcm_mmap_control(substream, file, area);
3280 default: 3251 default: