Esempio n. 1
0
/*********************************************************************************************************
** 函数名称: __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);
}
Esempio n. 2
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)));
}
Esempio n. 3
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));
}
Esempio n. 4
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);
}
Esempio n. 5
0
/*********************************************************************************************************
** 函数名称: _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);
}
Esempio n. 6
0
/*********************************************************************************************************
** 函数名称: __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);
}
Esempio n. 7
0
/*********************************************************************************************************
** 函数名称: 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);
    }
}
Esempio n. 8
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. 9
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));
}
Esempio n. 10
0
/*********************************************************************************************************
** 函数名称: __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 {                                                            /*  读操作                      */