--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+\r
+Module Name:\r
+\r
+ FtwLite.h\r
+\r
+Abstract:\r
+\r
+ This is a simple fault tolerant write driver, based on PlatformFd library.\r
+ And it only supports write BufferSize <= SpareAreaLength.\r
+\r
+ This boot service only protocol provides fault tolerant write capability for \r
+ block devices. The protocol has internal non-volatile intermediate storage \r
+ of the data and private information. It should be able to recover \r
+ automatically from a critical fault, such as power failure. \r
+\r
+--*/\r
+\r
+#ifndef _EFI_FAULT_TOLERANT_WRITE_LITE_H_\r
+#define _EFI_FAULT_TOLERANT_WRITE_LITE_H_\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <PiDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Protocol/PciRootBridgeIo.h>\r
+#include <Guid/SystemNvDataGuid.h>\r
+#include <Protocol/FaultTolerantWriteLite.h>\r
+#include <Protocol/FirmwareVolumeBlock.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/PcdLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#include <Common/WorkingBlockHeader.h>\r
+\r
+#define EFI_D_FTW_LITE EFI_D_ERROR\r
+#define EFI_D_FTW_INFO EFI_D_INFO\r
+\r
+//\r
+// Flash erase polarity is 1\r
+//\r
+#define FTW_ERASE_POLARITY 1\r
+\r
+#define FTW_VALID_STATE 0\r
+#define FTW_INVALID_STATE 1\r
+\r
+#define FTW_ERASED_BYTE ((UINT8) (255))\r
+#define FTW_POLARITY_REVERT ((UINT8) (255))\r
+\r
+typedef struct {\r
+ UINT8 WriteAllocated : 1;\r
+ UINT8 SpareCompleted : 1;\r
+ UINT8 WriteCompleted : 1;\r
+ UINT8 Reserved : 5;\r
+#define WRITE_ALLOCATED 0x1\r
+#define SPARE_COMPLETED 0x2\r
+#define WRITE_COMPLETED 0x4\r
+\r
+ EFI_DEV_PATH DevPath;\r
+ EFI_LBA Lba;\r
+ UINTN Offset;\r
+ UINTN NumBytes;\r
+ //\r
+ // UINTN SpareAreaOffset;\r
+ //\r
+} EFI_FTW_LITE_RECORD;\r
+\r
+#define FTW_LITE_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('F', 'T', 'W', 'L')\r
+\r
+//\r
+// MACRO for Block size.\r
+// Flash Erasing will do in block granularity.\r
+//\r
+#ifdef FV_BLOCK_SIZE\r
+#define FTW_BLOCK_SIZE FV_BLOCK_SIZE\r
+#else\r
+#define FV_BLOCK_SIZE 0x10000\r
+#define FTW_BLOCK_SIZE FV_BLOCK_SIZE\r
+#endif\r
+//\r
+// MACRO for FTW WORK SPACE Base & Size\r
+//\r
+#ifdef EFI_FTW_WORKING_OFFSET\r
+#define FTW_WORK_SPACE_BASE EFI_FTW_WORKING_OFFSET\r
+#else\r
+#define FTW_WORK_SPACE_BASE 0x00E000\r
+#endif\r
+\r
+#ifdef EFI_FTW_WORKING_LENGTH\r
+#define FTW_WORK_SPACE_SIZE EFI_FTW_WORKING_LENGTH\r
+#else\r
+#define FTW_WORK_SPACE_SIZE 0x002000\r
+#endif\r
+//\r
+// MACRO for FTW header and record\r
+//\r
+#define FTW_WORKING_QUEUE_SIZE (FTW_WORK_SPACE_SIZE - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER))\r
+#define FTW_LITE_RECORD_SIZE (sizeof (EFI_FTW_LITE_RECORD))\r
+#define WRITE_TOTAL_SIZE FTW_LITE_RECORD_SIZE\r
+\r
+//\r
+// EFI Fault tolerant protocol private data structure\r
+//\r
+typedef struct {\r
+ UINTN Signature;\r
+ EFI_HANDLE Handle;\r
+ EFI_FTW_LITE_PROTOCOL FtwLiteInstance;\r
+ EFI_PHYSICAL_ADDRESS WorkSpaceAddress;\r
+ UINTN WorkSpaceLength;\r
+ EFI_PHYSICAL_ADDRESS SpareAreaAddress;\r
+ UINTN SpareAreaLength;\r
+ UINTN NumberOfSpareBlock; // Number of the blocks in spare block\r
+ UINTN SizeOfSpareBlock; // Block size in bytes of the blocks in spare block\r
+ EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FtwWorkSpaceHeader;\r
+ EFI_FTW_LITE_RECORD *FtwLastRecord;\r
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FtwFvBlock; // FVB of working block\r
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FtwBackupFvb; // FVB of spare block\r
+ EFI_LBA FtwSpareLba;\r
+ EFI_LBA FtwWorkBlockLba; // Start LBA of working block\r
+ EFI_LBA FtwWorkSpaceLba; // Start LBA of working space\r
+ UINTN FtwWorkSpaceBase; // Offset from LBA start addr\r
+ UINTN FtwWorkSpaceSize;\r
+ UINT8 *FtwWorkSpace;\r
+ //\r
+ // Following a buffer of FtwWorkSpace[FTW_WORK_SPACE_SIZE],\r
+ // Allocated with EFI_FTW_LITE_DEVICE.\r
+ //\r
+} EFI_FTW_LITE_DEVICE;\r
+\r
+#define FTW_LITE_CONTEXT_FROM_THIS(a) CR (a, EFI_FTW_LITE_DEVICE, FtwLiteInstance, FTW_LITE_DEVICE_SIGNATURE)\r
+\r
+//\r
+// Driver entry point\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeFtwLite (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ This function is the entry point of the Fault Tolerant Write driver.\r
+\r
+Arguments:\r
+ ImageHandle - EFI_HANDLE: A handle for the image that is initializing \r
+ this driver\r
+ SystemTable - EFI_SYSTEM_TABLE: A pointer to the EFI system table\r
+\r
+Returns:\r
+ EFI_SUCCESS - FTW has finished the initialization\r
+ EFI_ABORTED - FTW initialization error\r
+\r
+--*/\r
+;\r
+\r
+//\r
+// Fault Tolerant Write Protocol API\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+FtwLiteWrite (\r
+ IN EFI_FTW_LITE_PROTOCOL *This,\r
+ IN EFI_HANDLE FvbHandle,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN Offset,\r
+ IN UINTN *NumBytes,\r
+ IN VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Starts a target block update. This function will record data about write \r
+ in fault tolerant storage and will complete the write in a recoverable \r
+ manner, ensuring at all times that either the original contents or \r
+ the modified contents are available.\r
+\r
+Arguments:\r
+ This - Calling context\r
+ FvbHandle - The handle of FVB protocol that provides services for \r
+ reading, writing, and erasing the target block.\r
+ Lba - The logical block address of the target block. \r
+ Offset - The offset within the target block to place the data.\r
+ NumBytes - The number of bytes to write to the target block.\r
+ Buffer - The data to write.\r
+\r
+Returns:\r
+ EFI_SUCCESS - The function completed successfully\r
+ EFI_BAD_BUFFER_SIZE - The write would span a target block, which is not \r
+ a valid action.\r
+ EFI_ACCESS_DENIED - No writes have been allocated.\r
+ EFI_NOT_FOUND - Cannot find FVB by handle.\r
+ EFI_OUT_OF_RESOURCES - Cannot allocate memory.\r
+ EFI_ABORTED - The function could not complete successfully.\r
+\r
+--*/\r
+;\r
+\r
+//\r
+// Internal functions\r
+//\r
+EFI_STATUS\r
+FtwRestart (\r
+ IN EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Restarts a previously interrupted write. The caller must provide the \r
+ block protocol needed to complete the interrupted write.\r
+\r
+Arguments:\r
+ FtwLiteDevice - The private data of FTW_LITE driver\r
+ FvbHandle - The handle of FVB protocol that provides services for \r
+ reading, writing, and erasing the target block.\r
+\r
+Returns:\r
+ EFI_SUCCESS - The function completed successfully\r
+ EFI_ACCESS_DENIED - No pending writes exist\r
+ EFI_NOT_FOUND - FVB protocol not found by the handle\r
+ EFI_ABORTED - The function could not complete successfully\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+FtwAbort (\r
+ IN EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Aborts all previous allocated writes.\r
+\r
+Arguments:\r
+ FtwLiteDevice - The private data of FTW_LITE driver\r
+\r
+Returns:\r
+ EFI_SUCCESS - The function completed successfully\r
+ EFI_ABORTED - The function could not complete successfully.\r
+ EFI_NOT_FOUND - No allocated writes exist.\r
+\r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+FtwWriteRecord (\r
+ IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Write a record with fault tolerant mannaer.\r
+ Since the content has already backuped in spare block, the write is \r
+ guaranteed to be completed with fault tolerant manner.\r
+\r
+Arguments:\r
+ FtwLiteDevice - The private data of FTW_LITE driver\r
+ Fvb - The FVB protocol that provides services for \r
+ reading, writing, and erasing the target block.\r
+\r
+Returns:\r
+ EFI_SUCCESS - The function completed successfully\r
+ EFI_ABORTED - The function could not complete successfully\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+FtwEraseBlock (\r
+ IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
+ EFI_LBA Lba\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ To Erase one block. The size is FTW_BLOCK_SIZE\r
+\r
+Arguments:\r
+ FtwLiteDevice - Calling context\r
+ FvBlock - FVB Protocol interface\r
+ Lba - Lba of the firmware block\r
+\r
+Returns:\r
+ EFI_SUCCESS - Block LBA is Erased successfully\r
+ Others - Error occurs\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+FtwEraseSpareBlock (\r
+ IN EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Erase spare block.\r
+\r
+Arguments:\r
+\r
+ FtwLiteDevice - Calling context\r
+\r
+Returns:\r
+\r
+ Status code\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+FtwGetFvbByHandle (\r
+ IN EFI_HANDLE FvBlockHandle,\r
+ OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Retrive the proper FVB protocol interface by HANDLE.\r
+\r
+Arguments:\r
+ FvBlockHandle - The handle of FVB protocol that provides services for \r
+ reading, writing, and erasing the target block.\r
+ FvBlock - The interface of FVB protocol\r
+\r
+Returns:\r
+ EFI_SUCCESS - The function completed successfully\r
+ EFI_ABORTED - The function could not complete successfully\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+GetFvbByAddress (\r
+ IN EFI_PHYSICAL_ADDRESS Address,\r
+ OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get firmware block by address.\r
+\r
+Arguments:\r
+\r
+ Address - Address specified the block\r
+ FvBlock - The block caller wanted\r
+\r
+Returns:\r
+\r
+ Status code\r
+\r
+ EFI_NOT_FOUND - Block not found\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsInWorkingBlock (\r
+ EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
+ EFI_LBA Lba\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Is it in working block?\r
+\r
+Arguments:\r
+\r
+ FtwLiteDevice - Calling context\r
+ FvBlock - Fvb protocol instance\r
+ Lba - The block specified\r
+\r
+Returns:\r
+\r
+ In working block or not\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsBootBlock (\r
+ EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
+ EFI_LBA Lba\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check whether the block is a boot block.\r
+\r
+Arguments:\r
+\r
+ FtwLiteDevice - Calling context\r
+ FvBlock - Fvb protocol instance\r
+ Lba - Lba value\r
+\r
+Returns:\r
+\r
+ Is a boot block or not\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+FlushSpareBlockToTargetBlock (\r
+ EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
+ EFI_LBA Lba\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Copy the content of spare block to a target block. Size is FTW_BLOCK_SIZE.\r
+ Spare block is accessed by FTW backup FVB protocol interface. LBA is \r
+ FtwLiteDevice->FtwSpareLba.\r
+ Target block is accessed by FvBlock protocol interface. LBA is Lba.\r
+\r
+Arguments:\r
+ FtwLiteDevice - The private data of FTW_LITE driver\r
+ FvBlock - FVB Protocol interface to access target block\r
+ Lba - Lba of the target block\r
+\r
+Returns:\r
+ EFI_SUCCESS - Spare block content is copied to target block\r
+ EFI_INVALID_PARAMETER - Input parameter error\r
+ EFI_OUT_OF_RESOURCES - Allocate memory error\r
+ EFI_ABORTED - The function could not complete successfully\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+FlushSpareBlockToWorkingBlock (\r
+ EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Copy the content of spare block to working block. Size is FTW_BLOCK_SIZE.\r
+ Spare block is accessed by FTW backup FVB protocol interface. LBA is \r
+ FtwLiteDevice->FtwSpareLba.\r
+ Working block is accessed by FTW working FVB protocol interface. LBA is \r
+ FtwLiteDevice->FtwWorkBlockLba.\r
+\r
+Arguments:\r
+ FtwLiteDevice - The private data of FTW_LITE driver\r
+\r
+Returns:\r
+ EFI_SUCCESS - Spare block content is copied to target block\r
+ EFI_OUT_OF_RESOURCES - Allocate memory error\r
+ EFI_ABORTED - The function could not complete successfully\r
+\r
+Notes:\r
+ Since the working block header is important when FTW initializes, the \r
+ state of the operation should be handled carefully. The Crc value is \r
+ calculated without STATE element. \r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+FlushSpareBlockToBootBlock (\r
+ EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE.\r
+ Spare block is accessed by FTW backup FVB protocol interface. LBA is \r
+ FtwLiteDevice->FtwSpareLba.\r
+ Boot block is accessed by BootFvb protocol interface. LBA is 0.\r
+\r
+Arguments:\r
+ FtwLiteDevice - The private data of FTW_LITE driver\r
+\r
+Returns:\r
+ EFI_SUCCESS - Spare block content is copied to boot block\r
+ EFI_INVALID_PARAMETER - Input parameter error\r
+ EFI_OUT_OF_RESOURCES - Allocate memory error\r
+ EFI_ABORTED - The function could not complete successfully\r
+\r
+Notes:\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+FtwUpdateFvState (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN Offset,\r
+ IN UINT8 NewBit\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Update a bit of state on a block device. The location of the bit is \r
+ calculated by the (Lba, Offset, bit). Here bit is determined by the \r
+ the name of a certain bit.\r
+\r
+Arguments:\r
+ FvBlock - FVB Protocol interface to access SrcBlock and DestBlock\r
+ Lba - Lba of a block\r
+ Offset - Offset on the Lba\r
+ NewBit - New value that will override the old value if it can be change\r
+\r
+Returns:\r
+ EFI_SUCCESS - A state bit has been updated successfully\r
+ Others - Access block device error.\r
+\r
+Notes:\r
+ Assume all bits of State are inside the same BYTE. \r
+\r
+ EFI_ABORTED - Read block fail\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+FtwGetLastRecord (\r
+ IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
+ OUT EFI_FTW_LITE_RECORD **FtwLastRecord\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Get the last Write record pointer. \r
+ The last record is the record whose 'complete' state hasn't been set.\r
+ After all, this header may be a EMPTY header entry for next Allocate. \r
+\r
+Arguments:\r
+ FtwLiteDevice - Private data of this driver\r
+ FtwLastRecord - Pointer to retrieve the last write record\r
+\r
+Returns:\r
+ EFI_SUCCESS - Get the last write record successfully\r
+ EFI_ABORTED - The FTW work space is damaged\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsErasedFlashBuffer (\r
+ IN BOOLEAN Polarity,\r
+ IN UINT8 *Buffer,\r
+ IN UINTN BufferSize\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check whether a flash buffer is erased.\r
+\r
+Arguments:\r
+\r
+ Polarity - All 1 or all 0\r
+ Buffer - Buffer to check\r
+ BufferSize - Size of the buffer\r
+\r
+Returns:\r
+\r
+ Erased or not.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+InitWorkSpaceHeader (\r
+ IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Initialize a work space when there is no work space.\r
+\r
+Arguments:\r
+ WorkingHeader - Pointer of working block header \r
+\r
+Returns:\r
+ EFI_SUCCESS - The function completed successfully\r
+ EFI_ABORTED - The function could not complete successfully.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WorkSpaceRefresh (\r
+ IN EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Read from working block to refresh the work space in memory.\r
+\r
+Arguments:\r
+ FtwLiteDevice - Point to private data of FTW driver\r
+\r
+Returns:\r
+ EFI_SUCCESS - The function completed successfully\r
+ EFI_ABORTED - The function could not complete successfully.\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsValidWorkSpace (\r
+ IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Check to see if it is a valid work space.\r
+\r
+Arguments:\r
+ WorkingHeader - Pointer of working block header \r
+\r
+Returns:\r
+ EFI_SUCCESS - The function completed successfully\r
+ EFI_ABORTED - The function could not complete successfully.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CleanupWorkSpace (\r
+ IN EFI_FTW_LITE_DEVICE *FtwLiteDevice,\r
+ IN OUT UINT8 *BlockBuffer,\r
+ IN UINTN BufferSize\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Reclaim the work space. Get rid of all the completed write records\r
+ and write records in the Fault Tolerant work space.\r
+\r
+Arguments:\r
+ FtwLiteDevice - Point to private data of FTW driver\r
+ FtwSpaceBuffer - Buffer to contain the reclaimed clean data\r
+ BufferSize - Size of the FtwSpaceBuffer\r
+\r
+Returns:\r
+ EFI_SUCCESS - The function completed successfully\r
+ EFI_BUFFER_TOO_SMALL - The FtwSpaceBuffer is too small\r
+ EFI_ABORTED - The function could not complete successfully.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+FtwReclaimWorkSpace (\r
+ IN EFI_FTW_LITE_DEVICE *FtwLiteDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Reclaim the work space on the working block.\r
+\r
+Arguments:\r
+ FtwLiteDevice - Point to private data of FTW driver\r
+\r
+Returns:\r
+ EFI_SUCCESS - The function completed successfully\r
+ EFI_OUT_OF_RESOURCES - Allocate memory error\r
+ EFI_ABORTED - The function could not complete successfully\r
+\r
+--*/\r
+;\r
+\r
+#endif\r