⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rioctrl.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
				}				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 + -