summaryrefslogtreecommitdiff
path: root/firmware/common
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/common')
-rw-r--r--firmware/common/dir_uncached.c20
-rw-r--r--firmware/common/dircache.c106
2 files changed, 80 insertions, 46 deletions
diff --git a/firmware/common/dir_uncached.c b/firmware/common/dir_uncached.c
index e6b59c30ec..129ef35603 100644
--- a/firmware/common/dir_uncached.c
+++ b/firmware/common/dir_uncached.c
@@ -24,7 +24,6 @@
24#include "dir.h" 24#include "dir.h"
25#include "debug.h" 25#include "debug.h"
26#include "atoi.h" 26#include "atoi.h"
27//#include "dircache.h"
28 27
29#define MAX_OPEN_DIRS 8 28#define MAX_OPEN_DIRS 8
30 29
@@ -32,22 +31,9 @@ static DIR_UNCACHED opendirs[MAX_OPEN_DIRS];
32 31
33#ifdef HAVE_MULTIVOLUME 32#ifdef HAVE_MULTIVOLUME
34 33
35/* how to name volumes, first char must be outside of legal file names,
36 a number gets appended to enumerate, if applicable */
37#ifdef HAVE_MMC
38static const char* vol_names = "<MMC%d>";
39#define VOL_ENUM_POS 4 /* position of %d, to avoid runtime calculation */
40#elif defined(HAVE_HOTSWAP)
41static const char* vol_names = "<microSD%d>";
42#define VOL_ENUM_POS 8 /* position of %d, to avoid runtime calculation */
43#else
44static const char* vol_names = "<HD%d>";
45#define VOL_ENUM_POS 3
46#endif
47
48/* returns on which volume this is, and copies the reduced name 34/* returns on which volume this is, and copies the reduced name
49 (sortof a preprocessor for volume-decorated pathnames) */ 35 (sortof a preprocessor for volume-decorated pathnames) */
50static int strip_volume(const char* name, char* namecopy) 36int strip_volume(const char* name, char* namecopy)
51{ 37{
52 int volume = 0; 38 int volume = 0;
53 const char *temp = name; 39 const char *temp = name;
@@ -55,7 +41,7 @@ static int strip_volume(const char* name, char* namecopy)
55 while (*temp == '/') /* skip all leading slashes */ 41 while (*temp == '/') /* skip all leading slashes */
56 ++temp; 42 ++temp;
57 43
58 if (*temp && !strncmp(temp, vol_names, VOL_ENUM_POS)) 44 if (*temp && !strncmp(temp, VOL_NAMES, VOL_ENUM_POS))
59 { 45 {
60 temp += VOL_ENUM_POS; /* behind special name */ 46 temp += VOL_ENUM_POS; /* behind special name */
61 volume = atoi(temp); /* number is following */ 47 volume = atoi(temp); /* number is following */
@@ -199,7 +185,7 @@ struct dirent_uncached* readdir_uncached(DIR_UNCACHED* dir)
199 memset(theent, 0, sizeof(*theent)); 185 memset(theent, 0, sizeof(*theent));
200 theent->attribute = FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME; 186 theent->attribute = FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME;
201 snprintf(theent->d_name, sizeof(theent->d_name), 187 snprintf(theent->d_name, sizeof(theent->d_name),
202 vol_names, dir->volumecounter); 188 VOL_NAMES, dir->volumecounter);
203 return theent; 189 return theent;
204 } 190 }
205 } 191 }
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();