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

📄 cha.c

📁 vxworks中的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * cha.c -- Channel/CHA operations code for MPCPQ27e Driver 
 * 
 Revision History:
 *			
 */
#include "MPCPQ27eDriver.h"

/********************************************************************/
/* Function Name: ReserveChannelStatic 				    */
/* Purpose:  To allocate a channel for use by a single task.        */
/* Input: channel - the channel number (1-4)			    */	
/*		  callingTaskId - the task id			    */
/* Output: channel - the channel number that allocated		    */
/* Return: MPCPQ27e_SUCCESS if success otherwise the error code	    */
/********************************************************************/
int ReserveChannelStatic(PULONG channel, int callingTaskId)
{
	unsigned long chan;
		
	MPCPQ27eDump(MPCINITDEV, ("ReserveChannelStatic\n")); 

	IOLockChannelAssignment(); /*semaphore take*/

	/* look for a free channel */
	for (chan=0; chan<NUM_CHANNELS; chan++)
	{
		MPCPQ27eDump(MPCINITDEV, ("ReserveChannelStatic chan=%d\n", (int)chan));

		if (ChannelAssignments[chan].assignment == CHANNEL_FREE)
		{
			/* found a free channel, make it static */
			ChannelAssignments[chan].assignment = CHANNEL_STATIC_ASSIGNED;
			MPCPQ27eDump(MPCINITDEV, ("ReserveChannelStatic found a free channel\n"));

			FreeChannels--;

			/* set the channel's owner task ID */
			ChannelAssignments[chan].ownerTaskId = callingTaskId;
			IOUnLockChannelAssignment();
			/* set return value */
			
			*channel = chan+1;
			MPCPQ27eDump(MPCINITDEV, ("ReserveChannelStatic->*channel=%d\n", (int)*channel));
			return (MPCPQ27e_SUCCESS);
		}
	}

	IOUnLockChannelAssignment();

	/* we didn't find a free channel */
	MPCPQ27eDump(MPCINITDEV, ("ReserveChannelStatic->we didn't find a free channel\n"));
	return (MPCPQ27e_CHANNEL_NOT_AVAILABLE);
}

/************************************************************************/
/* Function Name: ReserveChannelManual									*/
/* Purpose:  To reserve a crypto channel for use in manual/debug mode	*/
/* Input: reserve - the MPCPQ27e_RESERVE_MANUAL structure					*/
/*		  callingTaskId - the task id									*/
/* Output: reserve->channel - the channel Id if success					*/       
/* Return: MPCPQ27e_SUCCESS if success otherwise the error code			*/
/************************************************************************/
int ReserveChannelManual(MPCPQ27e_RESERVE_MANUAL *reserve, int callingTaskId)
{
	int channel;

	MPCPQ27eDump(MPCINITDEV, ("ReserveChannelManual\n"));
	
	IOLockChannelAssignment();

 	/* look for a free channel */
	for (channel=0; channel<NUM_CHANNELS; channel++)
	{
		if (ChannelAssignments[channel].assignment == CHANNEL_FREE)
		{
			/* found a free channel, make it manual */
			MPCPQ27eDump(MPCINITDEV, ("ReserveChannelManual->FreeChannel=%d\n",(int)channel));
			ChannelAssignments[channel].assignment = CHANNEL_MANUAL;

			FreeChannels--;

			/* set the channel's owner task ID */
			ChannelAssignments[channel].ownerTaskId = callingTaskId;

			IOUnLockChannelAssignment();
			/* set return value */
			MPCPQ27eDump(MPCINITDEV, ("ReserveChannelManual->(reserve->channel)=%d\n", (int)channel+1));
			*(reserve->channel) = channel + 1;
			MPCPQ27eDump(MPCINITDEV, ("ReserveChannelManual->Return\n"));
			return (MPCPQ27e_SUCCESS);
		}
	}

	IOUnLockChannelAssignment();

	/* we didn't find a free channel */
	MPCPQ27eDump(MPCINITDEV, ("ReserveChannelManual->we didn't find a free channel\n"));
	return (MPCPQ27e_CHANNEL_NOT_AVAILABLE);
}

