]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c
MdeModulePkg/NvmExpressDxe: Fix data buffer not mapped for Write cmd
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / NvmExpressDxe / NvmExpressPassthru.c
index c33038f0e926555deca50827b021f9a38cd55d68..302cfdcd8d8dfe688c2fd9fd2ad28a690133ea3a 100644 (file)
@@ -3,7 +3,7 @@
   NVM Express specification.\r
 \r
   (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
-  Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -453,6 +453,7 @@ NvmExpressPassThru (
 {\r
   NVME_CONTROLLER_PRIVATE_DATA   *Private;\r
   EFI_STATUS                     Status;\r
+  EFI_STATUS                     PreviousStatus;\r
   EFI_PCI_IO_PROTOCOL            *PciIo;\r
   NVME_SQ                        *Sq;\r
   NVME_CQ                        *Cq;\r
@@ -592,7 +593,8 @@ NvmExpressPassThru (
   // these two cmds are special which requires their data buffer must support simultaneous access by both the\r
   // processor and a PCI Bus Master. It's caller's responsbility to ensure this.\r
   //\r
-  if (((Sq->Opc & (BIT0 | BIT1)) != 0) && (Sq->Opc != NVME_ADMIN_CRIOCQ_CMD) && (Sq->Opc != NVME_ADMIN_CRIOSQ_CMD)) {\r
+  if (((Sq->Opc & (BIT0 | BIT1)) != 0) &&\r
+      !((Packet->QueueType == NVME_ADMIN_QUEUE) && ((Sq->Opc == NVME_ADMIN_CRIOCQ_CMD) || (Sq->Opc == NVME_ADMIN_CRIOSQ_CMD)))) {\r
     if ((Packet->TransferLength == 0) || (Packet->TransferBuffer == NULL)) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
@@ -831,6 +833,7 @@ NvmExpressPassThru (
   }\r
 \r
   Data = ReadUnaligned32 ((UINT32*)&Private->CqHdbl[QueueId]);\r
+  PreviousStatus = Status;\r
   Status = PciIo->Mem.Write (\r
                PciIo,\r
                EfiPciIoWidthUint32,\r
@@ -839,6 +842,9 @@ NvmExpressPassThru (
                1,\r
                &Data\r
                );\r
+  // The return status of PciIo->Mem.Write should not override\r
+  // previous status if previous status contains error.\r
+  Status = EFI_ERROR (PreviousStatus) ? PreviousStatus : Status;\r
 \r
   //\r
   // For now, the code does not support the non-blocking feature for admin queue.\r