nt9856x/BSP/u-boot/include/exfat.h
2023-03-28 15:07:53 +08:00

252 lines
7.7 KiB
C
Executable File

/* SPDX-License-Identifier: GPL-2.0+ */
/*
* R/O exFAT filesystem implementation
*
*/
#ifndef _EXFAT_H_
#define _EXFAT_H_
#include <asm/byteorder.h>
#include <fs.h>
/* Maximum Long File Name length supported here is 128 UTF-16 code units */
#define EXFAT_MAXLEN_BYTES 256 /* Maximum LFN buffer in bytes */
#define EXFAT_MAXSEQ 9 /* Up to 9 of 13 2-byte UTF-16 entries */
#define EXFAT_PREFETCH_BLOCKS 2
#ifndef CONFIG_FS_EXFAT_MAX_CLUSTSIZE
#define CONFIG_FS_EXFAT_MAX_CLUSTSIZE (256*1024)
#endif
#define EXFAT_MAX_CLUSTSIZE CONFIG_FS_EXFAT_MAX_CLUSTSIZE
#define EXFAT_DIRENTSPERBLOCK (mydata->sect_size / EXFAT_SIZE_PER_ENTRY)
#define EXFAT_DIRENTSPERCLUST ((mydata->clust_size * mydata->sect_size) / \
EXFAT_SIZE_PER_ENTRY)
#define FATBUFBLOCKS 6
#define FATBUFSIZE (mydata->sect_size * FATBUFBLOCKS)
#define EXFATBUFSIZE (FATBUFSIZE/4)
/* Maximum number of entry for long file name according to spec */
#define MAX_LFN_SLOT 20
/* Filesystem identifiers */
#define EXFAT_SIGN "EXFAT "
#define EXFAT_SIGNLEN 8
/* File attributes */
#define ATTR_RO 1
#define ATTR_HIDDEN 2
#define ATTR_SYS 4
#define ATTR_VOLUME 8
#define ATTR_DIR 16
#define ATTR_ARCH 32
#define ATTR_EXFAT (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
/*
* Indicates that the entry is the last long entry in a set of long
* dir entries
*/
#define LAST_LONG_ENTRY_MASK 0x40
/* Flags telling whether we should read a file or list a directory */
#define LS_NO 0
#define LS_YES 1
#define LS_DIR 1
#define LS_ROOT 2
#define ISDIRDELIM(c) ((c) == '/' || (c) == '\\')
//#define FSTYPE_NONE (-1)
#if defined(__linux__) && defined(__KERNEL__)
#define FAT2CPU16 le16_to_cpu
#define FAT2CPU32 le32_to_cpu
#else
#if __LITTLE_ENDIAN
#define FAT2CPU16(x) (x)
#define FAT2CPU32(x) (x)
#else
#define FAT2CPU16(x) ((((x) & 0x00ff) << 8) | (((x) & 0xff00) >> 8))
#define FAT2CPU32(x) ((((x) & 0x000000ff) << 24) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x00ff0000) >> 8) | \
(((x) & 0xff000000) >> 24))
#endif
#endif
#define EXFAT_START(strmptr) (FAT2CPU32((strmptr)->first_clus))
#define EXFAT_SIZE(strmptr) ((unsigned long long)FAT2CPU32((strmptr)->valid_data_len[0]) \
+ FAT2CPU32((unsigned long long)(strmptr)->valid_data_len[1] << 32))
#define EXFAT_IS_CONTIGUOUS(strmptr) ((strmptr)->flags & EXFAT_ENTRY_CONTIGUOUS ? 1 : 0)
#define EXFAT_CHECK_CLUST(x, fatsize) ((x) <= 1 || (x) >= (0xffffff0))
#define START(dent) (FAT2CPU16((dent)->start) \
+ (mydata->fatsize != 32 ? 0 : \
(FAT2CPU16((dent)->starthi) << 16)))
#define IS_LAST_CLUST(x, fatsize) ((x) >= ((fatsize) != 32 ? \
((fatsize) != 16 ? 0xff8 : 0xfff8) : \
0xffffff8))
#define CHECK_CLUST(x, fatsize) ((x) <= 1 || \
(x) >= ((fatsize) != 32 ? \
((fatsize) != 16 ? 0xff0 : 0xfff0) : \
0xffffff0))
typedef struct exfat_boot_sector {
__u8 ignored[3]; /* Bootstrap code */
char file_system_name[8]; /* Name of fs */
__u8 must_be_zero[53]; /* All 00h */
__u32 partition_offset[2];
__u32 volume_length[2]; /* Number of sectors (if sectors == 0) */
__u32 fat_offset;
__u32 fat_length; /* Sectors/FAT */
__u32 cluster_heap_offset;
__u32 cluster_count;
__u32 first_clus_of_root_dir;
__u32 volume_serial_number;
__u16 file_system_revision;
__u16 volume_flags;
__u8 byte_per_sector_shift;
__u8 sector_per_clus_shift;
__u8 number_of_fats;
} exfat_boot_sector;
typedef struct exfat_volume_info
{
__u8 drive_number; /* BIOS drive number */
__u8 reserved; /* Unused */
__u8 ext_boot_sign; /* 0x29 if fields below exist (DOS 3.3+) */
__u8 volume_id[4]; /* Volume ID number */
char volume_label[11]; /* Volume label */
char fs_type[8]; /* Typically FAT12, FAT16, FAT32 or EXFAT */
/* Boot code comes next, all but 2 bytes to fill up sector */
/* Boot sign comes last, 2 bytes */
} exfat_volume_info;
#define EXFAT_SIZE_PER_ENTRY 32
#define EXFAT_NAME_ENTRY_MAXCHAR 15 //max characters of each name entry (15)
#define EXFAT_NAME_ENTRY_MAXNUM 17 //the max number of name entries (17)
#define EXFAT_FILENAME_MAXLEN EXFAT_NAME_ENTRY_MAXCHAR*EXFAT_NAME_ENTRY_MAXNUM //255
#define EXFAT_ENTRYTYPE_INUSE 0x80
#define EXFAT_ENTRY_CONTIGUOUS 0x2
#define EXFAT_ENTRY_TYPE_FILE 0x85
#define EXFAT_ENTRY_TYPE_STREAM 0xC0
#define EXFAT_ENTRY_TYPE_NAME 0xC1
#define EXFAT_ENTRY_TYPE_EMPTY 0x00
#define EXFAT_DELETED_FLAG_FILE 0x05 /* Marks deleted files */
#define EXFAT_DELETED_FLAG_STREAM 0x40 /* Marks deleted files */
#define EXFAT_DELETED_FLAG_NAME 0x41 /* Marks deleted files */
/* MS-DOS EXFAT bitmap directory entry (32 bytes) */
typedef struct {
__u8 entry_type;
__u8 flags;
__u16 reserved[9];
__u32 first_clus;
__u32 data_len[2];
} exfat_bitmap_dentry;
/* MS-DOS EXFAT file directory entry (32 bytes) */
typedef struct {
__u8 entry_type;
__u8 second_count;
__u16 check_sum;
__u16 attrib;
__u16 reserved1;
__u16 create_time;
__u16 create_date;
__u16 modify_time;
__u16 modify_date;
__u16 access_time;
__u16 access_date;
__u8 create_time_10ms;
__u8 modify_time_10ms;
__u8 create_utc_offset;
__u8 modify_utc_offset;
__u8 access_utc_offset;
__u8 reserved2[7];
} exfat_file_dentry;
/* MS-DOS EXFAT stream extension directory entry (32 bytes) */
typedef struct {
__u8 entry_type;
__u8 flags;
__u8 reserved1;
__u8 name_len;
__u16 name_hash;
__u16 reserved2;
__u32 valid_data_len[2];
__u32 reserved3;
__u32 first_clus;
__u32 data_len[2];
} exfat_stream_dentry;
/* MS-DOS EXFAT file name directory entry (32 bytes) */
typedef struct {
__u8 entry_type;
__u8 flags;
__u16 name[EXFAT_NAME_ENTRY_MAXCHAR];
} exfat_name_dentry;
typedef struct {
exfat_file_dentry file_dentry ;
exfat_stream_dentry stream_dentry ;
exfat_name_dentry name_dentry[EXFAT_NAME_ENTRY_MAXNUM];//although this is an array, but the valid number should be calculate from Stream_Entry
} exfat_entry_set;
/*
* Private filesystem parameters
*
* Note: FAT buffer has to be 32 bit aligned
* (see FAT32 accesses)
*/
typedef struct {
__u8 *fatbuf; /* Current FAT buffer */
int fatsize; /* Size of FAT in bits */
__u32 fatlength; /* Length of FAT in sectors */
__u16 fat_sect; /* Starting sector of the FAT */
__u8 fat_dirty; /* Set if fatbuf has been modified */
__u32 rootdir_sect; /* Start sector of root directory */
__u16 sect_size; /* Size of sectors in bytes */
__u16 clust_size; /* Size of clusters in sectors */
int data_begin; /* The sector of the first cluster, can be negative */
int fatbufnum; /* Used by get_fatent, init to -1 */
int rootdir_size; /* Size of root dir for non-FAT32 */
__u32 root_cluster; /* First cluster of root dir for FAT32 */
u32 total_sect; /* Number of sectors */
int fats; /* Number of FATs */
} exfat_fsdata;
static inline u32 exfat_clust_to_sect(exfat_fsdata *fsdata, u32 clust)
{
return fsdata->data_begin + clust * fsdata->clust_size;
}
int file_exfat_detectfs(void);
int exfat_ls(const char *dir);
int exfat_exists(const char *filename);
int exfat_size(const char *filename, loff_t *size);
int file_exfat_read_at(const char *filename, loff_t pos, void *buffer,
loff_t maxsize, loff_t *actread);
int file_exfat_read(const char *filename, void *buffer, int maxsize);
int exfat_set_blk_dev(struct blk_desc *rbdd, disk_partition_t *info);
int exfat_register_device(struct blk_desc *dev_desc, int part_no);
int file_exfat_write(const char *filename, void *buf, loff_t offset, loff_t len,
loff_t *actwrite);
int exfat_read_file(const char *filename, void *buf, loff_t offset, loff_t len,
loff_t *actread);
int exfat_opendir(const char *filename, struct fs_dir_stream **dirsp);
int exfat_readdir(struct fs_dir_stream *dirs, struct fs_dirent **dentp);
void exfat_closedir(struct fs_dir_stream *dirs);
int exfat_unlink(const char *filename);
int exfat_mkdir(const char *dirname);
void exfat_close(void);
#endif /* _EXFAT_H_ */