summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/drivers/ata.c27
-rw-r--r--firmware/drivers/ata.h3
2 files changed, 27 insertions, 3 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 5af3efe..e8fd446 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -285,6 +285,9 @@ int ata_hard_reset(void)
ret = wait_for_rdy();
+ /* Massage the return code so it is 0 on success and -1 on failure */
+ ret = ret?0:-1;
+
mutex_unlock(&ata_mtx);
return ret;
}
@@ -292,6 +295,7 @@ int ata_hard_reset(void)
int ata_soft_reset(void)
{
int ret;
+ int retry_count;
mutex_lock(&ata_mtx);
@@ -302,8 +306,16 @@ int ata_soft_reset(void)
ATA_CONTROL = CONTROL_nIEN;
sleep(HZ/400); /* >2ms */
- ret = wait_for_rdy();
+ /* This little sucker can take up to 30 seconds */
+ retry_count = 8;
+ do
+ {
+ ret = wait_for_rdy();
+ } while(!ret && retry_count--);
+ /* Massage the return code so it is 0 on success and -1 on failure */
+ ret = ret?0:-1;
+
mutex_unlock(&ata_mtx);
return ret;
}
@@ -367,14 +379,23 @@ static int io_address_detect(void)
return 0;
}
+void ata_enable(bool on)
+{
+ if(on)
+ PADR &= ~0x80; /* enable ATA */
+ else
+ PADR |= 0x80; /* disable ATA */
+
+ PAIOR |= 0x80;
+}
+
int ata_init(void)
{
mutex_init(&ata_mtx);
led(false);
- PADR |= 0x800; /* disable USB */
- PADR &= ~0x80; /* activate ATA */
+ ata_enable(true);
if (master_slave_detect())
return -1;
diff --git a/firmware/drivers/ata.h b/firmware/drivers/ata.h
index 38e45d9..fb25f71 100644
--- a/firmware/drivers/ata.h
+++ b/firmware/drivers/ata.h
@@ -19,6 +19,8 @@
#ifndef __ATA_H__
#define __ATA_H__
+#include <stdbool.h>
+
/*
ata_spindown() time values:
-1 Immediate spindown
@@ -30,6 +32,7 @@
254 Reserved
255 21 min 15 s
*/
+extern void ata_enable(bool on);
extern int ata_spindown(int time);
extern int ata_hard_reset(void);
extern int ata_soft_reset(void);