From b2d380ccbed1a4781e7a8069d6197ba417bdc1c1 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 16 May 1998 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1998-05-16 --- ip/ipifc.c | 17 ++++++-- pc/devata.c | 111 +++++++++++++++++++++---------------------------- pc/trap.c | 25 ++++++----- port/portdat.h | 3 ++ 4 files changed, 75 insertions(+), 81 deletions(-) diff --git a/ip/ipifc.c b/ip/ipifc.c index ae724e2146785739b897093df314684be04baad6..42d7e9eaf1ef6f213c43b246170330a7f16d5d7a 100644 --- a/ip/ipifc.c +++ b/ip/ipifc.c @@ -135,7 +135,11 @@ ipifcbind(Conv *c, char **argv, int argc) ifc->m = m; ifc->minmtu = ifc->m->minmtu; ifc->maxmtu = ifc->m->maxmtu; - ifc->conv->inuse++; + if(ifc->m->unbindonclose == 0){ + lock(ifc->conv); + ifc->conv->inuse++; + unlock(ifc->conv); + } ifc->ifcid++; wunlock(ifc); @@ -161,11 +165,15 @@ ipifcunbind(Ipifc *ifc) wlock(ifc); /* dissociate routes */ - ifc->conv->inuse--; + if(ifc->m != nil && ifc->m->unbindonclose == 0){ + lock(ifc->conv); + ifc->conv->inuse--; + unlock(ifc->conv); + } ifc->ifcid++; /* disassociate device */ - if(ifc->m) + if(ifc->m != nil && ifc->m->unbind) (*ifc->m->unbind)(ifc); memset(ifc->dev, 0, sizeof(ifc->dev)); ifc->arg = nil; @@ -188,6 +196,7 @@ ipifcunbind(Ipifc *ifc) ifc->m = nil; wunlock(ifc); poperror(); + return nil; } @@ -294,7 +303,7 @@ ipifcclose(Conv *c) ifc = (Ipifc*)c->ptcl; m = ifc->m; - if(m == nil || m->unbindonclose) + if(m != nil && m->unbindonclose) ipifcunbind(ifc); unlock(c); } diff --git a/pc/devata.c b/pc/devata.c index 20bd622761e91e6e1f58e22567c77f10367c4898..e627077ec7295ba8957a0761c6c804c6c19ffb14 100644 --- a/pc/devata.c +++ b/pc/devata.c @@ -669,7 +669,6 @@ ataread(Chan* c, void* a, long n, vlong off) atapipart(dp); qunlock(dp); poperror(); - return atapirwio(c, a, n, off, Cread2); } pp = &dp->p[PART(c->qid.path)]; @@ -681,7 +680,10 @@ ataread(Chan* c, void* a, long n, vlong off) skip = off % dp->bytes; for(rv = 0; rv < n; rv += i){ - i = ataxfer(dp, pp, Cread, off+rv-skip, n-rv+skip, buf); + if(dp->atapi) + i = atapirwio(c, buf, n-rv+skip, off+rv-skip, Cread2); + else + i = ataxfer(dp, pp, Cread, off+rv-skip, n-rv+skip, buf); if(i == 0) break; i -= skip; @@ -1674,7 +1676,7 @@ atapiexec(Drive *dp) } ILOCK(&cp->reglock); - cp->nsecs = 1; + cp->count = 0; cp->sofar = 0; cp->error = 0; cp->cmd = Cpktcmd; @@ -1734,8 +1736,8 @@ atapireqsense(Drive* dp) return; } + cp->nsecs = 1; cp->len = 18; - cp->count = 0; memset(cp->cmdblk, 0, sizeof(cp->cmdblk)); cp->cmdblk[0] = Creqsense; cp->cmdblk[4] = 18; @@ -1751,19 +1753,23 @@ atapireqsense(Drive* dp) } static long -atapiio(Drive *dp, uchar *a, ulong len, vlong off, int cmd) +atapiio(Drive *dp, uchar *buf, ulong len, vlong off, int cmd) { - ulong bn, n, o, m; + ulong start; Controller *cp; - uchar *buf; int retrycount; - cp = dp->cp; + /* + * cut transfer size down to disk buffer size + */ + start = off / dp->bytes; + if(len > Maxxfer) + len = Maxxfer; + len = (len + dp->bytes - 1) / dp->bytes; + if(len == 0) + return 0; - if(cmd == Cread2) - buf = smalloc(Maxxfer); - else - buf = 0; + cp = dp->cp; qlock(cp->ctlrlock); retrycount = 2; @@ -1780,55 +1786,35 @@ retry: } } cp->dp = 0; - if(cmd == Cread2) - free(buf); + cp->buf = 0; qunlock(cp->ctlrlock); nexterror(); } - if(cmd == Cread2) - cp->buf = buf; - else - cp->buf = a; + cp->buf = buf; + cp->nsecs = len; + cp->len = len*dp->bytes; + cp->cmd = cmd; cp->dp = dp; - cp->len = dp->bytes; - n = len; - while(n > 0){ - bn = off / dp->bytes; - if(off > dp->cap-dp->bytes) - break; - o = off % dp->bytes; - m = dp->bytes - o; - if(m > n) - m = n; - memset(cp->cmdblk, 0, 12); - cp->cmdblk[0] = cmd; - cp->cmdblk[2] = bn >> 24; - cp->cmdblk[3] = bn >> 16; - cp->cmdblk[4] = bn >> 8; - cp->cmdblk[5] = bn; - cp->cmdblk[7] = 0; - cp->cmdblk[8] = 1; - atapiexec(dp); - if(cp->count != dp->bytes){ - print("short read\n"); - break; - } - if(cmd == Cread2) - memmove(a, cp->buf + o, m); - else - cp->buf += m; - n -= m; - off += m; - a += m; - } - poperror(); - if(cmd == Cread2) - free(buf); + memset(cp->cmdblk, 0, 12); + cp->cmdblk[0] = cmd; + cp->cmdblk[2] = start>>24; + cp->cmdblk[3] = start>>16; + cp->cmdblk[4] = start>>8; + cp->cmdblk[5] = start; + cp->cmdblk[7] = cp->nsecs>>8; + cp->cmdblk[8] = cp->nsecs; + atapiexec(dp); + if(cp->count != cp->len) + print("short read\n"); cp->dp = 0; + cp->buf = 0; + len = cp->count; qunlock(cp->ctlrlock); - return len-n; + poperror(); + + return len; } static long @@ -1901,8 +1887,8 @@ retry: cp->buf = buf; cp->dp = dp; + cp->nsecs = 1; cp->len = 18; - cp->count = 0; memset(cp->cmdblk, 0, sizeof(cp->cmdblk)); cp->cmdblk[0] = Creqsense; cp->cmdblk[4] = 18; @@ -1914,8 +1900,8 @@ retry: error(Eio); } + cp->nsecs = 1; cp->len = 8; - cp->count = 0; memset(cp->cmdblk, 0, sizeof(cp->cmdblk)); cp->cmdblk[0] = Ccapacity; atapiexec(dp); @@ -1946,7 +1932,6 @@ atapiintr(Controller *cp) { uchar cause; int count, loop, pbase; - uchar *addr; pbase = cp->pbase; cause = inb(pbase+Pcount) & 0x03; @@ -1966,8 +1951,7 @@ atapiintr(Controller *cp) case 0: /* data out */ case 2: /* data in */ - addr = cp->buf; - if(addr == 0){ + if(cp->buf == 0){ cp->lastcmd = cp->cmd; cp->cmd = 0; if(cp->status & Serr) @@ -1993,14 +1977,13 @@ atapiintr(Controller *cp) break; } count = inb(pbase+Pcyllsb)|(inb(pbase+Pcylmsb)<<8); - if (count > Maxxfer) - count = Maxxfer; + if(cp->count+count > Maxxfer) + panic("hd%d: count %d, already %d\n", count, cp->count); if(cause == 0) - outss(pbase+Pdata, addr, count/2); + outss(pbase+Pdata, cp->buf+cp->count, count/2); else - inss(pbase+Pdata, addr, count/2); - cp->count = count; - cp->lastcmd = cp->cmd; + inss(pbase+Pdata, cp->buf+cp->count, count/2); + cp->count += count; break; case 3: /* status */ diff --git a/pc/trap.c b/pc/trap.c index 79286fbfb7b74c65c5a5a65c8373a8c8472d0d66..89f35084063497c13c3e36743ea81117d3a69c7d 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -140,17 +140,6 @@ trap(Ureg* ureg) up->dbgreg = ureg; } -{ -ulong x, y; - -if(up) - x = (ulong)(up->kstack); -else - x = (ulong)(m->stack); -y = (ulong)&mach; -if(y < x+512) panic("cpu%d: trap: kstack %lux %lux", m->machno, x, y); -} - v = ureg->trap; if(ctl = irqctl[v]){ if(ctl->isintr){ @@ -167,12 +156,22 @@ if(y < x+512) panic("cpu%d: trap: kstack %lux %lux", m->machno, x, y); if(ctl->eoi) ctl->eoi(v); - /* preemptive scheduling */ + /* + * preemptive scheduling. to limit stack depth, + * make sure process has a chance to return from + * the current interrupt before being preempted a + * second time. + */ if(ctl->isintr && v != VectorTIMER && v != VectorCLOCK) if(up && up->state == Running) if(anyhigher()) - if(!active.exiting) + if(up->preempted == 0) + if(!active.exiting){ + up->preempted = 1; sched(); + splhi(); + up->preempted = 0; + } } else if(v <= 16 && user){ spllo(); diff --git a/port/portdat.h b/port/portdat.h index faffcd3ce94f65ebdf2f165641131fbf1ca1e66b..1c5695638a9d37553f2d3b7754cdd0ea8648b3b1 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -611,6 +611,9 @@ struct Proc ulong movetime; /* last time process switched processors */ ulong readytime; /* time process went ready */ ulong lockpri; /* priority of process holding lock we're trying for */ + int preempted; /* true if this process hasn't finished the interrupt + * that last preempted it + */ void *ureg; /* User registers for notes */ void *dbgreg; /* User registers for devproc */