Exemple #1
0
/*!
******************************************************************************

 @Function				RMAN_Deinitialise

******************************************************************************/
IMG_VOID RMAN_Deinitialise(IMG_VOID)
{
    IMG_UINT32				i;

    /* Make sure no other cpu is using the shared resources.  */
    SYSOSKM_DisableInt();

    /* If initialised...*/
    if (gInitialised)
    {
        /* Destroy the golbal resource bucket...*/
        RMAN_DestroyBucket(gpsGlobalResBucket);

        /* Destroy the shared resource bucket...*/
        RMAN_DestroyBucket(gpsSharedResBucket);

        /* Make sure we destroy the mutex after destroying the bucket. */
        SYSOSKM_DestroyMutex(globalMutext);

        /* Destroy mutex...*/
        SYSOSKM_DestroyMutex(ghSharedResMutexHandle);

        /* Check all buckets destroyed...*/
        for (i=0; i<RMAN_CRESID_MAX_BUCKET_INDEX; i++)
        {
            IMG_ASSERT(gapsBucket[i] == IMG_NULL);
        }

        /* Reset initialised flag...*/
        gInitialised = IMG_FALSE;
    }

    SYSOSKM_EnableInt();
}
/*!
 ******************************************************************************

 @Function              dmankm_DisconnectComps

 ******************************************************************************/
