Exemplo n.º 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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
/*----------------------------------------------------------------------------
*Function: CMM_Open

*Parameters:         InitHandle        :Handle to JPEG  context
                    dwAccess        :
                    dwShareMode        :File share mode of JPEG
*Return Value:        This function returns a handle that identifies the 
                    open context of JPEG  to the calling application.
*Implementation Notes: Opens JPEG CODEC device for reading, writing, or both 
-----------------------------------------------------------------------------*/
DWORD
CMM_Open(
    DWORD InitHandle,
    DWORD dwAccess,
    DWORD dwShareMode
    )
{
    CODEC_MEM_CTX *CodecMem;
    DWORD    ret;
    UINT8    inst_no;


    ret = LockCMMMutex();
    if(!ret){
        RETAILMSG(1, (TEXT("[CMM_Open] CMM Mutex Lock Fail\r\n")));
        return FALSE;
    }

    // check the number of instance 
    if((inst_no = GetInstanceNo()) < 0){
        RETAILMSG(1, (TEXT("[CMM_Open] Instance Number error-too many instance\r\n")));
        UnlockCMMMutex();
        return FALSE;
    }

    CodecMem = (CODEC_MEM_CTX *)malloc(sizeof(CODEC_MEM_CTX));
    if(CodecMem == NULL){
        RETAILMSG(1, (TEXT("[CMM_Init] CodecMem allocatopn failed\r\n")));
        UnlockCMMMutex();
        return FALSE;
    }
    
    memset(CodecMem, 0x00, sizeof(CODEC_MEM_CTX));

    CodecMem->inst_no = inst_no;
    printD("\n*****************************\n[CMM_Open] instanceNo : %d\n*****************************\n", CodecMem->inst_no);
    PrintList();
    UnlockCMMMutex();
    return (DWORD)CodecMem;
}
Exemplo n.º 4
0
static int s3c_cmm_open(struct inode *inode, struct file *file)
{
	CODEC_MEM_CTX	*CodecMem;
	int			ret;
	int			inst_no;


	ret = LockCMMMutex();
	if (!ret){
		LOG_MSG(LOG_ERROR, "s3c_cmm_open", "DD::CMM Mutex Lock Fail\n");
		return -1;
	}

	// check the number of instance 
	if((inst_no = GetInstanceNo()) < 0){
		LOG_MSG(LOG_ERROR, "s3c_cmm_open", "Instance Number error-too many instance\r\n");
		UnlockCMMMutex();
		return -1;
	}
	
	CodecMem = (CODEC_MEM_CTX *)kmalloc(sizeof(CODEC_MEM_CTX), GFP_KERNEL);
	if(CodecMem == NULL){
		LOG_MSG(LOG_ERROR, "s3c_cmm_open", "CodecMem application failed\n");
		UnlockCMMMutex();
		return -1;
	}
	
	memset(CodecMem, 0x00, sizeof(CODEC_MEM_CTX));

	CodecMem->inst_no = inst_no;
	printk("\n*****************************\n[CMM_Open] instanceNo : %d\n*****************************\n", CodecMem->inst_no);
	PrintList();
	
	file->private_data = (CODEC_MEM_CTX	*)CodecMem;

	UnlockCMMMutex();


	return 0;
}
Exemplo n.º 5
0
/*----------------------------------------------------------------------------
*Function: CMM_IOControl

*Parameters:         OpenHandle        :
                    dwIoControlCode    :
*Return Value:        True/False
*Implementation Notes: JPEG_IOControl sends commands to initiate different
*                       operations like Init,Decode and Deinit.The test 
*                       application uses the DeviceIOControl function to 
*                       specify an operation to perform 
-----------------------------------------------------------------------------*/
BOOL
CMM_IOControl(
    DWORD OpenHandle,
    DWORD dwIoControlCode,
    PBYTE pInBuf,
    DWORD nInBufSize,
    PBYTE pOutBuf,
    DWORD nOutBufSize,
    PDWORD pBytesReturned
    )
{
    CODEC_MEM_CTX       *CodecMem;
    BOOL                result = TRUE;
    DWORD               ret;
    UINT8               *u_addr;
    ALLOC_MEM_T         *node;
    CMM_ALLOC_PRAM_T    allocParam;
    
    CodecMem = (CODEC_MEM_CTX *)OpenHandle;

    if(!CodecMem){
        RETAILMSG(1, (TEXT("[CMM_IOControl] CMM Invalid Input Handle\r\n")));
        return FALSE;
    }

    if ((pInBuf == NULL) || (nInBufSize == 0)){
        RETAILMSG(1, (TEXT("[CMM_IOControl] Invalid Input buffer or size\r\n")));
        return FALSE;
    }

    ret = LockCMMMutex();
    if(!ret){
        RETAILMSG(1, (TEXT("[CMM_IOControl] CMM Mutex Lock Fail\r\n")));
        return FALSE;
    }

    switch ( dwIoControlCode ) {

    case IOCTL_CODEC_MEM_ALLOC:
        
        printD("\n[%d][CMM_IOControl] IOCTL_CODEC_MEM_ALLOC\n", CodecMem->inst_no);
        if ((pInBuf == NULL) || 
            (nInBufSize < sizeof(CMM_ALLOC_PRAM_T)) ||
            (pOutBuf == NULL) ||
            (nOutBufSize < sizeof(UINT)))
        {
            RETAILMSG(1, (TEXT("[CMM_IOControl] IOCTL_CODEC_MEM_ALLOC Invalid parameters\r\n")));
            result = FALSE;
            break;
        }

        // Create a local copy of the input buffer first.
        if (!CeSafeCopyMemory(&allocParam, pInBuf, sizeof(CMM_ALLOC_PRAM_T)))// Copies memory inside a __try/__except block
        {
            result = FALSE;
            break;
        }  

        if((allocParam.size) & (0xFFF)) // For 4K alignment
        {
            allocParam.size = (allocParam.size & 0xFFFFF000) + 0x1000;    
        }
    
        printD("[IOCTL_CODEC_MEM_ALLOC] buffSize : %ld\n", allocParam.size);

        if((node = GetCodecVirAddr(CodecMem->inst_no, &allocParam)) == NULL){
            result = FALSE;
            break;
        }

        CodecMem->callerProcess = (HANDLE) GetDirectCallerProcessId();
        node->u_addr = (PBYTE)VirtualAllocEx(CodecMem->callerProcess, 
                                            NULL, 
                                            node->size, 
                                            MEM_RESERVE, 
                                            PAGE_NOACCESS);
        if (node->u_addr == NULL)
        {
            RETAILMSG(1, (_T("[CMM_IOControl]: Memory VirtualAlloc Fail.  Error = %d\r\n"), GetLastError()));
            result = FALSE;
        }
        else
        {
            if (!VirtualCopyEx(CodecMem->callerProcess,           
                                node->u_addr,
                                (HANDLE) GetCurrentProcessId(),
                                node->v_addr,    
                                node->size, 
                                allocParam.cacheFlag ? PAGE_READWRITE : (PAGE_READWRITE | PAGE_NOCACHE)))
            {
                RETAILMSG(1, (_T("[CMM_IOControl]: Memory VirtualCopyEx Fail. Error = %d\r\n"), GetLastError()));
                result = FALSE;
            }
        }

        __try
        {
            if (result)
            {
                *((UINT *)pOutBuf) = (UINT) node->u_addr;
            }
        }
        __except ( EXCEPTION_EXECUTE_HANDLER )
        {
            RETAILMSG( 1, ( _T("[CMM_IOControl]: exception in IOCTL_CODEC_MEM_ALLOC \r\n")) );
            result = FALSE;
        }

        if (!result)
        {
            // free alloc node
            ReleaseAllocMem(node, CodecMem);
        }        

        break;

    case IOCTL_CODEC_MEM_FREE:
        printD("\n[%d][CMM_IOControl] IOCTL_CODEC_MEM_FREE\n", CodecMem->inst_no);
        u_addr = (UINT8 *)pInBuf;
        printD("[CMM_IOControl] free adder : 0x%x \n", u_addr);

        for(node = AllocMemHead; node != AllocMemTail; node = node->next)
        {
            if(node->u_addr == u_addr)
                break;
        }

        if(node  == AllocMemTail)
        {
            RETAILMSG(1, (TEXT("[CMM_IOControl] invalid virtual address(0x%x)\r\n"), u_addr));
            result = FALSE;
            break;
        }
        // free alloc node
        ReleaseAllocMem(node, CodecMem);
        break;

    case IOCTL_CODEC_CACHE_INVALIDATE:
        printD("\n[CMM_IOControl] IOCTL_CODEC_CACHE_INVALIDATE\n");
        u_addr = (UINT8 *)pInBuf;
        printD("[CMM_IOControl] flush adder : 0x%x \n", u_addr);

        for(node = AllocMemHead; node != AllocMemTail; node = node->next)
        {
            if(node->u_addr == u_addr)
                break;
        }

        if(node  == AllocMemTail){
            RETAILMSG(1, (TEXT("[%d][CMM_IOControl] invalid virtual address(0x%x)\r\n"), CodecMem->inst_no, u_addr));
            result = FALSE;
            break;
        }

        InvalidateCacheRange((PBYTE) node->v_addr, 
            (PBYTE) node->v_addr + node->size);
        break;

    case IOCTL_CODEC_CACHE_CLEAN:
        printD("\n[CMM_IOControl] IOCTL_CODEC_CACHE_CLEAN\n");
        u_addr = (UINT8 *)pInBuf;
        printD("[CMM_IOControl] flush adder : 0x%x \n", u_addr);

        for(node = AllocMemHead; node != AllocMemTail; node = node->next)
        {
            if(node->u_addr == u_addr)
                break;
        }

        if(node  == AllocMemTail){
            RETAILMSG(1, (TEXT("[%d][CMM_IOControl] invalid virtual address(0x%x)\r\n"), CodecMem->inst_no, u_addr));
            result = FALSE;
            break;
        }

        CleanCacheRange((PBYTE) node->v_addr, 
            (PBYTE) node->v_addr + node->size);
        break;


        // IOCTL_CODEC_CACHE_FLUSH is same as IOCTL_CODEC_CACHE_CLEAN_INVALIDATE.
        // This is remained for backward capability
    case IOCTL_CODEC_CACHE_FLUSH: 
    case IOCTL_CODEC_CACHE_CLEAN_INVALIDATE:
        printD("\n[CMM_IOControl] IOCTL_CODEC_CACHE_CLEAN_INVALIDATE\n");
        u_addr = (UINT8 *)pInBuf;
        printD("[CMM_IOControl] flush adder : 0x%x \n", u_addr);

        for(node = AllocMemHead; node != AllocMemTail; node = node->next)
        {
            if(node->u_addr == u_addr)
                break;
        }

        if(node  == AllocMemTail){
            RETAILMSG(1, (TEXT("[%d][CMM_IOControl] invalid virtual address(0x%x)\r\n"), CodecMem->inst_no, u_addr));
            result = FALSE;
            break;
        }

        CleanInvalidateCacheRange((PBYTE) node->v_addr, 
            (PBYTE) node->v_addr + node->size);
        break;


    case IOCTL_CODEC_GET_PHY_ADDR:
        u_addr  = (UINT8 *)pInBuf;
        for(node = AllocMemHead; node != AllocMemTail; node = node->next)
        {
            if(node->u_addr == u_addr)
                break;
        }

        if(node  == AllocMemTail){
            RETAILMSG(1, (TEXT("[CMM_IOControl] invalid virtual address(0x%x)\r\n"), u_addr));
            result = FALSE;
            break;
        }
        
        if ((pOutBuf == NULL) || (nOutBufSize < sizeof(UINT8 *)))
        {
            RETAILMSG(1, (TEXT("[CMM_IOControl] IOCTL_CODEC_GET_PHY_ADDR Invalid Output buffer or size\r\n")));
            result = FALSE;
            break;
        }

        __try
        {
            *((UINT *)pOutBuf) = (UINT) node->cached_p_addr;
        }
        __except ( EXCEPTION_EXECUTE_HANDLER )
        {
            RETAILMSG( 1, ( _T("[CMM_IOControl]: exception in IOCTL_CODEC_GET_PHY_ADDR \r\n")) );
            result = FALSE;
        }

        break;


    default : RETAILMSG(1, (TEXT("[CMM_IOControl] CMM Invalid IOControl\r\n")));
    }


    UnlockCMMMutex();
    return result;
}
Exemplo n.º 6
0
static int __init s3c_cmm_init(void)
{
	HANDLE 		h_Mutex;
	int			ret;
	FREE_MEM_T	*node;
	ALLOC_MEM_T	*alloc_node;
	
	
	printk(banner);

	// Mutex initialization
	h_Mutex = CreateCMMmutex();
	if (h_Mutex == NULL) 
	{
		LOG_MSG(LOG_ERROR, "s3c_cmm_init", "DD::CMM Mutex Initialize error\r\n");
		return FALSE;
	}

	ret = LockCMMMutex();

	ret = misc_register(&s3c_cmm_miscdev);


	// First 4MB will use cacheable memory
	CachedVirAddr = (unsigned char *)ioremap_cached( (unsigned long)CODEC_MEM_START, 		\
					(int)CODEC_CACHED_MEM_SIZE );

	// Second 4MB will use non-cacheable memory
	NonCachedVirAddr = (unsigned char *)ioremap_nocache( (unsigned long)(CODEC_MEM_START + 	\
					CODEC_CACHED_MEM_SIZE), (int)CODEC_NON_CACHED_MEM_SIZE );

	// init alloc list, if(AllocMemHead == AllocMemTail) then, the list is NULL
	alloc_node = (ALLOC_MEM_T *)kmalloc(sizeof(ALLOC_MEM_T), GFP_KERNEL);
	memset(alloc_node, 0x00, sizeof(ALLOC_MEM_T));
	alloc_node->next = alloc_node;
	alloc_node->prev = alloc_node;
	AllocMemHead = alloc_node;
	AllocMemTail = AllocMemHead;

	// init free list, if(FreeMemHead == FreeMemTail) then, the list is NULL
	node = (FREE_MEM_T *)kmalloc(sizeof(FREE_MEM_T), GFP_KERNEL);
	memset(node, 0x00, sizeof(FREE_MEM_T));
	node->next = node;
	node->prev = node;
	FreeMemHead = node;
	FreeMemTail = FreeMemHead;

	node = (FREE_MEM_T *)kmalloc(sizeof(FREE_MEM_T), GFP_KERNEL);
	memset(node, 0x00, sizeof(FREE_MEM_T));
	node->startAddr = CODEC_MEM_START;
	node->cacheFlag = 1;
	node->size = CODEC_CACHED_MEM_SIZE;
	InsertNodeToFreeList(node, -1);

	node = (FREE_MEM_T *)kmalloc(sizeof(FREE_MEM_T), GFP_KERNEL);
	memset(node, 0x00, sizeof(FREE_MEM_T));
	node->startAddr = CODEC_MEM_START + CODEC_CACHED_MEM_SIZE;
	node->cacheFlag = 0;
	node->size = CODEC_NON_CACHED_MEM_SIZE;
	InsertNodeToFreeList(node, -1);

	UnlockCMMMutex();

	return 0;
}
Exemplo n.º 7
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;
}