[coreboot] [FILO] r116 - in trunk/filo: drivers fs

repository service svn at coreboot.org
Fri Mar 26 13:01:44 CET 2010


Author: stepan
Date: Fri Mar 26 13:01:39 2010
New Revision: 116
URL: http://tracker.coreboot.org/trac/filo/changeset/116

Log:
improve IDE error handling

Signed-off-by: Stefan Reinauer <stepan at coresystems.de>

Modified:
   trunk/filo/drivers/ide_new.c
   trunk/filo/drivers/ide_new.h
   trunk/filo/fs/blockdev.c

Modified: trunk/filo/drivers/ide_new.c
==============================================================================
--- trunk/filo/drivers/ide_new.c	Fri Mar 26 12:59:14 2010	(r115)
+++ trunk/filo/drivers/ide_new.c	Fri Mar 26 13:01:39 2010	(r116)
@@ -3,7 +3,7 @@
  *   
  *   Copyright (C) 2004 Jens Axboe <axboe at suse.de>
  *   Copyright (C) 2005 Stefan Reinauer <stepan at openbios.org>
- *   Copyright (C) 2009 coresystems GmbH
+ *   Copyright (C) 2009-2010 coresystems GmbH
  *
  *   Credit goes to Hale Landis for his excellent ata demo software
  *
@@ -164,14 +164,15 @@
 	if (!stat)
 		stat = ob_ide_pio_readb(drive, IDEREG_STATUS);
 
-	printf("ob_ide_error drive<%d>: %s:\n", drive->nr, msg);
-	printf("    cmd=%x, stat=%x", chan->ata_cmd.command, stat);
+	debug("ob_ide_error ");
+	printf("drive<%d>: %s:\n", drive->nr, msg);
+	debug("    cmd=%x, stat=%x", chan->ata_cmd.command, stat);
 
 	if ((stat & (BUSY_STAT | ERR_STAT)) == ERR_STAT) {
 		err = ob_ide_pio_readb(drive, IDEREG_ERROR);
-		printf(", err=%x", err);
+		debug(", err=%x", err);
 	}
-	printf("\n");
+	debug("\n");
 
 	/*
 	 * see if sense is valid and dump that
@@ -183,19 +184,19 @@
 		if (cmd->cdb[0] == ATAPI_REQ_SENSE) {
 			old_cdb = cmd->old_cdb;
 
-			printf("    atapi opcode=%02x", old_cdb);
+			debug("    atapi opcode=%02x", old_cdb);
 		} else {
 			int i;
 
-			printf("    cdb: ");
+			debug("    cdb: ");
 			for (i = 0; i < sizeof(cmd->cdb); i++)
-				printf("%02x ", cmd->cdb[i]);
+				debug("%02x ", cmd->cdb[i]);
 		}
 		if (cmd->sense_valid)
-			printf(", sense: %02x/%02x/%02x", cmd->sense.sense_key, cmd->sense.asc, cmd->sense.ascq);
+			debug(", sense: %02x/%02x/%02x", cmd->sense.sense_key, cmd->sense.asc, cmd->sense.ascq);
 		else
-			printf(", no sense");
-		printf("\n");
+			debug(", no sense");
+		debug("\n");
 	}
 }
 
@@ -567,10 +568,15 @@
 		/*
 		 * ... except 'medium not present'
 		 */
-		if (cmd->sense.asc == 0x3a)
+		if (cmd->sense.asc == 0x3a) {
+			/* 'medium not present' is not an error */
+			ret = 0;
+			/* force reevaluation */
+			drive->channel->present = 0;
 			break;
+		}
 
-		udelay(1000000);
+		mdelay(1000);
 	} while (retries--);
 
 	if (ret)
@@ -613,10 +619,23 @@
 {
 	struct atapi_command *cmd = &drive->channel->atapi_cmd;
 	struct atapi_capacity cap;
+	int i;
 
 	/*
 	 * Test Unit Ready is like a ping
+	 * But wait a bit, as the drive might take a while
 	 */
+	i = 30;
+	while (i-- != 0) {
+		memset(cmd, 0, sizeof(*cmd));
+		cmd->cdb[0] = ATAPI_TUR;
+
+		if (!ob_ide_atapi_packet(drive,cmd)) break;
+
+		/* Give the drive some time to breathe */
+		mdelay(500);
+	}
+
 	memset(cmd, 0, sizeof(*cmd));
 	cmd->cdb[0] = ATAPI_TUR;
 
@@ -671,7 +690,7 @@
 	struct atapi_command *cmd = &drive->channel->atapi_cmd;
 
 	if (ob_ide_atapi_drive_ready(drive))
-		return 1;
+		return RETURN_NO_MEDIUM;
 
 	if (drive->bs == 2048) {
 		if (((block & 3) != 0) || ((sectors & 3) != 0)) {
@@ -1149,7 +1168,9 @@
 			    val == 0x0000ffff || val == 0xffff0000)
 				continue;
 
-			if (val == 0xac8f104c) {
+			// skip TI bridges on Rocky (ac8f) and Getac (803b)
+			// There must be a better way to do this...
+			if (val == 0xac8f104c || val == 0x803b104c) {
 				debug("Skipping TI bridge\n");
 				continue;
 			}

Modified: trunk/filo/drivers/ide_new.h
==============================================================================
--- trunk/filo/drivers/ide_new.h	Fri Mar 26 12:59:14 2010	(r115)
+++ trunk/filo/drivers/ide_new.h	Fri Mar 26 13:01:39 2010	(r116)
@@ -5,6 +5,14 @@
 #include "hdreg.h"
 
 /*
+ * Return values
+ */
+
+#define RETURN_OK		0x00
+#define RETURN_ERROR		0x01
+#define RETURN_NO_MEDIUM	0x02
+
+/*
  * legacy ide ports
  */
 #define IDEREG_DATA	0x00

Modified: trunk/filo/fs/blockdev.c
==============================================================================
--- trunk/filo/fs/blockdev.c	Fri Mar 26 12:59:14 2010	(r115)
+++ trunk/filo/fs/blockdev.c	Fri Mar 26 13:01:39 2010	(r116)
@@ -394,7 +394,11 @@
 		case DISK_IDE:
 		{
 			int count = (NUM_CACHE-hash>8)?8:(NUM_CACHE-hash);
-			if (ide_read_blocks(dev_drive, sector, count, buf) != 0)
+			int ret;
+			ret = ide_read_blocks(dev_drive, sector, count, buf);
+			if (ret == 2)
+				goto nomedium;
+			if (ret != 0)
 				goto readerr;
 			while (--count>0) {
 				cache_sect[hash+count] = sector + count;
@@ -439,6 +443,12 @@
       readerr:
 	printf("Disk read error dev=%d drive=%d sector=%lu\n",
 	       dev_type, dev_drive, sector);
+	flush_cache();
+	dev_name[0] = '\0';	/* force re-open the device next time */
+	return 0;
+      nomedium:
+	printf("No disk in drive.\n");
+	flush_cache();
 	dev_name[0] = '\0';	/* force re-open the device next time */
 	return 0;
 }




More information about the coreboot mailing list