M port/devcons.c => port/devcons.c +7 -4
@@ 47,9 47,9 @@ printinit(void)
void
putstrn(char *str, int n)
{
- char buf[PRINTSIZE+2];
int m;
char *t;
+ char buf[PRINTSIZE+2];
/*
* if there's an attached bit mapped display,
@@ 66,9 66,10 @@ putstrn(char *str, int n)
*/
if(printq == 0)
return;
- while(n > 0){
+
+ while(n > 0) {
t = memchr(str, '\n', n);
- if(t){
+ if(t) {
m = t - str;
memmove(buf, str, m);
buf[m] = '\r';
@@ 76,7 77,8 @@ putstrn(char *str, int n)
qwrite(printq, buf, m+2, 1);
str = t + 1;
n -= m + 1;
- } else {
+ }
+ else {
qwrite(printq, str, n, 1);
break;
}
@@ 97,6 99,7 @@ print(char *fmt, ...)
n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
putstrn(buf, n);
+
return n;
}
M port/devlance.c => port/devlance.c +224 -619
@@ 5,11 5,11 @@
#include "fns.h"
#include "io.h"
#include "../port/error.h"
-#include "devtab.h"
+#include "../port/netif.h"
enum {
- Ntypes= 9, /* max number of ethernet packet types */
- Maxrb= 128, /* max buffers in a ring */
+ Ntypes= 9, /* max number of ethernet packet types */
+ Maxrb= 128, /* max buffers in a ring */
};
#define RSUCC(x) (((x)+1)%l.nrrb)
#define TSUCC(x) (((x)+1)%l.ntrb)
@@ 23,7 23,7 @@ typedef struct {
ushort laddr; /* low order piece of address */
ushort flags; /* flags and high order piece of address */
short size; /* size of buffer */
- ushort cntflags; /* (rcv)count of bytes in buffer; (xmt) more flags */
+ ushort cntflags; /* (rcv)count of buffer; (xmt) more flags */
} Msg;
/*
@@ 69,386 69,89 @@ struct Lancemem
#define MPs(a) (*(short *)(l.lanceram + l.sep*((ushort*)&a - (ushort*)0)))
#define MPus(a) (*(ushort *)(l.lanceram + l.sep*((ushort*)&a - (ushort*)0)))
-/*
- * one per ethernet packet type
- */
-typedef struct Ethertype Ethertype;
-struct Ethertype
+enum
{
- QLock;
- Netprot; /* stat info */
- int type; /* ethernet type */
- int prom; /* promiscuous mode */
- Queue *q;
- int inuse;
- Rendez rc; /* rendzvous for close */
- Ethertype *closeline; /* close list */
+ PROM = 0x8000,
+ INTL = 0x40,
+ DRTY = 0x20,
+ COLL = 0x10,
+ DTCR = 0x8,
+ LOOP = 0x4,
+ DTX = 0x2,
+ DRX = 0x1,
+ ERR0 = 0x8000,
+ BABL = 0x4000,
+ CERR = 0x2000,
+ MISS = 0x1000,
+ MERR = 0x800,
+ RINT = 0x400,
+ TINT = 0x200,
+ IDON = 0x100,
+ INTR = 0x80,
+ INEA = 0x40,
+ RXON = 0x20,
+ TXON = 0x10,
+ TDMD = 0x8,
+ STOP = 0x4,
+ STRT = 0x2,
+ INIT = 0x1,
+ /* flag bits from a buffer descriptor in the rcv/xmt rings */
+ LANCEOWNER= 0x8000, /* 1 means buffer can be used by the chip */
+ ERR = 0x4000, /* error summary, the OR of all error bits */
+ FRAM = 0x2000, /* CRC error */
+ OFLO = 0x1000, /* (receive) lost some of the packet */
+ MORE = 0x1000, /* (transmit) more than 1 retry to tx pkt */
+ CRC = 0x800, /* (rcv) crc error reading packet */
+ ONE = 0x800, /* (tx) one retry to transmit the packet */
+ BUF = 0x400, /* (rcv) out of buffers */
+ DEF = 0x400, /* (tx) deffered while transmitting packet */
+ STP = 0x200, /* start of packet */
+ ENP = 0x100, /* end of packet */
+ /* cntflags bits from a buffer descriptor in the rcv/xmt rings */
+ BUFF = 0x8000, /* buffer error (host screwed up?) */
+ UFLO = 0x4000, /* underflow from memory */
+ LCOL = 0x1000, /* late collision (ether too long?) */
+ LCAR = 0x800, /* loss of carrier (ether broken?) */
+ RTRY = 0x400, /* couldn't transmit (ether jammed?) */
+ TTDR = 0x3FF, /* time domain reflectometer */
};
+struct Softlance
+{
+ Lance; /* host dependent lance params */
-/*
- * lance state
- */
-typedef struct {
- QLock;
+ uchar ea[6];
+ uchar bcast[6];
- Lance; /* host dependent lance params */
- int prom; /* number of promiscuous channels */
- int all; /* number of channels listening to all packets */
int wedged; /* the lance is wedged */
- Network net;
- int inited;
- uchar *lmp; /* location of parity test */
-
- Rendez rr; /* rendezvous for an input buffer */
- QLock rlock; /* semaphore on tc */
ushort rl; /* first rcv Message belonging to Lance */
-
- Rendez tr; /* rendezvous for an output buffer */
- QLock tlock; /* semaphore on tc */
ushort tc; /* next xmt Message CPU will try for */
- Ethertype *closeline; /* channels waiting to close */
- Lock closepin; /* lock for closeline */
- Ethertype e[Ntypes];
- int debug;
- int kstarted;
- uchar bcast[6];
-
- Queue self; /* packets turned around at the interface */
-
- /* sadistics */
-
- int misses;
- int inpackets;
- int outpackets;
- int crcs; /* input crc errors */
- int oerrs; /* output erros */
- int frames; /* framing errors */
- int overflows; /* packet overflows */
- int buffs; /* buffering errors */
-} SoftLance;
-static SoftLance l;
-
-/*
- * mode bits in the lance initialization block
- */
-#define PROM 0x8000
-#define INTL 0x40
-#define DRTY 0x20
-#define COLL 0x10
-#define DTCR 0x8
-#define LOOP 0x4
-#define DTX 0x2
-#define DRX 0x1
-
-/*
- * LANCE CSR0, this is the register we play with most often. We leave
- * this register pointed to by l.rap in normal operation.
- */
-#define ERR0 0x8000
-#define BABL 0x4000
-#define CERR 0x2000
-#define MISS 0x1000
-#define MERR 0x800
-#define RINT 0x400
-#define TINT 0x200
-#define IDON 0x100
-#define INTR 0x80
-#define INEA 0x40
-#define RXON 0x20
-#define TXON 0x10
-#define TDMD 0x8
-#define STOP 0x4
-#define STRT 0x2
-#define INIT 0x1
-
-/*
- * flag bits from a buffer descriptor in the rcv/xmt rings
- */
-#define LANCEOWNER 0x8000 /* 1 means that the buffer can be used by the chip */
-#define ERR 0x4000 /* error summary, the OR of all error bits */
-#define FRAM 0x2000 /* CRC error and incoming packet not a multiple of 8 bits */
-#define OFLO 0x1000 /* (receive) lost some of the packet */
-#define MORE 0x1000 /* (transmit) more than 1 retry to send the packet */
-#define CRC 0x800 /* (receive) crc error reading packet */
-#define ONE 0x800 /* (transmit) one retry to transmit the packet */
-#define BUF 0x400 /* (receive) out of buffers while reading a packet */
-#define DEF 0x400 /* (transmit) deffered while transmitting packet */
-#define STP 0x200 /* start of packet */
-#define ENP 0x100 /* end of packet */
-
-/*
- * cntflags bits from a buffer descriptor in the rcv/xmt rings
- */
-#define BUFF 0x8000 /* buffer error (host screwed up?) */
-#define UFLO 0x4000 /* underflow from memory */
-#define LCOL 0x1000 /* late collision (ether too long?) */
-#define LCAR 0x800 /* loss of carrier (ether broken?) */
-#define RTRY 0x400 /* couldn't transmit (bad station on ether?) */
-#define TTDR 0x3FF /* time domain reflectometer */
-
-/*
- * predeclared
- */
-static void lancekproc(void *);
-static void lancestart(int);
-static void lanceup(Etherpkt*, int);
-static int lanceclonecon(Chan*);
-static void lancestatsfill(Chan*, char*, int);
-static void lancetypefill(Chan*, char*, int);
-
-/*
- * lance stream module definition
- */
-static void lanceoput(Queue*, Block*);
-static void lancestopen(Queue*, Stream*);
-static void lancestclose(Queue*);
-static void stagerbuf(void);
-Qinfo lanceinfo = { nullput, lanceoput, lancestopen, lancestclose, "lance" };
-
-/*
- * open a lance line discipline
- */
-void
-lancestopen(Queue *q, Stream *s)
-{
- Ethertype *et;
-
- et = &l.e[s->id];
- RD(q)->ptr = WR(q)->ptr = et;
- et->type = 0;
- et->q = RD(q);
- et->inuse = 1;
-}
-
-/*
- * close lance line discipline
- *
- * the lock is to synchronize changing the ethertype with
- * sending packets up the stream on interrupts.
- */
-static int
-isclosed(void *x)
-{
- return ((Ethertype *)x)->q == 0;
-}
-
-static void
-lancestclose(Queue *q)
-{
- Ethertype *et;
-
- et = (Ethertype *)(q->ptr);
- if(et->prom){
- qlock(&l);
- l.prom--;
- if(l.prom == 0)
- lancestart(0);
- qunlock(&l);
- }
- if(et->type == -1){
- qlock(&l);
- l.all--;
- qunlock(&l);
- }
-
- /*
- * mark as closing and wait for kproc to close us
- */
- lock(&l.closepin);
- et->closeline = l.closeline;
- l.closeline = et;
- unlock(&l.closepin);
- wakeup(&l.rr);
- sleep(&et->rc, isclosed, et);
-
- et->type = 0;
- et->q = 0;
- et->prom = 0;
- et->inuse = 0;
- netdisown(et);
-}
-
-/*
- * the ``connect'' control message specifyies the type
- */
-Proc *lanceout;
-static int
-isobuf(void *x)
-{
- Msg *m;
-
- m = x;
- return l.wedged || (MPus(m->flags)&LANCEOWNER) == 0;
-}
-
-static void
-lanceoput(Queue *q, Block *bp)
-{
- int n, len;
- Etherpkt *p;
- Ethertype *e;
- Msg *m;
- Block *nbp;
-
- if(bp->type == M_CTL){
- e = q->ptr;
- qlock(&l);
- if(streamparse("connect", bp)){
- if(e->type == -1)
- l.all--;
- e->type = strtol((char *)bp->rptr, 0, 0);
- if(e->type == -1)
- l.all++;
- } else if(streamparse("promiscuous", bp)) {
- e->prom = 1;
- l.prom++;
- if(l.prom == 1)
- lancestart(PROM);/**/
- }
- qunlock(&l);
- freeb(bp);
- return;
- }
-
- /*
- * give packet a local address, return upstream if destined for
- * this machine.
- */
- if(BLEN(bp) < ETHERHDRSIZE){
- bp = pullup(bp, ETHERHDRSIZE);
- if(bp == 0)
- return;
- }
- p = (Etherpkt *)bp->rptr;
- memmove(p->s, l.ea, sizeof(l.ea));
- if(*p->d == 0xff || l.prom || l.all){
- len = blen(bp);
- nbp = copyb(bp, len);
- nbp = expandb(nbp, len >= ETHERMINTU ? len : ETHERMINTU);
- if(nbp){
- nbp->wptr = nbp->rptr+len;
- putq(&l.self, nbp);
- wakeup(&l.rr);
- }
- } else if(*p->d == *l.ea && memcmp(l.ea, p->d, sizeof(l.ea)) == 0){
- len = blen(bp);
- bp = expandb(bp, len >= ETHERMINTU ? len : ETHERMINTU);
- if(bp){
- putq(&l.self, bp);
- wakeup(&l.rr);
- }
- return;
- }
-
- if(l.wedged) {
- freeb(bp);
- return;
- }
+ QLock tlock; /* lock for grabbing transmitter queue */
+ Rendez tr; /* wait here for free xmit buffer */
- /*
- * only one transmitter at a time
- */
- qlock(&l.tlock);
- if(l.wedged) {
- qunlock(&l.tlock);
- freeb(bp);
- return;
- }
+ Netif;
+} l;
- if(waserror()){
- qunlock(&l.tlock);
- freeb(bp);
- nexterror();
- }
+static void promiscuous(void*, int);
- /*
- * Wait till we get an output buffer, complain if input
- * or output seems wedged.
- */
- m = &(LANCEMEM->tmr[l.tc]);
- p = &l.tp[l.tc];
- while((MPus(m->flags)&LANCEOWNER) != 0) {
- tsleep(&l.tr, isobuf, m, 128);
- if(l.wedged || isobuf(m) == 0){
- qunlock(&l.tlock);
- freeb(bp);
- poperror();
- print("lance wedged, dumping block & restarting\n");
- lancestart(0);
- l.wedged = 0;
- return;
- }
- }
-
- /*
- * copy message into lance RAM
- */
- len = 0;
- for(nbp = bp; nbp; nbp = nbp->next){
- if(sizeof(Etherpkt) - len >= (n = BLEN(nbp))){
- memmove(((uchar *)p)+len, nbp->rptr, n);
- len += n;
- } else
- print("no room damn it\n");
- if(bp->flags & S_DELIM)
- break;
- }
-
- /*
- * pad the packet (zero the pad)
- */
- if(len < ETHERMINTU){
- memset(((char*)p)+len, 0, ETHERMINTU-len);
- len = ETHERMINTU;
- }
-
- /*
- * set up the ring descriptor and hand to lance
- */
- l.outpackets++;
- MPs(m->size) = -len;
- MPus(m->cntflags) = 0;
- MPus(m->laddr) = LADDR(&l.ltp[l.tc]);
- MPus(m->flags) = LANCEOWNER|STP|ENP|HADDR(&l.ltp[l.tc]);
- l.tc = TSUCC(l.tc);
- *l.rdp = INEA|TDMD; /**/
- wbflush();
- qunlock(&l.tlock);
- freeb(bp);
- poperror();
-}
-
-/*
- * stop the lance and allocate buffers
- */
void
lancereset(void)
{
static int already;
- int i;
if(already == 0){
already = 1;
lancesetup(&l);
- l.net.name = "ether";
- l.net.nconv = Ntypes;
- l.net.devp = &lanceinfo;
- l.net.protop = 0;
- l.net.listen = 0;
- l.net.clone = lanceclonecon;
- l.net.ninfo = 2;
- l.net.info[0].name = "stats";
- l.net.info[0].fill = lancestatsfill;
- l.net.info[1].name = "type";
- l.net.info[1].fill = lancetypefill;
- for(i = 0; i < Ntypes; i++)
- netadd(&l.net, &l.e[i], i);
-
- memset(l.bcast, 0xff, sizeof l.bcast);
+ /* general network interface structure */
+ netifinit(&l, "ether", Ntypes, 32*1024);
+ l.alen = 6;
+ memmove(l.addr, l.ea, 6);
+ memmove(l.bcast, etherbcast, 6);
+ l.promiscuous = promiscuous;
+ l.arg = &l;
}
/*
@@ 459,8 162,9 @@ lancereset(void)
}
/*
- * Initialize and start the lance. This routine can be called only from a process.
- * It may be used to restart a dead lance.
+ * Initialize and start the lance.
+ * This routine can be called only from a process.
+ * It may be used to restart a dead lance.
*/
static void
lancestart(int mode)
@@ 474,7 178,6 @@ lancestart(int mode)
* quiescent
*/
qlock(&l.tlock);
- qlock(&l.rlock);
lancereset();
l.rl = 0;
@@ 507,7 210,7 @@ lancestart(int mode)
*/
m = lm->rmr;
for(i = 0; i < l.nrrb; i++, m++){
- MPs(m->size) = -sizeof(Etherpkt);
+ MPs(m->size) = -sizeof(Lancepkt);
MPus(m->cntflags) = 0;
MPus(m->laddr) = LADDR(&l.lrp[i]);
MPus(m->flags) = HADDR(&l.lrp[i]);
@@ 561,147 264,13 @@ lancestart(int mode)
}
void
-lanceinit(void)
-{
-}
-
-Chan*
-lanceattach(char *spec)
-{
- if(l.kstarted == 0){
- kproc("lancekproc", lancekproc, 0);
- l.kstarted = 1;
- lancestart(0);
- print("lance ether: %.2x%.2x%.2x%.2x%.2x%.2x\n",
- l.ea[0], l.ea[1], l.ea[2], l.ea[3], l.ea[4], l.ea[5]);
- }
- return devattach('l', spec);
-}
-
-Chan*
-lanceclone(Chan *c, Chan *nc)
-{
- return devclone(c, nc);
-}
-
-int
-lancewalk(Chan *c, char *name)
-{
- return netwalk(c, name, &l.net);
-}
-
-void
-lancestat(Chan *c, char *dp)
-{
- netstat(c, dp, &l.net);
-}
-
-/*
- * Pass open's of anything except the directory to streamopen
- */
-Chan*
-lanceopen(Chan *c, int omode)
-{
- return netopen(c, omode, &l.net);
-}
-
-void
-lancecreate(Chan *c, char *name, int omode, ulong perm)
-{
- USED(c, name, omode, perm);
- error(Eperm);
-}
-
-void
-lanceclose(Chan *c)
-{
- if(c->stream)
- streamclose(c);
-}
-
-long
-lanceread(Chan *c, void *a, long n, ulong offset)
-{
- return netread(c, a, n, offset, &l.net);
-}
-
-long
-lancewrite(Chan *c, void *a, long n, ulong offset)
-{
- USED(offset);
- return streamwrite(c, a, n, 0);
-}
-
-void
-lanceremove(Chan *c)
-{
- USED(c);
- error(Eperm);
-}
-
-void
-lancewstat(Chan *c, char *dp)
-{
- netwstat(c, dp, &l.net);
-}
-
-/*
- * user level network interface routines
- */
-static void
-lancestatsfill(Chan *c, char* p, int n)
-{
- char buf[512];
-
- USED(c);
- sprint(buf, "in: %d\nout: %d\ncrc errs %d\noverflows: %d\nframe errs %d\nbuff errs: %d\noerrs %d\naddr: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x\n",
- l.inpackets, l.outpackets, l.crcs,
- l.overflows, l.frames, l.buffs, l.oerrs,
- l.ea[0], l.ea[1], l.ea[2], l.ea[3], l.ea[4], l.ea[5]);
- strncpy(p, buf, n);
-}
-
-static void
-lancetypefill(Chan *c, char* p, int n)
-{
- char buf[16];
- Ethertype *e;
-
- e = &l.e[STREAMID(c->qid.path)];
- sprint(buf, "%d", e->type);
- strncpy(p, buf, n);
-}
-
-static int
-lanceclonecon(Chan *c)
-{
- Ethertype *e;
-
- USED(c);
- for(e = l.e; e < &l.e[Ntypes]; e++){
- qlock(e);
- if(e->inuse || e->q){
- qunlock(e);
- continue;
- }
- e->inuse = 1;
- netown(e, up->user, 0);
- qunlock(e);
- return e - l.e;
- }
- error(Enodev);
- return -1; /* never reached */
-}
-
-/*
- * We will:
- * (1) Clear interrupt cause in the lance
- * (2) service all current events
- */
-void
lanceintr(void)
{
- ushort csr;
+ Msg *m;
+ Lancepkt *p;
+ Netfile *f, **fp;
+ ushort csr, t, x;
+ Lancemem *lm = LANCEMEM;
csr = *l.rdp;
@@ 721,7 290,6 @@ lanceintr(void)
l.wedged = 1;
l.misses = 0;
lancereset();
- wakeup(&l.rr);
wakeup(&l.tr);
return;
}
@@ 729,7 297,6 @@ lanceintr(void)
if(csr & IDON){
l.wedged = 0;
- qunlock(&l.rlock);
qunlock(&l.tlock);
}
@@ 740,91 307,9 @@ lanceintr(void)
l.wedged = 1;
/*
- * wakeup the input process
- */
- if(csr & RINT)
- wakeup(&l.rr);
-
- /*
- * wake any process waiting for a transmit buffer
+ * process incoming frames
*/
- if(csr & TINT)
- wakeup(&l.tr);
-}
-
-/*
- * send a packet upstream
- */
-static void
-lanceup(Etherpkt *p, int len)
-{
- int t;
- Block *bp;
- Ethertype *e;
-
- if(len <= 0)
- return;
-
- t = (p->type[0]<<8) | p->type[1];
- for(e = &l.e[0]; e < &l.e[Ntypes]; e++){
- /*
- * check for open, the right type, and flow control
- */
- if(e->q==0 || (t!=e->type && e->type!=-1) || e->q->next->len>Streamhi)
- continue;
-
- /*
- * only a trace channel gets packets destined for other machines
- */
- if(e->type!=-1 && p->d[0]!=0xff
- && (*p->d != *l.ea || memcmp(p->d, l.ea, sizeof(p->d))!=0))
- continue;
-
- if(!waserror()){
- bp = allocb(len);
- memmove(bp->rptr, (uchar *)p, len);
- bp->wptr += len;
- bp->flags |= S_DELIM;
- PUTNEXT(e->q, bp);
- poperror();
- }
- }
-}
-
-/*
- * input process, awakened on each interrupt with rcv buffers filled
- */
-static int
-isinput(void *arg)
-{
- Msg *m = arg;
-
- return ((MPus(m->flags) & LANCEOWNER)==0) || l.wedged || l.self.first
- || l.closeline;
-}
-
-static void
-lancekproc(void *arg)
-{
- Etherpkt *p;
- Ethertype *e;
- int len;
- int t;
- Lancemem *lm = LANCEMEM;
- Msg *m;
- Block *bp;
-
- USED(arg);
-
- while(waserror())
- print("lancekproc err %s\n", up->error);
-
- for(;;){
- qlock(&l.rlock);
- while(bp = getq(&l.self)){
- lanceup((Etherpkt*)bp->rptr, BLEN(bp));
- freeb(bp);
- }
+ if(csr & RINT) {
m = &(lm->rmr[l.rl]);
while((MPus(m->flags) & LANCEOWNER)==0){
l.inpackets++;
@@ 839,18 324,23 @@ lancekproc(void *arg)
if(t & BUFF)
l.buffs++;
} else {
- /*
- * stuff packet up each queue that wants it
- */
+ /* stuff packet up each queue that wants it */
p = &l.rp[l.rl];
- len = MPus(m->cntflags) - 4;
- lanceup(p, len);
+ x = MPus(m->cntflags) - 4;
+ t = (p->type[0]<<8) | p->type[1];
+ for(fp = l.f; fp < &l.f[Ntypes]; fp++){
+ f = *fp;
+ if(f == 0)
+ continue;
+ if(f->type == t || f->type < 0)
+ qproduce(f->in, p->d, x);
+ }
}
/*
* stage the next input buffer
*/
- MPs(m->size) = -sizeof(Etherpkt);
+ MPs(m->size) = -sizeof(Lancepkt);
MPus(m->cntflags) = 0;
MPus(m->laddr) = LADDR(&l.lrp[l.rl]);
MPus(m->flags) = LANCEOWNER|HADDR(&l.lrp[l.rl]);
@@ 858,29 348,144 @@ lancekproc(void *arg)
l.rl = RSUCC(l.rl);
m = &(lm->rmr[l.rl]);
}
- qunlock(&l.rlock);
- sleep(&l.rr, isinput, m);
-
- /*
- * if the lance is wedged, restart it
- */
- if(l.wedged){
- print("lance wedged, restarting\n");
- lancestart(0);
- l.wedged = 0;
- }
+ }
- /*
- * close ethertypes requesting it
- */
- if(l.closeline){
- lock(&l.closepin);
- for(e = l.closeline; e; e = e->closeline){
- e->q = 0;
- wakeup(&e->rc);
- }
- l.closeline = 0;
- unlock(&l.closepin);
+ /*
+ * wake any process waiting for a transmit buffer
+ */
+ if(csr & TINT)
+ wakeup(&l.tr);
+}
+
+/*
+ * turn promiscuous mode on/off
+ */
+static void
+promiscuous(void *arg, int on)
+{
+ USED(arg);
+ if(on)
+ lancestart(PROM);
+ else
+ lancestart(0);;
+}
+
+void
+lanceinit(void)
+{
+ lancestart(0);
+ print("lance ether: %.2x%.2x%.2x%.2x%.2x%.2x\n",
+ l.ea[0], l.ea[1], l.ea[2], l.ea[3], l.ea[4], l.ea[5]);
+}
+
+Chan*
+lanceattach(char *spec)
+{
+ return devattach('l', spec);
+}
+
+Chan*
+lanceclone(Chan *c, Chan *nc)
+{
+ return devclone(c, nc);
+}
+
+int
+lancewalk(Chan *c, char *name)
+{
+ return netifwalk(&l, c, name);
+}
+
+Chan*
+lanceopen(Chan *c, int omode)
+{
+ return netifopen(&l, c, omode);
+}
+
+void
+lancecreate(Chan *c, char *name, int omode, ulong perm)
+{
+ USED(c, name, omode, perm);
+}
+
+void
+lanceclose(Chan *c)
+{
+ netifclose(&l, c);
+}
+
+long
+lanceread(Chan *c, void *buf, long n, ulong offset)
+{
+ return netifread(&l, c, buf, n, offset);
+}
+
+static int
+isoutbuf(void *x)
+{
+ Msg *m;
+
+ m = x;
+ return l.wedged || (MPus(m->flags)&LANCEOWNER) == 0;
+}
+
+long
+lancewrite(Chan *c, void *buf, long n, ulong offset)
+{
+ Msg *m;
+ Lancepkt *p;
+
+ USED(offset);
+
+ if(n > ETHERMAXTU)
+ error(Ebadarg);
+
+ /* etherif.c handles structure */
+ if(NETTYPE(c->qid.path) != Ndataqid)
+ return netifwrite(&l, c, buf, n);
+
+ /* we handle data */
+ qlock(&l.tlock);
+ m = &(LANCEMEM->tmr[l.tc]);
+ tsleep(&l.tr, isoutbuf, m, 10000);
+ if(!isoutbuf(m) || l.wedged){
+ print("lance transmitter jammed\n");
+ }
+ else {
+ p = &l.tp[l.tc];
+ memmove(p->d, buf, n);
+ if(n < 60) {
+ memset(p->d+n, 0, 60-n);
+ n = 60;
}
+ memmove(p->s, l.ea, sizeof(l.ea));
+
+ l.outpackets++;
+ MPs(m->size) = -n;
+ MPus(m->cntflags) = 0;
+ MPus(m->laddr) = LADDR(&l.ltp[l.tc]);
+ MPus(m->flags) = LANCEOWNER|STP|ENP|HADDR(&l.ltp[l.tc]);
+ l.tc = TSUCC(l.tc);
+ *l.rdp = INEA|TDMD; /**/
}
+ qunlock(&l.tlock);
+ return n;
+}
+
+void
+lanceremove(Chan *c)
+{
+ USED(c);
+}
+
+void
+lancestat(Chan *c, char *dp)
+{
+ netifstat(&l, c, dp);
+}
+
+void
+lancewstat(Chan *c, char *dp)
+{
+ netifwstat(&l, c, dp);
}
M port/portdat.h => port/portdat.h +4 -4
@@ 68,7 68,7 @@ struct RWlock
{
Lock; /* Lock modify lock */
QLock x; /* Mutual exclusion lock */
- QLock k; /* Lock for waiting writers held for readers */
+ QLock k; /* Lock for waiting writers */
int readers; /* Count of readers in lock */
};
@@ 84,7 84,7 @@ struct Alarms
Proc *head;
};
-#define MAXSYSARG 5 /* for mount(fd, mpt, flag, arg, srv) */
+#define MAXSYSARG 5 /* for mount(fd, mpt, flag, arg, srv) */
struct Sargs
{
ulong args[MAXSYSARG];
@@ 458,7 458,7 @@ struct Palloc
Rendez r; /* Sleep for free mem */
QLock pwait; /* Queue of procs waiting for memory */
int wanted; /* Do the wakeup at free */
- ulong cmembase; /* Key memory protected from read by devproc */
+ ulong cmembase; /* Key memory */
ulong cmemtop;
};
@@ 565,7 565,7 @@ struct Proc
int kp; /* true if a kernel process */
Proc *palarm; /* Next alarm time */
ulong alarm; /* Time of call */
- int newtlb; /* Pager has changed my pte's so I must flush */
+ int newtlb; /* Pager has changed my pte's, I must flush */
ulong rendtag; /* Tag for rendezvous */
ulong rendval; /* Value for rendezvous */
M power/dat.h => power/dat.h +14 -4
@@ 1,4 1,5 @@
typedef struct Conf Conf;
+typedef struct Lancepkt Lancepkt;
typedef struct FPsave FPsave;
typedef struct Cycmsg Cycmsg;
typedef struct Lance Lance;
@@ 148,6 149,15 @@ typedef void KMap;
#define ACON 0x2
#define BCON 0x1
+struct Lancepkt
+{
+ uchar d[6];
+ uchar s[6];
+ uchar type[2];
+ uchar data[1500];
+ uchar crc[4];
+};
+
/*
* system dependent lance stuff
* filled by lancesetup()
@@ 166,10 176,10 @@ struct Lance
as seen by host */
ushort *lanceram; /* start of lance ram as seen by host */
Lancemem *lm; /* start of lance ram as seen by lance */
- Etherpkt *rp; /* receive buffers (host address) */
- Etherpkt *tp; /* transmit buffers (host address) */
- Etherpkt *lrp; /* receive buffers (lance address) */
- Etherpkt *ltp; /* transmit buffers (lance address) */
+ Lancepkt *rp; /* receive buffers (host address) */
+ Lancepkt *tp; /* transmit buffers (host address) */
+ Lancepkt *lrp; /* receive buffers (lance address) */
+ Lancepkt *ltp; /* transmit buffers (lance address) */
};
struct
D power/debugger.c => power/debugger.c +0 -249
@@ 1,249 0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "ureg.h"
-
-IOQ dkbdq;
-IOQ dprintq;
-
-typedef struct Syslogbuf Syslogbuf;
-struct Syslogbuf
-{
- char *next;
- char buf[4*1024];
-};
-
-Syslogbuf syslogbuf[4];
-
-static int
-dprint(char *fmt, ...)
-{
- char buf[PRINTSIZE];
- int n;
-
- n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
- dprintq.puts(&dprintq, buf, n);
- return n;
-}
-
-static int
-dgetline(char *p, int n)
-{
- int c;
- char *end, *start;
- char buf[1];
-
- start = p;
- end = p + n - 1;
- for(;;){
- c = getc(&dkbdq);
- if(c <= 0)
- continue;
-
- /* echo */
- buf[0] = c;
- if(c == '\r' || c == '\n')
- dprintq.puts(&dprintq, "\r\n", 2);
- else
- dprintq.puts(&dprintq, buf, 1);
-
- if(c == '\b'){
- if(p != start)
- p--;
- continue;
- }
- if(c == '\r' || c == '\n')
- break;
- if(p >= end)
- continue;
- *p++ = c;
- }
- *p = 0;
- return p - start;
-}
-
-static void
-printlog(char *cpu)
-{
- int i, c;
- char *p, *end;
- Syslogbuf *s;
-
- if(cpu == 0)
- i = 0;
- else
- i = atoi(cpu);
- if(i < 0 || i > 3)
- return;
- s = &syslogbuf[i];
-
- if(s->next < s->buf || s->next >= &s->buf[sizeof(s->buf)])
- s->next = s->buf;
- end = s->next;
- p = end + 1;
- if(p >= &s->buf[sizeof(s->buf)] || p < s->buf)
- p = s->buf;
- while(p != end){
- c = *p & 0xff;
- if(c == '\r' || c == '\n')
- dprintq.puts(&dprintq, "\r\n", 2);
- else if(c >= ' ' && c <= '~')
- dprintq.puts(&dprintq, p, 1);
- p++;
- if(p >= &s->buf[sizeof(s->buf)])
- p = s->buf;
- }
-}
-
-static void
-printhex(char *start, char *len)
-{
- int i;
- ulong n;
- ulong *p;
-
- if(start == 0){
- dprint("! h <location> <howmany> - hex display\r\n");
- return;
- }
- n = strtoul(start, 0, 16);
- if((n & KZERO) == 0)
- return;
- p = (ulong *)n;
-
- if(len)
- n = strtoul(len, 0, 0);
- else
- n = 1;
-
- while(n > 0){
- dprint("%lux/", p);
- for(i = 0; i < 8 && n > 0; i++, n--)
- dprint(" %8.8lux", p[i]);
- dprint("\r\n");
- p += 8;
- }
-}
-
-static void
-printinfo(void)
-{
- Mach *mp;
- Proc *p;
- Page *pg;
- Ureg *ur;
- ulong l;
- int i;
-
- for(i = 0; i < 4; i++){
- if((active.machs&(1<<i)) == 0)
- continue;
- mp = (void*)(MACHADDR+i*BY2PG);
- l = (ulong)(mp->proc);
- dprint("mach[%d] proc/%lux\r\n", i, l);
- dprint("mach[%d] splpc/%lux\r\n", i, mp->splpc);
-
- if(l & KZERO){
- p = (Proc*)l;
- l = (ulong)(p->upage);
- if(l & KZERO){
- pg = (Page*)l;
- l = pg->pa;
- dprint("mach[%d] proc->upage->pa/%lux\r\n", i, l);
- }
- }
- l = (ulong)(mp->ur);
- dprint("mach[%d] ur/%lux", i, l);
- ur = (Ureg*)l;
- dprint(" &status/%lux &cause/%lux &sp/%lux &pc/%lux",
- &ur->status, &ur->cause, &ur->sp, &ur->pc);
- dprint("\r\n");
- }
-}
-
-void
-debugger(void *arg)
-{
- int n, level;
- char buf[256];
- char *field[3];
-
- USED(arg);
-
- /*
- * sched() until we are on processor 1
- */
- for(;;){
- level = splhi();
- if(m->machno == 1)
- break;
- splx(level);
- sched();
- }
-
- /*
- * grab a port for a console
- */
- initq(&dprintq);
- initq(&dkbdq);
- duartspecial(3, &dprintq, &dkbdq, 9600);
-
- /*
- * take processor and process out of active groups
- */
- active.machs &= ~(1<<1);
- splx(level);
-
- for(;;){
- dprint("kdb> ");
- dgetline(buf, sizeof(buf));
- memset(field, 0, sizeof(field));
- n = getfields(buf, field, 3, ' ');
- if(n == 0)
- continue;
- switch(*field[0]){
- case 'l':
- printlog(field[1]);
- break;
- case 'h':
- printhex(field[1], field[2]);
- break;
- case 'i':
- printinfo();
- break;
- case 'q':
- firmware(cpuserver ? PROM_AUTOBOOT : PROM_REINIT);
- break;
- default:
- dprint("!commands are:\r\n");
- dprint("! l <cpu#> - print cpu log\r\n");
- dprint("! h <location> <howmany> - hex display\r\n");
- dprint("! i - display some addresses\r\n");
- dprint("! q - quit/rebooot\r\n");
- break;
- }
- }
-}
-
-void
-syslog(char *str, int n)
-{
- Syslogbuf *s;
- int level;
-
- level = splhi();
- s = &syslogbuf[m->machno];
- if(s->next < s->buf || s->next >= &s->buf[sizeof(s->buf)])
- s->next = s->buf;
- while(n-- > 0){
- *s->next = *str++;
- if(s->next >= &s->buf[sizeof(s->buf)-1])
- s->next = s->buf;
- else
- s->next++;
- }
- splx(level);
-}
M power/devduart.c => power/devduart.c +356 -513
@@ 6,104 6,103 @@
#include "io.h"
#include "../port/error.h"
-void duartputs(IOQ*, char*, int);
-void iprint(char*, ...);
-
-#define PAD 15 /* registers are well-spaced */
+#include "devtab.h"
+#include "../port/netif.h"
/*
- * Register set for half the duart. There are really two sets in adjacent
- * memory locations.
+ * Register set for half the duart.
+ * There are really two sets in adjacent memory locations.
*/
struct Duartreg
{
- uchar mr1_2, /* Mode Register Channels 1 & 2 */
- pad0[PAD];
- uchar sr_csr, /* Status Register/Clock Select Register */
- pad1[PAD];
- uchar cmnd, /* Command Register */
- pad2[PAD];
- uchar data, /* RX Holding / TX Holding Register */
- pad3[PAD];
- uchar ipc_acr, /* Input Port Change/Aux. Control Register */
- pad4[PAD];
- uchar is_imr, /* Interrupt Status/Interrupt Mask Register */
- pad5[PAD];
- uchar ctur, /* Counter/Timer Upper Register */
- pad6[PAD];
- uchar ctlr, /* Counter/Timer Lower Register */
- pad7[PAD];
+ uchar mr12; /* Mode Register Channels 1 & 2 */
+ uchar pad0[15];
+ uchar srcsr; /* Status Register/Clock Select Register */
+ uchar pad1[15];
+ uchar cmnd; /* Command Register */
+ uchar pad2[15];
+ uchar data; /* RX Holding / TX Holding Register */
+ uchar pad3[15];
+ uchar ipcacr; /* Input Uart Change/Aux. Control Register */
+ uchar pad4[15];
+ uchar isimr; /* Interrupt Status/Interrupt Mask Register */
+ uchar pad5[15];
+ uchar ctur; /* Counter/Timer Upper Register */
+ uchar pad6[15];
+ uchar ctlr; /* Counter/Timer Lower Register */
+ uchar pad7[15];
};
-#define ppcr is_imr /* in the second register set */
-
-#define DBD75 0
-#define DBD110 1
-#define DBD38400 2
-#define DBD150 3
-#define DBD300 4
-#define DBD600 5
-#define DBD1200 6
-#define DBD2000 7
-#define DBD2400 8
-#define DBD4800 9
-#define DBD1800 10
-#define DBD9600 11
-#define DBD19200 12
-
-enum{
- CHAR_ERR =0x00, /* MR1x - Mode Register 1 */
- EVEN_PAR =0x00,
- ODD_PAR =0x04,
- NO_PAR =0x10,
- CBITS8 =0x03,
- CBITS7 =0x02,
- CBITS6 =0x01,
- CBITS5 =0x00,
- NORM_OP =0x00, /* MR2x - Mode Register 2 */
- TWOSTOPB =0x0F,
- ONESTOPB =0x07,
- ENB_RX =0x01, /* CRx - Command Register */
- DIS_RX =0x02,
- ENB_TX =0x04,
- DIS_TX =0x08,
- RESET_MR =0x10,
- RESET_RCV =0x20,
- RESET_TRANS =0x30,
- RESET_ERR =0x40,
- RESET_BCH =0x50,
- STRT_BRK =0x60,
- STOP_BRK =0x70,
- RCV_RDY =0x01, /* SRx - Channel Status Register */
- FIFOFULL =0x02,
- XMT_RDY =0x04,
- XMT_EMT =0x08,
- OVR_ERR =0x10,
- PAR_ERR =0x20,
- FRM_ERR =0x40,
- RCVD_BRK =0x80,
- IM_IPC =0x80, /* IMRx/ISRx - Interrupt Mask/Interrupt Status */
- IM_DBB =0x40,
- IM_RRDYB =0x20,
- IM_XRDYB =0x10,
- IM_CRDY =0x08,
- IM_DBA =0x04,
- IM_RRDYA =0x02,
- IM_XRDYA =0x01,
- BD38400 =0xCC|0x0000,
- BD19200 =0xCC|0x0100,
- BD9600 =0xBB|0x0000,
- BD4800 =0x99|0x0000,
- BD2400 =0x88|0x0000,
- BD1200 =0x66|0x0000,
- BD300 =0x44|0x0000,
-
- Maxduart =8,
+#define ppcr isimr /* in the second register set */
+
+enum
+{
+ DBD75 = 0,
+ DBD110 = 1,
+ DBD38400 = 2,
+ DBD150 = 3,
+ DBD300 = 4,
+ DBD600 = 5,
+ DBD1200 = 6,
+ DBD2000 = 7,
+ DBD2400 = 8,
+ DBD4800 = 9,
+ DBD1800 = 10,
+ DBD9600 = 11,
+ DBD19200 = 12,
+ CHARERR = 0x00, /* MR1x - Mode Register 1 */
+ EVENPAR = 0x00,
+ ODDPAR = 0x04,
+ NOPAR = 0x10,
+ CBITS8 = 0x03,
+ CBITS7 = 0x02,
+ CBITS6 = 0x01,
+ CBITS5 = 0x00,
+ NORMOP = 0x00, /* MR2x - Mode Register 2 */
+ TWOSTOPB = 0x0F,
+ ONESTOPB = 0x07,
+ ENBRX = 0x01, /* CRx - Command Register */
+ DISRX = 0x02,
+ ENBTX = 0x04,
+ DISTX = 0x08,
+ RESETMR = 0x10,
+ RESETRCV = 0x20,
+ RESETTRANS = 0x30,
+ RESETERR = 0x40,
+ RESETBCH = 0x50,
+ STRTBRK = 0x60,
+ STOPBRK = 0x70,
+ RCVRDY = 0x01, /* SRx - Channel Status Register */
+ FIFOFULL = 0x02,
+ XMTRDY = 0x04,
+ XMTEMT = 0x08,
+ OVRERR = 0x10,
+ PARERR = 0x20,
+ FRMERR = 0x40,
+ RCVDBRK = 0x80,
+ IMIPC = 0x80, /* IMRx/ISRx - Int Mask/Interrupt Status */
+ IMDBB = 0x40,
+ IMRRDYB = 0x20,
+ IMXRDYB = 0x10,
+ IMCRDY = 0x08,
+ IMDBA = 0x04,
+ IMRRDYA = 0x02,
+ IMXRDYA = 0x01,
+ BD38400 = 0xCC|0x0000,
+ BD19200 = 0xCC|0x0100,
+ BD9600 = 0xBB|0x0000,
+ BD4800 = 0x99|0x0000,
+ BD2400 = 0x88|0x0000,
+ BD1200 = 0x66|0x0000,
+ BD300 = 0x44|0x0000,
+
+ Maxduart = 8,
};
/*
* requests to perform on a duart
*/
-enum {
+enum
+{
Dnone= 0,
Dbaud,
Dbreak,
@@ 130,11 129,10 @@ Duart duart[Maxduart];
/*
* values specific to a single duart port
*/
-typedef struct Port Port;
-struct Port
+typedef struct Uart Uart;
+struct Uart
{
QLock;
- int printing; /* true if printing */
Duart *d; /* device */
Duartreg *reg; /* duart registers (for this port) */
int c; /* character to restart output */
@@ 142,24 140,25 @@ struct Port
int val; /* value of operation */
Rendez opr; /* waiot here for op to complete */
- /* console interface */
- int nostream; /* can't use the stream interface */
- IOQ *iq; /* input character queue */
- IOQ *oq; /* output character queue */
+ int printing; /* need kick */
+ int opens;
+ Rendez r;
- /* stream interface */
- Queue *wq; /* write queue */
- Rendez r; /* kproc waiting for input */
- int kstarted; /* kproc started */
+ /* buffers */
+ int (*putc)(Queue*, int);
+ Queue *iq;
+ Queue *oq;
};
-Port duartport[2*Maxduart];
+Uart uart[2*Maxduart];
+
+void duartkick(Uart*);
/*
* configure a duart port, default is 9600 baud, 8 bits/char, 1 stop bit,
* no parity
*/
void
-duartsetup(Port *p, Duart *d, int devno)
+duartsetup(Uart *p, Duart *d, int devno)
{
Duartreg *reg;
@@ 167,16 166,19 @@ duartsetup(Port *p, Duart *d, int devno)
reg = &d->reg[devno];
p->reg = reg;
- reg->cmnd = RESET_RCV|DIS_TX|DIS_RX;
- reg->cmnd = RESET_TRANS;
- reg->cmnd = RESET_ERR;
- reg->cmnd = STOP_BRK;
+ reg->cmnd = RESETRCV|DISTX|DISRX;
+ reg->cmnd = RESETTRANS;
+ reg->cmnd = RESETERR;
+ reg->cmnd = STOPBRK;
- 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;
+ reg->cmnd = RESETMR;
+ reg->mr12 = NOPAR|CBITS8;
+ reg->mr12 = ONESTOPB;
+ reg->srcsr = (DBD9600<<4)|DBD9600;
+ reg->cmnd = ENBTX|ENBRX;
+
+ p->iq = qopen(4*1024, 0, 0, 0);
+ p->oq = qopen(4*1024, 0, duartkick, p);
}
/*
@@ 185,19 187,21 @@ duartsetup(Port *p, Duart *d, int devno)
void
duartinit(void)
{
- Port *p;
+ Uart *p;
Duart *d;
d = &duart[m->machno];
if(d->inited)
return;
+
d->reg = DUARTREG;
- d->imr = IM_RRDYA|IM_XRDYA|IM_RRDYB|IM_XRDYB;
- d->reg->is_imr = d->imr;
+ d->imr = IMRRDYA|IMXRDYA|IMRRDYB|IMXRDYB;
+ d->reg->isimr = d->imr;
d->acr = 0x80; /* baud rate set 2 */
- d->reg->ipc_acr = d->acr;
+ d->reg->ipcacr = d->acr;
+
+ p = &uart[2*m->machno];
- p = &duartport[2*m->machno];
duartsetup(p, d, 0);
p++;
duartsetup(p, d, 1);
@@ 208,19 212,19 @@ duartinit(void)
* enable a duart port
*/
void
-duartenable(Port *p)
+duartenable(Uart *p)
{
- p->reg->cmnd = ENB_TX|ENB_RX;
+ p->reg->cmnd = ENBTX|ENBRX;
}
void
duartenable0(void)
{
- DUARTREG->cmnd = ENB_TX|ENB_RX;
+ DUARTREG->cmnd = ENBTX|ENBRX;
}
void
-duartbaud(Port *p, int b)
+duartbaud(Uart *p, int b)
{
int x;
@@ 253,12 257,12 @@ duartbaud(Port *p, int b)
p->d->acr |= 0x80;
else
p->d->acr &= ~0x80;
- p->d->reg->ipc_acr = p->d->acr;
- p->reg->sr_csr = x;
+ p->d->reg->ipcacr = p->d->acr;
+ p->reg->srcsr = x;
}
void
-duartdtr(Port *p, int val)
+duartdtr(Uart *p, int val)
{
if (val)
p->reg->ctlr = 0x01;
@@ 267,19 271,19 @@ duartdtr(Port *p, int val)
}
void
-duartbreak(Port *p, int val)
+duartbreak(Uart *p, int val)
{
Duartreg *reg;
reg = p->reg;
if (val){
- p->d->imr &= ~IM_XRDYB;
- p->d->reg->is_imr = p->d->imr;
- reg->cmnd = STRT_BRK|ENB_TX;
+ p->d->imr &= ~IMXRDYB;
+ p->d->reg->isimr = p->d->imr;
+ reg->cmnd = STRTBRK|ENBTX;
} else {
- reg->cmnd = STOP_BRK|ENB_TX;
- p->d->imr |= IM_XRDYB;
- p->d->reg->is_imr = p->d->imr;
+ reg->cmnd = STOPBRK|ENBTX;
+ p->d->imr |= IMXRDYB;
+ p->d->reg->isimr = p->d->imr;
}
}
@@ 287,7 291,7 @@ duartbreak(Port *p, int val)
* do anything requested for this CPU's duarts
*/
void
-duartslave0(Port *p)
+duartslave0(Uart *p)
{
switch(p->op){
case Ddtr:
@@ 300,8 304,9 @@ duartslave0(Port *p)
duartbreak(p, p->val);
break;
case Dprint:
- p->reg->cmnd = ENB_TX;
+ p->reg->cmnd = ENBTX;
p->reg->data = p->val;
+iprint("slave %c\n", p->val);
break;
case Dena:
duartenable(p);
@@ 316,62 321,75 @@ duartslave0(Port *p)
void
duartslave(void)
{
- IOQ *cq;
- Port *p;
+ Uart *p;
- p = &duartport[2*m->machno];
- cq = p->iq;
- if(p->wq && cangetc(cq))
- wakeup(&cq->r);
+ p = &uart[2*m->machno];
if(p->op != Dnone)
duartslave0(p);
p++;
- cq = p->iq;
- if(p->wq && cangetc(cq))
- wakeup(&cq->r);
if(p->op != Dnone)
duartslave0(p);
}
void
-duartrintr(Port *p)
+duartrintr(Uart *p)
{
- Duartreg *reg;
- IOQ *cq;
- int status;
char ch;
+ int status;
+ Duartreg *reg;
reg = p->reg;
- status = reg->sr_csr;
+ status = reg->srcsr;
ch = reg->data;
- if(status & (FRM_ERR|OVR_ERR|PAR_ERR))
- reg->cmnd = RESET_ERR;
+ if(status & (FRMERR|OVRERR|PARERR))
+ reg->cmnd = RESETERR;
- cq = p->iq;
- if(cq->putc)
- (*cq->putc)(cq, ch);
+ if(p->putc)
+ (*p->putc)(p->iq, ch);
else
- putc(cq, ch);
+ qproduce(p->iq, &ch, 1);
}
+/*
+ * (re)start output
+ */
void
-duartxintr(Port *p)
+duartkick(Uart *p)
+{
+ char ch;
+ int n, x;
+
+ x = splhi();
+ if(p->printing) {
+ splx(x);
+ return;
+ }
+
+ n = qconsume(p->oq, &ch, 1);
+ if(n <= 0){
+ splx(x);
+ return;
+ }
+
+ p->printing = 1;
+ p->val = ch;
+ p->op = Dprint;
+ splx(x);
+}
+
+void
+duartxintr(Uart *p)
{
- Duartreg *reg;
- IOQ *cq;
int ch;
+ Duartreg *reg;
- cq = p->oq;
- lock(cq);
- ch = getc(cq);
reg = p->reg;
- if(ch < 0){
+ if(qconsume(p->oq, &ch, 1) <= 0) {
p->printing = 0;
- wakeup(&cq->r);
- reg->cmnd = DIS_TX;
- } else
+ reg->cmnd = DISTX;
+ }
+ else
reg->data = ch;
- unlock(cq);
}
void
@@ 379,34 397,22 @@ duartintr(void)
{
int cause;
Duartreg *reg;
- Port *p;
+ Uart *p;
- p = &duartport[2*m->machno];
+ p = &uart[2*m->machno];
reg = p->reg;
- cause = reg->is_imr;
-
- /*
- * I can guess your interrupt.
- */
- /*
- * Is it 1?
- */
- if(cause & IM_RRDYA)
+ cause = reg->isimr;
+
+ if(cause & IMRRDYA)
duartrintr(p);
- /*
- * Is it 2?
- */
- if(cause & IM_XRDYA)
+
+ if(cause & IMXRDYA)
duartxintr(p);
- /*
- * Is it 3?
- */
- if(cause & IM_RRDYB)
+
+ if(cause & IMRRDYB)
duartrintr(p+1);
- /*
- * Is it 4?
- */
- if(cause & IM_XRDYB)
+
+ if(cause & IMXRDYB)
duartxintr(p+1);
}
@@ 416,310 422,85 @@ duartintr(void)
int
duartrawputc(int c)
{
- Duartreg *reg;
int i;
+ Duartreg *reg;
reg = DUARTREG;
- if(c == '\n')
+ if(c == '\n') {
duartrawputc('\r');
- reg->cmnd = ENB_TX;
+ delay(100);
+ }
+ reg->cmnd = ENBTX;
i = 0;
- while((reg->sr_csr&XMT_RDY) == 0)
- if(++i >= 1000000){
- duartsetup(&duartport[0], &duart[0], 0);
- for(i=0; i<100000; i++)
- ;
- break;
- }
+ while((reg->srcsr&XMTRDY) == 0 && i++ < 100000)
+ ;
reg->data = c;
- if(c == '\n')
- for(i=0; i<100000; i++)
- ;
return c;
}
-void
-duartrawputs(char *s)
-{
- int i;
- while(*s){
- duartrawputc(*s++);
- }
- for(i=0; i < 1000000; i++)
- ;
-}
-void
+int
iprint(char *fmt, ...)
{
+ int n, i;
char buf[512];
- doprint(buf, buf+sizeof(buf), fmt, (&fmt+1));
- duartrawputs(buf);
+ n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
+ for(i = 0; i < n; i++)
+ duartrawputc(buf[i]);
+ return n;
}
-/*
- * Queue n characters for output; if queue is full, we lose characters.
- * Get the output going if it isn't already.
- */
void
-duartputs(IOQ *cq, char *s, int n)
+duartspecial(int port, int s, Queue **in, Queue **out, int (*putc)(Queue*, int))
{
- int ch, x;
- Port *p;
+ Uart *p;
- x = splhi();
- lock(cq);
- puts(cq, s, n);
- p = cq->ptr;
- if(p->printing == 0){
- ch = getc(cq);
- if(ch >= 0){
- p->printing = 1;
- p->val = ch;
- p->op = Dprint;
- }
- }
- unlock(cq);
- splx(x);
-}
-
-/*
- * set up an duart port as something other than a stream
- */
-void
-duartspecial(int port, IOQ *oq, IOQ *iq, int baud)
-{
- Port *p = &duartport[port];
- IOQ *zq;
+ p = &uart[port];
- p->nostream = 1;
- if(oq){
- p->oq = oq;
- p->oq->puts = duartputs;
- p->oq->ptr = p;
- }
- if(iq){
- p->iq = iq;
- p->iq->ptr = p;
-
- /*
- * Stupid HACK to undo a stupid hack
- */
- zq = &kbdq;
- if(iq == zq)
- kbdq.putc = kbdcr2nl;
- }
duartenable(p);
- duartbaud(p, baud);
-}
+ if(s)
+ duartbaud(p, s);
-static int duartputc(IOQ *, int);
-static void duartstopen(Queue*, Stream*);
-static void duartstclose(Queue*);
-static void duartoput(Queue*, Block*);
-static void duartkproc(void *);
-Qinfo duartinfo =
-{
- nullput,
- duartoput,
- duartstopen,
- duartstclose,
- "duart"
-};
+ p->putc = putc;
+ if(in)
+ *in = p->iq;
+ if(out)
+ *out = p->oq;
+
+ p->opens++;
+}
static int
opdone(void *x)
{
- Port *p = x;
+ Uart *p = x;
return p->op == Dnone;
}
-static void
-duartstopen(Queue *q, Stream *s)
-{
- Port *p;
- char name[NAMELEN];
-
- p = &duartport[s->id];
-
- qlock(p);
- p->wq = WR(q);
- WR(q)->ptr = p;
- RD(q)->ptr = p;
- qunlock(p);
-
- if(p->kstarted == 0){
- p->kstarted = 1;
- sprint(name, "duart%d", s->id+1);
- kproc(name, duartkproc, p);
- }
-
- /* enable the port */
- qlock(p);
- p->op = Dena;
- sleep(&p->opr, opdone, p);
- qunlock(p);
-}
-
-static void
-duartstclose(Queue *q)
-{
- Port *p = q->ptr;
-
- qlock(p);
- p->wq = 0;
- p->iq->putc = 0;
- WR(q)->ptr = 0;
- RD(q)->ptr = 0;
- qunlock(p);
-}
-
-static void
-duartoput(Queue *q, Block *bp)
-{
- Port *p = q->ptr;
- IOQ *cq;
- int n, m;
-
- if(p == 0){
- freeb(bp);
- return;
- }
- cq = p->oq;
- if(waserror()){
- freeb(bp);
- nexterror();
- }
- if(bp->type == M_CTL){
- if(waserror()){
- qunlock(p);
- qunlock(p->d);
- nexterror();
- }
- qlock(p);
- qlock(p->d);
- while (cangetc(cq)) /* let output drain */
- sleep(&cq->r, cangetc, cq);
- n = strtoul((char *)(bp->rptr+1), 0, 0);
- switch(*bp->rptr){
- case 'B':
- case 'b':
- p->val = n;
- p->op = Dbaud;
- sleep(&p->opr, opdone, p);
- break;
- case 'D':
- case 'd':
- p->val = n;
- p->op = Ddtr;
- sleep(&p->opr, opdone, p);
- break;
- case 'K':
- case 'k':
- 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);
- break;
- case 'R':
- case 'r':
- /* can't control? */
- break;
- }
- qunlock(p->d);
- qunlock(p);
- poperror();
- }else while((m = BLEN(bp)) > 0){
- while ((n = canputc(cq)) == 0){
- kprint(" duartoput: sleeping\n");
- sleep(&cq->r, canputc, cq);
- }
- if(n > m)
- n = m;
- (*cq->puts)(cq, bp->rptr, n);
- bp->rptr += n;
- }
- freeb(bp);
- poperror();
-}
-
-/*
- * process to send bytes upstream for a port
- */
-static void
-duartkproc(void *a)
-{
- Port *p = a;
- IOQ *cq = p->iq;
- Block *bp;
- int n;
-
-loop:
- while ((n = cangetc(cq)) == 0)
- sleep(&cq->r, cangetc, cq);
- qlock(p);
- if(p->wq == 0){
- cq->out = cq->in;
- }else{
- bp = allocb(n);
- bp->flags |= S_DELIM;
- bp->wptr += gets(cq, bp->wptr, n);
- PUTNEXT(RD(p->wq), bp);
- }
- qunlock(p);
- goto loop;
-}
-
Dirtab *duartdir;
-int nduartport;
+int nuart;
-/*
- * allocate the queues if no one else has
- */
void
duartreset(void)
{
- Port *p;
int i;
-
- /*
- * allocate the directory and fill it in
- */
- nduartport = 2*conf.nmach;
- duartdir = xalloc(nduartport*2*sizeof(Dirtab));
- for(i = 0; i < nduartport; i++){
- sprint(duartdir[2*i].name, "eia%d", i+1);
- sprint(duartdir[2*i+1].name, "eia%dctl", i+1);
- duartdir[2*i].length = 0;
- duartdir[2*i+1].length = 0;
- duartdir[2*i].perm = 0666;
- duartdir[2*i+1].perm = 0666;
- duartdir[2*i].qid.path = STREAMQID(i, Sdataqid);
- duartdir[2*i+1].qid.path = STREAMQID(i, Sctlqid);
- }
-
- /*
- * allocate queues for any stream interfaces
- */
- for(p = duartport; p < &duartport[nduartport]; p++){
- if(p->nostream)
- continue;
-
- p->iq = xalloc(sizeof(IOQ));
- initq(p->iq);
- p->iq->ptr = p;
-
- p->oq = xalloc(sizeof(IOQ));
- initq(p->oq);
- p->oq->ptr = p;
- p->oq->puts = duartputs;
+ Dirtab *dp;
+
+ nuart = 2*conf.nmach;
+ duartdir = xalloc(2 * nuart * sizeof(Dirtab));
+ dp = duartdir;
+ for(i = 0; i < nuart; i++){
+ /* 2 directory entries per port */
+ print(dp->name, "eia%d", i);
+ dp->qid.path = NETQID(i, Ndataqid);
+ dp->perm = 0666;
+ dp++;
+
+ print(dp->name, "eia%dctl", i);
+ dp->qid.path = NETQID(i, Nctlqid);
+ dp->perm = 0666;
+ dp++;
}
}
@@ 738,19 519,25 @@ duartclone(Chan *c, Chan *nc)
int
duartwalk(Chan *c, char *name)
{
- return devwalk(c, name, duartdir, 2*nduartport, devgen);
+ return devwalk(c, name, duartdir, 2*nuart, devgen);
}
void
-duartstat(Chan *c, char *p)
+duartstat(Chan *c, char *dp)
{
- switch(STREAMTYPE(c->qid.path)){
- case Sdataqid:
- streamstat(c, p, duartdir[2*STREAMID(c->qid.path)].name,
- duartdir[2*STREAMID(c->qid.path)].perm);
+ int i;
+ Uart *p;
+ Dir dir;
+
+ i = NETID(c->qid.path);
+ switch(NETTYPE(c->qid.path)){
+ case Ndataqid:
+ p = &uart[i];
+ devdir(c, c->qid, duartdir[2*i].name, qlen(p->iq), eve, 0660, &dir);
+ convD2M(&dir, dp);
break;
default:
- devstat(c, p, duartdir, 2*nduartport, devgen);
+ devstat(c, dp, duartdir, 2*nuart, devgen);
break;
}
}
@@ 758,75 545,143 @@ duartstat(Chan *c, char *p)
Chan*
duartopen(Chan *c, int omode)
{
- Port *p;
+ Uart *p;
- switch(STREAMTYPE(c->qid.path)){
- case Sdataqid:
- case Sctlqid:
- p = &duartport[STREAMID(c->qid.path)];
- break;
- default:
- p = 0;
- break;
+ if(c->qid.path & CHDIR){
+ if(omode != OREAD)
+ error(Ebadarg);
+ }
+ else {
+ p = &uart[NETID(c->qid.path)];
+ qlock(p);
+ p->opens++;
+ if(p->opens == 1) {
+ /* enable the port */
+ p->op = Dena;
+ sleep(&p->opr, opdone, p);
+
+ qreopen(p->iq);
+ qreopen(p->oq);
+ }
+ qunlock(p);
}
- if(p && p->nostream)
- error(Einuse);
-
- if((c->qid.path & CHDIR) == 0)
- streamopen(c, &duartinfo);
- return devopen(c, omode, duartdir, 2*nduartport, devgen);
+ c->mode = omode&~OTRUNC;
+ c->flag |= COPEN;
+ c->offset = 0;
+ return c;
}
void
duartcreate(Chan *c, char *name, int omode, ulong perm)
{
- USED(c);
- USED(name);
- USED(omode);
- USED(perm);
+ USED(c, name, omode, perm);
error(Eperm);
}
void
duartclose(Chan *c)
{
- if(c->stream)
- streamclose(c);
+ Uart *p;
+
+ if(c->qid.path & CHDIR)
+ return;
+
+ p = &uart[NETID(c->qid.path)];
+ qlock(p);
+ p->opens++;
+ if(p->opens == 0){
+ qclose(p->iq);
+ qclose(p->oq);
+ }
+ qunlock(p);
}
long
duartread(Chan *c, void *buf, long n, ulong offset)
{
- Port *p;
+ Uart *p;
- if(c->qid.path&CHDIR)
- return devdirread(c, buf, n, duartdir, 2*nduartport, devgen);
+ if(c->qid.path & CHDIR)
+ return devdirread(c, buf, n, duartdir, 2*nuart, devgen);
- switch(STREAMTYPE(c->qid.path)){
- case Sdataqid:
- return streamread(c, buf, n);
- case Sctlqid:
- if(offset)
- return 0;
- p = &duartport[STREAMID(c->qid.path)];
- qlock(p);
- p->op = Dstate;
- sleep(&p->opr, opdone, p);
- *(uchar *)buf = p->val;
- qunlock(p);
- return 1;
+ p = &uart[NETID(c->qid.path)];
+ 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);
}
- error(Egreg);
- return 0; /* not reached */
+ return 0;
+}
+
+static void
+duartctl(Uart *p, char *cmd)
+{
+ int n, i;
+
+ /* let output drain for a while */
+ for(i = 0; i < 16 && qlen(p->oq); i++)
+ tsleep(&p->r, qlen, p->oq, 125);
+
+ n = atoi(cmd+1);
+ switch(cmd[0]){
+ case 'B':
+ case 'b':
+ p->val = n;
+ p->op = Dbaud;
+ sleep(&p->opr, opdone, p);
+ break;
+ case 'D':
+ case 'd':
+ p->val = n;
+ p->op = Ddtr;
+ sleep(&p->opr, opdone, p);
+ break;
+ case 'K':
+ case 'k':
+ 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);
+ break;
+ case 'R':
+ case 'r':
+ /* can't control? */
+ break;
+ }
}
long
duartwrite(Chan *c, void *va, long n, ulong offset)
{
+ Uart *p;
+ char cmd[32];
+
USED(offset);
- return streamwrite(c, va, n, 0);
+
+ if(c->qid.path & CHDIR)
+ error(Eperm);
+
+ p = &uart[NETID(c->qid.path)];
+ switch(NETTYPE(c->qid.path)){
+ case Ndataqid:
+ return qwrite(p->oq, va, n, 0);
+ case Nctlqid:
+ if(n >= sizeof(cmd))
+ n = sizeof(cmd)-1;
+ memmove(cmd, va, n);
+ cmd[n] = 0;
+ duartctl(p, cmd);
+ return n;
+ }
}
void
@@ 839,18 694,6 @@ duartremove(Chan *c)
void
duartwstat(Chan *c, char *p)
{
- USED(c);
- USED(p);
+ USED(c, p);
error(Eperm);
}
-
-int
-duartactive(void)
-{
- int i;
-
- for(i = 0; i < nduartport; i++)
- if(duartport[i].printing)
- return 1;
- return 0;
-}
D power/devhs.c => power/devhs.c +0 -595
@@ 1,595 0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "devtab.h"
-
-#include "io.h"
-
-typedef struct Hs Hs;
-
-enum {
- Maxburst= 1023, /* maximum transmit burst size */
- Intvec= 0xd0, /* vme vector for interrupts */
- Intlevel= 5, /* level to interrupt on */
- Nhs= 1,
-
- /*
- * csr flags
- */
- ALIVE = 0x0001,
- IENABLE = 0x0004,
- EXOFLOW = 0x0008,
- IRQ = 0x0010,
- EMUTE = 0x0020,
- EPARITY = 0x0040,
- EFRAME = 0x0080,
- EROFLOW = 0x0100,
- REF = 0x0800,
- XFF = 0x4000,
- XHF = 0x8000,
-
- /*
- * csr reset flags
- */
- FORCEW = 0x0008,
- NORESET = 0xFF00,
- RESET = 0x0000,
-
- /*
- * data flags
- */
- CTL = 0x0100,
- CHNO = 0x0200,
- TXEOD = 0x0400,
- NND = 0x8000,
-};
-
-#define NOW (MACHP(0)->ticks*MS2HZ)
-#define IPL(x) ((x)<<5)
-
-struct Hs {
- QLock;
-
- QLock xmit;
- HSdev *addr;
- int vec; /* interupt vector */
- Rendez r; /* output process */
- Rendez kr; /* input kernel process */
- int chan; /* current input channel */
- Queue *rq; /* read queue */
- uchar buf[1024]; /* bytes being collected */
- uchar *wptr; /* pointer into buf */
- ulong time; /* time byte in buf[0] arrived */
- int kstarted; /* true if kernel process started */
- int started;
-
- /* statistics */
-
- ulong parity; /* parity errors */
- ulong rintr; /* rcv interrupts */
- ulong tintr; /* transmit interrupts */
- ulong in; /* bytes in */
- ulong out; /* bytes out */
-};
-
-Hs hs[Nhs];
-
-static void hsintr(int);
-static void hskproc(void*);
-
-/*
- * hs stream module definition
- */
-static void hsoput(Queue*, Block*);
-static void hsstopen(Queue*, Stream*);
-static void hsstclose(Queue*);
-Qinfo hsinfo =
-{
- nullput,
- hsoput,
- hsstopen,
- hsstclose,
- "hs"
-};
-
-void
-hsrestart(Hs *hp)
-{
- HSdev *addr;
-
- addr = hp->addr;
-
- addr->csr = RESET;
- wbflush();
- delay(20);
-
- /*
- * set interrupt vector
- * turn on device
- * set forcew to a known value
- * interrupt on level `Intlevel'
- */
- addr->vector = hp->vec;
- addr->csr = NORESET|IPL(Intlevel)|IENABLE|ALIVE;
- wbflush();
- delay(1);
- addr->csr = NORESET|IPL(Intlevel)|FORCEW|IENABLE|ALIVE;
- wbflush();
- delay(1);
- hp->started = 1;
-}
-
-/*
- * reset all vme boards
- */
-void
-hsreset(void)
-{
- int i;
- Hs *hp;
-
- for(i=0; i<Nhs; i++){
- hp = &hs[i];
- hp->addr = HSDEV+i;
- hp->vec = Intvec+i;
- hp->addr->csr = RESET;
- setvmevec(hp->vec, hsintr);
- }
- wbflush();
- delay(20);
-}
-
-void
-hsinit(void)
-{
-}
-
-/*
- * enable the device for interrupts, spec is the device number
- */
-Chan*
-hsattach(char *spec)
-{
- Hs *hp;
- int i;
- Chan *c;
-
- i = strtoul(spec, 0, 0);
- if(i >= Nhs)
- error(Ebadarg);
- hp = &hs[i];
- if(!hp->started)
- hsrestart(hp);
-
- c = devattach('h', spec);
- c->dev = i;
- c->qid.path = CHDIR;
- return c;
-}
-
-Chan*
-hsclone(Chan *c, Chan *nc)
-{
- return devclone(c, nc);
-}
-
-int
-hswalk(Chan *c, char *name)
-{
- return devwalk(c, name, 0, 0, streamgen);
-}
-
-void
-hsstat(Chan *c, char *dp)
-{
- devstat(c, dp, 0, 0, streamgen);
-}
-
-Chan*
-hsopen(Chan *c, int omode)
-{
- if(c->qid.path == CHDIR){
- if(omode != OREAD)
- error(Eperm);
- }else
- streamopen(c, &hsinfo);
- c->mode = openmode(omode);
- c->flag |= COPEN;
- c->offset = 0;
- return c;
-}
-
-void
-hscreate(Chan *c, char *name, int omode, ulong perm)
-{
- USED(c);
- USED(name);
- USED(omode);
- USED(perm);
- error(Eperm);
-}
-
-void
-hsclose(Chan *c)
-{
- if(c->qid.path != CHDIR)
- streamclose(c);
-}
-
-long
-hsread(Chan *c, void *buf, long n, ulong offset)
-{
- USED(offset);
- return streamread(c, buf, n);
-}
-
-long
-hswrite(Chan *c, void *buf, long n, ulong offset)
-{
- USED(offset);
- return streamwrite(c, buf, n, 0);
-}
-
-void
-hsremove(Chan *c)
-{
- USED(c);
- error(Eperm);
-}
-
-void
-hswstat(Chan *c, char *dp)
-{
- USED(c);
- USED(dp);
- error(Eperm);
-}
-
-/*
- * the stream routines
- */
-
-/*
- * create the kernel process for input
- */
-static void
-hsstopen(Queue *q, Stream *s)
-{
- Hs *hp;
- char name[32];
-
- hp = &hs[s->dev];
- sprint(name, "hs%d", s->dev);
- q->ptr = q->other->ptr = hp;
- hp->rq = q;
- kproc(name, hskproc, hp);
-}
-
-/*
- * ask kproc to die and wait till it happens
- */
-static int
-kdead(void *arg)
-{
- Hs *hp;
-
- hp = (Hs *)arg;
- return hp->kstarted == 0;
-}
-static void
-hsstclose(Queue * q)
-{
- Hs *hp;
-
- hp = (Hs *)q->ptr;
- qlock(hp);
- hp->rq = 0;
- qunlock(hp);
- while(waserror())
- ;
- while(hp->kstarted){
- wakeup(&hp->kr);
- sleep(&hp->r, kdead, hp);
- }
- poperror();
-}
-
-/*
- * free all blocks of a message in `q', `bp' is the first block
- * of the message
- */
-static void
-freemsg(Queue *q, Block *bp)
-{
- for(; bp; bp = getq(q)){
- if(bp->flags & S_DELIM){
- freeb(bp);
- return;
- }
- freeb(bp);
- }
-}
-
-/*
- * return true if the output fifo is at least half empty.
- * the implication is that it can take at least another 1000 byte burst.
- */
-static int
-halfempty(void *arg)
-{
- HSdev *addr;
-
- addr = (HSdev*)arg;
- return addr->csr & XHF;
-}
-
-/*
- * output a block
- *
- * the first 2 bytes of every message are the channel number,
- * low order byte first. the third is a possible trailing control
- * character.
- */
-void
-hsoput(Queue *q, Block *bp)
-{
- HSdev *addr;
- Hs *hp;
- int burst;
- int chan;
- int ctl;
- int n;
-
- if(bp->type != M_DATA){
- freeb(bp);
- return;
- }
- if(BLEN(bp) < 3){
- bp = pullup(bp, 3);
- if(bp == 0){
- print("hsoput pullup failed\n");
- return;
- }
- }
-
- /*
- * get a whole message before handing bytes to the device
- */
- if(!putq(q, bp))
- return;
-
- /*
- * one transmitter at a time
- */
- hp = (Hs *)q->ptr;
- qlock(&hp->xmit);
- if(waserror()){
- qunlock(&hp->xmit);
- nexterror();
- }
- addr = hp->addr;
-
- /*
- * parse message
- */
- bp = getq(q);
- chan = CHNO | bp->rptr[0] | (bp->rptr[1]<<8);
- ctl = bp->rptr[2];
- bp->rptr += 3;
-
- /*
- * send the 8 bit data, burst are up to Maxburst (9-bit) bytes long
- */
- if(!(addr->csr & XHF))
- sleep(&hp->r, halfempty, addr);
-/* print("->%.2uo\n", CHNO|chan);/**/
- addr->data = CHNO|chan;
- burst = Maxburst;
- while(bp){
- if(burst == 0){
- addr->data = TXEOD;
-/* print("->%.2uo\n", TXEOD); /**/
- if(!(addr->csr & XHF))
- sleep(&hp->r, halfempty, addr);
-/* print("->%.2uo\n", CHNO|chan); /**/
- addr->data = CHNO|chan;
- burst = Maxburst;
- }
- n = bp->wptr - bp->rptr;
- if(n > burst)
- n = burst;
- burst -= n;
- while(n--){
-/* print("->%.2uo\n", *bp->rptr); /**/
- addr->data = *bp->rptr++;
- }
- if(bp->rptr >= bp->wptr){
- if(bp->flags & S_DELIM){
- freeb(bp);
- break;
- }
- freeb(bp);
- bp = getq(q);
- }
- }
-
- /*
- * send the control byte if there is one
- */
- if(ctl){
-/* print("->%.2uo\n", CTL|ctl); /**/
- addr->data = CTL|ctl;
- }
-
- /*
- * start the fifo emptying
- */
-/* print("->%.2uo\n", TXEOD); /**/
- addr->data = TXEOD;
-
- qunlock(&hp->xmit);
- poperror();
-}
-
-/*
- * return true if the input fifo is non-empty
- */
-static int
-notempty(void *arg)
-{
- HSdev *addr;
-
- addr = (HSdev *)arg;
- return addr->csr & REF;
-}
-
-/*
- * fill a block with what is currently buffered and send it upstream
- */
-static void
-upstream(Hs *hp, unsigned int ctl)
-{
- int n;
- Block *bp;
-
- n = hp->wptr - hp->buf;
- bp = allocb(3 + n);
- bp->wptr[0] = hp->chan;
- bp->wptr[1] = hp->chan>>8;
- bp->wptr[2] = ctl;
- if(n)
- memmove(&bp->wptr[3], hp->buf, n);
- bp->wptr += 3 + n;
- bp->flags |= S_DELIM;
- PUTNEXT(hp->rq, bp);
- hp->wptr = hp->buf;
- hp->time = 0;
-}
-
-/*
- * Read bytes from the input fifo. Since we take an interrupt every
- * time the fifo goes non-empty, we need to waste time to let the
- * fifo fill up.
- */
-static void
-hskproc(void *arg)
-{
- Hs *hp;
- HSdev *addr;
- unsigned int c;
- int locked;
-
- hp = (Hs *)arg;
- addr = hp->addr;
- hp->kstarted = 1;
- hp->wptr = hp->buf;
-
- locked = 0;
- if(waserror()){
- if(locked)
- qunlock(hp);
- hp->kstarted = 0;
- wakeup(&hp->r);
- return;
- }
-
- for(;;){
- /*
- * die if the device is closed
- */
- USED(locked); /* so locked = 0 and locked = 1 stay */
- qlock(hp);
- locked = 1;
- if(hp->rq == 0){
- qunlock(hp);
- hp->kstarted = 0;
- wakeup(&hp->r);
- poperror();
- return;
- }
-
- /*
- * 0xFFFF means an empty fifo
- */
- while((c = addr->data) != 0xFFFF){
- hp->in++;
- if(c & CHNO){
- c &= 0x1FF;
- if(hp->chan == c)
- continue;
- /*
- * new channel, put anything saved upstream
- */
- if(hp->wptr - hp->buf != 0)
- upstream(hp, 0);
- hp->chan = c;
- } else if(c & NND){
- /*
- * ctl byte, this ends a message
- */
- upstream(hp, c);
- } else {
- /*
- * data byte, put in local buffer
- */
- if(hp->time == 0)
- hp->time = NOW + 100;
- *hp->wptr++ = c;
- if(hp->wptr == &hp->buf[sizeof hp->buf])
- upstream(hp, 0);
- }
- }
- if(hp->time && NOW >= hp->time)
- upstream(hp, 0);
- USED(locked);
- qunlock(hp);
- locked = 0;
-
- /*
- * Sleep if input fifo empty. Make sure we don't hold onto
- * any byte for more than 1/10 second.
- */
- if(!(addr->csr & REF)){
- if(hp->wptr == hp->buf)
- tsleep(&hp->kr, notempty, addr, 2000);
- else
- tsleep(&hp->kr, notempty, addr, 100);
- }
- }
-}
-
-/*
- * only one flavor interrupt. we have to use the less than half full
- * and not empty bits to figure out whom to wake.
- */
-static void
-hsintr(int vec)
-{
- ushort csr;
- Hs *hp;
-
- hp = &hs[vec - Intvec];
- if(hp < hs || hp > &hs[Nhs]){
- print("bad hs vec\n");
- return;
- }
- csr = hp->addr->csr;
-
- if(csr & REF){
- hp->rintr++;
- wakeup(&hp->kr);
- }
- if(csr & XHF){
- hp->tintr++;
- wakeup(&hp->r);
- }
- if((csr^XFF) & (XFF|EROFLOW|EFRAME|EPARITY|EXOFLOW)){
- hp->parity++;
- hsrestart(hp);
- print("hs %d: reset, csr = 0x%ux\n",
- vec - Intvec, csr);
- }
-}
M power/fns.h => power/fns.h +3 -3
@@ 9,14 9,13 @@ void confprint(void);
void confset(char*);
int conschar(void);
void dcflush(void*, ulong);
-void debugger(void*);
int duartactive(void);
void duartenable0(void);
void duartinit(void);
void duartintr(void);
void duartreset(void);
void duartslave(void);
-void duartspecial(int, IOQ*, IOQ*, int);
+void duartspecial(int, int, Queue**, Queue**, int (*)(Queue*, int));
void duartxmit(int);
void evenaddr(ulong);
void faultmips(Ureg*, int, int);
@@ 32,6 31,7 @@ ulong getcallerpc(void*);
void icflush(void *, ulong);
void ioboardinit(void);
void intr(Ureg*);
+int iprint(char*, ...);
void kbdchar(int);
void kproftimer(ulong);
void lanceintr(void);
@@ 58,7 58,7 @@ void puttlb(ulong, ulong);
void puttlbx(int, ulong, ulong);
int readlog(ulong, char*, ulong);
void restfpregs(FPsave*, ulong);
-#define screenputs syslog
+#define screenputs(a, b)
void scsiintr(int);
void setvmevec(int, void (*)(int));
void sinit(void);
D power/ipdat.h => power/ipdat.h +0 -440
@@ 1,440 0,0 @@
-typedef struct Ipconv Ipconv;
-typedef struct Ipifc Ipifc;
-typedef struct Fragq Fragq;
-typedef struct Ipfrag Ipfrag;
-typedef ulong Ipaddr;
-typedef struct Arpcache Arpcache;
-typedef ushort Port;
-typedef struct Udphdr Udphdr;
-typedef struct Etherhdr Etherhdr;
-typedef struct Reseq Reseq;
-typedef struct Tcp Tcp;
-typedef struct Tcpctl Tcpctl;
-typedef struct Tcphdr Tcphdr;
-typedef struct Timer Timer;
-
-struct Etherhdr {
-#define ETHER_HDR 14
- uchar d[6];
- uchar s[6];
- uchar type[2];
-
- /* Now we have the ip fields */
-#define ETHER_IPHDR 20
- uchar vihl; /* Version and header length */
- uchar tos; /* Type of service */
- uchar length[2]; /* packet length */
- uchar id[2]; /* Identification */
- uchar frag[2]; /* Fragment information */
- uchar ttl; /* Time to live */
- uchar proto; /* Protocol */
- uchar cksum[2]; /* Header checksum */
- uchar src[4]; /* Ip source */
- uchar dst[4]; /* Ip destination */
-};
-
-/* Ethernet packet types */
-#define ET_IP 0x0800
-
-/* A userlevel data gram */
-struct Udphdr {
-#define UDP_EHSIZE 22
- uchar d[6]; /* Ethernet destination */
- uchar s[6]; /* Ethernet source */
- uchar type[2]; /* Ethernet packet type */
- uchar vihl; /* Version and header length */
- uchar tos; /* Type of service */
- uchar length[2]; /* packet length */
- uchar id[2]; /* Identification */
- uchar frag[2]; /* Fragment information */
-
- /* Udp pseudo ip really starts here */
-#define UDP_PHDRSIZE 12
-#define UDP_HDRSIZE 20
- uchar Unused;
- uchar udpproto; /* Protocol */
- uchar udpplen[2]; /* Header plus data length */
- uchar udpsrc[4]; /* Ip source */
- uchar udpdst[4]; /* Ip destination */
- uchar udpsport[2]; /* Source port */
- uchar udpdport[2]; /* Destination port */
- uchar udplen[2]; /* data length */
- uchar udpcksum[2]; /* Checksum */
-};
-
-#define TCP_PKT (TCP_EHSIZE+TCP_IPLEN+TCP_PHDRSIZE)
-
-struct Tcphdr {
-#define TCP_EHSIZE 14
- uchar d[6]; /* Ethernet destination */
- uchar s[6]; /* Ethernet source */
- uchar type[2]; /* Ethernet packet type */
-#define TCP_IPLEN 8
- uchar vihl; /* Version and header length */
- uchar tos; /* Type of service */
- uchar length[2]; /* packet length */
- uchar id[2]; /* Identification */
- uchar frag[2]; /* Fragment information */
-
-#define TCP_PHDRSIZE 12
- uchar Unused;
- uchar proto;
- uchar tcplen[2];
- uchar tcpsrc[4];
- uchar tcpdst[4];
-
-#define TCP_HDRSIZE 20
- uchar tcpsport[2];
- uchar tcpdport[2];
- uchar tcpseq[4];
- uchar tcpack[4];
- uchar tcpflag[2];
- uchar tcpwin[2];
- uchar tcpcksum[2];
- uchar tcpurg[2];
-
- /* Options segment */
- uchar tcpopt[2];
- uchar tcpmss[2];
- };
-
-
-
-struct Timer {
- Timer *next;
- Timer *prev;
- int state;
- int start;
- int count;
- void (*func)(void*);
- void *arg;
- };
-
-struct Tcpctl {
- QLock;
- uchar state; /* Connection state */
- uchar type; /* Listening or active connection */
- uchar code; /* Icmp code */
- struct {
- int una; /* Unacked data pointer */
- int nxt; /* Next sequence expected */
- int ptr; /* Data pointer */
- ushort wnd; /* Tcp send window */
- int up; /* Urgent data pointer */
- int wl1;
- int wl2;
- } snd;
- int iss;
- ushort cwind;
- ushort ssthresh;
- int resent;
- struct {
- int nxt;
- ushort wnd;
- int up;
- } rcv;
- int irs;
- ushort mss;
- int rerecv;
- ushort window;
- int max_snd;
- int last_ack;
- char backoff;
- char flags;
- char tos;
-
- Block *rcvq;
- ushort rcvcnt;
-
- Block *rcvoobq;
- ushort rcvoobcnt;
-
- Block *sndq; /* List of data going out */
- ushort sndcnt; /* Amount of data in send queue */
-
- Block *sndoobq; /* List of blocks going oob */
- ushort sndoobcnt; /* Size of out of band queue */
- ushort oobmark; /* Out of band sequence mark */
- char oobflags; /* Out of band data flags */
-
- Reseq *reseq; /* Resequencing queue */
- Timer timer;
- Timer acktimer; /* Acknoledge timer */
- Timer rtt_timer; /* Round trip timer */
- int rttseq; /* Round trip sequence */
- int srtt; /* Shortened round trip */
- int mdev; /* Mean deviation of round trip */
-};
-
-struct Tcp {
- Port source;
- Port dest;
- int seq;
- int ack;
- char flags;
- ushort wnd;
- ushort up;
- ushort mss;
- };
-
-struct Reseq {
- Reseq *next;
- Tcp seg;
- Block *bp;
- ushort length;
- char tos;
- };
-
-/* An ip interface used for UDP/TCP/ARP/ICMP */
-struct Ipconv {
- QLock; /* Ref count lock */
- int ref;
- Qinfo *stproto; /* Stream protocol for this device */
- Ipaddr dst; /* Destination from connect */
-
- Port psrc; /* Source port */
- Port pdst; /* Destination port */
-
- uchar ptype; /* Source port type */
- Ipifc *ipinterface; /* Ip protocol interface */
- Queue *readq; /* Pointer to upstream read q */
-
- QLock listenq; /* List of people waiting incoming cons */
- Rendez listenr; /* Some where to sleep while waiting */
- Ipconv *listen;
-
- char err; /* Async protocol error */
- int backlog; /* Maximum number of waiting connections */
- int curlog; /* Number of waiting connections */
- int contype;
- Tcpctl tcpctl; /* Tcp control block */
-};
-
-#define MAX_TIME 100000000 /* Forever */
-#define TCP_ACK 200 /* Timed ack sequence every 200ms */
-
-#define URG 0x20
-#define ACK 0x10
-#define PSH 0x08
-#define RST 0x04
-#define SYN 0x02
-#define FIN 0x01
-
-#define EOL_KIND 0
-#define NOOP_KIND 1
-#define MSS_KIND 2
-
-#define MSS_LENGTH 4
-#define MSL2 10
-#define MSPTICK 200
-#define DEF_MSS 1024
-#define DEF_RTT 1000
-#define TCPOOB_HADDATA 1
-#define TCPOOB_HAVEDATA 2
-
-#define TCP_PASSIVE 0
-#define TCP_ACTIVE 1
-
-#define MAXBACKOFF 5
-#define FORCE 1
-#define CLONE 2
-#define RETRAN 4
-#define ACTIVE 8
-#define SYNACK 16
-#define AGAIN 8
-#define DGAIN 4
-
-#define TIMER_STOP 0
-#define TIMER_RUN 1
-#define TIMER_EXPIRE 2
-
-#define set_timer(t,x) (((t)->start) = (x)/MSPTICK)
-#define dur_timer(t) ((t)->start)
-#define read_timer(t) ((t)->count)
-#define run_timer(t) ((t)->state == TIMER_RUN)
-
-enum {
- CLOSED = 0,
- LISTEN,
- SYN_SENT,
- SYN_RECEIVED,
- ESTABLISHED,
- FINWAIT1,
- FINWAIT2,
- CLOSE_WAIT,
- CLOSING,
- LAST_ACK,
- TIME_WAIT
- };
-
-/*
- * Ip interface structure. We have one for each active protocol driver
- */
-struct Ipifc {
- QLock;
- int ref;
- uchar protocol; /* Ip header protocol number */
- char name[NAMELEN]; /* Protocol name */
- void (*iprcv) (Ipconv *, Block *); /* Receive demultiplexor */
- Ipconv *connections; /* Connection list */
- int maxmtu; /* Maximum transfer unit */
- int minmtu; /* Minumum tranfer unit */
- int hsize; /* Media header size */
- Lock;
-};
-
-struct Fragq {
- QLock;
- Block *blist;
- Fragq *next;
- Ipaddr src;
- Ipaddr dst;
- ushort id;
- };
-
-struct Ipfrag {
- ushort foff;
- ushort flen;
- };
-
-struct Arpcache {
- uchar status; /* Entry status */
- uchar type; /* Entry type */
- Ipaddr ip; /* Host byte order */
- uchar eip[4]; /* Network byte order */
- uchar et[6]; /* Ethernet address for this ip */
- int age; /* Entry timeout */
- Arpcache *hash;
- Arpcache **hashhd;
- Arpcache *frwd;
- Arpcache *prev;
-};
-#define ARP_FREE 0
-#define ARP_OK 1
-#define ARP_ASKED 2
-#define ARP_TEMP 0
-#define ARP_PERM 1
-#define Arphashsize 32
-#define ARPHASH(p) arphash[((p[2]^p[3])%Arphashsize)]
-#define ARP_WAITMS 2500 /* Wait for arp replys */
-
-#define IP_VER 0x40 /* Using IP version 4 */
-#define IP_HLEN 0x05 /* Header length in characters */
-#define IP_DF 0x4000 /* Don't fragment */
-#define IP_MF 0x2000 /* More fragments */
-
-#define ICMP_ECHOREPLY 0 /* Echo Reply */
-#define ICMP_UNREACH 3 /* Destination Unreachable */
-#define ICMP_SOURCEQUENCH 4 /* Source Quench */
-#define ICMP_REDIRECT 5 /* Redirect */
-#define ICMP_ECHO 8 /* Echo Request */
-#define ICMP_TIMXCEED 11 /* Time-to-live Exceeded */
-#define ICMP_PARAMPROB 12 /* Parameter Problem */
-#define ICMP_TSTAMP 13 /* Timestamp */
-#define ICMP_TSTAMPREPLY 14 /* Timestamp Reply */
-#define ICMP_IREQ 15 /* Information Request */
-#define ICMP_IREQREPLY 16 /* Information Reply */
-
-/* Sizes */
-#define IP_MAX 8192 /* Maximum Internet packet size */
-#define UDP_MAX (IP_MAX-ETHER_IPHDR) /* Maximum UDP datagram size */
-#define UDP_DATMAX (UDP_MAX-UDP_HDRSIZE) /* Maximum amount of udp data */
-
-/* Protocol numbers */
-#define IP_UDPPROTO 17
-#define IP_TCPPROTO 6
-
-/* Protocol port numbers */
-#define PORTALLOC 5000 /* First automatic allocated port */
-#define PRIVPORTALLOC 600 /* First priveleged port allocated */
-#define PORTMAX 30000 /* Last port to allocte */
-
-/* Stuff to go in funs.h someday */
-Ipifc *newipifc(uchar, void (*)(Ipconv *, Block*), Ipconv *, int, int, int, char*);
-void closeipifc(Ipifc*);
-ushort ip_csum(uchar*);
-int arp_lookup(uchar*, uchar*);
-Ipaddr ipparse(char*);
-void hnputs(uchar*, ushort);
-void hnputl(uchar*, ulong);
-ulong nhgetl(uchar*);
-ushort nhgets(uchar*);
-ushort ptcl_csum(Block*bp, int, int);
-void ppkt(Block*);
-void udprcvmsg(Ipconv *, Block*);
-Block *btrim(Block*, int, int);
-Block *ip_reassemble(int, Block*, Etherhdr*);
-Ipconv *portused(Ipconv *, Port);
-Port nextport(Ipconv *, Port);
-void arp_enter(Arpentry*, int);
-void arp_flush(void);
-int arp_delete(char*);
-void arplinkhead(Arpcache*);
-Fragq *ipfragallo(void);
-void ipfragfree(Fragq*);
-void iproute(uchar*, uchar*);
-void initfrag(int);
-Block *copyb(Block*, int);
-int ntohtcp(Tcp*, Block**);
-void reset(Ipaddr, Ipaddr, char, ushort, Tcp*);
-void proc_syn(Ipconv*, char, Tcp*);
-void send_syn(Tcpctl*);
-void tcp_output(Ipconv*);
-int seq_within(int, int, int);
-void update(Ipconv *, Tcp *);
-int trim(Tcpctl *, Tcp *, Block **, ushort *);
-void add_reseq(Tcpctl *, char, Tcp *, Block *, ushort);
-void close_self(Ipconv *, int);
-int seq_gt(int, int);
-void appendb(Block **, Block *);
-Ipconv *ip_conn(Ipconv *, Port, Port, Ipaddr dest, char proto);
-void ipmkdir(Qinfo *, Dirtab *, Ipconv *);
-int inb_window(Tcpctl *, int);
-Block *htontcp(Tcp *, Block *, Tcphdr *);
-void start_timer(Timer *);
-void stop_timer(Timer *);
-int copyupb(Block **, uchar *, int);
-void init_tcpctl(Ipconv *);
-void close_self(Ipconv *, int);
-int iss(void);
-int seq_within(int, int, int);
-int seq_lt(int, int);
-int seq_le(int, int);
-int seq_gt(int, int);
-int seq_ge(int, int);
-void setstate(Ipconv *, char);
-void tcpackproc(void*);
-Block *htontcp(Tcp *, Block *, Tcphdr *);
-int ntohtcp(Tcp *, Block **);
-void extract_oob(Block **, Block **, Tcp *);
-void get_reseq(Tcpctl *, char *, Tcp *, Block **, ushort *);
-void state_upcall(Ipconv*, char oldstate, char newstate);
-int backoff(int);
-int dupb(Block **, Block *, int, int);
-void tcp_input(Ipconv *, Block *);
-void tcprcvwin(Ipconv *);
-void open_tcp(Ipconv *, int, ushort, char);
-void tcpflow(void*);
-void tcp_timeout(void *);
-void tcp_acktimer(void *);
-Ipconv *ipclonecon(Chan *);
-void iplisten(Chan *, Ipconv *, Ipconv *);
-
-#define fmtaddr(xx) (xx>>24)&0xff,(xx>>16)&0xff,(xx>>8)&0xff,xx&0xff
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-#define BLKIP(xp) ((Etherhdr *)((xp)->rptr))
-#define BLKFRAG(xp) ((Ipfrag *)((xp)->rptr))
-#define PREC(x) ((x)>>5 & 7)
-
-#define WORKBUF 64
-
-extern Ipaddr Myip;
-extern Ipaddr Mymask;
-extern Ipaddr classmask[4];
-extern Ipconv *ipconv[];
-extern char *tcpstate[];
-extern Rendez tcpflowr;
-extern Qinfo tcpinfo;
-extern Qinfo ipinfo;
-extern Qinfo udpinfo;
M power/main.c => power/main.c +12 -11
@@ 23,22 23,24 @@ main(void)
machinit();
active.exiting = 0;
active.machs = 1;
+iprint("Boot baby\n");
arginit();
confinit();
lockinit();
xinit();
+ duartinit();
printinit();
- duartspecial(0, &printq, &kbdq, 9600);
- print("\n\nBRAZIL\n");
+ duartspecial(0, 9600, &kbdq, &printq, kbdcr2nl);
+iprint("F:\n", printq);
+ print("\n\nBrazil\n");
pageinit();
tlbinit();
- vecinit();
procinit0();
+ vecinit();
initseg();
clockinit();
ioboardinit();
chandevreset();
- streaminit();
swapinit();
userinit();
launchinit();
@@ 55,7 57,6 @@ machinit(void)
memset(m, 0, sizeof(Mach));
m->machno = n;
m->stb = &stlb[n][0];
- duartinit();
m->ledval = 0xff;
}
@@ 307,12 308,12 @@ launch(int n)
void
online(void)
{
-
machinit();
lock(&active);
active.machs |= 1<<m->machno;
unlock(&active);
tlbinit();
+ duartinit();
clockinit();
schedinit();
}
@@ 636,9 637,9 @@ lanceIO2setup(Lance *lp)
* Start at 4k to avoid the initialization block and
* descriptor rings.
*/
- lp->lrp = (Etherpkt*)(4*1024);
+ lp->lrp = (Lancepkt*)(4*1024);
lp->ltp = lp->lrp + lp->nrrb;
- lp->rp = (Etherpkt*)(((ulong)LANCERAM) + (ulong)lp->lrp);
+ lp->rp = (Lancepkt*)(((ulong)LANCERAM) + (ulong)lp->lrp);
lp->tp = lp->rp + lp->nrrb;
}
@@ 670,11 671,11 @@ lanceIO3setup(Lance *lp)
* allocate some host memory for buffers and map it into lance
* space
*/
- len = (lp->nrrb + lp->ntrb)*sizeof(Etherpkt);
- lp->rp = (Etherpkt*)xspanalloc(len , BY2PG, 0);
+ len = (lp->nrrb + lp->ntrb)*sizeof(Lancepkt);
+ lp->rp = (Lancepkt*)xspanalloc(len , BY2PG, 0);
lp->tp = lp->rp + lp->nrrb;
x = (ulong)lp->rp;
- lp->lrp = (Etherpkt*)(x & 0xFFF);
+ lp->lrp = (Lancepkt*)(x & 0xFFF);
lp->ltp = lp->lrp + lp->nrrb;
index = LANCEINDEX;
for(y = x+len; x < y; x += 0x1000){
M power/mmu.c => power/mmu.c +2 -2
@@ 70,10 70,10 @@ putmmu(ulong tlbvirt, ulong tlbphys, Page *pg)
splhi();
ctl = &pg->cachectl[m->machno];
- if(*ctl == PG_TXTFLUSH) {
+ if(*ctl & PG_TXTFLUSH) {
dcflush((void*)pg->pa, BY2PG);
icflush((void*)pg->pa, BY2PG);
- *ctl = PG_NOFLUSH;
+ *ctl &= ~PG_TXTFLUSH;
}
tp = up->pidonmach[m->machno];
M power/trap.c => power/trap.c +2 -0
@@ 245,10 245,12 @@ intr(Ureg *ur)
any = 1;
if(v & (1<<2))
lanceintr();
+/*
if(v & (1<<1))
scsiintr(1);
if(v & (1<<0))
scsiintr(0);
+*/
}
}
/*