diff options
Diffstat (limited to 'firmware/drivers/ata.c')
-rw-r--r-- | firmware/drivers/ata.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index 935b91271e..5e6df91cc5 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c | |||
@@ -110,6 +110,7 @@ static int wait_for_bsy(void) __attribute__ ((section (".icode"))); | |||
110 | static int wait_for_bsy(void) | 110 | static int wait_for_bsy(void) |
111 | { | 111 | { |
112 | int timeout = current_tick + HZ*10; | 112 | int timeout = current_tick + HZ*10; |
113 | last_disk_activity = timeout; | ||
113 | while (TIME_BEFORE(current_tick, timeout) && (ATA_ALT_STATUS & STATUS_BSY)) | 114 | while (TIME_BEFORE(current_tick, timeout) && (ATA_ALT_STATUS & STATUS_BSY)) |
114 | sleep_thread(); | 115 | sleep_thread(); |
115 | wake_up_thread(); | 116 | wake_up_thread(); |
@@ -129,7 +130,8 @@ static int wait_for_rdy(void) | |||
129 | return 0; | 130 | return 0; |
130 | 131 | ||
131 | timeout = current_tick + HZ*10; | 132 | timeout = current_tick + HZ*10; |
132 | 133 | last_disk_activity = timeout; | |
134 | |||
133 | while (TIME_BEFORE(current_tick, timeout) && | 135 | while (TIME_BEFORE(current_tick, timeout) && |
134 | !(ATA_ALT_STATUS & STATUS_RDY)) | 136 | !(ATA_ALT_STATUS & STATUS_RDY)) |
135 | sleep_thread(); | 137 | sleep_thread(); |
@@ -180,12 +182,14 @@ int ata_read_sectors(unsigned long start, | |||
180 | if (poweroff) { | 182 | if (poweroff) { |
181 | if (ata_power_on()) { | 183 | if (ata_power_on()) { |
182 | mutex_unlock(&ata_mtx); | 184 | mutex_unlock(&ata_mtx); |
185 | led(false); | ||
183 | return -1; | 186 | return -1; |
184 | } | 187 | } |
185 | } | 188 | } |
186 | else { | 189 | else { |
187 | if (perform_soft_reset()) { | 190 | if (perform_soft_reset()) { |
188 | mutex_unlock(&ata_mtx); | 191 | mutex_unlock(&ata_mtx); |
192 | led(false); | ||
189 | return -1; | 193 | return -1; |
190 | } | 194 | } |
191 | } | 195 | } |
@@ -198,6 +202,7 @@ int ata_read_sectors(unsigned long start, | |||
198 | if (!wait_for_rdy()) | 202 | if (!wait_for_rdy()) |
199 | { | 203 | { |
200 | mutex_unlock(&ata_mtx); | 204 | mutex_unlock(&ata_mtx); |
205 | led(false); | ||
201 | return -2; | 206 | return -2; |
202 | } | 207 | } |
203 | 208 | ||
@@ -218,6 +223,13 @@ int ata_read_sectors(unsigned long start, | |||
218 | ATA_SELECT = ((start >> 24) & 0xf) | SELECT_LBA | ata_device; | 223 | ATA_SELECT = ((start >> 24) & 0xf) | SELECT_LBA | ata_device; |
219 | ATA_COMMAND = CMD_READ_MULTIPLE; | 224 | ATA_COMMAND = CMD_READ_MULTIPLE; |
220 | 225 | ||
226 | /* wait at least 400ns between writing command and reading status */ | ||
227 | asm volatile ("nop"); | ||
228 | asm volatile ("nop"); | ||
229 | asm volatile ("nop"); | ||
230 | asm volatile ("nop"); | ||
231 | asm volatile ("nop"); | ||
232 | |||
221 | while (count) { | 233 | while (count) { |
222 | int j; | 234 | int j; |
223 | int sectors; | 235 | int sectors; |
@@ -226,8 +238,6 @@ int ata_read_sectors(unsigned long start, | |||
226 | 238 | ||
227 | if (!wait_for_start_of_transfer()) { | 239 | if (!wait_for_start_of_transfer()) { |
228 | ret = -4; | 240 | ret = -4; |
229 | if(ata_hard_reset()) | ||
230 | break; | ||
231 | goto retry; | 241 | goto retry; |
232 | } | 242 | } |
233 | 243 | ||
@@ -312,17 +322,21 @@ int ata_write_sectors(unsigned long start, | |||
312 | 322 | ||
313 | last_disk_activity = current_tick; | 323 | last_disk_activity = current_tick; |
314 | 324 | ||
325 | led(true); | ||
326 | |||
315 | if ( sleeping ) { | 327 | if ( sleeping ) { |
316 | spinup = true; | 328 | spinup = true; |
317 | if (poweroff) { | 329 | if (poweroff) { |
318 | if (ata_power_on()) { | 330 | if (ata_power_on()) { |
319 | mutex_unlock(&ata_mtx); | 331 | mutex_unlock(&ata_mtx); |
332 | led(false); | ||
320 | return -1; | 333 | return -1; |
321 | } | 334 | } |
322 | } | 335 | } |
323 | else { | 336 | else { |
324 | if (perform_soft_reset()) { | 337 | if (perform_soft_reset()) { |
325 | mutex_unlock(&ata_mtx); | 338 | mutex_unlock(&ata_mtx); |
339 | led(false); | ||
326 | return -1; | 340 | return -1; |
327 | } | 341 | } |
328 | } | 342 | } |
@@ -332,11 +346,10 @@ int ata_write_sectors(unsigned long start, | |||
332 | if (!wait_for_rdy()) | 346 | if (!wait_for_rdy()) |
333 | { | 347 | { |
334 | mutex_unlock(&ata_mtx); | 348 | mutex_unlock(&ata_mtx); |
349 | led(false); | ||
335 | return -2; | 350 | return -2; |
336 | } | 351 | } |
337 | 352 | ||
338 | led(true); | ||
339 | |||
340 | if ( count == 256 ) | 353 | if ( count == 256 ) |
341 | ATA_NSECTOR = 0; /* 0 means 256 sectors */ | 354 | ATA_NSECTOR = 0; /* 0 means 256 sectors */ |
342 | else | 355 | else |