From 9849cf57b1dafffba54a6a73655592ccabe35eaa Mon Sep 17 00:00:00 2001 From: simin Date: Thu, 13 Dec 2012 17:47:36 +0900 Subject: [PATCH] add free dma buffer function --- linux/include/uprotocol.h | 10 ++++++++++ linux/mod_mcctrl/control.c | 41 +++++++++++++++++++++++++++++++++++--- linux/mod_mcctrl/driver.c | 1 + 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/linux/include/uprotocol.h b/linux/include/uprotocol.h index 6076a501..761507d5 100644 --- a/linux/include/uprotocol.h +++ b/linux/include/uprotocol.h @@ -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 diff --git a/linux/mod_mcctrl/control.c b/linux/mod_mcctrl/control.c index 863061ea..6080fbf2 100644 --- a/linux/mod_mcctrl/control.c +++ b/linux/mod_mcctrl/control.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -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; } diff --git a/linux/mod_mcctrl/driver.c b/linux/mod_mcctrl/driver.c index f4092abb..8f3bf9c5 100644 --- a/linux/mod_mcctrl/driver.c +++ b/linux/mod_mcctrl/driver.c @@ -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 = {