/********************************************************************************************************* ** 函数名称: _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); } }
/********************************************************************************************************* ** 函数名称: __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)); }
/********************************************************************************************************* ** 函数名称: __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); }
/********************************************************************************************************* ** 函数名称: __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 线程可写 */ }
/********************************************************************************************************* ** 函数名称: __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() 激活 */ } }
/********************************************************************************************************* ** 函数名称: __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)); }
/********************************************************************************************************* ** 函数名称: _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)); }
/********************************************************************************************************* ** 函数名称: _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)); }