diff options
author | Gary Lin <glin@suse.com> | 2020-07-17 14:11:28 +0800 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2020-07-17 20:51:55 +0000 |
commit | 97e60818b64495db562dc456a1fb31980898f4c3 (patch) | |
tree | 1fded5c5af1a103ecfff33e8da75cc8a36e08c21 /OvmfPkg/LsiScsiDxe | |
parent | f1d6c1eba1b76e57568c8d7c947f60041939f1f9 (diff) | |
download | edk2-97e60818b64495db562dc456a1fb31980898f4c3.tar.gz edk2-97e60818b64495db562dc456a1fb31980898f4c3.tar.bz2 edk2-97e60818b64495db562dc456a1fb31980898f4c3.zip |
OvmfPkg/LsiScsiDxe: Examine the incoming SCSI Request Packet
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.
v2: Make LsiScsiPassThru() return EFI_UNSUPPORTED since this function is
half-implemented
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Gary Lin <glin@suse.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20200717061130.8881-10-glin@suse.com>
Diffstat (limited to 'OvmfPkg/LsiScsiDxe')
-rw-r--r-- | OvmfPkg/LsiScsiDxe/LsiScsi.c | 98 | ||||
-rw-r--r-- | OvmfPkg/LsiScsiDxe/LsiScsi.h | 4 |
2 files changed, 102 insertions, 0 deletions
diff --git a/OvmfPkg/LsiScsiDxe/LsiScsi.c b/OvmfPkg/LsiScsiDxe/LsiScsi.c index 52c224aad9..9859632e02 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,6 +159,15 @@ LsiScsiPassThru ( IN EFI_EVENT Event OPTIONAL
)
{
+ 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_UNSUPPORTED;
}
diff --git a/OvmfPkg/LsiScsiDxe/LsiScsi.h b/OvmfPkg/LsiScsiDxe/LsiScsi.h index 9f9e5c7fed..05deeed379 100644 --- a/OvmfPkg/LsiScsiDxe/LsiScsi.h +++ b/OvmfPkg/LsiScsiDxe/LsiScsi.h @@ -14,6 +14,10 @@ typedef struct {
//
+ // The max size of CDB is 32.
+ //
+ UINT8 Cdb[32];
+ //
// Allocate 64KB for read/write buffer. It seems sufficient for the common
// boot scenarios.
//
|