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 <[email protected]>

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 <[email protected]>
  *   Copyright (C) 2005 Stefan Reinauer <[email protected]>
- *   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;
 }

-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to