static IMG_RESULT dmankm_DisconnectComps(DMANKM_sConnContext * psConnContext) 
{
	DMANKM_sAttachContext * psAttachContext;
	IMG_UINT32 ui32Result;

	psAttachContext = (DMANKM_sAttachContext *) LST_first(
			&psConnContext->sAttachList);
	while (psAttachContext != IMG_NULL ) {
		/* If there is a disconnect function...*/
		if (psAttachContext->sCompAttach.pfnCompDisconnect != IMG_NULL ) {
			/* Call it...*/
			ui32Result = psAttachContext->sCompAttach.pfnCompDisconnect(
					psAttachContext, psAttachContext->pvCompAttachmentData);
			if (ui32Result != IMG_SUCCESS) {
                IMG_ASSERT(ui32Result == IMG_SUCCESS);
				return ui32Result;
			}
		}

		/* Remove, free the name and control block...*/
		LST_remove(&psConnContext->sAttachList, psAttachContext);
		RMAN_DestroyBucket(psAttachContext->hResBHandle);
		RMAN_FreeResource(psAttachContext->hResHandle);
		IMG_FREE(psAttachContext->pszCompName);
		IMG_FREE(psAttachContext);
		psAttachContext = (DMANKM_sAttachContext *) LST_first(
				&psConnContext->sAttachList);
	}

	/* Return success...*/
	return IMG_SUCCESS;
}
/*!
******************************************************************************

 @Function              palloc_fnCompDisconnect

******************************************************************************/
static IMG_RESULT palloc_fnCompDisconnect (
    IMG_HANDLE  hAttachHandle,
    IMG_VOID *  pvCompAttachmentData
)
{
    PALLOC_sAttachContext *  psAttachContext = pvCompAttachmentData;

    LOG_EVENT(PALLOC, PALLOC_COMPDISCONNECT, (LOG_FLAG_START), 0, 0);

    /* Destroy the bucket and it's resources...*/
    RMAN_DestroyBucket(psAttachContext->hResBHandle);

    /* If we opened a device...*/
    if (psAttachContext->hSysDevHandle != IMG_NULL)
    {
        SYSDEVKM_CloseDevice(psAttachContext->hSysDevHandle);
    }

    /* Free attachment context...*/
    IMG_FREE(psAttachContext);

    LOG_EVENT(PALLOC, PALLOC_COMPDISCONNECT, (LOG_FLAG_END), 0, 0);

    /* Return success...*/
    return IMG_SUCCESS;
}
/*!
******************************************************************************

 @Function              palloc_fnCompConnect

******************************************************************************/
static IMG_RESULT palloc_fnCompConnect (
    IMG_HANDLE   hAttachHandle,
    IMG_VOID **  ppvCompAttachmentData
)
{
    PALLOC_sAttachContext *  psAttachContext;
    IMG_UINT32               ui32Result;
    IMG_CHAR *               pszDeviceName;

    /* Allocate attachment context structure...*/
    psAttachContext = IMG_MALLOC(sizeof(*psAttachContext));
    IMG_ASSERT(psAttachContext != IMG_NULL);
    if (psAttachContext == IMG_NULL)
    {
        return IMG_ERROR_OUT_OF_MEMORY;
    }
    IMG_MEMSET(psAttachContext, 0, sizeof(*psAttachContext));

    /* Ensure the resource manager is initialised...*/
    ui32Result = RMAN_Initialise();
    IMG_ASSERT(ui32Result == IMG_SUCCESS);
    if (ui32Result != IMG_SUCCESS)
    {
        goto error_rman_init;
    }

    /* Create a bucket for the resources...*/
    ui32Result = RMAN_CreateBucket(&psAttachContext->hResBHandle);
    IMG_ASSERT(ui32Result == IMG_SUCCESS);
    if (ui32Result != IMG_SUCCESS)
    {
        goto error_rman_bucket;
    }

    /* Get device information...*/
    psAttachContext->hDevHandle = DMANKM_GetDevHandleFromAttach(hAttachHandle);
    pszDeviceName = DMANKM_GetDeviceName(psAttachContext->hDevHandle);
    ui32Result = SYSDEVU_OpenDevice(pszDeviceName, &psAttachContext->hSysDevHandle);
    IMG_ASSERT(ui32Result == IMG_SUCCESS);
    if (ui32Result != IMG_SUCCESS)
    {
        goto error_sysdev_open;
    }

    /* Return attachment context...*/
    *ppvCompAttachmentData = psAttachContext;

    /* Return success...*/
    return IMG_SUCCESS;

    /* Error handling. */
error_sysdev_open:
    RMAN_DestroyBucket(psAttachContext->hResBHandle);
error_rman_bucket:
error_rman_init:
    IMG_FREE(psAttachContext);

    return ui32Result;
}
/*!
******************************************************************************

 @Function              wrapu_fnCompDisconnect

******************************************************************************/
static IMG_RESULT wrapu_fnCompDisconnect (
    IMG_HANDLE  hAttachHandle,
    IMG_VOID *  pvCompAttachmentData
)
{
    WRAPU_sAttachContext *  psAttachContext = pvCompAttachmentData;

    /* Destroy the bucket and it's resources...*/
    RMAN_DestroyBucket(psAttachContext->hResBHandle);

    /* If we opened a device...*/
    if (psAttachContext->hSysDevHandle != IMG_NULL)
    {
        SYSDEVKM_CloseDevice(psAttachContext->hSysDevHandle);
    }

    /* Free attachment context...*/
    IMG_FREE(psAttachContext);

    /* Return success...*/
    return IMG_SUCCESS;
}
/*!
 ******************************************************************************

 @Function				DMANKM_OpenDevice

 ******************************************************************************/
