diff options
author | Linus Nielsen Feltzing <linus@haxx.se> | 2002-08-02 06:01:22 +0000 |
---|---|---|
committer | Linus Nielsen Feltzing <linus@haxx.se> | 2002-08-02 06:01:22 +0000 |
commit | 513e8510ccf4a940e52f073d3fb0fd355cd071f6 (patch) | |
tree | c6b2e9cf343a5a28872c960154d7f1ae7efef396 /firmware | |
parent | 63e9bedfc4203d662766e30e3b209cd286f1d652 (diff) | |
download | rockbox-513e8510ccf4a940e52f073d3fb0fd355cd071f6.tar.gz rockbox-513e8510ccf4a940e52f073d3fb0fd355cd071f6.zip |
Cleaned up the sleep options a little
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@1514 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/ata.c | 75 |
1 files changed, 65 insertions, 10 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index 10efecc342..29d2851875 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c | |||
@@ -28,6 +28,16 @@ | |||
28 | #include "usb.h" | 28 | #include "usb.h" |
29 | #include "power.h" | 29 | #include "power.h" |
30 | 30 | ||
31 | /* Define one of USE_STANDBY, USE_SLEEP or USE_POWEROFF */ | ||
32 | #define USE_STANDBY | ||
33 | |||
34 | /* We can only use power off on the recorder */ | ||
35 | #if !defined(ARCHOS_RECORDER) && defined(USE_POWEROFF) | ||
36 | #undef USE_POWEROFF | ||
37 | #define USE_STANDBY | ||
38 | #endif | ||
39 | |||
40 | |||
31 | #define SECTOR_SIZE 512 | 41 | #define SECTOR_SIZE 512 |
32 | #define ATA_DATA (*((volatile unsigned short*)0x06104100)) | 42 | #define ATA_DATA (*((volatile unsigned short*)0x06104100)) |
33 | #define ATA_ERROR (*((volatile unsigned char*)0x06100101)) | 43 | #define ATA_ERROR (*((volatile unsigned char*)0x06100101)) |
@@ -80,6 +90,10 @@ static char ata_thread_name[] = "ata"; | |||
80 | static struct event_queue ata_queue; | 90 | static struct event_queue ata_queue; |
81 | static bool initialized = false; | 91 | static bool initialized = false; |
82 | 92 | ||
93 | #ifdef USE_POWEROFF | ||
94 | static int ata_power_on(void); | ||
95 | #endif | ||
96 | |||
83 | static int wait_for_bsy(void) __attribute__ ((section (".icode"))); | 97 | static int wait_for_bsy(void) __attribute__ ((section (".icode"))); |
84 | static int wait_for_bsy(void) | 98 | static int wait_for_bsy(void) |
85 | { | 99 | { |
@@ -131,12 +145,19 @@ int ata_read_sectors(unsigned long start, | |||
131 | int i; | 145 | int i; |
132 | int ret = 0; | 146 | int ret = 0; |
133 | 147 | ||
148 | #ifndef USE_STANDBY | ||
134 | if ( sleeping ) { | 149 | if ( sleeping ) { |
150 | #ifdef USE_POWEROFF | ||
151 | if (ata_power_on()) { | ||
152 | return -1; | ||
153 | } | ||
154 | #else | ||
135 | if (ata_soft_reset()) { | 155 | if (ata_soft_reset()) { |
136 | return -1; | 156 | return -1; |
137 | } | 157 | } |
158 | #endif | ||
138 | } | 159 | } |
139 | 160 | #endif | |
140 | mutex_lock(&ata_mtx); | 161 | mutex_lock(&ata_mtx); |
141 | sleep_timer = sleep_timeout; | 162 | sleep_timer = sleep_timeout; |
142 | 163 | ||
@@ -188,12 +209,17 @@ int ata_write_sectors(unsigned long start, | |||
188 | { | 209 | { |
189 | int i; | 210 | int i; |
190 | 211 | ||
191 | if ( sleeping ) { | 212 | #ifndef USE_STANDBY |
213 | #ifdef USE_POWEROFF | ||
214 | if (ata_power_on()) { | ||
215 | return -1; | ||
216 | } | ||
217 | #else | ||
192 | if (ata_soft_reset()) { | 218 | if (ata_soft_reset()) { |
193 | return -1; | 219 | return -1; |
194 | } | 220 | } |
195 | } | 221 | #endif |
196 | 222 | #endif | |
197 | mutex_lock(&ata_mtx); | 223 | mutex_lock(&ata_mtx); |
198 | sleep_timer = sleep_timeout; | 224 | sleep_timer = sleep_timeout; |
199 | 225 | ||
@@ -291,11 +317,15 @@ static int ata_perform_sleep(void) | |||
291 | return -1; | 317 | return -1; |
292 | } | 318 | } |
293 | 319 | ||
294 | #ifdef ATA_POWER_OFF | 320 | #ifdef USE_POWEROFF |
295 | ide_power_enable(false); | 321 | ide_power_enable(false); |
296 | #else | 322 | #else |
297 | ATA_SELECT = ata_device; | 323 | ATA_SELECT = ata_device; |
324 | #ifdef USE_SLEEP | ||
325 | ATA_COMMAND = CMD_SLEEP; | ||
326 | #else | ||
298 | ATA_COMMAND = CMD_STANDBY; | 327 | ATA_COMMAND = CMD_STANDBY; |
328 | #endif | ||
299 | 329 | ||
300 | if (!wait_for_rdy()) | 330 | if (!wait_for_rdy()) |
301 | ret = -1; | 331 | ret = -1; |
@@ -373,17 +403,13 @@ int ata_soft_reset(void) | |||
373 | 403 | ||
374 | mutex_lock(&ata_mtx); | 404 | mutex_lock(&ata_mtx); |
375 | 405 | ||
376 | #ifdef ATA_POWER_OFF | ||
377 | ide_power_enable(true); | ||
378 | sleep(HZ); | ||
379 | #else | ||
380 | ATA_SELECT = SELECT_LBA | ata_device; | 406 | ATA_SELECT = SELECT_LBA | ata_device; |
381 | ATA_CONTROL = CONTROL_nIEN|CONTROL_SRST; | 407 | ATA_CONTROL = CONTROL_nIEN|CONTROL_SRST; |
382 | sleep(HZ/20000); /* >= 5us */ | 408 | sleep(HZ/20000); /* >= 5us */ |
383 | 409 | ||
384 | ATA_CONTROL = CONTROL_nIEN; | 410 | ATA_CONTROL = CONTROL_nIEN; |
385 | sleep(HZ/400); /* >2ms */ | 411 | sleep(HZ/400); /* >2ms */ |
386 | #endif | 412 | |
387 | /* This little sucker can take up to 30 seconds */ | 413 | /* This little sucker can take up to 30 seconds */ |
388 | retry_count = 8; | 414 | retry_count = 8; |
389 | do | 415 | do |
@@ -399,6 +425,35 @@ int ata_soft_reset(void) | |||
399 | return ret; | 425 | return ret; |
400 | } | 426 | } |
401 | 427 | ||
428 | #ifdef USE_POWEROFF | ||
429 | static int ata_power_on(void) | ||
430 | { | ||
431 | int ret; | ||
432 | int retry_count; | ||
433 | |||
434 | mutex_lock(&ata_mtx); | ||
435 | |||
436 | ide_power_enable(true); | ||
437 | sleep(HZ/2); | ||
438 | |||
439 | ATA_CONTROL = CONTROL_nIEN; | ||
440 | |||
441 | /* This little sucker can take up to 30 seconds */ | ||
442 | retry_count = 8; | ||
443 | do | ||
444 | { | ||
445 | ret = wait_for_rdy(); | ||
446 | } while(!ret && retry_count--); | ||
447 | |||
448 | /* Massage the return code so it is 0 on success and -1 on failure */ | ||
449 | ret = ret?0:-1; | ||
450 | |||
451 | sleeping = false; | ||
452 | mutex_unlock(&ata_mtx); | ||
453 | return ret; | ||
454 | } | ||
455 | #endif | ||
456 | |||
402 | static int master_slave_detect(void) | 457 | static int master_slave_detect(void) |
403 | { | 458 | { |
404 | /* master? */ | 459 | /* master? */ |