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

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

1991/0801/sys/src/9/pc/devuart.c:37,431991/0803/sys/src/9/pc/devuart.c:37,43 (short | long)
1991/0801    
	 Loop=	(1<<4),		/*  loop bask */ 
	Lstat=	5,		/* line status */ 
	 Inready=(1<<0),	/*  receive buffer full */ 
	 Outbusy=(1<<5),	/*  output buffer full */ 
1991/0803    
	 Outready=(1<<5),	/*  output buffer full */ 
1991/0801    
	Mstat=	6,		/* modem status */ 
	Scratch=7,		/* scratchpad */ 
	Dlsb=	0,		/* divisor lsb */ 
1991/0801/sys/src/9/pc/devuart.c:88,941991/0803/sys/src/9/pc/devuart.c:88,94
1991/0801    
{ 
	ulong brconst; 
 
	brconst = (UartFREQ+8*rate-1)/16*rate; 
1991/0803    
	brconst = (UartFREQ+8*rate-1)/(16*rate); 
1991/0801    
 
	uartwrreg(up, Format, Dra); 
	uartwrreg(up, Dmsb, (brconst>>8) & 0xff); 
1991/0801/sys/src/9/pc/devuart.c:178,1831991/0803/sys/src/9/pc/devuart.c:178,184
1991/0801    
{ 
	Uart *up = cq->ptr; 
	int st, ch, x; 
1991/0803    
	int tries; 
1991/0801    
 
	x = splhi(); 
	lock(cq); 
1991/0801/sys/src/9/pc/devuart.c:187,1931991/0803/sys/src/9/pc/devuart.c:188,195
1991/0801    
print("<start %2.2ux>", ch);/**/ 
		if(ch >= 0){ 
			up->printing = 1; 
			while(uartrdreg(up, Lstat) & Outbusy) 
1991/0803    
			for(tries = 0; tries<10000 && !(uartrdreg(up, Lstat)&Outready); 
				tries++) 
1991/0801    
				; 
			outb(up->port + Data, ch); 
		} 
1991/0801/sys/src/9/pc/devuart.c:202,2121991/0803/sys/src/9/pc/devuart.c:204,216
1991/0801    
void 
uartintr(Uart *up) 
{ 
	int s; 
	int ch; 
	IOQ *cq; 
1991/0803    
	int s; 
1991/0801    
 
	switch(uartrdreg(up, Istat)){ 
1991/0803    
	s = uartrdreg(up, Istat); 
print("uartintr %lux\n", s); 
	switch(s){ 
1991/0801    
	case 3: 
		/* 
		 *  get any input characters 
1991/0801/sys/src/9/pc/devuart.c:227,2361991/0803/sys/src/9/pc/devuart.c:231,241
1991/0801    
		/* 
		 *  send next output character 
		 */ 
		if((s & Outbusy)==0){ 
1991/0803    
		if(uartrdreg(up, Lstat)&Outready){ 
1991/0801    
			cq = up->oq; 
			lock(cq); 
			ch = getc(cq); 
1991/0803    
print("<cont %2.2ux>", ch);/**/ 
1991/0801    
			if(ch < 0){ 
				up->printing = 0; 
				wakeup(&cq->r); 
1991/0801/sys/src/9/pc/devuart.c:270,2751991/0803/sys/src/9/pc/devuart.c:275,281
1991/0801    
		up->iq->ptr = up; 
		up->sticky[Iena] |= Ircv; 
	} 
1991/0803    
	up->sticky[Iena] |= (1<<2) | (1<<3); 
1991/0801    
 
	/* 
 	 *  turn on interrupts 
1991/0801/sys/src/9/pc/devuart.c:465,4711991/0803/sys/src/9/pc/devuart.c:471,476
1991/0801    
 
loop: 
	while ((n = cangetc(cq)) == 0){ 
print("uart0 sleeping/n"); 
		sleep(&cq->r, cangetc, cq); 
	} 
	qlock(up); 
1991/0801/sys/src/9/pc/devuart.c:505,5101991/0803/sys/src/9/pc/devuart.c:510,518
1991/0801    
uartreset(void) 
{ 
	Uart *up; 
1991/0803    
 
	if(serial(0) < 0) 
		print("can't turn on power\n"); 
1991/0801    
 
	uartsetup(); 
	for(up = uart; up < &uart[2]; up++){ 
1991/0803/sys/src/9/pc/devuart.c:49,551991/0804/sys/src/9/pc/devuart.c:49,55 (short | long)
1991/0801    
{ 
	QLock; 
	int	port; 
	ushort	sticky[16];	/* sticky write register values */ 
1991/0804    
	uchar	sticky[8];	/* sticky write register values */ 
1991/0801    
	int	printing;	/* true if printing */ 
 
	/* console interface */ 
1991/0803/sys/src/9/pc/devuart.c:70,771991/0804/sys/src/9/pc/devuart.c:70,77
1991/0801    
 
#define UartFREQ 1846200 
 
#define uartwrreg(u,r,v)	outb(u->port + r, u->sticky[r] | v) 
#define uartrdreg(u,r)		inb(u->port + r) 
1991/0804    
#define uartwrreg(u,r,v)	outb((u)->port + r, (u)->sticky[r] | (v)) 
#define uartrdreg(u,r)		inb((u)->port + r) 
1991/0801    
 
void	uartintr(Uart*); 
void	uartintr0(Ureg*); 
1991/0803/sys/src/9/pc/devuart.c:91,981991/0804/sys/src/9/pc/devuart.c:91,98
1991/0803    
	brconst = (UartFREQ+8*rate-1)/(16*rate); 
1991/0801    
 
	uartwrreg(up, Format, Dra); 
	uartwrreg(up, Dmsb, (brconst>>8) & 0xff); 
	uartwrreg(up, Dlsb, brconst & 0xff); 
1991/0804    
	outb(up->port+Dmsb, (brconst>>8) & 0xff); 
	outb(up->port+Dlsb, brconst & 0xff); 
1991/0801    
	uartwrreg(up, Format, 0); 
} 
 
1991/0803/sys/src/9/pc/devuart.c:148,1541991/0804/sys/src/9/pc/devuart.c:148,154
1991/0801    
	already = 1; 
 
	/* 
	 *  get port addresses 
1991/0804    
	 *  set port addresses 
1991/0801    
	 */ 
	uart[0].port = 0x3F8; 
	uart[1].port = 0x2F8; 
1991/0804/sys/src/9/pc/devuart.c:206,2501991/0806/sys/src/9/pc/devuart.c:206,245 (short | long)
1991/0801    
{ 
	int ch; 
	IOQ *cq; 
1991/0803    
	int s; 
1991/0806    
	int s, l; 
1991/0801    
 
1991/0806    
	l = uartrdreg(up, Lstat); 
1991/0803    
	s = uartrdreg(up, Istat); 
print("uartintr %lux\n", s); 
	switch(s){ 
1991/0801    
	case 3: 
		/* 
		 *  get any input characters 
		 */ 
		cq = up->iq; 
		while(uartrdreg(up, Lstat) & Inready){ 
			ch = uartrdreg(up, Data) & 0xff; 
			if(cq->putc) 
				(*cq->putc)(cq, ch); 
			else { 
				putc(cq, ch); 
				if(up->delim[ch/8] & (1<<(ch&7)) ) 
					wakeup(&cq->r); 
			} 
		} 
		break; 
	case 5: 
		/* 
		 *  send next output character 
		 */ 
1991/0803    
		if(uartrdreg(up, Lstat)&Outready){ 
1991/0801    
			cq = up->oq; 
			lock(cq); 
			ch = getc(cq); 
1991/0803    
print("<cont %2.2ux>", ch);/**/ 
1991/0801    
			if(ch < 0){ 
				up->printing = 0; 
1991/0806    
 
	cq = up->iq; 
	while(l & Inready){ 
		ch = uartrdreg(up, Data) & 0xff; 
print("<get %2.2ux>", ch); 
		if(cq->putc) 
			(*cq->putc)(cq, ch); 
		else { 
			putc(cq, ch); 
			if(up->delim[ch/8] & (1<<(ch&7)) ) 
1991/0801    
				wakeup(&cq->r); 
			}else 
				outb(up->port + Data, ch); 
			unlock(cq); 
		} 
		break; 
1991/0806    
		l = uartrdreg(up, Lstat); 
1991/0801    
	} 
1991/0806    
 
	/* 
	 *  send next output character 
	 */ 
	if(up->printing && (l&Outready)){ 
		cq = up->oq; 
		lock(cq); 
		ch = getc(cq); 
print("<put %2.2ux>", ch);/**/ 
		if(ch < 0){ 
			up->printing = 0; 
			wakeup(&cq->r); 
		}else 
			outb(up->port + Data, ch); 
		unlock(cq); 
	} 
1991/0801    
} 
void 
uartintr0(Ureg *ur) 
1991/0804/sys/src/9/pc/devuart.c:263,2681991/0806/sys/src/9/pc/devuart.c:258,265
1991/0801    
void 
uartenable(Uart *up) 
{ 
1991/0806    
	int x; 
 
1991/0801    
	/* 
	 *  set up i/o routines 
	 */ 
1991/0804/sys/src/9/pc/devuart.c:287,2921991/0806/sys/src/9/pc/devuart.c:284,298
1991/0801    
	 */ 
	uartdtr(up, 1); 
	uartrts(up, 1); 
1991/0806    
 
	/* 
	 *  read interrupt status till there aren't any pending 
	 */ 
	while(uartrdreg(up, Istat) != 1){ 
		x = splhi(); 
		uartintr(up); 
		splx(x); 
	} 
1991/0801    
} 
 
/* 
1991/0804/sys/src/9/pc/devuart.c:303,3081991/0806/sys/src/9/pc/devuart.c:309,318
1991/0801    
	up->iq = iq; 
	uartenable(up); 
	uartsetbaud(up, baud); 
1991/0806    
	if(port == 0){ 
		if(serial(0) < 0) 
			print("can't turn on serial port power\n"); 
	} 
1991/0801    
 
	if(iq){ 
		/* 
1991/0804/sys/src/9/pc/devuart.c:366,3741991/0806/sys/src/9/pc/devuart.c:376,389
1991/0801    
	Uart *up; 
	char name[NAMELEN]; 
 
	kprint("uartstopen: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n", 
1991/0806    
print("uartstopen: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n", 
1991/0801    
		q, s->inuse, s->type, s->dev, s->id); 
1991/0806    
 
1991/0801    
	up = &uart[s->id]; 
1991/0806    
	uartenable(up); 
	if(s->id==0 && serial(0)<0) 
		print("can't turn on serial power\n"); 
 
1991/0801    
	qlock(up); 
	up->wq = WR(q); 
	WR(q)->ptr = up; 
1991/0804/sys/src/9/pc/devuart.c:399,4041991/0806/sys/src/9/pc/devuart.c:414,422
1991/0801    
	WR(q)->ptr = 0; 
	RD(q)->ptr = 0; 
	qunlock(up); 
1991/0806    
 
	if(serial(1) < 0) 
		print("can't turn off serial power\n"); 
1991/0801    
} 
 
static void 
1991/0804/sys/src/9/pc/devuart.c:511,5191991/0806/sys/src/9/pc/devuart.c:529,534
1991/0801    
{ 
	Uart *up; 
1991/0803    
 
	if(serial(0) < 0) 
		print("can't turn on power\n"); 
1991/0801    
                 
	uartsetup(); 
	for(up = uart; up < &uart[2]; up++){ 
		if(up->nostream) 
1991/0804/sys/src/9/pc/devuart.c:522,5281991/0806/sys/src/9/pc/devuart.c:537,542
1991/0801    
		initq(up->iq); 
		up->oq = ialloc(sizeof(IOQ), 0); 
		initq(up->oq); 
		uartenable(up); 
	} 
} 
 
1991/0806/sys/src/9/pc/devuart.c:51,561991/0807/sys/src/9/pc/devuart.c:51,57 (short | long)
1991/0801    
	int	port; 
1991/0804    
	uchar	sticky[8];	/* sticky write register values */ 
1991/0801    
	int	printing;	/* true if printing */ 
1991/0807    
	int	enabled; 
1991/0801    
 
	/* console interface */ 
	int	nostream;	/* can't use the stream interface */ 
1991/0806/sys/src/9/pc/devuart.c:185,1911991/0807/sys/src/9/pc/devuart.c:186,191
1991/0801    
	puts(cq, s, n); 
	if(up->printing == 0){ 
		ch = getc(cq); 
print("<start %2.2ux>", ch);/**/ 
		if(ch >= 0){ 
			up->printing = 1; 
1991/0803    
			for(tries = 0; tries<10000 && !(uartrdreg(up, Lstat)&Outready); 
1991/0806/sys/src/9/pc/devuart.c:214,2201991/0807/sys/src/9/pc/devuart.c:214,219
1991/0806    
	cq = up->iq; 
	while(l & Inready){ 
		ch = uartrdreg(up, Data) & 0xff; 
print("<get %2.2ux>", ch); 
		if(cq->putc) 
			(*cq->putc)(cq, ch); 
		else { 
1991/0806/sys/src/9/pc/devuart.c:232,2381991/0807/sys/src/9/pc/devuart.c:231,236
1991/0806    
		cq = up->oq; 
		lock(cq); 
		ch = getc(cq); 
print("<put %2.2ux>", ch);/**/ 
		if(ch < 0){ 
			up->printing = 0; 
			wakeup(&cq->r); 
1991/0806/sys/src/9/pc/devuart.c:244,2501991/0807/sys/src/9/pc/devuart.c:242,249
1991/0801    
void 
uartintr0(Ureg *ur) 
{ 
	uartintr(&uart[0]); 
1991/0807    
	if(uart[0].enabled) 
		uartintr(&uart[0]); 
1991/0801    
} 
void 
uartintr1(Ureg *ur) 
1991/0806/sys/src/9/pc/devuart.c:261,2661991/0807/sys/src/9/pc/devuart.c:260,273
1991/0806    
	int x; 
 
1991/0801    
	/* 
1991/0807    
	 *  turn on power to the port 
	 */ 
	if(up == &uart[0]){ 
		if(serial(0) < 0) 
			print("can't turn on serial port power\n"); 
	} 
 
	/* 
1991/0801    
	 *  set up i/o routines 
	 */ 
	if(up->oq){ 
1991/0806/sys/src/9/pc/devuart.c:272,2771991/0807/sys/src/9/pc/devuart.c:279,285
1991/0801    
		up->iq->ptr = up; 
		up->sticky[Iena] |= Ircv; 
	} 
1991/0807    
	up->enabled = 1; 
1991/0803    
	up->sticky[Iena] |= (1<<2) | (1<<3); 
1991/0801    
 
	/* 
1991/0806/sys/src/9/pc/devuart.c:284,2971991/0807/sys/src/9/pc/devuart.c:292,324
1991/0801    
	 */ 
	uartdtr(up, 1); 
	uartrts(up, 1); 
1991/0807    
} 
1991/0806    
 
1991/0807    
/* 
 *  turn off the uart 
 */ 
uartdisable(Uart *up) 
{ 
 
1991/0806    
	/* 
	 *  read interrupt status till there aren't any pending 
1991/0807    
 	 *  turn off interrupts 
1991/0806    
	 */ 
	while(uartrdreg(up, Istat) != 1){ 
		x = splhi(); 
		uartintr(up); 
		splx(x); 
1991/0807    
	up->sticky[Iena] = 0; 
	uartwrreg(up, Iena, 0); 
 
	/* 
	 *  turn off DTR and RTS 
	 */ 
	uartdtr(up, 0); 
	uartrts(up, 0); 
	up->enabled = 0; 
 
	/* 
	 *  turn off power 
	 */ 
	if(up == &uart[0]){ 
		if(serial(1) < 0) 
			print("can't turn off serial power\n"); 
1991/0806    
	} 
1991/0801    
} 
 
1991/0806/sys/src/9/pc/devuart.c:309,3181991/0807/sys/src/9/pc/devuart.c:336,341
1991/0801    
	up->iq = iq; 
	uartenable(up); 
	uartsetbaud(up, baud); 
1991/0806    
	if(port == 0){ 
		if(serial(0) < 0) 
			print("can't turn on serial port power\n"); 
	} 
1991/0801    
 
	if(iq){ 
		/* 
1991/0806/sys/src/9/pc/devuart.c:381,3881991/0807/sys/src/9/pc/devuart.c:404,409
1991/0806    
 
1991/0801    
	up = &uart[s->id]; 
1991/0806    
	uartenable(up); 
	if(s->id==0 && serial(0)<0) 
		print("can't turn on serial power\n"); 
 
1991/0801    
	qlock(up); 
	up->wq = WR(q); 
1991/0806/sys/src/9/pc/devuart.c:407,4121991/0807/sys/src/9/pc/devuart.c:428,435
1991/0801    
{ 
	Uart *up = q->ptr; 
 
1991/0807    
	uartdisable(up); 
 
1991/0801    
	qlock(up); 
	kprint("uartstclose: q=0x%ux, id=%d\n", q, up-uart); 
	up->wq = 0; 
1991/0806/sys/src/9/pc/devuart.c:414,4221991/0807/sys/src/9/pc/devuart.c:437,442
1991/0801    
	WR(q)->ptr = 0; 
	RD(q)->ptr = 0; 
	qunlock(up); 
1991/0806    
                 
	if(serial(1) < 0) 
		print("can't turn off serial power\n"); 
1991/0801    
} 
 
static void 
1991/0807/sys/src/9/pc/devuart.c:1,41991/0808/sys/src/9/pc/devuart.c:1,4 (short | long)
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{ 
1991/0808/sys/src/9/pc/devuart.c:32,381991/0810/sys/src/9/pc/devuart.c:32,38 (short | long)
1991/0801    
	 Dtr=	(1<<0),		/*  data terminal ready */ 
	 Rts=	(1<<1),		/*  request to send */ 
	 Ri=	(1<<2),		/*  ring */ 
	 Dcd=	(1<<3),		/*  carrier */ 
1991/0810    
	 Inton=	(1<<3),		/*  turn on interrupts */ 
1991/0801    
	 Loop=	(1<<4),		/*  loop bask */ 
	Lstat=	5,		/* line status */ 
	 Inready=(1<<0),	/*  receive buffer full */ 
1991/0808/sys/src/9/pc/devuart.c:164,1731991/0810/sys/src/9/pc/devuart.c:164,176
1991/0801    
		 *  set rate to 9600 baud. 
		 *  8 bits/character. 
		 *  1 stop bit. 
1991/0810    
		 *  interrupts enabled. 
1991/0801    
		 */ 
		uartsetbaud(up, 9600); 
		up->sticky[Format] = Bits8; 
		uartwrreg(up, Format, 0); 
1991/0810    
		up->sticky[Mctl] |= Inton; 
		uartwrreg(up, Mctl, 0x0); 
1991/0801    
	} 
} 
 
1991/0808/sys/src/9/pc/devuart.c:209,2561991/0810/sys/src/9/pc/devuart.c:212,269
1991/0801    
	IOQ *cq; 
1991/0806    
	int s, l; 
1991/0801    
 
1991/0806    
	l = uartrdreg(up, Lstat); 
1991/0803    
	s = uartrdreg(up, Istat); 
1991/0806    
                 
	cq = up->iq; 
	while(l & Inready){ 
		ch = uartrdreg(up, Data) & 0xff; 
		if(cq->putc) 
			(*cq->putc)(cq, ch); 
		else { 
			putc(cq, ch); 
			if(up->delim[ch/8] & (1<<(ch&7)) ) 
1991/0810    
	for(;;){ 
		s = uartrdreg(up, Istat); 
		switch(s){ 
		case 6:	/* receiver line status */ 
			l = uartrdreg(up, Lstat); 
			break; 
	 
		case 4:	/* received data available */ 
			cq = up->iq; 
			ch = uartrdreg(up, Data) & 0xff; 
			if(cq->putc) 
				(*cq->putc)(cq, ch); 
			else { 
				putc(cq, ch); 
				if(up->delim[ch/8] & (1<<(ch&7)) ) 
					wakeup(&cq->r); 
			} 
			break; 
	 
		case 2:	/* transmitter empty */ 
			cq = up->oq; 
			lock(cq); 
			ch = getc(cq); 
			if(ch < 0){ 
				up->printing = 0; 
1991/0801    
				wakeup(&cq->r); 
1991/0810    
			}else 
				outb(up->port + Data, ch); 
			unlock(cq); 
			break; 
	 
		case 0:	/* modem status */ 
			l = uartrdreg(up, Mstat); 
			break; 
	 
		default: 
			if(s&1) 
				return; 
			print("weird modem interrupt\n"); 
			break; 
1991/0801    
		} 
1991/0806    
		l = uartrdreg(up, Lstat); 
1991/0801    
	} 
1991/0806    
                 
	/* 
	 *  send next output character 
	 */ 
	if(up->printing && (l&Outready)){ 
		cq = up->oq; 
		lock(cq); 
		ch = getc(cq); 
		if(ch < 0){ 
			up->printing = 0; 
			wakeup(&cq->r); 
		}else 
			outb(up->port + Data, ch); 
		unlock(cq); 
	} 
1991/0801    
} 
void 
uartintr0(Ureg *ur) 
{ 
1991/0807    
	if(uart[0].enabled) 
		uartintr(&uart[0]); 
1991/0810    
	uartintr(&uart[0]); 
1991/0801    
} 
void 
uartintr1(Ureg *ur) 
{ 
1991/0808    
	if(uart[1].enabled) 
		uartintr(&uart[1]); 
1991/0810    
	uartintr(&uart[1]); 
1991/0801    
} 
 
/* 
1991/0808/sys/src/9/pc/devuart.c:271,2781991/0810/sys/src/9/pc/devuart.c:284,291
1991/0807    
 
	/* 
1991/0808    
	 *  speed up the clock to poll the uart 
	 */ 
	fclockinit(); 
1991/0810    
	 */ 
1991/0808    
 
	/* 
1991/0801    
	 *  set up i/o routines 
1991/0808/sys/src/9/pc/devuart.c:285,2971991/0810/sys/src/9/pc/devuart.c:298,309
1991/0801    
		up->iq->ptr = up; 
	} 
1991/0807    
	up->enabled = 1; 
1991/0808    
	up->sticky[Iena] = 0xf; 
1991/0801    
 
	/* 
 	 *  turn on interrupts 
	 */ 
1991/0810    
	up->sticky[Iena] = 0x7; 
1991/0801    
	uartwrreg(up, Iena, 0); 
1991/0808    
	uartwrreg(up, Tctl, 0x0); 
1991/0801    
 
	/* 
	 *  turn on DTR and RTS 
1991/0808/sys/src/9/pc/devuart.c:298,3051991/0810/sys/src/9/pc/devuart.c:310,315
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/0808/sys/src/9/pc/devuart.c:392,4001991/0810/sys/src/9/pc/devuart.c:402,407
1991/0801    
{ 
	Uart *up; 
	char name[NAMELEN]; 
                 
1991/0806    
print("uartstopen: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n", 
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/0810/sys/src/9/pc/devuart.c:36,411991/0822/sys/src/9/pc/devuart.c:36,42 (short | long)
1991/0801    
	 Loop=	(1<<4),		/*  loop bask */ 
	Lstat=	5,		/* line status */ 
	 Inready=(1<<0),	/*  receive buffer full */ 
1991/0822    
	 Overrun=(1<<1),	/*  we lost an input char */ 
1991/0803    
	 Outready=(1<<5),	/*  output buffer full */ 
1991/0801    
	Mstat=	6,		/* modem status */ 
	Scratch=7,		/* scratchpad */ 
1991/0810/sys/src/9/pc/devuart.c:212,2171991/0822/sys/src/9/pc/devuart.c:213,221
1991/0801    
	IOQ *cq; 
1991/0806    
	int s, l; 
1991/0801    
 
1991/0822    
	/* 
	 *  the for loop takes care of multiple events per interrupt 
	 */ 
1991/0810    
	for(;;){ 
		s = uartrdreg(up, Istat); 
		switch(s){ 
1991/0810/sys/src/9/pc/devuart.c:229,2341991/0822/sys/src/9/pc/devuart.c:233,241
1991/0810    
				if(up->delim[ch/8] & (1<<(ch&7)) ) 
					wakeup(&cq->r); 
			} 
1991/0822    
			l = uartrdreg(up, Lstat); 
			if(l & Overrun) 
				screenputc('!'); 
1991/0810    
			break; 
	 
		case 2:	/* transmitter empty */ 
1991/0810/sys/src/9/pc/devuart.c:281,2911991/0822/sys/src/9/pc/devuart.c:288,293
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/0810    
	 */ 
1991/0808    
 
	/* 
1991/0801    
	 *  set up i/o routines 
1991/0822/sys/src/9/pc/devuart.c:1,41991/0823/sys/src/9/pc/devuart.c:1,4 (short | long)
1991/0808    

#include	"u.h" 
1991/0823    
#include	"u.h" 
1991/0801    
#include	"lib.h" 
#include	"mem.h" 
#include	"dat.h" 
1991/0822/sys/src/9/pc/devuart.c:18,231991/0823/sys/src/9/pc/devuart.c:18,27
1991/0801    
	 */ 
	Data=	0,		/* xmit/rcv buffer */ 
	Iena=	1,		/* interrupt enable */ 
1991/0823    
	 Ircv=	(1<<0),		/*  for char rcv'd */ 
	 Ixmt=	(1<<1),		/*  for xmit buffer empty */ 
	 Irstat=(1<<2),		/*  for change in rcv'er status */ 
	 Imstat=(1<<3),		/*  for change in modem status */ 
1991/0808    
	Istat=	2,		/* interrupt flag (read) */ 
	Tctl=	2,		/* test control (write) */ 
1991/0801    
	Format=	3,		/* byte format */ 
1991/0822/sys/src/9/pc/devuart.c:36,421991/0823/sys/src/9/pc/devuart.c:40,48
1991/0801    
	 Loop=	(1<<4),		/*  loop bask */ 
	Lstat=	5,		/* line status */ 
	 Inready=(1<<0),	/*  receive buffer full */ 
1991/0822    
	 Overrun=(1<<1),	/*  we lost an input char */ 
1991/0823    
	 Oerror=(1<<1),		/*  receiver overrun */ 
	 Perror=(1<<2),		/*  receiver parity error */ 
	 Ferror=(1<<3),		/*  rcv framing error */ 
1991/0803    
	 Outready=(1<<5),	/*  output buffer full */ 
1991/0801    
	Mstat=	6,		/* modem status */ 
	Scratch=7,		/* scratchpad */ 
1991/0822/sys/src/9/pc/devuart.c:67,721991/0823/sys/src/9/pc/devuart.c:73,82
1991/0801    
	Alarm	*a;		/* alarm for waking the kernel process */ 
 	int	kstarted;	/* kproc started */ 
	uchar	delim[256/8];	/* characters that act as delimiters */ 
1991/0823    
 
	/* error statistics */ 
	ulong	frame; 
	ulong	overrun; 
1991/0801    
}; 
 
Uart uart[2]; 
1991/0822/sys/src/9/pc/devuart.c:213,2261991/0823/sys/src/9/pc/devuart.c:223,237
1991/0801    
	IOQ *cq; 
1991/0806    
	int s, l; 
1991/0801    
 
1991/0822    
	/* 
	 *  the for loop takes care of multiple events per interrupt 
	 */ 
1991/0810    
	for(;;){ 
		s = uartrdreg(up, Istat); 
		switch(s){ 
		case 6:	/* receiver line status */ 
			l = uartrdreg(up, Lstat); 
1991/0823    
			if(l & Ferror) 
				up->frame++; 
			if(l & Oerror) 
				up->overrun++; 
1991/0810    
			break; 
	 
		case 4:	/* received data available */ 
1991/0822/sys/src/9/pc/devuart.c:233,2411991/0823/sys/src/9/pc/devuart.c:244,249
1991/0810    
				if(up->delim[ch/8] & (1<<(ch&7)) ) 
					wakeup(&cq->r); 
			} 
1991/0822    
			l = uartrdreg(up, Lstat); 
			if(l & Overrun) 
				screenputc('!'); 
1991/0810    
			break; 
	 
		case 2:	/* transmitter empty */ 
1991/0822/sys/src/9/pc/devuart.c:257,2631991/0823/sys/src/9/pc/devuart.c:265,271
1991/0810    
		default: 
			if(s&1) 
				return; 
			print("weird modem interrupt\n"); 
1991/0823    
/*			print("weird modem interrupt\n");/**/ 
1991/0810    
			break; 
1991/0801    
		} 
	} 
1991/0822/sys/src/9/pc/devuart.c:290,2951991/0823/sys/src/9/pc/devuart.c:298,308
1991/0807    
	} 
1991/0808    
 
	/* 
1991/0823    
	 *  speed up the clock to poll the uart 
	fclockinit(); 
	 */ 
 
	/* 
1991/0801    
	 *  set up i/o routines 
	 */ 
	if(up->oq){ 
1991/0822/sys/src/9/pc/devuart.c:304,3101991/0823/sys/src/9/pc/devuart.c:317,323
1991/0801    
	/* 
 	 *  turn on interrupts 
	 */ 
1991/0810    
	up->sticky[Iena] = 0x7; 
1991/0823    
	up->sticky[Iena] = Ircv | Ixmt | Irstat; 
1991/0801    
	uartwrreg(up, Iena, 0); 
 
	/* 
1991/0822/sys/src/9/pc/devuart.c:514,5191991/0823/sys/src/9/pc/devuart.c:527,533
1991/0801    
	IOQ *cq = up->iq; 
	Block *bp; 
	int n; 
1991/0823    
	ulong frame, overrun; 
1991/0801    
 
1991/0808    
	if(waserror()) 
		print("uartkproc got an error\n"); 
1991/0822/sys/src/9/pc/devuart.c:531,5361991/0823/sys/src/9/pc/devuart.c:545,558
1991/0808    
			PUTNEXT(RD(up->wq), bp); 
		} 
		qunlock(up); 
1991/0823    
		if(up->frame != frame){ 
			kprint("uart%d: %d framing\n", up-uart, up->frame); 
			frame = up->frame; 
		} 
		if(up->overrun != overrun){ 
			kprint("uart%d: %d overruns\n", up-uart, up->overrun); 
			overrun = up->overrun; 
		} 
1991/0801    
	} 
} 
 
1991/0823/sys/src/9/pc/devuart.c:259,2651991/0904/sys/src/9/pc/devuart.c:259,265 (short | long)
1991/0810    
			break; 
	 
		case 0:	/* modem status */ 
			l = uartrdreg(up, Mstat); 
1991/0904    
			uartrdreg(up, Mstat); 
1991/0810    
			break; 
	 
		default: 
1991/0823/sys/src/9/pc/devuart.c:528,5331991/0904/sys/src/9/pc/devuart.c:528,536
1991/0801    
	Block *bp; 
	int n; 
1991/0823    
	ulong frame, overrun; 
1991/0904    
 
	frame = 0; 
	overrun = 0; 
1991/0801    
 
1991/0808    
	if(waserror()) 
		print("uartkproc got an error\n"); 
1991/0904/sys/src/9/pc/devuart.c:295,3001991/1001/sys/src/9/pc/devuart.c:295,303 (short | long)
1991/0808    
	if(up == &uart[Serial]){ 
1991/0807    
		if(serial(0) < 0) 
			print("can't turn on serial port power\n"); 
1991/1001    
	} else { 
		if(modem(0) < 0) 
			print("can't turn on modem speaker\n"); 
1991/0807    
	} 
1991/0808    
 
	/* 
1991/1001/sys/src/9/pc/devuart.c:72,781991/1113/sys/src/9/pc/devuart.c:72,77 (short | long)
1991/0801    
	Rendez	r;		/* kproc waiting for input */ 
	Alarm	*a;		/* alarm for waking the kernel process */ 
 	int	kstarted;	/* kproc started */ 
	uchar	delim[256/8];	/* characters that act as delimiters */ 
1991/0823    
 
	/* error statistics */ 
	ulong	frame; 
1991/1001/sys/src/9/pc/devuart.c:239,2491991/1113/sys/src/9/pc/devuart.c:238,245
1991/0810    
			ch = uartrdreg(up, Data) & 0xff; 
			if(cq->putc) 
				(*cq->putc)(cq, ch); 
			else { 
1991/1113    
			else 
1991/0810    
				putc(cq, ch); 
				if(up->delim[ch/8] & (1<<(ch&7)) ) 
					wakeup(&cq->r); 
			} 
			break; 
	 
		case 2:	/* transmitter empty */ 
1991/1001/sys/src/9/pc/devuart.c:281,2861991/1113/sys/src/9/pc/devuart.c:277,296
1991/0810    
	uartintr(&uart[1]); 
1991/0801    
} 
 
1991/1113    
void 
uartclock(void) 
{ 
	Uart *up; 
	IOQ *cq; 
 
	for(up = uart; up < &uart[2]; up++){ 
		cq = up->iq; 
		if(up->wq && cangetc(cq)) 
			wakeup(&cq->r); 
	} 
} 
 
 
1991/0801    
/* 
 *  turn on a port's interrupts.  set DTR and RTS 
 */ 
1991/1001/sys/src/9/pc/devuart.c:301,3111991/1113/sys/src/9/pc/devuart.c:311,316
1991/0807    
	} 
1991/0808    
 
	/* 
1991/0823    
	 *  speed up the clock to poll the uart 
	fclockinit(); 
	 */ 
                 
	/* 
1991/0801    
	 *  set up i/o routines 
	 */ 
	if(up->oq){ 
1991/1001/sys/src/9/pc/devuart.c:431,4391991/1113/sys/src/9/pc/devuart.c:436,441
1991/0801    
	RD(q)->ptr = up; 
	qunlock(up); 
 
	/* start with all characters as delimiters */ 
1991/0808    
	memset(up->delim, 0xff, sizeof(up->delim)); 
1991/0801    
	                 
	if(up->kstarted == 0){ 
		up->kstarted = 1; 
		sprint(name, "uart%d", s->id); 
1991/1001/sys/src/9/pc/devuart.c:486,5031991/1113/sys/src/9/pc/devuart.c:488,493
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/1001/sys/src/9/pc/devuart.c:531,5361991/1113/sys/src/9/pc/devuart.c:521,527
1991/0801    
	Block *bp; 
	int n; 
1991/0823    
	ulong frame, overrun; 
1991/1113    
	static ulong ints; 
1991/0904    
 
	frame = 0; 
	overrun = 0; 
1991/1001/sys/src/9/pc/devuart.c:540,5451991/1113/sys/src/9/pc/devuart.c:531,538
1991/0808    
 
	for(;;){ 
1991/0801    
		sleep(&cq->r, cangetc, cq); 
1991/1113    
		if((ints++ & 0x1f) == 0) 
			owl(ints>>5); 
1991/0808    
		qlock(up); 
		if(up->wq == 0){ 
			cq->out = cq->in; 
1991/1113/sys/src/9/pc/devuart.c:557,5731991/1115/sys/src/9/pc/devuart.c:557,573 (short | long)
1991/0801    
 
enum{ 
	Qdir=		0, 
	Qtty0=		STREAMQID(0, Sdataqid), 
	Qtty0ctl=	STREAMQID(0, Sctlqid), 
	Qtty1=		STREAMQID(1, Sdataqid), 
	Qtty1ctl=	STREAMQID(1, Sctlqid), 
1991/1115    
	Qeia0=		STREAMQID(0, Sdataqid), 
	Qeia0ctl=	STREAMQID(0, Sctlqid), 
	Qeia1=		STREAMQID(1, Sdataqid), 
	Qeia1ctl=	STREAMQID(1, Sctlqid), 
1991/0801    
}; 
 
Dirtab uartdir[]={ 
	"tty0",		{Qtty0},	0,		0666, 
	"tty0ctl",	{Qtty0ctl},	0,		0666, 
	"tty1",		{Qtty1},	0,		0666, 
	"tty1ctl",	{Qtty1ctl},	0,		0666, 
1991/1115    
	"eia0",		{Qeia0},	0,		0666, 
	"eia0ctl",	{Qeia0ctl},	0,		0666, 
	"eia1",		{Qeia1},	0,		0666, 
	"eia1ctl",	{Qeia1ctl},	0,		0666, 
1991/0801    
}; 
 
#define	NUart	(sizeof uartdir/sizeof(Dirtab)) 
1991/1113/sys/src/9/pc/devuart.c:618,6281991/1115/sys/src/9/pc/devuart.c:618,628
1991/0801    
uartstat(Chan *c, char *dp) 
{ 
	switch(c->qid.path){ 
	case Qtty0: 
		streamstat(c, dp, "tty0"); 
1991/1115    
	case Qeia0: 
		streamstat(c, dp, "eia0"); 
1991/0801    
		break; 
	case Qtty1: 
		streamstat(c, dp, "tty1"); 
1991/1115    
	case Qeia1: 
		streamstat(c, dp, "eia1"); 
1991/0801    
		break; 
	default: 
		devstat(c, dp, uartdir, NUart, devgen); 
1991/1113/sys/src/9/pc/devuart.c:636,6471991/1115/sys/src/9/pc/devuart.c:636,647
1991/0801    
	Uart *up; 
 
	switch(c->qid.path){ 
	case Qtty0: 
	case Qtty0ctl: 
1991/1115    
	case Qeia0: 
	case Qeia0ctl: 
1991/0801    
		up = &uart[0]; 
		break; 
	case Qtty1: 
	case Qtty1ctl: 
1991/1115    
	case Qeia1: 
	case Qeia1ctl: 
1991/0801    
		up = &uart[1]; 
		break; 
	default: 
1991/1113/sys/src/9/pc/devuart.c:676,6831991/1115/sys/src/9/pc/devuart.c:676,683
1991/0801    
	switch(c->qid.path&~CHDIR){ 
	case Qdir: 
		return devdirread(c, buf, n, uartdir, NUart, devgen); 
	case Qtty1ctl: 
	case Qtty0ctl: 
1991/1115    
	case Qeia1ctl: 
	case Qeia0ctl: 
1991/0801    
		return 0; 
	} 
	return streamread(c, buf, n); 
1991/1115/sys/src/9/pc/devuart.c:303,3121991/1210/sys/src/9/pc/devuart.c:303,312 (short | long)
1991/0807    
	 *  turn on power to the port 
	 */ 
1991/0808    
	if(up == &uart[Serial]){ 
1991/0807    
		if(serial(0) < 0) 
1991/1210    
		if(serial(1) < 0) 
1991/0807    
			print("can't turn on serial port power\n"); 
1991/1001    
	} else { 
		if(modem(0) < 0) 
1991/1210    
		if(modem(1) < 0) 
1991/1001    
			print("can't turn on modem speaker\n"); 
1991/0807    
	} 
1991/0808    
 
1991/1115/sys/src/9/pc/devuart.c:358,3651991/1210/sys/src/9/pc/devuart.c:358,368
1991/0807    
	 *  turn off power 
	 */ 
1991/0808    
	if(up == &uart[Serial]){ 
1991/0807    
		if(serial(1) < 0) 
1991/1210    
		if(serial(0) < 0) 
1991/0807    
			print("can't turn off serial power\n"); 
1991/1210    
	} else { 
		if(modem(0) < 0) 
			print("can't turn off modem speaker\n"); 
1991/0806    
	} 
1991/0808    
 
	/* 
1991/1115/sys/src/9/pc/devuart.c:532,5381991/1210/sys/src/9/pc/devuart.c:535,541
1991/0808    
	for(;;){ 
1991/0801    
		sleep(&cq->r, cangetc, cq); 
1991/1113    
		if((ints++ & 0x1f) == 0) 
			owl(ints>>5); 
1991/1210    
			lights((ints>>5)&1); 
1991/0808    
		qlock(up); 
		if(up->wq == 0){ 
			cq->out = cq->in; 
1991/1210/sys/src/9/pc/devuart.c:140,1451992/0101/sys/src/9/pc/devuart.c:140,147 (short | long)
1991/0801    
void 
uartbreak(Uart *up, int ms) 
{ 
1992/0101    
	if(ms == 0) 
		ms = 200; 
1991/0801    
	uartwrreg(up, Format, Break); 
	tsleep(&u->p->sleep, return0, 0, ms); 
	uartwrreg(up, Format, 0); 
1992/0101/sys/src/9/pc/devuart.c:4,101992/0111/sys/src/9/pc/devuart.c:4,10 (short | long)
1991/0801    
#include	"dat.h" 
#include	"fns.h" 
#include	"io.h" 
#include	"errno.h" 
1992/0111    
#include	"../port/error.h" 
1991/0801    
 
#include	"devtab.h" 
 
1992/0111/sys/src/9/pc/devuart.c:655,6611992/0114/sys/src/9/pc/devuart.c:655,661 (short | long)
1991/0801    
	} 
 
	if(up && up->nostream) 
		errors("in use"); 
1992/0114    
		error(Einuse); 
1991/0801    
 
	if((c->qid.path & CHDIR) == 0) 
		streamopen(c, &uartinfo); 
1992/0114/sys/src/9/pc/devuart.c:1,51992/0321/sys/src/9/pc/devuart.c:1,5 (short | long)
1991/0823    
#include	"u.h" 
1991/0801    
#include	"lib.h" 
1992/0321    
#include	"../port/lib.h" 
1991/0801    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
1992/0321/sys/src/9/pc/devuart.c:236,2431992/0409/sys/src/9/pc/devuart.c:236,245 (short | long)
1991/0810    
			break; 
	 
		case 4:	/* received data available */ 
			cq = up->iq; 
			ch = uartrdreg(up, Data) & 0xff; 
1992/0409    
			cq = up->iq; 
			if(cq == 0) 
				break; 
1991/0810    
			if(cq->putc) 
				(*cq->putc)(cq, ch); 
1991/1113    
			else 
1992/0321/sys/src/9/pc/devuart.c:246,2511992/0409/sys/src/9/pc/devuart.c:248,255
1991/0810    
	 
		case 2:	/* transmitter empty */ 
			cq = up->oq; 
1992/0409    
			if(cq == 0) 
				break; 
1991/0810    
			lock(cq); 
			ch = getc(cq); 
			if(ch < 0){ 
1992/0321/sys/src/9/pc/devuart.c:263,2691992/0409/sys/src/9/pc/devuart.c:267,273
1991/0810    
		default: 
			if(s&1) 
				return; 
1991/0823    
/*			print("weird modem interrupt\n");/**/ 
1992/0409    
			print("weird modem interrupt\n"); 
1991/0810    
			break; 
1991/0801    
		} 
	} 
1992/0409/sys/src/9/pc/devuart.c:70,761992/0602/sys/src/9/pc/devuart.c:70,75 (short | long)
1991/0801    
	/* stream interface */ 
	Queue	*wq;		/* write queue */ 
	Rendez	r;		/* kproc waiting for input */ 
	Alarm	*a;		/* alarm for waking the kernel process */ 
 	int	kstarted;	/* kproc started */ 
1991/0823    
 
	/* error statistics */ 
1992/0409/sys/src/9/pc/devuart.c:401,4071992/0602/sys/src/9/pc/devuart.c:400,405
1991/0801    
	} 
} 
 
static void	uarttimer(Alarm*); 
static int	uartputc(IOQ *, int); 
static void	uartstopen(Queue*, Stream*); 
static void	uartstclose(Queue*); 
1992/0409/sys/src/9/pc/devuart.c:415,4331992/0602/sys/src/9/pc/devuart.c:413,418
1991/0801    
	uartstclose, 
	"uart" 
}; 
                 
/* 
 *  create a helper process per port 
 */ 
static void 
uarttimer(Alarm *a) 
{ 
	Uart *up = a->arg; 
                 
	cancel(a); 
	up->a = 0; 
	wakeup(&up->iq->r); 
} 
 
static void 
uartstopen(Queue *q, Stream *s) 
1992/0602/sys/src/9/pc/devuart.c:578,5861992/0625/sys/src/9/pc/devuart.c:578,586 (short | long)
1991/0801    
	for(up = uart; up < &uart[2]; up++){ 
		if(up->nostream) 
			continue; 
		up->iq = ialloc(sizeof(IOQ), 0); 
1992/0625    
		up->iq = xalloc(sizeof(IOQ)); 
1991/0801    
		initq(up->iq); 
		up->oq = ialloc(sizeof(IOQ), 0); 
1992/0625    
		up->oq = xalloc(sizeof(IOQ)); 
1991/0801    
		initq(up->oq); 
	} 
} 
1992/0625/sys/src/9/pc/devuart.c:193,1991992/0711/sys/src/9/pc/devuart.c:193,199 (short | long)
1991/0801    
uartputs(IOQ *cq, char *s, int n) 
{ 
	Uart *up = cq->ptr; 
	int st, ch, x; 
1992/0711    
	int ch, x; 
1991/0803    
	int tries; 
1991/0801    
 
	x = splhi(); 
1992/0625/sys/src/9/pc/devuart.c:274,2841992/0711/sys/src/9/pc/devuart.c:274,286
1991/0801    
void 
uartintr0(Ureg *ur) 
{ 
1992/0711    
	USED(ur); 
1991/0810    
	uartintr(&uart[0]); 
1991/0801    
} 
void 
uartintr1(Ureg *ur) 
{ 
1992/0711    
	USED(ur); 
1991/0810    
	uartintr(&uart[1]); 
1991/0801    
} 
 
1992/0625/sys/src/9/pc/devuart.c:302,3091992/0711/sys/src/9/pc/devuart.c:304,309
1991/0801    
void 
uartenable(Uart *up) 
{ 
1991/0806    
	int x; 
                 
1991/0801    
	/* 
1991/0807    
	 *  turn on power to the port 
	 */ 
1992/0625/sys/src/9/pc/devuart.c:343,3481992/0711/sys/src/9/pc/devuart.c:343,349
1991/0807    
/* 
 *  turn off the uart 
 */ 
1992/0711    
void 
1991/0807    
uartdisable(Uart *up) 
{ 
 
1992/0625/sys/src/9/pc/devuart.c:654,6591992/0711/sys/src/9/pc/devuart.c:655,661
1991/0801    
void 
uartcreate(Chan *c, char *name, int omode, ulong perm) 
{ 
1992/0711    
	USED(c, name, omode, perm); 
1991/0801    
	error(Eperm); 
} 
 
1992/0625/sys/src/9/pc/devuart.c:667,6721992/0711/sys/src/9/pc/devuart.c:669,675
1991/0801    
long 
uartread(Chan *c, void *buf, long n, ulong offset) 
{ 
1992/0711    
	USED(offset); 
1991/0801    
	switch(c->qid.path&~CHDIR){ 
	case Qdir: 
		return devdirread(c, buf, n, uartdir, NUart, devgen); 
1992/0625/sys/src/9/pc/devuart.c:680,6851992/0711/sys/src/9/pc/devuart.c:683,689
1991/0801    
long 
uartwrite(Chan *c, void *va, long n, ulong offset) 
{ 
1992/0711    
	USED(offset); 
1991/0801    
	return streamwrite(c, va, n, 0); 
} 
 
1992/0625/sys/src/9/pc/devuart.c:686,6911992/0711/sys/src/9/pc/devuart.c:690,696
1991/0801    
void 
uartremove(Chan *c) 
{ 
1992/0711    
	USED(c); 
1991/0801    
	error(Eperm); 
} 
 
1992/0625/sys/src/9/pc/devuart.c:692,6961992/0711/sys/src/9/pc/devuart.c:697,702
1991/0801    
void 
uartwstat(Chan *c, char *dp) 
{ 
1992/0711    
	USED(c, dp); 
1991/0801    
	error(Eperm); 
} 
1992/0711/sys/src/9/pc/devuart.c:614,6231992/0826/sys/src/9/pc/devuart.c:614,623 (short | long)
1991/0801    
{ 
	switch(c->qid.path){ 
1991/1115    
	case Qeia0: 
		streamstat(c, dp, "eia0"); 
1992/0826    
		streamstat(c, dp, uartdir[0].name, uartdir[0].perm); 
1991/0801    
		break; 
1991/1115    
	case Qeia1: 
		streamstat(c, dp, "eia1"); 
1992/0826    
		streamstat(c, dp, uartdir[2].name, uartdir[2].perm); 
1991/0801    
		break; 
	default: 
		devstat(c, dp, uartdir, NUart, devgen); 
1992/0826/sys/src/9/pc/devuart.c:37,431992/1016/sys/src/9/pc/devuart.c:37,43 (short | long)
1991/0801    
	 Rts=	(1<<1),		/*  request to send */ 
	 Ri=	(1<<2),		/*  ring */ 
1991/0810    
	 Inton=	(1<<3),		/*  turn on interrupts */ 
1991/0801    
	 Loop=	(1<<4),		/*  loop bask */ 
1992/1016    
	 Loop=	(1<<4),		/*  loop back */ 
1991/0801    
	Lstat=	5,		/* line status */ 
	 Inready=(1<<0),	/*  receive buffer full */ 
1991/0823    
	 Oerror=(1<<1),		/*  receiver overrun */ 
1992/0826/sys/src/9/pc/devuart.c:147,1521992/1016/sys/src/9/pc/devuart.c:147,204
1991/0801    
} 
 
/* 
1992/1016    
 *  set bits/char 
 */ 
void 
uartbits(Uart *up, int bits) 
{ 
	if(bits < 5 || bits > 8) 
		error(Ebadarg); 
	up->sticky[Format] &= ~3; 
	up->sticky[Format] |= bits-5; 
	uartwrreg(up, Format, 0); 
} 
 
/* 
 *  set parity 
 */ 
void 
uartparity(Uart *up, int c) 
{ 
	switch(c&0xff){ 
	case 'e': 
		up->sticky[Format] |= Pena|Peven; 
		break; 
	case 'o': 
		up->sticky[Format] &= ~Peven; 
		up->sticky[Format] |= Pena; 
		break; 
	default: 
		up->sticky[Format] &= ~(Pena|Peven); 
		break; 
	} 
	uartwrreg(up, Format, 0); 
} 
 
/* 
 *  set stop bits 
 */ 
void 
uartstop(Uart *up, int n) 
{ 
	switch(n){ 
	case 1: 
		up->sticky[Format] &= ~Stop2; 
		break; 
	case 2: 
	default: 
		up->sticky[Format] |= Stop2; 
		break; 
	} 
	uartwrreg(up, Format, 0); 
} 
 
/* 
1991/0801    
 *  default is 9600 baud, 1 stop bit, 8 bit chars, no interrupts, 
 *  transmit and receive enabled, interrupts disabled. 
 */ 
1992/0826/sys/src/9/pc/devuart.c:182,1871992/1016/sys/src/9/pc/devuart.c:234,242
1991/0801    
		uartwrreg(up, Format, 0); 
1991/0810    
		up->sticky[Mctl] |= Inton; 
		uartwrreg(up, Mctl, 0x0); 
1992/1016    
 
		uartdtr(up, 1); 
		uartrts(up, 1); 
1991/0801    
	} 
} 
 
1992/0826/sys/src/9/pc/devuart.c:355,3631992/1016/sys/src/9/pc/devuart.c:410,418
1991/0807    
 
	/* 
	 *  turn off DTR and RTS 
	 */ 
	uartdtr(up, 0); 
	uartrts(up, 0); 
1992/1016    
	 */ 
1991/0807    
	up->enabled = 0; 
 
	/* 
1992/0826/sys/src/9/pc/devuart.c:487,4951992/1016/sys/src/9/pc/devuart.c:542,562
1991/0801    
		case 'k': 
			uartbreak(up, n); 
			break; 
1992/1016    
		case 'L': 
		case 'l': 
			uartbits(up, n); 
			break; 
		case 'P': 
		case 'p': 
			uartparity(up, *(bp->rptr+1)); 
			break; 
1991/0801    
		case 'R': 
		case 'r': 
			uartrts(up, n); 
1992/1016    
			break; 
		case 'S': 
		case 's': 
			uartstop(up, n); 
1991/0801    
			break; 
		} 
	}else while((m = BLEN(bp)) > 0){ 
1992/1016/sys/src/9/pc/devuart.c:63,691992/1017/sys/src/9/pc/devuart.c:63,69 (short | long)
1991/0807    
	int	enabled; 
1991/0801    
 
	/* console interface */ 
	int	nostream;	/* can't use the stream interface */ 
1992/1017    
	int	special;	/* can't use the stream interface */ 
1991/0801    
	IOQ	*iq;		/* input character queue */ 
	IOQ	*oq;		/* output character queue */ 
 
1992/1016/sys/src/9/pc/devuart.c:234,2421992/1017/sys/src/9/pc/devuart.c:234,239
1991/0801    
		uartwrreg(up, Format, 0); 
1991/0810    
		up->sticky[Mctl] |= Inton; 
		uartwrreg(up, Mctl, 0x0); 
1992/1016    
                 
		uartdtr(up, 1); 
		uartrts(up, 1); 
1991/0801    
	} 
} 
 
1992/1016/sys/src/9/pc/devuart.c:409,4181992/1017/sys/src/9/pc/devuart.c:406,421
1991/0807    
	uartwrreg(up, Iena, 0); 
 
	/* 
1992/1017    
	 *  revert to default settings 
	 */ 
	up->sticky[Format] = Bits8; 
	uartwrreg(up, Format, 0); 
 
	/* 
1991/0807    
	 *  turn off DTR and RTS 
1992/1017    
	 */ 
1991/0807    
	uartdtr(up, 0); 
	uartrts(up, 0); 
1992/1016    
	 */ 
1991/0807    
	up->enabled = 0; 
 
	/* 
1992/1016/sys/src/9/pc/devuart.c:425,4351992/1017/sys/src/9/pc/devuart.c:428,433
1991/1210    
		if(modem(0) < 0) 
			print("can't turn off modem speaker\n"); 
1991/0806    
	} 
1991/0808    
                 
	/* 
	 *  slow the clock down again 
	 */ 
	clockinit(); 
1991/0801    
} 
 
/* 
1992/1016/sys/src/9/pc/devuart.c:441,4511992/1017/sys/src/9/pc/devuart.c:439,450
1991/0801    
	Uart *up = &uart[port]; 
 
	uartsetup(); 
	up->nostream = 1; 
1992/1017    
	up->special = 1; 
1991/0801    
	up->oq = oq; 
	up->iq = iq; 
	uartenable(up); 
	uartsetbaud(up, baud); 
1992/1017    
	if(baud) 
		uartsetbaud(up, baud); 
1991/0801    
 
	if(iq){ 
		/* 
1992/1016/sys/src/9/pc/devuart.c:498,5031992/1017/sys/src/9/pc/devuart.c:497,505
1991/0801    
{ 
	Uart *up = q->ptr; 
 
1992/1017    
	if(up->special) 
		return; 
 
1991/0807    
	uartdisable(up); 
 
1991/0801    
	qlock(up); 
1992/1016/sys/src/9/pc/devuart.c:644,6501992/1017/sys/src/9/pc/devuart.c:646,652
1991/0803    
 
1991/0801    
	uartsetup(); 
	for(up = uart; up < &uart[2]; up++){ 
		if(up->nostream) 
1992/1017    
		if(up->special) 
1991/0801    
			continue; 
1992/0625    
		up->iq = xalloc(sizeof(IOQ)); 
1991/0801    
		initq(up->iq); 
1992/1016/sys/src/9/pc/devuart.c:711,7171992/1017/sys/src/9/pc/devuart.c:713,719
1991/0801    
		break; 
	} 
 
	if(up && up->nostream) 
1992/1017    
	if(up && up->special) 
1992/0114    
		error(Einuse); 
1991/0801    
 
	if((c->qid.path & CHDIR) == 0) 
1992/1017/sys/src/9/pc/devuart.c:45,501992/1210/sys/src/9/pc/devuart.c:45,58 (short | long)
1991/0823    
	 Ferror=(1<<3),		/*  rcv framing error */ 
1991/0803    
	 Outready=(1<<5),	/*  output buffer full */ 
1991/0801    
	Mstat=	6,		/* modem status */ 
1992/1210    
	 Ctsc=	(1<<0),		/*  clear to send changed */ 
	 Dsrc=	(1<<1),		/*  data set ready changed */ 
	 Rire=	(1<<2),		/*  rising edge of ring indicator */ 
	 Dcdc=	(1<<3),		/*  data carrier detect changed */ 
	 Cts=	(1<<4),		/*  complement of clear to send line */ 
	 Dsr=	(1<<5),		/*  complement of data set ready line */ 
	 Ring=	(1<<6),		/*  complement of ring indicator line */ 
	 Dcd=	(1<<7),		/*  complement of data carrier detect line */ 
1991/0801    
	Scratch=7,		/* scratchpad */ 
	Dlsb=	0,		/* divisor lsb */ 
	Dmsb=	1,		/* divisor msb */ 
1992/1017/sys/src/9/pc/devuart.c:61,661992/1210/sys/src/9/pc/devuart.c:69,75
1991/0804    
	uchar	sticky[8];	/* sticky write register values */ 
1991/0801    
	int	printing;	/* true if printing */ 
1991/0807    
	int	enabled; 
1992/1210    
	int	cts; 
1991/0801    
 
	/* console interface */ 
1992/1017    
	int	special;	/* can't use the stream interface */ 
1992/1017/sys/src/9/pc/devuart.c:199,2041992/1210/sys/src/9/pc/devuart.c:208,231
1992/1016    
} 
 
/* 
1992/1210    
 *  modem flow control on/off (rts/cts) 
 */ 
void 
uartmflow(Uart *up, int n) 
{ 
	if(n){ 
		up->sticky[Iena] |= Imstat; 
		uartwrreg(up, Iena, 0); 
		up->cts = uartrdreg(up, Mstat) & Cts; 
	} else { 
		up->sticky[Iena] &= ~Imstat; 
		uartwrreg(up, Iena, 0); 
		up->cts = 1; 
	} 
} 
 
 
/* 
1991/0801    
 *  default is 9600 baud, 1 stop bit, 8 bit chars, no interrupts, 
 *  transmit and receive enabled, interrupts disabled. 
 */ 
1992/1017/sys/src/9/pc/devuart.c:245,2551992/1210/sys/src/9/pc/devuart.c:272,284
1991/0801    
uartputs(IOQ *cq, char *s, int n) 
{ 
	Uart *up = cq->ptr; 
1992/0711    
	int ch, x; 
1992/1210    
	int ch, x, multiprocessor; 
1991/0803    
	int tries; 
1991/0801    
 
1992/1210    
	multiprocessor = active.machs > 1; 
1991/0801    
	x = splhi(); 
	lock(cq); 
1992/1210    
	if(multiprocessor) 
		lock(cq); 
1991/0801    
	puts(cq, s, n); 
	if(up->printing == 0){ 
		ch = getc(cq); 
1992/1017/sys/src/9/pc/devuart.c:261,2671992/1210/sys/src/9/pc/devuart.c:290,297
1991/0801    
			outb(up->port + Data, ch); 
		} 
	} 
	unlock(cq); 
1992/1210    
	if(multiprocessor) 
		unlock(cq); 
1991/0801    
	splx(x); 
} 
 
1992/1017/sys/src/9/pc/devuart.c:273,2801992/1210/sys/src/9/pc/devuart.c:303,311
1991/0801    
{ 
	int ch; 
	IOQ *cq; 
1991/0806    
	int s, l; 
1992/1210    
	int s, l, multiprocessor; 
1991/0801    
 
1992/1210    
	multiprocessor = active.machs > 1; 
1991/0810    
	for(;;){ 
		s = uartrdreg(up, Istat); 
		switch(s){ 
1992/1017/sys/src/9/pc/devuart.c:301,3181992/1210/sys/src/9/pc/devuart.c:332,373
1991/0810    
			cq = up->oq; 
1992/0409    
			if(cq == 0) 
				break; 
1991/0810    
			lock(cq); 
			ch = getc(cq); 
			if(ch < 0){ 
1992/1210    
			if(multiprocessor) 
				lock(cq); 
			if(up->cts == 0) 
1991/0810    
				up->printing = 0; 
1991/0801    
				wakeup(&cq->r); 
1991/0810    
			}else 
				outb(up->port + Data, ch); 
			unlock(cq); 
1992/1210    
			else { 
				ch = getc(cq); 
				if(ch < 0){ 
					up->printing = 0; 
					wakeup(&cq->r); 
				}else 
					outb(up->port + Data, ch); 
			} 
			if(multiprocessor) 
				unlock(cq); 
1991/0810    
			break; 
	 
		case 0:	/* modem status */ 
1991/0904    
			uartrdreg(up, Mstat); 
1992/1210    
			ch = uartrdreg(up, Mstat); 
			if(ch & Ctsc){ 
				up->cts = ch & Cts; 
				cq = up->oq; 
				if(cq == 0) 
					break; 
				if(multiprocessor) 
					lock(cq); 
				if(up->cts && up->printing == 0){ 
					ch = getc(cq); 
					if(ch >= 0){ 
						up->printing = 1; 
						outb(up->port + Data, getc(cq)); 
					} else 
						wakeup(&cq->r); 
				} 
				if(multiprocessor) 
					unlock(cq); 
			} 
1991/0810    
			break; 
	 
		default: 
1992/1017/sys/src/9/pc/devuart.c:390,3951992/1210/sys/src/9/pc/devuart.c:445,455
1991/0801    
	 */ 
	uartdtr(up, 1); 
	uartrts(up, 1); 
1992/1210    
 
	/* 
	 *  assume we can send 
	 */ 
	up->cts = 1; 
1991/0807    
} 
1991/0806    
 
1991/0807    
/* 
1992/1017/sys/src/9/pc/devuart.c:547,5521992/1210/sys/src/9/pc/devuart.c:607,616
1992/1016    
		case 'L': 
		case 'l': 
			uartbits(up, n); 
1992/1210    
			break; 
		case 'm': 
		case 'M': 
			uartmflow(up, n); 
1992/1016    
			break; 
		case 'P': 
		case 'p': 
Too many diffs (26 > 25). Stopping.


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