00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00022 #include "sceptre.h"
00023 #include <stdio.h>
00024 #include "ff.h"
00025 #include "device.h"
00026 #include "sdcard_device_ff.h"
00027 #include "drive.h"
00028
00029
00030 static uint8_t sdcard_allocate_fcb(void);
00031 static int sdcard_open(struct _reent *p_reent, const char *p_name, int flags, int always666);
00032 static int sdcard_close(struct _reent *p_reent, int file);
00033 static _ssize_t sdcard_read(struct _reent *p_reent, int file, void *p_dst, size_t dst_size);
00034 static _ssize_t sdcard_write(struct _reent *p_reent, int file, const void *p_src, size_t src_size);
00035 static int ioctl_dos_seek(struct _reent *p_reent, int file, _off_t pos, int whence);
00036 static int ioctl_dos_unlink(struct _reent *p_reent, char *p_name);
00037 static int ioctl_dos_rename(struct _reent *p_reent, const char *p_old, const char *p_new);
00038 static int ioctl_dos_flush_dir(struct _reent *p_reent, int file);
00039 static int sdcard_ioctl(struct _reent *p_reent, int file, int cmd, void *ptr);
00040 static int sdcard_init(void);
00041
00042
00043 device_table_entry_t sdcard_device =
00044 {
00045 "sdcard",
00046 SCEPTRE_SDCARD,
00047 sdcard_open,
00048 sdcard_close,
00049 sdcard_read,
00050 sdcard_write,
00051 sdcard_init,
00052 sdcard_ioctl
00053 };
00054
00055
00056 extern struct DRIVE_DESCRIPTION Drive;
00057
00058
00059
00060
00061 FIL fcbs[MaxFileBuffers+1];
00062
00063
00064 static uint8_t sdcard_allocate_fcb(void)
00065 {
00066
00067 int i;
00068 for (i=0; i<MaxFileBuffers; i++)
00069 {
00070 if (fcbs[i].BufferInUse!=0) continue;
00071 return i;
00072 }
00073 return -1;
00074 }
00075
00076
00077 static int sdcard_open(struct _reent *p_reent, const char *p_name, int flags, int always666)
00078 {
00079 int result;
00080 unsigned handle;
00081
00082
00083 if (DriveDesc.IsValid==0)
00084 {
00085 p_reent->_errno = ENODEV;
00086 return -1;
00087 }
00088
00089
00090 if ((handle=sdcard_allocate_fcb())==-1)
00091 {
00092 p_reent->_errno = ENOBUFS;
00093 return -1;
00094 }
00095
00096 result = f_open(&fcbs[handle],p_name,flags);
00097 if (result!=0)
00098 {
00099 p_reent->_errno = ~result;
00100 return -1;
00101 }
00102
00103 return DEVICE(SCEPTRE_SDCARD) | handle;
00104 }
00105
00106
00107 static int sdcard_close(struct _reent *p_reent, int file)
00108 {
00109 int result;
00110
00111
00112 if (DriveDesc.IsValid==0)
00113 {
00114 p_reent->_errno = ENODEV;
00115 return -1;
00116 }
00117
00118 result = f_close(&fcbs[file&0xff]);
00119 if (result!=0)
00120 {
00121 p_reent->_errno = ~result;
00122 return -1;
00123 }
00124
00125 return 0;
00126 }
00127
00128
00129 static _ssize_t sdcard_read(struct _reent *p_reent, int file, void *p_dst, size_t dst_size)
00130 {
00131 int result;
00132
00133
00134 if (DriveDesc.IsValid==0)
00135 {
00136 p_reent->_errno = ENODEV;
00137 return -1;
00138 }
00139
00140 result = f_read(&fcbs[file&0xff],p_dst,dst_size);
00141 if (result<0)
00142 {
00143 p_reent->_errno = ~result;
00144 return -1;
00145 }
00146
00147 return result;
00148 }
00149
00150
00151 static _ssize_t sdcard_write(struct _reent *p_reent, int file, const void *p_src, size_t src_size)
00152 {
00153 int result;
00154
00155
00156 if (DriveDesc.IsValid==0)
00157 {
00158 p_reent->_errno = ENODEV;
00159 return -1;
00160 }
00161
00162 result = f_write(&fcbs[file&0xff],p_src,src_size);
00163 if (result<0)
00164 {
00165 p_reent->_errno = ~result;
00166 return -1;
00167 }
00168
00169 return result;
00170 }
00171
00172
00173 static int ioctl_dos_seek(struct _reent *p_reent, int file, _off_t pos, int whence)
00174 {
00175 int result;
00176
00177 switch (whence)
00178 {
00179 case SEEK_SET:
00180 result = f_lseek(&fcbs[file&0xff],pos);
00181 if (result<0)
00182 {
00183 p_reent->_errno = ~result;
00184 return -1;
00185 }
00186 return fcbs[file & 0xff].position;
00187
00188 case SEEK_CUR:
00189 case SEEK_END:
00190 break;
00191 }
00192 p_reent->_errno = EINVAL;
00193 return -1;
00194 }
00195
00196
00197 static int ioctl_dos_unlink(struct _reent *p_reent, char *p_name)
00198 {
00199 int result = f_unlink(p_name);
00200 if (result<0)
00201 {
00202 p_reent->_errno = ~result;
00203 return -1;
00204 }
00205 return 0;
00206 }
00207
00208
00209 static int ioctl_dos_rename(struct _reent *p_reent, const char *p_old, const char *p_new)
00210 {
00211 int result = f_rename(p_old,p_new);
00212 if (result<0)
00213 {
00214 p_reent->_errno = ~result;
00215 return -1;
00216 }
00217 return 0;
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 static int sdcard_ioctl(struct _reent *p_reent, int file, int cmd, void *ptr)
00241 {
00242
00243 if (DriveDesc.IsValid==0)
00244 {
00245 p_reent->_errno = ENODEV;
00246 return -1;
00247 }
00248
00249 switch (cmd)
00250 {
00251 case SDCARD_IOCTL_SEEK:
00252
00253 return ioctl_dos_seek(p_reent,file,*(_off_t*)((long*)ptr)[0],*(int*)((long*)ptr)[1]);
00254
00255 case SDCARD_IOCTL_UNLINK:
00256
00257 return ioctl_dos_unlink(p_reent,(char*)((long*)ptr)[0]);
00258
00259 case SDCARD_IOCTL_RENAME:
00260 return ioctl_dos_rename(p_reent,(const char*)((long*)ptr)[0],(const char*)((long*)ptr)[1]);
00261
00262
00263
00264 }
00265
00266
00267 p_reent->_errno = EINVAL;
00268 return -1;
00269 }
00270
00271
00272 static int sdcard_init(void)
00273 {
00274
00275 return drive_init();
00276 }
00277
00278