~kris/9p

9hist

a76b648b539679455efd04cd2855209fda71e95f — David du Colombier 26 years ago 4eed1e1
Plan 9 from Bell Labs 1999-11-16
5 files changed, 84 insertions(+), 93 deletions(-)

M pc/devusb.c
M port/devsdp.c
M port/thwack.c
M port/thwack.h
M port/unthwack.c
M pc/devusb.c => pc/devusb.c +73 -33
@@ 30,7 30,9 @@
#define Pprint
#define Chatty	1
#define DPRINT if(Chatty)print
#define XPRINT if(0)print
#define XPRINT if(debug)print

static int debug = 1;

/*
 * USB packet definitions


@@ 211,10 213,10 @@ static char *devstates[] = {
struct Endpt {
	Ref;
	Lock;
	int	x;	/* index in Udev.ep */
	int	id;		/* hardware endpoint address */
	int	maxpkt;	/* maximum packet size (from endpoint descriptor) */
	int	data01;	/* 0=DATA0, 1=DATA1 */
	int		x;	/* index in Udev.ep */
	int		id;		/* hardware endpoint address */
	int		maxpkt;	/* maximum packet size (from endpoint descriptor) */
	int		data01;	/* 0=DATA0, 1=DATA1 */
	byte	eof;
	byte	class;
	byte	subclass;


@@ 225,11 227,11 @@ struct Endpt {
	byte	iso;
	byte	debug;
	byte	active;	/* listed for examination by interrupts */
	int	sched;	/* schedule index; -1 if undefined or aperiodic */
	int	setin;
	int		sched;	/* schedule index; -1 if undefined or aperiodic */
	int		setin;
	ulong	bw;	/* bandwidth requirement */
	int	pollms;	/* polling interval in msec */
	QH*	epq;	/* queue of TDs for this endpoint */
	int		pollms;	/* polling interval in msec */
	QH*		epq;	/* queue of TDs for this endpoint */

	QLock	rlock;
	Rendez	rr;


@@ 238,7 240,7 @@ struct Endpt {
	Rendez	wr;
	Queue*	wq;

	int	ntd;
	int		ntd;
	char*	err;

	Udev*	dev;	/* owning device */


@@ 470,6 472,7 @@ queuetd(Ctlr *ub, QH *q, TD *t, int vf)
		q->entries = PADDR(t);
	}
	q->last = lt;
	dumpqh(q);
	iunlock(ub);
}



@@ 541,36 544,60 @@ cleantd(TD *t, int discard)
}

static void
cleanq(QH *q, int discard)
cleanq(QH *q, int discard, int vf)
{
	TD *t;
	TD *t, *tp;
	Ctlr *ub;

	ub = &ubus;
	ilock(ub);
	tp = nil;
	for(t = q->first; t != nil;){
//		XPRINT("cleanq: %8.8lux %8.8lux %8.8lux %8.8lux\n", t->link, t->status, t->dev, t->buffer);
		XPRINT("cleanq: %8.8lux %8.8lux %8.8lux %8.8lux %8.8lux %8.8lux\n", t->link, t->status, t->dev, t->buffer, t->flags, t->next);
		if(t->status & Active){
			if(t->status & NAKed){
				t->status = (t->status & ~NAKed) | IOC;	/* ensure interrupt next frame */
				tp = t;
				t = t->next;
				continue;
			}
			if(t->flags & CancelTD){
				XPRINT("cancelTD: %8.8lux\n", (ulong)t);
				t->status = (t->status & ~Active) | IOC;	/* ensure interrupt next frame */
				tp = t;
				t = t->next;
				continue;
			}
tp = t;
t = t->next;
continue;
			break;
		}
		t->status &= ~IOC;
		/* TO DO: need to deal with TDs as chain if necessary */
		q->first = t->next;
		if(q->first != nil)
			q->entries = PADDR(q->first);
		else
			q->entries = Terminate;
		t->next = nil;
		if (tp == nil) {
			q->first = t->next;
			if(q->first != nil)
				q->entries = PADDR(q->first);
			else
				q->entries = Terminate;
		} else {
			tp->next = t->next;
			if (t->next != nil)
				tp->link = PADDR(t->next) | vf;
			else
				tp->link = Terminate;
		}
		if (q->last == t)
			q->last = tp;
		iunlock(ub);
		cleantd(t, discard);
		ilock(ub);
		t = q->first;
		if (tp)
			t = tp->next;
		else
			t = q->first;
		XPRINT("t = %8.8lux\n", t);
		dumpqh(q);
	}
	iunlock(ub);
}


