/*---------------------------------------------------------------------------- *Function: CMM_Close *Parameters: OpenHandle : *Return Value: True/False *Implementation Notes: This function closes the device context identified by OpenHandle -----------------------------------------------------------------------------*/ BOOL CMM_Close( DWORD OpenHandle ) { CODEC_MEM_CTX *CodecMem; DWORD ret; ALLOC_MEM_T *node, *tmp_node; int count=0; ret = LockCMMMutex(); if(!ret){ RETAILMSG(1, (TEXT("[CMM_Close] CMM Mutex Lock Fail\r\n"))); return FALSE; } CodecMem = (CODEC_MEM_CTX *)OpenHandle; printD("[%d][CMM Close] \n", CodecMem->inst_no); if(!CodecMem){ RETAILMSG(1, (TEXT("[CMM_Close] CMM Invalid Input Handle\r\n"))); UnlockCMMMutex(); return FALSE; } printD("[CMM_Close] CodecMem->inst_no : %d CodecMem->callerProcess : 0x%x\n", CodecMem->inst_no, CodecMem->callerProcess); __try { // release u_addr and v_addr accoring to inst_no for(node = AllocMemHead; node != AllocMemTail; node = node->next){ if(node->inst_no == CodecMem->inst_no){ tmp_node = node; node = node->prev; ReleaseAllocMem(tmp_node, CodecMem); } } } __except ( EXCEPTION_EXECUTE_HANDLER ) { RETAILMSG( 1, ( _T("CMM_Close:Exception in releasing memory\n")) ); return FALSE; } printD("[%d][CMM Close] MergeFragmentation\n", CodecMem->inst_no); MergeFragmentation(CodecMem->inst_no); ReturnInstanceNo(CodecMem->inst_no); free(CodecMem); UnlockCMMMutex(); return TRUE; }
static int s3c_cmm_release(struct inode *inode, struct file *file) { DWORD ret; CODEC_MEM_CTX *CodecMem; ALLOC_MEM_T *node, *tmp_node; ret = LockCMMMutex(); if(!ret){ LOG_MSG(LOG_ERROR, "s3c_cmm_release", "DD::CMM Mutex Lock Fail\r\n"); return -1; } CodecMem = (CODEC_MEM_CTX *)file->private_data; LOG_MSG(LOG_TRACE, "s3c_cmm_release", "[%d][CMM Close] \n", CodecMem->inst_no); if(!CodecMem){ LOG_MSG(LOG_ERROR, "s3c_cmm_close", "CMM Invalid Input Handle\r\n"); UnlockCMMMutex(); return -1; } LOG_MSG(LOG_TRACE, "s3c_cmm_close", "CodecMem->inst_no : %d\n", CodecMem->inst_no); // release u_addr and v_addr accoring to inst_no for(node = AllocMemHead; node != AllocMemTail; node = node->next){ if(node->inst_no == CodecMem->inst_no){ tmp_node = node; node = node->prev; ReleaseAllocMem(tmp_node, CodecMem); } } LOG_MSG(LOG_TRACE, "s3c_cmm_release", "[%d]instance MergeFragmentation\n", CodecMem->inst_no); MergeFragmentation(CodecMem->inst_no); ReturnInstanceNo(CodecMem->inst_no); kfree(CodecMem); UnlockCMMMutex(); return 0; }
static int s3c_cmm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int ret; CODEC_MEM_CTX * CodecMem; CODEC_MEM_ALLOC_ARG codec_mem_alloc_arg; CODEC_CACHE_FLUSH_ARG codec_cache_flush_arg; CODEC_GET_PHY_ADDR_ARG codec_get_phy_addr_arg; int result = 0; void * start; void * end; ALLOC_MEM_T * node; CODEC_MEM_FREE_ARG codec_mem_free_arg; CodecMem = (CODEC_MEM_CTX *)file->private_data; if (!CodecMem) { LOG_MSG(LOG_ERROR, "s3c_cmm_ioctl", "CMM Invalid Input Handle\n"); return -1; } ret = LockCMMMutex(); if(!ret){ LOG_MSG(LOG_ERROR, "s3c_cmm_ioctl", "DD::CMM Mutex Lock Fail\r\n"); return -1; } switch (cmd) { case IOCTL_CODEC_MEM_ALLOC: LOG_MSG(LOG_TRACE, "s3c_cmm_ioctl", "IOCTL_CODEC_MEM_GET\n"); copy_from_user(&codec_mem_alloc_arg, (CODEC_MEM_ALLOC_ARG *)arg, sizeof(CODEC_MEM_ALLOC_ARG)); node = GetCodecVirAddr(CodecMem->inst_no, &codec_mem_alloc_arg); if(node == NULL){ LOG_MSG(LOG_WARNING, "s3c_cmm_ioctl", "GetCodecVirAddr(%d)\r\n", CodecMem->inst_no); result = -1; break; } ret = copy_to_user((void *)arg, (void *)&codec_mem_alloc_arg, sizeof(CODEC_MEM_ALLOC_ARG)); break; case IOCTL_CODEC_MEM_FREE: LOG_MSG(LOG_TRACE, "s3c_cmm_ioctl", "IOCTL_CODEC_MEM_FREE\n"); copy_from_user(&codec_mem_free_arg, (CODEC_MEM_FREE_ARG *)arg, sizeof(CODEC_MEM_FREE_ARG)); for(node = AllocMemHead; node != AllocMemTail; node = node->next) { if(node->u_addr == (unsigned char *)codec_mem_free_arg.u_addr) break; } if(node == AllocMemTail){ LOG_MSG(LOG_ERROR, "s3c_cmm_ioctl", "invalid virtual address(0x%x)\r\n", codec_mem_free_arg.u_addr); result = -1; break; } ReleaseAllocMem(node, CodecMem); break; case IOCTL_CODEC_CACHE_FLUSH: LOG_MSG(LOG_TRACE, "s3c_cmm_ioctl", "IOCTL_CODEC_CACHE_FLUSH\n"); copy_from_user(&codec_cache_flush_arg, (CODEC_CACHE_FLUSH_ARG *)arg, sizeof(CODEC_CACHE_FLUSH_ARG)); for(node = AllocMemHead; node != AllocMemTail; node = node->next) { if(node->u_addr == (unsigned char *)codec_cache_flush_arg.u_addr) break; } if(node == AllocMemTail){ LOG_MSG(LOG_ERROR, "s3c_cmm_ioctl", "invalid virtual address(0x%x)\r\n", codec_cache_flush_arg.u_addr); result = -1; break; } start = node->v_addr; end = start + codec_cache_flush_arg.size; dmac_clean_range(start, end); outer_clean_range(__pa(start), __pa(end)); break; case IOCTL_CODEC_GET_PHY_ADDR: copy_from_user(&codec_get_phy_addr_arg, (CODEC_GET_PHY_ADDR_ARG *)arg, sizeof(CODEC_GET_PHY_ADDR_ARG)); for(node = AllocMemHead; node != AllocMemTail; node = node->next) { if(node->u_addr == (unsigned char *)codec_get_phy_addr_arg.u_addr) break; } if(node == AllocMemTail){ LOG_MSG(LOG_ERROR, "s3c_cmm_ioctl", "invalid virtual address(0x%x)\r\n", codec_get_phy_addr_arg.u_addr); result = -1; break; } if(node->cacheFlag) codec_get_phy_addr_arg.p_addr = node->cached_p_addr; else codec_get_phy_addr_arg.p_addr = node->uncached_p_addr; copy_to_user((void *)arg, (void *)&codec_get_phy_addr_arg, sizeof(CODEC_GET_PHY_ADDR_ARG)); break; case IOCTL_CODEC_MERGE_FRAGMENTATION: MergeFragmentation(CodecMem->inst_no); break; case IOCTL_CODEC_CACHE_INVALIDATE: LOG_MSG(LOG_TRACE, "s3c_cmm_ioctl", "IOCTL_CODEC_CACHE_INVALIDATE\n"); copy_from_user(&codec_cache_flush_arg, (CODEC_CACHE_FLUSH_ARG *)arg, sizeof(CODEC_CACHE_FLUSH_ARG)); for(node = AllocMemHead; node != AllocMemTail; node = node->next) { if(node->u_addr == (unsigned char *)codec_cache_flush_arg.u_addr) break; } if(node == AllocMemTail){ LOG_MSG(LOG_ERROR, "s3c_cmm_ioctl", "invalid virtual address(0x%x)\r\n", codec_cache_flush_arg.u_addr); result = -1; break; } start = node->v_addr; end = start + codec_cache_flush_arg.size; dmac_flush_range(start, end); break; case IOCTL_CODEC_CACHE_CLEAN: LOG_MSG(LOG_TRACE, "s3c_cmm_ioctl", "IOCTL_CODEC_CACHE_CLEAN\n"); copy_from_user(&codec_cache_flush_arg, (CODEC_CACHE_FLUSH_ARG *)arg, sizeof(CODEC_CACHE_FLUSH_ARG)); for(node = AllocMemHead; node != AllocMemTail; node = node->next) { if(node->u_addr == (unsigned char *)codec_cache_flush_arg.u_addr) break; } if(node == AllocMemTail){ LOG_MSG(LOG_ERROR, "s3c_cmm_ioctl", "invalid virtual address(0x%x)\r\n", codec_cache_flush_arg.u_addr); result = -1; break; } start = node->v_addr; end = start + codec_cache_flush_arg.size; dmac_clean_range(start, end); break; case IOCTL_CODEC_CACHE_CLEAN_INVALIDATE: LOG_MSG(LOG_TRACE, "s3c_cmm_ioctl", "IOCTL_CODEC_CACHE_INVALIDATE\n"); copy_from_user(&codec_cache_flush_arg, (CODEC_CACHE_FLUSH_ARG *)arg, sizeof(CODEC_CACHE_FLUSH_ARG)); for(node = AllocMemHead; node != AllocMemTail; node = node->next) { if(node->u_addr == (unsigned char *)codec_cache_flush_arg.u_addr) break; } if(node == AllocMemTail){ LOG_MSG(LOG_ERROR, "s3c_cmm_ioctl", "invalid virtual address(0x%x)\r\n", codec_cache_flush_arg.u_addr); result = -1; break; } start = node->v_addr; end = start + codec_cache_flush_arg.size; dmac_clean_range(start, end); dmac_flush_range(start, end); break; default : LOG_MSG(LOG_ERROR, "s3c_cmm_ioctl", "DD::CMM Invalid ioctl : 0x%X\r\n", cmd); } UnlockCMMMutex(); if(result == 0) return TRUE; else return FALSE; }