git: 9front

Download patch

ref: 19d1bfd5224e47048f53b0ccbfc6824f8a15dd8a
parent: 81652c664317a96fe28dda30cb647b6d8b93094d
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Wed Apr 18 11:55:51 EDT 2012

sdide: do drive probles the non-clever way, this got a-'s cdrom to working

--- a/sys/src/9/pc/sdide.c
+++ b/sys/src/9/pc/sdide.c
@@ -574,7 +574,8 @@
 
 	memset(info, 0, 512);
 	inss(cmdport+Data, info, 256);
-	ataready(cmdport, ctlport, dev, Bsy|Drq, Drdy, 3*1000);
+
+	ataready(cmdport, ctlport, dev, Bsy|Drq, drdy, 3*1000);
 	inb(cmdport+Status);
 
 	return 0;
@@ -621,7 +622,7 @@
 
 	memmove(drive->info, buf, sizeof(drive->info));
 
-	setfissig(drive, pkt? 0xeb140000: 0x0101);
+	setfissig(drive, pkt ? 0xeb140000 : 0x0101);
 	drive->sectors = idfeat(drive, drive->info);
 	drive->secsize = idss(drive, drive->info);
 
@@ -686,24 +687,12 @@
 	microdelay(2*1000);
 }
 
-static int
-seldev(int dev, int map)
-{
-	if((dev & Devs) == Dev0 && map&1)
-		return dev;
-	if((dev & Devs) == Dev1 && map&2)
-		return dev;
-	return -1;
-}
-
 static SDev*
 ataprobe(int cmdport, int ctlport, int irq, int map)
 {
+	static int nonlegacy = 'C';
 	Ctlr* ctlr;
 	SDev *sdev;
-	Drive *drive;
-	int dev, error, rhi, rlo;
-	static int nonlegacy = 'C';
 
 	if(ioalloc(cmdport, 8, 0, "atacmd") < 0) {
 		print("ataprobe: Cannot allocate %X\n", cmdport);
@@ -715,142 +704,32 @@
 		return nil;
 	}
 
-	/*
-	 * Try to detect a floating bus.
-	 * Bsy should be cleared. If not, see if the cylinder registers
-	 * are read/write capable.
-	 * If the master fails, try the slave to catch slave-only
-	 * configurations.
-	 * There's no need to restore the tested registers as they will
-	 * be reset on any detected drives by the Cedd command.
-	 * All this indicates is that there is at least one drive on the
-	 * controller; when the non-existent drive is selected in a
-	 * single-drive configuration the registers of the existing drive
-	 * are often seen, only command execution fails.
-	 */
-	if((dev = seldev(Dev0, map)) == -1)
-	if((dev = seldev(Dev1, map)) == -1)
+	if((ctlr = malloc(sizeof(Ctlr))) == nil)
 		goto release;
-	if(inb(ctlport+As) & Bsy){
-		outb(cmdport+Dh, dev);
-		microdelay(1);
-trydev1:
-		atadebug(cmdport, ctlport, "ataprobe bsy");
-		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)){
-			if(dev == Dev1 || (dev = seldev(Dev1, map)) == -1){
-release:
-				outb(cmdport+Dc, Nien);
-				inb(cmdport+Status);
-				/* further measures to prevent irqs? */
-				iofree(cmdport);
-				iofree(ctlport+As);
-				return nil;
-			}
-			if(ataready(cmdport, ctlport, dev, Bsy, 0, 20*1000) < 0)
-				goto trydev1;
-		}
-	}
-
-	/*
-	 * Disable interrupts on any detected controllers.
-	 */
-	outb(ctlport+Dc, Nien);
-tryedd1:
-	if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 105*1000) < 0){
-		/*
-		 * There's something there, but it didn't come up clean,
-		 * so try hitting it with a big stick. The timing here is
-		 * wrong but this is a last-ditch effort and it sometimes
-		 * gets some marginal hardware back online.
-		 */
-		atasrst(ctlport);
-		if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 106*1000) < 0)
-			goto release;
-	}
-
-	/*
-	 * Can only get here if controller is not busy.
-	 * If there are drives Bsy will be set within 400nS,
-	 * must wait 2mS before testing Status.
-	 * Wait for the command to complete (6 seconds max).
-	 */
-	outb(cmdport+Command, Cedd);
-	delay(2);
-	if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 6*1000*1000) < 0)
+	if((sdev = malloc(sizeof(SDev))) == nil){
+		free(ctlr);
 		goto release;
-
-	/*
-	 * If bit 0 of the error register is set then the selected drive
-	 * exists. This is enough to detect single-drive configurations.
-	 * However, if the master exists there is no way short of executing
-	 * a command to determine if a slave is present.
-	 * It appears possible to get here testing Dev0 although it doesn't
-	 * exist and the EDD won't take, so try again with Dev1.
-	 */
-	error = inb(cmdport+Error);
-	atadebug(cmdport, ctlport, "ataprobe: dev %uX", dev);
-	if((error & ~0x80) != 0x01){
-		if(dev == Dev1)
-			goto release;
-		if((dev = seldev(Dev1, map)) == -1)
-			goto release;
-		goto tryedd1;
 	}
 
-	/*
-	 * At least one drive is known to exist, try to
-	 * identify it. If that fails, don't bother checking
-	 * any further.
-	 * If the one drive found is Dev0 and the EDD command
-	 * didn't indicate Dev1 doesn't exist, check for it.
-	 */
-	if((drive = atadrive(0, 0, cmdport, ctlport, dev)) == nil)
-		goto release;
-	if((ctlr = malloc(sizeof(Ctlr))) == nil){
-		free(drive);
-		goto release;
-	}
-	if((sdev = malloc(sizeof(SDev))) == nil){
+	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(ctlr->drive[0] == nil && ctlr->drive[1] == nil){
+		free(ctlr->drive[0]);
+		free(ctlr->drive[1]);
 		free(ctlr);
-		free(drive);
+		free(sdev);
 		goto release;
 	}
-	drive->ctlr = ctlr;
-	if(dev == Dev0){
-		ctlr->drive[0] = drive;
-		if(!(error & 0x80)){
-			/*
-			 * Always leave Dh pointing to a valid drive,
-			 * otherwise a subsequent call to ataready on
-			 * this controller may try to test a bogus Status.
-			 * Ataprobe is the only place possibly invalid
-			 * drives should be selected.
-			 */
-			drive = atadrive(0, 0, cmdport, ctlport, Dev1);
-			if(drive != nil){
-				drive->ctlr = ctlr;
-				ctlr->drive[1] = drive;
-			}
-			else{
-				outb(cmdport+Dh, Dev0);
-				microdelay(1);
-			}
-		}
-	}
-	else
-		ctlr->drive[1] = drive;
 
 	ctlr->cmdport = cmdport;
 	ctlr->ctlport = ctlport;
 	ctlr->irq = irq;
 	ctlr->tbdf = BUSUNKNOWN;
-	ctlr->command = Cedd;		/* debugging */
-	
+	ctlr->command = Cnop;		/* debugging */
+
 	switch(cmdport){
 	default:
 		sdev->idno = nonlegacy;
@@ -870,6 +749,12 @@
 	ctlr->sdev = sdev;
 
 	return sdev;
+
+release:
+	iofree(cmdport);
+	iofree(ctlport+As);
+
+	return nil;
 }
 
 static void
@@ -1898,8 +1783,6 @@
 		if(ctlr->irqack != nil)
 			ctlr->irqack(ctlr);
 		iunlock(ctlr);
-		if((DEBUG & DbgINL) && ctlr->command != Cedd)
-			print("Inil%2.2uX+", ctlr->command);
 		return;
 	}
 	if(status & Err)
--