diff options
-rw-r--r-- | firmware/drivers/ata.c | 27 | ||||
-rw-r--r-- | firmware/drivers/ata.h | 3 |
2 files changed, 27 insertions, 3 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index 5af3efe793..e8fd4469cd 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c | |||
@@ -285,6 +285,9 @@ int ata_hard_reset(void) | |||
285 | 285 | ||
286 | ret = wait_for_rdy(); | 286 | ret = wait_for_rdy(); |
287 | 287 | ||
288 | /* Massage the return code so it is 0 on success and -1 on failure */ | ||
289 | ret = ret?0:-1; | ||
290 | |||
288 | mutex_unlock(&ata_mtx); | 291 | mutex_unlock(&ata_mtx); |
289 | return ret; | 292 | return ret; |
290 | } | 293 | } |
@@ -292,6 +295,7 @@ int ata_hard_reset(void) | |||
292 | int ata_soft_reset(void) | 295 | int ata_soft_reset(void) |
293 | { | 296 | { |
294 | int ret; | 297 | int ret; |
298 | int retry_count; | ||
295 | 299 | ||
296 | mutex_lock(&ata_mtx); | 300 | mutex_lock(&ata_mtx); |
297 | 301 | ||
@@ -302,8 +306,16 @@ int ata_soft_reset(void) | |||
302 | ATA_CONTROL = CONTROL_nIEN; | 306 | ATA_CONTROL = CONTROL_nIEN; |
303 | sleep(HZ/400); /* >2ms */ | 307 | sleep(HZ/400); /* >2ms */ |
304 | 308 | ||
305 | ret = wait_for_rdy(); | 309 | /* This little sucker can take up to 30 seconds */ |
310 | retry_count = 8; | ||
311 | do | ||
312 | { | ||
313 | ret = wait_for_rdy(); | ||
314 | } while(!ret && retry_count--); | ||
306 | 315 | ||
316 | /* Massage the return code so it is 0 on success and -1 on failure */ | ||
317 | ret = ret?0:-1; | ||
318 | |||
307 | mutex_unlock(&ata_mtx); | 319 | mutex_unlock(&ata_mtx); |
308 | return ret; | 320 | return ret; |
309 | } | 321 | } |
@@ -367,14 +379,23 @@ static int io_address_detect(void) | |||
367 | return 0; | 379 | return 0; |
368 | } | 380 | } |
369 | 381 | ||
382 | void ata_enable(bool on) | ||
383 | { | ||
384 | if(on) | ||
385 | PADR &= ~0x80; /* enable ATA */ | ||
386 | else | ||
387 | PADR |= 0x80; /* disable ATA */ | ||
388 | |||
389 | PAIOR |= 0x80; | ||
390 | } | ||
391 | |||
370 | int ata_init(void) | 392 | int ata_init(void) |
371 | { | 393 | { |
372 | mutex_init(&ata_mtx); | 394 | mutex_init(&ata_mtx); |
373 | 395 | ||
374 | led(false); | 396 | led(false); |
375 | 397 | ||
376 | PADR |= 0x800; /* disable USB */ | 398 | ata_enable(true); |
377 | PADR &= ~0x80; /* activate ATA */ | ||
378 | 399 | ||
379 | if (master_slave_detect()) | 400 | if (master_slave_detect()) |
380 | return -1; | 401 | return -1; |
diff --git a/firmware/drivers/ata.h b/firmware/drivers/ata.h index 38e45d9e45..fb25f711d7 100644 --- a/firmware/drivers/ata.h +++ b/firmware/drivers/ata.h | |||
@@ -19,6 +19,8 @@ | |||
19 | #ifndef __ATA_H__ | 19 | #ifndef __ATA_H__ |
20 | #define __ATA_H__ | 20 | #define __ATA_H__ |
21 | 21 | ||
22 | #include <stdbool.h> | ||
23 | |||
22 | /* | 24 | /* |
23 | ata_spindown() time values: | 25 | ata_spindown() time values: |
24 | -1 Immediate spindown | 26 | -1 Immediate spindown |
@@ -30,6 +32,7 @@ | |||
30 | 254 Reserved | 32 | 254 Reserved |
31 | 255 21 min 15 s | 33 | 255 21 min 15 s |
32 | */ | 34 | */ |
35 | extern void ata_enable(bool on); | ||
33 | extern int ata_spindown(int time); | 36 | extern int ata_spindown(int time); |
34 | extern int ata_hard_reset(void); | 37 | extern int ata_hard_reset(void); |
35 | extern int ata_soft_reset(void); | 38 | extern int ata_soft_reset(void); |