提交 548a648b 编写于 作者: T Takashi Iwai 提交者: Jaroslav Kysela

[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: NTakashi Iwai <tiwai@suse.de>
Signed-off-by: NJaroslav Kysela <perex@suse.cz>
上级 1c398558
...@@ -190,7 +190,7 @@ struct snd_pcm_ops { ...@@ -190,7 +190,7 @@ struct snd_pcm_ops {
struct snd_pcm_file { struct snd_pcm_file {
struct snd_pcm_substream *substream; struct snd_pcm_substream *substream;
struct snd_pcm_file *next; int no_compat_mmap;
}; };
struct snd_pcm_hw_rule; struct snd_pcm_hw_rule;
...@@ -384,7 +384,6 @@ struct snd_pcm_substream { ...@@ -384,7 +384,6 @@ struct snd_pcm_substream {
struct snd_info_entry *proc_prealloc_entry; struct snd_info_entry *proc_prealloc_entry;
#endif #endif
/* misc flags */ /* misc flags */
unsigned int no_mmap_ctrl: 1;
unsigned int hw_opened: 1; unsigned int hw_opened: 1;
}; };
...@@ -402,7 +401,6 @@ struct snd_pcm_str { ...@@ -402,7 +401,6 @@ struct snd_pcm_str {
/* -- OSS things -- */ /* -- OSS things -- */
struct snd_pcm_oss_stream oss; struct snd_pcm_oss_stream oss;
#endif #endif
struct snd_pcm_file *files;
#ifdef CONFIG_SND_VERBOSE_PROCFS #ifdef CONFIG_SND_VERBOSE_PROCFS
struct snd_info_entry *proc_root; struct snd_info_entry *proc_root;
struct snd_info_entry *proc_info_entry; struct snd_info_entry *proc_info_entry;
......
...@@ -478,7 +478,7 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l ...@@ -478,7 +478,7 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
* mmap of PCM status/control records because of the size * mmap of PCM status/control records because of the size
* incompatibility. * incompatibility.
*/ */
substream->no_mmap_ctrl = 1; pcm_file->no_compat_mmap = 1;
switch (cmd) { switch (cmd) {
case SNDRV_PCM_IOCTL_PVERSION: case SNDRV_PCM_IOCTL_PVERSION:
......
...@@ -1992,35 +1992,9 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream) ...@@ -1992,35 +1992,9 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
return 0; return 0;
} }
static void snd_pcm_add_file(struct snd_pcm_str *str,
struct snd_pcm_file *pcm_file)
{
pcm_file->next = str->files;
str->files = pcm_file;
}
static void snd_pcm_remove_file(struct snd_pcm_str *str,
struct snd_pcm_file *pcm_file)
{
struct snd_pcm_file * pcm_file1;
if (str->files == pcm_file) {
str->files = pcm_file->next;
} else {
pcm_file1 = str->files;
while (pcm_file1 && pcm_file1->next != pcm_file)
pcm_file1 = pcm_file1->next;
if (pcm_file1 != NULL)
pcm_file1->next = pcm_file->next;
}
}
static void pcm_release_private(struct snd_pcm_substream *substream) static void pcm_release_private(struct snd_pcm_substream *substream)
{ {
struct snd_pcm_file *pcm_file = substream->file;
snd_pcm_unlink(substream); snd_pcm_unlink(substream);
snd_pcm_remove_file(substream->pstr, pcm_file);
kfree(pcm_file);
} }
void snd_pcm_release_substream(struct snd_pcm_substream *substream) void 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,7 +2034,6 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
return 0; return 0;
} }
substream->no_mmap_ctrl = 0;
err = snd_pcm_hw_constraints_init(substream); err = snd_pcm_hw_constraints_init(substream);
if (err < 0) { if (err < 0) {
snd_printd("snd_pcm_hw_constraints_init failed\n"); snd_printd("snd_pcm_hw_constraints_init failed\n");
...@@ -2105,19 +2078,16 @@ static int snd_pcm_open_file(struct file *file, ...@@ -2105,19 +2078,16 @@ static int snd_pcm_open_file(struct file *file,
if (err < 0) if (err < 0)
return err; return err;
if (substream->ref_count > 1)
pcm_file = substream->file;
else {
pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL); pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL);
if (pcm_file == NULL) { if (pcm_file == NULL) {
snd_pcm_release_substream(substream); snd_pcm_release_substream(substream);
return -ENOMEM; return -ENOMEM;
} }
pcm_file->substream = substream;
if (substream->ref_count == 1) {
str = substream->pstr; str = substream->pstr;
substream->file = pcm_file; substream->file = pcm_file;
substream->pcm_release = pcm_release_private; substream->pcm_release = pcm_release_private;
pcm_file->substream = substream;
snd_pcm_add_file(str, pcm_file);
} }
file->private_data = pcm_file; file->private_data = pcm_file;
*rpcm_file = pcm_file; *rpcm_file = pcm_file;
...@@ -2209,6 +2179,7 @@ static int snd_pcm_release(struct inode *inode, struct file *file) ...@@ -2209,6 +2179,7 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
fasync_helper(-1, file, 0, &substream->runtime->fasync); fasync_helper(-1, file, 0, &substream->runtime->fasync);
mutex_lock(&pcm->open_mutex); mutex_lock(&pcm->open_mutex);
snd_pcm_release_substream(substream); snd_pcm_release_substream(substream);
kfree(pcm_file);
mutex_unlock(&pcm->open_mutex); mutex_unlock(&pcm->open_mutex);
wake_up(&pcm->open_wait); wake_up(&pcm->open_wait);
module_put(pcm->card->module); module_put(pcm->card->module);
...@@ -3270,11 +3241,11 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area) ...@@ -3270,11 +3241,11 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
offset = area->vm_pgoff << PAGE_SHIFT; offset = area->vm_pgoff << PAGE_SHIFT;
switch (offset) { switch (offset) {
case SNDRV_PCM_MMAP_OFFSET_STATUS: case SNDRV_PCM_MMAP_OFFSET_STATUS:
if (substream->no_mmap_ctrl) if (pcm_file->no_compat_mmap)
return -ENXIO; return -ENXIO;
return snd_pcm_mmap_status(substream, file, area); return snd_pcm_mmap_status(substream, file, area);
case SNDRV_PCM_MMAP_OFFSET_CONTROL: case SNDRV_PCM_MMAP_OFFSET_CONTROL:
if (substream->no_mmap_ctrl) if (pcm_file->no_compat_mmap)
return -ENXIO; return -ENXIO;
return snd_pcm_mmap_control(substream, file, area); return snd_pcm_mmap_control(substream, file, area);
default: default:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册