]> git.proxmox.com Git - mirror_edk2.git/blobdiff - FatPkg/EnhancedFatDxe/ReadWrite.c
EFI_FILE_PROTOCOL spec conformance bug fix.
[mirror_edk2.git] / FatPkg / EnhancedFatDxe / ReadWrite.c
index 956db27a8677d39416db30e091a8c58abbef3ef7..9afb6bff89e06f4f7bf4354cd3321c98f1c28296 100644 (file)
@@ -1,7 +1,7 @@
 /*++\r
 \r
-Copyright (c) 2005 - 2009, Intel Corporation\r
-All rights reserved. This program and the accompanying materials are licensed and made available\r
+Copyright (c) 2005 - 2015, 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
 http://opensource.org/licenses/bsd-license.php\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
@@ -117,7 +120,7 @@ Returns:
   //\r
   // Set the position\r
   //\r
-  if (Position == -1) {\r
+  if (Position == (UINT64)-1) {\r
     Position = OFile->FileSize;\r
   }\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,19 @@ 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
+  //\r
+  // Write to a directory is unsupported\r
+  //\r
+  if ((OFile->ODir != NULL) && (IoMode == WRITE_DATA)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
 \r
   if (OFile->Error == EFI_NOT_FOUND) {\r
     return EFI_DEVICE_ERROR;\r
@@ -267,22 +281,32 @@ 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
   if (!EFI_ERROR (Status)) {\r
     if (OFile->ODir != NULL) {\r
       //\r
-      // Access a directory\r
+      // Read a directory is supported\r
       //\r
-      Status = EFI_UNSUPPORTED;\r
-      if (IoMode == READ_DATA) {\r
-        //\r
-        // Read a directory is supported\r
-        //\r
-        Status = FatIFileReadDir (IFile, BufferSize, Buffer);\r
-      }\r
-\r
+      ASSERT (IoMode == READ_DATA);\r
+      Status = FatIFileReadDir (IFile, BufferSize, Buffer);\r
       OFile = NULL;\r
     } else {\r
       //\r
@@ -318,15 +342,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 +365,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 +401,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 +464,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 +502,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 +553,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 +664,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