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

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

1990/0315/sys/src/9/gnot/devincon.c:7,121990/0320/sys/src/9/gnot/devincon.c:7,13 (short | long | prev | next)
1990/0312    
#include	"devtab.h" 
 
#include	"io.h" 
1990/0320    
#include	"ureg.h" 
1990/0312    
 
typedef struct Incon	Incon; 
typedef struct Device	Device; 
1990/0315/sys/src/9/gnot/devincon.c:22,281990/0320/sys/src/9/gnot/devincon.c:23,30
1990/0312    
	Minstation=	2,	/* lowest station # to poll */ 
	Maxstation=	15,	/* highest station # to poll */ 
	Nincon=		1,	/* number of incons */ 
1990/0315    
	Nin=		32,	/* size of raw input buffer */ 
1990/0320    
	Nin=		16,	/* Blocks in the input ring */ 
	Bsize=		128,	/* size of an input ring block */ 
1990/0312    
}; 
 
/* 
1990/0315/sys/src/9/gnot/devincon.c:522,5301990/0320/sys/src/9/gnot/devincon.c:524,530
1990/0312    
			n = 16; 
		size = n; 
		dev->cdata = chan; 
		DPRINT("CH|%uo->\n", chan); 
		while(n--){ 
			DPRINT("->%uo\n", *bp->rptr); 
			*(uchar *)&dev->data_cntl = *bp->rptr++; 
		} 
 
1990/0315/sys/src/9/gnot/devincon.c:554,5661990/0320/sys/src/9/gnot/devincon.c:554,566
1990/0312    
	if(ctl){ 
		if(size >= 16){ 
			dev->cdata = 0; 
			DPRINT("CH|%uo->\n", chan); 
1990/0320    
			MICROSECOND; 
1990/0312    
			dev->cdata = chan; 
1990/0320    
			MICROSECOND; 
1990/0312    
		} 
		DPRINT("CTL|%uo->\n", ctl); 
		dev->cdata = ctl; 
1990/0315    
		MICROSECOND; 
1990/0312    
	} 
1990/0320    
	MICROSECOND; 
1990/0312    
	dev->cdata = 0; 
 
	qunlock(&ip->xmit); 
1990/0315/sys/src/9/gnot/devincon.c:596,6021990/0320/sys/src/9/gnot/devincon.c:596,602
1990/0315    
	 *  create a number of blocks for input 
	 */ 
	for(i = 0; i < Nin; i++){ 
		bp = ip->inb[i] = allocb(128); 
1990/0320    
		bp = ip->inb[i] = allocb(Bsize); 
1990/0315    
		bp->wptr += 3; 
	} 
 
1990/0315/sys/src/9/gnot/devincon.c:622,6281990/0320/sys/src/9/gnot/devincon.c:622,628
1990/0312    
		 */ 
1990/0315    
		while(ip->ri != ip->wi){ 
			PUTNEXT(ip->rq, ip->inb[ip->ri]); 
			bp = ip->inb[ip->ri] = allocb(128); 
1990/0320    
			bp = ip->inb[ip->ri] = allocb(Bsize); 
1990/0315    
			bp->wptr += 3; 
			ip->ri = (ip->ri+1)%Nin; 
		} 
1990/0315/sys/src/9/gnot/devincon.c:639,6481990/0320/sys/src/9/gnot/devincon.c:639,651
1990/0315    
	int i; 
	int c; 
 
	for(i = 0; i < 17; i++){ 
		c = dev->data_cntl; 
		if(c==0) 
			break; 
1990/0320    
	screenputc('!'); 
	while(!(dev->status & RCV_EMPTY)){ 
		for(i = 0; i < 17; i++){ 
			c = dev->data_cntl; 
			if(c==0) 
				break; 
		} 
1990/0315    
	} 
} 
 
