summaryrefslogtreecommitdiff
path: root/firmware/common/dircache.c
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2008-03-11 19:39:26 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2008-03-11 19:39:26 +0000
commit52d827a26dec8bc4967cf3c2984a10ace114fa21 (patch)
tree83b9660b904934a62df38ee0ed138c66f3cdebb1 /firmware/common/dircache.c
parentafde7f74d4325c3a5a6883167c1f74f4fb689f90 (diff)
downloadrockbox-52d827a26dec8bc4967cf3c2984a10ace114fa21.tar.gz
rockbox-52d827a26dec8bc4967cf3c2984a10ace114fa21.zip
FS#7598 - Dircache support for multivolume targets (by Phil Light).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16632 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/common/dircache.c')
-rw-r--r--firmware/common/dircache.c106
1 files changed, 77 insertions, 29 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index ed392d6186..bf8ff45cff 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -37,6 +37,7 @@
37#include "usb.h" 37#include "usb.h"
38#include "file.h" 38#include "file.h"
39#include "buffer.h" 39#include "buffer.h"
40#include "dir.h"
40#if CONFIG_RTC 41#if CONFIG_RTC
41#include "time.h" 42#include "time.h"
42#include "timefuncs.h" 43#include "timefuncs.h"
@@ -51,6 +52,9 @@ DIR_CACHED opendirs[MAX_OPEN_DIRS];
51 52
52static struct dircache_entry *fd_bindings[MAX_OPEN_FILES]; 53static struct dircache_entry *fd_bindings[MAX_OPEN_FILES];
53static struct dircache_entry *dircache_root; 54static struct dircache_entry *dircache_root;
55#ifdef HAVE_MULTIVOLUME
56static struct dircache_entry *append_position;
57#endif
54 58
55static bool dircache_initialized = false; 59static bool dircache_initialized = false;
56static bool dircache_initializing = false; 60static bool dircache_initializing = false;
@@ -155,6 +159,9 @@ static bool check_event_queue(void)
155 { 159 {
156 case DIRCACHE_STOP: 160 case DIRCACHE_STOP:
157 case SYS_USB_CONNECTED: 161 case SYS_USB_CONNECTED:
162#ifdef HAVE_HOTSWAP
163 case SYS_FS_CHANGED:
164#endif
158 /* Put the event back into the queue. */ 165 /* Put the event back into the queue. */
159 queue_post(&dircache_queue, ev.id, ev.data); 166 queue_post(&dircache_queue, ev.id, ev.data);
160 return true; 167 return true;
@@ -166,7 +173,7 @@ static bool check_event_queue(void)
166/** 173/**
167 * Internal function to iterate a path. 174 * Internal function to iterate a path.
168 */ 175 */
169static int dircache_scan(struct travel_data *td) 176static int dircache_scan(IF_MV2(int volume,) struct travel_data *td)
170{ 177{
171#ifdef SIMULATOR 178#ifdef SIMULATOR
172 while ( ( td->entry = readdir_uncached(td->dir) ) ) 179 while ( ( td->entry = readdir_uncached(td->dir) ) )
@@ -273,22 +280,37 @@ static int dircache_scan(struct travel_data *td)
273 * Recursively scan the hard disk and build the cache. 280 * Recursively scan the hard disk and build the cache.
274 */ 281 */
275#ifdef SIMULATOR 282#ifdef SIMULATOR
276static int dircache_travel(DIR_UNCACHED *dir, struct dircache_entry *ce) 283static int dircache_travel(IF_MV2(int volume,) DIR_UNCACHED *dir, struct dircache_entry *ce)
277#else 284#else
278static int dircache_travel(struct fat_dir *dir, struct dircache_entry *ce) 285static int dircache_travel(IF_MV2(int volume,) struct fat_dir *dir, struct dircache_entry *ce)
279#endif 286#endif
280{ 287{
281 int depth = 0; 288 int depth = 0;
282 int result; 289 int result;
283 290
284 memset(ce, 0, sizeof(struct dircache_entry)); 291 memset(ce, 0, sizeof(struct dircache_entry));
292
293#if defined(HAVE_MULTIVOLUME) && !defined(SIMULATOR)
294 if (volume > 0)
295 {
296 ce->d_name = ((char *)dircache_root+dircache_size);
297 snprintf(ce->d_name, VOL_ENUM_POS + 3, VOL_NAMES, volume);
298 ce->name_len = VOL_ENUM_POS + 3;
299 dircache_size += ce->name_len;
300 ce->attribute = FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME;
301 ce->size = 0;
302 append_position = dircache_gen_next(ce);
303 ce = dircache_gen_down(ce);
304 }
305#endif
306
285 dir_recursion[0].dir = dir; 307 dir_recursion[0].dir = dir;
286 dir_recursion[0].ce = ce; 308 dir_recursion[0].ce = ce;
287 dir_recursion[0].first = ce; 309 dir_recursion[0].first = ce;
288 310
289 do { 311 do {
290 //logf("=> %s", dircache_cur_path); 312 //logf("=> %s", dircache_cur_path);
291 result = dircache_scan(&dir_recursion[depth]); 313 result = dircache_scan(IF_MV2(volume,) &dir_recursion[depth]);
292 switch (result) { 314 switch (result) {
293 case 0: /* Leaving the current directory. */ 315 case 0: /* Leaving the current directory. */
294 /* Add the standard . and .. entries. */ 316 /* Add the standard . and .. entries. */
@@ -536,37 +558,57 @@ static int dircache_do_rebuild(void)
536 start_tick = current_tick; 558 start_tick = current_tick;
537 dircache_initializing = true; 559 dircache_initializing = true;
538 appflags = 0; 560 appflags = 0;
561 entry_count = 0;
539 562
540#ifdef SIMULATOR
541 pdir = opendir_uncached("/");
542 if (pdir == NULL)
543 {
544 logf("Failed to open rootdir");
545 dircache_initializing = false;
546 return -3;
547 }
548#else
549 if ( fat_opendir(IF_MV2(volume,) &dir, 0, NULL) < 0 ) {
550 logf("Failed opening root dir");
551 dircache_initializing = false;
552 return -3;
553 }
554 pdir = &dir;
555#endif
556
557 memset(dircache_cur_path, 0, sizeof(dircache_cur_path)); 563 memset(dircache_cur_path, 0, sizeof(dircache_cur_path));
558 dircache_size = sizeof(struct dircache_entry); 564 dircache_size = sizeof(struct dircache_entry);
559 565
560 cpu_boost(true); 566#ifdef HAVE_MULTIVOLUME
561 if (dircache_travel(pdir, dircache_root) < 0) 567 append_position = dircache_root;
568
569 for (i = NUM_VOLUMES; i >= 0; i--)
562 { 570 {
563 logf("dircache_travel failed"); 571 if (fat_ismounted(i))
564 cpu_boost(false); 572 {
565 dircache_size = 0; 573#endif
566 dircache_initializing = false; 574#ifdef SIMULATOR
567 return -2; 575 pdir = opendir_uncached("/");
576 if (pdir == NULL)
577 {
578 logf("Failed to open rootdir");
579 dircache_initializing = false;
580 return -3;
581 }
582#else
583#ifdef HAVE_MULTIVOLUME
584 if ( fat_opendir(IF_MV2(i,) &dir, 0, NULL) < 0 ) {
585#else
586 if ( fat_opendir(IF_MV2(0,) &dir, 0, NULL) < 0 ) {
587#endif /* HAVE_MULTIVOLUME */
588 logf("Failed opening root dir");
589 dircache_initializing = false;
590 return -3;
591 }
592 pdir = &dir;
593#endif
594 cpu_boost(true);
595#ifdef HAVE_MULTIVOLUME
596 if (dircache_travel(IF_MV2(i,) pdir, append_position) < 0)
597#else
598 if (dircache_travel(IF_MV2(0,) pdir, dircache_root) < 0)
599#endif /* HAVE_MULTIVOLUME */
600 {
601 logf("dircache_travel failed");
602 cpu_boost(false);
603 dircache_size = 0;
604 dircache_initializing = false;
605 return -2;
606 }
607 cpu_boost(false);
608#ifdef HAVE_MULTIVOLUME
609 }
568 } 610 }
569 cpu_boost(false); 611#endif
570 612
571 logf("Done, %ld KiB used", dircache_size / 1024); 613 logf("Done, %ld KiB used", dircache_size / 1024);
572 614
@@ -610,6 +652,12 @@ static void dircache_thread(void)
610 652
611 switch (ev.id) 653 switch (ev.id)
612 { 654 {
655#ifdef HAVE_HOTSWAP
656 case SYS_FS_CHANGED:
657 if (!dircache_initialized)
658 break;
659 dircache_initialized = false;
660#endif
613 case DIRCACHE_BUILD: 661 case DIRCACHE_BUILD:
614 thread_enabled = true; 662 thread_enabled = true;
615 dircache_do_rebuild(); 663 dircache_do_rebuild();