IMG_RESULT DMANKM_OpenDevice(IMG_HANDLE hDevHandle, DMAN_eOpenMode eOpenMode,
		IMG_HANDLE * phConnHandle, IMG_UINT32 * pui32ConnId) 
{
	DMANKM_sDevContext * psDevContext = (DMANKM_sDevContext *) hDevHandle;
	DMANKM_sConnContext * psConnContext;
	DMANKM_sConnContext * psInitConnContext = IMG_NULL;
	IMG_UINT32 ui32Result;
	IMG_HANDLE hProcessId;

	/* Check mode. */
	if ((eOpenMode != DMAN_OMODE_EXCLUSIVE)
			&& (eOpenMode != DMAN_OMODE_SHARED)) {
		IMG_ASSERT(IMG_FALSE);
		return IMG_ERROR_INVALID_PARAMETERS;
	}

	/* Loop over the device connections to see if this process already has a connection...*/
	hProcessId = SYSOSKM_GetProcessId();
	psConnContext = (DMANKM_sConnContext *) LST_first(&psDevContext->sConnList);
	while (psConnContext != IMG_NULL ) {
		/* If process already has a connection. */
		if (psConnContext->hProcessId == hProcessId) {
			/* Update the open count...*/
			psConnContext->ui32OpenCnt++;

			/* Return the connection handle and/or id...*/
			if (phConnHandle != IMG_NULL ) {
				*phConnHandle = psConnContext;
			}
			if (pui32ConnId != IMG_NULL ) {
				*pui32ConnId = psConnContext->ui32ConnId;
			}

			/* Return success...*/
			return IMG_SUCCESS;
		}

		/* Look at next connection. */
		psConnContext = (DMANKM_sConnContext *) LST_next(psConnContext);
	}

	/* See if we have a connection exclusive access required or only exclusive access available. */
	psConnContext = (DMANKM_sConnContext *) LST_first(&psDevContext->sConnList);
	if ((psConnContext != IMG_NULL )&&
	( (eOpenMode == DMAN_OMODE_EXCLUSIVE) ||
			(psConnContext->psDevContext->sDevRegister.ui32ConnFlags == DMAN_CFLAG_EXCLUSIVE) )
	){
	IMG_ASSERT(IMG_FALSE);
	return IMG_ERROR_DEVICE_UNAVAILABLE;
}

	/* Allocate connection context...*/
	psConnContext = IMG_MALLOC(sizeof(*psConnContext));
	if (psConnContext == IMG_NULL ) 
    {
        IMG_ASSERT(psConnContext != IMG_NULL);
		return IMG_ERROR_OUT_OF_MEMORY;
	}
	IMG_MEMSET(psConnContext, 0, sizeof(*psConnContext));

	/* Initialise list of resource allocator...*/
	LST_init(&psConnContext->sAttachList);

	/* Setup connection context...*/
	psConnContext->psDevContext = psDevContext;
	psConnContext->ui32OpenCnt = 1;
	psConnContext->hProcessId = hProcessId;

	/* Update the count of connections...*/
	psDevContext->ui32ConnCnt++;

	/* If this is the first connection...*/
	if (psDevContext->ui32ConnCnt == 1) {
		/* Create resource bucket for connections and attachments...*/
		RMAN_Initialise();
		ui32Result = RMAN_CreateBucket(&psDevContext->hResBHandle);
		IMG_ASSERT(ui32Result == IMG_SUCCESS);
		if (ui32Result != IMG_SUCCESS) {
			goto error_create_bucket;
		}
	}

	/* Add to list of connections...*/
	LST_add(&psDevContext->sConnList, psConnContext);
	ui32Result = RMAN_RegisterResource(psDevContext->hResBHandle,
			DMAN_CONN_TYPE_ID, IMG_NULL, psConnContext,
			&psConnContext->hResHandle, &psConnContext->ui32ConnId);
	IMG_ASSERT(ui32Result == IMG_SUCCESS);
	if (ui32Result != IMG_SUCCESS) {
		goto error_register_resource;
	}

	/* Register with the Process Manager in case the process dies...*/
	ui32Result = PMAN_Initialise();
	IMG_ASSERT(ui32Result == IMG_SUCCESS);
	if (ui32Result != IMG_SUCCESS) {
		goto error_pman_init;
	}
	PMAN_RegisterProcessLostCb(dmankm_fnProcessLostCb, psConnContext,
			&psConnContext->hProcLostCbHandle);
	IMG_ASSERT(ui32Result == IMG_SUCCESS);
	if (ui32Result != IMG_SUCCESS) {
		goto error_pman_register_cb;
	}

	/* If this the first connection and initialise function...*/
	if ((psDevContext->ui32ConnCnt == 1)
			&& (psDevContext->sDevRegister.pfnDevInit != IMG_NULL )) {
		/* Allocate implicit connection context...*/
		psInitConnContext = IMG_MALLOC(sizeof(*psInitConnContext));
		if (psInitConnContext == IMG_NULL ) 
        {
            IMG_ASSERT(psInitConnContext != IMG_NULL);
			ui32Result = IMG_ERROR_OUT_OF_MEMORY;
			goto error_init_conn_ctx;
		}
		IMG_MEMSET(psInitConnContext, 0, sizeof(*psInitConnContext));

		/* Associated this connection with the device and process...*/
		psInitConnContext->psDevContext = psDevContext;
		psInitConnContext->ui32OpenCnt = 1;
		psInitConnContext->hProcessId = hProcessId;

		/* Mark this as the init connection...*/
		psInitConnContext->bInitConn = IMG_TRUE;

		/* Add implicit to list of connections...*/
		LST_add(&psDevContext->sConnList, psInitConnContext);
		ui32Result = RMAN_RegisterResource(psDevContext->hResBHandle,
				DMAN_CONN_TYPE_ID, IMG_NULL, psInitConnContext,
				&psInitConnContext->hResHandle, &psInitConnContext->ui32ConnId);
		IMG_ASSERT(ui32Result == IMG_SUCCESS);
		if (ui32Result != IMG_SUCCESS) {
			goto error_register_resource_init_ctx;
		}

		IMG_ASSERT(
				(psDevContext->sDevRegister.ui32ConnFlags == DMAN_CFLAG_EXCLUSIVE) || (psDevContext->sDevRegister.ui32ConnFlags == DMAN_CFLAG_SHARED));

		/* If it's not a pseudo device...  */
		if ((psDevContext->sDevRegister.ui32DevFlags & DMAN_DFLAG_PSEUDO_DEVICE)
				== 0) {
			/* Open the device...*/
			ui32Result = SYSDEVU_OpenDevice(psDevContext->pszDeviceName,
					&psDevContext->hSysDevHandle);
			IMG_ASSERT(ui32Result == IMG_SUCCESS);
			if (ui32Result != IMG_SUCCESS) {
				goto error_open_device;
			}

			/* Power the device on.  */
			SYSDEVU_SetPowerState(psDevContext->hSysDevHandle,
					SYSOSKM_POWERSTATE_S0, IMG_FALSE);
		}

		ui32Result = psDevContext->sDevRegister.pfnDevInit(psDevContext,
				psInitConnContext, &psDevContext->pvDevInstanceData);
		if (ui32Result != IMG_SUCCESS) {
			REPORT(REPORT_MODULE_DMAN, REPORT_ERR, "dev init failed (%d)",
				ui32Result);
			goto error_dev_init;
		}

		/* If there is a Device Kernel mode HISR...*/
		if (psDevContext->sDevRegister.pfnDevKmHisr != IMG_NULL ) {
			IMG_ASSERT(psDevContext->sDevRegister.pfnDevKmLisr != IMG_NULL);
			ui32Result = SYSOSKM_CreateKmHisr(&dmankm_fnDevKmHisr, psDevContext,
					&psDevContext->hHISRHandle);
			IMG_ASSERT(ui32Result == IMG_SUCCESS);
			if (ui32Result != IMG_SUCCESS) {
				goto error_create_km_hisr;
			}
		}

		/* If there is a Device Kernel mode LISR...*/
		if (psDevContext->sDevRegister.pfnDevKmLisr != IMG_NULL ) {
			/* Register the LISR wrapper...*/
			SYSDEVU_RegisterDevKmLisr(psDevContext->hSysDevHandle,
					&dmankm_fnDevKmLisr, psDevContext);
		}
	}

	/* If connect/open function...*/
	if (psDevContext->sDevRegister.pfnDevConnect != IMG_NULL ) {
		ui32Result = psDevContext->sDevRegister.pfnDevConnect(psConnContext,
				psDevContext->pvDevInstanceData,
				&psConnContext->pvDevConnectionData);
		IMG_ASSERT(
				ui32Result == IMG_SUCCESS || ui32Result == IMG_ERROR_INTERRUPTED);
		if (ui32Result != IMG_SUCCESS && ui32Result != IMG_ERROR_INTERRUPTED) {
			goto error_dev_connect;
		}
	}

	/* Return the connection handle and/or id...*/
	if (phConnHandle != IMG_NULL ) {
		*phConnHandle = psConnContext;
	}
	if (pui32ConnId != IMG_NULL ) {
		*pui32ConnId = psConnContext->ui32ConnId;
	}

	/* Return success...*/
	return ui32Result;

	/* Error handling. */
error_dev_connect:
	/* If this not the first connection or there's no initialise function...*/
	if ((1 != psDevContext->ui32ConnCnt)
			|| (IMG_NULL == psDevContext->sDevRegister.pfnDevInit)) {
		/* ...skip de-initialisation of this part. */
		goto error_init_conn_ctx;
	}

	if (IMG_NULL != psDevContext->sDevRegister.pfnDevKmHisr) {
		SYSOSKM_DestroyKmHisr(psDevContext->hHISRHandle);
	}

error_create_km_hisr:
	if (IMG_NULL
			!= psDevContext->sDevRegister.pfnDevDeinit) {
		psDevContext->sDevRegister.pfnDevDeinit(psDevContext, psInitConnContext,
				psDevContext->pvDevInstanceData);
	}

error_dev_init:
	if ((psDevContext->sDevRegister.ui32DevFlags
			& DMAN_DFLAG_PSEUDO_DEVICE) == 0) {
		SYSDEVU_CloseDevice(psDevContext->hSysDevHandle);
	}

error_open_device:
	RMAN_FreeResource(psInitConnContext->hResHandle);

error_register_resource_init_ctx:
	LST_remove(&psDevContext->sConnList, psInitConnContext);
	IMG_FREE(psInitConnContext);

error_init_conn_ctx:
	PMAN_RemoveProcessLostCb(psConnContext->hProcLostCbHandle);
	/* release per-process resources in PMAN, allocated inside
	   PMAN_RegisterProcessLostCb. We have to use device disconnect,
	   although the device wasn't actually initialised, because no
	   other function is exposed by PMAN */
	PMAN_DevDisconnectComplete(hProcessId);

error_pman_register_cb:
error_pman_init:
	RMAN_FreeResource(psConnContext->hResHandle);

error_register_resource:
	LST_remove(&psDevContext->sConnList,psConnContext);
	if (1 == psDevContext->ui32ConnCnt) {
		RMAN_DestroyBucket(psDevContext->hResBHandle);
	}

error_create_bucket:
	psDevContext->ui32ConnCnt--;
	IMG_FREE(psConnContext);

	return ui32Result;
}
/*!
 ******************************************************************************

 @Function				DMANKM_AttachComponent

 ******************************************************************************/
