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