mirror of
https://github.com/CTCaer/hekate.git
synced 2024-11-23 02:16:41 +00:00
[FatFS] Add error printing for important functions
So much needed
This commit is contained in:
parent
dcb77115c9
commit
526ffd4414
1 changed files with 164 additions and 39 deletions
203
ipl/ff.c
203
ipl/ff.c
|
@ -3,6 +3,7 @@
|
||||||
/-----------------------------------------------------------------------------/
|
/-----------------------------------------------------------------------------/
|
||||||
/
|
/
|
||||||
/ Copyright (C) 2017, ChaN, all right reserved.
|
/ Copyright (C) 2017, ChaN, all right reserved.
|
||||||
|
/ Copyright (c) 2018 naehrwert
|
||||||
/
|
/
|
||||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||||
/ source and binary forms, with or without modification, are permitted provided
|
/ source and binary forms, with or without modification, are permitted provided
|
||||||
|
@ -22,6 +23,11 @@
|
||||||
#include "ff.h" /* Declarations of FatFs API */
|
#include "ff.h" /* Declarations of FatFs API */
|
||||||
#include "diskio.h" /* Declarations of device I/O functions */
|
#include "diskio.h" /* Declarations of device I/O functions */
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
extern gfx_ctxt_t gfx_ctxt;
|
||||||
|
extern gfx_con_t gfx_con;
|
||||||
|
#define EFSPRINTF(text, ...) gfx_printf(&gfx_con, "\n\n%k[FatFS] "text"%k\n", 0xFF00FFFF, 0xFFFFFFFF)
|
||||||
|
//#define EFSPRINTF(...)
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -3253,6 +3259,7 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */
|
||||||
stat = disk_status(fs->pdrv);
|
stat = disk_status(fs->pdrv);
|
||||||
if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */
|
if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */
|
||||||
if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check write protection if needed */
|
if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check write protection if needed */
|
||||||
|
EFSPRINTF("Error: Write protected!");
|
||||||
return FR_WRITE_PROTECTED;
|
return FR_WRITE_PROTECTED;
|
||||||
}
|
}
|
||||||
return FR_OK; /* The filesystem object is valid */
|
return FR_OK; /* The filesystem object is valid */
|
||||||
|
@ -3266,9 +3273,11 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */
|
||||||
fs->pdrv = LD2PD(vol); /* Bind the logical drive and a physical drive */
|
fs->pdrv = LD2PD(vol); /* Bind the logical drive and a physical drive */
|
||||||
stat = disk_initialize(fs->pdrv); /* Initialize the physical drive */
|
stat = disk_initialize(fs->pdrv); /* Initialize the physical drive */
|
||||||
if (stat & STA_NOINIT) { /* Check if the initialization succeeded */
|
if (stat & STA_NOINIT) { /* Check if the initialization succeeded */
|
||||||
|
EFSPRINTF("Error: Medium not ready or hard error!");
|
||||||
return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */
|
return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */
|
||||||
}
|
}
|
||||||
if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check disk write protection if needed */
|
if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check disk write protection if needed */
|
||||||
|
EFSPRINTF("Error: Write protected!");
|
||||||
return FR_WRITE_PROTECTED;
|
return FR_WRITE_PROTECTED;
|
||||||
}
|
}
|
||||||
#if FF_MAX_SS != FF_MIN_SS /* Get sector size (multiple sector size cfg only) */
|
#if FF_MAX_SS != FF_MIN_SS /* Get sector size (multiple sector size cfg only) */
|
||||||
|
@ -3291,8 +3300,14 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */
|
||||||
fmt = bsect ? check_fs(fs, bsect) : 3; /* Check the partition */
|
fmt = bsect ? check_fs(fs, bsect) : 3; /* Check the partition */
|
||||||
} while (LD2PT(vol) == 0 && fmt >= 2 && ++i < 4);
|
} while (LD2PT(vol) == 0 && fmt >= 2 && ++i < 4);
|
||||||
}
|
}
|
||||||
if (fmt == 4) return FR_DISK_ERR; /* An error occured in the disk I/O layer */
|
if (fmt == 4) {
|
||||||
if (fmt >= 2) return FR_NO_FILESYSTEM; /* No FAT volume is found */
|
EFSPRINTF("Error: Disk I/O error - Could not load boot record!");
|
||||||
|
return FR_DISK_ERR; /* An error occured in the disk I/O layer */
|
||||||
|
}
|
||||||
|
if (fmt >= 2) {
|
||||||
|
EFSPRINTF("Error: No FAT/FAT32/exFAT filesystem found!");
|
||||||
|
return FR_NO_FILESYSTEM; /* No FAT volume is found */
|
||||||
|
}
|
||||||
|
|
||||||
/* An FAT volume is found (bsect). Following code initializes the filesystem object */
|
/* An FAT volume is found (bsect). Following code initializes the filesystem object */
|
||||||
|
|
||||||
|
@ -3303,36 +3318,58 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */
|
||||||
for (i = BPB_ZeroedEx; i < BPB_ZeroedEx + 53 && fs->win[i] == 0; i++) ; /* Check zero filler */
|
for (i = BPB_ZeroedEx; i < BPB_ZeroedEx + 53 && fs->win[i] == 0; i++) ; /* Check zero filler */
|
||||||
if (i < BPB_ZeroedEx + 53) return FR_NO_FILESYSTEM;
|
if (i < BPB_ZeroedEx + 53) return FR_NO_FILESYSTEM;
|
||||||
|
|
||||||
if (ld_word(fs->win + BPB_FSVerEx) != 0x100) return FR_NO_FILESYSTEM; /* Check exFAT version (must be version 1.0) */
|
if (ld_word(fs->win + BPB_FSVerEx) != 0x100) {
|
||||||
|
EFSPRINTF("Error: exFAT - Version check failed!");
|
||||||
|
return FR_NO_FILESYSTEM; /* Check exFAT version (must be version 1.0) */
|
||||||
|
}
|
||||||
|
|
||||||
if (1 << fs->win[BPB_BytsPerSecEx] != SS(fs)) { /* (BPB_BytsPerSecEx must be equal to the physical sector size) */
|
if (1 << fs->win[BPB_BytsPerSecEx] != SS(fs)) { /* (BPB_BytsPerSecEx must be equal to the physical sector size) */
|
||||||
|
EFSPRINTF("Error: exFAT - Bytes per sector does not match physical sector size!");
|
||||||
return FR_NO_FILESYSTEM;
|
return FR_NO_FILESYSTEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
maxlba = ld_qword(fs->win + BPB_TotSecEx) + bsect; /* Last LBA + 1 of the volume */
|
maxlba = ld_qword(fs->win + BPB_TotSecEx) + bsect; /* Last LBA + 1 of the volume */
|
||||||
if (maxlba >= 0x100000000) return FR_NO_FILESYSTEM; /* (It cannot be handled in 32-bit LBA) */
|
if (maxlba >= 0x100000000) {
|
||||||
|
EFSPRINTF("Error: exFAT - Cannot handle volume LBA with 32-bit LBA!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (It cannot be handled in 32-bit LBA) */
|
||||||
|
}
|
||||||
|
|
||||||
fs->fsize = ld_dword(fs->win + BPB_FatSzEx); /* Number of sectors per FAT */
|
fs->fsize = ld_dword(fs->win + BPB_FatSzEx); /* Number of sectors per FAT */
|
||||||
|
|
||||||
fs->n_fats = fs->win[BPB_NumFATsEx]; /* Number of FATs */
|
fs->n_fats = fs->win[BPB_NumFATsEx]; /* Number of FATs */
|
||||||
if (fs->n_fats != 1) return FR_NO_FILESYSTEM; /* (Supports only 1 FAT) */
|
if (fs->n_fats != 1) {
|
||||||
|
EFSPRINTF("Error: exFAT - Multiple or no file allocation tables found!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (Supports only 1 FAT) */
|
||||||
|
}
|
||||||
|
|
||||||
fs->csize = 1 << fs->win[BPB_SecPerClusEx]; /* Cluster size */
|
fs->csize = 1 << fs->win[BPB_SecPerClusEx]; /* Cluster size */
|
||||||
if (fs->csize == 0) return FR_NO_FILESYSTEM; /* (Must be 1..32768) */
|
if (fs->csize == 0) {
|
||||||
|
EFSPRINTF("Error: exFAT - Cluster size is not between 1KB - 32KB!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (Must be 1..32768) */
|
||||||
|
}
|
||||||
|
|
||||||
nclst = ld_dword(fs->win + BPB_NumClusEx); /* Number of clusters */
|
nclst = ld_dword(fs->win + BPB_NumClusEx); /* Number of clusters */
|
||||||
if (nclst > MAX_EXFAT) return FR_NO_FILESYSTEM; /* (Too many clusters) */
|
if (nclst > MAX_EXFAT) {
|
||||||
|
EFSPRINTF("Error: exFAT - Total clusters exceed allowed!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (Too many clusters) */
|
||||||
|
}
|
||||||
fs->n_fatent = nclst + 2;
|
fs->n_fatent = nclst + 2;
|
||||||
|
|
||||||
/* Boundaries and Limits */
|
/* Boundaries and Limits */
|
||||||
fs->volbase = bsect;
|
fs->volbase = bsect;
|
||||||
fs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx);
|
fs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx);
|
||||||
fs->fatbase = bsect + ld_dword(fs->win + BPB_FatOfsEx);
|
fs->fatbase = bsect + ld_dword(fs->win + BPB_FatOfsEx);
|
||||||
if (maxlba < (QWORD)fs->database + nclst * fs->csize) return FR_NO_FILESYSTEM; /* (Volume size must not be smaller than the size requiered) */
|
if (maxlba < (QWORD)fs->database + nclst * fs->csize) {
|
||||||
|
EFSPRINTF("Error: exFAT - Volume size is lower than required!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (Volume size must not be smaller than the size required) */
|
||||||
|
}
|
||||||
fs->dirbase = ld_dword(fs->win + BPB_RootClusEx);
|
fs->dirbase = ld_dword(fs->win + BPB_RootClusEx);
|
||||||
|
|
||||||
/* Check if bitmap location is in assumption (at the first cluster) */
|
/* Check if bitmap location is in assumption (at the first cluster) */
|
||||||
if (move_window(fs, clst2sect(fs, fs->dirbase)) != FR_OK) return FR_DISK_ERR;
|
if (move_window(fs, clst2sect(fs, fs->dirbase)) != FR_OK) {
|
||||||
|
EFSPRINTF("Error: exFAT - Bitmap location not at first cluster!");
|
||||||
|
return FR_DISK_ERR;
|
||||||
|
}
|
||||||
for (i = 0; i < SS(fs); i += SZDIRE) {
|
for (i = 0; i < SS(fs); i += SZDIRE) {
|
||||||
if (fs->win[i] == 0x81 && ld_dword(fs->win + i + 20) == 2) break; /* 81 entry with cluster #2? */
|
if (fs->win[i] == 0x81 && ld_dword(fs->win + i + 20) == 2) break; /* 81 entry with cluster #2? */
|
||||||
}
|
}
|
||||||
|
@ -3344,38 +3381,62 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */
|
||||||
} else
|
} else
|
||||||
#endif /* FF_FS_EXFAT */
|
#endif /* FF_FS_EXFAT */
|
||||||
{
|
{
|
||||||
if (ld_word(fs->win + BPB_BytsPerSec) != SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_BytsPerSec must be equal to the physical sector size) */
|
if (ld_word(fs->win + BPB_BytsPerSec) != SS(fs)) {
|
||||||
|
EFSPRINTF("Error: FAT - Bytes per sector does not match physical sector size!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (BPB_BytsPerSec must be equal to the physical sector size) */
|
||||||
|
}
|
||||||
|
|
||||||
fasize = ld_word(fs->win + BPB_FATSz16); /* Number of sectors per FAT */
|
fasize = ld_word(fs->win + BPB_FATSz16); /* Number of sectors per FAT */
|
||||||
if (fasize == 0) fasize = ld_dword(fs->win + BPB_FATSz32);
|
if (fasize == 0) fasize = ld_dword(fs->win + BPB_FATSz32);
|
||||||
fs->fsize = fasize;
|
fs->fsize = fasize;
|
||||||
|
|
||||||
fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */
|
fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */
|
||||||
if (fs->n_fats != 1 && fs->n_fats != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */
|
if (fs->n_fats != 1 && fs->n_fats != 2) {
|
||||||
|
EFSPRINTF("Error: FAT - No or more than 2 file allocation tables found!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */
|
||||||
|
}
|
||||||
fasize *= fs->n_fats; /* Number of sectors for FAT area */
|
fasize *= fs->n_fats; /* Number of sectors for FAT area */
|
||||||
|
|
||||||
fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */
|
fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */
|
||||||
if (fs->csize == 0 || (fs->csize & (fs->csize - 1))) return FR_NO_FILESYSTEM; /* (Must be power of 2) */
|
if (fs->csize == 0 || (fs->csize & (fs->csize - 1))) {
|
||||||
|
EFSPRINTF("Error: FAT - Cluster size is not a power of 2!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (Must be power of 2) */
|
||||||
|
}
|
||||||
|
|
||||||
fs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt); /* Number of root directory entries */
|
fs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt); /* Number of root directory entries */
|
||||||
if (fs->n_rootdir % (SS(fs) / SZDIRE)) return FR_NO_FILESYSTEM; /* (Must be sector aligned) */
|
if (fs->n_rootdir % (SS(fs) / SZDIRE)) {
|
||||||
|
EFSPRINTF("Error: FAT - Root directory entries are not sector aligned!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (Must be sector aligned) */
|
||||||
|
}
|
||||||
|
|
||||||
tsect = ld_word(fs->win + BPB_TotSec16); /* Number of sectors on the volume */
|
tsect = ld_word(fs->win + BPB_TotSec16); /* Number of sectors on the volume */
|
||||||
if (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32);
|
if (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32);
|
||||||
|
|
||||||
nrsv = ld_word(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */
|
nrsv = ld_word(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */
|
||||||
if (nrsv == 0) return FR_NO_FILESYSTEM; /* (Must not be 0) */
|
if (nrsv == 0) {
|
||||||
|
EFSPRINTF("Error: FAT - Zero reserved sectors!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (Must not be 0) */
|
||||||
|
}
|
||||||
|
|
||||||
/* Determine the FAT sub type */
|
/* Determine the FAT sub type */
|
||||||
sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE); /* RSV + FAT + DIR */
|
sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE); /* RSV + FAT + DIR */
|
||||||
if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */
|
if (tsect < sysect) {
|
||||||
|
EFSPRINTF("Error: FAT - Invalid volume size!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (Invalid volume size) */
|
||||||
|
}
|
||||||
nclst = (tsect - sysect) / fs->csize; /* Number of clusters */
|
nclst = (tsect - sysect) / fs->csize; /* Number of clusters */
|
||||||
if (nclst == 0) return FR_NO_FILESYSTEM; /* (Invalid volume size) */
|
if (nclst == 0) {
|
||||||
|
EFSPRINTF("Error: FAT - Invalid volume size!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (Invalid volume size) */
|
||||||
|
}
|
||||||
fmt = 0;
|
fmt = 0;
|
||||||
if (nclst <= MAX_FAT32) fmt = FS_FAT32;
|
if (nclst <= MAX_FAT32) fmt = FS_FAT32;
|
||||||
if (nclst <= MAX_FAT16) fmt = FS_FAT16;
|
if (nclst <= MAX_FAT16) fmt = FS_FAT16;
|
||||||
if (nclst <= MAX_FAT12) fmt = FS_FAT12;
|
if (nclst <= MAX_FAT12) fmt = FS_FAT12;
|
||||||
if (fmt == 0) return FR_NO_FILESYSTEM;
|
if (fmt == 0) {
|
||||||
|
EFSPRINTF("Error: FAT - Not compatible FAT12/16/32 filesystem!");
|
||||||
|
return FR_NO_FILESYSTEM;
|
||||||
|
}
|
||||||
|
|
||||||
/* Boundaries and Limits */
|
/* Boundaries and Limits */
|
||||||
fs->n_fatent = nclst + 2; /* Number of FAT entries */
|
fs->n_fatent = nclst + 2; /* Number of FAT entries */
|
||||||
|
@ -3383,17 +3444,29 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */
|
||||||
fs->fatbase = bsect + nrsv; /* FAT start sector */
|
fs->fatbase = bsect + nrsv; /* FAT start sector */
|
||||||
fs->database = bsect + sysect; /* Data start sector */
|
fs->database = bsect + sysect; /* Data start sector */
|
||||||
if (fmt == FS_FAT32) {
|
if (fmt == FS_FAT32) {
|
||||||
if (ld_word(fs->win + BPB_FSVer32) != 0) return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) */
|
if (ld_word(fs->win + BPB_FSVer32) != 0) {
|
||||||
if (fs->n_rootdir != 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */
|
EFSPRINTF("Error: FAT32 - Not a 0.0 revision!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) */
|
||||||
|
}
|
||||||
|
if (fs->n_rootdir != 0) {
|
||||||
|
EFSPRINTF("Error: FAT32 - Root entry sector is not 0!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */
|
||||||
|
}
|
||||||
fs->dirbase = ld_dword(fs->win + BPB_RootClus32); /* Root directory start cluster */
|
fs->dirbase = ld_dword(fs->win + BPB_RootClus32); /* Root directory start cluster */
|
||||||
szbfat = fs->n_fatent * 4; /* (Needed FAT size) */
|
szbfat = fs->n_fatent * 4; /* (Needed FAT size) */
|
||||||
} else {
|
} else {
|
||||||
if (fs->n_rootdir == 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */
|
if (fs->n_rootdir == 0) {
|
||||||
|
EFSPRINTF("Error: FAT - Root entry sector is 0!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */
|
||||||
|
}
|
||||||
fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */
|
fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */
|
||||||
szbfat = (fmt == FS_FAT16) ? /* (Needed FAT size) */
|
szbfat = (fmt == FS_FAT16) ? /* (Needed FAT size) */
|
||||||
fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);
|
fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);
|
||||||
}
|
}
|
||||||
if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_FATSz must not be less than the size needed) */
|
if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) {
|
||||||
|
EFSPRINTF("Error: FAT - FAT size is not the required size!");
|
||||||
|
return FR_NO_FILESYSTEM; /* (BPB_FATSz must not be less than the size needed) */
|
||||||
|
}
|
||||||
|
|
||||||
#if !FF_FS_READONLY
|
#if !FF_FS_READONLY
|
||||||
/* Get FSInfo if available */
|
/* Get FSInfo if available */
|
||||||
|
@ -3426,7 +3499,7 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */
|
||||||
#if FF_USE_LFN == 1
|
#if FF_USE_LFN == 1
|
||||||
fs->lfnbuf = LfnBuf; /* Static LFN working buffer */
|
fs->lfnbuf = LfnBuf; /* Static LFN working buffer */
|
||||||
#if FF_FS_EXFAT
|
#if FF_FS_EXFAT
|
||||||
fs->dirbuf = DirBuf; /* Static directory block scratchpad buuffer */
|
fs->dirbuf = DirBuf; /* Static directory block scratch-pad buffer */
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if FF_FS_RPATH != 0
|
#if FF_FS_RPATH != 0
|
||||||
|
@ -3504,7 +3577,10 @@ FRESULT f_mount (
|
||||||
|
|
||||||
/* Get logical drive number */
|
/* Get logical drive number */
|
||||||
vol = get_ldnumber(&rp);
|
vol = get_ldnumber(&rp);
|
||||||
if (vol < 0) return FR_INVALID_DRIVE;
|
if (vol < 0) {
|
||||||
|
EFSPRINTF("Error: Invalid drive!");
|
||||||
|
return FR_INVALID_DRIVE;
|
||||||
|
}
|
||||||
cfs = FatFs[vol]; /* Pointer to fs object */
|
cfs = FatFs[vol]; /* Pointer to fs object */
|
||||||
|
|
||||||
if (cfs) {
|
if (cfs) {
|
||||||
|
@ -3745,8 +3821,14 @@ FRESULT f_read (
|
||||||
|
|
||||||
*br = 0; /* Clear read byte counter */
|
*br = 0; /* Clear read byte counter */
|
||||||
res = validate(&fp->obj, &fs); /* Check validity of the file object */
|
res = validate(&fp->obj, &fs); /* Check validity of the file object */
|
||||||
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */
|
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
|
||||||
if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
|
EFSPRINTF("Error: File object Validation!");
|
||||||
|
LEAVE_FF(fs, res); /* Check validity */
|
||||||
|
}
|
||||||
|
if (!(fp->flag & FA_READ)) {
|
||||||
|
EFSPRINTF("Error: Access denied!");
|
||||||
|
LEAVE_FF(fs, FR_DENIED); /* Check access mode */
|
||||||
|
}
|
||||||
remain = fp->obj.objsize - fp->fptr;
|
remain = fp->obj.objsize - fp->fptr;
|
||||||
if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */
|
if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */
|
||||||
|
|
||||||
|
@ -3767,19 +3849,31 @@ FRESULT f_read (
|
||||||
clst = get_fat(&fp->obj, fp->clust); /* Follow cluster chain on the FAT */
|
clst = get_fat(&fp->obj, fp->clust); /* Follow cluster chain on the FAT */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (clst < 2) ABORT(fs, FR_INT_ERR);
|
if (clst < 2) {
|
||||||
if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
|
EFSPRINTF("Error: Cluster status check or Internal error!");
|
||||||
|
ABORT(fs, FR_INT_ERR);
|
||||||
|
}
|
||||||
|
if (clst == 0xFFFFFFFF) {
|
||||||
|
EFSPRINTF("Error: Disk error (cluster hard error)!");
|
||||||
|
ABORT(fs, FR_DISK_ERR);
|
||||||
|
}
|
||||||
fp->clust = clst; /* Update current cluster */
|
fp->clust = clst; /* Update current cluster */
|
||||||
}
|
}
|
||||||
sect = clst2sect(fs, fp->clust); /* Get current sector */
|
sect = clst2sect(fs, fp->clust); /* Get current sector */
|
||||||
if (sect == 0) ABORT(fs, FR_INT_ERR);
|
if (sect == 0) {
|
||||||
|
EFSPRINTF("Error: Get current sector error!");
|
||||||
|
ABORT(fs, FR_INT_ERR);
|
||||||
|
}
|
||||||
sect += csect;
|
sect += csect;
|
||||||
cc = btr / SS(fs); /* When remaining bytes >= sector size, */
|
cc = btr / SS(fs); /* When remaining bytes >= sector size, */
|
||||||
if (cc > 0) { /* Read maximum contiguous sectors directly */
|
if (cc > 0) { /* Read maximum contiguous sectors directly */
|
||||||
if (csect + cc > fs->csize) { /* Clip at cluster boundary */
|
if (csect + cc > fs->csize) { /* Clip at cluster boundary */
|
||||||
cc = fs->csize - csect;
|
cc = fs->csize - csect;
|
||||||
}
|
}
|
||||||
if (disk_read(fs->pdrv, rbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR);
|
if (disk_read(fs->pdrv, rbuff, sect, cc) != RES_OK) {
|
||||||
|
EFSPRINTF("Error: Read - Low level disk I/O!");
|
||||||
|
ABORT(fs, FR_DISK_ERR);
|
||||||
|
}
|
||||||
#if !FF_FS_READONLY && FF_FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */
|
#if !FF_FS_READONLY && FF_FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */
|
||||||
#if FF_FS_TINY
|
#if FF_FS_TINY
|
||||||
if (fs->wflag && fs->winsect - sect < cc) {
|
if (fs->wflag && fs->winsect - sect < cc) {
|
||||||
|
@ -3798,11 +3892,17 @@ FRESULT f_read (
|
||||||
if (fp->sect != sect) { /* Load data sector if not in cache */
|
if (fp->sect != sect) { /* Load data sector if not in cache */
|
||||||
#if !FF_FS_READONLY
|
#if !FF_FS_READONLY
|
||||||
if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */
|
if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */
|
||||||
if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
|
if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) {
|
||||||
|
EFSPRINTF("Error: Write-back dirty sector cache!");
|
||||||
|
ABORT(fs, FR_DISK_ERR);
|
||||||
|
}
|
||||||
fp->flag &= (BYTE)~FA_DIRTY;
|
fp->flag &= (BYTE)~FA_DIRTY;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */
|
if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) {
|
||||||
|
EFSPRINTF("Error: Read - Low level disk I/O!\n(fill sector cache)");
|
||||||
|
ABORT(fs, FR_DISK_ERR); /* Fill sector cache */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
fp->sect = sect;
|
fp->sect = sect;
|
||||||
|
@ -3844,8 +3944,14 @@ FRESULT f_write (
|
||||||
|
|
||||||
*bw = 0; /* Clear write byte counter */
|
*bw = 0; /* Clear write byte counter */
|
||||||
res = validate(&fp->obj, &fs); /* Check validity of the file object */
|
res = validate(&fp->obj, &fs); /* Check validity of the file object */
|
||||||
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */
|
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
|
||||||
if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
|
EFSPRINTF("Error: File object Validation!");
|
||||||
|
LEAVE_FF(fs, res); /* Check validity */
|
||||||
|
}
|
||||||
|
if (!(fp->flag & FA_WRITE)) {
|
||||||
|
EFSPRINTF("Error: Access denied!");
|
||||||
|
LEAVE_FF(fs, FR_DENIED); /* Check access mode */
|
||||||
|
}
|
||||||
|
|
||||||
/* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */
|
/* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */
|
||||||
if ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) {
|
if ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) {
|
||||||
|
@ -3872,9 +3978,18 @@ FRESULT f_write (
|
||||||
clst = create_chain(&fp->obj, fp->clust); /* Follow or stretch cluster chain on the FAT */
|
clst = create_chain(&fp->obj, fp->clust); /* Follow or stretch cluster chain on the FAT */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (clst == 0) break; /* Could not allocate a new cluster (disk full) */
|
if (clst == 0) {
|
||||||
if (clst == 1) ABORT(fs, FR_INT_ERR);
|
EFSPRINTF("Error: Could not allocate a new cluster\n(disk full or low level disk I/O error)!");
|
||||||
if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
|
break; /* Could not allocate a new cluster (disk full) */
|
||||||
|
}
|
||||||
|
if (clst == 1) {
|
||||||
|
EFSPRINTF("Error: Cluster status check or Internal error!");
|
||||||
|
ABORT(fs, FR_INT_ERR);
|
||||||
|
}
|
||||||
|
if (clst == 0xFFFFFFFF) {
|
||||||
|
EFSPRINTF("Error: Disk error (cluster hard error)!");
|
||||||
|
ABORT(fs, FR_DISK_ERR);
|
||||||
|
}
|
||||||
fp->clust = clst; /* Update current cluster */
|
fp->clust = clst; /* Update current cluster */
|
||||||
if (fp->obj.sclust == 0) fp->obj.sclust = clst; /* Set start cluster if the first write */
|
if (fp->obj.sclust == 0) fp->obj.sclust = clst; /* Set start cluster if the first write */
|
||||||
}
|
}
|
||||||
|
@ -3882,19 +3997,28 @@ FRESULT f_write (
|
||||||
if (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Write-back sector cache */
|
if (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Write-back sector cache */
|
||||||
#else
|
#else
|
||||||
if (fp->flag & FA_DIRTY) { /* Write-back sector cache */
|
if (fp->flag & FA_DIRTY) { /* Write-back sector cache */
|
||||||
if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
|
if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) {
|
||||||
|
EFSPRINTF("Error: Write-back sector cache!");
|
||||||
|
ABORT(fs, FR_DISK_ERR);
|
||||||
|
}
|
||||||
fp->flag &= (BYTE)~FA_DIRTY;
|
fp->flag &= (BYTE)~FA_DIRTY;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
sect = clst2sect(fs, fp->clust); /* Get current sector */
|
sect = clst2sect(fs, fp->clust); /* Get current sector */
|
||||||
if (sect == 0) ABORT(fs, FR_INT_ERR);
|
if (sect == 0) {
|
||||||
|
EFSPRINTF("Error: Get current sector error!");
|
||||||
|
ABORT(fs, FR_INT_ERR);
|
||||||
|
}
|
||||||
sect += csect;
|
sect += csect;
|
||||||
cc = btw / SS(fs); /* When remaining bytes >= sector size, */
|
cc = btw / SS(fs); /* When remaining bytes >= sector size, */
|
||||||
if (cc > 0) { /* Write maximum contiguous sectors directly */
|
if (cc > 0) { /* Write maximum contiguous sectors directly */
|
||||||
if (csect + cc > fs->csize) { /* Clip at cluster boundary */
|
if (csect + cc > fs->csize) { /* Clip at cluster boundary */
|
||||||
cc = fs->csize - csect;
|
cc = fs->csize - csect;
|
||||||
}
|
}
|
||||||
if (disk_write(fs->pdrv, wbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR);
|
if (disk_write(fs->pdrv, wbuff, sect, cc) != RES_OK) {
|
||||||
|
EFSPRINTF("Error: Write - Low level disk I/O!");
|
||||||
|
ABORT(fs, FR_DISK_ERR);
|
||||||
|
}
|
||||||
#if FF_FS_MINIMIZE <= 2
|
#if FF_FS_MINIMIZE <= 2
|
||||||
#if FF_FS_TINY
|
#if FF_FS_TINY
|
||||||
if (fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
|
if (fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
|
||||||
|
@ -3920,6 +4044,7 @@ FRESULT f_write (
|
||||||
if (fp->sect != sect && /* Fill sector cache with file data */
|
if (fp->sect != sect && /* Fill sector cache with file data */
|
||||||
fp->fptr < fp->obj.objsize &&
|
fp->fptr < fp->obj.objsize &&
|
||||||
disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) {
|
disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) {
|
||||||
|
EFSPRINTF("Error: Read - Low level disk I/O!\n(Could not fill sector cache with file data)");
|
||||||
ABORT(fs, FR_DISK_ERR);
|
ABORT(fs, FR_DISK_ERR);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue