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@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@suse.de * Copyright (C) 2005 Stefan Reinauer stepan@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; }