From 62321ed0bd7d8d5879a9caad3d8f642dbe876033 Mon Sep 17 00:00:00 2001 From: Torne Wuff Date: Wed, 7 Apr 2010 20:01:21 +0000 Subject: Make ATA code not bother to retry requests that return IDNF (specified sector not valid). There's no point retrying these requests for five seconds, the sector number isn't going to get any more valid. It interferes with being able to detect broken drives like the 5.5G 80GB iPod's. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25525 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/ata.c | 11 +++++++++++ firmware/target/arm/archos/av300/ata-target.h | 1 + firmware/target/arm/ata-target.h | 1 + firmware/target/arm/imx31/gigabeat-s/ata-target.h | 1 + firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h | 1 + firmware/target/arm/tms320dm320/creative-zvm/ata-target.h | 1 + firmware/target/arm/tms320dm320/mrobe-500/ata-target.h | 1 + firmware/target/coldfire/ata-target.h | 1 + firmware/target/sh/archos/ata-target.h | 1 + 9 files changed, 19 insertions(+) (limited to 'firmware') diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index ddbd6a1edf..2140456e6b 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c @@ -478,6 +478,7 @@ static int ata_transfer_sectors(unsigned long start, int sectors; int wordcount; int status; + int error; if (!wait_for_start_of_transfer()) { /* We have timed out waiting for RDY and/or DRQ, possibly @@ -502,6 +503,7 @@ static int ata_transfer_sectors(unsigned long start, /* read the status register exactly once per loop */ status = ATA_STATUS; + error = ATA_ERROR; if (count >= multisectors ) sectors = multisectors; @@ -526,6 +528,9 @@ static int ata_transfer_sectors(unsigned long start, if ( status & (STATUS_BSY | STATUS_ERR | STATUS_DF) ) { perform_soft_reset(); ret = -6; + /* no point retrying IDNF, sector no. was invalid */ + if (error & ERROR_IDNF) + break; goto retry; } @@ -537,8 +542,14 @@ static int ata_transfer_sectors(unsigned long start, } if(!ret && !wait_for_end_of_transfer()) { + int error; + + error = ATA_ERROR; perform_soft_reset(); ret = -4; + /* no point retrying IDNF, sector no. was invalid */ + if (error & ERROR_IDNF) + break; goto retry; } break; diff --git a/firmware/target/arm/archos/av300/ata-target.h b/firmware/target/arm/archos/av300/ata-target.h index f1b1d7dc15..9c59acc460 100644 --- a/firmware/target/arm/archos/av300/ata-target.h +++ b/firmware/target/arm/archos/av300/ata-target.h @@ -39,6 +39,7 @@ #define STATUS_DRQ 0x08 #define STATUS_ERR 0x01 #define ERROR_ABRT 0x04 +#define ERROR_IDNF 0x10 #define WRITE_PATTERN1 0xa5 #define WRITE_PATTERN2 0x5a diff --git a/firmware/target/arm/ata-target.h b/firmware/target/arm/ata-target.h index 82c5a5f555..c9d789d092 100644 --- a/firmware/target/arm/ata-target.h +++ b/firmware/target/arm/ata-target.h @@ -38,6 +38,7 @@ #define STATUS_DRQ 0x08 #define STATUS_ERR 0x01 #define ERROR_ABRT 0x04 +#define ERROR_IDNF 0x10 #define WRITE_PATTERN1 0xa5 #define WRITE_PATTERN2 0x5a diff --git a/firmware/target/arm/imx31/gigabeat-s/ata-target.h b/firmware/target/arm/imx31/gigabeat-s/ata-target.h index 8b308f28b5..f7f84f82e9 100644 --- a/firmware/target/arm/imx31/gigabeat-s/ata-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/ata-target.h @@ -52,6 +52,7 @@ #define STATUS_DRQ 0x08 #define STATUS_ERR 0x01 #define ERROR_ABRT 0x04 +#define ERROR_IDNF 0x10 #define WRITE_PATTERN1 0xa5 #define WRITE_PATTERN2 0x5a diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h index 54d0964560..01cdbb9ddb 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h +++ b/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h @@ -50,6 +50,7 @@ void copy_read_sectors(unsigned char* buf, int wordcount); #define STATUS_DRQ 0x08 #define STATUS_ERR 0x01 #define ERROR_ABRT 0x04 +#define ERROR_IDNF 0x10 #define WRITE_PATTERN1 0xa5 #define WRITE_PATTERN2 0x5a diff --git a/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h b/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h index a1d4a90cb8..46713e70c5 100644 --- a/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h +++ b/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h @@ -59,6 +59,7 @@ extern int _ata_write_sectors(IF_MD2(int drive,) unsigned long start, int count, #define STATUS_DRQ 0x08 #define STATUS_ERR 0x01 #define ERROR_ABRT 0x04 +#define ERROR_IDNF 0x10 #define WRITE_PATTERN1 0xa5 #define WRITE_PATTERN2 0x5a diff --git a/firmware/target/arm/tms320dm320/mrobe-500/ata-target.h b/firmware/target/arm/tms320dm320/mrobe-500/ata-target.h index 2a9d3e8010..0abeb2e9e7 100644 --- a/firmware/target/arm/tms320dm320/mrobe-500/ata-target.h +++ b/firmware/target/arm/tms320dm320/mrobe-500/ata-target.h @@ -55,6 +55,7 @@ void copy_write_sectors(const unsigned char* buf, int wordcount); #define STATUS_DRQ 0x08 #define STATUS_ERR 0x01 #define ERROR_ABRT 0x04 +#define ERROR_IDNF 0x10 #define WRITE_PATTERN1 0xa5 #define WRITE_PATTERN2 0x5a diff --git a/firmware/target/coldfire/ata-target.h b/firmware/target/coldfire/ata-target.h index a1c521e7df..3f462b9471 100644 --- a/firmware/target/coldfire/ata-target.h +++ b/firmware/target/coldfire/ata-target.h @@ -44,6 +44,7 @@ #define STATUS_ERR 0x0100 #define ERROR_ABRT 0x0400 +#define ERROR_IDNF 0x1000 #define WRITE_PATTERN1 0xa5 #define WRITE_PATTERN2 0x5a diff --git a/firmware/target/sh/archos/ata-target.h b/firmware/target/sh/archos/ata-target.h index 893737048e..aef025e1df 100644 --- a/firmware/target/sh/archos/ata-target.h +++ b/firmware/target/sh/archos/ata-target.h @@ -46,6 +46,7 @@ #define STATUS_ERR 0x01 #define ERROR_ABRT 0x04 +#define ERROR_IDNF 0x10 #define WRITE_PATTERN1 0xa5 #define WRITE_PATTERN2 0x5a -- cgit v1.2.3