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>
This commit is contained in:
Ruiyu Ni 2013-10-30 03:13:16 +00:00 committed by Jordan Justen
parent 04a4fdb99f
commit 149d633529
15 changed files with 914 additions and 151 deletions

View File

@ -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
};

View File

@ -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)) {

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
@ -400,6 +424,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 (
@ -510,6 +569,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 (
@ -610,6 +696,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 (
@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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
@ -24,6 +24,95 @@ Revision History
#include "Fat.h"
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.
--*/
{
FAT_IFILE *IFile;
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
//
if (EFI_ERROR (OFile->Error)) {
return OFile->Error;
}
if (Volume->ReadOnly) {
return EFI_WRITE_PROTECTED;
}
//
// If read only, return error
//
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, Task);
FatReleaseLock ();
if (Token != NULL) {
if (!EFI_ERROR (Status)) {
Status = FatQueueTask (IFile, Task);
} else {
FatDestroyTask (Task);
}
}
return Status;
}
EFI_STATUS
EFIAPI
FatFlush (
@ -48,39 +137,7 @@ Returns:
--*/
{
FAT_IFILE *IFile;
FAT_OFILE *OFile;
FAT_VOLUME *Volume;
EFI_STATUS Status;
IFile = IFILE_FROM_FHAND (FHand);
OFile = IFile->OFile;
Volume = OFile->Volume;
//
// If the file has a permanent error, return it
//
if (EFI_ERROR (OFile->Error)) {
return OFile->Error;
}
if (Volume->ReadOnly) {
return EFI_WRITE_PROTECTED;
}
//
// If read only, return error
//
if (IFile->ReadOnly) {
return EFI_ACCESS_DENIED;
}
//
// Flush the OFile
//
FatAcquireLock ();
Status = FatOFileFlush (OFile);
Status = FatCleanupVolume (OFile->Volume, OFile, Status);
FatReleaseLock ();
return Status;
return FatFlushEx (FHand, NULL);
}
EFI_STATUS
@ -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;
}

View File

@ -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;

View File

@ -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 &&

View File

@ -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;

View File

@ -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;
@ -187,6 +197,125 @@ Returns:
return FatOFileFlush (OFile);
}
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.
--*/
{
FAT_IFILE *IFile;
FAT_IFILE *NewIFile;
FAT_OFILE *OFile;
EFI_STATUS Status;
FAT_TASK *Task;
//
// Perform some parameter checking
//
if (FileName == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Check for a valid mode
//
switch (OpenMode) {
case EFI_FILE_MODE_READ:
case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE:
break;
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;
}
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
//
FatAcquireLock ();
//
// Open the file
//
Status = FatOFileOpen (OFile, &NewIFile, FileName, OpenMode, (UINT8) Attributes);
//
// If the file was opened, return the handle to the caller
//
if (!EFI_ERROR (Status)) {
*NewHandle = &NewIFile->Handle;
}
//
// Unlock
//
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 (
@ -220,61 +349,5 @@ Returns:
--*/
{
FAT_IFILE *IFile;
FAT_IFILE *NewIFile;
FAT_OFILE *OFile;
EFI_STATUS Status;
//
// Perform some parameter checking
//
if (FileName == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Check for a valid mode
//
switch (OpenMode) {
case EFI_FILE_MODE_READ:
case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE:
break;
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;
}
IFile = IFILE_FROM_FHAND (FHand);
OFile = IFile->OFile;
//
// Lock
//
FatAcquireLock ();
//
// Open the file
//
Status = FatOFileOpen (OFile, &NewIFile, FileName, OpenMode, (UINT8) Attributes);
//
// If the file was opened, return the handle to the caller
//
if (!EFI_ERROR (Status)) {
*NewHandle = &NewIFile->Handle;
}
//
// Unlock
//
Status = FatCleanupVolume (OFile->Volume, NULL, Status);
FatReleaseLock ();
return Status;
return FatOpenEx (FHand, NewHandle, FileName, OpenMode, Attributes, NULL);
}

View File

@ -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;

View File

@ -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;
}