Add DiskIo2 protocol definition to MdePkg.

Change DiskIoDxe to produce DiskIo2 protocol when the BlockIo2 protocol is available.
Change PartitionDxe to produce BlockIo2 protocol based on DiskIo2 protocol instead of BlockIo2 protocol.

Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Kinney Michael <michael.d.kinney@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14570 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Ruiyu Ni 2013-08-20 03:14:30 +00:00 committed by niruiyu
parent 61f2ab909d
commit 493d8e3a5e
11 changed files with 1464 additions and 523 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/** @file
Master header file for DiskIo driver. It includes the module private defininitions.
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 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
@ -17,6 +17,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Uefi.h>
#include <Protocol/BlockIo.h>
#include <Protocol/BlockIo2.h>
#include <Protocol/DiskIo2.h>
#include <Protocol/ComponentName.h>
#include <Protocol/DriverBinding.h>
#include <Protocol/DiskIo.h>
@ -28,18 +30,69 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
//
// Pre-allocate an aligned buffer of 64 blocks so very large Disk I/O requests
// will be broken up into 64 * BlockSize chunks to provide better performance
// than allocating an aligned 1 block buffer.
//
#define DATA_BUFFER_BLOCK_NUM 64
#define DISK_IO_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('d', 's', 'k', 'I')
typedef struct {
UINTN Signature;
EFI_DISK_IO_PROTOCOL DiskIo;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
} DISK_IO_PRIVATE_DATA;
UINT32 Signature;
#define DISK_IO_PRIVATE_DATA_FROM_THIS(a) CR (a, DISK_IO_PRIVATE_DATA, DiskIo, DISK_IO_PRIVATE_DATA_SIGNATURE)
EFI_DISK_IO_PROTOCOL DiskIo;
EFI_DISK_IO2_PROTOCOL DiskIo2;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_BLOCK_IO2_PROTOCOL *BlockIo2;
UINT8 *SharedWorkingBuffer;
EFI_LOCK TaskQueueLock;
LIST_ENTRY TaskQueue;
} DISK_IO_PRIVATE_DATA;
#define DISK_IO_PRIVATE_DATA_FROM_DISK_IO(a) CR (a, DISK_IO_PRIVATE_DATA, DiskIo, DISK_IO_PRIVATE_DATA_SIGNATURE)
#define DISK_IO_PRIVATE_DATA_FROM_DISK_IO2(a) CR (a, DISK_IO_PRIVATE_DATA, DiskIo2, DISK_IO_PRIVATE_DATA_SIGNATURE)
#define DISK_IO2_TASK_SIGNATURE SIGNATURE_32 ('d', 'i', 'a', 't')
typedef struct {
UINT32 Signature;
LIST_ENTRY Link; /// < link to other task
LIST_ENTRY Subtasks; /// < header of subtasks
EFI_DISK_IO2_TOKEN *Token;
DISK_IO_PRIVATE_DATA *Instance;
} DISK_IO2_TASK;
#define DISK_IO2_FLUSH_TASK_SIGNATURE SIGNATURE_32 ('d', 'i', 'f', 't')
typedef struct {
UINT32 Signature;
EFI_BLOCK_IO2_TOKEN BlockIo2Token;
EFI_DISK_IO2_TOKEN *Token;
} DISK_IO2_FLUSH_TASK;
#define DISK_IO_SUBTASK_SIGNATURE SIGNATURE_32 ('d', 'i', 's', 't')
typedef struct {
//
// UnderRun: Offset != 0, Length < BlockSize
// OverRun: Offset == 0, Length < BlockSize
// Middle: Offset is block aligned, Length is multiple of block size
//
UINT32 Signature;
LIST_ENTRY Link;
BOOLEAN Write;
UINT64 Lba;
UINT32 Offset;
UINTN Length;
UINT8 *WorkingBuffer; /// < NULL indicates using "Buffer" directly
UINT8 *Buffer;
BOOLEAN Blocking;
//
// Following fields are for DiskIo2
//
DISK_IO2_TASK *Task;
EFI_BLOCK_IO2_TOKEN BlockIo2Token;
} DISK_IO_SUBTASK;
//
// Global Variables
@ -189,6 +242,110 @@ DiskIoWriteDisk (
IN VOID *Buffer
);
/**
Terminate outstanding asynchronous requests to a device.
@param This Indicates a pointer to the calling context.
@retval EFI_SUCCESS All outstanding requests were successfully terminated.
@retval EFI_DEVICE_ERROR The device reported an error while performing the cancel
operation.
**/
EFI_STATUS
EFIAPI
DiskIo2Cancel (
IN EFI_DISK_IO2_PROTOCOL *This
);
/**
Reads a specified number of bytes from a device.
@param This Indicates a pointer to the calling context.
@param MediaId ID of the medium to be read.
@param Offset The starting byte offset on the logical block I/O device to read from.
@param Token A pointer to the token associated with the transaction.
If this field is NULL, synchronous/blocking IO is performed.
@param BufferSize The size in bytes of Buffer. The number of bytes to read from the device.
@param Buffer A pointer to the destination buffer for the data.
The caller is responsible either having implicit or explicit ownership of the buffer.
@retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read correctly from the device.
If Event is not NULL (asynchronous I/O): The request was successfully queued for processing.
Event will be signaled upon completion.
@retval EFI_DEVICE_ERROR The device reported an error while performing the write.
@retval EFI_NO_MEDIA There is no medium in the device.
@retval EFI_MEDIA_CHNAGED The MediaId is not for the current medium.
@retval EFI_INVALID_PARAMETER The read request contains device addresses that are not valid for the device.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
**/
EFI_STATUS
EFIAPI
DiskIo2ReadDiskEx (
IN EFI_DISK_IO2_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 Offset,
IN OUT EFI_DISK_IO2_TOKEN *Token,
IN UINTN BufferSize,
OUT VOID *Buffer
);
/**
Writes a specified number of bytes to a device.
@param This Indicates a pointer to the calling context.
@param MediaId ID of the medium to be written.
@param Offset The starting byte offset on the logical block I/O device to write to.
@param Token A pointer to the token associated with the transaction.
If this field is NULL, synchronous/blocking IO is performed.
@param BufferSize The size in bytes of Buffer. The number of bytes to write to the device.
@param Buffer A pointer to the buffer containing the data to be written.
@retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was written correctly to the device.
If Event is not NULL (asynchronous I/O): The request was successfully queued for processing.
Event will be signaled upon completion.
@retval EFI_WRITE_PROTECTED The device cannot be written to.
@retval EFI_DEVICE_ERROR The device reported an error while performing the write operation.
@retval EFI_NO_MEDIA There is no medium in the device.
@retval EFI_MEDIA_CHNAGED The MediaId is not for the current medium.
@retval EFI_INVALID_PARAMETER The write request contains device addresses that are not valid for the device.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
**/
EFI_STATUS
EFIAPI
DiskIo2WriteDiskEx (
IN EFI_DISK_IO2_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 Offset,
IN EFI_DISK_IO2_TOKEN *Token,
IN UINTN BufferSize,
IN VOID *Buffer
);
/**
Flushes all modified data to the physical device.
@param This Indicates a pointer to the calling context.
@param Token A pointer to the token associated with the transaction.
If this field is NULL, synchronous/blocking IO is performed.
@retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was flushed successfully to the device.
If Event is not NULL (asynchronous I/O): The request was successfully queued for processing.
Event will be signaled upon completion.
@retval EFI_WRITE_PROTECTED The device cannot be written to.
@retval EFI_DEVICE_ERROR The device reported an error while performing the write operation.
@retval EFI_NO_MEDIA There is no medium in the device.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
**/
EFI_STATUS
EFIAPI
DiskIo2FlushDiskEx (
IN EFI_DISK_IO2_PROTOCOL *This,
IN OUT EFI_DISK_IO2_TOKEN *Token
);
//
// EFI Component Name Functions
//

