Commit 3ad5afcd authored by Nick Piggin's avatar Nick Piggin Committed by Jaroslav Kysela

[ALSA] alsa: nopage

Convert ALSA from nopage to fault.
Switch from OOM to SIGBUS if the resource is not available.
Signed-off-by: default avatarNick Piggin <npiggin@suse.de>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
parent bba8dee7
...@@ -3033,26 +3033,23 @@ static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait) ...@@ -3033,26 +3033,23 @@ static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait)
/* /*
* mmap status record * mmap status record
*/ */
static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area, static int snd_pcm_mmap_status_fault(struct vm_area_struct *area,
unsigned long address, int *type) struct vm_fault *vmf)
{ {
struct snd_pcm_substream *substream = area->vm_private_data; struct snd_pcm_substream *substream = area->vm_private_data;
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
struct page * page;
if (substream == NULL) if (substream == NULL)
return NOPAGE_SIGBUS; return VM_FAULT_SIGBUS;
runtime = substream->runtime; runtime = substream->runtime;
page = virt_to_page(runtime->status); vmf->page = virt_to_page(runtime->status);
get_page(page); get_page(vmf->page);
if (type) return 0;
*type = VM_FAULT_MINOR;
return page;
} }
static struct vm_operations_struct snd_pcm_vm_ops_status = static struct vm_operations_struct snd_pcm_vm_ops_status =
{ {
.nopage = snd_pcm_mmap_status_nopage, .fault = snd_pcm_mmap_status_fault,
}; };
static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file, 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,26 +3073,23 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file
/* /*
* mmap control record * mmap control record
*/ */
static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area, static int snd_pcm_mmap_control_fault(struct vm_area_struct *area,
unsigned long address, int *type) struct vm_fault *vmf)
{ {
struct snd_pcm_substream *substream = area->vm_private_data; struct snd_pcm_substream *substream = area->vm_private_data;
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
struct page * page;
if (substream == NULL) if (substream == NULL)
return NOPAGE_SIGBUS; return VM_FAULT_SIGBUS;
runtime = substream->runtime; runtime = substream->runtime;
page = virt_to_page(runtime->control); vmf->page = virt_to_page(runtime->control);
get_page(page); get_page(vmf->page);
if (type) return 0;
*type = VM_FAULT_MINOR;
return page;
} }
static struct vm_operations_struct snd_pcm_vm_ops_control = static struct vm_operations_struct snd_pcm_vm_ops_control =
{ {
.nopage = snd_pcm_mmap_control_nopage, .fault = snd_pcm_mmap_control_fault,
}; };
static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file, 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,10 +3126,10 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file
#endif /* coherent mmap */ #endif /* coherent mmap */
/* /*
* nopage callback for mmapping a RAM page * fault callback for mmapping a RAM page
*/ */
static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area, static int snd_pcm_mmap_data_fault(struct vm_area_struct *area,
unsigned long address, int *type) struct vm_fault *vmf)
{ {
struct snd_pcm_substream *substream = area->vm_private_data; struct snd_pcm_substream *substream = area->vm_private_data;
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
...@@ -3145,33 +3139,30 @@ static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area, ...@@ -3145,33 +3139,30 @@ static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area,
size_t dma_bytes; size_t dma_bytes;
if (substream == NULL) if (substream == NULL)
return NOPAGE_SIGBUS; return VM_FAULT_SIGBUS;
runtime = substream->runtime; runtime = substream->runtime;
offset = area->vm_pgoff << PAGE_SHIFT; offset = vmf->pgoff << PAGE_SHIFT;
offset += address - area->vm_start;
snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_SIGBUS);
dma_bytes = PAGE_ALIGN(runtime->dma_bytes); dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
if (offset > dma_bytes - PAGE_SIZE) if (offset > dma_bytes - PAGE_SIZE)
return NOPAGE_SIGBUS; return VM_FAULT_SIGBUS;
if (substream->ops->page) { if (substream->ops->page) {
page = substream->ops->page(substream, offset); page = substream->ops->page(substream, offset);
if (! page) if (!page)
return NOPAGE_OOM; /* XXX: is this really due to OOM? */ return VM_FAULT_SIGBUS;
} else { } else {
vaddr = runtime->dma_area + offset; vaddr = runtime->dma_area + offset;
page = virt_to_page(vaddr); page = virt_to_page(vaddr);
} }
get_page(page); get_page(page);
if (type) vmf->page = page;
*type = VM_FAULT_MINOR; return 0;
return page;
} }
static struct vm_operations_struct snd_pcm_vm_ops_data = static struct vm_operations_struct snd_pcm_vm_ops_data =
{ {
.open = snd_pcm_mmap_data_open, .open = snd_pcm_mmap_data_open,
.close = snd_pcm_mmap_data_close, .close = snd_pcm_mmap_data_close,
.nopage = snd_pcm_mmap_data_nopage, .fault = snd_pcm_mmap_data_fault,
}; };
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment