diff options
Diffstat (limited to 'arm9/lib')
-rw-r--r-- | arm9/lib/include/FS_archive.h | 5 | ||||
-rw-r--r-- | arm9/lib/include/FS_command.h | 2 | ||||
-rw-r--r-- | arm9/lib/include/FSi_util.h | 7 | ||||
-rw-r--r-- | arm9/lib/src/FS_command.c | 75 |
4 files changed, 89 insertions, 0 deletions
diff --git a/arm9/lib/include/FS_archive.h b/arm9/lib/include/FS_archive.h index d7c2a785..3bbbbff7 100644 --- a/arm9/lib/include/FS_archive.h +++ b/arm9/lib/include/FS_archive.h @@ -175,6 +175,11 @@ static inline BOOL FSi_IsArchiveAsync(volatile const FSArchive * p_arc) return (p_arc->flag & FS_ARCHIVE_FLAG_IS_ASYNC) != 0; } +static inline BOOL FSi_IsArchiveSync(volatile const FSArchive * p_arc) +{ + return (p_arc->flag & FS_ARCHIVE_FLAG_IS_SYNC) != 0; +} + static inline BOOL FS_IsArchiveTableLoaded(volatile const FSArchive * p_arc) { return (p_arc->flag & FS_ARCHIVE_FLAG_TABLE_LOAD) ? TRUE : FALSE; diff --git a/arm9/lib/include/FS_command.h b/arm9/lib/include/FS_command.h index db878f3f..b5e73bcf 100644 --- a/arm9/lib/include/FS_command.h +++ b/arm9/lib/include/FS_command.h @@ -3,6 +3,8 @@ #include "FS_file.h" +extern FSResult (*const fsi_default_command[])(FSFile *); + void FSi_ReleaseCommand(FSFile * file, FSResult signal); FSResult FSi_TranslateCommand(FSFile * file, FSCommandType command); diff --git a/arm9/lib/include/FSi_util.h b/arm9/lib/include/FSi_util.h index 1012df13..1f6faf6f 100644 --- a/arm9/lib/include/FSi_util.h +++ b/arm9/lib/include/FSi_util.h @@ -20,6 +20,13 @@ static inline void FSi_CutFromListCore(FSFileLink *trg) nx->link.prev = pr; } +static inline void FSi_CutFromList(FSFile *elem) +{ + FSFileLink *const trg = &elem->link; + FSi_CutFromListCore(trg); + trg->next = trg->prev = NULL; +} + static inline void FSi_AppendToList(FSFile *elem, FSFile *list) { FSFileLink *const trg = &elem->link; diff --git a/arm9/lib/src/FS_command.c b/arm9/lib/src/FS_command.c new file mode 100644 index 00000000..bc7839d8 --- /dev/null +++ b/arm9/lib/src/FS_command.c @@ -0,0 +1,75 @@ +#include "FS_file.h" +#include "FS_archive.h" +#include "FSi_util.h" +#include "FS_command.h" + +void FSi_ReleaseCommand(FSFile * p_file, FSResult ret) +{ + OSIntrMode bak_psr = OS_DisableInterrupts(); + FSi_CutFromList(p_file); + p_file->stat &= ~(FS_FILE_STATUS_CANCEL | FS_FILE_STATUS_BUSY | FS_FILE_STATUS_SYNC | FS_FILE_STATUS_ASYNC | FS_FILE_STATUS_OPERATING); + p_file->error = ret; + OS_WakeupThread(p_file->queue); + OS_RestoreInterrupts(bak_psr); +} + +FSResult FSi_TranslateCommand(FSFile *p_file, FSCommandType command) +{ + FSResult ret; + + FSArchive *const p_arc = p_file->arc; + const int bit = (1 << command); + + if (FS_IsFileSyncMode(p_file)) + p_arc->flag |= FS_ARCHIVE_FLAG_IS_SYNC; + else + p_arc->flag |= FS_ARCHIVE_FLAG_IS_ASYNC; + + if ((p_arc->proc_flag & bit) != 0) + { + switch (ret = (*p_arc->proc) (p_file, command)) + { + case FS_RESULT_SUCCESS: + case FS_RESULT_FAILURE: + case FS_RESULT_UNSUPPORTED: + p_file->error = ret; + break; + case FS_RESULT_PROC_ASYNC: + break; + case FS_RESULT_PROC_UNKNOWN: + ret = FS_RESULT_PROC_DEFAULT; + p_arc->proc_flag &= ~bit; + break; + } + } + else + { + ret = FS_RESULT_PROC_DEFAULT; + } + if (ret == FS_RESULT_PROC_DEFAULT) + { + ret = (*fsi_default_command[command]) (p_file); + } + if (ret == FS_RESULT_PROC_ASYNC) + { + if (FS_IsFileSyncMode(p_file)) + { + OSIntrMode bak_psr = OS_DisableInterrupts(); + while (FSi_IsArchiveSync(p_arc)) + OS_SleepThread(&p_arc->sync_q); + ret = p_file->error; + OS_RestoreInterrupts(bak_psr); + } + } + else if (!FS_IsFileSyncMode(p_file)) + { + p_arc->flag &= ~FS_ARCHIVE_FLAG_IS_ASYNC; + FSi_ReleaseCommand(p_file, ret); + } + else + { + p_arc->flag &= ~FS_ARCHIVE_FLAG_IS_SYNC; + p_file->error = ret; + } + return ret; +} |