From nobody Tue Feb 10 00:23:13 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+58086+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+58086+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=oracle.com ARC-Seal: i=1; a=rsa-sha256; t=1587751073; cv=none; d=zohomail.com; s=zohoarc; b=DNdxlT03idOH9x7cnacdiGn8UXZ/P1jxrf/n/CWA+htoXbXOBoICkuu+0EqnbMKEAsNr2VkWYRT+sA5iI8e3QND7P2+UWd5wnUwL7e8Fx/ktANjWyPFvSj7o2j/34vX2YbReTCHl32b2yMVNEhCKyw2uwybAzhgQseV8eGfNgQs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1587751073; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=2E9QDyCzW4ObbAJoMoBvtcf76RZK4RPd2wJJ6goEohw=; b=lnSVztf4ZkLdZTM7NzKc3Hrh9u7kaLGohcrj8ENUyw8hrgFQ/B5DC5kdOcKesh2ojstI75d8oiCxPwbIR5mH1BALPOZILYRk+GQ7TVFCHnCJ3e5SlM/CztqHV+LwhVDLHiVmIh8lbc7rOxkVfdEsub6nJI2YNmttzze/MGdyKsE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+58086+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1587751073855169.09915198508963; Fri, 24 Apr 2020 10:57:53 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id 2U8rYY1788612xgxcmD7cc8G; Fri, 24 Apr 2020 10:57:53 -0700 X-Received: from aserp2120.oracle.com (aserp2120.oracle.com [141.146.126.78]) by mx.groups.io with SMTP id smtpd.web12.2073.1587751001934057924 for ; Fri, 24 Apr 2020 10:56:42 -0700 X-Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 03OHqYPa185170; Fri, 24 Apr 2020 17:56:38 GMT X-Received: from userp3020.oracle.com (userp3020.oracle.com [156.151.31.79]) by aserp2120.oracle.com with ESMTP id 30jvq52fbn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 24 Apr 2020 17:56:38 +0000 X-Received: from pps.filterd (userp3020.oracle.com [127.0.0.1]) by userp3020.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 03OHleFX078243; Fri, 24 Apr 2020 17:56:37 GMT X-Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userp3020.oracle.com with ESMTP id 30k7qxk77v-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 24 Apr 2020 17:56:37 +0000 X-Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id 03OHua6P021783; Fri, 24 Apr 2020 17:56:36 GMT X-Received: from spark.ravello.local (/213.57.127.2) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 24 Apr 2020 10:56:36 -0700 From: "Nikita Leshenko" To: devel@edk2.groups.io Cc: Nikita Leshenko , liran.alon@oracle.com, aaron.young@oracle.com, Jordan Justen , Laszlo Ersek , Ard Biesheuvel Subject: [edk2-devel] [PATCH v5 11/12] OvmfPkg/MptScsiDxe: Implement the PassThru method Date: Fri, 24 Apr 2020 20:59:26 +0300 Message-Id: <20200424175927.41210-12-nikita.leshchenko@oracle.com> In-Reply-To: <20200424175927.41210-1-nikita.leshchenko@oracle.com> References: <20200424175927.41210-1-nikita.leshchenko@oracle.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,nikita.leshchenko@oracle.com X-Gm-Message-State: v3FUrp3ej5FJVKgD9jXCM8atx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1587751073; bh=2qCGoOw6irN/EjVAJzLtDoVCeABrTOTVyJ+Llu4aWzU=; h=Cc:Date:From:Reply-To:Subject:To; b=qV1LCjq8xQGOf4m05fAFZaaaUSVGDAs9DIBq0mNb0Kawptf3pNjAedkHFjUPMjFQR4m X3m7EptmAyKVgc0MTmUClRDQESbVtryX3zzXpXFRr//73XJLFb7VTjX2BteooSKFcAE40 AFsXnVTq5hv+qIHn1moeg8yapifA2MwHmrE= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" 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=3D2390 Signed-off-by: Nikita Leshenko Reviewed-by: Laszlo Ersek --- .../Include/IndustryStandard/FusionMptScsi.h | 9 + OvmfPkg/MptScsiDxe/MptScsi.c | 409 +++++++++++++++++- OvmfPkg/MptScsiDxe/MptScsiDxe.inf | 3 + OvmfPkg/OvmfPkg.dec | 3 + 4 files changed, 422 insertions(+), 2 deletions(-) diff --git a/OvmfPkg/Include/IndustryStandard/FusionMptScsi.h b/OvmfPkg/Inc= lude/IndustryStandard/FusionMptScsi.h index 655d629d902e..99778d1537da 100644 --- a/OvmfPkg/Include/IndustryStandard/FusionMptScsi.h +++ b/OvmfPkg/Include/IndustryStandard/FusionMptScsi.h @@ -44,6 +44,15 @@ =20 #define MPT_IOC_WHOINIT_ROM_BIOS 0x02 =20 +#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_IOCSTATUS_SUCCESS 0x0000 +#define MPT_SCSI_IOCSTATUS_DEVICE_NOT_THERE 0x0043 +#define MPT_SCSI_IOCSTATUS_DATA_OVERRUN 0x0044 +#define MPT_SCSI_IOCSTATUS_DATA_UNDERRUN 0x0045 + // // Device structures // diff --git a/OvmfPkg/MptScsiDxe/MptScsi.c b/OvmfPkg/MptScsiDxe/MptScsi.c index 15d671b544c2..9cb5088bfbf9 100644 --- a/OvmfPkg/MptScsiDxe/MptScsi.c +++ b/OvmfPkg/MptScsiDxe/MptScsi.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include =20 @@ -30,19 +31,50 @@ // Runtime Structures // =20 +typedef struct { + MPT_SCSI_REQUEST_ALIGNED IoRequest; + MPT_SCSI_IO_REPLY_ALIGNED IoReply; + // + // As EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET.SenseDataLength is defi= ned + // as UINT8, defining here SenseData size to MAX_UINT8 will guarantee it + // cannot overflow when passed to device. + // + UINT8 Sense[MAX_UINT8]; + // + // This size of the data is arbitrarily chosen. + // It seems to be sufficient for all I/O requests sent through + // EFI_SCSI_PASS_THRU_PROTOCOL.PassThru() for common boot scenarios. + // + UINT8 Data[0x2000]; +} MPT_SCSI_DMA_BUFFER; + #define MPT_SCSI_DEV_SIGNATURE SIGNATURE_32 ('M','P','T','S') typedef struct { UINT32 Signature; EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru; EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode; UINT8 MaxTarget; + UINT32 StallPerPollUsec; EFI_PCI_IO_PROTOCOL *PciIo; UINT64 OriginalPciAttributes; + MPT_SCSI_DMA_BUFFER *Dma; + EFI_PHYSICAL_ADDRESS DmaPhysical; + VOID *DmaMapping; + BOOLEAN IoReplyEnqueued; } MPT_SCSI_DEV; =20 #define MPT_SCSI_FROM_PASS_THRU(PassThruPtr) \ CR (PassThruPtr, MPT_SCSI_DEV, PassThru, MPT_SCSI_DEV_SIGNATURE) =20 +#define MPT_SCSI_DMA_ADDR(Dev, MemberName) \ + (Dev->DmaPhysical + OFFSET_OF (MPT_SCSI_DMA_BUFFER, MemberName)) + +#define MPT_SCSI_DMA_ADDR_HIGH(Dev, MemberName) \ + ((UINT32)(MPT_SCSI_DMA_ADDR (Dev, MemberName) >> 32)) + +#define MPT_SCSI_DMA_ADDR_LOW(Dev, MemberName) \ + ((UINT32)MPT_SCSI_DMA_ADDR (Dev, MemberName)) + // // Hardware functions // @@ -157,6 +189,9 @@ MptScsiInit ( "Req supports 255 targets only (max target is 254)"); Req.MaxDevices =3D Dev->MaxTarget + 1; Req.MaxBuses =3D 1; + Req.ReplyFrameSize =3D sizeof Dev->Dma->IoReply.Data; + Req.HostMfaHighAddr =3D MPT_SCSI_DMA_ADDR_HIGH (Dev, IoRequest); + Req.SenseBufferHighAddr =3D MPT_SCSI_DMA_ADDR_HIGH (Dev, Sense); =20 // // Send controller init through doorbell @@ -218,6 +253,289 @@ MptScsiInit ( return EFI_SUCCESS; } =20 +STATIC +EFI_STATUS +ReportHostAdapterError ( + OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet + ) +{ + DEBUG ((DEBUG_ERROR, "%a: fatal error in scsi request\n", __FUNCTION__)); + Packet->InTransferLength =3D 0; + Packet->OutTransferLength =3D 0; + Packet->SenseDataLength =3D 0; + Packet->HostAdapterStatus =3D EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER; + Packet->TargetStatus =3D EFI_EXT_SCSI_STATUS_TARGET_TASK_ABORTED; + return EFI_DEVICE_ERROR; +} + +STATIC +EFI_STATUS +ReportHostAdapterOverrunError ( + OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet + ) +{ + Packet->SenseDataLength =3D 0; + Packet->HostAdapterStatus =3D + EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN; + Packet->TargetStatus =3D EFI_EXT_SCSI_STATUS_TARGET_GOOD; + return EFI_BAD_BUFFER_SIZE; +} + +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 =3D &Dev->Dma->IoRequest.Data; + + if (Packet->DataDirection =3D=3D EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTION= AL || + (Packet->InTransferLength > 0 && Packet->OutTransferLength > 0) || + Packet->CdbLength > sizeof (Request->Header.Cdb)) { + return EFI_UNSUPPORTED; + } + + if (Target > Dev->MaxTarget || Lun > 0 || + Packet->DataDirection > EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL || + // + // Trying to receive, but destination pointer is NULL, or contradict= ing + // transfer direction + // + (Packet->InTransferLength > 0 && + (Packet->InDataBuffer =3D=3D NULL || + Packet->DataDirection =3D=3D EFI_EXT_SCSI_DATA_DIRECTION_WRITE + ) + ) || + + // + // Trying to send, but source pointer is NULL, or contradicting tran= sfer + // direction + // + (Packet->OutTransferLength > 0 && + (Packet->OutDataBuffer =3D=3D NULL || + Packet->DataDirection =3D=3D EFI_EXT_SCSI_DATA_DIRECTION_READ + ) + ) + ) { + return EFI_INVALID_PARAMETER; + } + + if (Packet->InTransferLength > sizeof (Dev->Dma->Data)) { + Packet->InTransferLength =3D sizeof (Dev->Dma->Data); + return ReportHostAdapterOverrunError (Packet); + } + if (Packet->OutTransferLength > sizeof (Dev->Dma->Data)) { + Packet->OutTransferLength =3D sizeof (Dev->Dma->Data); + return ReportHostAdapterOverrunError (Packet); + } + + ZeroMem (Request, sizeof (*Request)); + Request->Header.TargetId =3D Target; + // + // Only LUN 0 is currently supported, hence the cast is safe + // + Request->Header.Lun[1] =3D (UINT8)Lun; + Request->Header.Function =3D MPT_MESSAGE_HDR_FUNCTION_SCSI_IO_REQUEST; + Request->Header.MessageContext =3D 1; // We handle one request at a time + + Request->Header.CdbLength =3D Packet->CdbLength; + CopyMem (Request->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->Header.SenseBufferLength =3D Packet->SenseDataLength; + Request->Header.SenseBufferLowAddress =3D MPT_SCSI_DMA_ADDR_LOW (Dev, Se= nse); + + Request->Sg.EndOfList =3D 1; + Request->Sg.EndOfBuffer =3D 1; + Request->Sg.LastElement =3D 1; + Request->Sg.ElementType =3D MPT_SG_ENTRY_TYPE_SIMPLE; + Request->Sg.Is64BitAddress =3D 1; + Request->Sg.DataBufferAddress =3D MPT_SCSI_DMA_ADDR (Dev, Data); + + // + // "MPT_SG_ENTRY_SIMPLE.Length" is a 24-bit quantity. + // + STATIC_ASSERT ( + sizeof (Dev->Dma->Data) < SIZE_16MB, + "MPT_SCSI_DMA_BUFFER.Data must be smaller than 16MB" + ); + + if (Packet->DataDirection =3D=3D EFI_EXT_SCSI_DATA_DIRECTION_READ) { + Request->Header.DataLength =3D Packet->InTransferLength; + Request->Sg.Length =3D Packet->InTransferLength; + Request->Header.Control =3D MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ; + } else { + Request->Header.DataLength =3D Packet->OutTransferLength; + Request->Sg.Length =3D Packet->OutTransferLength; + Request->Header.Control =3D MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE; + + CopyMem (Dev->Dma->Data, Packet->OutDataBuffer, Packet->OutTransferLen= gth); + Request->Sg.BufferContainsData =3D 1; + } + + if (Request->Header.DataLength =3D=3D 0) { + Request->Header.Control =3D MPT_SCSIIO_REQUEST_CONTROL_TXDIR_NONE; + } + + 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; + + if (!Dev->IoReplyEnqueued) { + // + // Put one free reply frame on the reply queue, the hardware may use i= t to + // report an error to us. + // + Status =3D Out32 (Dev, MPT_REG_REP_Q, MPT_SCSI_DMA_ADDR_LOW (Dev, IoRe= ply)); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + Dev->IoReplyEnqueued =3D TRUE; + } + + Status =3D Out32 (Dev, MPT_REG_REQ_Q, MPT_SCSI_DMA_ADDR_LOW (Dev, IoRequ= est)); + if (EFI_ERROR (Status)) { + 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; + + // + // Timeouts are not supported for + // EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru() in this implementation. + // + for (;;) { + Status =3D 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 =3D 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 expec= t the + // next read reply to be the last. + // + Status =3D In32 (Dev, MPT_REG_REP_Q, &EmptyReply); + if (EFI_ERROR (Status) || EmptyReply !=3D 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 + ) +{ + if (Packet->DataDirection =3D=3D EFI_EXT_SCSI_DATA_DIRECTION_READ) { + CopyMem (Packet->InDataBuffer, Dev->Dma->Data, Packet->InTransferLengt= h); + } + + if (Reply =3D=3D Dev->Dma->IoRequest.Data.Header.MessageContext) { + // + // This is a turbo reply, everything is good + // + Packet->SenseDataLength =3D 0; + Packet->HostAdapterStatus =3D EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK; + Packet->TargetStatus =3D EFI_EXT_SCSI_STATUS_TARGET_GOOD; + + } else if ((Reply & BIT31) !=3D 0) { + DEBUG ((DEBUG_INFO, "%a: Full reply returned\n", __FUNCTION__)); + // + // When reply MSB is set, we got a full reply. Since we submitted only= one + // reply frame, we know it's IoReply. + // + Dev->IoReplyEnqueued =3D FALSE; + + Packet->TargetStatus =3D Dev->Dma->IoReply.Data.ScsiStatus; + // + // Make sure device only lowers SenseDataLength before copying sense + // + ASSERT (Dev->Dma->IoReply.Data.SenseCount <=3D Packet->SenseDataLength= ); + Packet->SenseDataLength =3D + (UINT8)MIN (Dev->Dma->IoReply.Data.SenseCount, Packet->SenseDataLeng= th); + CopyMem (Packet->SenseData, Dev->Dma->Sense, Packet->SenseDataLength); + + if (Packet->DataDirection =3D=3D EFI_EXT_SCSI_DATA_DIRECTION_READ) { + Packet->InTransferLength =3D Dev->Dma->IoReply.Data.TransferCount; + } else { + Packet->OutTransferLength =3D Dev->Dma->IoReply.Data.TransferCount; + } + + switch (Dev->Dma->IoReply.Data.IocStatus) { + case MPT_SCSI_IOCSTATUS_SUCCESS: + Packet->HostAdapterStatus =3D EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK; + break; + case MPT_SCSI_IOCSTATUS_DEVICE_NOT_THERE: + Packet->HostAdapterStatus =3D + EFI_EXT_SCSI_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT; + return EFI_TIMEOUT; + case MPT_SCSI_IOCSTATUS_DATA_UNDERRUN: + case MPT_SCSI_IOCSTATUS_DATA_OVERRUN: + Packet->HostAdapterStatus =3D + EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN; + break; + default: + Packet->HostAdapterStatus =3D EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER; + return EFI_DEVICE_ERROR; + } + + } else { + DEBUG ((DEBUG_ERROR, "%a: unexpected reply (%x)\n", __FUNCTION__, Repl= y)); + Packet->HostAdapterStatus =3D EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER; + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + // // Ext SCSI Pass Thru // @@ -233,7 +551,33 @@ MptScsiPassThru ( IN EFI_EVENT Event OPTIONAL ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + MPT_SCSI_DEV *Dev; + UINT32 Reply; + + Dev =3D MPT_SCSI_FROM_PASS_THRU (This); + // + // We only use first byte of target identifer + // + Status =3D MptScsiPopulateRequest (Dev, *Target, Lun, Packet); + if (EFI_ERROR (Status)) { + // + // MptScsiPopulateRequest modified packet according to the error + // + return Status; + } + + Status =3D MptScsiSendRequest (Dev, Packet); + if (EFI_ERROR (Status)) { + return ReportHostAdapterError (Packet); + } + + Status =3D MptScsiGetReply (Dev, &Reply); + if (EFI_ERROR (Status)) { + return ReportHostAdapterError (Packet); + } + + return MptScsiHandleReply (Dev, Reply, Packet); } =20 STATIC @@ -488,6 +832,8 @@ MptScsiControllerStart ( { EFI_STATUS Status; MPT_SCSI_DEV *Dev; + UINTN Pages; + UINTN BytesMapped; =20 Dev =3D AllocateZeroPool (sizeof (*Dev)); if (Dev =3D=3D NULL) { @@ -497,6 +843,7 @@ MptScsiControllerStart ( Dev->Signature =3D MPT_SCSI_DEV_SIGNATURE; =20 Dev->MaxTarget =3D PcdGet8 (PcdMptScsiMaxTargetLimit); + Dev->StallPerPollUsec =3D PcdGet32 (PcdMptScsiStallPerPollUsec); =20 Status =3D gBS->OpenProtocol ( ControllerHandle, @@ -557,11 +904,45 @@ MptScsiControllerStart ( )); } =20 - Status =3D MptScsiInit (Dev); + // + // Create buffers for data transfer + // + Pages =3D EFI_SIZE_TO_PAGES (sizeof (*Dev->Dma)); + Status =3D Dev->PciIo->AllocateBuffer ( + Dev->PciIo, + AllocateAnyPages, + EfiBootServicesData, + Pages, + (VOID **)&Dev->Dma, + EFI_PCI_ATTRIBUTE_MEMORY_CACHED + ); if (EFI_ERROR (Status)) { goto RestoreAttributes; } =20 + BytesMapped =3D EFI_PAGES_TO_SIZE (Pages); + Status =3D Dev->PciIo->Map ( + Dev->PciIo, + EfiPciIoOperationBusMasterCommonBuffer, + Dev->Dma, + &BytesMapped, + &Dev->DmaPhysical, + &Dev->DmaMapping + ); + if (EFI_ERROR (Status)) { + goto FreeBuffer; + } + + if (BytesMapped !=3D EFI_PAGES_TO_SIZE (Pages)) { + Status =3D EFI_OUT_OF_RESOURCES; + goto Unmap; + } + + Status =3D MptScsiInit (Dev); + if (EFI_ERROR (Status)) { + goto Unmap; + } + // // Host adapter channel, doesn't exist // @@ -594,6 +975,19 @@ MptScsiControllerStart ( UninitDev: MptScsiReset (Dev); =20 +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, @@ -655,6 +1049,17 @@ MptScsiControllerStop ( =20 MptScsiReset (Dev); =20 + 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, EfiPciIoAttributeOperationSet, diff --git a/OvmfPkg/MptScsiDxe/MptScsiDxe.inf b/OvmfPkg/MptScsiDxe/MptScsi= Dxe.inf index 4862ff9dd497..bb89e50e08f0 100644 --- a/OvmfPkg/MptScsiDxe/MptScsiDxe.inf +++ b/OvmfPkg/MptScsiDxe/MptScsiDxe.inf @@ -37,3 +37,6 @@ [Protocols] =20 [FixedPcd] gUefiOvmfPkgTokenSpaceGuid.PcdMptScsiMaxTargetLimit ## CONSUMES + +[Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdMptScsiStallPerPollUsec ## CONSUMES diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index 2d09444bbb16..3bf26e8df82d 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -167,6 +167,9 @@ [PcdsFixedAtBuild] # by ScsiBusDxe. gUefiOvmfPkgTokenSpaceGuid.PcdMptScsiMaxTargetLimit|7|UINT8|0x39 =20 + ## Microseconds to stall between polling for MptScsi request result + gUefiOvmfPkgTokenSpaceGuid.PcdMptScsiStallPerPollUsec|5|UINT32|0x40 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase|0x0|UINT32|= 0x8 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize|0x0|UINT32|= 0x9 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize|0x0|UINT32|0xa --=20 2.20.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#58086): https://edk2.groups.io/g/devel/message/58086 Mute This Topic: https://groups.io/mt/73247273/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-