Commit 66583c9f authored by Brian Norris's avatar Brian Norris Committed by Jeff Garzik

ahci: add AHCI_HFLAG_DELAY_ENGINE host flag

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 7faa33da
    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: default avatarBrian Norris <computersforpeace@gmail.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
Cc: stable@kernel.org
parent 6b4b8fc8
...@@ -210,6 +210,9 @@ enum { ...@@ -210,6 +210,9 @@ enum {
AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */ AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */
AHCI_HFLAG_NO_FPDMA_AA = (1 << 13), /* no FPDMA AA */ AHCI_HFLAG_NO_FPDMA_AA = (1 << 13), /* no FPDMA AA */
AHCI_HFLAG_YES_FBS = (1 << 14), /* force FBS cap on */ 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 */ /* ap->flags bits */
......
...@@ -737,6 +737,7 @@ static void ahci_power_down(struct ata_port *ap) ...@@ -737,6 +737,7 @@ static void ahci_power_down(struct ata_port *ap)
static void ahci_start_port(struct ata_port *ap) 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 ahci_port_priv *pp = ap->private_data;
struct ata_link *link; struct ata_link *link;
struct ahci_em_priv *emp; struct ahci_em_priv *emp;
...@@ -746,6 +747,10 @@ static void ahci_start_port(struct ata_port *ap) ...@@ -746,6 +747,10 @@ static void ahci_start_port(struct ata_port *ap)
/* enable FIS reception */ /* enable FIS reception */
ahci_start_fis_rx(ap); ahci_start_fis_rx(ap);
/* enable DMA */
if (!(hpriv->flags & AHCI_HFLAG_DELAY_ENGINE))
ahci_start_engine(ap);
/* turn on LEDs */ /* turn on LEDs */
if (ap->flags & ATA_FLAG_EM) { if (ap->flags & ATA_FLAG_EM) {
ata_for_each_link(link, ap, EDGE) { ata_for_each_link(link, ap, EDGE) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment