diff options
author | Jonathan Gordon <rockbox@jdgordon.info> | 2006-11-06 14:24:18 +0000 |
---|---|---|
committer | Jonathan Gordon <rockbox@jdgordon.info> | 2006-11-06 14:24:18 +0000 |
commit | 0b22795e26ee09de14f6ac23219adeda12f2fd5b (patch) | |
tree | c1ccbda32170de48111a4b75e1f723ba953096bf /firmware | |
parent | e543901777843a1734474aba7aa5d96cf61708ab (diff) | |
download | rockbox-0b22795e26ee09de14f6ac23219adeda12f2fd5b.tar.gz rockbox-0b22795e26ee09de14f6ac23219adeda12f2fd5b.zip |
adds ata_idle_notify system which allows callbacks in apps/ to be called
when the hard disk is idle but spinning, and just before shutting down.
on SWCODEC targets with > 8MB RAM the playback engine will try to
refill the buffer if it is less than 75% full while the disk is spinning
(temporarily disabled on the nano)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11451 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/SOURCES | 1 | ||||
-rw-r--r-- | firmware/ata_idle_notify.c | 96 | ||||
-rw-r--r-- | firmware/drivers/ata.c | 15 | ||||
-rw-r--r-- | firmware/export/ata_idle_notify.h | 41 |
4 files changed, 150 insertions, 3 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index e9ce8f909b..1ec3c82616 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -95,6 +95,7 @@ drivers/lcd-h300.c | |||
95 | drivers/power.c | 95 | drivers/power.c |
96 | #endif | 96 | #endif |
97 | drivers/led.c | 97 | drivers/led.c |
98 | ata_idle_notify.c | ||
98 | #ifndef SIMULATOR | 99 | #ifndef SIMULATOR |
99 | #ifndef TARGET_TREE | 100 | #ifndef TARGET_TREE |
100 | drivers/adc.c | 101 | drivers/adc.c |
diff --git a/firmware/ata_idle_notify.c b/firmware/ata_idle_notify.c new file mode 100644 index 0000000000..a0a56e958b --- /dev/null +++ b/firmware/ata_idle_notify.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 Jonathan Gordon | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include <stdbool.h> | ||
20 | #include "system.h" | ||
21 | #include "ata_idle_notify.h" | ||
22 | #include "logf.h" | ||
23 | |||
24 | #if USING_ATA_CALLBACK | ||
25 | static ata_idle_notify ata_idle_notify_funcs[MAX_ATA_CALLBACKS]; | ||
26 | static int ata_callback_count = 0; | ||
27 | #endif | ||
28 | |||
29 | bool register_ata_idle_func(ata_idle_notify function) | ||
30 | { | ||
31 | #if USING_ATA_CALLBACK | ||
32 | int i; | ||
33 | for (i=0; i<MAX_ATA_CALLBACKS; i++) | ||
34 | { | ||
35 | if (ata_idle_notify_funcs[i] == NULL) | ||
36 | { | ||
37 | ata_idle_notify_funcs[i] = function; | ||
38 | ata_callback_count++; | ||
39 | return true; | ||
40 | } | ||
41 | else if (ata_idle_notify_funcs[i] == function) | ||
42 | return true; | ||
43 | } | ||
44 | return false; | ||
45 | #else | ||
46 | function(); /* just call the function now */ | ||
47 | /* this _may_ cause problems later if the calling function | ||
48 | sets a variable expecting the callback to unset it, because | ||
49 | the callback will be run before this function exits, so before the var is set */ | ||
50 | return true; | ||
51 | #endif | ||
52 | } | ||
53 | |||
54 | #if USING_ATA_CALLBACK | ||
55 | void unregister_ata_idle_func(ata_idle_notify func) | ||
56 | { | ||
57 | int i; | ||
58 | for (i=0; i<MAX_ATA_CALLBACKS; i++) | ||
59 | { | ||
60 | if (ata_idle_notify_funcs[i] == func) | ||
61 | { | ||
62 | ata_idle_notify_funcs[i] = NULL; | ||
63 | ata_callback_count--; | ||
64 | } | ||
65 | } | ||
66 | return; | ||
67 | } | ||
68 | |||
69 | bool call_ata_idle_notifys(void) | ||
70 | { | ||
71 | int i; | ||
72 | ata_idle_notify function; | ||
73 | if (ata_callback_count == 0) | ||
74 | return false; | ||
75 | ata_callback_count = 0; /* so we dont re-enter every time the callbacks read/write */ | ||
76 | for (i = 0; i < MAX_ATA_CALLBACKS; i++) | ||
77 | { | ||
78 | if (ata_idle_notify_funcs[i]) | ||
79 | { | ||
80 | function = ata_idle_notify_funcs[i]; | ||
81 | ata_idle_notify_funcs[i] = NULL; | ||
82 | function(); | ||
83 | } | ||
84 | } | ||
85 | return true; | ||
86 | } | ||
87 | |||
88 | void ata_idle_notify_init(void) | ||
89 | { | ||
90 | int i; | ||
91 | for (i=0; i<MAX_ATA_CALLBACKS; i++) | ||
92 | { | ||
93 | ata_idle_notify_funcs[i] = NULL; | ||
94 | } | ||
95 | } | ||
96 | #endif | ||
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index 00ef0e8eb5..249cb3934e 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include "power.h" | 29 | #include "power.h" |
30 | #include "string.h" | 30 | #include "string.h" |
31 | #include "hwcompat.h" | 31 | #include "hwcompat.h" |
32 | 32 | #include "ata_idle_notify.h" | |
33 | #ifdef TARGET_TREE | 33 | #ifdef TARGET_TREE |
34 | #include "ata-target.h" | 34 | #include "ata-target.h" |
35 | #endif | 35 | #endif |
@@ -1364,6 +1364,7 @@ static void ata_thread(void) | |||
1364 | { | 1364 | { |
1365 | static long last_sleep = 0; | 1365 | static long last_sleep = 0; |
1366 | struct event ev; | 1366 | struct event ev; |
1367 | static long last_callback_run = 0; | ||
1367 | 1368 | ||
1368 | while (1) { | 1369 | while (1) { |
1369 | while ( queue_empty( &ata_queue ) ) { | 1370 | while ( queue_empty( &ata_queue ) ) { |
@@ -1373,8 +1374,16 @@ static void ata_thread(void) | |||
1373 | TIME_AFTER( current_tick, | 1374 | TIME_AFTER( current_tick, |
1374 | last_disk_activity + sleep_timeout ) ) | 1375 | last_disk_activity + sleep_timeout ) ) |
1375 | { | 1376 | { |
1376 | ata_perform_sleep(); | 1377 | if (!call_ata_idle_notifys()) |
1377 | last_sleep = current_tick; | 1378 | { |
1379 | ata_perform_sleep(); | ||
1380 | last_sleep = current_tick; | ||
1381 | } | ||
1382 | } | ||
1383 | else if (TIME_AFTER(current_tick, last_callback_run+(HZ*5))) | ||
1384 | { | ||
1385 | last_callback_run = current_tick; | ||
1386 | call_ata_idle_notifys(); | ||
1378 | } | 1387 | } |
1379 | 1388 | ||
1380 | #ifdef HAVE_ATA_POWER_OFF | 1389 | #ifdef HAVE_ATA_POWER_OFF |
diff --git a/firmware/export/ata_idle_notify.h b/firmware/export/ata_idle_notify.h new file mode 100644 index 0000000000..f5f2a25fd9 --- /dev/null +++ b/firmware/export/ata_idle_notify.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 Jonathan Gordon | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef __ATACALLBACK_H__ | ||
20 | #define __ATACALLBACK_H__ | ||
21 | |||
22 | #include <stdbool.h> | ||
23 | #define USING_ATA_CALLBACK !defined(SIMULATOR) \ | ||
24 | && !defined(HAVE_FLASH_DISK) \ | ||
25 | && !defined(HAVE_MMC) | ||
26 | |||
27 | #define MAX_ATA_CALLBACKS 5 | ||
28 | typedef bool (*ata_idle_notify)(void); | ||
29 | |||
30 | extern bool register_ata_idle_func(ata_idle_notify function); | ||
31 | #if USING_ATA_CALLBACK | ||
32 | extern void ata_idle_notify_init(void); | ||
33 | extern void unregister_ata_idle_func(ata_idle_notify function); | ||
34 | extern bool call_ata_idle_notifys(void); | ||
35 | #else | ||
36 | #define unregister_ata_idle_func(f) | ||
37 | #define call_ata_idle_notifys() | ||
38 | #define ata_idle_notify_init() | ||
39 | #endif | ||
40 | |||
41 | #endif /* __ATACALLBACK_H__ */ | ||