Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/gnot/devcons.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname gnot/devcons.c 1990/03091
## diff -e /dev/null /n/bootesdump/1990/03091/sys/src/9/68020/devcons.c
0a
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"
#include	"errno.h"

#include	"devtab.h"

static struct
{
	Lock;
	int	printing;
	int	c;
}printq;

typedef struct IOQ	IOQ;

#define	NQ	4096
struct IOQ{
	union{
		Lock;
		QLock;
	};
	uchar	buf[NQ];
	uchar	*in;
	uchar	*out;
	int	state;
	Rendez	r;
};

IOQ	kbdq;		/* qlock to getc; interrupt putc's */
IOQ	lineq;		/* lock to getc; interrupt putc's */

void
printinit(void)
{

	lock(&printq);		/* allocate lock */
	unlock(&printq);

	kbdq.in = kbdq.buf;
	kbdq.out = kbdq.buf;
	lineq.in = lineq.buf;
	lineq.out = lineq.buf;
	qlock(&kbdq);		/* allocate qlock */
	qunlock(&kbdq);
	lock(&lineq);		/* allocate lock */
	unlock(&lineq);

	screeninit();
}

/*
 * Print a string on the console.
 */
void
putstrn(char *str, long n)
{
	int s;

	s = splhi();
	lock(&printq);
	printq.printing = 1;
	while(--n >= 0)
		screenputc(*str++);
	printq.printing = 0;
	unlock(&printq);
	splx(s);
}

int
cangetc(IOQ *q)
{
	return q->in != q->out;
}

int
isbrkc(IOQ *q)
{
	uchar *p;

	for(p=q->out; p!=q->in; ){
		if(*p==0x04 || *p=='\n')
			return 1;
		p++;
		if(p >= q->buf+sizeof(q->buf))
			p = q->buf;
	}
	return 0;
}

int
getc(IOQ *q)
{
	int c;

	if(q->in == q->out)
		return -1;
	c = *q->out++;
	if(q->out == q->buf+sizeof(q->buf))
		q->out = q->buf;
	return c;
}

int
sprint(char *s, char *fmt, ...)
{
	return donprint(s, s+PRINTSIZE, fmt, (&fmt+1)) - s;
}

int
print(char *fmt, ...)
{
	char buf[PRINTSIZE];
	int n;

	n = donprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
	putstrn(buf, n);
	return n;
}

void
panic(char *fmt, ...)
{
	char buf[PRINTSIZE];
	int n;

	strcpy(buf, "panic: ");
	n = donprint(buf+7, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
	buf[n] = '\n';
	putstrn(buf, n+1);
	exit();
}
int
pprint(char *fmt, ...)
{
	char buf[2*PRINTSIZE];
	Chan *c;
	int n;

	c = u->fd[2];
	if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR))
		return;
	n = sprint(buf, "%s %d: ", u->p->text, u->p->pid);
	n = donprint(buf+n, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
	qlock(c);
	if(waserror()){
		qunlock(c);
		return;
	}
	(*devtab[c->type].write)(c, buf, n);
	c->offset += n;
	qunlock(c);
	return n;
}

void
prflush(void)
{
	while(printq.printing)
		delay(100);
}

void
echo(int c)
{
	char ch;

	/*
	 * ^t hack BUG
	 */
	if(c == 0x14)
		DEBUG();
	if(c == 0x15)
		putstrn("^U\n", 3);
	else{
		ch = c;
		putstrn(&ch, 1);
	}
}

/*
 * Put character into read queue at interrupt time.
 * Always called splhi from proc 0.
 */
void
kbdchar(int c)
{
	if(c == '\r')
		c = '\n';
	echo(c);
	*kbdq.in++ = c;
	if(kbdq.in == kbdq.buf+sizeof(kbdq.buf))
		kbdq.in = kbdq.buf;
	if(c=='\n' || c==0x04)
		wakeup(&kbdq.r);
}

int
consactive(void)
{
	return printq.printing;
}

/*
 * I/O interface
 */
enum{
	Qdir,
	Qcons,
	Qcputime,
	Qnull,
	Qpgrpid,
	Qpid,
	Qppid,
	Qtime,
	Quser,
};

Dirtab consdir[]={
	"cons",		Qcons,		0,	0600,
	"cputime",	Qcputime,	72,	0600,
	"null",		Qnull,		0,	0600,
	"pgrpid",	Qpgrpid,	12,	0600,
	"pid",		Qpid,		12,	0600,
	"ppid",		Qppid,		12,	0600,
	"time",		Qtime,		12,	0600,
	"user",		Quser,		0,	0600,
};

#define	NCONS	(sizeof consdir/sizeof(Dirtab))

ulong	boottime;		/* seconds since epoch at boot */

long
seconds(void)
{
	return boottime + MACHP(0)->ticks*MS2HZ/1000;
}

int
readnum(ulong off, char *buf, ulong n, ulong val, int size)
{
	char tmp[64];
	Op op = (Op){ tmp, tmp+sizeof(tmp), &val, size-1, 0, FUNSIGN|FLONG };

	numbconv(&op, 10);
	tmp[size-1] = ' ';
	off %= size;
	if(off+n > size)
		n = size-off;
	memcpy(buf, tmp+off, n);
	return n;
}

int
readstr(ulong off, char *buf, ulong n, char *str)
{
	int size;

	size = strlen(str);
	off %= size;
	if(off+n > size)
		n = size-off;
	memcpy(buf, str+off, n);
	return n;
}

void
consreset(void)
{
}

void
consinit(void)
{
}

Chan*
consattach(char *spec)
{
	return devattach('c', spec);
}

Chan*
consclone(Chan *c, Chan *nc)
{
	return devclone(c, nc);
}

int
conswalk(Chan *c, char *name)
{
	return devwalk(c, name, consdir, NCONS, devgen);
}

void
consstat(Chan *c, char *dp)
{
	devstat(c, dp, consdir, NCONS, devgen);
}

Chan*
consopen(Chan *c, int omode)
{
	if(c->qid==Quser && omode==(OWRITE|OTRUNC)){
		/* truncate? */
		if(strcmp(u->p->pgrp->user, "bootes") == 0)	/* BUG */
			u->p->pgrp->user[0] = 0;
		else
			error(0, Eperm);
	}
	return devopen(c, omode, consdir, NCONS, devgen);
}

