Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/port/stlapd.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname port/stlapd.c 1992/0609
## diff -e /dev/null /n/bootesdump/1992/0609/sys/src/9/port/stlapd.c
0a
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"
#include	"../port/error.h"

#define DPRINT if(q->flag&QDEBUG)kprint

typedef struct Lapd	Lapd;

#define NOW	TK2MS(MACHP(0)->ticks)
#define	T200	(NOW+2500)

	/* C/R bits */

#define	UCmd	0	/* command, user to network */
#define	UResp	2	/* response, user to network */
#define	NCmd	2	/* command, network to user */
#define	NResp	0	/* response, network to user */

#define	SAPI(s, cr)	(((s)<<2)|cr)
#define	TEI(t)		(((t)<<1)|1)

/*
 *  Commands and responses
 */

#define	RR	0x01	/* Receiver Ready */
#define	RNR	0x05	/* Receiver Not Ready */
#define	REJ	0x09	/* Reject */
#define	SABME	0x6f	/* Set Asynchronous Balanced Mode Extended */
#define	DM	0x0f	/* Disconnect Mode */
#define	UI	0x03	/* Unnumbered Information */
#define	DISC	0x43	/* Disconnect */
#define	UA	0x63	/* Unnumbered Acknowledgement */
#define	FRMR	0x87	/* Frame Reject */
#define	XID	0xaf	/* Exchange Identification */

enum States {
	Unused = 0,
	NoTEI,
	WaitTEI,
	TEIassigned,
	WaitEst,
	Multiframe,
	WaitRel,
};

enum Flags {
	Ownbusy = 0x01,
	Peerbusy = 0x02,
	Rejecting = 0x04,
	Timeout = 0x08,
	Hungup = 0x80
};

#define	SMASK		127
#define	NSEQ		(SMASK+1)
#define	THISS(i)	((i)&SMASK)
#define	NEXTS(i)	(((i)+1)&SMASK)

#define	OMASK		7
#define	NOBUF		(OMASK+1)
#define	THISO(i)	((i)&OMASK)
#define	NEXTO(i)	(((i)+1)&OMASK)

#define	RSTATE(lp)	((lp->flags&Ownbusy) ? RNR : \
			(lp->flags&Rejecting) ? REJ : RR)

struct Lapd {
	QLock;		/* access, state change */
	Rendez;		/* waiting for state change */
	int	state;
	int	flags;
	Queue *	rq;
	Queue *	wq;
	ushort	refnum;
	int	tei;
	int	kout;	/* maximum allowed number of outstanding I frames */
	int	vs;	/* send state variable (next seq. no. to send) */
	int	va;	/* acknowledge state variable (next expected ack) */
	int	vr;	/* receive state variable (next expected input) */
	Rendez	tr;	/* so transmit writer can wait */
	Block *	outb[NOBUF]; /* transmitter circular buffer */
	int	vt;	/* input pointer for outb */
	int	t200;
	Rendez	timer;
	int	kstarted;
	int	error;
};

enum {
	LAPD_OK,
	Address,
	BadUA,
	Badassign,
	Badmanage,
	Tooshort,
	Unimpmanage,
	Unkdlci,
	Egates,
};

char *lapderrors[] = {
	"LAPD OK",
	"Address",
	"BadUA",
	"Badassign",
	"Badmanage",
	"Tooshort",
	"Unimpmanage",
	"Egates",
};

Lapd	*lapd;

/*
 *  predeclared
 */
static void	assigntei(Lapd *);
static void	dl_establish(Lapd *);
static void	dl_release(Lapd *);
static void	lapdreset(void);
static void	lapdclose(Queue *);
static void	lapdiput(Queue*, Block*);
static void	lapdkproc(void *);
static void	lapdopen(Queue*, Stream*);
static void	lapdoput(Queue*, Block*);
static int	lapdxmit(Lapd *);
static void	mdl_assign(Lapd *);
static void	mdl_iput(Queue *, Block *);
static int	recvack(Lapd *, int);
static void	sendctl(Lapd *, int, int, int);

Qinfo lapdinfo = { lapdiput, lapdoput, lapdopen, lapdclose, "lapd", lapdreset };

#define	Predicate(name, expr)	static int name(void *arg) { return expr; }
#define	lp	((Lapd *)arg)

Predicate(pTEIassigned, lp->state == TEIassigned);
Predicate(pMultiframe, lp->state == Multiframe);

Predicate(tEmpty, lp->vs == lp->va)
Predicate(tFull, NEXTO(lp->vt) == THISO(lp->va))
Predicate(tNotFull, NEXTO(lp->vt) != THISO(lp->va))

#undef	lp

static void
lapderror(Lapd *lp, int code)
{
	lp->error = code;
	nexterror();
}

static void
lapdreset(void)
{
	lapd = ialloc(conf.nlapd*sizeof(Lapd), 0);
}

static void
lapdopen(Queue *q, Stream *s)
{
	Lapd *lp;
	char name[32];

	for(lp=lapd; lp<&lapd[conf.nlapd]; lp++){
		qlock(lp);
		if(lp->state == 0)
			break;
		qunlock(lp);
	}
	if(lp>=&lapd[conf.nlapd])
		error(Enoifc);

	/*q->flag |= QDEBUG;
	q->other->flag |= QDEBUG;*/
	DPRINT("lapdopen: lapd %d\n", lp - lapd);
	q->ptr = q->other->ptr = lp;
	lp->rq = q;
	lp->wq = q->other;
	lp->state = NoTEI;
	lp->flags = 0;
	lp->kout = 1;
	qunlock(lp);
	sprint(name, "lapd%d", lp - lapd);
	kproc(name, lapdkproc, lp);
	DPRINT("lapdopen: mdl_assign\n");
	mdl_assign(lp);
	DPRINT("lapdopen: dl_establish\n");
	dl_establish(lp);
}

static void
mdl_assign(Lapd *lp)
{
	Block *b; uchar *p;

	qlock(lp);
	if (lp->state != NoTEI) {
		qunlock(lp);
		error(Egreg);
	}
	lp->state = WaitTEI;
	assigntei(lp);
	lp->t200 = T200;
	qunlock(lp);
	sleep(lp, pTEIassigned, lp);
	if (lp->state != TEIassigned){
		lapdclose(lp->rq);
		error(Egreg);
	}
}

static void
assigntei(Lapd *lp)
{
	Queue *q = lp->rq;
	Block *b = allocb(16);
	uchar *p = b->wptr;

	lp->refnum = NOW;
	*p++ = SAPI(63, UCmd);
	*p++ = TEI(127);
	*p++ = UI;
	*p++ = 0x0f;
	*p++ = lp->refnum>>8;
	*p++ = lp->refnum;
	*p++ = 0x01;
	*p++ = 0xff;
	b->wptr = p;
	b->flags |= S_DELIM;
	DPRINT("assigntei: refnum=0x%4.4ux\n", lp->refnum);
	PUTNEXT(lp->wq, b);
}

static void
dl_establish(Lapd *lp)
{
	Block *b; uchar *p;

	qlock(lp);
	if (lp->state != TEIassigned) {
		qunlock(lp);
		error(Egreg);
	}
	lp->state = WaitEst;
	sendctl(lp, UCmd, SABME, 0);
	lp->t200 = T200;
	qunlock(lp);
	sleep(lp, pMultiframe, lp);
	if (lp->state != Multiframe){
		lapdclose(lp->rq);
		error(Egreg);
	}
}

static void
dl_release(Lapd *lp)
{
	Block *b; uchar *p;

	qlock(lp);
	if (lp->state != Multiframe) {
		qunlock(lp);
		error(Egreg);
	}
	lp->state = WaitRel;
	sendctl(lp, UCmd, DISC, 0);
	lp->t200 = T200;
	qunlock(lp);
	tsleep(lp, pTEIassigned, lp, 30*1000);
	qlock(lp);
	if(lp->state > TEIassigned)
		lp->state = TEIassigned;
	qunlock(lp);
}

static void
lapdclose(Queue *q)
{
	Lapd *lp = (Lapd *)q->ptr;
	int i;

	if(lp == 0)
		return;

	if (lp->state == Multiframe) {
		for(i=0; i<NOBUF && !tEmpty(lp); i++)
			tsleep(&lp->tr, tEmpty, lp, 2500);	/* drain */
		dl_release(lp);					/* DISC to NT */
		for(i=0; i<NOBUF; i++)
			if(lp->outb[i]){
				freeb(lp->outb[i]);
				lp->outb[i] = 0;
			}
	}

	lp->flags |= Hungup;			/* tell kernel proc */
	lp->t200 = NOW;
	wakeup(&lp->timer);
	for(i=0; i<10 && lp->kstarted; i++)
		tsleep(lp, return0, 0, 500);

	lp->state = 0;
}

/*
 *  upstream control messages
 */
static void
lapdctliput(Lapd *lp, Queue *q, Block *bp)
{
	switch(bp->type){
	case M_HANGUP:
		lp->flags |= Hungup;
		wakeup(lp);
		break;
	}
	PUTNEXT(q, bp);
}

void
lapdiput(Queue *q, Block *bp)
{
	Lapd *lp = (Lapd *)q->ptr;
	int sapi, cr, tei, ctl, ns, nr = 0, pf;
	uchar *start, *p;

	DPRINT("lapdiput: %d byte(s)\n", bp->wptr-bp->rptr);
	qlock(lp);
	lp->error = 0;
	p = start = bp->rptr;
	if (waserror()) {
		qunlock(lp);
		kprint("lapdiput: %s:", lapderrors[lp->error]);
		for(p=start; p<bp->wptr; p++)
			kprint(" %2.2ux", *p);
		kprint("\n");
		freeb(bp);
		return;
	}

	if(bp->type != M_DATA){
		lapdctliput(lp, q, bp);
		bp = 0;
		goto out;
	}
	if (bp->wptr-p < 3)
		lapderror(lp, Tooshort);
	if ((p[0] & 0x01) || !(p[1] & 0x01))
		lapderror(lp, Address);
	sapi = p[0] >> 2;
	cr = p[0] & 0x02;
	tei = p[1] >> 1;
	ctl = p[2];
	if ((ctl&0x03) != 0x03) {
		if (bp->wptr-p < 4)
			lapderror(lp, Tooshort);
		pf = p[3]&0x01;
		nr = p[3]>>1;
		p += 4;
	} else {
		pf = ctl&0x10;
		ctl &= ~0x10;
		p += 3;
	}
	bp->rptr = p;
	DPRINT("lapdiput: cr=%d sapi=%d tei=%d ctl=0x%2.2x pf=%d\n",
		cr, sapi, tei, ctl, pf);
	if (cr==NCmd && tei==127 && ctl==UI) {
		switch (sapi) {
		case 0:
			PUTNEXT(q, bp);
			bp = 0;
			break;
		case 63:
			mdl_iput(q, bp);
			bp = 0;
			break;
		default:
			lapderror(lp, Unkdlci);
			break;
		}
		goto out;
	}
	if (sapi != 0 || lp->state < TEIassigned || tei != lp->tei)
		lapderror(lp, Unkdlci);
	if (!(ctl&0x01)) {	/* Information */
		if (recvack(lp, nr)>0 && !(lp->flags&(Peerbusy|Timeout)))
			lp->t200 = 0;
		if (lp->flags&Ownbusy) {
			if (pf)
				sendctl(lp, cr, RNR, pf);
			lapdxmit(lp);
			goto out;
		}
		ns = ctl>>1;
		if (ns != lp->vr) {
			lp->flags |= Rejecting;
			sendctl(lp, cr, REJ, pf);
			lapdxmit(lp);
			goto out;
		}
		PUTNEXT(q, bp);
		bp = 0;
		lp->flags &= ~Rejecting;
		lp->vr = NEXTS(lp->vr);
		if (QFULL(q->next))
			lp->flags |= Ownbusy;
		if (pf || (lp->flags&Ownbusy)) {
			sendctl(lp, cr, RSTATE(lp), pf);
			lapdxmit(lp);
		} else if (!lapdxmit(lp))
			sendctl(lp, cr, RR, pf);
		goto out;
	}
	switch (ctl) {
	case RR:
		if (recvack(lp, nr)<0)
			goto out;
		lp->flags &= ~Peerbusy;
		if (cr==NCmd && pf)
			sendctl(lp, cr, RSTATE(lp), pf);
		if (!(lp->flags&Timeout)) {
			lp->t200 = 0;
			if (cr==NResp && pf)
				DPRINT("lapdiput: RR response with F==1\n");
			lapdxmit(lp);
		} else if (cr==NResp && pf) {
			lp->flags &= ~Timeout;
			lp->vs = nr;
			lp->t200 = 0;
			lapdxmit(lp);
		}
		break;
	case RNR:
		if (recvack(lp, nr)<0)
			goto out;
		lp->flags |= Peerbusy;
		if (cr==NCmd && pf)
			sendctl(lp, cr, RSTATE(lp), pf);
		if (!(lp->flags&Timeout)) {
			lp->t200 = T200;
			if (cr==NResp && pf)
				DPRINT("lapdiput: RNR response with F==1\n");
		} else if (cr==NResp && pf) {
			lp->flags &= ~Timeout;
			lp->vs = nr;
			lp->t200 = T200;
		}
		break;
	case REJ:
		if (recvack(lp, nr)<0)
			goto out;
		lp->flags &= ~Peerbusy;
		if (cr==NCmd && pf)
			sendctl(lp, cr, RSTATE(lp), pf);
		if (!(lp->flags&Timeout)) {
			lp->vs = nr;
			lp->t200 = 0;
			if (cr==NResp && pf)
				DPRINT("lapdiput: REJ response with F==1\n");
			lapdxmit(lp);
		} else if (cr==NResp && pf) {
			lp->flags &= ~Timeout;
			lp->vs = nr;
			lp->t200 = 0;
			lapdxmit(lp);
		}
		break;
	case DM:
		lp->state = TEIassigned;
		lp->flags = 0;
		lp->t200 = 0;
		wakeup(lp);
		break;
	case UA:
		if (lp->state == WaitEst) {
			lp->state = Multiframe;
			lp->flags = 0;
			lp->vs = 0;
			lp->va = 0;
			lp->vr = 0;
			lp->vt = 0;
			lp->t200 = 0;
			wakeup(lp);
		} else if (lp->state == WaitRel) {
			lp->state = TEIassigned;
			lp->flags = 0;
			lp->t200 = 0;
			wakeup(lp);
		} else
			lapderror(lp, BadUA);
		break;
	case SABME:
	case UI:
	case DISC:
	case FRMR:
	case XID:
		lapderror(lp, Egates);
		break;
	}
out:
	if (bp)
		freeb(bp);
	poperror();
	qunlock(lp);
}

static void
mdl_iput(Queue *q, Block *bp)
{
	Lapd *lp = (Lapd *)q->ptr;
	uchar *p = bp->rptr;
	ushort refnum;
	int ai;

	if (bp->wptr-p != 5 || p[0] != 0x0f || !(p[4]&0x01))
		lapderror(lp, Badmanage);
	refnum = (p[1]<<8)|p[2];
	ai = p[4]>>1;
	switch (p[3]) {
	case 2:		/* identity assigned */
		if (lp->state == WaitTEI && lp->refnum == refnum) {
			lp->state = TEIassigned;
			lp->tei = ai;
			lp->t200 = 0;
			DPRINT("assigned tei = %d\n", lp->tei);
			wakeup(lp);
		} else
			lapderror(lp, Badassign);
		break;
	case 3:		/* identity denied */
		if (lp->state == WaitTEI && lp->refnum == refnum) {
			lp->t200 = 0;
			DPRINT("denied tei = %d\n", ai);
			wakeup(lp);
		} else
			lapderror(lp, Badassign);
		break;
	case 4:		/* identity check request */
		if (lp->state >= TEIassigned && (ai==127||ai==lp->tei)) {
			Block *b = allocb(16);
			uchar *p = b->wptr;
		
			*p++ = SAPI(63, UCmd);
			*p++ = TEI(127);
			*p++ = UI;
			*p++ = 0x0f;
			*p++ = NOW>>8;
			*p++ = NOW;
			*p++ = 0x05;
			*p++ = (lp->tei<<1)|1;
			b->wptr = p;
			b->flags |= S_DELIM;
			DPRINT("id check response: tei=%d\n", lp->tei);
			PUTNEXT(lp->wq, b);
		} else
			lapderror(lp, Badassign);
		break;
	default:
		{
			Block *b = allocb(0);
			b->type = M_HANGUP;
			PUTNEXT(lp->rq, b);
		}
		lapderror(lp, Unimpmanage);
		break;
	}
	freeb(bp);
}

static int
recvack(Lapd *lp, int nr)
{
	Queue *q = lp->wq;
	int i;

	for(i=lp->va; i!=lp->vs; i=NEXTS(i)){
		if(i==nr)
			break;
	}
	if(i!=nr) {
		DPRINT("lapd recvack: va,nr,vs = %d,%d,%d\n",
			lp->va, nr, lp->vs);
		return -1;
	}
	i = 0;
	while (lp->va != nr) {
		freeb(lp->outb[THISO(lp->va)]);
		lp->outb[THISO(lp->va)] = 0;
		lp->va = NEXTS(lp->va);
		i++;
	}
	if (i > 0)
		wakeup(&lp->tr);
	return i;
}

/*
 *  downstream control
 */
static void
lapdctloput(Lapd *lp, Queue *q, Block *bp)
{
	char *fields[2];

	switch(bp->type){
	case M_CTL:
		if(streamparse("debug", bp)){
			switch(getfields((char *)bp->rptr, fields, 2, ' ')){
			case 1:
				if (strcmp(fields[0], "on") == 0) {
					q->flag |= QDEBUG;
					q->other->flag |= QDEBUG;
				}
				if (strcmp(fields[0], "off") == 0) {
					q->flag &= ~QDEBUG;
					q->other->flag &= ~QDEBUG;
				}
			}
			freeb(bp);
			return;
		}
	}
	PUTNEXT(q, bp);
}

/*
 *  accept data from a writer
 */
static void
lapdoput(Queue *q, Block *bp)
{
	Lapd *lp = (Lapd *)q->ptr;

	if(bp->type != M_DATA){
		lapdctloput(lp, q, bp);
		return;
	}
	if(!putq(q, bp))	/* send only whole messages */
		return;
	DPRINT("lapdoput: len=%d\n", q->len);
	if (tFull(lp))
		sleep(&lp->tr, tNotFull, lp);
	qlock(lp);
	if (waserror()) {
		qunlock(lp);
		nexterror();
	}
	lp->outb[lp->vt] = grabq(q);
	lp->vt = NEXTO(lp->vt);

	lapdxmit(lp);
	poperror();
	qunlock(lp);
}

static int
lapdxmit(Lapd *lp)
{
	Block *bp, *db;
	int i; uchar *p;

	for (i=0;;i++) {
		if (THISO(lp->vs) == lp->vt)		/* buffer empty */
			break;
		if (THISS(lp->va+lp->kout) == lp->vs)	/* window full */
			break;
		if (lp->flags & Peerbusy)		/* flow-controlled */
			break;
		bp = allocb(16);
		p = bp->wptr;
		*p++ = SAPI(0, UCmd);
		*p++ = TEI(lp->tei);
		*p++ = lp->vs<<1;
		*p++ = lp->vr<<1;
		bp->wptr = p;
		PUTNEXT(lp->wq, bp);
		for(bp=lp->outb[THISO(lp->vs)]; bp; bp=bp->next){
			db = allocb(0);
			db->rptr = bp->rptr;
			db->wptr = bp->wptr;
			db->flags |= (bp->flags&S_DELIM);
			PUTNEXT(lp->wq, db);
		}
		lp->vs = NEXTS(lp->vs);
		lp->t200 = T200;
	}
	return i;
}

/*
 *  send a control frame.
 */
static void
sendctl(Lapd *lp, int cmd, int ctl, int pf)
{
	Block *bp = allocb(16);
	uchar *p = bp->wptr;

	*p++ = SAPI(0, cmd);
	*p++ = TEI(lp->tei);
	if (ctl & 0x02) {
		*p++ = ctl|(pf?0x10:0);
	} else {
		*p++ = ctl;
		*p++ = (lp->vr<<1)|(pf?0x01:0);
	}
	bp->wptr = p;
	bp->flags |= S_DELIM;
	PUTNEXT(lp->wq, bp);
}

