From 5ae9f5655a4d6166dcd6a1009975c9329992b8ab Mon Sep 17 00:00:00 2001 From: Kostas Missos Date: Sat, 19 May 2018 02:01:39 +0300 Subject: [PATCH] [FatFS] Add error printing for important functions So much needed --- ipl/ff.c | 203 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 164 insertions(+), 39 deletions(-) diff --git a/ipl/ff.c b/ipl/ff.c index d29601d..19af830 100755 --- a/ipl/ff.c +++ b/ipl/ff.c @@ -3,6 +3,7 @@ /-----------------------------------------------------------------------------/ / / Copyright (C) 2017, ChaN, all right reserved. +/ Copyright (c) 2018 naehrwert / / FatFs module is an open source software. Redistribution and use of FatFs in / source and binary forms, with or without modification, are permitted provided @@ -22,6 +23,11 @@ #include "ff.h" /* Declarations of FatFs API */ #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); if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */ if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check write protection if needed */ + EFSPRINTF("Error: Write protected!"); return FR_WRITE_PROTECTED; } 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 */ stat = disk_initialize(fs->pdrv); /* Initialize the physical drive */ 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 */ } if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check disk write protection if needed */ + EFSPRINTF("Error: Write protected!"); return FR_WRITE_PROTECTED; } #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 */ } 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 >= 2) return FR_NO_FILESYSTEM; /* No FAT volume is found */ + if (fmt == 4) { + 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 */ @@ -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 */ 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) */ + EFSPRINTF("Error: exFAT - Bytes per sector does not match physical sector size!"); return FR_NO_FILESYSTEM; } 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->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 */ - 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 */ - 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; /* Boundaries and Limits */ fs->volbase = bsect; fs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx); 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); /* 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) { 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 #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 */ if (fasize == 0) fasize = ld_dword(fs->win + BPB_FATSz32); fs->fsize = fasize; 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 */ 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 */ - 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 */ if (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32); 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 */ 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 */ - 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; if (nclst <= MAX_FAT32) fmt = FS_FAT32; if (nclst <= MAX_FAT16) fmt = FS_FAT16; 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 */ 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->database = bsect + sysect; /* Data start sector */ if (fmt == FS_FAT32) { - if (ld_word(fs->win + BPB_FSVer32) != 0) return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) */ - if (fs->n_rootdir != 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ + if (ld_word(fs->win + BPB_FSVer32) != 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 */ szbfat = fs->n_fatent * 4; /* (Needed FAT size) */ } 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 */ szbfat = (fmt == FS_FAT16) ? /* (Needed FAT size) */ 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 /* Get FSInfo if available */ @@ -3426,7 +3499,7 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ #if FF_USE_LFN == 1 fs->lfnbuf = LfnBuf; /* Static LFN working buffer */ #if FF_FS_EXFAT - fs->dirbuf = DirBuf; /* Static directory block scratchpad buuffer */ + fs->dirbuf = DirBuf; /* Static directory block scratch-pad buffer */ #endif #endif #if FF_FS_RPATH != 0 @@ -3504,7 +3577,10 @@ FRESULT f_mount ( /* Get logical drive number */ 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 */ if (cfs) { @@ -3745,8 +3821,14 @@ FRESULT f_read ( *br = 0; /* Clear read byte counter */ 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 (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ + if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) { + 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; 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 */ } } - if (clst < 2) ABORT(fs, FR_INT_ERR); - if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); + if (clst < 2) { + 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 */ } 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; cc = btr / SS(fs); /* When remaining bytes >= sector size, */ if (cc > 0) { /* Read maximum contiguous sectors directly */ if (csect + cc > fs->csize) { /* Clip at cluster boundary */ 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_TINY 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 !FF_FS_READONLY 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; } #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 fp->sect = sect; @@ -3844,8 +3944,14 @@ FRESULT f_write ( *bw = 0; /* Clear write byte counter */ 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 (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ + if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) { + 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) */ 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 */ } } - if (clst == 0) break; /* Could not allocate a new cluster (disk full) */ - if (clst == 1) ABORT(fs, FR_INT_ERR); - if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); + if (clst == 0) { + EFSPRINTF("Error: Could not allocate a new cluster\n(disk full or low level disk I/O error)!"); + 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 */ 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 */ #else 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; } #endif 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; cc = btw / SS(fs); /* When remaining bytes >= sector size, */ if (cc > 0) { /* Write maximum contiguous sectors directly */ if (csect + cc > fs->csize) { /* Clip at cluster boundary */ 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_TINY 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 */ fp->fptr < fp->obj.objsize && 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); } #endif