From e497432c2ceadc3924f96e49593c8a77044efea7 Mon Sep 17 00:00:00 2001 From: Liran Alon Date: Sat, 28 Mar 2020 23:00:48 +0300 Subject: [PATCH] OvmfPkg/PvScsiDxe: Install stubbed EXT_SCSI_PASS_THRU Support dynamic insertion and removal of the protocol. Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567 Reviewed-by: Laszlo Ersek Signed-off-by: Liran Alon Message-Id: <20200328200100.60786-6-liran.alon@oracle.com> Reviewed-by: Nikita Leshenko --- OvmfPkg/PvScsiDxe/PvScsi.c | 209 +++++++++++++++++++++++++++++++- OvmfPkg/PvScsiDxe/PvScsi.h | 29 +++++ OvmfPkg/PvScsiDxe/PvScsiDxe.inf | 6 +- 3 files changed, 241 insertions(+), 3 deletions(-) create mode 100644 OvmfPkg/PvScsiDxe/PvScsi.h diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c index 9923a31d25..04c08036b7 100644 --- a/OvmfPkg/PvScsiDxe/PvScsi.c +++ b/OvmfPkg/PvScsiDxe/PvScsi.c @@ -11,17 +11,156 @@ #include #include +#include #include #include #include #include +#include "PvScsi.h" + // // Higher versions will be used before lower, 0x10-0xffffffef is the version // range for IHV (Indie Hardware Vendors) // #define PVSCSI_BINDING_VERSION 0x10 +// +// Ext SCSI Pass Thru +// + +STATIC +EFI_STATUS +EFIAPI +PvScsiPassThru ( + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, + IN UINT8 *Target, + IN UINT64 Lun, + IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet, + IN EFI_EVENT Event OPTIONAL + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +PvScsiGetNextTargetLun ( + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, + IN OUT UINT8 **Target, + IN OUT UINT64 *Lun + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +PvScsiBuildDevicePath ( + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, + IN UINT8 *Target, + IN UINT64 Lun, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +PvScsiGetTargetLun ( + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT UINT8 **Target, + OUT UINT64 *Lun + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +PvScsiResetChannel ( + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +PvScsiResetTargetLun ( + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, + IN UINT8 *Target, + IN UINT64 Lun + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +PvScsiGetNextTarget ( + IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, + IN OUT UINT8 **Target + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +PvScsiInit ( + IN OUT PVSCSI_DEV *Dev + ) +{ + // + // Populate the exported interface's attributes + // + Dev->PassThru.Mode = &Dev->PassThruMode; + Dev->PassThru.PassThru = &PvScsiPassThru; + Dev->PassThru.GetNextTargetLun = &PvScsiGetNextTargetLun; + Dev->PassThru.BuildDevicePath = &PvScsiBuildDevicePath; + Dev->PassThru.GetTargetLun = &PvScsiGetTargetLun; + Dev->PassThru.ResetChannel = &PvScsiResetChannel; + Dev->PassThru.ResetTargetLun = &PvScsiResetTargetLun; + Dev->PassThru.GetNextTarget = &PvScsiGetNextTarget; + + // + // AdapterId is a target for which no handle will be created during bus scan. + // Prevent any conflict with real devices. + // + Dev->PassThruMode.AdapterId = MAX_UINT32; + + // + // Set both physical and logical attributes for non-RAID SCSI channel + // + Dev->PassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | + EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL; + + // + // No restriction on transfer buffer alignment + // + Dev->PassThruMode.IoAlign = 0; + + return EFI_SUCCESS; +} + +STATIC +VOID +PvScsiUninit ( + IN OUT PVSCSI_DEV *Dev + ) +{ + // Currently nothing to do here +} + // // Driver Binding // @@ -90,7 +229,42 @@ PvScsiDriverBindingStart ( IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ) { - return EFI_UNSUPPORTED; + PVSCSI_DEV *Dev; + EFI_STATUS Status; + + Dev = (PVSCSI_DEV *) AllocateZeroPool (sizeof (*Dev)); + if (Dev == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = PvScsiInit (Dev); + if (EFI_ERROR (Status)) { + goto FreePvScsi; + } + + // + // Setup complete, attempt to export the driver instance's PassThru interface + // + Dev->Signature = PVSCSI_SIG; + Status = gBS->InstallProtocolInterface ( + &ControllerHandle, + &gEfiExtScsiPassThruProtocolGuid, + EFI_NATIVE_INTERFACE, + &Dev->PassThru + ); + if (EFI_ERROR (Status)) { + goto UninitDev; + } + + return EFI_SUCCESS; + +UninitDev: + PvScsiUninit (Dev); + +FreePvScsi: + FreePool (Dev); + + return Status; } STATIC @@ -103,7 +277,38 @@ PvScsiDriverBindingStop ( IN EFI_HANDLE *ChildHandleBuffer ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + EFI_EXT_SCSI_PASS_THRU_PROTOCOL *PassThru; + PVSCSI_DEV *Dev; + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiExtScsiPassThruProtocolGuid, + (VOID **)&PassThru, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL // Lookup only + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Dev = PVSCSI_FROM_PASS_THRU (PassThru); + + Status = gBS->UninstallProtocolInterface ( + ControllerHandle, + &gEfiExtScsiPassThruProtocolGuid, + &Dev->PassThru + ); + if (EFI_ERROR (Status)) { + return Status; + } + + PvScsiUninit (Dev); + + FreePool (Dev); + + return EFI_SUCCESS; } STATIC EFI_DRIVER_BINDING_PROTOCOL mPvScsiDriverBinding = { diff --git a/OvmfPkg/PvScsiDxe/PvScsi.h b/OvmfPkg/PvScsiDxe/PvScsi.h new file mode 100644 index 0000000000..3940b4c200 --- /dev/null +++ b/OvmfPkg/PvScsiDxe/PvScsi.h @@ -0,0 +1,29 @@ +/** @file + + Internal definitions for the PVSCSI driver, which produces Extended SCSI + Pass Thru Protocol instances for pvscsi devices. + + Copyright (C) 2020, Oracle and/or its affiliates. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __PVSCSI_DXE_H_ +#define __PVSCSI_DXE_H_ + +#include +#include + +#define PVSCSI_SIG SIGNATURE_32 ('P', 'S', 'C', 'S') + +typedef struct { + UINT32 Signature; + EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru; + EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode; +} PVSCSI_DEV; + +#define PVSCSI_FROM_PASS_THRU(PassThruPointer) \ + CR (PassThruPointer, PVSCSI_DEV, PassThru, PVSCSI_SIG) + +#endif // __PVSCSI_DXE_H_ diff --git a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf index c1f0663832..f4d452c6c3 100644 --- a/OvmfPkg/PvScsiDxe/PvScsiDxe.inf +++ b/OvmfPkg/PvScsiDxe/PvScsiDxe.inf @@ -19,15 +19,19 @@ [Sources] PvScsi.c + PvScsi.h [Packages] MdePkg/MdePkg.dec OvmfPkg/OvmfPkg.dec [LibraryClasses] + DebugLib + MemoryAllocationLib UefiBootServicesTableLib UefiDriverEntryPoint UefiLib [Protocols] - gEfiPciIoProtocolGuid ## TO_START + gEfiExtScsiPassThruProtocolGuid ## BY_START + gEfiPciIoProtocolGuid ## TO_START -- 2.39.2