BBR 1 Ebene

Committer:
borlanic
Date:
Mon May 14 11:29:06 2018 +0000
Revision:
0:fbdae7e6d805
BBR

Who changed what in which revision?

UserRevisionLine numberNew contents of line
borlanic 0:fbdae7e6d805 1 /* mbed Microcontroller Library
borlanic 0:fbdae7e6d805 2 * Copyright (c) 2006-2012 ARM Limited
borlanic 0:fbdae7e6d805 3 *
borlanic 0:fbdae7e6d805 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
borlanic 0:fbdae7e6d805 5 * of this software and associated documentation files (the "Software"), to deal
borlanic 0:fbdae7e6d805 6 * in the Software without restriction, including without limitation the rights
borlanic 0:fbdae7e6d805 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
borlanic 0:fbdae7e6d805 8 * copies of the Software, and to permit persons to whom the Software is
borlanic 0:fbdae7e6d805 9 * furnished to do so, subject to the following conditions:
borlanic 0:fbdae7e6d805 10 *
borlanic 0:fbdae7e6d805 11 * The above copyright notice and this permission notice shall be included in
borlanic 0:fbdae7e6d805 12 * all copies or substantial portions of the Software.
borlanic 0:fbdae7e6d805 13 *
borlanic 0:fbdae7e6d805 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
borlanic 0:fbdae7e6d805 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
borlanic 0:fbdae7e6d805 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
borlanic 0:fbdae7e6d805 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
borlanic 0:fbdae7e6d805 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
borlanic 0:fbdae7e6d805 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
borlanic 0:fbdae7e6d805 20 * SOFTWARE.
borlanic 0:fbdae7e6d805 21 */
borlanic 0:fbdae7e6d805 22 #include "mbed.h"
borlanic 0:fbdae7e6d805 23
borlanic 0:fbdae7e6d805 24 #include "diskio.h"
borlanic 0:fbdae7e6d805 25 #include "ffconf.h"
borlanic 0:fbdae7e6d805 26 #include "mbed_debug.h"
borlanic 0:fbdae7e6d805 27 #include "mbed_critical.h"
borlanic 0:fbdae7e6d805 28 #include <errno.h>
borlanic 0:fbdae7e6d805 29
borlanic 0:fbdae7e6d805 30 #include "FATFileSystem.h"
borlanic 0:fbdae7e6d805 31
borlanic 0:fbdae7e6d805 32
borlanic 0:fbdae7e6d805 33 ////// Error handling /////
borlanic 0:fbdae7e6d805 34
borlanic 0:fbdae7e6d805 35 static int fat_error_remap(FRESULT res)
borlanic 0:fbdae7e6d805 36 {
borlanic 0:fbdae7e6d805 37 switch(res) {
borlanic 0:fbdae7e6d805 38 case FR_OK: /* (0) Succeeded */
borlanic 0:fbdae7e6d805 39 return 0; /* no error */
borlanic 0:fbdae7e6d805 40 case FR_DISK_ERR: /* (1) A hard error occurred in the low level disk I/O layer */
borlanic 0:fbdae7e6d805 41 case FR_NOT_READY: /* (3) The physical drive cannot work */
borlanic 0:fbdae7e6d805 42 return -EIO; /* I/O error */
borlanic 0:fbdae7e6d805 43 case FR_NO_FILE: /* (4) Could not find the file */
borlanic 0:fbdae7e6d805 44 case FR_NO_PATH: /* (5) Could not find the path */
borlanic 0:fbdae7e6d805 45 case FR_INVALID_NAME: /* (6) The path name format is invalid */
borlanic 0:fbdae7e6d805 46 case FR_INVALID_DRIVE: /* (11) The logical drive number is invalid */
borlanic 0:fbdae7e6d805 47 case FR_NO_FILESYSTEM: /* (13) There is no valid FAT volume */
borlanic 0:fbdae7e6d805 48 return -ENOENT; /* No such file or directory */
borlanic 0:fbdae7e6d805 49 case FR_DENIED: /* (7) Access denied due to prohibited access or directory full */
borlanic 0:fbdae7e6d805 50 return -EACCES; /* Permission denied */
borlanic 0:fbdae7e6d805 51 case FR_EXIST: /* (8) Access denied due to prohibited access */
borlanic 0:fbdae7e6d805 52 return -EEXIST; /* File exists */
borlanic 0:fbdae7e6d805 53 case FR_WRITE_PROTECTED: /* (10) The physical drive is write protected */
borlanic 0:fbdae7e6d805 54 case FR_LOCKED: /* (16) The operation is rejected according to the file sharing policy */
borlanic 0:fbdae7e6d805 55 return -EACCES; /* Permission denied */
borlanic 0:fbdae7e6d805 56 case FR_INVALID_OBJECT: /* (9) The file/directory object is invalid */
borlanic 0:fbdae7e6d805 57 return -EFAULT; /* Bad address */
borlanic 0:fbdae7e6d805 58 case FR_NOT_ENABLED: /* (12) The volume has no work area */
borlanic 0:fbdae7e6d805 59 return -ENXIO; /* No such device or address */
borlanic 0:fbdae7e6d805 60 case FR_NOT_ENOUGH_CORE: /* (17) LFN working buffer could not be allocated */
borlanic 0:fbdae7e6d805 61 return -ENOMEM; /* Not enough space */
borlanic 0:fbdae7e6d805 62 case FR_TOO_MANY_OPEN_FILES: /* (18) Number of open files > _FS_LOCK */
borlanic 0:fbdae7e6d805 63 return -ENFILE; /* Too many open files in system */
borlanic 0:fbdae7e6d805 64 case FR_INVALID_PARAMETER: /* (19) Given parameter is invalid */
borlanic 0:fbdae7e6d805 65 return -ENOEXEC; /* Exec format error */
borlanic 0:fbdae7e6d805 66 case FR_INT_ERR: /* (2) Assertion failed */
borlanic 0:fbdae7e6d805 67 case FR_MKFS_ABORTED: /* (14) The f_mkfs() aborted due to any parameter error */
borlanic 0:fbdae7e6d805 68 case FR_TIMEOUT: /* (15) Could not get a grant to access the volume within defined period */
borlanic 0:fbdae7e6d805 69 default: /* Bad file number */
borlanic 0:fbdae7e6d805 70 return -EBADF;
borlanic 0:fbdae7e6d805 71 }
borlanic 0:fbdae7e6d805 72 }
borlanic 0:fbdae7e6d805 73
borlanic 0:fbdae7e6d805 74 // Helper class for deferring operations when variable falls out of scope
borlanic 0:fbdae7e6d805 75 template <typename T>
borlanic 0:fbdae7e6d805 76 class Deferred {
borlanic 0:fbdae7e6d805 77 public:
borlanic 0:fbdae7e6d805 78 T _t;
borlanic 0:fbdae7e6d805 79 Callback<void(T)> _ondefer;
borlanic 0:fbdae7e6d805 80
borlanic 0:fbdae7e6d805 81 Deferred(const Deferred&);
borlanic 0:fbdae7e6d805 82 Deferred &operator=(const Deferred&);
borlanic 0:fbdae7e6d805 83
borlanic 0:fbdae7e6d805 84 public:
borlanic 0:fbdae7e6d805 85 Deferred(T t, Callback<void(T)> ondefer = NULL)
borlanic 0:fbdae7e6d805 86 : _t(t), _ondefer(ondefer)
borlanic 0:fbdae7e6d805 87 {
borlanic 0:fbdae7e6d805 88 }
borlanic 0:fbdae7e6d805 89
borlanic 0:fbdae7e6d805 90 operator T()
borlanic 0:fbdae7e6d805 91 {
borlanic 0:fbdae7e6d805 92 return _t;
borlanic 0:fbdae7e6d805 93 }
borlanic 0:fbdae7e6d805 94
borlanic 0:fbdae7e6d805 95 ~Deferred()
borlanic 0:fbdae7e6d805 96 {
borlanic 0:fbdae7e6d805 97 if (_ondefer) {
borlanic 0:fbdae7e6d805 98 _ondefer(_t);
borlanic 0:fbdae7e6d805 99 }
borlanic 0:fbdae7e6d805 100 }
borlanic 0:fbdae7e6d805 101 };
borlanic 0:fbdae7e6d805 102
borlanic 0:fbdae7e6d805 103 static void dodelete(const char *data)
borlanic 0:fbdae7e6d805 104 {
borlanic 0:fbdae7e6d805 105 delete[] data;
borlanic 0:fbdae7e6d805 106 }
borlanic 0:fbdae7e6d805 107
borlanic 0:fbdae7e6d805 108 // Adds prefix needed internally by fatfs, this can be avoided for the first fatfs
borlanic 0:fbdae7e6d805 109 // (id 0) otherwise a prefix of "id:/" is inserted in front of the string.
borlanic 0:fbdae7e6d805 110 static Deferred<const char*> fat_path_prefix(int id, const char *path)
borlanic 0:fbdae7e6d805 111 {
borlanic 0:fbdae7e6d805 112 // We can avoid dynamic allocation when only on fatfs is in use
borlanic 0:fbdae7e6d805 113 if (id == 0) {
borlanic 0:fbdae7e6d805 114 return path;
borlanic 0:fbdae7e6d805 115 }
borlanic 0:fbdae7e6d805 116
borlanic 0:fbdae7e6d805 117 // Prefix path with id, will look something like 2:/hi/hello/filehere.txt
borlanic 0:fbdae7e6d805 118 char *buffer = new char[strlen("0:/") + strlen(path) + 1];
borlanic 0:fbdae7e6d805 119 if (!buffer) {
borlanic 0:fbdae7e6d805 120 return NULL;
borlanic 0:fbdae7e6d805 121 }
borlanic 0:fbdae7e6d805 122
borlanic 0:fbdae7e6d805 123 buffer[0] = '0' + id;
borlanic 0:fbdae7e6d805 124 buffer[1] = ':';
borlanic 0:fbdae7e6d805 125 buffer[2] = '/';
borlanic 0:fbdae7e6d805 126 strcpy(buffer + strlen("0:/"), path);
borlanic 0:fbdae7e6d805 127 return Deferred<const char*>(buffer, dodelete);
borlanic 0:fbdae7e6d805 128 }
borlanic 0:fbdae7e6d805 129
borlanic 0:fbdae7e6d805 130
borlanic 0:fbdae7e6d805 131 ////// Disk operations //////
borlanic 0:fbdae7e6d805 132
borlanic 0:fbdae7e6d805 133 // Global access to block device from FAT driver
borlanic 0:fbdae7e6d805 134 static BlockDevice *_ffs[FF_VOLUMES] = {0};
borlanic 0:fbdae7e6d805 135 static SingletonPtr<PlatformMutex> _ffs_mutex;
borlanic 0:fbdae7e6d805 136
borlanic 0:fbdae7e6d805 137
borlanic 0:fbdae7e6d805 138 // FAT driver functions
borlanic 0:fbdae7e6d805 139 DWORD get_fattime(void)
borlanic 0:fbdae7e6d805 140 {
borlanic 0:fbdae7e6d805 141 time_t rawtime;
borlanic 0:fbdae7e6d805 142 time(&rawtime);
borlanic 0:fbdae7e6d805 143 struct tm *ptm = localtime(&rawtime);
borlanic 0:fbdae7e6d805 144 return (DWORD)(ptm->tm_year - 80) << 25
borlanic 0:fbdae7e6d805 145 | (DWORD)(ptm->tm_mon + 1 ) << 21
borlanic 0:fbdae7e6d805 146 | (DWORD)(ptm->tm_mday ) << 16
borlanic 0:fbdae7e6d805 147 | (DWORD)(ptm->tm_hour ) << 11
borlanic 0:fbdae7e6d805 148 | (DWORD)(ptm->tm_min ) << 5
borlanic 0:fbdae7e6d805 149 | (DWORD)(ptm->tm_sec/2 );
borlanic 0:fbdae7e6d805 150 }
borlanic 0:fbdae7e6d805 151
borlanic 0:fbdae7e6d805 152 void *ff_memalloc(UINT size)
borlanic 0:fbdae7e6d805 153 {
borlanic 0:fbdae7e6d805 154 return malloc(size);
borlanic 0:fbdae7e6d805 155 }
borlanic 0:fbdae7e6d805 156
borlanic 0:fbdae7e6d805 157 void ff_memfree(void *p)
borlanic 0:fbdae7e6d805 158 {
borlanic 0:fbdae7e6d805 159 free(p);
borlanic 0:fbdae7e6d805 160 }
borlanic 0:fbdae7e6d805 161
borlanic 0:fbdae7e6d805 162 // Implementation of diskio functions (see ChaN/diskio.h)
borlanic 0:fbdae7e6d805 163 static WORD disk_get_sector_size(BYTE pdrv)
borlanic 0:fbdae7e6d805 164 {
borlanic 0:fbdae7e6d805 165 WORD ssize = _ffs[pdrv]->get_erase_size();
borlanic 0:fbdae7e6d805 166 if (ssize < 512) {
borlanic 0:fbdae7e6d805 167 ssize = 512;
borlanic 0:fbdae7e6d805 168 }
borlanic 0:fbdae7e6d805 169
borlanic 0:fbdae7e6d805 170 MBED_ASSERT(ssize >= FF_MIN_SS && ssize <= FF_MAX_SS);
borlanic 0:fbdae7e6d805 171 MBED_ASSERT(_ffs[pdrv]->get_read_size() <= _ffs[pdrv]->get_erase_size());
borlanic 0:fbdae7e6d805 172 MBED_ASSERT(_ffs[pdrv]->get_program_size() <= _ffs[pdrv]->get_erase_size());
borlanic 0:fbdae7e6d805 173 return ssize;
borlanic 0:fbdae7e6d805 174 }
borlanic 0:fbdae7e6d805 175
borlanic 0:fbdae7e6d805 176 static DWORD disk_get_sector_count(BYTE pdrv)
borlanic 0:fbdae7e6d805 177 {
borlanic 0:fbdae7e6d805 178 DWORD scount = _ffs[pdrv]->size() / disk_get_sector_size(pdrv);
borlanic 0:fbdae7e6d805 179 MBED_ASSERT(scount >= 64);
borlanic 0:fbdae7e6d805 180 return scount;
borlanic 0:fbdae7e6d805 181 }
borlanic 0:fbdae7e6d805 182
borlanic 0:fbdae7e6d805 183 DSTATUS disk_status(BYTE pdrv)
borlanic 0:fbdae7e6d805 184 {
borlanic 0:fbdae7e6d805 185 debug_if(FFS_DBG, "disk_status on pdrv [%d]\n", pdrv);
borlanic 0:fbdae7e6d805 186 return RES_OK;
borlanic 0:fbdae7e6d805 187 }
borlanic 0:fbdae7e6d805 188
borlanic 0:fbdae7e6d805 189 DSTATUS disk_initialize(BYTE pdrv)
borlanic 0:fbdae7e6d805 190 {
borlanic 0:fbdae7e6d805 191 debug_if(FFS_DBG, "disk_initialize on pdrv [%d]\n", pdrv);
borlanic 0:fbdae7e6d805 192 return (DSTATUS)_ffs[pdrv]->init();
borlanic 0:fbdae7e6d805 193 }
borlanic 0:fbdae7e6d805 194
borlanic 0:fbdae7e6d805 195 DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count)
borlanic 0:fbdae7e6d805 196 {
borlanic 0:fbdae7e6d805 197 debug_if(FFS_DBG, "disk_read(sector %d, count %d) on pdrv [%d]\n", sector, count, pdrv);
borlanic 0:fbdae7e6d805 198 DWORD ssize = disk_get_sector_size(pdrv);
borlanic 0:fbdae7e6d805 199 bd_addr_t addr = (bd_addr_t)sector*ssize;
borlanic 0:fbdae7e6d805 200 bd_size_t size = (bd_size_t)count*ssize;
borlanic 0:fbdae7e6d805 201 int err = _ffs[pdrv]->read(buff, addr, size);
borlanic 0:fbdae7e6d805 202 return err ? RES_PARERR : RES_OK;
borlanic 0:fbdae7e6d805 203 }
borlanic 0:fbdae7e6d805 204
borlanic 0:fbdae7e6d805 205 DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count)
borlanic 0:fbdae7e6d805 206 {
borlanic 0:fbdae7e6d805 207 debug_if(FFS_DBG, "disk_write(sector %d, count %d) on pdrv [%d]\n", sector, count, pdrv);
borlanic 0:fbdae7e6d805 208 DWORD ssize = disk_get_sector_size(pdrv);
borlanic 0:fbdae7e6d805 209 bd_addr_t addr = (bd_addr_t)sector*ssize;
borlanic 0:fbdae7e6d805 210 bd_size_t size = (bd_size_t)count*ssize;
borlanic 0:fbdae7e6d805 211 int err = _ffs[pdrv]->erase(addr, size);
borlanic 0:fbdae7e6d805 212 if (err) {
borlanic 0:fbdae7e6d805 213 return RES_PARERR;
borlanic 0:fbdae7e6d805 214 }
borlanic 0:fbdae7e6d805 215
borlanic 0:fbdae7e6d805 216 err = _ffs[pdrv]->program(buff, addr, size);
borlanic 0:fbdae7e6d805 217 if (err) {
borlanic 0:fbdae7e6d805 218 return RES_PARERR;
borlanic 0:fbdae7e6d805 219 }
borlanic 0:fbdae7e6d805 220
borlanic 0:fbdae7e6d805 221 return RES_OK;
borlanic 0:fbdae7e6d805 222 }
borlanic 0:fbdae7e6d805 223
borlanic 0:fbdae7e6d805 224 DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
borlanic 0:fbdae7e6d805 225 {
borlanic 0:fbdae7e6d805 226 debug_if(FFS_DBG, "disk_ioctl(%d)\n", cmd);
borlanic 0:fbdae7e6d805 227 switch (cmd) {
borlanic 0:fbdae7e6d805 228 case CTRL_SYNC:
borlanic 0:fbdae7e6d805 229 if (_ffs[pdrv] == NULL) {
borlanic 0:fbdae7e6d805 230 return RES_NOTRDY;
borlanic 0:fbdae7e6d805 231 } else {
borlanic 0:fbdae7e6d805 232 return RES_OK;
borlanic 0:fbdae7e6d805 233 }
borlanic 0:fbdae7e6d805 234 case GET_SECTOR_COUNT:
borlanic 0:fbdae7e6d805 235 if (_ffs[pdrv] == NULL) {
borlanic 0:fbdae7e6d805 236 return RES_NOTRDY;
borlanic 0:fbdae7e6d805 237 } else {
borlanic 0:fbdae7e6d805 238 *((DWORD*)buff) = disk_get_sector_count(pdrv);
borlanic 0:fbdae7e6d805 239 return RES_OK;
borlanic 0:fbdae7e6d805 240 }
borlanic 0:fbdae7e6d805 241 case GET_SECTOR_SIZE:
borlanic 0:fbdae7e6d805 242 if (_ffs[pdrv] == NULL) {
borlanic 0:fbdae7e6d805 243 return RES_NOTRDY;
borlanic 0:fbdae7e6d805 244 } else {
borlanic 0:fbdae7e6d805 245 *((WORD*)buff) = disk_get_sector_size(pdrv);
borlanic 0:fbdae7e6d805 246 return RES_OK;
borlanic 0:fbdae7e6d805 247 }
borlanic 0:fbdae7e6d805 248 case GET_BLOCK_SIZE:
borlanic 0:fbdae7e6d805 249 *((DWORD*)buff) = 1; // default when not known
borlanic 0:fbdae7e6d805 250 return RES_OK;
borlanic 0:fbdae7e6d805 251 case CTRL_TRIM:
borlanic 0:fbdae7e6d805 252 if (_ffs[pdrv] == NULL) {
borlanic 0:fbdae7e6d805 253 return RES_NOTRDY;
borlanic 0:fbdae7e6d805 254 } else {
borlanic 0:fbdae7e6d805 255 DWORD *sectors = (DWORD*)buff;
borlanic 0:fbdae7e6d805 256 DWORD ssize = disk_get_sector_size(pdrv);
borlanic 0:fbdae7e6d805 257 bd_addr_t addr = (bd_addr_t)sectors[0]*ssize;
borlanic 0:fbdae7e6d805 258 bd_size_t size = (bd_size_t)(sectors[1]-sectors[0]+1)*ssize;
borlanic 0:fbdae7e6d805 259 int err = _ffs[pdrv]->trim(addr, size);
borlanic 0:fbdae7e6d805 260 return err ? RES_PARERR : RES_OK;
borlanic 0:fbdae7e6d805 261 }
borlanic 0:fbdae7e6d805 262 }
borlanic 0:fbdae7e6d805 263
borlanic 0:fbdae7e6d805 264 return RES_PARERR;
borlanic 0:fbdae7e6d805 265 }
borlanic 0:fbdae7e6d805 266
borlanic 0:fbdae7e6d805 267
borlanic 0:fbdae7e6d805 268 ////// Generic filesystem operations //////
borlanic 0:fbdae7e6d805 269
borlanic 0:fbdae7e6d805 270 // Filesystem implementation (See FATFilySystem.h)
borlanic 0:fbdae7e6d805 271 FATFileSystem::FATFileSystem(const char *name, BlockDevice *bd)
borlanic 0:fbdae7e6d805 272 : FileSystem(name), _id(-1) {
borlanic 0:fbdae7e6d805 273 if (bd) {
borlanic 0:fbdae7e6d805 274 mount(bd);
borlanic 0:fbdae7e6d805 275 }
borlanic 0:fbdae7e6d805 276 }
borlanic 0:fbdae7e6d805 277
borlanic 0:fbdae7e6d805 278 FATFileSystem::~FATFileSystem()
borlanic 0:fbdae7e6d805 279 {
borlanic 0:fbdae7e6d805 280 // nop if unmounted
borlanic 0:fbdae7e6d805 281 unmount();
borlanic 0:fbdae7e6d805 282 }
borlanic 0:fbdae7e6d805 283
borlanic 0:fbdae7e6d805 284 int FATFileSystem::mount(BlockDevice *bd)
borlanic 0:fbdae7e6d805 285 {
borlanic 0:fbdae7e6d805 286 // requires duplicate definition to allow virtual overload to work
borlanic 0:fbdae7e6d805 287 return mount(bd, true);
borlanic 0:fbdae7e6d805 288 }
borlanic 0:fbdae7e6d805 289
borlanic 0:fbdae7e6d805 290 int FATFileSystem::mount(BlockDevice *bd, bool mount)
borlanic 0:fbdae7e6d805 291 {
borlanic 0:fbdae7e6d805 292 lock();
borlanic 0:fbdae7e6d805 293 if (_id != -1) {
borlanic 0:fbdae7e6d805 294 unlock();
borlanic 0:fbdae7e6d805 295 return -EINVAL;
borlanic 0:fbdae7e6d805 296 }
borlanic 0:fbdae7e6d805 297
borlanic 0:fbdae7e6d805 298 for (int i = 0; i < FF_VOLUMES; i++) {
borlanic 0:fbdae7e6d805 299 if (!_ffs[i]) {
borlanic 0:fbdae7e6d805 300 _id = i;
borlanic 0:fbdae7e6d805 301 _ffs[_id] = bd;
borlanic 0:fbdae7e6d805 302 _fsid[0] = '0' + _id;
borlanic 0:fbdae7e6d805 303 _fsid[1] = ':';
borlanic 0:fbdae7e6d805 304 _fsid[2] = '\0';
borlanic 0:fbdae7e6d805 305 debug_if(FFS_DBG, "Mounting [%s] on ffs drive [%s]\n", getName(), _fsid);
borlanic 0:fbdae7e6d805 306 FRESULT res = f_mount(&_fs, _fsid, mount);
borlanic 0:fbdae7e6d805 307 unlock();
borlanic 0:fbdae7e6d805 308 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 309 }
borlanic 0:fbdae7e6d805 310 }
borlanic 0:fbdae7e6d805 311
borlanic 0:fbdae7e6d805 312 unlock();
borlanic 0:fbdae7e6d805 313 return -ENOMEM;
borlanic 0:fbdae7e6d805 314 }
borlanic 0:fbdae7e6d805 315
borlanic 0:fbdae7e6d805 316 int FATFileSystem::unmount()
borlanic 0:fbdae7e6d805 317 {
borlanic 0:fbdae7e6d805 318 lock();
borlanic 0:fbdae7e6d805 319 if (_id == -1) {
borlanic 0:fbdae7e6d805 320 unlock();
borlanic 0:fbdae7e6d805 321 return -EINVAL;
borlanic 0:fbdae7e6d805 322 }
borlanic 0:fbdae7e6d805 323
borlanic 0:fbdae7e6d805 324 FRESULT res = f_mount(NULL, _fsid, 0);
borlanic 0:fbdae7e6d805 325 _ffs[_id] = NULL;
borlanic 0:fbdae7e6d805 326 _id = -1;
borlanic 0:fbdae7e6d805 327 unlock();
borlanic 0:fbdae7e6d805 328 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 329 }
borlanic 0:fbdae7e6d805 330
borlanic 0:fbdae7e6d805 331 /* See http://elm-chan.org/fsw/ff/en/mkfs.html for details of f_mkfs() and
borlanic 0:fbdae7e6d805 332 * associated arguments. */
borlanic 0:fbdae7e6d805 333 int FATFileSystem::format(BlockDevice *bd, bd_size_t cluster_size)
borlanic 0:fbdae7e6d805 334 {
borlanic 0:fbdae7e6d805 335 FATFileSystem fs;
borlanic 0:fbdae7e6d805 336 int err = fs.mount(bd, false);
borlanic 0:fbdae7e6d805 337 if (err) {
borlanic 0:fbdae7e6d805 338 return err;
borlanic 0:fbdae7e6d805 339 }
borlanic 0:fbdae7e6d805 340
borlanic 0:fbdae7e6d805 341 // Logical drive number, Partitioning rule, Allocation unit size (bytes per cluster)
borlanic 0:fbdae7e6d805 342 fs.lock();
borlanic 0:fbdae7e6d805 343 FRESULT res = f_mkfs(fs._fsid, FM_ANY | FM_SFD, cluster_size, NULL, 0);
borlanic 0:fbdae7e6d805 344 fs.unlock();
borlanic 0:fbdae7e6d805 345 if (res != FR_OK) {
borlanic 0:fbdae7e6d805 346 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 347 }
borlanic 0:fbdae7e6d805 348
borlanic 0:fbdae7e6d805 349 err = fs.unmount();
borlanic 0:fbdae7e6d805 350 if (err) {
borlanic 0:fbdae7e6d805 351 return err;
borlanic 0:fbdae7e6d805 352 }
borlanic 0:fbdae7e6d805 353
borlanic 0:fbdae7e6d805 354 return 0;
borlanic 0:fbdae7e6d805 355 }
borlanic 0:fbdae7e6d805 356
borlanic 0:fbdae7e6d805 357 int FATFileSystem::reformat(BlockDevice *bd, int allocation_unit)
borlanic 0:fbdae7e6d805 358 {
borlanic 0:fbdae7e6d805 359 lock();
borlanic 0:fbdae7e6d805 360 if (_id != -1) {
borlanic 0:fbdae7e6d805 361 if (!bd) {
borlanic 0:fbdae7e6d805 362 bd = _ffs[_id];
borlanic 0:fbdae7e6d805 363 }
borlanic 0:fbdae7e6d805 364
borlanic 0:fbdae7e6d805 365 int err = unmount();
borlanic 0:fbdae7e6d805 366 if (err) {
borlanic 0:fbdae7e6d805 367 unlock();
borlanic 0:fbdae7e6d805 368 return err;
borlanic 0:fbdae7e6d805 369 }
borlanic 0:fbdae7e6d805 370 }
borlanic 0:fbdae7e6d805 371
borlanic 0:fbdae7e6d805 372 if (!bd) {
borlanic 0:fbdae7e6d805 373 unlock();
borlanic 0:fbdae7e6d805 374 return -ENODEV;
borlanic 0:fbdae7e6d805 375 }
borlanic 0:fbdae7e6d805 376
borlanic 0:fbdae7e6d805 377 int err = FATFileSystem::format(bd, allocation_unit);
borlanic 0:fbdae7e6d805 378 if (err) {
borlanic 0:fbdae7e6d805 379 unlock();
borlanic 0:fbdae7e6d805 380 return err;
borlanic 0:fbdae7e6d805 381 }
borlanic 0:fbdae7e6d805 382
borlanic 0:fbdae7e6d805 383 err = mount(bd);
borlanic 0:fbdae7e6d805 384 unlock();
borlanic 0:fbdae7e6d805 385 return err;
borlanic 0:fbdae7e6d805 386 }
borlanic 0:fbdae7e6d805 387
borlanic 0:fbdae7e6d805 388 int FATFileSystem::remove(const char *path)
borlanic 0:fbdae7e6d805 389 {
borlanic 0:fbdae7e6d805 390 Deferred<const char*> fpath = fat_path_prefix(_id, path);
borlanic 0:fbdae7e6d805 391
borlanic 0:fbdae7e6d805 392 lock();
borlanic 0:fbdae7e6d805 393 FRESULT res = f_unlink(fpath);
borlanic 0:fbdae7e6d805 394 unlock();
borlanic 0:fbdae7e6d805 395
borlanic 0:fbdae7e6d805 396 if (res != FR_OK) {
borlanic 0:fbdae7e6d805 397 debug_if(FFS_DBG, "f_unlink() failed: %d\n", res);
borlanic 0:fbdae7e6d805 398 }
borlanic 0:fbdae7e6d805 399 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 400 }
borlanic 0:fbdae7e6d805 401
borlanic 0:fbdae7e6d805 402 int FATFileSystem::rename(const char *oldpath, const char *newpath)
borlanic 0:fbdae7e6d805 403 {
borlanic 0:fbdae7e6d805 404 Deferred<const char*> oldfpath = fat_path_prefix(_id, oldpath);
borlanic 0:fbdae7e6d805 405 Deferred<const char*> newfpath = fat_path_prefix(_id, newpath);
borlanic 0:fbdae7e6d805 406
borlanic 0:fbdae7e6d805 407 lock();
borlanic 0:fbdae7e6d805 408 FRESULT res = f_rename(oldfpath, newfpath);
borlanic 0:fbdae7e6d805 409 unlock();
borlanic 0:fbdae7e6d805 410
borlanic 0:fbdae7e6d805 411 if (res != FR_OK) {
borlanic 0:fbdae7e6d805 412 debug_if(FFS_DBG, "f_rename() failed: %d\n", res);
borlanic 0:fbdae7e6d805 413 }
borlanic 0:fbdae7e6d805 414 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 415 }
borlanic 0:fbdae7e6d805 416
borlanic 0:fbdae7e6d805 417 int FATFileSystem::mkdir(const char *path, mode_t mode)
borlanic 0:fbdae7e6d805 418 {
borlanic 0:fbdae7e6d805 419 Deferred<const char*> fpath = fat_path_prefix(_id, path);
borlanic 0:fbdae7e6d805 420
borlanic 0:fbdae7e6d805 421 lock();
borlanic 0:fbdae7e6d805 422 FRESULT res = f_mkdir(fpath);
borlanic 0:fbdae7e6d805 423 unlock();
borlanic 0:fbdae7e6d805 424
borlanic 0:fbdae7e6d805 425 if (res != FR_OK) {
borlanic 0:fbdae7e6d805 426 debug_if(FFS_DBG, "f_mkdir() failed: %d\n", res);
borlanic 0:fbdae7e6d805 427 }
borlanic 0:fbdae7e6d805 428 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 429 }
borlanic 0:fbdae7e6d805 430
borlanic 0:fbdae7e6d805 431 int FATFileSystem::stat(const char *path, struct stat *st)
borlanic 0:fbdae7e6d805 432 {
borlanic 0:fbdae7e6d805 433 Deferred<const char*> fpath = fat_path_prefix(_id, path);
borlanic 0:fbdae7e6d805 434
borlanic 0:fbdae7e6d805 435 lock();
borlanic 0:fbdae7e6d805 436 FILINFO f;
borlanic 0:fbdae7e6d805 437 memset(&f, 0, sizeof(f));
borlanic 0:fbdae7e6d805 438
borlanic 0:fbdae7e6d805 439 FRESULT res = f_stat(fpath, &f);
borlanic 0:fbdae7e6d805 440 if (res != FR_OK) {
borlanic 0:fbdae7e6d805 441 unlock();
borlanic 0:fbdae7e6d805 442 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 443 }
borlanic 0:fbdae7e6d805 444
borlanic 0:fbdae7e6d805 445 /* ARMCC doesnt support stat(), and these symbols are not defined by the toolchain. */
borlanic 0:fbdae7e6d805 446 #ifdef TOOLCHAIN_GCC
borlanic 0:fbdae7e6d805 447 st->st_size = f.fsize;
borlanic 0:fbdae7e6d805 448 st->st_mode = 0;
borlanic 0:fbdae7e6d805 449 st->st_mode |= (f.fattrib & AM_DIR) ? S_IFDIR : S_IFREG;
borlanic 0:fbdae7e6d805 450 st->st_mode |= (f.fattrib & AM_RDO) ?
borlanic 0:fbdae7e6d805 451 (S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) :
borlanic 0:fbdae7e6d805 452 (S_IRWXU | S_IRWXG | S_IRWXO);
borlanic 0:fbdae7e6d805 453 #endif /* TOOLCHAIN_GCC */
borlanic 0:fbdae7e6d805 454 unlock();
borlanic 0:fbdae7e6d805 455
borlanic 0:fbdae7e6d805 456 return 0;
borlanic 0:fbdae7e6d805 457 }
borlanic 0:fbdae7e6d805 458
borlanic 0:fbdae7e6d805 459 int FATFileSystem::statvfs(const char *path, struct statvfs *buf)
borlanic 0:fbdae7e6d805 460 {
borlanic 0:fbdae7e6d805 461
borlanic 0:fbdae7e6d805 462 memset(buf, 0, sizeof(struct statvfs));
borlanic 0:fbdae7e6d805 463 FATFS *fs;
borlanic 0:fbdae7e6d805 464 DWORD fre_clust;
borlanic 0:fbdae7e6d805 465
borlanic 0:fbdae7e6d805 466 lock();
borlanic 0:fbdae7e6d805 467 FRESULT res = f_getfree(_fsid, &fre_clust, &fs);
borlanic 0:fbdae7e6d805 468 if (res != FR_OK) {
borlanic 0:fbdae7e6d805 469 unlock();
borlanic 0:fbdae7e6d805 470 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 471 }
borlanic 0:fbdae7e6d805 472
borlanic 0:fbdae7e6d805 473 buf->f_bsize = fs->ssize;
borlanic 0:fbdae7e6d805 474 buf->f_frsize = fs->ssize;
borlanic 0:fbdae7e6d805 475 buf->f_blocks = (fs->n_fatent - 2) * fs->csize;
borlanic 0:fbdae7e6d805 476 buf->f_bfree = fre_clust * fs->csize;
borlanic 0:fbdae7e6d805 477 buf->f_bavail = buf->f_bfree;
borlanic 0:fbdae7e6d805 478 #if FF_USE_LFN
borlanic 0:fbdae7e6d805 479 buf->f_namemax = FF_LFN_BUF;
borlanic 0:fbdae7e6d805 480 #else
borlanic 0:fbdae7e6d805 481 buf->f_namemax = FF_SFN_BUF;
borlanic 0:fbdae7e6d805 482 #endif
borlanic 0:fbdae7e6d805 483
borlanic 0:fbdae7e6d805 484 unlock();
borlanic 0:fbdae7e6d805 485 return 0;
borlanic 0:fbdae7e6d805 486 }
borlanic 0:fbdae7e6d805 487
borlanic 0:fbdae7e6d805 488 void FATFileSystem::lock()
borlanic 0:fbdae7e6d805 489 {
borlanic 0:fbdae7e6d805 490 _ffs_mutex->lock();
borlanic 0:fbdae7e6d805 491 }
borlanic 0:fbdae7e6d805 492
borlanic 0:fbdae7e6d805 493 void FATFileSystem::unlock()
borlanic 0:fbdae7e6d805 494 {
borlanic 0:fbdae7e6d805 495 _ffs_mutex->unlock();
borlanic 0:fbdae7e6d805 496 }
borlanic 0:fbdae7e6d805 497
borlanic 0:fbdae7e6d805 498
borlanic 0:fbdae7e6d805 499 ////// File operations //////
borlanic 0:fbdae7e6d805 500 int FATFileSystem::file_open(fs_file_t *file, const char *path, int flags)
borlanic 0:fbdae7e6d805 501 {
borlanic 0:fbdae7e6d805 502 debug_if(FFS_DBG, "open(%s) on filesystem [%s], drv [%s]\n", path, getName(), _id);
borlanic 0:fbdae7e6d805 503
borlanic 0:fbdae7e6d805 504 FIL *fh = new FIL;
borlanic 0:fbdae7e6d805 505 Deferred<const char*> fpath = fat_path_prefix(_id, path);
borlanic 0:fbdae7e6d805 506
borlanic 0:fbdae7e6d805 507 /* POSIX flags -> FatFS open mode */
borlanic 0:fbdae7e6d805 508 BYTE openmode;
borlanic 0:fbdae7e6d805 509 if (flags & O_RDWR) {
borlanic 0:fbdae7e6d805 510 openmode = FA_READ | FA_WRITE;
borlanic 0:fbdae7e6d805 511 } else if (flags & O_WRONLY) {
borlanic 0:fbdae7e6d805 512 openmode = FA_WRITE;
borlanic 0:fbdae7e6d805 513 } else {
borlanic 0:fbdae7e6d805 514 openmode = FA_READ;
borlanic 0:fbdae7e6d805 515 }
borlanic 0:fbdae7e6d805 516
borlanic 0:fbdae7e6d805 517 if (flags & O_CREAT) {
borlanic 0:fbdae7e6d805 518 if (flags & O_TRUNC) {
borlanic 0:fbdae7e6d805 519 openmode |= FA_CREATE_ALWAYS;
borlanic 0:fbdae7e6d805 520 } else {
borlanic 0:fbdae7e6d805 521 openmode |= FA_OPEN_ALWAYS;
borlanic 0:fbdae7e6d805 522 }
borlanic 0:fbdae7e6d805 523 }
borlanic 0:fbdae7e6d805 524
borlanic 0:fbdae7e6d805 525 if (flags & O_APPEND) {
borlanic 0:fbdae7e6d805 526 openmode |= FA_OPEN_APPEND;
borlanic 0:fbdae7e6d805 527 }
borlanic 0:fbdae7e6d805 528
borlanic 0:fbdae7e6d805 529 lock();
borlanic 0:fbdae7e6d805 530 FRESULT res = f_open(fh, fpath, openmode);
borlanic 0:fbdae7e6d805 531
borlanic 0:fbdae7e6d805 532 if (res != FR_OK) {
borlanic 0:fbdae7e6d805 533 unlock();
borlanic 0:fbdae7e6d805 534 debug_if(FFS_DBG, "f_open('w') failed: %d\n", res);
borlanic 0:fbdae7e6d805 535 delete fh;
borlanic 0:fbdae7e6d805 536 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 537 }
borlanic 0:fbdae7e6d805 538
borlanic 0:fbdae7e6d805 539 unlock();
borlanic 0:fbdae7e6d805 540
borlanic 0:fbdae7e6d805 541 *file = fh;
borlanic 0:fbdae7e6d805 542 return 0;
borlanic 0:fbdae7e6d805 543 }
borlanic 0:fbdae7e6d805 544
borlanic 0:fbdae7e6d805 545 int FATFileSystem::file_close(fs_file_t file)
borlanic 0:fbdae7e6d805 546 {
borlanic 0:fbdae7e6d805 547 FIL *fh = static_cast<FIL*>(file);
borlanic 0:fbdae7e6d805 548
borlanic 0:fbdae7e6d805 549 lock();
borlanic 0:fbdae7e6d805 550 FRESULT res = f_close(fh);
borlanic 0:fbdae7e6d805 551 unlock();
borlanic 0:fbdae7e6d805 552
borlanic 0:fbdae7e6d805 553 delete fh;
borlanic 0:fbdae7e6d805 554 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 555 }
borlanic 0:fbdae7e6d805 556
borlanic 0:fbdae7e6d805 557 ssize_t FATFileSystem::file_read(fs_file_t file, void *buffer, size_t len)
borlanic 0:fbdae7e6d805 558 {
borlanic 0:fbdae7e6d805 559 FIL *fh = static_cast<FIL*>(file);
borlanic 0:fbdae7e6d805 560
borlanic 0:fbdae7e6d805 561 lock();
borlanic 0:fbdae7e6d805 562 UINT n;
borlanic 0:fbdae7e6d805 563 FRESULT res = f_read(fh, buffer, len, &n);
borlanic 0:fbdae7e6d805 564 unlock();
borlanic 0:fbdae7e6d805 565
borlanic 0:fbdae7e6d805 566 if (res != FR_OK) {
borlanic 0:fbdae7e6d805 567 debug_if(FFS_DBG, "f_read() failed: %d\n", res);
borlanic 0:fbdae7e6d805 568 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 569 } else {
borlanic 0:fbdae7e6d805 570 return n;
borlanic 0:fbdae7e6d805 571 }
borlanic 0:fbdae7e6d805 572 }
borlanic 0:fbdae7e6d805 573
borlanic 0:fbdae7e6d805 574 ssize_t FATFileSystem::file_write(fs_file_t file, const void *buffer, size_t len)
borlanic 0:fbdae7e6d805 575 {
borlanic 0:fbdae7e6d805 576 FIL *fh = static_cast<FIL*>(file);
borlanic 0:fbdae7e6d805 577
borlanic 0:fbdae7e6d805 578 lock();
borlanic 0:fbdae7e6d805 579 UINT n;
borlanic 0:fbdae7e6d805 580 FRESULT res = f_write(fh, buffer, len, &n);
borlanic 0:fbdae7e6d805 581 unlock();
borlanic 0:fbdae7e6d805 582
borlanic 0:fbdae7e6d805 583 if (res != FR_OK) {
borlanic 0:fbdae7e6d805 584 debug_if(FFS_DBG, "f_write() failed: %d", res);
borlanic 0:fbdae7e6d805 585 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 586 } else {
borlanic 0:fbdae7e6d805 587 return n;
borlanic 0:fbdae7e6d805 588 }
borlanic 0:fbdae7e6d805 589 }
borlanic 0:fbdae7e6d805 590
borlanic 0:fbdae7e6d805 591 int FATFileSystem::file_sync(fs_file_t file)
borlanic 0:fbdae7e6d805 592 {
borlanic 0:fbdae7e6d805 593 FIL *fh = static_cast<FIL*>(file);
borlanic 0:fbdae7e6d805 594
borlanic 0:fbdae7e6d805 595 lock();
borlanic 0:fbdae7e6d805 596 FRESULT res = f_sync(fh);
borlanic 0:fbdae7e6d805 597 unlock();
borlanic 0:fbdae7e6d805 598
borlanic 0:fbdae7e6d805 599 if (res != FR_OK) {
borlanic 0:fbdae7e6d805 600 debug_if(FFS_DBG, "f_sync() failed: %d\n", res);
borlanic 0:fbdae7e6d805 601 }
borlanic 0:fbdae7e6d805 602 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 603 }
borlanic 0:fbdae7e6d805 604
borlanic 0:fbdae7e6d805 605 off_t FATFileSystem::file_seek(fs_file_t file, off_t offset, int whence)
borlanic 0:fbdae7e6d805 606 {
borlanic 0:fbdae7e6d805 607 FIL *fh = static_cast<FIL*>(file);
borlanic 0:fbdae7e6d805 608
borlanic 0:fbdae7e6d805 609 lock();
borlanic 0:fbdae7e6d805 610 if (whence == SEEK_END) {
borlanic 0:fbdae7e6d805 611 offset += f_size(fh);
borlanic 0:fbdae7e6d805 612 } else if(whence==SEEK_CUR) {
borlanic 0:fbdae7e6d805 613 offset += f_tell(fh);
borlanic 0:fbdae7e6d805 614 }
borlanic 0:fbdae7e6d805 615
borlanic 0:fbdae7e6d805 616 FRESULT res = f_lseek(fh, offset);
borlanic 0:fbdae7e6d805 617 off_t noffset = fh->fptr;
borlanic 0:fbdae7e6d805 618 unlock();
borlanic 0:fbdae7e6d805 619
borlanic 0:fbdae7e6d805 620 if (res != FR_OK) {
borlanic 0:fbdae7e6d805 621 debug_if(FFS_DBG, "lseek failed: %d\n", res);
borlanic 0:fbdae7e6d805 622 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 623 } else {
borlanic 0:fbdae7e6d805 624 return noffset;
borlanic 0:fbdae7e6d805 625 }
borlanic 0:fbdae7e6d805 626 }
borlanic 0:fbdae7e6d805 627
borlanic 0:fbdae7e6d805 628 off_t FATFileSystem::file_tell(fs_file_t file)
borlanic 0:fbdae7e6d805 629 {
borlanic 0:fbdae7e6d805 630 FIL *fh = static_cast<FIL*>(file);
borlanic 0:fbdae7e6d805 631
borlanic 0:fbdae7e6d805 632 lock();
borlanic 0:fbdae7e6d805 633 off_t res = f_tell(fh);
borlanic 0:fbdae7e6d805 634 unlock();
borlanic 0:fbdae7e6d805 635
borlanic 0:fbdae7e6d805 636 return res;
borlanic 0:fbdae7e6d805 637 }
borlanic 0:fbdae7e6d805 638
borlanic 0:fbdae7e6d805 639 off_t FATFileSystem::file_size(fs_file_t file)
borlanic 0:fbdae7e6d805 640 {
borlanic 0:fbdae7e6d805 641 FIL *fh = static_cast<FIL*>(file);
borlanic 0:fbdae7e6d805 642
borlanic 0:fbdae7e6d805 643 lock();
borlanic 0:fbdae7e6d805 644 off_t res = f_size(fh);
borlanic 0:fbdae7e6d805 645 unlock();
borlanic 0:fbdae7e6d805 646
borlanic 0:fbdae7e6d805 647 return res;
borlanic 0:fbdae7e6d805 648 }
borlanic 0:fbdae7e6d805 649
borlanic 0:fbdae7e6d805 650
borlanic 0:fbdae7e6d805 651 ////// Dir operations //////
borlanic 0:fbdae7e6d805 652 int FATFileSystem::dir_open(fs_dir_t *dir, const char *path)
borlanic 0:fbdae7e6d805 653 {
borlanic 0:fbdae7e6d805 654 FATFS_DIR *dh = new FATFS_DIR;
borlanic 0:fbdae7e6d805 655 Deferred<const char*> fpath = fat_path_prefix(_id, path);
borlanic 0:fbdae7e6d805 656
borlanic 0:fbdae7e6d805 657 lock();
borlanic 0:fbdae7e6d805 658 FRESULT res = f_opendir(dh, fpath);
borlanic 0:fbdae7e6d805 659 unlock();
borlanic 0:fbdae7e6d805 660
borlanic 0:fbdae7e6d805 661 if (res != FR_OK) {
borlanic 0:fbdae7e6d805 662 debug_if(FFS_DBG, "f_opendir() failed: %d\n", res);
borlanic 0:fbdae7e6d805 663 delete dh;
borlanic 0:fbdae7e6d805 664 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 665 }
borlanic 0:fbdae7e6d805 666
borlanic 0:fbdae7e6d805 667 *dir = dh;
borlanic 0:fbdae7e6d805 668 return 0;
borlanic 0:fbdae7e6d805 669 }
borlanic 0:fbdae7e6d805 670
borlanic 0:fbdae7e6d805 671 int FATFileSystem::dir_close(fs_dir_t dir)
borlanic 0:fbdae7e6d805 672 {
borlanic 0:fbdae7e6d805 673 FATFS_DIR *dh = static_cast<FATFS_DIR*>(dir);
borlanic 0:fbdae7e6d805 674
borlanic 0:fbdae7e6d805 675 lock();
borlanic 0:fbdae7e6d805 676 FRESULT res = f_closedir(dh);
borlanic 0:fbdae7e6d805 677 unlock();
borlanic 0:fbdae7e6d805 678
borlanic 0:fbdae7e6d805 679 delete dh;
borlanic 0:fbdae7e6d805 680 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 681 }
borlanic 0:fbdae7e6d805 682
borlanic 0:fbdae7e6d805 683 ssize_t FATFileSystem::dir_read(fs_dir_t dir, struct dirent *ent)
borlanic 0:fbdae7e6d805 684 {
borlanic 0:fbdae7e6d805 685 FATFS_DIR *dh = static_cast<FATFS_DIR*>(dir);
borlanic 0:fbdae7e6d805 686 FILINFO finfo;
borlanic 0:fbdae7e6d805 687
borlanic 0:fbdae7e6d805 688 lock();
borlanic 0:fbdae7e6d805 689 FRESULT res = f_readdir(dh, &finfo);
borlanic 0:fbdae7e6d805 690 unlock();
borlanic 0:fbdae7e6d805 691
borlanic 0:fbdae7e6d805 692 if (res != FR_OK) {
borlanic 0:fbdae7e6d805 693 return fat_error_remap(res);
borlanic 0:fbdae7e6d805 694 } else if (finfo.fname[0] == 0) {
borlanic 0:fbdae7e6d805 695 return 0;
borlanic 0:fbdae7e6d805 696 }
borlanic 0:fbdae7e6d805 697
borlanic 0:fbdae7e6d805 698 ent->d_type = (finfo.fattrib & AM_DIR) ? DT_DIR : DT_REG;
borlanic 0:fbdae7e6d805 699
borlanic 0:fbdae7e6d805 700 #if FF_USE_LFN
borlanic 0:fbdae7e6d805 701 if (ent->d_name[0] == 0) {
borlanic 0:fbdae7e6d805 702 // No long filename so use short filename.
borlanic 0:fbdae7e6d805 703 strncpy(ent->d_name, finfo.fname, FF_LFN_BUF);
borlanic 0:fbdae7e6d805 704 }
borlanic 0:fbdae7e6d805 705 #else
borlanic 0:fbdae7e6d805 706 strncpy(ent->d_name, finfo.fname, FF_SFN_BUF);
borlanic 0:fbdae7e6d805 707 #endif
borlanic 0:fbdae7e6d805 708
borlanic 0:fbdae7e6d805 709 return 1;
borlanic 0:fbdae7e6d805 710 }
borlanic 0:fbdae7e6d805 711
borlanic 0:fbdae7e6d805 712 void FATFileSystem::dir_seek(fs_dir_t dir, off_t offset)
borlanic 0:fbdae7e6d805 713 {
borlanic 0:fbdae7e6d805 714 FATFS_DIR *dh = static_cast<FATFS_DIR*>(dir);
borlanic 0:fbdae7e6d805 715 off_t dptr = static_cast<off_t>(dh->dptr);
borlanic 0:fbdae7e6d805 716
borlanic 0:fbdae7e6d805 717 lock();
borlanic 0:fbdae7e6d805 718
borlanic 0:fbdae7e6d805 719 if (offset < dptr) {
borlanic 0:fbdae7e6d805 720 f_rewinddir(dh);
borlanic 0:fbdae7e6d805 721 }
borlanic 0:fbdae7e6d805 722 while (dptr < offset) {
borlanic 0:fbdae7e6d805 723 FILINFO finfo;
borlanic 0:fbdae7e6d805 724 FRESULT res;
borlanic 0:fbdae7e6d805 725
borlanic 0:fbdae7e6d805 726 res = f_readdir(dh, &finfo);
borlanic 0:fbdae7e6d805 727 dptr = dh->dptr;
borlanic 0:fbdae7e6d805 728 if (res != FR_OK) {
borlanic 0:fbdae7e6d805 729 break;
borlanic 0:fbdae7e6d805 730 } else if (finfo.fname[0] == 0) {
borlanic 0:fbdae7e6d805 731 break;
borlanic 0:fbdae7e6d805 732 }
borlanic 0:fbdae7e6d805 733 }
borlanic 0:fbdae7e6d805 734 unlock();
borlanic 0:fbdae7e6d805 735 }
borlanic 0:fbdae7e6d805 736
borlanic 0:fbdae7e6d805 737 off_t FATFileSystem::dir_tell(fs_dir_t dir)
borlanic 0:fbdae7e6d805 738 {
borlanic 0:fbdae7e6d805 739 FATFS_DIR *dh = static_cast<FATFS_DIR*>(dir);
borlanic 0:fbdae7e6d805 740
borlanic 0:fbdae7e6d805 741 lock();
borlanic 0:fbdae7e6d805 742 off_t offset = dh->dptr;
borlanic 0:fbdae7e6d805 743 unlock();
borlanic 0:fbdae7e6d805 744
borlanic 0:fbdae7e6d805 745 return offset;
borlanic 0:fbdae7e6d805 746 }
borlanic 0:fbdae7e6d805 747
borlanic 0:fbdae7e6d805 748 void FATFileSystem::dir_rewind(fs_dir_t dir)
borlanic 0:fbdae7e6d805 749 {
borlanic 0:fbdae7e6d805 750 FATFS_DIR *dh = static_cast<FATFS_DIR*>(dir);
borlanic 0:fbdae7e6d805 751
borlanic 0:fbdae7e6d805 752 lock();
borlanic 0:fbdae7e6d805 753 f_rewinddir(dh);
borlanic 0:fbdae7e6d805 754 unlock();
borlanic 0:fbdae7e6d805 755 }
borlanic 0:fbdae7e6d805 756