@@ 676,6 703,7 @@ qrcv(Endpt *e)
	QH *qh;
	int vf;

XPRINT("qrcv\n");
	t = alloctde(e, TokIN, e->maxpkt);
	b = allocb(e->maxpkt);
	t->bp = b;


@@ 683,9 711,10 @@ qrcv(Endpt *e)
	ub = &ubus;
	vf = 0;
	if(e->x == 0){
XPRINT("enq\n");
		qh = ub->ctlq;
		vf = 0;
	}else if((qh = e->epq) == nil || e->mode != OREAD){
XPRINT("bulkenq\n");
		qh = ub->bulkq;
		vf = Vf;
	}


@@ 912,6 941,10 @@ devendpt(Udev *d, int id, int add)
	e->nbuf = 1;
	e->dev = d;
	e->active = 0;
	e->epq = allocqh(ub);
	if(e->epq == nil)
		panic("devendpt");

	lock(d);
	if(*p != nil){
		incref(*p);


@@ 1065,22 1098,22 @@ interrupt(Ureg*, void *a)

	ub = a;
	s = IN(Status);
	XPRINT("usbint: #%x f%d\n", s, IN(Frnum));
	if (s & 0x1a) {
		XPRINT("usbint: #%x f%d\n", s, IN(Frnum));
		XPRINT("cmd #%x sofmod #%x\n", IN(Cmd), inb(ub->io+SOFMod));
		XPRINT("sc0 #%x sc1 #%x\n", IN(Portsc0), IN(Portsc1));
	}
	OUT(Status, s);

//	XPRINT("cleanq(ub->ctlq, 0)\n");
	cleanq(ub->ctlq, 0);
//	XPRINT("cleanq(ub->bulkq, 0)\n");
	cleanq(ub->bulkq, 0);
	XPRINT("cleanq(ub->ctlq, 0, 0)\n");
	cleanq(ub->ctlq, 0, 0);
	XPRINT("cleanq(ub->bulkq, 0, Vf)\n");
	cleanq(ub->bulkq, 0, Vf);
	ilock(&activends);
	for(e = activends.f; e != nil; e = e->activef)
		if(e->epq != nil) {
//			XPRINT("cleanq(e->epq, 0)\n");
			cleanq(e->epq, 0);
			XPRINT("cleanq(e->epq, 0, 0)\n");
			cleanq(e->epq, 0, 0);
		}
	iunlock(&activends);
}


@@ 1252,7 1285,7 @@ usbreset(void)
	ub->bwsop->entries = PADDR(t);
	ub->ctlq = allocqh(ub);
	ub->ctlq->head = PADDR(ub->bwsop) | IsQH;
//	ub->bulkq->head = PADDR(ub->bwsop) | IsQH;	/* loop back */
	ub->bulkq->head = PADDR(ub->bwsop) | IsQH;	/* loop back */
	print("usbcmd\t0x%.4x\nusbsts\t0x%.4x\nusbintr\t0x%.4x\nfrnum\t0x%.2x\n",
		IN(Cmd), IN(Status), IN(Usbintr), inb(port+Frnum));
	print("frbaseadd\t0x%.4x\nsofmod\t0x%x\nportsc1\t0x%.4x\nportsc2\t0x%.4x\n",


@@ 1523,7 1556,9 @@ readusb(Endpt *e, void *a, long n)
	uchar *p;
	long l, i;

	XPRINT("qlock(%p)\n", &e->rlock);
	qlock(&e->rlock);
	XPRINT("got qlock(%p)\n", &e->rlock);
	if(waserror()){
		qunlock(&e->rlock);
		eptcancel(e);


@@ 1794,10 1829,15 @@ usbwrite(Chan *c, void *a, long n, vlong)
				e->maxpkt = 1500;
		}else if(nf > 2 && strcmp(fields[0], "debug") == 0){
			i = strtoul(fields[1], nil, 0);
			if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil)
			if(i < -1 || i >= nelem(d->ep) || d->ep[i] == nil)
				error(Ebadarg);
			e = d->ep[i];
			e->debug = strtoul(fields[2], nil, 0);
			if (i == -1)
				debug = 0;
			else {
				debug = 1;
				e = d->ep[i];
				e->debug = strtoul(fields[2], nil, 0);
			}
		}else if(nf > 1 && strcmp(fields[0], "unstall") == 0){
			i = strtoul(fields[1], nil, 0);
			if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil)

M port/devsdp.c => port/devsdp.c +1 -3
@@ 341,8 341,6 @@ sdpinit(void)
	int i;
	Dirtab *dt;
	
	return;

	// setup dirtab with non directory entries
	for(i=0; i<nelem(sdpdirtab); i++) {
		dt = sdpdirtab + i;


@@ 774,7 772,7 @@ sdpclone(Sdp *sdp)
			break;
		}
		if(canqlock(c)){
			if(c->state == CClosed && c->reader == 0)
			if(c->state == CClosed && c->reader == 0 && c->ref == 0)
				break;
			qunlock(c);
		}

M port/thwack.c => port/thwack.c +7 -20
@@ 6,11 6,6 @@

#include "thwack.h"

/*
 * don't include compressed blocks
 */
#define NOUNCOMP

typedef struct Huff	Huff;

enum


@@ 27,12 22,11 @@ enum
	StatOutBytes,
	StatLits,
	StatMatches,
	StatLitBits,
	StatOffBits,
	StatLenBits,

	StatProbe,
	StatProbeMiss,
	StatDelay,
	StatHist,

	MaxStat
};


