📄 rioctrl.c
字号:
} if ( LpbReq.Link >= LINKS_PER_UNIT ) { /* eek! */ rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal link number %d\n", LpbReq.Link); p->RIOError.Error = LINK_NUMBER_OUT_OF_RANGE; return -EINVAL; } HostP = &p->RIOHosts[LpbReq.Host]; if ( (HostP->Flags & RUN_STATE) != RC_RUNNING ) { rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Host %d not running\n", LpbReq.Host ); p->RIOError.Error = HOST_NOT_RUNNING; return -EIO; } rio_dprintk (RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n", LpbReq.Link, LpbReq.Host); if (copyout((caddr_t)&HostP->LinkStrP[LpbReq.Link], (int)LpbReq.LpbP,sizeof(struct LPB) ) == COPYFAIL) { rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n"); p->RIOError.Error = COPYOUT_FAILED; return -EFAULT; } return retval; /* ** Here 3 IOCTL's that allow us to change the way in which ** rio logs errors. send them just to syslog or send them ** to both syslog and console or send them to just the console. ** ** See RioStrBuf() in util.c for the other half. */ case RIO_SYSLOG_ONLY: p->RIOPrintLogState = PRINT_TO_LOG; /* Just syslog */ return 0; case RIO_SYSLOG_CONS: p->RIOPrintLogState = PRINT_TO_LOG_CONS;/* syslog and console */ return 0; case RIO_CONS_ONLY: p->RIOPrintLogState = PRINT_TO_CONS; /* Just console */ return 0; case RIO_SIGNALS_ON: if ( p->RIOSignalProcess ) { p->RIOError.Error = SIGNALS_ALREADY_SET; return -EBUSY; } p->RIOSignalProcess = getpid(); p->RIOPrintDisabled = DONT_PRINT; return retval; case RIO_SIGNALS_OFF: if ( p->RIOSignalProcess != getpid() ) { p->RIOError.Error = NOT_RECEIVING_PROCESS; return -EPERM; } rio_dprintk (RIO_DEBUG_CTRL, "Clear signal process to zero\n"); p->RIOSignalProcess = 0; return retval; case RIO_SET_BYTE_MODE: for ( Host=0; Host<p->RIONumHosts; Host++ ) if ( p->RIOHosts[Host].Type == RIO_AT ) p->RIOHosts[Host].Mode &= ~WORD_OPERATION; return retval; case RIO_SET_WORD_MODE: for ( Host=0; Host<p->RIONumHosts; Host++ ) if ( p->RIOHosts[Host].Type == RIO_AT ) p->RIOHosts[Host].Mode |= WORD_OPERATION; return retval; case RIO_SET_FAST_BUS: for ( Host=0; Host<p->RIONumHosts; Host++ ) if ( p->RIOHosts[Host].Type == RIO_AT ) p->RIOHosts[Host].Mode |= FAST_AT_BUS; return retval; case RIO_SET_SLOW_BUS: for ( Host=0; Host<p->RIONumHosts; Host++ ) if ( p->RIOHosts[Host].Type == RIO_AT ) p->RIOHosts[Host].Mode &= ~FAST_AT_BUS; return retval; case RIO_MAP_B50_TO_50: case RIO_MAP_B50_TO_57600: case RIO_MAP_B110_TO_110: case RIO_MAP_B110_TO_115200: rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping\n"); port = (uint) arg; if ( port < 0 || port > 511 ) { rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port); p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; return -EINVAL; } rio_spin_lock_irqsave(&PortP->portSem, flags); switch( cmd ) { case RIO_MAP_B50_TO_50 : p->RIOPortp[port]->Config |= RIO_MAP_50_TO_50; break; case RIO_MAP_B50_TO_57600 : p->RIOPortp[port]->Config &= ~RIO_MAP_50_TO_50; break; case RIO_MAP_B110_TO_110 : p->RIOPortp[port]->Config |= RIO_MAP_110_TO_110; break; case RIO_MAP_B110_TO_115200 : p->RIOPortp[port]->Config &= ~RIO_MAP_110_TO_110; break; } rio_spin_unlock_irqrestore( &PortP->portSem , flags); return retval; case RIO_STREAM_INFO: rio_dprintk (RIO_DEBUG_CTRL, "RIO_STREAM_INFO\n"); return -EINVAL; case RIO_SEND_PACKET: rio_dprintk (RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n"); if ( copyin( (int)arg, (caddr_t)&SendPack, sizeof(SendPack) )==COPYFAIL ) { rio_dprintk (RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n"); p->RIOError.Error = COPYIN_FAILED; return -EFAULT; } if ( SendPack.PortNum >= 128 ) { p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; return -ENXIO; } PortP = p->RIOPortp[SendPack.PortNum]; rio_spin_lock_irqsave(&PortP->portSem, flags); if ( !can_add_transmit(&PacketP,PortP) ) { p->RIOError.Error = UNIT_IS_IN_USE; rio_spin_unlock_irqrestore( &PortP->portSem , flags); return -ENOSPC; } for ( loop=0; loop<(ushort)(SendPack.Len & 127); loop++ ) WBYTE(PacketP->data[loop], SendPack.Data[loop] ); WBYTE(PacketP->len, SendPack.Len); add_transmit( PortP ); /* ** Count characters transmitted for port statistics reporting */ if (PortP->statsGather) PortP->txchars += (SendPack.Len & 127); rio_spin_unlock_irqrestore( &PortP->portSem , flags); return retval; case RIO_NO_MESG: if ( su ) p->RIONoMessage = 1; return su ? 0 : -EPERM; case RIO_MESG: if ( su ) p->RIONoMessage = 0; return su ? 0 : -EPERM; case RIO_WHAT_MESG: if ( copyout( (caddr_t)&p->RIONoMessage, (int)arg, sizeof(p->RIONoMessage) )==COPYFAIL ) { rio_dprintk (RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n"); p->RIOError.Error = COPYOUT_FAILED; return -EFAULT; } return 0; case RIO_MEM_DUMP : if (copyin((int)arg, (caddr_t)&SubCmd, sizeof(struct SubCmdStruct)) == COPYFAIL) { p->RIOError.Error = COPYIN_FAILED; return -EFAULT; } rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP host %d rup %d addr %x\n", SubCmd.Host, SubCmd.Rup, SubCmd.Addr); if (SubCmd.Rup >= MAX_RUP+LINKS_PER_UNIT ) { p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; return -EINVAL; } if (SubCmd.Host >= p->RIONumHosts ) { p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; return -EINVAL; } port = p->RIOHosts[SubCmd.Host]. UnixRups[SubCmd.Rup].BaseSysPort; PortP = p->RIOPortp[port]; rio_spin_lock_irqsave(&PortP->portSem, flags); if ( RIOPreemptiveCmd(p, PortP, MEMDUMP ) == RIO_FAIL ) { rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n"); rio_spin_unlock_irqrestore( &PortP->portSem , flags); return -EBUSY; } else PortP->State |= RIO_BUSY; rio_spin_unlock_irqrestore( &PortP->portSem , flags); if ( copyout( (caddr_t)p->RIOMemDump, (int)arg, MEMDUMP_SIZE) == COPYFAIL ) { rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n"); p->RIOError.Error = COPYOUT_FAILED; return -EFAULT; } return 0; case RIO_TICK: if ((int)arg < 0 || (int)arg >= p->RIONumHosts) return -EINVAL; rio_dprintk (RIO_DEBUG_CTRL, "Set interrupt for host %d\n", (int)arg); WBYTE(p->RIOHosts[(int)arg].SetInt , 0xff); return 0; case RIO_TOCK: if ((int)arg < 0 || (int)arg >= p->RIONumHosts) return -EINVAL; rio_dprintk (RIO_DEBUG_CTRL, "Clear interrupt for host %d\n", (int)arg); WBYTE((p->RIOHosts[(int)arg].ResetInt) , 0xff); return 0; case RIO_READ_CHECK: /* Check reads for pkts with data[0] the same */ p->RIOReadCheck = !p->RIOReadCheck; if (copyout((caddr_t)&p->RIOReadCheck,(int)arg, sizeof(uint))== COPYFAIL) { p->RIOError.Error = COPYOUT_FAILED; return -EFAULT; } return 0; case RIO_READ_REGISTER : if (copyin((int)arg, (caddr_t)&SubCmd, sizeof(struct SubCmdStruct)) == COPYFAIL) { p->RIOError.Error = COPYIN_FAILED; return -EFAULT; } rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER host %d rup %d port %d reg %x\n", SubCmd.Host, SubCmd.Rup, SubCmd.Port, SubCmd.Addr); if (SubCmd.Port > 511) { rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", SubCmd.Port); p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; return -EINVAL; } if (SubCmd.Rup >= MAX_RUP+LINKS_PER_UNIT ) { p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; return -EINVAL; } if (SubCmd.Host >= p->RIONumHosts ) { p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; return -EINVAL; } port = p->RIOHosts[SubCmd.Host]. UnixRups[SubCmd.Rup].BaseSysPort + SubCmd.Port; PortP = p->RIOPortp[port]; rio_spin_lock_irqsave(&PortP->portSem, flags); if (RIOPreemptiveCmd(p, PortP, READ_REGISTER) == RIO_FAIL) { rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n"); rio_spin_unlock_irqrestore( &PortP->portSem , flags); return -EBUSY; } else PortP->State |= RIO_BUSY; rio_spin_unlock_irqrestore( &PortP->portSem , flags); if (copyout((caddr_t)&p->CdRegister, (int)arg, sizeof(uint)) == COPYFAIL ) { rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n"); p->RIOError.Error = COPYOUT_FAILED; return -EFAULT; } return 0; /* ** rio_make_dev: given port number (0-511) ORed with port type ** (RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT) return dev_t ** value to pass to mknod to create the correct device node. */ case RIO_MAKE_DEV: { uint port = (uint)arg & RIO_MODEM_MASK; switch ( (uint)arg & RIO_DEV_MASK ) { case RIO_DEV_DIRECT: arg = (caddr_t)drv_makedev(MAJOR(dev), port); rio_dprintk (RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n",port, (int)arg); return (int)arg; case RIO_DEV_MODEM: arg = (caddr_t)drv_makedev(MAJOR(dev), (port|RIO_MODEM_BIT) ); rio_dprintk (RIO_DEBUG_CTRL, "Makedev modem 0x%x is 0x%x\n",port, (int)arg); return (int)arg; case RIO_DEV_XPRINT: arg = (caddr_t)drv_makedev(MAJOR(dev), port); rio_dprintk (RIO_DEBUG_CTRL, "Makedev printer 0x%x is 0x%x\n",port, (int)arg); return (int)arg; } rio_dprintk (RIO_DEBUG_CTRL, "MAKE Device is called\n"); return -EINVAL; } /* ** rio_minor: given a dev_t from a stat() call, return ** the port number (0-511) ORed with the port type ** ( RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT ) */ case RIO_MINOR: { dev_t dv; int mino; dv = (dev_t)((int)arg); mino = RIO_UNMODEM(dv); if ( RIO_ISMODEM(dv) ) { rio_dprintk (RIO_DEBUG_CTRL, "Minor for device 0x%x: modem %d\n", dv, mino); arg = (caddr_t)(mino | RIO_DEV_MODEM); } else { rio_dprintk (RIO_DEBUG_CTRL, "Minor for device 0x%x: direct %d\n", dv, mino); arg = (caddr_t)(mino | RIO_DEV_DIRECT); } return (int)arg; } } rio_dprintk (RIO_DEBUG_CTRL, "INVALID DAEMON IOCTL 0x%x\n",cmd); p->RIOError.Error = IOCTL_COMMAND_UNKNOWN; func_exit (); return -EINVAL;}/*** Pre-emptive commands go on RUPs and are only one byte long.*/intRIOPreemptiveCmd(p, PortP, Cmd)struct rio_info * p;struct Port *PortP;uchar Cmd;{ struct CmdBlk *CmdBlkP; struct PktCmd_M *PktCmdP; int Ret; ushort rup; int port;#ifdef CHECK CheckPortP( PortP );#endif if ( PortP->State & RIO_DELETED ) { rio_dprintk (RIO_DEBUG_CTRL, "Preemptive command to deleted RTA ignored\n"); return RIO_FAIL; } if (((int)((char)PortP->InUse) == -1) || ! (CmdBlkP = RIOGetCmdBlk()) ) { rio_dprintk (RIO_DEBUG_CTRL, "Cannot allocate command block for command %d on port %d\n", Cmd, PortP->PortNum); return RIO_FAIL; } rio_dprintk (RIO_DEBUG_CTRL, "Command blk 0x%x - InUse now %d\n", (int)CmdBlkP,PortP->InUse); PktCmdP = (struct PktCmd_M *)&CmdBlkP->Packet.data[0]; CmdBlkP->Packet.src_unit = 0; if (PortP->SecondBlock) rup = PortP->ID2; else rup = PortP->RupNum; CmdBlkP->Packet.dest_unit = rup; CmdBlkP->Packet.src_port = COMMAND_RUP; CmdBlkP->Packet.dest_port = COMMAND_RUP; CmdBlkP->Packet.len = PKT_CMD_BIT | 2; CmdBlkP->PostFuncP = RIOUnUse; CmdBlkP->PostArg = (int)PortP; PktCmdP->Command = Cmd; port = PortP->HostPort % (ushort)PORTS_PER_RTA; /* ** Index ports 8-15 for 2nd block of 16 port RTA. */ if (PortP->SecondBlock) port += (ushort) PORTS_PER_RTA; PktCmdP->PhbNum = port; switch ( Cmd ) { case MEMDUMP: rio_dprintk (RIO_DEBUG_CTRL, "Queue MEMDUMP command blk 0x%x (addr 0x%x)\n", (int)CmdBlkP, (int)SubCmd.Addr); PktCmdP->SubCommand = MEMDUMP; PktCmdP->SubAddr = SubCmd.Addr; break; case FCLOSE: rio_dprintk (RIO_DEBUG_CTRL, "Queue FCLOSE command blk 0x%x\n",(int)CmdBlkP); break; case READ_REGISTER: rio_dprintk (RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) command blk 0x%x\n", (int)SubCmd.Addr, (int)CmdBlkP); PktCmdP->SubCommand = READ_REGISTER; PktCmdP->SubAddr = SubCmd.Addr; break; case RESUME: rio_dprintk (RIO_DEBUG_CTRL, "Queue RESUME command blk 0x%x\n",(int)CmdBlkP); break; case RFLUSH: rio_dprintk (RIO_DEBUG_CTRL, "Queue RFLUSH command blk 0x%x\n",(int)CmdBlkP); CmdBlkP->PostFuncP = RIORFlushEnable; break; case SUSPEND: rio_dprintk (RIO_DEBUG_CTRL, "Queue SUSPEND command blk 0x%x\n",(int)CmdBlkP); break; case MGET : rio_dprintk (RIO_DEBUG_CTRL, "Queue MGET command blk 0x%x\n", (int)CmdBlkP); break; case MSET : case MBIC : case MBIS : CmdBlkP->Packet.data[4] = (char) PortP->ModemLines; rio_dprintk (RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command blk 0x%x\n", (int)CmdBlkP); break; case WFLUSH: /* ** If we have queued up the maximum number of Write flushes ** allowed then we should not bother sending any more to the ** RTA. */ if ((int)((char)PortP->WflushFlag) == (int)-1) { rio_dprintk (RIO_DEBUG_CTRL, "Trashed WFLUSH, WflushFlag about to wrap!"); RIOFreeCmdBlk(CmdBlkP); return(RIO_FAIL); } else { rio_dprintk (RIO_DEBUG_CTRL, "Queue WFLUSH command blk 0x%x\n", (int)CmdBlkP); CmdBlkP->PostFuncP = RIOWFlushMark; } break; } PortP->InUse++; Ret = RIOQueueCmdBlk( PortP->HostP, rup, CmdBlkP ); return Ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -