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

1991/0808/pc/devuart.c (diff list | history)

1991/0807/sys/src/9/pc/devuart.c:1,41991/0808/sys/src/9/pc/devuart.c:1,4 (short | long | prev | next)
1991/0801    
#include	"u.h" 
1991/0808    

#include	"u.h" 
1991/0801    
#include	"lib.h" 
#include	"mem.h" 
#include	"dat.h" 
1991/0807/sys/src/9/pc/devuart.c:18,261991/0808/sys/src/9/pc/devuart.c:18,25
1991/0801    
	 */ 
	Data=	0,		/* xmit/rcv buffer */ 
	Iena=	1,		/* interrupt enable */ 
	 Ircv=	(1<<0),		/*  interrupt on receive */ 
	 Ixmt=	(1<<1),		/*  interrupt on xmit */ 
	Istat=	2,		/* interrupt flag */ 
1991/0808    
	Istat=	2,		/* interrupt flag (read) */ 
	Tctl=	2,		/* test control (write) */ 
1991/0801    
	Format=	3,		/* byte format */ 
	 Bits8=	(3<<0),		/*  8 bits/byte */ 
	 Stop2=	(1<<2),		/*  2 stop bits */ 
1991/0807/sys/src/9/pc/devuart.c:42,471991/0808/sys/src/9/pc/devuart.c:41,49
1991/0801    
	Scratch=7,		/* scratchpad */ 
	Dlsb=	0,		/* divisor lsb */ 
	Dmsb=	1,		/* divisor msb */ 
1991/0808    
 
	Serial=	0, 
	Modem=	1, 
1991/0801    
}; 
 
typedef struct Uart	Uart; 
1991/0807/sys/src/9/pc/devuart.c:62,681991/0808/sys/src/9/pc/devuart.c:64,69
1991/0801    
	Queue	*wq;		/* write queue */ 
	Rendez	r;		/* kproc waiting for input */ 
	Alarm	*a;		/* alarm for waking the kernel process */ 
	int	delay;		/* between character input and waking kproc */ 
 	int	kstarted;	/* kproc started */ 
	uchar	delim[256/8];	/* characters that act as delimiters */ 
}; 
1991/0807/sys/src/9/pc/devuart.c:248,2541991/0808/sys/src/9/pc/devuart.c:249,256
1991/0801    
void 
uartintr1(Ureg *ur) 
{ 
	uartintr(&uart[1]); 
1991/0808    
	if(uart[1].enabled) 
		uartintr(&uart[1]); 
1991/0801    
} 
 
/* 
1991/0807/sys/src/9/pc/devuart.c:262,2911991/0808/sys/src/9/pc/devuart.c:264,297
1991/0801    
	/* 
1991/0807    
	 *  turn on power to the port 
	 */ 
	if(up == &uart[0]){ 
1991/0808    
	if(up == &uart[Serial]){ 
1991/0807    
		if(serial(0) < 0) 
			print("can't turn on serial port power\n"); 
	} 
 
	/* 
1991/0808    
	 *  speed up the clock to poll the uart 
	 */ 
	fclockinit(); 
 
	/* 
1991/0801    
	 *  set up i/o routines 
	 */ 
	if(up->oq){ 
		up->oq->puts = uartputs; 
		up->oq->ptr = up; 
		up->sticky[Iena] |= Ixmt; 
	} 
	if(up->iq){ 
		up->iq->ptr = up; 
		up->sticky[Iena] |= Ircv; 
	} 
1991/0807    
	up->enabled = 1; 
1991/0803    
	up->sticky[Iena] |= (1<<2) | (1<<3); 
1991/0808    
	up->sticky[Iena] = 0xf; 
1991/0801    
 
	/* 
 	 *  turn on interrupts 
	 */ 
	uartwrreg(up, Iena, 0); 
1991/0808    
	uartwrreg(up, Tctl, 0x0); 
1991/0801    
 
	/* 
	 *  turn on DTR and RTS 
1991/0807/sys/src/9/pc/devuart.c:292,2971991/0808/sys/src/9/pc/devuart.c:298,305
1991/0801    
	 */ 
	uartdtr(up, 1); 
	uartrts(up, 1); 
1991/0808    
 
print("uart enabled: Iena=%lux\n", uartrdreg(up, Iena)); 
1991/0807    
} 
1991/0806    
 
1991/0807    
/* 
1991/0807/sys/src/9/pc/devuart.c:316,3251991/0808/sys/src/9/pc/devuart.c:324,338
1991/0807    
	/* 
	 *  turn off power 
	 */ 
	if(up == &uart[0]){ 
1991/0808    
	if(up == &uart[Serial]){ 
1991/0807    
		if(serial(1) < 0) 
			print("can't turn off serial power\n"); 
1991/0806    
	} 
1991/0808    
 
	/* 
	 *  slow the clock down again 
	 */ 
	clockinit(); 
1991/0801    
} 
 
/* 
1991/0807/sys/src/9/pc/devuart.c:374,3981991/0808/sys/src/9/pc/devuart.c:387,392
1991/0801    
	wakeup(&up->iq->r); 
} 
 
static int 
uartputc(IOQ *cq, int ch) 
{ 
	Uart *up = cq->ptr; int r; 
                 
	r = putc(cq, ch); 
                 
	/* 
	 *  pass upstream within up->delay milliseconds 
	 */ 
	if(up->a==0){ 
		if(up->delay == 0) 
			wakeup(&cq->r); 
		else 
			up->a = alarm(up->delay, uarttimer, up); 
	} 
	return r; 
} 
                 
static void 
uartstopen(Queue *q, Stream *s) 
{ 
1991/0807/sys/src/9/pc/devuart.c:403,4081991/0808/sys/src/9/pc/devuart.c:397,403
1991/0801    
		q, s->inuse, s->type, s->dev, s->id); 
1991/0806    
 
1991/0801    
	up = &uart[s->id]; 
1991/0808    
	up->iq->putc = 0; 
1991/0806    
	uartenable(up); 
 
1991/0801    
	qlock(up); 
1991/0807/sys/src/9/pc/devuart.c:409,4201991/0808/sys/src/9/pc/devuart.c:404,413
1991/0801    
	up->wq = WR(q); 
	WR(q)->ptr = up; 
	RD(q)->ptr = up; 
	up->delay = 64; 
	up->iq->putc = uartputc; 
	qunlock(up); 
 
	/* start with all characters as delimiters */ 
	memset(up->delim, 1, sizeof(up->delim)); 
1991/0808    
	memset(up->delim, 0xff, sizeof(up->delim)); 
1991/0801    
	 
	if(up->kstarted == 0){ 
		up->kstarted = 1; 
1991/0807/sys/src/9/pc/devuart.c:468,4731991/0808/sys/src/9/pc/devuart.c:461,478
1991/0801    
		case 'd': 
			uartdtr(up, n); 
			break; 
1991/0808    
		case 'e': 
		case 'E': 
			/* 
			 *  the characters in the block are the message 
			 *  delimiters to use upstream 
			 */ 
			memset(up->delim, 0, sizeof(up->delim)); 
			while(++(bp->rptr) < bp->wptr){ 
				m = *bp->rptr; 
				up->delim[m/8] |= 1<<(m&7); 
			} 
			break; 
1991/0801    
		case 'K': 
		case 'k': 
			uartbreak(up, n); 
1991/0807/sys/src/9/pc/devuart.c:476,4901991/0808/sys/src/9/pc/devuart.c:481,489
1991/0801    
		case 'r': 
			uartrts(up, n); 
			break; 
		case 'W': 
		case 'w': 
			if(n>=0 && n<1000) 
				up->delay = n; 
			break; 
		} 
	}else while((m = BLEN(bp)) > 0){ 
		while ((n = canputc(cq)) == 0){ 
print("uartoput: sleeping\n"); 
			sleep(&cq->r, canputc, cq); 
		} 
		if(n > m) 
1991/0807/sys/src/9/pc/devuart.c:507,5271991/0808/sys/src/9/pc/devuart.c:506,528
1991/0801    
	Block *bp; 
	int n; 
 
loop: 
	while ((n = cangetc(cq)) == 0){ 
1991/0808    
	if(waserror()) 
		print("uartkproc got an error\n"); 
 
	for(;;){ 
1991/0801    
		sleep(&cq->r, cangetc, cq); 
1991/0808    
		qlock(up); 
		if(up->wq == 0){ 
			cq->out = cq->in; 
		}else{ 
			n = cangetc(cq); 
			bp = allocb(n); 
			bp->flags |= S_DELIM; 
			bp->wptr += gets(cq, bp->wptr, n); 
			PUTNEXT(RD(up->wq), bp); 
		} 
		qunlock(up); 
1991/0801    
	} 
	qlock(up); 
	if(up->wq == 0){ 
		cq->out = cq->in; 
	}else{ 
		bp = allocb(n); 
		bp->flags |= S_DELIM; 
		bp->wptr += gets(cq, bp->wptr, n); 
		PUTNEXT(RD(up->wq), bp); 
	} 
	qunlock(up); 
	goto loop; 
} 
 
enum{ 


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