summaryrefslogtreecommitdiff
path: root/firmware/drivers/ata.c
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-11-27 15:55:47 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-11-27 15:55:47 +0000
commit494d261de33a6058af6bb5ae6f2965381a127b68 (patch)
tree7d5432cef9510f8c381cb95c913906d6ce65211b /firmware/drivers/ata.c
parentcde27c3909f9a4f74c43f20ce252e43227cbed2e (diff)
Added disk poweroff 2s after spindown. (Only for recorders yet.)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2887 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/ata.c')
-rw-r--r--firmware/drivers/ata.c95
1 files changed, 48 insertions, 47 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 58349f69a6..8ca3b75adb 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -29,16 +29,6 @@
#include "power.h"
#include "string.h"
-/* Define one of USE_STANDBY, USE_SLEEP or USE_POWEROFF */
-#define USE_SLEEP
-
-/* We can only use power off on the recorder */
-#if !defined(ARCHOS_RECORDER) && defined(USE_POWEROFF)
-#undef USE_POWEROFF
-#define USE_SLEEP
-#endif
-
-
#define SECTOR_SIZE 512
#define ATA_DATA (*((volatile unsigned short*)0x06104100))
#define ATA_ERROR (*((volatile unsigned char*)0x06100101))
@@ -92,6 +82,10 @@ static volatile unsigned char* ata_control;
bool old_recorder = false;
static bool sleeping = false;
static int sleep_timeout = 5*HZ;
+static bool poweroff = false;
+#ifdef ARCHOS_RECORDER
+static int poweroff_timeout = 2*HZ;
+#endif
static char ata_stack[DEFAULT_STACK_SIZE];
static char ata_thread_name[] = "ata";
static struct event_queue ata_queue;
@@ -106,10 +100,7 @@ long last_disk_activity = -1;
static int multisectors; /* number of supported multisectors */
static unsigned short identify_info[SECTOR_SIZE];
-#ifdef USE_POWEROFF
static int ata_power_on(void);
-#endif
-
static int perform_soft_reset(void);
static int wait_for_bsy(void) __attribute__ ((section (".icode")));
@@ -177,21 +168,23 @@ int ata_read_sectors(unsigned long start,
mutex_lock(&ata_mtx);
+ led(true);
+
if ( sleeping ) {
-#ifdef USE_POWEROFF
- if (ata_power_on()) {
- mutex_unlock(&ata_mtx);
- return -1;
+ if (poweroff) {
+ if (ata_power_on()) {
+ mutex_unlock(&ata_mtx);
+ return -1;
+ }
}
-#else
-#ifdef USE_SLEEP
- if (perform_soft_reset()) {
- mutex_unlock(&ata_mtx);
- return -1;
+ else {
+ if (perform_soft_reset()) {
+ mutex_unlock(&ata_mtx);
+ return -1;
+ }
}
-#endif
-#endif
sleeping = false;
+ poweroff = false;
}
if (!wait_for_rdy())
@@ -200,8 +193,6 @@ int ata_read_sectors(unsigned long start,
return -2;
}
- led(true);
-
timeout = current_tick + READ_TIMEOUT;
retry:
@@ -298,20 +289,20 @@ int ata_write_sectors(unsigned long start,
mutex_lock(&ata_mtx);
if ( sleeping ) {
-#ifdef USE_POWEROFF
- if (ata_power_on()) {
- mutex_unlock(&ata_mtx);
- return -1;
+ if (poweroff) {
+ if (ata_power_on()) {
+ mutex_unlock(&ata_mtx);
+ return -1;
+ }
}
-#else
-#ifdef USE_SLEEP
- if (perform_soft_reset()) {
- mutex_unlock(&ata_mtx);
- return -1;
+ else {
+ if (perform_soft_reset()) {
+ mutex_unlock(&ata_mtx);
+ return -1;
+ }
}
-#endif
-#endif
sleeping = false;
+ poweroff = false;
}
if (!wait_for_rdy())
@@ -437,22 +428,15 @@ static int ata_perform_sleep(void)
return -1;
}
-#ifdef USE_POWEROFF
- ide_power_enable(false);
-#else
ATA_SELECT = ata_device;
-#ifdef USE_SLEEP
ATA_COMMAND = CMD_SLEEP;
-#else
- ATA_COMMAND = CMD_STANDBY_IMMEDIATE;
-#endif
if (!wait_for_rdy())
{
DEBUGF("ata_perform_sleep() - CMD failed\n");
ret = -2;
}
-#endif
+
sleeping = true;
mutex_unlock(&ata_mtx);
return ret;
@@ -471,6 +455,7 @@ void ata_spin(void)
static void ata_thread(void)
{
+ static long last_sleep = 0;
struct event ev;
while (1) {
@@ -481,12 +466,30 @@ static void ata_thread(void)
last_user_activity + sleep_timeout ) &&
TIME_AFTER( current_tick,
last_disk_activity + sleep_timeout ) )
+ {
ata_perform_sleep();
+ last_sleep = current_tick;
+ }
+
+#ifdef ARCHOS_RECORDER
+ if ( sleeping && poweroff_timeout && !poweroff &&
+ TIME_AFTER( current_tick, last_sleep + poweroff_timeout ))
+ {
+ mutex_lock(&ata_mtx);
+ ide_power_enable(false);
+ mutex_unlock(&ata_mtx);
+ poweroff = true;
+ }
+#endif
+
sleep(HZ/4);
}
queue_wait(&ata_queue, &ev);
switch ( ev.id ) {
case SYS_USB_CONNECTED:
+ if (poweroff)
+ ata_power_on();
+
/* Tell the USB thread that we are safe */
DEBUGF("ata_thread got SYS_USB_CONNECTED\n");
usb_acknowledge(SYS_USB_CONNECTED_ACK);
@@ -562,7 +565,6 @@ int ata_soft_reset(void)
return ret;
}
-#ifdef USE_POWEROFF
static int ata_power_on(void)
{
int ret;
@@ -586,7 +588,6 @@ static int ata_power_on(void)
sleeping = false;
return ret;
}
-#endif
static int master_slave_detect(void)
{