]> git.proxmox.com Git - mirror_edk2.git/blobdiff - FatPkg/EnhancedFatDxe/ReadWrite.c
Change Fat driver to support asynchronous File IO introduced in UEFI spec 2.3.1.D.
[mirror_edk2.git] / FatPkg / EnhancedFatDxe / ReadWrite.c
index 8c41bd5788288666de8f63e978321fe7fda294ea..4621817c93d2562490142c6b3a7502f8d4be8cce 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials are licensed and made available\r
 under the terms and conditions of the BSD License which accompanies this\r
 distribution. The full text of the license may be found at\r
@@ -101,6 +101,9 @@ Returns:
   if (OFile->Error == EFI_NOT_FOUND) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
+\r
+  FatWaitNonblockingTask (IFile);\r
+\r
   //\r
   // If this is a directory, we can only set back to position 0\r
   //\r
@@ -207,7 +210,8 @@ FatIFileAccess (
   IN     EFI_FILE_PROTOCOL     *FHand,\r
   IN     IO_MODE               IoMode,\r
   IN OUT UINTN                 *BufferSize,\r
-  IN OUT VOID                  *Buffer\r
+  IN OUT VOID                  *Buffer,\r
+  IN     EFI_FILE_IO_TOKEN     *Token\r
   )\r
 /*++\r
 \r
@@ -221,6 +225,7 @@ Arguments:
   IoMode                - Indicate whether the access mode is reading or writing.\r
   BufferSize            - Size of Buffer.\r
   Buffer                - Buffer containing read data.\r
+  Token                 - A pointer to the token associated with the transaction.\r
 \r
 Returns:\r
 \r
@@ -238,10 +243,12 @@ Returns:
   FAT_OFILE   *OFile;\r
   FAT_VOLUME  *Volume;\r
   UINT64      EndPosition;\r
+  FAT_TASK    *Task;\r
 \r
   IFile  = IFILE_FROM_FHAND (FHand);\r
   OFile  = IFile->OFile;\r
   Volume = OFile->Volume;\r
+  Task   = NULL;\r
 \r
   if (OFile->Error == EFI_NOT_FOUND) {\r
     return EFI_DEVICE_ERROR;\r
@@ -267,6 +274,22 @@ Returns:
     }\r
   }\r
 \r
+  if (Token == NULL) {\r
+    FatWaitNonblockingTask (IFile);\r
+  } else {\r
+    //\r
+    // Caller shouldn't call the non-blocking interfaces if the low layer doesn't support DiskIo2.\r
+    // But if it calls, the below check can avoid crash.\r
+    //\r
+    if (FHand->Revision < EFI_FILE_PROTOCOL_REVISION2) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+    Task = FatCreateTask (IFile, Token);\r
+    if (Task == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+  }\r
+\r
   FatAcquireLock ();\r
 \r
   Status = OFile->Error;\r
@@ -318,15 +341,20 @@ Returns:
         }\r
       }\r
 \r
-      Status = FatAccessOFile (OFile, IoMode, (UINTN) IFile->Position, BufferSize, Buffer);\r
+      Status = FatAccessOFile (OFile, IoMode, (UINTN) IFile->Position, BufferSize, Buffer, Task);\r
       IFile->Position += *BufferSize;\r
     }\r
   }\r
 \r
-Done:\r
-  if (EFI_ERROR (Status)) {\r
-    Status = FatCleanupVolume (Volume, OFile, Status);\r
+  if (Token != NULL) {\r
+    if (!EFI_ERROR (Status)) {\r
+      Status = FatQueueTask (IFile, Task);\r
+    } else {\r
+      FatDestroyTask (Task);\r
+    }\r
   }\r
+\r
+Done:\r
   //\r
   // On EFI_SUCCESS case, not calling FatCleanupVolume():\r
   // 1) The Cache flush operation is avoided to enhance\r
@@ -336,6 +364,10 @@ Done:
   // 3) Write operation doesn't affect OFile/IFile structure, so\r
   // Reference checking is not necessary.\r
   //\r
+  if (EFI_ERROR (Status)) {\r
+    Status = FatCleanupVolume (Volume, OFile, Status, NULL);\r
+  }\r
+\r
   FatReleaseLock ();\r
   return Status;\r
 }\r
@@ -368,7 +400,36 @@ Returns:
 \r
 --*/\r
 {\r
-  return FatIFileAccess (FHand, READ_DATA, BufferSize, Buffer);\r
+  return FatIFileAccess (FHand, READ_DATA, BufferSize, Buffer, NULL);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FatReadEx (\r
+  IN     EFI_FILE_PROTOCOL  *FHand,\r
+  IN OUT EFI_FILE_IO_TOKEN  *Token\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get the file info.\r
+\r
+Arguments:\r
+\r
+  FHand                 - The handle of the file.\r
+  Token                 - A pointer to the token associated with the transaction.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - Get the file info successfully.\r
+  EFI_DEVICE_ERROR      - Can not find the OFile for the file.\r
+  EFI_VOLUME_CORRUPTED  - The file type of open file is error.\r
+  other                 - An error occurred when operation the disk.\r
+\r
+--*/\r
+{\r
+  return FatIFileAccess (FHand, READ_DATA, &Token->BufferSize, Token->Buffer, Token);\r
 }\r
 \r
 EFI_STATUS\r
@@ -402,7 +463,36 @@ Returns:
 \r
 --*/\r
 {\r
-  return FatIFileAccess (FHand, WRITE_DATA, BufferSize, Buffer);\r
+  return FatIFileAccess (FHand, WRITE_DATA, BufferSize, Buffer, NULL);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FatWriteEx (\r
+  IN     EFI_FILE_PROTOCOL  *FHand,\r
+  IN OUT EFI_FILE_IO_TOKEN  *Token\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get the file info.\r
+\r
+Arguments:\r
+\r
+  FHand                 - The handle of the file.\r
+  Token                 - A pointer to the token associated with the transaction.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - Get the file info successfully.\r
+  EFI_DEVICE_ERROR      - Can not find the OFile for the file.\r
+  EFI_VOLUME_CORRUPTED  - The file type of open file is error.\r
+  other                 - An error occurred when operation the disk.\r
+\r
+--*/\r
+{\r
+  return FatIFileAccess (FHand, WRITE_DATA, &Token->BufferSize, Token->Buffer, Token);\r
 }\r
 \r
 EFI_STATUS\r
@@ -411,7 +501,8 @@ FatAccessOFile (
   IN     IO_MODE        IoMode,\r
   IN     UINTN          Position,\r
   IN OUT UINTN          *DataBufferSize,\r
-  IN OUT UINT8          *UserBuffer\r
+  IN OUT UINT8          *UserBuffer,\r
+  IN FAT_TASK           *Task\r
   )\r
 /*++\r
 \r
@@ -461,7 +552,7 @@ Returns:
     //\r
     // Write the data\r
     //\r
-    Status = FatDiskIo (Volume, IoMode, OFile->PosDisk, Len, UserBuffer);\r
+    Status = FatDiskIo (Volume, IoMode, OFile->PosDisk, Len, UserBuffer, Task);\r
     if (EFI_ERROR (Status)) {\r
       break;\r
     }\r
@@ -572,7 +663,7 @@ Returns:
   do {\r
     WriteSize     = AppendedSize > BufferSize ? BufferSize : (UINTN) AppendedSize;\r
     AppendedSize -= WriteSize;\r
-    Status = FatAccessOFile (OFile, WRITE_DATA, WritePos, &WriteSize, ZeroBuffer);\r
+    Status = FatAccessOFile (OFile, WRITE_DATA, WritePos, &WriteSize, ZeroBuffer, NULL);\r
     if (EFI_ERROR (Status)) {\r
       break;\r
     }\r