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

📄 riointr.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 3 页
字号:
  */  intCount++;  TtyP = PortP->gs.tty;  if (!TtyP) {    rio_dprintk (RIO_DEBUG_INTR, "RIOReceive: tty is null. \n");    return;  }  if (PortP->State & RIO_THROTTLE_RX) {    rio_dprintk (RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n");    return;  }  if ( PortP->State & RIO_DELETED )    {      while ( can_remove_receive( &PacketP, PortP ) )	{	  remove_receive( PortP );	  put_free_end( PortP->HostP, PacketP );	}    }  else    {      /*      ** loop, just so long as:      **   i ) there's some data ( i.e. can_remove_receive )      **  ii ) we haven't been blocked      ** iii ) there's somewhere to put the data      **  iv ) we haven't outstayed our welcome      */      transCount = 1;      while ( can_remove_receive(&PacketP, PortP)	      && transCount)	{#ifdef STATS	  PortP->Stat.RxIntCnt++;#endif /* STATS */	  RxIntCnt++;	  /*	  ** check that it is not a command!	  */	  if ( PacketP->len & PKT_CMD_BIT ) {	    rio_dprintk (RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n");	    /*	    rio_dprint(RIO_DEBUG_INTR, (" sysport   = %d\n", p->RIOPortp->PortNum)); */	    rio_dprintk (RIO_DEBUG_INTR, " dest_unit = %d\n", PacketP->dest_unit);	    rio_dprintk (RIO_DEBUG_INTR, " dest_port = %d\n", PacketP->dest_port);	    rio_dprintk (RIO_DEBUG_INTR, " src_unit  = %d\n", PacketP->src_unit);	    rio_dprintk (RIO_DEBUG_INTR, " src_port  = %d\n", PacketP->src_port);	    rio_dprintk (RIO_DEBUG_INTR, " len	   = %d\n", PacketP->len);	    rio_dprintk (RIO_DEBUG_INTR, " control   = %d\n", PacketP->control);	    rio_dprintk (RIO_DEBUG_INTR, " csum	   = %d\n", PacketP->csum);	    rio_dprintk (RIO_DEBUG_INTR, "	 data bytes: ");	    for ( DataCnt=0; DataCnt<PKT_MAX_DATA_LEN; DataCnt++ )	      rio_dprintk (RIO_DEBUG_INTR, "%d\n", PacketP->data[DataCnt]);	    remove_receive( PortP );	    put_free_end( PortP->HostP, PacketP );	    continue; /* with next packet */	  }	  /*	  ** How many characters can we move 'upstream' ?	  **	  ** Determine the minimum of the amount of data	  ** available and the amount of space in which to	  ** put it.	  **	  ** 1.	Get the packet length by masking 'len'	  **	for only the length bits.	  ** 2.	Available space is [buffer size] - [space used]	  **	  ** Transfer count is the minimum of packet length	  ** and available space.	  */				  transCount = min_t(unsigned int, PacketP->len & PKT_LEN_MASK,			   TTY_FLIPBUF_SIZE - TtyP->flip.count);	  rio_dprintk (RIO_DEBUG_REC,  "port %d: Copy %d bytes\n", 				      PortP->PortNum, transCount);	  /*	  ** To use the following 'kkprintfs' for debugging - change the '#undef'	  ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the	  ** driver).	  */#undef ___DEBUG_IT___#ifdef ___DEBUG_IT___	  kkprintf("I:%d R:%d P:%d Q:%d C:%d F:%x ",		   intCount,		   RxIntCnt,		   PortP->PortNum,		   TtyP->rxqueue.count,		   transCount,		   TtyP->flags );#endif	  ptr = (uchar *) PacketP->data + PortP->RxDataStart;	  rio_memcpy_fromio (TtyP->flip.char_buf_ptr, ptr, transCount);	  memset(TtyP->flip.flag_buf_ptr, TTY_NORMAL, transCount);#ifdef STATS	  /*	  ** keep a count for statistical purposes	  */	  PortP->Stat.RxCharCnt	+= transCount;#endif	  PortP->RxDataStart	+= transCount;	  PacketP->len		-= transCount;	  copied += transCount;	  TtyP->flip.count += transCount;	  TtyP->flip.char_buf_ptr += transCount;	  TtyP->flip.flag_buf_ptr += transCount;#ifdef ___DEBUG_IT___	  kkprintf("T:%d L:%d\n", DataCnt, PacketP->len );#endif	  if ( PacketP->len == 0 )	    {				/*				** If we have emptied the packet, then we can				** free it, and reset the start pointer for				** the next packet.				*/	      remove_receive( PortP );	      put_free_end( PortP->HostP, PacketP );	      PortP->RxDataStart = 0;#ifdef STATS				/*				** more lies ( oops, I mean statistics )				*/	      PortP->Stat.RxPktCnt++;#endif /* STATS */	    }	}    }  if (copied) {    rio_dprintk (RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied);    tty_flip_buffer_push (TtyP);  }  return;}#ifdef FUTURE_RELEASE/*** The proc routine called by the line discipline to do the work for it.** The proc routine works hand in hand with the interrupt routine.*/intriotproc(p, tp, cmd, port)struct rio_info *	p;register struct ttystatics *tp;int cmd;int	port;{	register struct Port *PortP;	int SysPort;	struct PKT *PacketP;	SysPort = port;	/* Believe me, it works. */	if ( SysPort < 0 || SysPort >= RIO_PORTS ) {		rio_dprintk (RIO_DEBUG_INTR, "Illegal port %d derived from TTY in riotproc()\n",SysPort);		return 0;	}	PortP = p->RIOPortp[SysPort];	if ((uint)PortP->PhbP < (uint)PortP->Caddr || 			(uint)PortP->PhbP >= (uint)PortP->Caddr+SIXTY_FOUR_K ) {		rio_dprintk (RIO_DEBUG_INTR, "RIO: NULL or BAD PhbP on sys port %d in proc routine\n",							SysPort);		rio_dprintk (RIO_DEBUG_INTR, "	 PortP = 0x%x\n",PortP);		rio_dprintk (RIO_DEBUG_INTR, "	 PortP->PhbP = 0x%x\n",PortP->PhbP);		rio_dprintk (RIO_DEBUG_INTR, "	 PortP->Caddr = 0x%x\n",PortP->PhbP);		rio_dprintk (RIO_DEBUG_INTR, "	 PortP->HostPort = 0x%x\n",PortP->HostPort);		return 0;	}	switch(cmd) {		case T_WFLUSH:			rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH\n");			/*			** Because of the spooky way the RIO works, we don't need			** to issue a flush command on any of the SET*F commands,			** as that causes trouble with getty and login, which issue			** these commands to incur a READ flush, and rely on the fact			** that the line discipline does a wait for drain for them.			** As the rio doesn't wait for drain, the write flush would			** destroy the Password: prompt. This isn't very friendly, so			** here we only issue a WFLUSH command if we are in the interrupt			** routine, or we aren't executing a SET*F command.			*/			if ( PortP->HostP->InIntr || !PortP->FlushCmdBodge ) {				/*				** form a wflush packet - 1 byte long, no data				*/				if ( PortP->State & RIO_DELETED ) {					rio_dprintk (RIO_DEBUG_INTR, "WFLUSH on deleted RTA\n");				}				else {					if ( RIOPreemptiveCmd(p, PortP, WFLUSH ) == RIO_FAIL ) {						rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command failed\n");					}					else						rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command\n");				}				/*				** WFLUSH operation - flush the data!				*/				PortP->TxBufferIn = PortP->TxBufferOut = 0;			}			else {				rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command ignored\n");			}			/*			** sort out the line discipline			*/			if (PortP->CookMode == COOK_WELL)				goto start;			break;			case T_RESUME:			rio_dprintk (RIO_DEBUG_INTR, "T_RESUME\n");			/*			** send pre-emptive resume packet			*/			if ( PortP->State & RIO_DELETED ) {				rio_dprintk (RIO_DEBUG_INTR, "RESUME on deleted RTA\n");			}			else {				if ( RIOPreemptiveCmd(p, PortP, RESUME ) == RIO_FAIL ) {					rio_dprintk (RIO_DEBUG_INTR, "T_RESUME Command failed\n");				}			}			/*			** and re-start the sender software!			*/			if (PortP->CookMode == COOK_WELL)				goto start;			break;			case T_TIME:			rio_dprintk (RIO_DEBUG_INTR, "T_TIME\n");			/*			** T_TIME is called when xDLY is set in oflags and			** the line discipline timeout has expired. It's			** function in life is to clear the TIMEOUT flag			** and to re-start output to the port.			*/			/*			** Fall through and re-start output			*/		case T_OUTPUT:start:			if ( PortP->MagicFlags & MAGIC_FLUSH ) {				PortP->MagicFlags |= MORE_OUTPUT_EYGOR;				return 0;			}			RIOTxEnable((char *)PortP);			PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR;			/*rio_dprint(RIO_DEBUG_INTR, PortP,DBG_PROC,"T_OUTPUT finished\n");*/			break;			case T_SUSPEND:			rio_dprintk (RIO_DEBUG_INTR, "T_SUSPEND\n");			/*			** send a suspend pre-emptive packet.			*/			if ( PortP->State & RIO_DELETED ) {				rio_dprintk (RIO_DEBUG_INTR, "SUSPEND deleted RTA\n");			}			else {				if ( RIOPreemptiveCmd(p, PortP, SUSPEND ) == RIO_FAIL ) {					rio_dprintk (RIO_DEBUG_INTR, "T_SUSPEND Command failed\n");				}			}			/*			** done!			*/			break;			case T_BLOCK:			rio_dprintk (RIO_DEBUG_INTR, "T_BLOCK\n");			break;			case T_RFLUSH:			rio_dprintk (RIO_DEBUG_INTR, "T_RFLUSH\n");			if ( PortP->State & RIO_DELETED ) {				rio_dprintk (RIO_DEBUG_INTR, "RFLUSH on deleted RTA\n");				PortP->RxDataStart = 0;			}			else {				if ( RIOPreemptiveCmd( p, PortP, RFLUSH ) == RIO_FAIL ) {					rio_dprintk (RIO_DEBUG_INTR, "T_RFLUSH Command failed\n");					return 0;				}				PortP->RxDataStart = 0;				while ( can_remove_receive(&PacketP, PortP) ) {					remove_receive(PortP);					ShowPacket(DBG_PROC, PacketP );					put_free_end(PortP->HostP, PacketP );				}				if ( PortP->PhbP->handshake == PHB_HANDSHAKE_SET ) {					/*					** MAGIC!					*/					rio_dprintk (RIO_DEBUG_INTR, "Set receive handshake bit\n");					PortP->PhbP->handshake |= PHB_HANDSHAKE_RESET;				}			}			break;			/* FALLTHROUGH */		case T_UNBLOCK:			rio_dprintk (RIO_DEBUG_INTR, "T_UNBLOCK\n");			/*			** If there is any data to receive set a timeout to service it.			*/			RIOReceive(p, PortP);			break;			case T_BREAK:			rio_dprintk (RIO_DEBUG_INTR, "T_BREAK\n");			/*			** Send a break command. For Sys V			** this is a timed break, so we			** send a SBREAK[time] packet			*/			/*			** Build a BREAK command			*/			if ( PortP->State & RIO_DELETED ) {				rio_dprintk (RIO_DEBUG_INTR, "BREAK on deleted RTA\n");			}			else {				if (RIOShortCommand(PortP,SBREAK,2,								p->RIOConf.BreakInterval)==RIO_FAIL) {			   		rio_dprintk (RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n");				}			}				/*			** done!			*/			break;			case T_INPUT:			rio_dprintk (RIO_DEBUG_INTR, "Proc T_INPUT called - I don't know what to do!\n");			break;		case T_PARM:			rio_dprintk (RIO_DEBUG_INTR, "Proc T_PARM called - I don't know what to do!\n");			break;			case T_SWTCH:			rio_dprintk (RIO_DEBUG_INTR, "Proc T_SWTCH called - I don't know what to do!\n");			break;			default:			rio_dprintk (RIO_DEBUG_INTR, "Proc UNKNOWN command %d\n",cmd);	}	/*	** T_OUTPUT returns without passing through this point!	*/	/*rio_dprint(RIO_DEBUG_INTR, PortP,DBG_PROC,"riotproc done\n");*/	return(0);}#endif

⌨️ 快捷键说明

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