void
conscreate(Chan *c, char *name, int omode, ulong perm)
{
	error(0, Eperm);
}

void
consclose(Chan *c)
{
}

long
consread(Chan *c, void *buf, long n)
{
	int ch, i, j, k;
	ulong l;
	uchar *out;
	char *cbuf = buf;
	char *user;
	int userlen;
	char tmp[6*NUMSIZE];

	if(n <= 0)
		return n;
	switch(c->qid&~CHDIR){
	case Qdir:
		return devdirread(c, buf, n, consdir, NCONS, devgen);

	case Qcons:
		qlock(&kbdq);
		while(!cangetc(&lineq)){
			sleep(&kbdq.r, (int(*)(void*))isbrkc, &kbdq);
			do{
				ch = getc(&kbdq);
				switch(ch){
				case '\b':
					if(lineq.in != lineq.out){
						if(lineq.in == lineq.buf)
							lineq.in = lineq.buf+sizeof(lineq.buf);
						lineq.in--;
					}
					break;
				case 0x15:
					lineq.in = lineq.out;
					break;
				default:
					*lineq.in++ = ch;
					if(lineq.in == lineq.buf+sizeof(lineq.buf))
					lineq.in = lineq.buf;
				}
			}while(ch!='\n' && ch!=0x04);
		}
		i = 0;
		while(n>0){
			ch = getc(&lineq);
			if(ch == 0x04 || ch == -1)
				break;
			i++;
			*cbuf++ = ch;
			--n;
		}
		qunlock(&kbdq);
		return i;

	case Qcputime:
		k = c->offset % sizeof tmp;
		if(k+n > sizeof tmp)
			n = sizeof tmp - k;
		/* easiest to format in a separate buffer and copy out */
		for(i=0; i<6 && NUMSIZE*i<k+n; i++){
			l = u->p->time[i];
			if(i == TReal)
				l = MACHP(0)->ticks - l;
			l *= MS2HZ;
			readnum(0, tmp+NUMSIZE*i, NUMSIZE, l, NUMSIZE);
		}
		memcpy(buf, tmp+k, n);
		return n;

	case Qpgrpid:
		return readnum(c->offset, buf, n, u->p->pgrp->pgrpid, NUMSIZE);

	case Qpid:
		return readnum(c->offset, buf, n, u->p->pid, NUMSIZE);

	case Qppid:
		return readnum(c->offset, buf, n, u->p->parentpid, NUMSIZE);

	case Qtime:
		return readnum(c->offset, buf, n, boottime+MACHP(0)->ticks/(1000/MS2HZ), 12);

	case Quser:
		return readstr(c->offset, buf, n, u->p->pgrp->user);

	case Qnull:
		return 0;

	default:
		panic("consread %lux\n", c->qid);
		return 0;
	}
}

long
conswrite(Chan *c, void *va, long n)
{
	char cbuf[64];
	char buf[256];
	long l, m;
	char *a = va;

	switch(c->qid){
	case Qcons:
		/*
		 * Damn. Can't page fault in putstrn, so copy the data locally.
		 */
		l = n;
		while(l > 0){
			m = l;
			if(m > sizeof buf)
				m = sizeof buf;
			memcpy(buf, a, m);
			putstrn(a, m);
			a += m;
			l -= m;
		}
		break;

	case Qtime:
		if(n<=0 || boottime!=0)	/* only one write please */
			return 0;
		if(n >= sizeof cbuf)
			n = sizeof cbuf - 1;
		memcpy(cbuf, a, n);
		cbuf[n-1] = 0;
		boottime = strtoul(a, 0, 0);
		break;

	case Quser:
		if(u->p->pgrp->user[0])		/* trying to overwrite /dev/user */
			error(0, Eperm);
		if(c->offset >= NAMELEN-1)
			return 0;
		if(c->offset+n >= NAMELEN-1)
			n = NAMELEN-1 - c->offset;
		memcpy(u->p->pgrp->user+c->offset, a, n);
		u->p->pgrp->user[c->offset+n] = 0;
		break;

	case Qcputime:
	case Qpgrpid:
	case Qpid:
	case Qppid:
		error(0, Eperm);

	case Qnull:
		break;
	default:
		error(0, Egreg);
	}
	return n;
}

void
consremove(Chan *c)
{
	error(0, Eperm);
}

void
conswstat(Chan *c, char *dp)
{
	error(0, Eperm);
}

void
conserrstr(Error *e, char *buf)
{
	rooterrstr(e, buf);
}

void
consuserstr(Error *e, char *buf)
{
	strcpy(buf, u->p->pgrp->user);
}

typedef struct Incon{
	unsigned char	cdata;		unsigned char u0;
	unsigned char	cstatus;	unsigned char u1;
	unsigned char	creset;		unsigned char u2;
	unsigned char	csend;		unsigned char u3;
	unsigned short	data_cntl;	/* data is high byte, cntl is low byte */
	unsigned char	status;		unsigned char u5;
	unsigned char	reset;		unsigned char u6;
	unsigned char	send;		unsigned char u7;
}Incon;

inconintr(Ureg *ur)
{
	int x;
	x = ((Incon*)0x40700000)->status;
}
.
## diffname gnot/devcons.c 1990/0312
## diff -e /n/bootesdump/1990/03091/sys/src/9/68020/devcons.c /n/bootesdump/1990/0312/sys/src/9/68020/devcons.c
520a
*/
.
515a
/*
.
383c
		k = c->offset;
		if(k >= sizeof tmp)
			return 0;
.
264c
	if(off >= size)
		return 0;
.
251c
	if(off >= size)
		return 0;
.
## diffname gnot/devcons.c 1990/0321
## diff -e /n/bootesdump/1990/0312/sys/src/9/68020/devcons.c /n/bootesdump/1990/0321/sys/src/9/68020/devcons.c
198a
}

void
kbdrepeat(int rep)
{
	if(rep)
		kbdq.repeat = 1;
	else
		kbdq.repeat = 0;
}

void
kbdclock(void)
{
	if(kbdq.repeat==2 && (++kbdq.count&1))
		kbdchar(kbdq.c);
.
190a
	if(kbdq.repeat == 1){
		kbdq.c = c;
		kbdq.count = 0;
		kbdq.repeat = 2;
	}
.
187a

.
155a
	poperror();
.
151c
		return 0;
.
145c
		return 0;
.
35a
struct{
	IOQ;		/* qlock to getc; interrupt putc's */
	int	c;
	int	repeat;
	int	count;
}kbdq;