1990/0315/sys/src/9/gnot/devincon.c:655,6701990/0320/sys/src/9/gnot/devincon.c:658,676
1990/0315    
nextin(Incon *ip, unsigned int c) 
{ 
	Block *bp = ip->inb[ip->wi]; 
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/0315    
	bp->base[0] = ip->chan; 
	bp->base[1] = ip->chan>>8; 
	bp->base[2] = c; 
	ip->wi = (ip->wi + 1) % Nin; 
1990/0320    
	ip->wi = next; 
1990/0315    
 
	if(((ip->wi+1)%Nin) == ip->ri){ 
		droppacket(ip->dev); 
		return 0; 
	} 
	return ip->inb[ip->wi]; 
} 
 
1990/0315/sys/src/9/gnot/devincon.c:678,7031990/0320/sys/src/9/gnot/devincon.c:684,711
1990/0315    
	Block *bp; 
	unsigned int c; 
	Device *dev; 
1990/0320    
	uchar *p; 
	int first = ip->wi; 
1990/0315    
 
	dev = ip->dev; 
1990/0320    
	bp = ip->inb[ip->wi]; 
	if(bp==0){ 
		droppacket(ip->dev); 
		goto done; 
	} 
	p = bp->wptr; 
1990/0315    
	while(!(dev->status & RCV_EMPTY)){ 
		bp = ip->inb[ip->wi]; 
		if(((ip->wi+1)%Nin) == ip->ri || bp==0){ 
			c = dev->data_cntl; 
			droppacket(dev); 
			continue; 
		} 
                 
1990/0312    
		/* 
		 *  get channel number 
		 */ 
1990/0315    
		c = (dev->data_cntl)>>8; 
1990/0312    
		DPRINT("<-CH|%uo\n", c); 
		if(ip->chan != c){ 
1990/0315    
			if(bp->wptr - bp->rptr > 3){ 
1990/0320    
			if(p - bp->rptr > 3){ 
				bp->wptr = p; 
1990/0315    
				bp = nextin(ip, 0); 
				if(bp == 0) 
					continue; 
1990/0320    
					goto done; 
				p = bp->wptr; 
1990/0315    
			} 
1990/0312    
			ip->chan = c; 
		} 
1990/0315/sys/src/9/gnot/devincon.c:710,7371990/0320/sys/src/9/gnot/devincon.c:718,756
1990/0312    
				/* 
				 *  data byte, put in local buffer 
				 */ 
1990/0315    
				c = *bp->wptr++ = c>>8; 
1990/0312    
				DPRINT("<-%uo\n", c); 
1990/0315    
				if(bp->wptr >= bp->lim){ 
					bp = nextin(ip, 0); 
					if(bp == 0) 
						continue; 
				} 
1990/0320    
				*p++ = c>>8; 
1990/0312    
			} else if (c>>=8) { 
				/* 
				 *  control byte ends block 
				 */ 
				DPRINT("<-CTL|%uo\n", c); 
1990/0320    
				bp->wptr = p; 
1990/0315    
				bp = nextin(ip, c); 
				if(bp == 0) 
					continue; 
1990/0320    
					goto done; 
				p = bp->wptr; 
1990/0312    
			} else { 
				/* end of packet */ 
				break; 
			} 
		} 
	} 
	wakeup(&ip->kr); 
1990/0320    
 
		/* 
		 *  pass a block on if it doesn't have room for one more 
		 *  packet.  this way we don't have to check per byte. 
		 */ 
		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    
} 
 
/* 
1990/0315/sys/src/9/gnot/devincon.c:754,7641990/0320/sys/src/9/gnot/devincon.c:773,783
1990/0312    
	/* check for exceptional conditions */ 
	if(status&(OVERFLOW|CRC_ERROR)){ 
		if(status&OVERFLOW){ 
			print("incon overflow\n"); 
1990/0320    
			screenputc('^'); 
1990/0312    
			ip->overflow++; 
		} 
		if(status&CRC_ERROR){ 
			print("incon crc error\n"); 
1990/0320    
			screenputc('+'); 
1990/0312    
			ip->crc++; 
		} 
	} 


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