📄 sma_fat16.c
字号:
/***********************************************************************
* $Workfile: SMA_fat16.c $
* $Revision: 1.1 $
* $Author: WellsK $
* $Date: Sep 22 2002 12:50:20 $
*
* Project: FAT16 driver
*
* Description:
* See the fat16.h header file for a description of this package.
*
* Revision History:
* $Log: //smaicnt2/pvcs/VM/CHIPS/archives/SOC/Source/File Systems/FAT/SMA_fat16.c-arc $
*
* Rev 1.1 Sep 22 2002 12:50:20 WellsK
* Made non-active partitions usable.
* Masked for ATTB_ARCHIVE bit in usable files instead of
* using direct define.
*
* Rev 1.0 Aug 27 2002 08:43:34 WellsK
* Initial revision.
*
*
* SHARP MICROELECTRONICS OF THE AMERICAS MAKES NO REPRESENTATION
* OR WARRANTIES WITH RESPECT TO THE PERFORMANCE OF THIS SOFTWARE,
* AND SPECIFICALLY DISCLAIMS ANY RESPONSIBILITY FOR ANY DAMAGES,
* SPECIAL OR CONSEQUENTIAL, CONNECTED WITH THE USE OF THIS SOFTWARE.
*
* SHARP MICROELECTRONICS OF THE AMERICAS PROVIDES THIS SOFTWARE SOLELY
* FOR THE PURPOSE OF SOFTWARE DEVELOPMENT INCORPORATING THE USE OF A
* SHARP MICROCONTROLLER OR SYSTEM-ON-CHIP PRODUCT. USE OF THIS SOURCE
* FILE IMPLIES ACCEPTANCE OF THESE CONDITIONS.
*
* COPYRIGHT (C) 2002 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
* CAMAS, WA
**********************************************************************/
#include "SMA_types.h"
#include "SMA_fat16.h"
#include "SMA_fat16_private.h"
#include <stdlib.h>
//**********************************************************************
// Local defines
//**********************************************************************
// Computed offsets from the unaligned partition header
#define JUMP_OFS 0
#define JUMP_SZ 3
#define OEMID_OFS (JUMP_OFS + JUMP_SZ)
#define OEMID_SZ 8
#define BYTES_SEC_OFS (OEMID_OFS + OEMID_SZ)
#define BYTES_SEC_SZ 2
#define SECS_CLUS_OFS (BYTES_SEC_OFS + BYTES_SEC_SZ)
#define SECS_CLUS_SZ 1
#define RES_SECT_OFS (SECS_CLUS_OFS + SECS_CLUS_SZ)
#define RES_SECT_SZ 2
#define FAT_COPY_OFS (RES_SECT_OFS + RES_SECT_SZ)
#define FAT_COPY_SZ 1
#define ROOT_ENT_OFS (FAT_COPY_OFS + FAT_COPY_SZ)
#define ROOT_ENT_SZ 2
#define SMALL_SEC_OFS (ROOT_ENT_OFS + ROOT_ENT_SZ)
#define SMALL_SEC_SZ 2
#define MEDIA_DES_OFS (SMALL_SEC_OFS + SMALL_SEC_SZ)
#define MEDIA_DES_SZ 1
#define SECS_FAT_OFS (MEDIA_DES_OFS + MEDIA_DES_SZ)
#define SECS_FAT_SZ 2
#define SECS_TK_OFS (SECS_FAT_OFS + SECS_FAT_SZ)
#define SECS_TK_SZ 2
#define NUM_HDS_OFS (SECS_TK_OFS + SECS_TK_SZ)
#define NUM_HDS_SZ 2
#define HDN_SECS_OFS (NUM_HDS_OFS + NUM_HDS_SZ)
#define HDN_SECS_SZ 4
#define LG_SECS_OFS (HDN_SECS_OFS + HDN_SECS_SZ)
#define LG_SECS_SZ 4
#define DV_NUM_OFS (LG_SECS_OFS + LG_SECS_SZ)
#define DV_NUM_SZ 1
#define RSV_OFS (DV_NUM_OFS + DV_NUM_SZ)
#define RSV_SZ 1
#define BT_SIG_OFS (RSV_OFS + RSV_SZ)
#define BT_SIG_SZ 1
#define SERNUM_OFS (BT_SIG_OFS + BT_SIG_SZ)
#define SERNUM_SZ 4
#define LABEL_OFS (SERNUM_OFS + SERNUM_SZ)
#define LABEL_SZ 11
#define FSNAME_OFS (LABEL_OFS + LABEL_SZ)
#define FSNAME_SZ 8
//**********************************************************************
// Public functions
//**********************************************************************
//**********************************************************************
// Initialization functions
//**********************************************************************
/***********************************************************************
*
* Function: fat16_init_device
*
* Purpose:
* Initializes the FAT16 interface for the selected device.
*
* Processing:
* Copy the device name and function pointers into the FAT device
* structure. Clear the commit flag to indicate the FAT cluster table
* does not need to be written back to the device. Call the device
* initialization function. If the device was initialized, read the
* MBR into the FAT device structure.
*
* Parameters:
* device : Device name
* init_func : Pointer to initialization function
* shutdown_func : Pointer to shutdown function
* insert_ck_func : Pointer to insertion check function
* ready_ck_func : Pointer to ready check function
* busy_ck_func : Pointer to bust check function
* set_sector_func : Pointer to sector set function
* start_read_func : Pointer to read start function
* start_write_func : Pointer to write start function
* read_func : Pointer to read buffer function
* write_func : Pointer to write buffer function
*
* Outputs:
* Data in fat_data will be updated.
*
* Returns:
* The pointer to a binded device structure, or NULL if the device
* was not detected.
*
* Notes:
* The calling function should check to make sure that NULL was not
* returned. If NULL was returned, the device does not exist or
* memory could not be allocated.
*
**********************************************************************/
fat_device_type * fat16_init_device (
CHAR *device, // Name of device
ivfunc init_func, // Pointer to device init function
vvfunc shutdown_func, // Pointer to device shutdown function
ivfunc insert_ck_func, // Pointer to check for insert func
ivfunc ready_ck_func, // Pointer for ready? check
ivfunc busy_ck_func, // Pointer for busy? check
void (*set_sector_func) (UNS_32), // sector setting
vvfunc start_read_func, // Pointer for read start
vvfunc start_write_func, // Pointer for write start
ivifunc read_func, // Pointer for read of data
ivifunc write_func) // Pointer for write of data
{
fat_device_type *fat_data = (fat_device_type *) NULL;
// Try to initialize the device
if (init_func () == 1)
{
// Device initiailized, allocate the device data structure
fat_data = malloc (sizeof (fat_device_type));
if (fat_data != NULL)
{
// Copy device name into device name in structure
fat16_moveto (device, fat_data->device, (DSIZE - 1));
fat_data->device [DSIZE - 1] = '\0';
// Save function pointers
fat_data->func.init_func = init_func;
fat_data->func.shutdown_func = shutdown_func;
fat_data->func.insert_ck_func = insert_ck_func;
fat_data->func.ready_ck_func = ready_ck_func;
fat_data->func.busy_ck_func = busy_ck_func;
fat_data->func.set_sector_func = set_sector_func;
fat_data->func.start_read_func = start_read_func;
fat_data->func.start_write_func = start_write_func;
fat_data->func.read_func = read_func;
fat_data->func.write_func = write_func;
// Set active partition to (-1), disable commit
fat_data->fat_commit = 0;
// Read MBR and populate MBR structure
fat16_read_mbr (fat_data);
}
}
return fat_data;
}
/***********************************************************************
*
* Function: fat16_shutdown
*
* Purpose:
* Shutdown the FAT16 interface for the selected device.
*
* Processing:
* If the commit flag is set, write the cached FAT cluster table back
* to the device. Free the allocated memory for the cluster table and
* device structure.
*
* Parameters:
* fat_data : Pointer to a FAT data structure
*
* Outputs:
* None
*
* Returns:
* Nothing
*
* Notes:
* None
*
**********************************************************************/
void fat16_shutdown (fat_device_type *fat_data)
{
// If the commit flag in the FAT device structure is set, then a
// write operation occurred to the device and the cached FAT cluster
// table needs to be written back to the device before shutdown
if (fat_data->fat_commit != 0)
{
// Write FAT back to the device - although only FAT1 is used,
// this routine will write all FAT copies back to the device
// so they stay consistent in other machines
fat16_write_sectors (fat_data, fat_data->clusters,
fat_data->cfat.first_fat1_sector,
fat_data->cfat.fat_sectors);
// Does more than 1 FAT need to be written?
if (fat_data->pat_hdr.fat_copies > 1)
{
fat16_write_sectors (fat_data, fat_data->clusters,
fat_data->cfat.first_fat2_sector,
fat_data->cfat.fat_sectors);
}
}
// Destroy cached cluster allocation
free (fat_data->clusters);
// Destroy the FAT device structure
free (fat_data);
}
/***********************************************************************
*
* Function: fat16_get_status
*
* Purpose:
* Get the status of the partition from the MBR.
*
* Processing:
* Return the status and partition type values from the partition
* table in the FAT device structure.
*
* Parameters:
* fat_data : Pointer to a FAT data structure
* status : Pointer to status flag to populate
* ptype : Pointer to partition type flag to populate
* pnum : Partition number to return status on (1 - 4)
*
* Outputs:
* The partition type and the status will be updated in memory
* pointed to by status and ptype. The only valid ptype and status
* values are (FAT16_LT32M, FAT16_EXDOS, FAT16_GT32M).
*
* Returns:
* Nothing
*
* Notes:
* Only partition numbers 1 through 4 are valid.
*
**********************************************************************/
void fat16_get_status (fat_device_type *fat_data, UNS_8 *status,
UNS_8 *ptype, INT_32 pnum)
{
if ((pnum >= 1) && (pnum <= 4))
{
// Only return status for valid partition numbers
*status = fat_data->part [pnum - 1].state;
*ptype = fat_data->part [pnum - 1].partype;
}
else
{
// Invalid partition, return bad status
*status = 0x0;
*ptype = 0;
}
}
/***********************************************************************
*
* Function: fat16_set_partition
*
* Purpose:
* Set the active partition.
*
* Processing:
* If the partition is a valid type (FAT16), the starting sector value
* for the partition will be determined and the appropriate sector
* containing the boot record will be read from the device. Once the
* boot record has been read in, the partition dimensions are
* computed. Appropriate space for the FAT cluster table is allocated
* and the cluster table is cached in memory.
*
* Parameters:
* partnum : Partition number of set (1 - 4) on this device
* fat_data : Pointer to a FAT data structure
*
* Outputs:
* Data in fat_data will be updated.
*
* Returns:
* '1' if the partition was set, '0' otherwise.
*
* Notes:
* Only partition numbers 1 through 4 are valid.
*
**********************************************************************/
INT_32 fat16_set_partition (INT_32 partnum, fat_device_type *fat_data)
{
UNS_32 table_size;
UNS_8 data [PTAB_SIZE];
fatgeom_type *fg;
INT_32 valid = 0;
// Reset partnum to work with indices
partnum--;
// Is partition of correct type?
if (((partnum >= 0) && (partnum <= 3)) &&
((fat_data->part [partnum].partype == FAT16_LT32M) ||
(fat_data->part [partnum].partype == FAT16_EXDOS) ||
(fat_data->part [partnum].partype == FAT16_GT32M)))
{
// Set the sector to the start of the partition
fat_data->func.set_sector_func (
fat_data->part [partnum].mbr_sec_offset);
// Issue read command
fat_data->func.start_read_func ();
// Wait for the operation to complete
fat16_wait_busy (fat_data);
// Read the MBR data from the device (PTAB_SIZE bytes)
fat_data->func.read_func (data, PTAB_SIZE);
// Reformat the unaligned structure into the aligned
// fatgeom_type structure
fg = &fat_data->pat_hdr;
fat16_moveto (&data [JUMP_OFS], &fg->jump, JUMP_SZ);
fat16_moveto (&data [OEMID_OFS], &fg->oem_id, OEMID_SZ);
fat16_moveto (&data [BYTES_SEC_OFS], &fg->bytes_sector,
BYTES_SEC_SZ);
fat16_moveto (&data [SECS_CLUS_OFS], &fg->sectors_cluster,
SECS_CLUS_SZ);
fat16_moveto (&data [RES_SECT_OFS], &fg->res_sectors,
RES_SECT_SZ);
fat16_moveto (&data [FAT_COPY_OFS], &fg->fat_copies,
FAT_COPY_SZ);
fat16_moveto (&data [ROOT_ENT_OFS], &fg->root_entries,
ROOT_ENT_SZ);
fat16_moveto (&data [SMALL_SEC_OFS], &fg->small_sectors,
SMALL_SEC_SZ);
fat16_moveto (&data [MEDIA_DES_OFS], &fg->media_desc,
MEDIA_DES_SZ);
fat16_moveto (&data [SECS_FAT_OFS], &fg->sectors_fat,
SECS_FAT_SZ);
fat16_moveto (&data [SECS_TK_OFS], &fg->sectors_track,
SECS_TK_SZ);
fat16_moveto (&data [NUM_HDS_OFS], &fg->number_heads,
NUM_HDS_SZ);
fat16_moveto (&data [HDN_SECS_OFS], &fg->hidden_sectors,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -