⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 queue.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	{
		goto ErrorExit;
	}

	psQueueInfo->psNextKM = psSysData->psQueueList;
	psSysData->psQueueList = psQueueInfo;

	if (HostUnlockResource(&psSysData->hQProcessResource) != PVRSRV_OK)
	{
		goto ErrorExit;
	}


	/* setup the kicker address */
	psQueueInfo->pui32KickerAddr = psSysData->pui32KickerAddr;

	*ppsQueueInfo = psQueueInfo;

	if(HostNoResManOnThisProcess(HostGetCurrentProcessID()))
	{
		/* We can't do resource management on this process so just return */
		return PVRSRV_OK;
	}



	/* Require resource manager to track resource */
	psQueueInfo->psResItem = ResManRegisterRes((PRESMAN_ITEM)IMG_NULL, 
							                    RESMAN_TYPE_CMDQUEUE, 
												(IMG_VOID *)psQueueInfo,
												0, 
												DestroyCommandQueueCallBack, 
												RESMAN_AUTOFREE_LEV3);
	if (psQueueInfo->psResItem == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueue: Failed to register resource"));
		goto ErrorExit;
	}

	return PVRSRV_OK;
	
ErrorExit:

	if(psQueueInfo && psQueueInfo->pvLinQueueKM)
	{
		HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psQueueInfo->pvLinQueueKM);
	}

	if(psQueueInfo)
	{
		HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psQueueInfo);
	}
	
	return PVRSRV_ERROR_GENERIC;
}


/*!
******************************************************************************

 @Function	PVRSRVDestroyCommandQueue
 
 @Description 
 Destroys a command queue.
 
 @Input    psDevData : 

 @Input    psQueueInfo : 

 @Return   PVRSRV_ERROR  : 

******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueue(PVRSRV_DEV_DATA *psDevData, PVRSRV_QUEUE_INFO *psQueueInfo)
{
	PVRSRV_ERROR 	eError;

	if(psQueueInfo->psResItem)
	{
		eError = ResManFreeResByPtr(psQueueInfo->psResItem);
	}
	else
	{	
		/* Resource not managed call the free callback directly */
		eError = DestroyCommandQueueCallBack(0,(IMG_PVOID)psQueueInfo, 0);
	}

	return(eError);	
}



/***************************************************************************** 
	Kernel-only functions
******************************************************************************/


/*!
******************************************************************************

 @Function	ProcessLock
 
 @Description 
 
 processes a lock command from a Q
 
 @Input	   psDevInfo	- device info structure
 
 @Input	   psQueue		- for ROff update
 
 @Input	   psLockCmd	- Lock command info

 @Return   none 

******************************************************************************/
IMG_VOID ProcessLock (PVRSRV_DEV_INFO		*psDevInfo, 
					  PVRSRV_QUEUE_INFO		*psQueue,
					  PVRSRV_LOCK_CMD_INFO	*psLockCmd)
{
	if(psLockCmd->bLockSurface)
	{
		if ((*psLockCmd->psSyncInfoKM->pui32LastWriteOp == psLockCmd->ui32NextWriteOpVal - 1) 
			&& (psLockCmd->psSyncInfoKM->ui32ReadOpsComplete == psLockCmd->ui32ReadOpsPending)
		   )
		{
			/* Open the event for interprocess communication then set it */
			HostOpenEvent(&psLockCmd->hWaitEventHandle);
			HostSetEvent(psLockCmd->hWaitEventHandle);

			/*
				Locks can happen, so all read ops complete.
				Reset read count
			*/
			psLockCmd->psSyncInfoKM->ui32ReadOpsComplete = 0;

			/* update the ROff */
			UPDATE_QUEUE_ROFF(psQueue, psLockCmd->sCmdInfo.ui32Size);
		}
	}
	else /* Unlock */
	{
		(*psLockCmd->psSyncInfoKM->pui32LastWriteOp)++;

		/*
			If the lock is on the primary we must update
			the Single shot display (if there is one)
		*/
		if (psLockCmd->bPrimary)
		{
#if FIXME
			PDP_ScreenUpdate(g_PDPHandle);
#endif
		}

		/* Open the event for interprocess communication then set it */
		HostOpenEvent(&psLockCmd->hWaitEventHandle);

		/*
			Signal threads waiting on unlock
		*/
		HostSetEvent(psLockCmd->hWaitEventHandle);
		if(HostReleaseEvent(psLockCmd->hWaitEventHandle) != PVRSRV_OK)
		{
			PVR_ASSERT(0);
		}


		/* update the ROff */
		UPDATE_QUEUE_ROFF(psQueue, psLockCmd->sCmdInfo.ui32Size);
	}
}


/*!
******************************************************************************

 @Function	ProcessDummyLock
 
 @Description 
 
 does dummy processing on a lock command from a Q
 
 @Input	   psDevInfo	- device info structure
 
 @Input	   psQueue		- for ROff update
 
 @Input	   psLockCmd	- Lock command info

 @Return   none 

******************************************************************************/
IMG_VOID ProcessDummyLock (PVRSRV_DEV_INFO		*psDevInfo, 
					  PVRSRV_QUEUE_INFO		*psQueue,
					  PVRSRV_LOCK_CMD_INFO	*psLockCmd)
{
	if(psLockCmd->bLockSurface)
	{
		if ((*psLockCmd->psSyncInfoKM->pui32LastWriteOp == psLockCmd->ui32NextWriteOpVal - 1) 
			&& (psLockCmd->psSyncInfoKM->ui32ReadOpsComplete == psLockCmd->ui32ReadOpsPending)
		   )
		{
			HostSetEvent(psLockCmd->hWaitEventHandle);

			/* update the ROff */
			UPDATE_QUEUE_ROFF(psQueue, psLockCmd->sCmdInfo.ui32Size);
		}
	}
	else /* Unlock */
	{
		(*psLockCmd->psSyncInfoKM->pui32LastWriteOp)++;

		/*
			Signal threads waiting on unlock
		*/
		HostSetEvent(psLockCmd->hWaitEventHandle);
		if(!HostReleaseEvent(psLockCmd->hWaitEventHandle))
		{
			PVR_ASSERT(0);
		}
		/* update the ROff */
		UPDATE_QUEUE_ROFF(psQueue, psLockCmd->sCmdInfo.ui32Size);
	}
}



/*!
******************************************************************************

 @Function	PVRSRVProcessQueues
 
 @Description 
 
 tries to process a command from each Q
 
 @Input	   psDevInfo	- device info structure

 @Return   PVRSRV_ERROR 

******************************************************************************/
#if defined (HOST_REG_UPDATE_WORKAROUND)
/* 
	FIXME, workaround for instability issue where expected value in not in
	the expected place.
*/
PVRSRV_QUEUE_INFO 	*psQueueStore;
#endif /*HOST_REG_UPDATE_WORKAROUND*/

IMG_EXPORT
PVRSRV_ERROR PVRSRVProcessQueues(PVRSRV_DEV_INFO *psDevInfo)
{
	PVRSRV_QUEUE_INFO 	*psQueue;
	SYS_DATA			*psSysData;
	PVRSRV_CMD_HEADER 	*psCmdHeader;
	PVRSRV_ERROR		eError;
	IMG_VOID 			(*pfnProcessCommands) ( PPVRSRV_DEV_INFO, PVRSRV_QUEUE_INFO*, PVRSRV_CMD_HEADER*);
	
	eError = SysAcquireData(&psSysData);
	if (eError != PVRSRV_OK)
	{
		return eError;
	}
	
	/* Ensure we don't corrupt queue list, by blocking access */
	if(HostLockResource(&psSysData->hQProcessResource, IMG_FALSE) != PVRSRV_OK)
	{	
		PVR_DPF((PVR_DBG_MESSAGE,"Couldn't acquire queue processing mutex. Returning"));
		return PVRSRV_OK;
	}

	psQueue = psSysData->psQueueList;

	if(!psQueue)
		PVR_DPF((PVR_DBG_MESSAGE,"No Queues installed - cannot process commands"));

	/* dummy command processing? */
	if(psSysData->bDummyProcessing || psDevInfo->bDummyProcessing)
	{
		pfnProcessCommands = psDevInfo->pfnDummyProcessCommands;
	}
	else
	{
		pfnProcessCommands = psDevInfo->pfnProcessCommands;
	}

	/*! @todo rotate the order of processing for multiple queues */
	while (psQueue)
	{
#if defined (HOST_REG_UPDATE_WORKAROUND)
		/* FIXME: This is a workaround for the instability */
		volatile PVRSRV_QUEUE_INFO * psQueueVol; 
#endif /*HOST_REG_UPDATE_WORKAROUND*/

		psCmdHeader = (PVRSRV_CMD_HEADER *)((IMG_UINT32)psQueue->pvLinQueueKM + psQueue->ui32ReadOffset);

		if (psQueue->ui32ReadOffset != psQueue->ui32WriteOffset)
		{
			pfnProcessCommands(psDevInfo, psQueue, psCmdHeader);
		}

#if !defined (HOST_REG_UPDATE_WORKAROUND)
		psQueue = psQueue->psNextKM;
#else /*HOST_REG_UPDATE_WORKAROUND*/
		/* FIXME: This is a workaround for the instability */
		psQueueVol = psQueue;
		psQueue = psQueue->psNextKM;
		psQueueStore = psQueue;
		psQueue = psQueueVol->psNextKM;
#endif /*HOST_REG_UPDATE_WORKAROUND*/
	}

	return HostUnlockResource(&psSysData->hQProcessResource);
}

#endif /* QUEUE_C */

/*****************************************************************************
 End of file (queue.c)
*****************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -