diff --git a/source/ff.c b/source/ff.c index cf97f1fb913c1216449e96ed7a311c6003ada8de..185a1760ce193aa60c6e1c2defb37fa56f1baa73 100644 --- a/source/ff.c +++ b/source/ff.c @@ -4290,6 +4290,51 @@ FRESULT f_stat ( } +FRESULT fat_count_free_entries( + DWORD *nclst, /* Pointer to a variable to return number of free clusters */ + FATFS *fs /* Pointer to corresponding filesystem object */ +) +{ + DWORD nfree, clst, stat; + QWORD sect; + UINT i; + FFOBJID obj; + FRESULT res = FR_OK; + + nfree = 0; + if (fs->fs_type == FS_FAT12) { /* FAT12: Scan bit field FAT entries */ + clst = 2; obj.fs = fs; + do { + stat = get_fat(&obj, clst); + if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } + if (stat == 1) { res = FR_INT_ERR; break; } + if (stat == 0) nfree++; + } while (++clst < fs->n_fatent); + } else { + /* FAT16/32: Scan WORD/DWORD FAT entries */ + clst = fs->n_fatent; /* Number of entries */ + sect = fs->fatbase; /* Top of the FAT */ + i = 0; /* Offset in the sector */ + do { /* Counts numbuer of entries with zero in the FAT */ + if (i == 0) { + res = move_window(fs, sect++); + if (res != FR_OK) break; + } + if (fs->fs_type == FS_FAT16) { + if (ld_word(fs->win + i) == 0) nfree++; + i += 2; + } else { + if ((ld_dword(fs->win + i) & 0x0FFFFFFF) == 0) nfree++; + i += 4; + } + i %= SS(fs); + } while (--clst); + } + *nclst = nfree; /* Return the free clusters */ + fs->free_clst = nfree; /* Now free_clst is valid */ + fs->fsi_flag |= 1; /* FAT32: FSInfo is to be updated */ + return res; +} #if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ @@ -4304,11 +4349,6 @@ FRESULT f_getfree ( { FRESULT res; FATFS *fs; - DWORD nfree, clst, stat; - QWORD sect; - UINT i; - FFOBJID obj; - /* Get logical drive */ res = find_volume(&path, &fs, 0); @@ -4319,38 +4359,7 @@ FRESULT f_getfree ( *nclst = fs->free_clst; } else { /* Scan FAT to obtain number of free clusters */ - nfree = 0; - if (fs->fs_type == FS_FAT12) { /* FAT12: Scan bit field FAT entries */ - clst = 2; obj.fs = fs; - do { - stat = get_fat(&obj, clst); - if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } - if (stat == 1) { res = FR_INT_ERR; break; } - if (stat == 0) nfree++; - } while (++clst < fs->n_fatent); - } else { - /* FAT16/32: Scan WORD/DWORD FAT entries */ - clst = fs->n_fatent; /* Number of entries */ - sect = fs->fatbase; /* Top of the FAT */ - i = 0; /* Offset in the sector */ - do { /* Counts numbuer of entries with zero in the FAT */ - if (i == 0) { - res = move_window(fs, sect++); - if (res != FR_OK) break; - } - if (fs->fs_type == FS_FAT16) { - if (ld_word(fs->win + i) == 0) nfree++; - i += 2; - } else { - if ((ld_dword(fs->win + i) & 0x0FFFFFFF) == 0) nfree++; - i += 4; - } - i %= SS(fs); - } while (--clst); - } - *nclst = nfree; /* Return the free clusters */ - fs->free_clst = nfree; /* Now free_clst is valid */ - fs->fsi_flag |= 1; /* FAT32: FSInfo is to be updated */ + res = fat_count_free_entries(nclst, fs); } } diff --git a/source/ff.h b/source/ff.h index 40580a106fb3a58c9c3440a3bffd8dcaabefb69e..8fbc122d8eba02bbd939a24285b64ca3e078639f 100644 --- a/source/ff.h +++ b/source/ff.h @@ -450,7 +450,8 @@ FRESULT f_getclustinfo (FIL* fp, DWORD* fclust, DWORD* fcount); /* get the clust FRESULT f_checkopenlock(int index); FRESULT sync_fs (FATFS* fs); FRESULT sync_window(FATFS *fs); -FRESULT move_window ( FATFS* fs, QWORD sector); +FRESULT move_window (FATFS* fs, QWORD sector); +FRESULT fat_count_free_entries(DWORD *nclst, FATFS *fs); void get_fileinfo (DIR* dp, FILINFO* fno); DWORD get_fat (FFOBJID *obj, DWORD clst); FRESULT put_fat(FATFS *fs, DWORD clst, DWORD val);