summaryrefslogtreecommitdiff
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
parentafde7f74d4325c3a5a6883167c1f74f4fb689f90 (diff)
downloadrockbox-52d827a26dec8bc4967cf3c2984a10ace114fa21.zip
rockbox-52d827a26dec8bc4967cf3c2984a10ace114fa21.tar.gz
rockbox-52d827a26dec8bc4967cf3c2984a10ace114fa21.tar.bz2
rockbox-52d827a26dec8bc4967cf3c2984a10ace114fa21.tar.xz
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
-rw-r--r--docs/CREDITS2
-rw-r--r--firmware/common/dir_uncached.c20
-rw-r--r--firmware/common/dircache.c106
-rw-r--r--firmware/export/config.h2
-rw-r--r--firmware/include/dir.h17
-rw-r--r--firmware/include/dir_uncached.h4
6 files changed, 102 insertions, 49 deletions
diff --git a/docs/CREDITS b/docs/CREDITS
index c4d78ed..6bbc868 100644
--- a/docs/CREDITS
+++ b/docs/CREDITS
@@ -380,7 +380,7 @@ Keith Perri
Mark Fawcus
Ivan Pesic
Marcel Barbulescu
-
+Phil Light
The libmad team
The wavpack team
diff --git a/firmware/common/dir_uncached.c b/firmware/common/dir_uncached.c
index e6b59c3..129ef35 100644
--- a/firmware/common/dir_uncached.c
+++ b/firmware/common/dir_uncached.c
@@ -24,7 +24,6 @@
#include "dir.h"
#include "debug.h"
#include "atoi.h"
-//#include "dircache.h"
#define MAX_OPEN_DIRS 8
@@ -32,22 +31,9 @@ static DIR_UNCACHED opendirs[MAX_OPEN_DIRS];
#ifdef HAVE_MULTIVOLUME
-/* how to name volumes, first char must be outside of legal file names,
- a number gets appended to enumerate, if applicable */
-#ifdef HAVE_MMC
-static const char* vol_names = "<MMC%d>";
-#define VOL_ENUM_POS 4 /* position of %d, to avoid runtime calculation */
-#elif defined(HAVE_HOTSWAP)
-static const char* vol_names = "<microSD%d>";
-#define VOL_ENUM_POS 8 /* position of %d, to avoid runtime calculation */
-#else
-static const char* vol_names = "<HD%d>";
-#define VOL_ENUM_POS 3
-#endif
-
/* returns on which volume this is, and copies the reduced name
(sortof a preprocessor for volume-decorated pathnames) */
-static int strip_volume(const char* name, char* namecopy)
+int strip_volume(const char* name, char* namecopy)
{
int volume = 0;
const char *temp = name;
@@ -55,7 +41,7 @@ static int strip_volume(const char* name, char* namecopy)
while (*temp == '/') /* skip all leading slashes */
++temp;
- if (*temp && !strncmp(temp, vol_names, VOL_ENUM_POS))
+ if (*temp && !strncmp(temp, VOL_NAMES, VOL_ENUM_POS))
{
temp += VOL_ENUM_POS; /* behind special name */
volume = atoi(temp); /* number is following */
@@ -199,7 +185,7 @@ struct dirent_uncached* readdir_uncached(DIR_UNCACHED* dir)
memset(theent, 0, sizeof(*theent));
theent->attribute = FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME;
snprintf(theent->d_name, sizeof(theent->d_name),
- vol_names, dir->volumecounter);
+ VOL_NAMES, dir->volumecounter);
return theent;
}
}
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index ed392d6..bf8ff45 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -37,6 +37,7 @@
#include "usb.h"
#include "file.h"
#include "buffer.h"
+#include "dir.h"
#if CONFIG_RTC
#include "time.h"
#include "timefuncs.h"
@@ -51,6 +52,9 @@ DIR_CACHED opendirs[MAX_OPEN_DIRS];
static struct dircache_entry *fd_bindings[MAX_OPEN_FILES];
static struct dircache_entry *dircache_root;
+#ifdef HAVE_MULTIVOLUME
+static struct dircache_entry *append_position;
+#endif
static bool dircache_initialized = false;
static bool dircache_initializing = false;
@@ -155,6 +159,9 @@ static bool check_event_queue(void)
{
case DIRCACHE_STOP:
case SYS_USB_CONNECTED:
+#ifdef HAVE_HOTSWAP
+ case SYS_FS_CHANGED:
+#endif
/* Put the event back into the queue. */
queue_post(&dircache_queue, ev.id, ev.data);
return true;
@@ -166,7 +173,7 @@ static bool check_event_queue(void)
/**
* Internal function to iterate a path.
*/
-static int dircache_scan(struct travel_data *td)
+static int dircache_scan(IF_MV2(int volume,) struct travel_data *td)
{
#ifdef SIMULATOR
while ( ( td->entry = readdir_uncached(td->dir) ) )
@@ -273,22 +280,37 @@ static int dircache_scan(struct travel_data *td)
* Recursively scan the hard disk and build the cache.
*/
#ifdef SIMULATOR
-static int dircache_travel(DIR_UNCACHED *dir, struct dircache_entry *ce)
+static int dircache_travel(IF_MV2(int volume,) DIR_UNCACHED *dir, struct dircache_entry *ce)
#else
-static int dircache_travel(struct fat_dir *dir, struct dircache_entry *ce)
+static int dircache_travel(IF_MV2(int volume,) struct fat_dir *dir, struct dircache_entry *ce)
#endif
{
int depth = 0;
int result;
memset(ce, 0, sizeof(struct dircache_entry));
+
+#if defined(HAVE_MULTIVOLUME) && !defined(SIMULATOR)
+ if (volume > 0)
+ {
+ ce->d_name = ((char *)dircache_root+dircache_size);
+ snprintf(ce->d_name, VOL_ENUM_POS + 3, VOL_NAMES, volume);
+ ce->name_len = VOL_ENUM_POS + 3;
+ dircache_size += ce->name_len;
+ ce->attribute = FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME;
+ ce->size = 0;
+ append_position = dircache_gen_next(ce);
+ ce = dircache_gen_down(ce);
+ }
+#endif
+
dir_recursion[0].dir = dir;
dir_recursion[0].ce = ce;
dir_recursion[0].first = ce;
do {
//logf("=> %s", dircache_cur_path);
- result = dircache_scan(&dir_recursion[depth]);
+ result = dircache_scan(IF_MV2(volume,) &dir_recursion[depth]);
switch (result) {
case 0: /* Leaving the current directory. */
/* Add the standard . and .. entries. */
@@ -536,37 +558,57 @@ static int dircache_do_rebuild(void)
start_tick = current_tick;
dircache_initializing = true;
appflags = 0;
+ entry_count = 0;
-#ifdef SIMULATOR
- pdir = opendir_uncached("/");
- if (pdir == NULL)
- {
- logf("Failed to open rootdir");
- dircache_initializing = false;
- return -3;
- }
-#else
- if ( fat_opendir(IF_MV2(volume,) &dir, 0, NULL) < 0 ) {
- logf("Failed opening root dir");
- dircache_initializing = false;
- return -3;
- }
- pdir = &dir;
-#endif
-
memset(dircache_cur_path, 0, sizeof(dircache_cur_path));
dircache_size = sizeof(struct dircache_entry);
- cpu_boost(true);
- if (dircache_travel(pdir, dircache_root) < 0)
+#ifdef HAVE_MULTIVOLUME
+ append_position = dircache_root;
+
+ for (i = NUM_VOLUMES; i >= 0; i--)
{
- logf("dircache_travel failed");
- cpu_boost(false);
- dircache_size = 0;
- dircache_initializing = false;
- return -2;
+ if (fat_ismounted(i))
+ {
+#endif
+#ifdef SIMULATOR
+ pdir = opendir_uncached("/");
+ if (pdir == NULL)
+ {
+ logf("Failed to open rootdir");
+ dircache_initializing = false;
+ return -3;
+ }
+#else
+#ifdef HAVE_MULTIVOLUME
+ if ( fat_opendir(IF_MV2(i,) &dir, 0, NULL) < 0 ) {
+#else
+ if ( fat_opendir(IF_MV2(0,) &dir, 0, NULL) < 0 ) {
+#endif /* HAVE_MULTIVOLUME */
+ logf("Failed opening root dir");
+ dircache_initializing = false;
+ return -3;
+ }
+ pdir = &dir;
+#endif
+ cpu_boost(true);
+#ifdef HAVE_MULTIVOLUME
+ if (dircache_travel(IF_MV2(i,) pdir, append_position) < 0)
+#else
+ if (dircache_travel(IF_MV2(0,) pdir, dircache_root) < 0)
+#endif /* HAVE_MULTIVOLUME */
+ {
+ logf("dircache_travel failed");
+ cpu_boost(false);
+ dircache_size = 0;
+ dircache_initializing = false;
+ return -2;
+ }
+ cpu_boost(false);
+#ifdef HAVE_MULTIVOLUME
+ }
}
- cpu_boost(false);
+#endif
logf("Done, %ld KiB used", dircache_size / 1024);
@@ -610,6 +652,12 @@ static void dircache_thread(void)
switch (ev.id)
{
+#ifdef HAVE_HOTSWAP
+ case SYS_FS_CHANGED:
+ if (!dircache_initialized)
+ break;
+ dircache_initialized = false;
+#endif
case DIRCACHE_BUILD:
thread_enabled = true;
dircache_do_rebuild();
diff --git a/firmware/export/config.h b/firmware/export/config.h
index c2033df..e1c0cbc 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -313,9 +313,7 @@
* plenty of RAM. Both features can be enabled independently. */
#if ((defined(MEMORYSIZE) && (MEMORYSIZE > 8)) || MEM > 8) && \
!defined(BOOTLOADER)
-#if !defined(SANSA_E200) && !defined(SANSA_C200)
#define HAVE_DIRCACHE
-#endif
#ifdef HAVE_TAGCACHE
#define HAVE_TC_RAMCACHE
#endif
diff --git a/firmware/include/dir.h b/firmware/include/dir.h
index 4327b91..6433f1d 100644
--- a/firmware/include/dir.h
+++ b/firmware/include/dir.h
@@ -22,6 +22,23 @@
#include "config.h"
+#ifdef HAVE_MULTIVOLUME
+
+/* how to name volumes, first char must be outside of legal file names,
+ a number gets appended to enumerate, if applicable */
+#ifdef HAVE_MMC
+#define VOL_NAMES "<MMC%d>"
+#define VOL_ENUM_POS 4 /* position of %d, to avoid runtime calculation */
+#elif defined(HAVE_HOTSWAP)
+#define VOL_NAMES "<microSD%d>"
+#define VOL_ENUM_POS 8 /* position of %d, to avoid runtime calculation */
+#else
+#define VOL_NAMES "<HD%d>"
+#define VOL_ENUM_POS 3
+#endif
+
+#endif
+
#ifdef HAVE_DIRCACHE
# include "dircache.h"
# define DIR DIR_CACHED
diff --git a/firmware/include/dir_uncached.h b/firmware/include/dir_uncached.h
index 575c3b6..dd00c2c 100644
--- a/firmware/include/dir_uncached.h
+++ b/firmware/include/dir_uncached.h
@@ -75,6 +75,10 @@ typedef struct {
char *get_volume_name(int volume);
#endif
+#ifdef HAVE_MULTIVOLUME
+ int strip_volume(const char*, char*);
+#endif
+
#ifndef DIRFUNCTIONS_DEFINED
extern DIR_UNCACHED* opendir_uncached(const char* name);