From f9941d31dd6f95ca7557d5a5f2c1874bd3bd0e14 Mon Sep 17 00:00:00 2001 From: Nikita Leshenko Date: Tue, 5 May 2020 00:06:02 +0300 Subject: [PATCH] OvmfPkg/MptScsiDxe: Build and decode DevicePath Used to identify the individual disks in the hardware tree. Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2390 Signed-off-by: Nikita Leshenko Reviewed-by: Liran Alon Reviewed-by: Laszlo Ersek Message-Id: <20200504210607.144434-8-nikita.leshchenko@oracle.com> --- OvmfPkg/MptScsiDxe/MptScsi.c | 61 ++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c index d396bff85c..66d57f1c85 100644 --- a/OvmfPkg/MptScsiDxe/MptScsi.c +++ b/OvmfPkg/MptScsiDxe/MptScsi.c @@ -147,7 +147,36 @@ MptScsiBuildDevicePath ( IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath ) { - return EFI_UNSUPPORTED; + MPT_SCSI_DEV *Dev; + SCSI_DEVICE_PATH *ScsiDevicePath; + + if (DevicePath == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // This device support 256 targets only, so it's enough to dereference + // the LSB of Target. + // + Dev = MPT_SCSI_FROM_PASS_THRU (This); + if (*Target > Dev->MaxTarget || Lun > 0) { + return EFI_NOT_FOUND; + } + + ScsiDevicePath = AllocateZeroPool (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 = *Target; + ScsiDevicePath->Lun = (UINT16)Lun; + + *DevicePath = &ScsiDevicePath->Header; + return EFI_SUCCESS; } STATIC @@ -160,7 +189,35 @@ MptScsiGetTargetLun ( OUT UINT64 *Lun ) { - return EFI_UNSUPPORTED; + MPT_SCSI_DEV *Dev; + SCSI_DEVICE_PATH *ScsiDevicePath; + + 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; + } + + Dev = MPT_SCSI_FROM_PASS_THRU (This); + ScsiDevicePath = (SCSI_DEVICE_PATH *)DevicePath; + if (ScsiDevicePath->Pun > Dev->MaxTarget || + ScsiDevicePath->Lun > 0) { + return EFI_NOT_FOUND; + } + + ZeroMem (*Target, TARGET_MAX_BYTES); + // + // This device support 256 targets only, so it's enough to set the LSB + // of Target. + // + **Target = (UINT8)ScsiDevicePath->Pun; + *Lun = ScsiDevicePath->Lun; + + return EFI_SUCCESS; } STATIC