diff options
author | Nick Piggin <npiggin@suse.de> | 2007-12-13 10:15:00 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 11:29:32 -0500 |
commit | 3ad5afcd5fa91a00a9a19b9e39958acd9a3a25d7 (patch) | |
tree | 6e0af07b1af4d67c2bf8e67080b22d4dd3716e92 | |
parent | bba8dee78218752c6457d0dac9f5faa17755ac95 (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.c | 59 |
1 files changed, 25 insertions, 34 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index cdeae7c46e3b..51294dd3a7a3 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 | */ |
3036 | static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area, | 3036 | static 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 | ||
3053 | static struct vm_operations_struct snd_pcm_vm_ops_status = | 3050 | static 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 | ||
3058 | static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file, | 3055 | static 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 | */ |
3079 | static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area, | 3076 | static 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 | ||
3096 | static struct vm_operations_struct snd_pcm_vm_ops_control = | 3090 | static 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 | ||
3101 | static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file, | 3095 | static 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 | */ |
3137 | static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area, | 3131 | static 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 | ||
3170 | static struct vm_operations_struct snd_pcm_vm_ops_data = | 3161 | static 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 | /* |