View File

@ -8,7 +8,7 @@
# already have a Disk I/O protocol. File systems and other disk access
# code utilize the Disk I/O protocol.
#
# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2006 - 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
@ -59,5 +59,7 @@
[Protocols]
gEfiDiskIoProtocolGuid ## BY_START
gEfiDiskIo2ProtocolGuid ## BY_START
gEfiBlockIoProtocolGuid ## TO_START
gEfiBlockIo2ProtocolGuid ## TO_START

View File

@ -1,7 +1,7 @@
/** @file
Decode an El Torito formatted CD-ROM
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 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
@ -22,6 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@param[in] This Calling context.
@param[in] Handle Parent Handle.
@param[in] DiskIo Parent DiskIo interface.
@param[in] DiskIo2 Parent DiskIo2 interface.
@param[in] BlockIo Parent BlockIo interface.
@param[in] BlockIo2 Parent BlockIo2 interface.
@param[in] DevicePath Parent Device Path
@ -37,6 +38,7 @@ PartitionInstallElToritoChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_DISK_IO2_PROTOCOL *DiskIo2,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
@ -258,6 +260,7 @@ PartitionInstallElToritoChildHandles (
This,
Handle,
DiskIo,
DiskIo2,
BlockIo,
BlockIo2,
DevicePath,

View File

@ -184,6 +184,7 @@ PartitionSetCrc (
@param[in] This Calling context.
@param[in] Handle Parent Handle.
@param[in] DiskIo Parent DiskIo interface.
@param[in] DiskIo2 Parent DiskIo2 interface.
@param[in] BlockIo Parent BlockIo interface.
@param[in] BlockIo2 Parent BlockIo2 interface.
@param[in] DevicePath Parent Device Path.
@ -198,6 +199,7 @@ PartitionInstallGptChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_DISK_IO2_PROTOCOL *DiskIo2,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
@ -400,6 +402,7 @@ PartitionInstallGptChildHandles (
This,
Handle,
DiskIo,
DiskIo2,
BlockIo,
BlockIo2,
DevicePath,

View File

@ -11,7 +11,7 @@
always on the first sector of a media. The first sector also contains
the legacy boot strap code.
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 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
@ -104,6 +104,7 @@ PartitionValidMbr (
@param[in] This Calling context.
@param[in] Handle Parent Handle.
@param[in] DiskIo Parent DiskIo interface.
@param[in] DiskIo2 Parent DiskIo2 interface.
@param[in] BlockIo Parent BlockIo interface.
@param[in] BlockIo2 Parent BlockIo2 interface.
@param[in] DevicePath Parent Device Path.
@ -118,6 +119,7 @@ PartitionInstallMbrChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_DISK_IO2_PROTOCOL *DiskIo2,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
@ -226,6 +228,7 @@ PartitionInstallMbrChildHandles (
This,
Handle,
DiskIo,
DiskIo2,
BlockIo,
BlockIo2,
DevicePath,
@ -287,6 +290,7 @@ PartitionInstallMbrChildHandles (
This,
Handle,
DiskIo,
DiskIo2,
BlockIo,
BlockIo2,
DevicePath,

View File

@ -4,7 +4,7 @@
of the raw block devices media. Currently "El Torito CD-ROM", Legacy
MBR, and GPT partition schemes are supported.
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 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
@ -200,6 +200,7 @@ PartitionDriverBindingStart (
EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_BLOCK_IO2_PROTOCOL *BlockIo2;
EFI_DISK_IO_PROTOCOL *DiskIo;
EFI_DISK_IO2_PROTOCOL *DiskIo2;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
PARTITION_DETECT_ROUTINE *Routine;
BOOLEAN MediaPresent;
@ -243,8 +244,11 @@ PartitionDriverBindingStart (
(VOID **) &BlockIo2,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
BlockIo2 = NULL;
}
//
// Get the Device Path Protocol on ControllerHandle's handle.
@ -261,6 +265,9 @@ PartitionDriverBindingStart (
goto Exit;
}
//
// Get the DiskIo and DiskIo2.
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiDiskIoProtocolGuid,
@ -281,6 +288,18 @@ PartitionDriverBindingStart (
OpenStatus = Status;
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiDiskIo2ProtocolGuid,
(VOID **) &DiskIo2,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
DiskIo2 = NULL;
}
//
// Try to read blocks when there's media or it is removable physical partition.
//
@ -299,6 +318,7 @@ PartitionDriverBindingStart (
This,
ControllerHandle,
DiskIo,
DiskIo2,
BlockIo,
BlockIo2,
ParentDevicePath
@ -404,7 +424,7 @@ PartitionDriverBindingStop (
//
gBS->CloseProtocol (
ControllerHandle,
&gEfiBlockIo2ProtocolGuid,
&gEfiDiskIo2ProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
@ -699,7 +719,7 @@ PartitionFlushBlocks (
Probe the media status and return EFI_NO_MEDIA or EFI_MEDIA_CHANGED
for no media or media change case. Otherwise DefaultStatus is returned.
@param BlockIo2 Pointer to the BlockIo2 instance.
@param DiskIo2 Pointer to the DiskIo2 instance.
@param MediaId Id of the media, changes every time the media is replaced.
@param DefaultStatus The default status to return when it's not the no media
or media change case.
@ -710,7 +730,7 @@ PartitionFlushBlocks (
**/
EFI_STATUS
ProbeMediaStatusEx (
IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
IN EFI_DISK_IO2_PROTOCOL *DiskIo2,
IN UINT32 MediaId,
IN EFI_STATUS DefaultStatus
)
@ -718,16 +738,9 @@ ProbeMediaStatusEx (
EFI_STATUS Status;
//
// Read from LBA 0 but passing NULL as buffer pointer to detect the media status.
// Read 1 byte from offset 0 but passing NULL as buffer pointer
//
Status = BlockIo2->ReadBlocksEx (
BlockIo2,
MediaId,
0,
NULL,
0,
NULL
);
Status = DiskIo2->ReadDiskEx (DiskIo2, MediaId, 0, NULL, 1, NULL);
if ((Status == EFI_NO_MEDIA) || (Status == EFI_MEDIA_CHANGED)) {
return Status;
}
@ -762,6 +775,68 @@ PartitionResetEx (
);
}
/**
The general callback for the DiskIo2 interfaces.
@param Event Event whose notification function is being invoked.
@param Context The pointer to the notification function's context,
which points to the PARTITION_ACCESS_TASK instance.
**/
VOID
EFIAPI
PartitionOnAccessComplete (
IN EFI_EVENT Event,
IN VOID *Context
)
{
PARTITION_ACCESS_TASK *Task;
Task = (PARTITION_ACCESS_TASK *) Context;
gBS->CloseEvent (Event);
Task->BlockIo2Token->TransactionStatus = Task->DiskIo2Token.TransactionStatus;
gBS->SignalEvent (Task->BlockIo2Token->Event);
FreePool (Task);
}
/**
Create a new PARTITION_ACCESS_TASK instance.
@param Token Pointer to the EFI_BLOCK_IO2_TOKEN.
@return Pointer to the created PARTITION_ACCESS_TASK instance or NULL upon failure.
**/
PARTITION_ACCESS_TASK *
PartitionCreateAccessTask (
IN EFI_BLOCK_IO2_TOKEN *Token
)
{
EFI_STATUS Status;
PARTITION_ACCESS_TASK *Task;
Task = AllocatePool (sizeof (*Task));
if (Task == NULL) {
return NULL;
}
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
PartitionOnAccessComplete,
Task,
&Task->DiskIo2Token.Event
);
if (EFI_ERROR (Status)) {
FreePool (Task);
return NULL;
}
Task->BlockIo2Token = Token;
return Task;
}
/**
Read BufferSize bytes from Lba into Buffer.
@ -806,44 +881,38 @@ PartitionReadBlocksEx (
OUT VOID *Buffer
)
{
EFI_STATUS Status;
PARTITION_PRIVATE_DATA *Private;
UINT64 Offset;
UINT32 UnderRun;
PARTITION_ACCESS_TASK *Task;
Private = PARTITION_DEVICE_FROM_BLOCK_IO2_THIS (This);
if (Token == NULL) {
return ProbeMediaStatusEx (Private->ParentBlockIo2, MediaId, EFI_INVALID_PARAMETER);
}
if (BufferSize % Private->BlockSize != 0) {
return ProbeMediaStatusEx (Private->ParentBlockIo2, MediaId, EFI_BAD_BUFFER_SIZE);
return ProbeMediaStatusEx (Private->DiskIo2, MediaId, EFI_BAD_BUFFER_SIZE);
}
Offset = MultU64x32 (Lba, Private->BlockSize) + Private->Start;
if (Offset + BufferSize > Private->End) {
return ProbeMediaStatusEx (Private->ParentBlockIo2, MediaId, EFI_INVALID_PARAMETER);
return ProbeMediaStatusEx (Private->DiskIo2, MediaId, EFI_INVALID_PARAMETER);
}
//
// Since the BlockIO2 call Parent BlockIO2 directly, so here the offset must
// be multiple of BlockSize. If the Spec will be updated the DiskIO to support
// BlockIO2, this limitation will be removed and call DiskIO here.
//
Lba = DivU64x32Remainder (Offset, Private->BlockSize, &UnderRun);
if (UnderRun != 0) {
return ProbeMediaStatusEx (Private->ParentBlockIo2, MediaId, EFI_UNSUPPORTED);
if ((Token != NULL) && (Token->Event != NULL)) {
Task = PartitionCreateAccessTask (Token);
if (Task == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Status = Private->DiskIo2->ReadDiskEx (Private->DiskIo2, MediaId, Offset, &Task->DiskIo2Token, BufferSize, Buffer);
if (EFI_ERROR (Status)) {
gBS->CloseEvent (Task->DiskIo2Token.Event);
FreePool (Task);
}
} else {
Status = Private->DiskIo2->ReadDiskEx (Private->DiskIo2, MediaId, Offset, NULL, BufferSize, Buffer);
}
//
// Because some partitions have different block size from their parent
// device, in that case the Block I/O2 couldn't be called.
//
if (Private->BlockSize != Private->ParentBlockIo->Media->BlockSize) {
return ProbeMediaStatusEx (Private->ParentBlockIo2, MediaId, EFI_UNSUPPORTED);
}
return Private->ParentBlockIo2->ReadBlocksEx (Private->ParentBlockIo2, MediaId, Lba, Token, BufferSize, Buffer);
return Status;
}
/**
@ -888,44 +957,37 @@ PartitionWriteBlocksEx (
IN VOID *Buffer
)
{
EFI_STATUS Status;
PARTITION_PRIVATE_DATA *Private;
UINT64 Offset;
UINT32 UnderRun;
PARTITION_ACCESS_TASK *Task;
Private = PARTITION_DEVICE_FROM_BLOCK_IO2_THIS (This);
if (Token == NULL) {
return ProbeMediaStatusEx (Private->ParentBlockIo2, MediaId, EFI_INVALID_PARAMETER);
}
if (BufferSize % Private->BlockSize != 0) {
return ProbeMediaStatusEx (Private->ParentBlockIo2, MediaId, EFI_BAD_BUFFER_SIZE);
return ProbeMediaStatusEx (Private->DiskIo2, MediaId, EFI_BAD_BUFFER_SIZE);
}
Offset = MultU64x32 (Lba, Private->BlockSize) + Private->Start;
if (Offset + BufferSize > Private->End) {
return ProbeMediaStatusEx (Private->ParentBlockIo2, MediaId, EFI_INVALID_PARAMETER);
return ProbeMediaStatusEx (Private->DiskIo2, MediaId, EFI_INVALID_PARAMETER);
}
//
// Since the BlockIO2 call Parent BlockIO2 directly, so here the offset must
// be multiple of BlockSize. If the Spec will be updated the DiskIO to support
// BlockIO2, this limitation will be removed and call DiskIO here.
//
Lba = DivU64x32Remainder (Offset, Private->BlockSize, &UnderRun);
if (UnderRun != 0) {
return ProbeMediaStatusEx (Private->ParentBlockIo2, MediaId, EFI_UNSUPPORTED);
}
if ((Token != NULL) && (Token->Event != NULL)) {
Task = PartitionCreateAccessTask (Token);
if (Task == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Because some kinds of partition have different block size from their parent,
// in that case it couldn't call parent Block I/O2.
//
if (Private->BlockSize != Private->ParentBlockIo->Media->BlockSize) {
return ProbeMediaStatusEx (Private->ParentBlockIo2, MediaId, EFI_UNSUPPORTED);
Status = Private->DiskIo2->WriteDiskEx (Private->DiskIo2, MediaId, Offset, &Task->DiskIo2Token, BufferSize, Buffer);
if (EFI_ERROR (Status)) {
gBS->CloseEvent (Task->DiskIo2Token.Event);
FreePool (Task);
}
} else {
Status = Private->DiskIo2->WriteDiskEx (Private->DiskIo2, MediaId, Offset, NULL, BufferSize, Buffer);
}
return Private->ParentBlockIo2->WriteBlocksEx (Private->ParentBlockIo2, MediaId, Lba, Token, BufferSize, Buffer);
return Status;
}
/**
@ -957,19 +1019,27 @@ PartitionFlushBlocksEx (
IN OUT EFI_BLOCK_IO2_TOKEN *Token
)
{
EFI_STATUS Status;
PARTITION_PRIVATE_DATA *Private;
PARTITION_ACCESS_TASK *Task;
Private = PARTITION_DEVICE_FROM_BLOCK_IO2_THIS (This);
//
// Because some kinds of partition have different block size from their parent,
// in that case it couldn't call parent Block I/O2.
//
if (Private->BlockSize != Private->ParentBlockIo->Media->BlockSize) {
return EFI_UNSUPPORTED;
}
if ((Token != NULL) && (Token->Event != NULL)) {
Task = PartitionCreateAccessTask (Token);
if (Task == NULL) {
return EFI_OUT_OF_RESOURCES;
}
return Private->ParentBlockIo2->FlushBlocksEx (Private->ParentBlockIo2, Token);
Status = Private->DiskIo2->FlushDiskEx (Private->DiskIo2, &Task->DiskIo2Token);
if (EFI_ERROR (Status)) {
gBS->CloseEvent (Task->DiskIo2Token.Event);
FreePool (Task);
}
} else {
Status = Private->DiskIo2->FlushDiskEx (Private->DiskIo2, NULL);
}
return Status;
}
@ -980,6 +1050,7 @@ PartitionFlushBlocksEx (
@param[in] This Protocol instance pointer.
@param[in] ParentHandle Parent Handle for new child.
@param[in] ParentDiskIo Parent DiskIo interface.
@param[in] ParentDiskIo2 Parent DiskIo2 interface.
@param[in] ParentBlockIo Parent BlockIo interface.
@param[in] ParentBlockIo2 Parent BlockIo2 interface.
@param[in] ParentDevicePath Parent Device Path.
@ -998,6 +1069,7 @@ PartitionInstallChildHandle (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ParentHandle,
IN EFI_DISK_IO_PROTOCOL *ParentDiskIo,
IN EFI_DISK_IO2_PROTOCOL *ParentDiskIo2,
IN EFI_BLOCK_IO_PROTOCOL *ParentBlockIo,
IN EFI_BLOCK_IO2_PROTOCOL *ParentBlockIo2,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
@ -1026,6 +1098,7 @@ PartitionInstallChildHandle (
Private->ParentBlockIo = ParentBlockIo;
Private->ParentBlockIo2 = ParentBlockIo2;
Private->DiskIo = ParentDiskIo;
Private->DiskIo2 = ParentDiskIo2;
//
// Set the BlockIO into Private Data.
@ -1043,7 +1116,8 @@ PartitionInstallChildHandle (
//
// Set the BlockIO2 into Private Data.
//
if (Private->ParentBlockIo2 != NULL) {
if (Private->DiskIo2 != NULL) {
ASSERT (Private->ParentBlockIo2 != NULL);
Private->BlockIo2.Media = &Private->Media2;
CopyMem (Private->BlockIo2.Media, ParentBlockIo2->Media, sizeof (EFI_BLOCK_IO_MEDIA));
@ -1065,9 +1139,7 @@ PartitionInstallChildHandle (
Private->Media.BlockSize = (UINT32) BlockSize;
//
// For BlockIO2, it should keep the same alignment with the parent BlockIO2's.
//
Private->Media2.IoAlign = 0;
Private->Media2.LogicalPartition = TRUE;
Private->Media2.LastBlock = Private->Media.LastBlock;
Private->Media2.BlockSize = (UINT32) BlockSize;
@ -1105,17 +1177,9 @@ PartitionInstallChildHandle (
//
// Create the new handle.
// BlockIO2 will be installed on the condition that the blocksize of parent BlockIO
// is same with the child BlockIO's. Instead of calling the DiskIO, the child BlockIO2
// directly call the parent BlockIO and doesn't handle the different block size issue.
// If SPEC will update the DiskIO to support the Non-Blocking model, the BlockIO2 will call
// DiskIO to handle the blocksize unequal issue and the limitation will be remove from
// here.
//
Private->Handle = NULL;
if ((Private->ParentBlockIo2 != NULL) &&
(Private->ParentBlockIo2->Media->BlockSize == BlockSize)
) {
if (Private->DiskIo2 != NULL) {
Status = gBS->InstallMultipleProtocolInterfaces (
&Private->Handle,
&gEfiDevicePathProtocolGuid,

View File

@ -26,6 +26,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/DevicePath.h>
#include <Protocol/DriverBinding.h>
#include <Protocol/DiskIo.h>
#include <Protocol/DiskIo2.h>
#include <Library/DebugLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/BaseLib.h>
@ -54,6 +55,7 @@ typedef struct {
EFI_BLOCK_IO_MEDIA Media2;//For BlockIO2
EFI_DISK_IO_PROTOCOL *DiskIo;
EFI_DISK_IO2_PROTOCOL *DiskIo2;
EFI_BLOCK_IO_PROTOCOL *ParentBlockIo;
EFI_BLOCK_IO2_PROTOCOL *ParentBlockIo2;
UINT64 Start;
@ -64,6 +66,11 @@ typedef struct {
} PARTITION_PRIVATE_DATA;
typedef struct {
EFI_DISK_IO2_TOKEN DiskIo2Token;
EFI_BLOCK_IO2_TOKEN *BlockIo2Token;
} PARTITION_ACCESS_TASK;
#define PARTITION_DEVICE_FROM_BLOCK_IO_THIS(a) CR (a, PARTITION_PRIVATE_DATA, BlockIo, PARTITION_PRIVATE_DATA_SIGNATURE)
#define PARTITION_DEVICE_FROM_BLOCK_IO2_THIS(a) CR (a, PARTITION_PRIVATE_DATA, BlockIo2, PARTITION_PRIVATE_DATA_SIGNATURE)
@ -308,6 +315,7 @@ PartitionComponentNameGetControllerName (
@param[in] This Protocol instance pointer.
@param[in] ParentHandle Parent Handle for new child.
@param[in] ParentDiskIo Parent DiskIo interface.
@param[in] ParentDiskIo2 Parent DiskIo2 interface.
@param[in] ParentBlockIo Parent BlockIo interface.
@param[in] ParentBlockIo2 Parent BlockIo2 interface.
@param[in] ParentDevicePath Parent Device Path.
@ -326,6 +334,7 @@ PartitionInstallChildHandle (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ParentHandle,
IN EFI_DISK_IO_PROTOCOL *ParentDiskIo,
IN EFI_DISK_IO2_PROTOCOL *ParentDiskIo2,
IN EFI_BLOCK_IO_PROTOCOL *ParentBlockIo,
IN EFI_BLOCK_IO2_PROTOCOL *ParentBlockIo2,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
@ -342,6 +351,7 @@ PartitionInstallChildHandle (
@param[in] This Calling context.
@param[in] Handle Parent Handle.
@param[in] DiskIo Parent DiskIo interface.
@param[in] DiskIo2 Parent DiskIo2 interface.
@param[in] BlockIo Parent BlockIo interface.
@param[in] BlockIo2 Parent BlockIo2 interface.
@param[in] DevicePath Parent Device Path.
@ -357,6 +367,7 @@ PartitionInstallGptChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_DISK_IO2_PROTOCOL *DiskIo2,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
@ -368,6 +379,7 @@ PartitionInstallGptChildHandles (
@param[in] This Calling context.
@param[in] Handle Parent Handle.
@param[in] DiskIo Parent DiskIo interface.
@param[in] DiskIo2 Parent DiskIo2 interface.
@param[in] BlockIo Parent BlockIo interface.
@param[in] BlockIo2 Parent BlockIo2 interface.
@param[in] DevicePath Parent Device Path
@ -383,6 +395,7 @@ PartitionInstallElToritoChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_DISK_IO2_PROTOCOL *DiskIo2,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
@ -394,6 +407,7 @@ PartitionInstallElToritoChildHandles (
@param[in] This Calling context.
@param[in] Handle Parent Handle.
@param[in] DiskIo Parent DiskIo interface.
@param[in] DiskIo2 Parent DiskIo2 interface.
@param[in] BlockIo Parent BlockIo interface.
@param[in] BlockIo2 Parent BlockIo2 interface.
@param[in] DevicePath Parent Device Path.
@ -408,6 +422,7 @@ PartitionInstallMbrChildHandles (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_DISK_IO2_PROTOCOL *DiskIo2,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
@ -419,6 +434,7 @@ EFI_STATUS
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Handle,
IN EFI_DISK_IO_PROTOCOL *DiskIo,
IN EFI_DISK_IO2_PROTOCOL *DiskIo2,
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath

View File

@ -12,7 +12,7 @@
# This external input must be validated carefully to avoid security issue like
# buffer overflow, integer overflow.
#
# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2006 - 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
@ -74,7 +74,9 @@
gEfiBlockIoProtocolGuid ## BY_START
gEfiDevicePathProtocolGuid ## BY_START
gEfiDiskIoProtocolGuid ## BY_START
gEfiDiskIo2ProtocolGuid ## BY_START
gEfiBlockIoProtocolGuid ## TO_START
gEfiBlockIo2ProtocolGuid ## TO_START
gEfiDevicePathProtocolGuid ## TO_START
gEfiDiskIoProtocolGuid ## TO_START
gEfiDiskIo2ProtocolGuid ## TO_START

View File

@ -0,0 +1,173 @@
/** @file
Disk IO protocol as defined in the UEFI 2.0 specification.
The Disk IO2 protocol is used to convert block oriented devices into byte
oriented devices. The Disk IO protocol is intended to layer on top of the
Block IO protocol.
Copyright (c) 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
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef __DISK_IO2_H__
#define __DISK_IO2_H__
#define EFI_DISK_IO2_PROTOCOL_GUID \
{ \
0x151c8eae, 0x7f2c, 0x472c, 0x9e, 0x54, 0x98, 0x28, 0x19, 0x4f, 0x6a, 0x88 \
}
typedef struct _EFI_DISK_IO2_PROTOCOL EFI_DISK_IO2_PROTOCOL;
/**
The struct of Disk IO2 Token.
**/
typedef struct {
//
// If Event is NULL, then blocking I/O is performed.
// If Event is not NULL and non-blocking I/O is supported, then non-blocking I/O is performed,
// and Event will be signaled when the I/O request is completed.
// The caller must be prepared to handle the case where the callback associated with Event occurs
// before the original asynchronous I/O request call returns.
//
EFI_EVENT Event;
//
// Defines whether or not the signaled event encountered an error.
//
EFI_STATUS TransactionStatus;
} EFI_DISK_IO2_TOKEN;
/**
Terminate outstanding asynchronous requests to a device.
@param This Indicates a pointer to the calling context.
@retval EFI_SUCCESS All outstanding requests were successfully terminated.
@retval EFI_DEVICE_ERROR The device reported an error while performing the cancel
operation.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_DISK_CANCEL_EX) (
IN EFI_DISK_IO2_PROTOCOL *This
);
/**
Reads a specified number of bytes from a device.
@param This Indicates a pointer to the calling context.
@param MediaId ID of the medium to be read.
@param Offset The starting byte offset on the logical block I/O device to read from.
@param Token A pointer to the token associated with the transaction.
If this field is NULL, synchronous/blocking IO is performed.
@param BufferSize The size in bytes of Buffer. The number of bytes to read from the device.
@param Buffer A pointer to the destination buffer for the data.
The caller is responsible either having implicit or explicit ownership of the buffer.
@retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read correctly from the device.
If Event is not NULL (asynchronous I/O): The request was successfully queued for processing.
Event will be signaled upon completion.
@retval EFI_DEVICE_ERROR The device reported an error while performing the write.
@retval EFI_NO_MEDIA There is no medium in the device.
@retval EFI_MEDIA_CHNAGED The MediaId is not for the current medium.
@retval EFI_INVALID_PARAMETER The read request contains device addresses that are not valid for the device.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_DISK_READ_EX) (
IN EFI_DISK_IO2_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 Offset,
IN OUT EFI_DISK_IO2_TOKEN *Token,
IN UINTN BufferSize,
OUT VOID *Buffer
);
/**
Writes a specified number of bytes to a device.
@param This Indicates a pointer to the calling context.
@param MediaId ID of the medium to be written.
@param Offset The starting byte offset on the logical block I/O device to write to.
@param Token A pointer to the token associated with the transaction.
If this field is NULL, synchronous/blocking IO is performed.
@param BufferSize The size in bytes of Buffer. The number of bytes to write to the device.
@param Buffer A pointer to the buffer containing the data to be written.
@retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was written correctly to the device.
If Event is not NULL (asynchronous I/O): The request was successfully queued for processing.
Event will be signaled upon completion.
@retval EFI_WRITE_PROTECTED The device cannot be written to.
@retval EFI_DEVICE_ERROR The device reported an error while performing the write operation.
@retval EFI_NO_MEDIA There is no medium in the device.
@retval EFI_MEDIA_CHNAGED The MediaId is not for the current medium.
@retval EFI_INVALID_PARAMETER The write request contains device addresses that are not valid for the device.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_DISK_WRITE_EX) (
IN EFI_DISK_IO2_PROTOCOL *This,
IN UINT32 MediaId,
IN UINT64 Offset,
IN OUT EFI_DISK_IO2_TOKEN *Token,
IN UINTN BufferSize,
IN VOID *Buffer
);
/**
Flushes all modified data to the physical device.
@param This Indicates a pointer to the calling context.
@param MediaId ID of the medium to be written.
@param Token A pointer to the token associated with the transaction.
If this field is NULL, synchronous/blocking IO is performed.
@retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was flushed successfully to the device.
If Event is not NULL (asynchronous I/O): The request was successfully queued for processing.
Event will be signaled upon completion.
@retval EFI_WRITE_PROTECTED The device cannot be written to.
@retval EFI_DEVICE_ERROR The device reported an error while performing the write operation.
@retval EFI_NO_MEDIA There is no medium in the device.
@retval EFI_MEDIA_CHNAGED The MediaId is not for the current medium.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_DISK_FLUSH_EX) (
IN EFI_DISK_IO2_PROTOCOL *This,
IN OUT EFI_DISK_IO2_TOKEN *Token
);
#define EFI_DISK_IO2_PROTOCOL_REVISION 0x00020000
///
/// This protocol is used to abstract Block I/O interfaces.
///
struct _EFI_DISK_IO2_PROTOCOL {
///
/// The revision to which the disk I/O interface adheres. All future
/// revisions must be backwards compatible. If a future version is not
/// backwards compatible, it is not the same GUID.
///
UINT64 Revision;
EFI_DISK_CANCEL_EX Cancel;
EFI_DISK_READ_EX ReadDiskEx;
EFI_DISK_WRITE_EX WriteDiskEx;
EFI_DISK_FLUSH_EX FlushDiskEx;
};
extern EFI_GUID gEfiDiskIo2ProtocolGuid;
#endif

View File

@ -5,7 +5,7 @@
# It also provides the definitions(including PPIs/PROTOCOLs/GUIDs) of
# EFI1.10/UEFI2.3.1/PI1.2 and some Industry Standards.
#
# Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available under
@ -1290,10 +1290,16 @@
gEfiBlockIo2ProtocolGuid = { 0xa77b2472, 0xe282, 0x4e9f, {0xa2, 0x45, 0xc2, 0xc0, 0xe2, 0x7b, 0xbc, 0xc1 }}
## Include/Protocol/StorageSecurityCommand.h
gEfiStorageSecurityCommandProtocolGuid = { 0xc88b0b6d, 0x0dfc, 0x49a7, {0x9c, 0xb4, 0x49, 0x7, 0x4b, 0x4c, 0x3a, 0x78 }}
gEfiStorageSecurityCommandProtocolGuid = { 0xc88b0b6d, 0x0dfc, 0x49a7, {0x9c, 0xb4, 0x49, 0x7, 0x4b, 0x4c, 0x3a, 0x78 }}
## Include/Protocol/UserCredential2.h
gEfiUserCredential2ProtocolGuid = { 0xe98adb03, 0xb8b9, 0x4af8, {0xba, 0x20, 0x26, 0xe9, 0x11, 0x4c, 0xbc, 0xe5 }}
gEfiUserCredential2ProtocolGuid = { 0xe98adb03, 0xb8b9, 0x4af8, {0xba, 0x20, 0x26, 0xe9, 0x11, 0x4c, 0xbc, 0xe5 }}
#
# Protocols defined in UEFI2.4
#
## Include/Protocol/DiskIo2.h
gEfiDiskIo2ProtocolGuid = { 0x151c8eae, 0x7f2c, 0x472c, { 0x9e, 0x54, 0x98, 0x28, 0x19, 0x4f, 0x6a, 0x88 }}
[PcdsFeatureFlag]
## If TRUE, the component name protocol will not be installed.