## 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
|