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

📄 riocmd.c

📁 h内核
💻 C
📖 第 1 页 / 共 3 页
字号:
		return -EIO;	}	return 0;}intRIOFoadWakeup(p)struct rio_info *	p;{	int port;	register struct Port *PortP;	unsigned long flags;	for ( port=0; port<RIO_PORTS; port++) {		PortP = p->RIOPortp[port];		rio_spin_lock_irqsave(&PortP->portSem, flags);		PortP->Config = 0;		PortP->State = 0;		PortP->InUse = NOT_INUSE;		PortP->PortState = 0;		PortP->FlushCmdBodge = 0;		PortP->ModemLines = 0;		PortP->ModemState = 0;		PortP->CookMode = 0;		PortP->ParamSem = 0;		PortP->Mapped = 0;		PortP->WflushFlag = 0;		PortP->MagicFlags = 0;		PortP->RxDataStart = 0;		PortP->TxBufferIn = 0;		PortP->TxBufferOut = 0;		rio_spin_unlock_irqrestore(&PortP->portSem, flags);	}	return(0);}/*** Incoming command on the COMMAND_RUP to be processed.*/static intRIOCommandRup(p, Rup, HostP, PacketP)struct rio_info *	p;uint Rup;struct Host *HostP;PKT *PacketP; {	struct PktCmd *PktCmdP = (struct PktCmd *)PacketP->data;	struct Port *PortP;	struct UnixRup *UnixRupP;	ushort SysPort;	ushort ReportedModemStatus;	ushort rup;	ushort subCommand;	unsigned long flags;	func_enter ();#ifdef CHECK	CheckHost( Host );	CheckHostP( HostP );	CheckPacketP( PacketP );#endif	/*	** 16 port RTA note:	** Command rup packets coming from the RTA will have pkt->data[1] (which	** translates to PktCmdP->PhbNum) set to the host port number for the	** particular unit. To access the correct BaseSysPort for a 16 port RTA,	** we can use PhbNum to get the rup number for the appropriate 8 port	** block (for the first block, this should be equal to 'Rup').	*/	rup = RBYTE(PktCmdP->PhbNum) / (ushort)PORTS_PER_RTA;	UnixRupP = &HostP->UnixRups[rup];	SysPort = UnixRupP->BaseSysPort + 			(RBYTE(PktCmdP->PhbNum) % (ushort)PORTS_PER_RTA);	rio_dprintk (RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort);#ifdef CHECK	CheckRup( rup );	CheckUnixRupP( UnixRupP );#endif	if ( UnixRupP->BaseSysPort == NO_PORT ) {		rio_dprintk (RIO_DEBUG_CMD, "OBSCURE ERROR!\n");		rio_dprintk (RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n");		rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Host number %d, name ``%s''\n", 			     HostP-p->RIOHosts, HostP->Name );		rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Rup number  0x%x\n", rup);		if ( Rup >= (ushort)MAX_RUP ) {			rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n",				     HostP->Mapping[Rup].Name);		} else			rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", 				     ('A' + Rup - MAX_RUP), HostP->Name);		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n",			     PacketP->dest_unit, PacketP->dest_port );		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Source	  0x%x:0x%x\n",			     PacketP->src_unit, PacketP->src_port );		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Length	  0x%x (%d)\n", PacketP->len,PacketP->len );		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Control	 0x%x (%d)\n", PacketP->control, PacketP->control);		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Check	   0x%x (%d)\n", PacketP->csum, PacketP->csum );		rio_dprintk (RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, "					"Command Code 0x%x\n", PktCmdP->PhbNum, PktCmdP->Command );		return TRUE;	}#ifdef CHECK	CheckSysPort( SysPort );#endif	PortP = p->RIOPortp[ SysPort ];	rio_spin_lock_irqsave(&PortP->portSem, flags);	switch( RBYTE(PktCmdP->Command) ) {		case BREAK_RECEIVED:			rio_dprintk (RIO_DEBUG_CMD, "Received a break!\n");			/* If the current line disc. is not multi-threading and	   			the current processor is not the default, reset rup_intr	   			and return FALSE to ensure that the command packet is	   			not freed. */			/* Call tmgr HANGUP HERE */			/* Fix this later when every thing works !!!! RAMRAJ */			gs_got_break (&PortP->gs);			break;		case COMPLETE:			rio_dprintk (RIO_DEBUG_CMD, "Command complete on phb %d host %d\n",			     RBYTE(PktCmdP->PhbNum), HostP-p->RIOHosts);			subCommand = 1;			switch (RBYTE(PktCmdP->SubCommand)) {				case MEMDUMP :			rio_dprintk (RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n",				     RBYTE(PktCmdP->SubCommand), RWORD(PktCmdP->SubAddr));					break;				case READ_REGISTER :			rio_dprintk (RIO_DEBUG_CMD, "Read register (0x%x)\n", RWORD(PktCmdP->SubAddr));					p->CdRegister = (RBYTE(PktCmdP->ModemStatus) & MSVR1_HOST);					break;				default :					subCommand = 0;				break;			}			if (subCommand)				break;			rio_dprintk (RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n",				     RBYTE(PktCmdP->PortStatus),PortP->PortState);			if (PortP->PortState != RBYTE(PktCmdP->PortStatus)) {				rio_dprintk (RIO_DEBUG_CMD, "Mark status & wakeup\n");				PortP->PortState = RBYTE(PktCmdP->PortStatus);				/* What should we do here ...				wakeup( &PortP->PortState );				*/		} else 			rio_dprintk (RIO_DEBUG_CMD, "No change\n");			/* FALLTHROUGH */		case MODEM_STATUS:			/*			** Knock out the tbusy and tstop bits, as these are not relevant			** to the check for modem status change (they're just there because			** it's a convenient place to put them!).			*/			ReportedModemStatus = RBYTE(PktCmdP->ModemStatus);			if ((PortP->ModemState & MSVR1_HOST) ==					(ReportedModemStatus & MSVR1_HOST)) {				rio_dprintk (RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState);				/*				** Update ModemState just in case tbusy or tstop states have				** changed.				*/				PortP->ModemState = ReportedModemStatus;			}			else {				rio_dprintk (RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%x\n",				     PortP->ModemState, ReportedModemStatus);				PortP->ModemState = ReportedModemStatus;#ifdef MODEM_SUPPORT				if ( PortP->Mapped ) {				/***********************************************************\				*************************************************************				***													   ***				***		  M O D E M   S T A T E   C H A N G E		  ***				***													   ***				*************************************************************				\***********************************************************/				/*				** If the device is a modem, then check the modem				** carrier.				*/				if (PortP->gs.tty == NULL)					break;				if (PortP->gs.tty->termios == NULL)					break;			  				if (!(PortP->gs.tty->termios->c_cflag & CLOCAL) &&				((PortP->State & (RIO_MOPEN|RIO_WOPEN)))) {					rio_dprintk (RIO_DEBUG_CMD, "Is there a Carrier?\n");			/*			** Is there a carrier?			*/					if ( PortP->ModemState & MSVR1_CD ) {			/*			** Has carrier just appeared?			*/						if (!(PortP->State & RIO_CARR_ON)) {							rio_dprintk (RIO_DEBUG_CMD, "Carrier just came up.\n");							PortP->State |= RIO_CARR_ON;				/*				** wakeup anyone in WOPEN				*/							if (PortP->State & (PORT_ISOPEN | RIO_WOPEN) )								wake_up_interruptible (&PortP->gs.open_wait);#ifdef STATS				PortP->Stat.ModemOnCnt++;#endif			}					} else {			/*			** Has carrier just dropped?			*/						if (PortP->State & RIO_CARR_ON) {							if (PortP->State & (PORT_ISOPEN|RIO_WOPEN|RIO_MOPEN))								tty_hangup (PortP->gs.tty);							PortP->State &= ~RIO_CARR_ON;							rio_dprintk (RIO_DEBUG_CMD, "Carrirer just went down\n");#ifdef STATS				PortP->Stat.ModemOffCnt++;#endif			}			}		}		}#endif			}			break;		default:			rio_dprintk (RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %d\n",			     RBYTE(PktCmdP->Command),HostP-p->RIOHosts);			break;	}	rio_spin_unlock_irqrestore(&PortP->portSem, flags);	func_exit ();	return TRUE;}/*** The command mechanism:**	Each rup has a chain of commands associated with it.**	This chain is maintained by routines in this file.**	Periodically we are called and we run a quick check of all the**	active chains to determine if there is a command to be executed,**	and if the rup is ready to accept it.***//*** Allocate an empty command block.*/struct CmdBlk *RIOGetCmdBlk(){	struct CmdBlk *CmdBlkP;	CmdBlkP = (struct CmdBlk *)sysbrk(sizeof(struct CmdBlk));	if (CmdBlkP)		bzero(CmdBlkP, sizeof(struct CmdBlk));	return CmdBlkP;}/*** Return a block to the head of the free list.*/voidRIOFreeCmdBlk(CmdBlkP)struct CmdBlk *CmdBlkP;{	sysfree((void *)CmdBlkP, sizeof(struct CmdBlk));}/*** attach a command block to the list of commands to be performed for** a given rup.*/intRIOQueueCmdBlk(HostP, Rup, CmdBlkP)struct Host *HostP;uint Rup;struct CmdBlk *CmdBlkP;{	struct CmdBlk **Base;	struct UnixRup *UnixRupP;	unsigned long flags;#ifdef CHECK	CheckHostP( HostP );	CheckRup( Rup );	CheckCmdBlkP( CmdBlkP );#endif	if ( Rup >= (ushort)(MAX_RUP+LINKS_PER_UNIT) ) {		rio_dprintk (RIO_DEBUG_CMD, "Illegal rup number %d in RIOQueueCmdBlk\n",Rup);		RIOFreeCmdBlk( CmdBlkP );		return RIO_FAIL;	}	UnixRupP = &HostP->UnixRups[Rup];	rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);	/*	** If the RUP is currently inactive, then put the request	** straight on the RUP....	*/	if ( (UnixRupP->CmdsWaitingP == NULL) && (UnixRupP->CmdPendingP == NULL) && 	     (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE ) &&		(CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP)(CmdBlkP->PreArg,CmdBlkP)							:TRUE)) {		rio_dprintk (RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%x\n",					     CmdBlkP->Packet.data[0]);                                            		/*		** Whammy! blat that pack!		*/		HostP->Copy( (caddr_t)&CmdBlkP->Packet, 			RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt ), sizeof(PKT) );		/*		** place command packet on the pending position.		*/		UnixRupP->CmdPendingP = CmdBlkP;		/*		** set the command register		*/		WWORD(UnixRupP->RupP->txcontrol , TX_PACKET_READY);		rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);		return RIO_SUCCESS;	}	rio_dprintk (RIO_DEBUG_CMD, "RUP active - en-queing\n");	if ( UnixRupP->CmdsWaitingP != NULL)		rio_dprintk (RIO_DEBUG_CMD, "Rup active - command waiting\n");	if ( UnixRupP->CmdPendingP != NULL )		rio_dprintk (RIO_DEBUG_CMD, "Rup active - command pending\n");	if ( RWORD(UnixRupP->RupP->txcontrol) != TX_RUP_INACTIVE )		rio_dprintk (RIO_DEBUG_CMD, "Rup active - command rup not ready\n");	Base = &UnixRupP->CmdsWaitingP;	rio_dprintk (RIO_DEBUG_CMD, "First try to queue cmdblk 0x%x at 0x%x\n", (int)CmdBlkP,(int)Base);	while ( *Base ) {		rio_dprintk (RIO_DEBUG_CMD, "Command cmdblk 0x%x here\n", (int)(*Base));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -