~kris/9p

9hist

edb341368dc2c765f8d4f44697440a5bb8be52df — David du Colombier 33 years ago 62a22f8
Plan 9 from Bell Labs 1992-12-04
3 files changed, 110 insertions(+), 50 deletions(-)

M gnot/devhifi.c
M gnot/devisdn.c
M gnot/isdn.h
M gnot/devhifi.c => gnot/devhifi.c +28 -17
@@ 31,6 31,7 @@ typedef struct Hifichan
	QLock;			/* access to struct */
	int	hdlc;		/* hdlc mode enabled */
	int	hangup;		/* hangup pending */
	int	nohup;		/* hangups ignored */

	int	renable;	/* reading enabled */
	Block *	inb[NB];	/* input buffer */


@@ 76,12 77,13 @@ static void	hifixmitdis(Hifichan*, int);
static void	hifixmiten(Hifichan*, int);

enum {
	Qdir, Qdev, Qstats
	Qdir, Qdev, Qstats, Qdebug
};

Dirtab hifidir[]={
	"dev",		{Qdev},		0,	0666,
	"stats",	{Qstats},	0,	0444,
	"debug",	{Qdebug},	0,	0666,
};
#define	NHIFI	(sizeof hifidir/sizeof(Dirtab))



@@ 94,7 96,7 @@ static void hifistopen(Queue*, Stream*);
static void hifistclose(Queue*);
Qinfo hifiinfo = { hifiiput, hifioput, hifistopen, hifistclose, "hifi" };

int	hifidebug = 1;
int	hifidebug;

void
hifireset(void)


@@ 161,6 163,7 @@ hifiopen(Chan *c, int omode)
	}else switch(STREAMTYPE(c->qid.path)){
	case Qdev:
	case Qstats:
	case Qdebug:
		break;
	default:
		DPRINT("hifiopen dev=%d\n", c->dev);


@@ 190,7 193,7 @@ long
hifiread(Chan *c, void *buf, long n, ulong offset)
{
	Hifichan *hp = &hifichan[c->dev];
	char nbuf[512], *p; int k;
	char nbuf[512], *p;

	if(n <= 0)
		return 0;


@@ 198,10 201,9 @@ hifiread(Chan *c, void *buf, long n, ulong offset)
		return devdirread(c, buf, n, hifidir, NHIFI, streamgen);
	}else switch(STREAMTYPE(c->qid.path)){
	case Qdev:
		p = nbuf;
		p += sprint(p, "0x%2.2ux = 0x%2.2ux\n",
		sprint(nbuf, "0x%2.2ux = 0x%2.2ux\n",
			hp->devaddr, isdnpeek(hp->udev, (void *)hp->devaddr));
		goto Readnbuf;
		return readstr(offset, buf, n, nbuf);

	case Qstats:
		p = nbuf;


@@ 214,14 216,12 @@ hifiread(Chan *c, void *buf, long n, ulong offset)
		p += sprint(p, "toolong  %10lud\n", hp->toolong);
		p += sprint(p, "underrun %10lud\n", hp->underrun);
		p += sprint(p, "outchars %10lud\n", hp->outchars);
	Readnbuf:
		k = p - nbuf;
		if (offset >= k)
			return 0;
		if (offset+n > k)
			n = k - offset;
		memmove(buf, &nbuf[offset], n);
		return n;
		USED(p);
		return readstr(offset, buf, n, nbuf);

	case Qdebug:
		sprint(nbuf, "%d\n", hifidebug);
		return readstr(offset, buf, n, nbuf);
	}
	if(!hp->renable)
		hifirecven(hp, 1);


@@ 247,6 247,13 @@ hifiwrite(Chan *c, void *buf, long n, ulong offset)
		if(p = strchr(nbuf, '='))	/* assign = */
			isdnpoke(hp->udev, (void *)hp->devaddr, strtoul(++p,0,0));
		return n;
	case Qdebug:
		if (n>sizeof nbuf)
			n = sizeof nbuf;
		memmove(nbuf, buf, n);
		nbuf[n-1] = 0;
		hifidebug = strtoul(nbuf,0,0);
		return n;
	}
	return streamwrite(c, buf, n, 0);
}


@@ 309,6 316,7 @@ hifistclose(Queue * q)
	qlock(hp);
	hp->rq = 0;
	hp->hangup = 0;
	hp->nohup = 0;
	if(tActive(hp)){
		if(!hp->wactive || waserror()){
			hifixmitdis(hp, 1);


@@ 331,8 339,9 @@ hifiiput(Queue *q, Block *bp)
	Hifichan *hp = (Hifichan *)q->ptr;

	if(bp->type == M_HANGUP){
		DPRINT("hifiiput %d M_HANGUP\n", hp-hifichan);
		hifirecven(hp, 0);
		DPRINT("hifiiput %d M_HANGUP (%d)\n", hp-hifichan, hp->nohup);
		if(!hp->nohup)
			hifirecven(hp, 0);
	}
	freeb(bp);
}


@@ 366,6 375,8 @@ hifioput(Queue *q, Block *bp)
			hifirecven(hp, 0);
		}else if(streamparse("recven", bp)){
			hifirecven(hp, 1);
		}else if(streamparse("nohup", bp)){
			hp->nohup = 1;
		}
		freeb(bp);
		return;


@@ 661,7 672,7 @@ Loop:
	if(!(bp = hp->out)){	/* assign = */
		if(hp->ro == hp->wo){
			DPRINT("hifixmit %d: [%d] empty\n",
				TK2MS(MACHP(0)->ticks), hp-hifichan);
				hp-hifichan, TK2MS(MACHP(0)->ticks));
			return wake;
		}
		hp->out = bp = hp->outb[hp->ro];

M gnot/devisdn.c => gnot/devisdn.c +80 -33
@@ 23,6 23,7 @@ Isdn *	isdndevN;
static void	devinit(int);
static void	devctl(Isdn*, int, int);
static void	devlctl(Isdn*, int);
static void	devb1xb2(Isdn*, int);
static void	isdnkproc(void*);
static int	isdnintr(void);
static int	isdnInfo(Isdn*);


@@ 30,12 31,13 @@ static int	isdnrecv(Isdn*);
static int	isdnxmit(Isdn*);

enum {
	Qdir, Qloop, QInfo, Qstats, Qdev, Qdebug
	Qdir, Qloop, QInfo, Qb1xb2, Qstats, Qdev, Qdebug
};

Dirtab isdndir[]={
	"loop",		{Qloop},	5,	0666,
	"info",		{QInfo},	1,	0666,
	"b1xb2",	{Qb1xb2},	1,	0666,
	"stats",	{Qstats},	0,	0444,
	"dev",		{Qdev},		0,	0666,
	"debug",	{Qdebug},	0,	0666,


@@ 115,6 117,7 @@ isdnopen(Chan *c, int omode)
	}else switch(STREAMTYPE(c->qid.path)){
	case Qloop:
	case QInfo:
	case Qb1xb2:
	case Qstats:
	case Qdev:
	case Qdebug:


@@ 147,7 150,8 @@ long
isdnread(Chan *c, void *buf, long n, ulong offset)
{
	Isdn *ip = &isdndev[c->dev];
	char nbuf[512]; int k;
	char nbuf[512], *p;
	int k;

	if(n <= 0)
		return 0;


@@ 155,39 159,40 @@ isdnread(Chan *c, void *buf, long n, ulong offset)
		return devdirread(c, buf, n, isdndir, NISDN, streamgen);
	}else switch(STREAMTYPE(c->qid.path)){
	case Qloop:
		k = sprint(nbuf, "0x%2.2ux ", ip->lctl);
		goto Readnbuf;
		sprint(nbuf, "0x%2.2ux ", ip->lctl);
		return readstr(offset, buf, n, nbuf);
	case QInfo:
		if(offset>0)
			return 0;
		k = isdnpeek(ip, &unite->listat)&Rss;
		*(char *)buf = "024L"[k>>2];
		return 1;
	case Qb1xb2:
		if(offset>0)
			return 0;
		k = isdnpeek(ip, &unite->stictl)&B1xb2;
		*(char *)buf = "01"[k != 0];
		return 1;
	case Qstats:
		k = 0;
		k += sprint(&nbuf[k], "inchars  %10lud\n", ip->inchars);
		k += sprint(&nbuf[k], "badcrc   %10lud\n", ip->badcrc);
		k += sprint(&nbuf[k], "abort    %10lud\n", ip->abort);
		k += sprint(&nbuf[k], "overrun  %10lud\n", ip->overrun);
		k += sprint(&nbuf[k], "badcount %10lud\n", ip->badcount);
		k += sprint(&nbuf[k], "overflow %10lud\n", ip->overflow);
		k += sprint(&nbuf[k], "toolong  %10lud\n", ip->toolong);
		k += sprint(&nbuf[k], "underrun %10lud\n", ip->underrun);
		k += sprint(&nbuf[k], "outchars %10lud\n", ip->outchars);
		goto Readnbuf;
		p = nbuf;
		p += sprint(p, "inchars  %10lud\n", ip->inchars);
		p += sprint(p, "badcrc   %10lud\n", ip->badcrc);
		p += sprint(p, "abort    %10lud\n", ip->abort);
		p += sprint(p, "overrun  %10lud\n", ip->overrun);
		p += sprint(p, "badcount %10lud\n", ip->badcount);
		p += sprint(p, "overflow %10lud\n", ip->overflow);
		p += sprint(p, "toolong  %10lud\n", ip->toolong);
		p += sprint(p, "underrun %10lud\n", ip->underrun);
		p += sprint(p, "outchars %10lud\n", ip->outchars);
		USED(p);
		return readstr(offset, buf, n, nbuf);
	case Qdev:
		k = isdnpeek(ip, (void *)ip->devaddr);
		k = sprint(nbuf, "0x%2.2ux = 0x%2.2ux\n", ip->devaddr, k);
		goto Readnbuf;
		sprint(nbuf, "0x%2.2ux = 0x%2.2ux\n", ip->devaddr, k);
		return readstr(offset, buf, n, nbuf);
	case Qdebug:
		k = sprint(nbuf, "%d\n", isdndebug);
	Readnbuf:
		if (offset >= k)
			return 0;
		if (offset+n > k)
			n = k - offset;
		memmove(buf, nbuf+offset, n);
		return n;
		sprint(nbuf, "%d\n", isdndebug);
		return readstr(offset, buf, n, nbuf);
	}
	return streamread(c, buf, n);
}


@@ 222,7 227,19 @@ isdnwrite(Chan *c, void *buf, long n, ulong offset)
		default:
			error(Ebadarg);
		}
		return 1;
		return n;
	case Qb1xb2:
		if(offset>0)
			return 0;
		switch(*(char *)buf){
		case '0':
		case '1':
			devb1xb2(ip, *(char *)buf - '0');
			break;
		default:
			error(Ebadarg);
		}
		return n;
	case Qdev:
		if (n>sizeof nbuf)
			n = sizeof nbuf;


@@ 297,6 314,7 @@ isdnstopen(Queue *q, Stream *s)
	}
	q->ptr = q->other->ptr = ip;
	ip->rq = q;
	ip->hangup = 0;
	rss = (isdnpeek(ip, &unite->listat)&Rss)>>1;
	if (ip->lctl & Lld)		/* if loopback D, */
		devctl(ip, Tss, 0);	/* transmit INFO 0 */


