support > 512 bytes per sector in libfat (dimok)

This commit is contained in:
tantricity 2011-06-18 07:40:53 +00:00
parent 566206a741
commit d5f437723f
8 changed files with 226 additions and 175 deletions

View File

@ -46,7 +46,7 @@
#define CACHE_FREE UINT_MAX
CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition) {
CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition, unsigned int bytesPerSector) {
CACHE* cache;
unsigned int i;
CACHE_ENTRY* cacheEntries;
@ -68,6 +68,7 @@ CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsP
cache->endOfPartition = endOfPartition;
cache->numberOfPages = numberOfPages;
cache->sectorsPerPage = sectorsPerPage;
cache->bytesPerSector = bytesPerSector;
cacheEntries = (CACHE_ENTRY*) _FAT_mem_allocate ( sizeof(CACHE_ENTRY) * numberOfPages);
@ -81,7 +82,7 @@ CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsP
cacheEntries[i].count = 0;
cacheEntries[i].last_access = 0;
cacheEntries[i].dirty = false;
cacheEntries[i].cache = (uint8_t*) _FAT_mem_align ( sectorsPerPage * BYTES_PER_READ );
cacheEntries[i].cache = (uint8_t*) _FAT_mem_align ( sectorsPerPage * bytesPerSector );
}
cache->cacheEntries = cacheEntries;
@ -168,9 +169,9 @@ bool _FAT_cache_readSectors(CACHE *cache,sec_t sector,sec_t numSectors,void *buf
secs_to_read = entry->count - sec;
if(secs_to_read>numSectors) secs_to_read = numSectors;
memcpy(dest,entry->cache + (sec*BYTES_PER_READ),(secs_to_read*BYTES_PER_READ));
memcpy(dest,entry->cache + (sec*cache->bytesPerSector),(secs_to_read*cache->bytesPerSector));
dest += (secs_to_read*BYTES_PER_READ);
dest += (secs_to_read*cache->bytesPerSector);
sector += secs_to_read;
numSectors -= secs_to_read;
}
@ -186,13 +187,13 @@ bool _FAT_cache_readPartialSector (CACHE* cache, void* buffer, sec_t sector, uns
sec_t sec;
CACHE_ENTRY *entry;
if (offset + size > BYTES_PER_READ) return false;
if (offset + size > cache->bytesPerSector) return false;
entry = _FAT_cache_getPage(cache,sector);
if(entry==NULL) return false;
sec = sector - entry->sector;
memcpy(buffer,entry->cache + ((sec*BYTES_PER_READ) + offset),size);
memcpy(buffer,entry->cache + ((sec*cache->bytesPerSector) + offset),size);
return true;
}
@ -218,13 +219,13 @@ bool _FAT_cache_writePartialSector (CACHE* cache, const void* buffer, sec_t sect
sec_t sec;
CACHE_ENTRY *entry;
if (offset + size > BYTES_PER_READ) return false;
if (offset + size > cache->bytesPerSector) return false;
entry = _FAT_cache_getPage(cache,sector);
if(entry==NULL) return false;
sec = sector - entry->sector;
memcpy(entry->cache + ((sec*BYTES_PER_READ) + offset),buffer,size);
memcpy(entry->cache + ((sec*cache->bytesPerSector) + offset),buffer,size);
entry->dirty = true;
return true;
@ -251,14 +252,14 @@ bool _FAT_cache_eraseWritePartialSector (CACHE* cache, const void* buffer, sec_t
sec_t sec;
CACHE_ENTRY *entry;
if (offset + size > BYTES_PER_READ) return false;
if (offset + size > cache->bytesPerSector) return false;
entry = _FAT_cache_getPage(cache,sector);
if(entry==NULL) return false;
sec = sector - entry->sector;
memset(entry->cache + (sec*BYTES_PER_READ),0,BYTES_PER_READ);
memcpy(entry->cache + ((sec*BYTES_PER_READ) + offset),buffer,size);
memset(entry->cache + (sec*cache->bytesPerSector),0,cache->bytesPerSector);
memcpy(entry->cache + ((sec*cache->bytesPerSector) + offset),buffer,size);
entry->dirty = true;
return true;
@ -281,9 +282,9 @@ bool _FAT_cache_writeSectors (CACHE* cache, sec_t sector, sec_t numSectors, cons
secs_to_write = entry->count - sec;
if(secs_to_write>numSectors) secs_to_write = numSectors;
memcpy(entry->cache + (sec*BYTES_PER_READ),src,(secs_to_write*BYTES_PER_READ));
memcpy(entry->cache + (sec*cache->bytesPerSector),src,(secs_to_write*cache->bytesPerSector));
src += (secs_to_write*BYTES_PER_READ);
src += (secs_to_write*cache->bytesPerSector);
sector += secs_to_write;
numSectors -= secs_to_write;

View File

@ -39,9 +39,6 @@
#include "common.h"
#include "disc.h"
#define PAGE_SECTORS 64
#define CACHE_PAGE_SIZE (BYTES_PER_READ * PAGE_SECTORS)
typedef struct {
sec_t sector;
unsigned int count;
@ -55,6 +52,7 @@ typedef struct {
sec_t endOfPartition;
unsigned int numberOfPages;
unsigned int sectorsPerPage;
unsigned int bytesPerSector;
CACHE_ENTRY* cacheEntries;
} CACHE;
@ -100,14 +98,14 @@ bool _FAT_cache_readSectors (CACHE* cache, sec_t sector, sec_t numSectors, void*
Read a full sector from the cache
*/
static inline bool _FAT_cache_readSector (CACHE* cache, void* buffer, sec_t sector) {
return _FAT_cache_readPartialSector (cache, buffer, sector, 0, BYTES_PER_READ);
return _FAT_cache_readPartialSector (cache, buffer, sector, 0, cache->bytesPerSector);
}
/*
Write a full sector to the cache
*/
static inline bool _FAT_cache_writeSector (CACHE* cache, const void* buffer, sec_t sector) {
return _FAT_cache_writePartialSector (cache, buffer, sector, 0, BYTES_PER_READ);
return _FAT_cache_writePartialSector (cache, buffer, sector, 0, cache->bytesPerSector);
}
bool _FAT_cache_writeSectors (CACHE* cache, sec_t sector, sec_t numSectors, const void* buffer);
@ -122,7 +120,7 @@ Clear out the contents of the cache without writing any dirty sectors first
*/
void _FAT_cache_invalidate (CACHE* cache);
CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition);
CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition, unsigned int bytesPerSector);
void _FAT_cache_destructor (CACHE* cache);

View File

@ -29,7 +29,6 @@
#ifndef _COMMON_H
#define _COMMON_H
#define BYTES_PER_READ 512
#include <fat.h>
#include <stddef.h>
#include <stdint.h>

View File

@ -251,7 +251,7 @@ static bool _FAT_directory_incrementDirEntryPosition (PARTITION* partition, DIR_
// Increment offset, wrapping at the end of a sector
++ position.offset;
if (position.offset == BYTES_PER_READ / DIR_ENTRY_DATA_SIZE) {
if (position.offset == partition->bytesPerSector / DIR_ENTRY_DATA_SIZE) {
position.offset = 0;
// Increment sector when wrapping
++ position.sector;
@ -1113,8 +1113,8 @@ void _FAT_directory_entryStat (PARTITION* partition, DIR_ENTRY* entry, struct st
u8array_to_u16 (entry->entryData, DIR_ENTRY_cDate)
);
st->st_spare3 = 0;
st->st_blksize = BYTES_PER_READ; // Prefered file I/O block size
st->st_blocks = (st->st_size + BYTES_PER_READ - 1) / BYTES_PER_READ; // File size in blocks
st->st_blksize = partition->bytesPerSector; // Prefered file I/O block size
st->st_blocks = (st->st_size + partition->bytesPerSector - 1) / partition->bytesPerSector; // File size in blocks
st->st_spare4[0] = 0;
st->st_spare4[1] = 0;
}

View File

@ -216,8 +216,8 @@ int _FAT_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
// Set append pointer to the end of the file
file->appendPosition.cluster = _FAT_fat_lastCluster (partition, file->startCluster);
file->appendPosition.sector = (file->filesize % partition->bytesPerCluster) / BYTES_PER_READ;
file->appendPosition.byte = file->filesize % BYTES_PER_READ;
file->appendPosition.sector = (file->filesize % partition->bytesPerCluster) / partition->bytesPerSector;
file->appendPosition.byte = file->filesize % partition->bytesPerSector;
// Check if the end of the file is on the end of a cluster
if ( (file->filesize > 0) && ((file->filesize % partition->bytesPerCluster)==0) ){
@ -381,12 +381,12 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
cache = file->partition->cache;
// Align to sector
tempVar = BYTES_PER_READ - position.byte;
tempVar = partition->bytesPerSector - position.byte;
if (tempVar > remain) {
tempVar = remain;
}
if ((tempVar < BYTES_PER_READ) && flagNoError)
if ((tempVar < partition->bytesPerSector) && flagNoError)
{
_FAT_cache_readPartialSector ( cache, ptr, _FAT_fat_clusterToSector (partition, position.cluster) + position.sector,
position.byte, tempVar);
@ -395,7 +395,7 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
ptr += tempVar;
position.byte += tempVar;
if (position.byte >= BYTES_PER_READ) {
if (position.byte >= partition->bytesPerSector) {
position.byte = 0;
position.sector++;
}
@ -403,10 +403,10 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
// align to cluster
// tempVar is number of sectors to read
if (remain > (partition->sectorsPerCluster - position.sector) * BYTES_PER_READ) {
if (remain > (partition->sectorsPerCluster - position.sector) * partition->bytesPerSector) {
tempVar = partition->sectorsPerCluster - position.sector;
} else {
tempVar = remain / BYTES_PER_READ;
tempVar = remain / partition->bytesPerSector;
}
if ((tempVar > 0) && flagNoError) {
@ -416,8 +416,8 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
flagNoError = false;
r->_errno = EIO;
} else {
ptr += tempVar * BYTES_PER_READ;
remain -= tempVar * BYTES_PER_READ;
ptr += tempVar * partition->bytesPerSector;
remain -= tempVar * partition->bytesPerSector;
position.sector += tempVar;
}
}
@ -449,12 +449,12 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
chunkSize += partition->bytesPerCluster;
} while ((nextChunkStart == chunkEnd + 1) &&
#ifdef LIMIT_SECTORS
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * BYTES_PER_READ) &&
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * partition->bytesPerSector) &&
#endif
(chunkSize + partition->bytesPerCluster <= remain));
if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster),
chunkSize / BYTES_PER_READ, ptr))
chunkSize / partition->bytesPerSector, ptr))
{
flagNoError = false;
r->_errno = EIO;
@ -477,7 +477,7 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
}
// Read remaining sectors
tempVar = remain / BYTES_PER_READ; // Number of sectors left
tempVar = remain / partition->bytesPerSector; // Number of sectors left
if ((tempVar > 0) && flagNoError) {
if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster),
tempVar, ptr))
@ -485,8 +485,8 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
flagNoError = false;
r->_errno = EIO;
} else {
ptr += tempVar * BYTES_PER_READ;
remain -= tempVar * BYTES_PER_READ;
ptr += tempVar * partition->bytesPerSector;
remain -= tempVar * partition->bytesPerSector;
position.sector += tempVar;
}
}
@ -555,13 +555,14 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {
PARTITION* partition = file->partition;
CACHE* cache = file->partition->cache;
FILE_POSITION position;
uint8_t zeroBuffer [BYTES_PER_READ] = {0};
uint8_t zeroBuffer [partition->bytesPerSector];
memset(zeroBuffer, 0, partition->bytesPerSector);
uint32_t remain;
uint32_t tempNextCluster;
unsigned int sector;
position.byte = file->filesize % BYTES_PER_READ;
position.sector = (file->filesize % partition->bytesPerCluster) / BYTES_PER_READ;
position.byte = file->filesize % partition->bytesPerSector;
position.sector = (file->filesize % partition->bytesPerCluster) / partition->bytesPerSector;
// It is assumed that there is always a startCluster
// This will be true when _FAT_file_extend_r is called from _FAT_write_r
position.cluster = _FAT_fat_lastCluster (partition, file->startCluster);
@ -580,7 +581,7 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {
position.sector = 0;
}
if (remain + position.byte < BYTES_PER_READ) {
if (remain + position.byte < partition->bytesPerSector) {
// Only need to clear to the end of the sector
_FAT_cache_writePartialSector (cache, zeroBuffer,
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, remain);
@ -589,13 +590,13 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {
if (position.byte > 0) {
_FAT_cache_writePartialSector (cache, zeroBuffer,
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte,
BYTES_PER_READ - position.byte);
remain -= (BYTES_PER_READ - position.byte);
partition->bytesPerSector - position.byte);
remain -= (partition->bytesPerSector - position.byte);
position.byte = 0;
position.sector ++;
}
while (remain >= BYTES_PER_READ) {
while (remain >= partition->bytesPerSector) {
if (position.sector >= partition->sectorsPerCluster) {
position.sector = 0;
// Ran out of clusters so get a new one
@ -611,7 +612,7 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {
sector = _FAT_fat_clusterToSector (partition, position.cluster) + position.sector;
_FAT_cache_writeSectors (cache, sector, 1, zeroBuffer);
remain -= BYTES_PER_READ;
remain -= partition->bytesPerSector;
position.sector ++;
}
@ -712,12 +713,12 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
_FAT_check_position_for_next_cluster(r, &position, partition, remain, &flagNoError);
// Align to sector
tempVar = BYTES_PER_READ - position.byte;
tempVar = partition->bytesPerSector - position.byte;
if (tempVar > remain) {
tempVar = remain;
}
if ((tempVar < BYTES_PER_READ) && flagNoError) {
if ((tempVar < partition->bytesPerSector) && flagNoError) {
// Write partial sector to disk
_FAT_cache_writePartialSector (cache, ptr,
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, tempVar);
@ -728,7 +729,7 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
// Move onto next sector
if (position.byte >= BYTES_PER_READ) {
if (position.byte >= partition->bytesPerSector) {
position.byte = 0;
position.sector ++;
}
@ -736,10 +737,10 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
// Align to cluster
// tempVar is number of sectors to write
if (remain > (partition->sectorsPerCluster - position.sector) * BYTES_PER_READ) {
if (remain > (partition->sectorsPerCluster - position.sector) * partition->bytesPerSector) {
tempVar = partition->sectorsPerCluster - position.sector;
} else {
tempVar = remain / BYTES_PER_READ;
tempVar = remain / partition->bytesPerSector;
}
if ((tempVar > 0 && tempVar < partition->sectorsPerCluster) && flagNoError) {
@ -749,8 +750,8 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
flagNoError = false;
r->_errno = EIO;
} else {
ptr += tempVar * BYTES_PER_READ;
remain -= tempVar * BYTES_PER_READ;
ptr += tempVar * partition->bytesPerSector;
remain -= tempVar * partition->bytesPerSector;
position.sector += tempVar;
}
}
@ -769,7 +770,7 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
// group consecutive clusters
while (flagNoError &&
#ifdef LIMIT_SECTORS
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * BYTES_PER_READ) &&
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * partition->bytesPerSector) &&
#endif
(chunkSize + partition->bytesPerCluster < remain))
{
@ -786,7 +787,7 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
}
if ( !_FAT_cache_writeSectors (cache,
_FAT_fat_clusterToSector(partition, position.cluster), chunkSize / BYTES_PER_READ, ptr))
_FAT_fat_clusterToSector(partition, position.cluster), chunkSize / partition->bytesPerSector, ptr))
{
flagNoError = false;
r->_errno = EIO;
@ -810,15 +811,15 @@ ssize_t _FAT_write_r (struct _reent *r, int fd, const char *ptr, size_t len) {
_FAT_check_position_for_next_cluster(r, &position, partition, remain, &flagNoError);
// Write remaining sectors
tempVar = remain / BYTES_PER_READ; // Number of sectors left
tempVar = remain / partition->bytesPerSector; // Number of sectors left
if ((tempVar > 0) && flagNoError) {
if (!_FAT_cache_writeSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster), tempVar, ptr))
{
flagNoError = false;
r->_errno = EIO;
} else {
ptr += tempVar * BYTES_PER_READ;
remain -= tempVar * BYTES_PER_READ;
ptr += tempVar * partition->bytesPerSector;
remain -= tempVar * partition->bytesPerSector;
position.sector += tempVar;
}
}
@ -927,8 +928,8 @@ off_t _FAT_seek_r (struct _reent *r, int fd, off_t pos, int dir) {
}
// Calculate the sector and byte of the current position,
// and store them
file->rwPosition.sector = (position % partition->bytesPerCluster) / BYTES_PER_READ;
file->rwPosition.byte = position % BYTES_PER_READ;
file->rwPosition.sector = (position % partition->bytesPerCluster) / partition->bytesPerSector;
file->rwPosition.byte = position % partition->bytesPerSector;
nextCluster = _FAT_fat_nextCluster (partition, cluster);
while ((clusCount > 0) && (nextCluster != CLUSTER_FREE) && (nextCluster != CLUSTER_EOF)) {
@ -1087,13 +1088,13 @@ int _FAT_ftruncate_r (struct _reent *r, int fd, off_t len) {
lastCluster = _FAT_fat_trimChain (partition, file->startCluster, chainLength);
if (file->append) {
file->appendPosition.byte = newSize % BYTES_PER_READ;
file->appendPosition.byte = newSize % partition->bytesPerSector;
// Does the end of the file fall on the edge of a cluster?
if (newSize % partition->bytesPerCluster == 0) {
// Set a flag to allocate a new cluster
file->appendPosition.sector = partition->sectorsPerCluster;
} else {
file->appendPosition.sector = (newSize % partition->bytesPerCluster) / BYTES_PER_READ;
file->appendPosition.sector = (newSize % partition->bytesPerCluster) / partition->bytesPerSector;
}
file->appendPosition.cluster = lastCluster;
}

View File

@ -54,15 +54,15 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
case FS_FAT12:
{
u32 nextCluster_h;
sector = partition->fat.fatStart + (((cluster * 3) / 2) / BYTES_PER_READ);
offset = ((cluster * 3) / 2) % BYTES_PER_READ;
sector = partition->fat.fatStart + (((cluster * 3) / 2) / partition->bytesPerSector);
offset = ((cluster * 3) / 2) % partition->bytesPerSector;
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u8));
offset++;
if (offset >= BYTES_PER_READ) {
if (offset >= partition->bytesPerSector) {
offset = 0;
sector++;
}
@ -85,8 +85,8 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
break;
}
case FS_FAT16:
sector = partition->fat.fatStart + ((cluster << 1) / BYTES_PER_READ);
offset = (cluster % (BYTES_PER_READ >> 1)) << 1;
sector = partition->fat.fatStart + ((cluster << 1) / partition->bytesPerSector);
offset = (cluster % (partition->bytesPerSector >> 1)) << 1;
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u16));
@ -96,8 +96,8 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
break;
case FS_FAT32:
sector = partition->fat.fatStart + ((cluster << 2) / BYTES_PER_READ);
offset = (cluster % (BYTES_PER_READ >> 2)) << 2;
sector = partition->fat.fatStart + ((cluster << 2) / partition->bytesPerSector);
offset = (cluster % (partition->bytesPerSector >> 2)) << 2;
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u32));
@ -135,8 +135,8 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
break;
case FS_FAT12:
sector = partition->fat.fatStart + (((cluster * 3) / 2) / BYTES_PER_READ);
offset = ((cluster * 3) / 2) % BYTES_PER_READ;
sector = partition->fat.fatStart + (((cluster * 3) / 2) / partition->bytesPerSector);
offset = ((cluster * 3) / 2) % partition->bytesPerSector;
if (cluster & 0x01) {
@ -147,7 +147,7 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
_FAT_cache_writeLittleEndianValue (partition->cache, value & 0xFF, sector, offset, sizeof(u8));
offset++;
if (offset >= BYTES_PER_READ) {
if (offset >= partition->bytesPerSector) {
offset = 0;
sector++;
}
@ -159,7 +159,7 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u8));
offset++;
if (offset >= BYTES_PER_READ) {
if (offset >= partition->bytesPerSector) {
offset = 0;
sector++;
}
@ -174,16 +174,16 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
break;
case FS_FAT16:
sector = partition->fat.fatStart + ((cluster << 1) / BYTES_PER_READ);
offset = (cluster % (BYTES_PER_READ >> 1)) << 1;
sector = partition->fat.fatStart + ((cluster << 1) / partition->bytesPerSector);
offset = (cluster % (partition->bytesPerSector >> 1)) << 1;
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u16));
break;
case FS_FAT32:
sector = partition->fat.fatStart + ((cluster << 2) / BYTES_PER_READ);
offset = (cluster % (BYTES_PER_READ >> 2)) << 2;
sector = partition->fat.fatStart + ((cluster << 2) / partition->bytesPerSector);
offset = (cluster % (partition->bytesPerSector >> 2)) << 2;
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u32));
@ -269,7 +269,7 @@ If an error occurs, return CLUSTER_ERROR
uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster) {
uint32_t newCluster;
uint32_t i;
uint8_t emptySector[BYTES_PER_READ];
uint8_t emptySector[partition->bytesPerSector];
// Link the cluster
newCluster = _FAT_fat_linkFreeCluster(partition, cluster);
@ -279,7 +279,7 @@ uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster
}
// Clear all the sectors within the cluster
memset (emptySector, 0, BYTES_PER_READ);
memset (emptySector, 0, partition->bytesPerSector);
for (i = 0; i < partition->sectorsPerCluster; i++) {
_FAT_cache_writeSectors (partition->cache,
_FAT_fat_clusterToSector (partition, newCluster) + i,

View File

@ -103,16 +103,20 @@ static const char FAT_SIG[3] = {'F', 'A', 'T'};
static const char FS_INFO_SIG1[4] = {'R', 'R', 'a', 'A'};
static const char FS_INFO_SIG2[4] = {'r', 'r', 'A', 'a'};
static uint8_t sectorBuffer[BYTES_PER_READ] __attribute__((aligned(32)));
sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
{
uint8_t part_table[16*4];
uint8_t *ptr;
int i;
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(MAX_SECTOR_SIZE);
if(!sectorBuffer) {
return 0;
}
// Read first sector of disc
if (!_FAT_disc_readSectors (disc, 0, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return 0;
}
@ -124,6 +128,7 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) ||
!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
_FAT_mem_free(sectorBuffer);
return part_lba;
}
@ -136,29 +141,40 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
for(n=0;n<8;n++) // max 8 logic partitions
{
if(!_FAT_disc_readSectors (disc, part_lba+next_lba2, 1, sectorBuffer)) return 0;
if(!_FAT_disc_readSectors (disc, part_lba+next_lba2, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return 0;
}
part_lba2 = part_lba + next_lba2 + u8array_to_u32(sectorBuffer, 0x1C6) ;
next_lba2 = u8array_to_u32(sectorBuffer, 0x1D6);
if(!_FAT_disc_readSectors (disc, part_lba2, 1, sectorBuffer)) return 0;
if(!_FAT_disc_readSectors (disc, part_lba2, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return 0;
}
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) ||
!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
{
!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
_FAT_mem_free(sectorBuffer);
return part_lba2;
}
if(next_lba2==0) break;
}
} else {
if(!_FAT_disc_readSectors (disc, part_lba, 1, sectorBuffer)) return 0;
if(!_FAT_disc_readSectors (disc, part_lba, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return 0;
}
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) ||
!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
_FAT_mem_free(sectorBuffer);
return part_lba;
}
}
}
_FAT_mem_free(sectorBuffer);
return 0;
}
@ -166,13 +182,20 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector) {
PARTITION* partition;
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(MAX_SECTOR_SIZE);
if(!sectorBuffer) {
return NULL;
}
// Read first sector of disc
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return NULL;
}
// Make sure it is a valid MBR or boot sector
if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) {
_FAT_mem_free(sectorBuffer);
return NULL;
}
@ -187,19 +210,21 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
} else {
startSector = FindFirstValidPartition(disc);
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return NULL;
}
}
// Now verify that this is indeed a FAT partition
if (memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) &&
memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
{
memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
_FAT_mem_free(sectorBuffer);
return NULL;
}
partition = (PARTITION*) _FAT_mem_allocate (sizeof(PARTITION));
if (partition == NULL) {
_FAT_mem_free(sectorBuffer);
return NULL;
}
@ -226,8 +251,15 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
partition->numberOfSectors = u8array_to_u32( sectorBuffer, BPB_numSectors);
}
partition->bytesPerSector = BYTES_PER_READ; // Sector size is redefined to be 512 bytes
partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster] * u8array_to_u16(sectorBuffer, BPB_bytesPerSector) / BYTES_PER_READ;
partition->bytesPerSector = u8array_to_u16(sectorBuffer, BPB_bytesPerSector);
if(partition->bytesPerSector < MIN_SECTOR_SIZE || partition->bytesPerSector > MAX_SECTOR_SIZE) {
// Unsupported sector size
_FAT_mem_free(sectorBuffer);
_FAT_mem_free(partition);
return NULL;
}
partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster];
partition->bytesPerCluster = partition->bytesPerSector * partition->sectorsPerCluster;
partition->fat.fatStart = startSector + u8array_to_u16(sectorBuffer, BPB_reservedSectors);
@ -268,7 +300,7 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
}
// Create a cache to use
partition->cache = _FAT_cache_constructor (cacheSize, sectorsPerPage, partition->disc, startSector+partition->numberOfSectors);
partition->cache = _FAT_cache_constructor (cacheSize, sectorsPerPage, partition->disc, startSector+partition->numberOfSectors, partition->bytesPerSector);
// Set current directory to the root
partition->cwdCluster = partition->rootDirCluster;
@ -282,6 +314,8 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
_FAT_partition_readFSinfo(partition);
_FAT_mem_free(sectorBuffer);
return partition;
}
@ -328,8 +362,11 @@ void _FAT_partition_createFSinfo(PARTITION * partition)
if(partition->readOnly || partition->filesysType != FS_FAT32)
return;
uint8_t sectorBuffer[BYTES_PER_READ];
memset(sectorBuffer, 0, sizeof(sectorBuffer));
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector);
if(!sectorBuffer) {
return;
}
memset(sectorBuffer, 0, partition->bytesPerSector);
int i;
for(i = 0; i < 4; ++i)
@ -346,6 +383,8 @@ void _FAT_partition_createFSinfo(PARTITION * partition)
sectorBuffer[FSIB_bootSig_AA] = 0xAA;
_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer);
_FAT_mem_free(sectorBuffer);
}
void _FAT_partition_readFSinfo(PARTITION * partition)
@ -353,24 +392,29 @@ void _FAT_partition_readFSinfo(PARTITION * partition)
if(partition->filesysType != FS_FAT32)
return;
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector);
if(!sectorBuffer) {
return;
}
memset(sectorBuffer, 0, partition->bytesPerSector);
// Read first sector of disc
if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return;
}
if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) != 0 ||
memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 4) != 0 ||
u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster) == 0)
{
u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster) == 0) {
//sector does not yet exist, create one!
_FAT_partition_createFSinfo(partition);
_FAT_mem_free(sectorBuffer);
return;
}
partition->fat.numberFreeCluster = u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster);
partition->fat.numberLastAllocCluster = u8array_to_u32(sectorBuffer, FSIB_numberLastAllocCluster);
_FAT_mem_free(sectorBuffer);
}
void _FAT_partition_writeFSinfo(PARTITION * partition)
@ -378,21 +422,26 @@ void _FAT_partition_writeFSinfo(PARTITION * partition)
if(partition->filesysType != FS_FAT32)
return;
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector);
if(!sectorBuffer) {
return;
}
memset(sectorBuffer, 0, partition->bytesPerSector);
// Read first sector of disc
if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
_FAT_mem_free(sectorBuffer);
return;
}
if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) || memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 4))
if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) || memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 4)) {
_FAT_mem_free(sectorBuffer);
return;
}
u32_to_u8array(sectorBuffer, FSIB_numberOfFreeCluster, partition->fat.numberFreeCluster);
u32_to_u8array(sectorBuffer, FSIB_numberLastAllocCluster, partition->fat.numberLastAllocCluster);
// Read first sector of disc
if (!_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
return;
}
_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer);
_FAT_mem_free(sectorBuffer);
}

View File

@ -34,6 +34,9 @@
#include "cache.h"
#include "lock.h"
#define MIN_SECTOR_SIZE 512
#define MAX_SECTOR_SIZE 4096
// Filesystem type
typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;