/**
Read BufferSize bytes from Lba into Buffer.
This function reads the requested number of blocks from the device. All the
blocks are read, or an error is returned.
If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_or EFI_MEDIA_CHANGED is returned and
non-blocking I/O is being used, the Event associated with this request will
not be signaled.
@param[in] This Indicates a pointer to the calling context.
@param[in] MediaId Id of the media, changes every time the media is
replaced.
@param[in] Lba The starting Logical Block Address to read from.
@param[in, out] Token A pointer to the token associated with the transaction.
@param[in] BufferSize Size of Buffer, must be a multiple of device block size.
@param[out] Buffer A pointer to the destination buffer for the data. The
caller is responsible for either having implicit or
explicit ownership of the buffer.
@retval EFI_SUCCESS The read request was queued if Token->Event is
not NULL.The data was read correctly from the
device if the Token->Event is NULL.
@retval EFI_DEVICE_ERROR The device reported an error while performing
the read.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
@retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
intrinsic block size of the device.
@retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
or the buffer is not on proper alignment.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
of resources.
**/
EFI_STATUS
EmuBlockIoReadBlocks (
IN EMU_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA LBA,
IN OUT EFI_BLOCK_IO2_TOKEN *Token,
IN UINTN BufferSize,
OUT VOID *Buffer
)
{
EFI_STATUS Status;
EMU_BLOCK_IO_PRIVATE *Private;
ssize_t len;
Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);
Status = EmuBlockIoReadWriteCommon (Private, MediaId, LBA, BufferSize, Buffer, "UnixReadBlocks");
if (EFI_ERROR (Status)) {
goto Done;
}
len = read (Private->fd, Buffer, BufferSize);
if (len != BufferSize) {
DEBUG ((EFI_D_INIT, "ReadBlocks: ReadFile failed.\n"));
Status = EmuBlockIoError (Private);
goto Done;
}
//
// If we read then media is present.
//
Private->Media->MediaPresent = TRUE;
Status = EFI_SUCCESS;
Done:
if (Token != NULL) {
if (Token->Event != NULL) {
// Caller is responsible for signaling EFI Event
Token->TransactionStatus = Status;
return EFI_SUCCESS;
}
}
return Status;
}