3 Block I/O protocol for CE-ATA device
5 Copyright (c) 2013-2015 Intel Corporation.
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "SDMediaDevice.h"
20 Implements EFI_BLOCK_IO_PROTOCOL.Reset() function.
22 @param This The EFI_BLOCK_IO_PROTOCOL instance.
23 @param ExtendedVerification Indicates that the driver may perform a more exhaustive.
24 verification operation of the device during reset.
25 (This parameter is ingored in this driver.)
27 @retval EFI_SUCCESS Success
32 IN EFI_BLOCK_IO_PROTOCOL
*This
,
33 IN BOOLEAN ExtendedVerification
38 EFI_SD_HOST_IO_PROTOCOL
*SDHostIo
;
40 CardData
= CARD_DATA_FROM_THIS(This
);
41 SDHostIo
= CardData
->SDHostIo
;
43 if (!ExtendedVerification
) {
44 Status
= SoftwareReset (CardData
);
46 Status
= SDHostIo
->ResetSDHost (SDHostIo
, Reset_DAT_CMD
);
47 if (EFI_ERROR (Status
)) {
48 DEBUG((EFI_D_ERROR
, "CEATABlockReset: Fail to ResetSDHost\n" ));
51 Status
= MMCSDCardInit (CardData
);
60 Implements EFI_BLOCK_IO_PROTOCOL.ReadBlocks() function.
62 @param This The EFI_BLOCK_IO_PROTOCOL instance.
63 @param MediaId The media id that the write request is for.
64 @param LBA The starting logical block address to read from on the device.
65 The caller is responsible for writing to only legitimate locations.
66 @param BufferSize The size of the Buffer in bytes. This must be a multiple of the
67 intrinsic block size of the device.
68 @param Buffer A pointer to the destination buffer for the data. The caller
69 is responsible for either having implicit or explicit ownership
72 @retval EFI_SUCCESS Success
73 @retval EFI_DEVICE_ERROR Hardware Error
74 @retval EFI_INVALID_PARAMETER Parameter is error
75 @retval EFI_NO_MEDIA No media
76 @retval EFI_MEDIA_CHANGED Media Change
77 @retval EFI_BAD_BUFFER_SIZE Buffer size is bad
81 CEATABlockReadBlocks (
82 IN EFI_BLOCK_IO_PROTOCOL
*This
,
100 CardData
= CARD_DATA_FROM_THIS(This
);
103 Address
= MultU64x32(LBA
, CardData
->BlockIoMedia
.BlockSize
);
104 BoundarySize
= CardData
->SDHostIo
->HostCapability
.BoundarySize
;
107 Status
= EFI_INVALID_PARAMETER
;
108 DEBUG((EFI_D_ERROR
, "CEATABlockReadBlocks:Invalid parameter\n" ));
112 if (MediaId
!= CardData
->BlockIoMedia
.MediaId
) {
113 Status
= EFI_MEDIA_CHANGED
;
114 DEBUG((EFI_D_ERROR
, "CEATABlockReadBlocks:Media changed\n" ));
118 if ((BufferSize
% CardData
->BlockIoMedia
.BlockSize
) != 0) {
119 Status
= EFI_BAD_BUFFER_SIZE
;
120 DEBUG((EFI_D_ERROR
, "CEATABlockReadBlocks:Bad buffer size\n" ));
124 if (BufferSize
== 0) {
125 Status
= EFI_SUCCESS
;
129 if ((Address
+ BufferSize
) > MultU64x32 (CardData
->BlockIoMedia
.LastBlock
+ 1, CardData
->BlockIoMedia
.BlockSize
)) {
130 Status
= EFI_INVALID_PARAMETER
;
131 DEBUG((EFI_D_ERROR
, "CEATABlockReadBlocks:Invalid parameter\n" ));
137 if (BufferSize
< BoundarySize
) {
138 TransferSize
= (UINT32
)BufferSize
;
140 TransferSize
= BoundarySize
;
143 Address
+= Index
* TransferSize
;
144 CEATALBA
= DivU64x32Remainder (Address
, DATA_UNIT_SIZE
, &Remainder
);
145 ASSERT(Remainder
== 0);
147 Status
= ReadDMAExt (
151 (UINT16
)(TransferSize
/ DATA_UNIT_SIZE
)
153 if (EFI_ERROR (Status
)) {
154 DEBUG((EFI_D_ERROR
, "Read Failed at 0x%x, Index %d, Size 0x%x\n", Address
, Index
, TransferSize
));
155 This
->Reset (This
, TRUE
);
158 BufferSize
-= TransferSize
;
159 pBuf
+= TransferSize
;
161 } while (BufferSize
!= 0);
169 Implements EFI_BLOCK_IO_PROTOCOL.WriteBlocks() function.
171 @param This The EFI_BLOCK_IO_PROTOCOL instance.
172 @param MediaId The media id that the write request is for.
173 @param LBA The starting logical block address to read from on the device.
174 The caller is responsible for writing to only legitimate locations.
175 @param BufferSize The size of the Buffer in bytes. This must be a multiple of the
176 intrinsic block size of the device.
177 @param Buffer A pointer to the destination buffer for the data. The caller
178 is responsible for either having implicit or explicit ownership
181 @retval EFI_SUCCESS Success
182 @retval EFI_DEVICE_ERROR Hardware Error
183 @retval EFI_INVALID_PARAMETER Parameter is error
184 @retval EFI_NO_MEDIA No media
185 @retval EFI_MEDIA_CHANGED Media Change
186 @retval EFI_BAD_BUFFER_SIZE Buffer size is bad
190 CEATABlockWriteBlocks (
191 IN EFI_BLOCK_IO_PROTOCOL
*This
,
209 Status
= EFI_SUCCESS
;
210 CardData
= CARD_DATA_FROM_THIS(This
);
213 Address
= MultU64x32(LBA
, CardData
->BlockIoMedia
.BlockSize
);
214 BoundarySize
= CardData
->SDHostIo
->HostCapability
.BoundarySize
;
218 Status
= EFI_INVALID_PARAMETER
;
222 if (MediaId
!= CardData
->BlockIoMedia
.MediaId
) {
223 Status
= EFI_MEDIA_CHANGED
;
227 if ((BufferSize
% CardData
->BlockIoMedia
.BlockSize
) != 0) {
228 Status
= EFI_BAD_BUFFER_SIZE
;
232 if (BufferSize
== 0) {
233 Status
= EFI_SUCCESS
;
237 if (CardData
->BlockIoMedia
.ReadOnly
) {
238 Status
= EFI_WRITE_PROTECTED
;
242 if ((Address
+ BufferSize
) > MultU64x32 (CardData
->BlockIoMedia
.LastBlock
+ 1, CardData
->BlockIoMedia
.BlockSize
)) {
243 Status
= EFI_INVALID_PARAMETER
;
247 CardData
->NeedFlush
= TRUE
;
250 if (BufferSize
< BoundarySize
) {
251 TransferSize
= (UINT32
)BufferSize
;
253 TransferSize
= BoundarySize
;
256 Address
+= Index
* TransferSize
;
257 CEATALBA
= DivU64x32Remainder (Address
, DATA_UNIT_SIZE
, &Remainder
);
258 ASSERT(Remainder
== 0);
260 Status
= WriteDMAExt (
264 (UINT16
)(TransferSize
/ DATA_UNIT_SIZE
)
266 if (EFI_ERROR (Status
)) {
267 DEBUG((EFI_D_ERROR
, "Write Failed at 0x%x, Index %d, Size 0x%x\n", Address
, Index
, TransferSize
));
268 This
->Reset (This
, TRUE
);
271 BufferSize
-= TransferSize
;
272 pBuf
+= TransferSize
;
274 } while (BufferSize
!= 0);
282 Implements EFI_BLOCK_IO_PROTOCOL.FlushBlocks() function.
283 (In this driver, this function just returns EFI_SUCCESS.)
285 @param This The EFI_BLOCK_IO_PROTOCOL instance.
292 CEATABlockFlushBlocks (
293 IN EFI_BLOCK_IO_PROTOCOL
*This
299 CardData
= CARD_DATA_FROM_THIS(This
);
301 if (CardData
->NeedFlush
) {
302 CardData
->NeedFlush
= FALSE
;
303 FlushCache (CardData
);
311 CEATA card BlockIo init function.
313 @param CardData Pointer to CARD_DATA.
320 IN CARD_DATA
*CardData
325 CEATA card BlockIo init function
328 CardData - Pointer to CARD_DATA
331 EFI_SUCCESS - Success
340 CardData
->BlockIo
.Revision
= EFI_BLOCK_IO_PROTOCOL_REVISION
;
341 CardData
->BlockIo
.Media
= &(CardData
->BlockIoMedia
);
342 CardData
->BlockIo
.Reset
= CEATABlockReset
;
343 CardData
->BlockIo
.ReadBlocks
= CEATABlockReadBlocks
;
344 CardData
->BlockIo
.WriteBlocks
= CEATABlockWriteBlocks
;
345 CardData
->BlockIo
.FlushBlocks
= CEATABlockFlushBlocks
;
347 CardData
->BlockIoMedia
.MediaId
= 0;
348 CardData
->BlockIoMedia
.RemovableMedia
= FALSE
;
349 CardData
->BlockIoMedia
.MediaPresent
= TRUE
;
350 CardData
->BlockIoMedia
.LogicalPartition
= FALSE
;
352 if (CardData
->CSDRegister
.PERM_WRITE_PROTECT
| CardData
->CSDRegister
.TMP_WRITE_PROTECT
) {
353 CardData
->BlockIoMedia
.ReadOnly
= TRUE
;
355 CardData
->BlockIoMedia
.ReadOnly
= FALSE
;
359 CardData
->BlockIoMedia
.WriteCaching
= FALSE
;
360 CardData
->BlockIoMedia
.IoAlign
= 1;
362 Status
= IndentifyDevice (CardData
);
363 if (EFI_ERROR (Status
)) {
368 //Some device does not support this feature
371 if (CardData
->IndentifyDeviceData
.MaxWritesPerAddress
== 0) {
372 CardData
->BlockIoMedia
.ReadOnly
= TRUE
;
375 CardData
->BlockIoMedia
.BlockSize
= (1 << CardData
->IndentifyDeviceData
.Sectorsize
);
376 ASSERT(CardData
->BlockIoMedia
.BlockSize
>= 12);
379 MaxSize
= *(UINT64
*)(CardData
->IndentifyDeviceData
.MaximumLBA
);
380 MaxSize
= MultU64x32 (MaxSize
, 512);
383 CardData
->BlockNumber
= DivU64x32Remainder (MaxSize
, CardData
->BlockIoMedia
.BlockSize
, &Remainder
);
384 ASSERT(Remainder
== 0);
386 CardData
->BlockIoMedia
.LastBlock
= (EFI_LBA
)(CardData
->BlockNumber
- 1);