/** @file
  Miscellaneous functions.

Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent


**/

#include "Fat.h"
UINT8  mMonthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

/**

  Create the task

  @param  IFile                 - The instance of the open file.
  @param  Token                 - A pointer to the token associated with the transaction.

  @return FAT_TASK *            - Return the task instance.

**/
FAT_TASK *
FatCreateTask (
  FAT_IFILE          *IFile,
  EFI_FILE_IO_TOKEN  *Token
  )
{
  FAT_TASK  *Task;

  Task = AllocateZeroPool (sizeof (*Task));
  if (Task != NULL) {
    Task->Signature   = FAT_TASK_SIGNATURE;
    Task->IFile       = IFile;
    Task->FileIoToken = Token;
    InitializeListHead (&Task->Subtasks);
    InitializeListHead (&Task->Link);
  }

  return Task;
}

/**

  Destroy the task.

  @param  Task                  - The task to be destroyed.

**/
VOID
FatDestroyTask (
  FAT_TASK  *Task
  )
{
  LIST_ENTRY   *Link;
  FAT_SUBTASK  *Subtask;

  Link = GetFirstNode (&Task->Subtasks);
  while (!IsNull (&Task->Subtasks, Link)) {
    Subtask = CR (Link, FAT_SUBTASK, Link, FAT_SUBTASK_SIGNATURE);
    Link    = FatDestroySubtask (Subtask);
  }

  FreePool (Task);
}

/**

  Wait all non-blocking requests complete.

  @param  IFile                 - The instance of the open file.

**/
VOID
FatWaitNonblockingTask (
  FAT_IFILE  *IFile
  )
{
  BOOLEAN  TaskQueueEmpty;

  do {
    EfiAcquireLock (&FatTaskLock);
    TaskQueueEmpty = IsListEmpty (&IFile->Tasks);
    EfiReleaseLock (&FatTaskLock);
  } while (!TaskQueueEmpty);
}

/**

  Remove the subtask from subtask list.

  @param  Subtask               - The subtask to be removed.

  @return LIST_ENTRY *          - The next node in the list.

**/
LIST_ENTRY *
FatDestroySubtask (
  FAT_SUBTASK  *Subtask
  )
{
  LIST_ENTRY  *Link;

  gBS->CloseEvent (Subtask->DiskIo2Token.Event);

  Link = RemoveEntryList (&Subtask->Link);
  FreePool (Subtask);

  return Link;
}

