From: Jan Dąbroś <[email protected]>

SD_STOP_TRANSMISSION command is necessary for multi block operations
(read and write). This patch adds this functionality.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jan Dabros <[email protected]>
Signed-off-by: Marcin Wojtas <[email protected]>
---
 MdeModulePkg/Bus/Sd/SdDxe/SdBlockIo.c | 48 +++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/MdeModulePkg/Bus/Sd/SdDxe/SdBlockIo.c 
b/MdeModulePkg/Bus/Sd/SdDxe/SdBlockIo.c
index d8b9459..411f353 100644
--- a/MdeModulePkg/Bus/Sd/SdDxe/SdBlockIo.c
+++ b/MdeModulePkg/Bus/Sd/SdDxe/SdBlockIo.c
@@ -296,6 +296,46 @@ SdGetCid (
 }
 
 /**
+  Send command SD_STOP_TRANSMISSION to stop multiple block transfer.
+
+  @param[in]  Device            A pointer to the SD_DEVICE instance.
+
+  @retval EFI_SUCCESS           The request is executed successfully.
+  @retval Others                The request could not be executed successfully.
+
+**/
+EFI_STATUS
+SdSendStopTransmission (
+  IN     SD_DEVICE              *Device
+  )
+{
+  EFI_STATUS                           Status;
+  EFI_SD_MMC_PASS_THRU_PROTOCOL        *PassThru;
+  EFI_SD_MMC_COMMAND_BLOCK             SdMmcCmdBlk;
+  EFI_SD_MMC_STATUS_BLOCK              SdMmcStatusBlk;
+  EFI_SD_MMC_PASS_THRU_COMMAND_PACKET  Packet;
+
+  PassThru = Device->Private->PassThru;
+
+  ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
+  ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
+  ZeroMem (&Packet, sizeof (Packet));
+
+  Packet.SdMmcCmdBlk    = &SdMmcCmdBlk;
+  Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
+  Packet.Timeout        = SD_GENERIC_TIMEOUT;
+
+  SdMmcCmdBlk.CommandIndex = SD_STOP_TRANSMISSION;
+  SdMmcCmdBlk.CommandType  = SdMmcCommandTypeAc;
+  SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1b;
+  SdMmcCmdBlk.CommandArgument = 0;
+
+  Status = PassThru->PassThru (PassThru, Device->Slot, &Packet, NULL);
+
+  return Status;
+}
+
+/**
   Read/write single block through sync or async I/O request.
 
   @param[in]  Device            A pointer to the SD_DEVICE instance.
@@ -523,6 +563,14 @@ SdRwMultiBlocks (
   }
 
   Status = PassThru->PassThru (PassThru, Device->Slot, &RwMultiBlkReq->Packet, 
RwMultiBlkReq->Event);
+  if (EFI_ERROR(Status)) {
+    goto Error;
+  }
+
+  // Send STOP_TRANSMISSION command for multi block transfers
+  if (FeaturePcdGet(PcdSdForcePioMode)) {
+    Status = SdSendStopTransmission (Device);
+  }
 
 Error:
   if ((Token != NULL) && (Token->Event != NULL)) {
-- 
1.8.3.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to