From d0b2f91bede3bd5e3d24dd6803e56eee959c1797 Mon Sep 17 00:00:00 2001 From: André Fabian Silva Delgado Date: Thu, 20 Oct 2016 00:10:27 -0300 Subject: Linux-libre 4.8.2-gnu --- drivers/ata/Kconfig | 8 +- drivers/ata/Makefile | 2 +- drivers/ata/ahci.c | 2 +- drivers/ata/ahci_brcm.c | 406 +++++++++++++++++++++++++++++++++++++++++ drivers/ata/libahci.c | 10 +- drivers/ata/libata-core.c | 18 +- drivers/ata/libata-eh.c | 8 +- drivers/ata/libata-scsi.c | 84 +++++---- drivers/ata/libata-transport.c | 9 +- drivers/ata/pata_arasan_cf.c | 2 +- drivers/ata/pata_atiixp.c | 4 +- drivers/ata/pata_hpt366.c | 2 +- drivers/ata/pata_marvell.c | 2 +- drivers/ata/pata_ninja32.c | 2 +- drivers/ata/sata_dwc_460ex.c | 14 +- 15 files changed, 505 insertions(+), 68 deletions(-) create mode 100644 drivers/ata/ahci_brcm.c (limited to 'drivers/ata') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index e2dc4c045..2c8be74f4 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -98,12 +98,12 @@ config SATA_AHCI_PLATFORM If unsure, say N. -config AHCI_BRCMSTB - tristate "Broadcom STB AHCI SATA support" - depends on ARCH_BRCMSTB || BMIPS_GENERIC +config AHCI_BRCM + tristate "Broadcom AHCI SATA support" + depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM_NSP help This option enables support for the AHCI SATA3 controller found on - STB SoC's. + Broadcom SoC's. If unsure, say N. diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 0b2afb7e5..a46e6b784 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o obj-$(CONFIG_SATA_SIL24) += sata_sil24.o obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o -obj-$(CONFIG_AHCI_BRCMSTB) += ahci_brcmstb.o libahci.o libahci_platform.o +obj-$(CONFIG_AHCI_BRCM) += ahci_brcm.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_CEVA) += ahci_ceva.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_DA850) += ahci_da850.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index a83bbcc58..90eabaf81 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -580,7 +580,7 @@ static struct pci_driver ahci_pci_driver = { }, }; -#if defined(CONFIG_PATA_MARVELL) || defined(CONFIG_PATA_MARVELL_MODULE) +#if IS_ENABLED(CONFIG_PATA_MARVELL) static int marvell_enable; #else static int marvell_enable = 1; diff --git a/drivers/ata/ahci_brcm.c b/drivers/ata/ahci_brcm.c new file mode 100644 index 000000000..6f8a7341f --- /dev/null +++ b/drivers/ata/ahci_brcm.c @@ -0,0 +1,406 @@ +/* + * Broadcom SATA3 AHCI Controller Driver + * + * Copyright © 2009-2015 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ahci.h" + +#define DRV_NAME "brcm-ahci" + +#define SATA_TOP_CTRL_VERSION 0x0 +#define SATA_TOP_CTRL_BUS_CTRL 0x4 + #define MMIO_ENDIAN_SHIFT 0 /* CPU->AHCI */ + #define DMADESC_ENDIAN_SHIFT 2 /* AHCI->DDR */ + #define DMADATA_ENDIAN_SHIFT 4 /* AHCI->DDR */ + #define PIODATA_ENDIAN_SHIFT 6 + #define ENDIAN_SWAP_NONE 0 + #define ENDIAN_SWAP_FULL 2 + #define OVERRIDE_HWINIT BIT(16) +#define SATA_TOP_CTRL_TP_CTRL 0x8 +#define SATA_TOP_CTRL_PHY_CTRL 0xc + #define SATA_TOP_CTRL_PHY_CTRL_1 0x0 + #define SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE BIT(14) + #define SATA_TOP_CTRL_PHY_CTRL_2 0x4 + #define SATA_TOP_CTRL_2_SW_RST_MDIOREG BIT(0) + #define SATA_TOP_CTRL_2_SW_RST_OOB BIT(1) + #define SATA_TOP_CTRL_2_SW_RST_RX BIT(2) + #define SATA_TOP_CTRL_2_SW_RST_TX BIT(3) + #define SATA_TOP_CTRL_2_PHY_GLOBAL_RESET BIT(14) + #define SATA_TOP_CTRL_PHY_OFFS 0x8 + #define SATA_TOP_MAX_PHYS 2 + +#define SATA_FIRST_PORT_CTRL 0x700 +#define SATA_NEXT_PORT_CTRL_OFFSET 0x80 +#define SATA_PORT_PCTRL6(reg_base) (reg_base + 0x18) + +/* On big-endian MIPS, buses are reversed to big endian, so switch them back */ +#if defined(CONFIG_MIPS) && defined(__BIG_ENDIAN) +#define DATA_ENDIAN 2 /* AHCI->DDR inbound accesses */ +#define MMIO_ENDIAN 2 /* CPU->AHCI outbound accesses */ +#else +#define DATA_ENDIAN 0 +#define MMIO_ENDIAN 0 +#endif + +#define BUS_CTRL_ENDIAN_CONF \ + ((DATA_ENDIAN << DMADATA_ENDIAN_SHIFT) | \ + (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) | \ + (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT)) + +enum brcm_ahci_version { + BRCM_SATA_BCM7425 = 1, + BRCM_SATA_BCM7445, + BRCM_SATA_NSP, +}; + +enum brcm_ahci_quirks { + BRCM_AHCI_QUIRK_NO_NCQ = BIT(0), + BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(1), +}; + +struct brcm_ahci_priv { + struct device *dev; + void __iomem *top_ctrl; + u32 port_mask; + u32 quirks; + enum brcm_ahci_version version; +}; + +static const struct ata_port_info ahci_brcm_port_info = { + .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM, + .link_flags = ATA_LFLAG_NO_DB_DELAY, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_platform_ops, +}; + +static inline u32 brcm_sata_readreg(void __iomem *addr) +{ + /* + * MIPS endianness is configured by boot strap, which also reverses all + * bus endianness (i.e., big-endian CPU + big endian bus ==> native + * endian I/O). + * + * Other architectures (e.g., ARM) either do not support big endian, or + * else leave I/O in little endian mode. + */ + if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) + return __raw_readl(addr); + else + return readl_relaxed(addr); +} + +static inline void brcm_sata_writereg(u32 val, void __iomem *addr) +{ + /* See brcm_sata_readreg() comments */ + if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) + __raw_writel(val, addr); + else + writel_relaxed(val, addr); +} + +static void brcm_sata_alpm_init(struct ahci_host_priv *hpriv) +{ + struct brcm_ahci_priv *priv = hpriv->plat_data; + u32 bus_ctrl, port_ctrl, host_caps; + int i; + + /* Enable support for ALPM */ + bus_ctrl = brcm_sata_readreg(priv->top_ctrl + + SATA_TOP_CTRL_BUS_CTRL); + brcm_sata_writereg(bus_ctrl | OVERRIDE_HWINIT, + priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL); + host_caps = readl(hpriv->mmio + HOST_CAP); + writel(host_caps | HOST_CAP_ALPM, hpriv->mmio); + brcm_sata_writereg(bus_ctrl, priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL); + + /* + * Adjust timeout to allow PLL sufficient time to lock while waking + * up from slumber mode. + */ + for (i = 0, port_ctrl = SATA_FIRST_PORT_CTRL; + i < SATA_TOP_MAX_PHYS; + i++, port_ctrl += SATA_NEXT_PORT_CTRL_OFFSET) { + if (priv->port_mask & BIT(i)) + writel(0xff1003fc, + hpriv->mmio + SATA_PORT_PCTRL6(port_ctrl)); + } +} + +static void brcm_sata_phy_enable(struct brcm_ahci_priv *priv, int port) +{ + void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL + + (port * SATA_TOP_CTRL_PHY_OFFS); + void __iomem *p; + u32 reg; + + if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE) + return; + + /* clear PHY_DEFAULT_POWER_STATE */ + p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1; + reg = brcm_sata_readreg(p); + reg &= ~SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE; + brcm_sata_writereg(reg, p); + + /* reset the PHY digital logic */ + p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2; + reg = brcm_sata_readreg(p); + reg &= ~(SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB | + SATA_TOP_CTRL_2_SW_RST_RX); + reg |= SATA_TOP_CTRL_2_SW_RST_TX; + brcm_sata_writereg(reg, p); + reg = brcm_sata_readreg(p); + reg |= SATA_TOP_CTRL_2_PHY_GLOBAL_RESET; + brcm_sata_writereg(reg, p); + reg = brcm_sata_readreg(p); + reg &= ~SATA_TOP_CTRL_2_PHY_GLOBAL_RESET; + brcm_sata_writereg(reg, p); + (void)brcm_sata_readreg(p); +} + +static void brcm_sata_phy_disable(struct brcm_ahci_priv *priv, int port) +{ + void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL + + (port * SATA_TOP_CTRL_PHY_OFFS); + void __iomem *p; + u32 reg; + + if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE) + return; + + /* power-off the PHY digital logic */ + p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2; + reg = brcm_sata_readreg(p); + reg |= (SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB | + SATA_TOP_CTRL_2_SW_RST_RX | SATA_TOP_CTRL_2_SW_RST_TX | + SATA_TOP_CTRL_2_PHY_GLOBAL_RESET); + brcm_sata_writereg(reg, p); + + /* set PHY_DEFAULT_POWER_STATE */ + p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1; + reg = brcm_sata_readreg(p); + reg |= SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE; + brcm_sata_writereg(reg, p); +} + +static void brcm_sata_phys_enable(struct brcm_ahci_priv *priv) +{ + int i; + + for (i = 0; i < SATA_TOP_MAX_PHYS; i++) + if (priv->port_mask & BIT(i)) + brcm_sata_phy_enable(priv, i); +} + +static void brcm_sata_phys_disable(struct brcm_ahci_priv *priv) +{ + int i; + + for (i = 0; i < SATA_TOP_MAX_PHYS; i++) + if (priv->port_mask & BIT(i)) + brcm_sata_phy_disable(priv, i); +} + +static u32 brcm_ahci_get_portmask(struct platform_device *pdev, + struct brcm_ahci_priv *priv) +{ + void __iomem *ahci; + struct resource *res; + u32 impl; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ahci"); + ahci = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(ahci)) + return 0; + + impl = readl(ahci + HOST_PORTS_IMPL); + + if (fls(impl) > SATA_TOP_MAX_PHYS) + dev_warn(priv->dev, "warning: more ports than PHYs (%#x)\n", + impl); + else if (!impl) + dev_info(priv->dev, "no ports found\n"); + + devm_iounmap(&pdev->dev, ahci); + devm_release_mem_region(&pdev->dev, res->start, resource_size(res)); + + return impl; +} + +static void brcm_sata_init(struct brcm_ahci_priv *priv) +{ + void __iomem *ctrl = priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL; + + /* Configure endianness */ + if (priv->version == BRCM_SATA_NSP) { + u32 data = brcm_sata_readreg(ctrl); + + data &= ~((0x03 << DMADATA_ENDIAN_SHIFT) | + (0x03 << DMADESC_ENDIAN_SHIFT)); + data |= (0x02 << DMADATA_ENDIAN_SHIFT) | + (0x02 << DMADESC_ENDIAN_SHIFT); + brcm_sata_writereg(data, ctrl); + } else + brcm_sata_writereg(BUS_CTRL_ENDIAN_CONF, ctrl); +} + +#ifdef CONFIG_PM_SLEEP +static int brcm_ahci_suspend(struct device *dev) +{ + struct ata_host *host = dev_get_drvdata(dev); + struct ahci_host_priv *hpriv = host->private_data; + struct brcm_ahci_priv *priv = hpriv->plat_data; + int ret; + + ret = ahci_platform_suspend(dev); + brcm_sata_phys_disable(priv); + return ret; +} + +static int brcm_ahci_resume(struct device *dev) +{ + struct ata_host *host = dev_get_drvdata(dev); + struct ahci_host_priv *hpriv = host->private_data; + struct brcm_ahci_priv *priv = hpriv->plat_data; + + brcm_sata_init(priv); + brcm_sata_phys_enable(priv); + brcm_sata_alpm_init(hpriv); + return ahci_platform_resume(dev); +} +#endif + +static struct scsi_host_template ahci_platform_sht = { + AHCI_SHT(DRV_NAME), +}; + +static const struct of_device_id ahci_of_match[] = { + {.compatible = "brcm,bcm7425-ahci", .data = (void *)BRCM_SATA_BCM7425}, + {.compatible = "brcm,bcm7445-ahci", .data = (void *)BRCM_SATA_BCM7445}, + {.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP}, + {}, +}; +MODULE_DEVICE_TABLE(of, ahci_of_match); + +static int brcm_ahci_probe(struct platform_device *pdev) +{ + const struct of_device_id *of_id; + struct device *dev = &pdev->dev; + struct brcm_ahci_priv *priv; + struct ahci_host_priv *hpriv; + struct resource *res; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + of_id = of_match_node(ahci_of_match, pdev->dev.of_node); + if (!of_id) + return -ENODEV; + + priv->version = (enum brcm_ahci_version)of_id->data; + priv->dev = dev; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl"); + priv->top_ctrl = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->top_ctrl)) + return PTR_ERR(priv->top_ctrl); + + if ((priv->version == BRCM_SATA_BCM7425) || + (priv->version == BRCM_SATA_NSP)) { + priv->quirks |= BRCM_AHCI_QUIRK_NO_NCQ; + priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE; + } + + brcm_sata_init(priv); + + priv->port_mask = brcm_ahci_get_portmask(pdev, priv); + if (!priv->port_mask) + return -ENODEV; + + brcm_sata_phys_enable(priv); + + hpriv = ahci_platform_get_resources(pdev); + if (IS_ERR(hpriv)) + return PTR_ERR(hpriv); + hpriv->plat_data = priv; + hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP; + + brcm_sata_alpm_init(hpriv); + + ret = ahci_platform_enable_resources(hpriv); + if (ret) + return ret; + + if (priv->quirks & BRCM_AHCI_QUIRK_NO_NCQ) + hpriv->flags |= AHCI_HFLAG_NO_NCQ; + + ret = ahci_platform_init_host(pdev, hpriv, &ahci_brcm_port_info, + &ahci_platform_sht); + if (ret) + return ret; + + dev_info(dev, "Broadcom AHCI SATA3 registered\n"); + + return 0; +} + +static int brcm_ahci_remove(struct platform_device *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ahci_host_priv *hpriv = host->private_data; + struct brcm_ahci_priv *priv = hpriv->plat_data; + int ret; + + ret = ata_platform_remove_one(pdev); + if (ret) + return ret; + + brcm_sata_phys_disable(priv); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume); + +static struct platform_driver brcm_ahci_driver = { + .probe = brcm_ahci_probe, + .remove = brcm_ahci_remove, + .driver = { + .name = DRV_NAME, + .of_match_table = ahci_of_match, + .pm = &ahci_brcm_pm_ops, + }, +}; +module_platform_driver(brcm_ahci_driver); + +MODULE_DESCRIPTION("Broadcom SATA3 AHCI Controller Driver"); +MODULE_AUTHOR("Brian Norris"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:sata-brcmstb"); diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index ccd8cc47c..dcf2c724f 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1975,7 +1975,7 @@ unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) */ pp->active_link = qc->dev->link; - if (qc->tf.protocol == ATA_PROT_NCQ) + if (ata_is_ncq(qc->tf.protocol)) writel(1 << qc->tag, port_mmio + PORT_SCR_ACT); if (pp->fbs_enabled && pp->fbs_last_dev != qc->dev->link->pmp) { @@ -2392,12 +2392,20 @@ static int ahci_port_start(struct ata_port *ap) static void ahci_port_stop(struct ata_port *ap) { const char *emsg = NULL; + struct ahci_host_priv *hpriv = ap->host->private_data; + void __iomem *host_mmio = hpriv->mmio; int rc; /* de-initialize port */ rc = ahci_deinit_port(ap, &emsg); if (rc) ata_port_warn(ap, "%s (%d)\n", emsg, rc); + + /* + * Clear GHC.IS to prevent stuck INTx after disabling MSI and + * re-enabling INTx. + */ + writel(1 << ap->port_no, host_mmio + HOST_IRQ_STAT); } void ahci_print_info(struct ata_host *host, const char *scc_s) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 0506c49da..9f8b07029 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -69,6 +69,7 @@ #include #include #include +#include #include #include @@ -1238,7 +1239,7 @@ static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors) } else tf.command = ATA_CMD_READ_NATIVE_MAX; - tf.protocol |= ATA_PROT_NODATA; + tf.protocol = ATA_PROT_NODATA; tf.device |= ATA_LBA; err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); @@ -1297,7 +1298,7 @@ static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors) tf.device |= (new_sectors >> 24) & 0xf; } - tf.protocol |= ATA_PROT_NODATA; + tf.protocol = ATA_PROT_NODATA; tf.device |= ATA_LBA; tf.lbal = (new_sectors >> 0) & 0xff; @@ -4852,7 +4853,7 @@ int ata_std_qc_defer(struct ata_queued_cmd *qc) { struct ata_link *link = qc->dev->link; - if (qc->tf.protocol == ATA_PROT_NCQ) { + if (ata_is_ncq(qc->tf.protocol)) { if (!ata_tag_valid(link->active_tag)) return 0; } else { @@ -5017,7 +5018,7 @@ void __ata_qc_complete(struct ata_queued_cmd *qc) ata_sg_clean(qc); /* command should be marked inactive atomically with qc completion */ - if (qc->tf.protocol == ATA_PROT_NCQ) { + if (ata_is_ncq(qc->tf.protocol)) { link->sactive &= ~(1 << qc->tag); if (!link->sactive) ap->nr_active_links--; @@ -5054,7 +5055,7 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc) { struct ata_device *dev = qc->dev; - if (ata_is_nodata(qc->tf.protocol)) + if (!ata_is_data(qc->tf.protocol)) return; if ((dev->mwdma_mask || dev->udma_mask) && ata_is_pio(qc->tf.protocol)) @@ -5082,6 +5083,9 @@ void ata_qc_complete(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; + /* Trigger the LED (if available) */ + ledtrig_disk_activity(); + /* XXX: New EH and old EH use different mechanisms to * synchronize EH with regular execution path. * @@ -5137,7 +5141,9 @@ void ata_qc_complete(struct ata_queued_cmd *qc) switch (qc->tf.command) { case ATA_CMD_SET_FEATURES: if (qc->tf.feature != SETFEATURES_WC_ON && - qc->tf.feature != SETFEATURES_WC_OFF) + qc->tf.feature != SETFEATURES_WC_OFF && + qc->tf.feature != SETFEATURES_RA_ON && + qc->tf.feature != SETFEATURES_RA_OFF) break; /* fall through */ case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */ diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index c6f017458..0e1ec3707 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2607,9 +2607,13 @@ static void ata_eh_link_report(struct ata_link *link) [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", + [ATA_PROT_NCQ] = "ncq dma", + [ATA_PROT_NCQ_NODATA] = "ncq nodata", + [ATAPI_PROT_NODATA] = "nodata", [ATAPI_PROT_PIO] = "pio", [ATAPI_PROT_DMA] = "dma", }; @@ -3177,7 +3181,7 @@ static void ata_eh_park_issue_cmd(struct ata_device *dev, int park) } tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; - tf.protocol |= ATA_PROT_NODATA; + tf.protocol = ATA_PROT_NODATA; err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); if (park && (err_mask || tf.lbal != 0xc4)) { ata_dev_err(dev, "head unload failed!\n"); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index bfec66fb2..e207b33e4 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -304,7 +304,7 @@ static void ata_scsi_set_invalid_field(struct ata_device *dev, struct scsi_cmnd *cmd, u16 field, u8 bit) { ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x24, 0x0); - /* "Invalid field in cbd" */ + /* "Invalid field in CDB" */ scsi_set_sense_field_pointer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, field, bit, 1); } @@ -1190,7 +1190,7 @@ static int atapi_drain_needed(struct request *rq) if (likely(rq->cmd_type != REQ_TYPE_BLOCK_PC)) return 0; - if (!blk_rq_bytes(rq) || (rq->cmd_flags & REQ_WRITE)) + if (!blk_rq_bytes(rq) || op_is_write(req_op(rq))) return 0; return atapi_cmd_type(rq->cmd[0]) == ATAPI_MISC; @@ -2075,8 +2075,8 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) 0x03, 0x20, /* SBC-2 (no version claimed) */ - 0x02, - 0x60 /* SPC-3 (no version claimed) */ + 0x03, + 0x00 /* SPC-3 (no version claimed) */ }; const u8 versions_zbc[] = { 0x00, @@ -2097,7 +2097,10 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) 0, 0x5, /* claim SPC-3 version compatibility */ 2, - 95 - 4 + 95 - 4, + 0, + 0, + 2 }; VPRINTK("ENTER\n"); @@ -2109,8 +2112,10 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) (args->dev->link->ap->pflags & ATA_PFLAG_EXTERNAL)) hdr[1] |= (1 << 7); - if (args->dev->class == ATA_DEV_ZAC) + if (args->dev->class == ATA_DEV_ZAC) { hdr[0] = TYPE_ZBC; + hdr[2] = 0x7; /* claim SPC-5 version compatibility */ + } memcpy(rbuf, hdr, sizeof(hdr)); memcpy(&rbuf[8], "ATA ", 8); @@ -2314,7 +2319,7 @@ static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf) * with the unmap bit set. */ if (ata_id_has_trim(args->id)) { - put_unaligned_be64(65535 * 512 / 8, &rbuf[36]); + put_unaligned_be64(65535 * ATA_MAX_TRIM_RNUM, &rbuf[36]); put_unaligned_be32(1, &rbuf[28]); } @@ -2424,15 +2429,17 @@ static void modecpy(u8 *dest, const u8 *src, int n, bool changeable) static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable) { modecpy(buf, def_cache_mpage, sizeof(def_cache_mpage), changeable); - if (changeable || ata_id_wcache_enabled(id)) - buf[2] |= (1 << 2); /* write cache enable */ - if (!changeable && !ata_id_rahead_enabled(id)) - buf[12] |= (1 << 5); /* disable read ahead */ + if (changeable) { + buf[2] |= (1 << 2); /* ata_mselect_caching() */ + } else { + buf[2] |= (ata_id_wcache_enabled(id) << 2); /* write cache enable */ + buf[12] |= (!ata_id_rahead_enabled(id) << 5); /* disable read ahead */ + } return sizeof(def_cache_mpage); } /** - * ata_msense_ctl_mode - Simulate MODE SENSE control mode page + * ata_msense_control - Simulate MODE SENSE control mode page * @dev: ATA device of interest * @buf: output buffer * @changeable: whether changeable parameters are requested @@ -2442,12 +2449,17 @@ static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable) * LOCKING: * None. */ -static unsigned int ata_msense_ctl_mode(struct ata_device *dev, u8 *buf, +static unsigned int ata_msense_control(struct ata_device *dev, u8 *buf, bool changeable) { modecpy(buf, def_control_mpage, sizeof(def_control_mpage), changeable); - if (changeable && (dev->flags & ATA_DFLAG_D_SENSE)) - buf[2] |= (1 << 2); /* Descriptor sense requested */ + if (changeable) { + buf[2] |= (1 << 2); /* ata_mselect_control() */ + } else { + bool d_sense = (dev->flags & ATA_DFLAG_D_SENSE); + + buf[2] |= (d_sense << 2); /* descriptor format sense data */ + } return sizeof(def_control_mpage); } @@ -2566,13 +2578,13 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) break; case CONTROL_MPAGE: - p += ata_msense_ctl_mode(args->dev, p, page_control == 1); + p += ata_msense_control(args->dev, p, page_control == 1); break; case ALL_MPAGES: p += ata_msense_rw_recovery(p, page_control == 1); p += ata_msense_caching(args->id, p, page_control == 1); - p += ata_msense_ctl_mode(args->dev, p, page_control == 1); + p += ata_msense_control(args->dev, p, page_control == 1); break; default: /* invalid page code */ @@ -3077,6 +3089,9 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) goto invalid_fld; } + if (ata_is_ncq(tf->protocol) && (cdb[2] & 0x3) == 0) + tf->protocol = ATA_PROT_NCQ_NODATA; + /* enable LBA */ tf->flags |= ATA_TFLAG_LBA; @@ -3125,8 +3140,8 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) tf->command = cdb[9]; } - /* For NCQ commands with FPDMA protocol, copy the tag value */ - if (tf->protocol == ATA_PROT_NCQ) + /* For NCQ commands copy the tag value */ + if (ata_is_ncq(tf->protocol)) tf->nsect = qc->tag << 3; /* enforce correct master/slave bit */ @@ -3305,7 +3320,13 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) goto invalid_param_len; buf = page_address(sg_page(scsi_sglist(scmd))); - size = ata_set_lba_range_entries(buf, 512, block, n_block); + + if (n_block <= 65535 * ATA_MAX_TRIM_RNUM) { + size = ata_set_lba_range_entries(buf, ATA_MAX_TRIM_RNUM, block, n_block); + } else { + fp = 2; + goto invalid_fld; + } if (ata_ncq_enabled(dev) && ata_fpdma_dsm_supported(dev)) { /* Newer devices support queued TRIM commands */ @@ -3454,7 +3475,7 @@ static unsigned int ata_scsi_zbc_in_xlat(struct ata_queued_cmd *qc) goto invalid_param_len; } sect = n_block / 512; - options = cdb[14]; + options = cdb[14] & 0xbf; if (ata_ncq_enabled(qc->dev) && ata_fpdma_zac_mgmt_in_supported(qc->dev)) { @@ -3464,7 +3485,7 @@ static unsigned int ata_scsi_zbc_in_xlat(struct ata_queued_cmd *qc) tf->nsect = qc->tag << 3; tf->feature = sect & 0xff; tf->hob_feature = (sect >> 8) & 0xff; - tf->auxiliary = ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES; + tf->auxiliary = ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES | (options << 8); } else { tf->command = ATA_CMD_ZAC_MGMT_IN; tf->feature = ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES; @@ -3506,7 +3527,7 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc) struct scsi_cmnd *scmd = qc->scsicmd; struct ata_device *dev = qc->dev; const u8 *cdb = scmd->cmnd; - u8 reset_all, sa; + u8 all, sa; u64 block; u32 n_block; u16 fp = (u16)-1; @@ -3533,20 +3554,20 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc) if (block > dev->n_sectors) goto out_of_range; - reset_all = cdb[14] & 0x1; + all = cdb[14] & 0x1; if (ata_ncq_enabled(qc->dev) && ata_fpdma_zac_mgmt_out_supported(qc->dev)) { - tf->protocol = ATA_PROT_NCQ; + tf->protocol = ATA_PROT_NCQ_NODATA; tf->command = ATA_CMD_NCQ_NON_DATA; - tf->hob_nsect = ATA_SUBCMD_NCQ_NON_DATA_ZAC_MGMT_OUT; + tf->feature = ATA_SUBCMD_NCQ_NON_DATA_ZAC_MGMT_OUT; tf->nsect = qc->tag << 3; - tf->auxiliary = sa | (reset_all & 0x1) << 8; + tf->auxiliary = sa | ((u16)all << 8); } else { tf->protocol = ATA_PROT_NODATA; tf->command = ATA_CMD_ZAC_MGMT_OUT; tf->feature = sa; - tf->hob_feature = reset_all & 0x1; + tf->hob_feature = all; } tf->lbah = (block >> 16) & 0xff; tf->lbam = (block >> 8) & 0xff; @@ -3667,7 +3688,7 @@ static int ata_mselect_control(struct ata_queued_cmd *qc, /* * Check that read-only bits are not modified. */ - ata_msense_ctl_mode(dev, mpage, false); + ata_msense_control(dev, mpage, false); for (i = 0; i < CONTROL_MPAGE_LEN - 2; i++) { if (i == 0) continue; @@ -4039,11 +4060,6 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) args.done = cmd->scsi_done; switch(scsicmd[0]) { - /* TODO: worth improving? */ - case FORMAT_UNIT: - ata_scsi_invalid_field(dev, cmd, 0); - break; - case INQUIRY: if (scsicmd[1] & 2) /* is CmdDt set? */ ata_scsi_invalid_field(dev, cmd, 1); diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c index e2d949729..7ef16c085 100644 --- a/drivers/ata/libata-transport.c +++ b/drivers/ata/libata-transport.c @@ -495,12 +495,13 @@ struct ata_show_ering_arg { static int ata_show_ering(struct ata_ering_entry *ent, void *void_arg) { struct ata_show_ering_arg* arg = void_arg; - struct timespec time; + u64 seconds; + u32 rem; - jiffies_to_timespec(ent->timestamp,&time); + seconds = div_u64_rem(ent->timestamp, HZ, &rem); arg->written += sprintf(arg->buf + arg->written, - "[%5lu.%06lu]", - time.tv_sec, time.tv_nsec); + "[%5llu.%09lu]", seconds, + rem * NSEC_PER_SEC / HZ); arg->written += get_ata_err_names(ent->err_mask, arg->buf + arg->written); return 0; diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 80fe0f6fe..b4d54771c 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -565,7 +565,7 @@ chan_request_fail: qc->ap->hsm_task_state = HSM_ST_ERR; cf_ctrl_reset(acdev); - spin_unlock_irqrestore(qc->ap->lock, flags); + spin_unlock_irqrestore(&acdev->host->lock, flags); sff_intr: dma_complete(acdev); } diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 970f7767e..49d705c9f 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -183,8 +183,8 @@ static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev) * We must now look at the PIO mode situation. We may need to * adjust the PIO mode to keep the timings acceptable */ - if (adev->dma_mode >= XFER_MW_DMA_2) - wanted_pio = 4; + if (adev->dma_mode >= XFER_MW_DMA_2) + wanted_pio = 4; else if (adev->dma_mode == XFER_MW_DMA_1) wanted_pio = 3; else if (adev->dma_mode == XFER_MW_DMA_0) diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index e5fb7525a..a219a503c 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -368,7 +368,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* PCI clocking determines the ATA timing values to use */ /* info_hpt366 is safe against re-entry so we can scribble on it */ - switch ((reg1 & 0x700) >> 8) { + switch ((reg1 & 0xf00) >> 8) { case 9: hpriv = &hpt366_40; break; diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index ae9feb1ba..ff468a6fd 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c @@ -146,7 +146,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i if (pdev->device == 0x6101) ppi[1] = &ata_dummy_port_info; -#if defined(CONFIG_SATA_AHCI) || defined(CONFIG_SATA_AHCI_MODULE) +#if IS_ENABLED(CONFIG_SATA_AHCI) if (!marvell_pata_active(pdev)) { printk(KERN_INFO DRV_NAME ": PATA port not active, deferring to AHCI driver.\n"); return -ENODEV; diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c index 633aa2934..44f97ad3c 100644 --- a/drivers/ata/pata_ninja32.c +++ b/drivers/ata/pata_ninja32.c @@ -144,7 +144,7 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id) ap->ioaddr.altstatus_addr = base + 0x1E; ap->ioaddr.bmdma_addr = base; ata_sff_std_ports(&ap->ioaddr); - ap->pflags = ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE; + ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE; ninja32_program(base); /* FIXME: Should we disable them at remove ? */ diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 00c2af1d2..e0939bd5e 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -259,11 +259,8 @@ static int sata_dwc_dma_init_old(struct platform_device *pdev, /* Get physical SATA DMA register base address */ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); hsdev->dma->regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(hsdev->dma->regs)) { - dev_err(&pdev->dev, - "ioremap failed for AHBDMA register address\n"); + if (IS_ERR(hsdev->dma->regs)) return PTR_ERR(hsdev->dma->regs); - } /* Initialize AHB DMAC */ return dw_dma_probe(hsdev->dma); @@ -281,7 +278,7 @@ static void sata_dwc_dma_exit_old(struct sata_dwc_device *hsdev) static const char *get_prot_descript(u8 protocol) { - switch ((enum ata_tf_protocols)protocol) { + switch (protocol) { case ATA_PROT_NODATA: return "ATA no data"; case ATA_PROT_PIO: @@ -290,6 +287,8 @@ static const char *get_prot_descript(u8 protocol) return "ATA DMA"; case ATA_PROT_NCQ: return "ATA NCQ"; + case ATA_PROT_NCQ_NODATA: + return "ATA NCQ no data"; case ATAPI_PROT_NODATA: return "ATAPI no data"; case ATAPI_PROT_PIO: @@ -1225,11 +1224,8 @@ static int sata_dwc_probe(struct platform_device *ofdev) /* Ioremap SATA registers */ res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&ofdev->dev, res); - if (IS_ERR(base)) { - dev_err(&ofdev->dev, - "ioremap failed for SATA register address\n"); + if (IS_ERR(base)) return PTR_ERR(base); - } dev_dbg(&ofdev->dev, "ioremap done for SATA register address\n"); /* Synopsys DWC SATA specific Registers */ -- cgit v1.2.3-54-g00ecf