diff --git a/sys/src/9/pc/ether82563.c b/sys/src/9/pc/ether82563.c index f4eab6a0f..bd3690288 100644 --- a/sys/src/9/pc/ether82563.c +++ b/sys/src/9/pc/ether82563.c @@ -1053,7 +1053,9 @@ i82563replenish(Ctlr *ctlr, int maysleep) print("i82563%d: no rx buffers\n", ctlr->pool); if(maysleep == 0) return -1; + ilock(p); p->starve = 1; + iunlock(p); sleep(p, icansleep, p); goto redux; } diff --git a/sys/src/9/pc/etheriwl.c b/sys/src/9/pc/etheriwl.c index 9bf90ef07..72a577166 100644 --- a/sys/src/9/pc/etheriwl.c +++ b/sys/src/9/pc/etheriwl.c @@ -349,7 +349,6 @@ struct Ctlr { Rendez; u32int m; u32int w; - u32int r; } wait; struct { @@ -1014,39 +1013,35 @@ readfirmware(char *name) return fw; } -typedef struct Irqwait Irqwait; -struct Irqwait { - Ctlr *ctlr; - u32int mask; -}; static int gotirq(void *arg) { - Irqwait *w; - Ctlr *ctlr; - - w = arg; - ctlr = w->ctlr; - ctlr->wait.r = ctlr->wait.m & w->mask; - if(ctlr->wait.r){ - ctlr->wait.m &= ~ctlr->wait.r; - return 1; - } - ctlr->wait.w = w->mask; - return 0; + Ctlr *ctlr = arg; + return (ctlr->wait.m & ctlr->wait.w) != 0; } static u32int irqwait(Ctlr *ctlr, u32int mask, int timeout) { - Irqwait w; + u32int r; - w.ctlr = ctlr; - w.mask = mask; - tsleep(&ctlr->wait, gotirq, &w, timeout); - ctlr->wait.w = 0; - return ctlr->wait.r & mask; + ilock(ctlr); + r = ctlr->wait.m & mask; + if(r == 0){ + ctlr->wait.w = mask; + iunlock(ctlr); + if(!waserror()){ + tsleep(&ctlr->wait, gotirq, ctlr, timeout); + poperror(); + } + ilock(ctlr); + ctlr->wait.w = 0; + r = ctlr->wait.m & mask; + } + ctlr->wait.m &= ~r; + iunlock(ctlr); + return r; } static int @@ -1206,7 +1201,7 @@ reset(Ctlr *ctlr) csr32w(ctlr, UcodeGp1Clr, UcodeGp1CmdBlocked); ctlr->broken = 0; - ctlr->wait.r = 0; + ctlr->wait.m = 0; ctlr->wait.w = 0; ctlr->ie = Idefmask; @@ -2197,11 +2192,8 @@ iwlinterrupt(Ureg*, void *arg) dumpctlr(ctlr); } ctlr->wait.m |= isr; - if(ctlr->wait.m & ctlr->wait.w){ - ctlr->wait.r = ctlr->wait.m & ctlr->wait.w; - ctlr->wait.m &= ~ctlr->wait.r; + if(ctlr->wait.m & ctlr->wait.w) wakeup(&ctlr->wait); - } done: csr32w(ctlr, Imr, ctlr->ie); iunlock(ctlr); diff --git a/sys/src/9/pc/pmmc.c b/sys/src/9/pc/pmmc.c index 7c95d74bb..2d2cd8af6 100644 --- a/sys/src/9/pc/pmmc.c +++ b/sys/src/9/pc/pmmc.c @@ -362,7 +362,9 @@ intrwait(Ctlr *c, u32int mask, int tmo) { u32int status; + ilock(c); c->waitmsk = Seint | mask; + iunlock(c); do { if(!waserror()){ tsleep(&c->r, waitcond, c, 100); @@ -373,11 +375,10 @@ intrwait(Ctlr *c, u32int mask, int tmo) break; tmo -= 100; } while(tmo > 0); - ilock(c); + c->waitmsk = 0; status = c->waitsts; c->waitsts &= ~(status & mask); - c->waitmsk = 0; if((status & mask) == 0 || (status & Seint) != 0){ /* abort command on timeout/error interrupt */ softreset(c, 0); @@ -386,7 +387,7 @@ intrwait(Ctlr *c, u32int mask, int tmo) } iunlock(c); - return status; + return status & mask; }