From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by ml01.01.org (Postfix) with ESMTP id AFDD71A1DF3 for ; Tue, 9 Aug 2016 00:42:14 -0700 (PDT) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga104.fm.intel.com with ESMTP; 09 Aug 2016 00:42:14 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,493,1464678000"; d="scan'208";a="1022181243" Received: from shwdeftian.ccr.corp.intel.com ([10.239.158.36]) by fmsmga001.fm.intel.com with ESMTP; 09 Aug 2016 00:42:13 -0700 From: Feng Tian To: star.zeng@intel.com Cc: edk2-devel@lists.01.org Date: Tue, 9 Aug 2016 15:42:03 +0800 Message-Id: X-Mailer: git-send-email 2.7.1.windows.2 Subject: [patch] MdeModulePkg/AtaAtapiPassThru: update AtaStatusBlock after cmd exec X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Aug 2016 07:42:14 -0000 AhciDumpPortStatus doesn't fully populate all the fields of AtaStatusBlock after completing command execution, which may bring issue if someone depends on the return status. Cc: Star Zeng Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Feng Tian --- MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c | 39 ++++++++++++++++++------ 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c index 469a40a..f4dbc92 100644 --- a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c +++ b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c @@ -371,6 +371,7 @@ AhciClearPortStatus ( in the Status Register, the Error Register's value is also be dumped. @param PciIo The PCI IO protocol instance. + @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. @param Port The number of port. @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure. @@ -379,24 +380,42 @@ VOID EFIAPI AhciDumpPortStatus ( IN EFI_PCI_IO_PROTOCOL *PciIo, + IN EFI_AHCI_REGISTERS *AhciRegisters, IN UINT8 Port, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock ) { - UINT32 Offset; + UINTN Offset; UINT32 Data; + UINTN FisBaseAddr; + EFI_STATUS Status; ASSERT (PciIo != NULL); - Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD; - Data = AhciReadReg (PciIo, Offset); - if (AtaStatusBlock != NULL) { ZeroMem (AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK)); - AtaStatusBlock->AtaStatus = (UINT8)Data; - if ((AtaStatusBlock->AtaStatus & BIT0) != 0) { - AtaStatusBlock->AtaError = (UINT8)(Data >> 8); + FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS); + Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET; + + Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, EFI_AHCI_FIS_REGISTER_D2H, NULL); + if (!EFI_ERROR (Status)) { + // + // If D2H FIS is received, update StatusBlock with its content. + // + CopyMem (AtaStatusBlock, (UINT8 *)Offset, sizeof (EFI_ATA_STATUS_BLOCK)); + } else { + // + // If D2H FIS is not received, only update Status & Error field through PxTFD + // as there is no other way to get the content of the Shadow Register Block. + // + Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD; + Data = AhciReadReg (PciIo, (UINT32)Offset); + + AtaStatusBlock->AtaStatus = (UINT8)Data; + if ((AtaStatusBlock->AtaStatus & BIT0) != 0) { + AtaStatusBlock->AtaError = (UINT8)(Data >> 8); + } } } } @@ -866,7 +885,7 @@ Exit: Map ); - AhciDumpPortStatus (PciIo, Port, AtaStatusBlock); + AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock); return Status; } @@ -1085,7 +1104,7 @@ Exit: } } - AhciDumpPortStatus (PciIo, Port, AtaStatusBlock); + AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock); return Status; } @@ -1201,7 +1220,7 @@ Exit: Timeout ); - AhciDumpPortStatus (PciIo, Port, AtaStatusBlock); + AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock); return Status; } -- 2.7.1.windows.2