⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cluster.c

📁 PDA上的CF CARD 文件系统的建立程式
💻 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 + -