summaryrefslogtreecommitdiff
path: root/drivers/ata
diff options
context:
space:
mode:
authorRichard Zhu <Richard.Zhu@freescale.com>2015-07-07 15:29:01 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:23:04 +0800
commit634a28baf81a54a6552e6f13d7dfc16128905ae4 (patch)
tree69e82d2134382645390e4ac67087050059c55651 /drivers/ata
parentfbcbb58910d247c92fd5d840b0b4688bafae4f94 (diff)
MLK-11444 ata: imx: cmd buf corruption errata bug fix
errata: When a read command returns less data than specified in the PRDs (for example, there are two PRDs for this command, but the device returns a number of bytes which is less than in the first PRD), the second PRD of this command is not read out of the PRD FIFO, causing the next command to use this PRD erroneously. workaround - forces sg_tablesize = 1 - modified the sg_io function in block/scsi_ioctl.c to use a 64k buffer allocated with dma_alloc_coherent during the probe in ahci_imx - In order to fix the scsi/sata hang, when CD_ROM and HDD are accessed simultaneously after the workaround is applied. Do not go to sleep in scsi_eh_handler, when there is host failed. Signed-off-by: Richard Zhu <Richard.Zhu@freescale.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/ahci_imx.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index 787567e840bd..8da450ba2eaa 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -72,6 +72,8 @@ struct imx_ahci_priv {
u32 phy_params;
};
+void *sg_io_buffer_hack;
+
static int ahci_imx_hotplug;
module_param_named(hotplug, ahci_imx_hotplug, int, 0644);
MODULE_PARM_DESC(hotplug, "AHCI IMX hot-plug support (0=Don't support, 1=support)");
@@ -818,6 +820,24 @@ static int imx_ahci_probe(struct platform_device *pdev)
reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
writel(reg_val, hpriv->mmio + IMX_TIMER1MS);
+ /*
+ * Due to IP bug on the Synopsis 3.00 SATA version,
+ * which is present on mx6q, and not on mx53,
+ * we should use sg_tablesize = 1 for reliable operation
+ */
+ if (imxpriv->type == AHCI_IMX6Q) {
+ dma_addr_t dma;
+
+ ahci_platform_sht.sg_tablesize = 1;
+
+ sg_io_buffer_hack = dma_alloc_coherent(NULL, 0x10000,
+ &dma, GFP_KERNEL);
+ if (!sg_io_buffer_hack) {
+ ret = -ENOMEM;
+ goto disable_sata;
+ }
+ }
+
ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info,
&ahci_platform_sht);
if (ret)