1a7ce5b29Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 2a7ce5b29Sopenharmony_ci/* 3a7ce5b29Sopenharmony_ci * Copyright (C) 2019 Namjae Jeon <linkinjeon@kernel.org> 4a7ce5b29Sopenharmony_ci */ 5a7ce5b29Sopenharmony_ci 6a7ce5b29Sopenharmony_ci#ifndef _EXFAT_H 7a7ce5b29Sopenharmony_ci#define _EXFAT_H 8a7ce5b29Sopenharmony_ci 9a7ce5b29Sopenharmony_ci#include <stdint.h> 10a7ce5b29Sopenharmony_ci#include <linux/fs.h> 11a7ce5b29Sopenharmony_ci 12a7ce5b29Sopenharmony_ci#ifdef HAVE_CONFIG_H 13a7ce5b29Sopenharmony_ci#include <config.h> 14a7ce5b29Sopenharmony_ci#endif 15a7ce5b29Sopenharmony_ci 16a7ce5b29Sopenharmony_ci#ifdef WORDS_BIGENDIAN 17a7ce5b29Sopenharmony_ci#define cpu_to_le16(x) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8)) 18a7ce5b29Sopenharmony_ci#define cpu_to_le32(x) \ 19a7ce5b29Sopenharmony_ci ((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8) | \ 20a7ce5b29Sopenharmony_ci (((x) & 0x0000ff00u) << 8) | (((x) & 0x000000ffu) << 24)) 21a7ce5b29Sopenharmony_ci#define cpu_to_le64(x) (cpu_to_le32((uint64_t)(x)) << 32 | \ 22a7ce5b29Sopenharmony_ci cpu_to_le32((uint64_t)(x) >> 32)) 23a7ce5b29Sopenharmony_ci#else 24a7ce5b29Sopenharmony_ci#define cpu_to_le16(x) (x) 25a7ce5b29Sopenharmony_ci#define cpu_to_le32(x) (x) 26a7ce5b29Sopenharmony_ci#define cpu_to_le64(x) (x) 27a7ce5b29Sopenharmony_ci#endif 28a7ce5b29Sopenharmony_ci 29a7ce5b29Sopenharmony_ci#define le64_to_cpu(x) ((uint64_t)cpu_to_le64(x)) 30a7ce5b29Sopenharmony_ci#define le32_to_cpu(x) ((uint32_t)cpu_to_le32(x)) 31a7ce5b29Sopenharmony_ci#define le16_to_cpu(x) ((uint16_t)cpu_to_le16(x)) 32a7ce5b29Sopenharmony_ci 33a7ce5b29Sopenharmony_ci#define PBR_SIGNATURE 0xAA55 34a7ce5b29Sopenharmony_ci 35a7ce5b29Sopenharmony_ci#define VOL_CLEAN 0x0000 36a7ce5b29Sopenharmony_ci#define VOL_DIRTY 0x0002 37a7ce5b29Sopenharmony_ci 38a7ce5b29Sopenharmony_ci#define DENTRY_SIZE 32 /* directory entry size */ 39a7ce5b29Sopenharmony_ci#define DENTRY_SIZE_BITS 5 40a7ce5b29Sopenharmony_ci/* exFAT allows 8388608(256MB) directory entries */ 41a7ce5b29Sopenharmony_ci#define MAX_EXFAT_DENTRIES 8388608 42a7ce5b29Sopenharmony_ci#define MIN_FILE_DENTRIES 3 43a7ce5b29Sopenharmony_ci#define MAX_NAME_DENTRIES 17 44a7ce5b29Sopenharmony_ci 45a7ce5b29Sopenharmony_ci/* dentry types */ 46a7ce5b29Sopenharmony_ci#define MSDOS_DELETED 0xE5 /* deleted mark */ 47a7ce5b29Sopenharmony_ci#define MSDOS_UNUSED 0x00 /* end of directory */ 48a7ce5b29Sopenharmony_ci 49a7ce5b29Sopenharmony_ci#define EXFAT_LAST 0x00 /* end of directory */ 50a7ce5b29Sopenharmony_ci#define EXFAT_DELETE ~(0x80) 51a7ce5b29Sopenharmony_ci#define IS_EXFAT_DELETED(x) ((x) < 0x80) /* deleted file (0x01~0x7F) */ 52a7ce5b29Sopenharmony_ci#define EXFAT_INVAL 0x80 /* invalid value */ 53a7ce5b29Sopenharmony_ci#define EXFAT_BITMAP 0x81 /* allocation bitmap */ 54a7ce5b29Sopenharmony_ci#define EXFAT_UPCASE 0x82 /* upcase table */ 55a7ce5b29Sopenharmony_ci#define EXFAT_VOLUME 0x83 /* volume label */ 56a7ce5b29Sopenharmony_ci#define EXFAT_FILE 0x85 /* file or dir */ 57a7ce5b29Sopenharmony_ci#define EXFAT_GUID 0xA0 58a7ce5b29Sopenharmony_ci#define EXFAT_PADDING 0xA1 59a7ce5b29Sopenharmony_ci#define EXFAT_ACLTAB 0xA2 60a7ce5b29Sopenharmony_ci#define EXFAT_STREAM 0xC0 /* stream entry */ 61a7ce5b29Sopenharmony_ci#define EXFAT_NAME 0xC1 /* file name entry */ 62a7ce5b29Sopenharmony_ci#define EXFAT_ACL 0xC2 /* stream entry */ 63a7ce5b29Sopenharmony_ci 64a7ce5b29Sopenharmony_ci/* checksum types */ 65a7ce5b29Sopenharmony_ci#define CS_DIR_ENTRY 0 66a7ce5b29Sopenharmony_ci#define CS_PBR_SECTOR 1 67a7ce5b29Sopenharmony_ci#define CS_DEFAULT 2 68a7ce5b29Sopenharmony_ci 69a7ce5b29Sopenharmony_ci/* file attributes */ 70a7ce5b29Sopenharmony_ci#define ATTR_READONLY 0x0001 71a7ce5b29Sopenharmony_ci#define ATTR_HIDDEN 0x0002 72a7ce5b29Sopenharmony_ci#define ATTR_SYSTEM 0x0004 73a7ce5b29Sopenharmony_ci#define ATTR_VOLUME 0x0008 74a7ce5b29Sopenharmony_ci#define ATTR_SUBDIR 0x0010 75a7ce5b29Sopenharmony_ci#define ATTR_ARCHIVE 0x0020 76a7ce5b29Sopenharmony_ci#define ATTR_EXTEND (ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | \ 77a7ce5b29Sopenharmony_ci ATTR_VOLUME) /* 0x000F */ 78a7ce5b29Sopenharmony_ci 79a7ce5b29Sopenharmony_ci#define ATTR_EXTEND_MASK (ATTR_EXTEND | ATTR_SUBDIR | ATTR_ARCHIVE) 80a7ce5b29Sopenharmony_ci#define ATTR_RWMASK (ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME | \ 81a7ce5b29Sopenharmony_ci ATTR_SUBDIR | ATTR_ARCHIVE) 82a7ce5b29Sopenharmony_ci 83a7ce5b29Sopenharmony_ci#define ATTR_READONLY_LE cpu_to_le16(0x0001) 84a7ce5b29Sopenharmony_ci#define ATTR_HIDDEN_LE cpu_to_le16(0x0002) 85a7ce5b29Sopenharmony_ci#define ATTR_SYSTEM_LE cpu_to_le16(0x0004) 86a7ce5b29Sopenharmony_ci#define ATTR_VOLUME_LE cpu_to_le16(0x0008) 87a7ce5b29Sopenharmony_ci#define ATTR_SUBDIR_LE cpu_to_le16(0x0010) 88a7ce5b29Sopenharmony_ci#define ATTR_ARCHIVE_LE cpu_to_le16(0x0020) 89a7ce5b29Sopenharmony_ci 90a7ce5b29Sopenharmony_ci/* stream flags */ 91a7ce5b29Sopenharmony_ci#define EXFAT_SF_CONTIGUOUS 0x02 92a7ce5b29Sopenharmony_ci 93a7ce5b29Sopenharmony_ci#define CLUSTER_32(x) ((unsigned int)((x) & 0xFFFFFFFFU)) 94a7ce5b29Sopenharmony_ci#define EXFAT_EOF_CLUSTER CLUSTER_32(~0) 95a7ce5b29Sopenharmony_ci#define EXFAT_BAD_CLUSTER (0xFFFFFFF7U) 96a7ce5b29Sopenharmony_ci#define EXFAT_FREE_CLUSTER (0) 97a7ce5b29Sopenharmony_ci#define EXFAT_FIRST_CLUSTER (2) 98a7ce5b29Sopenharmony_ci#define EXFAT_RESERVED_CLUSTERS (2) 99a7ce5b29Sopenharmony_ci 100a7ce5b29Sopenharmony_ci 101a7ce5b29Sopenharmony_ci/* EXFAT BIOS parameter block (64 bytes) */ 102a7ce5b29Sopenharmony_cistruct bpb64 { 103a7ce5b29Sopenharmony_ci __u8 jmp_boot[3]; 104a7ce5b29Sopenharmony_ci __u8 oem_name[8]; 105a7ce5b29Sopenharmony_ci __u8 res_zero[53]; 106a7ce5b29Sopenharmony_ci}; 107a7ce5b29Sopenharmony_ci 108a7ce5b29Sopenharmony_ci/* EXFAT EXTEND BIOS parameter block (56 bytes) */ 109a7ce5b29Sopenharmony_cistruct bsx64 { 110a7ce5b29Sopenharmony_ci __le64 vol_offset; 111a7ce5b29Sopenharmony_ci __le64 vol_length; 112a7ce5b29Sopenharmony_ci __le32 fat_offset; 113a7ce5b29Sopenharmony_ci __le32 fat_length; 114a7ce5b29Sopenharmony_ci __le32 clu_offset; 115a7ce5b29Sopenharmony_ci __le32 clu_count; 116a7ce5b29Sopenharmony_ci __le32 root_cluster; 117a7ce5b29Sopenharmony_ci __le32 vol_serial; 118a7ce5b29Sopenharmony_ci __u8 fs_version[2]; 119a7ce5b29Sopenharmony_ci __le16 vol_flags; 120a7ce5b29Sopenharmony_ci __u8 sect_size_bits; 121a7ce5b29Sopenharmony_ci __u8 sect_per_clus_bits; 122a7ce5b29Sopenharmony_ci __u8 num_fats; 123a7ce5b29Sopenharmony_ci __u8 phy_drv_no; 124a7ce5b29Sopenharmony_ci __u8 perc_in_use; 125a7ce5b29Sopenharmony_ci __u8 reserved2[7]; 126a7ce5b29Sopenharmony_ci}; 127a7ce5b29Sopenharmony_ci 128a7ce5b29Sopenharmony_ci/* Common PBR[Partition Boot Record] (512 bytes) */ 129a7ce5b29Sopenharmony_cistruct pbr { 130a7ce5b29Sopenharmony_ci struct bpb64 bpb; 131a7ce5b29Sopenharmony_ci struct bsx64 bsx; 132a7ce5b29Sopenharmony_ci __u8 boot_code[390]; 133a7ce5b29Sopenharmony_ci __le16 signature; 134a7ce5b29Sopenharmony_ci}; 135a7ce5b29Sopenharmony_ci 136a7ce5b29Sopenharmony_ci#define VOLUME_LABEL_MAX_LEN 11 137a7ce5b29Sopenharmony_ci#define ENTRY_NAME_MAX 15 138a7ce5b29Sopenharmony_ci 139a7ce5b29Sopenharmony_cistruct exfat_dentry { 140a7ce5b29Sopenharmony_ci __u8 type; 141a7ce5b29Sopenharmony_ci union { 142a7ce5b29Sopenharmony_ci struct { 143a7ce5b29Sopenharmony_ci __u8 character_count; 144a7ce5b29Sopenharmony_ci __le16 volume_label[VOLUME_LABEL_MAX_LEN]; 145a7ce5b29Sopenharmony_ci __u8 reserved[8]; 146a7ce5b29Sopenharmony_ci } __attribute__((packed)) vol; /* file directory entry */ 147a7ce5b29Sopenharmony_ci 148a7ce5b29Sopenharmony_ci struct { 149a7ce5b29Sopenharmony_ci __u8 num_ext; 150a7ce5b29Sopenharmony_ci __le16 checksum; 151a7ce5b29Sopenharmony_ci __le16 attr; 152a7ce5b29Sopenharmony_ci __le16 reserved1; 153a7ce5b29Sopenharmony_ci __le16 create_time; 154a7ce5b29Sopenharmony_ci __le16 create_date; 155a7ce5b29Sopenharmony_ci __le16 modify_time; 156a7ce5b29Sopenharmony_ci __le16 modify_date; 157a7ce5b29Sopenharmony_ci __le16 access_time; 158a7ce5b29Sopenharmony_ci __le16 access_date; 159a7ce5b29Sopenharmony_ci __u8 create_time_ms; 160a7ce5b29Sopenharmony_ci __u8 modify_time_ms; 161a7ce5b29Sopenharmony_ci __u8 create_tz; 162a7ce5b29Sopenharmony_ci __u8 modify_tz; 163a7ce5b29Sopenharmony_ci __u8 access_tz; 164a7ce5b29Sopenharmony_ci __u8 reserved2[7]; 165a7ce5b29Sopenharmony_ci } __attribute__((packed)) file; /* file directory entry */ 166a7ce5b29Sopenharmony_ci struct { 167a7ce5b29Sopenharmony_ci __u8 flags; 168a7ce5b29Sopenharmony_ci __u8 reserved1; 169a7ce5b29Sopenharmony_ci __u8 name_len; 170a7ce5b29Sopenharmony_ci __le16 name_hash; 171a7ce5b29Sopenharmony_ci __le16 reserved2; 172a7ce5b29Sopenharmony_ci __le64 valid_size; 173a7ce5b29Sopenharmony_ci __le32 reserved3; 174a7ce5b29Sopenharmony_ci __le32 start_clu; 175a7ce5b29Sopenharmony_ci __le64 size; 176a7ce5b29Sopenharmony_ci } __attribute__((packed)) stream; /* stream extension directory entry */ 177a7ce5b29Sopenharmony_ci struct { 178a7ce5b29Sopenharmony_ci __u8 flags; 179a7ce5b29Sopenharmony_ci __le16 unicode_0_14[15]; 180a7ce5b29Sopenharmony_ci } __attribute__((packed)) name; /* file name directory entry */ 181a7ce5b29Sopenharmony_ci struct { 182a7ce5b29Sopenharmony_ci __u8 flags; 183a7ce5b29Sopenharmony_ci __u8 reserved[18]; 184a7ce5b29Sopenharmony_ci __le32 start_clu; 185a7ce5b29Sopenharmony_ci __le64 size; 186a7ce5b29Sopenharmony_ci } __attribute__((packed)) bitmap; /* allocation bitmap directory entry */ 187a7ce5b29Sopenharmony_ci struct { 188a7ce5b29Sopenharmony_ci __u8 reserved1[3]; 189a7ce5b29Sopenharmony_ci __le32 checksum; 190a7ce5b29Sopenharmony_ci __u8 reserved2[12]; 191a7ce5b29Sopenharmony_ci __le32 start_clu; 192a7ce5b29Sopenharmony_ci __le64 size; 193a7ce5b29Sopenharmony_ci } __attribute__((packed)) upcase; /* up-case table directory entry */ 194a7ce5b29Sopenharmony_ci } __attribute__((packed)) dentry; 195a7ce5b29Sopenharmony_ci} __attribute__((packed)); 196a7ce5b29Sopenharmony_ci 197a7ce5b29Sopenharmony_ci#define vol_char_cnt dentry.vol.character_count 198a7ce5b29Sopenharmony_ci#define vol_label dentry.vol.volume_label 199a7ce5b29Sopenharmony_ci#define file_num_ext dentry.file.num_ext 200a7ce5b29Sopenharmony_ci#define file_checksum dentry.file.checksum 201a7ce5b29Sopenharmony_ci#define file_attr dentry.file.attr 202a7ce5b29Sopenharmony_ci#define file_create_time dentry.file.create_time 203a7ce5b29Sopenharmony_ci#define file_create_date dentry.file.create_date 204a7ce5b29Sopenharmony_ci#define file_modify_time dentry.file.modify_time 205a7ce5b29Sopenharmony_ci#define file_modify_date dentry.file.modify_date 206a7ce5b29Sopenharmony_ci#define file_access_time dentry.file.access_time 207a7ce5b29Sopenharmony_ci#define file_access_date dentry.file.access_date 208a7ce5b29Sopenharmony_ci#define file_create_time_ms dentry.file.create_time_ms 209a7ce5b29Sopenharmony_ci#define file_modify_time_ms dentry.file.modify_time_ms 210a7ce5b29Sopenharmony_ci#define file_access_time_ms dentry.file.access_time_ms 211a7ce5b29Sopenharmony_ci#define stream_flags dentry.stream.flags 212a7ce5b29Sopenharmony_ci#define stream_name_len dentry.stream.name_len 213a7ce5b29Sopenharmony_ci#define stream_name_hash dentry.stream.name_hash 214a7ce5b29Sopenharmony_ci#define stream_start_clu dentry.stream.start_clu 215a7ce5b29Sopenharmony_ci#define stream_valid_size dentry.stream.valid_size 216a7ce5b29Sopenharmony_ci#define stream_size dentry.stream.size 217a7ce5b29Sopenharmony_ci#define name_flags dentry.name.flags 218a7ce5b29Sopenharmony_ci#define name_unicode dentry.name.unicode_0_14 219a7ce5b29Sopenharmony_ci#define bitmap_flags dentry.bitmap.flags 220a7ce5b29Sopenharmony_ci#define bitmap_start_clu dentry.bitmap.start_clu 221a7ce5b29Sopenharmony_ci#define bitmap_size dentry.bitmap.size 222a7ce5b29Sopenharmony_ci#define upcase_start_clu dentry.upcase.start_clu 223a7ce5b29Sopenharmony_ci#define upcase_size dentry.upcase.size 224a7ce5b29Sopenharmony_ci#define upcase_checksum dentry.upcase.checksum 225a7ce5b29Sopenharmony_ci 226a7ce5b29Sopenharmony_ci#endif /* !_EXFAT_H */ 227