Esempio n. 1
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);
    }
}
Esempio n. 2
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));
}
Esempio n. 3
0
/*********************************************************************************************************
** 函数名称: __canClose
** 功能描述: CAN 设备关闭
** 输 入  :
**           pcanDev          CAN 设备
** 输 出  : CAN 设备指针
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static INT __canClose (__CAN_DEV   *pcanDev)
{
    __CAN_PORT      *pcanport = (__CAN_PORT *)pcanDev;

    if (LW_DEV_GET_USE_COUNT(&pcanDev->CAN_devhdr)) {
        if (!LW_DEV_DEC_USE_COUNT(&pcanDev->CAN_devhdr)) {
            if (pcanport->CANPORT_pcanchan->pDrvFuncs->ioctl) {
                pcanport->CANPORT_pcanchan->pDrvFuncs->ioctl(pcanport->CANPORT_pcanchan,
                        CAN_DEV_CLOSE, LW_NULL);
                /*  挂起端口                    */
            }
            SEL_WAKE_UP_ALL(&pcanDev->CAN_selwulList,
                            SELEXCEPT);                                 /*  激活异常等待                */
        }
    }

    return  (ERROR_NONE);
}
Esempio n. 4
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 线程可写        */
}
Esempio n. 5
0
/*********************************************************************************************************
** 函数名称: __canSetBusState
** 功能描述: 设置 CAN 设备的总线状态
** 输 入  :
**           pcanDev            CAN 设备
**           iState             总线状态
** 输 出  : ERROR_NONE or PX_ERROR
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static VOID __canSetBusState (__CAN_DEV  *pcanDev, INT iState)
{
    INTREG           iregInterLevel;
    __CAN_PORT      *pcanport = (__CAN_PORT *)pcanDev;

    LW_SPIN_LOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, &iregInterLevel);
    if (iState) {
        pcanDev->CAN_uiBusState |= iState;
    } else {
        pcanDev->CAN_uiBusState = CAN_DEV_BUS_ERROR_NONE;
    }
    LW_SPIN_UNLOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, iregInterLevel);

    if (pcanDev->CAN_uiBusState != CAN_DEV_BUS_ERROR_NONE) {            /*  总线异常                    */
        API_SemaphoreBFlush(pcanDev->CAN_ulSendSemB, LW_NULL);          /*  激活写等待任务              */
        API_SemaphoreBFlush(pcanDev->CAN_ulRcvSemB, LW_NULL);           /*  激活读等待任务              */
        SEL_WAKE_UP_ALL(&pcanDev->CAN_selwulList, SELEXCEPT);           /*  select() 激活               */
    }
}
Esempio n. 6
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));
}
Esempio n. 7
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));
}
Esempio n. 8
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));
}