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

1992/0520/power/devduart.c (diff list | history)

1992/0519/sys/src/9/power/devduart.c:6,141992/0520/sys/src/9/power/devduart.c:6,11 (short | long | prev | next)
1991/0607    
#include	"io.h" 
1992/0111    
#include	"../port/error.h" 
1991/0607    
 
int	duartacr; 
int	duartimr; 
                 
void	duartputs(IOQ*, char*, int); 
void	iprint(char*, ...); 
 
1992/0519/sys/src/9/power/devduart.c:15,231992/0520/sys/src/9/power/devduart.c:12,22
1991/0607    
#define	PAD	15	/* registers are well-spaced */ 
 
/* 
 * Register set for half the duart.  There are really two sets. 
1992/0520    
 *  Register set for half the duart.  There are really two sets in adjacent 
 *  memory locations. 
1991/0607    
 */ 
struct Duart{ 
1992/0520    
struct Duartreg 
{ 
1991/0607    
	uchar	mr1_2,		/* Mode Register Channels 1 & 2 */ 
		pad0[PAD]; 
	uchar	sr_csr,		/* Status Register/Clock Select Register */ 
1992/0519/sys/src/9/power/devduart.c:98,1041992/0520/sys/src/9/power/devduart.c:97,103
1991/0607    
	BD1200		=0x66|0x0000, 
	BD300		=0x44|0x0000, 
 
	Maxport		=8, 
1992/0520    
	Maxduart	=8, 
1991/0607    
}; 
 
/* 
1992/0519/sys/src/9/power/devduart.c:115,1451992/0520/sys/src/9/power/devduart.c:114,158
1991/0607    
}; 
 
/* 
 *  software info for a serial duart interface 
1992/0520    
 *  a duart 
1991/0607    
 */ 
typedef struct Duartport	Duartport; 
struct Duartport 
1992/0520    
typedef struct Duart	Duart; 
struct Duart 
1991/0607    
{ 
	QLock; 
	int	printing;	/* true if printing */ 
	Duart	*duart;		/* device */ 
	int	inited; 
	int	c;		/* character to restart output */ 
	int	op;		/* operation requested */ 
	int	val;		/* value of operation */ 
	Rendez	opr;		/* waiot here for op to complete */ 
1992/0520    
	Duartreg	*reg;		/* duart registers */ 
	uchar		imr;		/* sticky interrupt mask reg bits */ 
	uchar		acr;		/* sticky auxiliary reg bits */ 
	int		inited; 
}; 
Duart duart[Maxduart]; 
1991/0607    
 
1992/0520    
/* 
 *  values specific to a single duart port 
 */ 
typedef struct Port	Port; 
struct Port 
{ 
	QLock; 
	int		printing;	/* true if printing */ 
	Duart		*d;		/* device */ 
	Duartreg	*reg;		/* duart registers (for this port) */ 
	int		c;		/* character to restart output */ 
	int		op;		/* operation requested */ 
	int		val;		/* value of operation */ 
	Rendez		opr;		/* waiot here for op to complete */ 
 
1991/0607    
	/* console interface */ 
	int	nostream;	/* can't use the stream interface */ 
	IOQ	*iq;		/* input character queue */ 
	IOQ	*oq;		/* output character queue */ 
1992/0520    
	int		nostream;	/* can't use the stream interface */ 
	IOQ		*iq;		/* input character queue */ 
	IOQ		*oq;		/* output character queue */ 
1991/0607    
 
