~kris/9p

9hist

d8cb5b49a33c3014386c37c296ba49f82f5d2a5e — David du Colombier 26 years ago de239c0
Plan 9 from Bell Labs 1999-10-06
6 files changed, 128 insertions(+), 111 deletions(-)

M ip/tcp.c
M pc/cga.c
M pc/devusb.c
M pc/devvga.c
M pc/screen.c
M pc/screen.h
M ip/tcp.c => ip/tcp.c +14 -6
@@ 237,7 237,7 @@ struct Tcppriv
	QLock	apl;
};

void	addreseq(Tcpctl*, Tcp*, Block*, ushort);
int	addreseq(Tcpctl*, Tcp*, Block*, ushort);
void	getreseq(Tcpctl*, Tcp*, Block**, ushort*);
void	localclose(Conv*, char*);
void	procsyn(Conv*, Tcp*);


@@ 1386,7 1386,8 @@ tcpiput(Proto *tcp, uchar*, Block *bp)
	if(length != 0 || (seg.flags & (SYN|FIN))) {
		update(s, &seg);
		tpriv->order++;
		addreseq(tcb, &seg, bp, length);
		if(addreseq(tcb, &seg, bp, length) < 0)
			print("reseq %I.%d -> %I.%d\n", s->raddr, s->rport, s->laddr, s->lport);
		tcb->flags |= FORCE;
		goto output;
	}


@@ 1973,16 1974,17 @@ procsyn(Conv *s, Tcp *seg)
	tcb->cwind = tcb->mss;
}

void
int
addreseq(Tcpctl *tcb, Tcp *seg, Block *bp, ushort length)
{
	Reseq *rp, *rp1;
	int i;
	static int once;

	rp = malloc(sizeof(Reseq));
	if(rp == nil){
		freeblist(bp);	/* bp always consumed by add_reseq */
		return;
		return 0;
	}

	rp->seg = *seg;


@@ 1994,7 1996,7 @@ addreseq(Tcpctl *tcb, Tcp *seg, Block *bp, ushort length)
	if(rp1 == nil || seq_lt(seg->seq, rp1->seg.seq)) {
		rp->next = rp1;
		tcb->reseq = rp;
		return;
		return 0;
	}

	length = 0;


@@ 2007,8 2009,14 @@ addreseq(Tcpctl *tcb, Tcp *seg, Block *bp, ushort length)
		}
		rp1 = rp1->next;
	}
	if(i > 100)
	if(i > 100 && once++ == 0){
		print("very long tcp resequence queue: %d\n", length);
		for(rp1 = tcb->reseq, i = 0; i < 10 && rp1 != nil; rp1 = rp1->next, i++)
			print("0x%lux 0x%lux 0x%ux", rp1->seg.seq, rp1->seg.ack,
				rp1->seg.flags);
		return -1;
	}
	return 0;
}

void

M pc/cga.c => pc/cga.c +3 -1
@@ 26,7 26,9 @@ enum {
	Width		= 80*2,
	Height		= 25,

	Attr		= (Black<<4)|White,		/* high nibble background, low foreground */
	Attr		= (Black<<4)|Grey,	/* high nibble background
						 * low foreground
						 */
};

#define CGASCREENBASE	((uchar*)KADDR(0xB8000))

M pc/devusb.c => pc/devusb.c +99 -99
@@ 1123,101 1123,6 @@ interrupt(Ureg*, void *a)
	iunlock(&activends);
}

