/**@file

Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Host.h"

#define EMU_BLOCK_IO_PRIVATE_SIGNATURE SIGNATURE_32 ('E', 'M', 'b', 'k')
typedef struct {
  UINTN                       Signature;

  EMU_IO_THUNK_PROTOCOL       *Thunk;

  char                        *Filename;
  UINTN                       ReadMode;
  UINTN                       Mode;

  int                         fd;

  BOOLEAN                     RemovableMedia;
  BOOLEAN                     WriteProtected;

  UINT64                      NumberOfBlocks;
  UINT32                      BlockSize;

  EMU_BLOCK_IO_PROTOCOL       EmuBlockIo;
  EFI_BLOCK_IO_MEDIA          *Media;

} EMU_BLOCK_IO_PRIVATE;

#define EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS(a) \
         CR(a, EMU_BLOCK_IO_PRIVATE, EmuBlockIo, EMU_BLOCK_IO_PRIVATE_SIGNATURE)



EFI_STATUS
EmuBlockIoReset (
  IN EMU_BLOCK_IO_PROTOCOL    *This,
  IN BOOLEAN                  ExtendedVerification
  );


/*++

This function extends the capability of SetFilePointer to accept 64 bit parameters

**/
EFI_STATUS
SetFilePointer64 (
  IN  EMU_BLOCK_IO_PRIVATE        *Private,
  IN  INT64                      DistanceToMove,
  OUT UINT64                     *NewFilePointer,
  IN  INT32                      MoveMethod
  )
{
  EFI_STATUS    Status;
  off_t         res;
  off_t         offset = DistanceToMove;

  Status = EFI_SUCCESS;
  res = lseek (Private->fd, offset, (int)MoveMethod);
  if (res == -1) {
    Status = EFI_INVALID_PARAMETER;
  }

  if (NewFilePointer != NULL) {
    *NewFilePointer = res;
  }

  return Status;
}


EFI_STATUS
EmuBlockIoOpenDevice (
  IN EMU_BLOCK_IO_PRIVATE   *Private
  )
{
  EFI_STATUS            Status;
  UINT64                FileSize;
  struct statfs         buf;


  //
  // If the device is already opened, close it
  //
  if (Private->fd >= 0) {
    EmuBlockIoReset (&Private->EmuBlockIo, FALSE);
  }

  //
  // Open the device
  //
  Private->fd = open (Private->Filename, Private->Mode, 0644);
  if (Private->fd < 0) {
    printf ("EmuOpenBlock: Could not open %s: %s\n", Private->Filename, strerror(errno));
    Private->Media->MediaPresent  = FALSE;
    Status                        = EFI_NO_MEDIA;
    goto Done;
  }

  if (!Private->Media->MediaPresent) {
    //
    // BugBug: try to emulate if a CD appears - notify drivers to check it out
    //
    Private->Media->MediaPresent = TRUE;
  }

  //
  // get the size of the file
  //
  Status = SetFilePointer64 (Private, 0, &FileSize, SEEK_END);
  if (EFI_ERROR (Status)) {
    printf ("EmuOpenBlock: Could not get filesize of %s\n", Private->Filename);
    Status = EFI_UNSUPPORTED;
    goto Done;
  }

  if (FileSize == 0) {
    // lseek fails on a real device. ioctl calls are OS specific
#if __APPLE__
    {
      UINT32 BlockSize;

      if (ioctl (Private->fd, DKIOCGETBLOCKSIZE, &BlockSize) == 0) {
        Private->Media->BlockSize = BlockSize;
      }
      if (ioctl (Private->fd, DKIOCGETBLOCKCOUNT, &Private->NumberOfBlocks) == 0) {
        if ((Private->NumberOfBlocks == 0) && (BlockSize == 0x800)) {
          // A DVD is ~ 4.37 GB so make up a number
          Private->Media->LastBlock = (0x100000000ULL/0x800) - 1;
        } else {
          Private->Media->LastBlock = Private->NumberOfBlocks - 1;
        }
      }
      ioctl (Private->fd, DKIOCGETMAXBLOCKCOUNTWRITE, &Private->Media->OptimalTransferLengthGranularity);
    }
#else
    {
      size_t BlockSize;
      UINT64 DiskSize;

      if (ioctl (Private->fd, BLKSSZGET, &BlockSize) == 0) {
        Private->Media->BlockSize = BlockSize;
      }
      if (ioctl (Private->fd, BLKGETSIZE64, &DiskSize) == 0) {
        Private->NumberOfBlocks = DivU64x32 (DiskSize, (UINT32)BlockSize);
        Private->Media->LastBlock = Private->NumberOfBlocks - 1;
      }
    }
#endif

  } else {
    Private->Media->BlockSize = Private->BlockSize;
    Private->NumberOfBlocks = DivU64x32 (FileSize, Private->Media->BlockSize);
    Private->Media->LastBlock = Private->NumberOfBlocks - 1;

    if (fstatfs (Private->fd, &buf) == 0) {
#if __APPLE__
      Private->Media->OptimalTransferLengthGranularity = buf.f_iosize/buf.f_bsize;
#else
      Private->Media->OptimalTransferLengthGranularity = buf.f_bsize/buf.f_bsize;
#endif
    }
  }

  DEBUG ((EFI_D_INIT, "%HEmuOpenBlock: opened %a%N\n", Private->Filename));
  Status = EFI_SUCCESS;

Done:
  if (EFI_ERROR (Status)) {
    if (Private->fd >= 0) {
      EmuBlockIoReset (&Private->EmuBlockIo, FALSE);
    }
  }

  return Status;
}