	/* stream interface */ 
	Queue	*wq;		/* write queue */ 
	Rendez	r;		/* kproc waiting for input */ 
 	int	kstarted;	/* kproc started */ 
1992/0520    
	Queue		*wq;		/* write queue */ 
	Rendez		r;		/* kproc waiting for input */ 
 	int		kstarted;	/* kproc started */ 
1991/0607    
}; 
Duartport	duartport[Maxport];	/* max possible */ 
1992/0520    
Port duartport[2*Maxduart]; 
1991/0607    
 
/* 
 *  configure a duart port, default is 9600 baud, 8 bits/char, 1 stop bit, 
1992/0519/sys/src/9/power/devduart.c:146,1691992/0520/sys/src/9/power/devduart.c:159,182
1991/0607    
 *  no parity 
 */ 
void 
duartsetup(Duartport *dp) 
1992/0520    
duartsetup(Port *p, Duart *d, int devno) 
1991/0607    
{ 
	Duart *duart; 
1992/0520    
	Duartreg *reg; 
1991/0607    
 
	duart = dp->duart; 
1992/0520    
	p->d = d; 
	reg = &d->reg[devno]; 
	p->reg = reg; 
1991/0607    
 
	duart->cmnd = RESET_RCV|DIS_TX|DIS_RX; 
	duart->cmnd = RESET_TRANS; 
	duart->cmnd = RESET_ERR; 
	duart->cmnd = STOP_BRK; 
1992/0520    
	reg->cmnd = RESET_RCV|DIS_TX|DIS_RX; 
	reg->cmnd = RESET_TRANS; 
	reg->cmnd = RESET_ERR; 
	reg->cmnd = STOP_BRK; 
1991/0607    
 
	duart->ipc_acr = 0x80;		/* baud-rate set 2 */ 
	duart->cmnd = RESET_MR; 
	duart->mr1_2 = NO_PAR|CBITS8; 
	duart->mr1_2 = ONESTOPB; 
	duart->sr_csr = (DBD9600<<4)|DBD9600; 
	duart->is_imr = IM_RRDYA|IM_XRDYA; 
	duart->cmnd = ENB_TX|ENB_RX; 
1992/0520    
	reg->cmnd = RESET_MR; 
	reg->mr1_2 = NO_PAR|CBITS8; 
	reg->mr1_2 = ONESTOPB; 
	reg->sr_csr = (DBD9600<<4)|DBD9600; 
	reg->cmnd = ENB_TX|ENB_RX; 
1991/0607    
} 
 
/* 
1992/0519/sys/src/9/power/devduart.c:172,1891992/0520/sys/src/9/power/devduart.c:185,206
1991/0607    
void 
duartinit(void) 
{ 
	Duartport *dp; 
1992/0520    
	Port *p; 
	Duart *d; 
1991/0607    
 
	dp = &duartport[2*m->machno]; 
	if(dp->inited) 
1992/0520    
	d = &duart[m->machno]; 
	if(d->inited) 
1991/0607    
		return; 
	dp->inited = 1; 
1992/0520    
	d->reg = DUARTREG; 
	d->imr = IM_RRDYA|IM_XRDYA|IM_RRDYB|IM_XRDYB; 
	d->reg->is_imr = d->imr; 
	d->acr = 0x80;			/* baud rate set 2 */ 
	d->reg->ipc_acr = d->acr; 
1991/0607    
 
	dp->duart = DUARTREG; 
	duartsetup(dp); 
	dp++; 
	dp->duart = DUARTREG+1; 
	duartsetup(dp); 
1992/0520    
	p = &duartport[2*m->machno]; 
	duartsetup(p, d, 0); 
	p++; 
	duartsetup(p, d, 1); 
1991/0607    
} 
 
/* 
1992/0519/sys/src/9/power/devduart.c:190,1981992/0520/sys/src/9/power/devduart.c:207,215
1991/0607    
 *  enable a duart port 
 */ 
void 
duartenable(Duartport *dp) 
1992/0520    
duartenable(Port *p) 
1991/0607    
{ 
	dp->duart->cmnd = ENB_TX|ENB_RX; 
1992/0520    
	p->reg->cmnd = ENB_TX|ENB_RX; 
1991/0607    
} 
 
void 
1992/0519/sys/src/9/power/devduart.c:202,2081992/0520/sys/src/9/power/devduart.c:219,225
1991/0607    
} 
 
void 
duartbaud(Duartport *dp, int b) 
1992/0520    
duartbaud(Port *p, int b) 
1991/0607    
{ 
1992/0519    
	int x; 
1991/0607    
 
1992/0519/sys/src/9/power/devduart.c:232,2671992/0520/sys/src/9/power/devduart.c:249,284
1992/0516    
		return; 
1991/0607    
	} 
	if(x & 0x0100) 