static void
resetusbctlr(void)
{
	Ctlr *ub;
	Pcidev *cfg;
	int i;
	ulong port;
	QTree *qt;
	TD *t;

	ub = &ubus;
	memset(&cfg, 0, sizeof(cfg));
	cfg = pcimatch(0, 0x8086, 0x7112);	/* Intel chipset PIIX 4*/
	if(cfg == nil) {
//		cfg = pcimatch(0, 0x8086, 0x7112);	/* Intel chipset PIIX 3*/
//		if(cfg == nil) {
			cfg = pcimatch(0, 0x1106, 0x0586);	/* Via chipset */
			if(cfg == nil) {
				DPRINT("No USB device found\n");
				return;
			}
//		}
	}
	port = cfg->mem[4].bar & ~0x0F;
	if (port == 0) {
		print("usb: failed to map registers\n");
		return;
	}

	print("USB: %x/%x port 0x%lux size 0x%x irq %d\n",
		cfg->vid, cfg->did, port, cfg->mem[4].size, cfg->intl);

	i = inb(port+SOFMod);
	if(0){
		OUT(Cmd, 4);	/* global reset */
		delay(15);
		OUT(Cmd, 0);	/* end reset */
		delay(4);
	}
	outb(port+SOFMod, i);
	// Interrupt handler
	intrenable(cfg->intl, interrupt, ub, cfg->tbdf, "usb");

	ub->io = port;
	ub->tdpool = xspanalloc(128*sizeof(TD), 16, 0);
	for(i=128; --i>=0;){
		ub->tdpool[i].next = ub->freetd;
		ub->freetd = &ub->tdpool[i];
	}
	ub->qhpool = xspanalloc(32*sizeof(QH), 16, 0);
	for(i=32; --i>=0;){
		ub->qhpool[i].next = ub->freeqh;
		ub->freeqh = &ub->qhpool[i];
	}

	/*
	 * the root of the periodic (interrupt & isochronous) scheduling tree
	 * points to the control queue and the bandwidth sop for bulk traffic.
	 * this is looped following the instructions in PIIX4 errata 29773804.pdf:
	 * a QH links to a looped but inactive TD as its sole entry,
	 * with its head entry leading on to the bulk traffic, the last QH of which
	 * links back to the empty QH.
	 */
	ub->bulkq = allocqh(ub);
	t = alloctd(ub);	/* inactive TD, looped */
	t->link = PADDR(t);
	ub->bwsop = allocqh(ub);
	ub->bwsop->head = PADDR(ub->bulkq) | IsQH;
	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 */
	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",
		IN(Flbaseadd), inb(port+SOFMod), IN(Portsc0), IN(Portsc1));
	OUT(Cmd, 0);	/* stop */
	ub->frames = xspanalloc(FRAMESIZE, FRAMESIZE, 0);
	qt = mkqhtree(ub->frames, NFRAME, 32);
	if(qt == nil){
		print("usb: can't allocate scheduling tree\n");
		ub->io = 0;
		return;
	}
	qt->root->head = PADDR(ub->ctlq) | IsQH;
	ub->tree = qt;
	print("usb tree: nel=%d depth=%d\n", qt->nel, qt->depth);

	outl(port+Flbaseadd, PADDR(ub->frames));
	OUT(Frnum, 0);
	OUT(Usbintr, 0xF);	/* enable all interrupts */
	print("cmd 0x%x sofmod 0x%x\n", IN(Cmd), inb(port+SOFMod));
	print("sc0 0x%x sc1 0x%x\n", IN(Portsc0), IN(Portsc1));
}

enum
{
	Qtopdir = 0,


@@ 1317,7 1222,96 @@ usbnewdevice(void)
static void
usbreset(void)
{
	resetusbctlr();
	Ctlr *ub;
	Pcidev *cfg;
	int i;
	ulong port;
	QTree *qt;
	TD *t;

	ub = &ubus;
	memset(&cfg, 0, sizeof(cfg));
	cfg = pcimatch(0, 0x8086, 0x7112);	/* Intel chipset PIIX 4*/
	if(cfg == nil) {
//		cfg = pcimatch(0, 0x8086, 0x7112);	/* Intel chipset PIIX 3*/
//		if(cfg == nil) {
			cfg = pcimatch(0, 0x1106, 0x0586);	/* Via chipset */
			if(cfg == nil) {
				DPRINT("No USB device found\n");
				return;
			}
//		}
	}
	port = cfg->mem[4].bar & ~0x0F;
	if (port == 0) {
		print("usb: failed to map registers\n");
		return;
	}

	print("USB: %x/%x port 0x%lux size 0x%x irq %d\n",
		cfg->vid, cfg->did, port, cfg->mem[4].size, cfg->intl);

	i = inb(port+SOFMod);
	if(0){
		OUT(Cmd, 4);	/* global reset */
		delay(15);
		OUT(Cmd, 0);	/* end reset */
		delay(4);
	}
	outb(port+SOFMod, i);
	// Interrupt handler
	intrenable(cfg->intl, interrupt, ub, cfg->tbdf, "usb");

	ub->io = port;
	ub->tdpool = xspanalloc(128*sizeof(TD), 16, 0);
	for(i=128; --i>=0;){
		ub->tdpool[i].next = ub->freetd;
		ub->freetd = &ub->tdpool[i];
	}
	ub->qhpool = xspanalloc(32*sizeof(QH), 16, 0);
	for(i=32; --i>=0;){
		ub->qhpool[i].next = ub->freeqh;
		ub->freeqh = &ub->qhpool[i];
	}

	/*
	 * the root of the periodic (interrupt & isochronous) scheduling tree
	 * points to the control queue and the bandwidth sop for bulk traffic.
	 * this is looped following the instructions in PIIX4 errata 29773804.pdf:
	 * a QH links to a looped but inactive TD as its sole entry,
	 * with its head entry leading on to the bulk traffic, the last QH of which
	 * links back to the empty QH.
	 */
	ub->bulkq = allocqh(ub);
	t = alloctd(ub);	/* inactive TD, looped */
	t->link = PADDR(t);
	ub->bwsop = allocqh(ub);
	ub->bwsop->head = PADDR(ub->bulkq) | IsQH;
	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 */
	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",
		IN(Flbaseadd), inb(port+SOFMod), IN(Portsc0), IN(Portsc1));
	OUT(Cmd, 0);	/* stop */
	ub->frames = xspanalloc(FRAMESIZE, FRAMESIZE, 0);
	qt = mkqhtree(ub->frames, NFRAME, 32);
	if(qt == nil){
		print("usb: can't allocate scheduling tree\n");
		ub->io = 0;
		return;
	}
	qt->root->head = PADDR(ub->ctlq) | IsQH;
	ub->tree = qt;
	print("usb tree: nel=%d depth=%d\n", qt->nel, qt->depth);

