/** @file
DiskIoDxe.h -- Header for DiskIoDxe
Copyright (c) HR650X BIOS Decompilation Project
**/
#ifndef __DISKIODXE_H__
#define __DISKIODXE_H__
#include "../uefi_headers/Uefi.h"
//
// Function Prototypes
//
EFI_STATUS
EFIAPI
InternalAssert(
VOID
);
EFI_STATUS
EFIAPI
_ModuleEntryPoint(
VOID
);
EFI_STATUS
EFIAPI
DiskIoDxeInstallProtocols(
VOID
);
EFI_STATUS
EFIAPI
DiskIoDriverBindingSupported(
VOID
);
EFI_STATUS
EFIAPI
DiskIoDriverBindingStart(
VOID
);
EFI_STATUS
EFIAPI
DiskIoDriverBindingStop(
VOID
);
EFI_STATUS
EFIAPI
DiskIoReadDisk(
VOID
);
EFI_STATUS
EFIAPI
DiskIoWriteDisk(
VOID
);
EFI_STATUS
EFIAPI
DiskIo2ReadDiskEx(
VOID
);
EFI_STATUS
EFIAPI
DiskIo2WriteDiskEx(
VOID
);
EFI_STATUS
EFIAPI
DiskIo2FlushDiskEx(
VOID
);
EFI_STATUS
EFIAPI
DiskIo2Cancel(
VOID
);
EFI_STATUS
EFIAPI
DiskIoRequest(
VOID
);
EFI_STATUS
EFIAPI
DiskIoCreateSubtasks(
VOID
);
EFI_STATUS
EFIAPI
DiskIoSubtaskCallback(
VOID
);
EFI_STATUS
EFIAPI
DiskIoCheckAllSubtasksCompleted(
VOID
);
EFI_STATUS
EFIAPI
DiskIoComponentNameGetDriverName(
VOID
);
EFI_STATUS
EFIAPI
DiskIoComponentNameGetControllerName(
VOID
);
EFI_STATUS
EFIAPI
ProcessLibraryConstructorList(
VOID
);
EFI_STATUS
EFIAPI
globals (set by _ModuleEntryPoint at 0x390)(
VOID
);
EFI_STATUS
EFIAPI
gImageHandle = NULL;(
VOID
);
EFI_STATUS
EFIAPI
print error level protocol (lazily resolved)(
VOID
);
EFI_STATUS
EFIAPI
in the binary(
VOID
);
EFI_STATUS
EFIAPI
*gDebugPrintErrorLevelProtocol = NULL;(
VOID
);
EFI_STATUS
EFIAPI
Binding Protocol instance(
VOID
);
EFI_STATUS
EFIAPI
in DiskIoDxeInstallProtocols (sub_448)(
VOID
);
EFI_STATUS
EFIAPI
gDiskIoDriverBinding = {(
VOID
);
EFI_STATUS
EFIAPI
NULL, // ImageHandle - set during binding(
VOID
);
EFI_STATUS
EFIAPI
- set by InstallMultipleProtocolInterfaces(
VOID
);
EFI_STATUS
EFIAPI
Name tables (at .rdata +0x3868 and +0x3880)(
VOID
);
EFI_STATUS
EFIAPI
as: { GetDriverName, GetControllerName, DriverNameString }(
VOID
);
EFI_STATUS
EFIAPI
GetDriverName = DiskIoComponentNameGetDriverName (0x1CEC)(
VOID
);
EFI_STATUS
EFIAPI
= DiskIoComponentNameGetControllerName (0x1E48)(
VOID
);
EFI_STATUS
EFIAPI
= "Generic Disk I/O Driver" (0x2EA0) for COMPONENT_NAME(
VOID
);
EFI_STATUS
EFIAPI
= "Disk I/O Driver" (0x2E94 "eng;en" table) for COMPONENT_NAME2(
VOID
);
EFI_STATUS
EFIAPI
gDiskIoComponentName = {(
VOID
);
EFI_STATUS
EFIAPI
Languages(
VOID
);
EFI_STATUS
EFIAPI
declarations for library-internal helpers(
VOID
);
EFI_STATUS
EFIAPI
Entry Point(
VOID
);
EFI_STATUS
EFIAPI
library constructors (sub_26D0)(
VOID
);
EFI_STATUS
EFIAPI
calls ProcessLibraryConstructorList to initialize HOB list, etc.(
VOID
);
EFI_STATUS
EFIAPI
();(
VOID
);
EFI_STATUS
EFIAPI
the driver binding and component name protocols (sub_448)(
VOID
);
EFI_STATUS
EFIAPI
DiskIoDxeInstallProtocols (ImageHandle);(
VOID
);
EFI_STATUS
EFIAPI
Installation(
VOID
);
EFI_STATUS
EFIAPI
Binding Protocol: Supported, Start, Stop(
VOID
);
EFI_STATUS
EFIAPI
a pool tag (8 bytes) for tracking(
VOID
);
EFI_STATUS
EFIAPI
= gBootServices->AllocatePool (EfiBootServicesData, sizeof (EFI_HANDLE));(
VOID
);
EFI_STATUS
EFIAPI
Block I/O protocol BY_DRIVER(
VOID
);
EFI_STATUS
EFIAPI
= gBootServices->OpenProtocol ((
VOID
);
EFI_STATUS
EFIAPI
open Block I/O 2 protocol BY_DRIVER(
VOID
);
EFI_STATUS
EFIAPI
and initialize the private data structure(
VOID
);
EFI_STATUS
EFIAPI
= InternalAllocateCopyPool (BlockIo2, sizeof (DISK_IO_PRIVATE_DATA));(
VOID
);
EFI_STATUS
EFIAPI
BlockIo vs BlockIo2 alignment consistency(
VOID
);
EFI_STATUS
EFIAPI
(BlockIo2 != NULL) {(
VOID
);
EFI_STATUS
EFIAPI
DiskIo protocol interface (at Instance + 0x08)(
VOID
);
EFI_STATUS
EFIAPI
DiskIo2 protocol interface (at Instance + 0x28)(
VOID
);
EFI_STATUS
EFIAPI
the task list(
VOID
);
EFI_STATUS
EFIAPI
(&Instance->TaskList);(
VOID
);
EFI_STATUS
EFIAPI
the EFI lock (LockType=16, Tpl=4, EfiLockReleased=1)(
VOID
);
EFI_STATUS
EFIAPI
(&Instance->TaskListLock, TPL_NOTIFY);(
VOID
);
EFI_STATUS
EFIAPI
an aligned media buffer for bouncing unaligned transfers(
VOID
);
EFI_STATUS
EFIAPI
= BlockIo->Media->BlockSize;(
VOID
);
EFI_STATUS
EFIAPI
the Disk I/O protocols on the controller handle(
VOID
);
EFI_STATUS
EFIAPI
failure, free the aligned buffer and instance(
VOID
);
EFI_STATUS
EFIAPI
((
VOID
);
EFI_STATUS
EFIAPI
the installed DiskIo protocol to get our private instance(
VOID
);
EFI_STATUS
EFIAPI
macro: DiskIo is at Instance + 0x08 (offset 8)(
VOID
);
EFI_STATUS
EFIAPI
= CR (DiskIo, DISK_IO_PRIVATE_DATA, DiskIo, DISK_IO_PRIVATE_DATA_SIGNATURE);(
VOID
);
EFI_STATUS
EFIAPI
all outstanding non-blocking I/O(
VOID
);
EFI_STATUS
EFIAPI
{(
VOID
);
EFI_STATUS
EFIAPI
protocols(
VOID
);
EFI_STATUS
EFIAPI
(Instance->BlockIo2 != NULL) {(
VOID
);
EFI_STATUS
EFIAPI
the aligned media buffer(
VOID
);
EFI_STATUS
EFIAPI
(Instance->MediaBuffer != NULL) {(
VOID
);
EFI_STATUS
EFIAPI
the underlying Block I/O protocols(
VOID
);
EFI_STATUS
EFIAPI
the instance(
VOID
);
EFI_STATUS
EFIAPI
(Instance);(
VOID
);
EFI_STATUS
EFIAPI
Implementation(
VOID
);
EFI_STATUS
EFIAPI
flush(
VOID
);
EFI_STATUS
EFIAPI
Instance->BlockIo2->FlushBlocksEx (Instance->BlockIo2, NULL);(
VOID
);
EFI_STATUS
EFIAPI
= InternalAllocatePool (EfiBootServicesData, sizeof (DISK_IO_FLUSH_TASK));(
VOID
);
EFI_STATUS
EFIAPI
a notification event(
VOID
);
EFI_STATUS
EFIAPI
= gBootServices->CreateEvent ((
VOID
);
EFI_STATUS
EFIAPI
to BlockIo2 with our event(
VOID
);
EFI_STATUS
EFIAPI
= Instance->BlockIo2->FlushBlocksEx (Instance->BlockIo2, FlushTask->Event);(
VOID
);
EFI_STATUS
EFIAPI
(&Instance->TaskListLock);(
VOID
);
EFI_STATUS
EFIAPI
= GetFirstNode (&Instance->TaskList);(
VOID
);
EFI_STATUS
EFIAPI
this task: abort the user's token(
VOID
);
EFI_STATUS
EFIAPI
(Task->Token != NULL) {(
VOID
);
EFI_STATUS
EFIAPI
the task (implicitly removes from list)(
VOID
);
EFI_STATUS
EFIAPI
(Entry);(
VOID
);
EFI_STATUS
EFIAPI
I/O Dispatcher: DiskIoRequest(
VOID
);
EFI_STATUS
EFIAPI
= FALSE;(
VOID
);
EFI_STATUS
EFIAPI
for previous non-blocking requests to drain(
VOID
);
EFI_STATUS
EFIAPI
(!DiskIoCheckAllSubtasksCompleted (Instance)) {(
VOID
);
EFI_STATUS
EFIAPI
until all subtasks complete(
VOID
);
EFI_STATUS
EFIAPI
a DISK_IO_TASK (0x50 bytes)(
VOID
);
EFI_STATUS
EFIAPI
= InternalAllocatePool (EfiBootServicesData, sizeof (DISK_IO_TASK));(
VOID
);
EFI_STATUS
EFIAPI
the task into the instance's task list(
VOID
);
EFI_STATUS
EFIAPI
(&Instance->TaskList, &Task->Link);(
VOID
);
EFI_STATUS
EFIAPI
the subtask list for this task(
VOID
);
EFI_STATUS
EFIAPI
(&Task->SubtaskList);(
VOID
);
EFI_STATUS
EFIAPI
the subtasks(
VOID
);
EFI_STATUS
EFIAPI
path (Token == NULL or Token->Event == NULL)(
VOID
);
EFI_STATUS
EFIAPI
= TRUE;(
VOID
);
EFI_STATUS
EFIAPI
local stack variable for the subtask list head(
VOID
);
EFI_STATUS
EFIAPI
(&SubtaskList);(
VOID
);
EFI_STATUS
EFIAPI
Instance->MediaBuffer(
VOID
);
EFI_STATUS
EFIAPI
no subtasks were created, clean up and return error(
VOID
);
EFI_STATUS
EFIAPI
(IsListEmpty (SubtaskListPtr)) {(
VOID
);
EFI_STATUS
EFIAPI
all subtasks(
VOID
);
EFI_STATUS
EFIAPI
= EFI_SUCCESS;(
VOID
);
EFI_STATUS
EFIAPI
block alignment(
VOID
);
EFI_STATUS
EFIAPI
((Subtask->Length % BlockSize != 0) && (Subtask->Length >= BlockSize)) {(
VOID
);
EFI_STATUS
EFIAPI
between BlockIo2 (non-blocking) and BlockIo (blocking)(
VOID
);
EFI_STATUS
EFIAPI
(Subtask->IsWrite) {(
VOID
);
EFI_STATUS
EFIAPI
operation(
VOID
);
EFI_STATUS
EFIAPI
(Subtask->WorkingBuffer != NULL) {(
VOID
);
EFI_STATUS
EFIAPI
from user buffer to bounce buffer first(
VOID
);
EFI_STATUS
EFIAPI
(Subtask->UseBlockIo2) {(
VOID
);
EFI_STATUS
EFIAPI
= BlockIo2->ReadBlocksEx ((
VOID
);
EFI_STATUS
EFIAPI
read via BlockIo(
VOID
);
EFI_STATUS
EFIAPI
= BlockIo->ReadBlocks ((
VOID
);
EFI_STATUS
EFIAPI
blocking reads with bounce buffer: copy to user buffer(
VOID
);
EFI_STATUS
EFIAPI
(!EFI_ERROR (Status) && (Subtask->WorkingBuffer != NULL)) {(
VOID
);
EFI_STATUS
EFIAPI
up completed subtask(
VOID
);
EFI_STATUS
EFIAPI
(Instance, (DISK_IO_TASK *)Subtask);(
VOID
);
EFI_STATUS
EFIAPI
blocking and error: stop processing further subtasks(
VOID
);
EFI_STATUS
EFIAPI
(EFI_ERROR (Status) && !Subtask->UseBlockIo2) {(
VOID
);
EFI_STATUS
EFIAPI
any blocking subtask failed, drain remaining subtask list(
VOID
);
EFI_STATUS
EFIAPI
(EFI_ERROR (Status)) {(
VOID
);
EFI_STATUS
EFIAPI
non-blocking tasks: cleanup and possibly signal completion(
VOID
);
EFI_STATUS
EFIAPI
(!IsBlocking && Task != NULL) {(
VOID
);
EFI_STATUS
EFIAPI
the non-blocking request was effectively blocking (all subtasks(
VOID
);
EFI_STATUS
EFIAPI
synchronously), signal the user's event directly(
VOID
);
EFI_STATUS
EFIAPI
(!EFI_ERROR (Status) && (Task->Token != NULL)) {(
VOID
);
EFI_STATUS
EFIAPI
the task from the instance's task list and free it(
VOID
);
EFI_STATUS
EFIAPI
(&Task->Link);(
VOID
);
EFI_STATUS
EFIAPI
Management(
VOID
);
EFI_STATUS
EFIAPI
starting LBA and offset within first block(
VOID
);
EFI_STATUS
EFIAPI
(Offset, (UINT32)BlockSize, &OffsetInBlock);(
VOID
);
EFI_STATUS
EFIAPI
= DiskIoCreateSubtask ((
VOID
);
EFI_STATUS
EFIAPI
for non-blocking(
VOID
);
EFI_STATUS
EFIAPI
fragment: start is not block-aligned(
VOID
);
EFI_STATUS
EFIAPI
= BlockSize - OffsetInBlock;(
VOID
);
EFI_STATUS
EFIAPI
blocking: use MediaBuffer as the bounce buffer(
VOID
);
EFI_STATUS
EFIAPI
non-blocking: reuse the subtask's own buffer(
VOID
);
EFI_STATUS
EFIAPI
(!IsBlocking) {(
VOID
);
EFI_STATUS
EFIAPI
aligned remaining data(
VOID
);
EFI_STATUS
EFIAPI
(Remaining > 0) {(
VOID
);
EFI_STATUS
EFIAPI
the remaining data is perfectly block-aligned(
VOID
);
EFI_STATUS
EFIAPI
it as one large aligned transfer (no bounce buffer needed)(
VOID
);
EFI_STATUS
EFIAPI
(Remaining % BlockSize == 0) {(
VOID
);
EFI_STATUS
EFIAPI
bounce buffer for aligned transfer(
VOID
);
EFI_STATUS
EFIAPI
aligned full blocks one at a time(
VOID
);
EFI_STATUS
EFIAPI
(Remaining >= BlockSize) {(
VOID
);
EFI_STATUS
EFIAPI
bounce buffer needed(
VOID
);
EFI_STATUS
EFIAPI
unaligned fragment(
VOID
);
EFI_STATUS
EFIAPI
buffer for tail fragment(
VOID
);
EFI_STATUS
EFIAPI
the subtask (0x68 = 104 bytes)(
VOID
);
EFI_STATUS
EFIAPI
= InternalAllocatePool (EfiBootServicesData, sizeof (DISK_IO_SUBTASK));(
VOID
);
EFI_STATUS
EFIAPI
the structure(
VOID
);
EFI_STATUS
EFIAPI
(Subtask, sizeof (DISK_IO_SUBTASK));(
VOID
);
EFI_STATUS
EFIAPI
reads with bounce buffer: copy data to user buffer(
VOID
);
EFI_STATUS
EFIAPI
(!Subtask->IsWrite && (Subtask->WorkingBuffer != NULL)) {(
VOID
);
EFI_STATUS
EFIAPI
the event(
VOID
);
EFI_STATUS
EFIAPI
by the cleanup code in DiskIoRequest(
VOID
);
EFI_STATUS
EFIAPI
from linked list(
VOID
);
EFI_STATUS
EFIAPI
(&Subtask->Link);(
VOID
);
EFI_STATUS
EFIAPI
event if non-blocking subtask(
VOID
);
EFI_STATUS
EFIAPI
(Subtask->Token != NULL) {(
VOID
);
EFI_STATUS
EFIAPI
is actually the subtask's Event field at offset 0x58(
VOID
);
EFI_STATUS
EFIAPI
the allocation(
VOID
);
EFI_STATUS
EFIAPI
(Subtask);(
VOID
);
EFI_STATUS
EFIAPI
completed, signal its token(
VOID
);
EFI_STATUS
EFIAPI
and free the completed task(
VOID
);
EFI_STATUS
EFIAPI
(TaskEntry);(
VOID
);
EFI_STATUS
EFIAPI
Name Protocol(
VOID
);
EFI_STATUS
EFIAPI
component name table at .rdata +0x3868 / +0x3880 contains:(
VOID
);
EFI_STATUS
EFIAPI
COMPONENT_NAME: DriverNameString = "Generic Disk I/O Driver" (0x2EA0)(
VOID
);
EFI_STATUS
EFIAPI
COMPONENT_NAME2: DriverNameString = "eng;en" string table -> "Disk I/O Driver"(
VOID
);
EFI_STATUS
EFIAPI
actual implementation iterates over the language table checking(
VOID
);
EFI_STATUS
EFIAPI
entry against the requested Language parameter.(
VOID
);
EFI_STATUS
EFIAPI
((Language == NULL) || (DriverName == NULL)) {(
VOID
);
EFI_STATUS
EFIAPI
entry with string comparison. For English, returns the known string.(
VOID
);
EFI_STATUS
EFIAPI
Constructors(
VOID
);
EFI_STATUS
EFIAPI
find the DebugPrintErrorLevelLib protocol and cache it.(
VOID
);
EFI_STATUS
EFIAPI
qword_38E0 and qword_38E8, the debug print protocol pointer(
VOID
);
EFI_STATUS
EFIAPI
lazily resolved on first use via DebugPrintErrorLevelLibGetDebug(
VOID
);
#endif /* __DISKIODXE_H__ */