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.PcdVirtioScsiMaxTargetLimit|31|UINT16|6
|
||||||
gUefiOvmfPkgTokenSpaceGuid.PcdVirtioScsiMaxLunLimit|7|UINT32|7
|
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.PcdOvmfFlashNvStorageEventLogBase|0x0|UINT32|0x8
|
||||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize|0x0|UINT32|0x9
|
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize|0x0|UINT32|0x9
|
||||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize|0x0|UINT32|0xa
|
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize|0x0|UINT32|0xa
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <IndustryStandard/Pci.h>
|
#include <IndustryStandard/Pci.h>
|
||||||
#include <IndustryStandard/PvScsi.h>
|
#include <IndustryStandard/PvScsi.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
#include <Library/MemoryAllocationLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
#include <Library/UefiLib.h>
|
#include <Library/UefiLib.h>
|
||||||
|
@ -25,6 +26,30 @@
|
||||||
//
|
//
|
||||||
#define PVSCSI_BINDING_VERSION 0x10
|
#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
|
// Ext SCSI Pass Thru
|
||||||
//
|
//
|
||||||
|
@ -52,7 +77,54 @@ PvScsiGetNextTargetLun (
|
||||||
IN OUT UINT64 *Lun
|
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
|
STATIC
|
||||||
|
@ -111,7 +183,47 @@ PvScsiGetNextTarget (
|
||||||
IN OUT UINT8 **Target
|
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
|
STATIC
|
||||||
|
@ -120,6 +232,12 @@ PvScsiInit (
|
||||||
IN OUT PVSCSI_DEV *Dev
|
IN OUT PVSCSI_DEV *Dev
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
// Init configuration
|
||||||
|
//
|
||||||
|
Dev->MaxTarget = PcdGet8 (PcdPvScsiMaxTargetLimit);
|
||||||
|
Dev->MaxLun = PcdGet8 (PcdPvScsiMaxLunLimit);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Populate the exported interface's attributes
|
// Populate the exported interface's attributes
|
||||||
//
|
//
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT32 Signature;
|
UINT32 Signature;
|
||||||
|
UINT8 MaxTarget;
|
||||||
|
UINT8 MaxLun;
|
||||||
EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;
|
EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;
|
||||||
EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode;
|
EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode;
|
||||||
} PVSCSI_DEV;
|
} PVSCSI_DEV;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
OvmfPkg/OvmfPkg.dec
|
OvmfPkg/OvmfPkg.dec
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
|
BaseMemoryLib
|
||||||
DebugLib
|
DebugLib
|
||||||
MemoryAllocationLib
|
MemoryAllocationLib
|
||||||
UefiBootServicesTableLib
|
UefiBootServicesTableLib
|
||||||
|
@ -35,3 +36,7 @@
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiExtScsiPassThruProtocolGuid ## BY_START
|
gEfiExtScsiPassThruProtocolGuid ## BY_START
|
||||||
gEfiPciIoProtocolGuid ## TO_START
|
gEfiPciIoProtocolGuid ## TO_START
|
||||||
|
|
||||||
|
[Pcd]
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxLunLimit ## CONSUMES
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdPvScsiMaxTargetLimit ## CONSUMES
|
||||||
|
|
Loading…
Reference in New Issue