1992/0519    
		duartacr |= 0x80; 
1992/0520    
		p->d->acr |= 0x80; 
1991/0607    
	else 
1992/0519    
		duartacr &= ~0x80; 
	dp->duart->ipc_acr = duartacr; 
1991/0607    
	dp->duart->sr_csr = x; 
1992/0520    
		p->d->acr &= ~0x80; 
	p->d->reg->ipc_acr = p->d->acr; 
	p->reg->sr_csr = x; 
1991/0607    
} 
 
void 
duartdtr(Duartport *dp, int val) 
1992/0520    
duartdtr(Port *p, int val) 
1991/0607    
{ 
	if (val) 
		dp->duart->ctlr=0x01; 
1992/0520    
		p->reg->ctlr = 0x01; 
1991/0607    
	else 
		dp->duart->ctur=0x01; 
1992/0520    
		p->reg->ctur = 0x01; 
1991/0607    
} 
 
void 
duartbreak(Duartport *dp, int val) 
1992/0520    
duartbreak(Port *p, int val) 
1991/0607    
{ 
	Duart *duart; 
1992/0520    
	Duartreg *reg; 
1991/0607    
 
	duart = dp->duart; 
1992/0520    
	reg = p->reg; 
1991/0607    
	if (val){ 
1992/0519    
		duartimr &= ~IM_XRDYB; 
		duart->is_imr = duartimr; 
1991/0607    
		duart->cmnd = STRT_BRK|ENB_TX; 
1992/0520    
		p->d->imr &= ~IM_XRDYB; 
		p->d->reg->is_imr = p->d->imr; 
		reg->cmnd = STRT_BRK|ENB_TX; 
1991/0607    
	} else { 
		duart->cmnd = STOP_BRK|ENB_TX; 
1992/0519    
		duartimr |= IM_XRDYB; 
		duart->is_imr = duartimr; 
1992/0520    
		reg->cmnd = STOP_BRK|ENB_TX; 
		p->d->imr |= IM_XRDYB; 
		p->d->reg->is_imr = p->d->imr; 
1991/0607    
	} 
} 
 
1992/0519/sys/src/9/power/devduart.c:269,3351992/0520/sys/src/9/power/devduart.c:286,352
1991/0607    
 *  do anything requested for this CPU's duarts 
 */ 
void 
duartslave0(Duartport *dp) 
1992/0520    
duartslave0(Port *p) 
1991/0607    
{ 
	switch(dp->op){ 
1992/0520    
	switch(p->op){ 
1991/0607    
	case Ddtr: 
1992/0519    
		duartdtr(dp, dp->val); 
1992/0520    
		duartdtr(p, p->val); 
1991/0607    
		break; 
	case Dbaud: 
1992/0519    
		duartbaud(dp, dp->val); 
1992/0520    
		duartbaud(p, p->val); 
1991/0607    
		break; 
	case Dbreak: 
		duartbreak(dp, dp->val); 
1992/0520    
		duartbreak(p, p->val); 
1991/0607    
		break; 
	case Dprint: 
		dp->duart->cmnd = ENB_TX; 
		dp->duart->data = dp->val; 
1992/0520    
		p->reg->cmnd = ENB_TX; 
		p->reg->data = p->val; 
1991/0607    
		break; 
	case Dena: 
		duartenable(dp); 
1992/0520    
		duartenable(p); 
1991/0607    
		break; 
	case Dstate: 
		dp->val = dp->duart->is_imr; 
1992/0520    
		p->val = p->reg->ppcr; 
1991/0607    
		break; 
	} 
	dp->op = Dnone; 
	wakeup(&dp->opr); 
1992/0520    
	p->op = Dnone; 
	wakeup(&p->opr); 
1991/0607    
} 
void 
duartslave(void) 
{ 
1992/0519    
	IOQ *cq; 
1991/0607    
	Duartport *dp; 
1992/0520    
	Port *p; 
1991/0607    
 
	dp = &duartport[2*m->machno]; 
1992/0519    
	cq = dp->iq; 
	if(dp->wq && cangetc(cq)) 
1992/0520    
	p = &duartport[2*m->machno]; 
	cq = p->iq; 
	if(p->wq && cangetc(cq)) 
1992/0519    
		wakeup(&cq->r); 
1991/0607    
	if(dp->op != Dnone) 
		duartslave0(dp); 
	dp++; 
1992/0519    
	cq = dp->iq; 
	if(dp->wq && cangetc(cq)) 
1992/0520    
	if(p->op != Dnone) 
		duartslave0(p); 
	p++; 
	cq = p->iq; 
	if(p->wq && cangetc(cq)) 
1992/0519    
		wakeup(&cq->r); 
1991/0607    
	if(dp->op != Dnone) 
		duartslave0(dp); 
1992/0520    
	if(p->op != Dnone) 
		duartslave0(p); 
1991/0607    
} 
 
1992/0519    
void 
1991/0607    
duartrintr(Duartport *dp) 
1992/0520    
duartrintr(Port *p) 
1991/0607    
{ 
	Duart *duart; 
1992/0520    
	Duartreg *reg; 
1991/0607    
	IOQ *cq; 
	int status; 
	char ch; 
 
	duart = dp->duart; 
	status = duart->sr_csr; 
	ch = duart->data; 
1992/0520    
	reg = p->reg; 
	status = reg->sr_csr; 
	ch = reg->data; 
1991/0607    
	if(status & (FRM_ERR|OVR_ERR|PAR_ERR)) 
		duart->cmnd = RESET_ERR; 
1992/0520    
		reg->cmnd = RESET_ERR; 
1991/0607    
 
	cq = dp->iq; 
1992/0520    
	cq = p->iq; 
1991/0607    
	if(cq->putc) 
		(*cq->putc)(cq, ch); 
1992/0519    
	else 
1992/0519/sys/src/9/power/devduart.c:337,3581992/0520/sys/src/9/power/devduart.c:354,375
1991/0607    
} 
 
1992/0519    
void 
1991/0607    
duartxintr(Duartport *dp) 
1992/0520    
duartxintr(Port *p) 
1991/0607    
{ 
	Duart *duart; 
1992/0520    
	Duartreg *reg; 
1991/0607    
	IOQ *cq; 
1992/0325    
	int ch; 
1991/0607    
 
	cq = dp->oq; 
1992/0520    
	cq = p->oq; 
1991/0607    
	lock(cq); 
	ch = getc(cq); 
	duart = dp->duart; 
1992/0520    
	reg = p->reg; 
1991/0607    
	if(ch < 0){ 
		dp->printing = 0; 
1992/0520    
		p->printing = 0; 
1991/0607    
		wakeup(&cq->r); 
		duart->cmnd = DIS_TX; 
1992/0520    
		reg->cmnd = DIS_TX; 
1991/0607    
	} else 
		duart->data = ch; 
1992/0520    
		reg->data = ch; 
1991/0607    
	unlock(cq); 
} 
 
1992/0519/sys/src/9/power/devduart.c:360,3711992/0520/sys/src/9/power/devduart.c:377,389
1991/0607    
duartintr(void) 
{ 
	int cause, status, c; 
	Duart *duart; 
	Duartport *dp; 
1992/0520    
	Duartreg *reg; 
	Port *p; 
1991/0607    
 
	dp = &duartport[2*m->machno]; 
	duart = dp->duart; 
	cause = duart->is_imr; 
1992/0520    
	p = &duartport[2*m->machno]; 
	reg = p->reg; 
	cause = reg->is_imr; 
 
1991/0607    
	/* 
	 * I can guess your interrupt. 
	 */ 
1992/0519/sys/src/9/power/devduart.c:373,3941992/0520/sys/src/9/power/devduart.c:391,412
1991/0607    
	 * Is it 1? 
	 */ 
	if(cause & IM_RRDYA) 
		duartrintr(dp); 
1992/0520    
		duartrintr(p); 
1991/0607    
	/* 
	 * Is it 2? 
	 */ 
	if(cause & IM_XRDYA) 
		duartxintr(dp); 
1992/0520    
		duartxintr(p); 
1991/0607    
	/* 
	 * Is it 3? 
	 */ 
	if(cause & IM_RRDYB) 
		duartrintr(dp+1); 
1992/0520    
		duartrintr(p+1); 
1991/0607    
	/* 
	 * Is it 4? 
	 */ 
	if(cause & IM_XRDYB) 
		duartxintr(dp+1); 
1992/0520    
		duartxintr(p+1); 
1991/0607    
} 
 
/* 
1992/0519/sys/src/9/power/devduart.c:397,4181992/0520/sys/src/9/power/devduart.c:415,436
1991/0607    
int 
duartrawputc(int c) 
{ 
	Duart *duart; 
1992/0520    
	Duartreg *reg; 
1991/0607    
	int i; 
 
	duart = DUARTREG; 
1992/0520    
	reg = DUARTREG; 
1991/0607    
	if(c == '\n') 
		duartrawputc('\r'); 
	duart->cmnd = ENB_TX; 
1992/0520    
	reg->cmnd = ENB_TX; 
1991/0607    
	i = 0; 
	while((duart->sr_csr&XMT_RDY) == 0) 
1992/0520    
	while((reg->sr_csr&XMT_RDY) == 0) 
1991/0607    
		if(++i >= 1000000){ 
			duartsetup(&duartport[0]); 
1992/0520    
			duartsetup(&duartport[0], &duart[0], 0); 
1991/0607    
			for(i=0; i<100000; i++) 
				; 
			break; 
		} 
	duart->data = c; 
1992/0520    
	reg->data = c; 
1991/0607    
	if(c == '\n') 
		for(i=0; i<100000; i++) 
			; 
1992/0519/sys/src/9/power/devduart.c:447,4651992/0520/sys/src/9/power/devduart.c:465,483
1991/0607    
duartputs(IOQ *cq, char *s, int n) 
{ 
	int ch, x; 
	Duartport *dp; 
	Duart *duart; 
1992/0520    
	Port *p; 
	Duartreg *reg; 
1991/0607    
 
	x = splhi(); 
	lock(cq); 
	puts(cq, s, n); 
	dp = cq->ptr; 
	if(dp->printing == 0){ 
1992/0520    
	p = cq->ptr; 
	if(p->printing == 0){ 
1991/0607    
		ch = getc(cq); 
		if(ch >= 0){ 
			dp->printing = 1; 
			dp->val = ch; 
			dp->op = Dprint; 
1992/0520    
			p->printing = 1; 
			p->val = ch; 
			p->op = Dprint; 
1991/0607    
		} 
	} 
	unlock(cq); 
1992/0519/sys/src/9/power/devduart.c:472,4891992/0520/sys/src/9/power/devduart.c:490,507
1991/0607    
void 
duartspecial(int port, IOQ *oq, IOQ *iq, int baud) 
{ 
	Duartport *dp = &duartport[port]; 
1992/0520    
	Port *p = &duartport[port]; 
1991/0727    
	IOQ *zq; 
1991/0607    
 
	dp->nostream = 1; 
1992/0520    
	p->nostream = 1; 
1991/0607    
	if(oq){ 
		dp->oq = oq; 
		dp->oq->puts = duartputs; 
		dp->oq->ptr = dp; 
1992/0520    
		p->oq = oq; 
		p->oq->puts = duartputs; 
		p->oq->ptr = p; 
1991/0607    
	} 
	if(iq){ 
		dp->iq = iq; 
		dp->iq->ptr = dp; 
1992/0520    
		p->iq = iq; 
		p->iq->ptr = p; 
1991/0727    
 
		/* 
		 *  Stupid HACK to undo a stupid hack 
1992/0519/sys/src/9/power/devduart.c:492,4991992/0520/sys/src/9/power/devduart.c:510,517
1991/0727    
		if(iq == zq) 
			kbdq.putc = kbdcr2nl; 
1991/0607    
	} 
	duartenable(dp); 
	duartbaud(dp, baud); 
1992/0520    
	duartenable(p); 
	duartbaud(p, baud); 
1991/0607    
} 
 
static int	duartputc(IOQ *, int); 
1992/0519/sys/src/9/power/devduart.c:513,5791992/0520/sys/src/9/power/devduart.c:531,605
1991/0607    
static int 
1992/0519    
opdone(void *x) 
1991/0607    
{ 
1992/0519    
	Duartport *dp = x; 
1992/0520    
	Port *p = x; 
1991/0607    
 
1992/0519    
	return dp->op == Dnone; 
1992/0520    
	return p->op == Dnone; 
1991/0607    
} 
 
static void 
duartstopen(Queue *q, Stream *s) 
{ 
	Duartport *dp; 
1992/0520    
	Port *p; 
1991/0607    
	char name[NAMELEN]; 
 
	dp = &duartport[s->id]; 
1992/0520    
	p = &duartport[s->id]; 
1991/0607    
 
	qlock(dp); 
	dp->wq = WR(q); 
	WR(q)->ptr = dp; 
	RD(q)->ptr = dp; 
	qunlock(dp); 
1992/0520    
	qlock(p); 
	p->wq = WR(q); 
	WR(q)->ptr = p; 
	RD(q)->ptr = p; 
	qunlock(p); 
1991/0607    
 
	if(dp->kstarted == 0){ 
		dp->kstarted = 1; 
		sprint(name, "duart%d", s->id); 
		kproc(name, duartkproc, dp); 
1992/0520    
	if(p->kstarted == 0){ 
		p->kstarted = 1; 
		sprint(name, "duart%d", s->id+1); 
		kproc(name, duartkproc, p); 
1991/0607    
	} 
1992/0519    
 
	/* enable the port */ 
	dp->op = Dena; 
	sleep(&dp->opr, opdone, dp); 
1992/0520    
	qlock(p); 
	p->op = Dena; 
	sleep(&p->opr, opdone, p); 
	qunlock(p); 
1991/0607    
} 
 
static void 
duartstclose(Queue *q) 
{ 
	Duartport *dp = q->ptr; 
1992/0520    
	Port *p = q->ptr; 
1991/0607    
 
	qlock(dp); 
	dp->wq = 0; 
	dp->iq->putc = 0; 
1992/0520    
	qlock(p); 
	p->wq = 0; 
	p->iq->putc = 0; 
1991/0607    
	WR(q)->ptr = 0; 
	RD(q)->ptr = 0; 
	qunlock(dp); 
1992/0520    
	qunlock(p); 
1991/0607    
} 
 
static void 
duartoput(Queue *q, Block *bp) 
{ 
	Duartport *dp = q->ptr; 
1992/0520    
	Port *p = q->ptr; 
1991/0607    
	IOQ *cq; 
	int n, m; 
 
	if(dp == 0){ 
1992/0520    
	if(p == 0){ 
1991/0607    
		freeb(bp); 
		return; 
	} 
	cq = dp->oq; 
1992/0520    
	cq = p->oq; 
1991/0607    
	if(waserror()){ 
		freeb(bp); 
		nexterror(); 
	} 
	if(bp->type == M_CTL){ 
		qlock(dp); 
1992/0520    
		if(waserror()){ 
			qunlock(p); 
			qunlock(p->d); 
			nexterror(); 
		} 
		qlock(p); 
		qlock(p->d); 
1991/0607    
		while (cangetc(cq))	/* let output drain */ 
			sleep(&cq->r, cangetc, cq); 
		n = strtoul((char *)(bp->rptr+1), 0, 0); 
1992/0519/sys/src/9/power/devduart.c:580,6041992/0520/sys/src/9/power/devduart.c:606,633
1991/0607    
		switch(*bp->rptr){ 
		case 'B': 
		case 'b': 
			dp->val = n; 
			dp->op = Dbaud; 
			sleep(&dp->opr, opdone, dp); 
1992/0520    
			p->val = n; 
			p->op = Dbaud; 
			sleep(&p->opr, opdone, p); 
1991/0607    
			break; 
		case 'D': 
		case 'd': 
			dp->val = n; 
			dp->op = Ddtr; 
			sleep(&dp->opr, opdone, dp); 
1992/0520    
			p->val = n; 
			p->op = Ddtr; 
			sleep(&p->opr, opdone, p); 
1991/0607    
			break; 
		case 'K': 
		case 'k': 
			dp->val = 1; 
			dp->op = Dbreak; 
			sleep(&dp->opr, opdone, dp); 
			tsleep(&dp->opr, return0, 0, n); 
			dp->val = 0; 
			dp->op = Dbreak; 
			sleep(&dp->opr, opdone, dp); 
1992/0520    
			p->val = 1; 
			p->op = Dbreak; 
			if(!waserror()){ 
				sleep(&p->opr, opdone, p); 
				tsleep(&p->opr, return0, 0, n); 
				poperror(); 
			} 
			p->val = 0; 
			p->op = Dbreak; 
			sleep(&p->opr, opdone, p); 
1991/0607    
			break; 
		case 'R': 
		case 'r': 
1992/0519/sys/src/9/power/devduart.c:605,6111992/0520/sys/src/9/power/devduart.c:634,642
1991/0607    
			/* can't control? */ 
			break; 
		} 
		qunlock(dp); 
1992/0520    
		qunlock(p->d); 
		qunlock(p); 
		poperror(); 
1991/0607    
	}else while((m = BLEN(bp)) > 0){ 
		while ((n = canputc(cq)) == 0){ 
			kprint(" duartoput: sleeping\n"); 
1992/0519/sys/src/9/power/devduart.c:626,6331992/0520/sys/src/9/power/devduart.c:657,664
1991/0607    
static void 
duartkproc(void *a) 
{ 
	Duartport *dp = a; 
	IOQ *cq = dp->iq; 
1992/0520    
	Port *p = a; 
	IOQ *cq = p->iq; 
1991/0607    
	Block *bp; 
	int n; 
 
1992/0519/sys/src/9/power/devduart.c:634,6491992/0520/sys/src/9/power/devduart.c:665,680
1991/0607    
loop: 
	while ((n = cangetc(cq)) == 0) 
		sleep(&cq->r, cangetc, cq); 
	qlock(dp); 
	if(dp->wq == 0){ 
1992/0520    
	qlock(p); 
	if(p->wq == 0){ 
1991/0607    
		cq->out = cq->in; 
	}else{ 
		bp = allocb(n); 
		bp->flags |= S_DELIM; 
		bp->wptr += gets(cq, bp->wptr, n); 
		PUTNEXT(RD(dp->wq), bp); 
1992/0520    
		PUTNEXT(RD(p->wq), bp); 
1991/0607    
	} 
	qunlock(dp); 
1992/0520    
	qunlock(p); 
1991/0607    
	goto loop; 
} 
 
1992/0519/sys/src/9/power/devduart.c:656,6621992/0520/sys/src/9/power/devduart.c:687,693
1991/0607    
void 
duartreset(void) 
{ 
	Duartport *dp; 
1992/0520    
	Port *p; 
1991/0607    
	int i; 
 
	/* 
1992/0519/sys/src/9/power/devduart.c:665,6721992/0520/sys/src/9/power/devduart.c:696,703
1991/0607    
	nduartport = 2*conf.nmach; 
	duartdir = ialloc(nduartport*2*sizeof(Dirtab), 0); 
	for(i = 0; i < nduartport; i++){ 
1991/1115    
		sprint(duartdir[2*i].name, "eia%d", i); 
		sprint(duartdir[2*i+1].name, "eia%dctl", i); 
1992/0520    
		sprint(duartdir[2*i].name, "eia%d", i+1); 
		sprint(duartdir[2*i+1].name, "eia%dctl", i+1); 
1992/0519    
		duartdir[2*i].length = 0; 
		duartdir[2*i+1].length = 0; 
		duartdir[2*i].perm = 0666; 
1992/0519/sys/src/9/power/devduart.c:678,6951992/0520/sys/src/9/power/devduart.c:709,726
1991/0607    
	/* 
	 *  allocate queues for any stream interfaces 
	 */ 
	for(dp = duartport; dp < &duartport[nduartport]; dp++){ 
		if(dp->nostream) 
1992/0520    
	for(p = duartport; p < &duartport[nduartport]; p++){ 
		if(p->nostream) 
1991/0607    
			continue; 
 
		dp->iq = ialloc(sizeof(IOQ), 0); 
		initq(dp->iq); 
		dp->iq->ptr = dp; 
1992/0520    
		p->iq = ialloc(sizeof(IOQ), 0); 
		initq(p->iq); 
		p->iq->ptr = p; 
1991/0607    
 
		dp->oq = ialloc(sizeof(IOQ), 0); 
		initq(dp->oq); 
		dp->oq->ptr = dp; 
		dp->oq->puts = duartputs; 
1992/0520    
		p->oq = ialloc(sizeof(IOQ), 0); 
		initq(p->oq); 
		p->oq->ptr = p; 
		p->oq->puts = duartputs; 
1991/0607    
	} 
} 
 
1992/0519/sys/src/9/power/devduart.c:712,7251992/0520/sys/src/9/power/devduart.c:743,756
1991/0607    
} 
 
void 
duartstat(Chan *c, char *dp) 
1992/0520    
duartstat(Chan *c, char *p) 
1991/0607    
{ 
	switch(STREAMTYPE(c->qid.path)){ 
	case Sdataqid: 
1992/0519    
		streamstat(c, dp, duartdir[2*STREAMID(c->qid.path)].name); 
1992/0520    
		streamstat(c, p, duartdir[2*STREAMID(c->qid.path)].name); 
1991/0607    
		break; 
	default: 
		devstat(c, dp, duartdir, 2*nduartport, devgen); 
1992/0520    
		devstat(c, p, duartdir, 2*nduartport, devgen); 
1991/0607    
		break; 
	} 
} 
1992/0519/sys/src/9/power/devduart.c:727,7451992/0520/sys/src/9/power/devduart.c:758,776
1991/0607    
Chan* 
duartopen(Chan *c, int omode) 
{ 
	Duartport *dp; 
1992/0520    
	Port *p; 
1991/0607    
 
	switch(STREAMTYPE(c->qid.path)){ 
	case Sdataqid: 
	case Sctlqid: 
		dp = &duartport[STREAMID(c->qid.path)]; 
1992/0520    
		p = &duartport[STREAMID(c->qid.path)]; 
1991/0607    
		break; 
	default: 
		dp = 0; 
1992/0520    
		p = 0; 
1991/0607    
		break; 
	} 
 
	if(dp && dp->nostream) 
1992/0520    
	if(p && p->nostream) 
1992/0114    
		error(Einuse); 
1991/0607    
 
	if((c->qid.path & CHDIR) == 0) 
1992/0519/sys/src/9/power/devduart.c:764,7701992/0520/sys/src/9/power/devduart.c:795,801
1991/0607    
long 
duartread(Chan *c, void *buf, long n, ulong offset) 
{ 
	Duartport *dp; 
1992/0520    
	Port *p; 
1991/0607    
 
	if(c->qid.path&CHDIR) 
		return devdirread(c, buf, n, duartdir, 2*nduartport, devgen); 
1992/0519/sys/src/9/power/devduart.c:775,7861992/0520/sys/src/9/power/devduart.c:806,817
1991/0607    
	case Sctlqid: 
		if(offset) 
			return 0; 
		dp = &duartport[STREAMID(c->qid.path)]; 
		qlock(dp); 
		dp->op = Dstate; 
		sleep(&dp->opr, opdone, dp); 
		*(uchar *)buf = dp->val; 
		qunlock(dp); 
1992/0520    
		p = &duartport[STREAMID(c->qid.path)]; 
		qlock(p); 
		p->op = Dstate; 
		sleep(&p->opr, opdone, p); 
		*(uchar *)buf = p->val; 
		qunlock(p); 
1991/0607    
		return 1; 
	} 
 
1992/0519/sys/src/9/power/devduart.c:802,8081992/0520/sys/src/9/power/devduart.c:833,839
1991/0607    
} 
 
void 
duartwstat(Chan *c, char *dp) 
1992/0520    
duartwstat(Chan *c, char *p) 
1991/0607    
{ 
1991/1214    
	USED(c); 
1992/0114    
	error(Eperm); 


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