42 return EFI_OUT_OF_RESOURCES;
48 Volume->Signature = FAT_VOLUME_SIGNATURE;
49 Volume->Handle = Handle;
50 Volume->DiskIo = DiskIo;
51 Volume->DiskIo2 = DiskIo2;
52 Volume->BlockIo = BlockIo;
53 Volume->MediaId = BlockIo->Media->MediaId;
54 Volume->ReadOnly = BlockIo->Media->ReadOnly;
55 Volume->VolumeInterface.
Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
62 Volume->RootDirEnt.FileString = Volume->RootFileString;
63 Volume->RootDirEnt.Entry.Attributes = FAT_ATTRIBUTE_DIRECTORY;
65 if ((BlockIo ==
NULL) || (BlockIo->Media ==
NULL)) {
66 DEBUG ((DEBUG_ERROR,
"%a BlockIo or BlockIo is NULL!\n", __func__));
67 Status = EFI_INVALID_PARAMETER;
74 if ((BlockIo->Media->BlockSize != 512) &&
75 (BlockIo->Media->BlockSize != SIZE_1KB) &&
76 (BlockIo->Media->BlockSize != SIZE_2KB) &&
77 (BlockIo->Media->BlockSize != SIZE_4KB))
79 Status = EFI_UNSUPPORTED;
82 "%a invalid BlockIo BlockSize %u for FAT filesystem on MediaId %u. Must be 512B, 1KB, 2KB, or 4KB\n",
84 BlockIo->Media->BlockSize,
85 BlockIo->Media->MediaId
94 if (EFI_ERROR (Status)) {
102 if (EFI_ERROR (Status)) {
109 Status =
gBS->InstallMultipleProtocolInterfaces (
111 &gEfiSimpleFileSystemProtocolGuid,
112 &Volume->VolumeInterface,
115 if (EFI_ERROR (Status)) {
122 DEBUG ((DEBUG_INIT,
"Installed Fat filesystem on %p\n", Handle));
123 Volume->Valid =
TRUE;
126 if (EFI_ERROR (Status)) {
154 if (Volume->Handle !=
NULL) {
155 Status =
gBS->UninstallMultipleProtocolInterfaces (
157 &gEfiSimpleFileSystemProtocolGuid,
158 &Volume->VolumeInterface,
161 if (EFI_ERROR (Status)) {
175 if (!EFI_ERROR (Status)) {
184 if (Volume->Root !=
NULL) {
187 Volume->BlockIo->Media->MediaPresent ? EFI_MEDIA_CHANGED : EFI_NO_MEDIA
191 Volume->Valid =
FALSE;
231 FAT_VOLUME_TYPE FatType;
232 UINTN RootDirSectors;
235 UINTN FirstClusterLba;
238 UINT8 SectorsPerClusterAlignment;
239 UINT8 BlockAlignment;
246 DiskIo = Volume->DiskIo;
247 Status = DiskIo->ReadDisk (DiskIo, Volume->MediaId, 0, sizeof (FatBs), &FatBs);
249 if (EFI_ERROR (Status)) {
250 DEBUG ((DEBUG_VERBOSE,
"%a: read of part_lba failed %r\n", __func__, Status));
254 FatType = FatUndefined;
259 Sectors = FatBs.FatBsb.Sectors;
261 Sectors = FatBs.FatBsb.LargeSectors;
264 SectorsPerFat = FatBs.FatBsb.SectorsPerFat;
265 if (SectorsPerFat == 0) {
266 SectorsPerFat = FatBs.FatBse.Fat32Bse.LargeSectorsPerFat;
276 if ((FatBs.FatBsb.ReservedSectors == 0) || (FatBs.FatBsb.NumFats == 0) || (Sectors == 0)) {
277 return EFI_UNSUPPORTED;
280 if ((FatBs.FatBsb.SectorSize & (FatBs.FatBsb.SectorSize - 1)) != 0) {
281 return EFI_UNSUPPORTED;
284 BlockAlignment = (UINT8)
HighBitSet32 (FatBs.FatBsb.SectorSize);
285 if ((BlockAlignment > MAX_BLOCK_ALIGNMENT) || (BlockAlignment < MIN_BLOCK_ALIGNMENT)) {
286 return EFI_UNSUPPORTED;
289 if ((FatBs.FatBsb.SectorsPerCluster & (FatBs.FatBsb.SectorsPerCluster - 1)) != 0) {
290 return EFI_UNSUPPORTED;
293 SectorsPerClusterAlignment = (UINT8)
HighBitSet32 (FatBs.FatBsb.SectorsPerCluster);
294 if (SectorsPerClusterAlignment > MAX_SECTORS_PER_CLUSTER_ALIGNMENT) {
295 return EFI_UNSUPPORTED;
298 if ((FatBs.FatBsb.Media <= 0xf7) &&
299 (FatBs.FatBsb.Media != 0xf0) &&
300 (FatBs.FatBsb.Media != 0x00) &&
301 (FatBs.FatBsb.Media != 0x01)
304 return EFI_UNSUPPORTED;
310 if (FatType != Fat32) {
311 if (FatBs.FatBsb.RootEntries == 0) {
312 return EFI_UNSUPPORTED;
318 Volume->RootEntries = FatBs.FatBsb.RootEntries;
323 if (((SectorsPerFat == 0) || (FatBs.FatBse.Fat32Bse.FsVersion != 0)) || (FatBs.FatBse.Fat32Bse.ExtendedFlags & 0x80)) {
324 return EFI_UNSUPPORTED;
330 Volume->RootCluster = FatBs.FatBse.Fat32Bse.RootDirFirstCluster;
333 Volume->NumFats = FatBs.FatBsb.NumFats;
337 BlockSize = FatBs.FatBsb.SectorSize;
338 RootDirSectors = ((Volume->RootEntries *
sizeof (
FAT_DIRECTORY_ENTRY)) + (BlockSize - 1)) / BlockSize;
340 FatLba = FatBs.FatBsb.ReservedSectors;
341 RootLba = FatBs.FatBsb.NumFats * SectorsPerFat + FatLba;
342 FirstClusterLba = RootLba + RootDirSectors;
344 Volume->FatPos = FatLba * BlockSize;
345 Volume->FatSize = SectorsPerFat * BlockSize;
347 Volume->VolumeSize =
LShiftU64 (Sectors, BlockAlignment);
348 Volume->RootPos =
LShiftU64 (RootLba, BlockAlignment);
349 Volume->FirstClusterPos =
LShiftU64 (FirstClusterLba, BlockAlignment);
350 Volume->MaxCluster = (Sectors - FirstClusterLba) >> SectorsPerClusterAlignment;
351 Volume->ClusterAlignment = (UINT8)(BlockAlignment + SectorsPerClusterAlignment);
352 Volume->ClusterSize = (
UINTN)1 << (Volume->ClusterAlignment);
357 if (FatType != Fat32) {
358 if (Volume->MaxCluster >= FAT_MAX_FAT16_CLUSTER) {
359 return EFI_VOLUME_CORRUPTED;
362 FatType = Volume->MaxCluster < FAT_MAX_FAT12_CLUSTER ? Fat12 : Fat16;
366 Volume->FatEntrySize =
sizeof (UINT16);
367 DirtyMask = FAT16_DIRTY_MASK;
369 if (Volume->MaxCluster < FAT_MAX_FAT16_CLUSTER) {
370 return EFI_VOLUME_CORRUPTED;
376 Volume->FatEntrySize =
sizeof (UINT32);
377 DirtyMask = FAT32_DIRTY_MASK;
385 if (FatType != Fat12) {
387 if (EFI_ERROR (Status)) {
391 Volume->DirtyValue = Volume->NotDirtyValue & DirtyMask;
397 if (FatType == Fat32) {
398 Volume->FreeInfoPos = FatBs.FatBse.Fat32Bse.FsInfoSector * BlockSize;
399 if (FatBs.FatBse.Fat32Bse.FsInfoSector != 0) {
401 if ((Volume->FatInfoSector.Signature == FAT_INFO_SIGNATURE) &&
402 (Volume->FatInfoSector.InfoBeginSignature == FAT_INFO_BEGIN_SIGNATURE) &&
403 (Volume->FatInfoSector.InfoEndSignature == FAT_INFO_END_SIGNATURE) &&
404 (Volume->FatInfoSector.FreeInfo.ClusterCount <= Volume->MaxCluster)
407 Volume->FreeInfoValid =
TRUE;
415 if ((FAT_MIN_CLUSTER > Volume->FatInfoSector.FreeInfo.NextCluster) ||
416 (Volume->FatInfoSector.FreeInfo.NextCluster > Volume->MaxCluster + 1)
419 Volume->FatInfoSector.FreeInfo.NextCluster = FAT_MIN_CLUSTER;
425 Volume->FatType = FatType;
426 ASSERT (FatType != FatUndefined);
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
INTN EFIAPI HighBitSet32(IN UINT32 Operand)
EFI_STATUS FatInitializeDiskCache(IN FAT_VOLUME *Volume)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID FatFreeVolume(IN FAT_VOLUME *Volume)
EFI_STATUS FatAcquireLockOrFail(VOID)
EFI_STATUS EFIAPI FatOpenVolume(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, OUT EFI_FILE_PROTOCOL **File)
EFI_STATUS FatDiskIo(IN FAT_VOLUME *Volume, IN IO_MODE IoMode, IN UINT64 Offset, IN UINTN BufferSize, IN OUT VOID *Buffer, IN FAT_TASK *Task)
VOID FatSetVolumeError(IN FAT_OFILE *OFile, IN EFI_STATUS Status)
EFI_STATUS FatAccessVolumeDirty(IN FAT_VOLUME *Volume, IN IO_MODE IoMode, IN VOID *DirtyValue)
VOID FatReleaseLock(VOID)
EFI_STATUS FatCleanupVolume(IN FAT_VOLUME *Volume, IN FAT_OFILE *OFile, IN EFI_STATUS EfiStatus, IN FAT_TASK *Task)
EFI_STATUS FatOpenDevice(IN OUT FAT_VOLUME *Volume)
EFI_STATUS FatAllocateVolume(IN EFI_HANDLE Handle, IN EFI_DISK_IO_PROTOCOL *DiskIo, IN EFI_DISK_IO2_PROTOCOL *DiskIo2, IN EFI_BLOCK_IO_PROTOCOL *BlockIo)
EFI_STATUS FatAbandonVolume(IN FAT_VOLUME *Volume)
#define DEBUG(Expression)