Message ID | 1403518538-30697-3-git-send-email-stripathi@apm.com |
---|---|
State | Not Applicable |
Delegated to: | David Miller |
Headers | show |
Hello, On Mon, Jun 23, 2014 at 03:45:37PM +0530, Suman Tripathi wrote: > @@ -234,15 +237,20 @@ static int xgene_ahci_do_hardreset(struct ata_link *link, > u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; > void __iomem *port_mmio = ahci_port_base(ap); > struct ata_taskfile tf; > + int link_down_retry = 0; > int rc; > u32 val; > > - /* clear D2H reception area to properly wait for D2H FIS */ > - ata_tf_init(link->device, &tf); > - tf.command = ATA_BUSY; > - ata_tf_to_fis(&tf, 0, 0, d2h_fis); > - rc = sata_link_hardreset(link, timing, deadline, online, > + do { > + /* clear D2H reception area to properly wait for D2H FIS */ > + ata_tf_init(link->device, &tf); > + tf.command = ATA_BUSY; > + ata_tf_to_fis(&tf, 0, 0, d2h_fis); > + rc = sata_link_hardreset(link, timing, deadline, online, > ahci_check_ready); > + if (*online) > + break; > + } while (link_down_retry++ < MAX_LINK_DOWN_RETRY); Hmm... so it's retrying w/o extending deadline if the link is reported to be offline. This definitely needs comment explaining what's going on. Wouldn't it make more sense to change @timing instead rather than retrying resets? sata_sil24 already does something similar. Does, f.e., using sata_deb_timing_long for @timing make the problem go away? Thanks.
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index 03b6b0f..cc26342 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c @@ -78,6 +78,9 @@ #define CFG_MEM_RAM_SHUTDOWN 0x00000070 #define BLOCK_MEM_RDY 0x00000074 +/* Max retry for link down */ +#define MAX_LINK_DOWN_RETRY 3 + struct xgene_ahci_context { struct ahci_host_priv *hpriv; struct device *dev; @@ -234,15 +237,20 @@ static int xgene_ahci_do_hardreset(struct ata_link *link, u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; void __iomem *port_mmio = ahci_port_base(ap); struct ata_taskfile tf; + int link_down_retry = 0; int rc; u32 val; - /* clear D2H reception area to properly wait for D2H FIS */ - ata_tf_init(link->device, &tf); - tf.command = ATA_BUSY; - ata_tf_to_fis(&tf, 0, 0, d2h_fis); - rc = sata_link_hardreset(link, timing, deadline, online, + do { + /* clear D2H reception area to properly wait for D2H FIS */ + ata_tf_init(link->device, &tf); + tf.command = ATA_BUSY; + ata_tf_to_fis(&tf, 0, 0, d2h_fis); + rc = sata_link_hardreset(link, timing, deadline, online, ahci_check_ready); + if (*online) + break; + } while (link_down_retry++ < MAX_LINK_DOWN_RETRY); val = readl(port_mmio + PORT_SCR_ERR); if (val & (SERR_DISPARITY | SERR_10B_8B_ERR))