shithub: riscv

Download patch

ref: 50c9769bbdffc4d9b8d5122d1956f6ee5fd9f043
parent: a9206fa5ada872e160e7aab664f6a5166c3f5551
author: cinap_lenrek <[email protected]>
date: Sat Dec 1 23:50:37 EST 2012

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.

--- a/sys/src/9/pc/sdiahci.c
+++ b/sys/src/9/pc/sdiahci.c
@@ -612,17 +612,16 @@
 	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 @@
 
 	/* 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;