📄 cluster.c
字号:
/*************************************************************
File Name: CLUSTER.C *
**************************************************************
Programmer: Huang Giun-Haur
Last Modified Date: 1999/2/1
Compiler : Gnu Cross-compiler
Platform : X86 protection mode
Usage :
int FAT_read_cluster(unsigned short cluster,
unsigned short *buffer)
unsigned short FAT_write_cluster(unsigned short cluster,
unsigned short *buffer)
unsigned short FAT_find_free_cluster(void)
void FAT_clear_fat_cluster_chain(int fhandle)
void FAT_free_fat_cluster_chain(unsigned short startCluster)
void FAT_Delete_SubDir_Entry(unsigned short clusterNo,
unsigned short nThEntry,
unsigned short *clusterBuffer)
void dump_fat1x_cluster_chain(int fhandle)
void FAT_recycleUnusedCluster(short drive, unsigned short clusterNo)
*************************************************************/
#include <sys/syscall.h>
// we're using compiler-versioned stdio.h
#include <stdio.h>
//#include "../../RDebug/include/RDebug.h"
#ifdef _PROCOMP_
#include "/rtos/driver/FileSys/FileSys.h"
#else
#include "filesys/include/FileSys.h"
#endif
#include "../include/fat1x.h"
#include "../include/cluster.h"
#ifdef FAT_USE_PCMCIA
/**** added by chilong ****/
//#include "../pcm/cf_typedef.h"
/**** added by chilong ****/
#include "../include/ata_pcc.h"
#else
#include "../include/ata_pcc.h"
#endif
#ifdef FAT_ID
//int FATAtaSemaphoreID;
// modified by chilong 02/08/2002
int FATAtaSemaphoreID = -1;
unsigned short FATEndOfChain[16] = {0, // (0x00) Unknown
0x0FF8, // (0x01) FAT12
0, // (0x02) non DOS
0, // (0x03) non DOS
0xFFF8, // (0x04) FAT16 (<32MB)
0, // (0x05) Extended
0xFFF8, // (0x06) FAT16 (>32MB)
0, // (0x07) non DOS
0, // (0x08) non DOS
0, // (0x09) non DOS
0, // (0x0A) non DOS
0, // (0x0B) FAT32
0, // (0x0C) FAT32 (LBA)
0, // (0x0D) non DOS
0xFFF8, // (0x0E) FAT16 (>32MB, LBA)
0 // (0x0F) Extended (LBA)
};
unsigned short FATBadCluster[16] = { 0, // (0x00) Unknown
0x0FF7, // (0x01) FAT12
0, // (0x02) non DOS
0, // (0x03) non DOS
0xFFF7, // (0x04) FAT16 (<32MB)
0, // (0x05) Extended
0xFFF7, // (0x06) FAT16 (>32MB)
0, // (0x07) non DOS
0, // (0x08) non DOS
0, // (0x09) non DOS
0, // (0x0A) non DOS
0, // (0x0B) FAT32
0, // (0x0C) FAT32 (LBA)
0, // (0x0D) non DOS
0xFFF7, // (0x0E) FAT16 (>32MB, LBA)
0 // (0x0F) Extended (LBA)
};
#ifdef FAT_CLUSTER_CACHE_ON
/* data cache */
struct FAT_clusterCache FATClusterCache[FAT_CACHE_TAG_NO][FAT_BLOCK_PER_TAG];
unsigned long FATClusterSize = 0;
#endif
#ifdef FAT_FAT_CACHE_ON
/* FAT cache */
struct FAT_fatCache FATFatCache[FAT_FAT_CACHE_BLOCK];
#endif
unsigned short FATBuffer[SECTOR_SIZE / 2];
/* fdebug.c */
#ifdef FAT_CLUSTER_CACHE_ON
#ifdef FAT1X_DEBUG
extern unsigned long FATClusterReadHit; /* cluster read hit count */
extern unsigned long FATClusterReadMiss; /* cluster read miss count */
extern unsigned long FATClusterWriteHit; /* cluster write hit count */
extern unsigned long FATClusterWriteMiss; /* cluster write miss count */
extern unsigned long FATClusterSwap; /* cluster cache swap count */
extern unsigned long FATClusterFlush; /* cluster cache flush count */
#endif
#endif
#ifdef FAT_FAT_CACHE_ON
/* cache statistics */
#ifdef FAT1X_DEBUG
extern unsigned long FATFatReadHit; /* FAT read hit count */
extern unsigned long FATFatReadMiss; /* FAT read miss count */
extern unsigned long FATFatWriteHit; /* FAT write hit count */
extern unsigned long FATFatWriteMiss; /* FAT write miss count */
extern unsigned long FATFatSwap; /* FAT cache swap count */
extern unsigned long FATFatFlush; /* FAT cache flush count */
#endif
#endif
/* init.c */
//extern int FATFatSemaphoreID;
extern unsigned short FATSecPerCluster[DRIVE_NUM];
extern unsigned long FATBytesPerCluster[DRIVE_NUM];
extern unsigned long FATWordsPerCluster[DRIVE_NUM];
extern unsigned short FATTotalCluster[DRIVE_NUM];
extern unsigned short FATSecPerFAT[DRIVE_NUM];
extern unsigned long FAT1Begin[DRIVE_NUM];
extern unsigned long FAT2Begin[DRIVE_NUM];
extern unsigned char FATType[DRIVE_NUM];
extern unsigned short FATFreeClusterBegin[DRIVE_NUM];
//extern int FATErrno;
extern char FATAvailDrive;
/* fat1x.c */
extern int FATHdDriver;
extern struct FAT_FILE **FATHandleTable;
#ifdef FAT_CLUSTER_CACHE_ON
/************************************************************
Function: FAT_init_cluster_cache
Description:
Initialize the cluster cache
Clear the buffer information
Output:
0 SUCCESS
-1 FAILURE
**************************************************************/
int FAT_init_cluster_cache(void)
{
int i, j;
#ifdef FAT1X_DEBUG
SprintStringLn("[FAT_init_cluster_cache]");
#endif
// find the largest cluster size among the partitions
for (i = 0; i < FATAvailDrive; i++)
{
if (FATBytesPerCluster[i] > FATClusterSize)
FATClusterSize = FATBytesPerCluster[i];
}
/* clean up the buffer information in the data cache */
for (i = 0; i < FAT_CACHE_TAG_NO; i++)
for (j = 0; j < FAT_BLOCK_PER_TAG; j++)
{
FATClusterCache[i][j].drive = -1;
FATClusterCache[i][j].cluster_no = 0;
FATClusterCache[i][j].luCount = 0;
FATClusterCache[i][j].dirty = FALSE;
FATClusterCache[i][j].diskBuffer = (void *)ap_malloc(FATClusterSize);
if (FATClusterCache[i][j].diskBuffer == NULL)
{
FATErrno = ERROR_ALLOC_MEM;
return -1;
}
}
return 0;
}
#endif
#ifdef FAT_FAT_CACHE_ON
/************************************************************
Function: FAT_init_cluster_cache
Description:
Initialize the FAT cache
Put the 1st ten sectors from FAT1 to the FAT cache.
Output:
0 SUCCESS
-1 FAILURE
**************************************************************/
int FAT_init_fat_cache(void)
{
short status;
int i;
#ifdef FAT1X_DEBUG
SprintStringLn("[FAT_init_fat_cache]");
#endif
/* read the 1st N sectors from FAT1 to the FAT cache */
for (i = 0; i < FAT_FAT_CACHE_BLOCK; i++)
{
FATFatCache[i].drive = 0;
FATFatCache[i].sec_num = i + FAT1Begin[0];
FATFatCache[i].lu = 0;
FATFatCache[i].DirtySec = FALSE;
FATFatCache[i].Entry = (unsigned short *)ap_malloc(SECTOR_SIZE);
if (FATFatCache[i].Entry == NULL)
{
FATErrno = ERROR_ALLOC_MEM;
return -1;
}
sc_waitSemaphore(FATAtaSemaphoreID);
status = ATA_READ(FATHdDriver, 1, i + FAT1Begin[0], FATFatCache[i].Entry);
sc_signalSemaphore(FATAtaSemaphoreID);
if (status == ATA_FAILURE)
{
FATErrno = ERROR_ATA_READ;
return -1;
}
}
return 0;
}
#endif
/*************************************************************
Function: FAT_read_cluster
Description:
Read the start cluster recorded in the dir entry
Input:
drive - read the cluster from this drive
cluster - the target cluster number
buffer - buffer to hold the content of the cluster
Output:
-1 -> read error
**************************************************************/
int FAT_read_cluster(short drive, unsigned short cluster, unsigned short *buffer)
{
unsigned short status;
unsigned long readSecNO;
#ifdef FAT_CLUSTER_CACHE_ON
unsigned short *p;
unsigned long mincount;
int tag, i, j;
char flushDrive;
#endif
#ifdef FAT1X_DEBUG
SprintStringLn("[FAT_read_cluster]");
#endif
/**** added by chilong 01/28/2002 ****/
if (cluster >= (FATTotalCluster[drive] + 2) || cluster < NO_OF_RESERVED_CLUSTER)
{
return -1;
}
/**** added by chilong 01/28/2002 ****/
#ifdef FAT_CLUSTER_CACHE_ON /* if cluster cache is available */
/* clusters are assigned to cache tag in interleaved way */
tag = cluster % FAT_CACHE_TAG_NO;
/* check if the requested cluster is already in the cache */
for (i = 0; i < FAT_BLOCK_PER_TAG; i++)
{
if ((cluster == FATClusterCache[tag][i].cluster_no) && (drive == FATClusterCache[tag][i].drive))
{
/* requested cluster found in cache */
#ifdef FAT1X_DEBUG
/* data hit count scores 1 */
FATClusterReadHit++;
#endif
/* move the data from cache to the user buffer */
for (j = 0; j < FATWordsPerCluster[drive]; j++)
{
*(buffer + j) = *(FATClusterCache[tag][i].diskBuffer + j);
}
/* the buffer has been accessed once more */
FATClusterCache[tag][i].luCount++;
return SUCCESS;
}
}
/* cache miss, read the data from the drive to user buffer */
#ifdef FAT1X_DEBUG
/* data miss count scores 1 */
FATClusterReadMiss++;
#endif
readSecNO = FAT_cluster_to_logical_sector(drive, cluster);
sc_waitSemaphore(FATAtaSemaphoreID); // 玂臔 ATA ざ
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -