📄 fsmdfs.c
字号:
/*****************************************************************************
FILE NAME: FsmDfs.c
DESCRIPTION:
This module contains functions of Data file system.
Copyright (c) 2002, VIA Technologies, Inc.
*****************************************************************************/
#include "fsmdefs.h"
#include "ostype.h"
#include "FsmApi.h"
#include "string.h"
#include "FsmQueue.h"
#include "FsmDev.h"
#include "FsmDfs.h"
#include "stdlib.h"
#include "FsmFlash.h"
#define FsmGetCurrentDate() 0
#define MAX_DFS_FD 20
/* global vairibale declare */
FsmFsDrvT FsmDfsDrv =
{
FsmDfsCreate,
FsmDfsOpen,
FsmDfsDelete,
FsmDfsClose,
FsmDfsRead,
FsmDfsWrite,
FsmDfsIoCtrl,
FsmDfsInit,
FsmDfsTerminate
};
FsmDfsFileDescriptorT FsmDfsFds[MAX_DFS_FD];
/* local vairibale declare */
static HMSEM FsmDfsMtxSem;
static HFSMTASK hWriteTask;
static uint32
DfsLocateFile(
FsmDevObjHdrT * DevP,
char * path,
uint32 * ParentDirFirstLsn,
FsmFileDirEntryT * entry
);
static uint32
DfsReadFileEntry(
FsmDevObjHdrT * DevP,
uint32 * StartLsn,
uint32 * offset,
FsmFileDirEntryT * entry
);
static uint32 DfsFilenameValid(const char * path);
static uint32 DfsAllocFd(void);
static uint32 DfsFreeFd(uint32 fd);
static uint32 DfsIsParentDirOpened(char * path);
static uint32 DfsIsFileOpened(char * path);
/*****************************************************************
*
* FsmDfsStartup :
* Initialize the internal structure of data file system.
*
* Input:
* NONE
*
* Output:
* ERR_NONE on success
*
* error code on failure.
*
*****************************************************************/
uint32 FsmDfsStartup()
{
uint32 i;
uint32 status;
FsmDfsMtxSem = FsmCreateMtxSem(1);
if (FsmDfsMtxSem == NULL)
{
return ERR_SYSTEM;
}
status = QueueCreate();
if (status != ERR_NONE)
{
FsmDeleteMtxSem(FsmDfsMtxSem);
return status;
}
FsmMemorySet((uint8 *)&FsmDfsFds[0],
0,
MAX_DFS_FD * sizeof(FsmDfsFileDescriptorT)
);
for(i = 0; i < MAX_DFS_FD; i++)
{
FsmDfsFds[i].Flag = DFD_FLAG_FREE;
}
for(i = 0; i < MAX_DFS_FD; i++)
{
FsmDfsFds[i].MutexSem = FsmCreateMtxSem(1);
if(FsmDfsFds[i].MutexSem == NULL)
break;
}
if(i < MAX_DFS_FD)
{
while(i > 0)
{
FsmDeleteMtxSem(FsmDfsFds[i - 1].MutexSem);
FsmDfsFds[i - 1].MutexSem = NULL;
i--;
}
QueueDestroy();
FsmDeleteMtxSem(FsmDfsMtxSem);
return ERR_SYSTEM;
}
hWriteTask = FsmCreateTask( "bkgd_wr",
FSM_WRITE_TASK_PRIORITY,
FSM_WRITE_TASK_STACK_SIZE,
(uint32)BkgdWriteTask
);
if (hWriteTask == NULL)
{
for(i = 0; i < MAX_DFS_FD; i++)
{
FsmDeleteMtxSem(FsmDfsFds[i].MutexSem);
FsmDfsFds[i].MutexSem = NULL;
}
QueueDestroy();
FsmDeleteMtxSem(FsmDfsMtxSem);
return ERR_SYSTEM;
}
return ERR_NONE;
}
/*****************************************************************
*
* FsmDfsExit :
* cleanup the internal structure of data file system
* before data file system terminates.
*
* Input:
* NONE
*
* Output:
* ERR_NONE on success
*
* error code on failure.
*
*****************************************************************/
uint32 FsmDfsExit()
{
uint32 i;
FsmDeleteTask(hWriteTask);
for(i = 0; i < MAX_DFS_FD; i++)
{
FsmDeleteMtxSem(FsmDfsFds[i].MutexSem);
FsmDfsFds[i].MutexSem = NULL;
}
QueueDestroy();
FsmDeleteMtxSem(FsmDfsMtxSem);
return ERR_NONE;
}
/*****************************************************************
* Function Name:
* FsmDfsInit
*
* Description :
* Parse command , implement the ioctrl interface
*
* Input :
* DevObjP : pointer to the Device structure
* SectorSize : sector size
*
* First Edit 2003.8.13 wsm
*
*****************************************************************/
uint32 FsmDfsInit(FsmDevObjHdrT * DevObjP, uint32 SectorSize)
{
uint32 temp;
FsmFlashMediaT * FlashMedia;
if (SectorSize == 0)
return ERR_PARAM;
if (DevObjP->DevDrvP->FsmDevInit(DevObjP) != HW_ERR_NONE)
{
#ifdef FSM_DEBUG
MonPrintf("\nFailed on Initializing device!");
#endif
return ERR_SYSTEM;
}
/* creat the media structure */
FlashMedia = (FsmFlashMediaT *)FsmTryMalloc(sizeof(FsmFlashMediaT));
if (FlashMedia == NULL )
{
DevObjP->DevDrvP->FsmDevCtrl(DevObjP, DEV_CTRL_DEVICE_DETACH, NULL);
#ifdef FSM_DEBUG
MonPrintf("Malloc fail at start up");
#endif
return ERR_MEMORY;
}
FlashMedia->MediaObjHdr.DevObjP = DevObjP;
FlashMedia->SectorSize = SectorSize;
FlashMedia->BlockSize = ((FsmFlashDevT *)DevObjP)->BlockSize;
temp = ((FsmFlashDevT *)DevObjP)->BlockSize - sizeof(FsmBlockInfoT);
FlashMedia->SectorsPerBlock = (uint16)(temp / (SectorSize + sizeof(FsmFlashSectorHdrT)));
FlashMedia->MaxPsn = ((uint32)FlashMedia->SectorsPerBlock) * (((FsmFlashDevT *)DevObjP)->Blocks);
/* FlashMedia->SpareBlk = (uint16)(-1); */
FlashMedia->MapTblLock = FsmCreateMtxSem(1);
if (FlashMedia->MapTblLock == NULL)
{
#ifdef FSM_DEBUG
MonPrintf("Malloc fail at start up");
#endif
FsmFree((void *)FlashMedia);
DevObjP->DevDrvP->FsmDevCtrl(DevObjP, DEV_CTRL_DEVICE_DETACH, NULL);
return ERR_SYSTEM;
}
FlashMedia->InfoLock = FsmCreateMtxSem(1);
if (FlashMedia->InfoLock == NULL)
{
#ifdef FSM_DEBUG
MonPrintf("Malloc fail at start up");
#endif
FsmDeleteMtxSem(FlashMedia->MapTblLock);
FsmFree((void *)FlashMedia);
DevObjP->DevDrvP->FsmDevCtrl(DevObjP, DEV_CTRL_DEVICE_DETACH, NULL);
return ERR_SYSTEM;
}
temp = FlashMedia->MaxPsn * sizeof(uint32 *);
FlashMedia->Lsn2PsnP = (uint32 *)FsmTryMalloc(temp);
if (FlashMedia->Lsn2PsnP == NULL )
{
#ifdef FSM_DEBUG
MonPrintf("Malloc fail at start up");
#endif
FsmDeleteMtxSem(FlashMedia->InfoLock);
FsmDeleteMtxSem(FlashMedia->MapTblLock);
FsmFree((void *)FlashMedia);
DevObjP->DevDrvP->FsmDevCtrl(DevObjP, DEV_CTRL_DEVICE_DETACH, NULL);
return ERR_MEMORY;
}
FsmMemorySet((uint8 *)FlashMedia->Lsn2PsnP, (uint8)INVALID_PSN, temp);
temp = sizeof(FsmBlockStatisticT) * ((uint32)((FsmFlashDevT*)DevObjP)->Blocks);
FlashMedia->BlockInfoP = (FsmBlockStatisticT *)FsmTryMalloc(temp);
if(FlashMedia->BlockInfoP == NULL)
{
#ifdef FSM_DEBUG
MonPrintf("Malloc fail at start up");
#endif
FsmFree(FlashMedia->Lsn2PsnP);
FsmDeleteMtxSem(FlashMedia->InfoLock);
FsmDeleteMtxSem(FlashMedia->MapTblLock);
FsmFree((void *)FlashMedia);
DevObjP->DevDrvP->FsmDevCtrl(DevObjP, DEV_CTRL_DEVICE_DETACH, NULL);
return ERR_MEMORY;
}
FsmMemorySet((uint8 *)FlashMedia->BlockInfoP, 0, temp);
/* Now FlashMedia (MediaObj) has been initialized. */
DevObjP->MediaObjP = (void *)FlashMedia; /* DevObj has been initialized. It can be passed to InitUnit. */
/* call power lost recovery process */
temp = FsmPlrDfsCheck(DevObjP,
((FsmFlashDevT*)DevObjP)->BlockSize,
((FsmFlashDevT*)DevObjP)->Blocks
);
if(temp != ERR_NONE)
{
FsmFree((void *)FlashMedia->BlockInfoP);
FsmFree(FlashMedia->Lsn2PsnP);
FsmDeleteMtxSem(FlashMedia->InfoLock);
FsmDeleteMtxSem(FlashMedia->MapTblLock);
FsmFree((void *)FlashMedia);
DevObjP->DevDrvP->FsmDevCtrl(DevObjP, DEV_CTRL_DEVICE_DETACH, NULL);
return temp;
}
return ERR_NONE;
}
/*****************************************************************
* Function Name:
* FsmDfsTerminate
* All files opened from this device
* should be closed before calling this function.
* FsmDfsTerminate doesn't close any files.
*
* Description :
* Parse command , implement the ioctrl interface
*
* Input :
* DevObjP : pointer to the Device structure
*
* First Edit 2003.8.13 wsm
*
*****************************************************************/
uint32 FsmDfsTerminate(FsmDevObjHdrT * DevObjP)
{
/* uint32 status;*/
uint32 i;
FsmFlashMediaT * FlashMedia;
FsmGetMtxSem(FsmDfsMtxSem);
/* If it is called when system starts, FsmGetMtxSem always fails.
status = FsmGetMtxSem(FsmDfsMtxSem);
if(status != ERR_NONE)
{
return status;
}
*/
for(i = 0; i < MAX_DFS_FD; i++)
{
if((FsmDfsFds[i].Flag != DFD_FLAG_FREE)
&& (FsmDfsFds[i].FdHdr.DevObjP == DevObjP))
{
break;
}
}
FsmReleaseMtxSem(FsmDfsMtxSem);
if(i < MAX_DFS_FD)
{
return ERR_ACCESS_DENY;
}
/* all files from this device must have been closed before came to here. */
FlashMedia = (FsmFlashMediaT *)DevObjP->MediaObjP;
FsmFree((void *)FlashMedia->BlockInfoP);
FsmFree(FlashMedia->Lsn2PsnP);
FsmDeleteMtxSem(FlashMedia->InfoLock);
FsmDeleteMtxSem(FlashMedia->MapTblLock);
FsmFree((void *)FlashMedia);
DevObjP->DevDrvP->FsmDevCtrl(DevObjP, DEV_CTRL_DEVICE_DETACH, NULL);
return ERR_NONE;
}
/*
* Function Name: DfsOpen
* Description : Open a file, return the file descriptor, implement the open interface
* Arguments : path : file path
* : mode : open mode
* First Edit 2003.8.13 wsm
*/
uint32 FsmDfsOpen(FsmDevObjHdrT * DevObjP, char * path, uint32 mode, uint32 * ErrorCodeP )
{
uint32 status;
uint32 index;
uint32 length;
uint8 root_dir = FALSE;
uint32 ParentDirFirstLsn;
uint32 fd;
FsmFileDirEntryT entry;
#ifdef FSM_DEBUG
MonPrintf("Interface DfsOpen \n");
#endif
root_dir = FALSE;
if(path == NULL)
{
status = ERR_PARAM;
goto DfsOpen_Exit;
}
length = strlen(path);
if((length == 0) || (length > DFS_MAX_PATH_LEN))
{
status = ERR_PARAM;
goto DfsOpen_Exit;
}
if(DfsFilenameValid(path) == FALSE)
{
status = ERR_PARAM;
goto DfsOpen_Exit;
}
if(length > 1)
{
/* path should not end with slash if it is not the root dir. */
if((path[length - 1] == '\\') || (path[length - 1] == '/'))
{
status = ERR_PARAM;
goto DfsOpen_Exit;
}
}
else
{
if ((length == 1) && ((*path == '\\') || (*path == '/')))
{
if(mode & FSM_OPEN_FILE)
{
status = ERR_PARAM;
goto DfsOpen_Exit;
}
root_dir = TRUE;
}
}
if ((status = FsmGetMtxSem(FsmDfsMtxSem)) != ERR_NONE)
{
goto DfsOpen_Exit;
}
index = DfsIsFileOpened(path);
if (index != INVALID_FILE_HANDLE)
{
if ((FsmDfsFds[index].AccessMode & FSM_OPEN_WRITE)
|| (mode & FSM_OPEN_WRITE))
{
/* the file or directory has been opened or is being re-opened for writing. */
FsmReleaseMtxSem(FsmDfsMtxSem);
status = ERR_ACCESS_DENY;
goto DfsOpen_Exit;
}
/* allows multiple open for read. */
}
fd = DfsAllocFd();
if (fd == INVALID_FILE_HANDLE)
{
FsmReleaseMtxSem(FsmDfsMtxSem);
status = ERR_MAX_OPEN;
goto DfsOpen_Exit;
}
FsmDfsFds[fd].AccessMode = mode; /* prevent the followed open for write or for read if mode = WRITE. */
FsmDfsFds[fd].FdHdr.DevObjP = DevObjP; /* prevent this device from being unmounted. */
strcpy(FsmDfsFds[fd].PathName, path);
FsmReleaseMtxSem(FsmDfsMtxSem);
status = FsmGetMtxSem(FsmDfsFds[fd].MutexSem);
if(status != ERR_NONE)
{
DfsFreeFd(fd);
goto DfsOpen_Exit;
}
/* Is it the root directory ? */
if (root_dir)
{
/* FsmDfsFds[fd].AccessMode = mode; */
FsmDfsFds[fd].FileLength = 0;
FsmDfsFds[fd].FirstLsn = 0;
FsmDfsFds[fd].ParentDirFirstLsn = (uint32)(-1); /* 0; */
FsmDfsFds[fd].FilePointer = 0; /* 1; */
FsmDfsFds[fd].CreateDate = 0;
FsmDfsFds[fd].CreateTime = 0;
FsmDfsFds[fd].Attrib = ENTRY_TYPE_SUBDIR;
goto DfsOpen_Exit_Success;
/*
FsmDfsFds[fd].Flag = DFD_FLAG_IN_USE; // prevent from being preempted.
FsmReleaseMtxSem(FsmDfsFds[fd].MutexSem);
if(ErrorCodeP != NULL)
*ErrorCodeP = ERR_NONE;
return fd;
*/
}
else
{
status = DfsLocateFile(DevObjP, path, &ParentDirFirstLsn, &entry);
if (status != ERR_NONE)
{
goto DfsOpen_Exit2;
}
}
if ((entry.Type == ENTRY_TYPE_FILE) && (mode & FSM_OPEN_FILE))
{
status = ERR_NONE;
FsmDfsFds[fd].FileLength = entry.Length;
FsmDfsFds[fd].FilePointer = 0;
}
else if ((entry.Type == ENTRY_TYPE_SUBDIR) && (mode & FSM_OPEN_DIR))
{
status = ERR_NONE;
/*
* For subdirectory, Length always = 0.
* We will use this field as file pointer
* along with FilePointer field.
* In that case, Length field stores sector LSN,
* and FilePointer field stores offset into the sector.
*/
FsmDfsFds[fd].FileLength = entry.FirstLsn;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -