## diffname bitsy/devuart.c 2000/0904
## diff -e /dev/null /n/emeliedump/2000/0904/sys/src/9/bitsy/devuart.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "../port/error.h"
#include "../port/netif.h"
enum
{
Nuart = 1,
Stagesize= 1024,
};
/* hardware registers */
typedef struct Uartregs Uartregs;
struct Uartregs
{
ulong ctl0;
ulong ctl1;
ulong ctl2;
ulong ctl3;
uchar dummyd[4];
ulong data;
uchar dummyf[4];
ulong status0;
ulong status1;
};
#define UART3REGS IOA(Uartregs, 0x50000)
/* ctl0 bits */
enum
{
XmitNotFull = (1 << 2),
};
/* software representation */
typedef struct Uart Uart;
struct Uart
{
QLock;
int opens;
int enabled;
Uart *elist; /* next enabled interface */
char name[NAMELEN];
uchar sticky[8]; /* sticky write register values */
uchar osticky[8]; /* kernel saved sticky write register values */
ulong port; /* io ports */
ulong freq; /* clock frequency */
uchar mask; /* bits/char */
int dev;
int baud; /* baud rate */
uchar istat; /* last istat read */
int frame; /* framing errors */
int overrun; /* rcvr overruns */
/* buffers */
int (*putc)(Queue*, int);
Queue *iq;
Queue *oq;
Lock flock; /* fifo */
uchar fifoon; /* fifo's enabled */
uchar type; /* chip version */
Lock rlock; /* receive */
uchar istage[Stagesize];
uchar *ip;
uchar *ie;
int haveinput;
Lock tlock; /* transmit */
uchar ostage[Stagesize];
uchar *op;
uchar *oe;
int modem; /* hardware flow control on */
int xonoff; /* software flow control on */
int blocked;
int cts, dsr, dcd, dcdts; /* keep track of modem status */
int ctsbackoff;
int hup_dsr, hup_dcd; /* send hangup upstream? */
int dohup;
int kinuse; /* device in use by kernel */
Rendez r;
};
static Uart* uart[Nuart];
static int nuart;
static Dirtab *uartdir;
static int uartndir;
/*
* means the kernel is using this for debugging output
*/
static char Ekinuse[] = "device in use by kernel";
/*
* default is 9600 baud, 1 stop bit, 8 bit chars, no interrupts,
* transmit and receive enabled, interrupts disabled.
*/
static void
uartsetup0(Uart *p)
{
memset(p->sticky, 0, sizeof(p->sticky));
/*
* set rate to 9600 baud.
* 8 bits/character.
* 1 stop bit.
* interrupts enabled.
*/
// p->sticky[Format] = Bits8;
// uartwrreg(p, Format, 0);
// p->sticky[Mctl] |= Inton;
// uartwrreg(p, Mctl, 0x0);
// uartsetbaud(p, 9600);
// p->iq = qopen(4*1024, 0, uartflow, p);
// p->oq = qopen(4*1024, 0, uartkick, p);
if(p->iq == nil || p->oq == nil)
panic("uartsetup0");
p->ip = p->istage;
p->ie = &p->istage[Stagesize];
p->op = p->ostage;
p->oe = p->ostage;
}
/*
* called by main() to create a new duart
*/
void
uartsetup(ulong port, ulong freq, char *name, int type)
{
Uart *p;
if(nuart >= Nuart)
return;
p = xalloc(sizeof(Uart));
uart[nuart] = p;
strcpy(p->name, name);
p->dev = nuart;
nuart++;
p->port = port;
p->freq = freq;
p->type = type;
uartsetup0(p);
}
static void
uartenable(Uart *p)
{
USED(p);
}
static void
uartdisable(Uart *p)
{
USED(p);
}
static long
uartstatus(Chan*, Uart *p, void *buf, long n, long offset)
{
USED(p);
// "b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n"
// "dev(%d) type(%d) framing(%d) overruns(%d)%s%s%s%s\n",
return readstr(offset, buf, n, "");
}
static void
setlength(int i)
{
Uart *p;
if(i > 0){
p = uart[i];
if(p && p->opens && p->iq)
uartdir[3*i].length = qlen(p->iq);
} else for(i = 0; i < nuart; i++){
p = uart[i];
if(p && p->opens && p->iq)
uartdir[3*i].length = qlen(p->iq);
}
}
static void
uartreset(void)
{
int i;
Dirtab *dp;
nuart = Nuart;
uartndir = 3*nuart;
uartdir = xalloc(uartndir * sizeof(Dirtab));
dp = uartdir;
for(i = 0; i < nuart; i++){
/* 3 directory entries per port */
sprint(dp->name, "eia%d", i);
dp->qid.path = NETQID(i, Ndataqid);
dp->perm = 0660;
dp++;
sprint(dp->name, "eia%dctl", i);
dp->qid.path = NETQID(i, Nctlqid);
dp->perm = 0660;
dp++;
sprint(dp->name, "eia%dstat", i);
dp->qid.path = NETQID(i, Nstatqid);
dp->perm = 0444;
dp++;
}
}
static Chan*
uartattach(char *spec)
{
return devattach('t', spec);
}
static int
uartwalk(Chan *c, char *name)
{
return devwalk(c, name, uartdir, uartndir, devgen);
}
static void
uartstat(Chan *c, char *dp)
{
if(NETTYPE(c->qid.path) == Ndataqid)
setlength(NETID(c->qid.path));
devstat(c, dp, uartdir, uartndir, devgen);
}
static Chan*
uartopen(Chan *c, int omode)
{
Uart *p;
c = devopen(c, omode, uartdir, uartndir, devgen);
switch(NETTYPE(c->qid.path)){
case Nctlqid:
case Ndataqid:
p = uart[NETID(c->qid.path)];
if(p->kinuse)
error(Ekinuse);
qlock(p);
if(p->opens++ == 0){
uartenable(p);
qreopen(p->iq);
qreopen(p->oq);
}
qunlock(p);
break;
}
return c;
}
static void
uartclose(Chan *c)
{
Uart *p;
if(c->qid.path & CHDIR)
return;
if((c->flag & COPEN) == 0)
return;
switch(NETTYPE(c->qid.path)){
case Ndataqid:
case Nctlqid:
p = uart[NETID(c->qid.path)];
if(p->kinuse)
error(Ekinuse);
qlock(p);
if(--(p->opens) == 0){
uartdisable(p);
qclose(p->iq);
qclose(p->oq);
p->ip = p->istage;
p->dcd = p->dsr = p->dohup = 0;
}
qunlock(p);
break;
}
}
static long
uartread(Chan *c, void *buf, long n, vlong off)
{
Uart *p;
ulong offset = off;
if(c->qid.path & CHDIR){
setlength(-1);
return devdirread(c, buf, n, uartdir, uartndir, devgen);
}
p = uart[NETID(c->qid.path)];
if(p->kinuse)
error(Ekinuse);
switch(NETTYPE(c->qid.path)){
case Ndataqid:
return qread(p->iq, buf, n);
case Nctlqid:
return readnum(offset, buf, n, NETID(c->qid.path), NUMSIZE);
case Nstatqid:
return uartstatus(c, p, buf, n, offset);
}
return 0;
}
static void
uartctl(Uart *p, char *cmd)
{
int i, n;
char *f[32];
int nf;
/* let output drain for a while */
for(i = 0; i < 16 && qlen(p->oq); i++)
tsleep(&p->r, (int(*)(void*))qlen, p->oq, 125);
nf = getfields(cmd, f, nelem(f), 1, " \t\n");
for(i = 0; i < nf; i++){
if(strncmp(f[i], "break", 5) == 0){
// uartbreak(p, 0);
continue;
}
n = atoi(f[i]+1);
switch(*f[i]){
case 'B':
case 'b':
// uartsetbaud(p, n);
break;
case 'C':
case 'c':
// uartdcdhup(p, n);
break;
case 'D':
case 'd':
// uartdtr(p, n);
break;
case 'E':
case 'e':
// uartdsrhup(p, n);
break;
case 'f':
case 'F':
qflush(p->oq);
break;
case 'H':
case 'h':
qhangup(p->iq, 0);
qhangup(p->oq, 0);
break;
case 'i':
case 'I':
// lock(&p->flock);
// uartfifo(p, n);
// unlock(&p->flock);
break;
case 'L':
case 'l':
// uartbits(p, n);
break;
case 'm':
case 'M':
// uartmflow(p, n);
break;
case 'n':
case 'N':
qnoblock(p->oq, n);
break;
case 'P':
case 'p':
// uartparity(p, *(cmd+1));
break;
case 'K':
case 'k':
// uartbreak(p, n);
break;
case 'R':
case 'r':
// uartrts(p, n);
break;
case 'Q':
case 'q':
qsetlimit(p->iq, n);
qsetlimit(p->oq, n);
break;
case 'T':
case 't':
// uartdcdts(p, n);
break;
case 'W':
case 'w':
/* obsolete */
break;
case 'X':
case 'x':
ilock(&p->tlock);
p->xonoff = n;
iunlock(&p->tlock);
break;
}
}
}
static long
uartwrite(Chan *c, void *buf, long n, vlong)
{
Uart *p;
char cmd[32];
if(c->qid.path & CHDIR)
error(Eperm);
p = uart[NETID(c->qid.path)];
if(p->kinuse)
error(Ekinuse);
switch(NETTYPE(c->qid.path)){
case Ndataqid:
return qwrite(p->oq, buf, n);
case Nctlqid:
if(n >= sizeof(cmd))
n = sizeof(cmd)-1;
memmove(cmd, buf, n);
cmd[n] = 0;
uartctl(p, cmd);
return n;
}
}
static void
uartwstat(Chan *c, char *dp)
{
Dir d;
Dirtab *dt;
if(!iseve())
error(Eperm);
if(CHDIR & c->qid.path)
error(Eperm);
if(NETTYPE(c->qid.path) == Nstatqid)
error(Eperm);
dt = &uartdir[3 * NETID(c->qid.path)];
convM2D(dp, &d);
d.mode &= 0666;
dt[0].perm = dt[1].perm = d.mode;
}
Dev uartdevtab = {
't',
"uart",
uartreset,
devinit,
uartattach,
devclone,
uartwalk,
uartstat,
uartopen,
devcreate,
uartclose,
uartread,
devbread,
uartwrite,
devbwrite,
devremove,
uartwstat,
};
void
putuartstr(char *str)
{
Uartregs *ur;
ur = UART3REGS;
while(*str){
/* wait for output ready */
while(ur->status1 & XmitNotFull)
;
ur->data = *str++;
}
}
.
## diffname bitsy/devuart.c 2000/0905
## diff -e /n/emeliedump/2000/0904/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/0905/sys/src/9/bitsy/devuart.c
504d
501c
while((ur->status1 & XmitNotFull) == 0)
.
499c
while(n-- > 0){
.
494c
serialputs(char *str, int n)
.
35a
/* status register 1 bits */
XmitBusy = (1 << 0),
.
27c
ulong dummyb;
.
25c
ulong dummya;
.
## diffname bitsy/devuart.c 2000/0906
## diff -e /n/emeliedump/2000/0905/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/0906/sys/src/9/bitsy/devuart.c
500c
ur = uart3regs;
.
32a
static Uartregs *uart3regs = UART3REGS;
.
31d
## diffname bitsy/devuart.c 2000/0907
## diff -e /n/emeliedump/2000/0906/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/0907/sys/src/9/bitsy/devuart.c
32c
Uartregs *uart3regs = UART3REGS;
.
18d
## diffname bitsy/devuart.c 2000/0928
## diff -e /n/emeliedump/2000/0907/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/0928/sys/src/9/bitsy/devuart.c
506a
while((ur->status1 & XmitBusy))
;
.
## diffname bitsy/devuart.c 2000/0930
## diff -e /n/emeliedump/2000/0928/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/0930/sys/src/9/bitsy/devuart.c
507c
while((ur->status1 & Tbusy))
.
503c
while((ur->status1 & Tnotfull) == 0)
.
494a
static void
uartsetbaud(Uart *p, int rate)
{
ulong brconst;
if(rate <= 0)
return;
brconst = (p->freq+8*rate-1)/(16*rate) - 1;
p->regs->ctl[1] = (brconst>>8) & 0xf;
p->regs->ctl[2] = brconst;
p->baud = rate;
}
.
205c
uartsetup(uart3regs, ;
.
198a
/*
* setup the '#t' directory
*/
.
171c
p->sticky[3] &= ~(Rintena|Tintena);
p->regs->ctl[3] = p->sticky[3];
.
167a
/*
* disable interrupts. clear DTR, and RTS
*/
.
165c
p->sticky[3] |= Rintena|Tintena;
p->regs->ctl[3] = p->sticky[3];
.
143,161d
141c
* enable a port's interrupts. set DTR and RTS
.
132c
panic("uartsetup");
.
127,130c
p->iq = qopen(4*1024, 0, uartflow, p);
p->oq = qopen(4*1024, 0, uartkick, p);
.
122,125c
p->sticky[0] = Bits8;
p->regs->ctl[0] = p->sticky[0];
p->sticky[3] = Rena|Tena;
p->regs->ctl[3] = p->sticky[3];
uartsetbaud(p, 115200);
.
120c
* interrupts disabled.
.
117c
* set rate to 115200 baud.
.
115a
.
114a
Uart *p;
if(nuart >= Nuart)
return;
p = xalloc(sizeof(Uart));
uart[nuart] = p;
strcpy(p->name, name);
p->dev = nuart++;
p->port = port;
p->freq = freq;
p->regs = regs;
.
113c
uartsetup(Uartregs *regs, ulong freq, char *name)
.
109,110c
* define a Uart.
.
107a
static void uartsetbaud(Uart *p, int rate);
.
104c
* means the kernel is using this as a console
.
69,72d
60c
int parity; /* parity errors */
.
57d
52,54c
uchar sticky[4]; /* sticky write register values */
.
46a
Uartregs *regs;
.
45a
int dev;
.
40a
Uartregs *uart3regs = UART3REGS;
.
36,38c
/* ctl[0] bits */
Parity= 1<<0,
Even= 1<<1,
Stop1= 0<<2,
Stop2= 1<<2,
Bits7= 0<<3,
Bits8= 1<<3,
SCE= 1<<4, /* synchronous clock enable */
RCE= 1<<5, /* rx on falling edge of clock */
TCE= 1<<6, /* tx on falling edge of clock */
/* ctl[3] bits */
Rena= 1<<0, /* receiver enable */
Tena= 1<<1, /* transmitter enable */
Break= 1<<2, /* force TXD3 low */
Rintena= 1<<3, /* enable receive interrupt */
Tintena= 1<<4, /* enable transmitter interrupt */
Loopback= 1<<5, /* loop back data */
/* data bits */
DEparity= 1<<8, /* parity error */
DEframe= 1<<9, /* framing error */
DEoverrun= 1<<10, /* overrun error */
/* status0 bits */
Tint= 1<<0, /* transmit fifo half full interrupt */
Rint0= 1<<1, /* receiver fifo 1/3-2/3 full */
Rint1= 1<<2, /* receiver fifo not empty and receiver idle */
Breakstart= 1<<3,
Breakend= 1<<4,
Fifoerror= 1<<5, /* fifo error */
/* status1 bits */
Tbusy= 1<<0, /* transmitting */
Rnotempty= 1<<1, /* receive fifo not empty */
Tnotfull= 1<<2, /* transmit fifo not full */
ParityError= 1<<3,
FrameError= 1<<4,
Overrun= 1<<5,
.
31,33d
20,23c
ulong ctl[4];
.
## diffname bitsy/devuart.c 2000/1002
## diff -e /n/emeliedump/2000/0930/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/1002/sys/src/9/bitsy/devuart.c
537a
}
/*
* turn on/off rts
*/
static void
uartrts(Uart *p, int on)
{
}
/*
* restart input if it's off
*/
static void
uartflow(void *v)
{
Uart *p;
p = v;
if(p->modem){
uartrts(p, 1);
ilock(&p->rlock);
p->haveinput = 1;
iunlock(&p->rlock);
}
}
/*
* restart output if not blocked and OK to send
*/
static void
uartkick0(void *v)
{
int i;
Uart *p;
p = v;
if(p->cts == 0 || p->blocked)
return;
/*
* 128 here is an arbitrary limit to make sure
* we don't stay in this loop too long. If the
* chips output queue is longer than 128, too
* bad -- presotto
*/
for(i = 0; i < 128; i++){
// if(!(uartrdreg(p, Lstat) & Outready))
// break;
// if(p->op >= p->oe && stageoutput(p) == 0)
// break;
// outb(p->port + Data, *(p->op++));
}
}
static void
uartkick(void *v)
{
Uart *p;
p = v;
ilock(&p->tlock);
uartkick0(p);
iunlock(&p->tlock);
.
524a
/*
* set the buad rate
*/
.
235,236d
152d
135a
static void uartflow(void *v);
static void uartkick0(void *v);
static void uartkick(void *v);
static void uartrts(Uart *p, int on);
.
## diffname bitsy/devuart.c 2000/1006
## diff -e /n/emeliedump/2000/1002/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/1006/sys/src/9/bitsy/devuart.c
605a
}
static void
uartintr(Ureg*, void *x)
{
Uart *p;
p = x;
.
548c
uartrts(Uart*, int)
.
256d
191a
intrenable(IRQuart3, uartintr, p, p->name);
.
184a
* setup all uarts (called early by main() to allow debugging output to
* a serial port)
*/
void
uartsetup(void)
{
uart3regs = mapspecial(UART3REGS, 64);
uartsetup0(uart3regs, 36864000, "serialport3");
}
/*
.
145c
uartsetup0(Uartregs *regs, ulong freq, char *name)
.
139a
static void uartintr(Ureg*, void*);
.
## diffname bitsy/devuart.c 2000/1007
## diff -e /n/emeliedump/2000/1006/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/1007/sys/src/9/bitsy/devuart.c
590,641c
n = qconsume(p->oq, p->ostage, Stagesize);
if(n <= 0)
return 0;
p->op = p->ostage;
p->oe = p->ostage + n;
return n;
.
587,588c
int n;
.
584,585c
int
uartstageoutput(Uart *p)
.
582c
* put some bytes into the local queue to avoid calling
* qconsume for every character
.
570,578c
p->dcdts = n;
.
568c
uartdcdts(Uart *p, int n)
.
565c
* save dcd timestamps for gps clock
.
561a
p->hup_dcd = n;
.
560c
uartdcdhup(Uart *p, int n)
.
556,558d
544,553c
p->hup_dsr = n;
.
542c
uartdsrhup(Uart *p, int n)
.
539c
* decide if we should hangup when dsr or dcd drops.
.
456c
uartdcdts(p, n);
.
447c
(*p->phys->rts)(p, n);
.
443c
(*p->phys->dobreak)(p, n);
.
439c
(*p->phys->parity)(p, *(cmd+1));
.
431c
(*p->phys->modemctl)(p, n);
.
427c
(*p->phys->bits)(p, n);
.
421,423d
408c
uartdsrhup(p, n);
.
404c
(*p->phys->dtr)(p, n);
.
400c
uartdcdhup(p, n);
.
396c
(*p->phys->baud)(p, n);
.
388c
(*p->phys->dobreak)(p, 0);
.
366c
return (*p->phys->status)(p, buf, n, offset);
.
335c
(*p->phys->disable)(p);
.
307c
(*p->phys->enable)(p, 1);
.
200,226d
185,198d
182a
return p;
.
174,175c
p->iq = qopen(4*1024, 0, p->phys->flow, p);
p->oq = qopen(4*1024, 0, p->phys->kick, p);
.
168,172c
(*p->phys->bits)(p, 8);
(*p->phys->stop)(p, 1);
(*p->phys->baud)(p, 115200);
(*p->phys->enable)(p, 0);
.
166c
* enabled with interrupts disabled.
.
160,161d
158a
p->phys = phys;
.
151c
return nil;
.
145,146c
Uart*
uartsetup(PhysUart *phys, void *regs, ulong freq, char *name)
.
143c
* define a Uart
.
135,140c
static void uartdcdhup(Uart*, int);
static void uartdcdts(Uart*, int);
static void uartdsrhup(Uart*, int);
.
17,123d
11,15d
## diffname bitsy/devuart.c 2000/1015
## diff -e /n/emeliedump/2000/1007/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/1015/sys/src/9/bitsy/devuart.c
416a
}
/*
* restart output
*/
void
uartkick(void *v)
{
Uart *p = v;
ilock(&p->tlock);
(*p->phys->kick)(p);
iunlock(&p->tlock);
}
/*
* streceiveage a character at interrupt time
*/
void
uartrecv(Uart *p, char ch)
{
/* software flow control */
if(p->xonoff){
if(ch == CTLS){
p->blocked = 1;
}else if (ch == CTLQ){
p->blocked = 0;
p->ctsbackoff = 2; /* clock gets output going again */
}
}
/* receive the character */
if(p->putc)
p->putc(p->iq, ch);
else {
ilock(&p->rlock);
if(p->ip < p->ie)
*p->ip++ = ch;
p->haveinput = 1;
iunlock(&p->rlock);
}
}
/*
* we save up input characters till clock time to reduce
* per character interrupt overhead.
*
* There's also a bit of code to get a stalled print going.
* It shouldn't happen, but it does. Obviously I don't
* understand something. Since it was there, I bundled a
* restart after flow control with it to give some hysteresis
* to the hardware flow control. This makes compressing
* modems happier but will probably bother something else.
* -- presotto
*/
static void
uartclock(void)
{
int n;
Uart *p;
for(p = uartalloc.elist; p; p = p->elist){
/* this amortizes cost of qproduce to many chars */
if(p->haveinput){
ilock(&p->rlock);
if(p->haveinput){
n = p->ip - p->istage;
if(n > 0 && p->iq){
if(n > Stagesize)
panic("uartclock");
if(qproduce(p->iq, p->istage, n) < 0)
(*p->phys->rts)(p, 0);
else
p->ip = p->istage;
}
p->haveinput = 0;
}
iunlock(&p->rlock);
}
if(p->dohup){
ilock(&p->rlock);
if(p->dohup){
qhangup(p->iq, 0);
qhangup(p->oq, 0);
}
p->dohup = 0;
iunlock(&p->rlock);
}
/* this adds hysteresis to hardware/software flow control */
if(p->ctsbackoff){
ilock(&p->tlock);
if(p->ctsbackoff){
if(--(p->ctsbackoff) == 0)
(*p->phys->kick)(p);
}
iunlock(&p->tlock);
}
}
}
/*
* configure a uart port as a console or a mouse
*/
void
uartspecial(Uart *p, int baud, Queue **in, Queue **out, int (*putc)(Queue*, int))
{
uartenable(p);
if(baud)
(*p->phys->baud)(p, baud);
p->putc = putc;
if(in)
*in = p->iq;
if(out)
*out = p->oq;
p->opens++;
.
402a
* restart input if it's off
*/
static void
uartflow(void *v)
{
Uart *p;
p = v;
if(p->modem){
(*p->phys->rts)(p, 1);
ilock(&p->rlock);
p->haveinput = 1;
iunlock(&p->rlock);
}
}
/*
.
178c
uartdisable(p);
.
150c
uartenable(p);
.
111a
addclock0link(uartclock);
.
69a
uartenable(Uart *p)
{
Uart **l;
p->hup_dsr = p->hup_dcd = 0;
p->dsr = p->dcd = 0;
/* assume we can send */
p->cts = 1;
(*p->phys->enable)(p, 1);
lock(&uartalloc);
for(l = &uartalloc.elist; *l; l = &(*l)->elist){
if(*l == p)
break;
}
if(*l == 0){
p->elist = uartalloc.elist;
uartalloc.elist = p;
}
p->enabled = 1;
unlock(&uartalloc);
}
static void
uartdisable(Uart *p)
{
Uart **l;
(*p->phys->disable)(p);
lock(&uartalloc);
for(l = &uartalloc.elist; *l; l = &(*l)->elist){
if(*l == p){
*l = p->elist;
break;
}
}
p->enabled = 0;
unlock(&uartalloc);
}
static void
.
68a
/*
* enable/diable uart and add/remove to list of enabled uarts
*/
.
57,58c
p->iq = qopen(4*1024, 0, uartflow, p);
p->oq = qopen(4*1024, 0, uartkick, p);
.
25a
static void uartenable(Uart*);
static void uartdisable(Uart*);
static void uartclock(void);
static void uartflow(void*);
.
22a
struct Uartalloc {
Lock;
Uart *elist; /* list of enabled interfaces */
} uartalloc;
.
## diffname bitsy/devuart.c 2000/1019
## diff -e /n/emeliedump/2000/1015/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/1019/sys/src/9/bitsy/devuart.c
578d
572,576c
qhangup(p->iq, 0);
qhangup(p->oq, 0);
.
570a
/* hang up if requested */
.
569d
567c
} else {
if(qproduce(p->iq, p->ir, iw-p->ir) < 0)
(*p->phys->rts)(p, 0);
p->ir = iw;
.
564,565c
p->ir = iw;
.
555,562c
if(p->iw != p->ir){
iw = p->iw;
if(iw < p->ir){
if(qproduce(p->iq, p->ir, p->ie-p->ir) < 0){
(*p->phys->rts)(p, 0);
p->ir = p->istage;
} else {
if(qproduce(p->iq, p->istage, iw-p->istage) < 0)
.
550a
uchar *iw;
.
549d
537,544d
526,530c
next = p->iw + 1;
if(next == p->ie)
next = p->istage;
if(next != p->ir){
*p->iw = ch;
p->iw = next;
}
.
511a
uchar *next;
.
470,473d
468c
if(p->modem)
.
238c
p->ir = p->iw = p->istage;
.
71c
p->ir = p->istage;
p->iw = p->istage;
.
47a
memset(p, 0, sizeof(*p));
.
## diffname bitsy/devuart.c 2000/1020
## diff -e /n/emeliedump/2000/1019/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/1020/sys/src/9/bitsy/devuart.c
564a
if(qproduce(p->iq, p->ir, iw-p->ir) < 0)
(*p->phys->rts)(p, 0);
p->ir = iw;
.
554,563c
p->ir = p->istage;
.
552c
if(qproduce(p->iq, p->ir, p->ie-p->ir) < 0)
.
## diffname bitsy/devuart.c 2000/1121
## diff -e /n/emeliedump/2000/1020/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/1121/sys/src/9/bitsy/devuart.c
10a
enum
{
Nuart = 4,
/* soft flow control chars */
CTLS= 023,
CTLQ= 021,
};
.
## diffname bitsy/devuart.c 2001/0529 # deleted
## diff -e /n/emeliedump/2000/1121/sys/src/9/bitsy/devuart.c /n/emeliedump/2001/0529/sys/src/9/bitsy/devuart.c
1,603d
|