diff options
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/control.c | 9 | ||||
-rw-r--r-- | sound/core/isadma.c | 10 | ||||
-rw-r--r-- | sound/core/oss/mixer_oss.c | 4 | ||||
-rw-r--r-- | sound/core/pcm.c | 6 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 83 | ||||
-rw-r--r-- | sound/core/rawmidi.c | 17 |
6 files changed, 92 insertions, 37 deletions
diff --git a/sound/core/control.c b/sound/core/control.c index a8b7fabe645e..268ab7471224 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -75,7 +75,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file) | |||
75 | ctl->card = card; | 75 | ctl->card = card; |
76 | ctl->prefer_pcm_subdevice = -1; | 76 | ctl->prefer_pcm_subdevice = -1; |
77 | ctl->prefer_rawmidi_subdevice = -1; | 77 | ctl->prefer_rawmidi_subdevice = -1; |
78 | ctl->pid = current->pid; | 78 | ctl->pid = get_pid(task_pid(current)); |
79 | file->private_data = ctl; | 79 | file->private_data = ctl; |
80 | write_lock_irqsave(&card->ctl_files_rwlock, flags); | 80 | write_lock_irqsave(&card->ctl_files_rwlock, flags); |
81 | list_add_tail(&ctl->list, &card->ctl_files); | 81 | list_add_tail(&ctl->list, &card->ctl_files); |
@@ -125,6 +125,7 @@ static int snd_ctl_release(struct inode *inode, struct file *file) | |||
125 | control->vd[idx].owner = NULL; | 125 | control->vd[idx].owner = NULL; |
126 | up_write(&card->controls_rwsem); | 126 | up_write(&card->controls_rwsem); |
127 | snd_ctl_empty_read_queue(ctl); | 127 | snd_ctl_empty_read_queue(ctl); |
128 | put_pid(ctl->pid); | ||
128 | kfree(ctl); | 129 | kfree(ctl); |
129 | module_put(card->module); | 130 | module_put(card->module); |
130 | snd_card_file_remove(card, file); | 131 | snd_card_file_remove(card, file); |
@@ -672,7 +673,7 @@ static int snd_ctl_elem_info(struct snd_ctl_file *ctl, | |||
672 | info->access |= SNDRV_CTL_ELEM_ACCESS_LOCK; | 673 | info->access |= SNDRV_CTL_ELEM_ACCESS_LOCK; |
673 | if (vd->owner == ctl) | 674 | if (vd->owner == ctl) |
674 | info->access |= SNDRV_CTL_ELEM_ACCESS_OWNER; | 675 | info->access |= SNDRV_CTL_ELEM_ACCESS_OWNER; |
675 | info->owner = vd->owner_pid; | 676 | info->owner = pid_vnr(vd->owner->pid); |
676 | } else { | 677 | } else { |
677 | info->owner = -1; | 678 | info->owner = -1; |
678 | } | 679 | } |
@@ -827,7 +828,6 @@ static int snd_ctl_elem_lock(struct snd_ctl_file *file, | |||
827 | result = -EBUSY; | 828 | result = -EBUSY; |
828 | else { | 829 | else { |
829 | vd->owner = file; | 830 | vd->owner = file; |
830 | vd->owner_pid = current->pid; | ||
831 | result = 0; | 831 | result = 0; |
832 | } | 832 | } |
833 | } | 833 | } |
@@ -858,7 +858,6 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file, | |||
858 | result = -EPERM; | 858 | result = -EPERM; |
859 | else { | 859 | else { |
860 | vd->owner = NULL; | 860 | vd->owner = NULL; |
861 | vd->owner_pid = 0; | ||
862 | result = 0; | 861 | result = 0; |
863 | } | 862 | } |
864 | } | 863 | } |
@@ -1120,7 +1119,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file, | |||
1120 | goto __kctl_end; | 1119 | goto __kctl_end; |
1121 | } | 1120 | } |
1122 | if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { | 1121 | if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { |
1123 | if (file && vd->owner != NULL && vd->owner != file) { | 1122 | if (vd->owner != NULL && vd->owner != file) { |
1124 | err = -EPERM; | 1123 | err = -EPERM; |
1125 | goto __kctl_end; | 1124 | goto __kctl_end; |
1126 | } | 1125 | } |
diff --git a/sound/core/isadma.c b/sound/core/isadma.c index 79f0f16af339..950e19ba91fc 100644 --- a/sound/core/isadma.c +++ b/sound/core/isadma.c | |||
@@ -85,16 +85,24 @@ EXPORT_SYMBOL(snd_dma_disable); | |||
85 | unsigned int snd_dma_pointer(unsigned long dma, unsigned int size) | 85 | unsigned int snd_dma_pointer(unsigned long dma, unsigned int size) |
86 | { | 86 | { |
87 | unsigned long flags; | 87 | unsigned long flags; |
88 | unsigned int result; | 88 | unsigned int result, result1; |
89 | 89 | ||
90 | flags = claim_dma_lock(); | 90 | flags = claim_dma_lock(); |
91 | clear_dma_ff(dma); | 91 | clear_dma_ff(dma); |
92 | if (!isa_dma_bridge_buggy) | 92 | if (!isa_dma_bridge_buggy) |
93 | disable_dma(dma); | 93 | disable_dma(dma); |
94 | result = get_dma_residue(dma); | 94 | result = get_dma_residue(dma); |
95 | /* | ||
96 | * HACK - read the counter again and choose higher value in order to | ||
97 | * avoid reading during counter lower byte roll over if the | ||
98 | * isa_dma_bridge_buggy is set. | ||
99 | */ | ||
100 | result1 = get_dma_residue(dma); | ||
95 | if (!isa_dma_bridge_buggy) | 101 | if (!isa_dma_bridge_buggy) |
96 | enable_dma(dma); | 102 | enable_dma(dma); |
97 | release_dma_lock(flags); | 103 | release_dma_lock(flags); |
104 | if (unlikely(result < result1)) | ||
105 | result = result1; | ||
98 | #ifdef CONFIG_SND_DEBUG | 106 | #ifdef CONFIG_SND_DEBUG |
99 | if (result > size) | 107 | if (result > size) |
100 | snd_printk(KERN_ERR "pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size); | 108 | snd_printk(KERN_ERR "pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size); |
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 772423889eb3..54e2eb56e4c2 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c | |||
@@ -1251,7 +1251,9 @@ static void snd_mixer_oss_build(struct snd_mixer_oss *mixer) | |||
1251 | { SOUND_MIXER_SYNTH, "FM", 0 }, /* fallback */ | 1251 | { SOUND_MIXER_SYNTH, "FM", 0 }, /* fallback */ |
1252 | { SOUND_MIXER_SYNTH, "Music", 0 }, /* fallback */ | 1252 | { SOUND_MIXER_SYNTH, "Music", 0 }, /* fallback */ |
1253 | { SOUND_MIXER_PCM, "PCM", 0 }, | 1253 | { SOUND_MIXER_PCM, "PCM", 0 }, |
1254 | { SOUND_MIXER_SPEAKER, "PC Speaker", 0 }, | 1254 | { SOUND_MIXER_SPEAKER, "Beep", 0 }, |
1255 | { SOUND_MIXER_SPEAKER, "PC Speaker", 0 }, /* fallback */ | ||
1256 | { SOUND_MIXER_SPEAKER, "Speaker", 0 }, /* fallback */ | ||
1255 | { SOUND_MIXER_LINE, "Line", 0 }, | 1257 | { SOUND_MIXER_LINE, "Line", 0 }, |
1256 | { SOUND_MIXER_MIC, "Mic", 0 }, | 1258 | { SOUND_MIXER_MIC, "Mic", 0 }, |
1257 | { SOUND_MIXER_CD, "CD", 0 }, | 1259 | { SOUND_MIXER_CD, "CD", 0 }, |
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index c69c60b2a48a..6884ae031f6f 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -435,6 +435,7 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, | |||
435 | return; | 435 | return; |
436 | } | 436 | } |
437 | snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state)); | 437 | snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state)); |
438 | snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid)); | ||
438 | snd_iprintf(buffer, "trigger_time: %ld.%09ld\n", | 439 | snd_iprintf(buffer, "trigger_time: %ld.%09ld\n", |
439 | status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_nsec); | 440 | status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_nsec); |
440 | snd_iprintf(buffer, "tstamp : %ld.%09ld\n", | 441 | snd_iprintf(buffer, "tstamp : %ld.%09ld\n", |
@@ -809,7 +810,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, | |||
809 | card = pcm->card; | 810 | card = pcm->card; |
810 | read_lock(&card->ctl_files_rwlock); | 811 | read_lock(&card->ctl_files_rwlock); |
811 | list_for_each_entry(kctl, &card->ctl_files, list) { | 812 | list_for_each_entry(kctl, &card->ctl_files, list) { |
812 | if (kctl->pid == current->pid) { | 813 | if (kctl->pid == task_pid(current)) { |
813 | prefer_subdevice = kctl->prefer_pcm_subdevice; | 814 | prefer_subdevice = kctl->prefer_pcm_subdevice; |
814 | if (prefer_subdevice != -1) | 815 | if (prefer_subdevice != -1) |
815 | break; | 816 | break; |
@@ -900,6 +901,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, | |||
900 | substream->private_data = pcm->private_data; | 901 | substream->private_data = pcm->private_data; |
901 | substream->ref_count = 1; | 902 | substream->ref_count = 1; |
902 | substream->f_flags = file->f_flags; | 903 | substream->f_flags = file->f_flags; |
904 | substream->pid = get_pid(task_pid(current)); | ||
903 | pstr->substream_opened++; | 905 | pstr->substream_opened++; |
904 | *rsubstream = substream; | 906 | *rsubstream = substream; |
905 | return 0; | 907 | return 0; |
@@ -921,6 +923,8 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream) | |||
921 | kfree(runtime->hw_constraints.rules); | 923 | kfree(runtime->hw_constraints.rules); |
922 | kfree(runtime); | 924 | kfree(runtime); |
923 | substream->runtime = NULL; | 925 | substream->runtime = NULL; |
926 | put_pid(substream->pid); | ||
927 | substream->pid = NULL; | ||
924 | substream->pstr->substream_opened--; | 928 | substream->pstr->substream_opened--; |
925 | } | 929 | } |
926 | 930 | ||
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index ab73edf2c89a..29ab46a12e11 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/time.h> | 26 | #include <linux/time.h> |
27 | #include <linux/pm_qos_params.h> | 27 | #include <linux/pm_qos_params.h> |
28 | #include <linux/uio.h> | 28 | #include <linux/uio.h> |
29 | #include <linux/dma-mapping.h> | ||
29 | #include <sound/core.h> | 30 | #include <sound/core.h> |
30 | #include <sound/control.h> | 31 | #include <sound/control.h> |
31 | #include <sound/info.h> | 32 | #include <sound/info.h> |
@@ -3061,6 +3062,27 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file | |||
3061 | } | 3062 | } |
3062 | #endif /* coherent mmap */ | 3063 | #endif /* coherent mmap */ |
3063 | 3064 | ||
3065 | static inline struct page * | ||
3066 | snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs) | ||
3067 | { | ||
3068 | void *vaddr = substream->runtime->dma_area + ofs; | ||
3069 | #if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT) | ||
3070 | if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) | ||
3071 | return virt_to_page(CAC_ADDR(vaddr)); | ||
3072 | #endif | ||
3073 | #if defined(CONFIG_PPC32) && defined(CONFIG_NOT_COHERENT_CACHE) | ||
3074 | if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) { | ||
3075 | dma_addr_t addr = substream->runtime->dma_addr + ofs; | ||
3076 | addr -= get_dma_offset(substream->dma_buffer.dev.dev); | ||
3077 | /* assume dma_handle set via pfn_to_phys() in | ||
3078 | * mm/dma-noncoherent.c | ||
3079 | */ | ||
3080 | return pfn_to_page(addr >> PAGE_SHIFT); | ||
3081 | } | ||
3082 | #endif | ||
3083 | return virt_to_page(vaddr); | ||
3084 | } | ||
3085 | |||
3064 | /* | 3086 | /* |
3065 | * fault callback for mmapping a RAM page | 3087 | * fault callback for mmapping a RAM page |
3066 | */ | 3088 | */ |
@@ -3071,7 +3093,6 @@ static int snd_pcm_mmap_data_fault(struct vm_area_struct *area, | |||
3071 | struct snd_pcm_runtime *runtime; | 3093 | struct snd_pcm_runtime *runtime; |
3072 | unsigned long offset; | 3094 | unsigned long offset; |
3073 | struct page * page; | 3095 | struct page * page; |
3074 | void *vaddr; | ||
3075 | size_t dma_bytes; | 3096 | size_t dma_bytes; |
3076 | 3097 | ||
3077 | if (substream == NULL) | 3098 | if (substream == NULL) |
@@ -3081,36 +3102,53 @@ static int snd_pcm_mmap_data_fault(struct vm_area_struct *area, | |||
3081 | dma_bytes = PAGE_ALIGN(runtime->dma_bytes); | 3102 | dma_bytes = PAGE_ALIGN(runtime->dma_bytes); |
3082 | if (offset > dma_bytes - PAGE_SIZE) | 3103 | if (offset > dma_bytes - PAGE_SIZE) |
3083 | return VM_FAULT_SIGBUS; | 3104 | return VM_FAULT_SIGBUS; |
3084 | if (substream->ops->page) { | 3105 | if (substream->ops->page) |
3085 | page = substream->ops->page(substream, offset); | 3106 | page = substream->ops->page(substream, offset); |
3086 | if (!page) | 3107 | else |
3087 | return VM_FAULT_SIGBUS; | 3108 | page = snd_pcm_default_page_ops(substream, offset); |
3088 | } else { | 3109 | if (!page) |
3089 | vaddr = runtime->dma_area + offset; | 3110 | return VM_FAULT_SIGBUS; |
3090 | page = virt_to_page(vaddr); | ||
3091 | } | ||
3092 | get_page(page); | 3111 | get_page(page); |
3093 | vmf->page = page; | 3112 | vmf->page = page; |
3094 | return 0; | 3113 | return 0; |
3095 | } | 3114 | } |
3096 | 3115 | ||
3097 | static const struct vm_operations_struct snd_pcm_vm_ops_data = | 3116 | static const struct vm_operations_struct snd_pcm_vm_ops_data = { |
3098 | { | 3117 | .open = snd_pcm_mmap_data_open, |
3118 | .close = snd_pcm_mmap_data_close, | ||
3119 | }; | ||
3120 | |||
3121 | static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = { | ||
3099 | .open = snd_pcm_mmap_data_open, | 3122 | .open = snd_pcm_mmap_data_open, |
3100 | .close = snd_pcm_mmap_data_close, | 3123 | .close = snd_pcm_mmap_data_close, |
3101 | .fault = snd_pcm_mmap_data_fault, | 3124 | .fault = snd_pcm_mmap_data_fault, |
3102 | }; | 3125 | }; |
3103 | 3126 | ||
3127 | #ifndef ARCH_HAS_DMA_MMAP_COHERENT | ||
3128 | /* This should be defined / handled globally! */ | ||
3129 | #ifdef CONFIG_ARM | ||
3130 | #define ARCH_HAS_DMA_MMAP_COHERENT | ||
3131 | #endif | ||
3132 | #endif | ||
3133 | |||
3104 | /* | 3134 | /* |
3105 | * mmap the DMA buffer on RAM | 3135 | * mmap the DMA buffer on RAM |
3106 | */ | 3136 | */ |
3107 | static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, | 3137 | static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, |
3108 | struct vm_area_struct *area) | 3138 | struct vm_area_struct *area) |
3109 | { | 3139 | { |
3110 | area->vm_ops = &snd_pcm_vm_ops_data; | ||
3111 | area->vm_private_data = substream; | ||
3112 | area->vm_flags |= VM_RESERVED; | 3140 | area->vm_flags |= VM_RESERVED; |
3113 | atomic_inc(&substream->mmap_count); | 3141 | #ifdef ARCH_HAS_DMA_MMAP_COHERENT |
3142 | if (!substream->ops->page && | ||
3143 | substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) | ||
3144 | return dma_mmap_coherent(substream->dma_buffer.dev.dev, | ||
3145 | area, | ||
3146 | substream->runtime->dma_area, | ||
3147 | substream->runtime->dma_addr, | ||
3148 | area->vm_end - area->vm_start); | ||
3149 | #endif /* ARCH_HAS_DMA_MMAP_COHERENT */ | ||
3150 | /* mmap with fault handler */ | ||
3151 | area->vm_ops = &snd_pcm_vm_ops_data_fault; | ||
3114 | return 0; | 3152 | return 0; |
3115 | } | 3153 | } |
3116 | 3154 | ||
@@ -3118,12 +3156,6 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, | |||
3118 | * mmap the DMA buffer on I/O memory area | 3156 | * mmap the DMA buffer on I/O memory area |
3119 | */ | 3157 | */ |
3120 | #if SNDRV_PCM_INFO_MMAP_IOMEM | 3158 | #if SNDRV_PCM_INFO_MMAP_IOMEM |
3121 | static const struct vm_operations_struct snd_pcm_vm_ops_data_mmio = | ||
3122 | { | ||
3123 | .open = snd_pcm_mmap_data_open, | ||
3124 | .close = snd_pcm_mmap_data_close, | ||
3125 | }; | ||
3126 | |||
3127 | int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, | 3159 | int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, |
3128 | struct vm_area_struct *area) | 3160 | struct vm_area_struct *area) |
3129 | { | 3161 | { |
@@ -3133,8 +3165,6 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, | |||
3133 | #ifdef pgprot_noncached | 3165 | #ifdef pgprot_noncached |
3134 | area->vm_page_prot = pgprot_noncached(area->vm_page_prot); | 3166 | area->vm_page_prot = pgprot_noncached(area->vm_page_prot); |
3135 | #endif | 3167 | #endif |
3136 | area->vm_ops = &snd_pcm_vm_ops_data_mmio; | ||
3137 | area->vm_private_data = substream; | ||
3138 | area->vm_flags |= VM_IO; | 3168 | area->vm_flags |= VM_IO; |
3139 | size = area->vm_end - area->vm_start; | 3169 | size = area->vm_end - area->vm_start; |
3140 | offset = area->vm_pgoff << PAGE_SHIFT; | 3170 | offset = area->vm_pgoff << PAGE_SHIFT; |
@@ -3142,7 +3172,6 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, | |||
3142 | (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, | 3172 | (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, |
3143 | size, area->vm_page_prot)) | 3173 | size, area->vm_page_prot)) |
3144 | return -EAGAIN; | 3174 | return -EAGAIN; |
3145 | atomic_inc(&substream->mmap_count); | ||
3146 | return 0; | 3175 | return 0; |
3147 | } | 3176 | } |
3148 | 3177 | ||
@@ -3159,6 +3188,7 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, | |||
3159 | long size; | 3188 | long size; |
3160 | unsigned long offset; | 3189 | unsigned long offset; |
3161 | size_t dma_bytes; | 3190 | size_t dma_bytes; |
3191 | int err; | ||
3162 | 3192 | ||
3163 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 3193 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
3164 | if (!(area->vm_flags & (VM_WRITE|VM_READ))) | 3194 | if (!(area->vm_flags & (VM_WRITE|VM_READ))) |
@@ -3183,10 +3213,15 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, | |||
3183 | if (offset > dma_bytes - size) | 3213 | if (offset > dma_bytes - size) |
3184 | return -EINVAL; | 3214 | return -EINVAL; |
3185 | 3215 | ||
3216 | area->vm_ops = &snd_pcm_vm_ops_data; | ||
3217 | area->vm_private_data = substream; | ||
3186 | if (substream->ops->mmap) | 3218 | if (substream->ops->mmap) |
3187 | return substream->ops->mmap(substream, area); | 3219 | err = substream->ops->mmap(substream, area); |
3188 | else | 3220 | else |
3189 | return snd_pcm_default_mmap(substream, area); | 3221 | err = snd_pcm_default_mmap(substream, area); |
3222 | if (!err) | ||
3223 | atomic_inc(&substream->mmap_count); | ||
3224 | return err; | ||
3190 | } | 3225 | } |
3191 | 3226 | ||
3192 | EXPORT_SYMBOL(snd_pcm_mmap_data); | 3227 | EXPORT_SYMBOL(snd_pcm_mmap_data); |
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 70d6f25ba526..2f766123b158 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c | |||
@@ -242,8 +242,6 @@ static int assign_substream(struct snd_rawmidi *rmidi, int subdevice, | |||
242 | return -ENXIO; | 242 | return -ENXIO; |
243 | if (subdevice >= 0 && subdevice >= s->substream_count) | 243 | if (subdevice >= 0 && subdevice >= s->substream_count) |
244 | return -ENODEV; | 244 | return -ENODEV; |
245 | if (s->substream_opened >= s->substream_count) | ||
246 | return -EAGAIN; | ||
247 | 245 | ||
248 | list_for_each_entry(substream, &s->substreams, list) { | 246 | list_for_each_entry(substream, &s->substreams, list) { |
249 | if (substream->opened) { | 247 | if (substream->opened) { |
@@ -280,9 +278,10 @@ static int open_substream(struct snd_rawmidi *rmidi, | |||
280 | substream->active_sensing = 0; | 278 | substream->active_sensing = 0; |
281 | if (mode & SNDRV_RAWMIDI_LFLG_APPEND) | 279 | if (mode & SNDRV_RAWMIDI_LFLG_APPEND) |
282 | substream->append = 1; | 280 | substream->append = 1; |
281 | substream->pid = get_pid(task_pid(current)); | ||
282 | rmidi->streams[substream->stream].substream_opened++; | ||
283 | } | 283 | } |
284 | substream->use_count++; | 284 | substream->use_count++; |
285 | rmidi->streams[substream->stream].substream_opened++; | ||
286 | return 0; | 285 | return 0; |
287 | } | 286 | } |
288 | 287 | ||
@@ -413,7 +412,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) | |||
413 | subdevice = -1; | 412 | subdevice = -1; |
414 | read_lock(&card->ctl_files_rwlock); | 413 | read_lock(&card->ctl_files_rwlock); |
415 | list_for_each_entry(kctl, &card->ctl_files, list) { | 414 | list_for_each_entry(kctl, &card->ctl_files, list) { |
416 | if (kctl->pid == current->pid) { | 415 | if (kctl->pid == task_pid(current)) { |
417 | subdevice = kctl->prefer_rawmidi_subdevice; | 416 | subdevice = kctl->prefer_rawmidi_subdevice; |
418 | if (subdevice != -1) | 417 | if (subdevice != -1) |
419 | break; | 418 | break; |
@@ -466,7 +465,6 @@ static void close_substream(struct snd_rawmidi *rmidi, | |||
466 | struct snd_rawmidi_substream *substream, | 465 | struct snd_rawmidi_substream *substream, |
467 | int cleanup) | 466 | int cleanup) |
468 | { | 467 | { |
469 | rmidi->streams[substream->stream].substream_opened--; | ||
470 | if (--substream->use_count) | 468 | if (--substream->use_count) |
471 | return; | 469 | return; |
472 | 470 | ||
@@ -491,6 +489,9 @@ static void close_substream(struct snd_rawmidi *rmidi, | |||
491 | snd_rawmidi_runtime_free(substream); | 489 | snd_rawmidi_runtime_free(substream); |
492 | substream->opened = 0; | 490 | substream->opened = 0; |
493 | substream->append = 0; | 491 | substream->append = 0; |
492 | put_pid(substream->pid); | ||
493 | substream->pid = NULL; | ||
494 | rmidi->streams[substream->stream].substream_opened--; | ||
494 | } | 495 | } |
495 | 496 | ||
496 | static void rawmidi_release_priv(struct snd_rawmidi_file *rfile) | 497 | static void rawmidi_release_priv(struct snd_rawmidi_file *rfile) |
@@ -1338,6 +1339,9 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, | |||
1338 | substream->number, | 1339 | substream->number, |
1339 | (unsigned long) substream->bytes); | 1340 | (unsigned long) substream->bytes); |
1340 | if (substream->opened) { | 1341 | if (substream->opened) { |
1342 | snd_iprintf(buffer, | ||
1343 | " Owner PID : %d\n", | ||
1344 | pid_vnr(substream->pid)); | ||
1341 | runtime = substream->runtime; | 1345 | runtime = substream->runtime; |
1342 | snd_iprintf(buffer, | 1346 | snd_iprintf(buffer, |
1343 | " Mode : %s\n" | 1347 | " Mode : %s\n" |
@@ -1359,6 +1363,9 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, | |||
1359 | substream->number, | 1363 | substream->number, |
1360 | (unsigned long) substream->bytes); | 1364 | (unsigned long) substream->bytes); |
1361 | if (substream->opened) { | 1365 | if (substream->opened) { |
1366 | snd_iprintf(buffer, | ||
1367 | " Owner PID : %d\n", | ||
1368 | pid_vnr(substream->pid)); | ||
1362 | runtime = substream->runtime; | 1369 | runtime = substream->runtime; |
1363 | snd_iprintf(buffer, | 1370 | snd_iprintf(buffer, |
1364 | " Buffer size : %lu\n" | 1371 | " Buffer size : %lu\n" |