	outl(port+Flbaseadd, PADDR(ub->frames));
	OUT(Frnum, 0);
	OUT(Usbintr, 0xF);	/* enable all interrupts */
	print("cmd 0x%x sofmod 0x%x\n", IN(Cmd), inb(port+SOFMod));
	print("sc0 0x%x sc1 0x%x\n", IN(Portsc0), IN(Portsc1));
}

void


@@ 1851,8 1845,10 @@ usbwrite(Chan *c, void *a, long n, vlong)
		}else if(nf == 6 && strcmp(fields[0], "ep") == 0){
			/* ep n maxpkt mode poll nbuf */
			i = strtoul(fields[1], nil, 0);
			if(i < 0 || i >= nelem(d->ep))
			if(i < 0 || i >= nelem(d->ep)) {
				pprint("field 1: 0 <= %d < %d\n", i, nelem(d->ep));
				error(Ebadarg);
			}
			if(d->ep[i] != nil)
				error(Einuse);
			e = devendpt(d, i, 1);


@@ 1872,15 1868,19 @@ usbwrite(Chan *c, void *a, long n, vlong)
				i = strtoul(fields[4], nil, 0);
				if(i > 0 && i <= 1000)
					e->pollms = i;
				else
				else {
					pprint("field 4: 0 <= %d <= 1000\n", i);
					error(Ebadarg);
				}
			}
			i = strtoul(fields[5], nil, 0);
			if(i >= 1 && i <= 32)
				e->nbuf = i;
			poperror();
		}else
		}else {
			pprint("command %s, fields %d\n", fields[0], nf);
			error(Ebadarg);
		}
		return n;

	case Qsetup:	/* SETUP endpoint 0 */

M pc/devvga.c => pc/devvga.c +7 -3
@@ 294,9 294,13 @@ vgactl(char* a)
		drawblankscreen(atoi(field[1]));
		return;
	}
	else if(strcmp(field[0], "hwacceloff") == 0){
		scr->fill = nil;
		scr->scroll = nil;
	else if(strcmp(field[0], "hwaccel") == 0){
		if(n < 2)
			error(Ebadarg);
		if(strcmp(field[1], "on") == 0)
			hwaccel = 1;
		else if(strcmp(field[1], "off") == 0)
			hwaccel = 0;
		return;
	}


M pc/screen.c => pc/screen.c +4 -2
@@ 464,14 464,17 @@ rgbatoimg(Memimage *img, ulong rgba)
Memimage *lastbadi;
Memdata *lastbad;
Memimage *lastbadsrc, *lastbaddst;
int hwaccel = 1;

#ifndef SDFSDF
int
hwdraw(Memdrawparam *par)
{
	VGAscr *scr;
	Memimage *dst, *src;

	if(hwaccel == 0)
		return 0;

	dst = par->dst;
	scr = &vgascreen[0];
	if(dst == nil || dst->data == nil)


@@ 514,4 517,3 @@ hwdraw(Memdrawparam *par)

	return 0;	
}
#endif

M pc/screen.h => pc/screen.h +1 -0
@@ 123,6 123,7 @@ enum {
extern void mousectl(char*[], int);

/* screen.c */
extern int		hwaccel;	/* use hw acceleration; default on */
extern void	flushmemscreen(Rectangle);
extern int	cursoron(int);
extern void	cursoroff(int);