Beispiel #1
0
/*----------------------------------------------------------------------------
*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;
}