/********************************************************************************************************* ** 函数名称: __ataPread ** 功能描述: 读取设备的参数 ** 输 入 : patactrler ATA控制器结构指针 ** iDrive 驱动号 ** pvBuffer 缓冲 ** 输 出 : ERROR ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __ataPread (__PATA_CTRL patactrler, INT iDrive, PVOID pvBuffer) { __PATA_CTRL patactrl = LW_NULL; INT iRetry = 1; INT iRetryCount = 0; ULONG ulSemStatus = 0; INT16 *psBuf = LW_NULL; if ((!patactrler) || (!pvBuffer)) { _DebugHandle(__ERRORMESSAGE_LEVEL, "parameter error.\r\n"); _ErrorHandle(EINVAL); return (PX_ERROR); } patactrl = patactrler; while (iRetry) { if (__ataWait(patactrl, __ATA_STAT_READY) != ERROR_NONE) { return (PX_ERROR); } __ATA_CTRL_OUTBYTE(patactrl, __ATA_SDH(patactrl), \ (UINT8)(__ATA_SDH_LBA | (iDrive << __ATA_DRIVE_BIT))); __ATA_CTRL_OUTBYTE(patactrl, __ATA_COMMAND(patactrl), __ATA_CMD_READP); /* 写入确认命令 */ if (patactrl->ATACTRL_bIntDisable == LW_FALSE) { ulSemStatus = API_SemaphoreBPend(patactrl->ATACTRL_ulSyncSem, \ patactrl->ATACTRL_ulSyncSemTimeout); /* 等待同步信号 */ } if ((patactrl->ATACTRL_iIntStatus & __ATA_STAT_ERR) || (ulSemStatus != ERROR_NONE)) { ATA_DEBUG_MSG(("__ataPread() error : status=0x%x intStatus=0x%x " \ "error=0x%x ulSemStatus=%d\n", \ __ATA_CTRL_INBYTE(patactrl, __ATA_ASTATUS(patactrl)), \ patactrl->ATACTRL_iIntStatus, \ __ATA_CTRL_INBYTE(patactrl, __ATA_ERROR(patactrl)), ulSemStatus)); if (++iRetryCount > _G_iAtaRetry) { return (PX_ERROR); } } else { iRetry = 0; } } if (__ataWait(patactrl, __ATA_STAT_DRQ) != ERROR_NONE) { /* 等待设备准备好传输数据 */ return (PX_ERROR); } psBuf = (INT16 *)pvBuffer; __ATA_CTRL_INSTRING(patactrl, __ATA_DATA(patactrl), psBuf, 256); ATA_DEBUG_MSG(("__ataPread() end :\n")); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __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)); }
/********************************************************************************************************* ** 函数名称: _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); }
/********************************************************************************************************* ** 函数名称: _jobQueueExec ** 功能描述: 执行工作队列中的工作 ** 输 入 : pjobq 工作队列控制块 ** ulTimeout 等待超时时间 ** 输 出 : 不为 ERROR_NONE 表示超时 ** 全局变量: ** 调用模块: *********************************************************************************************************/ ULONG _jobQueueExec (PLW_JOB_QUEUE pjobq, ULONG ulTimeout) { INTREG iregInterLevel; PLW_JOB_MSG pjobmsg; LW_JOB_MSG jobmsgRun; if (pjobq->JOBQ_ulSync) { for (;;) { if (API_SemaphoreBPend(pjobq->JOBQ_ulSync, ulTimeout)) { return (ERROR_THREAD_WAIT_TIMEOUT); } LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel); if (pjobq->JOBQ_uiCnt) { break; } LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel); } } else { LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel); } while (pjobq->JOBQ_uiCnt) { pjobmsg = &pjobq->JOBQ_pjobmsgQueue[pjobq->JOBQ_uiOut]; jobmsgRun = *pjobmsg; if (pjobq->JOBQ_uiOut == (pjobq->JOBQ_uiSize - 1)) { pjobq->JOBQ_uiOut = 0; } else { pjobq->JOBQ_uiOut++; } pjobq->JOBQ_uiCnt--; LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel); if (jobmsgRun.JOBM_pfuncFunc) { jobmsgRun.JOBM_pfuncFunc(jobmsgRun.JOBM_pvArg[0], jobmsgRun.JOBM_pvArg[1], jobmsgRun.JOBM_pvArg[2], jobmsgRun.JOBM_pvArg[3], jobmsgRun.JOBM_pvArg[4], jobmsgRun.JOBM_pvArg[5]); } LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel); } LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __ataCmd ** 功能描述: ATA命令 ** 输 入 : patactrler ATA控制器结构指针 ** iDrive 驱动号 ** iCmd ATA命令 ** iArg0 参数0 ** iArg1 参数1 ** 输 出 : ERROR ** 全局变量: ** 调用模块: *********************************************************************************************************/ INT __ataCmd (__PATA_CTRL patactrler, INT iDrive, INT iCmd, INT iArg0, INT iArg1) { __PATA_CTRL patactrl = LW_NULL; __PATA_DRIVE patadrive = LW_NULL; __PATA_TYPE patatype = LW_NULL; INT iRetry = 1; INT iRetryCount = 0; ULONG ulSemStatus = 0; if (!patactrler) { _DebugHandle(__ERRORMESSAGE_LEVEL, "parameter error.\r\n"); _ErrorHandle(EINVAL); return (PX_ERROR); } patactrl = patactrler; patadrive = &patactrl->ATACTRL_ataDrive[iDrive]; patatype = patadrive->ATADRIVE_patatypeDriverInfo; while (iRetry) { if (__ataWait(patactrler, __ATA_STAT_READY)) { /* 超时,错误返回 */ ATA_DEBUG_MSG(("__ataCmd() error : time out")); return (PX_ERROR); } switch (iCmd) { case __ATA_CMD_DIAGNOSE: /* 运行驱动器诊断 */ case __ATA_CMD_RECALIB: /* 校准 */ __ATA_CTRL_OUTBYTE(patactrl, __ATA_SDH(patactrl), (UINT8)(__ATA_SDH_LBA | (iDrive << __ATA_DRIVE_BIT))); break; case __ATA_CMD_INITP: /* 驱动器参数初始化 */ __ATA_CTRL_OUTBYTE(patactrl, __ATA_CYLLO(patactrl), (UINT8)patatype->ATATYPE_iCylinders); __ATA_CTRL_OUTBYTE(patactrl, __ATA_CYLHI(patactrl), \ (UINT8)(patatype->ATATYPE_iCylinders >> 8)); __ATA_CTRL_OUTBYTE(patactrl, __ATA_SECCNT(patactrl), (UINT8)patatype->ATATYPE_iSectors); __ATA_CTRL_OUTBYTE(patactrl, __ATA_SDH(patactrl), \ (UINT8)(__ATA_SDH_LBA | \ (iDrive << __ATA_DRIVE_BIT) | \ ((patatype->ATATYPE_iHeads - 1) & 0x0f))); break; case __ATA_CMD_SEEK: /* 查询定位 */ __ATA_CTRL_OUTBYTE(patactrl, __ATA_CYLLO(patactrl), (UINT8)iArg0); __ATA_CTRL_OUTBYTE(patactrl, __ATA_CYLHI(patactrl), (UINT8)(iArg0 >> 8)); __ATA_CTRL_OUTBYTE(patactrl, __ATA_SDH(patactrl), \ (UINT8)(__ATA_SDH_LBA | \ (iDrive << __ATA_DRIVE_BIT) | \ (iArg1 & 0xf))); break; case __ATA_CMD_SET_FEATURE: /* 设置特征 */ __ATA_CTRL_OUTBYTE(patactrl, __ATA_SECCNT(patactrl), (UINT8)iArg1); __ATA_CTRL_OUTBYTE(patactrl, __ATA_FEATURE(patactrl), (UINT8)iArg0); __ATA_CTRL_OUTBYTE(patactrl, __ATA_SDH(patactrl), \ (UINT8)(__ATA_SDH_LBA | (iDrive << __ATA_DRIVE_BIT))); break; case __ATA_CMD_SET_MULTI: /* 多重模式设定 */ __ATA_CTRL_OUTBYTE(patactrl, __ATA_SECCNT(patactrl), (UINT8)iArg0); __ATA_CTRL_OUTBYTE(patactrl, __ATA_SDH(patactrl), \ (UINT8)(__ATA_SDH_LBA | (iDrive << __ATA_DRIVE_BIT))); break; default: __ATA_CTRL_OUTBYTE(patactrl, __ATA_SDH(patactrl), \ (UINT8)(__ATA_SDH_LBA | (iDrive << __ATA_DRIVE_BIT))); break; } __ATA_CTRL_OUTBYTE(patactrl, __ATA_COMMAND(patactrl), (UINT8)iCmd); /* 写命令寄存器 */ if (patactrl->ATACTRL_bIntDisable == LW_FALSE) { ulSemStatus = API_SemaphoreBPend(patactrl->ATACTRL_ulSyncSem, \ patactrl->ATACTRL_ulSyncSemTimeout); /* 等待同步信号 */ } if ((patactrl->ATACTRL_iIntStatus & __ATA_STAT_ERR) || (ulSemStatus != ERROR_NONE)) { ATA_DEBUG_MSG(("__ataCmd() error : status=0x%x ulSemStatus=%d err=0x%x\n", patactrl->ATACTRL_iIntStatus, ulSemStatus, __ATA_CTRL_INBYTE(patactrl, __ATA_ERROR(patactrl)))); if (++iRetryCount > _G_iAtaRetry) { /* 重试大于默认次数,错误返回 */ return (PX_ERROR); } } else { iRetry = 0; } } if (iCmd == __ATA_CMD_SEEK) { if (__ataWait(patactrler, __ATA_STAT_SEEKCMPLT) != ERROR_NONE) { return (PX_ERROR); } } ATA_DEBUG_MSG(("__ataCmd() end : - iCtrl %d, iDrive %d: Ok\n", patactrl->ATACTRL_iCtrl, iDrive)); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: waitread ** 功能描述: select() 变种,等待单个文件可读. ** 输 入 : iFd 文件描述符 ** ptmvalTO 等待超时时间, LW_NULL 表示永远等待. ** 输 出 : 正常等待到的文件数, 为 1 表示文件可以读, 为 0 表示超时 ,错误返回 PX_ERROR. ** errno == ERROR_IO_SELECT_UNSUPPORT_IN_DRIVER 驱动程序不支持 ** errno == ERROR_IO_SELECT_CONTEXT 线程不存在 context ** errno == ERROR_THREAD_WAIT_TIMEOUT 等待超时 ** errno == ERROR_KERNEL_IN_ISR 在中断中调用 ** errno == ERROR_IOS_INVALID_FILE_DESCRIPTOR 文件描述符无效. ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT waitread (INT iFd, struct timeval *ptmvalTO) { REGISTER INT iIsOk = ERROR_NONE; /* 初始化为没有错误 */ REGISTER INT iWidth = iFd + 1; /* iFd + 1 */ REGISTER INT iWidthInBytes; /* 需要检测的位数占多少字节 */ REGISTER ULONG ulWaitTime; /* 等待时间 */ REGISTER LW_SEL_CONTEXT *pselctx; PLW_CLASS_TCB ptcbCur; fd_set fdsetRead; LW_SEL_WAKEUPNODE selwunNode; /* 生成的 NODE 模板 */ ULONG ulError; if (LW_CPU_GET_CUR_NESTING()) { _ErrorHandle(ERROR_KERNEL_IN_ISR); /* 不能在中断中调用 */ return (PX_ERROR); } if (iFd > (FD_SETSIZE - 1) || iFd < 0) { /* 文件号错误 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "file descriptor invalidate..\r\n"); _ErrorHandle(ERROR_IOS_INVALID_FILE_DESCRIPTOR); /* 文件描述符无效 */ return (PX_ERROR); } LW_TCB_GET_CUR_SAFE(ptcbCur); pselctx = ptcbCur->TCB_pselctxContext; if (!pselctx) { /* 没有 select context */ _DebugHandle(__ERRORMESSAGE_LEVEL, "no select context.\r\n"); _ErrorHandle(ERROR_IO_SELECT_CONTEXT); return (PX_ERROR); } iWidthInBytes = __HOWMANY(iWidth, NFDBITS) * sizeof(fd_mask); /* 需要检测的位数占多少字节 */ FD_ZERO(&fdsetRead); /* 清除文件集 */ FD_SET(iFd, &fdsetRead); /* 指定文件置位 */ __selFdsetInit(iWidthInBytes, &fdsetRead, /* 设置 OrigRead 文件位 */ LW_NULL, LW_NULL, pselctx); /* __selTaskDeleteHook 使用 */ FD_CLR(iFd, &fdsetRead); /* 清除文件集 */ if (!ptmvalTO) { /* 计算等待时间 */ ulWaitTime = LW_OPTION_WAIT_INFINITE; /* 无限等待 */ } else { ulWaitTime = __timevalToTick(ptmvalTO); /* 计算超时时间 */ } pselctx->SELCTX_pfdsetReadFds = &fdsetRead; pselctx->SELCTX_pfdsetWriteFds = LW_NULL; /* 保存用户参数地址 */ pselctx->SELCTX_pfdsetExceptFds = LW_NULL; API_SemaphoreBClear(pselctx->SELCTX_hSembWakeup); /* 清除信号量 */ selwunNode.SELWUN_hThreadId = API_ThreadIdSelf(); selwunNode.SELWUN_seltypType = SELREAD; selwunNode.SELWUN_iFd = iFd; pselctx->SELCTX_iWidth = iWidth; /* 记录最大文件号 */ pselctx->SELCTX_bPendedOnSelect = LW_TRUE; /* 需要 delete hook 清除 NODE */ iIsOk = ioctl(iFd, FIOSELECT, (LONG)&selwunNode); /* FIOSELECT */ if (iIsOk != ERROR_NONE) { ULONG ulError = API_GetLastError(); iIsOk = ioctl(iFd, FIOUNSELECT, (LONG)&selwunNode); /* FIOUNSELECT */ if (ulError == ERROR_IO_UNKNOWN_REQUEST) { _ErrorHandle(ERROR_IO_SELECT_UNSUPPORT_IN_DRIVER); /* 驱动程序不支持 */ } pselctx->SELCTX_bPendedOnSelect = LW_FALSE; /* 自行清理完毕 */ return (PX_ERROR); /* 错误 */ } API_SemaphoreBPend(pselctx->SELCTX_hSembWakeup, ulWaitTime); /* 开始等待 */ ulError = API_GetLastError(); iIsOk = ioctl(iFd, FIOUNSELECT, (LONG)&selwunNode); /* FIOUNSELECT */ pselctx->SELCTX_bPendedOnSelect = LW_FALSE; /* 自行清理完毕 */ if (iIsOk != ERROR_NONE) { return (PX_ERROR); /* 出现错误 */ } else { _ErrorHandle(ulError); } if (FD_ISSET(iFd, &fdsetRead)) { /* 检查文件是否可读 */ return (1); } else { return (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)); }
/********************************************************************************************************* ** 函数名称: _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)); }
/********************************************************************************************************* ** 函数名称: __ataRW ** 功能描述: 读写当前磁道一定数量的扇区数 ** 输 入 : iCtrl 控制器号 ** iDrive 设备驱动号 ** iCylinder 柱面 ** iHead 磁头 ** iSector 扇区 ** pusBuf 缓冲区 ** iNSecs 扇区数 ** iDirection 操作方向 ** iRetry 重试次数 ** 输 出 : ERROR ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __ataRW (__PATA_CTRL patactrler, INT iDrive, INT iCylinder, INT iHead, INT iSector, PVOID pvBuffer, INT iNSecs, INT iDirection, INT iRetry) { __PATA_CTRL patactrl = LW_NULL; __PATA_DRIVE patadrive = LW_NULL; __PATA_TYPE patatype = LW_NULL; INT iRetryCount = 0; INT iBlock = 1; INT iNSectors = iNSecs; INT iNWords = 0; INT iStatus = 0; ULONG ulSemStatus = ERROR_NONE; volatile INT i = 0; INT16 *psBuf = LW_NULL; if ((!patactrler) || (!pvBuffer)) { _DebugHandle(__ERRORMESSAGE_LEVEL, "buffer address error.\r\n"); _ErrorHandle(EINVAL); return (PX_ERROR); } patactrl = patactrler; patadrive = &patactrl->ATACTRL_ataDrive[iDrive]; patatype = patadrive->ATADRIVE_patatypeDriverInfo; ATA_DEBUG_MSG(("__ataRW(): ctrl=%d drive=%d c=%d h=%d s=%d n=%d dir=%d\n", patactrl->ATACTRL_iCtrl, iDrive, iCylinder, iHead, iSector, iNSecs, iDirection)); if (patactrl->ATACTRL_bIsExist != LW_TRUE) { /* ATA设备不存在 */ return (PX_ERROR); } __retry_rw: iStatus = __ataWait(patactrl, __ATA_STAT_IDLE); /* 等待BSY跟DRQ为0 */ if (iStatus != ERROR_NONE) { ATA_DEBUG_MSG(("__ataRW() %d/%d: istatus = 0x%x read timed out\n", patactrl->ATACTRL_iCtrl, iDrive, istatus)); return (PX_ERROR); } psBuf = (INT16 *)pvBuffer; iNSectors = iNSecs; __ATA_CTRL_OUTBYTE(patactrl, __ATA_SECTOR(patactrl), (UINT8)(iSector >> 8)); __ATA_CTRL_OUTBYTE(patactrl, __ATA_SECTOR(patactrl), (UINT8)iSector); __ATA_CTRL_OUTBYTE(patactrl, __ATA_SECCNT(patactrl), (UINT8)iNSecs); __ATA_CTRL_OUTBYTE(patactrl, __ATA_CYLLO(patactrl), (UINT8)iCylinder); __ATA_CTRL_OUTBYTE(patactrl, __ATA_CYLHI(patactrl), (UINT8)(iCylinder >> 8)); iStatus = __ataWait(patactrl, __ATA_STAT_IDLE); if (iStatus != ERROR_NONE) { ATA_DEBUG_MSG(("__ataRW() %d/%d: istatus = 0x%x read timed out\n", patactrl->ATACTRL_iCtrl, iDrive, istatus)); return (PX_ERROR); } if (patadrive->ATADRIVE_sOkLba) { __ATA_CTRL_OUTBYTE(patactrl, __ATA_SDH(patactrl), (UINT8)(__ATA_SDH_LBA | \ (iDrive << __ATA_DRIVE_BIT) | \ (iHead & 0xf))); } else { __ATA_CTRL_OUTBYTE(patactrl, __ATA_SDH(patactrl), (UINT8)(__ATA_SDH_CHS | \ (iDrive << __ATA_DRIVE_BIT) | \ (iHead & 0xf))); } if (patadrive->ATADRIVE_sRwPio == ATA_PIO_MULTI) { iBlock = patadrive->ATADRIVE_sMultiSecs; } iNWords = (patatype->ATATYPE_iBytes * iBlock) >> 1; /* 所需读写的数据的字数量 */ iStatus = __ataWait(patactrl, __ATA_STAT_IDLE); if (iStatus != ERROR_NONE) { ATA_DEBUG_MSG(("__ataRW() %d/%d: istatus = 0x%x read timed out\n", patactrl->ATACTRL_iCtrl, iDrive, istatus)); return (PX_ERROR); } if (iDirection == O_WRONLY) { /* 写操作 */ if (patadrive->ATADRIVE_sRwPio == ATA_PIO_MULTI) { __ATA_CTRL_OUTBYTE(patactrl, __ATA_COMMAND(patactrl), __ATA_CMD_WRITE_MULTI); /* 发送多重写操作命令 */ } else { __ATA_CTRL_OUTBYTE(patactrl, __ATA_COMMAND(patactrl), __ATA_CMD_WRITE); /* 发送单扇区写操作命令 */ } while (iNSectors > 0) { if ((patadrive->ATADRIVE_sRwPio == ATA_PIO_MULTI) && (iNSectors < iBlock)) { /* 所需操作的扇区数少于默认设置 的多重读写扇区数 */ iBlock = iNSectors; iNWords = (patatype->ATATYPE_iBytes * iBlock) >> 1; /* 一次读写操作的字数 */ } iStatus = __ataWait(patactrl, __ATA_STAT_DRQ); if (iStatus != ERROR_NONE) { ATA_DEBUG_MSG(("__ataRW() %d/%d: istatus = 0x%x read timed out\n", patactrl->ATACTRL_iCtrl, iDrive, istatus)); return (PX_ERROR); } if (patadrive->ATADRIVE_sRwBits == ATA_BITS_8) { /* 8位操作 */ INT8 *pcBuff = (INT8 *)psBuf; INT iNByteWords = (1 << iNWords); for (i = 0; i < iNByteWords; i++) { __ATA_CTRL_OUTBYTE(patactrl, __ATA_DATA(patactrl), *pcBuff); pcBuff++; } } else if (patadrive->ATADRIVE_sRwBits == ATA_BITS_16) { /* 16位操作 */ __ATA_CTRL_OUTSTRING(patactrl, __ATA_DATA(patactrl), psBuf, iNWords); } else { /* 32位操作 */ /* * TODO: 32位操作 */ ATA_DEBUG_MSG(("__ataRW() error: 32 bits write operation\n")); return (PX_ERROR); } iStatus = __ataWait(patactrl, __ATA_STAT_BUSY); if (iStatus != ERROR_NONE) { ATA_DEBUG_MSG(("__ataRW() %d/%d: istatus = 0x%x read timed out\n", patactrl->ATACTRL_iCtrl, iDrive, istatus)); return (PX_ERROR); } if (patactrl->ATACTRL_bIntDisable == LW_FALSE) { /* 假如使能了中断 */ ulSemStatus = API_SemaphoreBPend(patactrl->ATACTRL_ulSyncSem, \ patactrl->ATACTRL_ulSyncSemTimeout);/* 等待同步信号 */ } if ((patactrl->ATACTRL_iIntStatus & __ATA_STAT_ERR) || (ulSemStatus != ERROR_NONE)) { goto __error_handle; } psBuf += iNWords; /* 调整缓冲区的指针 */ iNSectors -= iBlock; /* 计算还需操作的扇区数 */ } } else { /* 读操作 */