From nobody Mon Feb 9 15:45:34 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+66925+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+66925+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1604409855; cv=none; d=zohomail.com; s=zohoarc; b=j8yPrhBsXJi2nlnL2EQb1mQt8JOTJxeyz1VGSvOc4YT/XVanqS8y4oTWv1ev0ClZv4NL5Im/aUAKRzr6OsGd6IEa/bCckFmhryWrxWd8PEGjowNncYBrqeI5jWe5LSdHeGorY7rHTPjYKKVRrLBuu8m6M+eJAgu/92H3LKHkni0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604409855; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=7A/el34vldM+IdJ33DjP4sJYNZT19tu9dUDDgInmfvc=; b=oArGeaY6lDTrOMU9zRMJ5KxmbSRQZaOAvzsndCikqwljE56bXuaSaMeniVGpd5Vw62wOgwP8k6EpITxEJfbWHGJWCoG/ITFFgVbapyw9qPvpDo0jAHPONDveeicqQOa7Ne/D9SpKCzPAyR8jZRN2qDVHV/jl/0oo+5qPiDW9gvo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+66925+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604409855674375.5926248294936; Tue, 3 Nov 2020 05:24:15 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id hSuKYY1788612xo4G6lJ09u4; Tue, 03 Nov 2020 05:24:15 -0800 X-Received: from mga03.intel.com (mga03.intel.com []) by mx.groups.io with SMTP id smtpd.web11.3908.1604409850765584058 for ; Tue, 03 Nov 2020 05:24:14 -0800 IronPort-SDR: NJnHRDg9s55M10V+i5CpJbkTRR2g37oQxIes87pBk1SxRPlzTwW4vnB6uI0eU2ZQYZqdMMZrcK d5lzlILKj5qw== X-IronPort-AV: E=McAfee;i="6000,8403,9793"; a="169155229" X-IronPort-AV: E=Sophos;i="5.77,448,1596524400"; d="scan'208";a="169155229" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Nov 2020 05:24:14 -0800 IronPort-SDR: Y2+LFXKezjQ/OXDoSUZq++ATBPBWhpri/vEkDiudW9ZFtLux9ogW3gOFxIxKY3Q0aEifog6F23 BlDtor5xpXpA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,448,1596524400"; d="scan'208";a="363023639" X-Received: from gklab-27-32.ger.corp.intel.com ([10.102.28.45]) by FMSMGA003.fm.intel.com with ESMTP; 03 Nov 2020 05:24:12 -0800 From: "Albecki, Mateusz" To: devel@edk2.groups.io Cc: Albecki , Ray Ni , Hao A Wu Subject: [edk2-devel] [PATCH 3/4] MdeModulePkg/AtaAtapiPassThru: Restart failed packets Date: Tue, 3 Nov 2020 14:23:47 +0100 Message-Id: <20201103132348.2916-4-mateusz.albecki@intel.com> In-Reply-To: <20201103132348.2916-1-mateusz.albecki@intel.com> References: <20201103132348.2916-1-mateusz.albecki@intel.com> 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,mateusz.albecki@intel.com X-Gm-Message-State: gVRdre8dNCTzuZmryL0abLVox1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604409855; bh=xMzrZl5VlGMx44eMzUciRtKFCMMbmlgehFAJtgj6DHQ=; h=Cc:Date:From:Reply-To:Subject:To; b=cXivd04KiscgLU1QMQkMb46VS+BIdXQweVdqRtV573e029c2l4TQB7Qtq1wNcLr1XK8 E9LyWUsawfi2a/Bro5I1kEUuxim4SIY5IjfMEZ7/PQFXJh3Mb05PoC5v8NSjylt4VwhrE sOBgCzEtvJt1cVjq/RqNd25YhSDlrBL62tg= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Albecki BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3026 This commit adds code to restart the ATA packets that failed due to the CRC error or other link condition. For sync transfers the code will try to get the command working for up to 5 times and for async in accordance to the RetryTimes field in Task structure. For sync case the count of 5 retries has been chosen arbitrarily and if needed can be increased or decreased. Signed-off-by: Mateusz Albecki Cc: Ray Ni Cc: Hao A Wu --- .../Bus/Ata/AtaAtapiPassThru/AhciMode.c | 305 +++++++++++------- .../Bus/Ata/AtaAtapiPassThru/AhciMode.h | 2 + 2 files changed, 182 insertions(+), 125 deletions(-) diff --git a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c b/MdeModulePk= g/Bus/Ata/AtaAtapiPassThru/AhciMode.c index cf735d5983..4fe7e4b1dc 100644 --- a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c +++ b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c @@ -897,6 +897,7 @@ AhciPioTransfer ( EFI_AHCI_COMMAND_FIS CFis; EFI_AHCI_COMMAND_LIST CmdList; UINT32 PrdCount; + UINT32 Retry; =20 if (Read) { Flag =3D EfiPciIoOperationBusMasterWrite; @@ -931,49 +932,56 @@ AhciPioTransfer ( CmdList.AhciCmdCfl =3D EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4; CmdList.AhciCmdW =3D Read ? 0 : 1; =20 - AhciBuildCommand ( - PciIo, - AhciRegisters, - Port, - PortMultiplier, - &CFis, - &CmdList, - AtapiCommand, - AtapiCommandLength, - 0, - (VOID *)(UINTN)PhyAddr, - DataCount - ); + for (Retry =3D 0; Retry < AHCI_COMMAND_RETRIES; Retry++) { + AhciBuildCommand ( + PciIo, + AhciRegisters, + Port, + PortMultiplier, + &CFis, + &CmdList, + AtapiCommand, + AtapiCommandLength, + 0, + (VOID *)(UINTN)PhyAddr, + DataCount + ); =20 - Status =3D AhciStartCommand ( - PciIo, - Port, - 0, - Timeout - ); - if (EFI_ERROR (Status)) { - goto Exit; - } + Status =3D AhciStartCommand ( + PciIo, + Port, + 0, + Timeout + ); + if (EFI_ERROR (Status)) { + break; + } =20 - if (Read && (AtapiCommand =3D=3D 0)) { - Status =3D AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisPioS= etup); - if (Status =3D=3D EFI_SUCCESS) { - PrdCount =3D *(volatile UINT32 *) (&(AhciRegisters->AhciCmdList[0].A= hciCmdPrdbc)); - if (PrdCount =3D=3D DataCount) { - Status =3D EFI_SUCCESS; - } else { - Status =3D EFI_DEVICE_ERROR; + if (Read && (AtapiCommand =3D=3D 0)) { + Status =3D AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisPi= oSetup); + if (Status =3D=3D EFI_SUCCESS) { + PrdCount =3D *(volatile UINT32 *) (&(AhciRegisters->AhciCmdList[0]= .AhciCmdPrdbc)); + if (PrdCount =3D=3D DataCount) { + Status =3D EFI_SUCCESS; + } else { + Status =3D EFI_DEVICE_ERROR; + } } + } else { + Status =3D AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2= H); } - } else { - Status =3D AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2H); - } =20 - if (Status =3D=3D EFI_DEVICE_ERROR) { - AhciRecoverPortError (PciIo, Port); + if (Status =3D=3D EFI_DEVICE_ERROR) { + DEBUG ((DEBUG_ERROR, "PIO command failed at retry %d\n", Retry)); + Status =3D AhciRecoverPortError (PciIo, Port); + if (EFI_ERROR (Status)) { + break; + } + } else { + break; + } } =20 -Exit: AhciStopCommand ( PciIo, Port, @@ -992,7 +1000,6 @@ Exit: ); =20 AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock); - return Status; } =20 @@ -1046,9 +1053,9 @@ AhciDmaTransfer ( EFI_PCI_IO_PROTOCOL_OPERATION Flag; EFI_AHCI_COMMAND_FIS CFis; EFI_AHCI_COMMAND_LIST CmdList; - EFI_PCI_IO_PROTOCOL *PciIo; EFI_TPL OldTpl; + UINT32 Retry; =20 Map =3D NULL; PciIo =3D Instance->PciIo; @@ -1058,36 +1065,16 @@ AhciDmaTransfer ( } =20 // - // Before starting the Blocking BlockIO operation, push to finish all no= n-blocking - // BlockIO tasks. - // Delay 100us to simulate the blocking time out checking. + // DMA buffer allocation. Needs to be done only once for both sync and a= sync + // DMA transfers irrespective of number of retries. // - OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); - while ((Task =3D=3D NULL) && (!IsListEmpty (&Instance->NonBlockingTaskLi= st))) { - AsyncNonBlockingTransferRoutine (NULL, Instance); - // - // Stall for 100us. - // - MicroSecondDelay (100); - } - gBS->RestoreTPL (OldTpl); - - if ((Task =3D=3D NULL) || ((Task !=3D NULL) && (!Task->IsStart))) { - // - // Mark the Task to indicate that it has been started. - // - if (Task !=3D NULL) { - Task->IsStart =3D TRUE; - } + if ((Task =3D=3D NULL) || ((Task !=3D NULL) && (Task->Map =3D=3D NULL)))= { if (Read) { Flag =3D EfiPciIoOperationBusMasterWrite; } else { Flag =3D EfiPciIoOperationBusMasterRead; } =20 - // - // Construct command list and command table with pci bus address. - // MapLength =3D DataCount; Status =3D PciIo->Map ( PciIo, @@ -1101,63 +1088,123 @@ AhciDmaTransfer ( if (EFI_ERROR (Status) || (DataCount !=3D MapLength)) { return EFI_BAD_BUFFER_SIZE; } - if (Task !=3D NULL) { Task->Map =3D Map; } - // - // Package read needed - // + } + + if (Task =3D=3D NULL || (Task !=3D NULL && !Task->IsStart)) { AhciBuildCommandFis (&CFis, AtaCommandBlock); =20 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST)); =20 CmdList.AhciCmdCfl =3D EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4; CmdList.AhciCmdW =3D Read ? 0 : 1; + } =20 - AhciBuildCommand ( - PciIo, - AhciRegisters, - Port, - PortMultiplier, - &CFis, - &CmdList, - AtapiCommand, - AtapiCommandLength, - 0, - (VOID *)(UINTN)PhyAddr, - DataCount - ); - - Status =3D AhciStartCommand ( - PciIo, - Port, - 0, - Timeout - ); - if (EFI_ERROR (Status)) { - goto Exit; + if (Task =3D=3D NULL) { + // + // Before starting the Blocking BlockIO operation, push to finish all = non-blocking + // BlockIO tasks. + // Delay 100us to simulate the blocking time out checking. + // + OldTpl =3D gBS->RaiseTPL (TPL_NOTIFY); + while (!IsListEmpty (&Instance->NonBlockingTaskList)) { + AsyncNonBlockingTransferRoutine (NULL, Instance); + // + // Stall for 100us. + // + MicroSecondDelay (100); } - } + gBS->RestoreTPL (OldTpl); + for (Retry =3D 0; Retry < AHCI_COMMAND_RETRIES; Retry++) { + AhciBuildCommand ( + PciIo, + AhciRegisters, + Port, + PortMultiplier, + &CFis, + &CmdList, + AtapiCommand, + AtapiCommandLength, + 0, + (VOID *)(UINTN)PhyAddr, + DataCount + ); =20 - if (Task !=3D NULL) { - Status =3D AhciCheckFisReceived (PciIo, Port, SataFisD2H); - if (Status =3D=3D EFI_NOT_READY) { - if (!Task->InfiniteWait && Task->RetryTimes =3D=3D 0) { - Status =3D EFI_TIMEOUT; + Status =3D AhciStartCommand ( + PciIo, + Port, + 0, + Timeout + ); + if (EFI_ERROR (Status)) { + break; + } + Status =3D AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2= H); + if (Status =3D=3D EFI_DEVICE_ERROR) { + DEBUG ((DEBUG_ERROR, "DMA command failed at retry: %d\n", Retry)); + Status =3D AhciRecoverPortError (PciIo, Port); + if (EFI_ERROR (Status)) { + break; + } } else { - Task->RetryTimes--; + break; } } } else { - Status =3D AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2H); - } + if (!Task->IsStart) { + AhciBuildCommand ( + PciIo, + AhciRegisters, + Port, + PortMultiplier, + &CFis, + &CmdList, + AtapiCommand, + AtapiCommandLength, + 0, + (VOID *)(UINTN)PhyAddr, + DataCount + ); =20 - if (Status =3D=3D EFI_DEVICE_ERROR) { - AhciRecoverPortError (PciIo, Port); + Status =3D AhciStartCommand ( + PciIo, + Port, + 0, + Timeout + ); + if (!EFI_ERROR (Status)) { + Task->IsStart =3D TRUE; + } + } + if (Task->IsStart) { + Status =3D AhciCheckFisReceived (PciIo, Port, SataFisD2H); + if (Status =3D=3D EFI_DEVICE_ERROR) { + DEBUG ((DEBUG_ERROR, "DMA command failed at retry: %d\n", Task->Re= tryTimes)); + Status =3D AhciRecoverPortError (PciIo, Port); + // + // If recovery passed mark the Task as not started and change the = status + // to EFI_NOT_READY. This will make the higher level call this fun= ction again + // and on next call the command will be re-issued due to IsStart b= eing FALSE. + // This also makes the next condition decrement the RetryTimes. + // + if (Status =3D=3D EFI_SUCCESS) { + Task->IsStart =3D FALSE; + Status =3D EFI_NOT_READY; + } + } + + if (Status =3D=3D EFI_NOT_READY) { + if (!Task->InfiniteWait && Task->RetryTimes =3D=3D 0) { + Status =3D EFI_TIMEOUT; + } else { + Task->RetryTimes--; + } + } + } } =20 -Exit: // // For Blocking mode, the command should be stopped, the Fis should be d= isabled // and the PciIo should be unmapped. @@ -1234,6 +1281,7 @@ AhciNonDataTransfer ( EFI_STATUS Status; EFI_AHCI_COMMAND_FIS CFis; EFI_AHCI_COMMAND_LIST CmdList; + UINT32 Retry; =20 // // Package read needed @@ -1244,36 +1292,43 @@ AhciNonDataTransfer ( =20 CmdList.AhciCmdCfl =3D EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4; =20 - AhciBuildCommand ( - PciIo, - AhciRegisters, - Port, - PortMultiplier, - &CFis, - &CmdList, - AtapiCommand, - AtapiCommandLength, - 0, - NULL, - 0 - ); + for (Retry =3D 0; Retry < AHCI_COMMAND_RETRIES; Retry++) { + AhciBuildCommand ( + PciIo, + AhciRegisters, + Port, + PortMultiplier, + &CFis, + &CmdList, + AtapiCommand, + AtapiCommandLength, + 0, + NULL, + 0 + ); =20 - Status =3D AhciStartCommand ( - PciIo, - Port, - 0, - Timeout - ); - if (EFI_ERROR (Status)) { - goto Exit; - } + Status =3D AhciStartCommand ( + PciIo, + Port, + 0, + Timeout + ); + if (EFI_ERROR (Status)) { + break; + } =20 - Status =3D AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2H); - if (Status =3D=3D EFI_DEVICE_ERROR) { - AhciRecoverPortError (PciIo, Port); + Status =3D AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2H); + if (Status =3D=3D EFI_DEVICE_ERROR) { + DEBUG ((DEBUG_ERROR, "Non data transfer failed at retry %d\n", Retry= )); + Status =3D AhciRecoverPortError (PciIo, Port); + if (EFI_ERROR (Status)) { + break; + } + } else { + break; + } } =20 -Exit: AhciStopCommand ( PciIo, Port, diff --git a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.h b/MdeModulePk= g/Bus/Ata/AtaAtapiPassThru/AhciMode.h index 4d2aafe483..0540b0f4fa 100644 --- a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.h +++ b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.h @@ -192,6 +192,8 @@ typedef union { #define AHCI_PORT_DEVSLP_DITO_MASK 0x01FF8000 #define AHCI_PORT_DEVSLP_DM_MASK 0x1E000000 =20 +#define AHCI_COMMAND_RETRIES 5 + #pragma pack(1) // // Command List structure includes total 32 entries. --=20 2.28.0.windows.1 --------------------------------------------------------------------- Intel Technology Poland sp. z o.o. ul. Sowackiego 173 | 80-298 Gdask | Sd Rejonowy Gdask Pnoc | VII Wydzia Gos= podarczy Krajowego Rejestru Sdowego - KRS 101882 | NIP 957-07-52-316 | Kapi= ta zakadowy 200.000 PLN. Ta wiadomo wraz z zacznikami jest przeznaczona dla okrelonego adresata i mo= e zawiera informacje poufne. W razie przypadkowego otrzymania tej wiadomoci= , prosimy o powiadomienie nadawcy oraz trwae jej usunicie; jakiekolwiek prz= egldanie lub rozpowszechnianie jest zabronione. This e-mail and any attachments may contain confidential material for the s= ole use of the intended recipient(s). If you are not the intended recipient= , please contact the sender and delete all copies; any review or distributi= on by others is strictly prohibited. =20 -=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 (#66925): https://edk2.groups.io/g/devel/message/66925 Mute This Topic: https://groups.io/mt/78005851/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-