M port/devnonet.c => port/devnonet.c +53 -16
@@ 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,25 1154,56 @@ 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
*/
if(h->mid != mp->mid){
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);
}
M port/stnoether.c => port/stnoether.c +17 -4
@@ 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;
}
M port/stream.c => port/stream.c +18 -19
@@ 227,6 227,9 @@ allocb(ulong size)
bp->next = 0;
bp->type = M_DATA;
bp->flags &= S_CLASS;
+ if(bp->lim-bp->rptr<size && size<4096)
+ panic("allocb %lux %lux %d %ux %d", bp->lim, 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);
}
/*
M power/dat.h => power/dat.h +0 -120
@@ 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;
@@ 522,121 517,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)
*/
#define BSWP 0x4
M power/devhotrod.c => power/devhotrod.c +12 -0
@@ 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
@@ 194,6 198,14 @@ hotrodopen(Chan *c, int omode)
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);
c->flag |= COPEN;
M power/fns.h => power/fns.h +0 -4
@@ 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*);
M ss/dat.h => ss/dat.h +0 -118
@@ 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
{
M ss/fns.h => ss/fns.h +0 -5
@@ 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);