From 650ae0cfac7ea871a7ad2684ad2142de8e456094 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 28 Mar 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-03-28 --- port/devnonet.c | 69 +++++++++++++++++++------- port/stnoether.c | 21 ++++++-- port/stream.c | 37 +++++++------- power/dat.h | 120 ---------------------------------------------- power/devhotrod.c | 12 +++++ power/fns.h | 4 -- ss/dat.h | 118 --------------------------------------------- ss/fns.h | 5 -- 8 files changed, 100 insertions(+), 286 deletions(-) diff --git a/port/devnonet.c b/port/devnonet.c index fdd5b4e7b1cf389382d55f8d539efde64da4c584..4675c9fa10895fde653b2909826152023304edc0 100644 --- a/port/devnonet.c +++ b/port/devnonet.c @@ -5,6 +5,7 @@ #include "fns.h" #include "io.h" #include "errno.h" +#include "../port/nonet.h" #define DPRINT if(pnonet)print #define NOW (MACHP(0)->ticks*MS2HZ) @@ -510,6 +511,10 @@ noclose(Queue *q) norack(cp, cp->out[i].mid); cp->rcvcircuit = -1; cp->state = Cclosed; + if(cp->media){ + freeb(cp->media); + cp->media = 0; + } qunlock(cp); poperror(); @@ -885,11 +890,12 @@ nohangup(Noconv *cp) } /* - * send a hangup signal up the stream to get all line disciplines - * to cease and desist. The Creset state makes any subsequent close not - * send hangup messages. + * Send a hangup signal up the stream to get all line disciplines + * to cease and desist. Disassociate this conversation from a circuit + * number. Any subsequent close of the conversation will + * not send hangup messages. * - * State Transition: {Cconnected, Cconnecting} -> Creset + * State Transition: {Cconnected, Cconnecting, Chungup} -> Creset */ static void noreset(Noconv *cp) @@ -900,8 +906,11 @@ noreset(Noconv *cp) switch(cp->state){ case Cconnected: case Cconnecting: + case Chungup: + print("resetting connection\n"); cp->state = Creset; - bp = allocb(0); + cp->rcvcircuit = -1; + bp = allocb(0); bp->type = M_HANGUP; q = cp->rq; PUTNEXT(q, bp); @@ -1145,15 +1154,48 @@ nonetrcvmsg(Noconv *cp, Block *bp) f = h->flag; /* - * if a new call request comes in on a connected channel, hang up the call + * Obey reset even if the message id is bogus */ - if((f&NO_NEWCALL) && cp->state==Cconnected){ - print("new call on connected channel\n"); - freeb(bp); + if(f & NO_RESET){ + print("reset received\n"); noreset(cp); + freeb(bp); return; } + /* + * A new call request (maybe), treat it as a reset if seen on a + * connected, hungup, or reset channel. + * + * On a connecting channel, treat as a reset if this is an + * invalid message ID. + */ + if(f & NO_NEWCALL){ + switch(cp->state){ + case Cclosed: + case Copen: + case Cannounced: + case Creset: + panic("nonetrcvmsg %d %d\n", cp->rcvcircuit, cp - cp->ifc->conv); + case Chungup: + case Cconnected: + print("Nonet call on connected/hanging-up circ %d conv %d\n", + cp->rcvcircuit, cp - cp->ifc->conv); + freeb(bp); + noreset(cp); + return; + case Cconnecting: + if(h->mid != mp->mid){ + print("Nonet call on connecting circ %d conv %d\n", + cp->rcvcircuit, cp - cp->ifc->conv); + freeb(bp); + noreset(cp); + return; + } + break; + } + } + /* * ignore old messages and process the acknowledgement */ @@ -1161,9 +1203,7 @@ nonetrcvmsg(Noconv *cp, Block *bp) DPRINT("old msg %d instead of %d r==%d\n", h->mid, mp->mid, r); if(r == 0){ norack(cp, h->ack); - if(f & NO_RESET) - noreset(cp); - else if(f & NO_HANGUP) + if(f & NO_HANGUP) nohangup(cp); } else { if(r>0){ @@ -1243,10 +1283,7 @@ nonetrcvmsg(Noconv *cp, Block *bp) /* * hangup (after processing message) */ - if(f & NO_RESET){ - DPRINT("reset with message\n"); - noreset(cp); - } else if(f & NO_HANGUP){ + if(f & NO_HANGUP){ DPRINT("hangup with message\n"); nohangup(cp); } diff --git a/port/stnoether.c b/port/stnoether.c index 875c18001875978803f69a2ddb316e3c71240a50..acbbe52c9560e57b792fd610eedfbec0d448dd43 100644 --- a/port/stnoether.c +++ b/port/stnoether.c @@ -11,6 +11,7 @@ #include "fns.h" #include "io.h" #include "errno.h" +#include "../port/nonet.h" #define DPRINT if(pnonet)print extern int pnonet; @@ -116,12 +117,12 @@ noetheroput(Queue *q, Block *bp) * respond to a misaddressed message with a close */ void -noetherbad(Noifc *ifc, Block *bp) +noetherbad(Noifc *ifc, Block *bp, int circuit) { Etherhdr *eh, *neh; - int circuit; Block *nbp; int r; + Noconv *cp, *ep; /* * crack the packet header @@ -129,10 +130,22 @@ noetherbad(Noifc *ifc, Block *bp) eh = (Etherhdr *)bp->rptr; print("bad %.2ux%.2ux%.2ux%.2ux%.2ux%.2ux c %d m %d f %d\n", eh->s[0], eh->s[1], eh->s[2], eh->s[3], eh->s[4], - eh->s[5], eh->circuit[0], eh->mid, eh->flag); + eh->s[5], circuit, eh->mid, eh->flag); if(eh->flag & NO_RESET) goto out; +ep = &ifc->conv[conf.nnoconv]; +for(cp = &ifc->conv[0]; cp < ep; cp++){ + qlock(cp); + if(cp->media){ + neh = (Etherhdr *)(cp->media->rptr); + print("%lux %.2ux%.2ux%.2ux%.2ux%.2ux%.2ux %s c %d\n", neh, + neh->s[0], neh->s[1], neh->s[2], neh->s[3], neh->s[4], + neh->s[5], cp->raddr, cp->rcvcircuit); + } + qunlock(cp); +} + /* * only one reset per message */ @@ -221,7 +234,7 @@ noetheriput(Queue *q, Block *bp) * if not a new call, then its misaddressed */ if((h->flag & NO_NEWCALL) == 0){ - noetherbad(ifc, bp); + noetherbad(ifc, bp, circuit); return; } diff --git a/port/stream.c b/port/stream.c index 255120d2a31f702f89c2684b252f13fe2e617b92..815ee12fa1b5146a4ce71021268fe3a8640c092a 100644 --- a/port/stream.c +++ b/port/stream.c @@ -227,6 +227,9 @@ allocb(ulong size) bp->next = 0; bp->type = M_DATA; bp->flags &= S_CLASS; + if(bp->lim-bp->rptrlim, bp->rptr, + size, bp->flags, bcp-bclass); return bp; } @@ -237,31 +240,27 @@ allocb(ulong size) void freeb(Block *bp) { + Block *nbp; Bclass *bcp; - int tries; int x; if((bp->flags&S_CLASS) >= Nclass) panic("freeb class"); - bcp = &bclass[bp->flags & S_CLASS]; - lock(bcp); - bp->rptr = bp->wptr = 0; - if(bcp->first) - bcp->last->next = bp; - else - bcp->first = bp; - tries = 0; - while(bp->next){ - if(++tries > 10){ - dumpstack(); - panic("freeb"); - } - bp = bp->next; + for(; bp; bp = nbp){ + bcp = &bclass[bp->flags & S_CLASS]; + lock(bcp); + bp->rptr = bp->wptr = 0; + if(bcp->first) + bcp->last->next = bp; + else + bcp->first = bp; + bcp->last = bp; + nbp = bp->next; + bp->next = 0; + unlock(bcp); + if(bcp->r.p) + wakeup(&bcp->r); } - bcp->last = bp; - unlock(bcp); - if(bcp->r.p) - wakeup(&bcp->r); } /* diff --git a/power/dat.h b/power/dat.h index f6d0a9962a99b3a85fcd786dcdcfb387be07650f..ef6198edff7dc59ddcf614884db5d43344d64c8e 100644 --- a/power/dat.h +++ b/power/dat.h @@ -20,12 +20,7 @@ typedef struct Lock Lock; typedef struct Mach Mach; typedef struct Mount Mount; typedef struct Mtab Mtab; -typedef struct Noconv Noconv; -typedef struct Nohdr Nohdr; -typedef struct Noifc Noifc; typedef struct Note Note; -typedef struct Nomsg Nomsg; -typedef struct Nocall Nocall; typedef struct Orig Orig; typedef struct PTE PTE; typedef struct Page Page; @@ -521,121 +516,6 @@ struct Etherpkt { }; #define ETHERMINMTU 60 /* minimum transmit size */ -/* - * nonet constants - */ -enum { - Nnomsg = 128, /* max number of outstanding messages */ - Nnocalls = 5, /* maximum queued incoming calls */ -}; - -/* - * generic nonet header - */ -struct Nohdr { - uchar circuit[3]; /* circuit number */ - uchar flag; - uchar mid; /* message id */ - uchar ack; /* piggy back ack */ - uchar remain[2]; /* count of remaing bytes of data */ - uchar sum[2]; /* checksum (0 means none) */ -}; -#define NO_HDRSIZE 10 -#define NO_NEWCALL 0x1 /* flag bit marking a new circuit */ -#define NO_HANGUP 0x2 /* flag bit requesting hangup */ -#define NO_ACKME 0x4 /* acknowledge this message */ -#define NO_SERVICE 0x8 /* message includes a service name */ -#define NO_RESET 0x10 /* reset the connection */ -/* - * a buffer describing a nonet message - */ -struct Nomsg { - Blist; - int mid; /* sequence number */ - int rem; /* remaining */ - ulong time; - int acked; - int inuse; -}; - -/* - * one exists for each Nonet conversation. - */ -struct Noconv { - QLock; - - Stream *s; - Queue *rq; /* input queue */ - int version; /* incremented each time struct is changed */ - int state; /* true if listening */ - - Nomsg in[Nnomsg]; /* messages being received */ - int rcvcircuit; /* circuit number of incoming packets */ - - uchar ack[Nnomsg]; /* acknowledgements waiting to be sent */ - int afirst; - int anext; - - QLock xlock; /* one trasmitter at a time */ - Rendez r; /* process waiting for an output mid */ - QLock mlock; /* lock for allocating out messages */ - Nomsg out[Nnomsg]; /* messages being sent */ - int first; /* first unacknowledged message */ - int next; /* next message buffer to use */ - int lastacked; /* last message acked */ - Block *media; /* prototype media output header */ - Nohdr *hdr; /* nonet header inside of media header */ - - Noifc *ifc; - char raddr[NAMELEN]; /* remote address */ - char ruser[NAMELEN]; /* remote user */ - char addr[NAMELEN]; /* local address */ - int rexmit; /* statistics */ - int retry; - int bad; - int sent; - int rcvd; -}; - -/* - * an incoming call - */ -struct Nocall { - Block *msg; - char raddr[NAMELEN]; - long circuit; -}; - -/* - * a nonet interface. one exists for every stream that a - * nonet multiplexor is pushed onto. - */ -struct Noifc { - Lock; - int ref; - char name[NAMELEN]; /* interface name */ - Queue *wq; /* interface output queue */ - Noconv *conv; - - /* - * media dependent - */ - int maxtu; /* maximum transfer unit */ - int mintu; /* minimum transfer unit */ - int hsize; /* media header size */ - void (*connect)(Noconv *, char *); - - /* - * calls and listeners - */ - QLock listenl; - Rendez listenr; - Lock lock; - Nocall call[Nnocalls]; - int rptr; - int wptr; -}; - /* * LANCE CSR3 (bus control bits) */ diff --git a/power/devhotrod.c b/power/devhotrod.c index 2f3c803b8a27083241c1a2f8fe07acd0ec85ddb4..d493c688993c371c5272a82f418f0fef73382abe 100644 --- a/power/devhotrod.c +++ b/power/devhotrod.c @@ -18,6 +18,10 @@ void mem(Hot*, ulong*, ulong); #define NTESTBUF 256 ulong testbuf[NTESTBUF]; #endif +/* + * If defined, ENABBUSTEST causes bus error diagnostic to be run at device open + */ +#define ENABBUSTEST /* * If 1, ENABCKSUM causes data transfers to have checksums @@ -193,6 +197,14 @@ hotrodopen(Chan *c, int omode) print("-"); mem(hp->addr, &hp->addr->ram[(mp->param[0]-0x40000)/sizeof(ulong)], mp->param[1]); } +#endif +#ifdef ENABBUSTEST + /* + * Issue test + */ + mp = &u->khot; + mp->cmd = Ubus; + hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); #endif } c->mode = openmode(omode); diff --git a/power/fns.h b/power/fns.h index 01c614591714ad8ef81b2570276db2426c4652e9..ea727ebb9c7ab21f48aaebd5f611aa6215274996 100644 --- a/power/fns.h +++ b/power/fns.h @@ -118,10 +118,6 @@ void newqinfo(Qinfo*); char *nextelem(char*, char*); void newstart(void); int newtlbpid(Proc*); -int nonetcksum(Block*, int); -void nonetfreeifc(Noifc*); -Noifc *nonetnewifc(Queue*, Stream*, int, int, int, void (*)(Noconv*, char*)); -void nonetrcvmsg(Noconv*, Block*); void notify(Ureg*); void novme(int); void nullput(Queue*, Block*); diff --git a/ss/dat.h b/ss/dat.h index d135985e2c1496e16e668c686b9f3374506ce54e..2a953d0636a500cd45eed206899367be73efa71f 100644 --- a/ss/dat.h +++ b/ss/dat.h @@ -514,124 +514,6 @@ struct Etherpkt { }; #define ETHERMINMTU 60 /* minimum transmit size */ -/* - * nonet constants - */ -enum { - Nnomsg = 128, /* max number of outstanding messages */ - Nnocalls = 5, /* maximum queued incoming calls */ -}; - -/* - * generic nonet header - */ -struct Nohdr { - uchar circuit[3]; /* circuit number */ - uchar flag; - uchar mid; /* message id */ - uchar ack; /* piggy back ack */ - uchar remain[2]; /* count of remaing bytes of data */ - uchar sum[2]; /* checksum (0 means none) */ -}; -#define NO_HDRSIZE 10 -#define NO_NEWCALL 0x1 /* flag bit marking a new circuit */ -#define NO_HANGUP 0x2 /* flag bit requesting hangup */ -#define NO_ACKME 0x4 /* acknowledge this message */ -#define NO_SERVICE 0x8 /* message includes a service name */ -#define NO_RESET 0x10 /* reset the connection */ - -/* - * a buffer describing a nonet message - */ -struct Nomsg { - Blist; - int mid; /* sequence number */ - int rem; /* remaining */ - ulong time; - int acked; - int inuse; -}; - -/* - * one exists for each Nonet conversation. - */ -struct Noconv { - QLock; - - Stream *s; - Queue *rq; /* input queue */ - int version; /* incremented each time struct is changed */ - int state; /* true if listening */ - - Nomsg in[Nnomsg]; /* messages being received */ - int rcvcircuit; /* circuit number of incoming packets */ - - uchar ack[Nnomsg]; /* acknowledgements waiting to be sent */ - int afirst; - int anext; - - QLock xlock; /* one trasmitter at a time */ - Rendez r; /* process waiting for an output mid */ - Nomsg ctl; /* for control messages */ - Nomsg ackmsg; /* for acknowledge messages */ - QLock mlock; /* lock for out */ - Nomsg out[Nnomsg]; /* messages being sent */ - int first; /* first unacknowledged message */ - int next; /* next message buffer to use */ - int lastacked; /* last message acked */ - Block *media; /* prototype media output header */ - Nohdr *hdr; /* nonet header inside of media header */ - - Noifc *ifc; - char raddr[NAMELEN]; /* remote address */ - char ruser[NAMELEN]; /* remote user */ - char addr[NAMELEN]; /* local address */ - int rexmit; /* statistics */ - int retry; - int bad; - int sent; - int rcvd; -}; - -/* - * an incoming call - */ -struct Nocall { - Block *msg; - char raddr[NAMELEN]; - long circuit; -}; - -/* - * a nonet interface. one exists for every stream that a - * nonet multiplexor is pushed onto. - */ -struct Noifc { - Lock; - int ref; - char name[NAMELEN]; /* interface name */ - Queue *wq; /* interface output queue */ - Noconv *conv; - - /* - * media dependent - */ - int maxtu; /* maximum transfer unit */ - int mintu; /* minimum transfer unit */ - int hsize; /* media header size */ - void (*connect)(Noconv *, char *); - - /* - * calls and listeners - */ - QLock listenl; - Rendez listenr; - Lock lock; - Nocall call[Nnocalls]; - int rptr; - int wptr; -}; - #define NSTUB 32 struct Service { diff --git a/ss/fns.h b/ss/fns.h index e6982c5263a9520710e62a1e56de5cbad015c5ca..cf39f90bfd939b933fc6c0d0c5a8ae39ad743d56 100644 --- a/ss/fns.h +++ b/ss/fns.h @@ -130,11 +130,6 @@ Pgrp *newpgrp(void); Proc *newproc(void); void newqinfo(Qinfo*); char *nextelem(char*, char*); -int nonetcksum(Block*, int); -void nonetfreeifc(Noifc*); -Noifc *nonetnewifc(Queue*, Stream*, int, int, int, void (*)(Noconv*, char*)); -void nonetrcvmsg(Noconv*, Block*); -void nonettoggle(void); void notify(Ureg*); void nullput(Queue*, Block*); int openmode(ulong);