static void
lapdkproc(void *arg)
{
	Lapd *lp = (Lapd *)arg;
	int locked = 0;
	lp->kstarted = 1;

	if(waserror()){
		if (locked)
			qunlock(lp);
		print("lapdkproc %d error\n", lp-lapd);
		lp->kstarted = 0;
		wakeup(lp);
		return;
	}
	for(;;){
		tsleep(&lp->timer, return0, 0, 500);
		if(!lp->t200 || NOW < lp->t200)
			continue;
		qlock(lp);
		locked = 1;
		USED(locked);
		if(lp->flags & Hungup){
			qunlock(lp);
			locked = 0;
			USED(locked);
			break;
		}
		switch(lp->state){
		case WaitTEI:
			assigntei(lp);
			lp->t200 = T200;
			break;
		case WaitEst:
			sendctl(lp, UCmd, SABME, 0);
			break;
		case Multiframe:
			sendctl(lp, UCmd, RSTATE(lp), 1);
			lp->flags |= Timeout;
			lp->t200 = T200;
			break;
		}
		qunlock(lp);
		locked = 0;
		USED(locked);
	}
	lp->kstarted = 0;
	wakeup(lp);
	poperror();
}
.
## diffname port/stlapd.c 1992/0622
## diff -e /n/bootesdump/1992/0609/sys/src/9/port/stlapd.c /n/bootesdump/1992/0622/sys/src/9/port/stlapd.c
161c
	lapd = xalloc(conf.nlapd*sizeof(Lapd));
.
72c
struct Lapd
{
.
51,56c
enum Flags
{
	Ownbusy 	= 0x01,
	Peerbusy 	= 0x02,
	Rejecting	= 0x04,
	Timeout		= 0x08,
	Hungup		= 0x80
.
41c
enum States
{
.
30,39c
	/* C/R bits */
	UCmd	= 0,	/* command, user to network */
	UResp	= 2,	/* response, user to network */
	NCmd	= 2,	/* command, network to user */
	NResp	= 0	/* response, network to user */
};
.
28a
enum
{
	RR	= 0x01,	/* Receiver Ready */
	RNR	= 0x05,	/* Receiver Not Ready */
	REJ	= 0x09,	/* Reject */
	SABME	= 0x6f,	/* Set Asynchronous Balanced Mode Extended */
	DM	= 0x0f,	/* Disconnect Mode */
	UI	= 0x03,	/* Unnumbered Information */
	DISC	= 0x43,	/* Disconnect */
	UA	= 0x63,	/* Unnumbered Acknowledgement */
	FRMR	= 0x87,	/* Frame Reject */
	XID	= 0xaf,	/* Exchange Identification */
.
13,22c
#define NOW		TK2MS(MACHP(0)->ticks)
#define	T200		(NOW+2500)
.
## diffname port/stlapd.c 1992/0627
## diff -e /n/bootesdump/1992/0622/sys/src/9/port/stlapd.c /n/bootesdump/1992/0627/sys/src/9/port/stlapd.c
765,766c
		lp->klocked = 0;
.
746,747c
			lp->klocked = 0;
.
742,743c
		lp->klocked = 1;
.
731a
		lp->klocked = 0;
.
730c
		if(lp->klocked)
.
726c

