Open PciIo protocol and use it to initialize the device. The initialization of LSI 53C895A is simple: just set the SRST bit in Interrupt Status Zero register to reset the device.
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 | 21 ++++ OvmfPkg/LsiScsiDxe/LsiScsi.c | 129 ++++++++++++++++++++- OvmfPkg/LsiScsiDxe/LsiScsi.h | 3 + 3 files changed, 152 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/Include/IndustryStandard/LsiScsi.h b/OvmfPkg/Include/IndustryStandard/LsiScsi.h index c09e864a1f39..60e527f1c6a7 100644 --- a/OvmfPkg/Include/IndustryStandard/LsiScsi.h +++ b/OvmfPkg/Include/IndustryStandard/LsiScsi.h @@ -17,4 +17,25 @@ #define LSI_LOGIC_PCI_VENDOR_ID 0x1000 #define LSI_53C895A_PCI_DEVICE_ID 0x0012 +// +// LSI 53C895A Registers +// +#define LSI_REG_DSTAT 0x0C +#define LSI_REG_ISTAT0 0x14 +#define LSI_REG_DSP 0x2C +#define LSI_REG_SIST0 0x42 +#define LSI_REG_SIST1 0x43 + +// +// The status bits for Interrupt Status Zero (ISTAT0) +// +#define LSI_ISTAT0_DIP 0x01 +#define LSI_ISTAT0_SIP 0x02 +#define LSI_ISTAT0_INTF 0x04 +#define LSI_ISTAT0_CON 0x08 +#define LSI_ISTAT0_SEM 0x10 +#define LSI_ISTAT0_SIGP 0x20 +#define LSI_ISTAT0_SRST 0x40 +#define LSI_ISTAT0_ABRT 0x80 + #endif // _LSI_SCSI_H_ diff --git a/OvmfPkg/LsiScsiDxe/LsiScsi.c b/OvmfPkg/LsiScsiDxe/LsiScsi.c index e10a81a5f9f7..f03774cc4ced 100644 --- a/OvmfPkg/LsiScsiDxe/LsiScsi.c +++ b/OvmfPkg/LsiScsiDxe/LsiScsi.c @@ -25,6 +25,33 @@ #include "LsiScsi.h" +STATIC +EFI_STATUS +Out8 ( + IN LSI_SCSI_DEV *Dev, + IN UINT32 Addr, + IN UINT8 Data + ) +{ + return Dev->PciIo->Io.Write ( + Dev->PciIo, + EfiPciIoWidthUint8, + PCI_BAR_IDX0, + Addr, + 1, + &Data + ); +} + +STATIC +EFI_STATUS +LsiScsiReset ( + IN LSI_SCSI_DEV *Dev + ) +{ + return Out8 (Dev, LSI_REG_ISTAT0, LSI_ISTAT0_SRST); +} + // // The next seven functions implement EFI_EXT_SCSI_PASS_THRU_PROTOCOL // for the LSI 53C895A SCSI Controller. Refer to UEFI Spec 2.3.1 + Errata C, @@ -246,6 +273,21 @@ LsiScsiGetNextTarget ( return EFI_NOT_FOUND; } +STATIC +VOID +EFIAPI +LsiScsiExitBoot ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + LSI_SCSI_DEV *Dev; + + Dev = Context; + DEBUG ((DEBUG_VERBOSE, "%a: Context=0x%p\n", __FUNCTION__, Context)); + LsiScsiReset (Dev); +} + // // Probe, start and stop functions of this driver, called by the DXE core for // specific devices. @@ -328,6 +370,58 @@ LsiScsiControllerStart ( Dev->MaxTarget = PcdGet8 (PcdLsiScsiMaxTargetLimit); Dev->MaxLun = PcdGet8 (PcdLsiScsiMaxLunLimit); + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiPciIoProtocolGuid, + (VOID **)&Dev->PciIo, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + goto FreePool; + } + + Status = Dev->PciIo->Attributes ( + Dev->PciIo, + EfiPciIoAttributeOperationGet, + 0, + &Dev->OrigPciAttrs + ); + if (EFI_ERROR (Status)) { + goto CloseProtocol; + } + + // + // Enable I/O Space & Bus-Mastering + // + Status = Dev->PciIo->Attributes ( + Dev->PciIo, + EfiPciIoAttributeOperationEnable, + (EFI_PCI_IO_ATTRIBUTE_IO | + EFI_PCI_IO_ATTRIBUTE_BUS_MASTER), + NULL + ); + if (EFI_ERROR (Status)) { + goto CloseProtocol; + } + + Status = LsiScsiReset (Dev); + if (EFI_ERROR (Status)) { + goto RestoreAttributes; + } + + Status = gBS->CreateEvent ( + EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_CALLBACK, + &LsiScsiExitBoot, + Dev, + &Dev->ExitBoot + ); + if (EFI_ERROR (Status)) { + goto UninitDev; + } + // // Host adapter channel, doesn't exist // @@ -352,11 +446,33 @@ LsiScsiControllerStart ( &Dev->PassThru ); if (EFI_ERROR (Status)) { - goto FreePool; + goto CloseExitBoot; } return EFI_SUCCESS; +CloseExitBoot: + gBS->CloseEvent (Dev->ExitBoot); + +UninitDev: + LsiScsiReset (Dev); + +RestoreAttributes: + Dev->PciIo->Attributes ( + Dev->PciIo, + EfiPciIoAttributeOperationSet, + Dev->OrigPciAttrs, + NULL + ); + +CloseProtocol: + gBS->CloseProtocol ( + ControllerHandle, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + FreePool: FreePool (Dev); @@ -399,6 +515,17 @@ LsiScsiControllerStop ( return Status; } + gBS->CloseEvent (Dev->ExitBoot); + + LsiScsiReset (Dev); + + Dev->PciIo->Attributes ( + Dev->PciIo, + EfiPciIoAttributeOperationSet, + Dev->OrigPciAttrs, + NULL + ); + gBS->CloseProtocol ( ControllerHandle, &gEfiPciIoProtocolGuid, diff --git a/OvmfPkg/LsiScsiDxe/LsiScsi.h b/OvmfPkg/LsiScsiDxe/LsiScsi.h index a3d51d8f2386..ffaee6188536 100644 --- a/OvmfPkg/LsiScsiDxe/LsiScsi.h +++ b/OvmfPkg/LsiScsiDxe/LsiScsi.h @@ -14,6 +14,9 @@ typedef struct { UINT32 Signature; + UINT64 OrigPciAttrs; + EFI_EVENT ExitBoot; + EFI_PCI_IO_PROTOCOL *PciIo; UINT8 MaxTarget; UINT8 MaxLun; EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode; -- 2.25.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#61907): https://edk2.groups.io/g/devel/message/61907 Mute This Topic: https://groups.io/mt/75228765/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-