/**************************************************************************/
/* Function Name: AssignCha												  */
/* Purpose:  To reserve a specific CHA for use by either a static channel */
/*				or a manual channel.									  */
/* Input: channelCha - the bottom eight bits is the CHA chaType			  */
/*					   the next eight bits is the channel number (1-4)	  */	
/*		  callingTaskId - the task id									  */
/* Return: MPCPQ27e_SUCCESS if success otherwise the error code			  */
/**************************************************************************/
int AssignCha(unsigned long channelCha, int callingTaskId)
{
	unsigned char channel = (unsigned char)((channelCha >> 8) & 0xFF);
	unsigned char chaType = (unsigned char)(channelCha & 0xFF);
	unsigned long chaStatus[2] = {0,0};
	unsigned long chaAssignment;
	unsigned long temp[2] = {0,0};
	unsigned long cha;
	int chasLeft=0;
	int numChas=0;
	int chaBitMask;
	GENERIC_REQ *request;

	MPCPQ27eDump(MPCINITDEV, ("AssignCha channel=%d chaType=0x%x\n",channel,chaType));

	/* check channel value */
	if ((channel == 0) || (channel > (unsigned char) NUM_CHANNELS))
		return (MPCPQ27e_INVALID_CHANNEL);

	/* check chaType value */
	if ((chaType != CHA_AFHA) && (chaType != CHA_DES) && (chaType != CHA_MDHA)
		&& (chaType != CHA_RNG) && (chaType != CHA_PKHA)
		&& (chaType != CHA_AESA)

			)
		return (MPCPQ27e_INVALID_CHA_TYPE);

	IOLockChannelAssignment();

	/* check that requested channel is either static or manual */
	if ((ChannelAssignments[channel - 1].assignment != CHANNEL_STATIC_ASSIGNED) &&
		(ChannelAssignments[channel - 1].assignment != CHANNEL_MANUAL))
	{
		/* error, channel assignment is wrong */
		IOUnLockChannelAssignment();
		return (MPCPQ27e_INVALID_CHANNEL);
	}

	/* check that callingTaskId matches channel owner */
	if (callingTaskId != ChannelAssignments[channel - 1].ownerTaskId)
	{
		/* error, channel is not owned by the caller */
		IOUnLockChannelAssignment();
		return (MPCPQ27e_INVALID_CHANNEL);
	}

	/* check how many non-static CHAs of this type are left */
	switch (chaType)
	{
	case CHA_AFHA:
		chasLeft = FreeAfhas;
		numChas = NUM_AFHAS;
		chaBitMask = CHA_AFHA_BITMASK;
		break;
	case CHA_DES:
		chasLeft = FreeDesas;
		numChas = NUM_DESAS;
		chaBitMask = CHA_DESA_BITMASK;
		break;
	case CHA_MDHA:
		chasLeft = FreeMdhas;
		numChas = NUM_MDHAS;
		chaBitMask = CHA_MDHA_BITMASK;
		break;
	case CHA_RNG:
		chasLeft = FreeRngas;
		numChas = NUM_RNGAS;
		chaBitMask = CHA_RNGA_BITMASK;
		break;
	case CHA_PKHA:
		chasLeft = FreePkhas;
		numChas = NUM_PKHAS;
		chaBitMask = CHA_PKHA_BITMASK;
		break;
	case CHA_AESA:
		chasLeft = FreeAesas;
		numChas = NUM_AESAS;
		chaBitMask = CHA_AESA_BITMASK;
		break;
	case CHA_KEA:
		chasLeft = FreeKeas;
		numChas = NUM_KEAS;
		chaBitMask = CHA_KEA_BITMASK;
		break;
	}

	/* check to see that there is at least one CHA left */
	if (chasLeft == 0)
	{
		/* no CHAs left to assign, return error */
		IOUnLockChannelAssignment();
		return (MPCPQ27e_CHA_NOT_AVAILABLE);
	}
	else if (chasLeft == 1)
	{
		/* check to see if there are dynamic requests for this CHA in the queue */
		request = ProcessQueueTop->pReq;
		while (request != NULL)
		{
			if (CheckChas(request->opId) != 0)
			{
				/* found a queued request that requires the last non-static CHA */
				IOUnLockChannelAssignment();
				return (MPCPQ27e_CHA_NOT_AVAILABLE);
			}
			/* move to next request in the queue */
			request = ProcessQueueTop->next->pReq;
		}
	}

	/* read CHA assignment status register */
	IORead(chaStatus, 2, ChaAssignmentStatusRegister);

	/* at least one CHA of this type is potentially available */
	/*
	  cha=0 , AFEU
	  cha=1 , MDEU
	  cha=2 , PKEU
	  cha=3 , RNG 
	  cha=4 , AESU
	  cha=5 , DEU
	 */
	for (cha=chaType; cha<(chaType+numChas); cha++)
	{
		if (ChaAssignments[cha] == CHA_DYNAMIC)
		{

			/* found a potentially free CHA, check the CHA assignment register */
			if (cha < 4) 					/* 4 chas per status word */
			{
				/* cha is in lower half of cha status */
				chaAssignment = 0xF << (cha * 8);
				if ((chaStatus[0] & chaAssignment) != 0)
				{
					/* this CHA is being used dynamically, try next CHA */
					continue;
				}
				else
				{
					/* cha is not in use, assign it */
					/* set flag to indicate attempting CHA assignment ??? */
			
					chaStatus[0] |= (channel << (cha * 8));
					IOWrite(chaStatus, 2, ChaAssignmentControlRegister);
					ChaAssignments[cha] = channel;
					break;
				}
			}
			else
			{
				/* cha is in upper half of cha status */
				chaAssignment = (0xF << ((cha - 4) * 8)) << 16;
				if ((chaStatus[1] & chaAssignment) != 0)
				{
					/* this CHA is being used dynamically, try next CHA */
					continue;
				}
				else
				{
					/* cha is not in use, assign it */
					/* set flag to indicate attempting CHA assignment ??? */

					chaStatus[1] |= (channel << ((cha - 4) * 8)) << 16;
					IOWrite(chaStatus, 2, ChaAssignmentControlRegister);
					ChaAssignments[cha] = channel;
					break;
				}
			}
		}
	}

	/* see if we were successful */
	if (cha >= (chaType + numChas))
	{
		/* we didn't find a non-busy CHA, return an error */
		IOUnLockChannelAssignment();
		return (MPCPQ27e_CHA_NOT_AVAILABLE);
	}

	/* check that assignment was successful (check flag) ??? */

	/* wait until here to make ChaAssignment[cha] update ??? */

	/* if channel is in manual mode, enable the CHA done interrupt */
	if (ChannelAssignments[channel].assignment == CHANNEL_MANUAL)
	{
		/* read current interrupt enables */
		IORead(temp, 2, InterruptControlRegister);
		/* set CHA interrupt for this CHA */
		temp[1] |= (0x1 << (2*cha));
		/* write data back to interrupt control register */
		IOWrite(temp, 2, InterruptControlRegister);
	}

	/* update free CHA counts */
	switch (chaType)
	{
		case CHA_AFHA:
			FreeAfhas--;
			break;
		case CHA_DES:
			FreeDesas--;
			break;
		case CHA_MDHA:
			FreeMdhas--;
			break;
		case CHA_RNG:
			FreeRngas--;
			break;
		case CHA_PKHA:
			FreePkhas--;
			break;
		case CHA_AESA:
			FreeAesas--;
			break;
		case CHA_KEA:
			FreeKeas--;
			break;
	}

	IOUnLockChannelAssignment();

	return (MPCPQ27e_SUCCESS);
} /* AssignCha */

/**************************************************************************/

⌨️ 快捷键说明

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