IMG_RESULT DMANKM_AttachComponent(IMG_HANDLE hConnHandle,
		IMG_CHAR * pszCompName, DMANKM_pfnCompAttach pfnCompAttach,
		IMG_HANDLE * phAttachHandle, IMG_UINT32 * pui32AttachId) 
{
	DMANKM_sConnContext * psConnContext = (DMANKM_sConnContext *) hConnHandle;
	IMG_BOOL bFound;
	DMANKM_sAttachContext * psAttachContext;
	IMG_UINT32 ui32Result;

	IMG_ASSERT(gDmanKmInitialised);

	/* See if this component is already register with this connection...*/
	bFound = dman_LocateComponentKM(pszCompName, psConnContext,
			&psAttachContext);
	if (bFound) {
		/* Cross check name and attach function should be the same...*/
		IMG_ASSERT(psAttachContext->pfnCompAttach == pfnCompAttach);

		/* Return the attachment handle and/or id...*/
		if (phAttachHandle != IMG_NULL ) {
			*phAttachHandle = psAttachContext;
		}
		if (pui32AttachId != IMG_NULL ) {
			*pui32AttachId = psAttachContext->ui32AttachId;
		}

		return IMG_SUCCESS;
	}

	/* Allocate a attachment context structure...*/
	psAttachContext = IMG_MALLOC(sizeof(*psAttachContext));
	if (psAttachContext == IMG_NULL ) 
    {
        IMG_ASSERT(psAttachContext != IMG_NULL);
		return IMG_ERROR_OUT_OF_MEMORY;
	}
	IMG_MEMSET(psAttachContext, 0, sizeof(*psAttachContext));

	/* Copy the component name etc...*/
	psAttachContext->pszCompName = IMG_STRDUP(pszCompName);
	if (psAttachContext->pszCompName == IMG_NULL ) 
    {
        IMG_ASSERT(psAttachContext->pszCompName != IMG_NULL);
		ui32Result = IMG_ERROR_OUT_OF_MEMORY;
		goto error_comp_name;
	}
	psAttachContext->pfnCompAttach = pfnCompAttach;
	psAttachContext->psConnContext = psConnContext;
	ui32Result = RMAN_CreateBucket(&psAttachContext->hResBHandle);
	IMG_ASSERT(ui32Result == IMG_SUCCESS);
	if (ui32Result != IMG_SUCCESS) {
		goto error_create_bucket;
	}

	/* Add to the attachment component list...*/
	LST_add(&psConnContext->sAttachList, psAttachContext);
	ui32Result = RMAN_RegisterResource(psConnContext->psDevContext->hResBHandle,
			DMAN_ATTACH_TYPE_ID, IMG_NULL, psAttachContext,
			&psAttachContext->hResHandle, &psAttachContext->ui32AttachId);
	IMG_ASSERT(ui32Result == IMG_SUCCESS);
	if (ui32Result != IMG_SUCCESS) {
		goto error_register_resource;
	}

	/* Call components attach function...*/
	ui32Result = pfnCompAttach(psAttachContext, &psAttachContext->sCompAttach);
	IMG_ASSERT(ui32Result == IMG_SUCCESS);
	if (ui32Result != IMG_SUCCESS) {
		goto error_comp_attach;
	}

	/* If connect/open function...*/
	if (psAttachContext->sCompAttach.pfnCompConnect != IMG_NULL ) {
		ui32Result = psAttachContext->sCompAttach.pfnCompConnect(
				psAttachContext, &psAttachContext->pvCompAttachmentData);
		IMG_ASSERT(ui32Result == IMG_SUCCESS);
		if (ui32Result != IMG_SUCCESS) {
			goto error_comp_connect;
		}
	}

	/* Return the attachment handle and/or id...*/
	if (phAttachHandle != IMG_NULL ) {
		*phAttachHandle = psAttachContext;
	}
	if (pui32AttachId != IMG_NULL ) {
		*pui32AttachId = psAttachContext->ui32AttachId;
	}

	/* Return success...*/
	return IMG_SUCCESS;

	/* Error handling. */
	error_comp_connect: error_comp_attach: RMAN_FreeResource(
			psAttachContext->hResHandle);
	error_register_resource: LST_remove(&psConnContext->sAttachList,
			psAttachContext);
	RMAN_DestroyBucket(psAttachContext->hResBHandle);
	error_create_bucket:
	IMG_FREE(psAttachContext->pszCompName);
	error_comp_name:
	IMG_FREE(psAttachContext);

	return ui32Result;
}
/*!
 ******************************************************************************

 @Function				DMANKM_DevDisconnectComplete

 ******************************************************************************/