EFI_STATUS
EmuBlockIoCreateMapping (
  IN     EMU_BLOCK_IO_PROTOCOL    *This,
  IN     EFI_BLOCK_IO_MEDIA       *Media
  )
{
  EFI_STATUS              Status;
  EMU_BLOCK_IO_PRIVATE    *Private;

  Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);

  Private->Media = Media;

  Media->MediaId          = 0;
  Media->RemovableMedia   = Private->RemovableMedia;
  Media->MediaPresent     = TRUE;
  Media->LogicalPartition = FALSE;
  Media->ReadOnly         = Private->WriteProtected;
  Media->WriteCaching     = FALSE;
  Media->IoAlign          = 1;
  Media->LastBlock        = 0; // Filled in by OpenDevice

  // EFI_BLOCK_IO_PROTOCOL_REVISION2
  Media->LowestAlignedLba              = 0;
  Media->LogicalBlocksPerPhysicalBlock = 0;


  // EFI_BLOCK_IO_PROTOCOL_REVISION3
  Media->OptimalTransferLengthGranularity = 0;

  Status = EmuBlockIoOpenDevice (Private);


  return Status;
}


EFI_STATUS
EmuBlockIoError (
  IN EMU_BLOCK_IO_PRIVATE      *Private
  )
{
  EFI_STATUS            Status;
  BOOLEAN               ReinstallBlockIoFlag;


  switch (errno) {

  case EAGAIN:
    Status                        = EFI_NO_MEDIA;
    Private->Media->ReadOnly      = FALSE;
    Private->Media->MediaPresent  = FALSE;
    ReinstallBlockIoFlag          = FALSE;
    break;

  case EACCES:
    Private->Media->ReadOnly      = FALSE;
    Private->Media->MediaPresent  = TRUE;
    Private->Media->MediaId += 1;
    ReinstallBlockIoFlag  = TRUE;
    Status                = EFI_MEDIA_CHANGED;
    break;

  case EROFS:
    Private->Media->ReadOnly  = TRUE;
    ReinstallBlockIoFlag      = FALSE;
    Status                    = EFI_WRITE_PROTECTED;
    break;

  default:
    ReinstallBlockIoFlag  = FALSE;
    Status                = EFI_DEVICE_ERROR;
    break;
  }
  return Status;
}


