aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2007-12-13 10:15:00 -0500
committerJaroslav Kysela <perex@perex.cz>2008-01-31 11:29:32 -0500
commit3ad5afcd5fa91a00a9a19b9e39958acd9a3a25d7 (patch)
tree6e0af07b1af4d67c2bf8e67080b22d4dd3716e92
parentbba8dee78218752c6457d0dac9f5faa17755ac95 (diff)
[ALSA] alsa: nopage
Convert ALSA from nopage to fault. Switch from OOM to SIGBUS if the resource is not available. Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r--sound/core/pcm_native.c59
1 files changed, 25 insertions, 34 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index cdeae7c46e3..51294dd3a7a 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -3033,26 +3033,23 @@ static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait)
3033/* 3033/*
3034 * mmap status record 3034 * mmap status record
3035 */ 3035 */
3036static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area, 3036static int snd_pcm_mmap_status_fault(struct vm_area_struct *area,
3037 unsigned long address, int *type) 3037 struct vm_fault *vmf)
3038{ 3038{
3039 struct snd_pcm_substream *substream = area->vm_private_data; 3039 struct snd_pcm_substream *substream = area->vm_private_data;
3040 struct snd_pcm_runtime *runtime; 3040 struct snd_pcm_runtime *runtime;
3041 struct page * page;
3042 3041
3043 if (substream == NULL) 3042 if (substream == NULL)
3044 return NOPAGE_SIGBUS; 3043 return VM_FAULT_SIGBUS;
3045 runtime = substream->runtime; 3044 runtime = substream->runtime;
3046 page = virt_to_page(runtime->status); 3045 vmf->page = virt_to_page(runtime->status);
3047 get_page(page); 3046 get_page(vmf->page);
3048 if (type) 3047 return 0;
3049 *type = VM_FAULT_MINOR;
3050 return page;
3051} 3048}
3052 3049
3053static struct vm_operations_struct snd_pcm_vm_ops_status = 3050static struct vm_operations_struct snd_pcm_vm_ops_status =
3054{ 3051{
3055 .nopage = snd_pcm_mmap_status_nopage, 3052 .fault = snd_pcm_mmap_status_fault,
3056}; 3053};
3057 3054
3058static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file, 3055static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file,
@@ -3076,26 +3073,23 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file
3076/* 3073/*
3077 * mmap control record 3074 * mmap control record
3078 */ 3075 */
3079static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area, 3076static int snd_pcm_mmap_control_fault(struct vm_area_struct *area,
3080 unsigned long address, int *type) 3077 struct vm_fault *vmf)
3081{ 3078{
3082 struct snd_pcm_substream *substream = area->vm_private_data; 3079 struct snd_pcm_substream *substream = area->vm_private_data;
3083 struct snd_pcm_runtime *runtime; 3080 struct snd_pcm_runtime *runtime;
3084 struct page * page;
3085 3081
3086 if (substream == NULL) 3082 if (substream == NULL)
3087 return NOPAGE_SIGBUS; 3083 return VM_FAULT_SIGBUS;
3088 runtime = substream->runtime; 3084 runtime = substream->runtime;
3089 page = virt_to_page(runtime->control); 3085 vmf->page = virt_to_page(runtime->control);
3090 get_page(page); 3086 get_page(vmf->page);
3091 if (type) 3087 return 0;
3092 *type = VM_FAULT_MINOR;
3093 return page;
3094} 3088}
3095 3089
3096static struct vm_operations_struct snd_pcm_vm_ops_control = 3090static struct vm_operations_struct snd_pcm_vm_ops_control =
3097{ 3091{
3098 .nopage = snd_pcm_mmap_control_nopage, 3092 .fault = snd_pcm_mmap_control_fault,
3099}; 3093};
3100 3094
3101static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file, 3095static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file,
@@ -3132,10 +3126,10 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file
3132#endif /* coherent mmap */ 3126#endif /* coherent mmap */
3133 3127
3134/* 3128/*
3135 * nopage callback for mmapping a RAM page 3129 * fault callback for mmapping a RAM page
3136 */ 3130 */
3137static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area, 3131static int snd_pcm_mmap_data_fault(struct vm_area_struct *area,
3138 unsigned long address, int *type) 3132 struct vm_fault *vmf)
3139{ 3133{
3140 struct snd_pcm_substream *substream = area->vm_private_data; 3134 struct snd_pcm_substream *substream = area->vm_private_data;
3141 struct snd_pcm_runtime *runtime; 3135 struct snd_pcm_runtime *runtime;
@@ -3145,33 +3139,30 @@ static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area,
3145 size_t dma_bytes; 3139 size_t dma_bytes;
3146 3140
3147 if (substream == NULL) 3141 if (substream == NULL)
3148 return NOPAGE_SIGBUS; 3142 return VM_FAULT_SIGBUS;
3149 runtime = substream->runtime; 3143 runtime = substream->runtime;
3150 offset = area->vm_pgoff << PAGE_SHIFT; 3144 offset = vmf->pgoff << PAGE_SHIFT;
3151 offset += address - area->vm_start;
3152 snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_SIGBUS);
3153 dma_bytes = PAGE_ALIGN(runtime->dma_bytes); 3145 dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
3154 if (offset > dma_bytes - PAGE_SIZE) 3146 if (offset > dma_bytes - PAGE_SIZE)
3155 return NOPAGE_SIGBUS; 3147 return VM_FAULT_SIGBUS;
3156 if (substream->ops->page) { 3148 if (substream->ops->page) {
3157 page = substream->ops->page(substream, offset); 3149 page = substream->ops->page(substream, offset);
3158 if (! page) 3150 if (!page)
3159 return NOPAGE_OOM; /* XXX: is this really due to OOM? */ 3151 return VM_FAULT_SIGBUS;
3160 } else { 3152 } else {
3161 vaddr = runtime->dma_area + offset; 3153 vaddr = runtime->dma_area + offset;
3162 page = virt_to_page(vaddr); 3154 page = virt_to_page(vaddr);
3163 } 3155 }
3164 get_page(page); 3156 get_page(page);
3165 if (type) 3157 vmf->page = page;
3166 *type = VM_FAULT_MINOR; 3158 return 0;
3167 return page;
3168} 3159}
3169 3160
3170static struct vm_operations_struct snd_pcm_vm_ops_data = 3161static struct vm_operations_struct snd_pcm_vm_ops_data =
3171{ 3162{
3172 .open = snd_pcm_mmap_data_open, 3163 .open = snd_pcm_mmap_data_open,
3173 .close = snd_pcm_mmap_data_close, 3164 .close = snd_pcm_mmap_data_close,
3174 .nopage = snd_pcm_mmap_data_nopage, 3165 .fault = snd_pcm_mmap_data_fault,
3175}; 3166};
3176 3167
3177/* 3168/*