2 Produce EFI_BLOCK_IO_PROTOCOL on a RAM disk device.
4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "RamDiskImpl.h"
18 // The EFI_BLOCK_IO_PROTOCOL instances that is installed onto the handle
19 // for newly registered RAM disks
21 EFI_BLOCK_IO_PROTOCOL mRamDiskBlockIoTemplate
= {
22 EFI_BLOCK_IO_PROTOCOL_REVISION
,
23 (EFI_BLOCK_IO_MEDIA
*) 0,
25 RamDiskBlkIoReadBlocks
,
26 RamDiskBlkIoWriteBlocks
,
27 RamDiskBlkIoFlushBlocks
31 // The EFI_BLOCK_IO_PROTOCOL2 instances that is installed onto the handle
32 // for newly registered RAM disks
34 EFI_BLOCK_IO2_PROTOCOL mRamDiskBlockIo2Template
= {
35 (EFI_BLOCK_IO_MEDIA
*) 0,
37 RamDiskBlkIo2ReadBlocksEx
,
38 RamDiskBlkIo2WriteBlocksEx
,
39 RamDiskBlkIo2FlushBlocksEx
44 Initialize the BlockIO & BlockIO2 protocol of a RAM disk device.
46 @param[in] PrivateData Points to RAM disk private data.
51 IN RAM_DISK_PRIVATE_DATA
*PrivateData
54 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
55 EFI_BLOCK_IO2_PROTOCOL
*BlockIo2
;
56 EFI_BLOCK_IO_MEDIA
*Media
;
58 BlockIo
= &PrivateData
->BlockIo
;
59 BlockIo2
= &PrivateData
->BlockIo2
;
60 Media
= &PrivateData
->Media
;
62 CopyMem (BlockIo
, &mRamDiskBlockIoTemplate
, sizeof (EFI_BLOCK_IO_PROTOCOL
));
63 CopyMem (BlockIo2
, &mRamDiskBlockIo2Template
, sizeof (EFI_BLOCK_IO2_PROTOCOL
));
65 BlockIo
->Media
= Media
;
66 BlockIo2
->Media
= Media
;
67 Media
->RemovableMedia
= FALSE
;
68 Media
->MediaPresent
= TRUE
;
69 Media
->LogicalPartition
= FALSE
;
70 Media
->ReadOnly
= FALSE
;
71 Media
->WriteCaching
= FALSE
;
72 Media
->BlockSize
= RAM_DISK_BLOCK_SIZE
;
73 Media
->LastBlock
= DivU64x32 (
74 PrivateData
->Size
+ RAM_DISK_BLOCK_SIZE
- 1,
81 Reset the Block Device.
83 @param This Indicates a pointer to the calling context.
84 @param ExtendedVerification Driver may perform diagnostics on reset.
86 @retval EFI_SUCCESS The device was reset.
87 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
94 IN EFI_BLOCK_IO_PROTOCOL
*This
,
95 IN BOOLEAN ExtendedVerification
103 Read BufferSize bytes from Lba into Buffer.
105 @param[in] This Indicates a pointer to the calling context.
106 @param[in] MediaId Id of the media, changes every time the media is
108 @param[in] Lba The starting Logical Block Address to read from.
109 @param[in] BufferSize Size of Buffer, must be a multiple of device block
111 @param[out] Buffer A pointer to the destination buffer for the data.
112 The caller is responsible for either having
113 implicit or explicit ownership of the buffer.
115 @retval EFI_SUCCESS The data was read correctly from the device.
116 @retval EFI_DEVICE_ERROR The device reported an error while performing
118 @retval EFI_NO_MEDIA There is no media in the device.
119 @retval EFI_MEDIA_CHANGED The MediaId does not matched the current
121 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block
123 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not
124 valid, or the buffer is not on proper alignment.
129 RamDiskBlkIoReadBlocks (
130 IN EFI_BLOCK_IO_PROTOCOL
*This
,
137 RAM_DISK_PRIVATE_DATA
*PrivateData
;
138 UINTN NumberOfBlocks
;
140 if (Buffer
== NULL
) {
141 return EFI_INVALID_PARAMETER
;
144 if (BufferSize
== 0) {
148 PrivateData
= RAM_DISK_PRIVATE_FROM_BLKIO (This
);
150 if (MediaId
!= PrivateData
->Media
.MediaId
) {
151 return EFI_MEDIA_CHANGED
;
154 if ((BufferSize
% PrivateData
->Media
.BlockSize
) != 0) {
155 return EFI_BAD_BUFFER_SIZE
;
158 if (Lba
> PrivateData
->Media
.LastBlock
) {
159 return EFI_INVALID_PARAMETER
;
162 NumberOfBlocks
= BufferSize
/ PrivateData
->Media
.BlockSize
;
163 if ((Lba
+ NumberOfBlocks
- 1) > PrivateData
->Media
.LastBlock
) {
164 return EFI_INVALID_PARAMETER
;
169 (VOID
*)(UINTN
)(PrivateData
->StartingAddr
+ MultU64x32 (Lba
, PrivateData
->Media
.BlockSize
)),
178 Write BufferSize bytes from Lba into Buffer.
180 @param[in] This Indicates a pointer to the calling context.
181 @param[in] MediaId The media ID that the write request is for.
182 @param[in] Lba The starting logical block address to be written.
183 The caller is responsible for writing to only
184 legitimate locations.
185 @param[in] BufferSize Size of Buffer, must be a multiple of device block
187 @param[in] Buffer A pointer to the source buffer for the data.
189 @retval EFI_SUCCESS The data was written correctly to the device.
190 @retval EFI_WRITE_PROTECTED The device can not be written to.
191 @retval EFI_DEVICE_ERROR The device reported an error while performing
193 @retval EFI_NO_MEDIA There is no media in the device.
194 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current
196 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block
198 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not
199 valid, or the buffer is not on proper alignment.
204 RamDiskBlkIoWriteBlocks (
205 IN EFI_BLOCK_IO_PROTOCOL
*This
,
212 RAM_DISK_PRIVATE_DATA
*PrivateData
;
213 UINTN NumberOfBlocks
;
215 if (Buffer
== NULL
) {
216 return EFI_INVALID_PARAMETER
;
219 if (BufferSize
== 0) {
223 PrivateData
= RAM_DISK_PRIVATE_FROM_BLKIO (This
);
225 if (MediaId
!= PrivateData
->Media
.MediaId
) {
226 return EFI_MEDIA_CHANGED
;
229 if (TRUE
== PrivateData
->Media
.ReadOnly
) {
230 return EFI_WRITE_PROTECTED
;
233 if ((BufferSize
% PrivateData
->Media
.BlockSize
) != 0) {
234 return EFI_BAD_BUFFER_SIZE
;
237 if (Lba
> PrivateData
->Media
.LastBlock
) {
238 return EFI_INVALID_PARAMETER
;
241 NumberOfBlocks
= BufferSize
/ PrivateData
->Media
.BlockSize
;
242 if ((Lba
+ NumberOfBlocks
- 1) > PrivateData
->Media
.LastBlock
) {
243 return EFI_INVALID_PARAMETER
;
247 (VOID
*)(UINTN
)(PrivateData
->StartingAddr
+ MultU64x32 (Lba
, PrivateData
->Media
.BlockSize
)),
257 Flush the Block Device.
259 @param[in] This Indicates a pointer to the calling context.
261 @retval EFI_SUCCESS All outstanding data was written to the device.
262 @retval EFI_DEVICE_ERROR The device reported an error while writting
264 @retval EFI_NO_MEDIA There is no media in the device.
269 RamDiskBlkIoFlushBlocks (
270 IN EFI_BLOCK_IO_PROTOCOL
*This
278 Resets the block device hardware.
280 @param[in] This The pointer of EFI_BLOCK_IO2_PROTOCOL.
281 @param[in] ExtendedVerification The flag about if extend verificate.
283 @retval EFI_SUCCESS The device was reset.
284 @retval EFI_DEVICE_ERROR The block device is not functioning correctly
285 and could not be reset.
291 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
292 IN BOOLEAN ExtendedVerification
300 Reads the requested number of blocks from the device.
302 @param[in] This Indicates a pointer to the calling context.
303 @param[in] MediaId The media ID that the read request is for.
304 @param[in] Lba The starting logical block address to read
306 @param[in, out] Token A pointer to the token associated with the
308 @param[in] BufferSize The size of the Buffer in bytes. This must be
309 a multiple of the intrinsic block size of the
311 @param[out] Buffer A pointer to the destination buffer for the
312 data. The caller is responsible for either
313 having implicit or explicit ownership of the
316 @retval EFI_SUCCESS The read request was queued if Token->Event
317 is not NULL. The data was read correctly from
318 the device if the Token->Event is NULL.
319 @retval EFI_DEVICE_ERROR The device reported an error while attempting
320 to perform the read operation.
321 @retval EFI_NO_MEDIA There is no media in the device.
322 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
323 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of
324 the intrinsic block size of the device.
325 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not
326 valid, or the buffer is not on proper
328 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
334 RamDiskBlkIo2ReadBlocksEx (
335 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
338 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
,
343 RAM_DISK_PRIVATE_DATA
*PrivateData
;
346 PrivateData
= RAM_DISK_PRIVATE_FROM_BLKIO2 (This
);
348 Status
= RamDiskBlkIoReadBlocks (
349 &PrivateData
->BlockIo
,
355 if (EFI_ERROR (Status
)) {
360 // If caller's event is given, signal it after the memory read completes.
362 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
363 Token
->TransactionStatus
= EFI_SUCCESS
;
364 gBS
->SignalEvent (Token
->Event
);
372 Writes a specified number of blocks to the device.
374 @param[in] This Indicates a pointer to the calling context.
375 @param[in] MediaId The media ID that the write request is for.
376 @param[in] Lba The starting logical block address to be
377 written. The caller is responsible for
378 writing to only legitimate locations.
379 @param[in, out] Token A pointer to the token associated with the
381 @param[in] BufferSize The size in bytes of Buffer. This must be a
382 multiple of the intrinsic block size of the
384 @param[in] Buffer A pointer to the source buffer for the data.
386 @retval EFI_SUCCESS The write request was queued if Event is not
387 NULL. The data was written correctly to the
388 device if the Event is NULL.
389 @retval EFI_WRITE_PROTECTED The device cannot be written to.
390 @retval EFI_NO_MEDIA There is no media in the device.
391 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
392 @retval EFI_DEVICE_ERROR The device reported an error while attempting
393 to perform the write operation.
394 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of
395 the intrinsic block size of the device.
396 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not
397 valid, or the buffer is not on proper
399 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
405 RamDiskBlkIo2WriteBlocksEx (
406 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
409 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
,
414 RAM_DISK_PRIVATE_DATA
*PrivateData
;
417 PrivateData
= RAM_DISK_PRIVATE_FROM_BLKIO2 (This
);
419 Status
= RamDiskBlkIoWriteBlocks (
420 &PrivateData
->BlockIo
,
426 if (EFI_ERROR (Status
)) {
431 // If caller's event is given, signal it after the memory write completes.
433 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
434 Token
->TransactionStatus
= EFI_SUCCESS
;
435 gBS
->SignalEvent (Token
->Event
);
443 Flushes all modified data to a physical block device.
445 @param[in] This Indicates a pointer to the calling context.
446 @param[in, out] Token A pointer to the token associated with the
449 @retval EFI_SUCCESS The flush request was queued if Event is not
450 NULL. All outstanding data was written
451 correctly to the device if the Event is NULL.
452 @retval EFI_DEVICE_ERROR The device reported an error while attempting
454 @retval EFI_WRITE_PROTECTED The device cannot be written to.
455 @retval EFI_NO_MEDIA There is no media in the device.
456 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
457 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
463 RamDiskBlkIo2FlushBlocksEx (
464 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
465 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
468 RAM_DISK_PRIVATE_DATA
*PrivateData
;
470 PrivateData
= RAM_DISK_PRIVATE_FROM_BLKIO2 (This
);
472 if (TRUE
== PrivateData
->Media
.ReadOnly
) {
473 return EFI_WRITE_PROTECTED
;
477 // If caller's event is given, signal it directly.
479 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
480 Token
->TransactionStatus
= EFI_SUCCESS
;
481 gBS
->SignalEvent (Token
->Event
);