From: SeokYeon Hwang Date: Fri, 12 Sep 2014 08:33:56 +0000 (+0900) Subject: brillcodec: introduce brillcodec version 3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a6149eb9e0cb359cc805444935e23ce578cc4afc;p=sdk%2Femulator%2Femulator-kernel.git brillcodec: introduce brillcodec version 3 Change-Id: Ie08b8b4ee8094ce20b9f80f52c72aadcd4f34df5 Signed-off-by: SeokYeon Hwang --- diff --git a/drivers/maru/maru_brillcodec.c b/drivers/maru/maru_brillcodec.c index 2d3dc37d9dd3..a406788b213e 100644 --- a/drivers/maru/maru_brillcodec.c +++ b/drivers/maru/maru_brillcodec.c @@ -49,27 +49,22 @@ #include #include - MODULE_DESCRIPTION("Virtual Codec Device Driver"); MODULE_AUTHOR("Kitae KIM ioaddr + CODEC_CMD_GET_CTX_FROM_QUEUE); + readl(maru_brill_codec->ioaddr + DEVICE_CMD_GET_CTX_FROM_QUEUE); DEBUG("read a value from device %x.\n", value); if (value) { context_flags[value] = 1; @@ -334,12 +336,13 @@ static int secure_device_memory(uint32_t ctx_id, uint32_t buf_size, return ret; } -static void release_device_memory(uint32_t mem_offset) +static int release_device_memory(uint32_t mem_offset) { struct device_mem *unit = NULL; enum block_size index = SMALL; struct memory_block *block = NULL; bool found = false; + int ret = 0; struct list_head *pos, *temp; @@ -352,7 +355,7 @@ static void release_device_memory(uint32_t mem_offset) } else { // error ERROR("invalid memory offsset. offset = 0x%x.\n", (uint32_t)mem_offset); - return; + return -2; } block = &maru_brill_codec->memory_blocks[index]; @@ -381,12 +384,16 @@ static void release_device_memory(uint32_t mem_offset) if (!found) { // can not enter here... ERROR("cannot find this memory block. offset = 0x%x.\n", (uint32_t)mem_offset); + ret = -1; } } else { // can not enter here... ERROR("there is not any using memory block.\n"); + ret = -1; } mutex_unlock(&block->access_mutex); + + return ret; } static void dispose_device_memory(uint32_t context_id) @@ -444,29 +451,29 @@ static void maru_brill_codec_info_cache(void) maru_brill_codec->codec_elem_cached = true; } -static long put_data_into_buffer(struct codec_buffer_id *opaque) { +static long put_data_into_buffer(struct ioctl_data *data) { long value = 0, ret = 0; uint32_t offset = 0; unsigned long flags; DEBUG("read data into small buffer\n"); - value = secure_device_memory(opaque->buffer_index, opaque->buffer_size, 0, &offset); + value = secure_device_memory(data->ctx_index, data->buffer_size, 0, &offset); if (value < 0) { DEBUG("failed to get available memory\n"); ret = -EINVAL; } else { - DEBUG("send a request to pop data from device. %d\n", opaque->buffer_index); + DEBUG("send a request to pop data from device. %d\n", data->ctx_index); ENTER_CRITICAL_SECTION(flags); writel((uint32_t)offset, - maru_brill_codec->ioaddr + CODEC_CMD_DEVICE_MEM_OFFSET); - writel((uint32_t)opaque->buffer_index, - maru_brill_codec->ioaddr + CODEC_CMD_GET_DATA_FROM_QUEUE); + maru_brill_codec->ioaddr + DEVICE_CMD_DEVICE_MEM_OFFSET); + writel((uint32_t)data->ctx_index, + maru_brill_codec->ioaddr + DEVICE_CMD_GET_DATA_FROM_QUEUE); LEAVE_CRITICAL_SECTION(flags); - opaque->buffer_size = offset; + data->mem_offset = offset; } /* 1 means that only an available buffer is left at the moment. @@ -480,14 +487,17 @@ static long put_data_into_buffer(struct codec_buffer_id *opaque) { return ret; } -static long maru_brill_codec_ioctl(struct file *file, - unsigned int cmd, +static long brillcodec_ioctl(struct file *file, + unsigned int request, unsigned long arg) { long value = 0, ret = 0; + int cmd = _IOC_NR(request); + DEBUG("%s ioctl cmd: %d\n", DEVICE_NAME, cmd); + switch (cmd) { - case CODEC_CMD_GET_VERSION: + case IOCTL_CMD_GET_VERSION: { DEBUG("%s version: %d\n", DEVICE_NAME, maru_brill_codec->version); @@ -497,7 +507,7 @@ static long maru_brill_codec_ioctl(struct file *file, } break; } - case CODEC_CMD_GET_ELEMENT: + case IOCTL_CMD_GET_ELEMENTS_SIZE: { uint32_t len = 0; unsigned long flags; @@ -506,7 +516,7 @@ static long maru_brill_codec_ioctl(struct file *file, ENTER_CRITICAL_SECTION(flags); if (!maru_brill_codec->codec_elem_cached) { - value = readl(maru_brill_codec->ioaddr + cmd); + value = readl(maru_brill_codec->ioaddr + DEVICE_CMD_GET_ELEMENT); if (value < 0) { ERROR("ioctl: failed to get elements. %d\n", (int)value); ret = -EINVAL; @@ -522,7 +532,7 @@ static long maru_brill_codec_ioctl(struct file *file, } break; } - case CODEC_CMD_GET_ELEMENT_DATA: + case IOCTL_CMD_GET_ELEMENTS: { void *codec_elem = NULL; uint32_t elem_len = maru_brill_codec->codec_elem.buf_size; @@ -539,11 +549,11 @@ static long maru_brill_codec_ioctl(struct file *file, } break; } - case CODEC_CMD_GET_CONTEXT_INDEX: + case IOCTL_CMD_GET_CONTEXT_INDEX: { DEBUG("request a device to get an index of codec context \n"); - value = readl(maru_brill_codec->ioaddr + cmd); + value = readl(maru_brill_codec->ioaddr + DEVICE_CMD_GET_CONTEXT_INDEX); if (value < 1 || value > (CODEC_CONTEXT_SIZE - 1)) { ERROR("ioctl: failed to get proper context. %d\n", (int)value); ret = -EINVAL; @@ -552,85 +562,64 @@ static long maru_brill_codec_ioctl(struct file *file, DEBUG("add context. ctx_id: %d\n", (int)value); context_add((uint32_t)file, value); - if (copy_to_user((void *)arg, &value, sizeof(int))) { - ERROR("ioctl: failed to copy data to user\n"); + if (copy_to_user((void *)arg, &value, sizeof(uint32_t))) { + ERROR("ioctl: failed to copy data to user.\n"); ret = -EIO; } } break; } - case CODEC_CMD_PUT_DATA_INTO_BUFFER: // for old plugins - { - struct codec_buffer_id opaque; - - if (copy_from_user(&opaque, (void *)arg, sizeof(struct codec_buffer_id))) { - ERROR("ioctl: failed to copy data from user\n"); - ret = -EIO; - break; - } - ret = put_data_into_buffer(&opaque); - if (ret < 0) { - ret = -EIO; - break; - } - - if (copy_to_user((void *)arg, &opaque, sizeof(struct codec_buffer_id))) { - ERROR("ioctl: failed to copy data to user.\n"); - ret = -EIO; - } - break; - } - case CODEC_CMD_SECURE_BUFFER: + case IOCTL_CMD_SECURE_BUFFER: { uint32_t offset = 0; - struct codec_buffer_id opaque; + struct ioctl_data opaque; DEBUG("read data into small buffer\n"); - if (copy_from_user(&opaque, (void *)arg, sizeof(struct codec_buffer_id))) { + if (copy_from_user(&opaque, (void *)arg, sizeof(struct ioctl_data))) { ERROR("ioctl: failed to copy data from user\n"); ret = -EIO; break; } - value = secure_device_memory(opaque.buffer_index, opaque.buffer_size, 0, &offset); + value = secure_device_memory(opaque.ctx_index, opaque.buffer_size, 0, &offset); if (value < 0) { DEBUG("failed to get available memory\n"); ret = -EINVAL; } else { - opaque.buffer_size = offset; - if (copy_to_user((void *)arg, &opaque, sizeof(struct codec_buffer_id))) { + opaque.mem_offset = offset; + if (copy_to_user((void *)arg, &opaque, sizeof(struct ioctl_data))) { ERROR("ioctl: failed to copy data to user.\n"); ret = -EIO; } } break; } - case CODEC_CMD_TRY_SECURE_BUFFER: + case IOCTL_CMD_TRY_SECURE_BUFFER: { uint32_t offset = 0; - struct codec_buffer_id opaque; + struct ioctl_data opaque; DEBUG("read data into small buffer\n"); - if (copy_from_user(&opaque, (void *)arg, sizeof(struct codec_buffer_id))) { + if (copy_from_user(&opaque, (void *)arg, sizeof(struct ioctl_data))) { ERROR("ioctl: failed to copy data from user\n"); ret = -EIO; break; } - value = secure_device_memory(opaque.buffer_index, opaque.buffer_size, 1, &offset); + value = secure_device_memory(opaque.ctx_index, opaque.buffer_size, 1, &offset); if (value < 0) { DEBUG("failed to get available memory\n"); ret = -EINVAL; } else { - opaque.buffer_size = offset; - if (copy_to_user((void *)arg, &opaque, sizeof(struct codec_buffer_id))) { + opaque.mem_offset = offset; + if (copy_to_user((void *)arg, &opaque, sizeof(struct ioctl_data))) { ERROR("ioctl: failed to copy data to user.\n"); ret = -EIO; } } break; } - case CODEC_CMD_RELEASE_BUFFER: + case IOCTL_CMD_RELEASE_BUFFER: { uint32_t mem_offset; @@ -639,35 +628,41 @@ static long maru_brill_codec_ioctl(struct file *file, ret = -EIO; break; } - release_device_memory(mem_offset); + ret = release_device_memory(mem_offset); + if (ret < 0) { + ERROR("failed to release device memory\n"); + } break; } - case CODEC_CMD_INVOKE_API_AND_RELEASE_BUFFER: + case IOCTL_CMD_INVOKE_API_AND_GET_DATA: { - struct codec_param ioparam = { 0, }; + struct ioctl_data opaque = { 0, }; - if (copy_from_user(&ioparam, (void *)arg, sizeof(struct codec_param))) { + if (copy_from_user(&opaque, (void *)arg, sizeof(struct ioctl_data))) { ERROR("failed to get codec parameter info from user\n"); ret = -EIO; break; } - invoke_api_and_release_buffer(&ioparam); + ret = invoke_api_and_release_buffer(&opaque); + if (ret < 0) { + ERROR("failed to invoke API : [%d]\n", opaque.api_index); + } - if (ioparam.buffer_id.buffer_index) { // if client wants output data - ret = put_data_into_buffer((struct codec_buffer_id *)&ioparam.buffer_id); + if (opaque.buffer_size != -1) { + ret = put_data_into_buffer(&opaque); if (ret < 0) { ret = -EIO; break; } - if (copy_to_user((void *)arg, &ioparam, sizeof(struct codec_param))) { + if (copy_to_user((void *)arg, &opaque, sizeof(struct ioctl_data))) { ERROR("ioctl: failed to copy data to user.\n"); ret = -EIO; } } - } break; + } default: DEBUG("no available command."); ret = -EINVAL; @@ -677,44 +672,50 @@ static long maru_brill_codec_ioctl(struct file *file, return ret; } -static int invoke_api_and_release_buffer(void *opaque) +static int invoke_api_and_release_buffer(struct ioctl_data *data) { - struct codec_param *ioparam = (struct codec_param *)opaque; int api_index, ctx_index; unsigned long flags; + int ret = 0; DEBUG("enter %s\n", __func__); - api_index = ioparam->api_index; - ctx_index = ioparam->ctx_index; + api_index = data->api_index; + ctx_index = data->ctx_index; switch (api_index) { case CODEC_INIT: - case CODEC_DECODE_VIDEO ... CODEC_ENCODE_AUDIO: - case CODEC_DECODE_VIDEO2: - case CODEC_PICTURE_COPY: // for old plugins + case CODEC_DECODE_VIDEO: + case CODEC_ENCODE_VIDEO: + case CODEC_DECODE_AUDIO: + case CODEC_ENCODE_AUDIO: + case CODEC_DECODE_VIDEO_AND_PICTURE_COPY: { ENTER_CRITICAL_SECTION(flags); - writel((uint32_t)ioparam->mem_offset, - maru_brill_codec->ioaddr + CODEC_CMD_DEVICE_MEM_OFFSET); - writel((int32_t)ioparam->ctx_index, - maru_brill_codec->ioaddr + CODEC_CMD_CONTEXT_INDEX); - writel((int32_t)ioparam->api_index, - maru_brill_codec->ioaddr + CODEC_CMD_API_INDEX); + writel((uint32_t)data->mem_offset, + maru_brill_codec->ioaddr + DEVICE_CMD_DEVICE_MEM_OFFSET); + writel((int32_t)data->ctx_index, + maru_brill_codec->ioaddr + DEVICE_CMD_CONTEXT_INDEX); + writel((int32_t)data->api_index, + maru_brill_codec->ioaddr + DEVICE_CMD_API_INDEX); LEAVE_CRITICAL_SECTION(flags); - release_device_memory(ioparam->mem_offset); + ret = release_device_memory(data->mem_offset); + if (ret < 0) { + ERROR("failed to release device memory\n"); + } break; } + case CODEC_PICTURE_COPY: case CODEC_DEINIT: case CODEC_FLUSH_BUFFERS: { ENTER_CRITICAL_SECTION(flags); - writel((int32_t)ioparam->ctx_index, - maru_brill_codec->ioaddr + CODEC_CMD_CONTEXT_INDEX); - writel((int32_t)ioparam->api_index, - maru_brill_codec->ioaddr + CODEC_CMD_API_INDEX); + writel((int32_t)data->ctx_index, + maru_brill_codec->ioaddr + DEVICE_CMD_CONTEXT_INDEX); + writel((int32_t)data->api_index, + maru_brill_codec->ioaddr + DEVICE_CMD_API_INDEX); LEAVE_CRITICAL_SECTION(flags); break; @@ -728,15 +729,15 @@ static int invoke_api_and_release_buffer(void *opaque) context_flags[ctx_index] = 0; if (api_index == CODEC_DEINIT) { - dispose_device_memory(ioparam->ctx_index); + dispose_device_memory(data->ctx_index); } DEBUG("leave %s\n", __func__); - return 0; + return ret; } -static int maru_brill_codec_mmap(struct file *file, struct vm_area_struct *vm) +static int brillcodec_mmap(struct file *file, struct vm_area_struct *vm) { unsigned long off; unsigned long phys_addr; @@ -768,7 +769,7 @@ static irqreturn_t maru_brill_codec_irq_handler(int irq, void *dev_id) unsigned long flags = 0; int val = 0; - val = readl(dev->ioaddr + CODEC_CMD_GET_THREAD_STATE); + val = readl(dev->ioaddr + DEVICE_CMD_GET_THREAD_STATE); if (!(val & CODEC_IRQ_TASK)) { return IRQ_NONE; } @@ -843,7 +844,7 @@ static void maru_brill_codec_context_remove(struct user_process_id *pid_elem) if (cid_elem->id > 0 && cid_elem->id < CODEC_CONTEXT_SIZE) { DEBUG("remove context. ctx_id: %d\n", cid_elem->id); writel(cid_elem->id, - maru_brill_codec->ioaddr + CODEC_CMD_RELEASE_CONTEXT); + maru_brill_codec->ioaddr + DEVICE_CMD_RELEASE_CONTEXT); dispose_device_memory(cid_elem->id); } @@ -924,7 +925,7 @@ static void maru_brill_codec_task_remove(uint32_t user_pid) } -static int maru_brill_codec_open(struct inode *inode, struct file *file) +static int brillcodec_open(struct inode *inode, struct file *file) { DEBUG("open! struct file: %p\n", file); @@ -942,7 +943,7 @@ static int maru_brill_codec_open(struct inode *inode, struct file *file) return 0; } -static int maru_brill_codec_release(struct inode *inode, struct file *file) +static int brillcodec_release(struct inode *inode, struct file *file) { DEBUG("close! struct file: %p\n", file); @@ -964,10 +965,10 @@ static int maru_brill_codec_release(struct inode *inode, struct file *file) /* define file opertion for CODEC */ const struct file_operations maru_brill_codec_fops = { .owner = THIS_MODULE, - .unlocked_ioctl = maru_brill_codec_ioctl, - .open = maru_brill_codec_open, - .mmap = maru_brill_codec_mmap, - .release = maru_brill_codec_release, + .unlocked_ioctl = brillcodec_ioctl, + .open = brillcodec_open, + .mmap = brillcodec_mmap, + .release = brillcodec_release, }; static struct miscdevice codec_dev = { @@ -980,7 +981,7 @@ static struct miscdevice codec_dev = { static void maru_brill_codec_get_device_version(void) { maru_brill_codec->version = - readl(maru_brill_codec->ioaddr + CODEC_CMD_GET_VERSION); + readl(maru_brill_codec->ioaddr + DEVICE_CMD_GET_VERSION); printk(KERN_INFO "%s: device version: %d\n", DEVICE_NAME, maru_brill_codec->version);