[coreboot-gerrit] New patch to review for coreboot: 59c7c7e libpayload: ahci: Fix command engine shutdown

Nico Huber (nico.huber@secunet.com) gerrit at coreboot.org
Mon Jun 17 17:57:35 CEST 2013


Nico Huber (nico.huber at secunet.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3494

-gerrit

commit 59c7c7e94105a40a333916c7152763ba1bfade74
Author: Nico Huber <nico.huber at secunet.com>
Date:   Mon Jun 17 17:47:24 2013 +0200

    libpayload: ahci: Fix command engine shutdown
    
    A timeout while waiting for a device' signature has shown that our
    error path wasn't correct. The shutdown of the ports command engine
    always timed out. Fix that by waiting for FR (FIS Receive Running)
    to be cleared independently from CR (Command List Running) and after
    clearing FRE (FIS Receive Enable).
    
    Change-Id: I50edf426ef0241424456f1489a7fc86a2cfc5753
    Signed-off-by: Nico Huber <nico.huber at secunet.com>
---
 payloads/libpayload/drivers/storage/ahci.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/payloads/libpayload/drivers/storage/ahci.c b/payloads/libpayload/drivers/storage/ahci.c
index deecd2b..fe83d46 100644
--- a/payloads/libpayload/drivers/storage/ahci.c
+++ b/payloads/libpayload/drivers/storage/ahci.c
@@ -73,7 +73,7 @@ static inline int ahci_port_is_active(const hba_port_t *const port)
 
 static int ahci_cmdengine_start(hba_port_t *const port)
 {
-	/* Wait for the controller to clear CR.
+	/* CR has to be clear before starting the command engine.
 	   This shouldn't take too long, but we should time out nevertheless. */
 	int timeout = 1000; /* Time out after 1000 * 1us == 1ms. */
 	while ((port->cmd_stat & HBA_PxCMD_CR) && timeout--)
@@ -92,10 +92,10 @@ static int ahci_cmdengine_stop(hba_port_t *const port)
 {
 	port->cmd_stat &= ~HBA_PxCMD_ST;
 
-	/* Wait for the controller to clear FR and CR.
+	/* Wait for the controller to clear CR.
 	   This shouldn't take too long, but we should time out nevertheless. */
 	int timeout = 1000; /* Time out after 1000 * 1us == 1ms. */
-	while ((port->cmd_stat & (HBA_PxCMD_FR | HBA_PxCMD_CR)) && timeout--)
+	while ((port->cmd_stat & HBA_PxCMD_CR) && timeout--)
 		udelay(1);
 	if (timeout < 0) {
 		printf("ahci: Timeout during stopping of command engine.\n");
@@ -103,6 +103,17 @@ static int ahci_cmdengine_stop(hba_port_t *const port)
 	}
 
 	port->cmd_stat &= ~HBA_PxCMD_FRE;
+
+	/* Wait for the controller to clear FR.
+	   This shouldn't take too long, but we should time out nevertheless. */
+	timeout = 1000; /* Time out after 1000 * 1us == 1ms. */
+	while ((port->cmd_stat & HBA_PxCMD_FR) && timeout--)
+		udelay(1);
+	if (timeout < 0) {
+		printf("ahci: Timeout during stopping of command engine.\n");
+		return 1;
+	}
+
 	return 0;
 }
 



More information about the coreboot-gerrit mailing list