EFI_STATUS
EmuBlockIoReadWriteCommon (
  IN  EMU_BLOCK_IO_PRIVATE        *Private,
  IN UINT32                       MediaId,
  IN EFI_LBA                      Lba,
  IN UINTN                        BufferSize,
  IN VOID                         *Buffer,
  IN CHAR8                        *CallerName
  )
{
  EFI_STATUS  Status;
  UINTN       BlockSize;
  UINT64      LastBlock;
  INT64       DistanceToMove;
  UINT64      DistanceMoved;

  if (Private->fd < 0) {
    Status = EmuBlockIoOpenDevice (Private);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  if (!Private->Media->MediaPresent) {
    DEBUG ((EFI_D_INIT, "%s: No Media\n", CallerName));
    return EFI_NO_MEDIA;
  }

  if (Private->Media->MediaId != MediaId) {
    return EFI_MEDIA_CHANGED;
  }

  if ((UINTN) Buffer % Private->Media->IoAlign != 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Verify buffer size
  //
  BlockSize = Private->Media->BlockSize;
  if (BufferSize == 0) {
    DEBUG ((EFI_D_INIT, "%s: Zero length read\n", CallerName));
    return EFI_SUCCESS;
  }

  if ((BufferSize % BlockSize) != 0) {
    DEBUG ((EFI_D_INIT, "%s: Invalid read size\n", CallerName));
    return EFI_BAD_BUFFER_SIZE;
  }

  LastBlock = Lba + (BufferSize / BlockSize) - 1;
  if (LastBlock > Private->Media->LastBlock) {
    DEBUG ((EFI_D_INIT, "ReadBlocks: Attempted to read off end of device\n"));
    return EFI_INVALID_PARAMETER;
  }
  //
  // Seek to End of File
  //
  DistanceToMove = MultU64x32 (Lba, BlockSize);
  Status = SetFilePointer64 (Private, DistanceToMove, &DistanceMoved, SEEK_SET);

  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_INIT, "WriteBlocks: SetFilePointer failed\n"));
    return EmuBlockIoError (Private);
  }

  return EFI_SUCCESS;
}


/**
  Read BufferSize bytes from Lba into Buffer.

  This function reads the requested number of blocks from the device. All the
  blocks are read, or an error is returned.
  If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_or EFI_MEDIA_CHANGED is returned and
  non-blocking I/O is being used, the Event associated with this request will
  not be signaled.

  @param[in]       This       Indicates a pointer to the calling context.
  @param[in]       MediaId    Id of the media, changes every time the media is
                              replaced.
  @param[in]       Lba        The starting Logical Block Address to read from.
  @param[in, out]  Token	    A pointer to the token associated with the transaction.
  @param[in]       BufferSize Size of Buffer, must be a multiple of device block size.
  @param[out]      Buffer     A pointer to the destination buffer for the data. The
                              caller is responsible for either having implicit or
                              explicit ownership of the buffer.

  @retval EFI_SUCCESS           The read request was queued if Token->Event is
                                not NULL.The data was read correctly from the
                                device if the Token->Event is NULL.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing
                                the read.
  @retval EFI_NO_MEDIA          There is no media in the device.
  @retval EFI_MEDIA_CHANGED     The MediaId is not for the current media.
  @retval EFI_BAD_BUFFER_SIZE   The BufferSize parameter is not a multiple of the
                                intrinsic block size of the device.
  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
                                or the buffer is not on proper alignment.
  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack
                                of resources.
**/
EFI_STATUS
EmuBlockIoReadBlocks (
  IN     EMU_BLOCK_IO_PROTOCOL  *This,
  IN     UINT32                 MediaId,
  IN     EFI_LBA                LBA,
  IN OUT EFI_BLOCK_IO2_TOKEN    *Token,
  IN     UINTN                  BufferSize,
     OUT VOID                   *Buffer
  )
{
  EFI_STATUS              Status;
  EMU_BLOCK_IO_PRIVATE    *Private;
  ssize_t                 len;

  Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);

  Status  = EmuBlockIoReadWriteCommon (Private, MediaId, LBA, BufferSize, Buffer, "UnixReadBlocks");
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  len = read (Private->fd, Buffer, BufferSize);
  if (len != BufferSize) {
    DEBUG ((EFI_D_INIT, "ReadBlocks: ReadFile failed.\n"));
    Status = EmuBlockIoError (Private);
    goto Done;
  }

  //
  // If we read then media is present.
  //
  Private->Media->MediaPresent = TRUE;
  Status = EFI_SUCCESS;

Done:
  if (Token != NULL) {
    if (Token->Event != NULL) {
      // Caller is responcible for signaling EFI Event
      Token->TransactionStatus = Status;
      return EFI_SUCCESS;
    }
  }
  return Status;
}


/**
  Write BufferSize bytes from Lba into Buffer.

  This function writes the requested number of blocks to the device. All blocks
  are written, or an error is returned.If EFI_DEVICE_ERROR, EFI_NO_MEDIA,
  EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED is returned and non-blocking I/O is
  being used, the Event associated with this request will not be signaled.

  @param[in]       This       Indicates a pointer to the calling context.
  @param[in]       MediaId    The media ID that the write request is for.
  @param[in]       Lba        The starting logical block address to be written. The
                              caller is responsible for writing to only legitimate
                              locations.
  @param[in, out]  Token      A pointer to the token associated with the transaction.
  @param[in]       BufferSize Size of Buffer, must be a multiple of device block size.
  @param[in]       Buffer     A pointer to the source buffer for the data.

  @retval EFI_SUCCESS           The write request was queued if Event is not NULL.
                                The data was written correctly to the device if
                                the Event is NULL.
  @retval EFI_WRITE_PROTECTED   The device can not be written to.
  @retval EFI_NO_MEDIA          There is no media in the device.
  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.
  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
  @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
                                or the buffer is not on proper alignment.
  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack
                                of resources.

**/
EFI_STATUS
EmuBlockIoWriteBlocks (
  IN     EMU_BLOCK_IO_PROTOCOL  *This,
  IN     UINT32                 MediaId,
  IN     EFI_LBA                LBA,
  IN OUT EFI_BLOCK_IO2_TOKEN    *Token,
  IN     UINTN                  BufferSize,
  IN     VOID                   *Buffer
  )
{
  EMU_BLOCK_IO_PRIVATE    *Private;
  ssize_t                 len;
  EFI_STATUS              Status;


  Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);

  Status  = EmuBlockIoReadWriteCommon (Private, MediaId, LBA, BufferSize, Buffer, "UnixWriteBlocks");
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  len = write (Private->fd, Buffer, BufferSize);
  if (len != BufferSize) {
    DEBUG ((EFI_D_INIT, "ReadBlocks: WriteFile failed.\n"));
    Status = EmuBlockIoError (Private);
    goto Done;
  }

  //
  // If the write succeeded, we are not write protected and media is present.
  //
  Private->Media->MediaPresent = TRUE;
  Private->Media->ReadOnly     = FALSE;
  Status = EFI_SUCCESS;

Done:
  if (Token != NULL) {
    if (Token->Event != NULL) {
      // Caller is responcible for signaling EFI Event
      Token->TransactionStatus = Status;
      return EFI_SUCCESS;
    }
  }

  return Status;
}


/**
  Flush the Block Device.

  If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED
  is returned and non-blocking I/O is being used, the Event associated with
  this request will not be signaled.

  @param[in]      This     Indicates a pointer to the calling context.
  @param[in,out]  Token    A pointer to the token associated with the transaction

  @retval EFI_SUCCESS          The flush request was queued if Event is not NULL.
                               All outstanding data was written correctly to the
                               device if the Event is NULL.
  @retval EFI_DEVICE_ERROR     The device reported an error while writting back
                               the data.
  @retval EFI_WRITE_PROTECTED  The device cannot be written to.
  @retval EFI_NO_MEDIA         There is no media in the device.
  @retval EFI_MEDIA_CHANGED    The MediaId is not for the current media.
  @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
                               of resources.

**/
EFI_STATUS
EmuBlockIoFlushBlocks (
  IN     EMU_BLOCK_IO_PROTOCOL    *This,
  IN OUT EFI_BLOCK_IO2_TOKEN      *Token
  )
{
  EMU_BLOCK_IO_PRIVATE *Private;

  Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);

  if (Private->fd >= 0) {
    fsync (Private->fd);
#if __APPLE__
    fcntl (Private->fd, F_FULLFSYNC);
#endif
  }


  if (Token != NULL) {
    if (Token->Event != NULL) {
      // Caller is responcible for signaling EFI Event
      Token->TransactionStatus = EFI_SUCCESS;
      return EFI_SUCCESS;
    }
  }

  return EFI_SUCCESS;
}


/**
  Reset the block device hardware.

  @param[in]  This                 Indicates a pointer to the calling context.
  @param[in]  ExtendedVerification Indicates that the driver may perform a more
                                   exhausive verfication operation of the device
                                   during reset.

  @retval EFI_SUCCESS          The device was reset.
  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could
                               not be reset.

**/
EFI_STATUS
EmuBlockIoReset (
  IN EMU_BLOCK_IO_PROTOCOL    *This,
  IN BOOLEAN                  ExtendedVerification
  )
{
  EMU_BLOCK_IO_PRIVATE *Private;

  Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);

  if (Private->fd >= 0) {
    close (Private->fd);
    Private->fd = -1;
  }

  return EFI_SUCCESS;
}


char *
StdDupUnicodeToAscii (
  IN  CHAR16 *Str
  )
{
  UINTN   Size;
  char    *Ascii;
  char    *Ptr;

  Size = StrLen (Str) + 1;
  Ascii = malloc (Size);
  if (Ascii == NULL) {
    return NULL;
  }

  for (Ptr = Ascii; *Str != '\0'; Ptr++, Str++) {
    *Ptr = *Str;
  }
  *Ptr = 0;

  return Ascii;
}


EMU_BLOCK_IO_PROTOCOL gEmuBlockIoProtocol = {
  GasketEmuBlockIoReset,
  GasketEmuBlockIoReadBlocks,
  GasketEmuBlockIoWriteBlocks,
  GasketEmuBlockIoFlushBlocks,
  GasketEmuBlockIoCreateMapping
};

EFI_STATUS
EmuBlockIoThunkOpen (
  IN  EMU_IO_THUNK_PROTOCOL   *This
  )
{
  EMU_BLOCK_IO_PRIVATE  *Private;
  char                  *Str;

  if (This->Private != NULL) {
    return EFI_ALREADY_STARTED;
  }

  if (!CompareGuid (This->Protocol, &gEmuBlockIoProtocolGuid)) {
    return EFI_UNSUPPORTED;
  }

  Private = malloc (sizeof (EMU_BLOCK_IO_PRIVATE));
  if (Private == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }


  Private->Signature = EMU_BLOCK_IO_PRIVATE_SIGNATURE;
  Private->Thunk     = This;
  CopyMem (&Private->EmuBlockIo, &gEmuBlockIoProtocol, sizeof (gEmuBlockIoProtocol));
  Private->fd        = -1;
  Private->BlockSize = 512;

  Private->Filename = StdDupUnicodeToAscii (This->ConfigString);
  if (Private->Filename == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Str = strstr (Private->Filename, ":");
  if (Str == NULL) {
    Private->RemovableMedia = FALSE;
    Private->WriteProtected = FALSE;
  } else {
    for (*Str++ = '\0'; *Str != 0; Str++) {
      if (*Str == 'R' || *Str == 'F') {
        Private->RemovableMedia = (BOOLEAN) (*Str == 'R');
      }
      if (*Str == 'O' || *Str == 'W') {
        Private->WriteProtected  = (BOOLEAN) (*Str == 'O');
      }
      if (*Str == ':') {
        Private->BlockSize = strtol (++Str, NULL, 0);
        break;
      }
    }
  }

  Private->Mode = Private->WriteProtected ? O_RDONLY : O_RDWR;

  This->Interface = &Private->EmuBlockIo;
  This->Private   = Private;
  return EFI_SUCCESS;
}


EFI_STATUS
EmuBlockIoThunkClose (
  IN  EMU_IO_THUNK_PROTOCOL   *This
  )
{
  EMU_BLOCK_IO_PRIVATE  *Private;

  if (!CompareGuid (This->Protocol, &gEmuBlockIoProtocolGuid)) {
    return EFI_UNSUPPORTED;
  }

  Private = This->Private;

  if (This->Private != NULL) {
    if (Private->Filename != NULL) {
      free (Private->Filename);
    }
    free (This->Private);
    This->Private = NULL;
  }

  return EFI_SUCCESS;
}



EMU_IO_THUNK_PROTOCOL gBlockIoThunkIo = {
  &gEmuBlockIoProtocolGuid,
  NULL,
  NULL,
  0,
  GasketBlockIoThunkOpen,
  GasketBlockIoThunkClose,
  NULL
};


