| From 66583c9fa63d05d5580e409f9a58d3cad6d76d17 Mon Sep 17 00:00:00 2001 |
| From: Brian Norris <computersforpeace@gmail.com> |
| Date: Tue, 21 Feb 2012 10:38:42 -0800 |
| Subject: ahci: add AHCI_HFLAG_DELAY_ENGINE host flag |
| |
| From: Brian Norris <computersforpeace@gmail.com> |
| |
| commit 66583c9fa63d05d5580e409f9a58d3cad6d76d17 upstream. |
| |
| The following commit was intended to fix problems with specific AHCI |
| controller(s) that would become bricks if the AHCI specification was not |
| followed strictly (that is, if ahci_start_engine() was called while the |
| controller was in the wrong state): |
| |
| commit 7faa33da9b7add01db9f1ad92c6a5d9145e940a7 |
| ahci: start engine only during soft/hard resets |
| |
| However, some devices currently have issues with that fix, so we must |
| implement a flag that delays the ahci_start_engine() call only for specific |
| controllers. |
| |
| This commit simply introduces the flag, without enabling it in any driver. |
| |
| Note that even when AHCI_HFLAG_DELAY_ENGINE is not enabled, this patch does |
| not constitue a full revert to commit 7faa33da; there is still a change in |
| behavior to the ahci_port_suspend() failure path. |
| |
| Signed-off-by: Brian Norris <computersforpeace@gmail.com> |
| Signed-off-by: Jeff Garzik <jgarzik@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/ata/ahci.h | 3 +++ |
| drivers/ata/libahci.c | 5 +++++ |
| 2 files changed, 8 insertions(+) |
| |
| --- a/drivers/ata/ahci.h |
| +++ b/drivers/ata/ahci.h |
| @@ -210,6 +210,9 @@ enum { |
| AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */ |
| AHCI_HFLAG_NO_FPDMA_AA = (1 << 13), /* no FPDMA AA */ |
| AHCI_HFLAG_YES_FBS = (1 << 14), /* force FBS cap on */ |
| + AHCI_HFLAG_DELAY_ENGINE = (1 << 15), /* do not start engine on |
| + port start (wait until |
| + error-handling stage) */ |
| |
| /* ap->flags bits */ |
| |
| --- a/drivers/ata/libahci.c |
| +++ b/drivers/ata/libahci.c |
| @@ -737,6 +737,7 @@ static void ahci_power_down(struct ata_p |
| |
| static void ahci_start_port(struct ata_port *ap) |
| { |
| + struct ahci_host_priv *hpriv = ap->host->private_data; |
| struct ahci_port_priv *pp = ap->private_data; |
| struct ata_link *link; |
| struct ahci_em_priv *emp; |
| @@ -746,6 +747,10 @@ static void ahci_start_port(struct ata_p |
| /* enable FIS reception */ |
| ahci_start_fis_rx(ap); |
| |
| + /* enable DMA */ |
| + if (!(hpriv->flags & AHCI_HFLAG_DELAY_ENGINE)) |
| + ahci_start_engine(ap); |
| + |
| /* turn on LEDs */ |
| if (ap->flags & ATA_FLAG_EM) { |
| ata_for_each_link(link, ap, EDGE) { |