aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/sata_highbank.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c
index b20aa96b958d..c846fd3c5c09 100644
--- a/drivers/ata/sata_highbank.c
+++ b/drivers/ata/sata_highbank.c
@@ -196,10 +196,26 @@ static int highbank_initialize_phys(struct device *dev, void __iomem *addr)
196 return 0; 196 return 0;
197} 197}
198 198
199/*
200 * The Calxeda SATA phy intermittently fails to bring up a link with Gen3
201 * Retrying the phy hard reset can work around the issue, but the drive
202 * may fail again. In less than 150 out of 15000 test runs, it took more
203 * than 10 tries for the link to be established (but never more than 35).
204 * Triple the maximum observed retry count to provide plenty of margin for
205 * rare events and to guarantee that the link is established.
206 *
207 * Also, the default 2 second time-out on a failed drive is too long in
208 * this situation. The uboot implementation of the same driver function
209 * uses a much shorter time-out period and never experiences a time out
210 * issue. Reducing the time-out to 500ms improves the responsiveness.
211 * The other timing constants were kept the same as the stock AHCI driver.
212 * This change was also tested 15000 times on 24 drives and none of them
213 * experienced a time out.
214 */
199static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class, 215static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class,
200 unsigned long deadline) 216 unsigned long deadline)
201{ 217{
202 const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); 218 static const unsigned long timing[] = { 5, 100, 500};
203 struct ata_port *ap = link->ap; 219 struct ata_port *ap = link->ap;
204 struct ahci_port_priv *pp = ap->private_data; 220 struct ahci_port_priv *pp = ap->private_data;
205 u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; 221 u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
@@ -207,7 +223,7 @@ static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class,
207 bool online; 223 bool online;
208 u32 sstatus; 224 u32 sstatus;
209 int rc; 225 int rc;
210 int retry = 10; 226 int retry = 100;
211 227
212 ahci_stop_engine(ap); 228 ahci_stop_engine(ap);
213 229