REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the FatPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
		
			
				
	
	
		
			404 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			404 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Initialization routines.
 | 
						|
 | 
						|
Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>
 | 
						|
SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "Fat.h"
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Allocates volume structure, detects FAT file system, installs protocol,
 | 
						|
  and initialize cache.
 | 
						|
 | 
						|
  @param  Handle                - The handle of parent device.
 | 
						|
  @param  DiskIo                - The DiskIo of parent device.
 | 
						|
  @param  DiskIo2               - The DiskIo2 of parent device.
 | 
						|
  @param  BlockIo               - The BlockIo of parent device.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           - Allocate a new volume successfully.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  - Can not allocate the memory.
 | 
						|
  @return Others                - Allocating a new volume failed.
 | 
						|
 | 
						|
**/
 | 
						|
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  Status;
 | 
						|
  FAT_VOLUME  *Volume;
 | 
						|
 | 
						|
  //
 | 
						|
  // Allocate a volume structure
 | 
						|
  //
 | 
						|
  Volume = AllocateZeroPool (sizeof (FAT_VOLUME));
 | 
						|
  if (Volume == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize the structure
 | 
						|
  //
 | 
						|
  Volume->Signature                  = FAT_VOLUME_SIGNATURE;
 | 
						|
  Volume->Handle                     = Handle;
 | 
						|
  Volume->DiskIo                     = DiskIo;
 | 
						|
  Volume->DiskIo2                    = DiskIo2;
 | 
						|
  Volume->BlockIo                    = BlockIo;
 | 
						|
  Volume->MediaId                    = BlockIo->Media->MediaId;
 | 
						|
  Volume->ReadOnly                   = BlockIo->Media->ReadOnly;
 | 
						|
  Volume->VolumeInterface.Revision   = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
 | 
						|
  Volume->VolumeInterface.OpenVolume = FatOpenVolume;
 | 
						|
  InitializeListHead (&Volume->CheckRef);
 | 
						|
  InitializeListHead (&Volume->DirCacheList);
 | 
						|
  //
 | 
						|
  // Initialize Root Directory entry
 | 
						|
  //
 | 
						|
  Volume->RootDirEnt.FileString       = Volume->RootFileString;
 | 
						|
  Volume->RootDirEnt.Entry.Attributes = FAT_ATTRIBUTE_DIRECTORY;
 | 
						|
  //
 | 
						|
  // Check to see if there's a file system on the volume
 | 
						|
  //
 | 
						|
  Status = FatOpenDevice (Volume);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize cache
 | 
						|
  //
 | 
						|
  Status = FatInitializeDiskCache (Volume);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Install our protocol interfaces on the device's handle
 | 
						|
  //
 | 
						|
  Status = gBS->InstallMultipleProtocolInterfaces (
 | 
						|
                  &Volume->Handle,
 | 
						|
                  &gEfiSimpleFileSystemProtocolGuid,
 | 
						|
                  &Volume->VolumeInterface,
 | 
						|
                  NULL
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Volume installed
 | 
						|
  //
 | 
						|
  DEBUG ((DEBUG_INIT, "Installed Fat filesystem on %p\n", Handle));
 | 
						|
  Volume->Valid = TRUE;
 | 
						|
 | 
						|
Done:
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    FatFreeVolume (Volume);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Called by FatDriverBindingStop(), Abandon the volume.
 | 
						|
 | 
						|
  @param  Volume                - The volume to be abandoned.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           - Abandoned the volume successfully.
 | 
						|
  @return Others                - Can not uninstall the protocol interfaces.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
FatAbandonVolume (
 | 
						|
  IN FAT_VOLUME  *Volume
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  BOOLEAN     LockedByMe;
 | 
						|
 | 
						|
  //
 | 
						|
  // Uninstall the protocol interface.
 | 
						|
  //
 | 
						|
  if (Volume->Handle != NULL) {
 | 
						|
    Status = gBS->UninstallMultipleProtocolInterfaces (
 | 
						|
                    Volume->Handle,
 | 
						|
                    &gEfiSimpleFileSystemProtocolGuid,
 | 
						|
                    &Volume->VolumeInterface,
 | 
						|
                    NULL
 | 
						|
                    );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  LockedByMe = FALSE;
 | 
						|
 | 
						|
  //
 | 
						|
  // Acquire the lock.
 | 
						|
  // If the caller has already acquired the lock (which
 | 
						|
  // means we are in the process of some Fat operation),
 | 
						|
  // we can not acquire again.
 | 
						|
  //
 | 
						|
  Status = FatAcquireLockOrFail ();
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    LockedByMe = TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // The volume is still being used. Hence, set error flag for all OFiles still in
 | 
						|
  // use. In two cases, we could get here. One is EFI_MEDIA_CHANGED, the other is
 | 
						|
  // EFI_NO_MEDIA.
 | 
						|
  //
 | 
						|
  if (Volume->Root != NULL) {
 | 
						|
    FatSetVolumeError (
 | 
						|
      Volume->Root,
 | 
						|
      Volume->BlockIo->Media->MediaPresent ? EFI_MEDIA_CHANGED : EFI_NO_MEDIA
 | 
						|
      );
 | 
						|
  }
 | 
						|
 | 
						|
  Volume->Valid = FALSE;
 | 
						|
 | 
						|
  //
 | 
						|
  // Release the lock.
 | 
						|
  // If locked by me, this means DriverBindingStop is NOT
 | 
						|
  // called within an on-going Fat operation, so we should
 | 
						|
  // take responsibility to cleanup and free the volume.
 | 
						|
  // Otherwise, the DriverBindingStop is called within an on-going
 | 
						|
  // Fat operation, we shouldn't check reference, so just let outer
 | 
						|
  // FatCleanupVolume do the task.
 | 
						|
  //
 | 
						|
  if (LockedByMe) {
 | 
						|
    FatCleanupVolume (Volume, NULL, EFI_SUCCESS, NULL);
 | 
						|
    FatReleaseLock ();
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Detects FAT file system on Disk and set relevant fields of Volume.
 | 
						|
 | 
						|
  @param Volume                - The volume structure.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           - The Fat File System is detected successfully
 | 
						|
  @retval EFI_UNSUPPORTED       - The volume is not FAT file system.
 | 
						|
  @retval EFI_VOLUME_CORRUPTED  - The volume is corrupted.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
FatOpenDevice (
 | 
						|
  IN OUT FAT_VOLUME  *Volume
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS            Status;
 | 
						|
  UINT32                BlockSize;
 | 
						|
  UINT32                DirtyMask;
 | 
						|
  EFI_DISK_IO_PROTOCOL  *DiskIo;
 | 
						|
  FAT_BOOT_SECTOR       FatBs;
 | 
						|
  FAT_VOLUME_TYPE       FatType;
 | 
						|
  UINTN                 RootDirSectors;
 | 
						|
  UINTN                 FatLba;
 | 
						|
  UINTN                 RootLba;
 | 
						|
  UINTN                 FirstClusterLba;
 | 
						|
  UINTN                 Sectors;
 | 
						|
  UINTN                 SectorsPerFat;
 | 
						|
  UINT8                 SectorsPerClusterAlignment;
 | 
						|
  UINT8                 BlockAlignment;
 | 
						|
 | 
						|
  //
 | 
						|
  // Read the FAT_BOOT_SECTOR BPB info
 | 
						|
  // This is the only part of FAT code that uses parent DiskIo,
 | 
						|
  // Others use FatDiskIo which utilizes a Cache.
 | 
						|
  //
 | 
						|
  DiskIo = Volume->DiskIo;
 | 
						|
  Status = DiskIo->ReadDisk (DiskIo, Volume->MediaId, 0, sizeof (FatBs), &FatBs);
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    DEBUG ((DEBUG_INIT, "FatOpenDevice: read of part_lba failed %r\n", Status));
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  FatType = FatUndefined;
 | 
						|
 | 
						|
  //
 | 
						|
  // Use LargeSectors if Sectors is 0
 | 
						|
  //
 | 
						|
  Sectors = FatBs.FatBsb.Sectors;
 | 
						|
  if (Sectors == 0) {
 | 
						|
    Sectors = FatBs.FatBsb.LargeSectors;
 | 
						|
  }
 | 
						|
 | 
						|
  SectorsPerFat = FatBs.FatBsb.SectorsPerFat;
 | 
						|
  if (SectorsPerFat == 0) {
 | 
						|
    SectorsPerFat = FatBs.FatBse.Fat32Bse.LargeSectorsPerFat;
 | 
						|
    FatType       = Fat32;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Is boot sector a fat sector?
 | 
						|
  // (Note that so far we only know if the sector is FAT32 or not, we don't
 | 
						|
  // know if the sector is Fat16 or Fat12 until later when we can compute
 | 
						|
  // the volume size)
 | 
						|
  //
 | 
						|
  if ((FatBs.FatBsb.ReservedSectors == 0) || (FatBs.FatBsb.NumFats == 0) || (Sectors == 0)) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((FatBs.FatBsb.SectorSize & (FatBs.FatBsb.SectorSize - 1)) != 0) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  BlockAlignment = (UINT8)HighBitSet32 (FatBs.FatBsb.SectorSize);
 | 
						|
  if ((BlockAlignment > MAX_BLOCK_ALIGNMENT) || (BlockAlignment < MIN_BLOCK_ALIGNMENT)) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((FatBs.FatBsb.SectorsPerCluster & (FatBs.FatBsb.SectorsPerCluster - 1)) != 0) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  SectorsPerClusterAlignment = (UINT8)HighBitSet32 (FatBs.FatBsb.SectorsPerCluster);
 | 
						|
  if (SectorsPerClusterAlignment > MAX_SECTORS_PER_CLUSTER_ALIGNMENT) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((FatBs.FatBsb.Media <= 0xf7) &&
 | 
						|
      (FatBs.FatBsb.Media != 0xf0) &&
 | 
						|
      (FatBs.FatBsb.Media != 0x00) &&
 | 
						|
      (FatBs.FatBsb.Media != 0x01)
 | 
						|
      )
 | 
						|
  {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize fields the volume information for this FatType
 | 
						|
  //
 | 
						|
  if (FatType != Fat32) {
 | 
						|
    if (FatBs.FatBsb.RootEntries == 0) {
 | 
						|
      return EFI_UNSUPPORTED;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Unpack fat12, fat16 info
 | 
						|
    //
 | 
						|
    Volume->RootEntries = FatBs.FatBsb.RootEntries;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // If this is fat32, refuse to mount mirror-disabled volumes
 | 
						|
    //
 | 
						|
    if (((SectorsPerFat == 0) || (FatBs.FatBse.Fat32Bse.FsVersion != 0)) || (FatBs.FatBse.Fat32Bse.ExtendedFlags & 0x80)) {
 | 
						|
      return EFI_UNSUPPORTED;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Unpack fat32 info
 | 
						|
    //
 | 
						|
    Volume->RootCluster = FatBs.FatBse.Fat32Bse.RootDirFirstCluster;
 | 
						|
  }
 | 
						|
 | 
						|
  Volume->NumFats = FatBs.FatBsb.NumFats;
 | 
						|
  //
 | 
						|
  // Compute some fat locations
 | 
						|
  //
 | 
						|
  BlockSize      = FatBs.FatBsb.SectorSize;
 | 
						|
  RootDirSectors = ((Volume->RootEntries * sizeof (FAT_DIRECTORY_ENTRY)) + (BlockSize - 1)) / BlockSize;
 | 
						|
 | 
						|
  FatLba          = FatBs.FatBsb.ReservedSectors;
 | 
						|
  RootLba         = FatBs.FatBsb.NumFats * SectorsPerFat + FatLba;
 | 
						|
  FirstClusterLba = RootLba + RootDirSectors;
 | 
						|
 | 
						|
  Volume->FatPos  = FatLba * BlockSize;
 | 
						|
  Volume->FatSize = SectorsPerFat * BlockSize;
 | 
						|
 | 
						|
  Volume->VolumeSize       = LShiftU64 (Sectors, BlockAlignment);
 | 
						|
  Volume->RootPos          = LShiftU64 (RootLba, BlockAlignment);
 | 
						|
  Volume->FirstClusterPos  = LShiftU64 (FirstClusterLba, BlockAlignment);
 | 
						|
  Volume->MaxCluster       = (Sectors - FirstClusterLba) >> SectorsPerClusterAlignment;
 | 
						|
  Volume->ClusterAlignment = (UINT8)(BlockAlignment + SectorsPerClusterAlignment);
 | 
						|
  Volume->ClusterSize      = (UINTN)1 << (Volume->ClusterAlignment);
 | 
						|
 | 
						|
  //
 | 
						|
  // If this is not a fat32, determine if it's a fat16 or fat12
 | 
						|
  //
 | 
						|
  if (FatType != Fat32) {
 | 
						|
    if (Volume->MaxCluster >= FAT_MAX_FAT16_CLUSTER) {
 | 
						|
      return EFI_VOLUME_CORRUPTED;
 | 
						|
    }
 | 
						|
 | 
						|
    FatType = Volume->MaxCluster < FAT_MAX_FAT12_CLUSTER ? Fat12 : Fat16;
 | 
						|
    //
 | 
						|
    // fat12 & fat16 fat-entries are 2 bytes
 | 
						|
    //
 | 
						|
    Volume->FatEntrySize = sizeof (UINT16);
 | 
						|
    DirtyMask            = FAT16_DIRTY_MASK;
 | 
						|
  } else {
 | 
						|
    if (Volume->MaxCluster < FAT_MAX_FAT16_CLUSTER) {
 | 
						|
      return EFI_VOLUME_CORRUPTED;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // fat32 fat-entries are 4 bytes
 | 
						|
    //
 | 
						|
    Volume->FatEntrySize = sizeof (UINT32);
 | 
						|
    DirtyMask            = FAT32_DIRTY_MASK;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the DirtyValue and NotDirtyValue
 | 
						|
  // We should keep the initial value as the NotDirtyValue
 | 
						|
  // in case the volume is dirty already
 | 
						|
  //
 | 
						|
  if (FatType != Fat12) {
 | 
						|
    Status = FatAccessVolumeDirty (Volume, ReadDisk, &Volume->NotDirtyValue);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    Volume->DirtyValue = Volume->NotDirtyValue & DirtyMask;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // If present, read the fat hint info
 | 
						|
  //
 | 
						|
  if (FatType == Fat32) {
 | 
						|
    Volume->FreeInfoPos = FatBs.FatBse.Fat32Bse.FsInfoSector * BlockSize;
 | 
						|
    if (FatBs.FatBse.Fat32Bse.FsInfoSector != 0) {
 | 
						|
      FatDiskIo (Volume, ReadDisk, Volume->FreeInfoPos, sizeof (FAT_INFO_SECTOR), &Volume->FatInfoSector, NULL);
 | 
						|
      if ((Volume->FatInfoSector.Signature == FAT_INFO_SIGNATURE) &&
 | 
						|
          (Volume->FatInfoSector.InfoBeginSignature == FAT_INFO_BEGIN_SIGNATURE) &&
 | 
						|
          (Volume->FatInfoSector.InfoEndSignature == FAT_INFO_END_SIGNATURE) &&
 | 
						|
          (Volume->FatInfoSector.FreeInfo.ClusterCount <= Volume->MaxCluster)
 | 
						|
          )
 | 
						|
      {
 | 
						|
        Volume->FreeInfoValid = TRUE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Just make up a FreeInfo.NextCluster for use by allocate cluster
 | 
						|
  //
 | 
						|
  if ((FAT_MIN_CLUSTER > Volume->FatInfoSector.FreeInfo.NextCluster) ||
 | 
						|
      (Volume->FatInfoSector.FreeInfo.NextCluster > Volume->MaxCluster + 1)
 | 
						|
      )
 | 
						|
  {
 | 
						|
    Volume->FatInfoSector.FreeInfo.NextCluster = FAT_MIN_CLUSTER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // We are now defining FAT Type
 | 
						|
  //
 | 
						|
  Volume->FatType = FatType;
 | 
						|
  ASSERT (FatType != FatUndefined);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 |