Example #1
0
/*********************************************************************************************************
** 函数名称: _hotplugRead
** 功能描述: 读热插拔消息文件
** 输 入  : photplugfil      热插拔消息文件
**           pcBuffer         接收缓冲区
**           stMaxBytes       接收缓冲区大小
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static ssize_t  _hotplugRead (PLW_HOTPLUG_FILE  photplugfil, 
                              PCHAR             pcBuffer, 
                              size_t            stMaxBytes)
{
    ULONG      ulErrCode;
    ULONG      ulTimeout;
    size_t     stMsgLen;
    ssize_t    sstRet;

    if (!pcBuffer || !stMaxBytes) {
        _ErrorHandle(EINVAL);
        return  (PX_ERROR);
    }
    
    if (photplugfil->HOTPFIL_iFlag & O_NONBLOCK) {                      /*  非阻塞 IO                   */
        ulTimeout = LW_OPTION_NOT_WAIT;
    } else {
        ulTimeout = LW_OPTION_WAIT_INFINITE;
    }

    for (;;) {
        ulErrCode = API_SemaphoreBPend(photplugfil->HOTPFIL_ulReadSync, /*  等待数据有效                */
                                       ulTimeout);
        if (ulErrCode != ERROR_NONE) {                                  /*  超时                        */
            _ErrorHandle(EAGAIN);
            return  (0);
        }
        
        HOTPLUG_DEV_LOCK();
        stMsgLen = (size_t)_bmsgNBytesNext(photplugfil->HOTPFIL_pbmsg);
        if (stMsgLen > stMaxBytes) {
            HOTPLUG_DEV_UNLOCK();
            API_SemaphoreBPost(photplugfil->HOTPFIL_ulReadSync);
            _ErrorHandle(EMSGSIZE);                                     /*  缓冲区太小                  */
            return  (PX_ERROR);
        
        } else if (stMsgLen) {
            break;                                                      /*  数据可读                    */
        }
        HOTPLUG_DEV_UNLOCK();
    }
    
    sstRet = (ssize_t)_bmsgGet(photplugfil->HOTPFIL_pbmsg, pcBuffer, stMaxBytes);
    
    if (!_bmsgIsEmpty(photplugfil->HOTPFIL_pbmsg)) {
        API_SemaphoreBPost(photplugfil->HOTPFIL_ulReadSync);
    }
    
    HOTPLUG_DEV_UNLOCK();
    
    return  (sstRet);
}
Example #2
0
/*********************************************************************************************************
** 函数名称: _hotplugDevPutMsg
** 功能描述: 产生一条 hotplug 消息
** 输 入  : iMsg      信息类型
**           pvMsg     需要保存的消息
**           stSize    消息长度.
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
VOID  _hotplugDevPutMsg (INT  iMsg, CPVOID pvMsg, size_t stSize)
{
    PLW_LIST_LINE       plineTemp;
    PLW_HOTPLUG_FILE    photplugfil;
    BOOL                bWakeup = LW_FALSE;
    
    if ((_G_hotplugdev.HOTPDEV_ulMutex   == LW_OBJECT_HANDLE_INVALID) ||
        (_G_hotplugdev.HOTPDEV_plineFile == LW_NULL)) {
        return;
    }
    
    HOTPLUG_DEV_LOCK();
    for (plineTemp  = _G_hotplugdev.HOTPDEV_plineFile;
         plineTemp != LW_NULL;
         plineTemp  = _list_line_get_next(plineTemp)) {
        
        photplugfil = _LIST_ENTRY(plineTemp, LW_HOTPLUG_FILE, HOTPFIL_lineManage);
        if ((photplugfil->HOTPFIL_iMsg == iMsg) ||
            (photplugfil->HOTPFIL_iMsg == LW_HOTPLUG_MSG_ALL)) {
            _bmsgPut(photplugfil->HOTPFIL_pbmsg, pvMsg, stSize);
            API_SemaphoreBPost(photplugfil->HOTPFIL_ulReadSync);
            bWakeup = LW_TRUE;
        }
    }
    HOTPLUG_DEV_UNLOCK();
    
    if (bWakeup) {
        SEL_WAKE_UP_ALL(&_G_hotplugdev.HOTPDEV_selwulList, SELREAD);
    }
}
Example #3
0
/*********************************************************************************************************
** 函数名称: __canWrite
** 功能描述: 写 CAN 设备
** 输 入  :
**           pcanDev          CAN 设备
**           pcanframe        写缓冲区指针
**           stNbyte          发送缓冲区字节数
** 输 出  : 返回实际写入的个数
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static ssize_t __canWrite (__CAN_DEV        *pcanDev,
                           PCAN_FRAME        pcanframe,
                           size_t            stNbyte)
{

    INTREG         iregInterLevel;
    INT            iFrameput;
    INT            i = 0;
    ULONG          ulError;
    __CAN_PORT    *pcanport = (__CAN_PORT *)pcanDev;
    size_t         stNumber = stNbyte / sizeof(CAN_FRAME);              /*  转换为数据包个数            */

    while (stNumber > 0) {
        ulError = API_SemaphoreBPend(pcanDev->CAN_ulSendSemB,
                                     pcanDev->CAN_ulSendTimeout);
        if (ulError) {
            _ErrorHandle(ERROR_IO_DEVICE_TIMEOUT);                      /*   超时                       */
            return  ((ssize_t)(i * sizeof(CAN_FRAME)));
        }

        CANDEV_LOCK(pcanDev);                                           /*  等待设备使用权              */

        LW_SPIN_LOCK_QUICK(&pcanDev->CAN_slLock, &iregInterLevel);
        if (pcanDev->CAN_uiBusState != CAN_DEV_BUS_ERROR_NONE) {        /*  总线错误                    */
            LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel);
            CANDEV_UNLOCK(pcanDev);
            _ErrorHandle(EIO);
            return  ((ssize_t)(i * sizeof(CAN_FRAME)));
        }
        LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel);

        iFrameput = __canWriteQueue(pcanDev,
                                    pcanDev->CAN_pcanqSendQueue,
                                    pcanframe,
                                    (INT)stNumber);

        __canTxStartup(pcanport);                                       /*  启动一次发送                */

        stNumber  -= (size_t)iFrameput;                                 /*  剩余需要发送的数据          */
        pcanframe += iFrameput;                                         /*  新的缓冲区起始地址          */
        i         += iFrameput;

        LW_SPIN_LOCK_QUICK(&pcanDev->CAN_slLock, &iregInterLevel);
        /*  关闭中断                    */
        if (__canQFreeNum(pcanDev->CAN_pcanqSendQueue) > 0) {
            LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel); /*  打开中断                    */
            API_SemaphoreBPost(pcanDev->CAN_ulSendSemB);                /*  缓冲区还有空间              */

        } else {
            LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel);
            /*  打开中断                    */
        }

        CANDEV_UNLOCK(pcanDev);                                         /*  释放设备使用权              */
    }

    return  ((ssize_t)(i * sizeof(CAN_FRAME)));
}
Example #4
0
/*********************************************************************************************************
** 函数名称: __canRead
** 功能描述: 读 CAN 设备
** 输 入  :
**           pcanDev          CAN 设备
**           pcanframe        CAN发送缓冲区指针
**           stNbyte          读取缓冲区的字节数
** 输 出  : 返回实际读取的个数
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static ssize_t __canRead (__CAN_DEV       *pcanDev,
                          PCAN_FRAME       pcanframe,
                          size_t           stNbyte)
{
    INTREG        iregInterLevel;

    REGISTER ssize_t      sstNRead;
    size_t       stNumber = stNbyte / sizeof(CAN_FRAME);       /*  转换为数据包个数            */
    ULONG        ulError;

    for (;;) {
        ulError = API_SemaphoreBPend(pcanDev->CAN_ulRcvSemB,
                                     pcanDev->CAN_ulRecvTimeout);
        if (ulError) {
            _ErrorHandle(ERROR_IO_DEVICE_TIMEOUT);                       /*  超时                        */
            return   (0);
        }

        CANDEV_LOCK(pcanDev);                                           /*  等待设备使用权              */

        LW_SPIN_LOCK_QUICK(&pcanDev->CAN_slLock, &iregInterLevel);
        /*  关闭中断                    */
        if (__canQCount(pcanDev->CAN_pcanqRecvQueue)) {                 /*  检查是否有数据              */
            break;

        } else {
            if (pcanDev->CAN_uiBusState != CAN_DEV_BUS_ERROR_NONE) {    /*  总线错误                    */
                LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel);
                CANDEV_UNLOCK(pcanDev);
                _ErrorHandle(EIO);
                return  (0);
            }
        }
        LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel);
        /*  打开中断                    */
        CANDEV_UNLOCK(pcanDev);                                         /*  释放设备使用权              */
    }

    LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel);
    sstNRead = __canReadQueue(pcanDev,
                              pcanDev->CAN_pcanqRecvQueue,
                              pcanframe,
                              (INT)stNumber);
    LW_SPIN_LOCK_QUICK(&pcanDev->CAN_slLock, &iregInterLevel);

    if (__canQCount(pcanDev->CAN_pcanqRecvQueue)) {                     /*  是否还有数据                */
        LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel);
        API_SemaphoreBPost(pcanDev->CAN_ulRcvSemB);                     /*  通知其他等待读的线程        */

    } else {
        LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel);
    }

    CANDEV_UNLOCK(pcanDev);                                             /*  释放设备使用权              */

    return  (sstNRead * sizeof(CAN_FRAME));
}
Example #5
0
/*********************************************************************************************************
** 函数名称: __canIRx
** 功能描述: 向接收缓冲区中写入一个数据
** 输 入  :
**           pcanDev            CAN 设备
**           pcanframe          指向待写入的数据
** 输 出  : ERROR_NONE or PX_ERROR
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static INT  __canIRx (__CAN_DEV  *pcanDev, PCAN_FRAME   pcanframe)
{
    INT           iTemp = 0;

    if (!pcanDev || !pcanframe) {
        return (PX_ERROR);
    }

    iTemp = __canWriteQueue(pcanDev,
                            pcanDev->CAN_pcanqRecvQueue,
                            pcanframe, 1);                              /*  往接收队列中写入一帧数据    */

    API_SemaphoreBPost(pcanDev->CAN_ulRcvSemB);                         /*  释放信号量                  */
    SEL_WAKE_UP_ALL(&pcanDev->CAN_selwulList, SELREAD);                 /*  select() 激活               */

    return ((iTemp) ? (ERROR_NONE) : (PX_ERROR));
}
Example #6
0
/*********************************************************************************************************
** 函数名称: __canFlushWrt
** 功能描述: 清除 CAN 设备写缓冲区
** 输 入  :
**           pcanport           CAN 设备
** 输 出  : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static VOID   __canFlushWrt (__CAN_PORT  *pcanport)
{
    INTREG                 iregInterLevel;

    CANPORT_LOCK(pcanport);                                             /*  等待设备使用权              */

    LW_SPIN_LOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, &iregInterLevel);
    __canFlushQueue(pcanport->CANPORT_can.CAN_pcanqSendQueue);          /*  清除缓冲区                  */
    pcanport->CANPORT_can.CAN_canstatWriteState.CANSTAT_bBufEmpty = LW_TRUE;
    /*  发送队列空                  */
    LW_SPIN_UNLOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, iregInterLevel);

    API_SemaphoreBPost(pcanport->CANPORT_can.CAN_ulSendSemB);           /*  通知线程可写                */

    CANPORT_UNLOCK(pcanport);                                           /*  释放设备使用权              */

    SEL_WAKE_UP_ALL(&pcanport->CANPORT_can.CAN_selwulList, SELWRITE);   /*  通知 select 线程可写        */
}
Example #7
0
/*********************************************************************************************************
** 函数名称: __ataWrite
** 功能描述: ata设备写操作回调
** 输 入  : patactrl   ATA控制器节点结构指针
** 输 出  : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static INT  __ataWrite (__PATA_CTRL patactrl)
{
    INTREG        iregInterLevel;

    if (!patactrl) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "parameter error.\r\n");
        _ErrorHandle(EINVAL);
        return  (PX_ERROR);
    }

    LW_SPIN_LOCK_QUICK(&patactrl->ATACTRL_slLock, &iregInterLevel);
    patactrl->ATACTRL_iIntStatus =  __ATA_CTRL_INBYTE(patactrl, __ATA_STATUS(patactrl));
    LW_SPIN_UNLOCK_QUICK(&patactrl->ATACTRL_slLock, iregInterLevel);

    API_SemaphoreBPost(patactrl->ATACTRL_ulSyncSem);

    return  (ERROR_NONE);
}
Example #8
0
/*********************************************************************************************************
** 函数名称: _JobQueueAdd
** 功能描述: 添加一个工作到工作队列
** 输 入  : pjobq         工作队列控制块
**           pfunc         要执行的函数
**           pvArg0 ~ 5    函数参数
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
ULONG  _jobQueueAdd (PLW_JOB_QUEUE pjobq,
                     VOIDFUNCPTR   pfunc,
                     PVOID         pvArg0,
                     PVOID         pvArg1,
                     PVOID         pvArg2,
                     PVOID         pvArg3,
                     PVOID         pvArg4,
                     PVOID         pvArg5)
{
    INTREG           iregInterLevel;
    PLW_JOB_MSG      pjobmsg;
    
    LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel);
    if (pjobq->JOBQ_uiCnt == pjobq->JOBQ_uiSize) {
        pjobq->JOBQ_stLost++;
        LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel);
        _DebugHandle(__ERRORMESSAGE_LEVEL, "job message lost.\r\n");
        return  (ENOSPC);
    }
    
    pjobmsg                 = &pjobq->JOBQ_pjobmsgQueue[pjobq->JOBQ_uiIn];
    pjobmsg->JOBM_pfuncFunc = pfunc;
    pjobmsg->JOBM_pvArg[0]  = pvArg0;
    pjobmsg->JOBM_pvArg[1]  = pvArg1;
    pjobmsg->JOBM_pvArg[2]  = pvArg2;
    pjobmsg->JOBM_pvArg[3]  = pvArg3;
    pjobmsg->JOBM_pvArg[4]  = pvArg4;
    pjobmsg->JOBM_pvArg[5]  = pvArg5;
    
    if (pjobq->JOBQ_uiIn == (pjobq->JOBQ_uiSize - 1)) {
        pjobq->JOBQ_uiIn =  0;
    } else {
        pjobq->JOBQ_uiIn++;
    }
    
    pjobq->JOBQ_uiCnt++;
    LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel);
    
    if (pjobq->JOBQ_ulSync) {
        API_SemaphoreBPost(pjobq->JOBQ_ulSync);
    }
    
    return  (ERROR_NONE);
}
Example #9
0
/*********************************************************************************************************
** 函数名称: eventfd
** 功能描述: 打开 eventfd 文件
** 输 入  : initval   初始化值
**           flags     打开标志 EFD_SEMAPHORE / EFD_CLOEXEC / EFD_NONBLOCK
** 输 出  : eventfd 文件描述符
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
int  eventfd (unsigned int initval, int flags)
{
    INT             iFd;
    PLW_EVTFD_FILE  pevtfdfil;
    
    flags &= (EFD_SEMAPHORE | EFD_CLOEXEC | EFD_NONBLOCK);
    
    iFd = open(LW_EVTFD_DEV_PATH, O_RDWR | flags);
    if (iFd >= 0) {
        pevtfdfil = (PLW_EVTFD_FILE)API_IosFdValue(iFd);
        pevtfdfil->EF_u64Counter = (UINT64)initval;
        if (pevtfdfil->EF_u64Counter) {
            API_SemaphoreBPost(pevtfdfil->EF_ulReadLock);
        }
    }
    
    return  (iFd);
}
Example #10
0
/*********************************************************************************************************
** 函数名称: __canITx
** 功能描述: 从发送缓冲区中读出一个数据
** 输 入  :
**           pcanDev           CAN 设备
**           pcanframe         指向待读出的数据
** 输 出  : ERROR_NONE or PX_ERROR
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static INT  __canITx (__CAN_DEV  *pcanDev, PCAN_FRAME  pcanframe)
{
    INTREG        iregInterLevel;
    INT           iTemp = 0;

    if (!pcanDev || !pcanframe) {
        return (PX_ERROR);
    }

    iTemp = __canReadQueue(pcanDev,
                           pcanDev->CAN_pcanqSendQueue,
                           pcanframe, 1);                               /*  从发送队列中读取一帧数据    */

    LW_SPIN_LOCK_QUICK(&pcanDev->CAN_slLock, &iregInterLevel);
    if (iTemp <=  0) {
        pcanDev->CAN_canstatWriteState.CANSTAT_bBufEmpty = LW_TRUE;     /*  发送队列空                  */
    }
    LW_SPIN_UNLOCK_QUICK(&pcanDev->CAN_slLock, iregInterLevel);

    API_SemaphoreBPost(pcanDev->CAN_ulSendSemB);                        /*  释放信号量                  */
    SEL_WAKE_UP_ALL(&pcanDev->CAN_selwulList, SELWRITE);                /*  释放所有等待写的线程        */

    return ((iTemp) ? (ERROR_NONE) : (PX_ERROR));
}
Example #11
0
/*********************************************************************************************************
** 函数名称: _evtfdWrite
** 功能描述: 写 eventfd 设备
** 输 入  : pevtfdfil        eventfd 文件
**           pcBuffer         将要写入的数据指针
**           stNBytes         写入数据大小
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static ssize_t  _evtfdWrite (PLW_EVTFD_FILE pevtfdfil, 
                             PCHAR          pcBuffer, 
                             size_t         stNBytes)
{
    INTREG  iregInterLevel;
    UINT64  u64Add;
    ULONG   ulLwErrCode;
    ULONG   ulTimeout;
    BOOL    bRelease = LW_FALSE;
    
    if (!pcBuffer || (stNBytes < sizeof(UINT64))) {
        _ErrorHandle(EINVAL);
        return  (PX_ERROR);
    }
    
    if (LW_CPU_GET_CUR_NESTING()) {                                     /*  是否在中断中调用            */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n");
        _ErrorHandle(ERROR_KERNEL_IN_ISR);
        return  (PX_ERROR);                                             /*  不能在中断中调用            */
    }
    
    lib_memcpy(&u64Add, pcBuffer, sizeof(UINT64));
    
    if (u64Add == LW_EVENTFD_MAX_CNT) {
        _ErrorHandle(EINVAL);
        return  (PX_ERROR);
    }
    
    if (pevtfdfil->EF_iFlag & O_NONBLOCK) {
        ulTimeout = LW_OPTION_NOT_WAIT;
    } else {
        ulTimeout = LW_OPTION_WAIT_INFINITE;
    }
    
    for (;;) {
        ulLwErrCode = API_SemaphoreBPend(pevtfdfil->EF_ulWriteLock, ulTimeout);
        if (ulLwErrCode != ERROR_NONE) {                                /*  超时                        */
            _ErrorHandle(EAGAIN);
            return  (0);
        }
        
        LW_SPIN_LOCK_QUICK(&pevtfdfil->EF_slLock, &iregInterLevel);
        if ((LW_EVENTFD_MAX_CNT - u64Add) > pevtfdfil->EF_u64Counter) { /*  不能产生溢出                */
            break;
        }
        LW_SPIN_UNLOCK_QUICK(&pevtfdfil->EF_slLock, iregInterLevel);
    }
    
    pevtfdfil->EF_u64Counter += u64Add;
    if (pevtfdfil->EF_u64Counter) {
        bRelease = LW_TRUE;
    }
    LW_SPIN_UNLOCK_QUICK(&pevtfdfil->EF_slLock, iregInterLevel);
    
    if (bRelease) {
        API_SemaphoreBPost(pevtfdfil->EF_ulReadLock);
        SEL_WAKE_UP_ALL(&pevtfdfil->EF_selwulist, SELREAD);
    }
    
    return  (sizeof(UINT64));
}
Example #12
0
/*********************************************************************************************************
** 函数名称: _evtfdRead
** 功能描述: 读 eventfd 设备
** 输 入  : pevtfdfil        eventfd 文件
**           pcBuffer         接收缓冲区
**           stMaxBytes       接收缓冲区大小
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static ssize_t  _evtfdRead (PLW_EVTFD_FILE  pevtfdfil, 
                            PCHAR           pcBuffer, 
                            size_t          stMaxBytes)
{
    INTREG  iregInterLevel;
    ULONG   ulLwErrCode;
    ULONG   ulTimeout;
    BOOL    bRelease = LW_FALSE;

    if (!pcBuffer || (stMaxBytes < sizeof(UINT64))) {
        _ErrorHandle(EINVAL);
        return  (PX_ERROR);
    }
    
    if (LW_CPU_GET_CUR_NESTING()) {                                     /*  是否在中断中调用            */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n");
        _ErrorHandle(ERROR_KERNEL_IN_ISR);
        return  (PX_ERROR);                                             /*  不能在中断中调用            */
    }
    
    if (pevtfdfil->EF_iFlag & O_NONBLOCK) {
        ulTimeout = LW_OPTION_NOT_WAIT;
    } else {
        ulTimeout = LW_OPTION_WAIT_INFINITE;
    }
    
    for (;;) {
        ulLwErrCode = API_SemaphoreBPend(pevtfdfil->EF_ulReadLock, ulTimeout);
        if (ulLwErrCode != ERROR_NONE) {                                /*  超时                        */
            _ErrorHandle(EAGAIN);
            return  (0);
        }
        
        LW_SPIN_LOCK_QUICK(&pevtfdfil->EF_slLock, &iregInterLevel);
        if (pevtfdfil->EF_u64Counter) {
            break;
        }
        LW_SPIN_UNLOCK_QUICK(&pevtfdfil->EF_slLock, iregInterLevel);
    }
    
    if (pevtfdfil->EF_iFlag & EFD_SEMAPHORE) {                          /*  EFD_SEMAPHORE               */
        UINT64  u64One = 1;
        lib_memcpy(pcBuffer, &u64One, sizeof(UINT64));                  /*  host bytes order            */
        pevtfdfil->EF_u64Counter--;
    
    } else {
        lib_memcpy(pcBuffer, &pevtfdfil->EF_u64Counter, sizeof(UINT64));
        pevtfdfil->EF_u64Counter = 0;
    }
    
    if (pevtfdfil->EF_u64Counter) {
        bRelease = LW_TRUE;
    }
    LW_SPIN_UNLOCK_QUICK(&pevtfdfil->EF_slLock, iregInterLevel);
    
    if (bRelease) {
        API_SemaphoreBPost(pevtfdfil->EF_ulReadLock);
        SEL_WAKE_UP_ALL(&pevtfdfil->EF_selwulist, SELREAD);
    }
    
    API_SemaphoreBPost(pevtfdfil->EF_ulWriteLock);
    SEL_WAKE_UP_ALL(&pevtfdfil->EF_selwulist, SELWRITE);
    
    return  (sizeof(UINT64));
}