@@ 413,6 431,7 @@ static void
isdnkproc(void *arg)
{
	Isdn *ip = (Isdn *)arg;
	Block *bp;
	int i;

	if(waserror()){


@@ 434,15 453,21 @@ isdnkproc(void *arg)
	wakeup(&ip->kctlr);
	for(;;){
		qlock(ip);
		if (!ip->rq){
		if(!ip->rq){
			qunlock(ip);
			break;
		}
		while (ip->ri != ip->wi){
		while(ip->ri != ip->wi){
			FLOWCTL(ip->rq, ip->inb[ip->ri]);
			ip->inb[ip->ri] = allocb(BSIZE);
			ip->ri = NEXT(ip->ri);
		}
		if(ip->hangup){
			ip->hangup = 0;
			bp = allocb(0);
			bp->type = M_HANGUP;
			PUTNEXT(ip->rq, bp);
		}
		i = 0;
		while(ip->so != ip->ro){
			freeb(ip->outb[ip->so]);


@@ 497,7 522,8 @@ devinit(int h)
	SET(unite->reset, Mres);
	ip->lctl = 0;		/* no loopback or 1's transmission */
	SET(unite->lctl, ip->lctl);
	SET(unite->stictl, Prye); /* S/T interface normal */
	ip->stictl = Prye;	/* S/T interface normal */
	SET(unite->stictl, ip->stictl);
	SET(unite->itl, 0x88);	/* interrupt on 8 rcv/xmit char's */
	SET(unite->hcr, Tpol|Ipol|Clkmux|B2f|B1f);
	ip->tctl = Ent;		/* enable transmitter, send INFO 0 */


@@ 555,10 581,24 @@ devlctl(Isdn *ip, int val)
	isdnlock(ip);
	ip->lctl = val;
	SET(unite->lctl, val);
	ip->stictl &= ~(Clrmm|Prye);
	if (val & Lld)
		SET(unite->stictl, Clrmm);
		ip->stictl |= Clrmm;
	else
		SET(unite->stictl, Prye);
		ip->stictl |= Prye;
	SET(unite->stictl, ip->stictl);
	isdnunlock(ip);
}

static void
devb1xb2(Isdn *ip, int val)
{
	isdnlock(ip);
	if(val)
		ip->stictl |= B1xb2;
	else
		ip->stictl &= ~B1xb2;
	SET(unite->stictl, ip->stictl);
	isdnunlock(ip);
}



@@ 590,11 630,12 @@ isdnintr(void)
static int
isdnInfo(Isdn *ip)
{
	int newstat;
	int oldstat, newstat;

	newstat = GET(unite->listat);
	DPRINT("isdnInfo: old=0x%2.2ux, new=0x%2.2ux\n",
		ip->listat, newstat);
	oldstat = (ip->listat&Rss)>>1;
	ip->listat = newstat;
	if (!ip->rq) {
		ip->imask &= ~Richgie;


@@ 609,8 650,14 @@ isdnInfo(Isdn *ip)
		ip->tctl |= 1;	/* transmit INFO 1 */
	SET(unite->tctl, ip->tctl);
	DPRINT("isdnInfo: tctl=0x%2.2ux\n", ip->tctl);
	if (newstat == 4)
	if(newstat == 4){
		wakeup(&ip->ar);
		return 0;
	}
	if(oldstat == 4){
		ip->hangup = 1;
		return 1;
	}
	return 0;
}


M gnot/isdn.h => gnot/isdn.h +2 -0
@@ 97,9 97,11 @@ struct Isdn
	uchar	venval;
	uchar *	asr;
	uchar *	data;
	int	hangup;		/* hangup pending */
	uchar	listat;		/* previous line interface status */
	uchar	tctl;		/* transmitter control */
	uchar	imask;		/* interrupt mask */
	uchar	stictl;		/* S/T interface control and b1xb2 bit */
	uchar	lctl;		/* loopback control */
	uchar	devaddr;	/* debug access */