From 50c9769bbdffc4d9b8d5122d1956f6ee5fd9f043 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 2 Dec 2012 04:50:37 +0100 Subject: [PATCH] sdiahci: fix staggered spinup wait loop, fix confusion setting Asud in the cmd register is not needed, because Apwr is (Asud|Apod) already. the problem really was that the drive comes up with sstatus Spresent (001), so we never spun it up because (p->sstatus & Sphylink) == 0 was never met (Sphylink being a mask (011) overlaping Spresent bit). the spinup wait loop has to run only for the staggered spinup case (h->cap & Hss) and it should wait for the drive to be detected by the phy, not just cold presence detect. --- sys/src/9/pc/sdiahci.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/sys/src/9/pc/sdiahci.c b/sys/src/9/pc/sdiahci.c index f1dafe20b..e00ce29b5 100644 --- a/sys/src/9/pc/sdiahci.c +++ b/sys/src/9/pc/sdiahci.c @@ -612,16 +612,15 @@ ahciconfigdrive(Ahba *h, Aportc *c, int mode) dprint("ahci: configdrive cmd=%lux sstatus=%lux\n", p->cmd, p->sstatus); p->cmd |= Afre; - if((p->sstatus & Sbist) == 0 && (p->cmd & Apwr) != Apwr){ + if((p->cmd & Apwr) != Apwr) p->cmd |= Apwr; - dprint("ahci: power up ... [%.3lux]\n", p->sstatus); - } - if((p->sstatus & Sphylink) == 0){ - if(h->cap & Hss) - p->cmd |= Asud; + + if((h->cap & Hss) != 0){ dprint("ahci: spin up ... [%.3lux]\n", p->sstatus); for(int i = 0; i < 1400; i += 50){ - if(p->sstatus & (Sphylink | Sbist)) + if((p->sstatus & Sbist) != 0) + break; + if((p->sstatus & Sphylink) == Sphylink) break; asleep(50); } @@ -633,8 +632,7 @@ ahciconfigdrive(Ahba *h, Aportc *c, int mode) /* disable power managment sequence from book. */ p->sctl = 3*Aipm | mode*Aspd | 0*Adet; - if(h->cap & Halp) - p->cmd &= ~Aalpe; + p->cmd &= ~Aalpe; p->cmd |= Ast; p->ie = IEM;