diff options
author | Björn Stenberg <bjorn@haxx.se> | 2002-11-27 15:55:47 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2002-11-27 15:55:47 +0000 |
commit | 494d261de33a6058af6bb5ae6f2965381a127b68 (patch) | |
tree | 7d5432cef9510f8c381cb95c913906d6ce65211b /firmware/drivers | |
parent | cde27c3909f9a4f74c43f20ce252e43227cbed2e (diff) | |
download | rockbox-494d261de33a6058af6bb5ae6f2965381a127b68.tar.gz rockbox-494d261de33a6058af6bb5ae6f2965381a127b68.zip |
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')
-rw-r--r-- | firmware/drivers/ata.c | 95 |
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 @@ | |||
29 | #include "power.h" | 29 | #include "power.h" |
30 | #include "string.h" | 30 | #include "string.h" |
31 | 31 | ||
32 | /* Define one of USE_STANDBY, USE_SLEEP or USE_POWEROFF */ | ||
33 | #define USE_SLEEP | ||
34 | |||
35 | /* We can only use power off on the recorder */ | ||
36 | #if !defined(ARCHOS_RECORDER) && defined(USE_POWEROFF) | ||
37 | #undef USE_POWEROFF | ||
38 | #define USE_SLEEP | ||
39 | #endif | ||
40 | |||
41 | |||
42 | #define SECTOR_SIZE 512 | 32 | #define SECTOR_SIZE 512 |
43 | #define ATA_DATA (*((volatile unsigned short*)0x06104100)) | 33 | #define ATA_DATA (*((volatile unsigned short*)0x06104100)) |
44 | #define ATA_ERROR (*((volatile unsigned char*)0x06100101)) | 34 | #define ATA_ERROR (*((volatile unsigned char*)0x06100101)) |
@@ -92,6 +82,10 @@ static volatile unsigned char* ata_control; | |||
92 | bool old_recorder = false; | 82 | bool old_recorder = false; |
93 | static bool sleeping = false; | 83 | static bool sleeping = false; |
94 | static int sleep_timeout = 5*HZ; | 84 | static int sleep_timeout = 5*HZ; |
85 | static bool poweroff = false; | ||
86 | #ifdef ARCHOS_RECORDER | ||
87 | static int poweroff_timeout = 2*HZ; | ||
88 | #endif | ||
95 | static char ata_stack[DEFAULT_STACK_SIZE]; | 89 | static char ata_stack[DEFAULT_STACK_SIZE]; |
96 | static char ata_thread_name[] = "ata"; | 90 | static char ata_thread_name[] = "ata"; |
97 | static struct event_queue ata_queue; | 91 | static struct event_queue ata_queue; |
@@ -106,10 +100,7 @@ long last_disk_activity = -1; | |||
106 | static int multisectors; /* number of supported multisectors */ | 100 | static int multisectors; /* number of supported multisectors */ |
107 | static unsigned short identify_info[SECTOR_SIZE]; | 101 | static unsigned short identify_info[SECTOR_SIZE]; |
108 | 102 | ||
109 | #ifdef USE_POWEROFF | ||
110 | static int ata_power_on(void); | 103 | static int ata_power_on(void); |
111 | #endif | ||
112 | |||
113 | static int perform_soft_reset(void); | 104 | static int perform_soft_reset(void); |
114 | 105 | ||
115 | static int wait_for_bsy(void) __attribute__ ((section (".icode"))); | 106 | static int wait_for_bsy(void) __attribute__ ((section (".icode"))); |
@@ -177,21 +168,23 @@ int ata_read_sectors(unsigned long start, | |||
177 | 168 | ||
178 | mutex_lock(&ata_mtx); | 169 | mutex_lock(&ata_mtx); |
179 | 170 | ||
171 | led(true); | ||
172 | |||
180 | if ( sleeping ) { | 173 | if ( sleeping ) { |
181 | #ifdef USE_POWEROFF | 174 | if (poweroff) { |
182 | if (ata_power_on()) { | 175 | if (ata_power_on()) { |
183 | mutex_unlock(&ata_mtx); | 176 | mutex_unlock(&ata_mtx); |
184 | return -1; | 177 | return -1; |
178 | } | ||
185 | } | 179 | } |
186 | #else | 180 | else { |
187 | #ifdef USE_SLEEP | 181 | if (perform_soft_reset()) { |
188 | if (perform_soft_reset()) { | 182 | mutex_unlock(&ata_mtx); |
189 | mutex_unlock(&ata_mtx); | 183 | return -1; |
190 | return -1; | 184 | } |
191 | } | 185 | } |
192 | #endif | ||
193 | #endif | ||
194 | sleeping = false; | 186 | sleeping = false; |
187 | poweroff = false; | ||
195 | } | 188 | } |
196 | 189 | ||
197 | if (!wait_for_rdy()) | 190 | if (!wait_for_rdy()) |
@@ -200,8 +193,6 @@ int ata_read_sectors(unsigned long start, | |||
200 | return -2; | 193 | return -2; |
201 | } | 194 | } |
202 | 195 | ||
203 | led(true); | ||
204 | |||
205 | timeout = current_tick + READ_TIMEOUT; | 196 | timeout = current_tick + READ_TIMEOUT; |
206 | 197 | ||
207 | retry: | 198 | retry: |
@@ -298,20 +289,20 @@ int ata_write_sectors(unsigned long start, | |||
298 | mutex_lock(&ata_mtx); | 289 | mutex_lock(&ata_mtx); |
299 | 290 | ||
300 | if ( sleeping ) { | 291 | if ( sleeping ) { |
301 | #ifdef USE_POWEROFF | 292 | if (poweroff) { |
302 | if (ata_power_on()) { | 293 | if (ata_power_on()) { |
303 | mutex_unlock(&ata_mtx); | 294 | mutex_unlock(&ata_mtx); |
304 | return -1; | 295 | return -1; |
296 | } | ||
305 | } | 297 | } |
306 | #else | 298 | else { |
307 | #ifdef USE_SLEEP | 299 | if (perform_soft_reset()) { |
308 | if (perform_soft_reset()) { | 300 | mutex_unlock(&ata_mtx); |
309 | mutex_unlock(&ata_mtx); | 301 | return -1; |
310 | return -1; | 302 | } |
311 | } | 303 | } |
312 | #endif | ||
313 | #endif | ||
314 | sleeping = false; | 304 | sleeping = false; |
305 | poweroff = false; | ||
315 | } | 306 | } |
316 | 307 | ||
317 | if (!wait_for_rdy()) | 308 | if (!wait_for_rdy()) |
@@ -437,22 +428,15 @@ static int ata_perform_sleep(void) | |||
437 | return -1; | 428 | return -1; |
438 | } | 429 | } |
439 | 430 | ||
440 | #ifdef USE_POWEROFF | ||
441 | ide_power_enable(false); | ||
442 | #else | ||
443 | ATA_SELECT = ata_device; | 431 | ATA_SELECT = ata_device; |
444 | #ifdef USE_SLEEP | ||
445 | ATA_COMMAND = CMD_SLEEP; | 432 | ATA_COMMAND = CMD_SLEEP; |
446 | #else | ||
447 | ATA_COMMAND = CMD_STANDBY_IMMEDIATE; | ||
448 | #endif | ||
449 | 433 | ||
450 | if (!wait_for_rdy()) | 434 | if (!wait_for_rdy()) |
451 | { | 435 | { |
452 | DEBUGF("ata_perform_sleep() - CMD failed\n"); | 436 | DEBUGF("ata_perform_sleep() - CMD failed\n"); |
453 | ret = -2; | 437 | ret = -2; |
454 | } | 438 | } |
455 | #endif | 439 | |
456 | sleeping = true; | 440 | sleeping = true; |
457 | mutex_unlock(&ata_mtx); | 441 | mutex_unlock(&ata_mtx); |
458 | return ret; | 442 | return ret; |
@@ -471,6 +455,7 @@ void ata_spin(void) | |||
471 | 455 | ||
472 | static void ata_thread(void) | 456 | static void ata_thread(void) |
473 | { | 457 | { |
458 | static long last_sleep = 0; | ||
474 | struct event ev; | 459 | struct event ev; |
475 | 460 | ||
476 | while (1) { | 461 | while (1) { |
@@ -481,12 +466,30 @@ static void ata_thread(void) | |||
481 | last_user_activity + sleep_timeout ) && | 466 | last_user_activity + sleep_timeout ) && |
482 | TIME_AFTER( current_tick, | 467 | TIME_AFTER( current_tick, |
483 | last_disk_activity + sleep_timeout ) ) | 468 | last_disk_activity + sleep_timeout ) ) |
469 | { | ||
484 | ata_perform_sleep(); | 470 | ata_perform_sleep(); |
471 | last_sleep = current_tick; | ||
472 | } | ||
473 | |||
474 | #ifdef ARCHOS_RECORDER | ||
475 | if ( sleeping && poweroff_timeout && !poweroff && | ||
476 | TIME_AFTER( current_tick, last_sleep + poweroff_timeout )) | ||
477 | { | ||
478 | mutex_lock(&ata_mtx); | ||
479 | ide_power_enable(false); | ||
480 | mutex_unlock(&ata_mtx); | ||
481 | poweroff = true; | ||
482 | } | ||
483 | #endif | ||
484 | |||
485 | sleep(HZ/4); | 485 | sleep(HZ/4); |
486 | } | 486 | } |
487 | queue_wait(&ata_queue, &ev); | 487 | queue_wait(&ata_queue, &ev); |
488 | switch ( ev.id ) { | 488 | switch ( ev.id ) { |
489 | case SYS_USB_CONNECTED: | 489 | case SYS_USB_CONNECTED: |
490 | if (poweroff) | ||
491 | ata_power_on(); | ||
492 | |||
490 | /* Tell the USB thread that we are safe */ | 493 | /* Tell the USB thread that we are safe */ |
491 | DEBUGF("ata_thread got SYS_USB_CONNECTED\n"); | 494 | DEBUGF("ata_thread got SYS_USB_CONNECTED\n"); |
492 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | 495 | usb_acknowledge(SYS_USB_CONNECTED_ACK); |
@@ -562,7 +565,6 @@ int ata_soft_reset(void) | |||
562 | return ret; | 565 | return ret; |
563 | } | 566 | } |
564 | 567 | ||
565 | #ifdef USE_POWEROFF | ||
566 | static int ata_power_on(void) | 568 | static int ata_power_on(void) |
567 | { | 569 | { |
568 | int ret; | 570 | int ret; |
@@ -586,7 +588,6 @@ static int ata_power_on(void) | |||
586 | sleeping = false; | 588 | sleeping = false; |
587 | return ret; | 589 | return ret; |
588 | } | 590 | } |
589 | #endif | ||
590 | 591 | ||
591 | static int master_slave_detect(void) | 592 | static int master_slave_detect(void) |
592 | { | 593 | { |