This is the first part of LsiScsiPassThru(). Before processing the SCSI
Request packet, we have to make sure whether the packet is valid or not.

Cc: Jordan Justen <jordan.l.jus...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Ard Biesheuvel <ard.biesheu...@arm.com>
Signed-off-by: Gary Lin <g...@suse.com>
---
 OvmfPkg/LsiScsiDxe/LsiScsi.c | 100 ++++++++++++++++++++++++++++++++++-
 OvmfPkg/LsiScsiDxe/LsiScsi.h |   4 ++
 2 files changed, 103 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/LsiScsiDxe/LsiScsi.c b/OvmfPkg/LsiScsiDxe/LsiScsi.c
index b728d18d51df..1bcebd92e455 100644
--- a/OvmfPkg/LsiScsiDxe/LsiScsi.c
+++ b/OvmfPkg/LsiScsiDxe/LsiScsi.c
@@ -52,6 +52,95 @@ LsiScsiReset (
   return Out8 (Dev, LSI_REG_ISTAT0, LSI_ISTAT0_SRST);

 }

 

+STATIC

+EFI_STATUS

+ReportHostAdapterOverrunError (

+  OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet

+  )

+{

+  Packet->SenseDataLength = 0;

+  Packet->HostAdapterStatus =

+            EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;

+  Packet->TargetStatus = EFI_EXT_SCSI_STATUS_TARGET_GOOD;

+  return EFI_BAD_BUFFER_SIZE;

+}

+

+/**

+

+  Check the request packet from the Extended SCSI Pass Thru Protocol. The

+  request packet is modified, to be forwarded outwards by LsiScsiPassThru(),

+  if invalid or unsupported parameters are detected.

+

+  @param[in] Dev          The LSI 53C895A SCSI device the packet targets.

+

+  @param[in] Target       The SCSI target controlled by the LSI 53C895A SCSI

+                          device.

+

+  @param[in] Lun          The Logical Unit Number under the SCSI target.

+

+  @param[in out] Packet   The Extended SCSI Pass Thru Protocol packet.

+

+

+  @retval EFI_SUCCESS  The Extended SCSI Pass Thru Protocol packet was valid.

+

+  @return              Otherwise, invalid or unsupported parameters were

+                       detected. Status codes are meant for direct forwarding

+                       by the EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru()

+                       implementation.

+

+ **/

+STATIC

+EFI_STATUS

+LsiScsiCheckRequest (

+  IN LSI_SCSI_DEV                                   *Dev,

+  IN UINT8                                          Target,

+  IN UINT64                                         Lun,

+  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet

+  )

+{

+  if (Target > Dev->MaxTarget || Lun > Dev->MaxLun ||

+      Packet->DataDirection > EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL ||

+      //

+      // Trying to receive, but destination pointer is NULL, or contradicting

+      // transfer direction

+      //

+      (Packet->InTransferLength > 0 &&

+       (Packet->InDataBuffer == NULL ||

+        Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_WRITE

+         )

+        ) ||

+

+      //

+      // Trying to send, but source pointer is NULL, or contradicting transfer

+      // direction

+      //

+      (Packet->OutTransferLength > 0 &&

+       (Packet->OutDataBuffer == NULL ||

+        Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ

+         )

+        )

+    ) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL ||

+      (Packet->InTransferLength > 0 && Packet->OutTransferLength > 0) ||

+      Packet->CdbLength > sizeof Dev->Dma->Cdb) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Packet->InTransferLength > sizeof Dev->Dma->Data) {

+    Packet->InTransferLength = sizeof Dev->Dma->Data;

+    return ReportHostAdapterOverrunError (Packet);

+  }

+  if (Packet->OutTransferLength > sizeof Dev->Dma->Data) {

+    Packet->OutTransferLength = sizeof Dev->Dma->Data;

+    return ReportHostAdapterOverrunError (Packet);

+  }

+

+  return EFI_SUCCESS;

+}

+

 //

 // The next seven functions implement EFI_EXT_SCSI_PASS_THRU_PROTOCOL

 // for the LSI 53C895A SCSI Controller. Refer to UEFI Spec 2.3.1 + Errata C,

@@ -70,7 +159,16 @@ LsiScsiPassThru (
   IN EFI_EVENT                                      Event     OPTIONAL

   )

 {

-  return EFI_UNSUPPORTED;

+  EFI_STATUS   Status;

+  LSI_SCSI_DEV *Dev;

+

+  Dev = LSI_SCSI_FROM_PASS_THRU (This);

+  Status = LsiScsiCheckRequest (Dev, *Target, Lun, Packet);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

 }

 

 EFI_STATUS

diff --git a/OvmfPkg/LsiScsiDxe/LsiScsi.h b/OvmfPkg/LsiScsiDxe/LsiScsi.h
index 1e4bbc56f933..9272eb7506c7 100644
--- a/OvmfPkg/LsiScsiDxe/LsiScsi.h
+++ b/OvmfPkg/LsiScsiDxe/LsiScsi.h
@@ -13,6 +13,10 @@
 #define _LSI_SCSI_DXE_H_

 

 typedef struct {

+  //

+  // The max size of CDB is 32.

+  //

+  UINT8                           Cdb[32];

   //

   // Allocate 64KB for read/write buffer.

   //

-- 
2.25.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#61909): https://edk2.groups.io/g/devel/message/61909
Mute This Topic: https://groups.io/mt/75228768/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to