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
This commit is contained in:
parent
67c1a0c63c
commit
bb6e51aa0d
1 changed files with 16 additions and 11 deletions
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue