/*----------------------------------------------------------------------------/\r
-/ FatFs - FAT file system module R0.10b (C)ChaN, 2014\r
+/ FatFs - FAT file system module R0.10c (C)ChaN, 2014\r
/-----------------------------------------------------------------------------/\r
/ FatFs module is a generic FAT file system module for small embedded systems.\r
/ This is a free software that opened for education, research and commercial\r
/ Fixed creation of an entry with LFN fails on too many SFN collisions.\r
/ May 19,'14 R0.10b Fixed a hard error in the disk I/O layer can collapse the directory entry.\r
/ Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN.\r
+/ Nov 09,'14 R0.10c Added a configuration option for the platforms without RTC. (_FS_NORTC)\r
+/ Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel().\r
+/ Fixed a potential problem of FAT access that can appear on disk error.\r
+/ Fixed null pointer dereference on attempting to delete the root direcotry.\r
/---------------------------------------------------------------------------*/\r
\r
#include "ff.h" /* Declarations of FatFs API */\r
\r
---------------------------------------------------------------------------*/\r
\r
-#if _FATFS != 8051 /* Revision ID */\r
+#if _FATFS != 80376 /* Revision ID */\r
#error Wrong include file (ff.h).\r
#endif\r
\r
/* Reentrancy related */\r
#if _FS_REENTRANT\r
#if _USE_LFN == 1\r
-#error Static LFN work area cannot be used at thread-safe configuration.\r
+#error Static LFN work area cannot be used at thread-safe configuration\r
#endif\r
#define ENTER_FF(fs) { if (!lock_fs(fs)) return FR_TIMEOUT; }\r
#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; }\r
\r
/* Definitions of sector size */\r
#if (_MAX_SS < _MIN_SS) || (_MAX_SS != 512 && _MAX_SS != 1024 && _MAX_SS != 2048 && _MAX_SS != 4096) || (_MIN_SS != 512 && _MIN_SS != 1024 && _MIN_SS != 2048 && _MIN_SS != 4096)\r
-#error Wrong sector size configuration.\r
+#error Wrong sector size configuration\r
#endif\r
#if _MAX_SS == _MIN_SS\r
#define SS(fs) ((UINT)_MAX_SS) /* Fixed sector size */\r
#endif\r
\r
\r
+/* Timestamp feature */\r
+#if _FS_NORTC\r
+#define GET_FATTIME() ((DWORD)_NORTC_YEAR << 25 | (DWORD)_NORTC_MON << 21 | (DWORD)_NORTC_MDAY << 16)\r
+#else\r
+#define GET_FATTIME() get_fattime()\r
+#endif\r
+\r
+\r
/* File access control feature */\r
#if _FS_LOCK\r
#if _FS_READONLY\r
-#error _FS_LOCK must be 0 at read-only cfg.\r
+#error _FS_LOCK must be 0 at read-only configuration\r
#endif\r
typedef struct {\r
FATFS *fs; /* Object ID 1, volume (NULL:blank entry) */\r
\r
\r
/* Name status flags */\r
-#define NS 11 /* Index of name status byte in fn[] */\r
+#define NSFLAG 11 /* Index of name status byte in fn[] */\r
#define NS_LOSS 0x01 /* Out of 8.3 format */\r
#define NS_LFN 0x02 /* Force to create LFN entry */\r
#define NS_LAST 0x04 /* Last segment */\r
#define NS_DOT 0x20 /* Dot entry */\r
\r
\r
-/* FAT sub-type boundaries */\r
-#define MIN_FAT16 4086U /* Minimum number of clusters for FAT16 */\r
-#define MIN_FAT32 65526U /* Minimum number of clusters for FAT32 */\r
+/* FAT sub-type boundaries (Differ from specs but correct for real DOS/Windows) */\r
+#define MIN_FAT16 4086U /* Minimum number of clusters as FAT16 */\r
+#define MIN_FAT32 65526U /* Minimum number of clusters as FAT32 */\r
\r
\r
/* FatFs refers the members in the FAT structures as byte array instead of\r
/ structure member because the structure is not binary compatible between\r
/ different platforms */\r
\r
-#define BS_jmpBoot 0 /* Jump instruction (3) */\r
+#define BS_jmpBoot 0 /* x86 jump instruction (3) */\r
#define BS_OEMName 3 /* OEM name (8) */\r
#define BPB_BytsPerSec 11 /* Sector size [byte] (2) */\r
#define BPB_SecPerClus 13 /* Cluster size [sector] (1) */\r
/*------------------------------------------------------------*/\r
/* Module private work area */\r
/*------------------------------------------------------------*/\r
-/* Note that uninitialized variables with static duration are\r
-/ guaranteed zero/null as initial value. If not, either the\r
-/ linker or start-up routine is out of ANSI-C standard.\r
+/* Remark: Uninitialized variables with static duration are\r
+/ guaranteed zero/null at start-up. If not, either the linker\r
+/ or start-up routine being used is out of ANSI-C standard.\r
*/\r
\r
-#if _VOLUMES >= 1 || _VOLUMES <= 10\r
-static\r
-FATFS *FatFs[_VOLUMES]; /* Pointer to the file system objects (logical drives) */\r
-#else\r
-#error Number of volumes must be 1 to 10.\r
+#if _VOLUMES < 1 || _VOLUMES > 9\r
+#error Wrong _VOLUMES setting\r
#endif\r
-\r
-static\r
-WORD Fsid; /* File system mount ID */\r
+static FATFS *FatFs[_VOLUMES]; /* Pointer to the file system objects (logical drives) */\r
+static WORD Fsid; /* File system mount ID */\r
\r
#if _FS_RPATH && _VOLUMES >= 2\r
-static\r
-BYTE CurrVol; /* Current drive */\r
+static BYTE CurrVol; /* Current drive */\r
#endif\r
\r
#if _FS_LOCK\r
-static\r
-FILESEM Files[_FS_LOCK]; /* Open object lock semaphores */\r
+static FILESEM Files[_FS_LOCK]; /* Open object lock semaphores */\r
#endif\r
\r
-#if _USE_LFN == 0 /* No LFN feature */\r
+#if _USE_LFN == 0 /* Non LFN feature */\r
#define DEF_NAMEBUF BYTE sfn[12]\r
#define INIT_BUF(dobj) (dobj).fn = sfn\r
#define FREE_BUF()\r
-\r
-#elif _USE_LFN == 1 /* LFN feature with static working buffer */\r
-static\r
-WCHAR LfnBuf[_MAX_LFN+1];\r
+#else\r
+#if _MAX_LFN < 12 || _MAX_LFN > 255\r
+#error Wrong _MAX_LFN setting\r
+#endif\r
+#if _USE_LFN == 1 /* LFN feature with static working buffer */\r
+static WCHAR LfnBuf[_MAX_LFN+1];\r
#define DEF_NAMEBUF BYTE sfn[12]\r
#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = LfnBuf; }\r
#define FREE_BUF()\r
-\r
#elif _USE_LFN == 2 /* LFN feature with dynamic working buffer on the stack */\r
#define DEF_NAMEBUF BYTE sfn[12]; WCHAR lbuf[_MAX_LFN+1]\r
#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = lbuf; }\r
#define FREE_BUF()\r
-\r
#elif _USE_LFN == 3 /* LFN feature with dynamic working buffer on the heap */\r
#define DEF_NAMEBUF BYTE sfn[12]; WCHAR *lfn\r
-#define INIT_BUF(dobj) { lfn = ff_memalloc((_MAX_LFN + 1) * 2); \\r
- if (!lfn) LEAVE_FF((dobj).fs, FR_NOT_ENOUGH_CORE); \\r
- (dobj).lfn = lfn; (dobj).fn = sfn; }\r
+#define INIT_BUF(dobj) { lfn = ff_memalloc((_MAX_LFN + 1) * 2); if (!lfn) LEAVE_FF((dobj).fs, FR_NOT_ENOUGH_CORE); (dobj).lfn = lfn; (dobj).fn = sfn; }\r
#define FREE_BUF() ff_memfree(lfn)\r
-\r
#else\r
-#error Wrong LFN configuration.\r
+#error Wrong _USE_LFN setting\r
+#endif\r
#endif\r
-\r
\r
#ifdef _EXCVT\r
-static\r
-const BYTE ExCvt[] = _EXCVT; /* Upper conversion table for extended characters */\r
+static const BYTE ExCvt[] = _EXCVT; /* Upper conversion table for extended characters */\r
#endif\r
\r
\r
{\r
DWORD wsect;\r
UINT nf;\r
+ FRESULT res = FR_OK;\r
\r
\r
if (fs->wflag) { /* Write back the sector if it is dirty */\r
wsect = fs->winsect; /* Current sector number */\r
- if (disk_write(fs->drv, fs->win, wsect, 1))\r
- return FR_DISK_ERR;\r
- fs->wflag = 0;\r
- if (wsect - fs->fatbase < fs->fsize) { /* Is it in the FAT area? */\r
- for (nf = fs->n_fats; nf >= 2; nf--) { /* Reflect the change to all FAT copies */\r
- wsect += fs->fsize;\r
- disk_write(fs->drv, fs->win, wsect, 1);\r
+ if (disk_write(fs->drv, fs->win, wsect, 1) != RES_OK) {\r
+ res = FR_DISK_ERR;\r
+ } else {\r
+ fs->wflag = 0;\r
+ if (wsect - fs->fatbase < fs->fsize) { /* Is it in the FAT area? */\r
+ for (nf = fs->n_fats; nf >= 2; nf--) { /* Reflect the change to all FAT copies */\r
+ wsect += fs->fsize;\r
+ disk_write(fs->drv, fs->win, wsect, 1);\r
+ }\r
}\r
}\r
}\r
- return FR_OK;\r
+ return res;\r
}\r
#endif\r
\r
DWORD sector /* Sector number to make appearance in the fs->win[] */\r
)\r
{\r
- if (sector != fs->winsect) { /* Changed current window */\r
+ FRESULT res = FR_OK;\r
+\r
+\r
+ if (sector != fs->winsect) { /* Window offset changed? */\r
#if !_FS_READONLY\r
- if (sync_window(fs) != FR_OK)\r
- return FR_DISK_ERR;\r
+ res = sync_window(fs); /* Write-back changes */\r
#endif\r
- if (disk_read(fs->drv, fs->win, sector, 1))\r
- return FR_DISK_ERR;\r
- fs->winsect = sector;\r
+ if (res == FR_OK) { /* Fill sector window with new data */\r
+ if (disk_read(fs->drv, fs->win, sector, 1) != RES_OK) {\r
+ sector = 0xFFFFFFFF; /* Invalidate window if data is not reliable */\r
+ res = FR_DISK_ERR;\r
+ }\r
+ fs->winsect = sector;\r
+ }\r
}\r
-\r
- return FR_OK;\r
+ return res;\r
}\r
\r
\r
/*-----------------------------------------------------------------------*/\r
/* Get sector# from cluster# */\r
/*-----------------------------------------------------------------------*/\r
-\r
+/* Hidden API for hacks and disk tools */\r
\r
DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */\r
FATFS* fs, /* File system object */\r
)\r
{\r
clst -= 2;\r
- if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */\r
+ if (clst >= fs->n_fatent - 2) return 0; /* Invalid cluster# */\r
return clst * fs->csize + fs->database;\r
}\r
\r
/*-----------------------------------------------------------------------*/\r
/* FAT access - Read value of a FAT entry */\r
/*-----------------------------------------------------------------------*/\r
+/* Hidden API for hacks and disk tools */\r
\r
-\r
-DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */\r
+DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x0FFFFFFF:Cluster status */\r
FATFS* fs, /* File system object */\r
- DWORD clst /* Cluster# to get the link information */\r
+ DWORD clst /* FAT item index (cluster#) to get the value */\r
)\r
{\r
UINT wc, bc;\r
BYTE *p;\r
+ DWORD val;\r
\r
\r
- if (clst < 2 || clst >= fs->n_fatent) /* Check range */\r
- return 1;\r
+ if (clst < 2 || clst >= fs->n_fatent) { /* Check range */\r
+ val = 1; /* Internal error */\r
\r
- switch (fs->fs_type) {\r
- case FS_FAT12 :\r
- bc = (UINT)clst; bc += bc / 2;\r
- if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;\r
- wc = fs->win[bc % SS(fs)]; bc++;\r
- if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;\r
- wc |= fs->win[bc % SS(fs)] << 8;\r
- return clst & 1 ? wc >> 4 : (wc & 0xFFF);\r
+ } else {\r
+ val = 0xFFFFFFFF; /* Default value falls on disk error */\r
\r
- case FS_FAT16 :\r
- if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break;\r
- p = &fs->win[clst * 2 % SS(fs)];\r
- return LD_WORD(p);\r
+ switch (fs->fs_type) {\r
+ case FS_FAT12 :\r
+ bc = (UINT)clst; bc += bc / 2;\r
+ if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break;\r
+ wc = fs->win[bc++ % SS(fs)];\r
+ if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break;\r
+ wc |= fs->win[bc % SS(fs)] << 8;\r
+ val = clst & 1 ? wc >> 4 : (wc & 0xFFF);\r
+ break;\r
+\r
+ case FS_FAT16 :\r
+ if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))) != FR_OK) break;\r
+ p = &fs->win[clst * 2 % SS(fs)];\r
+ val = LD_WORD(p);\r
+ break;\r
\r
- case FS_FAT32 :\r
- if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break;\r
- p = &fs->win[clst * 4 % SS(fs)];\r
- return LD_DWORD(p) & 0x0FFFFFFF;\r
+ case FS_FAT32 :\r
+ if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break;\r
+ p = &fs->win[clst * 4 % SS(fs)];\r
+ val = LD_DWORD(p) & 0x0FFFFFFF;\r
+ break;\r
\r
- default:\r
- return 1;\r
+ default:\r
+ val = 1; /* Internal error */\r
+ }\r
}\r
\r
- return 0xFFFFFFFF; /* An error occurred at the disk I/O layer */\r
+ return val;\r
}\r
\r
\r
/*-----------------------------------------------------------------------*/\r
/* FAT access - Change value of a FAT entry */\r
/*-----------------------------------------------------------------------*/\r
-#if !_FS_READONLY\r
+/* Hidden API for hacks and disk tools */\r
\r
+#if !_FS_READONLY\r
FRESULT put_fat (\r
FATFS* fs, /* File system object */\r
- DWORD clst, /* Cluster# to be changed in range of 2 to fs->n_fatent - 1 */\r
+ DWORD clst, /* FAT item index (cluster#) to be set */\r
DWORD val /* New value to mark the cluster */\r
)\r
{\r
bc = (UINT)clst; bc += bc / 2;\r
res = move_window(fs, fs->fatbase + (bc / SS(fs)));\r
if (res != FR_OK) break;\r
- p = &fs->win[bc % SS(fs)];\r
+ p = &fs->win[bc++ % SS(fs)];\r
*p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;\r
- bc++;\r
fs->wflag = 1;\r
res = move_window(fs, fs->fatbase + (bc / SS(fs)));\r
if (res != FR_OK) break;\r
p = &fs->win[bc % SS(fs)];\r
*p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));\r
+ fs->wflag = 1;\r
break;\r
\r
case FS_FAT16 :\r
if (res != FR_OK) break;\r
p = &fs->win[clst * 2 % SS(fs)];\r
ST_WORD(p, (WORD)val);\r
+ fs->wflag = 1;\r
break;\r
\r
case FS_FAT32 :\r
p = &fs->win[clst * 4 % SS(fs)];\r
val |= LD_DWORD(p) & 0xF0000000;\r
ST_DWORD(p, val);\r
+ fs->wflag = 1;\r
break;\r
\r
default :\r
res = FR_INT_ERR;\r
}\r
- fs->wflag = 1;\r
}\r
\r
return res;\r
{\r
FRESULT res;\r
DWORD nxt;\r
-#if _USE_ERASE\r
+#if _USE_TRIM\r
DWORD scl = clst, ecl = clst, rt[2];\r
#endif\r
\r
fs->free_clust++;\r
fs->fsi_flag |= 1;\r
}\r
-#if _USE_ERASE\r
+#if _USE_TRIM\r
if (ecl + 1 == nxt) { /* Is next cluster contiguous? */\r
ecl = nxt;\r
} else { /* End of contiguous clusters */ \r
rt[0] = clust2sect(fs, scl); /* Start sector */\r
rt[1] = clust2sect(fs, ecl) + fs->csize - 1; /* End sector */\r
- disk_ioctl(fs->drv, CTRL_ERASE_SECTOR, rt); /* Erase the block */\r
+ disk_ioctl(fs->drv, CTRL_TRIM, rt); /* Erase the block */\r
scl = ecl = nxt;\r
}\r
#endif\r
do {\r
res = move_window(dp->fs, dp->sect);\r
if (res != FR_OK) break;\r
- if (dp->dir[0] == DDE || dp->dir[0] == 0) { /* Is it a blank entry? */\r
- if (++n == nent) break; /* A block of contiguous entries is found */\r
+ if (dp->dir[0] == DDE || dp->dir[0] == 0) { /* Is it a free entry? */\r
+ if (++n == nent) break; /* A block of contiguous free entries is found */\r
} else {\r
n = 0; /* Not a blank entry. Restart to search */\r
}\r
}\r
} else { /* An SFN entry is found */\r
if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */\r
- if (!(dp->fn[NS] & NS_LOSS) && !mem_cmp(dir, dp->fn, 11)) break; /* SFN matched? */\r
+ if (!(dp->fn[NSFLAG] & NS_LOSS) && !mem_cmp(dir, dp->fn, 11)) break; /* SFN matched? */\r
ord = 0xFF; dp->lfn_idx = 0xFFFF; /* Reset LFN sequence */\r
}\r
}\r
if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */\r
a = dir[DIR_Attr] & AM_MASK;\r
#if _USE_LFN /* LFN configuration */\r
- if (c == DDE || (!_FS_RPATH && c == '.') || (int)(a == AM_VOL) != vol) { /* An entry without valid data */\r
+ if (c == DDE || (!_FS_RPATH && c == '.') || (int)((a & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */\r
ord = 0xFF;\r
} else {\r
if (a == AM_LFN) { /* An LFN entry is found */\r
}\r
}\r
#else /* Non LFN configuration */\r
- if (c != DDE && (_FS_RPATH || c != '.') && a != AM_LFN && (int)(a == AM_VOL) == vol) /* Is it a valid entry? */\r
+ if (c != DDE && (_FS_RPATH || c != '.') && a != AM_LFN && (int)((a & ~AM_ARC) == AM_VOL) == vol) /* Is it a valid entry? */\r
break;\r
#endif\r
res = dir_next(dp, 0); /* Next entry */\r
fn = dp->fn; lfn = dp->lfn;\r
mem_cpy(sn, fn, 12);\r
\r
- if (_FS_RPATH && (sn[NS] & NS_DOT)) /* Cannot create dot entry */\r
+ if (_FS_RPATH && (sn[NSFLAG] & NS_DOT)) /* Cannot create dot entry */\r
return FR_INVALID_NAME;\r
\r
- if (sn[NS] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */\r
- fn[NS] = 0; dp->lfn = 0; /* Find only SFN */\r
+ if (sn[NSFLAG] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */\r
+ fn[NSFLAG] = 0; dp->lfn = 0; /* Find only SFN */\r
for (n = 1; n < 100; n++) {\r
gen_numname(fn, sn, lfn, n); /* Generate a numbered name */\r
res = dir_find(dp); /* Check if the name collides with existing SFN */\r
}\r
if (n == 100) return FR_DENIED; /* Abort if too many collisions */\r
if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */\r
- fn[NS] = sn[NS]; dp->lfn = lfn;\r
+ fn[NSFLAG] = sn[NSFLAG]; dp->lfn = lfn;\r
}\r
\r
- if (sn[NS] & NS_LFN) { /* When LFN is to be created, allocate entries for an SFN + LFNs. */\r
+ if (sn[NSFLAG] & NS_LFN) { /* When LFN is to be created, allocate entries for an SFN + LFNs. */\r
for (n = 0; lfn[n]; n++) ;\r
nent = (n + 25) / 13;\r
} else { /* Otherwise allocate an entry for an SFN */\r
mem_set(dp->dir, 0, SZ_DIR); /* Clean the entry */\r
mem_cpy(dp->dir, dp->fn, 11); /* Put SFN */\r
#if _USE_LFN\r
- dp->dir[DIR_NTres] = dp->fn[NS] & (NS_BODY | NS_EXT); /* Put NT flag */\r
+ dp->dir[DIR_NTres] = dp->fn[NSFLAG] & (NS_BODY | NS_EXT); /* Put NT flag */\r
#endif\r
dp->fs->wflag = 1;\r
}\r
if ((b & 0x0C) == 0x04) cf |= NS_BODY; /* NT flag (Filename has only small capital) */\r
}\r
\r
- dp->fn[NS] = cf; /* SFN is created */\r
+ dp->fn[NSFLAG] = cf; /* SFN is created */\r
\r
return FR_OK;\r
\r
}\r
if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME;\r
*path = &p[si]; /* Return pointer to the next segment */\r
- sfn[NS] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of path */\r
+ sfn[NSFLAG] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of path */\r
return FR_OK;\r
}\r
#endif\r
if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Name extension has only small capital) */\r
if ((b & 0x0C) == 0x04) c |= NS_BODY; /* NT flag (Name body has only small capital) */\r
\r
- sfn[NS] = c; /* Store NT flag, File name is created */\r
+ sfn[NSFLAG] = c; /* Store NT flag, File name is created */\r
\r
return FR_OK;\r
#endif\r
res = create_name(dp, &path); /* Get a segment name of the path */\r
if (res != FR_OK) break;\r
res = dir_find(dp); /* Find an object with the sagment name */\r
- ns = dp->fn[NS];\r
+ ns = dp->fn[NSFLAG];\r
if (res != FR_OK) { /* Failed to find the object */\r
if (res == FR_NO_FILE) { /* Object is not found */\r
if (_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exist, */\r
szbfat = (fmt == FS_FAT16) ? /* (Needed FAT size) */\r
fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);\r
}\r
- if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) /* (BPB_FATSz must not be less than needed) */\r
+ if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) /* (BPB_FATSz must not be less than the size needed) */\r
return FR_NO_FILESYSTEM;\r
\r
#if !_FS_READONLY\r
}\r
}\r
if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */\r
- dw = get_fattime(); /* Created time */\r
+ dw = GET_FATTIME(); /* Created time */\r
ST_DWORD(dir+DIR_CrtTime, dw);\r
dir[DIR_Attr] = 0; /* Reset attribute */\r
ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */\r
if (cc) { /* Read maximum contiguous sectors directly */\r
if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */\r
cc = fp->fs->csize - csect;\r
- if (disk_read(fp->fs->drv, rbuff, sect, cc))\r
+ if (disk_read(fp->fs->drv, rbuff, sect, cc) != RES_OK)\r
ABORT(fp->fs, FR_DISK_ERR);\r
#if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */\r
#if _FS_TINY\r
if (fp->dsect != sect) { /* Load data sector if not in cache */\r
#if !_FS_READONLY\r
if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */\r
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1))\r
+ if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)\r
ABORT(fp->fs, FR_DISK_ERR);\r
fp->flag &= ~FA__DIRTY;\r
}\r
#endif\r
- if (disk_read(fp->fs->drv, fp->buf, sect, 1)) /* Fill sector cache */\r
+ if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) /* Fill sector cache */\r
ABORT(fp->fs, FR_DISK_ERR);\r
}\r
#endif\r
rcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */\r
if (rcnt > btr) rcnt = btr;\r
#if _FS_TINY\r
- if (move_window(fp->fs, fp->dsect)) /* Move sector window */\r
+ if (move_window(fp->fs, fp->dsect) != FR_OK) /* Move sector window */\r
ABORT(fp->fs, FR_DISK_ERR);\r
mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */\r
#else\r
ABORT(fp->fs, FR_DISK_ERR);\r
#else\r
if (fp->flag & FA__DIRTY) { /* Write-back sector cache */\r
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1))\r
+ if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)\r
ABORT(fp->fs, FR_DISK_ERR);\r
fp->flag &= ~FA__DIRTY;\r
}\r
if (cc) { /* Write maximum contiguous sectors directly */\r
if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */\r
cc = fp->fs->csize - csect;\r
- if (disk_write(fp->fs->drv, wbuff, sect, cc))\r
+ if (disk_write(fp->fs->drv, wbuff, sect, cc) != RES_OK)\r
ABORT(fp->fs, FR_DISK_ERR);\r
#if _FS_MINIMIZE <= 2\r
#if _FS_TINY\r
#else\r
if (fp->dsect != sect) { /* Fill sector cache with file data */\r
if (fp->fptr < fp->fsize &&\r
- disk_read(fp->fs->drv, fp->buf, sect, 1))\r
+ disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)\r
ABORT(fp->fs, FR_DISK_ERR);\r
}\r
#endif\r
wcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs));/* Put partial sector into file I/O buffer */\r
if (wcnt > btw) wcnt = btw;\r
#if _FS_TINY\r
- if (move_window(fp->fs, fp->dsect)) /* Move sector window */\r
+ if (move_window(fp->fs, fp->dsect) != FR_OK) /* Move sector window */\r
ABORT(fp->fs, FR_DISK_ERR);\r
mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */\r
fp->fs->wflag = 1;\r
/* Write-back dirty buffer */\r
#if !_FS_TINY\r
if (fp->flag & FA__DIRTY) {\r
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1))\r
+ if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)\r
LEAVE_FF(fp->fs, FR_DISK_ERR);\r
fp->flag &= ~FA__DIRTY;\r
}\r
dir[DIR_Attr] |= AM_ARC; /* Set archive bit */\r
ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */\r
st_clust(dir, fp->sclust); /* Update start cluster */\r
- tm = get_fattime(); /* Update updated time */\r
+ tm = GET_FATTIME(); /* Update updated time */\r
ST_DWORD(dir+DIR_WrtTime, tm);\r
ST_WORD(dir+DIR_LstAccDate, 0);\r
fp->flag &= ~FA__WRITTEN;\r
#if !_FS_TINY\r
#if !_FS_READONLY\r
if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */\r
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1))\r
+ if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)\r
ABORT(fp->fs, FR_DISK_ERR);\r
fp->flag &= ~FA__DIRTY;\r
}\r
#endif\r
- if (disk_read(fp->fs->drv, fp->buf, dsc, 1)) /* Load current sector */\r
+ if (disk_read(fp->fs->drv, fp->buf, dsc, 1) != RES_OK) /* Load current sector */\r
ABORT(fp->fs, FR_DISK_ERR);\r
#endif\r
fp->dsect = dsc;\r
#if !_FS_TINY\r
#if !_FS_READONLY\r
if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */\r
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1))\r
+ if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)\r
ABORT(fp->fs, FR_DISK_ERR);\r
fp->flag &= ~FA__DIRTY;\r
}\r
#endif\r
- if (disk_read(fp->fs->drv, fp->buf, nsect, 1)) /* Fill sector cache */\r
+ if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK) /* Fill sector cache */\r
ABORT(fp->fs, FR_DISK_ERR);\r
#endif\r
fp->dsect = nsect;\r
}\r
#if !_FS_TINY\r
if (res == FR_OK && (fp->flag & FA__DIRTY)) {\r
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1))\r
+ if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)\r
res = FR_DISK_ERR;\r
else\r
fp->flag &= ~FA__DIRTY;\r
FRESULT res;\r
DIR dj, sdj;\r
BYTE *dir;\r
- DWORD dclst;\r
+ DWORD dclst = 0;\r
DEF_NAMEBUF;\r
\r
\r
if (res == FR_OK) {\r
INIT_BUF(dj);\r
res = follow_path(&dj, path); /* Follow the file path */\r
- if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))\r
+ if (_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT))\r
res = FR_INVALID_NAME; /* Cannot remove dot entry */\r
#if _FS_LOCK\r
- if (res == FR_OK) res = chk_lock(&dj, 2); /* Cannot remove open file */\r
+ if (res == FR_OK) res = chk_lock(&dj, 2); /* Cannot remove open object */\r
#endif\r
if (res == FR_OK) { /* The object is accessible */\r
dir = dj.dir;\r
if (!dir) {\r
- res = FR_INVALID_NAME; /* Cannot remove the start directory */\r
+ res = FR_INVALID_NAME; /* Cannot remove the origin directory */\r
} else {\r
if (dir[DIR_Attr] & AM_RDO)\r
res = FR_DENIED; /* Cannot remove R/O object */\r
}\r
- dclst = ld_clust(dj.fs, dir);\r
if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-dir? */\r
- if (dclst < 2) {\r
+ dclst = ld_clust(dj.fs, dir);\r
+ if (!dclst) {\r
res = FR_INT_ERR;\r
- } else {\r
- mem_cpy(&sdj, &dj, sizeof (DIR)); /* Check if the sub-directory is empty or not */\r
+ } else { /* Make sure the sub-directory is empty */\r
+ mem_cpy(&sdj, &dj, sizeof (DIR));\r
sdj.sclust = dclst;\r
res = dir_sdi(&sdj, 2); /* Exclude dot entries */\r
if (res == FR_OK) {\r
res = dir_read(&sdj, 0); /* Read an item */\r
if (res == FR_OK /* Not empty directory */\r
#if _FS_RPATH\r
- || dclst == dj.fs->cdir /* Current directory */\r
+ || dclst == dj.fs->cdir /* or current directory */\r
#endif\r
) res = FR_DENIED;\r
- if (res == FR_NO_FILE) res = FR_OK; /* Empty */\r
+ if (res == FR_NO_FILE) res = FR_OK; /* It is empty */\r
}\r
}\r
}\r
if (res == FR_OK) {\r
res = dir_remove(&dj); /* Remove the directory entry */\r
- if (res == FR_OK) {\r
- if (dclst) /* Remove the cluster chain if exist */\r
- res = remove_chain(dj.fs, dclst);\r
- if (res == FR_OK) res = sync_fs(dj.fs);\r
- }\r
+ if (res == FR_OK && dclst) /* Remove the cluster chain if exist */\r
+ res = remove_chain(dj.fs, dclst);\r
+ if (res == FR_OK) res = sync_fs(dj.fs);\r
}\r
}\r
FREE_BUF();\r
FRESULT res;\r
DIR dj;\r
BYTE *dir, n;\r
- DWORD dsc, dcl, pcl, tm = get_fattime();\r
+ DWORD dsc, dcl, pcl, tm = GET_FATTIME();\r
DEF_NAMEBUF;\r
\r
\r
INIT_BUF(dj);\r
res = follow_path(&dj, path); /* Follow the file path */\r
if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */\r
- if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT))\r
+ if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT))\r
res = FR_INVALID_NAME;\r
if (res == FR_NO_FILE) { /* Can create a new directory */\r
dcl = create_chain(dj.fs, 0); /* Allocate a cluster for the new directory table */\r
INIT_BUF(dj);\r
res = follow_path(&dj, path); /* Follow the file path */\r
FREE_BUF();\r
- if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))\r
+ if (_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT))\r
res = FR_INVALID_NAME;\r
if (res == FR_OK) {\r
dir = dj.dir;\r
\r
\r
\r
-/*-----------------------------------------------------------------------*/\r
-/* Change Timestamp */\r
-/*-----------------------------------------------------------------------*/\r
-\r
-FRESULT f_utime (\r
- const TCHAR* path, /* Pointer to the file/directory name */\r
- const FILINFO* fno /* Pointer to the time stamp to be set */\r
-)\r
-{\r
- FRESULT res;\r
- DIR dj;\r
- BYTE *dir;\r
- DEF_NAMEBUF;\r
-\r
-\r
- /* Get logical drive number */\r
- res = find_volume(&dj.fs, &path, 1);\r
- if (res == FR_OK) {\r
- INIT_BUF(dj);\r
- res = follow_path(&dj, path); /* Follow the file path */\r
- FREE_BUF();\r
- if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))\r
- res = FR_INVALID_NAME;\r
- if (res == FR_OK) {\r
- dir = dj.dir;\r
- if (!dir) { /* Root directory */\r
- res = FR_INVALID_NAME;\r
- } else { /* File or sub-directory */\r
- ST_WORD(dir+DIR_WrtTime, fno->ftime);\r
- ST_WORD(dir+DIR_WrtDate, fno->fdate);\r
- dj.fs->wflag = 1;\r
- res = sync_fs(dj.fs);\r
- }\r
- }\r
- }\r
-\r
- LEAVE_FF(dj.fs, res);\r
-}\r
-\r
-\r
-\r
-\r
/*-----------------------------------------------------------------------*/\r
/* Rename File/Directory */\r
/*-----------------------------------------------------------------------*/\r
djn.fs = djo.fs;\r
INIT_BUF(djo);\r
res = follow_path(&djo, path_old); /* Check old object */\r
- if (_FS_RPATH && res == FR_OK && (djo.fn[NS] & NS_DOT))\r
+ if (_FS_RPATH && res == FR_OK && (djo.fn[NSFLAG] & NS_DOT))\r
res = FR_INVALID_NAME;\r
#if _FS_LOCK\r
if (res == FR_OK) res = chk_lock(&djo, 2);\r
mem_cpy(buf, djo.dir+DIR_Attr, 21); /* Save the object information except name */\r
mem_cpy(&djn, &djo, sizeof (DIR)); /* Duplicate the directory object */\r
if (get_ldnumber(&path_new) >= 0) /* Snip drive number off and ignore it */\r
- res = follow_path(&djn, path_new); /* and check if new object is exist */\r
+ res = follow_path(&djn, path_new); /* and make sure if new object name is not conflicting */\r
else\r
res = FR_INVALID_DRIVE;\r
if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */\r
- if (res == FR_NO_FILE) { /* Is it a valid path and no name collision? */\r
-/* Start critical section that any interruption can cause a cross-link */\r
+ if (res == FR_NO_FILE) { /* It is a valid path and no name collision */\r
+/* Start of critical section that any interruption can cause a cross-link */\r
res = dir_register(&djn); /* Register the new entry */\r
if (res == FR_OK) {\r
dir = djn.dir; /* Copy object information except name */\r
mem_cpy(dir+13, buf+2, 19);\r
dir[DIR_Attr] = buf[0] | AM_ARC;\r
djo.fs->wflag = 1;\r
- if (djo.sclust != djn.sclust && (dir[DIR_Attr] & AM_DIR)) { /* Update .. entry in the directory if needed */\r
+ if ((dir[DIR_Attr] & AM_DIR) && djo.sclust != djn.sclust) { /* Update .. entry in the directory if needed */\r
dw = clust2sect(djo.fs, ld_clust(djo.fs, dir));\r
if (!dw) {\r
res = FR_INT_ERR;\r
res = move_window(djo.fs, dw);\r
dir = djo.fs->win+SZ_DIR; /* .. entry */\r
if (res == FR_OK && dir[1] == '.') {\r
- dw = (djo.fs->fs_type == FS_FAT32 && djn.sclust == djo.fs->dirbase) ? 0 : djn.sclust;\r
- st_clust(dir, dw);\r
+ st_clust(dir, djn.sclust);\r
djo.fs->wflag = 1;\r
}\r
}\r
res = sync_fs(djo.fs);\r
}\r
}\r
-/* End critical section */\r
+/* End of critical section */\r
}\r
}\r
}\r
LEAVE_FF(djo.fs, res);\r
}\r
\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Change Timestamp */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_utime (\r
+ const TCHAR* path, /* Pointer to the file/directory name */\r
+ const FILINFO* fno /* Pointer to the time stamp to be set */\r
+)\r
+{\r
+ FRESULT res;\r
+ DIR dj;\r
+ BYTE *dir;\r
+ DEF_NAMEBUF;\r
+\r
+\r
+ /* Get logical drive number */\r
+ res = find_volume(&dj.fs, &path, 1);\r
+ if (res == FR_OK) {\r
+ INIT_BUF(dj);\r
+ res = follow_path(&dj, path); /* Follow the file path */\r
+ FREE_BUF();\r
+ if (_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT))\r
+ res = FR_INVALID_NAME;\r
+ if (res == FR_OK) {\r
+ dir = dj.dir;\r
+ if (!dir) { /* Root directory */\r
+ res = FR_INVALID_NAME;\r
+ } else { /* File or sub-directory */\r
+ ST_WORD(dir+DIR_WrtTime, fno->ftime);\r
+ ST_WORD(dir+DIR_WrtDate, fno->fdate);\r
+ dj.fs->wflag = 1;\r
+ res = sync_fs(dj.fs);\r
+ }\r
+ }\r
+ }\r
+\r
+ LEAVE_FF(dj.fs, res);\r
+}\r
+\r
#endif /* !_FS_READONLY */\r
#endif /* _FS_MINIMIZE == 0 */\r
#endif /* _FS_MINIMIZE <= 1 */\r
if (res == FR_OK) { /* A volume label is found */\r
if (vn[0]) {\r
mem_cpy(dj.dir, vn, 11); /* Change the volume label name */\r
- tm = get_fattime();\r
+ tm = GET_FATTIME();\r
ST_DWORD(dj.dir+DIR_WrtTime, tm);\r
} else {\r
dj.dir[0] = DDE; /* Remove the volume label */\r
mem_set(dj.dir, 0, SZ_DIR); /* Set volume label */\r
mem_cpy(dj.dir, vn, 11);\r
dj.dir[DIR_Attr] = AM_VOL;\r
- tm = get_fattime();\r
+ tm = GET_FATTIME();\r
ST_DWORD(dj.dir+DIR_WrtTime, tm);\r
dj.fs->wflag = 1;\r
res = sync_fs(dj.fs);\r
sect = clust2sect(fp->fs, fp->clust); /* Get current data sector */\r
if (!sect) ABORT(fp->fs, FR_INT_ERR);\r
sect += csect;\r
- if (move_window(fp->fs, sect)) /* Move sector window */\r
+ if (move_window(fp->fs, sect) != FR_OK) /* Move sector window */\r
ABORT(fp->fs, FR_DISK_ERR);\r
fp->dsect = sect;\r
rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs)); /* Forward data from sector window */\r
/* Create File System on the Drive */\r
/*-----------------------------------------------------------------------*/\r
#define N_ROOTDIR 512 /* Number of root directory entries for FAT12/16 */\r
-#define N_FATS 1 /* Number of FAT copies (1 or 2) */\r
+#define N_FATS 1 /* Number of FATs (1 or 2) */\r
\r
\r
FRESULT f_mkfs (\r
const TCHAR* path, /* Logical drive number */\r
BYTE sfd, /* Partitioning rule 0:FDISK, 1:SFD */\r
- UINT au /* Allocation unit [bytes] */\r
+ UINT au /* Size of allocation unit in unit of byte or sector */\r
)\r
{\r
static const WORD vst[] = { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 0};\r
\r
\r
/* Check mounted drive and clear work area */\r
+ if (sfd > 1) return FR_INVALID_PARAMETER;\r
vol = get_ldnumber(&path);\r
if (vol < 0) return FR_INVALID_DRIVE;\r
- if (sfd > 1) return FR_INVALID_PARAMETER;\r
- if (au & (au - 1)) return FR_INVALID_PARAMETER;\r
fs = FatFs[vol];\r
if (!fs) return FR_NOT_ENABLED;\r
fs->fs_type = 0;\r
#endif\r
if (_MULTI_PARTITION && part) {\r
/* Get partition information from partition table in the MBR */\r
- if (disk_read(pdrv, fs->win, 0, 1)) return FR_DISK_ERR;\r
+ if (disk_read(pdrv, fs->win, 0, 1) != RES_OK) return FR_DISK_ERR;\r
if (LD_WORD(fs->win+BS_55AA) != 0xAA55) return FR_MKFS_ABORTED;\r
tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE];\r
if (!tbl[4]) return FR_MKFS_ABORTED; /* No partition? */\r
n_vol -= b_vol; /* Volume size */\r
}\r
\r
- if (!au) { /* AU auto selection */\r
+ if (au & (au - 1)) au = 0;\r
+ if (!au) { /* AU auto selection */\r
vs = n_vol / (2000 / (SS(fs) / 512));\r
for (i = 0; vs < vst[i]; i++) ;\r
au = cst[i];\r
}\r
- au /= SS(fs); /* Number of sectors per cluster */\r
- if (au == 0) au = 1;\r
+ if (au >= _MIN_SS) au /= SS(fs); /* Number of sectors per cluster */\r
+ if (!au) au = 1;\r
if (au > 128) au = 128;\r
\r
/* Pre-compute number of clusters and FAT sub-type */\r
/* Update system ID in the partition table */\r
tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE];\r
tbl[4] = sys;\r
- if (disk_write(pdrv, fs->win, 0, 1)) /* Write it to teh MBR */\r
+ if (disk_write(pdrv, fs->win, 0, 1) != RES_OK) /* Write it to teh MBR */\r
return FR_DISK_ERR;\r
md = 0xF8;\r
} else {\r
ST_DWORD(tbl+8, 63); /* Partition start in LBA */\r
ST_DWORD(tbl+12, n_vol); /* Partition size in LBA */\r
ST_WORD(fs->win+BS_55AA, 0xAA55); /* MBR signature */\r
- if (disk_write(pdrv, fs->win, 0, 1)) /* Write it to the MBR */\r
+ if (disk_write(pdrv, fs->win, 0, 1) != RES_OK) /* Write it to the MBR */\r
return FR_DISK_ERR;\r
md = 0xF8;\r
}\r
ST_WORD(tbl+BPB_SecPerTrk, 63); /* Number of sectors per track */\r
ST_WORD(tbl+BPB_NumHeads, 255); /* Number of heads */\r
ST_DWORD(tbl+BPB_HiddSec, b_vol); /* Hidden sectors */\r
- n = get_fattime(); /* Use current time as VSN */\r
+ n = GET_FATTIME(); /* Use current time as VSN */\r
if (fmt == FS_FAT32) {\r
ST_DWORD(tbl+BS_VolID32, n); /* VSN */\r
ST_DWORD(tbl+BPB_FATSz32, n_fat); /* Number of sectors per FAT */\r
mem_cpy(tbl+BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */\r
}\r
ST_WORD(tbl+BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */\r
- if (disk_write(pdrv, tbl, b_vol, 1)) /* Write it to the VBR sector */\r
+ if (disk_write(pdrv, tbl, b_vol, 1) != RES_OK) /* Write it to the VBR sector */\r
return FR_DISK_ERR;\r
if (fmt == FS_FAT32) /* Write backup VBR if needed (VBR+6) */\r
disk_write(pdrv, tbl, b_vol + 6, 1);\r
ST_DWORD(tbl+4, 0xFFFFFFFF);\r
ST_DWORD(tbl+8, 0x0FFFFFFF); /* Reserve cluster #2 for root directory */\r
}\r
- if (disk_write(pdrv, tbl, wsect++, 1))\r
+ if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)\r
return FR_DISK_ERR;\r
mem_set(tbl, 0, SS(fs)); /* Fill following FAT entries with zero */\r
for (n = 1; n < n_fat; n++) { /* This loop may take a time on FAT32 volume due to many single sector writes */\r
- if (disk_write(pdrv, tbl, wsect++, 1))\r
+ if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)\r
return FR_DISK_ERR;\r
}\r
}\r
/* Initialize root directory */\r
i = (fmt == FS_FAT32) ? au : (UINT)n_dir;\r
do {\r
- if (disk_write(pdrv, tbl, wsect++, 1))\r
+ if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)\r
return FR_DISK_ERR;\r
} while (--i);\r
\r
-#if _USE_ERASE /* Erase data area if needed */\r
+#if _USE_TRIM /* Erase data area if needed */\r
{\r
DWORD eb[2];\r
\r
eb[0] = wsect; eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1;\r
- disk_ioctl(pdrv, CTRL_ERASE_SECTOR, eb);\r
+ disk_ioctl(pdrv, CTRL_TRIM, eb);\r
}\r
#endif\r
\r
ST_WORD(p, 0xAA55);\r
\r
/* Write it to the MBR */\r
- return (disk_write(pdrv, buf, 0, 1) || disk_ioctl(pdrv, CTRL_SYNC, 0)) ? FR_DISK_ERR : FR_OK;\r
+ return (disk_write(pdrv, buf, 0, 1) != RES_OK || disk_ioctl(pdrv, CTRL_SYNC, 0) != RES_OK) ? FR_DISK_ERR : FR_OK;\r
}\r
\r
\r