M ip/devip.c => ip/devip.c +8 -0
@@ 1344,3 1344,11 @@ ndbwrite(Fs *f, char *a, ulong off, int n)
f->ndb[off+n] = 0;
return n;
}
+
+ulong
+scalednconv(void)
+{
+ if(cpuserver && conf.npage*BY2PG >= 128*MB)
+ return Nchans*4;
+ return Nchans;
+}
M ip/il.c => ip/il.c +1 -1
@@ 1386,7 1386,7 @@ ilinit(Fs *f)
il->inuse = ilinuse;
il->gc = nil;
il->ipproto = IP_ILPROTO;
- il->nc = Nchans;
+ il->nc = scalednconv();
il->ptclsize = sizeof(Ilcb);
Fsproto(f, il);
}
M ip/ip.h => ip/ip.h +2 -0
@@ 305,7 305,9 @@ Proto* Fsrcvpcolx(Fs*, uchar);
char* Fsstdconnect(Conv*, char**, int);
char* Fsstdannounce(Conv*, char**, int);
char* Fsstdbind(Conv*, char**, int);
+ulong scalednconv(void);
void closeconv(Conv*);
+
/*
* logging
*/
M ip/tcp.c => ip/tcp.c +2 -2
@@ 2321,9 2321,9 @@ tcpinit(Fs *fs)
tcp->inuse = tcpinuse;
tcp->gc = tcpgc;
tcp->ipproto = IP_TCPPROTO;
- tcp->nc = Nchans;
+ tcp->nc = scalednconv();
tcp->ptclsize = sizeof(Tcpctl);
- tpriv->stats[MaxConn] = Nchans;
+ tpriv->stats[MaxConn] = tcp->nc;
Fsproto(fs, tcp);
}
M pc/devusb.c => pc/devusb.c +14 -7
@@ 204,7 204,7 @@ struct Endpt {
int data01; /* 0=DATA0, 1=DATA1 */
byte eof;
ulong csp;
- byte isopen; /* ep operations forbidde on open endpoints */
+ byte isopen; /* ep operations forbidden on open endpoints */
byte mode; /* OREAD, OWRITE, ORDWR */
byte nbuf; /* number of buffers allowed */
byte iso;
@@ 877,8 877,8 @@ schedendpt(Endpt *e)
if (e->isopen){
return -1;
}
-
- e->curblock = allocb(e->maxpkt);
+ if (e->curblock == nil)
+ e->curblock = allocb(e->maxpkt);
if (e->curblock == nil)
panic("schedept: allocb");
e->curbytes = 0;
@@ 975,10 975,8 @@ devendpt(Udev *d, int id, int add)
e->ref = 1;
e->x = id&0xF;
e->id = id;
- e->iso = 0;
e->sched = -1;
e->maxpkt = 8;
- e->pollms = 0;
e->nbuf = 1;
e->dev = d;
e->active = 0;
@@ 1005,7 1003,6 @@ freept(Endpt *e)
{
if(e != nil && decref(e) == 0){
XPRINT("freept(%d,%d)\n", e->dev->x, e->x);
- e->isopen = 0;
unschedendpt(e);
e->dev->ep[e->x] = nil;
eptdeactivate(e);
@@ 1561,8 1558,8 @@ usbopen(Chan *c, int omode)
}
if(schedendpt(e) < 0)
error("can't schedule USB endpoint");
+ e->isopen++;
eptactivate(e);
- e->isopen = 1;
}
incref(d);
break;
@@ 1599,6 1596,7 @@ void
usbclose(Chan *c)
{
Udev *d;
+ int s;
if(c->qid.type == QTDIR || c->qid.path < Q3rd)
return;
@@ 1608,6 1606,15 @@ usbclose(Chan *c)
nexterror();
}
d = usbdevice(c);
+ s = QID(c->qid) - Qep0;
+ if(s >= 0 && s < nelem(d->ep)){
+ Endpt *e;
+ if((e = d->ep[s]) == nil) {
+ XPRINT("usbopen failed (endpoint)\n");
+ error(Enodev);
+ }
+ e->isopen--;
+ }
if(QID(c->qid) == Qctl)
d->busy = 0;
if(c->flag & COPEN)
M pc/fns.h => pc/fns.h +1 -0
@@ 43,6 43,7 @@ int i8042auxcmd(int);
void i8042auxenable(void (*)(int, int));
void i8042reset(void);
void i8250console(void);
+void* i8250alloc(int, int, int);
void i8253init(int, int);
void i8253enable(void);
uvlong i8253read(uvlong*);
M pc/uarti8250.c => pc/uarti8250.c +19 -0
@@ 521,6 521,11 @@ i8250disable(Uart* uart)
ctlr = uart->regs;
ctlr->sticky[Ier] = 0;
csr8w(ctlr, Ier, 0);
+
+ if(ctlr->iena != 0){
+ intrdisable(ctlr->irq, i8250interrupt, uart, ctlr->tbdf, uart->name);
+ ctlr->iena = 0;
+ }
}
static void
@@ 554,6 559,20 @@ i8250enable(Uart* uart, int ie)
(*uart->phys->rts)(uart, 1);
}
+void*
+i8250alloc(int io, int irq, int tbdf)
+{
+ Ctlr *ctlr;
+
+ if((ctlr = malloc(sizeof(Ctlr))) != nil){
+ ctlr->io = io;
+ ctlr->irq = irq;
+ ctlr->tbdf = tbdf;
+ }
+
+ return ctlr;
+}
+
static Uart*
i8250pnp(void)
{
A pc/uartpci.c => pc/uartpci.c +131 -0
@@ 0,0 1,131 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "../port/error.h"
+
+extern PhysUart i8250physuart;
+extern PhysUart pciphysuart;
+extern void* i8250alloc(int, int, int);
+
+static Uart*
+uartpci(int ctlrno, Pcidev* p, int barno, int n, int freq, char* name)
+{
+ int i, io;
+ void *ctlr;
+ char buf[64];
+ Uart *head, *uart;
+
+ io = p->mem[barno].bar & ~0x01;
+ snprint(buf, sizeof(buf), "%s%d", pciphysuart.name, ctlrno);
+ if(ioalloc(io, p->mem[barno].size, 0, buf) < 0){
+ print("uartpci: I/O 0x%uX in use\n", io);
+ return nil;
+ }
+
+ head = uart = malloc(sizeof(Uart)*n);
+
+ for(i = 0; i < n; i++){
+ ctlr = i8250alloc(io, p->intl, p->tbdf);
+ io += 8;
+ if(ctlr == nil)
+ continue;
+
+ uart->regs = ctlr;
+ snprint(buf, sizeof(buf), "%s.%8.8uX", name, p->tbdf);
+ kstrdup(&uart->name, buf);
+ uart->freq = freq;
+ uart->phys = &i8250physuart;
+ if(uart != head)
+ (uart-1)->next = uart;
+ uart++;
+ }
+
+ return head;
+}
+
+static Uart*
+uartpcipnp(void)
+{
+ Pcidev *p;
+ char *name;
+ int ctlrno, n, subid;
+ Uart *head, *tail, *uart;
+
+ /*
+ * Loop through all PCI devices looking for simple serial
+ * controllers (ccrb == 0x07) and configure the ones which
+ * are familiar. All suitable devices are configured to
+ * simply point to the generic i8250 driver.
+ */
+ head = tail = nil;
+ ctlrno = 0;
+ for(p = pcimatch(nil, 0, 0); p != nil; p = pcimatch(p, 0, 0)){
+ if(p->ccrb != 0x07 || p->ccru != 0)
+ continue;
+
+ switch((p->did<<16)|p->vid){
+ default:
+ continue;
+ case (0x9050<<16)|0x10B5: /* Perle PCI-Fast4 */
+ /*
+ * These devices consists of a PLX bridge (the above
+ * PCI VID+DID) behind which are some 16C654 UARTs.
+ * Must check the subsystem VID and DID for correct
+ * match.
+ */
+ subid = pcicfgr16(p, PciSVID);
+ subid |= pcicfgr16(p, PciSID)<<16;
+ switch(subid){
+ default:
+ continue;
+ case (0x0011<<16)|0x12E0: /* Perle PCI-Fast16 */
+ n = 16;
+ name = "PCI-Fast16";
+ break;
+ case (0x0021<<16)|0x12E0: /* Perle PCI-Fast8 */
+ n = 8;
+ name = "PCI-Fast8";
+ break;
+ case (0x0031<<16)|0x12E0: /* Perle PCI-Fast4 */
+ n = 4;
+ name = "PCI-Fast4";
+ break;
+ }
+ uart = uartpci(ctlrno, p, 2, n, 7372800, name);
+ if(uart == nil)
+ continue;
+ break;
+ }
+
+ if(head != nil)
+ tail->next = uart;
+ else
+ head = uart;
+ for(tail = uart; tail->next != nil; tail = tail->next)
+ ;
+ ctlrno++;
+ }
+
+ return head;
+}
+
+PhysUart pciphysuart = {
+ .name = "UartPCI",
+ .pnp = uartpcipnp,
+ .enable = nil,
+ .disable = nil,
+ .kick = nil,
+ .dobreak = nil,
+ .baud = nil,
+ .bits = nil,
+ .stop = nil,
+ .parity = nil,
+ .modemctl = nil,
+ .rts = nil,
+ .dtr = nil,
+ .status = nil,
+ .fifo = nil,
+};
M port/chan.c => port/chan.c +1 -0
@@ 1237,6 1237,7 @@ if(c->umh != nil){
putmhead(m);
cclose(c);
c = cnew;
+ c->name = addelem(c->name, e.elems[e.nelems-1]);
break;
}else{ /* create failed */
cclose(cnew);