Exemplo n.º 1
0
/*********************************************************************************************************
** 函数名称: __canIoctl
** 功能描述: CAN 设备控制
** 输 入  :
**           pcanDev          CAN 设备
**           cmd              控制命令
**           lArg             参数
** 输 出  : ERROR_NONE or PX_ERROR
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static INT __canIoctl (__CAN_DEV    *pcanDev, INT  cmd, LONG  lArg)
{
    INTREG               iregInterLevel;
    INT                  iStatus = ERROR_NONE;
    struct stat         *pstat;
    PLW_SEL_WAKEUPNODE   pselwunNode;

    struct timeval  *timevalTemp;

    __CAN_PORT      *pcanport     = (__CAN_PORT *)pcanDev;
    CAN_DRV_FUNCS   *pCanDevFuncs = pcanport->CANPORT_pcanchan->pDrvFuncs;

    CANDEV_LOCK(pcanDev);                                               /*  等待设备使用权              */

    if (pCanDevFuncs->ioctl) {
        iStatus = pCanDevFuncs->ioctl(pcanport->CANPORT_pcanchan, cmd, (PVOID)lArg);
    } else {
        iStatus = ENOSYS;
    }

    if ((iStatus == ENOSYS) ||
            ((iStatus == PX_ERROR) && (errno == ENOSYS))) {                 /*  驱动程序无法识别的命令      */

        iStatus = ERROR_NONE;                                           /*  清除驱动程序错误            */

        switch (cmd) {

        case FIONREAD:                                                  /*  读缓冲区有效数据数量        */
        {
            LONG  lNFrame   = __canQCount(pcanDev->CAN_pcanqRecvQueue);
            *((INT *)lArg) = (INT)(lNFrame * sizeof(CAN_FRAME));
        }
        break;

        case FIONWRITE:
        {
            LONG  lNFrame   = __canQCount(pcanDev->CAN_pcanqSendQueue);
            *((INT *)lArg) = (INT)(lNFrame * sizeof(CAN_FRAME));
        }
        break;

        case FIOFLUSH:                                                  /*  清空设备缓冲区              */
            __canFlushRd(pcanport);
            __canFlushWrt(pcanport);
            break;

        case FIOWFLUSH:
            __canFlushRd(pcanport);                                     /*  清空写缓冲区                */
            break;

        case FIORFLUSH:
            __canFlushWrt(pcanport);                                    /*  清空读缓冲区                */
            break;

        case FIOFSTATGET:                                               /*  获得文件属性                */
            pstat = (struct stat *)lArg;
            pstat->st_dev     = (dev_t)pcanDev;
            pstat->st_ino     = (ino_t)0;                               /*  相当于唯一节点              */
            pstat->st_mode    = 0666 | S_IFCHR;                         /*  默认属性                    */
            pstat->st_nlink   = 1;
            pstat->st_uid     = 0;
            pstat->st_gid     = 0;
            pstat->st_rdev    = 1;
            pstat->st_size    = 0;
            pstat->st_blksize = 0;
            pstat->st_blocks  = 0;
            pstat->st_atime   = API_RootFsTime(LW_NULL);                /*  默认使用 root fs 基准时间   */
            pstat->st_mtime   = API_RootFsTime(LW_NULL);
            pstat->st_ctime   = API_RootFsTime(LW_NULL);
            break;

        case FIOSELECT:
            pselwunNode = (PLW_SEL_WAKEUPNODE)lArg;
            SEL_WAKE_NODE_ADD(&pcanDev->CAN_selwulList, pselwunNode);

            switch (pselwunNode->SELWUN_seltypType) {

            case SELREAD:                                               /*  等待数据可读                */
                if (__canQCount(pcanDev->CAN_pcanqRecvQueue) > 0) {
                    SEL_WAKE_UP(pselwunNode);                           /*  唤醒节点                    */
                }
                break;

            case SELWRITE:
                if (__canQFreeNum(pcanDev->CAN_pcanqSendQueue) > 0) {
                    SEL_WAKE_UP(pselwunNode);                           /*  唤醒节点                    */
                }
                break;

            case SELEXCEPT:                                             /*  总线是否异常                */
                LW_SPIN_LOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, &iregInterLevel);
                if (pcanDev->CAN_uiBusState != CAN_DEV_BUS_ERROR_NONE) {
                    LW_SPIN_UNLOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, iregInterLevel);
                    SEL_WAKE_UP(pselwunNode);                           /*  唤醒节点                    */
                } else {
                    LW_SPIN_UNLOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, iregInterLevel);
                }
                break;
            }
            break;

        case FIOUNSELECT:
            SEL_WAKE_NODE_DELETE(&pcanDev->CAN_selwulList, (PLW_SEL_WAKEUPNODE)lArg);
            break;

        case CAN_DEV_GET_BUS_STATE:                                     /*  获取 CAN 控制器状态         */
            LW_SPIN_LOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, &iregInterLevel);
            *((LONG *)lArg)         = pcanDev->CAN_uiBusState;
            pcanDev->CAN_uiBusState = CAN_DEV_BUS_ERROR_NONE;           /* 读取后清除状态               */
            LW_SPIN_UNLOCK_QUICK(&pcanport->CANPORT_can.CAN_slLock, iregInterLevel);
            break;

        case FIOWTIMEOUT:
            if (lArg) {
                timevalTemp = (struct timeval *)lArg;
                pcanDev->CAN_ulSendTimeout = __timevalToTick(timevalTemp);
                /*  转换为系统时钟              */
            } else {
                pcanDev->CAN_ulSendTimeout = LW_OPTION_WAIT_INFINITE;
            }
            break;

        case FIORTIMEOUT:
            if (lArg) {
                timevalTemp = (struct timeval *)lArg;
                pcanDev->CAN_ulRecvTimeout = __timevalToTick(timevalTemp);
                /*  转换为系统时钟              */
            } else {
                pcanDev->CAN_ulRecvTimeout = LW_OPTION_WAIT_INFINITE;
            }
            break;

        default:
            _ErrorHandle(ERROR_IO_UNKNOWN_REQUEST);
            iStatus = PX_ERROR;
            break;
        }
    }

    CANDEV_UNLOCK(pcanDev);                                             /*  释放设备使用权              */

    return (iStatus);
}
Exemplo n.º 2
0
/*********************************************************************************************************
** 函数名称: _hotplugIoctl
** 功能描述: 控制热插拔消息文件
** 输 入  : photplugfil      热插拔消息文件
**           iRequest         功能
**           lArg             参数
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static INT  _hotplugIoctl (PLW_HOTPLUG_FILE  photplugfil, 
                           INT               iRequest, 
                           LONG              lArg)
{
    PLW_SEL_WAKEUPNODE   pselwunNode;
    struct stat         *pstatGet;
    PLW_BMSG             pbmsg;

    switch (iRequest) {
    
    case FIONREAD:
        HOTPLUG_DEV_LOCK();
        *(INT *)lArg = _bmsgNBytes(photplugfil->HOTPFIL_pbmsg);
        HOTPLUG_DEV_UNLOCK();
        break;
        
    case FIONMSGS:
        HOTPLUG_DEV_LOCK();
        if (!_bmsgIsEmpty(photplugfil->HOTPFIL_pbmsg)) {
            *(INT *)lArg = 1;                                           /*  目前暂不通知具体消息数量    */
        } else {
            *(INT *)lArg = 0;
        }
        HOTPLUG_DEV_UNLOCK();
        break;
        
    case FIONBIO:
        HOTPLUG_DEV_LOCK();
        if (*(INT *)lArg) {
            photplugfil->HOTPFIL_iFlag |= O_NONBLOCK;
        } else {
            photplugfil->HOTPFIL_iFlag &= ~O_NONBLOCK;
        }
        HOTPLUG_DEV_UNLOCK();
        break;
        
    case FIORFLUSH:
    case FIOFLUSH:
        HOTPLUG_DEV_LOCK();
        _bmsgFlush(photplugfil->HOTPFIL_pbmsg);
        HOTPLUG_DEV_UNLOCK();
        break;
        
    case FIORBUFSET:
        if (lArg < LW_HOTPLUG_DEV_MAX_MSGSIZE) {
            _ErrorHandle(EMSGSIZE);
            return  (PX_ERROR);
        }
        pbmsg = _bmsgCreate((size_t)lArg);
        if (pbmsg) {
            HOTPLUG_DEV_LOCK();
            _bmsgDelete(photplugfil->HOTPFIL_pbmsg);
            photplugfil->HOTPFIL_pbmsg = pbmsg;
            HOTPLUG_DEV_UNLOCK();
        } else {
            _ErrorHandle(ENOMEM);
            return  (PX_ERROR);
        }
        break;
        
    case LW_HOTPLUG_FIOSETMSG:
        photplugfil->HOTPFIL_iMsg = (INT)lArg;
        break;
        
    case FIOFSTATGET:
        pstatGet = (struct stat *)lArg;
        if (pstatGet) {
            pstatGet->st_dev     = (dev_t)&_G_hotplugdev;
            pstatGet->st_ino     = (ino_t)0;                            /*  相当于唯一节点              */
            pstatGet->st_mode    = 0444 | S_IFCHR;
            pstatGet->st_nlink   = 1;
            pstatGet->st_uid     = 0;
            pstatGet->st_gid     = 0;
            pstatGet->st_rdev    = 1;
            pstatGet->st_size    = (off_t)_bmsgSizeGet(photplugfil->HOTPFIL_pbmsg);
            pstatGet->st_blksize = 0;
            pstatGet->st_blocks  = 0;
            pstatGet->st_atime   = API_RootFsTime(LW_NULL);
            pstatGet->st_mtime   = API_RootFsTime(LW_NULL);
            pstatGet->st_ctime   = API_RootFsTime(LW_NULL);
        } else {
            return  (PX_ERROR);
        }
        break;
        
    case FIOSELECT:
        pselwunNode = (PLW_SEL_WAKEUPNODE)lArg;
        SEL_WAKE_NODE_ADD(&_G_hotplugdev.HOTPDEV_selwulList, pselwunNode);
        
        switch (pselwunNode->SELWUN_seltypType) {
        
        case SELREAD:
            if ((photplugfil->HOTPFIL_pbmsg == LW_NULL) ||
                _bmsgNBytes(photplugfil->HOTPFIL_pbmsg)) {
                SEL_WAKE_UP(pselwunNode);
            }
            break;
            
        case SELWRITE:
            SEL_WAKE_UP(pselwunNode);
            break;
            
        case SELEXCEPT:                                                 /*  不退出                      */
            break;
        }
        break;
        
    case FIOUNSELECT:
        SEL_WAKE_NODE_DELETE(&_G_hotplugdev.HOTPDEV_selwulList, (PLW_SEL_WAKEUPNODE)lArg);
        break;
        
    default:
        _ErrorHandle(ERROR_IO_UNKNOWN_REQUEST);
        return  (PX_ERROR);
    }
    
    return  (ERROR_NONE);
}
Exemplo n.º 3
0
/*********************************************************************************************************
** 函数名称: _evtfdIoctl
** 功能描述: 控制 eventfd 文件
** 输 入  : pevtfdfil        eventfd 文件
**           iRequest         功能
**           lArg             参数
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static INT  _evtfdIoctl (PLW_EVTFD_FILE  pevtfdfil, 
                         INT             iRequest, 
                         LONG            lArg)
{
    struct stat         *pstatGet;
    PLW_SEL_WAKEUPNODE   pselwunNode;
    
    switch (iRequest) {
    
    case FIONBIO:
        if (*(INT *)lArg) {
            pevtfdfil->EF_iFlag |= O_NONBLOCK;
        } else {
            pevtfdfil->EF_iFlag &= ~O_NONBLOCK;
        }
        break;
        
    case FIOFSTATGET:
        pstatGet = (struct stat *)lArg;
        if (pstatGet) {
            pstatGet->st_dev     = (dev_t)&_G_evtfddev;
            pstatGet->st_ino     = (ino_t)0;                            /*  相当于唯一节点              */
            pstatGet->st_mode    = 0666 | S_IFCHR;
            pstatGet->st_nlink   = 1;
            pstatGet->st_uid     = 0;
            pstatGet->st_gid     = 0;
            pstatGet->st_rdev    = 1;
            pstatGet->st_size    = 0;
            pstatGet->st_blksize = 0;
            pstatGet->st_blocks  = 0;
            pstatGet->st_atime   = API_RootFsTime(LW_NULL);
            pstatGet->st_mtime   = API_RootFsTime(LW_NULL);
            pstatGet->st_ctime   = API_RootFsTime(LW_NULL);
        } else {
            _ErrorHandle(EINVAL);
            return  (PX_ERROR);
        }
        break;
        
    case FIOSELECT:
        pselwunNode = (PLW_SEL_WAKEUPNODE)lArg;
        SEL_WAKE_NODE_ADD(&pevtfdfil->EF_selwulist, pselwunNode);
        
        switch (pselwunNode->SELWUN_seltypType) {
        
        case SELREAD:
            if (__evtfd_can_read(pevtfdfil)) {
                SEL_WAKE_UP(pselwunNode);
            }
            break;
            
        case SELWRITE:
            if (__evtfd_can_write(pevtfdfil)) {
                SEL_WAKE_UP(pselwunNode);
            }
            break;
            
        case SELEXCEPT:
            break;
        }
        break;
        
    case FIOUNSELECT:
        SEL_WAKE_NODE_DELETE(&pevtfdfil->EF_selwulist, (PLW_SEL_WAKEUPNODE)lArg);
        break;
        
    default:
        _ErrorHandle(ERROR_IO_UNKNOWN_REQUEST);
        return  (PX_ERROR);
    }
    
    return  (ERROR_NONE);
}