]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Bus/Isa/IsaFloppy/Dxe/IsaFloppyBlock.c
Import IsaFloppy Dxe and Pei in IntelFrameworkModulePkg.
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / IsaFloppy / Dxe / IsaFloppyBlock.c
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaFloppy/Dxe/IsaFloppyBlock.c b/IntelFrameworkModulePkg/Bus/Isa/IsaFloppy/Dxe/IsaFloppyBlock.c
new file mode 100644 (file)
index 0000000..7d6f59f
--- /dev/null
@@ -0,0 +1,458 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation. All rights reserved. <BR> \r
+This software and associated documentation (if any) is furnished\r
+under a license and may only be used or copied in accordance\r
+with the terms of the license. Except as permitted by such\r
+license, no part of this software or documentation may be\r
+reproduced, stored in a retrieval system, or transmitted in any\r
+form or by any means without the express written consent of\r
+Intel Corporation.\r
+\r
+Module Name:\r
+\r
+  IsaFloppyBlock.c\r
+\r
+Abstract:\r
+\r
+  ISA Floppy Driver\r
+  1. Support two types diskette drive  \r
+     1.44M drive and 2.88M drive (and now only support 1.44M)\r
+  2. Support two diskette drives\r
+  3. Use DMA channel 2 to transfer data\r
+  4. Do not use interrupt\r
+  5. Support diskette change line signal and write protect\r
+  \r
+  Implement the Block IO interface\r
+\r
+Revision History:\r
+\r
+--*/\r
+\r
+#include "IsaFloppy.h"\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FdcReset (\r
+  IN  EFI_BLOCK_IO_PROTOCOL  *This,\r
+  IN  BOOLEAN                ExtendedVerification\r
+  )\r
+/*++\r
+  \r
+  Routine Description:  Reset the Floppy Logic Drive, call the FddReset function   \r
+  Parameters:\r
+    This EFI_BLOCK_IO *: A pointer to the Block I/O protocol interface\r
+    ExtendedVerification BOOLEAN: Indicate that the driver may perform a more \r
+                    exhaustive verification operation of the device during \r
+                    reset, now this par is ignored in this driver          \r
+  Returns:\r
+    EFI_SUCCESS:      The Floppy Logic Drive is reset\r
+    EFI_DEVICE_ERROR: The Floppy Logic Drive is not functioning correctly \r
+                      and can not be reset\r
+\r
+--*/\r
+// GC_TODO: function comment is missing 'Arguments:'\r
+// GC_TODO:    This - add argument and description to function comment\r
+// GC_TODO:    ExtendedVerification - add argument and description to function comment\r
+{\r
+  FDC_BLK_IO_DEV  *FdcDev;\r
+\r
+  //\r
+  // Reset the Floppy Disk Controller\r
+  //\r
+  FdcDev = FDD_BLK_IO_FROM_THIS (This);\r
+\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    EFI_P_PC_RESET | EFI_PERIPHERAL_REMOVABLE_MEDIA,\r
+    FdcDev->DevicePath\r
+    );\r
+\r
+  return FddReset (FdcDev);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FddFlushBlocks (\r
+  IN  EFI_BLOCK_IO_PROTOCOL  *This\r
+  )\r
+/*++\r
+  \r
+  Routine Description:  \r
+  Parameters:\r
+    This EFI_BLOCK_IO *: A pointer to the Block I/O protocol interface\r
+  Returns:\r
+    EFI_SUCCESS:    \r
+\r
+--*/\r
+// GC_TODO: function comment is missing 'Arguments:'\r
+// GC_TODO:    This - add argument and description to function comment\r
+{\r
+  //\r
+  // Not supported yet\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+VOID\r
+FddReportStatus (\r
+  IN  EFI_BLOCK_IO_PROTOCOL  *This,\r
+  IN  BOOLEAN                Read\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  This  - GC_TODO: add argument description\r
+  Read  - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  FDC_BLK_IO_DEV  *FdcDev;\r
+\r
+  FdcDev = FDD_BLK_IO_FROM_THIS (This);\r
+\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_ERROR_CODE,\r
+    ((Read) ? EFI_P_EC_INPUT_ERROR : EFI_P_EC_OUTPUT_ERROR) | EFI_PERIPHERAL_REMOVABLE_MEDIA,\r
+    FdcDev->DevicePath\r
+    );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FddReadBlocks (\r
+  IN  EFI_BLOCK_IO_PROTOCOL  *This,\r
+  IN  UINT32                 MediaId,\r
+  IN  EFI_LBA                LBA,\r
+  IN  UINTN                  BufferSize,\r
+  OUT VOID                   *Buffer\r
+  )\r
+/*++\r
+\r
+  Routine Description:  Read the requested number of blocks from the device   \r
+  Parameters:\r
+    This EFI_BLOCK_IO *: A pointer to the Block I/O protocol interface\r
+    MediaId UINT32:    The media id that the read request is for    \r
+    LBA EFI_LBA:     The starting logic block address to read from on the device\r
+    BufferSize UINTN:  The size of the Buffer in bytes\r
+    Buffer VOID *:     A pointer to the destination buffer for the data\r
+  Returns:\r
+    EFI_SUCCESS:     The data was read correctly from the device\r
+    EFI_DEVICE_ERROR:The device reported an error while attempting to perform\r
+                     the read operation\r
+    EFI_NO_MEDIA:    There is no media in the device\r
+    EFI_MEDIA_CHANGED:   The MediaId is not for the current media\r
+    EFI_BAD_BUFFER_SIZE: The BufferSize parameter is not a multiple of the \r
+                         intrinsic block size of the device\r
+    EFI_INVALID_PARAMETER:The read request contains LBAs that are not valid, \r
+                          or the buffer is not on proper alignment \r
+\r
+--*/\r
+// GC_TODO: function comment is missing 'Arguments:'\r
+// GC_TODO:    This - add argument and description to function comment\r
+// GC_TODO:    MediaId - add argument and description to function comment\r
+// GC_TODO:    LBA - add argument and description to function comment\r
+// GC_TODO:    BufferSize - add argument and description to function comment\r
+// GC_TODO:    Buffer - add argument and description to function comment\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = FddReadWriteBlocks (This, MediaId, LBA, BufferSize, READ, Buffer);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    FddReportStatus (This, TRUE);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FddWriteBlocks (\r
+  IN EFI_BLOCK_IO_PROTOCOL  *This,\r
+  IN UINT32                 MediaId,\r
+  IN EFI_LBA                LBA,\r
+  IN UINTN                  BufferSize,\r
+  IN VOID                   *Buffer\r
+  )\r
+/*++\r
+\r
+  Routine Description:  Write a specified number of blocks to the device   \r
+  Parameters:\r
+    This EFI_BLOCK_IO *: A pointer to the Block I/O protocol interface\r
+    MediaId UINT32:    The media id that the write request is for   \r
+    LBA EFI_LBA:     The starting logic block address to be written\r
+    BufferSize UINTN:  The size in bytes in Buffer\r
+    Buffer VOID *:     A pointer to the source buffer for the data\r
+  Returns :\r
+    EFI_SUCCESS:     The data were written correctly to the device\r
+    EFI_WRITE_PROTECTED: The device can not be written to \r
+    EFI_NO_MEDIA:    There is no media in the device\r
+    EFI_MEDIA_CHANGED:   The MediaId is not for the current media\r
+    EFI_DEVICE_ERROR:  The device reported an error while attempting to perform \r
+                       the write operation \r
+    EFI_BAD_BUFFER_SIZE: The BufferSize parameter is not a multiple of the \r
+                         intrinsic block size of the device\r
+    EFI_INVALID_PARAMETER:The write request contains LBAs that are not valid, \r
+                          or the buffer is not on proper alignment \r
+\r
+--*/\r
+// GC_TODO: function comment is missing 'Arguments:'\r
+// GC_TODO: function comment is missing 'Returns:'\r
+// GC_TODO:    This - add argument and description to function comment\r
+// GC_TODO:    MediaId - add argument and description to function comment\r
+// GC_TODO:    LBA - add argument and description to function comment\r
+// GC_TODO:    BufferSize - add argument and description to function comment\r
+// GC_TODO:    Buffer - add argument and description to function comment\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = FddReadWriteBlocks (This, MediaId, LBA, BufferSize, WRITE, Buffer);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    FddReportStatus (This, FALSE);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+FddReadWriteBlocks (\r
+  IN  EFI_BLOCK_IO_PROTOCOL  *This,\r
+  IN  UINT32                 MediaId,\r
+  IN  EFI_LBA                LBA,\r
+  IN  UINTN                  BufferSize,\r
+  IN  BOOLEAN                Operation,\r
+  OUT VOID                   *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  This        - GC_TODO: add argument description\r
+  MediaId     - GC_TODO: add argument description\r
+  LBA         - GC_TODO: add argument description\r
+  BufferSize  - GC_TODO: add argument description\r
+  Operation   - GC_TODO: add argument description\r
+  Buffer      - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER - GC_TODO: Add description for return value\r
+  EFI_SUCCESS - GC_TODO: Add description for return value\r
+  EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
+  EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
+  EFI_NO_MEDIA - GC_TODO: Add description for return value\r
+  EFI_MEDIA_CHANGED - GC_TODO: Add description for return value\r
+  EFI_WRITE_PROTECTED - GC_TODO: Add description for return value\r
+  EFI_BAD_BUFFER_SIZE - GC_TODO: Add description for return value\r
+  EFI_INVALID_PARAMETER - GC_TODO: Add description for return value\r
+  EFI_INVALID_PARAMETER - GC_TODO: Add description for return value\r
+  EFI_SUCCESS - GC_TODO: Add description for return value\r
+  EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
+  EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
+  EFI_SUCCESS - GC_TODO: Add description for return value\r
+\r
+--*/\r
+{\r
+  EFI_BLOCK_IO_MEDIA  *Media;\r
+  FDC_BLK_IO_DEV      *FdcDev;\r
+  UINTN               BlockSize;\r
+  UINTN               NumberOfBlocks;\r
+  UINTN               BlockCount;\r
+  EFI_STATUS          Status;\r
+  //\r
+  //  EFI_STATUS            CacheStatus;\r
+  //\r
+  EFI_LBA             LBA0;\r
+  UINT8               *Pointer;\r
+\r
+  //\r
+  // Get the intrinsic block size\r
+  //\r
+  Media     = This->Media;\r
+  BlockSize = Media->BlockSize;\r
+  FdcDev    = FDD_BLK_IO_FROM_THIS (This);\r
+\r
+  if (Operation == WRITE) {\r
+    if (LBA == 0) {\r
+      FdcFreeCache (FdcDev);\r
+    }\r
+  }\r
+  //\r
+  // Check the Parameter is valid\r
+  //\r
+  if (Buffer == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (BufferSize == 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+  //\r
+  // Set the drive motor on\r
+  //\r
+  Status = MotorOn (FdcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  //\r
+  // Check to see if media can be detected\r
+  //\r
+  Status = DetectMedia (FdcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    MotorOff (FdcDev);\r
+    FdcFreeCache (FdcDev);\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  //\r
+  // Check to see if media is present\r
+  //\r
+  if (!(Media->MediaPresent)) {\r
+    MotorOff (FdcDev);\r
+    FdcFreeCache (FdcDev);\r
+\r
+    /*\r
+    if (FdcDev->Cache) {\r
+      gBS->FreePool (FdcDev->Cache);\r
+      FdcDev->Cache = NULL;\r
+    }\r
+*/\r
+    return EFI_NO_MEDIA;\r
+  }\r
+  //\r
+  // Check to see if media has been changed\r
+  //\r
+  if (MediaId != Media->MediaId) {\r
+    MotorOff (FdcDev);\r
+    FdcFreeCache (FdcDev);\r
+    return EFI_MEDIA_CHANGED;\r
+  }\r
+\r
+  if (Operation == WRITE) {\r
+    if (Media->ReadOnly) {\r
+      MotorOff (FdcDev);\r
+      return EFI_WRITE_PROTECTED;\r
+    }\r
+  }\r
+  //\r
+  // Check the parameters for this read/write operation\r
+  //\r
+  if (BufferSize % BlockSize != 0) {\r
+    MotorOff (FdcDev);\r
+    return EFI_BAD_BUFFER_SIZE;\r
+  }\r
+\r
+  if (LBA > Media->LastBlock) {\r
+    MotorOff (FdcDev);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (((BufferSize / BlockSize) + LBA - 1) > Media->LastBlock) {\r
+    MotorOff (FdcDev);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Operation == READ) {\r
+    //\r
+    // See if the data that is being read is already in the cache\r
+    //\r
+    if (FdcDev->Cache) {\r
+      if (LBA == 0 && BufferSize == BlockSize) {\r
+        MotorOff (FdcDev);\r
+        CopyMem ((UINT8 *) Buffer, (UINT8 *) FdcDev->Cache, BlockSize);\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+  }\r
+  //\r
+  // Set up Floppy Disk Controller\r
+  //\r
+  Status = Setup (FdcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    MotorOff (FdcDev);\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  NumberOfBlocks  = BufferSize / BlockSize;\r
+  LBA0            = LBA;\r
+  Pointer         = Buffer;\r
+\r
+  //\r
+  // read blocks in the same cylinder.\r
+  // in a cylinder , there are 18 * 2 = 36 blocks\r
+  //\r
+  BlockCount = GetTransferBlockCount (FdcDev, LBA, NumberOfBlocks);\r
+  while ((BlockCount != 0) && !EFI_ERROR (Status)) {\r
+    Status = ReadWriteDataSector (FdcDev, Buffer, LBA, BlockCount, Operation);\r
+    if (EFI_ERROR (Status)) {\r
+      MotorOff (FdcDev);\r
+      FddReset (FdcDev);\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+\r
+    LBA += BlockCount;\r
+    NumberOfBlocks -= BlockCount;\r
+    Buffer      = (VOID *) ((UINTN) Buffer + BlockCount * BlockSize);\r
+    BlockCount  = GetTransferBlockCount (FdcDev, LBA, NumberOfBlocks);\r
+  }\r
+\r
+  Buffer = Pointer;\r
+\r
+  //\r
+  // Turn the motor off\r
+  //\r
+  MotorOff (FdcDev);\r
+\r
+  if (Operation == READ) {\r
+    //\r
+    // Cache the data read\r
+    //\r
+    if (LBA0 == 0 && !FdcDev->Cache) {\r
+      FdcDev->Cache = AllocateCopyPool (BlockSize, Buffer);\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+\r
+}\r
+\r
+VOID\r
+FdcFreeCache (\r
+  IN    FDC_BLK_IO_DEV  *FdcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  FdcDev  - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  if (FdcDev->Cache) {\r
+    gBS->FreePool (FdcDev->Cache);\r
+    FdcDev->Cache = NULL;\r
+  }\r
+}\r