diff options
author | Richard Zhu <Richard.Zhu@freescale.com> | 2015-07-07 15:29:01 +0800 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:20:42 +0300 |
commit | dd4da89a9dd7026d925f44780d00709a3e90fdbb (patch) | |
tree | 211d2c43faee5d811468d492f3fb751dc03132b5 /drivers/ata | |
parent | e06974f011133a8cb861f4f52f954ed6c08ce69e (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.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index 3f3a7db208ae..bf7caa669e5d 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c @@ -69,6 +69,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)"); @@ -622,6 +624,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) |