From d8cb5b49a33c3014386c37c296ba49f82f5d2a5e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 6 Oct 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-10-06 --- ip/tcp.c | 20 ++++-- pc/cga.c | 4 +- pc/devusb.c | 198 ++++++++++++++++++++++++++-------------------------- pc/devvga.c | 10 ++- pc/screen.c | 6 +- pc/screen.h | 1 + 6 files changed, 128 insertions(+), 111 deletions(-) diff --git a/ip/tcp.c b/ip/tcp.c index b8f8b5af9c8cb6117bf43d3a8d91038dc7da0deb..7dd920aae5eff420750f4ca1c26280983618fd73 100644 --- a/ip/tcp.c +++ b/ip/tcp.c @@ -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 diff --git a/pc/cga.c b/pc/cga.c index e205449e3e51b2a663ddfa8cda50e14ccde0cf46..c1ffa0275e85daa8ab3eac9bd27ea82d79fcdbac 100644 --- a/pc/cga.c +++ b/pc/cga.c @@ -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)) diff --git a/pc/devusb.c b/pc/devusb.c index 1201a86766af211777464b5cbc2b4b9ba1b2920c..42f8edb9a2e3395d8faa7d3805a60db1eea3bc83 100644 --- a/pc/devusb.c +++ b/pc/devusb.c @@ -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 */ diff --git a/pc/devvga.c b/pc/devvga.c index 0e33eedb15685176f261fbbe2dccd159828a86e9..814445d971fcd292dfa7b4588d0caf90a503ad54 100644 --- a/pc/devvga.c +++ b/pc/devvga.c @@ -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; } diff --git a/pc/screen.c b/pc/screen.c index 2ef2f428861d80429c5da8d2f72f9316f80f7429..710e620e7d5748521a0eb634dd9f92ff73d76706 100644 --- a/pc/screen.c +++ b/pc/screen.c @@ -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 diff --git a/pc/screen.h b/pc/screen.h index b7516eae0538541d0936d0170c23fbaedad8292a..68b7ad566b5c202dda6c3e9cb2fc13eea40ccca0 100644 --- a/pc/screen.h +++ b/pc/screen.h @@ -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);