From bb6e51aa0df865009680518ef04334f064fb6509 Mon Sep 17 00:00:00 2001 From: Björn Stenberg Date: Fri, 14 Mar 2003 16:06:09 +0000 Subject: Moved read code around a bit to more strictly obey the ATA specification. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3444 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/ata.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'firmware/drivers/ata.c') diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index 523b080ec8..26602b1342 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c @@ -221,19 +221,13 @@ int ata_read_sectors(unsigned long start, int j; int sectors; int wordcount; + int status; if (!wait_for_start_of_transfer()) { ret = -4; goto retry; } - if ( ATA_ALT_STATUS & (STATUS_ERR | STATUS_DF) ) { - ret = -5; - if (perform_soft_reset()) - break; - goto retry; - } - if (spinup) { ata_spinup_time = current_tick - last_disk_activity; spinup = false; @@ -241,6 +235,9 @@ int ata_read_sectors(unsigned long start, poweroff = false; } + /* read the status register exactly once per loop */ + status = ATA_STATUS; + /* if destination address is odd, use byte copying, otherwise use word copying */ @@ -263,10 +260,18 @@ int ata_read_sectors(unsigned long start, ((unsigned short*)buf)[j] = SWAB16(ATA_DATA); } -#ifdef USE_INTERRUPT - /* reading the status register clears the interrupt */ - j = ATA_STATUS; -#endif + /* + "Device errors encountered during READ MULTIPLE commands are + posted at the beginning of the block or partial block transfer, + but the DRQ bit is still set to one and the data transfer shall + take place, including transfer of corrupted data, if any." + -- ATA specification + */ + if ( status & (STATUS_BSY | STATUS_ERR | STATUS_DF) ) { + ret = -5; + goto retry; + } + buf += sectors * SECTOR_SIZE; /* Advance one chunk of sectors */ count -= sectors; -- cgit v1.2.3