IMG_RESULT DMANKM_DevDisconnectComplete(IMG_HANDLE hConnHandle) 
{
	IMG_UINT32 ui32Result;
	DMANKM_sConnContext * psConnContext = hConnHandle;
	DMANKM_sConnContext * psInitConnContext;
	DMANKM_sDevContext * psDevContext = psConnContext->psDevContext;
	IMG_HANDLE hProcessId;

	/* Disconnect components attached to this connection...*/
	ui32Result = dmankm_DisconnectComps(psConnContext);
	IMG_ASSERT(ui32Result == IMG_SUCCESS);
	if (ui32Result != IMG_SUCCESS) {
		return ui32Result;
	}

	/* Save the process id...*/
	hProcessId = psConnContext->hProcessId;

	/* Remove and free this connection...*/
	LST_remove(&psDevContext->sConnList, psConnContext);
	RMAN_FreeResource(psConnContext->hResHandle);
	IMG_FREE(psConnContext);

	/* Update the connection count...*/
	psDevContext->ui32ConnCnt--;

	/* If connection count 0...*/
	if (psDevContext->ui32ConnCnt == 0) {
		/* Deinitailise the device....*/
		psInitConnContext = (DMANKM_sConnContext *) LST_first(
				&psDevContext->sConnList);
        if(psInitConnContext == NULL)
        {
            IMG_ASSERT(psInitConnContext != IMG_NULL);
            return IMG_ERROR_GENERIC_FAILURE;
        }
        else
        {
            IMG_ASSERT(psInitConnContext->bInitConn);
        }

		/* Deregister the LISR...*/
		if (psDevContext->sDevRegister.pfnDevKmLisr != IMG_NULL ) {
			SYSDEVU_RemoveDevKmLisr(psDevContext->hSysDevHandle);
		}

		/* Deregister the HISR...*/
		if (psDevContext->sDevRegister.pfnDevKmHisr != IMG_NULL ) {
			if (psDevContext->hHISRHandle) {
				IMG_HANDLE HISRHandle = psDevContext->hHISRHandle;
				psDevContext->hHISRHandle = IMG_NULL;
				SYSOSKM_DestroyKmHisr(HISRHandle);
			}
		}

		/* If we have a deinitialise function...*/
		if (psDevContext->sDevRegister.pfnDevDeinit != IMG_NULL ) {
			psDevContext->sDevRegister.pfnDevDeinit(psDevContext,
					psInitConnContext, psDevContext->pvDevInstanceData);
		}

		if ((psDevContext->sDevRegister.ui32DevFlags & DMAN_DFLAG_PSEUDO_DEVICE)
				== 0) {
			/* Power the device off.  */
			SYSDEVU_SetPowerState(psDevContext->hSysDevHandle,
					SYSOSKM_POWERSTATE_S5, IMG_FALSE);
		}

		/* Disconnect components attached to the implicit connection...*/
		ui32Result = dmankm_DisconnectComps(psInitConnContext);
		IMG_ASSERT(ui32Result == IMG_SUCCESS);
		if (ui32Result != IMG_SUCCESS) {
			return ui32Result;
		}

		/* Remove and free the implicit connection...*/
		LST_remove(&psDevContext->sConnList, psInitConnContext);
		RMAN_FreeResource(psInitConnContext->hResHandle);
		IMG_FREE(psInitConnContext);

		/* Destroy the resource bucket used for connections and attachments...*/
		RMAN_DestroyBucket(psDevContext->hResBHandle);
		psDevContext->hResBHandle = IMG_NULL;

		/* If we opened the device with SYSDEVKM...*/
		if (psDevContext->hSysDevHandle != IMG_NULL ) {
			/* Close it...*/
			SYSDEVU_CloseDevice(psDevContext->hSysDevHandle);
			psDevContext->hSysDevHandle = IMG_NULL;
		}
	}

	/* Let the Process Manager know the connection has been broken...*/
	PMAN_DevDisconnectComplete(hProcessId);

	/* Unlock the device...*/
	DMANKM_UnlockDeviceContext(psDevContext);

	/* Return success...*/
	return IMG_SUCCESS;
}