From ef4f4f00eee84cc72158c3dc574a4ab11b245ed6 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 7 Jan 1995 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1995-01-07 --- pc/devhard.c | 76 ++++++++++++++++++++++++++++++-------------------- pc/devi82365.c | 5 +++- port/devmnt.c | 14 +++++----- port/portfns.h | 1 + port/proc.c | 3 +- port/sysproc.c | 4 +-- 6 files changed, 62 insertions(+), 41 deletions(-) diff --git a/pc/devhard.c b/pc/devhard.c index 426942e9e33db474fd8f6d67edafe8e7127f5ce4..30f6c690050fc5bb84adb2ee1b2afeaaaaf2d692 100644 --- a/pc/devhard.c +++ b/pc/devhard.c @@ -113,7 +113,9 @@ struct Drive */ struct Controller { - QLock; /* exclusive access to the drive */ + QLock; /* exclusive access to the controller */ + + Lock; /* exclusive access to the registers */ int confused; /* needs to be recalibrated (or worse) */ int pbase; /* base port */ @@ -190,10 +192,6 @@ hardreset(void) hard = xalloc(conf.nhard * sizeof(Drive)); hardc = xalloc(((conf.nhard+1)/2) * sizeof(Controller)); - p = getconf("spindowntime"); - if(p) - spindowntime = atoi(p); - /* * read nvram for number of hard drives (2 max) */ @@ -217,6 +215,9 @@ hardreset(void) setvec(Hardvec + (cp-hardc)*8, hardintr, 0); /* BUG!! guessing */ } } + + if(conf.nhard && (p = getconf("spindowntime"))) + spindowntime = atoi(p); } void @@ -241,6 +242,11 @@ hardattach(char *spec) } qlock(dp); if(!dp->online){ + /* + * Make sure hardclock() doesn't + * interfere. + */ + dp->usetime = m->ticks; hardparams(dp); dp->online = 1; hardsetbuf(dp, 1); @@ -447,7 +453,9 @@ cmddone(void *a) } /* - * wait for the controller to be ready to accept a command + * Wait for the controller to be ready to accept a command. + * This is protected from intereference by hardclock() by + * setting dp->usetime before it is called. */ static void cmdreadywait(Drive *dp) @@ -493,7 +501,7 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf) Controller *cp; long lblk; int cyl, sec, head; - int loop, s, stat; + int loop, stat; if(dp->online == 0) error(Eio); @@ -528,24 +536,28 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf) nexterror(); } - cmdreadywait(dp); - /* - * splhi to make command atomic + * Make sure hardclock() doesn't + * interfere. */ - s = splhi(); + dp->usetime = m->ticks; + cmdreadywait(dp); + + ilock(cp); cp->sofar = 0; cp->buf = buf; cp->nsecs = len; cp->cmd = cmd; cp->dp = dp; cp->status = 0; + outb(cp->pbase+Pcount, cp->nsecs); outb(cp->pbase+Psector, sec); outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4) | head); outb(cp->pbase+Pcyllsb, cyl); outb(cp->pbase+Pcylmsb, cyl>>8); outb(cp->pbase+Pcmd, cmd); + if(cmd == Cwrite){ loop = 0; while((stat = inb(cp->pbase+Pstatus) & (Serr|Sdrq)) == 0) @@ -554,7 +566,8 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf) outss(cp->pbase+Pdata, cp->buf, dp->bytes/2); } else stat = 0; - splx(s); + iunlock(cp); + if(stat & Serr) error(Eio); @@ -610,10 +623,12 @@ hardsetbuf(Drive *dp, int on) cmdreadywait(dp); + ilock(cp); cp->cmd = Csetbuf; outb(cp->pbase+Pprecomp, on ? 0xAA : 0x55); outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4)); outb(cp->pbase+Pcmd, Csetbuf); + iunlock(cp); sleep(&cp->r, cmddone, cp); @@ -672,7 +687,6 @@ hardident(Drive *dp) Controller *cp; char *buf; Ident *ip; - int s; cp = dp->cp; buf = smalloc(Maxxfer); @@ -684,7 +698,7 @@ hardident(Drive *dp) cmdreadywait(dp); - s = splhi(); + ilock(cp); cp->nsecs = 1; cp->sofar = 0; cp->cmd = Cident; @@ -692,7 +706,7 @@ hardident(Drive *dp) cp->buf = buf; outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4)); outb(cp->pbase+Pcmd, Cident); - splx(s); + iunlock(cp); sleep(&cp->r, cmddone, cp); if(cp->status & Serr){ @@ -744,6 +758,7 @@ hardprobe(Drive *dp, int cyl, int sec, int head) cmdreadywait(dp); + ilock(cp); cp->cmd = Cread; cp->dp = dp; cp->status = 0; @@ -756,6 +771,7 @@ hardprobe(Drive *dp, int cyl, int sec, int head) outb(cp->pbase+Pcyllsb, cyl); outb(cp->pbase+Pcylmsb, cyl>>8); outb(cp->pbase+Pcmd, Cread); + iunlock(cp); sleep(&cp->r, cmddone, cp); @@ -980,6 +996,8 @@ hardintr(Ureg *ur, void *arg) cp = &hardc[0]; dp = cp->dp; + ilock(cp); + loop = 0; while((cp->status = inb(cp->pbase+Pstatus)) & Sbusy){ if(++loop > 100) { @@ -988,6 +1006,7 @@ hardintr(Ureg *ur, void *arg) panic("hardintr: wait busy"); } } + switch(cp->cmd){ case Cwrite: if(cp->status & Serr){ @@ -995,7 +1014,7 @@ hardintr(Ureg *ur, void *arg) cp->cmd = 0; cp->error = inb(cp->pbase+Perror); wakeup(&cp->r); - return; + break; } cp->sofar++; if(cp->sofar < cp->nsecs){ @@ -1033,7 +1052,7 @@ hardintr(Ureg *ur, void *arg) cp->cmd = 0; cp->error = inb(cp->pbase+Perror); wakeup(&cp->r); - return; + break; } addr = cp->buf; if(addr){ @@ -1070,6 +1089,8 @@ hardintr(Ureg *ur, void *arg) cp->cmd, cp->lastcmd, cp->status); break; } + + iunlock(cp); } void @@ -1086,21 +1107,16 @@ hardclock(void) for(drive = 0; drive < conf.nhard; drive++){ dp = &hard[drive]; cp = dp->cp; - if(canqlock(cp) == 0) - continue; diff = TK2SEC(m->ticks - dp->usetime); - switch(dp->state){ - case Sspinning: - if(diff >= spindowntime){ - cp->cmd = Cstandby; - outb(cp->pbase+Pcount, 0); - outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4) | 0); - outb(cp->pbase+Pcmd, cp->cmd); - dp->state = Sstandby; - } - break; + if((dp->state == Sspinning) && (diff >= spindowntime)){ + ilock(cp); + cp->cmd = Cstandby; + outb(cp->pbase+Pcount, 0); + outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4) | 0); + outb(cp->pbase+Pcmd, cp->cmd); + iunlock(cp); + dp->state = Sstandby; } - qunlock(dp->cp); } } diff --git a/pc/devi82365.c b/pc/devi82365.c index b50771d1fb679c874f4b48d3cb831b2148ec1847..1b1ff369bb09caf71e427d1679ae24e4a644b45e 100644 --- a/pc/devi82365.c +++ b/pc/devi82365.c @@ -264,11 +264,14 @@ slotena(Slot *pp) static void slotdis(Slot *pp) { + int x; + /* disable the windows into the card */ wrreg(pp, Rwe, 0); /* disable the card */ - wrreg(pp, Rpc, 5|Fautopower); + x = vcode(5) | (vcode(5)<<2); + wrreg(pp, Rpc, x|Fautopower); pp->enabled = 0; } diff --git a/port/devmnt.c b/port/devmnt.c index fafa977c7af36a826ef9a9e117e320170e91fc00..c6b4c8bef868fa8ecee7e49778115c93bb9bdec2 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -8,13 +8,13 @@ struct Mntrpc { - Chan *c; /* Channel for whom we are working */ - Mntrpc *list; /* Free/pending list */ + Chan* c; /* Channel for whom we are working */ + Mntrpc* list; /* Free/pending list */ Fcall request; /* Outgoing file system protocol message */ Fcall reply; /* Incoming reply */ - Mnt *m; /* Mount device during rpc */ + Mnt* m; /* Mount device during rpc */ Rendez r; /* Place to hang out */ - char *rpc; /* I/O Data buffer */ + char* rpc; /* I/O Data buffer */ char done; /* Rpc completed */ char flushed; /* Flush was sent */ ushort flushtag; /* Tag flush sent on */ @@ -24,9 +24,9 @@ struct Mntrpc struct Mntalloc { Lock; - Mnt *list; /* Mount devices in use */ - Mnt *mntfree; /* Free list */ - Mntrpc *rpcfree; + Mnt* list; /* Mount devices in use */ + Mnt* mntfree; /* Free list */ + Mntrpc* rpcfree; ulong id; int rpctag; }mntalloc; diff --git a/port/portfns.h b/port/portfns.h index a14404d77e90328e5ff5fa24aed8e8d3006c2e35..77c3aafa56be8e43fc68a23e7fc8b73e4f9bbb46 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -294,3 +294,4 @@ void hnputl(void*, ulong); void hnputs(void*, ushort); ulong nhgetl(void*); ushort nhgets(void*); +void filsetalloc(void* (*)(long), void* (*)(long)); diff --git a/port/proc.c b/port/proc.c index e1fb2a12aa3098ce91299d0b5589e85d705fe376..35639a1a4c7733179c3e72ec5f09531bf78c5eae 100644 --- a/port/proc.c +++ b/port/proc.c @@ -115,9 +115,10 @@ anyhigher(void) Proc *p; int pri; + return runq.n; pri = up->pri; for(p=runq.head; p; p=p->rnext) - if(p->pri < pri) + if(p->pri <= pri) if(p->wired == 0 || p->wired == m) return 1; return 0; diff --git a/port/sysproc.c b/port/sysproc.c index d27cd7bcd69adfe18bdbead01a3e96ef0d5de5fa..8f4d7f3e4725f3adf61fac2ce8b49f4e88299786 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -465,12 +465,12 @@ syssleep(ulong *arg) int n; n = arg[0]; - if(n == 0) { + if(n <= 0) { up->yield = 1; sched(); return 0; } - if(MS2TK(n) == 0) + if(n < TK2MS(1)) n = TK2MS(1); tsleep(&up->sleep, return0, 0, n); return 0;