summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/ata.c27
1 files changed, 16 insertions, 11 deletions
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,
221 int j; 221 int j;
222 int sectors; 222 int sectors;
223 int wordcount; 223 int wordcount;
224 int status;
224 225
225 if (!wait_for_start_of_transfer()) { 226 if (!wait_for_start_of_transfer()) {
226 ret = -4; 227 ret = -4;
227 goto retry; 228 goto retry;
228 } 229 }
229 230
230 if ( ATA_ALT_STATUS & (STATUS_ERR | STATUS_DF) ) {
231 ret = -5;
232 if (perform_soft_reset())
233 break;
234 goto retry;
235 }
236
237 if (spinup) { 231 if (spinup) {
238 ata_spinup_time = current_tick - last_disk_activity; 232 ata_spinup_time = current_tick - last_disk_activity;
239 spinup = false; 233 spinup = false;
@@ -241,6 +235,9 @@ int ata_read_sectors(unsigned long start,
241 poweroff = false; 235 poweroff = false;
242 } 236 }
243 237
238 /* read the status register exactly once per loop */
239 status = ATA_STATUS;
240
244 /* if destination address is odd, use byte copying, 241 /* if destination address is odd, use byte copying,
245 otherwise use word copying */ 242 otherwise use word copying */
246 243
@@ -263,10 +260,18 @@ int ata_read_sectors(unsigned long start,
263 ((unsigned short*)buf)[j] = SWAB16(ATA_DATA); 260 ((unsigned short*)buf)[j] = SWAB16(ATA_DATA);
264 } 261 }
265 262
266#ifdef USE_INTERRUPT 263 /*
267 /* reading the status register clears the interrupt */ 264 "Device errors encountered during READ MULTIPLE commands are
268 j = ATA_STATUS; 265 posted at the beginning of the block or partial block transfer,
269#endif 266 but the DRQ bit is still set to one and the data transfer shall
267 take place, including transfer of corrupted data, if any."
268 -- ATA specification
269 */
270 if ( status & (STATUS_BSY | STATUS_ERR | STATUS_DF) ) {
271 ret = -5;
272 goto retry;
273 }
274
270 buf += sectors * SECTOR_SIZE; /* Advance one chunk of sectors */ 275 buf += sectors * SECTOR_SIZE; /* Advance one chunk of sectors */
271 count -= sectors; 276 count -= sectors;
272 277