From 62989cebd367a1aae1e009e1a5b1ec046a4c8fdc Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 3 Jan 2017 19:09:44 +0100 Subject: ata: SATA_MV should depend on HAS_DMA If NO_DMA=y: ERROR: "dma_pool_alloc" [drivers/ata/sata_mv.ko] undefined! ERROR: "dmam_pool_create" [drivers/ata/sata_mv.ko] undefined! ERROR: "dma_pool_free" [drivers/ata/sata_mv.ko] undefined! Add a dependency on HAS_DMA to fix this. Signed-off-by: Geert Uytterhoeven Signed-off-by: Tejun Heo --- drivers/ata/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/ata') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 2c8be74f401d..842cd3450b57 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -353,6 +353,7 @@ config SATA_HIGHBANK config SATA_MV tristate "Marvell SATA support" + depends on HAS_DMA depends on PCI || ARCH_DOVE || ARCH_MV78XX0 || \ ARCH_MVEBU || ARCH_ORION5X || COMPILE_TEST select GENERIC_PHY -- cgit v1.2.3-59-g8ed1b From 2a736e0585e585c2566b5119af8381910a170e44 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 3 Jan 2017 19:09:45 +0100 Subject: ata: SATA_HIGHBANK should depend on HAS_DMA If NO_DMA=y: ERROR: "bad_dma_ops" [drivers/ata/sata_highbank.ko] undefined! Add a dependency on HAS_DMA to fix this. Signed-off-by: Geert Uytterhoeven Signed-off-by: Tejun Heo --- drivers/ata/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/ata') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 842cd3450b57..47d9356991e9 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -344,6 +344,7 @@ config SATA_DWC_VDEBUG config SATA_HIGHBANK tristate "Calxeda Highbank SATA support" + depends on HAS_DMA depends on ARCH_HIGHBANK || COMPILE_TEST help This option enables support for the Calxeda Highbank SoC's -- cgit v1.2.3-59-g8ed1b From 7bc7ab1e63dfe004931502f90ce7020e375623da Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 3 Jan 2017 19:09:46 +0100 Subject: ata: ATA_BMDMA should depend on HAS_DMA If NO_DMA=y: ERROR: "dmam_alloc_coherent" [drivers/ata/libata.ko] undefined! Add a dependency on HAS_DMA to fix this. Signed-off-by: Geert Uytterhoeven Signed-off-by: Tejun Heo --- drivers/ata/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/ata') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 47d9356991e9..5d16fc4fa46c 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -289,6 +289,7 @@ config SATA_SX4 config ATA_BMDMA bool "ATA BMDMA support" + depends on HAS_DMA default y help This option adds support for SFF ATA controllers with BMDMA -- cgit v1.2.3-59-g8ed1b From b16a0168c41f9379476b5b5585071319078c542d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 3 Jan 2017 19:09:47 +0100 Subject: ata: AHCI and other non-SFF native drivers should depend on HAS_DMA If NO_DMA=y: ERROR: "bad_dma_ops" [drivers/ata/libahci_platform.ko] undefined! ERROR: "dmam_alloc_coherent" [drivers/ata/libahci.ko] undefined! Add a block dependency on HAS_DMA to fix this. Signed-off-by: Geert Uytterhoeven Signed-off-by: Tejun Heo --- drivers/ata/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/ata') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 5d16fc4fa46c..38318aaf29d3 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -80,6 +80,8 @@ config SATA_PMP This option adds support for SATA Port Multipliers (the SATA version of an ethernet hub, or SAS expander). +if HAS_DMA + comment "Controllers with non-SFF native interface" config SATA_AHCI @@ -232,6 +234,8 @@ config SATA_SIL24 If unsure, say N. +endif # HAS_DMA + config ATA_SFF bool "ATA SFF support (for legacy IDE and PATA)" default y -- cgit v1.2.3-59-g8ed1b From 6cf32ed9eee2d34db441ba6ebad3ec2d67952688 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 3 Jan 2017 19:09:48 +0100 Subject: libata: Make ata_sg_clean() static again Commit 70e6ad0c6d1e6cb9 ("[PATCH] libata: prepare ata_sg_clean() for invocation from EH") made ata_sg_clean() global, but no user outside libata-core.c has ever materialized. Signed-off-by: Geert Uytterhoeven Signed-off-by: Tejun Heo --- drivers/ata/libata-core.c | 2 +- drivers/ata/libata.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 9cd0a2d41816..a7e3df5abaa3 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4822,7 +4822,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev, * LOCKING: * spin_lock_irqsave(host lock) */ -void ata_sg_clean(struct ata_queued_cmd *qc) +static void ata_sg_clean(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct scatterlist *sg = qc->sg; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 8f3a5596dd67..1133e9439f9c 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -89,7 +89,6 @@ extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); extern unsigned int ata_dev_set_feature(struct ata_device *dev, u8 enable, u8 feature); -extern void ata_sg_clean(struct ata_queued_cmd *qc); extern void ata_qc_free(struct ata_queued_cmd *qc); extern void ata_qc_issue(struct ata_queued_cmd *qc); extern void __ata_qc_complete(struct ata_queued_cmd *qc); -- cgit v1.2.3-59-g8ed1b From 2874d5ee6c06ab72f2729968926b3d5ef8fca897 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 3 Jan 2017 19:09:49 +0100 Subject: libata: Protect DMA core code by #ifdef CONFIG_HAS_DMA If NO_DMA=y: ERROR: "bad_dma_ops" [drivers/ata/libata.ko] undefined! To fix this, protect the DMA code by #ifdef CONFIG_HAS_DMA, and provide dummies of ata_sg_clean() and ata_sg_setup() for the !CONFIG_HAS_DMA case. Signed-off-by: Geert Uytterhoeven Signed-off-by: Tejun Heo --- drivers/ata/libata-core.c | 61 +++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 26 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index a7e3df5abaa3..dc70b5f997f1 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4813,32 +4813,6 @@ static unsigned int ata_dev_init_params(struct ata_device *dev, return err_mask; } -/** - * ata_sg_clean - Unmap DMA memory associated with command - * @qc: Command containing DMA memory to be released - * - * Unmap all mapped DMA memory associated with this command. - * - * LOCKING: - * spin_lock_irqsave(host lock) - */ -static void ata_sg_clean(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct scatterlist *sg = qc->sg; - int dir = qc->dma_dir; - - WARN_ON_ONCE(sg == NULL); - - VPRINTK("unmapping %u sg elements\n", qc->n_elem); - - if (qc->n_elem) - dma_unmap_sg(ap->dev, sg, qc->orig_n_elem, dir); - - qc->flags &= ~ATA_QCFLAG_DMAMAP; - qc->sg = NULL; -} - /** * atapi_check_dma - Check whether ATAPI DMA can be supported * @qc: Metadata associated with taskfile to check @@ -4923,6 +4897,34 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, qc->cursg = qc->sg; } +#ifdef CONFIG_HAS_DMA + +/** + * ata_sg_clean - Unmap DMA memory associated with command + * @qc: Command containing DMA memory to be released + * + * Unmap all mapped DMA memory associated with this command. + * + * LOCKING: + * spin_lock_irqsave(host lock) + */ +void ata_sg_clean(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct scatterlist *sg = qc->sg; + int dir = qc->dma_dir; + + WARN_ON_ONCE(sg == NULL); + + VPRINTK("unmapping %u sg elements\n", qc->n_elem); + + if (qc->n_elem) + dma_unmap_sg(ap->dev, sg, qc->orig_n_elem, dir); + + qc->flags &= ~ATA_QCFLAG_DMAMAP; + qc->sg = NULL; +} + /** * ata_sg_setup - DMA-map the scatter-gather table associated with a command. * @qc: Command with scatter-gather table to be mapped. @@ -4955,6 +4957,13 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) return 0; } +#else /* !CONFIG_HAS_DMA */ + +static inline void ata_sg_clean(struct ata_queued_cmd *qc) {} +static inline int ata_sg_setup(struct ata_queued_cmd *qc) { return -1; } + +#endif /* !CONFIG_HAS_DMA */ + /** * swap_buf_le16 - swap halves of 16-bit words in place * @buf: Buffer to swap -- cgit v1.2.3-59-g8ed1b From de2518201e526f4491e5856b9818f5c18684a6a7 Mon Sep 17 00:00:00 2001 From: Michał Kępień Date: Thu, 5 Jan 2017 15:14:01 +0100 Subject: ata: ahci_xgene: free structure returned by acpi_get_object_info() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit acpi_get_object_info() allocates the returned structure, which the caller has to free when the call succeeds. Free it when appropriate. Fixes: c9802a4be661 ("ata: ahci_xgene: Add AHCI Support for 2nd HW version of APM X-Gene SoC AHCI SATA Host controller.") Signed-off-by: Michał Kępień Signed-off-by: Tejun Heo --- drivers/ata/ahci_xgene.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index 73b19b277138..c2b5941d9184 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c @@ -821,8 +821,10 @@ static int xgene_ahci_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "%s: Error reading device info. Assume version1\n", __func__); version = XGENE_AHCI_V1; - } else if (info->valid & ACPI_VALID_CID) { - version = XGENE_AHCI_V2; + } else { + if (info->valid & ACPI_VALID_CID) + version = XGENE_AHCI_V2; + kfree(info); } } } -- cgit v1.2.3-59-g8ed1b From 54643a83b41a2bff90a0615799686b37a1109404 Mon Sep 17 00:00:00 2001 From: Csaba Kertesz Date: Tue, 25 Oct 2016 22:08:07 +0200 Subject: ahci: imx: Add imx53 SATA temperature sensor support Add a hwmon entry to get the temperature from the die of imx53 SATA. The original patch was made by Richard Zhu for kernel 2.6.x: ENGR00134041-MX53-Add-the-SATA-AHCI-temperature-monitor.patch Signed-off-by: Fabien Lahoudere Signed-off-by: Tejun Heo --- drivers/ata/ahci_imx.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index 3f3a7db208ae..420f065978dc 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #include "ahci.h" #define DRV_NAME "ahci-imx" @@ -214,6 +217,180 @@ static int imx_sata_phy_reset(struct ahci_host_priv *hpriv) return timeout ? 0 : -ETIMEDOUT; } +enum { + /* SATA PHY Register */ + SATA_PHY_CR_CLOCK_CRCMP_LT_LIMIT = 0x0001, + SATA_PHY_CR_CLOCK_DAC_CTL = 0x0008, + SATA_PHY_CR_CLOCK_RTUNE_CTL = 0x0009, + SATA_PHY_CR_CLOCK_ADC_OUT = 0x000A, + SATA_PHY_CR_CLOCK_MPLL_TST = 0x0017, +}; + +static int read_adc_sum(void *dev, u16 rtune_ctl_reg, void __iomem * mmio) +{ + u16 adc_out_reg, read_sum; + u32 index, read_attempt; + const u32 attempt_limit = 100; + + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_RTUNE_CTL, mmio); + imx_phy_reg_write(rtune_ctl_reg, mmio); + + /* two dummy read */ + index = 0; + read_attempt = 0; + adc_out_reg = 0; + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_ADC_OUT, mmio); + while (index < 2) { + imx_phy_reg_read(&adc_out_reg, mmio); + /* check if valid */ + if (adc_out_reg & 0x400) + index++; + + read_attempt++; + if (read_attempt > attempt_limit) { + dev_err(dev, "Read REG more than %d times!\n", + attempt_limit); + break; + } + } + + index = 0; + read_attempt = 0; + read_sum = 0; + while (index < 80) { + imx_phy_reg_read(&adc_out_reg, mmio); + if (adc_out_reg & 0x400) { + read_sum = read_sum + (adc_out_reg & 0x3FF); + index++; + } + read_attempt++; + if (read_attempt > attempt_limit) { + dev_err(dev, "Read REG more than %d times!\n", + attempt_limit); + break; + } + } + + /* Use the U32 to make 1000 precision */ + return (read_sum * 1000) / 80; +} + +/* SATA AHCI temperature monitor */ +static int sata_ahci_read_temperature(void *dev, int *temp) +{ + u16 mpll_test_reg, rtune_ctl_reg, dac_ctl_reg, read_sum; + u32 str1, str2, str3, str4; + int m1, m2, a; + struct ahci_host_priv *hpriv = dev_get_drvdata(dev); + void __iomem *mmio = hpriv->mmio; + + /* check rd-wr to reg */ + read_sum = 0; + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_CRCMP_LT_LIMIT, mmio); + imx_phy_reg_write(read_sum, mmio); + imx_phy_reg_read(&read_sum, mmio); + if ((read_sum & 0xffff) != 0) + dev_err(dev, "Read/Write REG error, 0x%x!\n", read_sum); + + imx_phy_reg_write(0x5A5A, mmio); + imx_phy_reg_read(&read_sum, mmio); + if ((read_sum & 0xffff) != 0x5A5A) + dev_err(dev, "Read/Write REG error, 0x%x!\n", read_sum); + + imx_phy_reg_write(0x1234, mmio); + imx_phy_reg_read(&read_sum, mmio); + if ((read_sum & 0xffff) != 0x1234) + dev_err(dev, "Read/Write REG error, 0x%x!\n", read_sum); + + /* start temperature test */ + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_MPLL_TST, mmio); + imx_phy_reg_read(&mpll_test_reg, mmio); + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_RTUNE_CTL, mmio); + imx_phy_reg_read(&rtune_ctl_reg, mmio); + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_DAC_CTL, mmio); + imx_phy_reg_read(&dac_ctl_reg, mmio); + + /* mpll_tst.meas_iv ([12:2]) */ + str1 = (mpll_test_reg >> 2) & 0x7FF; + /* rtune_ctl.mode ([1:0]) */ + str2 = (rtune_ctl_reg) & 0x3; + /* dac_ctl.dac_mode ([14:12]) */ + str3 = (dac_ctl_reg >> 12) & 0x7; + /* rtune_ctl.sel_atbp ([4]) */ + str4 = (rtune_ctl_reg >> 4); + + /* Calculate the m1 */ + /* mpll_tst.meas_iv */ + mpll_test_reg = (mpll_test_reg & 0xE03) | (512) << 2; + /* rtune_ctl.mode */ + rtune_ctl_reg = (rtune_ctl_reg & 0xFFC) | (1); + /* dac_ctl.dac_mode */ + dac_ctl_reg = (dac_ctl_reg & 0x8FF) | (4) << 12; + /* rtune_ctl.sel_atbp */ + rtune_ctl_reg = (rtune_ctl_reg & 0xFEF) | (0) << 4; + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_MPLL_TST, mmio); + imx_phy_reg_write(mpll_test_reg, mmio); + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_DAC_CTL, mmio); + imx_phy_reg_write(dac_ctl_reg, mmio); + m1 = read_adc_sum(dev, rtune_ctl_reg, mmio); + + /* Calculate the m2 */ + /* rtune_ctl.sel_atbp */ + rtune_ctl_reg = (rtune_ctl_reg & 0xFEF) | (1) << 4; + m2 = read_adc_sum(dev, rtune_ctl_reg, mmio); + + /* restore the status */ + /* mpll_tst.meas_iv */ + mpll_test_reg = (mpll_test_reg & 0xE03) | (str1) << 2; + /* rtune_ctl.mode */ + rtune_ctl_reg = (rtune_ctl_reg & 0xFFC) | (str2); + /* dac_ctl.dac_mode */ + dac_ctl_reg = (dac_ctl_reg & 0x8FF) | (str3) << 12; + /* rtune_ctl.sel_atbp */ + rtune_ctl_reg = (rtune_ctl_reg & 0xFEF) | (str4) << 4; + + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_MPLL_TST, mmio); + imx_phy_reg_write(mpll_test_reg, mmio); + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_DAC_CTL, mmio); + imx_phy_reg_write(dac_ctl_reg, mmio); + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_RTUNE_CTL, mmio); + imx_phy_reg_write(rtune_ctl_reg, mmio); + + /* Compute temperature */ + if (!(m2 / 1000)) + m2 = 1000; + a = (m2 - m1) / (m2/1000); + *temp = ((-559) * a * a) / 1000 + (1379) * a + (-458000); + + return 0; +} + +static ssize_t sata_ahci_show_temp(struct device *dev, + struct device_attribute *da, + char *buf) +{ + unsigned int temp = 0; + int err; + + err = sata_ahci_read_temperature(dev, &temp); + if (err < 0) + return err; + + return sprintf(buf, "%u\n", temp); +} + +static const struct thermal_zone_of_device_ops fsl_sata_ahci_of_thermal_ops = { + .get_temp = sata_ahci_read_temperature, +}; + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, sata_ahci_show_temp, NULL, 0); + +static struct attribute *fsl_sata_ahci_attrs[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + NULL +}; +ATTRIBUTE_GROUPS(fsl_sata_ahci); + static int imx_sata_enable(struct ahci_host_priv *hpriv) { struct imx_ahci_priv *imxpriv = hpriv->plat_data; @@ -597,6 +774,24 @@ static int imx_ahci_probe(struct platform_device *pdev) if (ret) return ret; + if (imxpriv->type == AHCI_IMX53) { + /* Add the temperature monitor */ + struct device *hwmon_dev; + + hwmon_dev = + devm_hwmon_device_register_with_groups(dev, + "sata_ahci", + hpriv, + fsl_sata_ahci_groups); + if (IS_ERR(hwmon_dev)) { + ret = PTR_ERR(hwmon_dev); + goto disable_clk; + } + devm_thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev, + &fsl_sata_ahci_of_thermal_ops); + dev_info(dev, "%s: sensor 'sata_ahci'\n", dev_name(hwmon_dev)); + } + ret = imx_sata_enable(hpriv); if (ret) goto disable_clk; -- cgit v1.2.3-59-g8ed1b From 88af4bbd8f6983378c3098ca3e26c4e48434fe69 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 20 Dec 2016 22:15:22 +0100 Subject: ata: sata_mv: fix module license specification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The header allows GPL v2 only, so declare "GPL v2" for MODULE_LICENSE Signed-off-by: Uwe Kleine-König Signed-off-by: Tejun Heo --- drivers/ata/sata_mv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 823e938c9a78..bcbfe23a45f6 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -4526,7 +4526,7 @@ static void __exit mv_exit(void) MODULE_AUTHOR("Brett Russ"); MODULE_DESCRIPTION("SCSI low-level driver for Marvell SATA controllers"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(pci, mv_pci_tbl); MODULE_VERSION(DRV_VERSION); MODULE_ALIAS("platform:" DRV_NAME); -- cgit v1.2.3-59-g8ed1b From 368e5fbdfc60732643f34f538823ed4bc8829827 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 9 Jan 2017 00:49:22 +0200 Subject: ata: sata_mv: Convert to devm_ioremap_resource() Convert to devm_ioremap_resource() which provides more consistent error handling. Note that devm_ioremap_resource() provides its own error messages. Signed-off-by: Andy Shevchenko Signed-off-by: Tejun Heo --- drivers/ata/sata_mv.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 6eed4a72d328..00ce26d0c047 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -4067,6 +4067,7 @@ static int mv_platform_probe(struct platform_device *pdev) struct ata_host *host; struct mv_host_priv *hpriv; struct resource *res; + void __iomem *mmio; int n_ports = 0, irq = 0; int rc; int port; @@ -4085,8 +4086,9 @@ static int mv_platform_probe(struct platform_device *pdev) * Get the register base first */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) - return -EINVAL; + mmio = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(mmio)) + return PTR_ERR(mmio); /* allocate host */ if (pdev->dev.of_node) { @@ -4130,12 +4132,7 @@ static int mv_platform_probe(struct platform_device *pdev) hpriv->board_idx = chip_soc; host->iomap = NULL; - hpriv->base = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); - if (!hpriv->base) - return -ENOMEM; - - hpriv->base -= SATAHC0_REG_BASE; + hpriv->base = mmio - SATAHC0_REG_BASE; hpriv->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(hpriv->clk)) -- cgit v1.2.3-59-g8ed1b From fb1b8b117531f217e7d332bdc5cbdf8ebb077ea5 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 9 Jan 2017 15:49:28 +0100 Subject: libata-eh: Use switch() instead of sparse array for protocol strings Replace the sparse 256-pointer array for looking up protocol strings by a switch() statement to reduce kernel size. According to bloat-o-meter, this saves 910 bytes on m68k (32-bit), and 1892 bytes on arm64 (64-bit). Signed-off-by: Geert Uytterhoeven Signed-off-by: Tejun Heo --- drivers/ata/libata-eh.c | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 0e1ec37070d1..e7196fc29ff0 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2606,21 +2606,39 @@ static void ata_eh_link_report(struct ata_link *link) [DMA_TO_DEVICE] = "out", [DMA_FROM_DEVICE] = "in", }; - static const char *prot_str[] = { - [ATA_PROT_UNKNOWN] = "unknown", - [ATA_PROT_NODATA] = "nodata", - [ATA_PROT_PIO] = "pio", - [ATA_PROT_DMA] = "dma", - [ATA_PROT_NCQ] = "ncq dma", - [ATA_PROT_NCQ_NODATA] = "ncq nodata", - [ATAPI_PROT_NODATA] = "nodata", - [ATAPI_PROT_PIO] = "pio", - [ATAPI_PROT_DMA] = "dma", - }; + const char *prot_str = NULL; + switch (qc->tf.protocol) { + case ATA_PROT_UNKNOWN: + prot_str = "unknown"; + break; + case ATA_PROT_NODATA: + prot_str = "nodata"; + break; + case ATA_PROT_PIO: + prot_str = "pio"; + break; + case ATA_PROT_DMA: + prot_str = "dma"; + break; + case ATA_PROT_NCQ: + prot_str = "ncq dma"; + break; + case ATA_PROT_NCQ_NODATA: + prot_str = "ncq nodata"; + break; + case ATAPI_PROT_NODATA: + prot_str = "nodata"; + break; + case ATAPI_PROT_PIO: + prot_str = "pio"; + break; + case ATAPI_PROT_DMA: + prot_str = "dma"; + break; + } snprintf(data_buf, sizeof(data_buf), " %s %u %s", - prot_str[qc->tf.protocol], qc->nbytes, - dma_str[qc->dma_dir]); + prot_str, qc->nbytes, dma_str[qc->dma_dir]); } if (ata_is_atapi(qc->tf.protocol)) { -- cgit v1.2.3-59-g8ed1b From aa18da8b7ec57f6ff255634746aed6266a01b315 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 10 Jan 2017 09:41:43 +0100 Subject: libata: avoid global response buffer in atapi_qc_complete We only need to look at 4 bytes of the inquiry response for ATAPI devices. Instead of using the global ata_scsi_rbuf just use a a stack buffer. Also factor the fixup into it's own little helper function to make it more readable. Signed-off-by: Christoph Hellwig Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 1f863e757ee4..031a77aae19d 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2873,6 +2873,26 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) DPRINTK("EXIT\n"); } +/* + * ATAPI devices typically report zero for their SCSI version, and sometimes + * deviate from the spec WRT response data format. If SCSI version is + * reported as zero like normal, then we make the following fixups: + * 1) Fake MMC-5 version, to indicate to the Linux scsi midlayer this is a + * modern device. + * 2) Ensure response data format / ATAPI information are always correct. + */ +static void atapi_fixup_inquiry(struct scsi_cmnd *cmd) +{ + u8 buf[4]; + + sg_copy_to_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, 4); + if (buf[2] == 0) { + buf[2] = 0x5; + buf[3] = 0x32; + } + sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, 4); +} + static void atapi_qc_complete(struct ata_queued_cmd *qc) { struct scsi_cmnd *cmd = qc->scsicmd; @@ -2927,30 +2947,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) */ ata_gen_passthru_sense(qc); } else { - u8 *scsicmd = cmd->cmnd; - - if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) { - unsigned long flags; - u8 *buf; - - buf = ata_scsi_rbuf_get(cmd, true, &flags); - - /* ATAPI devices typically report zero for their SCSI version, - * and sometimes deviate from the spec WRT response data - * format. If SCSI version is reported as zero like normal, - * then we make the following fixups: 1) Fake MMC-5 version, - * to indicate to the Linux scsi midlayer this is a modern - * device. 2) Ensure response data format / ATAPI information - * are always correct. - */ - if (buf[2] == 0) { - buf[2] = 0x5; - buf[3] = 0x32; - } - - ata_scsi_rbuf_put(cmd, true, &flags); - } - + if (cmd->cmnd[0] == INQUIRY && (cmd->cmnd[1] & 0x03) == 0) + atapi_fixup_inquiry(cmd); cmd->result = SAM_STAT_GOOD; } -- cgit v1.2.3-59-g8ed1b From f0a37d12f51a51d61f68dd30123f2b1927b56bb6 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 10 Jan 2017 09:41:44 +0100 Subject: libata: move struct ata_scsi_args to libata-scsi.c It's only used in libata-scsi.c, so move it closer to the users. Signed-off-by: Christoph Hellwig Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 7 +++++++ drivers/ata/libata.h | 7 ------- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 031a77aae19d..43694f5f2c89 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2057,6 +2057,13 @@ defer: return SCSI_MLQUEUE_HOST_BUSY; } +struct ata_scsi_args { + struct ata_device *dev; + u16 *id; + struct scsi_cmnd *cmd; + void (*done)(struct scsi_cmnd *); +}; + /** * ata_scsi_rbuf_get - Map response buffer. * @cmd: SCSI command containing buffer to be mapped. diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 1133e9439f9c..bba39a62552b 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -31,13 +31,6 @@ #define DRV_NAME "libata" #define DRV_VERSION "3.00" /* must be exactly four chars */ -struct ata_scsi_args { - struct ata_device *dev; - u16 *id; - struct scsi_cmnd *cmd; - void (*done)(struct scsi_cmnd *); -}; - /* libata-core.c */ enum { /* flags for ata_dev_read_id() */ -- cgit v1.2.3-59-g8ed1b From 506db3609cdf30b0ff661e8e38e95e91c54fbb82 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 10 Jan 2017 09:41:45 +0100 Subject: libata: remove the done callback from ata_scsi_args It's always the scsi_done callback, and we can get at that easily in the place where ->done is called. Signed-off-by: Christoph Hellwig Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 43694f5f2c89..28e2530b9cd3 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2061,7 +2061,6 @@ struct ata_scsi_args { struct ata_device *dev; u16 *id; struct scsi_cmnd *cmd; - void (*done)(struct scsi_cmnd *); }; /** @@ -2140,7 +2139,7 @@ static void ata_scsi_rbuf_fill(struct ata_scsi_args *args, if (rc == 0) cmd->result = SAM_STAT_GOOD; - args->done(cmd); + cmd->scsi_done(cmd); } /** @@ -4357,7 +4356,6 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) args.dev = dev; args.id = dev->id; args.cmd = cmd; - args.done = cmd->scsi_done; switch(scsicmd[0]) { case INQUIRY: -- cgit v1.2.3-59-g8ed1b From 8fc6c0657bf852766f08d389c5c3378a032b3de7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 10 Jan 2017 09:41:46 +0100 Subject: libata: call ->scsi_done from ata_scsi_simulate We always need to call ->scsi_done after we've finished emulating a command, so do it in a single place at the end of ata_scsi_simulate. Signed-off-by: Christoph Hellwig Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 28e2530b9cd3..6078bc28b325 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -484,13 +484,6 @@ struct device_attribute *ata_common_sdev_attrs[] = { }; EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); -static void ata_scsi_invalid_field(struct ata_device *dev, - struct scsi_cmnd *cmd, u16 field) -{ - ata_scsi_set_invalid_field(dev, cmd, field, 0xff); - cmd->scsi_done(cmd); -} - /** * ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd. * @sdev: SCSI device for which BIOS geometry is to be determined @@ -2139,7 +2132,6 @@ static void ata_scsi_rbuf_fill(struct ata_scsi_args *args, if (rc == 0) cmd->result = SAM_STAT_GOOD; - cmd->scsi_done(cmd); } /** @@ -4360,7 +4352,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) switch(scsicmd[0]) { case INQUIRY: if (scsicmd[1] & 2) /* is CmdDt set? */ - ata_scsi_invalid_field(dev, cmd, 1); + ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */ ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std); else switch (scsicmd[2]) { @@ -4392,7 +4384,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) } /* Fallthrough */ default: - ata_scsi_invalid_field(dev, cmd, 2); + ata_scsi_set_invalid_field(dev, cmd, 2, 0xff); break; } break; @@ -4410,7 +4402,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16) ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); else - ata_scsi_invalid_field(dev, cmd, 1); + ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); break; case REPORT_LUNS: @@ -4420,7 +4412,6 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) case REQUEST_SENSE: ata_scsi_set_sense(dev, cmd, 0, 0, 0); cmd->result = (DRIVER_SENSE << 24); - cmd->scsi_done(cmd); break; /* if we reach this, then writeback caching is disabled, @@ -4442,23 +4433,24 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4])) ata_scsi_rbuf_fill(&args, ata_scsiop_noop); else - ata_scsi_invalid_field(dev, cmd, 1); + ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); break; case MAINTENANCE_IN: if (scsicmd[1] == MI_REPORT_SUPPORTED_OPERATION_CODES) ata_scsi_rbuf_fill(&args, ata_scsiop_maint_in); else - ata_scsi_invalid_field(dev, cmd, 1); + ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); break; /* all other commands */ default: ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x20, 0x0); /* "Invalid command operation code" */ - cmd->scsi_done(cmd); break; } + + cmd->scsi_done(cmd); } int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) -- cgit v1.2.3-59-g8ed1b From a0c0b0e945cad4d6b2871469883fbbc316afcd44 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 10 Jan 2017 09:41:47 +0100 Subject: libata: don't call ata_scsi_rbuf_fill for command without a response buffer No need to copy a zeroed buffer to the caller if the command is defined to not have a response in the SCSI spec. Signed-off-by: Christoph Hellwig Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 6078bc28b325..395c8591980f 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2452,23 +2452,6 @@ static unsigned int ata_scsiop_inq_b6(struct ata_scsi_args *args, u8 *rbuf) return 0; } -/** - * ata_scsiop_noop - Command handler that simply returns success. - * @args: device IDENTIFY data / SCSI command of interest. - * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. - * - * No operation. Simply returns success to caller, to indicate - * that the caller should successfully complete this SCSI command. - * - * LOCKING: - * spin_lock_irqsave(host lock) - */ -static unsigned int ata_scsiop_noop(struct ata_scsi_args *args, u8 *rbuf) -{ - VPRINTK("ENTER\n"); - return 0; -} - /** * modecpy - Prepare response for MODE SENSE * @dest: output buffer @@ -4425,14 +4408,11 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) case SEEK_6: case SEEK_10: case TEST_UNIT_READY: - ata_scsi_rbuf_fill(&args, ata_scsiop_noop); break; case SEND_DIAGNOSTIC: tmp8 = scsicmd[1] & ~(1 << 3); - if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4])) - ata_scsi_rbuf_fill(&args, ata_scsiop_noop); - else + if (tmp8 != 0x4 || scsicmd[3] || scsicmd[4]) ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); break; -- cgit v1.2.3-59-g8ed1b From a234f7395c9301a5048cb2daa4c86f15c6f02de8 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 10 Jan 2017 17:04:32 +0100 Subject: libata: switch to dynamic allocation instead of ata_scsi_rbuf Note of the emulated commands in the pageout/pagein path, so just do a GFP_NOIO dynamic allocation. Signed-off-by: Christoph Hellwig Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 122 ++++++++++++++-------------------------------- 1 file changed, 36 insertions(+), 86 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 395c8591980f..4de273b77abc 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -57,9 +57,6 @@ #define ATA_SCSI_RBUF_SIZE 4096 -static DEFINE_SPINLOCK(ata_scsi_rbuf_lock); -static u8 ata_scsi_rbuf[ATA_SCSI_RBUF_SIZE]; - typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc); static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, @@ -2056,53 +2053,6 @@ struct ata_scsi_args { struct scsi_cmnd *cmd; }; -/** - * ata_scsi_rbuf_get - Map response buffer. - * @cmd: SCSI command containing buffer to be mapped. - * @flags: unsigned long variable to store irq enable status - * @copy_in: copy in from user buffer - * - * Prepare buffer for simulated SCSI commands. - * - * LOCKING: - * spin_lock_irqsave(ata_scsi_rbuf_lock) on success - * - * RETURNS: - * Pointer to response buffer. - */ -static void *ata_scsi_rbuf_get(struct scsi_cmnd *cmd, bool copy_in, - unsigned long *flags) -{ - spin_lock_irqsave(&ata_scsi_rbuf_lock, *flags); - - memset(ata_scsi_rbuf, 0, ATA_SCSI_RBUF_SIZE); - if (copy_in) - sg_copy_to_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), - ata_scsi_rbuf, ATA_SCSI_RBUF_SIZE); - return ata_scsi_rbuf; -} - -/** - * ata_scsi_rbuf_put - Unmap response buffer. - * @cmd: SCSI command containing buffer to be unmapped. - * @copy_out: copy out result - * @flags: @flags passed to ata_scsi_rbuf_get() - * - * Returns rbuf buffer. The result is copied to @cmd's buffer if - * @copy_back is true. - * - * LOCKING: - * Unlocks ata_scsi_rbuf_lock. - */ -static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, bool copy_out, - unsigned long *flags) -{ - if (copy_out) - sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), - ata_scsi_rbuf, ATA_SCSI_RBUF_SIZE); - spin_unlock_irqrestore(&ata_scsi_rbuf_lock, *flags); -} - /** * ata_scsi_rbuf_fill - wrapper for SCSI command simulators * @args: device IDENTIFY data / SCSI command of interest. @@ -2121,17 +2071,22 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, bool copy_out, static void ata_scsi_rbuf_fill(struct ata_scsi_args *args, unsigned int (*actor)(struct ata_scsi_args *args, u8 *rbuf)) { - u8 *rbuf; - unsigned int rc; struct scsi_cmnd *cmd = args->cmd; - unsigned long flags; + u8 *buf; - rbuf = ata_scsi_rbuf_get(cmd, false, &flags); - rc = actor(args, rbuf); - ata_scsi_rbuf_put(cmd, rc == 0, &flags); + buf = kzalloc(ATA_SCSI_RBUF_SIZE, GFP_NOIO); + if (!buf) { + ata_scsi_set_sense(args->dev, cmd, NOT_READY, 0x08, 0); + return; + } - if (rc == 0) + if (actor(args, buf) == 0) { + sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), + buf, ATA_SCSI_RBUF_SIZE); cmd->result = SAM_STAT_GOOD; + } + + kfree(buf); } /** @@ -3363,24 +3318,17 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) * * Return: Number of bytes copied into sglist. */ -static size_t ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 trmax, +static ssize_t ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 trmax, u64 sector, u32 count) { - struct scsi_device *sdp = cmd->device; - size_t len = sdp->sector_size; size_t r; __le64 *buf; u32 i = 0; - unsigned long flags; - - WARN_ON(len > ATA_SCSI_RBUF_SIZE); - if (len > ATA_SCSI_RBUF_SIZE) - len = ATA_SCSI_RBUF_SIZE; + buf = kzalloc(cmd->device->sector_size, GFP_NOFS); + if (!buf) + return -ENOMEM; - spin_lock_irqsave(&ata_scsi_rbuf_lock, flags); - buf = ((void *)ata_scsi_rbuf); - memset(buf, 0, len); while (i < trmax) { u64 entry = sector | ((u64)(count > 0xffff ? 0xffff : count) << 48); @@ -3390,9 +3338,9 @@ static size_t ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 trmax, count -= 0xffff; sector += 0xffff; } - r = sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, len); - spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags); - + r = sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, + cmd->device->sector_size); + kfree(buf); return r; } @@ -3408,16 +3356,15 @@ static size_t ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 trmax, * * Return: Number of bytes copied into sglist. */ -static size_t ata_format_sct_write_same(struct scsi_cmnd *cmd, u64 lba, u64 num) +static ssize_t ata_format_sct_write_same(struct scsi_cmnd *cmd, u64 lba, + u64 num) { - struct scsi_device *sdp = cmd->device; - size_t len = sdp->sector_size; size_t r; u16 *buf; - unsigned long flags; - spin_lock_irqsave(&ata_scsi_rbuf_lock, flags); - buf = ((void *)ata_scsi_rbuf); + buf = kzalloc(cmd->device->sector_size, GFP_NOIO); + if (!buf) + return -ENOMEM; put_unaligned_le16(0x0002, &buf[0]); /* SCT_ACT_WRITE_SAME */ put_unaligned_le16(0x0101, &buf[1]); /* WRITE PTRN FG */ @@ -3425,14 +3372,9 @@ static size_t ata_format_sct_write_same(struct scsi_cmnd *cmd, u64 lba, u64 num) put_unaligned_le64(num, &buf[6]); put_unaligned_le32(0u, &buf[10]); /* pattern */ - WARN_ON(len > ATA_SCSI_RBUF_SIZE); - - if (len > ATA_SCSI_RBUF_SIZE) - len = ATA_SCSI_RBUF_SIZE; - - r = sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, len); - spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags); - + r = sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, + cmd->device->sector_size); + kfree(buf); return r; } @@ -3457,7 +3399,7 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) u64 block; u32 n_block; const u32 trmax = len >> 3; - u32 size; + ssize_t size; u16 fp; u8 bp = 0xff; u8 unmap = cdb[1] & 0x8; @@ -3508,6 +3450,8 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) */ if (unmap) { size = ata_format_dsm_trim_descr(scmd, trmax, block, n_block); + if (size < 0) + goto comm_fail; if (size != len) goto invalid_param_len; @@ -3531,6 +3475,8 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) } } else { size = ata_format_sct_write_same(scmd, block, n_block); + if (size < 0) + goto comm_fail; if (size != len) goto invalid_param_len; @@ -3569,6 +3515,10 @@ invalid_opcode: /* "Invalid command operation code" */ ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x20, 0x0); return 1; +comm_fail: + /* "Logical unit communication failure" */ + ata_scsi_set_sense(dev, scmd, NOT_READY, 0x08, 0); + return 1; } /** -- cgit v1.2.3-59-g8ed1b From 7563f625469e9488fcd23cb64f9a6d61f1758f47 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 30 Dec 2016 15:01:16 +0100 Subject: ata: allow subsystem to be used on m68k arch When libata was merged m68k lacked IOMAP support. This has not been true for a long time now so allow subsystem to be used on m68k. Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Geert Uytterhoeven Signed-off-by: Tejun Heo --- drivers/ata/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 38318aaf29d3..702b3514020c 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -14,7 +14,7 @@ menuconfig ATA tristate "Serial ATA and Parallel ATA drivers (libata)" depends on HAS_IOMEM depends on BLOCK - depends on !(M32R || M68K || S390) || BROKEN + depends on !(M32R || S390) || BROKEN select SCSI select GLOB ---help--- -- cgit v1.2.3-59-g8ed1b From 989e0aac1a801e9e9580632c9fd448a7aaca596a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 30 Dec 2016 15:01:17 +0100 Subject: ata: pass queued command to ->sff_data_xfer method For Atari Falcon PATA support we need to check the current command in its ->sff_data_xfer method. Update core code and all users accordingly. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Tejun Heo --- drivers/ata/libata-sff.c | 29 +++++++++++++++-------------- drivers/ata/pata_at91.c | 6 +++--- drivers/ata/pata_bf54x.c | 7 ++++--- drivers/ata/pata_ep93xx.c | 4 ++-- drivers/ata/pata_ixp4xx_cf.c | 4 ++-- drivers/ata/pata_legacy.c | 15 +++++++++------ drivers/ata/pata_octeon_cf.c | 12 ++++++------ drivers/ata/pata_pcmcia.c | 6 +++--- drivers/ata/pata_samsung_cf.c | 4 ++-- drivers/ata/sata_rcar.c | 4 ++-- include/linux/libata.h | 8 ++++---- 11 files changed, 52 insertions(+), 47 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 051b6158d1b7..4441b5c5e4fb 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -542,7 +542,7 @@ static inline void ata_tf_to_host(struct ata_port *ap, /** * ata_sff_data_xfer - Transfer data by PIO - * @dev: device to target + * @qc: queued command * @buf: data buffer * @buflen: buffer length * @rw: read/write @@ -555,10 +555,10 @@ static inline void ata_tf_to_host(struct ata_port *ap, * RETURNS: * Bytes consumed. */ -unsigned int ata_sff_data_xfer(struct ata_device *dev, unsigned char *buf, +unsigned int ata_sff_data_xfer(struct ata_queued_cmd *qc, unsigned char *buf, unsigned int buflen, int rw) { - struct ata_port *ap = dev->link->ap; + struct ata_port *ap = qc->dev->link->ap; void __iomem *data_addr = ap->ioaddr.data_addr; unsigned int words = buflen >> 1; @@ -595,7 +595,7 @@ EXPORT_SYMBOL_GPL(ata_sff_data_xfer); /** * ata_sff_data_xfer32 - Transfer data by PIO - * @dev: device to target + * @qc: queued command * @buf: data buffer * @buflen: buffer length * @rw: read/write @@ -610,16 +610,17 @@ EXPORT_SYMBOL_GPL(ata_sff_data_xfer); * Bytes consumed. */ -unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf, +unsigned int ata_sff_data_xfer32(struct ata_queued_cmd *qc, unsigned char *buf, unsigned int buflen, int rw) { + struct ata_device *dev = qc->dev; struct ata_port *ap = dev->link->ap; void __iomem *data_addr = ap->ioaddr.data_addr; unsigned int words = buflen >> 2; int slop = buflen & 3; if (!(ap->pflags & ATA_PFLAG_PIO32)) - return ata_sff_data_xfer(dev, buf, buflen, rw); + return ata_sff_data_xfer(qc, buf, buflen, rw); /* Transfer multiple of 4 bytes */ if (rw == READ) @@ -658,7 +659,7 @@ EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); /** * ata_sff_data_xfer_noirq - Transfer data by PIO - * @dev: device to target + * @qc: queued command * @buf: data buffer * @buflen: buffer length * @rw: read/write @@ -672,14 +673,14 @@ EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); * RETURNS: * Bytes consumed. */ -unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev, unsigned char *buf, +unsigned int ata_sff_data_xfer_noirq(struct ata_queued_cmd *qc, unsigned char *buf, unsigned int buflen, int rw) { unsigned long flags; unsigned int consumed; local_irq_save(flags); - consumed = ata_sff_data_xfer32(dev, buf, buflen, rw); + consumed = ata_sff_data_xfer32(qc, buf, buflen, rw); local_irq_restore(flags); return consumed; @@ -723,14 +724,14 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) buf = kmap_atomic(page); /* do the actual data transfer */ - ap->ops->sff_data_xfer(qc->dev, buf + offset, qc->sect_size, + ap->ops->sff_data_xfer(qc, buf + offset, qc->sect_size, do_write); kunmap_atomic(buf); local_irq_restore(flags); } else { buf = page_address(page); - ap->ops->sff_data_xfer(qc->dev, buf + offset, qc->sect_size, + ap->ops->sff_data_xfer(qc, buf + offset, qc->sect_size, do_write); } @@ -791,7 +792,7 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) DPRINTK("send cdb\n"); WARN_ON_ONCE(qc->dev->cdb_len < 12); - ap->ops->sff_data_xfer(qc->dev, qc->cdb, qc->dev->cdb_len, 1); + ap->ops->sff_data_xfer(qc, qc->cdb, qc->dev->cdb_len, 1); ata_sff_sync(ap); /* FIXME: If the CDB is for DMA do we need to do the transition delay or is bmdma_start guaranteed to do it ? */ @@ -868,14 +869,14 @@ next_sg: buf = kmap_atomic(page); /* do the actual data transfer */ - consumed = ap->ops->sff_data_xfer(dev, buf + offset, + consumed = ap->ops->sff_data_xfer(qc, buf + offset, count, rw); kunmap_atomic(buf); local_irq_restore(flags); } else { buf = page_address(page); - consumed = ap->ops->sff_data_xfer(dev, buf + offset, + consumed = ap->ops->sff_data_xfer(qc, buf + offset, count, rw); } diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index 1611e0e8d767..fd5b34f0d007 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c @@ -286,10 +286,10 @@ static void pata_at91_set_piomode(struct ata_port *ap, struct ata_device *adev) set_smc_timing(ap->dev, adev, info, &timing); } -static unsigned int pata_at91_data_xfer_noirq(struct ata_device *dev, +static unsigned int pata_at91_data_xfer_noirq(struct ata_queued_cmd *qc, unsigned char *buf, unsigned int buflen, int rw) { - struct at91_ide_info *info = dev->link->ap->host->private_data; + struct at91_ide_info *info = qc->dev->link->ap->host->private_data; unsigned int consumed; unsigned int mode; unsigned long flags; @@ -301,7 +301,7 @@ static unsigned int pata_at91_data_xfer_noirq(struct ata_device *dev, regmap_fields_write(fields.mode, info->cs, (mode & ~AT91_SMC_DBW) | AT91_SMC_DBW_16); - consumed = ata_sff_data_xfer(dev, buf, buflen, rw); + consumed = ata_sff_data_xfer(qc, buf, buflen, rw); /* restore 8bit mode after data is written */ regmap_fields_write(fields.mode, info->cs, (mode & ~AT91_SMC_DBW) | diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index ec748d31928d..9c5780a7e1b9 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -1143,7 +1143,7 @@ static unsigned char bfin_bmdma_status(struct ata_port *ap) /** * bfin_data_xfer - Transfer data by PIO - * @adev: device for this I/O + * @qc: queued command * @buf: data buffer * @buflen: buffer length * @write_data: read/write @@ -1151,10 +1151,11 @@ static unsigned char bfin_bmdma_status(struct ata_port *ap) * Note: Original code is ata_sff_data_xfer(). */ -static unsigned int bfin_data_xfer(struct ata_device *dev, unsigned char *buf, +static unsigned int bfin_data_xfer(struct ata_queued_cmd *qc, + unsigned char *buf, unsigned int buflen, int rw) { - struct ata_port *ap = dev->link->ap; + struct ata_port *ap = qc->dev->link->ap; void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; unsigned int words = buflen >> 1; unsigned short *buf16 = (u16 *)buf; diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c index bd6b089c67a3..bf1b910c5d69 100644 --- a/drivers/ata/pata_ep93xx.c +++ b/drivers/ata/pata_ep93xx.c @@ -474,11 +474,11 @@ static void ep93xx_pata_set_devctl(struct ata_port *ap, u8 ctl) } /* Note: original code is ata_sff_data_xfer */ -static unsigned int ep93xx_pata_data_xfer(struct ata_device *adev, +static unsigned int ep93xx_pata_data_xfer(struct ata_queued_cmd *qc, unsigned char *buf, unsigned int buflen, int rw) { - struct ata_port *ap = adev->link->ap; + struct ata_port *ap = qc->dev->link->ap; struct ep93xx_pata_data *drv_data = ap->host->private_data; u16 *data = (u16 *)buf; unsigned int words = buflen >> 1; diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index abda44183512..0b0d93065f5a 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -40,13 +40,13 @@ static int ixp4xx_set_mode(struct ata_link *link, struct ata_device **error) return 0; } -static unsigned int ixp4xx_mmio_data_xfer(struct ata_device *dev, +static unsigned int ixp4xx_mmio_data_xfer(struct ata_queued_cmd *qc, unsigned char *buf, unsigned int buflen, int rw) { unsigned int i; unsigned int words = buflen >> 1; u16 *buf16 = (u16 *) buf; - struct ata_port *ap = dev->link->ap; + struct ata_port *ap = qc->dev->link->ap; void __iomem *mmio = ap->ioaddr.data_addr; struct ixp4xx_pata_data *data = dev_get_platdata(ap->host->dev); diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index bce2a8ca4678..53828b6c3044 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -303,11 +303,12 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) } -static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, +static unsigned int pdc_data_xfer_vlb(struct ata_queued_cmd *qc, unsigned char *buf, unsigned int buflen, int rw) { - int slop = buflen & 3; + struct ata_device *dev = qc->dev; struct ata_port *ap = dev->link->ap; + int slop = buflen & 3; /* 32bit I/O capable *and* we need to write a whole number of dwords */ if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3) @@ -340,7 +341,7 @@ static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, } local_irq_restore(flags); } else - buflen = ata_sff_data_xfer_noirq(dev, buf, buflen, rw); + buflen = ata_sff_data_xfer_noirq(qc, buf, buflen, rw); return buflen; } @@ -702,9 +703,11 @@ static unsigned int qdi_qc_issue(struct ata_queued_cmd *qc) return ata_sff_qc_issue(qc); } -static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf, - unsigned int buflen, int rw) +static unsigned int vlb32_data_xfer(struct ata_queued_cmd *qc, + unsigned char *buf, + unsigned int buflen, int rw) { + struct ata_device *adev = qc->dev; struct ata_port *ap = adev->link->ap; int slop = buflen & 3; @@ -727,7 +730,7 @@ static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf, } return (buflen + 3) & ~3; } else - return ata_sff_data_xfer(adev, buf, buflen, rw); + return ata_sff_data_xfer(qc, buf, buflen, rw); } static int qdi_port(struct platform_device *dev, diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 475a00669427..e94e7ca0e743 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -293,17 +293,17 @@ static void octeon_cf_set_dmamode(struct ata_port *ap, struct ata_device *dev) /** * Handle an 8 bit I/O request. * - * @dev: Device to access + * @qc: Queued command * @buffer: Data buffer * @buflen: Length of the buffer. * @rw: True to write. */ -static unsigned int octeon_cf_data_xfer8(struct ata_device *dev, +static unsigned int octeon_cf_data_xfer8(struct ata_queued_cmd *qc, unsigned char *buffer, unsigned int buflen, int rw) { - struct ata_port *ap = dev->link->ap; + struct ata_port *ap = qc->dev->link->ap; void __iomem *data_addr = ap->ioaddr.data_addr; unsigned long words; int count; @@ -332,17 +332,17 @@ static unsigned int octeon_cf_data_xfer8(struct ata_device *dev, /** * Handle a 16 bit I/O request. * - * @dev: Device to access + * @qc: Queued command * @buffer: Data buffer * @buflen: Length of the buffer. * @rw: True to write. */ -static unsigned int octeon_cf_data_xfer16(struct ata_device *dev, +static unsigned int octeon_cf_data_xfer16(struct ata_queued_cmd *qc, unsigned char *buffer, unsigned int buflen, int rw) { - struct ata_port *ap = dev->link->ap; + struct ata_port *ap = qc->dev->link->ap; void __iomem *data_addr = ap->ioaddr.data_addr; unsigned long words; int count; diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index bcc4b968c049..a541eacc5e95 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -90,7 +90,7 @@ static int pcmcia_set_mode_8bit(struct ata_link *link, /** * ata_data_xfer_8bit - Transfer data by 8bit PIO - * @dev: device to target + * @qc: queued command * @buf: data buffer * @buflen: buffer length * @rw: read/write @@ -101,10 +101,10 @@ static int pcmcia_set_mode_8bit(struct ata_link *link, * Inherited from caller. */ -static unsigned int ata_data_xfer_8bit(struct ata_device *dev, +static unsigned int ata_data_xfer_8bit(struct ata_queued_cmd *qc, unsigned char *buf, unsigned int buflen, int rw) { - struct ata_port *ap = dev->link->ap; + struct ata_port *ap = qc->dev->link->ap; if (rw == READ) ioread8_rep(ap->ioaddr.data_addr, buf, buflen); diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c index f6facd686f94..431c7de30ce6 100644 --- a/drivers/ata/pata_samsung_cf.c +++ b/drivers/ata/pata_samsung_cf.c @@ -263,10 +263,10 @@ static u8 pata_s3c_check_altstatus(struct ata_port *ap) /* * pata_s3c_data_xfer - Transfer data by PIO */ -static unsigned int pata_s3c_data_xfer(struct ata_device *dev, +static unsigned int pata_s3c_data_xfer(struct ata_queued_cmd *qc, unsigned char *buf, unsigned int buflen, int rw) { - struct ata_port *ap = dev->link->ap; + struct ata_port *ap = qc->dev->link->ap; struct s3c_ide_info *info = ap->host->private_data; void __iomem *data_addr = ap->ioaddr.data_addr; unsigned int words = buflen >> 1, i; diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index f72d601e300a..5d38245a7a73 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -447,11 +447,11 @@ static void sata_rcar_exec_command(struct ata_port *ap, ata_sff_pause(ap); } -static unsigned int sata_rcar_data_xfer(struct ata_device *dev, +static unsigned int sata_rcar_data_xfer(struct ata_queued_cmd *qc, unsigned char *buf, unsigned int buflen, int rw) { - struct ata_port *ap = dev->link->ap; + struct ata_port *ap = qc->dev->link->ap; void __iomem *data_addr = ap->ioaddr.data_addr; unsigned int words = buflen >> 1; diff --git a/include/linux/libata.h b/include/linux/libata.h index c170be548b7f..0e8a8000b45f 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -968,7 +968,7 @@ struct ata_port_operations { void (*sff_tf_read)(struct ata_port *ap, struct ata_taskfile *tf); void (*sff_exec_command)(struct ata_port *ap, const struct ata_taskfile *tf); - unsigned int (*sff_data_xfer)(struct ata_device *dev, + unsigned int (*sff_data_xfer)(struct ata_queued_cmd *qc, unsigned char *buf, unsigned int buflen, int rw); void (*sff_irq_on)(struct ata_port *); bool (*sff_irq_check)(struct ata_port *); @@ -1823,11 +1823,11 @@ extern void ata_sff_tf_load(struct ata_port *ap, const struct ata_taskfile *tf); extern void ata_sff_tf_read(struct ata_port *ap, struct ata_taskfile *tf); extern void ata_sff_exec_command(struct ata_port *ap, const struct ata_taskfile *tf); -extern unsigned int ata_sff_data_xfer(struct ata_device *dev, +extern unsigned int ata_sff_data_xfer(struct ata_queued_cmd *qc, unsigned char *buf, unsigned int buflen, int rw); -extern unsigned int ata_sff_data_xfer32(struct ata_device *dev, +extern unsigned int ata_sff_data_xfer32(struct ata_queued_cmd *qc, unsigned char *buf, unsigned int buflen, int rw); -extern unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev, +extern unsigned int ata_sff_data_xfer_noirq(struct ata_queued_cmd *qc, unsigned char *buf, unsigned int buflen, int rw); extern void ata_sff_irq_on(struct ata_port *ap); extern void ata_sff_irq_clear(struct ata_port *ap); -- cgit v1.2.3-59-g8ed1b From 7e11aabd48eb00240b280bf927cba9198664dcf6 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 30 Dec 2016 15:01:18 +0100 Subject: ata: add Atari Falcon PATA controller driver Add Atari Falcon PATA controller driver. The major difference when compared to legacy IDE's falconide host driver is that we are using polled PIO mode and thus avoiding the need for STDMA locking magic altogether. Tested under ARAnyM emulator. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Tejun Heo --- drivers/ata/Kconfig | 9 +++ drivers/ata/Makefile | 1 + drivers/ata/pata_falcon.c | 184 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 194 insertions(+) create mode 100644 drivers/ata/pata_falcon.c (limited to 'drivers/ata') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 702b3514020c..78c002021029 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -902,6 +902,15 @@ config PATA_CMD640_PCI If unsure, say N. +config PATA_FALCON + tristate "Atari Falcon PATA support" + depends on M68K && ATARI + help + This option enables support for the on-board IDE + interface on the Atari Falcon. + + If unsure, say N. + config PATA_ISAPNP tristate "ISA Plug and Play PATA support" depends on ISAPNP diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index a46e6b784bda..89a0a1915d36 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -93,6 +93,7 @@ obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o obj-$(CONFIG_PATA_AT32) += pata_at32.o obj-$(CONFIG_PATA_AT91) += pata_at91.o obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o +obj-$(CONFIG_PATA_FALCON) += pata_falcon.o obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o diff --git a/drivers/ata/pata_falcon.c b/drivers/ata/pata_falcon.c new file mode 100644 index 000000000000..78264082a4cf --- /dev/null +++ b/drivers/ata/pata_falcon.c @@ -0,0 +1,184 @@ +/* + * Atari Falcon PATA controller driver + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Based on falconide.c: + * + * Created 12 Jul 1997 by Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define DRV_NAME "pata_falcon" +#define DRV_VERSION "0.1.0" + +#define ATA_HD_BASE 0xfff00000 +#define ATA_HD_CONTROL 0x39 + +static struct scsi_host_template pata_falcon_sht = { + ATA_PIO_SHT(DRV_NAME), +}; + +static unsigned int pata_falcon_data_xfer(struct ata_queued_cmd *qc, + unsigned char *buf, + unsigned int buflen, int rw) +{ + struct ata_device *dev = qc->dev; + struct ata_port *ap = dev->link->ap; + void __iomem *data_addr = ap->ioaddr.data_addr; + unsigned int words = buflen >> 1; + struct scsi_cmnd *cmd = qc->scsicmd; + bool swap = 1; + + if (dev->class == ATA_DEV_ATA && cmd && cmd->request && + cmd->request->cmd_type == REQ_TYPE_FS) + swap = 0; + + /* Transfer multiple of 2 bytes */ + if (rw == READ) { + if (swap) + raw_insw_swapw((u16 *)data_addr, (u16 *)buf, words); + else + raw_insw((u16 *)data_addr, (u16 *)buf, words); + } else { + if (swap) + raw_outsw_swapw((u16 *)data_addr, (u16 *)buf, words); + else + raw_outsw((u16 *)data_addr, (u16 *)buf, words); + } + + /* Transfer trailing byte, if any. */ + if (unlikely(buflen & 0x01)) { + unsigned char pad[2] = { }; + + /* Point buf to the tail of buffer */ + buf += buflen - 1; + + if (rw == READ) { + if (swap) + raw_insw_swapw((u16 *)data_addr, (u16 *)pad, 1); + else + raw_insw((u16 *)data_addr, (u16 *)pad, 1); + *buf = pad[0]; + } else { + pad[0] = *buf; + if (swap) + raw_outsw_swapw((u16 *)data_addr, (u16 *)pad, 1); + else + raw_outsw((u16 *)data_addr, (u16 *)pad, 1); + } + words++; + } + + return words << 1; +} + +/* + * Provide our own set_mode() as we don't want to change anything that has + * already been configured.. + */ +static int pata_falcon_set_mode(struct ata_link *link, + struct ata_device **unused) +{ + struct ata_device *dev; + + ata_for_each_dev(dev, link, ENABLED) { + /* We don't really care */ + dev->pio_mode = dev->xfer_mode = XFER_PIO_0; + dev->xfer_shift = ATA_SHIFT_PIO; + dev->flags |= ATA_DFLAG_PIO; + ata_dev_info(dev, "configured for PIO\n"); + } + return 0; +} + +static struct ata_port_operations pata_falcon_ops = { + .inherits = &ata_sff_port_ops, + .sff_data_xfer = pata_falcon_data_xfer, + .cable_detect = ata_cable_unknown, + .set_mode = pata_falcon_set_mode, +}; + +static int pata_falcon_init_one(void) +{ + struct ata_host *host; + struct ata_port *ap; + struct platform_device *pdev; + void __iomem *base; + + if (!MACH_IS_ATARI || !ATARIHW_PRESENT(IDE)) + return -ENODEV; + + pr_info(DRV_NAME ": Atari Falcon PATA controller\n"); + + pdev = platform_device_register_simple(DRV_NAME, 0, NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + if (!devm_request_mem_region(&pdev->dev, ATA_HD_BASE, 0x40, DRV_NAME)) { + pr_err(DRV_NAME ": resources busy\n"); + return -EBUSY; + } + + /* allocate host */ + host = ata_host_alloc(&pdev->dev, 1); + if (!host) + return -ENOMEM; + ap = host->ports[0]; + + ap->ops = &pata_falcon_ops; + ap->pio_mask = ATA_PIO4; + ap->flags |= ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY; + ap->flags |= ATA_FLAG_PIO_POLLING; + + base = (void __iomem *)ATA_HD_BASE; + ap->ioaddr.data_addr = base; + ap->ioaddr.error_addr = base + 1 + 1 * 4; + ap->ioaddr.feature_addr = base + 1 + 1 * 4; + ap->ioaddr.nsect_addr = base + 1 + 2 * 4; + ap->ioaddr.lbal_addr = base + 1 + 3 * 4; + ap->ioaddr.lbam_addr = base + 1 + 4 * 4; + ap->ioaddr.lbah_addr = base + 1 + 5 * 4; + ap->ioaddr.device_addr = base + 1 + 6 * 4; + ap->ioaddr.status_addr = base + 1 + 7 * 4; + ap->ioaddr.command_addr = base + 1 + 7 * 4; + + ap->ioaddr.altstatus_addr = base + ATA_HD_CONTROL; + ap->ioaddr.ctl_addr = base + ATA_HD_CONTROL; + + ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", (unsigned long)base, + (unsigned long)base + ATA_HD_CONTROL); + + /* activate */ + return ata_host_activate(host, 0, NULL, 0, &pata_falcon_sht); +} + +module_init(pata_falcon_init_one); + +MODULE_AUTHOR("Bartlomiej Zolnierkiewicz"); +MODULE_DESCRIPTION("low-level driver for Atari Falcon PATA"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); -- cgit v1.2.3-59-g8ed1b From d7969f5976a35b48ba4eb60aaad73535f1792019 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 11 Jan 2017 14:36:16 +0100 Subject: ahci: imx: fix building without hwmon or thermal When CONFIG_HWMON is disabled, we now get a link failure: ERROR: "devm_hwmon_device_register_with_groups" [drivers/ata/ahci_imx.ko] undefined! drivers/ata/ahci_imx.o: In function `imx_ahci_probe': ahci_imx.c:(.text.imx_ahci_probe+0x304): undefined reference to `devm_thermal_zone_of_sensor_register' This makes the code calling into the hwmon subsystem compile-time conditional, and adds a Kconfig dependency to avoid the corner case of having HWMON=m and AHCI_IMX=y, by forcing AHCI_IMX=m in this case. The thermal subsystem already has a check in its header, but that also doesn't cover the THERMAL=m case, so we need a somewhat complex Kconfig expression to handle all cases. Fixes: 54643a83b41a ("ahci: imx: Add imx53 SATA temperature sensor support") Signed-off-by: Arnd Bergmann Acked-by: Reviewed-by: Bartlomiej Zolnierkiewicz Signed-off-by: Tejun Heo --- drivers/ata/Kconfig | 1 + drivers/ata/ahci_imx.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 78c002021029..70b57d2229d6 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -129,6 +129,7 @@ config AHCI_ST config AHCI_IMX tristate "Freescale i.MX AHCI SATA support" depends on MFD_SYSCON && (ARCH_MXC || COMPILE_TEST) + depends on (HWMON && (THERMAL || !THERMAL_OF)) || !HWMON help This option enables support for the Freescale i.MX SoC's onboard AHCI SATA. diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index 420f065978dc..787567e840bd 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c @@ -774,7 +774,8 @@ static int imx_ahci_probe(struct platform_device *pdev) if (ret) return ret; - if (imxpriv->type == AHCI_IMX53) { + if (imxpriv->type == AHCI_IMX53 && + IS_ENABLED(CONFIG_HWMON)) { /* Add the temperature monitor */ struct device *hwmon_dev; -- cgit v1.2.3-59-g8ed1b From d4ae1e2648daf12e433b81f5718dac4be84abd01 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 18 Jan 2017 11:11:58 -0800 Subject: Revert "libata: switch to dynamic allocation instead of ata_scsi_rbuf" This reverts commit a234f7395c9301a5048cb2daa4c86f15c6f02de8. The commit tried to get rid of the shared global SCSI response buffer. Unfortunately, it added blocking allocation to atomic path. Revert it for now. Signed-off-by: Tejun Heo Cc: Christoph Hellwig --- drivers/ata/libata-scsi.c | 122 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 86 insertions(+), 36 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 4de273b77abc..395c8591980f 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -57,6 +57,9 @@ #define ATA_SCSI_RBUF_SIZE 4096 +static DEFINE_SPINLOCK(ata_scsi_rbuf_lock); +static u8 ata_scsi_rbuf[ATA_SCSI_RBUF_SIZE]; + typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc); static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, @@ -2053,6 +2056,53 @@ struct ata_scsi_args { struct scsi_cmnd *cmd; }; +/** + * ata_scsi_rbuf_get - Map response buffer. + * @cmd: SCSI command containing buffer to be mapped. + * @flags: unsigned long variable to store irq enable status + * @copy_in: copy in from user buffer + * + * Prepare buffer for simulated SCSI commands. + * + * LOCKING: + * spin_lock_irqsave(ata_scsi_rbuf_lock) on success + * + * RETURNS: + * Pointer to response buffer. + */ +static void *ata_scsi_rbuf_get(struct scsi_cmnd *cmd, bool copy_in, + unsigned long *flags) +{ + spin_lock_irqsave(&ata_scsi_rbuf_lock, *flags); + + memset(ata_scsi_rbuf, 0, ATA_SCSI_RBUF_SIZE); + if (copy_in) + sg_copy_to_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), + ata_scsi_rbuf, ATA_SCSI_RBUF_SIZE); + return ata_scsi_rbuf; +} + +/** + * ata_scsi_rbuf_put - Unmap response buffer. + * @cmd: SCSI command containing buffer to be unmapped. + * @copy_out: copy out result + * @flags: @flags passed to ata_scsi_rbuf_get() + * + * Returns rbuf buffer. The result is copied to @cmd's buffer if + * @copy_back is true. + * + * LOCKING: + * Unlocks ata_scsi_rbuf_lock. + */ +static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, bool copy_out, + unsigned long *flags) +{ + if (copy_out) + sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), + ata_scsi_rbuf, ATA_SCSI_RBUF_SIZE); + spin_unlock_irqrestore(&ata_scsi_rbuf_lock, *flags); +} + /** * ata_scsi_rbuf_fill - wrapper for SCSI command simulators * @args: device IDENTIFY data / SCSI command of interest. @@ -2071,22 +2121,17 @@ struct ata_scsi_args { static void ata_scsi_rbuf_fill(struct ata_scsi_args *args, unsigned int (*actor)(struct ata_scsi_args *args, u8 *rbuf)) { + u8 *rbuf; + unsigned int rc; struct scsi_cmnd *cmd = args->cmd; - u8 *buf; + unsigned long flags; - buf = kzalloc(ATA_SCSI_RBUF_SIZE, GFP_NOIO); - if (!buf) { - ata_scsi_set_sense(args->dev, cmd, NOT_READY, 0x08, 0); - return; - } + rbuf = ata_scsi_rbuf_get(cmd, false, &flags); + rc = actor(args, rbuf); + ata_scsi_rbuf_put(cmd, rc == 0, &flags); - if (actor(args, buf) == 0) { - sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), - buf, ATA_SCSI_RBUF_SIZE); + if (rc == 0) cmd->result = SAM_STAT_GOOD; - } - - kfree(buf); } /** @@ -3318,17 +3363,24 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) * * Return: Number of bytes copied into sglist. */ -static ssize_t ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 trmax, +static size_t ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 trmax, u64 sector, u32 count) { + struct scsi_device *sdp = cmd->device; + size_t len = sdp->sector_size; size_t r; __le64 *buf; u32 i = 0; + unsigned long flags; - buf = kzalloc(cmd->device->sector_size, GFP_NOFS); - if (!buf) - return -ENOMEM; + WARN_ON(len > ATA_SCSI_RBUF_SIZE); + if (len > ATA_SCSI_RBUF_SIZE) + len = ATA_SCSI_RBUF_SIZE; + + spin_lock_irqsave(&ata_scsi_rbuf_lock, flags); + buf = ((void *)ata_scsi_rbuf); + memset(buf, 0, len); while (i < trmax) { u64 entry = sector | ((u64)(count > 0xffff ? 0xffff : count) << 48); @@ -3338,9 +3390,9 @@ static ssize_t ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 trmax, count -= 0xffff; sector += 0xffff; } - r = sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, - cmd->device->sector_size); - kfree(buf); + r = sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, len); + spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags); + return r; } @@ -3356,15 +3408,16 @@ static ssize_t ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 trmax, * * Return: Number of bytes copied into sglist. */ -static ssize_t ata_format_sct_write_same(struct scsi_cmnd *cmd, u64 lba, - u64 num) +static size_t ata_format_sct_write_same(struct scsi_cmnd *cmd, u64 lba, u64 num) { + struct scsi_device *sdp = cmd->device; + size_t len = sdp->sector_size; size_t r; u16 *buf; + unsigned long flags; - buf = kzalloc(cmd->device->sector_size, GFP_NOIO); - if (!buf) - return -ENOMEM; + spin_lock_irqsave(&ata_scsi_rbuf_lock, flags); + buf = ((void *)ata_scsi_rbuf); put_unaligned_le16(0x0002, &buf[0]); /* SCT_ACT_WRITE_SAME */ put_unaligned_le16(0x0101, &buf[1]); /* WRITE PTRN FG */ @@ -3372,9 +3425,14 @@ static ssize_t ata_format_sct_write_same(struct scsi_cmnd *cmd, u64 lba, put_unaligned_le64(num, &buf[6]); put_unaligned_le32(0u, &buf[10]); /* pattern */ - r = sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, - cmd->device->sector_size); - kfree(buf); + WARN_ON(len > ATA_SCSI_RBUF_SIZE); + + if (len > ATA_SCSI_RBUF_SIZE) + len = ATA_SCSI_RBUF_SIZE; + + r = sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, len); + spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags); + return r; } @@ -3399,7 +3457,7 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) u64 block; u32 n_block; const u32 trmax = len >> 3; - ssize_t size; + u32 size; u16 fp; u8 bp = 0xff; u8 unmap = cdb[1] & 0x8; @@ -3450,8 +3508,6 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) */ if (unmap) { size = ata_format_dsm_trim_descr(scmd, trmax, block, n_block); - if (size < 0) - goto comm_fail; if (size != len) goto invalid_param_len; @@ -3475,8 +3531,6 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) } } else { size = ata_format_sct_write_same(scmd, block, n_block); - if (size < 0) - goto comm_fail; if (size != len) goto invalid_param_len; @@ -3515,10 +3569,6 @@ invalid_opcode: /* "Invalid command operation code" */ ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x20, 0x0); return 1; -comm_fail: - /* "Logical unit communication failure" */ - ata_scsi_set_sense(dev, scmd, NOT_READY, 0x08, 0); - return 1; } /** -- cgit v1.2.3-59-g8ed1b From 386dc3b87a04fe4929bc3afb83660f050a5a0faa Mon Sep 17 00:00:00 2001 From: Tang Yuantian Date: Fri, 20 Jan 2017 14:59:34 +0800 Subject: ahci: qoriq: added a condition to enable dma coherence Enable DMA coherence in SATA controller on condition that dma-coherent property exists in sata node in DTS. Signed-off-by: Tang Yuantian Signed-off-by: Tejun Heo --- drivers/ata/ahci_qoriq.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 9884c8c6e934..01ef66270a46 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -59,6 +59,7 @@ struct ahci_qoriq_priv { struct ccsr_ahci *reg_base; enum ahci_qoriq_type type; void __iomem *ecc_addr; + bool is_dmacoherent; }; static const struct of_device_id ahci_qoriq_of_match[] = { @@ -164,26 +165,31 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4); writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); - writel(AHCI_PORT_AXICC_CFG, reg_base + LS1021A_AXICC_ADDR); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, + reg_base + LS1021A_AXICC_ADDR); break; case AHCI_LS1043A: writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); - writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); break; case AHCI_LS2080A: writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); - writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); break; case AHCI_LS1046A: writel(LS1046A_SATA_ECC_DIS, qpriv->ecc_addr); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); - writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); break; } @@ -221,6 +227,7 @@ static int ahci_qoriq_probe(struct platform_device *pdev) if (IS_ERR(qoriq_priv->ecc_addr)) return PTR_ERR(qoriq_priv->ecc_addr); } + qoriq_priv->is_dmacoherent = of_dma_is_coherent(np); rc = ahci_platform_enable_resources(hpriv); if (rc) -- cgit v1.2.3-59-g8ed1b From 01f2901a264d954d3985e8bce1bf637ae52d4918 Mon Sep 17 00:00:00 2001 From: Tang Yuantian Date: Fri, 20 Jan 2017 14:59:35 +0800 Subject: ahci: qoriq: report error when ecc register address is missing in dts For ls1021a, and armv8 chasis 2 socs, sata ecc must be disabled. If ecc register is not found in sata node in dts, report error. This is a chip erratum described as bellow: The Read DMA operations get early termination indication from the controller. This issue is observed as CRC error in the status registers. The issue is due to address collision at address 0 in the dual port memory. The read is a dummy read to flush out the header, but due to collision the controller logs the mbit error reported by the ECC check logic. This results in the early termination of the Read DMA operation by the controller. The issue happens to all the interface speeds(GEN1/2/3) for all the products. Workaround: Disable ECC feature on those platforms. Signed-off-by: Tang Yuantian Signed-off-by: Tejun Heo --- drivers/ata/ahci_qoriq.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 01ef66270a46..137b1c76f259 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -46,7 +46,7 @@ #define LS1021A_AXICC_ADDR 0xC0 #define SATA_ECC_DISABLE 0x00020000 -#define LS1046A_SATA_ECC_DIS 0x80000000 +#define ECC_DIS_ARMV8_CH2 0x80000000 enum ahci_qoriq_type { AHCI_LS1021A, @@ -158,6 +158,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) switch (qpriv->type) { case AHCI_LS1021A: + if (!qpriv->ecc_addr) + return -EINVAL; writel(SATA_ECC_DISABLE, qpriv->ecc_addr); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(LS1021A_PORT_PHY2, reg_base + PORT_PHY2); @@ -171,6 +173,9 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) break; case AHCI_LS1043A: + if (!qpriv->ecc_addr) + return -EINVAL; + writel(ECC_DIS_ARMV8_CH2, qpriv->ecc_addr); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); if (qpriv->is_dmacoherent) @@ -185,7 +190,9 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) break; case AHCI_LS1046A: - writel(LS1046A_SATA_ECC_DIS, qpriv->ecc_addr); + if (!qpriv->ecc_addr) + return -EINVAL; + writel(ECC_DIS_ARMV8_CH2, qpriv->ecc_addr); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); if (qpriv->is_dmacoherent) -- cgit v1.2.3-59-g8ed1b From ce8f45370e118fb6d5fe820b97558b9e2e2fece5 Mon Sep 17 00:00:00 2001 From: Tang Yuantian Date: Fri, 20 Jan 2017 14:59:36 +0800 Subject: ahci: qoriq: added ls2088a platforms support Ls2088a is new introduced arm-based soc with sata support with following features: 1. Complies with the serial ATA 3.0 specification and the AHCI 1.3.1 specification 2. Contains a high-speed descriptor-based DMA controller 3. Supports the following: a. Speeds of 1.5 Gb/s (first-generation SATA), 3 Gb/s (second-generation SATA), and 6 Gb/s (third-generation SATA) b. FIS-based switching c. Native command queuing (NCQ) commands d. Port multiplier operation e. Asynchronous notification f. SATA BIST mode Signed-off-by: Tang Yuantian Signed-off-by: Tejun Heo --- drivers/ata/ahci_qoriq.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 137b1c76f259..85d833289f28 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -53,6 +53,7 @@ enum ahci_qoriq_type { AHCI_LS1043A, AHCI_LS2080A, AHCI_LS1046A, + AHCI_LS2088A, }; struct ahci_qoriq_priv { @@ -67,6 +68,7 @@ static const struct of_device_id ahci_qoriq_of_match[] = { { .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A}, { .compatible = "fsl,ls2080a-ahci", .data = (void *)AHCI_LS2080A}, { .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A}, + { .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A}, {}, }; MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match); @@ -198,6 +200,13 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) if (qpriv->is_dmacoherent) writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); break; + + case AHCI_LS2088A: + writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); + writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + break; } return 0; -- cgit v1.2.3-59-g8ed1b From d786b91f422c6ad4c0d9bb9c1bef2dd5008e3d9d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 23 Jan 2017 14:28:51 -0500 Subject: pata_octeon_cf: remove unused local variables from octeon_cf_set_piomode() @t1 and @t2i are calculated along with @t2 but never used. Drop them. Signed-off-by: Tejun Heo Reported-by: David Binderman --- drivers/ata/pata_octeon_cf.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index e94e7ca0e743..f524a9099d01 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -138,9 +138,7 @@ static void octeon_cf_set_piomode(struct ata_port *ap, struct ata_device *dev) int trh; int pause; /* These names are timing parameters from the ATA spec */ - int t1; int t2; - int t2i; /* * A divisor value of four will overflow the timing fields at @@ -154,15 +152,9 @@ static void octeon_cf_set_piomode(struct ata_port *ap, struct ata_device *dev) BUG_ON(ata_timing_compute(dev, dev->pio_mode, &timing, T, T)); - t1 = timing.setup; - if (t1) - t1--; t2 = timing.active; if (t2) t2--; - t2i = timing.act8b; - if (t2i) - t2i--; trh = ns_to_tim_reg(div, 20); if (trh) -- cgit v1.2.3-59-g8ed1b From 589d572671fe7ca342d25cde07a0e310a6912971 Mon Sep 17 00:00:00 2001 From: Darren Stevens Date: Mon, 23 Jan 2017 14:33:36 -0500 Subject: libata-sff: Don't scan disabled ports when checking for legacy mode. libata-sff.c checks for legacy mode by testing if both primary and secondary ports on a controller are in legacy mode and selects legacy if either one is. However on some south bridge chips (e.g AMD SB600/SB700) the secondary port is not wired, and when it is disabled by setting the disable bit in the PCI header it appears as a fixed legacy port. Prevent incorrect detection by not testing ports that are marked as 'dummy' tj: Addressed Sergei's review points. Other style edits. Signed-off-by: Darren Stevens Signed-off-by: Tejun Heo Cc: Sergei Shtylyov --- drivers/ata/libata-sff.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 4441b5c5e4fb..2bd92dca3e62 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -2428,11 +2428,21 @@ int ata_pci_sff_activate_host(struct ata_host *host, return rc; if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { - u8 tmp8, mask; + u8 tmp8, mask = 0; - /* TODO: What if one channel is in native mode ... */ + /* + * ATA spec says we should use legacy mode when one + * port is in legacy mode, but disabled ports on some + * PCI hosts appear as fixed legacy ports, e.g SB600/700 + * on which the secondary port is not wired, so + * ignore ports that are marked as 'dummy' during + * this check + */ pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); - mask = (1 << 2) | (1 << 0); + if (!ata_port_is_dummy(host->ports[0])) + mask |= (1 << 0); + if (!ata_port_is_dummy(host->ports[1])) + mask |= (1 << 2); if ((tmp8 & mask) != mask) legacy_mode = 1; } -- cgit v1.2.3-59-g8ed1b From 5946fdaee4ba449e8fbb5d403e1ed69437f916e8 Mon Sep 17 00:00:00 2001 From: Darren Stevens Date: Mon, 23 Jan 2017 14:38:28 -0500 Subject: pata_atiixp: Don't use unconnected secondary port on SB600/SB700 The SB600 and SB700 southbridge chips from ATI/AMD only have connections for the primary IDE port. As these chips have unique pci device ID's use these to mark the secondary port as 'dummy' Signed-off-by: Darren Stevens Signed-off-by: Tejun Heo --- drivers/ata/pata_atiixp.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/ata') diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 49d705c9f0f7..6c9aa95a9a05 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -278,6 +278,11 @@ static int atiixp_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }; const struct ata_port_info *ppi[] = { &info, &info }; + /* SB600/700 don't have secondary port wired */ + if ((pdev->device == PCI_DEVICE_ID_ATI_IXP600_IDE) || + (pdev->device == PCI_DEVICE_ID_ATI_IXP700_IDE)) + ppi[1] = &ata_dummy_port_info; + return ata_pci_bmdma_init_one(pdev, ppi, &atiixp_sht, NULL, ATA_HOST_PARALLEL_SCAN); } -- cgit v1.2.3-59-g8ed1b From 73b2951414f661e22dc4b88e4e6590c9406cf822 Mon Sep 17 00:00:00 2001 From: Kefeng Wang Date: Tue, 24 Jan 2017 20:08:29 +0800 Subject: ata: pata_of_platform: using of_property_read_u32() helper Using better of_property_read_u32() than generic of_get_property(). Cc: Bartlomiej Zolnierkiewicz Cc: Hans de Goede Cc: Tejun Heo Signed-off-by: Kefeng Wang Signed-off-by: Tejun Heo --- drivers/ata/pata_of_platform.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index b6b7af894d9d..201a32d0627f 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c @@ -32,7 +32,6 @@ static int pata_of_platform_probe(struct platform_device *ofdev) unsigned int reg_shift = 0; int pio_mode = 0; int pio_mask; - const u32 *prop; ret = of_address_to_resource(dn, 0, &io_res); if (ret) { @@ -50,13 +49,9 @@ static int pata_of_platform_probe(struct platform_device *ofdev) irq_res = platform_get_resource(ofdev, IORESOURCE_IRQ, 0); - prop = of_get_property(dn, "reg-shift", NULL); - if (prop) - reg_shift = be32_to_cpup(prop); + of_property_read_u32(dn, "reg-shift", ®_shift); - prop = of_get_property(dn, "pio-mode", NULL); - if (prop) { - pio_mode = be32_to_cpup(prop); + if (!of_property_read_u32(dn, "pio-mode", &pio_mode)) { if (pio_mode > 6) { dev_err(&ofdev->dev, "invalid pio-mode\n"); return -EINVAL; -- cgit v1.2.3-59-g8ed1b