| /* |
| * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License |
| * as published by the Free Software Foundation; either version 2 |
| * of the License, or (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, see <http://www.gnu.org/licenses/>. |
| */ |
| |
| #ifndef _SDFAT_FS_H |
| #define _SDFAT_FS_H |
| |
| #include <linux/types.h> |
| #include <linux/magic.h> |
| #include <asm/byteorder.h> |
| |
| /*----------------------------------------------------------------------*/ |
| /* Constant & Macro Definitions */ |
| /*----------------------------------------------------------------------*/ |
| #ifndef MSDOS_SUPER_MAGIC |
| #define MSDOS_SUPER_MAGIC 0x4d44 /* MD */ |
| #endif |
| |
| #ifndef EXFAT_SUPER_MAGIC |
| #define EXFAT_SUPER_MAGIC (0x2011BAB0UL) |
| #endif /* EXFAT_SUPER_MAGIC */ |
| |
| #ifndef SDFAT_SUPER_MAGIC |
| #define SDFAT_SUPER_MAGIC (0x5EC5DFA4UL) |
| #endif /* SDFAT_SUPER_MAGIC */ |
| |
| #define SDFAT_ROOT_INO 1 |
| |
| /* FAT types */ |
| #define FAT12 0x01 // FAT12 |
| #define FAT16 0x0E // Win95 FAT16 (LBA) |
| #define FAT32 0x0C // Win95 FAT32 (LBA) |
| #define EXFAT 0x07 // exFAT |
| |
| /* directory file name */ |
| #define DOS_CUR_DIR_NAME ". " |
| #define DOS_PAR_DIR_NAME ".. " |
| |
| #ifdef __LITTLE_ENDIAN |
| #define UNI_CUR_DIR_NAME ".\0" |
| #define UNI_PAR_DIR_NAME ".\0.\0" |
| #else |
| #define UNI_CUR_DIR_NAME "\0." |
| #define UNI_PAR_DIR_NAME "\0.\0." |
| #endif |
| |
| /* file name lengths */ |
| /* NOTE : |
| * The maximum length of input or output is limited to 256 including NULL, |
| * But we allocate 4 extra bytes for utf8 translation reside in last position, |
| * because utf8 can uses memory upto 6 bytes per one character. |
| * Therefore, MAX_CHARSET_SIZE supports upto 6 bytes for utf8 |
| */ |
| #define MAX_UNINAME_BUF_SIZE (((MAX_NAME_LENGTH+1)*2)+4) |
| #define MAX_DOSNAME_BUF_SIZE ((DOS_NAME_LENGTH+2)+6) |
| #define MAX_VFSNAME_BUF_SIZE ((MAX_NAME_LENGTH+1)*MAX_CHARSET_SIZE) |
| #define MAX_CHARSET_SIZE 6 // max size of multi-byte character |
| #define MAX_NAME_LENGTH 255 // max len of file name excluding NULL |
| #define DOS_NAME_LENGTH 11 // DOS file name length excluding NULL |
| |
| #define SECTOR_SIZE_BITS 9 /* VFS sector size is 512 bytes */ |
| |
| #define DENTRY_SIZE 32 /* directory entry size */ |
| #define DENTRY_SIZE_BITS 5 |
| |
| #define MAX_FAT_DENTRIES 65536 /* FAT allows 65536 directory entries */ |
| #define MAX_EXFAT_DENTRIES 8388608 /* exFAT allows 8388608(256MB) directory entries */ |
| |
| /* PBR entries */ |
| #define PBR_SIGNATURE 0xAA55 |
| #define EXT_SIGNATURE 0xAA550000 |
| #define VOL_LABEL "NO NAME " /* size should be 11 */ |
| #define OEM_NAME "MSWIN4.1" /* size should be 8 */ |
| #define STR_FAT12 "FAT12 " /* size should be 8 */ |
| #define STR_FAT16 "FAT16 " /* size should be 8 */ |
| #define STR_FAT32 "FAT32 " /* size should be 8 */ |
| #define STR_EXFAT "EXFAT " /* size should be 8 */ |
| |
| #define VOL_CLEAN 0x0000 |
| #define VOL_DIRTY 0x0002 |
| |
| #define FAT_VOL_DIRTY 0x01 |
| |
| /* max number of clusters */ |
| #define FAT12_THRESHOLD 4087 // 2^12 - 1 + 2 (clu 0 & 1) |
| #define FAT16_THRESHOLD 65527 // 2^16 - 1 + 2 |
| #define FAT32_THRESHOLD 268435457 // 2^28 - 1 + 2 |
| #define EXFAT_THRESHOLD 268435457 // 2^28 - 1 + 2 |
| |
| /* dentry types */ |
| #define MSDOS_DELETED 0xE5 /* deleted mark */ |
| #define MSDOS_UNUSED 0x00 /* end of directory */ |
| |
| #define EXFAT_UNUSED 0x00 /* end of directory */ |
| #define IS_EXFAT_DELETED(x) ((x) < 0x80) /* deleted file (0x01~0x7F) */ |
| #define EXFAT_INVAL 0x80 /* invalid value */ |
| #define EXFAT_BITMAP 0x81 /* allocation bitmap */ |
| #define EXFAT_UPCASE 0x82 /* upcase table */ |
| #define EXFAT_VOLUME 0x83 /* volume label */ |
| #define EXFAT_FILE 0x85 /* file or dir */ |
| #define EXFAT_STREAM 0xC0 /* stream entry */ |
| #define EXFAT_NAME 0xC1 /* file name entry */ |
| #define EXFAT_ACL 0xC2 /* stream entry */ |
| |
| /* specific flag */ |
| #define MSDOS_LAST_LFN 0x40 |
| |
| /* file attributes */ |
| #define ATTR_NORMAL 0x0000 |
| #define ATTR_READONLY 0x0001 |
| #define ATTR_HIDDEN 0x0002 |
| #define ATTR_SYSTEM 0x0004 |
| #define ATTR_VOLUME 0x0008 |
| #define ATTR_SUBDIR 0x0010 |
| #define ATTR_ARCHIVE 0x0020 |
| #define ATTR_SYMLINK 0x0040 |
| #define ATTR_EXTEND (ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | \ |
| ATTR_VOLUME) /* 0x000F */ |
| |
| #define ATTR_EXTEND_MASK (ATTR_EXTEND | ATTR_SUBDIR | ATTR_ARCHIVE) |
| #define ATTR_RWMASK (ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME | \ |
| ATTR_SUBDIR | ATTR_ARCHIVE | ATTR_SYMLINK)/* 0x007E */ |
| |
| /* file creation modes */ |
| #define FM_REGULAR 0x00 |
| #define FM_SYMLINK 0x40 |
| |
| /* time modes */ |
| #define TM_CREATE 0 |
| #define TM_MODIFY 1 |
| #define TM_ACCESS 2 |
| |
| /* checksum types */ |
| #define CS_DIR_ENTRY 0 |
| #define CS_PBR_SECTOR 1 |
| #define CS_DEFAULT 2 |
| |
| /* time min/max */ |
| /* Jan 1 GMT 00:00:00 1980 */ |
| #define SDFAT_MIN_TIMESTAMP_SECS 315532800LL |
| /* Dec 31 GMT 23:59:59 2107 */ |
| #define SDFAT_MAX_TIMESTAMP_SECS 4354819199LL |
| |
| |
| /* |
| * ioctl command |
| */ |
| #define SDFAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x12, __u32) |
| #define SDFAT_IOCTL_DFR_INFO _IOC(_IOC_NONE, 'E', 0x13, sizeof(u32)) |
| #define SDFAT_IOCTL_DFR_TRAV _IOC(_IOC_NONE, 'E', 0x14, sizeof(u32)) |
| #define SDFAT_IOCTL_DFR_REQ _IOC(_IOC_NONE, 'E', 0x15, sizeof(u32)) |
| #define SDFAT_IOCTL_DFR_SPO_FLAG _IOC(_IOC_NONE, 'E', 0x16, sizeof(u32)) |
| #define SDFAT_IOCTL_PANIC _IOC(_IOC_NONE, 'E', 0x17, sizeof(u32)) |
| |
| /* |
| * ioctl command for debugging |
| */ |
| |
| /* |
| * IOCTL code 'f' used by |
| * - file systems typically #0~0x1F |
| * - embedded terminal devices #128~ |
| * - exts for debugging purpose #99 |
| * number 100 and 101 is available now but has possible conflicts |
| * |
| * NOTE : This is available only If CONFIG_SDFAT_DVBG_IOCTL is enabled. |
| * |
| */ |
| #define SDFAT_IOC_GET_DEBUGFLAGS _IOR('f', 100, long) |
| #define SDFAT_IOC_SET_DEBUGFLAGS _IOW('f', 101, long) |
| |
| #define SDFAT_DEBUGFLAGS_INVALID_UMOUNT 0x01 |
| #define SDFAT_DEBUGFLAGS_ERROR_RW 0x02 |
| |
| /*----------------------------------------------------------------------*/ |
| /* On-Disk Type Definitions */ |
| /*----------------------------------------------------------------------*/ |
| |
| /* FAT12/16/32 BIOS parameter block (64 bytes) */ |
| typedef struct { |
| __u8 jmp_boot[3]; |
| __u8 oem_name[8]; |
| |
| __u8 sect_size[2]; /* unaligned */ |
| __u8 sect_per_clus; |
| __le16 num_reserved; /* . */ |
| __u8 num_fats; |
| __u8 num_root_entries[2]; /* unaligned */ |
| __u8 num_sectors[2]; /* unaligned */ |
| __u8 media_type; |
| __le16 num_fat_sectors; |
| __le16 sectors_in_track; |
| __le16 num_heads; |
| __le32 num_hid_sectors; /* . */ |
| __le32 num_huge_sectors; |
| |
| union { |
| struct { |
| __u8 phy_drv_no; |
| __u8 state; /* used by WinNT for mount state */ |
| __u8 ext_signature; |
| __u8 vol_serial[4]; |
| __u8 vol_label[11]; |
| __u8 vol_type[8]; |
| __le16 nouse; |
| } f16; |
| |
| struct { |
| __le32 num_fat32_sectors; |
| __le16 ext_flags; |
| __u8 fs_version[2]; |
| __le32 root_cluster; /* . */ |
| __le16 fsinfo_sector; |
| __le16 backup_sector; |
| __le16 reserved[6]; /* . */ |
| } f32; |
| }; |
| } bpb_t; |
| |
| /* FAT32 EXTEND BIOS parameter block (32 bytes) */ |
| typedef struct { |
| __u8 phy_drv_no; |
| __u8 state; /* used by WindowsNT for mount state */ |
| __u8 ext_signature; |
| __u8 vol_serial[4]; |
| __u8 vol_label[11]; |
| __u8 vol_type[8]; |
| __le16 dummy[3]; |
| } bsx32_t; |
| |
| /* EXFAT BIOS parameter block (64 bytes) */ |
| typedef struct { |
| __u8 jmp_boot[3]; |
| __u8 oem_name[8]; |
| __u8 res_zero[53]; |
| } bpb64_t; |
| |
| /* EXFAT EXTEND BIOS parameter block (56 bytes) */ |
| typedef struct { |
| __le64 vol_offset; |
| __le64 vol_length; |
| __le32 fat_offset; |
| __le32 fat_length; |
| __le32 clu_offset; |
| __le32 clu_count; |
| __le32 root_cluster; |
| __le32 vol_serial; |
| __u8 fs_version[2]; |
| __le16 vol_flags; |
| __u8 sect_size_bits; |
| __u8 sect_per_clus_bits; |
| __u8 num_fats; |
| __u8 phy_drv_no; |
| __u8 perc_in_use; |
| __u8 reserved2[7]; |
| } bsx64_t; |
| |
| /* FAT32 PBR (64 bytes) */ |
| typedef struct { |
| bpb_t bpb; |
| } pbr16_t; |
| |
| /* FAT32 PBR[BPB+BSX] (96 bytes) */ |
| typedef struct { |
| bpb_t bpb; |
| bsx32_t bsx; |
| } pbr32_t; |
| |
| /* EXFAT PBR[BPB+BSX] (120 bytes) */ |
| typedef struct { |
| bpb64_t bpb; |
| bsx64_t bsx; |
| } pbr64_t; |
| |
| /* Common PBR[Partition Boot Record] (512 bytes) */ |
| typedef struct { |
| union { |
| __u8 raw[64]; |
| bpb_t fat; |
| bpb64_t f64; |
| } bpb; |
| union { |
| __u8 raw[56]; |
| bsx32_t f32; |
| bsx64_t f64; |
| } bsx; |
| __u8 boot_code[390]; |
| __le16 signature; |
| } pbr_t; |
| |
| /* FAT32 filesystem information sector (512 bytes) */ |
| typedef struct { |
| __le32 signature1; // aligned |
| __u8 reserved1[480]; |
| __le32 signature2; // aligned |
| __le32 free_cluster; // aligned |
| __le32 next_cluster; // aligned |
| __u8 reserved2[14]; |
| __le16 signature3[2]; |
| } fat32_fsi_t; |
| |
| /* FAT directory entry (32 bytes) */ |
| typedef struct { |
| __u8 dummy[32]; |
| } DENTRY_T; |
| |
| typedef struct { |
| __u8 name[DOS_NAME_LENGTH]; /* 11 chars */ |
| __u8 attr; |
| __u8 lcase; |
| __u8 create_time_ms; |
| __le16 create_time; // aligned |
| __le16 create_date; // aligned |
| __le16 access_date; // aligned |
| __le16 start_clu_hi; // aligned |
| __le16 modify_time; // aligned |
| __le16 modify_date; // aligned |
| __le16 start_clu_lo; // aligned |
| __le32 size; // aligned |
| } DOS_DENTRY_T; |
| |
| /* FAT extended directory entry (32 bytes) */ |
| typedef struct { |
| __u8 order; |
| __u8 unicode_0_4[10]; |
| __u8 attr; |
| __u8 sysid; |
| __u8 checksum; |
| __le16 unicode_5_10[6]; // aligned |
| __le16 start_clu; // aligned |
| __le16 unicode_11_12[2]; // aligned |
| } EXT_DENTRY_T; |
| |
| /* EXFAT file directory entry (32 bytes) */ |
| typedef struct { |
| __u8 type; |
| __u8 num_ext; |
| __le16 checksum; // aligned |
| __le16 attr; // aligned |
| __le16 reserved1; |
| __le16 create_time; // aligned |
| __le16 create_date; // aligned |
| __le16 modify_time; // aligned |
| __le16 modify_date; // aligned |
| __le16 access_time; // aligned |
| __le16 access_date; // aligned |
| __u8 create_time_ms; |
| __u8 modify_time_ms; |
| __u8 create_tz; |
| __u8 modify_tz; |
| __u8 access_tz; |
| __u8 reserved2[7]; |
| } FILE_DENTRY_T; |
| |
| /* EXFAT stream extension directory entry (32 bytes) */ |
| typedef struct { |
| __u8 type; |
| __u8 flags; |
| __u8 reserved1; |
| __u8 name_len; |
| __le16 name_hash; // aligned |
| __le16 reserved2; |
| __le64 valid_size; // aligned |
| __le32 reserved3; // aligned |
| __le32 start_clu; // aligned |
| __le64 size; // aligned |
| } STRM_DENTRY_T; |
| |
| /* EXFAT file name directory entry (32 bytes) */ |
| typedef struct { |
| __u8 type; |
| __u8 flags; |
| __le16 unicode_0_14[15]; // aligned |
| } NAME_DENTRY_T; |
| |
| /* EXFAT allocation bitmap directory entry (32 bytes) */ |
| typedef struct { |
| __u8 type; |
| __u8 flags; |
| __u8 reserved[18]; |
| __le32 start_clu; // aligned |
| __le64 size; // aligned |
| } BMAP_DENTRY_T; |
| |
| /* EXFAT up-case table directory entry (32 bytes) */ |
| typedef struct { |
| __u8 type; |
| __u8 reserved1[3]; |
| __le32 checksum; // aligned |
| __u8 reserved2[12]; |
| __le32 start_clu; // aligned |
| __le64 size; // aligned |
| } CASE_DENTRY_T; |
| |
| /* EXFAT volume label directory entry (32 bytes) */ |
| typedef struct { |
| __u8 type; |
| __u8 label_len; |
| __le16 unicode_0_10[11]; // aligned |
| __u8 reserved[8]; |
| } VOLM_DENTRY_T; |
| |
| #endif /* _SDFAT_FS_H */ |