From 5269c26e07381dcc7e9de4fe1f2a5b7ed1e5c78a Mon Sep 17 00:00:00 2001 From: Liran Alon Date: Sat, 28 Mar 2020 23:00:55 +0300 Subject: [PATCH] OvmfPkg/PvScsiDxe: Reset adapter on init The following commits will complete the implementation of device initialization. Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567 Reviewed-by: Laszlo Ersek Signed-off-by: Liran Alon Message-Id: <20200328200100.60786-13-liran.alon@oracle.com> Reviewed-by: Nikita Leshenko --- OvmfPkg/PvScsiDxe/PvScsi.c | 114 +++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c index 531bed4e5a..cf75884350 100644 --- a/OvmfPkg/PvScsiDxe/PvScsi.c +++ b/OvmfPkg/PvScsiDxe/PvScsi.c @@ -30,6 +30,107 @@ // Ext SCSI Pass Thru utilities // +/** + Writes a 32-bit value into BAR0 using MMIO +**/ +STATIC +EFI_STATUS +PvScsiMmioWrite32 ( + IN CONST PVSCSI_DEV *Dev, + IN UINT64 Offset, + IN UINT32 Value + ) +{ + return Dev->PciIo->Mem.Write ( + Dev->PciIo, + EfiPciIoWidthUint32, + PCI_BAR_IDX0, + Offset, + 1, // Count + &Value + ); +} + +/** + Writes multiple words of data into BAR0 using MMIO +**/ +STATIC +EFI_STATUS +PvScsiMmioWrite32Multiple ( + IN CONST PVSCSI_DEV *Dev, + IN UINT64 Offset, + IN UINTN Count, + IN UINT32 *Words + ) +{ + return Dev->PciIo->Mem.Write ( + Dev->PciIo, + EfiPciIoWidthFifoUint32, + PCI_BAR_IDX0, + Offset, + Count, + Words + ); +} + +/** + Send a PVSCSI command to device. + + @param[in] Dev The pvscsi host device. + @param[in] Cmd The command to send to device. + @param[in] OPTIONAL DescWords An optional command descriptor (If command + have a descriptor). The descriptor is + provided as an array of UINT32 words and + is must be 32-bit aligned. + @param[in] DescWordsCount The number of words in command descriptor. + Caller must specify here 0 if DescWords + is not supplied (It is optional). In that + case, DescWords is ignored. + + @return Status codes returned by Dev->PciIo->Mem.Write(). + +**/ +STATIC +EFI_STATUS +PvScsiWriteCmdDesc ( + IN CONST PVSCSI_DEV *Dev, + IN UINT32 Cmd, + IN UINT32 *DescWords OPTIONAL, + IN UINTN DescWordsCount + ) +{ + EFI_STATUS Status; + + if (DescWordsCount > PVSCSI_MAX_CMD_DATA_WORDS) { + return EFI_INVALID_PARAMETER; + } + + Status = PvScsiMmioWrite32 (Dev, PvScsiRegOffsetCommand, Cmd); + if (EFI_ERROR (Status)) { + return Status; + } + + if (DescWordsCount > 0) { + return PvScsiMmioWrite32Multiple ( + Dev, + PvScsiRegOffsetCommandData, + DescWordsCount, + DescWords + ); + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +PvScsiResetAdapter ( + IN CONST PVSCSI_DEV *Dev + ) +{ + return PvScsiWriteCmdDesc (Dev, PvScsiCmdAdapterReset, NULL, 0); +} + /** Check if Target argument to EXT_SCSI_PASS_THRU.GetNextTarget() and EXT_SCSI_PASS_THRU.GetNextTargetLun() is initialized @@ -357,6 +458,14 @@ PvScsiInit ( return Status; } + // + // Reset adapter + // + Status = PvScsiResetAdapter (Dev); + if (EFI_ERROR (Status)) { + goto RestorePciAttributes; + } + // // Populate the exported interface's attributes // @@ -387,6 +496,11 @@ PvScsiInit ( Dev->PassThruMode.IoAlign = 0; return EFI_SUCCESS; + +RestorePciAttributes: + PvScsiRestorePciAttributes (Dev); + + return Status; } STATIC