M boot/local.c => boot/local.c +4 -1
@@ 7,7 7,10 @@ static char *disk;
void
configlocal(Method *mp)
{
- disk = *sys ? sys : mp->arg;
+ if(*sys == '/' || *sys == '#')
+ disk = sys;
+ else
+ disk = mp->arg;
USED(mp);
}
M gnot/devduart.c => gnot/devduart.c +1 -1
@@ 675,7 675,7 @@ duartstat(Chan *c, char *dp)
{
switch(c->qid.path){
case Qeia0:
- streamstat(c, dp, "eia0");
+ streamstat(c, dp, duartdir[0].name, duartdir[0].perm);
break;
default:
devstat(c, dp, duartdir, NDuartport, devgen);
M pc/devhard.c => pc/devhard.c +17 -23
@@ 42,8 42,7 @@ enum
/* file types */
Qdir= 0,
- Maxxfer= 512, /* maximum transfer size/cmd */
- Maxread= 512, /* maximum transfer size/read */
+ Maxxfer= 32*512, /* maximum transfer size/cmd */
Npart= 8+2, /* 8 sub partitions, disk, and partition */
Nrepl= 64, /* maximum replacement blocks */
};
@@ 158,7 157,7 @@ Drive *hard;
static void hardintr(Ureg*);
static long hardxfer(Drive*, Partition*, int, long, long, char*);
static void hardident(Drive*);
-static void hardsetbuf(Drive*, int);
+static void hardsetbuf(Drive*);
static void hardpart(Drive*);
static int
@@ 239,14 238,13 @@ hardattach(char *spec)
for(dp = hard; dp < &hard[conf.nhard]; dp++){
if(!waserror()){
dp->bytes = 512;
- hardsetbuf(dp, 0);
hardident(dp);
switch(dp->id.magic){
case 0xA5A: /* conner drive on the AT&T NSX (safari) */
dp->cyl = dp->id.lcyls;
dp->heads = dp->id.lheads;
dp->sectors = dp->id.ls2t;
- hardsetbuf(dp, 1);
+ hardsetbuf(dp);
break;
case 0x324A: /* hard drive on the AT&T 6386 */
dp->cyl = dp->id.lcyls - 4;
@@ 500,8 498,6 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf)
start = start / dp->bytes;
if(len > Maxxfer)
len = Maxxfer;
- if(cmd == Cread && len > Maxread)
- len = Maxread;
len = (len + dp->bytes - 1) / dp->bytes;
if(len == 0)
return 0;
@@ 578,10 574,10 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf)
}
/*
- * set read ahead mode (1 == on, 0 == off)
+ * set read ahead mode
*/
static void
-hardsetbuf(Drive *dp, int on)
+hardsetbuf(Drive *dp)
{
Controller *cp = dp->cp;
@@ 594,12 590,16 @@ hardsetbuf(Drive *dp, int on)
cmdreadywait(cp);
cp->cmd = Csetbuf;
- outb(cp->pbase+Pprecomp, on ? 0xAA : 0xFF);
+ outb(cp->pbase+Pprecomp, 0xAA);
outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4));
outb(cp->pbase+Pcmd, Csetbuf);
sleep(&cp->r, cmddone, cp);
+ if(cp->status & Serr)
+ print("hd%d setbuf err: status %lux, err %lux\n",
+ dp-hard, cp->status, cp->error);
+
poperror();
qunlock(cp);
}
@@ 638,7 638,7 @@ hardident(Drive *dp)
memmove(&dp->id, buf, dp->bytes);
/*
* this function appears to respond with an extra interrupt after
- * the indent information is read, except on the safari. The following
+ * the ident information is read, except on the safari. The following
* delay gives this extra interrupt a chance to happen while we are quiet.
* Otherwise, the interrupt may come during a subsequent read or write,
* causing a panic and much confusion.
@@ 647,6 647,7 @@ hardident(Drive *dp)
tsleep(&cp->r, return0, 0, 10);
cp->cmd = 0;
cp->buf = 0;
+ free(buf);
poperror();
qunlock(cp);
}
@@ 786,7 787,6 @@ hardintr(Ureg *ur)
char *addr;
USED(ur);
- spllo(); /* let in other interrupts */
/*
* BUG!! if there is ever more than one controller, we need a way to
@@ 796,12 796,13 @@ hardintr(Ureg *ur)
dp = cp->dp;
loop = 0;
- while((cp->status = inb(cp->pbase+Pstatus)) & Sbusy)
- if(++loop > 10000) {
+ while((cp->status = inb(cp->pbase+Pstatus)) & Sbusy){
+ if(++loop > 100) {
print("cmd=%lux status=%lux\n",
cp->cmd, inb(cp->pbase+Pstatus));
panic("hardintr: wait busy");
}
+ }
switch(cp->cmd){
case Cwrite:
if(cp->status & Serr){
@@ 814,8 815,8 @@ hardintr(Ureg *ur)
cp->sofar++;
if(cp->sofar < cp->nsecs){
loop = 0;
- while((inb(cp->pbase+Pstatus) & Sdrq) == 0)
- if(++loop > 10000) {
+ while(((cp->status = inb(cp->pbase+Pstatus)) & Sdrq) == 0)
+ if(++loop > 100) {
print("cmd=%lux status=%lux\n",
cp->cmd, inb(cp->pbase+Pstatus));
panic("hardintr: write");
@@ 834,13 835,6 @@ hardintr(Ureg *ur)
case Cread:
case Cident:
loop = 0;
- while((inb(cp->pbase+Pstatus) & Sbusy) != 0)
- if(++loop > 10000) {
- print("cmd=%lux status=%lux\n",
- cp->cmd, inb(cp->pbase+Pstatus));
- panic("hardintr: wait busy");
- }
- loop = 0;
while((inb(cp->pbase+Pstatus) & Sdrq) == 0)
if(++loop > 10000) {
print("cmd=%lux status=%lux\n",
M pc/devrtc.c => pc/devrtc.c +3 -3
@@ 92,9 92,9 @@ rtcopen(Chan *c, int omode)
omode = openmode(omode);
switch(c->qid.path){
case Qrtc:
- if(omode == OREAD)
- break;
- /* fall through */
+ if(omode != OREAD && strcmp(u->p->user, eve)!=0)
+ error(Eperm);
+ break;
case Qnvram:
if(strcmp(u->p->user, eve)!=0 || !cpuserver)
error(Eperm);
M pc/devuart.c => pc/devuart.c +2 -2
@@ 614,10 614,10 @@ uartstat(Chan *c, char *dp)
{
switch(c->qid.path){
case Qeia0:
- streamstat(c, dp, "eia0");
+ streamstat(c, dp, uartdir[0].name, uartdir[0].perm);
break;
case Qeia1:
- streamstat(c, dp, "eia1");
+ streamstat(c, dp, uartdir[2].name, uartdir[2].perm);
break;
default:
devstat(c, dp, uartdir, NUart, devgen);
M port/devcons.c => port/devcons.c +17 -18
@@ 475,7 475,7 @@ consclose(Chan *c)
unlock(&ctl);
}
if(c->qid.path == Qcrypt && c->aux)
- freeb(c->aux);
+ free(c->aux);
c->aux = 0;
}
@@ 485,8 485,7 @@ consread(Chan *c, void *buf, long n, ulong offset)
int ch, i, k, id;
ulong l;
char *cbuf = buf;
- char *chal, *b, *bp;
- Block *cb;
+ char *chal, *b, *bp, *cb;
char tmp[128]; /* must be >= 6*NUMSIZE */
Mach *mp;
@@ 591,9 590,9 @@ consread(Chan *c, void *buf, long n, ulong offset)
cb = c->aux;
if(!cb)
return 0;
- if(n > cb->wptr - cb->base)
- n = cb->wptr - cb->base;
- memmove(buf, cb->base, n);
+ if(n > MAXCRYPT)
+ n = MAXCRYPT;
+ memmove(buf, &cb[1], n);
return n;
case Qchal:
@@ 738,8 737,7 @@ conswrite(Chan *c, void *va, long n, ulong offset)
char cbuf[64];
char buf[256];
long l, bp;
- char *a = va;
- Block *cb;
+ char *a = va, *cb;
Mach *mp;
int id, fd, ch;
Chan *swc;
@@ 801,23 799,24 @@ conswrite(Chan *c, void *va, long n, ulong offset)
case Qcrypt:
cb = c->aux;
if(!cb){
- cb = c->aux = allocb(128);
- cb->type = 'E';
+ /* first byte determines whether encrypting or decrypting */
+ cb = c->aux = smalloc(MAXCRYPT+1);
+ cb[0] = 'E';
}
if(n < 8){
if(n != 1 || a[0] != 'E' && a[0] != 'D')
error(Ebadarg);
- cb->type = a[0];
+ cb[0] = a[0];
return 1;
}
- if(n > cb->lim - cb->base)
- n = cb->lim - cb->base;
- memmove(cb->base, a, n);
- cb->wptr = cb->base + n;
- if(cb->type == 'E')
- encrypt(u->p->pgrp->crypt->key, cb->base, n);
+ if(n > MAXCRYPT)
+ n = MAXCRYPT;
+ memset(&cb[1], 0, MAXCRYPT);
+ memmove(&cb[1], a, n);
+ if(cb[0] == 'E')
+ encrypt(u->p->pgrp->crypt->key, &cb[1], n);
else
- decrypt(u->p->pgrp->crypt->key, cb->base, n);
+ decrypt(u->p->pgrp->crypt->key, &cb[1], n);
break;
case Qkey:
M port/devip.c => port/devip.c +2 -2
@@ 835,14 835,14 @@ tcpstclose(Queue *q)
qunlock(s);
qlock(tcb);
- close_self(s, 0);
+ localclose(s, 0);
qunlock(tcb);
break;
case Closed:
case Syn_sent:
qlock(tcb);
- close_self(s, 0);
+ localclose(s, 0);
qunlock(tcb);
break;
M port/devpipe.c => port/devpipe.c +1 -1
@@ 117,7 117,7 @@ pipewalk(Chan *c, char *name)
void
pipestat(Chan *c, char *db)
{
- streamstat(c, db, "pipe");
+ streamstat(c, db, "pipe", 0666);
}
/*
M port/devscc.c => port/devscc.c +1 -1
@@ 718,7 718,7 @@ sccstat(Chan *c, char *dp)
i = STREAMID(c->qid.path);
switch(STREAMTYPE(c->qid.path)){
case Sdataqid:
- streamstat(c, dp, sccdir[2*i].name);
+ streamstat(c, dp, sccdir[2*i].name, sccdir[2*i].perm);
break;
default:
devstat(c, dp, sccdir, 2*nscc, devgen);
M port/ipdat.h => port/ipdat.h +1 -1
@@ 429,7 429,7 @@ void add_reseq(Tcpctl *, char, Tcp *, Block *, ushort);
int arp_lookup(uchar*, uchar*);
int backoff(int);
Block* btrim(Block*, int, int);
-void close_self(Ipconv *, char []);
+void localclose(Ipconv *, char []);
int dupb(Block **, Block *, int, int);
void extract_oob(Block **, Block **, Tcp *);
void get_reseq(Tcpctl *, char *, Tcp *, Block **, ushort *);
M port/lib.h => port/lib.h +2 -0
@@ 33,6 33,8 @@ extern int countrune(char*);
extern char* utfrune(char*, long);
extern int utflen(char*);
+extern int abs(int);
+
/*
* print routines
*/
M port/portdat.h => port/portdat.h +1 -0
@@ 721,6 721,7 @@ struct Network
enum
{
PRINTSIZE = 256,
+ MAXCRYPT = 127,
NUMSIZE = 12, /* size of formatted number */
MB = (1024*1024),
};
M port/portfns.h => port/portfns.h +1 -1
@@ 235,7 235,7 @@ Stream* streamnew(ushort, ushort, ushort, Qinfo*, int);
void streamopen(Chan*, Qinfo*);
int streamparse(char*, Block*);
long streamread(Chan*, void*, long);
-void streamstat(Chan*, char*, char*);
+void streamstat(Chan*, char*, char*, long);
long streamwrite(Chan*, void*, long, int);
void naildownstream(Stream*);
void swapinit(void);
M port/stream.c => port/stream.c +2 -2
@@ 1232,7 1232,7 @@ streamwrite(Chan *c, void *a, long n, int docopy)
* first delimiter.
*/
void
-streamstat(Chan *c, char *db, char *name)
+streamstat(Chan *c, char *db, char *name, long perm)
{
Dir dir;
Stream *s;
@@ 1254,7 1254,7 @@ streamstat(Chan *c, char *db, char *name)
unlock(q);
}
- devdir(c, c->qid, name, n, eve, 0, &dir);
+ devdir(c, c->qid, name, n, eve, perm, &dir);
convD2M(&dir, db);
}
M port/tcpinput.c => port/tcpinput.c +36 -41
@@ 19,7 19,7 @@ char *tcpstate[] =
};
void
-reset(Ipaddr source, Ipaddr dest, char tos, ushort length, Tcp *seg)
+sndrst(Ipaddr source, Ipaddr dest, char tos, ushort length, Tcp *seg)
{
Block *hbp;
Port tmp;
@@ 85,8 85,8 @@ tcpflushincoming(Ipconv *s)
seg.seq = tcb->snd.ptr;
seg.ack = tcb->last_ack = tcb->rcv.nxt;
- reset(s->dst, Myip[Myself], 0, 0, &seg);
- close_self(s, 0);
+ sndrst(s->dst, Myip[Myself], 0, 0, &seg);
+ localclose(s, 0);
}
static void
@@ 159,7 159,7 @@ tcp_input(Ipifc *ifc, Block *bp)
if((hdrlen = ntohtcp(&seg, &bp)) < 0)
return;
- /* Adjust the data length */
+ /* trim the packet to the size claimed by the datagram */
length -= (hdrlen+TCP_IPLEN+TCP_PHDRSIZE);
bp = btrim(bp, hdrlen+TCP_PKT, length);
if(bp == 0)
@@ 198,7 198,7 @@ tcp_input(Ipifc *ifc, Block *bp)
}
if(s == 0){
freeb(bp);
- reset(source, dest, tos, length, &seg);
+ sndrst(source, dest, tos, length, &seg);
return;
}
}
@@ 212,7 212,7 @@ tcp_input(Ipifc *ifc, Block *bp)
switch(tcb->state) {
case Closed:
freeb(bp);
- reset(source, dest, tos, length, &seg);
+ sndrst(source, dest, tos, length, &seg);
goto done;
case Listen:
if(seg.flags & RST) {
@@ 221,7 221,7 @@ tcp_input(Ipifc *ifc, Block *bp)
}
if(seg.flags & ACK) {
freeb(bp);
- reset(source, dest, tos, length, &seg);
+ sndrst(source, dest, tos, length, &seg);
goto done;
}
if(seg.flags & SYN) {
@@ 239,13 239,13 @@ tcp_input(Ipifc *ifc, Block *bp)
if(seg.flags & ACK) {
if(!seq_within(seg.ack, tcb->iss+1, tcb->snd.nxt)) {
freeb(bp);
- reset(source, dest, tos, length, &seg);
+ sndrst(source, dest, tos, length, &seg);
goto done;
}
}
if(seg.flags & RST) {
if(seg.flags & ACK)
- close_self(s, Econrefused);
+ localclose(s, Econrefused);
freeb(bp);
goto done;
}
@@ 253,7 253,7 @@ tcp_input(Ipifc *ifc, Block *bp)
if(seg.flags & ACK)
if(PREC(tos) != PREC(tcb->tos)){
freeb(bp);
- reset(source, dest, tos, length, &seg);
+ sndrst(source, dest, tos, length, &seg);
goto done;
}
@@ 277,7 277,7 @@ tcp_input(Ipifc *ifc, Block *bp)
goto done;
}
- /* Trim segment to fit receive window. */
+ /* Cut the data to fit the receive window */
if(trim(tcb, &seg, &bp, &length) == -1) {
if(!(seg.flags & RST)) {
tcb->flags |= FORCE;
@@ 286,15 286,18 @@ tcp_input(Ipifc *ifc, Block *bp)
goto done;
}
- /* If we dont understand answer with a rst */
+ /* Cannot accept so answer with a rst */
if(length)
if(s->readq == 0)
if(tcb->state == Closed) {
freeb(bp);
- reset(source, dest, tos, length, &seg);
+ sndrst(source, dest, tos, length, &seg);
goto done;
}
+ /* The segment is beyond the current receive pointer so
+ * queue the data in the resequence queue
+ */
if(seg.seq != tcb->rcv.nxt)
if(length != 0 || (seg.flags & (SYN|FIN))) {
add_reseq(tcb, tos, &seg, bp, length);
@@ 308,7 311,7 @@ tcp_input(Ipifc *ifc, Block *bp)
&& !(tcb->flags & (CLONE|ACTIVE)))
setstate(s, Listen);
else
- close_self(s, Econrefused);
+ localclose(s, Econrefused);
freeb(bp);
goto done;
@@ 316,7 319,7 @@ tcp_input(Ipifc *ifc, Block *bp)
if(PREC(tos) != PREC(tcb->tos) || (seg.flags & SYN)){
freeb(bp);
- reset(source, dest, tos, length, &seg);
+ sndrst(source, dest, tos, length, &seg);
goto done;
}
@@ 333,7 336,7 @@ tcp_input(Ipifc *ifc, Block *bp)
}
else {
freeb(bp);
- reset(source, dest, tos, length, &seg);
+ sndrst(source, dest, tos, length, &seg);
goto done;
}
break;
@@ 361,7 364,7 @@ tcp_input(Ipifc *ifc, Block *bp)
update(s, &seg);
if(tcb->sndcnt == 0) {
freeb(bp);
- close_self(s, Enoerror);
+ localclose(s, Enoerror);
goto done;
}
case Time_wait:
@@ 393,7 396,7 @@ tcp_input(Ipifc *ifc, Block *bp)
case Syn_received:
case Established:
case Finwait1:
- /* Place on receive queue */
+ /* If we still have some data place on receive queue */
tcb->rcvcnt += blen(bp);
if(bp){
if(s->readq)
@@ 415,7 418,7 @@ tcp_input(Ipifc *ifc, Block *bp)
/* no process to read the data, send a reset */
if(bp)
freeb(bp);
- reset(source, dest, tos, length, &seg);
+ sndrst(source, dest, tos, length, &seg);
goto done;
}
}
@@ 454,15 457,17 @@ tcp_input(Ipifc *ifc, Block *bp)
break;
}
}
+
while(tcb->reseq != 0) {
if(seq_ge(tcb->rcv.nxt, tcb->reseq->seg.seq) == 0)
break;
+
get_reseq(tcb, &tos, &seg, &bp, &length);
+
if(trim(tcb, &seg, &bp, &length) == 0)
- goto gotone;
+ break;
}
break;
- gotone:;
}
output:
tcp_output(s);
@@ 473,11 478,10 @@ done:
void
update(Ipconv *s, Tcp *seg)
{
+ int rtt;
ushort acked;
ushort expand;
Tcpctl *tcb = &s->tcpctl;
- int rtt;
- int abserr;
if(seq_gt(seg->ack, tcb->snd.nxt)) {
tcb->flags |= FORCE;
@@ 498,6 502,7 @@ update(Ipconv *s, Tcp *seg)
if(!seq_gt(seg->ack, tcb->snd.una))
return;
+ /* Compute the new send window size */
acked = seg->ack - tcb->snd.una;
if(tcb->cwind < tcb->snd.wnd) {
if(tcb->cwind < tcb->ssthresh)
@@ 513,31 518,25 @@ update(Ipconv *s, Tcp *seg)
tcb->cwind += expand;
}
- /* Round trip time estimation */
+ /* Adjust the timers acorrding to the round trip time */
if(run_timer(&tcb->rtt_timer))
if(seq_ge(seg->ack, tcb->rttseq)) {
stop_timer(&tcb->rtt_timer);
if((tcb->flags&RETRAN) == 0) {
+ tcb->backoff = 0;
rtt = tcb->rtt_timer.start - tcb->rtt_timer.count;
- rtt *= MSPTICK;
+ rtt *= MSPTICK;
if(rtt > tcb->srtt &&
(tcb->state == Syn_sent || tcb->state == Syn_received))
tcb->srtt = rtt;
else {
- if(rtt > tcb->srtt)
- abserr = rtt - tcb->srtt;
- else
- abserr = tcb->srtt - rtt;
tcb->srtt = ((AGAIN-1)*tcb->srtt + rtt) / AGAIN;
- tcb->mdev = ((DGAIN-1)*tcb->mdev + abserr) / DGAIN;
- DPRINT("tcpout: rtt %d, srtt %d, mdev %d\n",
- rtt, tcb->srtt, tcb->mdev);
+ rtt = abs(rtt - tcb->srtt);
+ tcb->mdev = ((DGAIN-1)*tcb->mdev + rtt) / DGAIN;
}
- tcb->backoff = 0;
}
}
- /* If we're waiting for an ack of our SYN, note it and adjust count */
if((tcb->flags & SYNACK) == 0){
tcb->flags |= SYNACK;
acked--;
@@ 548,12 547,9 @@ update(Ipconv *s, Tcp *seg)
tcb->sndcnt -= acked;
tcb->snd.una = seg->ack;
- if (seq_gt(seg->ack, tcb->snd.up))
+ if(seq_gt(seg->ack, tcb->snd.up))
tcb->snd.up = seg->ack;
- /* Stop retransmission timer, but restart it if there is still
- * unacknowledged data.
- */
stop_timer(&tcb->timer);
if(tcb->snd.una != tcb->snd.nxt)
start_timer(&tcb->timer);
@@ 561,7 557,6 @@ update(Ipconv *s, Tcp *seg)
if(seq_lt(tcb->snd.ptr, tcb->snd.una))
tcb->snd.ptr = tcb->snd.una;
- /* All data is acked now */
tcb->flags &= ~RETRAN;
tcb->backoff = 0;
}
@@ 688,7 683,7 @@ trim(Tcpctl *tcb, Tcp *seg, Block **bp, ushort *length)
return 0;
}
else {
- /* Some part of the segment must be in the window */
+ /* Some part of the segment should be in the window */
if(in_window(tcb,seg->seq)) {
accept++;
}
@@ 839,7 834,7 @@ init_tcpctl(Ipconv *s)
* called with tcb locked
*/
void
-close_self(Ipconv *s, char reason[])
+localclose(Ipconv *s, char reason[])
{
Reseq *rp,*rp1;
Tcpctl *tcb = &s->tcpctl;
M port/tcpoutput.c => port/tcpoutput.c +2 -2
@@ 182,13 182,13 @@ tcp_timeout(void *arg)
default:
tcb->backoff++;
if (tcb->backoff >= MAXBACKOFF)
- close_self(s, Etimedout);
+ localclose(s, Etimedout);
else
tcprxmit(s);
break;
case Time_wait:
- close_self(s, 0);
+ localclose(s, 0);
break;
}
}
M power/devduart.c => power/devduart.c +2 -1
@@ 747,7 747,8 @@ duartstat(Chan *c, char *p)
{
switch(STREAMTYPE(c->qid.path)){
case Sdataqid:
- streamstat(c, p, duartdir[2*STREAMID(c->qid.path)].name);
+ streamstat(c, p, duartdir[2*STREAMID(c->qid.path)].name,
+ duartdir[2*STREAMID(c->qid.path)].perm);
break;
default:
devstat(c, p, duartdir, 2*nduartport, devgen);