M ip/il.c => ip/il.c +1 -1
@@ 884,7 884,7 @@ ilpullup(Conv *s)
bp = concatblock(bp);
if(bp == 0)
panic("ilpullup");
- qpass(s->rq, bp);
+ qpassnolim(s->rq, packblock(bp));
}
qunlock(&ic->outo);
}
M ip/tcp.c => ip/tcp.c +17 -6
@@ 20,7 20,7 @@ enum
TimerON = 1,
TimerDONE = 2,
MAX_TIME = (1<<20), /* Forever */
- TCP_ACK = 50, /* Timed ack sequence in ms */
+ TCP_ACK = 200, /* Timed ack sequence in ms */
URG = 0x20, /* Data marked urgent */
ACK = 0x10, /* Acknowledge is valid */
@@ 1384,17 1384,21 @@ tcpiput(Proto *tcp, uchar*, Block *bp)
* receive queue
*/
if(bp) {
- qpass(s->rq, bp);
+ qpassnolim(s->rq, packblock(bp));
bp = nil;
}
tcb->rcv.nxt += length;
tcprcvwin(s);
- if(tcb->acktimer.state != TimerON)
- tcpgo(tpriv, &tcb->acktimer);
- /* force an ack if there's a lot of unacked data */
- if(tcb->rcv.nxt-tcb->last_ack > (QMAX>>4))
+ /*
+ * force an ack if we've got 2 segs
+ * and the user isn't backing up
+ */
+ if(tcb->rcv.nxt - tcb->last_ack >= 2*tcb->mss &&
+ qlen(s->rq) < 8*tcb->mss)
tcb->flags |= FORCE;
+ else if(tcb->acktimer.state != TimerON)
+ tcpgo(tpriv, &tcb->acktimer);
break;
case Finwait2:
@@ 1637,8 1641,15 @@ tcpoutput(Conv *s)
* expect acknowledges
*/
if(ssize != 0){
+ /* round trip depenency */
x = backoff(tcb->backoff) *
(tcb->mdev + (tcb->srtt>>LOGAGAIN) + MSPTICK) / MSPTICK;
+
+ /* take into account delayed ack */
+ if(sent <= 2*tcb->mss)
+ x += TCP_ACK/MSPTICK;
+
+ /* sanity check */
if(x > (10000/MSPTICK))
x = 10000/MSPTICK;
tcb->timer.start = x;
M pc/ns16552.h => pc/ns16552.h +2 -2
@@ 129,7 129,7 @@ ns16552install(void)
if(sc->freq == 0)
sc->freq = UartFREQ;
sc->first = nuart;
- intrenable(VectorPIC+sc->irq, mp008intr, sc, BUSUNKNOWN);
+ intrenable(sc->irq, mp008intr, sc, BUSUNKNOWN);
port = sc->port;
for(j=0; j < sc->size; j++){
sprint(name, "eia%d%2.2d", nscard, j);
@@ 146,7 146,7 @@ ns16552install(void)
sc->freq = UartFREQ;
sprint(name, "eia%d00", nscard);
ns16552setup(sc->port, sc->freq, name);
- intrenable(VectorPIC+sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN);
+ intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN);
}
nscard++;
}
M pc/pcmciamodem.c => pc/pcmciamodem.c +1 -0
@@ 21,6 21,7 @@ enum {
static char* modems[] = {
"IBM 33.6 Data/Fax/Voice Modem",
+ "CM-56G", /* Xircom CreditCard Modem 56 - GlobalACCESS */
"KeepInTouch",
0,
};
M port/portdat.h => port/portdat.h +1 -0
@@ 136,6 136,7 @@ struct Block
ulong flag;
};
#define BLEN(s) ((s)->wp - (s)->rp)
+#define BALLOC(s) ((s)->lim - (s)->base);
struct Chan
{
M port/portfns.h => port/portfns.h +2 -0
@@ 170,6 170,7 @@ int notify(Ureg*);
int nrand(int);
int okaddr(ulong, ulong, int);
int openmode(ulong);
+Block* packblock(Block*);
Block* padblock(Block*, int);
void pagechainhead(Page*);
void pageinit(void);
@@ 229,6 230,7 @@ int qlen(Queue*);
void qlock(QLock*);
Queue* qopen(int, int, void (*)(void*), void*);
int qpass(Queue*, Block*);
+int qpassnolim(Queue*, Block*);
int qproduce(Queue*, void*, int);
long qread(Queue*, void*, int);
void qreopen(Queue*);
M port/qio.c => port/qio.c +102 -12
@@ 95,6 95,19 @@ checkb(Block *b, char *msg)
}
void
+checkqlen(Queue *q)
+{
+ int len;
+ Block *b;
+
+ len = 0;
+ for(b = q->bfirst; b; b = b->next)
+ len += BALLOC(b);
+ if(len != q->len)
+ panic("checkqlen");
+}
+
+void
ixsummary(void)
{
debugging ^= 1;
@@ 517,7 530,7 @@ qget(Queue *q)
}
q->bfirst = b->next;
b->next = 0;
- q->len -= BLEN(b);
+ q->len -= BALLOC(b);
QDEBUG checkb(b, "qget");
/* if writer flow controlled, restart */
@@ 554,12 567,12 @@ qdiscard(Queue *q, int len)
if(n <= len - sofar){
q->bfirst = b->next;
b->next = 0;
+ q->len -= BALLOC(b);
freeb(b);
} else {
n = len - sofar;
b->rp += n;
}
- q->len -= n;
}
/* if writer flow controlled, restart */
@@ 601,6 614,7 @@ qconsume(Queue *q, void *vp, int len)
if(n > 0)
break;
q->bfirst = b->next;
+ q->len -= BALLOC(b);
freeb(b);
};
@@ 611,7 625,6 @@ qconsume(Queue *q, void *vp, int len)
if((q->state & Qmsg) || len == n)
q->bfirst = b->next;
b->rp += len;
- q->len -= len;
/* if writer flow controlled, restart */
if((q->state & Qflow) && q->len < q->limit/2){
@@ 629,6 642,7 @@ qconsume(Queue *q, void *vp, int len)
/* discard the block if we're done with it */
if((q->state & Qmsg) || len == n){
b->next = 0;
+ q->len -= BALLOC(b);
freeb(b);
}
return len;
@@ 643,7 657,7 @@ qpass(Queue *q, Block *b)
dowakeup = 0;
ilock(q);
if(q->len >= q->limit){
- freeb(b);
+ freeblist(b);
iunlock(q);
return -1;
}
@@ 653,12 667,12 @@ qpass(Queue *q, Block *b)
q->blast->next = b;
else
q->bfirst = b;
- len = BLEN(b);
+ len = BALLOC(b);
QDEBUG checkb(b, "qpass");
while(b->next){
b = b->next;
QDEBUG checkb(b, "qpass");
- len += BLEN(b);
+ len += BALLOC(b);
}
q->blast = b;
q->len += len;
@@ 670,6 684,7 @@ qpass(Queue *q, Block *b)
q->state &= ~Qstarve;
dowakeup = 1;
}
+checkqlen(q);
iunlock(q);
if(dowakeup)
@@ 679,6 694,71 @@ qpass(Queue *q, Block *b)
}
int
+qpassnolim(Queue *q, Block *b)
+{
+ int len, dowakeup;
+
+ /* sync with qread */
+ dowakeup = 0;
+ ilock(q);
+
+ /* add buffer to queue */
+ if(q->bfirst)
+ q->blast->next = b;
+ else
+ q->bfirst = b;
+ len = BALLOC(b);
+ QDEBUG checkb(b, "qpass");
+ while(b->next){
+ b = b->next;
+ QDEBUG checkb(b, "qpass");
+ len += BALLOC(b);
+ }
+ q->blast = b;
+ q->len += len;
+
+ if(q->len >= q->limit/2)
+ q->state |= Qflow;
+
+ if(q->state & Qstarve){
+ q->state &= ~Qstarve;
+ dowakeup = 1;
+ }
+checkqlen(q);
+ iunlock(q);
+
+ if(dowakeup)
+ wakeup(&q->rr);
+
+ return len;
+}
+
+/*
+ * if the allocated space is way out of line with the used
+ * space, reallocate to a smaller block
+ */
+Block*
+packblock(Block *bp)
+{
+ int len, alen;
+ Block *nbp;
+
+ len = alen = 0;
+ for(nbp = bp; nbp; nbp = bp->next){
+ len += BLEN(bp);
+ alen += BALLOC(bp);
+ }
+
+ if(alen >= (len<<2)){
+ nbp = allocb(len);
+ nbp->next = bp;
+ return pullupblock(nbp, len);
+ }
+
+ return bp;
+}
+
+int
qproduce(Queue *q, void *vp, int len)
{
Block *b;
@@ 711,13 791,14 @@ qproduce(Queue *q, void *vp, int len)
q->bfirst = b;
q->blast = b;
/* b->next = 0; done by iallocb() */
- q->len += len;
+ q->len += BALLOC(b);
QDEBUG checkb(b, "qproduce");
if(q->state & Qstarve){
q->state &= ~Qstarve;
dowakeup = 1;
}
+checkqlen(q);
iunlock(q);
if(dowakeup)
@@ 854,7 935,7 @@ qbread(Queue *q, int len)
q->bfirst = b->next;
b->next = 0;
n = BLEN(b);
- q->len -= n;
+ q->len -= BALLOC(b);
QDEBUG checkb(b, "qbread 1");
/* if writer flow controlled, restart */
@@ 880,11 961,12 @@ qbread(Queue *q, int len)
if(q->bfirst == 0)
q->blast = b;
q->bfirst = b;
- q->len += n;
+ q->len += BALLOC(b);
}
nb->wp = nb->rp + len;
}
+checkqlen(q);
iunlock(q);
/* wakeup flow controlled writers */
@@ 975,7 1057,7 @@ qbwrite(Queue *q, Block *b)
q->bfirst = b;
q->blast = b;
b->next = 0;
- q->len += n;
+ q->len += BALLOC(b);
QDEBUG checkb(b, "qbwrite");
if(q->state & Qstarve){
@@ 983,6 1065,7 @@ qbwrite(Queue *q, Block *b)
dowakeup = 1;
}
+checkqlen(q);
iunlock(q);
if(dowakeup){
@@ 1063,13 1146,14 @@ qiwrite(Queue *q, void *vp, int len)
else
q->bfirst = b;
q->blast = b;
- q->len += n;
+ q->len += BALLOC(b);
if(q->state & Qstarve){
q->state &= ~Qstarve;
dowakeup = 1;
}
+checkqlen(q);
iunlock(q);
if(dowakeup){
@@ 1167,7 1251,13 @@ qreopen(Queue *q)
int
qlen(Queue *q)
{
- return q->len;
+ int len;
+ Block *b;
+
+ len = 0;
+ for(b = q->bfirst; b; b= b->next)
+ len += BLEN(b);
+ return len;
}
/*