From 9c2d8281af9bc4a3c598994ba1fee96f49dfc8e9 Mon Sep 17 00:00:00 2001 From: Liran Alon Date: Sat, 28 Mar 2020 23:00:50 +0300 Subject: [PATCH] OvmfPkg/PvScsiDxe: Translate Target & LUN to/from DevicePath Implement EXT_SCSI_PASS_THRU.BuildDevicePath() and EXT_SCSI_PASS_THRU.GetTargetLun(). Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2567 Reviewed-by: Laszlo Ersek Signed-off-by: Liran Alon Message-Id: <20200328200100.60786-8-liran.alon@oracle.com> Reviewed-by: Nikita Leshenko --- OvmfPkg/PvScsiDxe/PvScsi.c | 61 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/OvmfPkg/PvScsiDxe/PvScsi.c b/OvmfPkg/PvScsiDxe/PvScsi.c index 7f51ada19a..76fc1eb910 100644 --- a/OvmfPkg/PvScsiDxe/PvScsi.c +++ b/OvmfPkg/PvScsiDxe/PvScsi.c @@ -137,7 +137,38 @@ PvScsiBuildDevicePath ( IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath ) { - return EFI_UNSUPPORTED; + UINT8 TargetValue; + PVSCSI_DEV *Dev; + SCSI_DEVICE_PATH *ScsiDevicePath; + + if (DevicePath == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // We only use first byte of target identifer + // + TargetValue = *Target; + + Dev = PVSCSI_FROM_PASS_THRU (This); + if (TargetValue > Dev->MaxTarget || Lun > Dev->MaxLun) { + return EFI_NOT_FOUND; + } + + ScsiDevicePath = AllocatePool (sizeof (*ScsiDevicePath)); + if (ScsiDevicePath == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ScsiDevicePath->Header.Type = MESSAGING_DEVICE_PATH; + ScsiDevicePath->Header.SubType = MSG_SCSI_DP; + ScsiDevicePath->Header.Length[0] = (UINT8)sizeof (*ScsiDevicePath); + ScsiDevicePath->Header.Length[1] = (UINT8)(sizeof (*ScsiDevicePath) >> 8); + ScsiDevicePath->Pun = TargetValue; + ScsiDevicePath->Lun = (UINT16)Lun; + + *DevicePath = &ScsiDevicePath->Header; + return EFI_SUCCESS; } STATIC @@ -150,7 +181,33 @@ PvScsiGetTargetLun ( OUT UINT64 *Lun ) { - return EFI_UNSUPPORTED; + SCSI_DEVICE_PATH *ScsiDevicePath; + PVSCSI_DEV *Dev; + + if (DevicePath == NULL || Target == NULL || *Target == NULL || Lun == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (DevicePath->Type != MESSAGING_DEVICE_PATH || + DevicePath->SubType != MSG_SCSI_DP) { + return EFI_UNSUPPORTED; + } + + ScsiDevicePath = (SCSI_DEVICE_PATH *)DevicePath; + Dev = PVSCSI_FROM_PASS_THRU (This); + if (ScsiDevicePath->Pun > Dev->MaxTarget || + ScsiDevicePath->Lun > Dev->MaxLun) { + return EFI_NOT_FOUND; + } + + // + // We only use first byte of target identifer + // + **Target = (UINT8)ScsiDevicePath->Pun; + ZeroMem (*Target + 1, TARGET_MAX_BYTES - 1); + *Lun = ScsiDevicePath->Lun; + + return EFI_SUCCESS; } STATIC