	lp->klocked = 0;
.
77a
	int	klocked;/* locked by kernel proc */
.
## diffname port/stlapd.c 1992/0711
## diff -e /n/bootesdump/1992/0627/sys/src/9/port/stlapd.c /n/bootesdump/1992/0711/sys/src/9/port/stlapd.c
615a
	USED(lp);
.
268,269d
247,248d
204,205d
173a
	USED(s);
.
## diffname port/stlapd.c 1992/1205
## diff -e /n/bootesdump/1992/0711/sys/src/9/port/stlapd.c /n/bootesdump/1992/1205/sys/src/9/port/stlapd.c
562a
		break;
	case 6:		/* identity removal */
		DPRINT("id removal: ai=%d\n", ai);
		if(lp->state >= TEIassigned && (ai == lp->tei || ai == 127)){
			Block *b = allocb(0);
			lp->state = NoTEI;
			DPRINT("lapd hangup\n");
			b->type = M_HANGUP;
			PUTNEXT(lp->rq, b);
		}
.
300c
	for(i=0; i<NOBUF; i++)
		if(lp->outb[i]){
			freeb(lp->outb[i]);
			lp->outb[i] = 0;
		}
.
294,298d
290c
	if(lp->state == Multiframe){
.
268c
		sprint(buf, "dl_release: state=%d", lp->state);
		kprint("%s\n", buf);
		error(buf);
.
266c
	if(lp->state != Multiframe){
.
264a
	char buf[ERRLEN];

.
256,258c
	if(lp->state != Multiframe){
		/*lapdclose(lp->rq);*/
		sprint(buf, "dl_establish failed: state=%d", lp->state);
		kprint("%s\n", buf);
		error(buf);
.
249c
		sprint(buf, "dl_establish: state=%d", lp->state);
		kprint("%s\n", buf);
		error(buf);
.
247c
	if(lp->state != TEIassigned){
.
245a
	char buf[ERRLEN];

.
215,217c
	if(lp->state != TEIassigned){
		/*lapdclose(lp->rq);*/
		sprint(buf, "mdl_assign failed: state=%d", lp->state);
		kprint("%s\n", buf);
		error(buf);
.
208c
		sprint(buf, "mdl_assign: state=%d", lp->state);
		kprint("%s\n", buf);
		error(buf);
.
206c
	if(lp->state != NoTEI){
.
204a
	char buf[ERRLEN];

.
## diffname port/stlapd.c 1993/0122
## diff -e /n/bootesdump/1992/1205/sys/src/9/port/stlapd.c /n/bootesdump/1993/0122/sys/src/9/port/stlapd.c
598a
}

static void
lapdhangup(Lapd *lp)
{
	Queue *q = lp->rq;
	Block *bp;

	DPRINT("lapd hangup\n");
	bp = allocb(0);
	bp->type = M_HANGUP;
	PUTNEXT(q, bp);
.
590,594c
		lapdhangup(lp);
.
584,586c
			lapdhangup(lp);
.
582d
576,577c
		}
.
560c
		if(lp->state >= TEIassigned && (ai==127||ai==lp->tei)){
.
552c
		if(lp->state == WaitTEI && lp->refnum == refnum){
.
548,549c
		}
.
542c
		if(lp->state == WaitTEI && lp->refnum == refnum){
.
540c
	switch(p[3]){
.
515d
512a
	case DISC:
		lp->state = TEIassigned;
		lp->flags = 0;
		lp->t200 = 0;
		sendctl(lp, UResp, UA, pf);
		lapdhangup(lp);
		break;
.
234c
	now = NOW;
	if(now <= then)
		now = then+1;
	lp->refnum = now;
	then = now;
.
232a
	static ulong then;
	ulong now;
.
135,139c
static int	lapdxmit(Lapd*);
static void	mdl_assign(Lapd*);
static void	mdl_iput(Queue*, Block*);
static int	recvack(Lapd*, int);
static void	sendctl(Lapd*, int, int, int);
.
132c
static void	lapdkproc(void*);
.
130c
static void	lapdclose(Queue*);
static void	lapdhangup(Lapd*);
.
126,128c
static void	assigntei(Lapd*);
static void	dl_establish(Lapd*);
static void	dl_release(Lapd*);
.
117a
	"Unkdlci",
.
## diffname port/stlapd.c 1993/0226
## diff -e /n/bootesdump/1993/0122/sys/src/9/port/stlapd.c /n/bootesdump/1993/0226/sys/src/9/port/stlapd.c
183c
	if(lp>=lapdN)
.
177c
	for(lp=lapd; lp<lapdN; lp++){
.
167c
	int nlapd = 3; /* formerly conf.nlapd */

	lapd = xalloc(nlapd*sizeof(Lapd));
	lapdN = lapd + nlapd;
.
122a
Lapd	*lapdN;
.
## diffname port/stlapd.c 1993/0501 # deleted
## diff -e /n/bootesdump/1993/0226/sys/src/9/port/stlapd.c /n/fornaxdump/1993/0501/sys/src/brazil/port/stlapd.c
1,813d

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].