Files
BPI-M2C/source_sync_rls_25c/source/bsp/u-boot22/include/exfat.h
T
2026-09-22 09:38:26 +08:00

288 lines
8.9 KiB
C

/* SPDX-License-Identifier: GPL-2.0+ */
#ifndef _EXFAT_H_
#define _EXFAT_H_
#include <asm/byteorder.h>
#include <blk.h>
#include <asm/cache.h>
#define _uswap_64(x, sfx) \
((((x) & 0xff00000000000000##sfx) >> 56) | \
(((x) & 0x00ff000000000000##sfx) >> 40) | \
(((x) & 0x0000ff0000000000##sfx) >> 24) | \
(((x) & 0x000000ff00000000##sfx) >> 8) | \
(((x) & 0x00000000ff000000##sfx) << 8) | \
(((x) & 0x0000000000ff0000##sfx) << 24) | \
(((x) & 0x000000000000ff00##sfx) << 40) | \
(((x) & 0x00000000000000ff##sfx) << 56))
#define uswap_64(x) _uswap_64(x, ull)
#if defined(__linux__) && defined(__KERNEL__)
#define EXFAT2CPU16 le16_to_cpu
#define EXFAT2CPU32 le32_to_cpu
#define EXFAT2CPU64 le64_to_cpu
#else
#if __LITTLE_ENDIAN
#define EXFAT2CPU16(x) (x)
#define EXFAT2CPU32(x) (x)
#define EXFAT2CPU64(x) (x)
#else
#define EXFAT2CPU16(x) ((((x) & 0x00ff) << 8) | (((x) & 0xff00) >> 8))
#define EXFAT2CPU32(x) ((((x) & 0x000000ff) << 24) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x00ff0000) >> 8) | \
(((x) & 0xff000000) >> 24))
#define EXFAT2CPU64(x) uswap_64(x)
#endif
#endif
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define ROUND_UP(x, d) (DIV_ROUND_UP(x, d) * (d))
#define FNAME_MAXLEN_BYTES 256 /* Maximum LFN buffer in bytes */
#define MAX_RD_BLK_SIZE 65536
#define EXFAT_FAT_ENTRY_SIZE 4
#define EXFAT_ATTR_RDONLY 0x01
#define EXFAT_ATTR_HIDDEN 0x02
#define EXFAT_ATTR_SYSTEM 0x04
#define EXFAT_ATTR_DIR 0x10
#define EXFAT_ATTR_FILE 0x20
#define EXFAT_ENAME_MAX 15
#define EXFAT_FIRST_DATA_CLUSTER 2
#define EXFAT_LAST_DATA_CLUSTER 0xfffffff6
#define EXFAT_CLUSTER_FREE 0 /* free cluster */
#define EXFAT_CLUSTER_BAD 0xfffffff7 /* cluster contains bad sector */
#define EXFAT_CLUSTER_END 0xffffffff /* final cluster of file or directory */
#define CHAR_BIT 8 /* number of bits in a char */
#define FSOK 0 /* Check was OK */
#define FSBOOTMOD 1 /* Boot block was modified */
#define FSDIRMOD 2 /* Some directory was modified */
#define FSFATMOD 4 /* The FAT was modified */
#define FSERROR 8 /* Some unrecovered error remains */
#define FSFATAL 16 /* Some unrecoverable error occurred */
#define FSDIRTY 32 /* File system is dirty */
#define FSFIXFAT 64 /* Fix file system FAT */
#define FSNOSPACE 128 /* SD have no space for sysdump */
#define FSSMSIZE 256 /* SD card volume size is smaller than sysdump size */
enum {
EXFAT_DTYPE_BM = 0x01, // bitmap entry
EXFAT_DTYPE_UC = 0x02, // up-case table entry
EXFAT_DTYPE_LABLE = 0x03, // label
EXFAT_DTYPE_FILE = 0x05, // regular file or directory
EXFAT_DTYPE_STREXT = 0x40, // stream extension entry
EXFAT_DTYPE_FNEXT = 0x41, // file name extension entry
EXFAT_DTYPE_MASK = 0x7f, // entry type mask
EXFAT_DTYPE_USED = 0x80, // flag bit of whether entry is in used or not
};
struct exfat_super_block {
__u8 jump[3]; /* 0x00 jmp and nop instructions */
__u8 oem_name[8]; /* 0x03 "EXFAT " */
__u8 __unused1[53]; /* 0x0B always 0 */
__u64 sector_start; /* 0x40 partition first sector */
__u64 sector_count; /* 0x48 partition sectors count */
__u32 fat_sector_start; /* 0x50 FAT first sector */
__u32 fat_sector_count; /* 0x54 FAT sectors count */
__u32 cluster_sector_start; /* 0x58 first cluster sector */
__u32 cluster_count; /* 0x5C total clusters count */
__u32 rootdir_cluster; /* 0x60 first cluster of the root dir */
__u32 volume_serial; /* 0x64 volume serial number */
struct /* 0x68 FS version */
{
__u8 minor;
__u8 major;
}
version;
__u16 volume_state; /* 0x6A volume state flags */
__u8 sector_bits; /* 0x6C sector size as (1 << n) */
__u8 spc_bits; /* 0x6D sectors per cluster as (1 << n) */
__u8 fat_count; /* 0x6E always 1 */
__u8 drive_no; /* 0x6F always 0x80 */
__u8 allocated_percent; /* 0x70 percentage of allocated space */
__u8 __unused2[397]; /* 0x71 always 0 */
__u16 boot_signature; /* the value of 0xAA55 */
};
struct exfat_boot_sector {
__u8 ignored[3]; /* Bootstrap code */
char fs_name[8]; /* Name of fs, should be "EXFAT " */
__u8 zero_bytes[53]; /* Must be zero bytes */
__u64 part_off; /* Partition offset (in sector) */
__u64 vol_len; /* Volume length (in sector) */
__u32 fat_off; /* FATs start sector */
__u32 fat_len; /* FATs length */
__u32 cluster_heap_off; /* Cluster heap */
__u32 cluster_cnt; /* Cluster count */
__u32 root_cluster; /* first cluster of root dir */
__u32 vol_serial;
__u16 fs_version;
__u16 vol_flags;
__u8 sector_size_bits;
__u8 sectors_per_clu_bits;
__u8 num_fats;
__u8 phy_drv_no;
__u8 perc_in_use;
__u8 reserved[7];
__u8 boot_code[390];
__u8 boot_signature[2];
};
struct timestamp {
__u16 sec;
__u16 min;
__u16 hour;
__u16 day;
__u16 mon;
__u16 year;
};
/*
* Private filesystem parameters
*
* Note: exFAT buffer has to be 32 bit aligned
* (see exFAT accesses)
*/
struct exfsdata {
__u8 *fatbuf; /* Current FAT buffer */
__u8 *bitmap; /* Current bitmap buffer */
__u8 *bitmap_fatbuf; /* FAT buffer for bitmap file */
__u16 *uptab_buf; /* upcase-table buffer */
__u32 fat_num;
__u32 fatlength; /* Length of FAT in sectors */
__u32 bitmaplen; /* Length of bitmap in bytes */
__u32 cluster_cnt; /* Total cluster count */
__u32 fat_sect; /* Starting sector of the FAT */
__u32 bitmap_sect; /* Starting sector of the FAT */
__u32 bitmap_fatbuf_size; /* size in sector of FAT buffer for bitmap file */
__u32 cur_bitmap_cluster; /* current read in bitmap file cluster */
__u32 rootdir_sect; /* Start sector of root directory */
__u16 sect_size; /* Size of sectors in bytes */
__u16 clust_size; /* Size of clusters in sectors */
__u32 rd_sectors; /* read sectors once */
__u32 fatbuf_idx; /* got fat table buffer index */
__u32 bitmap_idx; /* got bitmap buffer index */
__u32 avail_clusters; /* free clusters can be used */
__s32 data_begin; /* The sector of the first cluster, can be negative */
};
struct exfat_entry_label { /* volume label */
__u8 entry_type; /* EXFAT_ENTRY_LABEL */
__u8 length; /* number of characters */
__u16 name[EXFAT_ENAME_MAX]; /* in UTF-16LE */
};
struct exfat_bitmap_entry {
__u8 entry_type; /*entry type */
__u8 bitmap_flags;
__u8 reserved[18];
__u32 start_clu;
__u64 data_len;
};
struct exfat_entry_upcase { /* upper case translation table */
__u8 entry_type; /* EXFAT_ENTRY_UPCASE */
__u8 __unknown1[3];
__u32 checksum;
__u8 __unknown2[12];
__u32 start_cluster;
__u64 size; /* in bytes */
};
struct exfat_strext_entry {
__u8 entry_type;
__u8 secondary_flags;
__u8 reserved0;
__u8 name_len;
__u16 name_hash;
__u8 reserved1[2];
__u64 val_data_len;
__u8 reserved2[4];
__u32 first_cluster;
__u64 data_len;
};
struct exfat_file_entry {
__u8 entry_type;
__u8 secondary_cnt;
__u16 checksum;
__u16 attr;
__u8 reserved0[2];
__u32 creat_time;
__u32 mod_time;
__u32 access_time;
__u8 creat_ms_inc;
__u8 mod_ms_inc;
__u8 creat_utc_off;
__u8 mod_utc_off;
struct exfat_strext_entry *str_dent;
};
struct exfat_fnext_entry {
__u8 entry_type;
__u8 secondary_flags;
__u16 uniname[15];
};
struct exfat_dentry {
__u8 entry_type;
__u8 secondary_flags;
__u8 bytes[30];
};
struct exfat_buf_info {
__u8 *pbuf;
__u32 cluster;
__u32 start_sec;
__u32 sectors;
};
struct exfat_whole_dentry {
struct exfat_buf_info bf0;
struct exfat_buf_info bf1;
struct exfat_file_entry *empty;
struct exfat_file_entry *prim;
struct exfat_strext_entry *strext;
struct exfat_fnext_entry *fname_dent[17];
void *parent;
};
struct exfat_buf_array {
struct exfat_buf_info bf0;
struct exfat_buf_info bf1;
};
extern __u8 bitmap_mask[9];
extern __u8 bitmap_clr_mask[8];
extern __u8 bits_num_table[256];
extern __u8 bitmap_avail[256];
extern __u8 upcase_table[5836];
int exfat_disk_read(__u32 block, __u32 nr_blocks, void *buf);
int exfat_disk_write(__u32 block, __u32 nr_blocks, void *buf);
int read_exfat_bootsec(struct exfat_boot_sector *bs);
void *exfat_malloc_aligned(size_t align, size_t bytes);
int exfat_mfree(void *ptr);
void downcase(char *str);
int exfat_register_device(struct blk_desc *dev_desc, int part_no);
int file_exfat_detectfs(void);
int get_exfat_blocks(struct exfsdata *mydata, __u32 start_sec, __u8 *buffer, __u32 rd_sec);
int check_bitmap_fatbuf(struct exfsdata *mydata);
int check_available_size(struct exfsdata *mydata, __u64 size);
int file_exfat_write(const char *filename, void *buffer, unsigned long maxsize);
int dir_exfat_create(const char *dirname);
int dir_exfat_rename(const char *scr, const char *dest);
int dir_exfat_remove(const char *dirname);
int dir_exfat_check(const char *dirname);
int exfat_checksys(size_t ram_size);
int exfat_format(void);
#endif /* _EXFAT_H_ */