Calculate the transferred bytes during data phases based on the Cumulative SCSI Byte Count (CSBC) and update InTransferLength/OutTransferLength of the request packet.
Cc: Jordan Justen <jordan.l.jus...@intel.com> Cc: Laszlo Ersek <ler...@redhat.com> Cc: Ard Biesheuvel <ard.biesheu...@arm.com> Signed-off-by: Gary Lin <g...@suse.com> --- OvmfPkg/Include/IndustryStandard/LsiScsi.h | 1 + OvmfPkg/LsiScsiDxe/LsiScsi.c | 50 ++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/OvmfPkg/Include/IndustryStandard/LsiScsi.h b/OvmfPkg/Include/IndustryStandard/LsiScsi.h index 9964bd40385c..01d75323cdbc 100644 --- a/OvmfPkg/Include/IndustryStandard/LsiScsi.h +++ b/OvmfPkg/Include/IndustryStandard/LsiScsi.h @@ -25,6 +25,7 @@ #define LSI_REG_DSP 0x2C #define LSI_REG_SIST0 0x42 #define LSI_REG_SIST1 0x43 +#define LSI_REG_CSBC 0xDC // // The status bits for DMA Status (DSTAT) diff --git a/OvmfPkg/LsiScsiDxe/LsiScsi.c b/OvmfPkg/LsiScsiDxe/LsiScsi.c index d5fe1d4ab3b8..10483ed02bd7 100644 --- a/OvmfPkg/LsiScsiDxe/LsiScsi.c +++ b/OvmfPkg/LsiScsiDxe/LsiScsi.c @@ -79,6 +79,24 @@ In8 ( ); } +STATIC +EFI_STATUS +In32 ( + IN LSI_SCSI_DEV *Dev, + IN UINT32 Addr, + OUT UINT32 *Data + ) +{ + return Dev->PciIo->Io.Read ( + Dev->PciIo, + EfiPciIoWidthUint32, + PCI_BAR_IDX0, + Addr, + 1, + Data + ); +} + STATIC EFI_STATUS LsiScsiReset ( @@ -219,6 +237,8 @@ LsiScsiProcessRequest ( UINT8 DStat; UINT8 SIst0; UINT8 SIst1; + UINT32 Csbc; + UINT32 CsbcBase; Script = Dev->Dma->Script; Cdb = Dev->Dma->Cdb; @@ -232,6 +252,18 @@ LsiScsiProcessRequest ( SetMem (Cdb, sizeof Dev->Dma->Cdb, 0x00); CopyMem (Cdb, Packet->Cdb, Packet->CdbLength); + // + // Fetch the first Cumulative SCSI Byte Count (CSBC). + // + // CSBC is a cumulative counter of the actual number of bytes that has been + // transferred across the SCSI bus during data phases, i.e. it will not + // bytes sent in command, status, message in and out phases. + // + Status = In32 (Dev, LSI_REG_CSBC, &CsbcBase); + if (EFI_ERROR (Status)) { + return Status; + } + // // Clean up the DMA buffer for the script. // @@ -407,6 +439,24 @@ LsiScsiProcessRequest ( gBS->Stall (Dev->StallPerPollUsec); } + // + // Fetch CSBC again to calculate the transferred bytes and update + // InTransferLength/OutTransferLength. + // + // Note: The number of transferred bytes is bounded by + // "sizeof Dev->Dma->Data", so it's safe to subtract CsbcBase + // from Csbc. + // + Status = In32 (Dev, LSI_REG_CSBC, &Csbc); + if (EFI_ERROR (Status)) { + return Status; + } + if (Packet->InTransferLength > 0) { + Packet->InTransferLength = Csbc - CsbcBase; + } else if (Packet->OutTransferLength > 0) { + Packet->OutTransferLength = Csbc - CsbcBase; + } + // // Check if everything is good. // SCSI Message Code 0x00: COMMAND COMPLETE -- 2.25.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#62665): https://edk2.groups.io/g/devel/message/62665 Mute This Topic: https://groups.io/mt/75537216/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-