📄 cha.c
字号:
/* 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 + -