summaryrefslogtreecommitdiff
path: root/arm9/lib/src/FS_command.c
blob: e677f6c61bbb1989f48402a1f3e4b345a3389289 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include "FS_file.h"
#include "FS_archive.h"
#include "FSi_util.h"
#include "FS_command.h"

ARM_FUNC 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);
    (void)OS_RestoreInterrupts(bak_psr);
}

ARM_FUNC 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;
        default:
            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;
            (void)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;
}