mirror of
https://github.com/wiiu-env/libfat.git
synced 2025-02-16 17:29:23 +01:00
support > 512 bytes per sector in libfat (dimok)
This commit is contained in:
parent
566206a741
commit
d5f437723f
@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
#define CACHE_FREE UINT_MAX
|
#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;
|
CACHE* cache;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
CACHE_ENTRY* cacheEntries;
|
CACHE_ENTRY* cacheEntries;
|
||||||
@ -68,6 +68,7 @@ CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsP
|
|||||||
cache->endOfPartition = endOfPartition;
|
cache->endOfPartition = endOfPartition;
|
||||||
cache->numberOfPages = numberOfPages;
|
cache->numberOfPages = numberOfPages;
|
||||||
cache->sectorsPerPage = sectorsPerPage;
|
cache->sectorsPerPage = sectorsPerPage;
|
||||||
|
cache->bytesPerSector = bytesPerSector;
|
||||||
|
|
||||||
|
|
||||||
cacheEntries = (CACHE_ENTRY*) _FAT_mem_allocate ( sizeof(CACHE_ENTRY) * numberOfPages);
|
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].count = 0;
|
||||||
cacheEntries[i].last_access = 0;
|
cacheEntries[i].last_access = 0;
|
||||||
cacheEntries[i].dirty = false;
|
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;
|
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;
|
secs_to_read = entry->count - sec;
|
||||||
if(secs_to_read>numSectors) secs_to_read = numSectors;
|
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;
|
sector += secs_to_read;
|
||||||
numSectors -= 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;
|
sec_t sec;
|
||||||
CACHE_ENTRY *entry;
|
CACHE_ENTRY *entry;
|
||||||
|
|
||||||
if (offset + size > BYTES_PER_READ) return false;
|
if (offset + size > cache->bytesPerSector) return false;
|
||||||
|
|
||||||
entry = _FAT_cache_getPage(cache,sector);
|
entry = _FAT_cache_getPage(cache,sector);
|
||||||
if(entry==NULL) return false;
|
if(entry==NULL) return false;
|
||||||
|
|
||||||
sec = sector - entry->sector;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -218,13 +219,13 @@ bool _FAT_cache_writePartialSector (CACHE* cache, const void* buffer, sec_t sect
|
|||||||
sec_t sec;
|
sec_t sec;
|
||||||
CACHE_ENTRY *entry;
|
CACHE_ENTRY *entry;
|
||||||
|
|
||||||
if (offset + size > BYTES_PER_READ) return false;
|
if (offset + size > cache->bytesPerSector) return false;
|
||||||
|
|
||||||
entry = _FAT_cache_getPage(cache,sector);
|
entry = _FAT_cache_getPage(cache,sector);
|
||||||
if(entry==NULL) return false;
|
if(entry==NULL) return false;
|
||||||
|
|
||||||
sec = sector - entry->sector;
|
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;
|
entry->dirty = true;
|
||||||
return true;
|
return true;
|
||||||
@ -251,14 +252,14 @@ bool _FAT_cache_eraseWritePartialSector (CACHE* cache, const void* buffer, sec_t
|
|||||||
sec_t sec;
|
sec_t sec;
|
||||||
CACHE_ENTRY *entry;
|
CACHE_ENTRY *entry;
|
||||||
|
|
||||||
if (offset + size > BYTES_PER_READ) return false;
|
if (offset + size > cache->bytesPerSector) return false;
|
||||||
|
|
||||||
entry = _FAT_cache_getPage(cache,sector);
|
entry = _FAT_cache_getPage(cache,sector);
|
||||||
if(entry==NULL) return false;
|
if(entry==NULL) return false;
|
||||||
|
|
||||||
sec = sector - entry->sector;
|
sec = sector - entry->sector;
|
||||||
memset(entry->cache + (sec*BYTES_PER_READ),0,BYTES_PER_READ);
|
memset(entry->cache + (sec*cache->bytesPerSector),0,cache->bytesPerSector);
|
||||||
memcpy(entry->cache + ((sec*BYTES_PER_READ) + offset),buffer,size);
|
memcpy(entry->cache + ((sec*cache->bytesPerSector) + offset),buffer,size);
|
||||||
|
|
||||||
entry->dirty = true;
|
entry->dirty = true;
|
||||||
return 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;
|
secs_to_write = entry->count - sec;
|
||||||
if(secs_to_write>numSectors) secs_to_write = numSectors;
|
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;
|
sector += secs_to_write;
|
||||||
numSectors -= secs_to_write;
|
numSectors -= secs_to_write;
|
||||||
|
|
||||||
|
@ -39,9 +39,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "disc.h"
|
#include "disc.h"
|
||||||
|
|
||||||
#define PAGE_SECTORS 64
|
|
||||||
#define CACHE_PAGE_SIZE (BYTES_PER_READ * PAGE_SECTORS)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
sec_t sector;
|
sec_t sector;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
@ -55,6 +52,7 @@ typedef struct {
|
|||||||
sec_t endOfPartition;
|
sec_t endOfPartition;
|
||||||
unsigned int numberOfPages;
|
unsigned int numberOfPages;
|
||||||
unsigned int sectorsPerPage;
|
unsigned int sectorsPerPage;
|
||||||
|
unsigned int bytesPerSector;
|
||||||
CACHE_ENTRY* cacheEntries;
|
CACHE_ENTRY* cacheEntries;
|
||||||
} CACHE;
|
} 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
|
Read a full sector from the cache
|
||||||
*/
|
*/
|
||||||
static inline bool _FAT_cache_readSector (CACHE* cache, void* buffer, sec_t sector) {
|
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
|
Write a full sector to the cache
|
||||||
*/
|
*/
|
||||||
static inline bool _FAT_cache_writeSector (CACHE* cache, const void* buffer, sec_t sector) {
|
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);
|
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);
|
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);
|
void _FAT_cache_destructor (CACHE* cache);
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
#ifndef _COMMON_H
|
#ifndef _COMMON_H
|
||||||
#define _COMMON_H
|
#define _COMMON_H
|
||||||
|
|
||||||
#define BYTES_PER_READ 512
|
|
||||||
#include <fat.h>
|
#include <fat.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -251,7 +251,7 @@ static bool _FAT_directory_incrementDirEntryPosition (PARTITION* partition, DIR_
|
|||||||
|
|
||||||
// Increment offset, wrapping at the end of a sector
|
// Increment offset, wrapping at the end of a sector
|
||||||
++ position.offset;
|
++ position.offset;
|
||||||
if (position.offset == BYTES_PER_READ / DIR_ENTRY_DATA_SIZE) {
|
if (position.offset == partition->bytesPerSector / DIR_ENTRY_DATA_SIZE) {
|
||||||
position.offset = 0;
|
position.offset = 0;
|
||||||
// Increment sector when wrapping
|
// Increment sector when wrapping
|
||||||
++ position.sector;
|
++ 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)
|
u8array_to_u16 (entry->entryData, DIR_ENTRY_cDate)
|
||||||
);
|
);
|
||||||
st->st_spare3 = 0;
|
st->st_spare3 = 0;
|
||||||
st->st_blksize = BYTES_PER_READ; // Prefered file I/O block size
|
st->st_blksize = partition->bytesPerSector; // 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_blocks = (st->st_size + partition->bytesPerSector - 1) / partition->bytesPerSector; // File size in blocks
|
||||||
st->st_spare4[0] = 0;
|
st->st_spare4[0] = 0;
|
||||||
st->st_spare4[1] = 0;
|
st->st_spare4[1] = 0;
|
||||||
}
|
}
|
||||||
|
@ -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
|
// Set append pointer to the end of the file
|
||||||
file->appendPosition.cluster = _FAT_fat_lastCluster (partition, file->startCluster);
|
file->appendPosition.cluster = _FAT_fat_lastCluster (partition, file->startCluster);
|
||||||
file->appendPosition.sector = (file->filesize % partition->bytesPerCluster) / BYTES_PER_READ;
|
file->appendPosition.sector = (file->filesize % partition->bytesPerCluster) / partition->bytesPerSector;
|
||||||
file->appendPosition.byte = file->filesize % BYTES_PER_READ;
|
file->appendPosition.byte = file->filesize % partition->bytesPerSector;
|
||||||
|
|
||||||
// Check if the end of the file is on the end of a cluster
|
// Check if the end of the file is on the end of a cluster
|
||||||
if ( (file->filesize > 0) && ((file->filesize % partition->bytesPerCluster)==0) ){
|
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;
|
cache = file->partition->cache;
|
||||||
|
|
||||||
// Align to sector
|
// Align to sector
|
||||||
tempVar = BYTES_PER_READ - position.byte;
|
tempVar = partition->bytesPerSector - position.byte;
|
||||||
if (tempVar > remain) {
|
if (tempVar > remain) {
|
||||||
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,
|
_FAT_cache_readPartialSector ( cache, ptr, _FAT_fat_clusterToSector (partition, position.cluster) + position.sector,
|
||||||
position.byte, tempVar);
|
position.byte, tempVar);
|
||||||
@ -395,7 +395,7 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
|
|||||||
ptr += tempVar;
|
ptr += tempVar;
|
||||||
|
|
||||||
position.byte += tempVar;
|
position.byte += tempVar;
|
||||||
if (position.byte >= BYTES_PER_READ) {
|
if (position.byte >= partition->bytesPerSector) {
|
||||||
position.byte = 0;
|
position.byte = 0;
|
||||||
position.sector++;
|
position.sector++;
|
||||||
}
|
}
|
||||||
@ -403,10 +403,10 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
|
|||||||
|
|
||||||
// align to cluster
|
// align to cluster
|
||||||
// tempVar is number of sectors to read
|
// 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;
|
tempVar = partition->sectorsPerCluster - position.sector;
|
||||||
} else {
|
} else {
|
||||||
tempVar = remain / BYTES_PER_READ;
|
tempVar = remain / partition->bytesPerSector;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tempVar > 0) && flagNoError) {
|
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;
|
flagNoError = false;
|
||||||
r->_errno = EIO;
|
r->_errno = EIO;
|
||||||
} else {
|
} else {
|
||||||
ptr += tempVar * BYTES_PER_READ;
|
ptr += tempVar * partition->bytesPerSector;
|
||||||
remain -= tempVar * BYTES_PER_READ;
|
remain -= tempVar * partition->bytesPerSector;
|
||||||
position.sector += tempVar;
|
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;
|
chunkSize += partition->bytesPerCluster;
|
||||||
} while ((nextChunkStart == chunkEnd + 1) &&
|
} while ((nextChunkStart == chunkEnd + 1) &&
|
||||||
#ifdef LIMIT_SECTORS
|
#ifdef LIMIT_SECTORS
|
||||||
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * BYTES_PER_READ) &&
|
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * partition->bytesPerSector) &&
|
||||||
#endif
|
#endif
|
||||||
(chunkSize + partition->bytesPerCluster <= remain));
|
(chunkSize + partition->bytesPerCluster <= remain));
|
||||||
|
|
||||||
if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster),
|
if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster),
|
||||||
chunkSize / BYTES_PER_READ, ptr))
|
chunkSize / partition->bytesPerSector, ptr))
|
||||||
{
|
{
|
||||||
flagNoError = false;
|
flagNoError = false;
|
||||||
r->_errno = EIO;
|
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
|
// 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 ((tempVar > 0) && flagNoError) {
|
||||||
if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster),
|
if (!_FAT_cache_readSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster),
|
||||||
tempVar, ptr))
|
tempVar, ptr))
|
||||||
@ -485,8 +485,8 @@ ssize_t _FAT_read_r (struct _reent *r, int fd, char *ptr, size_t len) {
|
|||||||
flagNoError = false;
|
flagNoError = false;
|
||||||
r->_errno = EIO;
|
r->_errno = EIO;
|
||||||
} else {
|
} else {
|
||||||
ptr += tempVar * BYTES_PER_READ;
|
ptr += tempVar * partition->bytesPerSector;
|
||||||
remain -= tempVar * BYTES_PER_READ;
|
remain -= tempVar * partition->bytesPerSector;
|
||||||
position.sector += tempVar;
|
position.sector += tempVar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -555,13 +555,14 @@ static bool _FAT_file_extend_r (struct _reent *r, FILE_STRUCT* file) {
|
|||||||
PARTITION* partition = file->partition;
|
PARTITION* partition = file->partition;
|
||||||
CACHE* cache = file->partition->cache;
|
CACHE* cache = file->partition->cache;
|
||||||
FILE_POSITION position;
|
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 remain;
|
||||||
uint32_t tempNextCluster;
|
uint32_t tempNextCluster;
|
||||||
unsigned int sector;
|
unsigned int sector;
|
||||||
|
|
||||||
position.byte = file->filesize % BYTES_PER_READ;
|
position.byte = file->filesize % partition->bytesPerSector;
|
||||||
position.sector = (file->filesize % partition->bytesPerCluster) / BYTES_PER_READ;
|
position.sector = (file->filesize % partition->bytesPerCluster) / partition->bytesPerSector;
|
||||||
// It is assumed that there is always a startCluster
|
// It is assumed that there is always a startCluster
|
||||||
// This will be true when _FAT_file_extend_r is called from _FAT_write_r
|
// This will be true when _FAT_file_extend_r is called from _FAT_write_r
|
||||||
position.cluster = _FAT_fat_lastCluster (partition, file->startCluster);
|
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;
|
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
|
// Only need to clear to the end of the sector
|
||||||
_FAT_cache_writePartialSector (cache, zeroBuffer,
|
_FAT_cache_writePartialSector (cache, zeroBuffer,
|
||||||
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, remain);
|
_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) {
|
if (position.byte > 0) {
|
||||||
_FAT_cache_writePartialSector (cache, zeroBuffer,
|
_FAT_cache_writePartialSector (cache, zeroBuffer,
|
||||||
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte,
|
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte,
|
||||||
BYTES_PER_READ - position.byte);
|
partition->bytesPerSector - position.byte);
|
||||||
remain -= (BYTES_PER_READ - position.byte);
|
remain -= (partition->bytesPerSector - position.byte);
|
||||||
position.byte = 0;
|
position.byte = 0;
|
||||||
position.sector ++;
|
position.sector ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (remain >= BYTES_PER_READ) {
|
while (remain >= partition->bytesPerSector) {
|
||||||
if (position.sector >= partition->sectorsPerCluster) {
|
if (position.sector >= partition->sectorsPerCluster) {
|
||||||
position.sector = 0;
|
position.sector = 0;
|
||||||
// Ran out of clusters so get a new one
|
// 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;
|
sector = _FAT_fat_clusterToSector (partition, position.cluster) + position.sector;
|
||||||
_FAT_cache_writeSectors (cache, sector, 1, zeroBuffer);
|
_FAT_cache_writeSectors (cache, sector, 1, zeroBuffer);
|
||||||
|
|
||||||
remain -= BYTES_PER_READ;
|
remain -= partition->bytesPerSector;
|
||||||
position.sector ++;
|
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);
|
_FAT_check_position_for_next_cluster(r, &position, partition, remain, &flagNoError);
|
||||||
|
|
||||||
// Align to sector
|
// Align to sector
|
||||||
tempVar = BYTES_PER_READ - position.byte;
|
tempVar = partition->bytesPerSector - position.byte;
|
||||||
if (tempVar > remain) {
|
if (tempVar > remain) {
|
||||||
tempVar = remain;
|
tempVar = remain;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tempVar < BYTES_PER_READ) && flagNoError) {
|
if ((tempVar < partition->bytesPerSector) && flagNoError) {
|
||||||
// Write partial sector to disk
|
// Write partial sector to disk
|
||||||
_FAT_cache_writePartialSector (cache, ptr,
|
_FAT_cache_writePartialSector (cache, ptr,
|
||||||
_FAT_fat_clusterToSector (partition, position.cluster) + position.sector, position.byte, tempVar);
|
_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
|
// Move onto next sector
|
||||||
if (position.byte >= BYTES_PER_READ) {
|
if (position.byte >= partition->bytesPerSector) {
|
||||||
position.byte = 0;
|
position.byte = 0;
|
||||||
position.sector ++;
|
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
|
// Align to cluster
|
||||||
// tempVar is number of sectors to write
|
// 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;
|
tempVar = partition->sectorsPerCluster - position.sector;
|
||||||
} else {
|
} else {
|
||||||
tempVar = remain / BYTES_PER_READ;
|
tempVar = remain / partition->bytesPerSector;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tempVar > 0 && tempVar < partition->sectorsPerCluster) && flagNoError) {
|
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;
|
flagNoError = false;
|
||||||
r->_errno = EIO;
|
r->_errno = EIO;
|
||||||
} else {
|
} else {
|
||||||
ptr += tempVar * BYTES_PER_READ;
|
ptr += tempVar * partition->bytesPerSector;
|
||||||
remain -= tempVar * BYTES_PER_READ;
|
remain -= tempVar * partition->bytesPerSector;
|
||||||
position.sector += tempVar;
|
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
|
// group consecutive clusters
|
||||||
while (flagNoError &&
|
while (flagNoError &&
|
||||||
#ifdef LIMIT_SECTORS
|
#ifdef LIMIT_SECTORS
|
||||||
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * BYTES_PER_READ) &&
|
(chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * partition->bytesPerSector) &&
|
||||||
#endif
|
#endif
|
||||||
(chunkSize + partition->bytesPerCluster < remain))
|
(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,
|
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;
|
flagNoError = false;
|
||||||
r->_errno = EIO;
|
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);
|
_FAT_check_position_for_next_cluster(r, &position, partition, remain, &flagNoError);
|
||||||
|
|
||||||
// Write remaining sectors
|
// 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 ((tempVar > 0) && flagNoError) {
|
||||||
if (!_FAT_cache_writeSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster), tempVar, ptr))
|
if (!_FAT_cache_writeSectors (cache, _FAT_fat_clusterToSector (partition, position.cluster), tempVar, ptr))
|
||||||
{
|
{
|
||||||
flagNoError = false;
|
flagNoError = false;
|
||||||
r->_errno = EIO;
|
r->_errno = EIO;
|
||||||
} else {
|
} else {
|
||||||
ptr += tempVar * BYTES_PER_READ;
|
ptr += tempVar * partition->bytesPerSector;
|
||||||
remain -= tempVar * BYTES_PER_READ;
|
remain -= tempVar * partition->bytesPerSector;
|
||||||
position.sector += tempVar;
|
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,
|
// Calculate the sector and byte of the current position,
|
||||||
// and store them
|
// and store them
|
||||||
file->rwPosition.sector = (position % partition->bytesPerCluster) / BYTES_PER_READ;
|
file->rwPosition.sector = (position % partition->bytesPerCluster) / partition->bytesPerSector;
|
||||||
file->rwPosition.byte = position % BYTES_PER_READ;
|
file->rwPosition.byte = position % partition->bytesPerSector;
|
||||||
|
|
||||||
nextCluster = _FAT_fat_nextCluster (partition, cluster);
|
nextCluster = _FAT_fat_nextCluster (partition, cluster);
|
||||||
while ((clusCount > 0) && (nextCluster != CLUSTER_FREE) && (nextCluster != CLUSTER_EOF)) {
|
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);
|
lastCluster = _FAT_fat_trimChain (partition, file->startCluster, chainLength);
|
||||||
|
|
||||||
if (file->append) {
|
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?
|
// Does the end of the file fall on the edge of a cluster?
|
||||||
if (newSize % partition->bytesPerCluster == 0) {
|
if (newSize % partition->bytesPerCluster == 0) {
|
||||||
// Set a flag to allocate a new cluster
|
// Set a flag to allocate a new cluster
|
||||||
file->appendPosition.sector = partition->sectorsPerCluster;
|
file->appendPosition.sector = partition->sectorsPerCluster;
|
||||||
} else {
|
} else {
|
||||||
file->appendPosition.sector = (newSize % partition->bytesPerCluster) / BYTES_PER_READ;
|
file->appendPosition.sector = (newSize % partition->bytesPerCluster) / partition->bytesPerSector;
|
||||||
}
|
}
|
||||||
file->appendPosition.cluster = lastCluster;
|
file->appendPosition.cluster = lastCluster;
|
||||||
}
|
}
|
||||||
|
@ -54,15 +54,15 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
|
|||||||
case FS_FAT12:
|
case FS_FAT12:
|
||||||
{
|
{
|
||||||
u32 nextCluster_h;
|
u32 nextCluster_h;
|
||||||
sector = partition->fat.fatStart + (((cluster * 3) / 2) / BYTES_PER_READ);
|
sector = partition->fat.fatStart + (((cluster * 3) / 2) / partition->bytesPerSector);
|
||||||
offset = ((cluster * 3) / 2) % BYTES_PER_READ;
|
offset = ((cluster * 3) / 2) % partition->bytesPerSector;
|
||||||
|
|
||||||
|
|
||||||
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u8));
|
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u8));
|
||||||
|
|
||||||
offset++;
|
offset++;
|
||||||
|
|
||||||
if (offset >= BYTES_PER_READ) {
|
if (offset >= partition->bytesPerSector) {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
sector++;
|
sector++;
|
||||||
}
|
}
|
||||||
@ -85,8 +85,8 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FS_FAT16:
|
case FS_FAT16:
|
||||||
sector = partition->fat.fatStart + ((cluster << 1) / BYTES_PER_READ);
|
sector = partition->fat.fatStart + ((cluster << 1) / partition->bytesPerSector);
|
||||||
offset = (cluster % (BYTES_PER_READ >> 1)) << 1;
|
offset = (cluster % (partition->bytesPerSector >> 1)) << 1;
|
||||||
|
|
||||||
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u16));
|
_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;
|
break;
|
||||||
|
|
||||||
case FS_FAT32:
|
case FS_FAT32:
|
||||||
sector = partition->fat.fatStart + ((cluster << 2) / BYTES_PER_READ);
|
sector = partition->fat.fatStart + ((cluster << 2) / partition->bytesPerSector);
|
||||||
offset = (cluster % (BYTES_PER_READ >> 2)) << 2;
|
offset = (cluster % (partition->bytesPerSector >> 2)) << 2;
|
||||||
|
|
||||||
_FAT_cache_readLittleEndianValue (partition->cache, &nextCluster, sector, offset, sizeof(u32));
|
_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;
|
break;
|
||||||
|
|
||||||
case FS_FAT12:
|
case FS_FAT12:
|
||||||
sector = partition->fat.fatStart + (((cluster * 3) / 2) / BYTES_PER_READ);
|
sector = partition->fat.fatStart + (((cluster * 3) / 2) / partition->bytesPerSector);
|
||||||
offset = ((cluster * 3) / 2) % BYTES_PER_READ;
|
offset = ((cluster * 3) / 2) % partition->bytesPerSector;
|
||||||
|
|
||||||
if (cluster & 0x01) {
|
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));
|
_FAT_cache_writeLittleEndianValue (partition->cache, value & 0xFF, sector, offset, sizeof(u8));
|
||||||
|
|
||||||
offset++;
|
offset++;
|
||||||
if (offset >= BYTES_PER_READ) {
|
if (offset >= partition->bytesPerSector) {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
sector++;
|
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));
|
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u8));
|
||||||
|
|
||||||
offset++;
|
offset++;
|
||||||
if (offset >= BYTES_PER_READ) {
|
if (offset >= partition->bytesPerSector) {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
sector++;
|
sector++;
|
||||||
}
|
}
|
||||||
@ -174,16 +174,16 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FS_FAT16:
|
case FS_FAT16:
|
||||||
sector = partition->fat.fatStart + ((cluster << 1) / BYTES_PER_READ);
|
sector = partition->fat.fatStart + ((cluster << 1) / partition->bytesPerSector);
|
||||||
offset = (cluster % (BYTES_PER_READ >> 1)) << 1;
|
offset = (cluster % (partition->bytesPerSector >> 1)) << 1;
|
||||||
|
|
||||||
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u16));
|
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u16));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FS_FAT32:
|
case FS_FAT32:
|
||||||
sector = partition->fat.fatStart + ((cluster << 2) / BYTES_PER_READ);
|
sector = partition->fat.fatStart + ((cluster << 2) / partition->bytesPerSector);
|
||||||
offset = (cluster % (BYTES_PER_READ >> 2)) << 2;
|
offset = (cluster % (partition->bytesPerSector >> 2)) << 2;
|
||||||
|
|
||||||
_FAT_cache_writeLittleEndianValue (partition->cache, value, sector, offset, sizeof(u32));
|
_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 _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster) {
|
||||||
uint32_t newCluster;
|
uint32_t newCluster;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint8_t emptySector[BYTES_PER_READ];
|
uint8_t emptySector[partition->bytesPerSector];
|
||||||
|
|
||||||
// Link the cluster
|
// Link the cluster
|
||||||
newCluster = _FAT_fat_linkFreeCluster(partition, 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
|
// 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++) {
|
for (i = 0; i < partition->sectorsPerCluster; i++) {
|
||||||
_FAT_cache_writeSectors (partition->cache,
|
_FAT_cache_writeSectors (partition->cache,
|
||||||
_FAT_fat_clusterToSector (partition, newCluster) + i,
|
_FAT_fat_clusterToSector (partition, newCluster) + i,
|
||||||
|
@ -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_SIG1[4] = {'R', 'R', 'a', 'A'};
|
||||||
static const char FS_INFO_SIG2[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)
|
sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
|
||||||
{
|
{
|
||||||
uint8_t part_table[16*4];
|
uint8_t part_table[16*4];
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(MAX_SECTOR_SIZE);
|
||||||
|
if(!sectorBuffer) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Read first sector of disc
|
// Read first sector of disc
|
||||||
if (!_FAT_disc_readSectors (disc, 0, 1, sectorBuffer)) {
|
if (!_FAT_disc_readSectors (disc, 0, 1, sectorBuffer)) {
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,6 +128,7 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
|
|||||||
|
|
||||||
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) ||
|
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_lba;
|
return part_lba;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,29 +141,40 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
|
|||||||
|
|
||||||
for(n=0;n<8;n++) // max 8 logic partitions
|
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) ;
|
part_lba2 = part_lba + next_lba2 + u8array_to_u32(sectorBuffer, 0x1C6) ;
|
||||||
next_lba2 = u8array_to_u32(sectorBuffer, 0x1D6);
|
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)) ||
|
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;
|
return part_lba2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(next_lba2==0) break;
|
if(next_lba2==0) break;
|
||||||
}
|
}
|
||||||
} else {
|
} 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)) ||
|
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_lba;
|
return part_lba;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return 0;
|
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* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector) {
|
||||||
PARTITION* partition;
|
PARTITION* partition;
|
||||||
|
|
||||||
|
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(MAX_SECTOR_SIZE);
|
||||||
|
if(!sectorBuffer) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Read first sector of disc
|
// Read first sector of disc
|
||||||
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
|
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure it is a valid MBR or boot sector
|
// Make sure it is a valid MBR or boot sector
|
||||||
if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) {
|
if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) {
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,19 +210,21 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
|
|||||||
} else {
|
} else {
|
||||||
startSector = FindFirstValidPartition(disc);
|
startSector = FindFirstValidPartition(disc);
|
||||||
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
|
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now verify that this is indeed a FAT partition
|
// Now verify that this is indeed a FAT partition
|
||||||
if (memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) &&
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
partition = (PARTITION*) _FAT_mem_allocate (sizeof(PARTITION));
|
partition = (PARTITION*) _FAT_mem_allocate (sizeof(PARTITION));
|
||||||
if (partition == NULL) {
|
if (partition == NULL) {
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return NULL;
|
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->numberOfSectors = u8array_to_u32( sectorBuffer, BPB_numSectors);
|
||||||
}
|
}
|
||||||
|
|
||||||
partition->bytesPerSector = BYTES_PER_READ; // Sector size is redefined to be 512 bytes
|
partition->bytesPerSector = u8array_to_u16(sectorBuffer, BPB_bytesPerSector);
|
||||||
partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster] * u8array_to_u16(sectorBuffer, BPB_bytesPerSector) / BYTES_PER_READ;
|
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->bytesPerCluster = partition->bytesPerSector * partition->sectorsPerCluster;
|
||||||
partition->fat.fatStart = startSector + u8array_to_u16(sectorBuffer, BPB_reservedSectors);
|
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
|
// 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
|
// Set current directory to the root
|
||||||
partition->cwdCluster = partition->rootDirCluster;
|
partition->cwdCluster = partition->rootDirCluster;
|
||||||
@ -282,6 +314,8 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
|
|||||||
|
|
||||||
_FAT_partition_readFSinfo(partition);
|
_FAT_partition_readFSinfo(partition);
|
||||||
|
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
|
|
||||||
return partition;
|
return partition;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,8 +362,11 @@ void _FAT_partition_createFSinfo(PARTITION * partition)
|
|||||||
if(partition->readOnly || partition->filesysType != FS_FAT32)
|
if(partition->readOnly || partition->filesysType != FS_FAT32)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint8_t sectorBuffer[BYTES_PER_READ];
|
uint8_t *sectorBuffer = (uint8_t*) _FAT_mem_allocate(partition->bytesPerSector);
|
||||||
memset(sectorBuffer, 0, sizeof(sectorBuffer));
|
if(!sectorBuffer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memset(sectorBuffer, 0, partition->bytesPerSector);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < 4; ++i)
|
for(i = 0; i < 4; ++i)
|
||||||
@ -346,6 +383,8 @@ void _FAT_partition_createFSinfo(PARTITION * partition)
|
|||||||
sectorBuffer[FSIB_bootSig_AA] = 0xAA;
|
sectorBuffer[FSIB_bootSig_AA] = 0xAA;
|
||||||
|
|
||||||
_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer);
|
_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer);
|
||||||
|
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _FAT_partition_readFSinfo(PARTITION * partition)
|
void _FAT_partition_readFSinfo(PARTITION * partition)
|
||||||
@ -353,24 +392,29 @@ void _FAT_partition_readFSinfo(PARTITION * partition)
|
|||||||
if(partition->filesysType != FS_FAT32)
|
if(partition->filesysType != FS_FAT32)
|
||||||
return;
|
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
|
// Read first sector of disc
|
||||||
if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
|
if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) != 0 ||
|
if(memcmp(sectorBuffer+FSIB_SIG1, FS_INFO_SIG1, 4) != 0 ||
|
||||||
memcmp(sectorBuffer+FSIB_SIG2, FS_INFO_SIG2, 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!
|
//sector does not yet exist, create one!
|
||||||
_FAT_partition_createFSinfo(partition);
|
_FAT_partition_createFSinfo(partition);
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
partition->fat.numberFreeCluster = u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster);
|
partition->fat.numberFreeCluster = u8array_to_u32(sectorBuffer, FSIB_numberOfFreeCluster);
|
||||||
partition->fat.numberLastAllocCluster = u8array_to_u32(sectorBuffer, FSIB_numberLastAllocCluster);
|
partition->fat.numberLastAllocCluster = u8array_to_u32(sectorBuffer, FSIB_numberLastAllocCluster);
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _FAT_partition_writeFSinfo(PARTITION * partition)
|
void _FAT_partition_writeFSinfo(PARTITION * partition)
|
||||||
@ -378,21 +422,26 @@ void _FAT_partition_writeFSinfo(PARTITION * partition)
|
|||||||
if(partition->filesysType != FS_FAT32)
|
if(partition->filesysType != FS_FAT32)
|
||||||
return;
|
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
|
// Read first sector of disc
|
||||||
if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
|
if (!_FAT_disc_readSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
|
||||||
|
_FAT_mem_free(sectorBuffer);
|
||||||
return;
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
u32_to_u8array(sectorBuffer, FSIB_numberOfFreeCluster, partition->fat.numberFreeCluster);
|
u32_to_u8array(sectorBuffer, FSIB_numberOfFreeCluster, partition->fat.numberFreeCluster);
|
||||||
u32_to_u8array(sectorBuffer, FSIB_numberLastAllocCluster, partition->fat.numberLastAllocCluster);
|
u32_to_u8array(sectorBuffer, FSIB_numberLastAllocCluster, partition->fat.numberLastAllocCluster);
|
||||||
|
|
||||||
// Read first sector of disc
|
// Read first sector of disc
|
||||||
if (!_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer)) {
|
_FAT_disc_writeSectors (partition->disc, partition->fsInfoSector, 1, sectorBuffer);
|
||||||
return;
|
_FAT_mem_free(sectorBuffer);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,9 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "lock.h"
|
#include "lock.h"
|
||||||
|
|
||||||
|
#define MIN_SECTOR_SIZE 512
|
||||||
|
#define MAX_SECTOR_SIZE 4096
|
||||||
|
|
||||||
// Filesystem type
|
// Filesystem type
|
||||||
typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;
|
typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user