diff options
-rw-r--r-- | apps/debug_menu.c | 18 | ||||
-rw-r--r-- | apps/main.c | 46 | ||||
-rw-r--r-- | apps/misc.c | 25 | ||||
-rw-r--r-- | apps/tagcache.c | 109 | ||||
-rw-r--r-- | apps/tagcache.h | 2 | ||||
-rw-r--r-- | apps/tree.c | 9 | ||||
-rw-r--r-- | firmware/SOURCES | 4 | ||||
-rw-r--r-- | firmware/common/crc32.c | 4 | ||||
-rw-r--r-- | firmware/common/dircache.c | 32 | ||||
-rw-r--r-- | firmware/drivers/eeprom_24cxx.c | 6 | ||||
-rw-r--r-- | firmware/eeprom_settings.c | 116 | ||||
-rw-r--r-- | firmware/export/config-h100.h | 6 | ||||
-rw-r--r-- | firmware/export/config-h120.h | 10 | ||||
-rw-r--r-- | firmware/export/eeprom_settings.h | 48 | ||||
-rw-r--r-- | firmware/export/system.h | 8 | ||||
-rw-r--r-- | firmware/include/crc32.h | 2 | ||||
-rw-r--r-- | firmware/powermgmt.c | 4 | ||||
-rw-r--r-- | firmware/system.c | 21 |
18 files changed, 422 insertions, 48 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 724bab90ab..ce3140be63 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c | |||
@@ -53,6 +53,8 @@ | |||
53 | #include "tagcache.h" | 53 | #include "tagcache.h" |
54 | #include "lcd-remote.h" | 54 | #include "lcd-remote.h" |
55 | #include "crc32.h" | 55 | #include "crc32.h" |
56 | #include "eeprom_24cxx.h" | ||
57 | #include "logf.h" | ||
56 | 58 | ||
57 | #ifdef HAVE_LCD_BITMAP | 59 | #ifdef HAVE_LCD_BITMAP |
58 | #include "widgets.h" | 60 | #include "widgets.h" |
@@ -1952,6 +1954,22 @@ bool dbg_save_roms(void) | |||
1952 | close(fd); | 1954 | close(fd); |
1953 | } | 1955 | } |
1954 | system_memory_guard(oldmode); | 1956 | system_memory_guard(oldmode); |
1957 | |||
1958 | #ifdef HAVE_EEPROM | ||
1959 | fd = creat("/internal_eeprom.bin", O_WRONLY); | ||
1960 | if (fd >= 0) | ||
1961 | { | ||
1962 | char buf[EEPROM_SIZE]; | ||
1963 | |||
1964 | if (!eeprom_24cxx_read(0, buf, sizeof buf)) | ||
1965 | gui_syncsplash(HZ*3, true, "Eeprom read failure!"); | ||
1966 | else | ||
1967 | write(fd, buf, sizeof buf); | ||
1968 | |||
1969 | close(fd); | ||
1970 | } | ||
1971 | #endif | ||
1972 | |||
1955 | return false; | 1973 | return false; |
1956 | } | 1974 | } |
1957 | #endif /* CPU */ | 1975 | #endif /* CPU */ |
diff --git a/apps/main.c b/apps/main.c index b725d0252f..907e1126cf 100644 --- a/apps/main.c +++ b/apps/main.c | |||
@@ -65,6 +65,7 @@ | |||
65 | #include "lang.h" | 65 | #include "lang.h" |
66 | #include "string.h" | 66 | #include "string.h" |
67 | #include "splash.h" | 67 | #include "splash.h" |
68 | #include "eeprom_settings.h" | ||
68 | 69 | ||
69 | #if (CONFIG_CODEC == SWCODEC) | 70 | #if (CONFIG_CODEC == SWCODEC) |
70 | #include "playback.h" | 71 | #include "playback.h" |
@@ -108,35 +109,30 @@ void app_main(void) | |||
108 | browse_root(); | 109 | browse_root(); |
109 | } | 110 | } |
110 | 111 | ||
111 | #ifdef HAVE_DIRCACHE | 112 | int init_dircache(void) |
112 | void init_dircache(void) | ||
113 | { | 113 | { |
114 | int result; | 114 | #ifdef HAVE_DIRCACHE |
115 | bool clear = false; | 115 | int result = 0; |
116 | 116 | ||
117 | dircache_init(); | 117 | dircache_init(); |
118 | if (global_settings.dircache) | 118 | if (global_settings.dircache) |
119 | { | 119 | { |
120 | if (global_settings.dircache_size == 0) | 120 | # ifdef HAVE_EEPROM |
121 | if (firmware_settings.initialized && firmware_settings.disk_clean) | ||
121 | { | 122 | { |
122 | gui_syncsplash(0, true, str(LANG_DIRCACHE_BUILDING)); | 123 | if (dircache_load(DIRCACHE_FILE) == 0) |
123 | clear = true; | 124 | return 0; |
124 | } | 125 | } |
126 | # endif | ||
125 | 127 | ||
126 | result = dircache_build(global_settings.dircache_size); | 128 | result = dircache_build(global_settings.dircache_size); |
127 | if (result < 0) | ||
128 | gui_syncsplash(0, true, "Failed! Result: %d", result); | ||
129 | |||
130 | if (clear) | ||
131 | { | ||
132 | backlight_on(); | ||
133 | show_logo(); | ||
134 | } | ||
135 | } | 129 | } |
136 | } | 130 | |
131 | return result; | ||
137 | #else | 132 | #else |
138 | # define init_dircache(...) | 133 | return 0; |
139 | #endif | 134 | #endif |
135 | } | ||
140 | 136 | ||
141 | void init_tagcache(void) | 137 | void init_tagcache(void) |
142 | { | 138 | { |
@@ -376,6 +372,10 @@ void init(void) | |||
376 | } | 372 | } |
377 | } | 373 | } |
378 | 374 | ||
375 | #ifdef HAVE_EEPROM | ||
376 | eeprom_settings_init(); | ||
377 | #endif | ||
378 | |||
379 | settings_calc_config_sector(); | 379 | settings_calc_config_sector(); |
380 | 380 | ||
381 | #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) | 381 | #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) |
@@ -395,11 +395,21 @@ void init(void) | |||
395 | settings_load(SETTINGS_ALL); | 395 | settings_load(SETTINGS_ALL); |
396 | 396 | ||
397 | 397 | ||
398 | init_dircache(); | ||
399 | |||
398 | gui_sync_wps_init(); | 400 | gui_sync_wps_init(); |
399 | settings_apply(); | 401 | settings_apply(); |
400 | init_dircache(); | 402 | //init_dircache(); |
401 | init_tagcache(); | 403 | init_tagcache(); |
402 | 404 | ||
405 | #ifdef HAVE_EEPROM | ||
406 | if (firmware_settings.initialized) | ||
407 | { | ||
408 | /* In case we crash. */ | ||
409 | firmware_settings.disk_clean = false; | ||
410 | eeprom_settings_store(); | ||
411 | } | ||
412 | #endif | ||
403 | status_init(); | 413 | status_init(); |
404 | playlist_init(); | 414 | playlist_init(); |
405 | tree_init(); | 415 | tree_init(); |
diff --git a/apps/misc.c b/apps/misc.c index ff05819a4d..b0c315af98 100644 --- a/apps/misc.c +++ b/apps/misc.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include "ata_mmc.h" | 49 | #include "ata_mmc.h" |
50 | #endif | 50 | #endif |
51 | #include "tree.h" | 51 | #include "tree.h" |
52 | #include "eeprom_settings.h" | ||
52 | 53 | ||
53 | #ifdef HAVE_LCD_BITMAP | 54 | #ifdef HAVE_LCD_BITMAP |
54 | #include "bmp.h" | 55 | #include "bmp.h" |
@@ -484,13 +485,6 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter) | |||
484 | #else | 485 | #else |
485 | int i; | 486 | int i; |
486 | 487 | ||
487 | if (tagcache_get_commit_step() > 0) | ||
488 | { | ||
489 | cancel_shutdown(); | ||
490 | gui_syncsplash(HZ, true, str(LANG_TAGCACHE_BUSY)); | ||
491 | return false; | ||
492 | } | ||
493 | |||
494 | #if defined(CONFIG_CHARGING) && !defined(HAVE_POWEROFF_WHILE_CHARGING) | 488 | #if defined(CONFIG_CHARGING) && !defined(HAVE_POWEROFF_WHILE_CHARGING) |
495 | if(!charger_inserted()) | 489 | if(!charger_inserted()) |
496 | #endif | 490 | #endif |
@@ -498,11 +492,26 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter) | |||
498 | FOR_NB_SCREENS(i) | 492 | FOR_NB_SCREENS(i) |
499 | screens[i].clear_display(); | 493 | screens[i].clear_display(); |
500 | gui_syncsplash(0, true, str(LANG_SHUTTINGDOWN)); | 494 | gui_syncsplash(0, true, str(LANG_SHUTTINGDOWN)); |
495 | |||
496 | if (!tagcache_prepare_shutdown()) | ||
497 | { | ||
498 | cancel_shutdown(); | ||
499 | gui_syncsplash(HZ, true, str(LANG_TAGCACHE_BUSY)); | ||
500 | return false; | ||
501 | } | ||
502 | |||
501 | if (callback != NULL) | 503 | if (callback != NULL) |
502 | callback(parameter); | 504 | callback(parameter); |
503 | 505 | ||
504 | system_flush(); | 506 | system_flush(); |
505 | 507 | #ifdef HAVE_EEPROM | |
508 | if (firmware_settings.initialized) | ||
509 | { | ||
510 | firmware_settings.disk_clean = true; | ||
511 | firmware_settings.bl_version = 0; | ||
512 | eeprom_settings_store(); | ||
513 | } | ||
514 | #endif | ||
506 | shutdown_hw(); | 515 | shutdown_hw(); |
507 | } | 516 | } |
508 | #endif | 517 | #endif |
diff --git a/apps/tagcache.c b/apps/tagcache.c index 1485ed8e51..4812198167 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c | |||
@@ -70,6 +70,7 @@ | |||
70 | #include "buffer.h" | 70 | #include "buffer.h" |
71 | #include "atoi.h" | 71 | #include "atoi.h" |
72 | #include "crc32.h" | 72 | #include "crc32.h" |
73 | #include "eeprom_settings.h" | ||
73 | 74 | ||
74 | /* Tag Cache thread. */ | 75 | /* Tag Cache thread. */ |
75 | static struct event_queue tagcache_queue; | 76 | static struct event_queue tagcache_queue; |
@@ -152,6 +153,13 @@ struct ramcache_header { | |||
152 | int entry_count[TAG_COUNT]; /* Number of entries in the indices. */ | 153 | int entry_count[TAG_COUNT]; /* Number of entries in the indices. */ |
153 | }; | 154 | }; |
154 | 155 | ||
156 | # ifdef HAVE_EEPROM | ||
157 | struct statefile_header { | ||
158 | struct ramcache_header *hdr; | ||
159 | struct tagcache_stat stat; | ||
160 | }; | ||
161 | # endif | ||
162 | |||
155 | /* Pointer to allocated ramcache_header */ | 163 | /* Pointer to allocated ramcache_header */ |
156 | static struct ramcache_header *hdr; | 164 | static struct ramcache_header *hdr; |
157 | #endif | 165 | #endif |
@@ -2795,6 +2803,85 @@ static bool allocate_tagcache(void) | |||
2795 | return true; | 2803 | return true; |
2796 | } | 2804 | } |
2797 | 2805 | ||
2806 | # ifdef HAVE_EEPROM | ||
2807 | static bool tagcache_dumpload(void) | ||
2808 | { | ||
2809 | struct statefile_header shdr; | ||
2810 | int fd, rc; | ||
2811 | long offpos; | ||
2812 | int i; | ||
2813 | |||
2814 | fd = open(TAGCACHE_STATEFILE, O_RDONLY); | ||
2815 | if (fd < 0) | ||
2816 | { | ||
2817 | logf("no tagcache statedump"); | ||
2818 | return false; | ||
2819 | } | ||
2820 | |||
2821 | /* Check the statefile memory placement */ | ||
2822 | hdr = buffer_alloc(0); | ||
2823 | rc = read(fd, &shdr, sizeof(struct statefile_header)); | ||
2824 | if (rc != sizeof(struct statefile_header) | ||
2825 | /* || (long)hdr != (long)shdr.hdr */) | ||
2826 | { | ||
2827 | logf("incorrect statefile"); | ||
2828 | hdr = NULL; | ||
2829 | close(fd); | ||
2830 | return false; | ||
2831 | } | ||
2832 | |||
2833 | offpos = (long)hdr - (long)shdr.hdr; | ||
2834 | |||
2835 | /* Lets allocate real memory and load it */ | ||
2836 | hdr = buffer_alloc(shdr.stat.ramcache_allocated); | ||
2837 | rc = read(fd, hdr, shdr.stat.ramcache_allocated); | ||
2838 | close(fd); | ||
2839 | |||
2840 | if (rc != shdr.stat.ramcache_allocated) | ||
2841 | { | ||
2842 | logf("read failure!"); | ||
2843 | hdr = NULL; | ||
2844 | return false; | ||
2845 | } | ||
2846 | |||
2847 | memcpy(&stat, &shdr.stat, sizeof(struct tagcache_stat)); | ||
2848 | |||
2849 | /* Now fix the pointers */ | ||
2850 | hdr->indices = (struct index_entry *)((long)hdr->indices + offpos); | ||
2851 | for (i = 0; i < TAG_COUNT; i++) | ||
2852 | hdr->tags[i] += offpos; | ||
2853 | |||
2854 | return true; | ||
2855 | } | ||
2856 | |||
2857 | static bool tagcache_dumpsave(void) | ||
2858 | { | ||
2859 | struct statefile_header shdr; | ||
2860 | int fd; | ||
2861 | |||
2862 | if (!stat.ramcache) | ||
2863 | return false; | ||
2864 | |||
2865 | fd = open(TAGCACHE_STATEFILE, O_WRONLY | O_CREAT | O_TRUNC); | ||
2866 | if (fd < 0) | ||
2867 | { | ||
2868 | logf("failed to create a statedump"); | ||
2869 | return false; | ||
2870 | } | ||
2871 | |||
2872 | /* Create the header */ | ||
2873 | shdr.hdr = hdr; | ||
2874 | memcpy(&shdr.stat, &stat, sizeof(struct tagcache_stat)); | ||
2875 | write(fd, &shdr, sizeof(struct statefile_header)); | ||
2876 | |||
2877 | /* And dump the data too */ | ||
2878 | write(fd, hdr, stat.ramcache_allocated); | ||
2879 | close(fd); | ||
2880 | |||
2881 | return true; | ||
2882 | } | ||
2883 | # endif | ||
2884 | |||
2798 | static bool load_tagcache(void) | 2885 | static bool load_tagcache(void) |
2799 | { | 2886 | { |
2800 | struct tagcache_header *tch; | 2887 | struct tagcache_header *tch; |
@@ -3250,8 +3337,15 @@ static void tagcache_thread(void) | |||
3250 | free_tempbuf(); | 3337 | free_tempbuf(); |
3251 | 3338 | ||
3252 | #ifdef HAVE_TC_RAMCACHE | 3339 | #ifdef HAVE_TC_RAMCACHE |
3340 | # ifdef HAVE_EEPROM | ||
3341 | if (firmware_settings.initialized && firmware_settings.disk_clean) | ||
3342 | check_done = tagcache_dumpload(); | ||
3343 | |||
3344 | remove(TAGCACHE_STATEFILE); | ||
3345 | # endif | ||
3346 | |||
3253 | /* Allocate space for the tagcache if found on disk. */ | 3347 | /* Allocate space for the tagcache if found on disk. */ |
3254 | if (global_settings.tagcache_ram) | 3348 | if (global_settings.tagcache_ram && !stat.ramcache) |
3255 | allocate_tagcache(); | 3349 | allocate_tagcache(); |
3256 | #endif | 3350 | #endif |
3257 | 3351 | ||
@@ -3330,6 +3424,19 @@ static void tagcache_thread(void) | |||
3330 | } | 3424 | } |
3331 | } | 3425 | } |
3332 | 3426 | ||
3427 | bool tagcache_prepare_shutdown(void) | ||
3428 | { | ||
3429 | if (tagcache_get_commit_step() > 0) | ||
3430 | return false; | ||
3431 | |||
3432 | #ifdef HAVE_EEPROM | ||
3433 | if (stat.ramcache) | ||
3434 | tagcache_dumpsave(); | ||
3435 | #endif | ||
3436 | |||
3437 | return true; | ||
3438 | } | ||
3439 | |||
3333 | static int get_progress(void) | 3440 | static int get_progress(void) |
3334 | { | 3441 | { |
3335 | int total_count = -1; | 3442 | int total_count = -1; |
diff --git a/apps/tagcache.h b/apps/tagcache.h index 450c21c26e..d5ce772904 100644 --- a/apps/tagcache.h +++ b/apps/tagcache.h | |||
@@ -64,6 +64,7 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title, | |||
64 | #define TAGCACHE_FILE_MASTER ROCKBOX_DIR "/tagcache_idx.tcd" | 64 | #define TAGCACHE_FILE_MASTER ROCKBOX_DIR "/tagcache_idx.tcd" |
65 | #define TAGCACHE_FILE_INDEX ROCKBOX_DIR "/tagcache_%d.tcd" | 65 | #define TAGCACHE_FILE_INDEX ROCKBOX_DIR "/tagcache_%d.tcd" |
66 | #define TAGCACHE_FILE_CHANGELOG ROCKBOX_DIR "/tagcache_changelog.txt" | 66 | #define TAGCACHE_FILE_CHANGELOG ROCKBOX_DIR "/tagcache_changelog.txt" |
67 | #define TAGCACHE_STATEFILE ROCKBOX_DIR "/tagcache_state.tcd" | ||
67 | 68 | ||
68 | /* Flags */ | 69 | /* Flags */ |
69 | #define FLAG_DELETED 0x0001 /* Entry has been removed from db */ | 70 | #define FLAG_DELETED 0x0001 /* Entry has been removed from db */ |
@@ -149,6 +150,7 @@ bool tagcache_modify_numeric_entry(struct tagcache_search *tcs, | |||
149 | 150 | ||
150 | struct tagcache_stat* tagcache_get_stat(void); | 151 | struct tagcache_stat* tagcache_get_stat(void); |
151 | int tagcache_get_commit_step(void); | 152 | int tagcache_get_commit_step(void); |
153 | bool tagcache_prepare_shutdown(void); | ||
152 | 154 | ||
153 | #ifdef HAVE_TC_RAMCACHE | 155 | #ifdef HAVE_TC_RAMCACHE |
154 | bool tagcache_is_ramcache(void); | 156 | bool tagcache_is_ramcache(void); |
diff --git a/apps/tree.c b/apps/tree.c index 7543ceb3f7..fde4da0e04 100644 --- a/apps/tree.c +++ b/apps/tree.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include "tagcache.h" | 64 | #include "tagcache.h" |
65 | #include "yesno.h" | 65 | #include "yesno.h" |
66 | #include "gwps-common.h" | 66 | #include "gwps-common.h" |
67 | #include "eeprom_settings.h" | ||
67 | 68 | ||
68 | /* gui api */ | 69 | /* gui api */ |
69 | #include "list.h" | 70 | #include "list.h" |
@@ -1367,8 +1368,13 @@ void tree_flush(void) | |||
1367 | #ifdef HAVE_DIRCACHE | 1368 | #ifdef HAVE_DIRCACHE |
1368 | if (global_settings.dircache) | 1369 | if (global_settings.dircache) |
1369 | { | 1370 | { |
1370 | if (dircache_is_enabled()) | 1371 | # ifdef HAVE_EEPROM |
1372 | if (dircache_is_enabled() && firmware_settings.initialized) | ||
1373 | { | ||
1371 | global_settings.dircache_size = dircache_get_cache_size(); | 1374 | global_settings.dircache_size = dircache_get_cache_size(); |
1375 | dircache_save(DIRCACHE_FILE); | ||
1376 | } | ||
1377 | # endif | ||
1372 | dircache_disable(); | 1378 | dircache_disable(); |
1373 | } | 1379 | } |
1374 | else | 1380 | else |
@@ -1382,6 +1388,7 @@ void tree_flush(void) | |||
1382 | void tree_restore(void) | 1388 | void tree_restore(void) |
1383 | { | 1389 | { |
1384 | #ifdef HAVE_DIRCACHE | 1390 | #ifdef HAVE_DIRCACHE |
1391 | remove(DIRCACHE_FILE); | ||
1385 | if (global_settings.dircache) | 1392 | if (global_settings.dircache) |
1386 | { | 1393 | { |
1387 | /* Print "Scanning disk..." to the display. */ | 1394 | /* Print "Scanning disk..." to the display. */ |
diff --git a/firmware/SOURCES b/firmware/SOURCES index 8e2ca740ab..480c7ce630 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -145,6 +145,10 @@ drivers/mas.c | |||
145 | #ifdef IRIVER_H300_SERIES | 145 | #ifdef IRIVER_H300_SERIES |
146 | drivers/pcf50606.c | 146 | drivers/pcf50606.c |
147 | #endif | 147 | #endif |
148 | #ifdef HAVE_EEPROM | ||
149 | drivers/eeprom_24cxx.c | ||
150 | eeprom_settings.c | ||
151 | #endif | ||
148 | #ifdef IPOD_ARCH | 152 | #ifdef IPOD_ARCH |
149 | drivers/pcf50605.c | 153 | drivers/pcf50605.c |
150 | #endif | 154 | #endif |
diff --git a/firmware/common/crc32.c b/firmware/common/crc32.c index 18ee6ac710..21fefac07f 100644 --- a/firmware/common/crc32.c +++ b/firmware/common/crc32.c | |||
@@ -21,8 +21,10 @@ | |||
21 | 21 | ||
22 | /* Tool function to calculate a CRC32 across some buffer */ | 22 | /* Tool function to calculate a CRC32 across some buffer */ |
23 | /* third argument is either 0xFFFFFFFF to start or value from last piece */ | 23 | /* third argument is either 0xFFFFFFFF to start or value from last piece */ |
24 | unsigned crc_32(unsigned char* buf, unsigned len, unsigned crc32) | 24 | unsigned crc_32(const void *src, unsigned len, unsigned crc32) |
25 | { | 25 | { |
26 | const unsigned char *buf = (const unsigned char *)src; | ||
27 | |||
26 | /* CCITT standard polynomial 0x04C11DB7 */ | 28 | /* CCITT standard polynomial 0x04C11DB7 */ |
27 | static const unsigned crc32_lookup[16] = | 29 | static const unsigned crc32_lookup[16] = |
28 | { /* lookup table for 4 bits at a time is affordable */ | 30 | { /* lookup table for 4 bits at a time is affordable */ |
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index 6167aa3933..d2c77a2e25 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c | |||
@@ -402,7 +402,7 @@ static struct dircache_entry* dircache_get_entry(const char *path, | |||
402 | return cache_entry; | 402 | return cache_entry; |
403 | } | 403 | } |
404 | 404 | ||
405 | #if 0 | 405 | #if 1 |
406 | /** | 406 | /** |
407 | * Function to load the internal cache structure from disk to initialize | 407 | * Function to load the internal cache structure from disk to initialize |
408 | * the dircache really fast and little disk access. | 408 | * the dircache really fast and little disk access. |
@@ -423,32 +423,41 @@ int dircache_load(const char *path) | |||
423 | if (fd < 0) | 423 | if (fd < 0) |
424 | return -2; | 424 | return -2; |
425 | 425 | ||
426 | dircache_root = (struct dircache_entry *)(((long)audiobuf & ~0x03) + 0x04); | ||
427 | bytes_read = read(fd, &maindata, sizeof(struct dircache_maindata)); | 426 | bytes_read = read(fd, &maindata, sizeof(struct dircache_maindata)); |
428 | if (bytes_read != sizeof(struct dircache_maindata) | 427 | if (bytes_read != sizeof(struct dircache_maindata) |
429 | || (long)maindata.root_entry != (long)dircache_root | ||
430 | || maindata.size <= 0) | 428 | || maindata.size <= 0) |
431 | { | 429 | { |
430 | logf("Dircache file header error"); | ||
432 | close(fd); | 431 | close(fd); |
433 | return -3; | 432 | return -3; |
434 | } | 433 | } |
435 | 434 | ||
435 | dircache_root = buffer_alloc(0); | ||
436 | if ((long)maindata.root_entry != (long)dircache_root) | ||
437 | { | ||
438 | logf("Position missmatch"); | ||
439 | close(fd); | ||
440 | return -4; | ||
441 | } | ||
442 | |||
443 | dircache_root = buffer_alloc(maindata.size + DIRCACHE_RESERVE); | ||
436 | entry_count = maindata.entry_count; | 444 | entry_count = maindata.entry_count; |
437 | bytes_read = read(fd, dircache_root, MIN(DIRCACHE_LIMIT, maindata.size)); | 445 | bytes_read = read(fd, dircache_root, MIN(DIRCACHE_LIMIT, maindata.size)); |
438 | close(fd); | 446 | close(fd); |
439 | 447 | ||
440 | if (bytes_read != maindata.size) | 448 | if (bytes_read != maindata.size) |
449 | { | ||
450 | logf("Dircache read failed"); | ||
441 | return -6; | 451 | return -6; |
452 | } | ||
442 | 453 | ||
443 | /* Cache successfully loaded. */ | 454 | /* Cache successfully loaded. */ |
444 | dircache_size = maindata.size; | 455 | dircache_size = maindata.size; |
456 | allocated_size = dircache_size + DIRCACHE_RESERVE; | ||
457 | reserve_used = 0; | ||
445 | logf("Done, %d KiB used", dircache_size / 1024); | 458 | logf("Done, %d KiB used", dircache_size / 1024); |
446 | dircache_initialized = true; | 459 | dircache_initialized = true; |
447 | memset(fd_bindings, 0, sizeof(fd_bindings)); | 460 | memset(fd_bindings, 0, sizeof(fd_bindings)); |
448 | |||
449 | /* We have to long align the audiobuf to keep the buffer access fast. */ | ||
450 | audiobuf += (long)((dircache_size & ~0x03) + 0x04); | ||
451 | audiobuf += DIRCACHE_RESERVE; | ||
452 | 461 | ||
453 | return 0; | 462 | return 0; |
454 | } | 463 | } |
@@ -472,7 +481,7 @@ int dircache_save(const char *path) | |||
472 | return -1; | 481 | return -1; |
473 | 482 | ||
474 | logf("Saving directory cache"); | 483 | logf("Saving directory cache"); |
475 | fd = open(path, O_WRONLY | O_CREAT); | 484 | fd = open(path, O_WRONLY | O_CREAT | O_TRUNC); |
476 | 485 | ||
477 | maindata.magic = DIRCACHE_MAGIC; | 486 | maindata.magic = DIRCACHE_MAGIC; |
478 | maindata.size = dircache_size; | 487 | maindata.size = dircache_size; |
@@ -484,6 +493,7 @@ int dircache_save(const char *path) | |||
484 | if (bytes_written != sizeof(struct dircache_maindata)) | 493 | if (bytes_written != sizeof(struct dircache_maindata)) |
485 | { | 494 | { |
486 | close(fd); | 495 | close(fd); |
496 | logf("dircache: write failed #1"); | ||
487 | return -2; | 497 | return -2; |
488 | } | 498 | } |
489 | 499 | ||
@@ -491,8 +501,11 @@ int dircache_save(const char *path) | |||
491 | bytes_written = write(fd, dircache_root, dircache_size); | 501 | bytes_written = write(fd, dircache_root, dircache_size); |
492 | close(fd); | 502 | close(fd); |
493 | if (bytes_written != dircache_size) | 503 | if (bytes_written != dircache_size) |
504 | { | ||
505 | logf("dircache: write failed #2"); | ||
494 | return -3; | 506 | return -3; |
495 | 507 | } | |
508 | |||
496 | return 0; | 509 | return 0; |
497 | } | 510 | } |
498 | #endif /* #if 0 */ | 511 | #endif /* #if 0 */ |
@@ -616,6 +629,7 @@ int dircache_build(int last_size) | |||
616 | return -3; | 629 | return -3; |
617 | 630 | ||
618 | logf("Building directory cache"); | 631 | logf("Building directory cache"); |
632 | /* Background build, dircache has been previously allocated */ | ||
619 | if (dircache_size > 0) | 633 | if (dircache_size > 0) |
620 | { | 634 | { |
621 | thread_enabled = true; | 635 | thread_enabled = true; |
diff --git a/firmware/drivers/eeprom_24cxx.c b/firmware/drivers/eeprom_24cxx.c index 4f7362ec82..33c02f1bc8 100644 --- a/firmware/drivers/eeprom_24cxx.c +++ b/firmware/drivers/eeprom_24cxx.c | |||
@@ -308,7 +308,7 @@ bool eeprom_24cxx_read_byte(unsigned int address, char *c) | |||
308 | bool eeprom_24cxx_write_byte(unsigned int address, char c) | 308 | bool eeprom_24cxx_write_byte(unsigned int address, char c) |
309 | { | 309 | { |
310 | int ret; | 310 | int ret; |
311 | int count = 10; | 311 | int count = 100; |
312 | 312 | ||
313 | if (address >= EEPROM_SIZE) | 313 | if (address >= EEPROM_SIZE) |
314 | { | 314 | { |
@@ -318,10 +318,6 @@ bool eeprom_24cxx_write_byte(unsigned int address, char c) | |||
318 | 318 | ||
319 | do { | 319 | do { |
320 | ret = sw_i2c_write_byte(address, c); | 320 | ret = sw_i2c_write_byte(address, c); |
321 | if (ret < 0) | ||
322 | { | ||
323 | logf("EEPROM Fail: %d/%d", ret, address); | ||
324 | } | ||
325 | } while (ret < 0 && count--) ; | 321 | } while (ret < 0 && count--) ; |
326 | 322 | ||
327 | if (ret < 0) | 323 | if (ret < 0) |
diff --git a/firmware/eeprom_settings.c b/firmware/eeprom_settings.c new file mode 100644 index 0000000000..43f519d3fa --- /dev/null +++ b/firmware/eeprom_settings.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Miika Pekkarinen | ||
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 | |||
20 | #include "eeprom_settings.h" | ||
21 | #include "eeprom_24cxx.h" | ||
22 | #include "crc32.h" | ||
23 | |||
24 | #include "string.h" | ||
25 | #include "logf.h" | ||
26 | |||
27 | struct eeprom_settings firmware_settings; | ||
28 | |||
29 | static void reset_config(void) | ||
30 | { | ||
31 | memset(&firmware_settings, 0, sizeof(struct eeprom_settings)); | ||
32 | firmware_settings.version = EEPROM_SETTINGS_VERSION; | ||
33 | firmware_settings.initialized = true; | ||
34 | firmware_settings.boot_disk = false; | ||
35 | firmware_settings.bl_version = 0; | ||
36 | } | ||
37 | |||
38 | bool eeprom_settings_init(void) | ||
39 | { | ||
40 | bool ret; | ||
41 | uint32_t sum; | ||
42 | |||
43 | eeprom_24cxx_init(); | ||
44 | |||
45 | /* Check if player has been flashed. */ | ||
46 | if (!detect_flashed_rockbox()) | ||
47 | { | ||
48 | memset(&firmware_settings, 0, sizeof(struct eeprom_settings)); | ||
49 | firmware_settings.initialized = false; | ||
50 | logf("Rockbox in flash is required"); | ||
51 | return false; | ||
52 | } | ||
53 | |||
54 | ret = eeprom_24cxx_read(0, &firmware_settings, | ||
55 | sizeof(struct eeprom_settings)); | ||
56 | |||
57 | if (!ret) | ||
58 | { | ||
59 | memset(&firmware_settings, 0, sizeof(struct eeprom_settings)); | ||
60 | firmware_settings.initialized = false; | ||
61 | return false; | ||
62 | } | ||
63 | |||
64 | sum = crc_32(&firmware_settings, sizeof(struct eeprom_settings)-4, | ||
65 | 0xffffffff); | ||
66 | |||
67 | if (firmware_settings.checksum != sum) | ||
68 | { | ||
69 | logf("Checksum mismatch"); | ||
70 | reset_config(); | ||
71 | return true; | ||
72 | } | ||
73 | |||
74 | if (firmware_settings.version != EEPROM_SETTINGS_VERSION) | ||
75 | { | ||
76 | logf("Version mismatch"); | ||
77 | reset_config(); | ||
78 | return true; | ||
79 | } | ||
80 | |||
81 | #ifndef BOOTLOADER | ||
82 | if (firmware_settings.bl_version < EEPROM_SETTINGS_BL_MINVER) | ||
83 | { | ||
84 | logf("Too old bootloader: %d", firmware_settings.bl_version); | ||
85 | reset_config(); | ||
86 | return true; | ||
87 | } | ||
88 | #endif | ||
89 | |||
90 | return true; | ||
91 | } | ||
92 | |||
93 | bool eeprom_settings_store(void) | ||
94 | { | ||
95 | bool ret; | ||
96 | uint32_t sum; | ||
97 | |||
98 | if (!firmware_settings.initialized || !detect_flashed_rockbox()) | ||
99 | { | ||
100 | logf("Rockbox in flash is required"); | ||
101 | return false; | ||
102 | } | ||
103 | |||
104 | /* Update the checksum. */ | ||
105 | sum = crc_32(&firmware_settings, sizeof(struct eeprom_settings)-4, | ||
106 | 0xffffffff); | ||
107 | firmware_settings.checksum = sum; | ||
108 | ret = eeprom_24cxx_write(0, &firmware_settings, | ||
109 | sizeof(struct eeprom_settings)); | ||
110 | |||
111 | if (!ret) | ||
112 | firmware_settings.initialized = false; | ||
113 | |||
114 | return ret; | ||
115 | } | ||
116 | |||
diff --git a/firmware/export/config-h100.h b/firmware/export/config-h100.h index 6d204c3d66..7310dfa42f 100644 --- a/firmware/export/config-h100.h +++ b/firmware/export/config-h100.h | |||
@@ -123,7 +123,10 @@ | |||
123 | #define BOOTFILE_EXT "iriver" | 123 | #define BOOTFILE_EXT "iriver" |
124 | #define BOOTFILE "rockbox." BOOTFILE_EXT | 124 | #define BOOTFILE "rockbox." BOOTFILE_EXT |
125 | 125 | ||
126 | #endif | 126 | /* Define this if there is an EEPROM chip */ |
127 | #define HAVE_EEPROM | ||
128 | |||
129 | #endif /* !SIMULATOR */ | ||
127 | 130 | ||
128 | /* Define this for S/PDIF input available */ | 131 | /* Define this for S/PDIF input available */ |
129 | #define HAVE_SPDIF_IN | 132 | #define HAVE_SPDIF_IN |
@@ -134,3 +137,4 @@ | |||
134 | /* Define this if you can control the S/PDIF power */ | 137 | /* Define this if you can control the S/PDIF power */ |
135 | #define HAVE_SPDIF_POWER | 138 | #define HAVE_SPDIF_POWER |
136 | #define SPDIF_POWER_INVERTED | 139 | #define SPDIF_POWER_INVERTED |
140 | |||
diff --git a/firmware/export/config-h120.h b/firmware/export/config-h120.h index 5635a92b51..ca618139e9 100644 --- a/firmware/export/config-h120.h +++ b/firmware/export/config-h120.h | |||
@@ -118,7 +118,14 @@ | |||
118 | #define BOOTFILE_EXT "iriver" | 118 | #define BOOTFILE_EXT "iriver" |
119 | #define BOOTFILE "rockbox." BOOTFILE_EXT | 119 | #define BOOTFILE "rockbox." BOOTFILE_EXT |
120 | 120 | ||
121 | #endif | 121 | #define BOOTLOADER_ENTRYPOINT 0x001F0000 |
122 | #define FLASH_ENTRYPOINT 0x00001000 | ||
123 | #define FLASH_MAGIC 0xfbfbfbf1 | ||
124 | |||
125 | /* Define this if there is an EEPROM chip */ | ||
126 | #define HAVE_EEPROM | ||
127 | |||
128 | #endif /* !SIMULATOR */ | ||
122 | 129 | ||
123 | /* Define this for S/PDIF input available */ | 130 | /* Define this for S/PDIF input available */ |
124 | #define HAVE_SPDIF_IN | 131 | #define HAVE_SPDIF_IN |
@@ -128,3 +135,4 @@ | |||
128 | 135 | ||
129 | /* Define this if you can control the S/PDIF power */ | 136 | /* Define this if you can control the S/PDIF power */ |
130 | #define HAVE_SPDIF_POWER | 137 | #define HAVE_SPDIF_POWER |
138 | |||
diff --git a/firmware/export/eeprom_settings.h b/firmware/export/eeprom_settings.h new file mode 100644 index 0000000000..a3515bd69e --- /dev/null +++ b/firmware/export/eeprom_settings.h | |||
@@ -0,0 +1,48 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Miika Pekkarinen | ||
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 | |||
20 | #ifndef _EEPROM_SETTINGS_H_ | ||
21 | #define _EEPROM_SETTINGS_H_ | ||
22 | |||
23 | #include <stdbool.h> | ||
24 | #include "inttypes.h" | ||
25 | |||
26 | #define EEPROM_SETTINGS_VERSION 0x24c01001 | ||
27 | #define EEPROM_SETTINGS_BL_MINVER 7 | ||
28 | |||
29 | struct eeprom_settings | ||
30 | { | ||
31 | long version; /* Settings version number */ | ||
32 | bool initialized; /* Is eeprom_settings ready to be used */ | ||
33 | bool disk_clean; /* Is disk intact from last reboot */ | ||
34 | bool boot_disk; /* Load firmware from disk (default=FLASH) */ | ||
35 | uint8_t bl_version; /* Installed bootloader version */ | ||
36 | |||
37 | /* This must be the last entry */ | ||
38 | uint32_t checksum; /* Checksum of this structure */ | ||
39 | }; | ||
40 | |||
41 | extern struct eeprom_settings firmware_settings; | ||
42 | |||
43 | bool detect_flashed_rockbox(void); | ||
44 | bool eeprom_settings_init(void); | ||
45 | bool eeprom_settings_store(void); | ||
46 | |||
47 | #endif | ||
48 | |||
diff --git a/firmware/export/system.h b/firmware/export/system.h index dae5d95794..1b326e1b8b 100644 --- a/firmware/export/system.h +++ b/firmware/export/system.h | |||
@@ -45,6 +45,14 @@ static inline void udelay(unsigned usecs) | |||
45 | } | 45 | } |
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | struct flash_header { | ||
49 | unsigned long magic; | ||
50 | unsigned long length; | ||
51 | char version[32]; | ||
52 | }; | ||
53 | |||
54 | bool detect_flashed_rockbox(void); | ||
55 | |||
48 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 56 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
49 | #define FREQ cpu_frequency | 57 | #define FREQ cpu_frequency |
50 | void set_cpu_frequency(long frequency); | 58 | void set_cpu_frequency(long frequency); |
diff --git a/firmware/include/crc32.h b/firmware/include/crc32.h index 5e998ab1b9..a2b7ae2f0a 100644 --- a/firmware/include/crc32.h +++ b/firmware/include/crc32.h | |||
@@ -19,7 +19,7 @@ | |||
19 | #ifndef _CRC32_H | 19 | #ifndef _CRC32_H |
20 | #define _CRC32_H | 20 | #define _CRC32_H |
21 | 21 | ||
22 | unsigned crc_32(unsigned char* buf, unsigned len, unsigned crc32); | 22 | unsigned crc_32(const void *src, unsigned len, unsigned crc32); |
23 | 23 | ||
24 | #endif | 24 | #endif |
25 | 25 | ||
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index 4bccd4e211..a8e641e1ed 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c | |||
@@ -993,8 +993,8 @@ void sys_poweroff(void) | |||
993 | { | 993 | { |
994 | logf("sys_poweroff()"); | 994 | logf("sys_poweroff()"); |
995 | /* If the main thread fails to shut down the system, we will force a | 995 | /* If the main thread fails to shut down the system, we will force a |
996 | power off after an 8 second timeout */ | 996 | power off after an 20 second timeout */ |
997 | shutdown_timeout = HZ*8; | 997 | shutdown_timeout = HZ*20; |
998 | 998 | ||
999 | queue_post(&button_queue, SYS_POWEROFF, NULL); | 999 | queue_post(&button_queue, SYS_POWEROFF, NULL); |
1000 | } | 1000 | } |
diff --git a/firmware/system.c b/firmware/system.c index 1874c0480e..bb09dbcd59 100644 --- a/firmware/system.c +++ b/firmware/system.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include "system.h" | 24 | #include "system.h" |
25 | #include "kernel.h" | 25 | #include "kernel.h" |
26 | #include "timer.h" | 26 | #include "timer.h" |
27 | #include "inttypes.h" | ||
28 | #include "string.h" | ||
27 | 29 | ||
28 | #ifndef SIMULATOR | 30 | #ifndef SIMULATOR |
29 | long cpu_frequency = CPU_FREQ; | 31 | long cpu_frequency = CPU_FREQ; |
@@ -76,6 +78,25 @@ void cpu_idle_mode(bool on_off) | |||
76 | 78 | ||
77 | #endif | 79 | #endif |
78 | 80 | ||
81 | #if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR) | ||
82 | bool detect_flashed_rockbox(void) | ||
83 | { | ||
84 | struct flash_header hdr; | ||
85 | uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT; | ||
86 | |||
87 | memcpy(&hdr, src, sizeof(struct flash_header)); | ||
88 | if (hdr.magic != FLASH_MAGIC) | ||
89 | return false; | ||
90 | |||
91 | return true; | ||
92 | } | ||
93 | #else | ||
94 | bool detect_flashed_rockbox(void) | ||
95 | { | ||
96 | return false; | ||
97 | } | ||
98 | #endif | ||
99 | |||
79 | #if CONFIG_CPU == TCC730 | 100 | #if CONFIG_CPU == TCC730 |
80 | 101 | ||
81 | void* volatile interrupt_vector[16] __attribute__ ((section(".idata"))); | 102 | void* volatile interrupt_vector[16] __attribute__ ((section(".idata"))); |