cfs-sdcard.c
00001 #include <efs-sdcard.h>
00002 #include <sys/process.h>
00003 #include <cfs/cfs.h>
00004 #include <debug-uart.h>
00005
00006 #include <stdio.h>
00007
00008
00009
00010 process_event_t sdcard_inserted_event;
00011
00012 process_event_t sdcard_removed_event;
00013
00014
00015
00016 #define MAX_FDS 4
00017
00018 static File file_descriptors[MAX_FDS];
00019
00020 static int
00021 find_free_fd()
00022 {
00023 int fd;
00024 for (fd = 0; fd < MAX_FDS; fd++) {
00025 if (!file_getAttr(&file_descriptors[fd], FILE_STATUS_OPEN)) {
00026 return fd;
00027 }
00028 }
00029 return -1;
00030 }
00031
00032 static File *
00033 get_file(int fd)
00034 {
00035 if (!sdcard_ready()) return 0;
00036 if (fd >= MAX_FDS || fd < 0) return NULL;
00037 if (!file_getAttr(&file_descriptors[fd], FILE_STATUS_OPEN)) return NULL;
00038 return &file_descriptors[fd];
00039 }
00040
00041 int
00042 cfs_open (const char *name, int flags)
00043 {
00044 static int initialized = 0;
00045 eint8 mode;
00046 int fd;
00047 if (!initialized) {
00048 int fd;
00049
00050 for (fd = 0; fd < MAX_FDS; fd++) {
00051 file_setAttr(&file_descriptors[fd], FILE_STATUS_OPEN,0);
00052 }
00053 }
00054 if (!sdcard_ready()) return -1;
00055 fd = find_free_fd();
00056 if (fd < 0) return -1;
00057 if (flags == CFS_READ) {
00058 mode = MODE_READ;
00059 } else {
00060 mode = MODE_APPEND;
00061 }
00062 if (file_fopen(&file_descriptors[fd], efs_sdcard_get_fs(),
00063 (char*)name, mode) < 0) {
00064 return -1;
00065 }
00066 return fd;
00067 }
00068
00069 void
00070 cfs_close(int fd)
00071 {
00072 File *file = get_file(fd);
00073 if (!file) return;
00074 file_fclose(file);
00075 fs_flushFs(efs_sdcard_get_fs());
00076 }
00077
00078 int
00079 cfs_read (int fd, void *buf, unsigned int len)
00080 {
00081 File *file = get_file(fd);
00082 if (!file) return 0;
00083 return file_read(file, len, (euint8*)buf);
00084 }
00085
00086 int
00087 cfs_write (int fd, const void *buf, unsigned int len)
00088 {
00089 File *file = get_file(fd);
00090 if (!file) return 0;
00091 return file_write(file, len, (euint8*)buf);
00092 }
00093
00094 cfs_offset_t
00095 cfs_seek (int fd, cfs_offset_t offset, int whence)
00096 {
00097 File *file;
00098 if (whence != CFS_SEEK_SET) return -1;
00099 file = get_file(fd);
00100 if (!file) return 0;
00101 if (file_setpos(file, offset) != 0) return -1;
00102 return file->FilePtr;
00103 }
00104
00105
00106
00107 #ifdef __GNUC__
00108 #define COMPILE_TIME_CHECK(expr) \
00109 (void) (__builtin_choose_expr ((expr), 0, ((void)0))+3)
00110 #else
00111 #define COMPILE_TIME_CHECK(expr)
00112 #endif
00113
00114 #define MAX_DIR_LISTS 4
00115 DirList dir_lists[MAX_DIR_LISTS];
00116
00117 static DirList *
00118 find_free_dir_list()
00119 {
00120 unsigned int l;
00121 for(l = 0; l < MAX_DIR_LISTS; l++) {
00122 if (dir_lists[l].fs == NULL) {
00123 return &dir_lists[l];
00124 }
00125 }
00126 return NULL;
00127 }
00128
00129 int
00130 cfs_opendir (struct cfs_dir *dirp, const char *name)
00131 {
00132 DirList *dirs;
00133 COMPILE_TIME_CHECK(sizeof(DirList*) <= sizeof(struct cfs_dir));
00134 if (!sdcard_ready()) return -1;
00135 dirs = find_free_dir_list();
00136 if (!dirs) return -1;
00137 if (ls_openDir(dirs, efs_sdcard_get_fs(), (eint8*)name) != 0) {
00138 dirs->fs = NULL;
00139 return -1;
00140 }
00141 *(DirList**)dirp = dirs;
00142 return 0;
00143 }
00144
00145 int
00146 cfs_readdir (struct cfs_dir *dirp, struct cfs_dirent *dirent)
00147 {
00148 euint8 *start;
00149 euint8 *end;
00150 char *to = dirent->name;
00151 DirList *dirs = *(DirList**)dirp;
00152 if (!sdcard_ready()) return 1;
00153 if (ls_getNext(dirs) != 0) return 1;
00154 start = dirs->currentEntry.FileName;
00155 end = start + 7;
00156 while(end > start) {
00157 if (*end > ' ') {
00158 end++;
00159 break;
00160 }
00161 end--;
00162 }
00163 while(start < end) {
00164 *to++ = *start++;
00165 }
00166 start = dirs->currentEntry.FileName + 8;
00167 end = start + 3;
00168 if (*start > ' ') {
00169 *to++ = '.';
00170 *to++ = *start++;
00171 while(start < end && *start > ' ') {
00172 *to++ = *start++;
00173 }
00174 }
00175 *to = '\0';
00176 if (dirs->currentEntry.Attribute & ATTR_DIRECTORY) {
00177 dirent->size = 0;
00178 } else {
00179 dirent->size = dirs->currentEntry.FileSize;
00180 }
00181 return 0;
00182 }
00183
00184 void
00185 cfs_closedir (struct cfs_dir *dirp)
00186 {
00187 (*(DirList**)dirp)->fs = NULL;
00188 }