mirror of https://github.com/acidanthera/audk.git
OvmfPkg/PvScsiDxe: Report the number of targets and LUNs
Implement EXT_SCSI_PASS_THRU.GetNextTarget() and EXT_SCSI_PASS_THRU.GetNextTargetLun(). ScsiBusDxe scans all MaxTarget * MaxLun possible devices. This can take unnecessarily long for large number of targets. To deal with this, VirtioScsiDxe has defined PCDs to limit the MaxTarget & MaxLun to desired values which gives sufficient performance. It is very important in virtio-scsi as it can have very big MaxTarget & MaxLun. Even though a common PVSCSI device has a default MaxTarget=64 and MaxLun=0, we implement similar mechanism as virtio-scsi for completeness. This may be useful in the future when PVSCSI will have bigger values for MaxTarget and MaxLun. Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567 Reviewed-by: Laszlo Ersek <lersek@redhat.com> Signed-off-by: Liran Alon <liran.alon@oracle.com> Message-Id: <20200328200100.60786-7-liran.alon@oracle.com> Reviewed-by: Nikita Leshenko <nikita.leshchenko@oracle.com>
This commit is contained in:
parent
e497432c2c
commit
7efce2e59c
|
@ -134,6 +134,15 @@
|
|||
gUefiOvmfPkgTokenSpaceGuid.PcdVirtioScsiMaxTargetLimit|31|UINT16|6
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdVirtioScsiMaxLunLimit|7|UINT32|7
|
||||
|
||||
## Sets the *inclusive* number of targets and LUNs that PvScsi exposes for
|
||||
# scan by ScsiBusDxe.
|
||||
# As specified above for VirtioScsi, ScsiBusDxe scans all MaxTarget * MaxLun
|
||||
# possible devices, which can take extremely long. Thus, the below constants
|
||||
# are used so that scanning the number of devices given by their product
|
||||
# is still acceptably fast.
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxTargetLimit|64|UINT8|0x36
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxLunLimit|0|UINT8|0x37
|
||||
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase|0x0|UINT32|0x8
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize|0x0|UINT32|0x9
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize|0x0|UINT32|0xa
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <IndustryStandard/Pci.h>
|
||||
#include <IndustryStandard/PvScsi.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
|
@ -25,6 +26,30 @@
|
|||
//
|
||||
#define PVSCSI_BINDING_VERSION 0x10
|
||||
|
||||
//
|
||||
// Ext SCSI Pass Thru utilities
|
||||
//
|
||||
|
||||
/**
|
||||
Check if Target argument to EXT_SCSI_PASS_THRU.GetNextTarget() and
|
||||
EXT_SCSI_PASS_THRU.GetNextTargetLun() is initialized
|
||||
**/
|
||||
STATIC
|
||||
BOOLEAN
|
||||
IsTargetInitialized (
|
||||
IN UINT8 *Target
|
||||
)
|
||||
{
|
||||
UINTN Idx;
|
||||
|
||||
for (Idx = 0; Idx < TARGET_MAX_BYTES; ++Idx) {
|
||||
if (Target[Idx] != 0xFF) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Ext SCSI Pass Thru
|
||||
//
|
||||
|
@ -52,7 +77,54 @@ PvScsiGetNextTargetLun (
|
|||
IN OUT UINT64 *Lun
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
UINT8 *TargetPtr;
|
||||
UINT8 LastTarget;
|
||||
PVSCSI_DEV *Dev;
|
||||
|
||||
if (Target == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// The Target input parameter is unnecessarily a pointer-to-pointer
|
||||
//
|
||||
TargetPtr = *Target;
|
||||
|
||||
//
|
||||
// If target not initialized, return first target & LUN
|
||||
//
|
||||
if (!IsTargetInitialized (TargetPtr)) {
|
||||
ZeroMem (TargetPtr, TARGET_MAX_BYTES);
|
||||
*Lun = 0;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// We only use first byte of target identifer
|
||||
//
|
||||
LastTarget = *TargetPtr;
|
||||
|
||||
//
|
||||
// Increment (target, LUN) pair if valid on input
|
||||
//
|
||||
Dev = PVSCSI_FROM_PASS_THRU (This);
|
||||
if (LastTarget > Dev->MaxTarget || *Lun > Dev->MaxLun) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (*Lun < Dev->MaxLun) {
|
||||
++*Lun;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
if (LastTarget < Dev->MaxTarget) {
|
||||
*Lun = 0;
|
||||
++LastTarget;
|
||||
*TargetPtr = LastTarget;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
STATIC
|
||||
|
@ -111,7 +183,47 @@ PvScsiGetNextTarget (
|
|||
IN OUT UINT8 **Target
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
UINT8 *TargetPtr;
|
||||
UINT8 LastTarget;
|
||||
PVSCSI_DEV *Dev;
|
||||
|
||||
if (Target == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// The Target input parameter is unnecessarily a pointer-to-pointer
|
||||
//
|
||||
TargetPtr = *Target;
|
||||
|
||||
//
|
||||
// If target not initialized, return first target
|
||||
//
|
||||
if (!IsTargetInitialized (TargetPtr)) {
|
||||
ZeroMem (TargetPtr, TARGET_MAX_BYTES);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// We only use first byte of target identifer
|
||||
//
|
||||
LastTarget = *TargetPtr;
|
||||
|
||||
//
|
||||
// Increment target if valid on input
|
||||
//
|
||||
Dev = PVSCSI_FROM_PASS_THRU (This);
|
||||
if (LastTarget > Dev->MaxTarget) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (LastTarget < Dev->MaxTarget) {
|
||||
++LastTarget;
|
||||
*TargetPtr = LastTarget;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
STATIC
|
||||
|
@ -120,6 +232,12 @@ PvScsiInit (
|
|||
IN OUT PVSCSI_DEV *Dev
|
||||
)
|
||||
{
|
||||
//
|
||||
// Init configuration
|
||||
//
|
||||
Dev->MaxTarget = PcdGet8 (PcdPvScsiMaxTargetLimit);
|
||||
Dev->MaxLun = PcdGet8 (PcdPvScsiMaxLunLimit);
|
||||
|
||||
//
|
||||
// Populate the exported interface's attributes
|
||||
//
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
UINT8 MaxTarget;
|
||||
UINT8 MaxLun;
|
||||
EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;
|
||||
EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode;
|
||||
} PVSCSI_DEV;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
OvmfPkg/OvmfPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
MemoryAllocationLib
|
||||
UefiBootServicesTableLib
|
||||
|
@ -35,3 +36,7 @@
|
|||
[Protocols]
|
||||
gEfiExtScsiPassThruProtocolGuid ## BY_START
|
||||
gEfiPciIoProtocolGuid ## TO_START
|
||||
|
||||
[Pcd]
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxLunLimit ## CONSUMES
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxTargetLimit ## CONSUMES
|
||||
|
|
Loading…
Reference in New Issue