summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2019-11-17 21:19:55 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2019-11-17 21:19:55 +0100
commit44615fba43debbde03c154976fb616a08788b311 (patch)
tree063d9496d567646f053d0df9f210025ee04c0312
parent521a0b336c7df8ad79efc7848c95a7b060beea27 (diff)
sdiahci: implement reset timeout for ahciencreset(), make blink() never block, fix map[] access in ledkproc()
Ori_B reports that his controller gets stuck in the ahciencreset() wait loop. so we implement a 1000 ms timeout. we replace delay() with esleep() as we are always called from the ledkproc(). blink() could enter infinite delay loop as well, so instead of waiting for the message to get transmitted we exit making it non-blocking (we will get called again anyway). the access to the controller map[] was wrong in ledkproc(). the index is the controller number, not the drive number!
-rw-r--r--sys/src/9/pc/sdiahci.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/sys/src/9/pc/sdiahci.c b/sys/src/9/pc/sdiahci.c
index 9d6400069..053fafa70 100644
--- a/sys/src/9/pc/sdiahci.c
+++ b/sys/src/9/pc/sdiahci.c
@@ -1215,14 +1215,19 @@ static int
ahciencreset(Ctlr *c)
{
Ahba *h;
+ int i;
if(c->enctype == Eesb)
return 0;
h = c->hba;
h->emctl |= Emrst;
- while(h->emctl & Emrst)
- delay(1);
- return 0;
+ for(i = 0; i < 1000; i++){
+ if((h->emctl & Emrst) == 0)
+ return 0;
+ esleep(1);
+ }
+ print("%s: ahciencreset: hung ctlr\n", Tname(c));
+ return -1;
}
/*
@@ -1301,9 +1306,11 @@ blink(Drive *d, ulong t)
return 0;
c = d->ctlr;
h = c->hba;
+
/* ensure last message has been transmitted */
- while(h->emctl & Tmsg)
- microdelay(1);
+ if(h->emctl & Tmsg)
+ return -1;
+
switch(c->enctype){
default:
panic("%s: bad led type %d", dnam(d), c->enctype);
@@ -1403,30 +1410,34 @@ ledkproc(void*)
memset(map, 0, sizeof map);
for(i = 0; i < niactlr; i++)
if(iactlr[i].enctype != 0){
- ahciencreset(iactlr + i);
+ if(ahciencreset(iactlr + i) == -1)
+ continue;
map[i] = 1;
j++;
}
if(j == 0)
pexit("no work", 1);
for(i = 0; i < niadrive; i++){
- iadrive[i]->nled = 3; /* hardcoded */
- if(iadrive[i]->ctlr->enctype == Eesb)
- iadrive[i]->nled = 3;
- iadrive[i]->ledbits = -1;
+ d = iadrive[i];
+ d->nled = 3; /* hardcoded */
+ if(d->ctlr->enctype == Eesb)
+ d->nled = 3;
+ d->ledbits = -1;
}
for(i = 0; ; i++){
t0 = Ticks;
for(j = 0; j < niadrive; ){
- c = iadrive[j]->ctlr;
- if(map[j] == 0)
- j += c->enctype;
- else if(c->enctype == Eesb){
+ d = iadrive[j];
+ c = d->ctlr;
+ if(map[c - iactlr] == 0)
+ j++;
+ else
+ if(c->enctype == Eesb){
blinkesb(c, i);
j += c->ndrive;
}else{
- d = iadrive[j++];
blink(d, i);
+ j++;
}
}
t1 = Ticks;