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