public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Liran Alon <liran.alon@oracle.com>
To: Nikita Leshenko <nikita.leshchenko@oracle.com>, devel@edk2.groups.io
Cc: aaron.young@oracle.com, jordan.l.justen@intel.com,
	lersek@redhat.com, ard.biesheuvel@linaro.org
Subject: Re: [PATCH v3 12/13] OvmfPkg/MptScsiDxe: Implement the PassThru method
Date: Thu, 5 Mar 2020 03:35:15 +0200	[thread overview]
Message-ID: <7939b20e-2b43-661e-4476-3b8574586098@oracle.com> (raw)
In-Reply-To: <20200304192257.96736-13-nikita.leshchenko@oracle.com>


On 04/03/2020 21:22, Nikita Leshenko wrote:
> Machines should be able to boot after this commit. Tested with different
> Linux distributions (Ubuntu, CentOS) and different Windows
> versions (Windows 7, Windows 10, Server 2016).
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2390
> Signed-off-by: Nikita Leshenko <nikita.leshchenko@oracle.com>
> ---
>   .../Include/IndustryStandard/FusionMptScsi.h  |  18 +
>   OvmfPkg/MptScsiDxe/MptScsi.c                  | 344 +++++++++++++++++-
>   OvmfPkg/MptScsiDxe/MptScsiDxe.inf             |   3 +
>   OvmfPkg/OvmfPkg.dec                           |   3 +
>   4 files changed, 365 insertions(+), 3 deletions(-)
>
> diff --git a/OvmfPkg/Include/IndustryStandard/FusionMptScsi.h b/OvmfPkg/Include/IndustryStandard/FusionMptScsi.h
> index 1ce2432bd3c2..e793f4856d0b 100644
> --- a/OvmfPkg/Include/IndustryStandard/FusionMptScsi.h
> +++ b/OvmfPkg/Include/IndustryStandard/FusionMptScsi.h
> @@ -50,6 +50,12 @@
>   
>   #define MPT_IOC_WHOINIT_ROM_BIOS 0x02
>   
> +#define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_NONE  (0x00 << 24)
> +#define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE (0x01 << 24)
> +#define MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ  (0x02 << 24)
> +
> +#define MPT_SCSI_IO_ERROR_IOCSTATUS_DEVICE_NOT_THERE 0x0043
> +
>   //
>   // Device structures
>   //
> @@ -109,6 +115,10 @@ typedef struct {
>     UINT32    Length:             24;
>     UINT32    EndOfList:          1;
>     UINT32    Is64BitAddress:     1;
> +  //
> +  // True when the buffer contains data to be transfered. Otherwise it's the
> +  // destination buffer
> +  //
Why is this comment added on this patch and not the previous one which 
introduced the struct?
>     UINT32    BufferContainsData: 1;
>     UINT32    LocalAddress:       1;
>     UINT32    ElementType:        2;
> @@ -141,4 +151,12 @@ typedef struct {
>     UINT64 Uint64; // 8 byte alignment required by HW
>   } MPT_SCSI_IO_ERROR_REPLY;
>   
> +typedef union {
> +  struct {
> +    MPT_SCSI_IO_REQUEST Header;
> +    MPT_SG_ENTRY_SIMPLE Sg;
> +  } Data;
> +  UINT64 Uint64; // 8 byte alignment required by HW
> +} MPT_SCSI_REQUEST_WITH_SG;
> +
>   #endif // __FUSION_MPT_SCSI_H__
> diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c
> index 37f1ea4b3506..0985be07bc8e 100644
> --- a/OvmfPkg/MptScsiDxe/MptScsi.c
> +++ b/OvmfPkg/MptScsiDxe/MptScsi.c
> @@ -23,6 +23,7 @@
>   #include <Library/UefiBootServicesTableLib.h>
>   #include <Library/UefiLib.h>
>   #include <Protocol/PciIo.h>
> +#include <Protocol/PciRootBridgeIo.h>
>   #include <Protocol/ScsiPassThruExt.h>
>   
>   //
> @@ -35,6 +36,13 @@
>   // Runtime Structures
>   //
>   
> +typedef struct {
> +  MPT_SCSI_IO_ERROR_REPLY         IoErrorReply;
> +  MPT_SCSI_REQUEST_WITH_SG        IoRequest;
> +  UINT8                           Sense[MAX_UINT8];
> +  UINT8                           Data[0x2000];
> +} MPT_SCSI_DMA_BUFFER;
> +
>   #define MPT_SCSI_DEV_SIGNATURE SIGNATURE_32 ('M','P','T','S')
>   typedef struct {
>     UINT32                          Signature;
> @@ -42,11 +50,18 @@ typedef struct {
>     EFI_EXT_SCSI_PASS_THRU_MODE     PassThruMode;
>     EFI_PCI_IO_PROTOCOL             *PciIo;
>     UINT64                          OriginalPciAttributes;
> +  UINT32                          StallPerPollUsec;
> +  MPT_SCSI_DMA_BUFFER             *Dma;
> +  EFI_PHYSICAL_ADDRESS            DmaPhysical;
> +  VOID                            *DmaMapping;
>   } MPT_SCSI_DEV;
>   
>   #define MPT_SCSI_FROM_PASS_THRU(PassThruPtr) \
>     CR (PassThruPtr, MPT_SCSI_DEV, PassThru, MPT_SCSI_DEV_SIGNATURE)
>   
> +#define MPT_SCSI_DMA_ADDR(Dev, MemberName) \
> +  (Dev->DmaPhysical + OFFSET_OF(MPT_SCSI_DMA_BUFFER, MemberName))
> +
>   //
>   // Hardware functions
>   //
> @@ -147,6 +162,8 @@ MptScsiInit (
>     UINT8                          *ReplyBytes;
>     UINT32                         Reply32;
>   
> +  Dev->StallPerPollUsec = PcdGet32 (PcdMptScsiStallPerPollUsec);
> +
>     Status = MptScsiReset (Dev);
>     if (EFI_ERROR (Status)) {
>       return Status;
> @@ -205,6 +222,227 @@ MptScsiInit (
>       return Status;
>     }
>   
> +  //
> +  // Put one free reply frame on the reply queue, the hardware may use it to
> +  // report an error to us.
> +  //
> +  Status = Out32 (Dev, MPT_REG_REP_Q, MPT_SCSI_DMA_ADDR (Dev, IoErrorReply));
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +MptScsiPopulateRequest (
> +  IN MPT_SCSI_DEV                                   *Dev,
> +  IN UINT8                                          Target,
> +  IN UINT64                                         Lun,
> +  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
> +  )
> +{
> +  MPT_SCSI_REQUEST_WITH_SG *Request;
> +
> +  Request = &Dev->Dma->IoRequest;
> +
> +  if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL ||
> +      Packet->CdbLength > sizeof (Request->Data.Header.CDB)) {
> +    return EFI_UNSUPPORTED;
> +  }
According to VirtioScsi implementation, you should also check for 
bidirectional direction by adding the following condition:
"(Packet->InTransferLength > 0 && Packet->OutTransferLength > 0).
> +
> +  if (Target > 0 || Lun > 0) {
> +    return EFI_INVALID_PARAMETER;
> +  }

According to VirtioScsi implementation, you should also check for the 
following contradicting parameters (I don't know if it's really 
required...):

       //
       // 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)
         )
        )

> +
> +  if (Packet->InTransferLength > sizeof (Dev->Dma->Data)) {
> +    Packet->InTransferLength = sizeof (Dev->Dma->Data);
> +    return EFI_BAD_BUFFER_SIZE;
> +  }
> +  if (Packet->OutTransferLength > sizeof (Dev->Dma->Data)) {
> +    Packet->OutTransferLength = sizeof (Dev->Dma->Data);
> +    return EFI_BAD_BUFFER_SIZE;
> +  }
> +
> +  ZeroMem (Request, sizeof (*Request));
> +  Request->Data.Header.TargetID = Target;
> +  //
> +  // It's 1 and not 0, for some reason...
> +  //
> +  Request->Data.Header.LUN[1] = Lun;
> +  Request->Data.Header.Function = MPT_MESSAGE_HDR_FUNCTION_SCSI_IO_REQUEST;
> +  Request->Data.Header.MessageContext = 1; // We handle one request at a time
> +
> +  Request->Data.Header.CDBLength = Packet->CdbLength;
> +  CopyMem (Request->Data.Header.CDB, Packet->Cdb, Packet->CdbLength);
> +
> +  //
> +  // SenseDataLength is UINT8, Sense[] is MAX_UINT8, so we can't overflow
> +  //
> +  ZeroMem (&Dev->Dma->Sense, Packet->SenseDataLength);
> +  Request->Data.Header.SenseBufferLength = Packet->SenseDataLength;
> +  Request->Data.Header.SenseBufferLowAddress = MPT_SCSI_DMA_ADDR (Dev, Sense);
> +
> +  Request->Data.Sg.EndOfList = 1;
> +  Request->Data.Sg.EndOfBuffer = 1;
> +  Request->Data.Sg.LastElement = 1;
> +  Request->Data.Sg.ElementType = MPT_SG_ENTRY_TYPE_SIMPLE;
> +  Request->Data.Sg.DataBufferAddress = MPT_SCSI_DMA_ADDR (Dev, Data);
> +
> +  Request->Data.Header.Control = MPT_SCSIIO_REQUEST_CONTROL_TXDIR_NONE;
Why explicitly init Control field to 0? You have already 
ZeroMem(Request). Seems redundant.
> +  switch (Packet->DataDirection)
> +  {
> +  case EFI_EXT_SCSI_DATA_DIRECTION_READ:
> +    if (Packet->InTransferLength == 0) {
> +      break;
> +    }
> +    Request->Data.Header.DataLength = Packet->InTransferLength;
> +    Request->Data.Sg.Length = Packet->InTransferLength;
> +    Request->Data.Header.Control = MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ;
> +    break;
> +  case EFI_EXT_SCSI_DATA_DIRECTION_WRITE:
> +    if (Packet->OutTransferLength == 0) {
> +      break;
> +    }
> +    Request->Data.Header.DataLength = Packet->OutTransferLength;
> +    Request->Data.Sg.Length = Packet->OutTransferLength;
> +    Request->Data.Header.Control = MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE;
> +
> +    CopyMem (Dev->Dma->Data, Packet->OutDataBuffer, Packet->OutTransferLength);
> +    Request->Data.Sg.BufferContainsData = 1;
> +    break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +MptScsiSendRequest (
> +  IN MPT_SCSI_DEV                                   *Dev,
> +  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  //
> +  // Make sure Request is fully written
> +  //
> +  MemoryFence ();
MemoryFence() shouldn't be required here and thus should be removed.
EDK2 IOPort and MMIO accessors should be responsible for performing 
required compiler-barrier and memory-barriers (Based on architecture). 
If that's not the case, then this is a bug in EDK2 that should be fixed.

On x86 specific (As we are talking about IOPorts which are x86 
specific), IOPort instruction (e.g. "outl") guarantees it is completed 
only after all previous reads/writes were completed and performed on 
memory (E.g. Store-buffer is flushed). In addition, writes to IOSpace 
are guaranteed to never be buffered. See AMD System Programming Manual 
Volume 2 section 7.5 Buffering and Combining Memory Writes.

Specifically, it can be seen in 
MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c that IoWrite32() use 
_ReadWriteBarrier() to perform required compiler-barrier. In contrast, 
MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c IoWrite32() seems to only 
execute "outl" using gcc inline asm. It seems a bit bizzare to me that 
it doesn't specify the "memory" clobber to perform required 
compiler-barrier. Lazlo, is this a bug? If so, I can submit a trivial 
commit to fix it.

> +
> +  Status = Out32 (Dev, MPT_REG_REQ_Q, MPT_SCSI_DMA_ADDR (Dev, IoRequest));
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // We couldn't enqueue the request, report it as an adapter error
> +    //
> +    Packet->InTransferLength  = 0;
> +    Packet->OutTransferLength = 0;
> +    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
> +    Packet->TargetStatus      = EFI_EXT_SCSI_STATUS_TARGET_GOOD;
> +    Packet->SenseDataLength   = 0;
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +MptScsiGetReply (
> +  IN MPT_SCSI_DEV                                   *Dev,
> +  OUT UINT32                                        *Reply
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT32     Istatus;
> +  UINT32     EmptyReply;
> +
Nit: Add a comment here that this loop is infinite as you currently 
don't support EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET Timeout.
> +  for (;;) {
> +    Status = In32 (Dev, MPT_REG_ISTATUS, &Istatus);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    //
> +    // Interrupt raised
> +    //
> +    if (Istatus & MPT_IMASK_REPLY) {
> +      break;
> +    }
> +
> +    gBS->Stall (Dev->StallPerPollUsec);
> +  }
> +
> +  Status = In32 (Dev, MPT_REG_REP_Q, Reply);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // The driver is supposed to fetch replies until 0xffffffff is returned, which
> +  // will reset the interrupt status. We put only one request, so we expect the
> +  // next read reply to be the last.
> +  //
> +  Status = In32 (Dev, MPT_REG_REP_Q, &EmptyReply);
> +  if (EFI_ERROR (Status) || EmptyReply != MAX_UINT32) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +MptScsiHandleReply (
> +  IN MPT_SCSI_DEV                                   *Dev,
> +  IN UINT32                                         Reply,
> +  OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  CopyMem (Packet->SenseData, Dev->Dma->Sense, Packet->SenseDataLength);
> +  if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
> +    CopyMem (Packet->InDataBuffer, Dev->Dma->Data, Packet->InTransferLength);
> +  }

You should populate Packet->TargetStatus with 
Dev->Dma->IoErrorReply.Data.SCSIStatus.

In theory, you should've also updated Packet->SenseDataLength according 
to Dev->Dma->IoErrorReply.Data.SenseCount, and 
Packet->InTransferLength/OutTransferLength according to 
Dev->Dma->IoErrorReply.Data.TransferCount. This is documented in these 
EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET documentation.
However, examining VirtualBox implementation for this device 
(https://www.virtualbox.org/browser/vbox/trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp) 
seems to reveal that it only updates SenseCount and TransferCount fields 
on I/O error. Therefore, it seems that the above suggestion won't work 
on this device emulation.
I would result to at least documenting why you don't update these fields 
if this is the case. i.e. To preserve working on buggy device emulation 
implementations.


> +
> +  if (Reply == Dev->Dma->IoRequest.Data.Header.MessageContext) {
> +    //
> +    // Everything is good
> +    //
> +    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;
> +    Packet->TargetStatus = EFI_EXT_SCSI_STATUS_TARGET_GOOD;
> +
> +  } else if (Reply & (1 << 31)) {
> +    DEBUG ((DEBUG_ERROR, "%a: request failed\n", __FUNCTION__));
> +    //
> +    // When reply MSB is set, it's an error frame.
> +    //
> +
> +    switch (Dev->Dma->IoErrorReply.Data.IOCStatus) {
> +    case MPT_SCSI_IO_ERROR_IOCSTATUS_DEVICE_NOT_THERE:
> +      Packet->HostAdapterStatus =
> +        EFI_EXT_SCSI_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT;
> +      break;
> +    default:
> +      Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
> +      break;
> +    }
> +
> +    //
> +    // Resubmit the reply frame to the reply queue
> +    //
> +    Status = Out32 (Dev, MPT_REG_REP_Q, MPT_SCSI_DMA_ADDR (Dev, IoErrorReply));
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +  } else {
> +    DEBUG ((DEBUG_ERROR, "%a: unexpected reply\n", __FUNCTION__));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
>     return EFI_SUCCESS;
>   }
>   
> @@ -223,7 +461,50 @@ MptScsiPassThru (
>     IN EFI_EVENT                                      Event     OPTIONAL
>     )
>   {
> -  return EFI_UNSUPPORTED;
> +  EFI_STATUS   Status;
> +  MPT_SCSI_DEV *Dev;
> +  UINT32       Reply;
> +
> +  Dev = MPT_SCSI_FROM_PASS_THRU (This);
> +  Status = MptScsiPopulateRequest (Dev, *Target, Lun, Packet);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = MptScsiSendRequest (Dev, Packet);
> +  if (EFI_ERROR (Status)) {
Nit: I suggest adding here a comment that in case of failure, 
MptScsiSendRequest() have modified Packet fields accordingly. As it's 
not immediately obvious.
> +    return Status;
> +  }
> +
> +  Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;
> +
> +  Status = MptScsiGetReply (Dev, &Reply);
> +  if (EFI_ERROR (Status)) {
> +    goto Fatal;
> +  }
> +
> +  Status = MptScsiHandleReply (Dev, Reply, Packet);
> +  if (EFI_ERROR (Status)) {
> +    goto Fatal;
> +  }
> +
> +  return Status;
> +
> +Fatal:
> +  //
> +  // We erred in the middle of a transaction, a very serious problem has occured
> +  // and it's not clear if it's possible to recover without leaving the hardware
> +  // in an inconsistent state. Perhaps we would want to reset the device...
> +  //
> +  DEBUG ((DEBUG_ERROR, "%a: fatal error in scsi request\n", __FUNCTION__));
> +  Packet->InTransferLength  = 0;
> +  Packet->OutTransferLength = 0;
> +  if (Packet->HostAdapterStatus == EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK) {
> +    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
> +  }
> +  Packet->TargetStatus      = EFI_EXT_SCSI_STATUS_TARGET_TASK_ABORTED;
> +  Packet->SenseDataLength   = 0;
> +  return EFI_DEVICE_ERROR;
>   }
>   
>   STATIC
> @@ -453,6 +734,7 @@ MptScsiControllerStart (
>   {
>     EFI_STATUS           Status;
>     MPT_SCSI_DEV         *Dev;
> +  UINTN                BytesMapped;
>   
>     Dev = AllocateZeroPool (sizeof (*Dev));
>     if (Dev == NULL) {
> @@ -497,9 +779,42 @@ MptScsiControllerStart (
>       goto CloseProtocol;
>     }
>   
> +  //
> +  // Create buffers for data transfer
> +  //
> +  Status = Dev->PciIo->AllocateBuffer (
> +                         Dev->PciIo,
> +                         AllocateAnyPages,
> +                         EfiBootServicesData,
> +                         EFI_SIZE_TO_PAGES (sizeof (*Dev->Dma)),
> +                         (VOID **)&Dev->Dma,
> +                         EFI_PCI_ATTRIBUTE_MEMORY_CACHED
> +                         );
> +  if (EFI_ERROR (Status)) {
> +    goto RestoreAttributes;
> +  }
> +
> +  BytesMapped = sizeof (*Dev->Dma);
> +  Status = Dev->PciIo->Map (
> +                         Dev->PciIo,
> +                         EfiPciIoOperationBusMasterCommonBuffer,
> +                         Dev->Dma,
> +                         &BytesMapped,
> +                         &Dev->DmaPhysical,
> +                         &Dev->DmaMapping
> +                         );
> +  if (EFI_ERROR (Status)) {
> +    goto FreeBuffer;
> +  }
> +
> +  if (BytesMapped != sizeof (*Dev->Dma)) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Unmap;
> +  }
> +
Nit: I suggest introducing the DMA communication buffer in a separate 
patch. It ease review and makes code easier to bisect.
>     Status = MptScsiInit (Dev);
>     if (EFI_ERROR (Status)) {
> -    goto CloseProtocol;
> +    goto Unmap;
>     }
>   
>     //
> @@ -526,11 +841,23 @@ MptScsiControllerStart (
>                     &Dev->PassThru
>                     );
>     if (EFI_ERROR (Status)) {
> -    goto RestoreAttributes;
> +    goto Unmap;
>     }
>   
>     return EFI_SUCCESS;
>   
> +Unmap:
> +    Dev->PciIo->Unmap (
> +                  Dev->PciIo,
> +                  Dev->DmaMapping
> +                  );
> +
> +FreeBuffer:
> +    Dev->PciIo->FreeBuffer (
> +                    Dev->PciIo,
> +                    EFI_SIZE_TO_PAGES (sizeof (*Dev->Dma)),
> +                    Dev->Dma
> +      );
>   RestoreAttributes:
>     Dev->PciIo->Attributes (
>                   Dev->PciIo,
> @@ -590,6 +917,17 @@ MptScsiControllerStop (
>   
>     MptScsiReset (Dev);
>   
> +  Dev->PciIo->Unmap (
> +                Dev->PciIo,
> +                Dev->DmaMapping
> +                );
> +
> +  Dev->PciIo->FreeBuffer (
> +                Dev->PciIo,
> +                EFI_SIZE_TO_PAGES (sizeof (*Dev->Dma)),
> +                Dev->Dma
> +                );
> +
>     Dev->PciIo->Attributes (
>                   Dev->PciIo,
>                   EfiPciIoAttributeOperationEnable,
> diff --git a/OvmfPkg/MptScsiDxe/MptScsiDxe.inf b/OvmfPkg/MptScsiDxe/MptScsiDxe.inf
> index 8f366b92eb72..1ba65f2fbbdf 100644
> --- a/OvmfPkg/MptScsiDxe/MptScsiDxe.inf
> +++ b/OvmfPkg/MptScsiDxe/MptScsiDxe.inf
> @@ -40,3 +40,6 @@ [LibraryClasses]
>   [Protocols]
>     gEfiPciIoProtocolGuid                  ## TO_START
>     gEfiExtScsiPassThruProtocolGuid        ## BY_START
> +
> +[Pcd]
> +  gUefiOvmfPkgTokenSpaceGuid.PcdMptScsiStallPerPollUsec ## CONSUMES
> diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
> index 4c5b6511cb97..7e8097f9952e 100644
> --- a/OvmfPkg/OvmfPkg.dec
> +++ b/OvmfPkg/OvmfPkg.dec
> @@ -228,6 +228,9 @@ [PcdsFixedAtBuild]
>     ## Number of page frames to use for storing grant table entries.
>     gUefiOvmfPkgTokenSpaceGuid.PcdXenGrantFrames|4|UINT32|0x33
>   
> +  ## Microseconds to stall between polling for MptScsi request result
> +  gUefiOvmfPkgTokenSpaceGuid.PcdMptScsiStallPerPollUsec|5|UINT32|0x36
> +
>   [PcdsDynamic, PcdsDynamicEx]
>     gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
>     gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10

  reply	other threads:[~2020-03-05  1:35 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-04 19:22 [PATCH v3 00/13] OvmfPkg: Support booting from Fusion-MPT SCSI controllers Nikita Leshenko
2020-03-04 19:22 ` [PATCH v3 01/13] OvmfPkg/MptScsiDxe: Create empty driver Nikita Leshenko
2020-03-04 23:32   ` Liran Alon
2020-03-04 19:22 ` [PATCH v3 02/13] OvmfPkg/MptScsiDxe: Install DriverBinding Protocol Nikita Leshenko
2020-03-04 23:34   ` Liran Alon
2020-03-04 19:22 ` [PATCH v3 03/13] OvmfPkg/MptScsiDxe: Report name of driver Nikita Leshenko
2020-03-04 23:34   ` Liran Alon
2020-03-04 19:22 ` [PATCH v3 04/13] OvmfPkg/MptScsiDxe: Probe PCI devices and look for MptScsi Nikita Leshenko
2020-03-04 23:36   ` Liran Alon
2020-03-04 19:22 ` [PATCH v3 05/13] OvmfPkg/MptScsiDxe: Install stubbed EXT_SCSI_PASS_THRU Nikita Leshenko
2020-03-04 23:42   ` Liran Alon
2020-03-04 19:22 ` [PATCH v3 06/13] OvmfPkg/MptScsiDxe: Report one Target and one LUN Nikita Leshenko
2020-03-04 23:45   ` Liran Alon
2020-03-04 19:22 ` [PATCH v3 07/13] OvmfPkg/MptScsiDxe: Build DevicePath for discovered devices Nikita Leshenko
2020-03-04 23:47   ` Liran Alon
2020-03-04 19:22 ` [PATCH v3 08/13] OvmfPkg/MptScsiDxe: Implement GetTargetLun Nikita Leshenko
2020-03-04 23:51   ` Liran Alon
2020-03-04 19:22 ` [PATCH v3 09/13] OvmfPkg/MptScsiDxe: Open PciIo protocol for later use Nikita Leshenko
2020-03-04 23:52   ` Liran Alon
2020-03-04 19:22 ` [PATCH v3 10/13] OvmfPkg/MptScsiDxe: Set and restore PCI attributes Nikita Leshenko
2020-03-04 23:55   ` Liran Alon
2020-03-04 19:22 ` [PATCH v3 11/13] OvmfPkg/MptScsiDxe: Initialize hardware Nikita Leshenko
2020-03-05  0:29   ` Liran Alon
2020-03-04 19:22 ` [PATCH v3 12/13] OvmfPkg/MptScsiDxe: Implement the PassThru method Nikita Leshenko
2020-03-05  1:35   ` Liran Alon [this message]
2020-03-04 19:22 ` [PATCH v3 13/13] OvmfPkg/MptScsiDxe: Report multiple targets Nikita Leshenko
2020-03-05  1:41   ` Liran Alon
2020-03-05 23:31 ` [edk2-devel] [PATCH v3 00/13] OvmfPkg: Support booting from Fusion-MPT SCSI controllers Laszlo Ersek
2020-03-06 20:14 ` Laszlo Ersek
2020-03-06 21:52   ` Liran Alon
2020-03-06 22:24     ` Laszlo Ersek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7939b20e-2b43-661e-4476-3b8574586098@oracle.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox