summaryrefslogtreecommitdiffstats
path: root/FatPkg
diff options
context:
space:
mode:
authorRuiyu Ni <ruiyu.ni@intel.com>2013-10-30 03:13:16 +0000
committerJordan Justen <jordan.l.justen@intel.com>2016-04-06 23:22:43 -0700
commit149d633529cc3105474f392215cc188741fb6617 (patch)
tree29b4f5d64fa95b1bbe04f44ac2b4cdad62a9519a /FatPkg
parent04a4fdb99f28e320ca0922f2ad1182702454ae22 (diff)
downloadedk2-149d633529cc3105474f392215cc188741fb6617.tar.gz
edk2-149d633529cc3105474f392215cc188741fb6617.tar.bz2
edk2-149d633529cc3105474f392215cc188741fb6617.zip
Change Fat driver to support asynchronous File IO introduced in UEFI spec 2.3.1.D.
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Reviewed-by: Feng Tian <feng.tian@intel.com> (based on FatPkg commit 063f6e8a9c263bafd52e1226399fc64d6d721dca) [jordan.l.justen@intel.com: Use script to relicense to 2-clause BSD] Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jordan Justen <jordan.l.justen@intel.com> Acked-by: Mark Doran <mark.doran@intel.com> Acked-by: Laszlo Ersek <lersek@redhat.com>
Diffstat (limited to 'FatPkg')
-rw-r--r--FatPkg/EnhancedFatDxe/Data.c12
-rw-r--r--FatPkg/EnhancedFatDxe/Delete.c6
-rw-r--r--FatPkg/EnhancedFatDxe/DirectoryManage.c4
-rw-r--r--FatPkg/EnhancedFatDxe/DiskCache.c21
-rw-r--r--FatPkg/EnhancedFatDxe/Fat.c30
-rw-r--r--FatPkg/EnhancedFatDxe/Fat.h188
-rw-r--r--FatPkg/EnhancedFatDxe/Fat.inf3
-rw-r--r--FatPkg/EnhancedFatDxe/FileSpace.c8
-rw-r--r--FatPkg/EnhancedFatDxe/Flush.c76
-rw-r--r--FatPkg/EnhancedFatDxe/Info.c6
-rw-r--r--FatPkg/EnhancedFatDxe/Init.c8
-rw-r--r--FatPkg/EnhancedFatDxe/Misc.c337
-rw-r--r--FatPkg/EnhancedFatDxe/Open.c99
-rw-r--r--FatPkg/EnhancedFatDxe/OpenVolume.c4
-rw-r--r--FatPkg/EnhancedFatDxe/ReadWrite.c113
15 files changed, 839 insertions, 76 deletions
diff --git a/FatPkg/EnhancedFatDxe/Data.c b/FatPkg/EnhancedFatDxe/Data.c
index 93909ac25b..b20cc4592d 100644
--- a/FatPkg/EnhancedFatDxe/Data.c
+++ b/FatPkg/EnhancedFatDxe/Data.c
@@ -1,6 +1,6 @@
/*++
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2013, 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
@@ -30,7 +30,9 @@ Revision History
//
// FatFsLock - Global lock for synchronizing all requests.
//
-EFI_LOCK FatFsLock = EFI_INITIALIZE_LOCK_VARIABLE(TPL_CALLBACK);
+EFI_LOCK FatFsLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_CALLBACK);
+
+EFI_LOCK FatTaskLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
//
// Filesystem interface functions
@@ -46,5 +48,9 @@ EFI_FILE_PROTOCOL FatFileInterface = {
FatSetPosition,
FatGetInfo,
FatSetInfo,
- FatFlush
+ FatFlush,
+ FatOpenEx,
+ FatReadEx,
+ FatWriteEx,
+ FatFlushEx
};
diff --git a/FatPkg/EnhancedFatDxe/Delete.c b/FatPkg/EnhancedFatDxe/Delete.c
index f39913ec00..e5103a850c 100644
--- a/FatPkg/EnhancedFatDxe/Delete.c
+++ b/FatPkg/EnhancedFatDxe/Delete.c
@@ -1,6 +1,6 @@
/*++
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2013, 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
@@ -55,6 +55,8 @@ Returns:
IFile = IFILE_FROM_FHAND (FHand);
OFile = IFile->OFile;
+ FatWaitNonblockingTask (IFile);
+
//
// Lock the volume
//
@@ -127,7 +129,7 @@ Done:
//
// Done
//
- Status = FatCleanupVolume (OFile->Volume, NULL, Status);
+ Status = FatCleanupVolume (OFile->Volume, NULL, Status, NULL);
FatReleaseLock ();
if (EFI_ERROR (Status)) {
diff --git a/FatPkg/EnhancedFatDxe/DirectoryManage.c b/FatPkg/EnhancedFatDxe/DirectoryManage.c
index cae6718734..116f87a4c2 100644
--- a/FatPkg/EnhancedFatDxe/DirectoryManage.c
+++ b/FatPkg/EnhancedFatDxe/DirectoryManage.c
@@ -1,6 +1,6 @@
/*++
-Copyright (c) 2005 - 2007, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2013, 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
@@ -67,7 +67,7 @@ Returns:
}
BufferSize = sizeof (FAT_DIRECTORY_ENTRY);
- return FatAccessOFile (Parent, IoMode, Position, &BufferSize, Entry);
+ return FatAccessOFile (Parent, IoMode, Position, &BufferSize, Entry, NULL);
}
EFI_STATUS
diff --git a/FatPkg/EnhancedFatDxe/DiskCache.c b/FatPkg/EnhancedFatDxe/DiskCache.c
index 9f527289a8..ddf99edf91 100644
--- a/FatPkg/EnhancedFatDxe/DiskCache.c
+++ b/FatPkg/EnhancedFatDxe/DiskCache.c
@@ -1,6 +1,6 @@
/*++
-Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2013, 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
@@ -109,7 +109,8 @@ FatExchangeCachePage (
IN FAT_VOLUME *Volume,
IN CACHE_DATA_TYPE DataType,
IN IO_MODE IoMode,
- IN CACHE_TAG *CacheTag
+ IN CACHE_TAG *CacheTag,
+ IN FAT_TASK *Task
)
/*++
@@ -167,7 +168,7 @@ Returns:
//
// Only fat table writing will execute more than once
//
- Status = FatDiskIo (Volume, IoMode, EntryPos, RealSize, PageAddress);
+ Status = FatDiskIo (Volume, IoMode, EntryPos, RealSize, PageAddress, Task);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -223,7 +224,7 @@ Returns:
// Write dirty cache page back to disk
//
if (CacheTag->RealSize > 0 && CacheTag->Dirty) {
- Status = FatExchangeCachePage (Volume, CacheDataType, WRITE_DISK, CacheTag);
+ Status = FatExchangeCachePage (Volume, CacheDataType, WRITE_DISK, CacheTag, NULL);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -232,7 +233,7 @@ Returns:
// Load new data from disk;
//
CacheTag->PageNo = PageNo;
- Status = FatExchangeCachePage (Volume, CacheDataType, READ_DISK, CacheTag);
+ Status = FatExchangeCachePage (Volume, CacheDataType, READ_DISK, CacheTag, NULL);
return Status;
}
@@ -305,7 +306,8 @@ FatAccessCache (
IN IO_MODE IoMode,
IN UINT64 Offset,
IN UINTN BufferSize,
- IN OUT UINT8 *Buffer
+ IN OUT UINT8 *Buffer,
+ IN FAT_TASK *Task
)
/*++
Routine Description:
@@ -393,7 +395,7 @@ Returns:
EntryPos = Volume->RootPos + LShiftU64 (PageNo, PageAlignment);
AlignedSize = AlignedPageCount << PageAlignment;
- Status = FatDiskIo (Volume, IoMode, EntryPos, AlignedSize, Buffer);
+ Status = FatDiskIo (Volume, IoMode, EntryPos, AlignedSize, Buffer, Task);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -421,7 +423,8 @@ Returns:
EFI_STATUS
FatVolumeFlushCache (
- IN FAT_VOLUME *Volume
+ IN FAT_VOLUME *Volume,
+ IN FAT_TASK *Task
)
/*++
@@ -460,7 +463,7 @@ Returns:
//
// Write back all Dirty Data Cache Page to disk
//
- Status = FatExchangeCachePage (Volume, CacheDataType, WRITE_DISK, CacheTag);
+ Status = FatExchangeCachePage (Volume, CacheDataType, WRITE_DISK, CacheTag, Task);
if (EFI_ERROR (Status)) {
return Status;
}
diff --git a/FatPkg/EnhancedFatDxe/Fat.c b/FatPkg/EnhancedFatDxe/Fat.c
index 38b70882c5..a52e6ea828 100644
--- a/FatPkg/EnhancedFatDxe/Fat.c
+++ b/FatPkg/EnhancedFatDxe/Fat.c
@@ -1,6 +1,6 @@
/*++
-Copyright (c) 2005 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2013, 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
@@ -269,6 +269,7 @@ Returns:
EFI_STATUS Status;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_DISK_IO_PROTOCOL *DiskIo;
+ EFI_DISK_IO2_PROTOCOL *DiskIo2;
BOOLEAN LockedByMe;
LockedByMe = FALSE;
@@ -311,11 +312,24 @@ Returns:
if (EFI_ERROR (Status)) {
goto Exit;
}
+
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiDiskIo2ProtocolGuid,
+ (VOID **) &DiskIo2,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ DiskIo2 = NULL;
+ }
+
//
// Allocate Volume structure. In FatAllocateVolume(), Resources
// are allocated with protocol installed and cached initialized
//
- Status = FatAllocateVolume (ControllerHandle, DiskIo, BlockIo);
+ Status = FatAllocateVolume (ControllerHandle, DiskIo, DiskIo2, BlockIo);
//
// When the media changes on a device it will Reinstall the BlockIo interaface.
@@ -338,6 +352,12 @@ Returns:
This->DriverBindingHandle,
ControllerHandle
);
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiDiskIo2ProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
}
}
@@ -406,6 +426,12 @@ Returns:
This->DriverBindingHandle,
ControllerHandle
);
+ Status = gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiDiskIo2ProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
return Status;
}
diff --git a/FatPkg/EnhancedFatDxe/Fat.h b/FatPkg/EnhancedFatDxe/Fat.h
index 3bc1e71ba5..6e6010dc50 100644
--- a/FatPkg/EnhancedFatDxe/Fat.h
+++ b/FatPkg/EnhancedFatDxe/Fat.h
@@ -1,6 +1,6 @@
/*++
-Copyright (c) 2005 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2013, 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
@@ -32,6 +32,7 @@ Revision History
#include <Guid/FileSystemVolumeLabelInfo.h>
#include <Protocol/BlockIo.h>
#include <Protocol/DiskIo.h>
+#include <Protocol/DiskIo2.h>
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/UnicodeCollation.h>
@@ -55,6 +56,8 @@ Revision History
#define FAT_ODIR_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'd')
#define FAT_DIRENT_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'e')
#define FAT_OFILE_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'o')
+#define FAT_TASK_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'T')
+#define FAT_SUBTASK_SIGNATURE SIGNATURE_32 ('f', 'a', 't', 'S')
#define ASSERT_VOLUME_LOCKED(a) ASSERT_LOCKED (&FatFsLock)
@@ -213,9 +216,29 @@ typedef struct {
UINT64 Position;
BOOLEAN ReadOnly;
struct _FAT_OFILE *OFile;
- LIST_ENTRY Link;
+ LIST_ENTRY Tasks; // List of all FAT_TASKs
+ LIST_ENTRY Link; // Link to other IFiles
} FAT_IFILE;
+typedef struct {
+ UINTN Signature;
+ EFI_FILE_IO_TOKEN *FileIoToken;
+ FAT_IFILE *IFile;
+ LIST_ENTRY Subtasks; // List of all FAT_SUBTASKs
+ LIST_ENTRY Link; // Link to other FAT_TASKs
+} FAT_TASK;
+
+typedef struct {
+ UINTN Signature;
+ EFI_DISK_IO2_TOKEN DiskIo2Token;
+ FAT_TASK *Task;
+ BOOLEAN Write;
+ UINT64 Offset;
+ VOID *Buffer;
+ UINTN BufferSize;
+ LIST_ENTRY Link;
+} FAT_SUBTASK;
+
//
// FAT_OFILE - Each opened file
//
@@ -296,6 +319,7 @@ typedef struct _FAT_VOLUME {
//
EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_DISK_IO_PROTOCOL *DiskIo;
+ EFI_DISK_IO2_PROTOCOL *DiskIo2;
UINT32 MediaId;
BOOLEAN ReadOnly;
@@ -401,6 +425,41 @@ Returns:
;
EFI_STATUS
+FatOpenEx (
+ IN EFI_FILE_PROTOCOL *FHand,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes,
+ IN OUT EFI_FILE_IO_TOKEN *Token
+ )
+/*++
+Routine Description:
+
+ Implements OpenEx() of Simple File System Protocol.
+
+Arguments:
+
+ FHand - File handle of the file serves as a starting reference point.
+ NewHandle - Handle of the file that is newly opened.
+ FileName - File name relative to FHand.
+ OpenMode - Open mode.
+ Attributes - Attributes to set if the file is created.
+ Token - A pointer to the token associated with the transaction.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
+ The OpenMode is not supported.
+ The Attributes is not the valid attributes.
+ EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.
+ EFI_SUCCESS - Open the file successfully.
+ Others - The status of open file.
+
+--*/
+;
+
+EFI_STATUS
EFIAPI
FatGetPosition (
IN EFI_FILE_PROTOCOL *FHand,
@@ -512,6 +571,33 @@ Returns:
EFI_STATUS
EFIAPI
+FatFlushEx (
+ IN EFI_FILE_PROTOCOL *FHand,
+ IN EFI_FILE_IO_TOKEN *Token
+ )
+/*++
+
+Routine Description:
+
+ Flushes all data associated with the file handle.
+
+Arguments:
+
+ FHand - Handle to file to flush.
+ Token - A pointer to the token associated with the transaction.
+
+Returns:
+
+ EFI_SUCCESS - Flushed the file successfully.
+ EFI_WRITE_PROTECTED - The volume is read only.
+ EFI_ACCESS_DENIED - The file is read only.
+ Others - Flushing of the file failed.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
FatClose (
IN EFI_FILE_PROTOCOL *FHand
)
@@ -612,6 +698,33 @@ Returns:
EFI_STATUS
EFIAPI
+FatReadEx (
+ IN EFI_FILE_PROTOCOL *FHand,
+ IN OUT EFI_FILE_IO_TOKEN *Token
+ )
+/*++
+
+Routine Description:
+
+ Get the file info.
+
+Arguments:
+
+ FHand - The handle of the file.
+ Token - A pointer to the token associated with the transaction.
+
+Returns:
+
+ EFI_SUCCESS - Get the file info successfully.
+ EFI_DEVICE_ERROR - Can not find the OFile for the file.
+ EFI_VOLUME_CORRUPTED - The file type of open file is error.
+ other - An error occurred when operation the disk.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
FatWrite (
IN EFI_FILE_PROTOCOL *FHand,
IN OUT UINTN *BufferSize,
@@ -642,6 +755,33 @@ Returns:
--*/
;
+EFI_STATUS
+EFIAPI
+FatWriteEx (
+ IN EFI_FILE_PROTOCOL *FHand,
+ IN OUT EFI_FILE_IO_TOKEN *Token
+ )
+/*++
+
+Routine Description:
+
+ Get the file info.
+
+Arguments:
+
+ FHand - The handle of the file.
+ Token - A pointer to the token associated with the transaction.
+
+Returns:
+
+ EFI_SUCCESS - Get the file info successfully.
+ EFI_DEVICE_ERROR - Can not find the OFile for the file.
+ EFI_VOLUME_CORRUPTED - The file type of open file is error.
+ other - An error occurred when operation the disk.
+
+--*/
+;
+
//
// DiskCache.c
//
@@ -657,12 +797,14 @@ FatAccessCache (
IN IO_MODE IoMode,
IN UINT64 Offset,
IN UINTN BufferSize,
- IN OUT UINT8 *Buffer
+ IN OUT UINT8 *Buffer,
+ IN FAT_TASK *Task
);
EFI_STATUS
FatVolumeFlushCache (
- IN FAT_VOLUME *Volume
+ IN FAT_VOLUME *Volume,
+ IN FAT_TASK *Task
);
//
@@ -693,7 +835,8 @@ EFI_STATUS
FatCleanupVolume (
IN FAT_VOLUME *Volume,
IN FAT_OFILE *OFile,
- IN EFI_STATUS EfiStatus
+ IN EFI_STATUS EfiStatus,
+ IN FAT_TASK *Task
);
//
@@ -741,6 +884,7 @@ EFI_STATUS
FatAllocateVolume (
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_DISK_IO2_PROTOCOL *DiskIo2,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo
);
@@ -757,6 +901,33 @@ FatAbandonVolume (
//
// Misc.c
//
+FAT_TASK *
+FatCreateTask (
+ FAT_IFILE *IFile,
+ EFI_FILE_IO_TOKEN *Token
+ );
+
+VOID
+FatDestroyTask (
+ FAT_TASK *Task
+ );
+
+VOID
+FatWaitNonblockingTask (
+ FAT_IFILE *IFile
+ );
+
+LIST_ENTRY *
+FatDestroySubtask (
+ FAT_SUBTASK *Subtask
+ );
+
+EFI_STATUS
+FatQueueTask (
+ IN FAT_IFILE *IFile,
+ IN FAT_TASK *Task
+ );
+
EFI_STATUS
FatAccessVolumeDirty (
IN FAT_VOLUME *Volume,
@@ -770,7 +941,8 @@ FatDiskIo (
IN IO_MODE IoMode,
IN UINT64 Offset,
IN UINTN BufferSize,
- IN OUT VOID *Buffer
+ IN OUT VOID *Buffer,
+ IN FAT_TASK *Task
);
VOID
@@ -895,7 +1067,8 @@ FatAccessOFile (
IN IO_MODE IoMode,
IN UINTN Position,
IN UINTN *DataBufferSize,
- IN UINT8 *UserBuffer
+ IN UINT8 *UserBuffer,
+ IN FAT_TASK *Task
);
EFI_STATUS
@@ -1113,6 +1286,7 @@ extern EFI_DRIVER_BINDING_PROTOCOL gFatDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gFatComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gFatComponentName2;
extern EFI_LOCK FatFsLock;
+extern EFI_LOCK FatTaskLock;
extern EFI_FILE_PROTOCOL FatFileInterface;
#endif
diff --git a/FatPkg/EnhancedFatDxe/Fat.inf b/FatPkg/EnhancedFatDxe/Fat.inf
index 82b76508ae..79cf0cd3eb 100644
--- a/FatPkg/EnhancedFatDxe/Fat.inf
+++ b/FatPkg/EnhancedFatDxe/Fat.inf
@@ -4,7 +4,7 @@
# This UEFI driver detects the FAT file system in the disk.
# It also produces the Simple File System protocol for the consumer to
# perform file and directory operations on the disk.
-# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2013, 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
@@ -80,6 +80,7 @@
[Protocols]
gEfiDiskIoProtocolGuid
+ gEfiDiskIo2ProtocolGuid
gEfiBlockIoProtocolGuid
gEfiSimpleFileSystemProtocolGuid
gEfiUnicodeCollationProtocolGuid
diff --git a/FatPkg/EnhancedFatDxe/FileSpace.c b/FatPkg/EnhancedFatDxe/FileSpace.c
index 869f345f5c..ce7c067a4a 100644
--- a/FatPkg/EnhancedFatDxe/FileSpace.c
+++ b/FatPkg/EnhancedFatDxe/FileSpace.c
@@ -1,6 +1,6 @@
/*++
-Copyright (c) 2005, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2013, 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
@@ -79,7 +79,8 @@ Returns:
READ_FAT,
Volume->FatEntryPos,
Volume->FatEntrySize,
- &Volume->FatEntryBuffer
+ &Volume->FatEntryBuffer,
+ NULL
);
if (EFI_ERROR (Status)) {
Volume->FatEntryBuffer = (UINT32) -1;
@@ -246,7 +247,8 @@ Returns:
WRITE_FAT,
Volume->FatEntryPos,
Volume->FatEntrySize,
- &Volume->FatEntryBuffer
+ &Volume->FatEntryBuffer,
+ NULL
);
return Status;
}
diff --git a/FatPkg/EnhancedFatDxe/Flush.c b/FatPkg/EnhancedFatDxe/Flush.c
index ad3b261703..2c960f3b99 100644
--- a/FatPkg/EnhancedFatDxe/Flush.c
+++ b/FatPkg/EnhancedFatDxe/Flush.c
@@ -1,6 +1,6 @@
/*++
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2013, 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
@@ -26,8 +26,9 @@ Revision History
EFI_STATUS
EFIAPI
-FatFlush (
- IN EFI_FILE_PROTOCOL *FHand
+FatFlushEx (
+ IN EFI_FILE_PROTOCOL *FHand,
+ IN EFI_FILE_IO_TOKEN *Token
)
/*++
@@ -38,6 +39,7 @@ Routine Description:
Arguments:
FHand - Handle to file to flush.
+ Token - A pointer to the token associated with the transaction.
Returns:
@@ -52,10 +54,12 @@ Returns:
FAT_OFILE *OFile;
FAT_VOLUME *Volume;
EFI_STATUS Status;
+ FAT_TASK *Task;
IFile = IFILE_FROM_FHAND (FHand);
OFile = IFile->OFile;
Volume = OFile->Volume;
+ Task = NULL;
//
// If the file has a permanent error, return it
@@ -73,18 +77,71 @@ Returns:
if (IFile->ReadOnly) {
return EFI_ACCESS_DENIED;
}
+
+ if (Token == NULL) {
+ FatWaitNonblockingTask (IFile);
+ } else {
+ //
+ // Caller shouldn't call the non-blocking interfaces if the low layer doesn't support DiskIo2.
+ // But if it calls, the below check can avoid crash.
+ //
+ if (FHand->Revision < EFI_FILE_PROTOCOL_REVISION2) {
+ return EFI_UNSUPPORTED;
+ }
+ Task = FatCreateTask (IFile, Token);
+ if (Task == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
//
// Flush the OFile
//
FatAcquireLock ();
Status = FatOFileFlush (OFile);
- Status = FatCleanupVolume (OFile->Volume, OFile, Status);
+ Status = FatCleanupVolume (OFile->Volume, OFile, Status, Task);
FatReleaseLock ();
+
+ if (Token != NULL) {
+ if (!EFI_ERROR (Status)) {
+ Status = FatQueueTask (IFile, Task);
+ } else {
+ FatDestroyTask (Task);
+ }
+ }
+
return Status;
}
EFI_STATUS
EFIAPI
+FatFlush (
+ IN EFI_FILE_PROTOCOL *FHand
+ )
+/*++
+
+Routine Description:
+
+ Flushes all data associated with the file handle.
+
+Arguments:
+
+ FHand - Handle to file to flush.
+
+Returns:
+
+ EFI_SUCCESS - Flushed the file successfully.
+ EFI_WRITE_PROTECTED - The volume is read only.
+ EFI_ACCESS_DENIED - The file is read only.
+ Others - Flushing of the file failed.
+
+--*/
+{
+ return FatFlushEx (FHand, NULL);
+}
+
+EFI_STATUS
+EFIAPI
FatClose (
IN EFI_FILE_PROTOCOL *FHand
)
@@ -125,7 +182,7 @@ Returns:
//
// Done. Unlock the volume
//
- FatCleanupVolume (Volume, OFile, EFI_SUCCESS);
+ FatCleanupVolume (Volume, OFile, EFI_SUCCESS, NULL);
FatReleaseLock ();
//
@@ -162,6 +219,8 @@ Returns:
ASSERT_VOLUME_LOCKED (Volume);
+ FatWaitNonblockingTask (IFile);
+
//
// Remove the IFile struct
//
@@ -359,7 +418,8 @@ EFI_STATUS
FatCleanupVolume (
IN FAT_VOLUME *Volume,
IN FAT_OFILE *OFile,
- IN EFI_STATUS EfiStatus
+ IN EFI_STATUS EfiStatus,
+ IN FAT_TASK *Task
)
/*++
@@ -402,7 +462,7 @@ Returns:
// indicates this a FAT32 volume
//
if (Volume->FreeInfoValid && Volume->FatDirty && Volume->FreeInfoPos) {
- Status = FatDiskIo (Volume, WRITE_DISK, Volume->FreeInfoPos, sizeof (FAT_INFO_SECTOR), &Volume->FatInfoSector);
+ Status = FatDiskIo (Volume, WRITE_DISK, Volume->FreeInfoPos, sizeof (FAT_INFO_SECTOR), &Volume->FatInfoSector, Task);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -420,7 +480,7 @@ Returns:
//
// Flush all dirty cache entries to disk
//
- Status = FatVolumeFlushCache (Volume);
+ Status = FatVolumeFlushCache (Volume, Task);
if (EFI_ERROR (Status)) {
return Status;
}
diff --git a/FatPkg/EnhancedFatDxe/Info.c b/FatPkg/EnhancedFatDxe/Info.c
index cd8869acbc..ae85cce859 100644
--- a/FatPkg/EnhancedFatDxe/Info.c
+++ b/FatPkg/EnhancedFatDxe/Info.c
@@ -1,6 +1,6 @@
/*++
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2013, 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
@@ -515,6 +515,8 @@ Returns:
return EFI_DEVICE_ERROR;
}
+ FatWaitNonblockingTask (IFile);
+
FatAcquireLock ();
//
@@ -556,7 +558,7 @@ Returns:
}
}
- Status = FatCleanupVolume (Volume, NULL, Status);
+ Status = FatCleanupVolume (Volume, NULL, Status, NULL);
FatReleaseLock ();
return Status;
diff --git a/FatPkg/EnhancedFatDxe/Init.c b/FatPkg/EnhancedFatDxe/Init.c
index ee258cd2c4..34a7250453 100644
--- a/FatPkg/EnhancedFatDxe/Init.c
+++ b/FatPkg/EnhancedFatDxe/Init.c
@@ -1,6 +1,6 @@
/*++
-Copyright (c) 2005 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2013, 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
@@ -26,6 +26,7 @@ EFI_STATUS
FatAllocateVolume (
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_DISK_IO2_PROTOCOL *DiskIo2,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo
)
/*++
@@ -66,6 +67,7 @@ Returns:
Volume->Signature = FAT_VOLUME_SIGNATURE;
Volume->Handle = Handle;
Volume->DiskIo = DiskIo;
+ Volume->DiskIo2 = DiskIo2;
Volume->BlockIo = BlockIo;
Volume->MediaId = BlockIo->Media->MediaId;
Volume->ReadOnly = BlockIo->Media->ReadOnly;
@@ -193,7 +195,7 @@ Returns:
// FatCleanupVolume do the task.
//
if (LockedByMe) {
- FatCleanupVolume (Volume, NULL, EFI_SUCCESS);
+ FatCleanupVolume (Volume, NULL, EFI_SUCCESS, NULL);
FatReleaseLock ();
}
@@ -388,7 +390,7 @@ Returns:
if (FatType == FAT32) {
Volume->FreeInfoPos = FatBs.FatBse.Fat32Bse.FsInfoSector * BlockSize;
if (FatBs.FatBse.Fat32Bse.FsInfoSector != 0) {
- FatDiskIo (Volume, READ_DISK, Volume->FreeInfoPos, sizeof (FAT_INFO_SECTOR), &Volume->FatInfoSector);
+ FatDiskIo (Volume, READ_DISK, Volume->FreeInfoPos, sizeof (FAT_INFO_SECTOR), &Volume->FatInfoSector, NULL);
if (Volume->FatInfoSector.Signature == FAT_INFO_SIGNATURE &&
Volume->FatInfoSector.InfoBeginSignature == FAT_INFO_BEGIN_SIGNATURE &&
Volume->FatInfoSector.InfoEndSignature == FAT_INFO_END_SIGNATURE &&
diff --git a/FatPkg/EnhancedFatDxe/Misc.c b/FatPkg/EnhancedFatDxe/Misc.c
index 9a8f3cab4f..5ee72f86b1 100644
--- a/FatPkg/EnhancedFatDxe/Misc.c
+++ b/FatPkg/EnhancedFatDxe/Misc.c
@@ -1,6 +1,6 @@
/*++
-Copyright (c) 2005 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2013, 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
@@ -24,6 +24,221 @@ Revision History
#include "Fat.h"
+FAT_TASK *
+FatCreateTask (
+ FAT_IFILE *IFile,
+ EFI_FILE_IO_TOKEN *Token
+ )
+/*++
+
+Routine Description:
+
+ Create the task
+
+Arguments:
+
+ IFile - The instance of the open file.
+ Token - A pointer to the token associated with the transaction.
+
+Return:
+ FAT_TASK * - Return the task instance.
+**/
+{
+ FAT_TASK *Task;
+
+ Task = AllocateZeroPool (sizeof (*Task));
+ if (Task != NULL) {
+ Task->Signature = FAT_TASK_SIGNATURE;
+ Task->IFile = IFile;
+ Task->FileIoToken = Token;
+ InitializeListHead (&Task->Subtasks);
+ InitializeListHead (&Task->Link);
+ }
+ return Task;
+}
+
+VOID
+FatDestroyTask (
+ FAT_TASK *Task
+ )
+/*++
+
+Routine Description:
+
+ Destroy the task
+
+Arguments:
+
+ Task - The task to be destroyed.
+**/
+{
+ LIST_ENTRY *Link;
+ FAT_SUBTASK *Subtask;
+
+ Link = GetFirstNode (&Task->Subtasks);
+ while (!IsNull (&Task->Subtasks, Link)) {
+ Subtask = CR (Link, FAT_SUBTASK, Link, FAT_SUBTASK_SIGNATURE);
+ Link = FatDestroySubtask (Subtask);
+ }
+ RemoveEntryList (&Task->Link);
+ FreePool (Task);
+}
+
+VOID
+FatWaitNonblockingTask (
+ FAT_IFILE *IFile
+ )
+/*++
+
+Routine Description:
+
+ Wait all non-blocking requests complete.
+
+Arguments:
+
+ IFile - The instance of the open file.
+**/
+{
+ BOOLEAN TaskQueueEmpty;
+
+ do {
+ EfiAcquireLock (&FatTaskLock);
+ TaskQueueEmpty = IsListEmpty (&IFile->Tasks);
+ EfiReleaseLock (&FatTaskLock);
+ } while (!TaskQueueEmpty);
+}
+
+LIST_ENTRY *
+FatDestroySubtask (
+ FAT_SUBTASK *Subtask
+ )
+/*++
+
+Routine Description:
+
+ Remove the subtask from subtask list.
+
+Arguments:
+
+ Subtask - The subtask to be removed.
+
+Returns:
+
+ LIST_ENTRY * - The next node in the list.
+
+--*/
+{
+ LIST_ENTRY *Link;
+
+ gBS->CloseEvent (Subtask->DiskIo2Token.Event);
+
+ Link = RemoveEntryList (&Subtask->Link);
+ FreePool (Subtask);
+
+ return Link;
+}
+
+EFI_STATUS
+FatQueueTask (
+ IN FAT_IFILE *IFile,
+ IN FAT_TASK *Task
+ )
+/*++
+
+Routine Description:
+
+ Execute the task
+
+Arguments:
+
+ IFile - The instance of the open file.
+ Task - The task to be executed.
+
+Returns:
+
+ EFI_SUCCESS - The task was executed sucessfully.
+ other - An error occurred when executing the task.
+
+--*/
+{
+ EFI_STATUS Status;
+ LIST_ENTRY *Link;
+ FAT_SUBTASK *Subtask;
+
+ //
+ // Sometimes the Task doesn't contain any subtasks, signal the event directly.
+ //
+ if (IsListEmpty (&Task->Subtasks)) {
+ Task->FileIoToken->Status = EFI_SUCCESS;
+ gBS->SignalEvent (Task->FileIoToken->Event);
+ FreePool (Task);
+ return EFI_SUCCESS;
+ }
+
+ EfiAcquireLock (&FatTaskLock);
+ InsertTailList (&IFile->Tasks, &Task->Link);
+ EfiReleaseLock (&FatTaskLock);
+
+ Status = EFI_SUCCESS;
+ for ( Link = GetFirstNode (&Task->Subtasks)
+ ; !IsNull (&Task->Subtasks, Link)
+ ; Link = GetNextNode (&Task->Subtasks, Link)
+ ) {
+ Subtask = CR (Link, FAT_SUBTASK, Link, FAT_SUBTASK_SIGNATURE);
+ if (Subtask->Write) {
+
+ Status = IFile->OFile->Volume->DiskIo2->WriteDiskEx (
+ IFile->OFile->Volume->DiskIo2,
+ IFile->OFile->Volume->MediaId,
+ Subtask->Offset,
+ &Subtask->DiskIo2Token,
+ Subtask->BufferSize,
+ Subtask->Buffer
+ );
+ } else {
+ Status = IFile->OFile->Volume->DiskIo2->ReadDiskEx (
+ IFile->OFile->Volume->DiskIo2,
+ IFile->OFile->Volume->MediaId,
+ Subtask->Offset,
+ &Subtask->DiskIo2Token,
+ Subtask->BufferSize,
+ Subtask->Buffer
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ EfiAcquireLock (&FatTaskLock);
+ //
+ // Remove all the remaining subtasks when failure.
+ // We shouldn't remove all the tasks because the non-blocking requests have
+ // been submitted and cannot be canceled.
+ //
+ while (!IsNull (&Task->Subtasks, Link)) {
+ Subtask = CR (Link, FAT_SUBTASK, Link, FAT_SUBTASK_SIGNATURE);
+ Link = FatDestroySubtask (Subtask);
+ }
+
+ if (IsListEmpty (&Task->Subtasks)) {
+ RemoveEntryList (&Task->Link);
+ FreePool (Task);
+ } else {
+ //
+ // If one or more subtasks have been already submitted, set FileIoToken
+ // to NULL so that the callback won't signal the event.
+ //
+ Task->FileIoToken = NULL;
+ }
+
+ EfiReleaseLock (&FatTaskLock);
+ }
+
+ return Status;
+}
+
EFI_STATUS
FatAccessVolumeDirty (
IN FAT_VOLUME *Volume,
@@ -52,7 +267,79 @@ Returns:
UINTN WriteCount;
WriteCount = Volume->FatEntrySize;
- return FatDiskIo (Volume, IoMode, Volume->FatPos + WriteCount, WriteCount, DirtyValue);
+ return FatDiskIo (Volume, IoMode, Volume->FatPos + WriteCount, WriteCount, DirtyValue, NULL);
+}
+
+/**
+ Invoke a notification event
+
+ @param Event Event whose notification function is being invoked.
+ @param Context The pointer to the notification function's context,
+ which is implementation-dependent.
+
+**/
+VOID
+EFIAPI
+FatOnAccessComplete (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ Invoke a notification event
+ case #1. some subtasks are not completed when the FatOpenEx checks the Task->Subtasks
+ - sets Task->SubtaskCollected so callback to signal the event and free the task.
+ case #2. all subtasks are completed when the FatOpenEx checks the Task->Subtasks
+ - FatOpenEx signal the event and free the task.
+Arguments:
+
+ Event - Event whose notification function is being invoked.
+ Context - The pointer to the notification function's context,
+ which is implementation-dependent.
+
+--*/
+{
+ EFI_STATUS Status;
+ FAT_SUBTASK *Subtask;
+ FAT_TASK *Task;
+
+ //
+ // Avoid someone in future breaks the below assumption.
+ //
+ ASSERT (EfiGetCurrentTpl () == FatTaskLock.Tpl);
+
+ Subtask = (FAT_SUBTASK *) Context;
+ Task = Subtask->Task;
+ Status = Subtask->DiskIo2Token.TransactionStatus;
+
+ ASSERT (Task->Signature == FAT_TASK_SIGNATURE);
+ ASSERT (Subtask->Signature == FAT_SUBTASK_SIGNATURE);
+
+ //
+ // Remove the task unconditionally
+ //
+ FatDestroySubtask (Subtask);
+
+ //
+ // Task->FileIoToken is NULL which means the task will be ignored (just recycle the subtask and task memory).
+ //
+ if (Task->FileIoToken != NULL) {
+ if (IsListEmpty (&Task->Subtasks) || EFI_ERROR (Status)) {
+ Task->FileIoToken->Status = Status;
+ gBS->SignalEvent (Task->FileIoToken->Event);
+ //
+ // Mark Task->FileIoToken to NULL so that the subtasks belonging to the task will be ignored.
+ //
+ Task->FileIoToken = NULL;
+ }
+ }
+
+ if (IsListEmpty (&Task->Subtasks)) {
+ RemoveEntryList (&Task->Link);
+ FreePool (Task);
+ }
}
EFI_STATUS
@@ -61,7 +348,8 @@ FatDiskIo (
IN IO_MODE IoMode,
IN UINT64 Offset,
IN UINTN BufferSize,
- IN OUT VOID *Buffer
+ IN OUT VOID *Buffer,
+ IN FAT_TASK *Task
)
/*++
@@ -88,6 +376,7 @@ Returns:
EFI_STATUS Status;
EFI_DISK_IO_PROTOCOL *DiskIo;
EFI_DISK_READ IoFunction;
+ FAT_SUBTASK *Subtask;
//
// Verify the IO is in devices range
@@ -98,20 +387,52 @@ Returns:
//
// Access cache
//
- Status = FatAccessCache (Volume, CACHE_TYPE (IoMode), RAW_ACCESS (IoMode), Offset, BufferSize, Buffer);
+ Status = FatAccessCache (Volume, CACHE_TYPE (IoMode), RAW_ACCESS (IoMode), Offset, BufferSize, Buffer, Task);
} else {
//
// Access disk directly
//
- DiskIo = Volume->DiskIo;
- IoFunction = (IoMode == READ_DISK) ? DiskIo->ReadDisk : DiskIo->WriteDisk;
- Status = IoFunction (DiskIo, Volume->MediaId, Offset, BufferSize, Buffer);
+ if (Task == NULL) {
+ //
+ // Blocking access
+ //
+ DiskIo = Volume->DiskIo;
+ IoFunction = (IoMode == READ_DISK) ? DiskIo->ReadDisk : DiskIo->WriteDisk;
+ Status = IoFunction (DiskIo, Volume->MediaId, Offset, BufferSize, Buffer);
+ } else {
+ //
+ // Non-blocking access
+ //
+ Subtask = AllocateZeroPool (sizeof (*Subtask));
+ if (Subtask == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ Subtask->Signature = FAT_SUBTASK_SIGNATURE;
+ Subtask->Task = Task;
+ Subtask->Write = (BOOLEAN) (IoMode == WRITE_DISK);
+ Subtask->Offset = Offset;
+ Subtask->Buffer = Buffer;
+ Subtask->BufferSize = BufferSize;
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ FatOnAccessComplete,
+ Subtask,
+ &Subtask->DiskIo2Token.Event
+ );
+ if (!EFI_ERROR (Status)) {
+ InsertTailList (&Task->Subtasks, &Subtask->Link);
+ } else {
+ FreePool (Subtask);
+ }
+ }
+ }
}
}
if (EFI_ERROR (Status)) {
Volume->DiskError = TRUE;
- DEBUG ((EFI_D_INFO, "FatDiskIo: error %r\n", Status));
+ DEBUG ((EFI_D_ERROR, "FatDiskIo: error %r\n", Status));
}
return Status;
diff --git a/FatPkg/EnhancedFatDxe/Open.c b/FatPkg/EnhancedFatDxe/Open.c
index f38f639e9b..16badf6462 100644
--- a/FatPkg/EnhancedFatDxe/Open.c
+++ b/FatPkg/EnhancedFatDxe/Open.c
@@ -1,6 +1,6 @@
/*++
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2013, 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
@@ -64,8 +64,18 @@ Returns:
CopyMem (&(IFile->Handle), &FatFileInterface, sizeof (EFI_FILE_PROTOCOL));
+ //
+ // Report the correct revision number based on the DiskIo2 availability
+ //
+ if (OFile->Volume->DiskIo2 != NULL) {
+ IFile->Handle.Revision = EFI_FILE_PROTOCOL_REVISION2;
+ } else {
+ IFile->Handle.Revision = EFI_FILE_PROTOCOL_REVISION;
+ }
+
IFile->OFile = OFile;
InsertTailList (&OFile->Opens, &IFile->Link);
+ InitializeListHead (&IFile->Tasks);
*PtrIFile = IFile;
return EFI_SUCCESS;
@@ -188,18 +198,18 @@ Returns:
}
EFI_STATUS
-EFIAPI
-FatOpen (
- IN EFI_FILE_PROTOCOL *FHand,
- OUT EFI_FILE_PROTOCOL **NewHandle,
- IN CHAR16 *FileName,
- IN UINT64 OpenMode,
- IN UINT64 Attributes
+FatOpenEx (
+ IN EFI_FILE_PROTOCOL *FHand,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes,
+ IN OUT EFI_FILE_IO_TOKEN *Token
)
/*++
Routine Description:
- Implements Open() of Simple File System Protocol.
+ Implements OpenEx() of Simple File System Protocol.
Arguments:
@@ -208,6 +218,7 @@ Arguments:
FileName - File name relative to FHand.
OpenMode - Open mode.
Attributes - Attributes to set if the file is created.
+ Token - A pointer to the token associated with the transaction.
Returns:
@@ -224,6 +235,7 @@ Returns:
FAT_IFILE *NewIFile;
FAT_OFILE *OFile;
EFI_STATUS Status;
+ FAT_TASK *Task;
//
// Perform some parameter checking
@@ -243,16 +255,33 @@ Returns:
default:
return EFI_INVALID_PARAMETER;
}
-
+
//
// Check for valid Attributes for file creation case.
//
if (((OpenMode & EFI_FILE_MODE_CREATE) != 0) && (Attributes & (EFI_FILE_READ_ONLY | (~EFI_FILE_VALID_ATTR))) != 0) {
- return EFI_INVALID_PARAMETER;
+ return EFI_INVALID_PARAMETER;
}
-
+
IFile = IFILE_FROM_FHAND (FHand);
OFile = IFile->OFile;
+ Task = NULL;
+
+ if (Token == NULL) {
+ FatWaitNonblockingTask (IFile);
+ } else {
+ //
+ // Caller shouldn't call the non-blocking interfaces if the low layer doesn't support DiskIo2.
+ // But if it calls, the below check can avoid crash.
+ //
+ if (FHand->Revision < EFI_FILE_PROTOCOL_REVISION2) {
+ return EFI_UNSUPPORTED;
+ }
+ Task = FatCreateTask (IFile, Token);
+ if (Task == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
//
// Lock
@@ -273,8 +302,52 @@ Returns:
//
// Unlock
//
- Status = FatCleanupVolume (OFile->Volume, NULL, Status);
+ Status = FatCleanupVolume (OFile->Volume, NULL, Status, Task);
FatReleaseLock ();
+ if (Token != NULL) {
+ if (!EFI_ERROR (Status)) {
+ Status = FatQueueTask (IFile, Task);
+ } else {
+ FatDestroyTask (Task);
+ }
+ }
+
return Status;
}
+
+EFI_STATUS
+EFIAPI
+FatOpen (
+ IN EFI_FILE_PROTOCOL *FHand,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ )
+/*++
+Routine Description:
+
+ Implements Open() of Simple File System Protocol.
+
+Arguments:
+
+ FHand - File handle of the file serves as a starting reference point.
+ NewHandle - Handle of the file that is newly opened.
+ FileName - File name relative to FHand.
+ OpenMode - Open mode.
+ Attributes - Attributes to set if the file is created.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - The FileName is NULL or the file string is empty.
+ The OpenMode is not supported.
+ The Attributes is not the valid attributes.
+ EFI_OUT_OF_RESOURCES - Can not allocate the memory for file string.
+ EFI_SUCCESS - Open the file successfully.
+ Others - The status of open file.
+
+--*/
+{
+ return FatOpenEx (FHand, NewHandle, FileName, OpenMode, Attributes, NULL);
+}
diff --git a/FatPkg/EnhancedFatDxe/OpenVolume.c b/FatPkg/EnhancedFatDxe/OpenVolume.c
index 50f02f0720..0f43ffae98 100644
--- a/FatPkg/EnhancedFatDxe/OpenVolume.c
+++ b/FatPkg/EnhancedFatDxe/OpenVolume.c
@@ -1,6 +1,6 @@
/*++
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2013, 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
@@ -73,7 +73,7 @@ Returns:
Done:
- Status = FatCleanupVolume (Volume, Volume->Root, Status);
+ Status = FatCleanupVolume (Volume, Volume->Root, Status, NULL);
FatReleaseLock ();
return Status;
diff --git a/FatPkg/EnhancedFatDxe/ReadWrite.c b/FatPkg/EnhancedFatDxe/ReadWrite.c
index 8c41bd5788..4621817c93 100644
--- a/FatPkg/EnhancedFatDxe/ReadWrite.c
+++ b/FatPkg/EnhancedFatDxe/ReadWrite.c
@@ -1,6 +1,6 @@
/*++
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2013, 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
@@ -101,6 +101,9 @@ Returns:
if (OFile->Error == EFI_NOT_FOUND) {
return EFI_DEVICE_ERROR;
}
+
+ FatWaitNonblockingTask (IFile);
+
//
// If this is a directory, we can only set back to position 0
//
@@ -207,7 +210,8 @@ FatIFileAccess (
IN EFI_FILE_PROTOCOL *FHand,
IN IO_MODE IoMode,
IN OUT UINTN *BufferSize,
- IN OUT VOID *Buffer
+ IN OUT VOID *Buffer,
+ IN EFI_FILE_IO_TOKEN *Token
)
/*++
@@ -221,6 +225,7 @@ Arguments:
IoMode - Indicate whether the access mode is reading or writing.
BufferSize - Size of Buffer.
Buffer - Buffer containing read data.
+ Token - A pointer to the token associated with the transaction.
Returns:
@@ -238,10 +243,12 @@ Returns:
FAT_OFILE *OFile;
FAT_VOLUME *Volume;
UINT64 EndPosition;
+ FAT_TASK *Task;
IFile = IFILE_FROM_FHAND (FHand);
OFile = IFile->OFile;
Volume = OFile->Volume;
+ Task = NULL;
if (OFile->Error == EFI_NOT_FOUND) {
return EFI_DEVICE_ERROR;
@@ -267,6 +274,22 @@ Returns:
}
}
+ if (Token == NULL) {
+ FatWaitNonblockingTask (IFile);
+ } else {
+ //
+ // Caller shouldn't call the non-blocking interfaces if the low layer doesn't support DiskIo2.
+ // But if it calls, the below check can avoid crash.
+ //
+ if (FHand->Revision < EFI_FILE_PROTOCOL_REVISION2) {
+ return EFI_UNSUPPORTED;
+ }
+ Task = FatCreateTask (IFile, Token);
+ if (Task == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
FatAcquireLock ();
Status = OFile->Error;
@@ -318,15 +341,20 @@ Returns:
}
}
- Status = FatAccessOFile (OFile, IoMode, (UINTN) IFile->Position, BufferSize, Buffer);
+ Status = FatAccessOFile (OFile, IoMode, (UINTN) IFile->Position, BufferSize, Buffer, Task);
IFile->Position += *BufferSize;
}
}
-Done:
- if (EFI_ERROR (Status)) {
- Status = FatCleanupVolume (Volume, OFile, Status);
+ if (Token != NULL) {
+ if (!EFI_ERROR (Status)) {
+ Status = FatQueueTask (IFile, Task);
+ } else {
+ FatDestroyTask (Task);
+ }
}
+
+Done:
//
// On EFI_SUCCESS case, not calling FatCleanupVolume():
// 1) The Cache flush operation is avoided to enhance
@@ -336,6 +364,10 @@ Done:
// 3) Write operation doesn't affect OFile/IFile structure, so
// Reference checking is not necessary.
//
+ if (EFI_ERROR (Status)) {
+ Status = FatCleanupVolume (Volume, OFile, Status, NULL);
+ }
+
FatReleaseLock ();
return Status;
}
@@ -368,7 +400,36 @@ Returns:
--*/
{
- return FatIFileAccess (FHand, READ_DATA, BufferSize, Buffer);
+ return FatIFileAccess (FHand, READ_DATA, BufferSize, Buffer, NULL);
+}
+
+EFI_STATUS
+EFIAPI
+FatReadEx (
+ IN EFI_FILE_PROTOCOL *FHand,
+ IN OUT EFI_FILE_IO_TOKEN *Token
+ )
+/*++
+
+Routine Description:
+
+ Get the file info.
+
+Arguments:
+
+ FHand - The handle of the file.
+ Token - A pointer to the token associated with the transaction.
+
+Returns:
+
+ EFI_SUCCESS - Get the file info successfully.
+ EFI_DEVICE_ERROR - Can not find the OFile for the file.
+ EFI_VOLUME_CORRUPTED - The file type of open file is error.
+ other - An error occurred when operation the disk.
+
+--*/
+{
+ return FatIFileAccess (FHand, READ_DATA, &Token->BufferSize, Token->Buffer, Token);
}
EFI_STATUS
@@ -402,7 +463,36 @@ Returns:
--*/
{
- return FatIFileAccess (FHand, WRITE_DATA, BufferSize, Buffer);
+ return FatIFileAccess (FHand, WRITE_DATA, BufferSize, Buffer, NULL);
+}
+
+EFI_STATUS
+EFIAPI
+FatWriteEx (
+ IN EFI_FILE_PROTOCOL *FHand,
+ IN OUT EFI_FILE_IO_TOKEN *Token
+ )
+/*++
+
+Routine Description:
+
+ Get the file info.
+
+Arguments:
+
+ FHand - The handle of the file.
+ Token - A pointer to the token associated with the transaction.
+
+Returns:
+
+ EFI_SUCCESS - Get the file info successfully.
+ EFI_DEVICE_ERROR - Can not find the OFile for the file.
+ EFI_VOLUME_CORRUPTED - The file type of open file is error.
+ other - An error occurred when operation the disk.
+
+--*/
+{
+ return FatIFileAccess (FHand, WRITE_DATA, &Token->BufferSize, Token->Buffer, Token);
}
EFI_STATUS
@@ -411,7 +501,8 @@ FatAccessOFile (
IN IO_MODE IoMode,
IN UINTN Position,
IN OUT UINTN *DataBufferSize,
- IN OUT UINT8 *UserBuffer
+ IN OUT UINT8 *UserBuffer,
+ IN FAT_TASK *Task
)
/*++
@@ -461,7 +552,7 @@ Returns:
//
// Write the data
//
- Status = FatDiskIo (Volume, IoMode, OFile->PosDisk, Len, UserBuffer);
+ Status = FatDiskIo (Volume, IoMode, OFile->PosDisk, Len, UserBuffer, Task);
if (EFI_ERROR (Status)) {
break;
}
@@ -572,7 +663,7 @@ Returns:
do {
WriteSize = AppendedSize > BufferSize ? BufferSize : (UINTN) AppendedSize;
AppendedSize -= WriteSize;
- Status = FatAccessOFile (OFile, WRITE_DATA, WritePos, &WriteSize, ZeroBuffer);
+ Status = FatAccessOFile (OFile, WRITE_DATA, WritePos, &WriteSize, ZeroBuffer, NULL);
if (EFI_ERROR (Status)) {
break;
}