@@ 172,7 166,7 @@ thwack(Thwack *tw, uchar *dst, uchar *src, int n, ulong seq, ulong stats[ThwStat
	ThwBlock *eblocks, *b, blocks[CompBlocks];
	uchar *s, *ss, *sss, *esrc, *half, *twdst, *twdmax;
	ulong cont, cseq, bseq, cmask, code, twbits;
	int now, toff, lithist, h, len, slot, bits, use, twnbits, lits, matches, offbits, lenbits;
	int now, toff, lithist, h, len, slot, bits, use, twnbits, lits, matches, offbits, lenbits, nhist;

	if(n > ThwMaxBlock || n < MinMatch)
		return -1;


@@ 204,6 198,7 @@ thwack(Thwack *tw, uchar *dst, uchar *src, int n, ulong seq, ulong stats[ThwStat
	b = blocks;
	b->maxoff = 0;
	b++;
	nhist = 0;
	while(b < blocks + CompBlocks){
		slot--;
		if(slot < 0)


@@ 222,18 217,13 @@ thwack(Thwack *tw, uchar *dst, uchar *src, int n, ulong seq, ulong stats[ThwStat
		else
			cmask |= 1 << (cseq - bseq - 1);
		*b = tw->blocks[slot];
		nhist += b->maxoff;
		b++;
	}
	eblocks = b;
	*twdst++ = seq - cseq;
	*twdst++ = cmask;

#ifndef NOUNCOMP
	tw->slot++;
	if(tw->slot >= EWinBlocks)
		tw->slot = 0;
#endif

	cont = (s[0] << 16) | (s[1] << 8) | s[2];

	esrc = s + n;


@@ 280,7 270,6 @@ thwack(Thwack *tw, uchar *dst, uchar *src, int n, ulong seq, ulong stats[ThwStat
			lits++;
			blocks->maxoff++;

#ifdef NOUNCOMP
			/*
			 * speed hack
			 * check for compression progress, bail if none achieved


@@ 290,7 279,6 @@ thwack(Thwack *tw, uchar *dst, uchar *src, int n, ulong seq, ulong stats[ThwStat
					return -1;
				half = esrc;
			}
#endif

			if(s + MinMatch <= esrc){
				blocks->hash[(h ^ blocks->seq) & HashMask] = now;


@@ 370,9 358,10 @@ thwack(Thwack *tw, uchar *dst, uchar *src, int n, ulong seq, ulong stats[ThwStat
	stats[StatBytes] += blocks->maxoff;
	stats[StatLits] += lits;
	stats[StatMatches] += matches;
	stats[StatLitBits] += (twdst - (dst + 2)) * 8 + twnbits - offbits - lenbits;
	stats[StatOffBits] += offbits;
	stats[StatLenBits] += lenbits;
	stats[StatDelay] = stats[StatDelay]*7/8 + dst[0];
	stats[StatHist] = stats[StatHist]*7/8 + nhist;

	if(twnbits & 7){
		twbits <<= 8 - (twnbits & 7);


@@ 384,11 373,9 @@ thwack(Thwack *tw, uchar *dst, uchar *src, int n, ulong seq, ulong stats[ThwStat
		*twdst++ = twbits >> (twnbits - 8);
	}

#ifdef NOUNCOMP
	tw->slot++;
	if(tw->slot >= EWinBlocks)
		tw->slot = 0;
#endif

	stats[StatOutBytes] += twdst - dst;


M port/thwack.h => port/thwack.h +0 -1
@@ 65,4 65,3 @@ void	unthwackinit(Unthwack*);
int	thwack(Thwack*, uchar *dst, uchar *src, int nsrc, ulong seq, ulong stats[ThwStats]);
void	thwackack(Thwack*, ulong seq, ulong mask);
int	unthwack(Unthwack*, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq);
int	unthwackadd(Unthwack*, uchar *src, int nsrc, ulong seq);

M port/unthwack.c => port/unthwack.c +3 -36
@@ 6,11 6,6 @@

#include "thwack.h"

/*
 * don't include compressed blocks
 */
#define NOUNCOMP

enum
{
	DMaxFastLen	= 7,


@@ 65,36 60,6 @@ unthwackinit(Unthwack *ut)
}

int
unthwackadd(Unthwack *ut, uchar *src, int nsrc, ulong seq)
{
	int slot, tslot;

	if(nsrc > ThwMaxBlock)
		return -1;

#ifndef NOUNCOMP
	tslot = ut->slot;
	for(;;){
		slot = tslot - 1;
		if(slot < 0)
			slot += DWinBlocks;
		if(ut->blocks[slot].seq <= seq)
			break;
		ut->blocks[slot] = ut->blocks[tslot];
		tslot = slot;
	}
	ut->blocks[tslot].seq = seq;
	ut->blocks[tslot].maxoff = nsrc;
	memmove(ut->blocks[tslot].data, src, nsrc);

	ut->slot++;
	if(ut->slot >= DWinBlocks)
		ut->slot = 0;
#endif
	return nsrc;
}

int
unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq)
{
	UnthwBlock blocks[CompBlocks], *b, *eblocks;


@@ 118,7 83,9 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq)
			slot += DWinBlocks;
		if(ut->blocks[slot].seq <= seq)
			break;
		ut->blocks[slot] = ut->blocks[tslot];
		d = ut->blocks[tslot].data;
		ut->blocks[tslot] = ut->blocks[slot];
		ut->blocks[slot].data = d;
		tslot = slot;
	}
	b = blocks;