diff options
Diffstat (limited to 'payloads/libpayload/drivers/storage/ahci.c')
-rw-r--r-- | payloads/libpayload/drivers/storage/ahci.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/payloads/libpayload/drivers/storage/ahci.c b/payloads/libpayload/drivers/storage/ahci.c index 72acd0b799..2b33b599f9 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; } |