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!
This commit is contained in:
parent
521a0b336c
commit
44615fba43
1 changed files with 26 additions and 15 deletions
|
@ -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);
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue