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