📄 sec2isr.c
字号:
/**************************************************************************** * sec2isr.c -- The Interrupt Service code for SEC2 Driver **************************************************************************** * Copyright (c) Certicom Corp. 1996-2002. All rights reserved * Copyright (c) 2003, 2004 Freescale Semiconductor * All Rights Reserved. Proprietary and Confidential. * * NOTICE: The information contained in this file is proprietary * to Freescale Semiconductor, and is being made available to * Freescale's customers under strict license agreements. * Use or disclosure of this information is permissible only * under the terms of the existing license agreement. ****************************************************************************//* * Revision History: * 1.0 Aug 24,2003 dgs - adapted from the final version of mpc18x * May 12,2004 sec - turned on some windview events for debug * Jun 06,2004 sec - corrected channel reset logic * Jun 10,2004 sec - remove superfluous I/O calls * Jul 22,2004 sec - added double CHA reset to handle errata * 1.1.0 Nov 16,2004 sec - updated for linux change merge from prior revs * 1.1.1 Dec 16,2004 sec - cleanup, remove unused diagnostics * 1.2 Jan 27,2005 */#include <stdio.h>#include "drvlib/include/drv_comm.h"#include "sec2Driver.h"#include "sec2_const.h"#include "ipsec_request.h"UINT32 sec2_ITO_times = 0;UINT32 sec2_doneoverflow_times = 0;/************************************************************************** * Function Name: sec2_InterruptServiceRoutine * Purpose: To handle all interrupt generated by Channel or CHA (Done or Error) * indicated by the Interrupt Status Register * If Error, clean the sec2_InterruptStatusRegister by writing sec2_InterruptClearRegister * If Done, call ProcessRequestDone routine * Input: Interrupt - PKINTERRUPT * Context - PVOID the request Context * *************************************************************************/void sec2_InterruptServiceRoutine(void){ register int channel; unsigned long temp[2]; unsigned long intStatus0, intStatus1; register GENERIC_REQ* req = (GENERIC_REQ*)NULL; /* save interrupt status register for the Sec2_ProcessingComplete */ /*保存中断状态寄存器*/ intStatus0 = *(sec2_InterruptStatusRegister); intStatus1 = *(sec2_InterruptStatusRegister + 1); if (((intStatus0 & DONE_OVERFLOW ) == 0) && ((intStatus0 & INTERNAL_TIME_OUT ) == 0) && ((intStatus0 & ALL_CHANNEL_INT_DONE_MASK ) == 0) && ((intStatus0 & ALL_CHANNEL_INT_ERROR_MASK ) == 0)) { pgsec2_global_debug->last_status0 = intStatus0; pgsec2_global_debug->last_status1 = intStatus1; pgsec2_global_debug->unknown_isr_cnt++; } pgsec2_global_debug->isr_out++; /*异常中断,暂时纪录发生次数*/ if(intStatus0 & DONE_OVERFLOW) { sec2_doneoverflow_times++; } if(intStatus0 & INTERNAL_TIME_OUT) { sec2_ITO_times++; } /* deal with any channel done interrupts */ /*通道发生完成中断*/ if ((intStatus0 & ALL_CHANNEL_INT_DONE_MASK) != 0) { /* found at least one channel done interrupt */ for (channel = 0; channel < SEC2_NUM_CHANNELS; channel++) { if ((intStatus0 & Sec2ChannelDoneInterruptMasks[channel]) != 0) { pgsec2_channel_debug[channel].channel_SuccCnt++; /* found a channel done interrupt */ req = Sec2_ChannelAssignments[channel].pReq; ((GENERIC_REQ*)req)->status = SEC2_SUCCESS; /*加入sec2的fwd缓存队列*/ if(SEC2_SUCCESS == sec2_addfwdQueue(req,Sec2_ChannelAssignments[channel].ownerTaskId)) { /*如果下行对列不为空,不释放通道,继续处理*/ if (SEC2_SUCCESS != Sec2_ScheduleQueue(channel)) { sec2_CompleteRequest(channel, SEC2_SUCCESS); Sec2_ChannelAssignments[channel].pReq = (GENERIC_REQ *)NULL; } else { /* 去pc-lint warning */ } } else { pgsec2_channel_debug[channel].channel_WaitCnt++; /*注意:可能导致死锁,完全依赖队列的大小,危险 yuhongtao*/ /*不释放通道*/ Sec2_ChannelAssignments[channel].assignment = CHANNEL_WAIT; } } } } /* check for error interrupts, was there any error? */ /*错误中断处理*/ if ((intStatus0 & ALL_CHANNEL_INT_ERROR_MASK) /*||(intStatus1 & ALL_INT_ERRORS_MASK_HIGH)*/) { /* look at the channel error interrupts next */ /*只观察通道是否产生错误中断*/ for (channel = 0; channel < SEC2_NUM_CHANNELS; channel++) { if (intStatus0 & Sec2ChannelErrorInterruptMasks[channel]) { pgsec2_channel_debug[channel].channel_ErrCnt++; /* reset the channel */ /*因为有错误中断,清除通道配置寄存器*/ *(sec2_ChannelConfigRegister[channel]) = (unsigned long)CHANNEL_RESET; *(sec2_ChannelConfigRegister[channel] + 1) = (unsigned long)0; /* give the hardware a chance to clock... */ temp[0] = *(volatile unsigned long *)(sec2_ChannelConfigRegister[channel]); /* re-enable channel interrupts */ /*设置通道中断使能*/ *(sec2_ChannelConfigRegister[channel]) = (unsigned long)0; *(sec2_ChannelConfigRegister[channel] + 1) = (unsigned long)CHANNEL_INTEN; req = Sec2_ChannelAssignments[channel].pReq; ((GENERIC_REQ*)req)->status = SEC2_ERROR; if(SEC2_SUCCESS == sec2_addfwdQueue(req,Sec2_ChannelAssignments[channel].ownerTaskId)) { /*如果下行对列不为空,不释放通道,继续处理*/ if (SEC2_SUCCESS != Sec2_ScheduleQueue(channel)) { sec2_CompleteRequest(channel, SEC2_ERROR); Sec2_ChannelAssignments[channel].pReq = (GENERIC_REQ *)NULL; } } else { Sec2_ChannelAssignments[channel].assignment = CHANNEL_WAIT; pgsec2_channel_debug[channel].channel_WaitCnt++; } } /* if (channel error) */ } /* for (all channels) */ } /* if (any error interrupt) */ /* clear latched interrupts at the control register level */ /*清除相应的位*/ *(sec2_InterruptClearRegister) = intStatus0; *(sec2_InterruptClearRegister + 1) = intStatus1;} /* end of SEC2InterruptService */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -