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

📄 stavfs.c

📁 ST5518机顶盒系统文件系统源代码!绝对超值!
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************    File Name   : stavfs.c    Description : Core driver functions.*****************************************************************************//* Includes ---------------------------------------------------------------- */#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <string.h>#include <assert.h>#include "stddefs.h"#include "sttbx.h"#include "stavfs.h"#include "internal.h"#include "avdevice.h"#include "hal.h"#include "diskpart.h"#include "rwbuffer.h"#include "root.h"#include "partitio.h"#include "cat.h"#include "file.h"#include "dir.h"/* Private Types ----------------------------------------------------------- *//* Private Constants ------------------------------------------------------- */#define STAVFS_REVISION "1.0.0"/* Private Variables ------------------------------------------------------- */static stavfs_Device_t LocalDevice[4]; /* Multiple devices    *//* For a quick fix make this global */static stavfs_HAL_t HALData[1];   /* Multiple hard disks *//* The current implementation only supports one hard disk */static BOOL InitialisedLock = FALSE;static semaphore_t GlobalDeviceLock; /* This locks access to the structures spaning the devices *//* Exported Variables -------------------------------------------------- *//* Private Macros ---------------------------------------------------------- *//* Private Function Prototypes --------------------------------------------- */static void InitialiseGlobalData (void);/* Functions --------------------------------------------------------------- *//******************************************************************************Function Name : STAVFS_GetRevision  Description : Report the revision of this implementation of the driver.   Parameters :******************************************************************************/ST_Revision_t STAVFS_GetRevision (){    return (STAVFS_REVISION);}/******************************************************************************Function Name : STAVFS_Close  Description : Close down the disk volume, closing all files and freeing all                allocated memory.   Parameters :******************************************************************************/ST_ErrorCode_t STAVFS_Close (STAVFS_Handle_t Handle){    ST_ErrorCode_t Error = ST_NO_ERROR;    stavfs_Device_t *Device_p = (stavfs_Device_t *) Handle;    if ((Device_p < LocalDevice) || (LocalDevice+TABLE_LEN(LocalDevice) < Device_p) ||        !Device_p->DeviceActive  || (Device_p->OpenHandles == 0))    {        STTBX_Print (("Invalid handle\n"));        Error = ST_ERROR_INVALID_HANDLE;    }    else    {        stavfs_RootSector_t RootSector;        ST_ErrorCode_t      Tmp;        semaphore_wait (&(Device_p->DeviceLock));                /* Flush MCAT now to avoid thrashing, since no more allocation is going          to take place. Leave error reporting to stavfs_CloseAllFilesOnDevice */        stavfs_FlushCat(Device_p);                /* no point flushing directories early because they change as file closes */                /* Find all open file handles and close them */        stavfs_CloseAllFilesOnDevice (Device_p);                /* Close the MCAT (shouldn't need to do any flushing)  */        Tmp = stavfs_CloseCat(Device_p);                if (Tmp != ST_NO_ERROR)        {            STTBX_Print (("Error closing cats\n"));            Error = Tmp;        }        /* Close the root directory (shouldn't need to do any flushing) */        Tmp = stavfs_CloseRootDir(Device_p);                if (Tmp != ST_NO_ERROR)        {            STTBX_Print (("Error closing directories\n"));            Error = Tmp;        }                /* Now mark partition as closed, but also in error if things didn't flush fully */        if (ST_NO_ERROR != stavfs_ReadRootSector (Device_p, &RootSector))        {            STTBX_Print (("Error reading the root sector\n"));            Error = STAVFS_ERROR_UNREADABLE_DISK;        }        else        {            RootSector.StateFlags &= ~ROOT_PARTITION_FLAG_INUSE;                        if (Error != ST_NO_ERROR)            {                RootSector.StateFlags |= ROOT_PARTITION_FLAG_BAD;            }             if (ST_NO_ERROR != stavfs_WriteRootSector (Device_p, &RootSector))            {                STTBX_Print (("Error writing the root sector\n"));                Error = STAVFS_ERROR_UNWRITABLE_DISK;            }        }         Device_p->OpenHandles--;        semaphore_signal (&(Device_p->DeviceLock));    }    return (Error);}/******************************************************************************Function Name : STAVFS_GetFreeDiskSpace  Description : Report the available disk space on the given partition.   Parameters :******************************************************************************/ST_ErrorCode_t STAVFS_GetFreeDiskSpace (STAVFS_Handle_t Handle, U64 * Size){    ST_ErrorCode_t   Error    = ST_NO_ERROR;    stavfs_Device_t *Device_p = (stavfs_Device_t*)Handle;        assert(NULL != Handle);    assert(NULL != Device_p);            if (ST_NO_ERROR != (Error = stavfs_ValidateDevice(Device_p)))    {        STTBX_Print (("Invalid Device\n"));        Error = ST_ERROR_INVALID_HANDLE;    }    else if (Size == NULL)    {        Error = ST_ERROR_BAD_PARAMETER;    }    else    {        /* Lock the driver */        semaphore_wait(&(Device_p->DeviceLock));                Error = stavfs_GetNumFreeClusters(Device_p, Size);                if (Error == ST_NO_ERROR)        {            /* Get the size in sectors */                        INT_I64_MulLit(*Size, Device_p->ClusterSize, *Size);                        /* Get the size in bytes */            /* Multiply by sector size (512) */                        I64_ShiftLeft(9, *Size);        }        else        {            /* Bad Cluster Count */                        INT_I64_SetValue(0, 0, *Size);        }         /* Release the driver */        semaphore_signal(&(Device_p->DeviceLock));    }    return (Error);}/******************************************************************************Function Name : STAVFS_Init  Description : Initialise the driver. We only currently support one instance of                the driver.   Parameters :******************************************************************************/ST_ErrorCode_t STAVFS_Init (ST_DeviceName_t Name, STAVFS_InitParams_t * InitParams){    ST_ErrorCode_t Error = ST_NO_ERROR;    stavfs_HAL_t *ThisHal = NULL;    stavfs_DiskPartitionTable_t PartitionTable;    int i;    /* Perform basic initialisation and aquire the lock */    InitialiseGlobalData ();    if ((Name == NULL)    ||        (Name[0] == '\0') ||                          /* zero length */        (strlen(Name) > sizeof(ST_DeviceName_t) - 1)) /* can't copy in full with zero termination */    {        STTBX_Print (("Bad device name\n"));        Error = ST_ERROR_BAD_PARAMETER;    }    else if (InitParams == NULL)    {        STTBX_Print (("NULL InitParams\n"));        Error = ST_ERROR_BAD_PARAMETER;    }    else if (InitParams->Flags != 0)    {        /* Check the structure flags */        STTBX_Print (("Feature not supported\n"));        Error = ST_ERROR_FEATURE_NOT_SUPPORTED;    }    else if (NULL == InitParams->MemoryPartition)    {        STTBX_Print (("Null Memory Partition\n"));        Error = ST_ERROR_BAD_PARAMETER;    }    else if (InitParams->PartitionNumber > 3 || InitParams->PartitionNumber < 0)    {        /* Check the partition number  */        STTBX_Print (("Bad partition number\n"));        Error = ST_ERROR_BAD_PARAMETER;    }    /* Do we have this disk open */    if (Error == ST_NO_ERROR)    {        for (i = 0; (i < TABLE_LEN (HALData)); i++)        {            if (HALData[i].Initialised)            {                if ((HALData[i].Protocol == InitParams->Protocol) &&                    (HALData[i].UnitNumber == InitParams->UnitNumber) &&                    (0 == strncmp (HALData[i].ATAPIName, InitParams->ATAPIName,                        sizeof (HALData[i].ATAPIName))) &&                    (0 == strncmp (HALData[i].EVTName, InitParams->EVTName,                        sizeof (HALData[i].EVTName))))                {                    ThisHal = HALData + i;                    break;                }            }        }    }    /* Do we have this device open */        if ((Error == ST_NO_ERROR) && (NULL != ThisHal))    {        for (i = 0; (i < TABLE_LEN (LocalDevice)); i++)        {            if ((LocalDevice[i].HALData == ThisHal) && (LocalDevice[i].Partition == InitParams->PartitionNumber))            {                /* We have this disk and partition open */                STTBX_Print (("This disk and partition is already open\n"));                Error = ST_ERROR_ALREADY_INITIALIZED;            }        }    }    /* Is the device name in use */        if ((Error == ST_NO_ERROR) && (NULL != ThisHal))    {        for (i = 0; (i < TABLE_LEN (LocalDevice)); i++)        {            if (LocalDevice[i].DeviceActive &&                (0 == strncmp (LocalDevice[i].DeviceName, Name, sizeof (LocalDevice[i].DeviceName))))            {                /* The name is in use */                STTBX_Print (("This device name is already in use\n"));                Error = ST_ERROR_ALREADY_INITIALIZED;            }        }    }    /* Open the HAL Layer */        if ((Error == ST_NO_ERROR) && (NULL == ThisHal))    {        for (i = 0; (i < TABLE_LEN (HALData)) && HALData[i].Initialised; i++)        {            /* All done in the FOR */        }        if (i == TABLE_LEN (HALData))        {            /* Out of space */            STTBX_Print (("No free handles\n"));            Error = ST_ERROR_NO_FREE_HANDLES;        }        else        {            strncpy (HALData[i].EVTName, InitParams->EVTName, sizeof (HALData[i].EVTName));            strncpy (HALData[i].ATAPIName, InitParams->ATAPIName, sizeof (HALData[i].ATAPIName));            HALData[i].Protocol = InitParams->Protocol;            HALData[i].UnitNumber = InitParams->UnitNumber;            ThisHal = HALData + i;            if (ST_NO_ERROR != (Error = stavfs_HalInit (ThisHal)))            {                STTBX_Print (("Error when opening the HAL layer\n"));            }        }    }    /* Open the Device */    if (Error == ST_NO_ERROR)    {        /* Find a free entry */                for (i = 0; (i < TABLE_LEN (LocalDevice)) && (LocalDevice[i].HALData != NULL); i++)        {            /* All done in the FOR */        }        if (i == TABLE_LEN (LocalDevice))        {            /* Out of space */            STTBX_Print (("No free device handles\n"));            Error = ST_ERROR_NO_FREE_HANDLES;        }        else        {            /* Lock the driver */            semaphore_wait(&(LocalDevice[i].DeviceLock));            /* Set the device name */            strncpy (LocalDevice[i].DeviceName, Name, sizeof (LocalDevice[i].DeviceName));            LocalDevice[i].DeviceActive    = TRUE;            LocalDevice[i].MemoryPartition = InitParams->MemoryPartition;            LocalDevice[i].OpenHandles     = 0;            LocalDevice[i].Partition       = InitParams->PartitionNumber;            LocalDevice[i].HALData         = ThisHal;            LocalDevice[i].RWCache         = NULL;            LocalDevice[i].RootDir         = NULL;            LocalDevice[i].MCat            = NULL;            /* Read the partition table from disk so we know where the root sector is */            if (ST_NO_ERROR != stavfs_ReadPartitionTable (&LocalDevice[i], &PartitionTable))            {                STTBX_Print (("Error reading partition table\n"));                Error = ST_ERROR_BAD_PARAMETER;            }            else            {                /* Set the root sector value */                I64_SetValue (PartitionTable.StartLBA, 0, LocalDevice[i].RootSectorLBA);            }            if (Error == ST_NO_ERROR)            {                /* Initialise the R/W Cache */                Error = stavfs_InitRWCache (LocalDevice + i);            }            if (Error != ST_NO_ERROR)            {                /* If we have had an error then clean up */                int j;                if (LocalDevice[i].RWCache != NULL)                {                    /* Clear the R/W Cache */                    stavfs_TermRWCache (LocalDevice + i);                }                LocalDevice[i].HALData = NULL;                /* Check if this leaves this HAL unused */                for (j = 0; (j < TABLE_LEN (LocalDevice)) && (LocalDevice[j].HALData != ThisHal); j++)                {                    /* All done in the FOR */                }                if (j == TABLE_LEN (LocalDevice))                {                    /* The HAL is not being used */                    /* Close down the HAL Layer */                    if (ST_NO_ERROR != stavfs_HalTerm (ThisHal))                    {                        STTBX_Print (("Failed to close HAL device\n"));                        Error = STAVFS_ERROR_UNWRITABLE_DISK;                    }                }            }            /* Release the driver */            semaphore_signal(&(LocalDevice[i].DeviceLock));        }    }    /* Release the lock */    semaphore_signal (&(GlobalDeviceLock));    return (Error);}/******************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -