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

📄 cha.c

📁 vxworks中的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Function Name: ReleaseCha											  */
/* Purpose:  To release 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									  */
/*        locked - TRUE or FALSE										  */
/* Return: MPCPQ27e_SUCCESS if success otherwise the error code			  */
/**************************************************************************/
int ReleaseCha(unsigned long channelCha, int callingTaskId, BOOLEAN locked)
{
	unsigned char channel = (unsigned char)((channelCha >> 8) & 0xFF);
	unsigned char chaType = (unsigned char)(channelCha & 0xFF);
	unsigned long chaStatus[2] = {0,0};
	unsigned long temp[2] = {0,0};
	int cha;
	int numChas=0;

	MPCPQ27eDump(MPCINITDEV, ("ReleaseCha(0x%x,0x%x,%d)\n", (unsigned int)channelCha,
	                      (unsigned int) callingTaskId, (int)locked));
	/* check chaType value */
	if ((chaType != CHA_AFHA) && (chaType != CHA_DES) && (chaType != CHA_MDHA)
		&& (chaType != CHA_RNG) && (chaType != CHA_PKHA)
		&& (chaType != CHA_AESA) && (chaType != CHA_KEA)
					)
		return (MPCPQ27e_INVALID_CHA_TYPE);

	if (!locked)
		IOLockChannelAssignment();

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

	/* determine number of CHAs for the chaType */
	switch (chaType)
	{
	case CHA_AFHA:
		numChas = NUM_AFHAS;
		break;
	case CHA_DES:
		numChas = NUM_DESAS;
		break;
	case CHA_MDHA:
		numChas = NUM_MDHAS;
		break;
	case CHA_RNG:
		numChas = NUM_RNGAS;
		break;
	case CHA_PKHA:
		numChas = NUM_PKHAS;
		break;
	case CHA_AESA:
		numChas = NUM_AESAS;
		break;
	case CHA_KEA:
		numChas = NUM_KEAS;
		break;
	}

	/* find the CHA to release */
	for (cha=chaType; cha<(chaType+numChas); cha++)
	{
		/* see if the CHA is assigned to the given channel */
		if (ChaAssignments[cha] == channel)
		{
			/* found a CHA assigned to the given channel */
			/* release the CHA */
			IORead(chaStatus, 2, ChaAssignmentStatusRegister);

			if (cha < 4)
			{
				chaStatus[0] &= (~(0xF << (cha * 8)));
				ChaAssignments[cha] = CHA_DYNAMIC;
			}
			else
			{
				chaStatus[1] &= (~(0xF << ((cha - 4) * 8)) << 16);
				ChaAssignments[cha] = CHA_DYNAMIC;
			}
			IOWrite(chaStatus, 2, ChaAssignmentControlRegister);

			/* reset the CHA */
			temp[0] = CHA_MODULE_INIT;
			temp[1] = 0;
			IOWrite(temp, 2, ChaResetControlRegister[cha_idx[cha]]);
			IORead(temp, 2, ChaResetControlRegister[cha_idx[cha]]);
			break;
		}
	}

	/* see if we found a CHA to release */
	if (cha >= (chaType + numChas))
	{
		/* we didn't find a CHA to release, return an error */
		if (!locked)
			IOUnLockChannelAssignment();
		return (MPCPQ27e_INVALID_CHA_TYPE);
	}

	/* if channel is in manual mode, disable 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;
	}

	if (!locked)
	{
		IOUnLockChannelAssignment();

		/* schedule queued requests on any freed CHAs */
		ScheduleNext();
	}

	return (MPCPQ27e_SUCCESS);
} /* End of ReleaseCha */

/****************************************************************/
/* Function Name: ChaNumToType									*/
/* Purpose: To translate the the CHA number to the CHA chaType	*/
/* Input: cha - CHA Number										*/
/* Output: ChaType												*/
/****************************************************************/
int ChaNumToType(int cha)
{
	switch (cha)
	{
	case CHA_AFHA:
		return (CHA_AFHA);
	case CHA_DES:
		return (CHA_DES);
	case CHA_MDHA:
		return (CHA_MDHA);
	case CHA_RNG:
		return (CHA_RNG);
	case CHA_PKHA:
		return (CHA_PKHA);
	case CHA_AESA:
		return (CHA_AESA);
	case CHA_KEA:
		return (CHA_KEA);
	default:
		return (MPCPQ27e_INVALID_CHA_TYPE);
	}
} /* End of ChaNumToType */

/********************************************************************/
/* Function Name: ReleaseChannel									*/
/* Purpose:  To free a reserved channel (either a static channel	*/
/*				or a manual channel.)								*/
/* Input: channel - the channel number (1-4)						*/	
/*		  callingTaskId - the task id								*/
/*        locked - TRUE or FALSE									*/
/* Return: MPCPQ27e_SUCCESS if success otherwise the error code		*/
/********************************************************************/
int ReleaseChannel(unsigned long channel, int callingTaskId, BOOLEAN locked)
{
	int cha, chaType;

	MPCPQ27eDump(MPCINITDEV, ("ReleaseChannel(%d,0x%x,%d)\n", 
	                  (unsigned int)channel, (unsigned int)callingTaskId,(int) locked));
	/* check channel value */
	if ((channel == 0) || (channel > NUM_CHANNELS)) return (MPCPQ27e_INVALID_CHANNEL);

	if (!locked)
		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 is not reserved */
		if (!locked)
			IOUnLockChannelAssignment();
#ifdef DBG
		printf("channel=%d,assignment=%d,ownerTaskId=0x%x\n",
			(int)   channel,
		      (int)ChannelAssignments[channel - 1].assignment,
		(unsigned int) ChannelAssignments[channel - 1].ownerTaskId);
#endif
		return (MPCPQ27e_INVALID_CHANNEL);
	}

	/* check that calling task is the channel's owner */
	if (ChannelAssignments[channel - 1].ownerTaskId != callingTaskId)
	{
		/* error, caller is not the channel owner */
		if (!locked)
			IOUnLockChannelAssignment();
		return (MPCPQ27e_INVALID_CHANNEL);
	}

	/* release all cha's assigned to this channel */
	for (cha=0; cha<16; cha++)
	{
		if (ChaAssignments[cha] == (unsigned char) channel)
		{
			/* determine cha type from cha number */
			chaType = ChaNumToType(cha);
			/* release the cha */
			ReleaseCha((channel << 8) | chaType, callingTaskId, TRUE);
		}
	}

	FreeChannels++;

	/* release the channel */
	ChannelAssignments[channel - 1].assignment = CHANNEL_FREE;

	if (!locked)
	{
		IOUnLockChannelAssignment();

		/* schedule queued requests on any freed channels */
		ScheduleNext();
	}

	return (MPCPQ27e_SUCCESS);
} /* end of ReleaseChannel */

/* this should only be called with channel assignments locked */
/********************************************************************/
/* Function Name: CheckChas											*/
/* Purpose: Check to see if the CHA is available (at least one of	*/
/*          this type of CHA is available)							*/
/* Input: The opId requested										*/
/* Output: MPCPQ27e_SUCCESS if this type of CHA is available			*/
/*         otherwise the error code									*/
/********************************************************************/
int CheckChas(unsigned long OpId)
{
	unsigned int chaType = 0;
	switch (OpId & 0xf000)
	{
	case 0x1000:						/* RNG Group */
		chaType |= CHA_RNGA_BITMASK;
		break;
	case 0x2000:						/* Des Groups */
		chaType |= CHA_DESA_BITMASK;
		break;
	case 0x3000:						/* RC4 Groups */
		chaType |= CHA_AFHA_BITMASK;
		break;
	case 0x4000:						/* MD Groups */
		chaType |= CHA_MDHA_BITMASK;
		break;
	case 0x5000:						/* PK Groups */
		chaType |= CHA_PKHA_BITMASK;
		break;
	case 0x6000:						/* AES Groups */
		chaType |= CHA_AESA_BITMASK;
		break;
	case 0x7000:						/* ipsec Des + MD Groups */
		chaType |= (CHA_MDHA_BITMASK | CHA_DESA_BITMASK);
		break;
	case 0x8000:						/* ipsec aes + md groups */
		chaType |= (CHA_MDHA_BITMASK | CHA_AESA_BITMASK);
		break;
	case 0xa000:						/* Kasumi groups */
		chaType |= CHA_KEA_BITMASK;
		break;

	default:
		/* invalid opId */
		return (MPCPQ27e_INVALID_OPERATION_ID);
	}
	if (((chaType & CHA_AFHA_BITMASK) != 0) && (FreeAfhas == 0)) 
	{
		return (MPCPQ27e_CHA_NOT_AVAILABLE);
	}
	else if (((chaType & CHA_DESA_BITMASK) != 0) && (FreeDesas == 0))
	{
		return (MPCPQ27e_CHA_NOT_AVAILABLE);
	}
	else if (((chaType & CHA_MDHA_BITMASK) != 0) && (FreeMdhas == 0)) 
	{
		return (MPCPQ27e_CHA_NOT_AVAILABLE);
	}
	else if (((chaType & CHA_RNGA_BITMASK) != 0) && (FreeRngas == 0)) 
	{
		return (MPCPQ27e_CHA_NOT_AVAILABLE);
	}
	else if (((chaType & CHA_PKHA_BITMASK) != 0) && (FreePkhas == 0)) 
	{
		return (MPCPQ27e_CHA_NOT_AVAILABLE);
	}
	else if (((chaType & CHA_AESA_BITMASK) != 0) && (FreeAesas == 0)) 
	{
		return (MPCPQ27e_CHA_NOT_AVAILABLE);
	}
	else if (((chaType & CHA_KEA_BITMASK) != 0) && (FreeKeas == 0)) 
	{
		return (MPCPQ27e_CHA_NOT_AVAILABLE);
	}

	/* CHA(s) are available, return OK */
	return (MPCPQ27e_SUCCESS);
}

⌨️ 快捷键说明

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