From f1d6c1eba1b76e57568c8d7c947f60041939f1f9 Mon Sep 17 00:00:00 2001 From: Gary Lin Date: Fri, 17 Jul 2020 14:11:27 +0800 Subject: OvmfPkg/LsiScsiDxe: Map DMA buffer Map DMA buffer and perpare for the implementation of LsiScsiPassThru(). v2: - Replace 0x10000 with SIZE_64KB macro for the DMA buffer data array - Remove DUAL_ADDRESS_CYCLE from PciIo since we don't really need 64-bit DMA address Cc: Jordan Justen Cc: Laszlo Ersek Cc: Ard Biesheuvel Signed-off-by: Gary Lin Reviewed-by: Laszlo Ersek Message-Id: <20200717061130.8881-9-glin@suse.com> --- OvmfPkg/LsiScsiDxe/LsiScsi.c | 62 +++++++++++++++++++++++++++++++++++++++++++- OvmfPkg/LsiScsiDxe/LsiScsi.h | 14 ++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) (limited to 'OvmfPkg/LsiScsiDxe') diff --git a/OvmfPkg/LsiScsiDxe/LsiScsi.c b/OvmfPkg/LsiScsiDxe/LsiScsi.c index a9c107c..52c224a 100644 --- a/OvmfPkg/LsiScsiDxe/LsiScsi.c +++ b/OvmfPkg/LsiScsiDxe/LsiScsi.c @@ -356,6 +356,8 @@ LsiScsiControllerStart ( { EFI_STATUS Status; LSI_SCSI_DEV *Dev; + UINTN Pages; + UINTN BytesMapped; Dev = AllocateZeroPool (sizeof (*Dev)); if (Dev == NULL) { @@ -411,11 +413,45 @@ LsiScsiControllerStart ( goto CloseProtocol; } - Status = LsiScsiReset (Dev); + // + // Create buffers for data transfer + // + Pages = EFI_SIZE_TO_PAGES (sizeof (*Dev->Dma)); + Status = Dev->PciIo->AllocateBuffer ( + Dev->PciIo, + AllocateAnyPages, + EfiBootServicesData, + Pages, + (VOID **)&Dev->Dma, + EFI_PCI_ATTRIBUTE_MEMORY_CACHED + ); if (EFI_ERROR (Status)) { goto RestoreAttributes; } + BytesMapped = EFI_PAGES_TO_SIZE (Pages); + Status = Dev->PciIo->Map ( + Dev->PciIo, + EfiPciIoOperationBusMasterCommonBuffer, + Dev->Dma, + &BytesMapped, + &Dev->DmaPhysical, + &Dev->DmaMapping + ); + if (EFI_ERROR (Status)) { + goto FreeBuffer; + } + + if (BytesMapped != EFI_PAGES_TO_SIZE (Pages)) { + Status = EFI_OUT_OF_RESOURCES; + goto Unmap; + } + + Status = LsiScsiReset (Dev); + if (EFI_ERROR (Status)) { + goto Unmap; + } + Status = gBS->CreateEvent ( EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK, @@ -462,6 +498,19 @@ CloseExitBoot: UninitDev: LsiScsiReset (Dev); +Unmap: + Dev->PciIo->Unmap ( + Dev->PciIo, + Dev->DmaMapping + ); + +FreeBuffer: + Dev->PciIo->FreeBuffer ( + Dev->PciIo, + Pages, + Dev->Dma + ); + RestoreAttributes: Dev->PciIo->Attributes ( Dev->PciIo, @@ -524,6 +573,17 @@ LsiScsiControllerStop ( LsiScsiReset (Dev); + Dev->PciIo->Unmap ( + Dev->PciIo, + Dev->DmaMapping + ); + + Dev->PciIo->FreeBuffer ( + Dev->PciIo, + EFI_SIZE_TO_PAGES (sizeof (*Dev->Dma)), + Dev->Dma + ); + Dev->PciIo->Attributes ( Dev->PciIo, EfiPciIoAttributeOperationSet, diff --git a/OvmfPkg/LsiScsiDxe/LsiScsi.h b/OvmfPkg/LsiScsiDxe/LsiScsi.h index 8c2acff..9f9e5c7 100644 --- a/OvmfPkg/LsiScsiDxe/LsiScsi.h +++ b/OvmfPkg/LsiScsiDxe/LsiScsi.h @@ -13,12 +13,26 @@ #define _LSI_SCSI_DXE_H_ typedef struct { + // + // Allocate 64KB for read/write buffer. It seems sufficient for the common + // boot scenarios. + // + // NOTE: The number of bytes for data transmission is bounded by DMA Byte + // Count (DBC), a 24-bit register, so the maximum is 0xFFFFFF (16MB-1). + // + UINT8 Data[SIZE_64KB]; +} LSI_SCSI_DMA_BUFFER; + +typedef struct { UINT32 Signature; UINT64 OrigPciAttrs; EFI_EVENT ExitBoot; EFI_PCI_IO_PROTOCOL *PciIo; UINT8 MaxTarget; UINT8 MaxLun; + LSI_SCSI_DMA_BUFFER *Dma; + EFI_PHYSICAL_ADDRESS DmaPhysical; + VOID *DmaMapping; EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode; EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru; } LSI_SCSI_DEV; -- cgit v1.1