add free dma buffer function
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#define MCEXEC_UP_LOAD_SYSCALL 0x30a02905
|
||||
|
||||
#define MCEXEC_UP_PREPARE_DMA 0x30a02910
|
||||
#define MCEXEC_UP_FREE_DMA 0x30a02911
|
||||
|
||||
struct program_transfer {
|
||||
unsigned long dest;
|
||||
@@ -72,4 +73,13 @@ struct syscall_ret_desc {
|
||||
unsigned long size;
|
||||
};
|
||||
|
||||
struct prepare_dma_desc {
|
||||
unsigned long size;
|
||||
unsigned long pa;
|
||||
};
|
||||
struct free_dma_desc {
|
||||
unsigned long pa;
|
||||
unsigned long size;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/delay.h>
|
||||
#include <asm/msr.h>
|
||||
@@ -289,24 +290,56 @@ int mcexec_wait_syscall(aal_os_t os, struct syscall_wait_desc *__user req)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long mcexec_pin_region(aal_os_t os, unsigned long *__user uaddress)
|
||||
long mcexec_pin_region(aal_os_t os, unsigned long *__user arg)
|
||||
{
|
||||
struct prepare_dma_desc desc;
|
||||
int pin_shift = 16;
|
||||
int order;
|
||||
unsigned long a;
|
||||
|
||||
a = __get_free_pages(GFP_KERNEL, pin_shift - PAGE_SHIFT);
|
||||
if (copy_from_user(&desc, arg, sizeof(struct prepare_dma_desc))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
order = pin_shift - PAGE_SHIFT;
|
||||
if(desc.size > 0){
|
||||
order = get_order (desc.size);
|
||||
}
|
||||
|
||||
a = __get_free_pages(GFP_KERNEL, order);
|
||||
if (!a) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
a = virt_to_phys((void *)a);
|
||||
|
||||
if (copy_to_user(uaddress, &a, sizeof(unsigned long))) {
|
||||
if (copy_to_user((void*)desc.pa, &a, sizeof(unsigned long))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long mcexec_free_region(aal_os_t os, unsigned long *__user arg)
|
||||
{
|
||||
struct free_dma_desc desc;
|
||||
int pin_shift = 16;
|
||||
int order;
|
||||
|
||||
if (copy_from_user(&desc, arg, sizeof(struct free_dma_desc))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
order = pin_shift - PAGE_SHIFT;
|
||||
if(desc.size > 0){
|
||||
order = get_order (desc.size);
|
||||
}
|
||||
|
||||
if(desc.pa > 0){
|
||||
free_pages((unsigned long)phys_to_virt(desc.pa), order);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long mcexec_load_syscall(aal_os_t os, struct syscall_load_desc *__user arg)
|
||||
{
|
||||
struct syscall_load_desc desc;
|
||||
@@ -463,6 +496,8 @@ long __mcctrl_control(aal_os_t os, unsigned int req, unsigned long arg)
|
||||
case MCEXEC_UP_PREPARE_DMA:
|
||||
return mcexec_pin_region(os, (unsigned long *)arg);
|
||||
|
||||
case MCEXEC_UP_FREE_DMA:
|
||||
return mcexec_free_region(os, (unsigned long *)arg);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ static struct aal_os_user_call_handler mcctrl_uchs[] = {
|
||||
{ .request = MCEXEC_UP_RET_SYSCALL, .func = mcctrl_ioctl },
|
||||
{ .request = MCEXEC_UP_LOAD_SYSCALL, .func = mcctrl_ioctl },
|
||||
{ .request = MCEXEC_UP_PREPARE_DMA, .func = mcctrl_ioctl },
|
||||
{ .request = MCEXEC_UP_FREE_DMA, .func = mcctrl_ioctl },
|
||||
};
|
||||
|
||||
static struct aal_os_user_call mcctrl_uc = {
|
||||
|
||||
Reference in New Issue
Block a user