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>
This commit is contained in:
Nick Piggin 2007-12-13 16:15:00 +01:00 коммит произвёл Jaroslav Kysela
Родитель bba8dee782
Коммит 3ad5afcd5f
1 изменённых файлов: 25 добавлений и 34 удалений

Просмотреть файл

@ -3033,26 +3033,23 @@ static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait)
/*
* mmap status record
*/
static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area,
unsigned long address, int *type)
static int snd_pcm_mmap_status_fault(struct vm_area_struct *area,
struct vm_fault *vmf)
{
struct snd_pcm_substream *substream = area->vm_private_data;
struct snd_pcm_runtime *runtime;
struct page * page;
if (substream == NULL)
return NOPAGE_SIGBUS;
return VM_FAULT_SIGBUS;
runtime = substream->runtime;
page = virt_to_page(runtime->status);
get_page(page);
if (type)
*type = VM_FAULT_MINOR;
return page;
vmf->page = virt_to_page(runtime->status);
get_page(vmf->page);
return 0;
}
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,
@ -3076,26 +3073,23 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file
/*
* mmap control record
*/
static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area,
unsigned long address, int *type)
static int snd_pcm_mmap_control_fault(struct vm_area_struct *area,
struct vm_fault *vmf)
{
struct snd_pcm_substream *substream = area->vm_private_data;
struct snd_pcm_runtime *runtime;
struct page * page;
if (substream == NULL)
return NOPAGE_SIGBUS;
return VM_FAULT_SIGBUS;
runtime = substream->runtime;
page = virt_to_page(runtime->control);
get_page(page);
if (type)
*type = VM_FAULT_MINOR;
return page;
vmf->page = virt_to_page(runtime->control);
get_page(vmf->page);
return 0;
}
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,
@ -3132,10 +3126,10 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file
#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,
unsigned long address, int *type)
static int snd_pcm_mmap_data_fault(struct vm_area_struct *area,
struct vm_fault *vmf)
{
struct snd_pcm_substream *substream = area->vm_private_data;
struct snd_pcm_runtime *runtime;
@ -3145,33 +3139,30 @@ static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area,
size_t dma_bytes;
if (substream == NULL)
return NOPAGE_SIGBUS;
return VM_FAULT_SIGBUS;
runtime = substream->runtime;
offset = area->vm_pgoff << PAGE_SHIFT;
offset += address - area->vm_start;
snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_SIGBUS);
offset = vmf->pgoff << PAGE_SHIFT;
dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
if (offset > dma_bytes - PAGE_SIZE)
return NOPAGE_SIGBUS;
return VM_FAULT_SIGBUS;
if (substream->ops->page) {
page = substream->ops->page(substream, offset);
if (! page)
return NOPAGE_OOM; /* XXX: is this really due to OOM? */
if (!page)
return VM_FAULT_SIGBUS;
} else {
vaddr = runtime->dma_area + offset;
page = virt_to_page(vaddr);
}
get_page(page);
if (type)
*type = VM_FAULT_MINOR;
return page;
vmf->page = page;
return 0;
}
static struct vm_operations_struct snd_pcm_vm_ops_data =
{
.open = snd_pcm_mmap_data_open,
.close = snd_pcm_mmap_data_close,
.nopage = snd_pcm_mmap_data_nopage,
.fault = snd_pcm_mmap_data_fault,
};
/*