X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FBus%2FPci%2FNvmExpressDxe%2FNvmExpressPassthru.c;h=cfad1587f299acff738723a73ca94d2a94d5fce2;hp=c33038f0e926555deca50827b021f9a38cd55d68;hb=67d3e63c2c92dc9729e7f56b4fa8b4b47bfefe73;hpb=5f5bba14b64bef23ac4fbe401db9313e91713026 diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c index c33038f0e9..cfad1587f2 100644 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c +++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c @@ -3,7 +3,7 @@ NVM Express specification. (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
- Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.
+ Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -453,6 +453,7 @@ NvmExpressPassThru ( { NVME_CONTROLLER_PRIVATE_DATA *Private; EFI_STATUS Status; + EFI_STATUS PreviousStatus; EFI_PCI_IO_PROTOCOL *PciIo; NVME_SQ *Sq; NVME_CQ *Cq; @@ -592,7 +593,8 @@ NvmExpressPassThru ( // these two cmds are special which requires their data buffer must support simultaneous access by both the // processor and a PCI Bus Master. It's caller's responsbility to ensure this. // - if (((Sq->Opc & (BIT0 | BIT1)) != 0) && (Sq->Opc != NVME_ADMIN_CRIOCQ_CMD) && (Sq->Opc != NVME_ADMIN_CRIOSQ_CMD)) { + if (((Sq->Opc & (BIT0 | BIT1)) != 0) && + !((Packet->QueueType == NVME_ADMIN_QUEUE) && ((Sq->Opc == NVME_ADMIN_CRIOCQ_CMD) || (Sq->Opc == NVME_ADMIN_CRIOSQ_CMD)))) { if ((Packet->TransferLength == 0) || (Packet->TransferBuffer == NULL)) { return EFI_INVALID_PARAMETER; } @@ -654,6 +656,7 @@ NvmExpressPassThru ( PhyAddr = (Sq->Prp[0] + EFI_PAGE_SIZE) & ~(EFI_PAGE_SIZE - 1); Prp = NvmeCreatePrpList (PciIo, PhyAddr, EFI_SIZE_TO_PAGES(Offset + Bytes) - 1, &PrpListHost, &PrpListNo, &MapPrpList); if (Prp == NULL) { + Status = EFI_OUT_OF_RESOURCES; goto EXIT; } @@ -831,6 +834,7 @@ NvmExpressPassThru ( } Data = ReadUnaligned32 ((UINT32*)&Private->CqHdbl[QueueId]); + PreviousStatus = Status; Status = PciIo->Mem.Write ( PciIo, EfiPciIoWidthUint32, @@ -839,6 +843,9 @@ NvmExpressPassThru ( 1, &Data ); + // The return status of PciIo->Mem.Write should not override + // previous status if previous status contains error. + Status = EFI_ERROR (PreviousStatus) ? PreviousStatus : Status; // // For now, the code does not support the non-blocking feature for admin queue.