/**

  Execute the task.

  @param  IFile                 - The instance of the open file.
  @param  Task                  - The task to be executed.

  @retval EFI_SUCCESS           - The task was executed successfully.
  @return other                 - An error occurred when executing the task.

**/
EFI_STATUS
FatQueueTask (
  IN FAT_IFILE  *IFile,
  IN FAT_TASK   *Task
  )
{
  EFI_STATUS   Status;
  LIST_ENTRY   *Link;
  LIST_ENTRY   *NextLink;
  FAT_SUBTASK  *Subtask;

  //
  // Sometimes the Task doesn't contain any subtasks, signal the event directly.
  //
  if (IsListEmpty (&Task->Subtasks)) {
    Task->FileIoToken->Status = EFI_SUCCESS;
    gBS->SignalEvent (Task->FileIoToken->Event);
    FreePool (Task);
    return EFI_SUCCESS;
  }

  EfiAcquireLock (&FatTaskLock);
  InsertTailList (&IFile->Tasks, &Task->Link);
  EfiReleaseLock (&FatTaskLock);

  Status = EFI_SUCCESS;
  //
  // Use NextLink to store the next link of the list, because Link might be remove from the
  // doubly-linked list and get freed in the end of current loop.
  //
  // Also, list operation APIs like IsNull() and GetNextNode() are avoided during the loop, since
  // they may check the validity of doubly-linked lists by traversing them. These APIs cannot
  // handle list elements being removed during the traverse.
  //
  for ( Link = GetFirstNode (&Task->Subtasks), NextLink = GetNextNode (&Task->Subtasks, Link)
        ; Link != &Task->Subtasks
        ; Link = NextLink, NextLink = Link->ForwardLink
        )
  {
    Subtask = CR (Link, FAT_SUBTASK, Link, FAT_SUBTASK_SIGNATURE);
    if (Subtask->Write) {
      Status = IFile->OFile->Volume->DiskIo2->WriteDiskEx (
                                                IFile->OFile->Volume->DiskIo2,
                                                IFile->OFile->Volume->MediaId,
                                                Subtask->Offset,
                                                &Subtask->DiskIo2Token,
                                                Subtask->BufferSize,
                                                Subtask->Buffer
                                                );
    } else {
      Status = IFile->OFile->Volume->DiskIo2->ReadDiskEx (
                                                IFile->OFile->Volume->DiskIo2,
                                                IFile->OFile->Volume->MediaId,
                                                Subtask->Offset,
                                                &Subtask->DiskIo2Token,
                                                Subtask->BufferSize,
                                                Subtask->Buffer
                                                );
    }

    if (EFI_ERROR (Status)) {
      break;
    }
  }

  if (EFI_ERROR (Status)) {
    EfiAcquireLock (&FatTaskLock);
    //
    // Remove all the remaining subtasks when failure.
    // We shouldn't remove all the tasks because the non-blocking requests have
    // been submitted and cannot be canceled.
    //
    while (!IsNull (&Task->Subtasks, Link)) {
      Subtask = CR (Link, FAT_SUBTASK, Link, FAT_SUBTASK_SIGNATURE);
      Link    = FatDestroySubtask (Subtask);
    }

    if (IsListEmpty (&Task->Subtasks)) {
      RemoveEntryList (&Task->Link);
      FreePool (Task);
    } else {
      //
      // If one or more subtasks have been already submitted, set FileIoToken
      // to NULL so that the callback won't signal the event.
      //
      Task->FileIoToken = NULL;
    }

    EfiReleaseLock (&FatTaskLock);
  }

  return Status;
}

/**

  Set the volume as dirty or not.

  @param  Volume                - FAT file system volume.
  @param  IoMode                - The access mode.
  @param  DirtyValue            - Set the volume as dirty or not.

  @retval EFI_SUCCESS           - Set the new FAT entry value successfully.
  @return other                 - An error occurred when operation the FAT entries.

**/
EFI_STATUS
FatAccessVolumeDirty (
  IN FAT_VOLUME  *Volume,
  IN IO_MODE     IoMode,
  IN VOID        *DirtyValue
  )
{
  UINTN  WriteCount;

  WriteCount = Volume->FatEntrySize;
  return FatDiskIo (Volume, IoMode, Volume->FatPos + WriteCount, WriteCount, DirtyValue, NULL);
}

/**
  Invoke a notification event.

  @param  Event                 Event whose notification function is being invoked.
  @param  Context               The pointer to the notification function's context,
                                which is implementation-dependent.

**/
VOID
EFIAPI
FatOnAccessComplete (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  EFI_STATUS   Status;
  FAT_SUBTASK  *Subtask;
  FAT_TASK     *Task;

  //
  // Avoid someone in future breaks the below assumption.
  //
  ASSERT (EfiGetCurrentTpl () == FatTaskLock.Tpl);

  Subtask = (FAT_SUBTASK *)Context;
  Task    = Subtask->Task;
  Status  = Subtask->DiskIo2Token.TransactionStatus;

  ASSERT (Task->Signature    == FAT_TASK_SIGNATURE);
  ASSERT (Subtask->Signature == FAT_SUBTASK_SIGNATURE);

  //
  // Remove the task unconditionally
  //
  FatDestroySubtask (Subtask);

  //
  // Task->FileIoToken is NULL which means the task will be ignored (just recycle the subtask and task memory).
  //
  if (Task->FileIoToken != NULL) {
    if (IsListEmpty (&Task->Subtasks) || EFI_ERROR (Status)) {
      Task->FileIoToken->Status = Status;
      gBS->SignalEvent (Task->FileIoToken->Event);
      //
      // Mark Task->FileIoToken to NULL so that the subtasks belonging to the task will be ignored.
      //
      Task->FileIoToken = NULL;
    }
  }

  if (IsListEmpty (&Task->Subtasks)) {
    RemoveEntryList (&Task->Link);
    FreePool (Task);
  }
}

/**

  General disk access function.

  @param  Volume                - FAT file system volume.
  @param  IoMode                - The access mode (disk read/write or cache access).
  @param  Offset                - The starting byte offset to read from.
  @param  BufferSize            - Size of Buffer.
  @param  Buffer                - Buffer containing read data.
  @param  Task                    point to task instance.

  @retval EFI_SUCCESS           - The operation is performed successfully.
  @retval EFI_VOLUME_CORRUPTED  - The access is
  @return Others                - The status of read/write the disk

**/
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
  )
{
  EFI_STATUS            Status;
  EFI_DISK_IO_PROTOCOL  *DiskIo;
  EFI_DISK_READ         IoFunction;
  FAT_SUBTASK           *Subtask;

  //
  // Verify the IO is in devices range
  //
  Status = EFI_VOLUME_CORRUPTED;
  if (Offset + BufferSize <= Volume->VolumeSize) {
    if (CACHE_ENABLED (IoMode)) {
      //
      // Access cache
      //
      Status = FatAccessCache (Volume, CACHE_TYPE (IoMode), RAW_ACCESS (IoMode), Offset, BufferSize, Buffer, Task);
    } else {
      //
      // Access disk directly
      //
      if (Task == NULL) {
        //
        // Blocking access
        //
        DiskIo     = Volume->DiskIo;
        IoFunction = (IoMode == ReadDisk) ? DiskIo->ReadDisk : DiskIo->WriteDisk;
        Status     = IoFunction (DiskIo, Volume->MediaId, Offset, BufferSize, Buffer);
      } else {
        //
        // Non-blocking access
        //
        Subtask = AllocateZeroPool (sizeof (*Subtask));
        if (Subtask == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
        } else {
          Subtask->Signature  = FAT_SUBTASK_SIGNATURE;
          Subtask->Task       = Task;
          Subtask->Write      = (BOOLEAN)(IoMode == WriteDisk);
          Subtask->Offset     = Offset;
          Subtask->Buffer     = Buffer;
          Subtask->BufferSize = BufferSize;
          Status              = gBS->CreateEvent (
                                       EVT_NOTIFY_SIGNAL,
                                       TPL_NOTIFY,
                                       FatOnAccessComplete,
                                       Subtask,
                                       &Subtask->DiskIo2Token.Event
                                       );
          if (!EFI_ERROR (Status)) {
            InsertTailList (&Task->Subtasks, &Subtask->Link);
          } else {
            FreePool (Subtask);
          }
        }
      }
    }
  }

  if (EFI_ERROR (Status)) {
    Volume->DiskError = TRUE;
    DEBUG ((DEBUG_ERROR, "FatDiskIo: error %r\n", Status));
  }

  return Status;
}

/**

  Lock the volume.

**/
VOID
FatAcquireLock (
  VOID
  )
{
  EfiAcquireLock (&FatFsLock);
}

/**

  Lock the volume.
  If the lock is already in the acquired state, then EFI_ACCESS_DENIED is returned.
  Otherwise, EFI_SUCCESS is returned.

  @retval EFI_SUCCESS           - The volume is locked.
  @retval EFI_ACCESS_DENIED     - The volume could not be locked because it is already locked.

**/
EFI_STATUS
FatAcquireLockOrFail (
  VOID
  )
{
  return EfiAcquireLockOrFail (&FatFsLock);
}

/**

  Unlock the volume.

**/
VOID
FatReleaseLock (
  VOID
  )
{
  EfiReleaseLock (&FatFsLock);
}

/**

  Free directory entry.

  @param  DirEnt                - The directory entry to be freed.

**/
VOID
FatFreeDirEnt (
  IN FAT_DIRENT  *DirEnt
  )
{
  if (DirEnt->FileString != NULL) {
    FreePool (DirEnt->FileString);
  }

  FreePool (DirEnt);
}

/**

  Free volume structure (including the contents of directory cache and disk cache).

  @param  Volume                - The volume structure to be freed.

**/
VOID
FatFreeVolume (
  IN FAT_VOLUME  *Volume
  )
{
  //
  // Free disk cache
  //
  if (Volume->CacheBuffer != NULL) {
    FreePool (Volume->CacheBuffer);
  }

  //
  // Free directory cache
  //
  FatCleanupODirCache (Volume);
  FreePool (Volume);
}

/**

  Translate EFI time to FAT time.

  @param  ETime                 - The time of EFI_TIME.
  @param  FTime                 - The time of FAT_DATE_TIME.

**/
VOID
FatEfiTimeToFatTime (
  IN  EFI_TIME       *ETime,
  OUT FAT_DATE_TIME  *FTime
  )
{
  //
  // ignores timezone info in source ETime
  //
  if (ETime->Year > 1980) {
    FTime->Date.Year = (UINT16)(ETime->Year - 1980);
  }

  if (ETime->Year >= 1980 + FAT_MAX_YEAR_FROM_1980) {
    FTime->Date.Year = FAT_MAX_YEAR_FROM_1980;
  }

  FTime->Date.Month        = ETime->Month;
  FTime->Date.Day          = ETime->Day;
  FTime->Time.Hour         = ETime->Hour;
  FTime->Time.Minute       = ETime->Minute;
  FTime->Time.DoubleSecond = (UINT16)(ETime->Second / 2);
}

/**

  Translate Fat time to EFI time.

  @param  FTime                 - The time of FAT_DATE_TIME.
  @param  ETime                 - The time of EFI_TIME..

**/
VOID
FatFatTimeToEfiTime (
  IN  FAT_DATE_TIME  *FTime,
  OUT EFI_TIME       *ETime
  )
{
  ETime->Year       = (UINT16)(FTime->Date.Year + 1980);
  ETime->Month      = (UINT8)FTime->Date.Month;
  ETime->Day        = (UINT8)FTime->Date.Day;
  ETime->Hour       = (UINT8)FTime->Time.Hour;
  ETime->Minute     = (UINT8)FTime->Time.Minute;
  ETime->Second     = (UINT8)(FTime->Time.DoubleSecond * 2);
  ETime->Nanosecond = 0;
  ETime->TimeZone   = EFI_UNSPECIFIED_TIMEZONE;
  ETime->Daylight   = 0;
}

/**

  Get Current FAT time.

  @param  FatNow                - Current FAT time.

**/
VOID
FatGetCurrentFatTime (
  OUT FAT_DATE_TIME  *FatNow
  )
{
  EFI_STATUS  Status;
  EFI_TIME    Now;

  Status = gRT->GetTime (&Now, NULL);
  if (!EFI_ERROR (Status)) {
    FatEfiTimeToFatTime (&Now, FatNow);
  } else {
    ZeroMem (&Now, sizeof (EFI_TIME));
    Now.Year  = 1980;
    Now.Month = 1;
    Now.Day   = 1;
    FatEfiTimeToFatTime (&Now, FatNow);
  }
}

/**

  Check whether a time is valid.

  @param  Time                  - The time of EFI_TIME.

  @retval TRUE                  - The time is valid.
  @retval FALSE                 - The time is not valid.

**/
BOOLEAN
FatIsValidTime (
  IN EFI_TIME  *Time
  )
{
  UINTN    Day;
  BOOLEAN  ValidTime;

  ValidTime = TRUE;

  //
  // Check the fields for range problems
  // Fat can only support from 1980
  //
  if ((Time->Year < 1980) ||
      (Time->Month < 1) ||
      (Time->Month > 12) ||
      (Time->Day < 1) ||
      (Time->Day > 31) ||
      (Time->Hour > 23) ||
      (Time->Minute > 59) ||
      (Time->Second > 59) ||
      (Time->Nanosecond > 999999999)
      )
  {
    ValidTime = FALSE;
  } else {
    //
    // Perform a more specific check of the day of the month
    //
    Day = mMonthDays[Time->Month - 1];
    if ((Time->Month == 2) && IS_LEAP_YEAR (Time->Year)) {
      Day += 1;
      //
      // 1 extra day this month
      //
    }

    if (Time->Day > Day) {
      ValidTime = FALSE;
    }
  }

  return ValidTime;
}
