shithub: riscv

Download patch

ref: df1d6ba99da637f21cc38d2690ad599c1a803a86
parent: e294bcae532ee21ab2f2709d20a9741fc8b59ff9
author: cinap_lenrek <[email protected]>
date: Thu Apr 19 19:56:10 EDT 2012

sdide: do drive presence check in atadrive, probe slave drive before master.

--- a/sys/src/9/pc/sdide.c
+++ b/sys/src/9/pc/sdide.c
@@ -549,7 +549,7 @@
 static int
 ataidentify(Ctlr*, int cmdport, int ctlport, int dev, int pkt, void* info)
 {
-	int as, command, drdy, rlo, rhi;
+	int as, command, drdy;
 
 	if(pkt){
 		command = Cidpkt;
@@ -561,36 +561,17 @@
 	}
 	dev &= ~Lba;
 	as = ataready(cmdport, ctlport, dev, Bsy|Drq, drdy, 103*1000);
-	if(as < 0){
-		/* try to detect floating bus */
-		outb(cmdport+Cyllo, 0xAA);
-		outb(cmdport+Cylhi, 0x55);
-		outb(cmdport+Sector, 0xFF);
-		rlo = inb(cmdport+Cyllo);
-		rhi = inb(cmdport+Cylhi);
-		if(rlo != 0xAA && (rlo == 0xFF || rhi != 0x55))
-			return as;
-
-		/* theres a device, try waiting some more */
-		as = ataready(cmdport, ctlport, dev, Bsy|Drq, drdy, 6*1000*1000);
-		if(as < 0)
-			return as;
-	}
+	if(as < 0)
+		return -1;
 	outb(cmdport+Command, command);
 	microdelay(1);
 
 	as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 400*1000);
-	if(as < 0)
-		return -1;
-	if(as & Err)
+	if(as < 0 || (as & Err))
 		return as;
-
 	memset(info, 0, 512);
 	inss(cmdport+Data, info, 256);
-
-	ataready(cmdport, ctlport, dev, Bsy|Drq, drdy, 3*1000);
 	inb(cmdport+Status);
-
 	return 0;
 }
 
@@ -597,7 +578,7 @@
 static Drive*
 atadrive(SDunit *unit, Drive *drive, int cmdport, int ctlport, int dev)
 {
-	int as, pkt;
+	int as, pkt, rlo, rhi;
 	uchar buf[512], oserial[21];
 	uvlong osectors;
 	Ctlr *ctlr;
@@ -604,8 +585,8 @@
 
 	if(DEBUG & DbgIDENTIFY)
 		print("identify: port %ux dev %.2ux\n", cmdport, dev & ~Lba);
+
 	atadebug(0, 0, "identify: port 0x%uX dev 0x%2.2uX\n", cmdport, dev);
-	pkt = 1;
 	if(drive != nil){
 		osectors = drive->sectors;
 		memmove(oserial, drive->serial, sizeof drive->serial);
@@ -614,7 +595,20 @@
 		osectors = 0;
 		memset(oserial, 0, sizeof drive->serial);
 		ctlr = nil;
+
+		/* detect if theres a drive present */
+		outb(cmdport+Dh, dev & ~Lba);
+		microdelay(1);
+		outb(cmdport+Cyllo, 0xAA);
+		outb(cmdport+Cylhi, 0x55);
+		outb(cmdport+Sector, 0xFF);
+		rlo = inb(cmdport+Cyllo);
+		rhi = inb(cmdport+Cylhi);
+		if(rlo != 0xAA && (rlo == 0xFF || rhi != 0x55))
+			return nil;
 	}
+
+	pkt = 1;
 retry:
 	as = ataidentify(ctlr, cmdport, ctlport, dev, pkt, buf);
 	if(as < 0)
@@ -724,10 +718,10 @@
 		goto release;
 	}
 
-	if((map & 1) && (ctlr->drive[0] = atadrive(0, 0, cmdport, ctlport, Dev0)))
-		ctlr->drive[0]->ctlr = ctlr;
 	if((map & 2) && (ctlr->drive[1] = atadrive(0, 0, cmdport, ctlport, Dev1)))
 		ctlr->drive[1]->ctlr = ctlr;
+	if((map & 1) && (ctlr->drive[0] = atadrive(0, 0, cmdport, ctlport, Dev0)))
+		ctlr->drive[0]->ctlr = ctlr;
 
 	if(ctlr->drive[0] == nil && ctlr->drive[1] == nil){
 		free(ctlr->drive[0]);