~kris/9p

9hist

650ae0cfac7ea871a7ad2684ad2142de8e456094 — David du Colombier 35 years ago 2ea3d68
Plan 9 from Bell Labs 1991-03-28
8 files changed, 100 insertions(+), 286 deletions(-)

M port/devnonet.c
M port/stnoether.c
M port/stream.c
M power/dat.h
M power/devhotrod.c
M power/fns.h
M ss/dat.h
M ss/fns.h
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);