plan 9 kernel history: overview | file list | diff list

1990/0321/gnot/devincon.c (diff list | history)

1990/0320/sys/src/9/gnot/devincon.c:23,301990/0321/sys/src/9/gnot/devincon.c:23,31 (short | long | prev | next)
1990/0312    
	Minstation=	2,	/* lowest station # to poll */ 
	Maxstation=	15,	/* highest station # to poll */ 
	Nincon=		1,	/* number of incons */ 
1990/0320    
	Nin=		16,	/* Blocks in the input ring */ 
1990/0321    
	Nin=		64,	/* Blocks in the input ring */ 
1990/0320    
	Bsize=		128,	/* size of an input ring block */ 
1990/0321    
	Mfifo=		0xff	/* a mask, must be 2^n-1, must be > Nin */ 
1990/0312    
}; 
 
/* 
1990/0320/sys/src/9/gnot/devincon.c:631,6371990/0321/sys/src/9/gnot/devincon.c:632,638
1990/0315    
} 
1990/0312    
 
1990/0315    
/* 
 *  drop an input packet on the floor 
1990/0321    
 *  drop a single packet 
1990/0315    
 */ 
static void 
droppacket(Device *dev) 
1990/0320/sys/src/9/gnot/devincon.c:639,6551990/0321/sys/src/9/gnot/devincon.c:640,663
1990/0315    
	int i; 
	int c; 
 
1990/0320    
	screenputc('!'); 
	while(!(dev->status & RCV_EMPTY)){ 
		for(i = 0; i < 17; i++){ 
			c = dev->data_cntl; 
			if(c==0) 
				break; 
		} 
1990/0321    
	for(i = 0; i < 17; i++){ 
		c = dev->data_cntl; 
		if(c==0) 
			break; 
1990/0315    
	} 
} 
 
/* 
1990/0321    
 *  flush the input fifo 
 */ 
static void 
flushfifo(Device *dev) 
{ 
	while(!(dev->status & RCV_EMPTY)) 
		droppacket(dev); 
} 
 
/* 
1990/0315    
 *  advance the queue. if we've run out of staged input blocks, 
 *  drop the packet and return 0.  otherwise return the next input 
 *  block to fill. 
1990/0320/sys/src/9/gnot/devincon.c:657,6761990/0321/sys/src/9/gnot/devincon.c:665,685
1990/0315    
static Block * 
nextin(Incon *ip, unsigned int c) 
{ 
	Block *bp = ip->inb[ip->wi]; 
1990/0321    
	Block *bp; 
1990/0320    
	int next; 
1990/0315    
 
1990/0320    
	next = (ip->wi+1)%Nin; 
	if(next == ip->ri){ 
		bp->wptr = bp->base+3; 
		droppacket(ip->dev); 
		return 0; 
	} 
1990/0321    
	bp = ip->inb[ip->wi]; 
1990/0315    
	bp->base[0] = ip->chan; 
	bp->base[1] = ip->chan>>8; 
	bp->base[2] = c; 
1990/0320    
	ip->wi = next; 
1990/0315    
 
1990/0321    
	next = (ip->wi+3)%Nin; 
	if(next == ip->ri){ 
		bp->wptr = bp->base+3; 
		return bp; 
	} 
	ip->wi = (ip->wi+1)%Nin; 
 
1990/0315    
	return ip->inb[ip->wi]; 
} 
 
1990/0320/sys/src/9/gnot/devincon.c:690,6971990/0321/sys/src/9/gnot/devincon.c:699,706
1990/0315    
	dev = ip->dev; 
1990/0320    
	bp = ip->inb[ip->wi]; 
	if(bp==0){ 
		droppacket(ip->dev); 
		goto done; 
1990/0321    
		flushfifo(ip->dev); 
		return; 
1990/0320    
	} 
	p = bp->wptr; 
1990/0315    
	while(!(dev->status & RCV_EMPTY)){ 
1990/0320/sys/src/9/gnot/devincon.c:699,7101990/0321/sys/src/9/gnot/devincon.c:708,721
1990/0312    
		 *  get channel number 
		 */ 
1990/0315    
		c = (dev->data_cntl)>>8; 
1990/0321    
		if(c == 0){ 
			droppacket(dev); 
			continue; 
		} 
1990/0312    
		if(ip->chan != c){ 
1990/0320    
			if(p - bp->rptr > 3){ 
				bp->wptr = p; 
1990/0315    
				bp = nextin(ip, 0); 
				if(bp == 0) 
1990/0320    
					goto done; 
				p = bp->wptr; 
1990/0315    
			} 
1990/0312    
			ip->chan = c; 
1990/0320/sys/src/9/gnot/devincon.c:725,7321990/0321/sys/src/9/gnot/devincon.c:736,741
1990/0312    
				 */ 
1990/0320    
				bp->wptr = p; 
1990/0315    
				bp = nextin(ip, c); 
				if(bp == 0) 
1990/0320    
					goto done; 
				p = bp->wptr; 
1990/0312    
			} else { 
				/* end of packet */ 
1990/0320/sys/src/9/gnot/devincon.c:741,7541990/0321/sys/src/9/gnot/devincon.c:750,760
1990/0320    
		if(p + 16 > bp->lim){ 
			bp->wptr = p; 
			bp = nextin(ip, 0); 
			if(bp == 0) 
				goto done; 
			p = bp->wptr; 
		} 
	}	 
	bp->wptr = p; 
 
done: 
	if(first != ip->wi)/**/ 
		wakeup(&ip->kr); 
1990/0312    
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)