3 Block I/O protocol for CE-ATA device
5 Copyright (c) 2013-2015 Intel Corporation.
7 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include "SDMediaDevice.h"
14 Implements EFI_BLOCK_IO_PROTOCOL.Reset() function.
16 @param This The EFI_BLOCK_IO_PROTOCOL instance.
17 @param ExtendedVerification Indicates that the driver may perform a more exhaustive.
18 verification operation of the device during reset.
19 (This parameter is ingored in this driver.)
21 @retval EFI_SUCCESS Success
26 IN EFI_BLOCK_IO_PROTOCOL
*This
,
27 IN BOOLEAN ExtendedVerification
32 EFI_SD_HOST_IO_PROTOCOL
*SDHostIo
;
34 CardData
= CARD_DATA_FROM_THIS(This
);
35 SDHostIo
= CardData
->SDHostIo
;
37 if (!ExtendedVerification
) {
38 Status
= SoftwareReset (CardData
);
40 Status
= SDHostIo
->ResetSDHost (SDHostIo
, Reset_DAT_CMD
);
41 if (EFI_ERROR (Status
)) {
42 DEBUG((EFI_D_ERROR
, "CEATABlockReset: Fail to ResetSDHost\n" ));
45 Status
= MMCSDCardInit (CardData
);
54 Implements EFI_BLOCK_IO_PROTOCOL.ReadBlocks() function.
56 @param This The EFI_BLOCK_IO_PROTOCOL instance.
57 @param MediaId The media id that the write request is for.
58 @param LBA The starting logical block address to read from on the device.
59 The caller is responsible for writing to only legitimate locations.
60 @param BufferSize The size of the Buffer in bytes. This must be a multiple of the
61 intrinsic block size of the device.
62 @param Buffer A pointer to the destination buffer for the data. The caller
63 is responsible for either having implicit or explicit ownership
66 @retval EFI_SUCCESS Success
67 @retval EFI_DEVICE_ERROR Hardware Error
68 @retval EFI_INVALID_PARAMETER Parameter is error
69 @retval EFI_NO_MEDIA No media
70 @retval EFI_MEDIA_CHANGED Media Change
71 @retval EFI_BAD_BUFFER_SIZE Buffer size is bad
75 CEATABlockReadBlocks (
76 IN EFI_BLOCK_IO_PROTOCOL
*This
,
94 CardData
= CARD_DATA_FROM_THIS(This
);
97 Address
= MultU64x32(LBA
, CardData
->BlockIoMedia
.BlockSize
);
98 BoundarySize
= CardData
->SDHostIo
->HostCapability
.BoundarySize
;
101 Status
= EFI_INVALID_PARAMETER
;
102 DEBUG((EFI_D_ERROR
, "CEATABlockReadBlocks:Invalid parameter\n" ));
106 if (MediaId
!= CardData
->BlockIoMedia
.MediaId
) {
107 Status
= EFI_MEDIA_CHANGED
;
108 DEBUG((EFI_D_ERROR
, "CEATABlockReadBlocks:Media changed\n" ));
112 if ((BufferSize
% CardData
->BlockIoMedia
.BlockSize
) != 0) {
113 Status
= EFI_BAD_BUFFER_SIZE
;
114 DEBUG((EFI_D_ERROR
, "CEATABlockReadBlocks:Bad buffer size\n" ));
118 if (BufferSize
== 0) {
119 Status
= EFI_SUCCESS
;
123 if ((Address
+ BufferSize
) > MultU64x32 (CardData
->BlockIoMedia
.LastBlock
+ 1, CardData
->BlockIoMedia
.BlockSize
)) {
124 Status
= EFI_INVALID_PARAMETER
;
125 DEBUG((EFI_D_ERROR
, "CEATABlockReadBlocks:Invalid parameter\n" ));
131 if (BufferSize
< BoundarySize
) {
132 TransferSize
= (UINT32
)BufferSize
;
134 TransferSize
= BoundarySize
;
137 Address
+= Index
* TransferSize
;
138 CEATALBA
= DivU64x32Remainder (Address
, DATA_UNIT_SIZE
, &Remainder
);
139 ASSERT(Remainder
== 0);
141 Status
= ReadDMAExt (
145 (UINT16
)(TransferSize
/ DATA_UNIT_SIZE
)
147 if (EFI_ERROR (Status
)) {
148 DEBUG((EFI_D_ERROR
, "Read Failed at 0x%x, Index %d, Size 0x%x\n", Address
, Index
, TransferSize
));
149 This
->Reset (This
, TRUE
);
152 BufferSize
-= TransferSize
;
153 pBuf
+= TransferSize
;
155 } while (BufferSize
!= 0);
163 Implements EFI_BLOCK_IO_PROTOCOL.WriteBlocks() function.
165 @param This The EFI_BLOCK_IO_PROTOCOL instance.
166 @param MediaId The media id that the write request is for.
167 @param LBA The starting logical block address to read from on the device.
168 The caller is responsible for writing to only legitimate locations.
169 @param BufferSize The size of the Buffer in bytes. This must be a multiple of the
170 intrinsic block size of the device.
171 @param Buffer A pointer to the destination buffer for the data. The caller
172 is responsible for either having implicit or explicit ownership
175 @retval EFI_SUCCESS Success
176 @retval EFI_DEVICE_ERROR Hardware Error
177 @retval EFI_INVALID_PARAMETER Parameter is error
178 @retval EFI_NO_MEDIA No media
179 @retval EFI_MEDIA_CHANGED Media Change
180 @retval EFI_BAD_BUFFER_SIZE Buffer size is bad
184 CEATABlockWriteBlocks (
185 IN EFI_BLOCK_IO_PROTOCOL
*This
,
203 Status
= EFI_SUCCESS
;
204 CardData
= CARD_DATA_FROM_THIS(This
);
207 Address
= MultU64x32(LBA
, CardData
->BlockIoMedia
.BlockSize
);
208 BoundarySize
= CardData
->SDHostIo
->HostCapability
.BoundarySize
;
212 Status
= EFI_INVALID_PARAMETER
;
216 if (MediaId
!= CardData
->BlockIoMedia
.MediaId
) {
217 Status
= EFI_MEDIA_CHANGED
;
221 if ((BufferSize
% CardData
->BlockIoMedia
.BlockSize
) != 0) {
222 Status
= EFI_BAD_BUFFER_SIZE
;
226 if (BufferSize
== 0) {
227 Status
= EFI_SUCCESS
;
231 if (CardData
->BlockIoMedia
.ReadOnly
) {
232 Status
= EFI_WRITE_PROTECTED
;
236 if ((Address
+ BufferSize
) > MultU64x32 (CardData
->BlockIoMedia
.LastBlock
+ 1, CardData
->BlockIoMedia
.BlockSize
)) {
237 Status
= EFI_INVALID_PARAMETER
;
241 CardData
->NeedFlush
= TRUE
;
244 if (BufferSize
< BoundarySize
) {
245 TransferSize
= (UINT32
)BufferSize
;
247 TransferSize
= BoundarySize
;
250 Address
+= Index
* TransferSize
;
251 CEATALBA
= DivU64x32Remainder (Address
, DATA_UNIT_SIZE
, &Remainder
);
252 ASSERT(Remainder
== 0);
254 Status
= WriteDMAExt (
258 (UINT16
)(TransferSize
/ DATA_UNIT_SIZE
)
260 if (EFI_ERROR (Status
)) {
261 DEBUG((EFI_D_ERROR
, "Write Failed at 0x%x, Index %d, Size 0x%x\n", Address
, Index
, TransferSize
));
262 This
->Reset (This
, TRUE
);
265 BufferSize
-= TransferSize
;
266 pBuf
+= TransferSize
;
268 } while (BufferSize
!= 0);
276 Implements EFI_BLOCK_IO_PROTOCOL.FlushBlocks() function.
277 (In this driver, this function just returns EFI_SUCCESS.)
279 @param This The EFI_BLOCK_IO_PROTOCOL instance.
286 CEATABlockFlushBlocks (
287 IN EFI_BLOCK_IO_PROTOCOL
*This
293 CardData
= CARD_DATA_FROM_THIS(This
);
295 if (CardData
->NeedFlush
) {
296 CardData
->NeedFlush
= FALSE
;
297 FlushCache (CardData
);
305 CEATA card BlockIo init function.
307 @param CardData Pointer to CARD_DATA.
314 IN CARD_DATA
*CardData
319 CEATA card BlockIo init function
322 CardData - Pointer to CARD_DATA
325 EFI_SUCCESS - Success
334 CardData
->BlockIo
.Revision
= EFI_BLOCK_IO_PROTOCOL_REVISION
;
335 CardData
->BlockIo
.Media
= &(CardData
->BlockIoMedia
);
336 CardData
->BlockIo
.Reset
= CEATABlockReset
;
337 CardData
->BlockIo
.ReadBlocks
= CEATABlockReadBlocks
;
338 CardData
->BlockIo
.WriteBlocks
= CEATABlockWriteBlocks
;
339 CardData
->BlockIo
.FlushBlocks
= CEATABlockFlushBlocks
;
341 CardData
->BlockIoMedia
.MediaId
= 0;
342 CardData
->BlockIoMedia
.RemovableMedia
= FALSE
;
343 CardData
->BlockIoMedia
.MediaPresent
= TRUE
;
344 CardData
->BlockIoMedia
.LogicalPartition
= FALSE
;
346 if (CardData
->CSDRegister
.PERM_WRITE_PROTECT
| CardData
->CSDRegister
.TMP_WRITE_PROTECT
) {
347 CardData
->BlockIoMedia
.ReadOnly
= TRUE
;
349 CardData
->BlockIoMedia
.ReadOnly
= FALSE
;
353 CardData
->BlockIoMedia
.WriteCaching
= FALSE
;
354 CardData
->BlockIoMedia
.IoAlign
= 1;
356 Status
= IndentifyDevice (CardData
);
357 if (EFI_ERROR (Status
)) {
362 //Some device does not support this feature
365 if (CardData
->IndentifyDeviceData
.MaxWritesPerAddress
== 0) {
366 CardData
->BlockIoMedia
.ReadOnly
= TRUE
;
369 CardData
->BlockIoMedia
.BlockSize
= (1 << CardData
->IndentifyDeviceData
.Sectorsize
);
370 ASSERT(CardData
->BlockIoMedia
.BlockSize
>= 12);
373 MaxSize
= *(UINT64
*)(CardData
->IndentifyDeviceData
.MaximumLBA
);
374 MaxSize
= MultU64x32 (MaxSize
, 512);
377 CardData
->BlockNumber
= DivU64x32Remainder (MaxSize
, CardData
->BlockIoMedia
.BlockSize
, &Remainder
);
378 ASSERT(Remainder
== 0);
380 CardData
->BlockIoMedia
.LastBlock
= (EFI_LBA
)(CardData
->BlockNumber
- 1);