2 The helper functions for BlockIo and BlockIo2 protocol.
4 Copyright (c) 2015 - 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.
18 Nonblocking I/O callback funtion when the event is signaled.
20 @param[in] Event The Event this notify function registered to.
21 @param[in] Context Pointer to the context data registered to the
34 gBS
->CloseEvent (Event
);
36 Request
= (SD_REQUEST
*) Context
;
39 DEBUG ((EFI_D_INFO
, "Sd Async Request: CmdIndex[%d] Arg[%08x] %r\n",
40 Request
->SdMmcCmdBlk
.CommandIndex
, Request
->SdMmcCmdBlk
.CommandArgument
,
41 Request
->Packet
.TransactionStatus
));
44 if (EFI_ERROR (Request
->Packet
.TransactionStatus
)) {
45 Request
->Token
->TransactionStatus
= Request
->Packet
.TransactionStatus
;
48 RemoveEntryList (&Request
->Link
);
51 gBS
->SignalEvent (Request
->Token
->Event
);
58 Send command SET_RELATIVE_ADDRESS to the device to set the device address.
60 @param[in] Device A pointer to the SD_DEVICE instance.
61 @param[out] Rca The relative device address to assign.
63 @retval EFI_SUCCESS The request is executed successfully.
64 @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources.
65 @retval Others The request could not be executed successfully.
75 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
76 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
77 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
78 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
80 PassThru
= Device
->Private
->PassThru
;
82 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
83 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
84 ZeroMem (&Packet
, sizeof (Packet
));
85 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
86 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
87 Packet
.Timeout
= SD_GENERIC_TIMEOUT
;
89 SdMmcCmdBlk
.CommandIndex
= SD_SET_RELATIVE_ADDR
;
90 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeBcr
;
91 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR6
;
93 Status
= PassThru
->PassThru (PassThru
, Device
->Slot
, &Packet
, NULL
);
94 if (!EFI_ERROR (Status
)) {
95 DEBUG ((EFI_D_INFO
, "Set RCA succeeds with Resp0 = 0x%x\n", SdMmcStatusBlk
.Resp0
));
96 *Rca
= (UINT16
)(SdMmcStatusBlk
.Resp0
>> 16);
103 Send command SELECT to the device to select/deselect the device.
105 @param[in] Device A pointer to the SD_DEVICE instance.
106 @param[in] Rca The relative device address to use.
108 @retval EFI_SUCCESS The request is executed successfully.
109 @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources.
110 @retval Others The request could not be executed successfully.
115 IN SD_DEVICE
*Device
,
120 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
121 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
122 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
123 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
125 PassThru
= Device
->Private
->PassThru
;
127 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
128 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
129 ZeroMem (&Packet
, sizeof (Packet
));
130 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
131 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
132 Packet
.Timeout
= SD_GENERIC_TIMEOUT
;
134 SdMmcCmdBlk
.CommandIndex
= SD_SELECT_DESELECT_CARD
;
135 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
137 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1b
;
139 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
141 Status
= PassThru
->PassThru (PassThru
, Device
->Slot
, &Packet
, NULL
);
147 Send command SEND_STATUS to the device to get device status.
149 @param[in] Device A pointer to the SD_DEVICE instance.
150 @param[in] Rca The relative device address to use.
151 @param[out] DevStatus The buffer to store the device status.
153 @retval EFI_SUCCESS The request is executed successfully.
154 @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources.
155 @retval Others The request could not be executed successfully.
160 IN SD_DEVICE
*Device
,
162 OUT UINT32
*DevStatus
166 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
167 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
168 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
169 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
171 PassThru
= Device
->Private
->PassThru
;
173 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
174 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
175 ZeroMem (&Packet
, sizeof (Packet
));
176 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
177 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
178 Packet
.Timeout
= SD_GENERIC_TIMEOUT
;
180 SdMmcCmdBlk
.CommandIndex
= SD_SEND_STATUS
;
181 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
182 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
183 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
185 Status
= PassThru
->PassThru (PassThru
, Device
->Slot
, &Packet
, NULL
);
186 if (!EFI_ERROR (Status
)) {
187 CopyMem (DevStatus
, &SdMmcStatusBlk
.Resp0
, sizeof (UINT32
));
193 Send command SEND_CSD to the device to get the CSD register data.
195 @param[in] Device A pointer to the SD_DEVICE instance.
196 @param[in] Rca The relative device address to use.
197 @param[out] Csd The buffer to store the SD_CSD register data.
199 @retval EFI_SUCCESS The request is executed successfully.
200 @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources.
201 @retval Others The request could not be executed successfully.
206 IN SD_DEVICE
*Device
,
212 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
213 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
214 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
215 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
217 PassThru
= Device
->Private
->PassThru
;
219 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
220 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
221 ZeroMem (&Packet
, sizeof (Packet
));
222 ZeroMem (Csd
, sizeof (SD_CSD
));
224 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
225 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
226 Packet
.Timeout
= SD_GENERIC_TIMEOUT
;
228 SdMmcCmdBlk
.CommandIndex
= SD_SEND_CSD
;
229 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
230 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR2
;
231 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
233 Status
= PassThru
->PassThru (PassThru
, Device
->Slot
, &Packet
, NULL
);
235 if (!EFI_ERROR (Status
)) {
237 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
239 CopyMem (((UINT8
*)Csd
) + 1, &SdMmcStatusBlk
.Resp0
, sizeof (SD_CSD
) - 1);
246 Send command SEND_CID to the device to get the CID register data.
248 @param[in] Device A pointer to the SD_DEVICE instance.
249 @param[in] Rca The relative device address to use.
250 @param[out] Cid The buffer to store the SD_CID register data.
252 @retval EFI_SUCCESS The request is executed successfully.
253 @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources.
254 @retval Others The request could not be executed successfully.
259 IN SD_DEVICE
*Device
,
265 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
266 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk
;
267 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk
;
268 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet
;
270 PassThru
= Device
->Private
->PassThru
;
272 ZeroMem (&SdMmcCmdBlk
, sizeof (SdMmcCmdBlk
));
273 ZeroMem (&SdMmcStatusBlk
, sizeof (SdMmcStatusBlk
));
274 ZeroMem (&Packet
, sizeof (Packet
));
275 ZeroMem (Cid
, sizeof (SD_CID
));
277 Packet
.SdMmcCmdBlk
= &SdMmcCmdBlk
;
278 Packet
.SdMmcStatusBlk
= &SdMmcStatusBlk
;
279 Packet
.Timeout
= SD_GENERIC_TIMEOUT
;
281 SdMmcCmdBlk
.CommandIndex
= SD_SEND_CID
;
282 SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
283 SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR2
;
284 SdMmcCmdBlk
.CommandArgument
= (UINT32
)Rca
<< 16;
286 Status
= PassThru
->PassThru (PassThru
, Device
->Slot
, &Packet
, NULL
);
288 if (!EFI_ERROR (Status
)) {
290 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
292 CopyMem (((UINT8
*)Cid
) + 1, &SdMmcStatusBlk
.Resp0
, sizeof (SD_CID
) - 1);
299 Read/write single block through sync or async I/O request.
301 @param[in] Device A pointer to the SD_DEVICE instance.
302 @param[in] Lba The starting logical block address to be read/written.
303 The caller is responsible for reading/writing to only
304 legitimate locations.
305 @param[in] Buffer A pointer to the destination/source buffer for the data.
306 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
307 @param[in] IsRead Indicates it is a read or write operation.
308 @param[in] Token A pointer to the token associated with the transaction.
309 @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds.
310 This parameter is only meaningful in async I/O request.
312 @retval EFI_SUCCESS The request is executed successfully.
313 @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources.
314 @retval Others The request could not be executed successfully.
319 IN SD_DEVICE
*Device
,
324 IN EFI_BLOCK_IO2_TOKEN
*Token
,
329 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
330 SD_REQUEST
*RwSingleBlkReq
;
333 RwSingleBlkReq
= NULL
;
334 PassThru
= Device
->Private
->PassThru
;
336 RwSingleBlkReq
= AllocateZeroPool (sizeof (SD_REQUEST
));
337 if (RwSingleBlkReq
== NULL
) {
338 Status
= EFI_OUT_OF_RESOURCES
;
342 RwSingleBlkReq
->Signature
= SD_REQUEST_SIGNATURE
;
343 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
344 InsertTailList (&Device
->Queue
, &RwSingleBlkReq
->Link
);
345 gBS
->RestoreTPL (OldTpl
);
346 RwSingleBlkReq
->Packet
.SdMmcCmdBlk
= &RwSingleBlkReq
->SdMmcCmdBlk
;
347 RwSingleBlkReq
->Packet
.SdMmcStatusBlk
= &RwSingleBlkReq
->SdMmcStatusBlk
;
349 // Calculate timeout value through the below formula.
350 // Timeout = (transfer size) / (2MB/s).
351 // Taking 2MB/s as divisor as it's the lowest transfer speed
353 // Refer to SD Physical Layer Simplified spec section 3.4 for details.
355 RwSingleBlkReq
->Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;
358 RwSingleBlkReq
->Packet
.InDataBuffer
= Buffer
;
359 RwSingleBlkReq
->Packet
.InTransferLength
= (UINT32
)BufferSize
;
361 RwSingleBlkReq
->SdMmcCmdBlk
.CommandIndex
= SD_READ_SINGLE_BLOCK
;
362 RwSingleBlkReq
->SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
363 RwSingleBlkReq
->SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
365 RwSingleBlkReq
->Packet
.OutDataBuffer
= Buffer
;
366 RwSingleBlkReq
->Packet
.OutTransferLength
= (UINT32
)BufferSize
;
368 RwSingleBlkReq
->SdMmcCmdBlk
.CommandIndex
= SD_WRITE_SINGLE_BLOCK
;
369 RwSingleBlkReq
->SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
370 RwSingleBlkReq
->SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
373 if (Device
->SectorAddressing
) {
374 RwSingleBlkReq
->SdMmcCmdBlk
.CommandArgument
= (UINT32
)Lba
;
376 RwSingleBlkReq
->SdMmcCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, Device
->BlockMedia
.BlockSize
);
379 RwSingleBlkReq
->IsEnd
= IsEnd
;
380 RwSingleBlkReq
->Token
= Token
;
382 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
383 Status
= gBS
->CreateEvent (
388 &RwSingleBlkReq
->Event
390 if (EFI_ERROR (Status
)) {
394 RwSingleBlkReq
->Event
= NULL
;
397 Status
= PassThru
->PassThru (PassThru
, Device
->Slot
, &RwSingleBlkReq
->Packet
, RwSingleBlkReq
->Event
);
400 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
402 // For asynchronous operation, only free request and event in error case.
403 // The request and event will be freed in asynchronous callback for success case.
405 if (EFI_ERROR (Status
) && (RwSingleBlkReq
!= NULL
)) {
406 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
407 RemoveEntryList (&RwSingleBlkReq
->Link
);
408 gBS
->RestoreTPL (OldTpl
);
409 if (RwSingleBlkReq
->Event
!= NULL
) {
410 gBS
->CloseEvent (RwSingleBlkReq
->Event
);
412 FreePool (RwSingleBlkReq
);
416 // For synchronous operation, free request whatever the execution result is.
418 if (RwSingleBlkReq
!= NULL
) {
419 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
420 RemoveEntryList (&RwSingleBlkReq
->Link
);
421 gBS
->RestoreTPL (OldTpl
);
422 FreePool (RwSingleBlkReq
);
430 Read/write multiple blocks through sync or async I/O request.
432 @param[in] Device A pointer to the SD_DEVICE instance.
433 @param[in] Lba The starting logical block address to be read/written.
434 The caller is responsible for reading/writing to only
435 legitimate locations.
436 @param[in] Buffer A pointer to the destination/source buffer for the data.
437 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
438 @param[in] IsRead Indicates it is a read or write operation.
439 @param[in] Token A pointer to the token associated with the transaction.
440 @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds.
441 This parameter is only meaningful in async I/O request.
443 @retval EFI_SUCCESS The request is executed successfully.
444 @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources.
445 @retval Others The request could not be executed successfully.
450 IN SD_DEVICE
*Device
,
455 IN EFI_BLOCK_IO2_TOKEN
*Token
,
460 SD_REQUEST
*RwMultiBlkReq
;
461 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
464 RwMultiBlkReq
= NULL
;
466 PassThru
= Device
->Private
->PassThru
;
468 RwMultiBlkReq
= AllocateZeroPool (sizeof (SD_REQUEST
));
469 if (RwMultiBlkReq
== NULL
) {
470 Status
= EFI_OUT_OF_RESOURCES
;
474 RwMultiBlkReq
->Signature
= SD_REQUEST_SIGNATURE
;
475 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
476 InsertTailList (&Device
->Queue
, &RwMultiBlkReq
->Link
);
477 gBS
->RestoreTPL (OldTpl
);
478 RwMultiBlkReq
->Packet
.SdMmcCmdBlk
= &RwMultiBlkReq
->SdMmcCmdBlk
;
479 RwMultiBlkReq
->Packet
.SdMmcStatusBlk
= &RwMultiBlkReq
->SdMmcStatusBlk
;
481 // Calculate timeout value through the below formula.
482 // Timeout = (transfer size) / (2MB/s).
483 // Taking 2MB/s as divisor as it's the lowest transfer speed
485 // Refer to SD Physical Layer Simplified spec section 3.4 for details.
487 RwMultiBlkReq
->Packet
.Timeout
= (BufferSize
/ (2 * 1024 * 1024) + 1) * 1000 * 1000;
490 RwMultiBlkReq
->Packet
.InDataBuffer
= Buffer
;
491 RwMultiBlkReq
->Packet
.InTransferLength
= (UINT32
)BufferSize
;
493 RwMultiBlkReq
->SdMmcCmdBlk
.CommandIndex
= SD_READ_MULTIPLE_BLOCK
;
494 RwMultiBlkReq
->SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
495 RwMultiBlkReq
->SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
497 RwMultiBlkReq
->Packet
.OutDataBuffer
= Buffer
;
498 RwMultiBlkReq
->Packet
.OutTransferLength
= (UINT32
)BufferSize
;
500 RwMultiBlkReq
->SdMmcCmdBlk
.CommandIndex
= SD_WRITE_MULTIPLE_BLOCK
;
501 RwMultiBlkReq
->SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAdtc
;
502 RwMultiBlkReq
->SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
505 if (Device
->SectorAddressing
) {
506 RwMultiBlkReq
->SdMmcCmdBlk
.CommandArgument
= (UINT32
)Lba
;
508 RwMultiBlkReq
->SdMmcCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (Lba
, Device
->BlockMedia
.BlockSize
);
511 RwMultiBlkReq
->IsEnd
= IsEnd
;
512 RwMultiBlkReq
->Token
= Token
;
514 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
515 Status
= gBS
->CreateEvent (
520 &RwMultiBlkReq
->Event
522 if (EFI_ERROR (Status
)) {
526 RwMultiBlkReq
->Event
= NULL
;
529 Status
= PassThru
->PassThru (PassThru
, Device
->Slot
, &RwMultiBlkReq
->Packet
, RwMultiBlkReq
->Event
);
532 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
534 // For asynchronous operation, only free request and event in error case.
535 // The request and event will be freed in asynchronous callback for success case.
537 if (EFI_ERROR (Status
) && (RwMultiBlkReq
!= NULL
)) {
538 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
539 RemoveEntryList (&RwMultiBlkReq
->Link
);
540 gBS
->RestoreTPL (OldTpl
);
541 if (RwMultiBlkReq
->Event
!= NULL
) {
542 gBS
->CloseEvent (RwMultiBlkReq
->Event
);
544 FreePool (RwMultiBlkReq
);
548 // For synchronous operation, free request whatever the execution result is.
550 if (RwMultiBlkReq
!= NULL
) {
551 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
552 RemoveEntryList (&RwMultiBlkReq
->Link
);
553 gBS
->RestoreTPL (OldTpl
);
554 FreePool (RwMultiBlkReq
);
562 This function transfers data from/to the sd memory card device.
564 @param[in] Device A pointer to the SD_DEVICE instance.
565 @param[in] MediaId The media ID that the read/write request is for.
566 @param[in] Lba The starting logical block address to be read/written.
567 The caller is responsible for reading/writing to only
568 legitimate locations.
569 @param[in, out] Buffer A pointer to the destination/source buffer for the data.
570 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
571 @param[in] IsRead Indicates it is a read or write operation.
572 @param[in, out] Token A pointer to the token associated with the transaction.
574 @retval EFI_SUCCESS The data was read/written correctly to the device.
575 @retval EFI_WRITE_PROTECTED The device can not be read/written to.
576 @retval EFI_DEVICE_ERROR The device reported an error while performing the read/write.
577 @retval EFI_NO_MEDIA There is no media in the device.
578 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
579 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
580 @retval EFI_INVALID_PARAMETER The read/write request contains LBAs that are not valid,
581 or the buffer is not on proper alignment.
586 IN SD_DEVICE
*Device
,
592 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
596 EFI_BLOCK_IO_MEDIA
*Media
;
604 Status
= EFI_SUCCESS
;
605 Media
= &Device
->BlockMedia
;
608 if (MediaId
!= Media
->MediaId
) {
609 return EFI_MEDIA_CHANGED
;
612 if (!IsRead
&& Media
->ReadOnly
) {
613 return EFI_WRITE_PROTECTED
;
619 if (Buffer
== NULL
) {
620 return EFI_INVALID_PARAMETER
;
623 if (BufferSize
== 0) {
624 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
625 Token
->TransactionStatus
= EFI_SUCCESS
;
626 gBS
->SignalEvent (Token
->Event
);
631 BlockSize
= Media
->BlockSize
;
632 if ((BufferSize
% BlockSize
) != 0) {
633 return EFI_BAD_BUFFER_SIZE
;
636 BlockNum
= BufferSize
/ BlockSize
;
637 if ((Lba
+ BlockNum
- 1) > Media
->LastBlock
) {
638 return EFI_INVALID_PARAMETER
;
641 IoAlign
= Media
->IoAlign
;
642 if (IoAlign
> 0 && (((UINTN
) Buffer
& (IoAlign
- 1)) != 0)) {
643 return EFI_INVALID_PARAMETER
;
646 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
647 Token
->TransactionStatus
= EFI_SUCCESS
;
651 // Start to execute data transfer. The max block number in single cmd is 65535 blocks.
653 Remaining
= BlockNum
;
656 while (Remaining
> 0) {
657 if (Remaining
<= MaxBlock
) {
658 BlockNum
= Remaining
;
664 BufferSize
= BlockNum
* BlockSize
;
666 Status
= SdRwSingleBlock (Device
, Lba
, Buffer
, BufferSize
, IsRead
, Token
, LastRw
);
668 Status
= SdRwMultiBlocks (Device
, Lba
, Buffer
, BufferSize
, IsRead
, Token
, LastRw
);
670 if (EFI_ERROR (Status
)) {
673 DEBUG ((EFI_D_INFO
, "Sd%a(): Lba 0x%x BlkNo 0x%x Event %p with %r\n", IsRead
? "Read" : "Write", Lba
, BlockNum
, Token
->Event
, Status
));
676 Buffer
= (UINT8
*)Buffer
+ BufferSize
;
677 Remaining
-= BlockNum
;
684 Reset the Block Device.
686 @param This Indicates a pointer to the calling context.
687 @param ExtendedVerification Driver may perform diagnostics on reset.
689 @retval EFI_SUCCESS The device was reset.
690 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
697 IN EFI_BLOCK_IO_PROTOCOL
*This
,
698 IN BOOLEAN ExtendedVerification
703 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
705 Device
= SD_DEVICE_DATA_FROM_BLKIO (This
);
707 PassThru
= Device
->Private
->PassThru
;
708 Status
= PassThru
->ResetDevice (PassThru
, Device
->Slot
);
709 if (EFI_ERROR (Status
)) {
710 Status
= EFI_DEVICE_ERROR
;
717 Read BufferSize bytes from Lba into Buffer.
719 @param This Indicates a pointer to the calling context.
720 @param MediaId Id of the media, changes every time the media is replaced.
721 @param Lba The starting Logical Block Address to read from
722 @param BufferSize Size of Buffer, must be a multiple of device block size.
723 @param Buffer A pointer to the destination buffer for the data. The caller is
724 responsible for either having implicit or explicit ownership of the buffer.
726 @retval EFI_SUCCESS The data was read correctly from the device.
727 @retval EFI_DEVICE_ERROR The device reported an error while performing the read.
728 @retval EFI_NO_MEDIA There is no media in the device.
729 @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.
730 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
731 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
732 or the buffer is not on proper alignment.
738 IN EFI_BLOCK_IO_PROTOCOL
*This
,
748 Device
= SD_DEVICE_DATA_FROM_BLKIO (This
);
750 Status
= SdReadWrite (Device
, MediaId
, Lba
, Buffer
, BufferSize
, TRUE
, NULL
);
755 Write BufferSize bytes from Lba into Buffer.
757 @param This Indicates a pointer to the calling context.
758 @param MediaId The media ID that the write request is for.
759 @param Lba The starting logical block address to be written. The caller is
760 responsible for writing to only legitimate locations.
761 @param BufferSize Size of Buffer, must be a multiple of device block size.
762 @param Buffer A pointer to the source buffer for the data.
764 @retval EFI_SUCCESS The data was written correctly to the device.
765 @retval EFI_WRITE_PROTECTED The device can not be written to.
766 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
767 @retval EFI_NO_MEDIA There is no media in the device.
768 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
769 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
770 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
771 or the buffer is not on proper alignment.
777 IN EFI_BLOCK_IO_PROTOCOL
*This
,
787 Device
= SD_DEVICE_DATA_FROM_BLKIO (This
);
789 Status
= SdReadWrite (Device
, MediaId
, Lba
, Buffer
, BufferSize
, FALSE
, NULL
);
794 Flush the Block Device.
796 @param This Indicates a pointer to the calling context.
798 @retval EFI_SUCCESS All outstanding data was written to the device
799 @retval EFI_DEVICE_ERROR The device reported an error while writing back the data
800 @retval EFI_NO_MEDIA There is no media in the device.
806 IN EFI_BLOCK_IO_PROTOCOL
*This
816 Reset the Block Device.
818 @param[in] This Indicates a pointer to the calling context.
819 @param[in] ExtendedVerification Driver may perform diagnostics on reset.
821 @retval EFI_SUCCESS The device was reset.
822 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
829 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
830 IN BOOLEAN ExtendedVerification
835 LIST_ENTRY
*NextLink
;
839 Device
= SD_DEVICE_DATA_FROM_BLKIO2 (This
);
841 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
842 for (Link
= GetFirstNode (&Device
->Queue
);
843 !IsNull (&Device
->Queue
, Link
);
845 NextLink
= GetNextNode (&Device
->Queue
, Link
);
846 RemoveEntryList (Link
);
848 Request
= SD_REQUEST_FROM_LINK (Link
);
850 gBS
->CloseEvent (Request
->Event
);
851 Request
->Token
->TransactionStatus
= EFI_ABORTED
;
853 if (Request
->IsEnd
) {
854 gBS
->SignalEvent (Request
->Token
->Event
);
859 gBS
->RestoreTPL (OldTpl
);
865 Read BufferSize bytes from Lba into Buffer.
867 @param[in] This Indicates a pointer to the calling context.
868 @param[in] MediaId Id of the media, changes every time the media is replaced.
869 @param[in] Lba The starting Logical Block Address to read from.
870 @param[in, out] Token A pointer to the token associated with the transaction.
871 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
872 @param[out] Buffer A pointer to the destination buffer for the data. The caller is
873 responsible for either having implicit or explicit ownership of the buffer.
875 @retval EFI_SUCCESS The read request was queued if Event is not NULL.
876 The data was read correctly from the device if
878 @retval EFI_DEVICE_ERROR The device reported an error while performing
880 @retval EFI_NO_MEDIA There is no media in the device.
881 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
882 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
883 intrinsic block size of the device.
884 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
885 or the buffer is not on proper alignment.
886 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
893 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
896 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
,
904 Device
= SD_DEVICE_DATA_FROM_BLKIO2 (This
);
906 Status
= SdReadWrite (Device
, MediaId
, Lba
, Buffer
, BufferSize
, TRUE
, Token
);
911 Write BufferSize bytes from Lba into Buffer.
913 @param[in] This Indicates a pointer to the calling context.
914 @param[in] MediaId The media ID that the write request is for.
915 @param[in] Lba The starting logical block address to be written. The
916 caller is responsible for writing to only legitimate
918 @param[in, out] Token A pointer to the token associated with the transaction.
919 @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
920 @param[in] Buffer A pointer to the source buffer for the data.
922 @retval EFI_SUCCESS The data was written correctly to the device.
923 @retval EFI_WRITE_PROTECTED The device can not be written to.
924 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
925 @retval EFI_NO_MEDIA There is no media in the device.
926 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
927 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
928 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
929 or the buffer is not on proper alignment.
935 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
938 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
,
946 Device
= SD_DEVICE_DATA_FROM_BLKIO2 (This
);
948 Status
= SdReadWrite (Device
, MediaId
, Lba
, Buffer
, BufferSize
, FALSE
, Token
);
953 Flush the Block Device.
955 @param[in] This Indicates a pointer to the calling context.
956 @param[in, out] Token A pointer to the token associated with the transaction.
958 @retval EFI_SUCCESS All outstanding data was written to the device
959 @retval EFI_DEVICE_ERROR The device reported an error while writing back the data
960 @retval EFI_NO_MEDIA There is no media in the device.
966 IN EFI_BLOCK_IO2_PROTOCOL
*This
,
967 IN OUT EFI_BLOCK_IO2_TOKEN
*Token
971 // Signal event and return directly.
973 if (Token
!= NULL
&& Token
->Event
!= NULL
) {
974 Token
->TransactionStatus
= EFI_SUCCESS
;
975 gBS
->SignalEvent (Token
->Event
);
982 Set the erase start address through sync or async I/O request.
984 @param[in] Device A pointer to the SD_DEVICE instance.
985 @param[in] StartLba The starting logical block address to be erased.
986 @param[in] Token A pointer to the token associated with the transaction.
987 @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds.
988 This parameter is only meaningful in async I/O request.
990 @retval EFI_SUCCESS The request is executed successfully.
991 @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources.
992 @retval Others The request could not be executed successfully.
997 IN SD_DEVICE
*Device
,
999 IN EFI_BLOCK_IO2_TOKEN
*Token
,
1004 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
1005 SD_REQUEST
*EraseBlockStart
;
1008 EraseBlockStart
= NULL
;
1009 PassThru
= Device
->Private
->PassThru
;
1011 EraseBlockStart
= AllocateZeroPool (sizeof (SD_REQUEST
));
1012 if (EraseBlockStart
== NULL
) {
1013 Status
= EFI_OUT_OF_RESOURCES
;
1017 EraseBlockStart
->Signature
= SD_REQUEST_SIGNATURE
;
1018 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1019 InsertTailList (&Device
->Queue
, &EraseBlockStart
->Link
);
1020 gBS
->RestoreTPL (OldTpl
);
1021 EraseBlockStart
->Packet
.SdMmcCmdBlk
= &EraseBlockStart
->SdMmcCmdBlk
;
1022 EraseBlockStart
->Packet
.SdMmcStatusBlk
= &EraseBlockStart
->SdMmcStatusBlk
;
1023 EraseBlockStart
->Packet
.Timeout
= SD_GENERIC_TIMEOUT
;
1025 EraseBlockStart
->SdMmcCmdBlk
.CommandIndex
= SD_ERASE_WR_BLK_START
;
1026 EraseBlockStart
->SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
1027 EraseBlockStart
->SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
1029 if (Device
->SectorAddressing
) {
1030 EraseBlockStart
->SdMmcCmdBlk
.CommandArgument
= (UINT32
)StartLba
;
1032 EraseBlockStart
->SdMmcCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (StartLba
, Device
->BlockMedia
.BlockSize
);
1035 EraseBlockStart
->IsEnd
= IsEnd
;
1036 EraseBlockStart
->Token
= Token
;
1038 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
1039 Status
= gBS
->CreateEvent (
1044 &EraseBlockStart
->Event
1046 if (EFI_ERROR (Status
)) {
1050 EraseBlockStart
->Event
= NULL
;
1053 Status
= PassThru
->PassThru (PassThru
, Device
->Slot
, &EraseBlockStart
->Packet
, EraseBlockStart
->Event
);
1056 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
1058 // For asynchronous operation, only free request and event in error case.
1059 // The request and event will be freed in asynchronous callback for success case.
1061 if (EFI_ERROR (Status
) && (EraseBlockStart
!= NULL
)) {
1062 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1063 RemoveEntryList (&EraseBlockStart
->Link
);
1064 gBS
->RestoreTPL (OldTpl
);
1065 if (EraseBlockStart
->Event
!= NULL
) {
1066 gBS
->CloseEvent (EraseBlockStart
->Event
);
1068 FreePool (EraseBlockStart
);
1072 // For synchronous operation, free request whatever the execution result is.
1074 if (EraseBlockStart
!= NULL
) {
1075 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1076 RemoveEntryList (&EraseBlockStart
->Link
);
1077 gBS
->RestoreTPL (OldTpl
);
1078 FreePool (EraseBlockStart
);
1086 Set the erase end address through sync or async I/O request.
1088 @param[in] Device A pointer to the SD_DEVICE instance.
1089 @param[in] EndLba The ending logical block address to be erased.
1090 @param[in] Token A pointer to the token associated with the transaction.
1091 @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds.
1092 This parameter is only meaningful in async I/O request.
1094 @retval EFI_SUCCESS The request is executed successfully.
1095 @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources.
1096 @retval Others The request could not be executed successfully.
1101 IN SD_DEVICE
*Device
,
1103 IN EFI_BLOCK_IO2_TOKEN
*Token
,
1108 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
1109 SD_REQUEST
*EraseBlockEnd
;
1112 EraseBlockEnd
= NULL
;
1113 PassThru
= Device
->Private
->PassThru
;
1115 EraseBlockEnd
= AllocateZeroPool (sizeof (SD_REQUEST
));
1116 if (EraseBlockEnd
== NULL
) {
1117 Status
= EFI_OUT_OF_RESOURCES
;
1121 EraseBlockEnd
->Signature
= SD_REQUEST_SIGNATURE
;
1122 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1123 InsertTailList (&Device
->Queue
, &EraseBlockEnd
->Link
);
1124 gBS
->RestoreTPL (OldTpl
);
1125 EraseBlockEnd
->Packet
.SdMmcCmdBlk
= &EraseBlockEnd
->SdMmcCmdBlk
;
1126 EraseBlockEnd
->Packet
.SdMmcStatusBlk
= &EraseBlockEnd
->SdMmcStatusBlk
;
1127 EraseBlockEnd
->Packet
.Timeout
= SD_GENERIC_TIMEOUT
;
1129 EraseBlockEnd
->SdMmcCmdBlk
.CommandIndex
= SD_ERASE_WR_BLK_END
;
1130 EraseBlockEnd
->SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
1131 EraseBlockEnd
->SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1
;
1133 if (Device
->SectorAddressing
) {
1134 EraseBlockEnd
->SdMmcCmdBlk
.CommandArgument
= (UINT32
)EndLba
;
1136 EraseBlockEnd
->SdMmcCmdBlk
.CommandArgument
= (UINT32
)MultU64x32 (EndLba
, Device
->BlockMedia
.BlockSize
);
1139 EraseBlockEnd
->IsEnd
= IsEnd
;
1140 EraseBlockEnd
->Token
= Token
;
1142 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
1143 Status
= gBS
->CreateEvent (
1148 &EraseBlockEnd
->Event
1150 if (EFI_ERROR (Status
)) {
1154 EraseBlockEnd
->Event
= NULL
;
1157 Status
= PassThru
->PassThru (PassThru
, Device
->Slot
, &EraseBlockEnd
->Packet
, EraseBlockEnd
->Event
);
1160 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
1162 // For asynchronous operation, only free request and event in error case.
1163 // The request and event will be freed in asynchronous callback for success case.
1165 if (EFI_ERROR (Status
) && (EraseBlockEnd
!= NULL
)) {
1166 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1167 RemoveEntryList (&EraseBlockEnd
->Link
);
1168 gBS
->RestoreTPL (OldTpl
);
1169 if (EraseBlockEnd
->Event
!= NULL
) {
1170 gBS
->CloseEvent (EraseBlockEnd
->Event
);
1172 FreePool (EraseBlockEnd
);
1176 // For synchronous operation, free request whatever the execution result is.
1178 if (EraseBlockEnd
!= NULL
) {
1179 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1180 RemoveEntryList (&EraseBlockEnd
->Link
);
1181 gBS
->RestoreTPL (OldTpl
);
1182 FreePool (EraseBlockEnd
);
1190 Erase specified blocks through sync or async I/O request.
1192 @param[in] Device A pointer to the SD_DEVICE instance.
1193 @param[in] Token A pointer to the token associated with the transaction.
1194 @param[in] IsEnd A boolean to show whether it's the last cmd in a series of cmds.
1195 This parameter is only meaningful in async I/O request.
1197 @retval EFI_SUCCESS The request is executed successfully.
1198 @retval EFI_OUT_OF_RESOURCES The request could not be executed due to a lack of resources.
1199 @retval Others The request could not be executed successfully.
1204 IN SD_DEVICE
*Device
,
1205 IN EFI_BLOCK_IO2_TOKEN
*Token
,
1210 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
1211 SD_REQUEST
*EraseBlock
;
1215 PassThru
= Device
->Private
->PassThru
;
1217 EraseBlock
= AllocateZeroPool (sizeof (SD_REQUEST
));
1218 if (EraseBlock
== NULL
) {
1219 Status
= EFI_OUT_OF_RESOURCES
;
1223 EraseBlock
->Signature
= SD_REQUEST_SIGNATURE
;
1224 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1225 InsertTailList (&Device
->Queue
, &EraseBlock
->Link
);
1226 gBS
->RestoreTPL (OldTpl
);
1227 EraseBlock
->Packet
.SdMmcCmdBlk
= &EraseBlock
->SdMmcCmdBlk
;
1228 EraseBlock
->Packet
.SdMmcStatusBlk
= &EraseBlock
->SdMmcStatusBlk
;
1229 EraseBlock
->Packet
.Timeout
= SD_GENERIC_TIMEOUT
;
1231 EraseBlock
->SdMmcCmdBlk
.CommandIndex
= SD_ERASE
;
1232 EraseBlock
->SdMmcCmdBlk
.CommandType
= SdMmcCommandTypeAc
;
1233 EraseBlock
->SdMmcCmdBlk
.ResponseType
= SdMmcResponseTypeR1b
;
1235 EraseBlock
->IsEnd
= IsEnd
;
1236 EraseBlock
->Token
= Token
;
1238 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
1239 Status
= gBS
->CreateEvent (
1246 if (EFI_ERROR (Status
)) {
1250 EraseBlock
->Event
= NULL
;
1253 Status
= PassThru
->PassThru (PassThru
, Device
->Slot
, &EraseBlock
->Packet
, EraseBlock
->Event
);
1256 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
1258 // For asynchronous operation, only free request and event in error case.
1259 // The request and event will be freed in asynchronous callback for success case.
1261 if (EFI_ERROR (Status
) && (EraseBlock
!= NULL
)) {
1262 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1263 RemoveEntryList (&EraseBlock
->Link
);
1264 gBS
->RestoreTPL (OldTpl
);
1265 if (EraseBlock
->Event
!= NULL
) {
1266 gBS
->CloseEvent (EraseBlock
->Event
);
1268 FreePool (EraseBlock
);
1272 // For synchronous operation, free request whatever the execution result is.
1274 if (EraseBlock
!= NULL
) {
1275 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1276 RemoveEntryList (&EraseBlock
->Link
);
1277 gBS
->RestoreTPL (OldTpl
);
1278 FreePool (EraseBlock
);
1286 Erase a specified number of device blocks.
1288 @param[in] This Indicates a pointer to the calling context.
1289 @param[in] MediaId The media ID that the erase request is for.
1290 @param[in] Lba The starting logical block address to be
1291 erased. The caller is responsible for erasing
1292 only legitimate locations.
1293 @param[in, out] Token A pointer to the token associated with the
1295 @param[in] Size The size in bytes to be erased. This must be
1296 a multiple of the physical block size of the
1299 @retval EFI_SUCCESS The erase request was queued if Event is not
1300 NULL. The data was erased correctly to the
1301 device if the Event is NULL.to the device.
1302 @retval EFI_WRITE_PROTECTED The device cannot be erased due to write
1304 @retval EFI_DEVICE_ERROR The device reported an error while attempting
1305 to perform the erase operation.
1306 @retval EFI_INVALID_PARAMETER The erase request contains LBAs that are not
1308 @retval EFI_NO_MEDIA There is no media in the device.
1309 @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
1315 IN EFI_ERASE_BLOCK_PROTOCOL
*This
,
1318 IN OUT EFI_ERASE_BLOCK_TOKEN
*Token
,
1323 EFI_BLOCK_IO_MEDIA
*Media
;
1329 Status
= EFI_SUCCESS
;
1330 Device
= SD_DEVICE_DATA_FROM_ERASEBLK (This
);
1331 Media
= &Device
->BlockMedia
;
1333 if (MediaId
!= Media
->MediaId
) {
1334 return EFI_MEDIA_CHANGED
;
1337 if (Media
->ReadOnly
) {
1338 return EFI_WRITE_PROTECTED
;
1342 // Check parameters.
1344 BlockSize
= Media
->BlockSize
;
1345 if ((Size
% BlockSize
) != 0) {
1346 return EFI_INVALID_PARAMETER
;
1349 BlockNum
= Size
/ BlockSize
;
1350 if ((Lba
+ BlockNum
- 1) > Media
->LastBlock
) {
1351 return EFI_INVALID_PARAMETER
;
1354 if ((Token
!= NULL
) && (Token
->Event
!= NULL
)) {
1355 Token
->TransactionStatus
= EFI_SUCCESS
;
1358 LastLba
= Lba
+ BlockNum
- 1;
1360 Status
= SdEraseBlockStart (Device
, Lba
, (EFI_BLOCK_IO2_TOKEN
*)Token
, FALSE
);
1361 if (EFI_ERROR (Status
)) {
1365 Status
= SdEraseBlockEnd (Device
, LastLba
, (EFI_BLOCK_IO2_TOKEN
*)Token
, FALSE
);
1366 if (EFI_ERROR (Status
)) {
1370 Status
= SdEraseBlock (Device
, (EFI_BLOCK_IO2_TOKEN
*)Token
, TRUE
);
1371 if (EFI_ERROR (Status
)) {
1375 DEBUG ((EFI_D_ERROR
, "SdEraseBlocks(): Lba 0x%x BlkNo 0x%x Event %p with %r\n", Lba
, BlockNum
, Token
->Event
, Status
));