M ip/il.c => ip/il.c +1 -1
@@ 56,7 56,7 @@ enum
Seconds = 1000,
Iltickms = 50, /* time base */
AckDelay = 2*Iltickms, /* max time twixt message rcvd & ack sent */
- MaxTimeout = 4*Seconds, /* max time between rexmit */
+ MaxTimeout = 30*Seconds, /* max time between rexmit */
QueryTime = 10*Seconds, /* time between subsequent queries */
DeathTime = 5*QueryTime,
M ip/tcp.c => ip/tcp.c +20 -9
@@ 31,14 31,14 @@ enum
EOLOPT = 0,
NOOPOPT = 1,
- MAXBACKOFF = 20,
+ MAXBACKMS = 30000, /* longest backoff time (ms) before hangup */
MSSOPT = 2,
MSS_LENGTH = 4, /* Mean segment size */
MSL2 = 10,
MSPTICK = 50, /* Milliseconds per timer tick */
DEF_MSS = 1460, /* Default mean segment */
DEF_RTT = 1000, /* Default round trip */
- DEF_KAT = 10000, /* Default keep alive trip in ms */
+ DEF_KAT = 10000, /* Default time ms) between keep alives */
TCP_LISTEN = 0, /* Listen connection */
TCP_CONNECT = 1, /* Outgoing connection */
@@ 249,6 249,7 @@ void tcpsndsyn(Tcpctl*);
void tcprcvwin(Conv*);
void tcpacktimer(void*);
void tcpkeepalive(void*);
+void tcpsetkacounter(Tcpctl*);
void tcprxmit(Conv*, int);
void
@@ 1285,7 1286,9 @@ tcpiput(Proto *tcp, uchar*, Block *bp)
qunlock(tcp);
if(tcb->kacounter > 0)
- tcb->kacounter = MAXBACKOFF;
+ tcb->kacounter = MAXBACKMS / (tcb->katimer.start*MSPTICK);
+ if(tcb->kacounter < 3)
+ tcb->kacounter = 3;
switch(tcb->state) {
case Closed:
@@ 1411,7 1414,7 @@ tcpiput(Proto *tcp, uchar*, Block *bp)
if(tcb->sndcnt == 0){
tcphalt(tpriv, &tcb->rtt_timer);
tcphalt(tpriv, &tcb->acktimer);
- tcb->kacounter = MAXBACKOFF;
+ tcpsetkacounter(tcb);
tcpsetstate(s, Finwait2);
tcb->katimer.start = MSL2 * (1000 / MSPTICK);
tcpgo(tpriv, &tcb->katimer);
@@ 1816,6 1819,13 @@ tcpsendka(Conv *s)
* otherwise, send a keepalive and restart the timer
*/
void
+tcpsetkacounter(Tcpctl *tcb)
+{
+ tcb->kacounter = MAXBACKMS / (tcb->katimer.start*MSPTICK);;
+ if(tcb->kacounter < 3)
+ tcb->kacounter = 3;
+}
+void
tcpkeepalive(void *v)
{
Tcpctl *tcb;
@@ 1848,7 1858,7 @@ tcpstartka(Conv *s, char **f, int n)
if(x >= MSPTICK)
tcb->katimer.start = x/MSPTICK;
}
- tcb->kacounter = MAXBACKOFF;
+ tcpsetkacounter(tcb);
tcpgo(s->p->priv, &tcb->katimer);
return nil;
@@ 1892,7 1902,7 @@ tcptimeout(void *arg)
{
Conv *s;
Tcpctl *tcb;
- int maxback;
+ int back, maxback;
Tcppriv *tpriv;
s = (Conv*)arg;
@@ 1904,10 1914,11 @@ tcptimeout(void *arg)
default:
tcb->backoff++;
if(tcb->state == Syn_sent)
- maxback = (3*MAXBACKOFF)/4;
+ maxback = MAXBACKMS/2;
else
- maxback = MAXBACKOFF;
- if(tcb->backoff >= maxback) {
+ maxback = MAXBACKMS;
+ back = backoff(tcb->backoff) * (tcb->mdev + (tcb->srtt>>LOGAGAIN));
+ if(back >= maxback) {
localclose(s, Etimedout);
break;
}
M pc/devlml.c => pc/devlml.c +12 -10
@@ 267,7 267,7 @@ lmlreset(void)
Physseg seggrab;
ulong regpa;
ulong cdsize;
- ulong *grabpa;
+ void *grabbuf;
ulong grablen;
int i;
@@ 275,28 275,30 @@ lmlreset(void)
if (pcidev == nil) {
return;
}
- cdsize = (sizeof(CodeData) + BY2PG - 1) & ~(BY2PG - 1);
+ cdsize = CODEDATASIZE;
codeData = (CodeData*)xspanalloc(cdsize, BY2PG, 0);
if (codeData == nil) {
print("devlml: xspanalloc(%lux, %ux, 0)\n", cdsize, BY2PG);
return;
}
- grablen = (720 * 480 * 2 * 2 + BY2PG - 1) & ~(BY2PG - 1);
- grabpa = (ulong *)xspanalloc(grablen, BY2PG, 0);
- if (grabpa == nil) {
+ grablen = GRABDATASIZE;
+ grabbuf = xspanalloc(grablen, BY2PG, 0);
+ if (grabbuf == nil) {
print("devlml: xspanalloc(%lux, %ux, 0)\n", grablen, BY2PG);
return;
}
- *grabpa = PADDR(grabpa);
+
+ memset(grabbuf, 0x33, grablen);
print("Installing Motion JPEG driver %s\n", MJPG_VERSION);
print("MJPG buffer at 0x%.8lux, size 0x%.8lux\n", codeData, cdsize);
- print("Grab buffer at 0x%.8lux, size 0x%.8lux\n", grabpa, grablen);
+ print("Grab buffer at 0x%.8lux, size 0x%.8lux\n", grabbuf, grablen);
// Get access to DMA memory buffer
memset(codeData, 0xAA, sizeof(CodeData));
- codeData->physaddr = PADDR(codeData->statCom);
+ codeData->pamjpg = PADDR(codeData->statCom);
+ codeData->pagrab = PADDR(grabbuf);
for (i = 0; i < NBUF; i++) {
codeData->statCom[i] = PADDR(&(codeData->fragdesc[i]));
codeData->fragdesc[i].addr = PADDR(&(codeData->frag[i]));
@@ 347,13 349,13 @@ lmlreset(void)
seggrab.attr = SG_PHYSICAL;
seggrab.name = smalloc(NAMELEN);
snprint(seggrab.name, NAMELEN, "lmlgrab");
- seggrab.pa = (ulong)PADDR(grabpa);
+ seggrab.pa = PADDR(grabbuf);
seggrab.size = grablen;
if (addphysseg(&seggrab) == -1) {
print("lml: physsegment: lmlgrab\n");
return;
}
- return;
+ return;
}
static Chan*
M pc/devlml.h => pc/devlml.h +7 -3
@@ 91,7 91,7 @@ struct FrameHeader { // Don't modify this struct, used by h/w
ulong frameSeqNo;
};
-#define FRAGSIZE ((MB-0x100)/NBUF)
+#define FRAGSIZE (128*1024)
union Fragment {
FrameHeader fh;
@@ 104,12 104,16 @@ struct FragmentTable { // Don't modify this struct, used by h/w
};
struct CodeData { // Don't modify this struct, used by h/w
- ulong physaddr; // Physical addr of statCom[0]
- ulong statCom[4]; // Physical address
+ ulong pamjpg; // Physical addr of statCom[0]
+ ulong pagrab; // Physical addr of grab buffer
+ ulong statCom[4]; // Physical addresses of fragdescs
FragmentTable fragdesc[4];
Fragment frag[4];
};
+#define CODEDATASIZE ((sizeof(CodeData) + BY2PG - 1) & ~(BY2PG - 1))
+#define GRABDATASIZE ((720 * 480 * 2 * 2 + BY2PG - 1) & ~(BY2PG - 1))
+
#define POST_OFFICE 0x200
#define POST_PEND 0x02000000
#define POST_TIME 0x01000000
M pc/fns.h => pc/fns.h +1 -0
@@ 95,6 95,7 @@ void procsetup(Proc*);
void putcr3(ulong);
void putcr4(ulong);
void rdmsr(int, vlong*);
+long readintrts(void*, int);
void screeninit(void);
int screenprint(char*, ...); /* debugging */
void (*screenputs)(char*, int);
M pc/trap.c => pc/trap.c +40 -1
@@ 15,7 15,16 @@ static void fault386(Ureg*, void*);
static Lock vctllock;
static Vctl *vctl[256];
-uvlong intrts;
+/* interrupt timestamps, l.s knows fills intrts each interupt */
+ uvlong intrts;
+static struct {
+ Lock;
+ int vno; /* vector to save timestamps for */
+ int n; /* number of valid timestamps in ts[] */
+ uvlong ts[128]; /* time stamps */
+} tsalloc;
+
+static void savets(void);
void
intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf)
@@ 32,6 41,8 @@ intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf)
ilock(&vctllock);
vno = arch->intrenable(v);
+ if(irq == IrqUART0)
+ tsalloc.vno = vno;
if(vno == -1){
iunlock(&vctllock);
print("intrenable: couldn't enable irq %d, tbdf 0x%uX\n",
@@ 181,6 192,8 @@ trap(Ureg* ureg)
}
vno = ureg->trap;
+ if(vno == tsalloc.vno)
+ savets();
if(ctl = vctl[vno]){
if(ctl->isintr){
m->intr++;
@@ 739,3 752,29 @@ dbgpc(Proc *p)
return ureg->pc;
}
+
+/* called with interrupts off */
+static void
+savets(void)
+{
+ lock(&tsalloc);
+ if(tsalloc.n < nelem(tsalloc.ts))
+ tsalloc.ts[tsalloc.n++] = intrts;
+ unlock(&tsalloc);
+}
+
+/* read interrupt timestamps */
+long
+readintrts(void *buf, int n)
+{
+ n /= sizeof(uvlong);
+ if(n <= 0)
+ return 0;
+ ilock(&tsalloc);
+ if(n > tsalloc.n)
+ n = tsalloc.n;
+ memmove(buf, tsalloc.ts, n*sizeof(uvlong));
+ tsalloc.n = 0;
+ iunlock(&tsalloc);
+ return n*sizeof(uvlong);
+}