//----------------------------------------------------------------------------- // fatfs_fat_read_sector: Read a FAT sector //----------------------------------------------------------------------------- static sector_buffer fatfs_fat_read_sector(fatfs fs, uint sector) { sector_buffer last = null; sector_buffer pcur = fs.fat_buffer_head; // Itterate through sector buffer list while (pcur != null) { // Sector already in sector list if (pcur.address == sector) break; // End of list? if (pcur.next == null) { // Remove buffer from list if (last != null) last.next = null; // We the first and last buffer in the chain? else fs.fat_buffer_head = null; } last = pcur; pcur = pcur.next; } // We found the sector already in FAT buffer chain if (pcur != null) return pcur; // Else, we removed the last item from the list pcur = last; // Add to start of sector buffer list (now newest sector) pcur.next = fs.fat_buffer_head; fs.fat_buffer_head = pcur; // Writeback sector if changed if (pcur.dirty) { if (!fs.disk_io.WriteSector(pcur.address, pcur.sector)) return null; // Now no longer 'dirty' pcur.dirty = false; } // Address is now new sector pcur.address = sector; // Read next sector if (!fs.disk_io.ReadSector(pcur.address, pcur.sector)) { // Read failed, invalidate buffer address pcur.address = FAT32_INVALID_CLUSTER; return null; } return pcur; }
//----------------------------------------------------------------------------- // General FAT Table Operations //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // fatfs_find_next_cluster: Return cluster number of next cluster in chain by // reading FAT table and traversing it. Return 0xffffffff for end of chain. //----------------------------------------------------------------------------- uint fatfs_find_next_cluster(fatfs fs, uint current_cluster) { uint fat_sector_offset; uint position; uint nextcluster; sector_buffer pbuf; // Why is '..' labelled with cluster 0 when it should be 2 ?? if (current_cluster == 0) current_cluster = 2; // Find which sector of FAT table to read fat_sector_offset = current_cluster / 128; // Read FAT sector into buffer pbuf = fatfs_fat_read_sector(fs, fs.fat_begin_lba + fat_sector_offset); if (!pbuf) return (FAT32_LAST_CLUSTER); // Find 32 bit entry of current sector relating to cluster number position = (current_cluster - (fat_sector_offset * 128)) * 4; // Read Next Clusters value from Sector Buffer nextcluster = FAT32_GET_32BIT_WORD(pbuf, (ushort)position); // Mask out MS 4 bits (its 28bit addressing) nextcluster = nextcluster & 0x0FFFFFFF; // If 0x0FFFFFFF then end of chain found if (nextcluster == 0x0FFFFFFF) return (FAT32_LAST_CLUSTER); else // Else return next cluster return (nextcluster); }
//----------------------------------------------------------------------------- // fatfs_find_blank_cluster: Find a free cluster entry by reading the FAT //----------------------------------------------------------------------------- #if FATFS_INC_WRITE_SUPPORT int fatfs_find_blank_cluster(fatfs fs, uint start_cluster, uint *free_cluster) { uint fat_sector_offset, position; uint nextcluster; uint current_cluster = start_cluster;
//----------------------------------------------------------------------------- // fatfs_fat_purge: Purge 'dirty' FAT sectors to disk //----------------------------------------------------------------------------- bool fatfs_fat_purge(fatfs fs) { sector_buffer pcur = fs.fat_buffer_head; // Itterate through sector buffer list while (pcur != null) { // Writeback sector if changed if (pcur.dirty) { if (!fs.disk_io.WriteSector(pcur.address, pcur.sector)) return false; pcur.dirty = false; } pcur = pcur.next; } return true; }