From 70747f9bf38fd659be227b575e8d28faeeec6300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Stenberg?= Date: Tue, 24 Sep 2002 14:23:18 +0000 Subject: Added read retry. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2397 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/ata.c | 98 +++++++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 45 deletions(-) (limited to 'firmware') diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index 807d441351..d547692b56 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c @@ -81,6 +81,8 @@ #define Q_SLEEP 0 +#define READ_TIMEOUT 5*HZ + static struct mutex ata_mtx; char ata_device; /* device 0 (master) or 1 (slave) */ int ata_io_address; /* 0x300 or 0x200, only valid on recorder */ @@ -166,6 +168,7 @@ int ata_read_sectors(unsigned long start, void* buf) { int ret = 0; + int timeout; last_disk_activity = current_tick; @@ -196,62 +199,67 @@ int ata_read_sectors(unsigned long start, led(true); - if ( count == 256 ) - ATA_NSECTOR = 0; /* 0 means 256 sectors */ - else - ATA_NSECTOR = (unsigned char)count; - - ATA_SECTOR = start & 0xff; - ATA_LCYL = (start >> 8) & 0xff; - ATA_HCYL = (start >> 16) & 0xff; - ATA_SELECT = ((start >> 24) & 0xf) | SELECT_LBA | ata_device; - ATA_COMMAND = CMD_READ_MULTIPLE; - - while (count) { - int j; - int sectors; - int wordcount; + timeout = current_tick + READ_TIMEOUT; + while (TIME_BEFORE(current_tick, timeout)) { - if (!wait_for_start_of_transfer()) - { - led(false); - mutex_unlock(&ata_mtx); - return -1; - } + if ( count == 256 ) + ATA_NSECTOR = 0; /* 0 means 256 sectors */ + else + ATA_NSECTOR = (unsigned char)count; + + ATA_SECTOR = start & 0xff; + ATA_LCYL = (start >> 8) & 0xff; + ATA_HCYL = (start >> 16) & 0xff; + ATA_SELECT = ((start >> 24) & 0xf) | SELECT_LBA | ata_device; + ATA_COMMAND = CMD_READ_MULTIPLE; + + while (count) { + int j; + int sectors; + int wordcount; + + if (!wait_for_start_of_transfer()) { + ret = -4; + continue; + } - /* if destination address is odd, use byte copying, - otherwise use word copying */ + /* if destination address is odd, use byte copying, + otherwise use word copying */ - if (count >= multisectors ) - sectors = multisectors; - else - sectors = count; + if (count >= multisectors ) + sectors = multisectors; + else + sectors = count; - wordcount = sectors * SECTOR_SIZE / 2; + wordcount = sectors * SECTOR_SIZE / 2; - if ( (unsigned int)buf & 1 ) { - for (j=0; j < wordcount; j++) { - unsigned short tmp = SWAB16(ATA_DATA); - ((unsigned char*)buf)[j*2] = tmp >> 8; - ((unsigned char*)buf)[j*2+1] = tmp & 0xff; + if ( (unsigned int)buf & 1 ) { + for (j=0; j < wordcount; j++) { + unsigned short tmp = SWAB16(ATA_DATA); + ((unsigned char*)buf)[j*2] = tmp >> 8; + ((unsigned char*)buf)[j*2+1] = tmp & 0xff; + } + } + else { + for (j=0; j < wordcount; j++) + ((unsigned short*)buf)[j] = SWAB16(ATA_DATA); } - } - else { - for (j=0; j < wordcount; j++) - ((unsigned short*)buf)[j] = SWAB16(ATA_DATA); - } #ifdef USE_INTERRUPT - /* reading the status register clears the interrupt */ - j = ATA_STATUS; + /* reading the status register clears the interrupt */ + j = ATA_STATUS; #endif - buf += sectors * SECTOR_SIZE; /* Advance one chunk of sectors */ - count -= sectors; - } + buf += sectors * SECTOR_SIZE; /* Advance one chunk of sectors */ + count -= sectors; + } - if(!wait_for_end_of_transfer()) - ret = -3; + if(!wait_for_end_of_transfer()) { + ret = -3; + continue; + } + break; + } led(false); mutex_unlock(&ata_mtx); -- cgit v1.2.3