Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | /* SPDX-License-Identifier: GPL-2.0+ */ /* * R/O (V)FAT 12/16/32 filesystem implementation by Marcus Sundberg * * 2002-07-28 - rjones@nexus-tech.net - ported to ppcboot v1.1.6 * 2003-03-10 - kharris@nexus-tech.net - ported to u-boot */ #ifndef _FAT_H_ #define _FAT_H_ #include <fs_legacy.h> #include <asm/byteorder.h> #include <asm/cache.h> struct disk_partition; /* Maximum Long File Name length supported here is 128 UTF-16 code units */ #define VFAT_MAXLEN_BYTES 256 /* Maximum LFN buffer in bytes */ #define VFAT_MAXSEQ 9 /* Up to 9 of 13 2-byte UTF-16 entries */ #define PREFETCH_BLOCKS 2 #define MAX_CLUSTSIZE CONFIG_FS_FAT_MAX_CLUSTSIZE #define DIRENTSPERCLUST ((mydata->clust_size * mydata->sect_size) / \ sizeof(dir_entry)) #define FATBUFBLOCKS 6 #define FATBUFSIZE (mydata->sect_size * FATBUFBLOCKS) #define FAT12BUFSIZE ((FATBUFSIZE*2)/3) #define FAT16BUFSIZE (FATBUFSIZE/2) #define FAT32BUFSIZE (FATBUFSIZE/4) /* Maximum number of entry for long file name according to spec */ #define MAX_LFN_SLOT 20 /* 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_VFAT (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME) #define DELETED_FLAG ((char)0xe5) /* Marks deleted files when in name[0] */ #define aRING 0x05 /* Used as special character in name[0] */ /* * Indicates that the entry is the last long entry in a set of long * dir entries */ #define LAST_LONG_ENTRY_MASK 0x40 #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 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)) /** * struct boot_sector - FAT boot sector structure * @ignored: bootstrap code (first 3 bytes) * @system_id: name of filesystem (8 bytes) * @sector_size: bytes per sector * @cluster_size: sectors per cluster * @reserved: number of reserved sectors * @fats: number of FAT copies * @dir_entries: number of root directory entries * @sectors: number of sectors (for small disks) * @media: media descriptor code * @fat_length: sectors per FAT (for FAT12/16) * @secs_track: sectors per track * @heads: number of heads * @hidden: number of hidden sectors * @total_sect: total number of sectors (for larger disks) * @fat32_length: sectors per FAT (FAT32 only) * @flags: flags (bit 8: fat mirroring, low 4: active fat) * @version: filesystem version (FAT32 only) * @root_cluster: first cluster of root directory (FAT32 only) * @info_sector: filesystem info sector (FAT32 only) * @backup_boot: backup boot sector location (FAT32 only) * @reserved2: unused (FAT32 only) */ struct boot_sector { u8 ignored[3]; char system_id[8]; u8 sector_size[2]; u8 cluster_size; u16 reserved; u8 fats; u8 dir_entries[2]; u8 sectors[2]; u8 media; u16 fat_length; u16 secs_track; u16 heads; u32 hidden; u32 total_sect; /* FAT32 only */ u32 fat32_length; u16 flags; u8 version[2]; u32 root_cluster; u16 info_sector; u16 backup_boot; u16 reserved2[6]; }; /** * struct volume_info - FAT volume information structure * @drive_number: BIOS drive number * @reserved: unused field * @ext_boot_sign: extended boot signature (0x29 if fields below exist) * @volume_id: volume serial number (4 bytes) * @volume_label: volume label (11 bytes, padded with spaces) * @fs_type: filesystem type string (typically "FAT12", "FAT16", or "FAT32") * * This structure is part of the boot sector, located after the common fields. * Boot code follows this structure, with boot signature at the end of sector. */ struct volume_info { u8 drive_number; u8 reserved; u8 ext_boot_sign; u8 volume_id[4]; char volume_label[11]; char fs_type[8]; }; /* see dir_entry::lcase: */ #define CASE_LOWER_BASE 8 /* base (name) is lower case */ #define CASE_LOWER_EXT 16 /* extension is lower case */ /** * struct nameext - 8.3 filename components * @name: filename (8 bytes) * @ext: extension (3 bytes) */ struct nameext { char name[8]; char ext[3]; }; /** * struct dir_entry - FAT directory entry * @nameext: filename and extension (8.3 format) * @attr: file attributes (ATTR_* flags) * @lcase: case flags for name and extension (CASE_LOWER_* flags) * @ctime_ms: creation time (milliseconds) * @ctime: creation time (hours, minutes, seconds) * @cdate: creation date * @adate: last access date * @starthi: high 16 bits of cluster number (FAT32 only) * @time: modification time * @date: modification date * @start: low 16 bits of cluster number * @size: file size in bytes */ struct dir_entry { struct nameext nameext; u8 attr; u8 lcase; u8 ctime_ms; u16 ctime; u16 cdate; u16 adate; u16 starthi; u16 time; u16 date; u16 start; u32 size; }; /** * struct dir_slot - VFAT long filename entry * @id: sequence number (bit 6 = last entry, bits 0-4 = sequence) * @name0_4: characters 0-4 of long filename (UTF-16LE) * @attr: must be ATTR_VFAT (0x0F) * @reserved: unused field * @alias_checksum: checksum of 8.3 alias for this long name * @name5_10: characters 5-10 of long filename (UTF-16LE) * @start: unused (always 0) * @name11_12: characters 11-12 of long filename (UTF-16LE) * * Long filename entries precede the corresponding short entry in directory. * Multiple entries may be used to store names longer than 13 characters. */ struct dir_slot { u8 id; u8 name0_4[10]; u8 attr; u8 reserved; u8 alias_checksum; u8 name5_10[12]; u16 start; u8 name11_12[4]; }; /** * struct fsdata - FAT filesystem instance data * @fatbuf: buffer for reading/writing FAT (must be 32-bit aligned for FAT32) * @fatsize: size of FAT in bits (12, 16, or 32) * @fatlength: length of FAT in sectors * @fat_sect: starting sector of the FAT * @fat_dirty: flag indicating if fatbuf has been modified * @rootdir_sect: starting sector of root directory * @sect_size: size of sectors in bytes * @clust_size: size of clusters in sectors * @data_begin: sector offset of first data cluster (can be negative) * @fatbufnum: currently buffered FAT sector number (init to -1) * @rootdir_size: size of root directory in entries (for non-FAT32) * @root_cluster: first cluster of root directory (FAT32 only) * @total_sect: total number of sectors * @fats: number of FAT copies * * This structure holds the runtime state of a mounted FAT filesystem. * The fatbuf must be 32-bit aligned due to FAT32 sector access requirements. */ struct fsdata { u8 *fatbuf; int fatsize; u32 fatlength; u16 fat_sect; u8 fat_dirty; u32 rootdir_sect; u16 sect_size; u16 clust_size; int data_begin; int fatbufnum; int rootdir_size; u32 root_cluster; u32 total_sect; int fats; }; struct fat_itr; /** * clust_to_sect() - convert cluster number to sector number * @fsdata: filesystem instance data * @clust: cluster number * * Return: sector number corresponding to the given cluster */ static inline u32 clust_to_sect(struct fsdata *fsdata, u32 clust) { return fsdata->data_begin + clust * fsdata->clust_size; } /** * sect_to_clust() - convert sector number to cluster number * @fsdata: filesystem instance data * @sect: sector number * * Return: cluster number corresponding to the given sector */ static inline u32 sect_to_clust(struct fsdata *fsdata, int sect) { return (sect - fsdata->data_begin) / fsdata->clust_size; } /** * file_fat_detectfs() - detect and initialize the FAT filesystem * * Return: 0 on success, -1 on error */ int file_fat_detectfs(void); /** * fat_exists() - check if a file exists * @filename: full path to file * * Return: 0 if file exists, -1 if not found or error */ int fat_exists(const char *filename); /** * fat_size() - get the size of a file * @filename: full path to file * @size: pointer to store file size * * Return: 0 on success, -1 on error */ int fat_size(const char *filename, loff_t *size); /** * file_fat_read() - read a file from FAT filesystem * @filename: full path to file * @buffer: buffer to read data into * @maxsize: maximum number of bytes to read * * Return: number of bytes read, -1 on error */ int file_fat_read(const char *filename, void *buffer, int maxsize); /** * fat_set_blk_dev() - set the block device and partition for FAT operations * @rbdd: block device descriptor * @info: partition information * * Return: 0 on success, -1 on error */ int fat_set_blk_dev(struct blk_desc *rbdd, struct disk_partition *info); /** * fat_register_device() - register a FAT filesystem on a block device * @dev_desc: block device descriptor * @part_no: partition number (0 = whole device) * * Return: 0 on success, -1 on error */ int fat_register_device(struct blk_desc *dev_desc, int part_no); /** * file_fat_write() - write to a file on FAT filesystem * @filename: full path to file * @buf: buffer containing data to write * @offset: offset in file to start writing * @len: number of bytes to write * @actwrite: pointer to store actual number of bytes written * * Return: 0 on success, -1 on error */ int file_fat_write(const char *filename, void *buf, loff_t offset, loff_t len, loff_t *actwrite); /** * fat_read_file() - read from a file on FAT filesystem * @filename: full path to file * @buf: buffer to read data into * @offset: offset in file to start reading * @len: number of bytes to read * @actread: pointer to store actual number of bytes read * * Return: 0 on success, -1 on error */ int fat_read_file(const char *filename, void *buf, loff_t offset, loff_t len, loff_t *actread); /** * fat_opendir() - open a directory for reading * @filename: full path to directory * @dirsp: pointer to store directory stream handle * * Return: 0 on success, -1 on error */ int fat_opendir(const char *filename, struct fs_dir_stream **dirsp); /** * fat_readdir() - read next entry from directory * @dirs: directory stream handle * @dentp: pointer to store directory entry * * Return: 0 on success, -1 on error or end of directory */ int fat_readdir(struct fs_dir_stream *dirs, struct fs_dirent **dentp); /** * fat_closedir() - close a directory stream * @dirs: directory stream handle */ void fat_closedir(struct fs_dir_stream *dirs); /** * fat_unlink() - delete a file or empty directory * @filename: full path to file or directory * * Return: 0 on success, -1 on error */ int fat_unlink(const char *filename); /** * fat_rename() - rename a file or directory * @old_path: current full path * @new_path: new full path * * Return: 0 on success, -1 on error */ int fat_rename(const char *old_path, const char *new_path); /** * fat_mkdir() - create a directory * @dirname: full path to new directory * * Return: 0 on success, -1 on error */ int fat_mkdir(const char *dirname); /** * fat_close() - close FAT filesystem and release resources */ void fat_close(void); /** * fat_next_cluster() - get the next cluster in a chain * @itr: directory iterator * @nbytes: pointer to store number of bytes in cluster * * Return: pointer to cluster data buffer */ void *fat_next_cluster(struct fat_itr *itr, unsigned int *nbytes); /** * fat_uuid() - get FAT volume ID * * The FAT volume ID returned in @uuid_str as hexadecimal number in XXXX-XXXX * format. * * @uuid_str: caller allocated buffer of at least 10 bytes for the volume ID * Return: 0 on success */ int fat_uuid(char *uuid_str); #endif /* _FAT_H_ */ |