.
33d
## diffname gnot/devcons.c 1990/0515
## diff -e /n/bootesdump/1990/0321/sys/src/9/68020/devcons.c /n/bootesdump/1990/0515/sys/src/9/68020/devcons.c
463a
	case Qrcons:
.
404c
			if(ch==-1 || (raw.ref==0 && ch==0x04))
.
402c
		while(n > 0){
.
399c
				unlock(&lineq);
			}while(raw.ref==0 && ch!='\n' && ch!=0x04);
.
397c
						lineq.in = lineq.buf;
.
393a
				Default:
.
382a
				if(raw.ref){
					unlock(&lineq);
					goto Default;
				}
.
381a
				lock(&lineq);
.
376a
	case Qrcons:
.
357a
	if(c->qid == Qrcons)
		decref(&raw);
.
345a
	if(c->qid == Qrcons)
		if(incref(&raw) == 0){
			lock(&lineq);
			while((ch=getc(&kbdq)) != -1){
				*lineq.in++ = ch;
				if(lineq.in == lineq.buf+sizeof(lineq.buf))
					lineq.in = lineq.buf;
			}
			unlock(&lineq);
		}
.
338a
	int ch;

.
257a
	"rcons",	Qrcons,		0,	0600,
.
246a
	Qrcons,
.
210c
	if(raw.ref || c=='\n' || c==0x04)
.
182a
	if(raw.ref)
		return;
.
90a
		if(raw.ref)
			return 1;
.
41a
Ref	raw;		/* whether kbd i/o is raw (rcons is open) */

.
33c
IOQ	lineq;
.
## diffname gnot/devcons.c 1990/06111
## diff -e /n/bootesdump/1990/0515/sys/src/9/68020/devcons.c /n/bootesdump/1990/06111/sys/src/9/68020/devcons.c
470c
		return readnum(c->offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12);
.
454c
			l = TK2MS(l);
.
277c
	return boottime + TK2SEC(MACHP(0)->ticks);
.
157c
	n = doprint(buf+n, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
.
141c
	n = doprint(buf+7, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
.
129c
	n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
.
120c
	return doprint(s, s+PRINTSIZE, fmt, (&fmt+1)) - s;
.
## diffname gnot/devcons.c 1990/0617
## diff -e /n/bootesdump/1990/06111/sys/src/9/68020/devcons.c /n/bootesdump/1990/0617/sys/src/9/68020/devcons.c
401a
		if(waserror()){
			qunlock(&kbdq);
			nexterror();
		}
.
190a
	if(c == 0x16)
		dumpqueues();
.
## diffname gnot/devcons.c 1990/0619
## diff -e /n/bootesdump/1990/0617/sys/src/9/68020/devcons.c /n/bootesdump/1990/0619/sys/src/9/68020/devcons.c
380c
	if(c->qid==Qrcons && (c->flag&COPEN))
.
## diffname gnot/devcons.c 1990/0629
## diff -e /n/bootesdump/1990/0619/sys/src/9/68020/devcons.c /n/bootesdump/1990/0629/sys/src/9/68020/devcons.c
574,592d
515a
	case Qrs232:
		qlock(&rs232oq);
		l = n;
		while(--l >= 0)
			putc(&rs232oq, *a++);
		splhi();
		if(rs232oq.state == 0){
			rs232oq.state = 1;
			duartstartrs232o();
		}
		spllo();
		qunlock(&rs232oq);
		break;

.
448a
	case Qrs232:
		qlock(&rs232iq);
		if(waserror()){
			qunlock(&rs232iq);
			nexterror();
		}
		while(!cangetc(&rs232iq))
			sleep(&rs232iq.r, (int(*)(void*))cangetc, &rs232iq);
		for(i=0; i<n; i++){
			if((ch=getc(&rs232iq)) == -1)
				break;
			*cbuf++ = ch;
		}
		qunlock(&rs232iq);
		return i;

.
359c
		if(incref(&raw) == 1){
.
267a
	"rs232",	Qrs232,		0,	0600,
.
255a
	Qrs232,
.
238a
getrs232o(void)
{
	int c;

	c = getc(&rs232oq);
	if(c == -1)
		rs232oq.state = 0;
	return c;
}

int
.
237a
void
rs232ichar(int c)
{
	*rs232iq.in++ = c;
	if(rs232iq.in == rs232iq.buf+sizeof(rs232iq.buf))
		rs232iq.in = rs232iq.buf;
	wakeup(&rs232iq.r);
}

.
191,192d
186a
	if(c == 0x16){
		incontoggle();
		urpdump();
		dumpqueues();
	}
.
116a
void
putc(IOQ *q, int c)
{
	*q->in++ = c;
	if(q->in == q->buf+sizeof(q->buf))
		q->in = q->buf;
}

.
58a
	lock(&rs232iq);		/* allocate lock */
	unlock(&rs232iq);
	lock(&rs232oq);		/* allocate lock */
	unlock(&rs232oq);
.
52a
	rs232iq.in = rs232iq.buf;
	rs232iq.out = rs232iq.buf;
	rs232oq.in = rs232oq.buf;
	rs232oq.out = rs232oq.buf;
.
33a
IOQ	rs232iq;
IOQ	rs232oq;
.
20c
#define	NQ	1024
.
## diffname gnot/devcons.c 1990/0702
## diff -e /n/bootesdump/1990/0629/sys/src/9/68020/devcons.c /n/bootesdump/1990/0702/sys/src/9/68020/devcons.c
206,207d
## diffname gnot/devcons.c 1990/0707
## diff -e /n/bootesdump/1990/0702/sys/src/9/68020/devcons.c /n/bootesdump/1990/0707/sys/src/9/68020/devcons.c
583d
576,581c
		while(--l >= 0) {
			while (putc(&rs232oq, *a) < 0)
				sleep(&rs232oq.r, (int(*)(void*))canputc, &rs232oq);
			a++;
			if(rs232oq.state == 0){
				splhi();
				if(rs232oq.state == 0){
					rs232oq.state = 1;
					duartstartrs232o();
				}
				spllo();
			}
.
540a
	case Qklog:
		qlock(&klogq);
		if(waserror()){
			qunlock(&klogq);
			nexterror();
		}
		while(!cangetc(&klogq))
			sleep(&klogq.r, (int(*)(void*))cangetc, &klogq);
		for(i=0; i<n; i++){
			if((ch=getc(&klogq)) == -1)
				break;
			*cbuf++ = ch;
		}
		qunlock(&klogq);
		return i;

.
440c
		return devdirread(c, buf, n, consdir, NCONS, consgen);
.
409c
	return devopen(c, omode, consdir, NCONS, consgen);
.
384c
	devstat(c, dp, consdir, NCONS, consgen);
.
378c
	return devwalk(c, name, consdir, NCONS, consgen);
.
314a
static int
consgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp)
{
	if(tab==0 || i>=ntab)
		return -1;
	tab += i;
	devdir(c, tab->qid, tab->name, tab->length, tab->perm, dp);
	switch(dp->qid){
	case Qrs232:
		dp->length = cangetc(&rs232iq); break;
	}
	return 1;
}

.
310a
	"klog",		Qklog,		0,	0400,
.
297a
	Qklog,
.
273a
	wakeup(&rs232oq.r);
.
260,262c
	putc(&rs232iq, c);
.
207c
	if(c == 0x18)
		mntdump();
.
205c
	if(c == 0x16)
.
151a
int
kprint(char *fmt, ...)
{
	char buf[PRINTSIZE];
	int n;

	n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
	putstrk(buf, n);
	return n;
}

.
134a
void
putstrk(char *str, long n)
{
	int s;

	s = splhi();
	lock(&klogq.put);
	while(--n >= 0){
		*klogq.in++ = *str++;
		if(klogq.in == klogq.buf+sizeof(klogq.buf))
			klogq.in = klogq.buf;
	}
	unlock(&klogq.put);
	splx(s);
	wakeup(&klogq.r);
}

.
130,132c
	uchar *nextin;
	if(q->in >= &q->buf[sizeof(q->buf)-1])
		nextin = q->buf;
	else
		nextin = q->in+1;
	if(nextin == q->out)
		return -1;
	*q->in = c;
	q->in = nextin;
	return 0;
.
127c
int
.
97a
canputc(IOQ *q)
{
	return sizeof(q->buf)-cangetc(q)-1;
}

int
.
94c
	int n = q->in - q->out;
	if (n < 0)
		n += sizeof(q->buf);
	return n;
.
68a
	lock(&klogq);		/* allocate lock */
	unlock(&klogq);
	lock(&klogq.put);		/* allocate lock */
	unlock(&klogq.put);
.
58a
	klogq.in = klogq.buf;
	klogq.out = klogq.buf;
.
37a
	IOQ;
	Lock	put;
}klogq;

struct{
.
## diffname gnot/devcons.c 1990/0808
## diff -e /n/bootesdump/1990/0707/sys/src/9/68020/devcons.c /n/bootesdump/1990/0808/sys/src/9/68020/devcons.c
675a
		qunlock(&rs232oq);
		break;

	case Qrs232ctl:
		qlock(&rs232oq);
		if(waserror()){
			qunlock(&rs232oq);
			nexterror();
		}
		if(n>2 && n<sizeof buf && *a=='B'){
			strncpy(buf, a, n);
			buf[n] = 0;
			duartbaud(strtoul(buf+1, 0, 0));
		}else
			error(0, Ebadarg);
.
576a
	case Qrs232ctl:
		return 0;

.
364a
	"rs232ctl",	Qrs232ctl,	0,	0600,
.
350a
	Qrs232ctl,
.
## diffname gnot/devcons.c 1990/08101
## diff -e /n/bootesdump/1990/0808/sys/src/9/68020/devcons.c /n/bootesdump/1990/08101/sys/src/9/68020/devcons.c
680a
		poperror();
.
670c
				sleep(&rs232oq.r, canputc, &rs232oq);
.
666a
		if(waserror()){
			qunlock(&rs232oq);
			nexterror();
		}
.
629a
		poperror();
.
624c
			sleep(&klogq.r, cangetc, &klogq);
.
610a
	case Qmsec:
		return readnum(c->offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE);
	case Qclock:
		k = c->offset;
		if(k >= 2*NUMSIZE)
			return 0;
		if(k+n > 2*NUMSIZE)
			n = 2*NUMSIZE - k;
		readnum(0, tmp, NUMSIZE, MACHP(0)->ticks, NUMSIZE);
		readnum(0, tmp+NUMSIZE, NUMSIZE, HZ, NUMSIZE);
		memcpy(buf, tmp+k, n);
		return n;

.
609c
		return readnum(c->offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), NUMSIZE);
.
575a
		poperror();
.
570c
			sleep(&rs232iq.r, cangetc, &rs232iq);
.
523c
			sleep(&kbdq.r, isbrkc, &kbdq);
.
358,369c
	"cons",		Qcons,		0,		0600,
	"cputime",	Qcputime,	6*NUMSIZE,	0600,
	"null",		Qnull,		0,		0600,
	"pgrpid",	Qpgrpid,	NUMSIZE,	0600,
	"pid",		Qpid,		NUMSIZE,	0600,
	"ppid",		Qppid,		NUMSIZE,	0600,
	"rcons",	Qrcons,		0,		0600,
	"rs232",	Qrs232,		0,		0600,
	"rs232ctl",	Qrs232ctl,	0,		0600,
	"time",		Qtime,		NUMSIZE,	0600,
	"user",		Quser,		0,		0600,
	"klog",		Qklog,		0,		0400,
	"msec",		Qmsec,		NUMSIZE,	0400,
	"clock",	Qclock,		2*NUMSIZE,	0400,
.
354a
	Qmsec,
	Qclock,
.
119a
	IOQ *q = (IOQ *)arg;
.
118c
isbrkc(void *arg)
.
113a
	IOQ *q = (IOQ *)arg;
.
112c
canputc(void *arg)
.
104a
	IOQ *q = (IOQ *)arg;
.
103c
cangetc(void *arg)
.
20c
#define	NQ	2048
.
## diffname gnot/devcons.c 1990/0825
## diff -e /n/bootesdump/1990/08101/sys/src/9/68020/devcons.c /n/bootesdump/1990/0825/sys/src/9/68020/devcons.c
290,291d
## diffname gnot/devcons.c 1990/0830
## diff -e /n/bootesdump/1990/0825/sys/src/9/68020/devcons.c /n/bootesdump/1990/0830/sys/src/9/68020/devcons.c
720a
		strncpy(buf, a, n);
		buf[n] = 0;
		l = strtoul(buf+1, 0, 0);
		switch(buf[0]){
		case 'B':
			duartbaud(l); break;
		case 'D':
			duartdtr(l); break;
		case 'K':
			duartbreak(l); break;
		default:
			error(0, Ebadarg);
		}
.
715,719c
		if(n<=2 || n>=sizeof buf)
.
586c
		if(c->offset)
			return 0;
		*(char *)buf = duartinputport();
		return 1;
.
## diffname gnot/devcons.c 1990/0831
## diff -e /n/bootesdump/1990/0830/sys/src/9/68020/devcons.c /n/bootesdump/1990/0831/sys/src/9/68020/devcons.c
792a
}

/*
 *  rs232 stream routines
 */
static void
rs232output(Rs232 *r)
{
	int next;
	Queue *q;
	Block *bp;

	qlock(&r->outlock);
	q = r->wq;

	/*
 	 *  free emptied blocks
	 */
	for(; r->out.f != r->out.r; r->out.f = NEXT(r->out.f)){
		freeb(r->out.bp[r->out.f]);
		r->out.bp[r->out.f] = 0;
	}

	/*
	 *  stage new blocks
	 */
	bp = getq(q);
	for(next = NEXT(r->out.w); bp && next!=r->out.r; next = NEXT(next)){
		r->out.bp[r->out.w] = bp;
		bp = getq(q);
		r->out.w = next;
	}

	/*
	 *  start output
	 */
	if(r->txenabled == 0){
		r->txenabled = 1;
		duartstartrs232o();
	}
	qunlock(&r->outlock);
}

static void
rs232input(Rs232 *r)
{
	Queue *q;
	char c;
	Block *bp;

	q = RD(r->wq);
	bp = 0;
	while((c = getc(&r->in)) >= 0){
		if(bp == 0){
			bp->flags |= S_DELIM;
			bp = allocb(64);
		}
		*bp->wptr++ = c;
		if(bp->wptr == bp->lim){
			if(QFULL(q->next))
				freeb(bp);
			else
				PUTNEXT(q, bp);
			bp = 0;
		}
	}
	if(bp){
		if(QFULL(q->next))
			freeb(bp);
		else
			PUTNEXT(q, bp);
	}
}

static int
rs232stuff(void *arg)
{
	Rs232 *r;

	r = arg;
	return (r->in.in != r->in.out) || (r->out.r != r->out.w)
		|| (r->out.f != r->out.r);
}

static void
rs232kproc(void *a)
{
	Rs232 *r;

	r = a;
	for(;;){
		qlock(r);
		if(r->wq != 0){
			rs232output(r);
			rs232input(r);
		}
		qunlock(r);
		sleep(&r->r, rs232stuff, r);
	}
}

static void
rs232open(Queue *q, Stream *c)
{
	Rs232 *r;

	r = &rs232;

	RD(q)->ptr = r;
	WR(q)->ptr = r;
	r->wq = WR(q);

	if(r->kstarted == 0){
		r->in.in = r->in.out = r->in.buf;
		kproc("rs232", rs232kproc, r);
		r->kstarted = 1;
	}
}

static void
rs232close(Queue *q)
{
	Rs232 *r;

	r = q->ptr;
	qlock(r);
	r->wq = 0;
	qunlock(r);
}

static void
rs232oput(Queue *q, Block *bp)
{
	if(bp->rptr == bp->wptr)
		freeb(bp);
	else
		putq(q, bp);
	rs232output(q->ptr);
}

static void
rs232timer(Alarm *a)
{
	Rs232 *r;

	r = a->arg;
	cancel(a);
	r->a = 0;
	wakeup(&r->r);
}

void
rs232ichar(int c)
{
	Rs232 *r;

	r = &rs232;
	putc(&r->in, c);
	if(r->a == 0)
		alarm(125, rs232timer, r);
}

int
getrs232o(void)
{
	int c;
	Rs232 *r;
	Block *bp;

	r = &rs232;
	if(r->out.r == r->out.w){
		r->txenabled = 0;
		return -1;
	}
	bp = r->out.bp[r->out.r];
	c = *bp->rptr++;
	if(bp->rptr >= bp->wptr){
		r->out.r = NEXT(r->out.r);
		if(r->out.r==r->out.w || NEXT(r->out.r)==r->out.w)
			wakeup(&r->r);
	}
	return c;
.
733c
		qunlock(&rs232);
.
715c
			qunlock(&rs232);
.
713c
		qlock(&rs232);
.
689,709c
		n = streamwrite(c, va, n, 1);
.
569,583c
		return streamread(c, buf, n);
.
500a
	if(c->qid == Qrs232)
		streamclose(c);
.
486a
	if(c->qid == Qrs232)
		streamopen(c, &rs232info);
.
462c
	switch(c->qid){
	case Qrs232:
		streamstat(c, dp, "rs232");
		break;
	default:
		devstat(c, dp, consdir, NCONS, consgen);
		break;
	}
.
386,389d
357a
	Qrs232 = STREAMQID(1, Sdataqid),
.
351d
322,333d
314,320d
72,75d
60,63d
50a
/*
 *  rs232 stream module
 */
typedef struct Rs232	Rs232;
typedef struct IOBQ	IOBQ;

#define NBQ 4
struct IOBQ{
	Block	*bp[NBQ];
	int	w;
	int	r;
	int	f;
};
#define NEXT(x) ((x+1)%NBQ)

struct Rs232{
	QLock;
	QLock	outlock;
	IOQ	in;
	IOBQ	out;
	int	kstarted;	/* true if kproc started */
	Queue	*wq;
	Alarm	*a;		/* alarm for waking the rs232 kernel process */
	int	txenabled;
	Rendez	r;
};

Rs232 rs232;

static void	rs232output(Rs232*);
static void	rs232input(Rs232*);
static void	rs232timer(Alarm*);
static void	rs232kproc(void*);
static void	rs232open(Queue*, Stream*);
static void	rs232close(Queue*);
static void	rs232oput(Queue*, Block*);
Qinfo rs232info = { nullput, rs232oput, rs232open, rs232close, "rs232" };

.
34,35d
18,19d
10a
typedef struct IOQ	IOQ;

.
## diffname gnot/devcons.c 1990/0901
## diff -e /n/bootesdump/1990/0831/sys/src/9/68020/devcons.c /n/bootesdump/1990/0901/sys/src/9/68020/devcons.c
946c
		r->started = 0;
.
940c
	uchar c;
.
936a
/*
 *  called by output interrupt.  runs splhi
 */
.
932,934c
	if(putc(&r->in, c) < 0)
		screenputc('^');

	/*
	 *  pass upstream within 1/16 second
	 */
	if(r->a==0)
		r->a = alarm(64, rs232timer, r);
.
925a
/*
 *  called by input interrupt.  runs splhi
 */
.
830a
			bp->flags |= S_DELIM;
.
829d
822c
	int c;
.
814a
	spllo();
.
811,812c
	splhi();
	if(r->started == 0){
		r->started = 1;
.
809c
	 *  start output, the spl's sync with interrupt level
	 *  this wouldn't work on a multi-processor
.
804a
		if(bp == 0)
			break;
		r->out.bp[r->out.w] = bp;
.
801,803c
	for(next = NEXT(r->out.w); next!=r->out.r; next = NEXT(next)){
.
72c
	int	started;
.
55c
#define NBQ 6
.
## diffname gnot/devcons.c 1990/0905
## diff -e /n/bootesdump/1990/0901/sys/src/9/68020/devcons.c /n/bootesdump/1990/0905/sys/src/9/68020/devcons.c
804a
		if(bp->type == M_CTL){
			while(!rs232empty(r))
				sleep(&r->r, rs232empty, r);
			l = strtoul((char *)(bp->rptr+1), 0, 0);
			switch(*bp->rptr){
			case 'B':
				duartbaud(l); break;
			case 'D':
				duartdtr(l); break;
			case 'K':
				duartbreak(l); break;
			}
			freeb(bp);
			break;
		}
.
801c
	for(next = NEXT(r->out.w); next != r->out.r; next = NEXT(next)){
.
799a
	 *
	 *  if we run into a control block, wait till the queue
	 *  is empty before doing the control.
.
791,798d
785a
	long l;
.
779a
static int
rs232empty(void *a)
{
	Rs232 *r;

	r = a;
	return r->out.w == r->out.r;
}

.
778a
 *
 *  A kernel process, rs232kproc, stages blocks to be output and
 *  packages input bytes into stream blocks to send upstream.
 *  The process is awakened whenever the interrupt side is almost
 *  out of bytes to xmit or 1/16 second has elapsed since a byte
 *  was input.
.
694,717d
690a
	case Qrs232ctl:
.
500a
		break;
	}
.
499c
		break;
	case Qrs232:
	case Qrs232ctl:
.
482,489c
	switch(c->qid){
	case Quser:
		if(omode==(OWRITE|OTRUNC)){
			/* truncate? */
			if(strcmp(u->p->pgrp->user, "bootes") == 0)	/* BUG */
				u->p->pgrp->user[0] = 0;
			else
				error(0, Eperm);
		}
		break;
	case Qrcons:
.
365a
	Qrs232ctl = STREAMQID(1, Sctlqid),
.
360d
## diffname gnot/devcons.c 1990/0911
## diff -e /n/bootesdump/1990/0905/sys/src/9/68020/devcons.c /n/bootesdump/1990/0911/sys/src/9/68020/devcons.c
955,956c
	if(r->a==0){
		if(r->delay == 0)
			wakeup(&r->r);
		else
			r->a = alarm(r->delay, rs232timer, r);
	}
.
922c
	if(bp->rptr >= bp->wptr)
.
810c
			case 'k':
				duartbreak(l);
				break;
			case 'W':
			case 'w':
				if(l>=0 && l<1000)
					r->delay = l;
				break;
.
808c
			case 'd':
				duartdtr(l);
				break;
.
806c
			case 'b':
				duartbaud(l);
				break;
.
796c
	for(next = NEXT(r->out.w); next != r->out.f; next = NEXT(next)){
.
790a
	 *  free old blocks
	 */
	for(next = r->out.f; next != r->out.r; next = NEXT(next)){
		freeb(r->out.bp[next]);
		r->out.bp[next] = 0;
	}
	r->out.f = next;

	/*
.
293c
	if(c == 0x1A)
.
72a
	int	delay;		/* time between character input and waking kproc */
.
## diffname gnot/devcons.c 1990/0914
## diff -e /n/bootesdump/1990/0911/sys/src/9/68020/devcons.c /n/bootesdump/1990/0914/sys/src/9/68020/devcons.c
107c
	lock(&klogq.put);	/* allocate lock */
.
100a
	rs232.in.in = rs232.in.buf;
	rs232.in.out = rs232.in.buf;
.
## diffname gnot/devcons.c 1990/0918
## diff -e /n/bootesdump/1990/0914/sys/src/9/68020/devcons.c /n/bootesdump/1990/0918/sys/src/9/68020/devcons.c
292,297c
	if(ctrlt == 2){
		ctrlt = 0;
		switch(c){
		case 0x14:
			break;	/* pass it on */
		case 'p':
			DEBUG();
			return;
		case 'q':
			dumpqueues();
			return;
		case 'm':
			mntdump();
			return;
		}
	}else if(c == 0x14){
		ctrlt++;
		return;
	}
	ctrlt = 0;
.
287a
	static int ctrlt;
.
## diffname gnot/devcons.c 1990/1024
## diff -e /n/bootesdump/1990/0918/sys/src/9/68020/devcons.c /n/bootesdump/1990/1024/sys/src/9/68020/devcons.c
540c
	if(c->stream)
.
## diffname gnot/devcons.c 1990/11151
## diff -e /n/bootesdump/1990/1024/sys/src/9/68020/devcons.c /n/bootesdump/1990/11151/sys/src/9/68020/devcons.c
86c
Qinfo rs232info =
{
	nullput,
	rs232oput,
	rs232open,
	rs232close,
	"rs232"
};
.
## diffname gnot/devcons.c 1990/11211
## diff -e /n/bootesdump/1990/11151/sys/src/9/68020/devcons.c /n/bootesdump/1990/11211/sys/src/9/68020/devcons.c
771,783c
	error(Eperm);
.
765c
	error(Eperm);
.
757c
		error(Egreg);
.
752c
		error(Eperm);
.
739c
			error(Eperm);
.
704c
	switch(c->qid.path){
.
564c
	switch(c->qid.path&~CHDIR){
.
545c
	if(c->qid.path==Qrcons && (c->flag&COPEN))
.
539c
	error(Eperm);
.
514c
				error(Eperm);
.
507c
	switch(c->qid.path){
.
492c
	switch(c->qid.path){
.
395,408c
	"cons",		{Qcons},	0,		0600,
	"cputime",	{Qcputime},	6*NUMSIZE,	0600,
	"null",		{Qnull},	0,		0600,
	"pgrpid",	{Qpgrpid},	NUMSIZE,	0600,
	"pid",		{Qpid},		NUMSIZE,	0600,
	"ppid",		{Qppid},	NUMSIZE,	0600,
	"rcons",	{Qrcons},	0,		0600,
	"rs232",	{Qrs232},	0,		0600,
	"rs232ctl",	{Qrs232ctl},	0,		0600,
	"time",		{Qtime},	NUMSIZE,	0600,
	"user",		{Quser},	0,		0600,
	"klog",		{Qklog},	0,		0400,
	"msec",		{Qmsec},	NUMSIZE,	0400,
	"clock",	{Qclock},	2*NUMSIZE,	0400,
.
## diffname gnot/devcons.c 1990/1212
## diff -e /n/bootesdump/1990/11211/sys/src/9/68020/devcons.c /n/bootesdump/1990/1212/sys/src/9/68020/devcons.c
313a
		case 'i':
			incontoggle();
			return;
.
## diffname gnot/devcons.c 1990/1219
## diff -e /n/bootesdump/1990/1212/sys/src/9/68020/devcons.c /n/bootesdump/1990/1219/sys/src/9/68020/devcons.c
337d
## diffname gnot/devcons.c 1991/0112
## diff -e /n/bootesdump/1990/1219/sys/src/9/68020/devcons.c /n/bootesdump/1991/0112/sys/src/9/68020/devcons.c
310a
		case 'r':
			panic("you asked for it");
			break;
.
## diffname gnot/devcons.c 1991/0221
## diff -e /n/bootesdump/1991/0201/sys/src/9/68020/devcons.c /n/bootesdump/1991/0221/sys/src/9/gnot/devcons.c
257a
	dumpstack();
.
## diffname gnot/devcons.c 1991/0311
## diff -e /n/bootesdump/1991/0221/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0311/sys/src/9/gnot/devcons.c
118,119d
97a
	screeninit();
.
## diffname gnot/devcons.c 1991/0318
## diff -e /n/bootesdump/1991/0311/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0318/sys/src/9/gnot/devcons.c
749c
		memmove(u->p->pgrp->user+c->offset, a, n);
.
737c
		memmove(cbuf, a, n);
.
720c
			memmove(buf, a, m);
.
669c
		memmove(buf, tmp+k, n);
.
644c
		memmove(buf, tmp+k, n);
.
462c
	memmove(buf, str+off, n);
.
448c
	memmove(buf, tmp+off, n);
.
## diffname gnot/devcons.c 1991/0411
## diff -e /n/bootesdump/1991/0318/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0411/sys/src/9/gnot/devcons.c
747,750c
		if(offset+n >= NAMELEN-1)
			n = NAMELEN-1 - offset;
		memmove(u->p->pgrp->user+offset, a, n);
		u->p->pgrp->user[offset+n] = 0;
.
745c
		if(offset >= NAMELEN-1)
.
702c
conswrite(Chan *c, void *va, long n, ulong offset)
.
673c
		return readstr(offset, buf, n, u->p->pgrp->user);
.
662c
		k = offset;
.
660c
		return readnum(offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE);
.
657c
		return readnum(offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), NUMSIZE);
.
654c
		return readnum(offset, buf, n, u->p->parentpid, NUMSIZE);
.
651c
		return readnum(offset, buf, n, u->p->pid, NUMSIZE);
.
648c
		return readnum(offset, buf, n, u->p->pgrp->pgrpid, NUMSIZE);
.
631c
		k = offset;
.
625c
		if(offset)
.
557c
consread(Chan *c, void *buf, long n, ulong offset)
.
279c
	qunlock(&c->wrl);
.
277c
	(*devtab[c->type].write)(c, buf, n, c->offset);
.
274c
		qunlock(&c->wrl);
.
272c
	qlock(&c->wrl);
.
## diffname gnot/devcons.c 1991/0419
## diff -e /n/bootesdump/1991/0411/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0419/sys/src/9/gnot/devcons.c
493a
Chan*
consclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

.
## diffname gnot/devcons.c 1991/0423
## diff -e /n/bootesdump/1991/0419/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0423/sys/src/9/gnot/devcons.c
1028a
	r->started = 1;
.
1018a
		wakeup(&r->rempty);
.
1008c
 *  called by output interrupt.  runs spl5
.
997c
	 *  pass upstream within r->delay milliseconds
.
957a
	qlock(&r->outlock);
	while(!rs232empty(r))
		sleep(&r->rempty, rs232empty, r);
	qunlock(&r->outlock);
	kprint("rs232close: emptied\n");
	rs232output(r);	/* reclaim blocks written */
.
956a
	kprint("rs232close: q=0x%ux\n", q);
.
949c
	}else
		wakeup(&r->r);	/* pick up any input characters */
.
944a
	kprint("rs232open: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n",
		q, c->inuse, c->type, c->dev, c->id);
.
871,872d
867,869c
	if(r->started == 0)
.
855a
			poperror();
.
835c
				sleep(&r->rempty, rs232empty, r);
.
833a
			if(waserror()){
				freeb(bp);
				qunlock(&r->outlock);
				nexterror();
			}
.
822a
	if(q==0){
		kprint("rs232output: null q\n");
		qunlock(&r->outlock);
		return;
	}

.
702c
		panic("consread %lux\n", c->qid.path);
.
339a

.
295a
	extern void DEBUG(void), dumpqueues(void), mntdump(void);
.
110a
	rs232.delay = 64;	/* msec */
.
74a
	Rendez	rempty;
.
72c
	int	started;	/* true if output interrupt pending */
.
## diffname gnot/devcons.c 1991/0427
## diff -e /n/bootesdump/1991/0423/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0427/sys/src/9/gnot/devcons.c
498,503d
## diffname gnot/devcons.c 1991/0514
## diff -e /n/bootesdump/1991/0427/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0514/sys/src/9/gnot/devcons.c
1010c
		/*screenputc('^')*/;
.
73c
	int	delay;		/* between character input and waking kproc */
.
## diffname gnot/devcons.c 1991/0605
## diff -e /n/bootesdump/1991/0514/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0605/sys/src/9/gnot/devcons.c
781,1047d
764a

	case Qnoise:
		consnoise(a, n);
		break;

	case Qlights:
		conslights(a, n);
		break;

	case Qsysstat:
		for(id = 0; id < 32; id++) {
			if(active.machs & (1<<id)) {
				mp = MACHP(id);
				mp->cs = 0;
				mp->intr = 0;
				mp->syscall = 0;
				mp->pfault = 0;
				mp->tlbfault = 0;
				mp->tlbpurge = 0;
				mp->spinlock = 0;
			}
		}
		break;

.
731,735d
715a
	case Qcons:
.
714d
711a
	Mach *mp;
	int id;
.
704a
void
conslights(char *a, int n)
{
	int l;
	char line[128];
	char *lp;
	int c;

	lp = line;
	while(n--){
		*lp++ = c = *a++;
		if(c=='\n' || n==0 || lp==&line[sizeof(line)-1])
			break;
	}
	*lp = 0;
	lights(strtoul(line, 0, 0));
}

void
consnoise(char *a, int n)
{
	int freq;
	int duration;
	char line[128];
	char *lp;
	int c;

	lp = line;
	while(n--){
		*lp++ = c = *a++;
		if(c=='\n' || n==0 || lp==&line[sizeof(line)-1]){
			*lp = 0;
			freq = strtoul(line, &lp, 0);
			while(*lp==' ' || *lp=='\t')
				lp++;
			duration = strtoul(lp, &lp, 0);
			buzz(freq, duration);
			lp = line;
		}
	}
}

.
700c
		panic("consread %lux\n", c->qid);
.
698a
	case Qmsec:
		return readnum(offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE);

	case Qsysstat:
		j = 0;
		for(id = 0; id < 32; id++) {
			if(active.machs & (1<<id)) {
				mp = MACHP(id);
				j += sprint(&xbuf[j], "%d %d %d %d %d %d %d %d\n",
					id, mp->cs, mp->intr, mp->syscall, mp->pfault,
					    mp->tlbfault, mp->tlbpurge, m->spinlock);
			}
		}
		return readstr(offset, buf, n, xbuf);

.
663,664d
661c
		return readnum(offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12);
.
625,633d
608a
					else
						lineq.in++;
.
606,607c
					*lineq.in = ch;
					if(lineq.in >= lineq.buf+sizeof(lineq.buf)-1)
.
575c
		return devdirread(c, buf, n, consdir, NCONS, devgen);
.
573c
	switch(c->qid.path & ~CHDIR){
.
569c
	char tmp[6*NUMSIZE], xbuf[1024];
	Mach *mp;
.
563c
	int ch, i, j, k, id;
.
559a

.
556,557d
542c
	return devopen(c, omode, consdir, NCONS, devgen);
.
537,540d
501,508c
	devstat(c, dp, consdir, NCONS, devgen);
.
495c
	return devwalk(c, name, consdir, NCONS, devgen);
.
422,431d
417a
	"sysstat",	{Qsysstat},	0,		0600,
.
411,412d
405a
	"lights",	{Qlights},	0,		0600,
	"noise",	{Qnoise},	0,		0600,
.
399,400c
	Qsysstat,
.
388a
	Qlights,
	Qnoise,
.
379c
	return printq.in != printq.out;
.
372,373c
	if(kbdq.repeat == 0)
		return;
	if(kbdq.repeat==1 && ++kbdq.count>HZ){
		kbdq.repeat = 2;
		kbdq.count = 0;
		return;
	}
	if(++kbdq.count&1)
		kbdputc(&kbdq, kbdq.c);
.
363,366c
	kbdq.repeat = rep;
	kbdq.count = 0;
.
357a
	return 0;
.
356c
	if(raw.ref || ch=='\n' || ch==0x04)
.
347,353c
	echo(ch);
	kbdq.c = ch;
	*kbdq.in++ = ch;
.
343,345c
int
kbdputc(IOQ *q, int ch)
.
317,322d
315c
			firmware();
.
307a
		case 'm':
			mntdump();
			return;
.
298d
289,290c
	while(printq.in != printq.out) ;
.
261a

.
260c
	for(;;);
.
245c
	klogputs(buf, n);
.
177,221d
144,161d
142c
isbrkc(KIOQ *q)
.
138a
	wakeup(&klogq.r);
.
132,137c
	lock(&klogq);
	while(n){
		m = &klogq.buf[NQ] - klogq.in;
		if(m > n)
			m = n;
		memmove(klogq.in, str, m);
		n -= m;
		str += m;
		nextin = klogq.in + m;
		if(nextin >= &klogq.buf[NQ])
			klogq.in = klogq.buf;
		else
			klogq.in = nextin;
	}
	unlock(&klogq);
.
129c
	int s, m;
	uchar *nextin;
.
127c
klogputs(char *str, long n)
.
124c
 *   Print a string in the kernel log.  Ignore overflow.
.
101,120c
	while(n > 0){
		if(printq.puts && *str=='\n')
			(*printq.puts)(&printq, "\r", 1);
		m = n;
		t = memchr(str+1, '\n', m-1);
		if(t)
			if(t-str < m)
				m = t - str;
		if(printq.puts)
			(*printq.puts)(&printq, str, m);
		screenputs(str, m);
		n -= m;
		str += m;
	}
.
99c
	int s, c, m;
	char *t;
.
97c
putstrn(char *str, int n)
.
95a
/*
 *   Print a string on the console.  Convert \n to \r\n
 */
.
89,94c
	initq(&printq);
	initq(&lineq);
	initq(&kbdq);
	initq(&klogq);
	initq(&mouseq);
	mouseq.putc = mouseputc;
}
.
52,87c
void
printinit(void)
.
50c
 *  init the queues and set the output routine
.
20,46d
13,18c
IOQ	lineq;			/* lock to getc; interrupt putc's */
IOQ	printq;
IOQ	mouseq;
KIOQ	kbdq;
.
11c
struct {
	IOQ;			/* lock to klogputs */
	QLock;			/* qlock to getc */
}	klogq;
.
## diffname gnot/devcons.c 1991/0608 # deleted
## diff -e /n/bootesdump/1991/0605/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0608/sys/src/9/gnot/devcons.c
1,715d

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.