diff options
Diffstat (limited to 'drivers/ata')
32 files changed, 1201 insertions, 1276 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index b595494ab9b4..e00536b49552 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -118,7 +118,7 @@ config SATA_AHCI config SATA_MOBILE_LPM_POLICY int "Default SATA Link Power Management policy" range 0 4 - default 0 + default 3 depends on SATA_AHCI help Select the Default SATA Link Power Management (LPM) policy to use diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index fc6fd583faf8..45f63b09828a 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1370,7 +1370,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) * V1.03 is known to be broken. V3.04 is known to * work. Between, there are V1.06, V2.06 and V3.03 * that we don't have much idea about. For now, - * blacklist anything older than V3.04. + * assume that anything older than V3.04 is broken. * * http://bugzilla.kernel.org/show_bug.cgi?id=15104 */ @@ -1732,8 +1732,10 @@ static void ahci_update_initial_lpm_policy(struct ata_port *ap) * Management Interaction in AHCI 1.3.1. Therefore, do not enable * LPM if the port advertises itself as an external port. */ - if (ap->pflags & ATA_PFLAG_EXTERNAL) + if (ap->pflags & ATA_PFLAG_EXTERNAL) { + ata_port_dbg(ap, "external port, not enabling LPM\n"); return; + } /* If no LPM states are supported by the HBA, do not bother with LPM */ if ((ap->host->flags & ATA_HOST_NO_PART) && diff --git a/drivers/ata/ahci_brcm.c b/drivers/ata/ahci_brcm.c index 70c3a33eee6f..2f16524c2526 100644 --- a/drivers/ata/ahci_brcm.c +++ b/drivers/ata/ahci_brcm.c @@ -437,7 +437,6 @@ static int brcm_ahci_probe(struct platform_device *pdev) 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); @@ -451,8 +450,7 @@ static int brcm_ahci_probe(struct platform_device *pdev) priv->version = (unsigned long)of_id->data; priv->dev = dev; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl"); - priv->top_ctrl = devm_ioremap_resource(dev, res); + priv->top_ctrl = devm_platform_ioremap_resource_byname(pdev, "top-ctrl"); if (IS_ERR(priv->top_ctrl)) return PTR_ERR(priv->top_ctrl); diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index cb768f66f0a7..6f955e9105e8 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c @@ -19,6 +19,7 @@ #include <linux/libata.h> #include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> +#include <linux/phy/phy.h> #include <linux/thermal.h> #include "ahci.h" @@ -44,42 +45,10 @@ enum { /* Clock Reset Register */ IMX_CLOCK_RESET = 0x7f3f, IMX_CLOCK_RESET_RESET = 1 << 0, - /* IMX8QM HSIO AHCI definitions */ - IMX8QM_SATA_PHY_RX_IMPED_RATIO_OFFSET = 0x03, - IMX8QM_SATA_PHY_TX_IMPED_RATIO_OFFSET = 0x09, - IMX8QM_SATA_PHY_IMPED_RATIO_85OHM = 0x6c, - IMX8QM_LPCG_PHYX2_OFFSET = 0x00000, - IMX8QM_CSR_PHYX2_OFFSET = 0x90000, - IMX8QM_CSR_PHYX1_OFFSET = 0xa0000, - IMX8QM_CSR_PHYX_STTS0_OFFSET = 0x4, - IMX8QM_CSR_PCIEA_OFFSET = 0xb0000, - IMX8QM_CSR_PCIEB_OFFSET = 0xc0000, - IMX8QM_CSR_SATA_OFFSET = 0xd0000, - IMX8QM_CSR_PCIE_CTRL2_OFFSET = 0x8, - IMX8QM_CSR_MISC_OFFSET = 0xe0000, - - IMX8QM_LPCG_PHYX2_PCLK0_MASK = (0x3 << 16), - IMX8QM_LPCG_PHYX2_PCLK1_MASK = (0x3 << 20), - IMX8QM_PHY_APB_RSTN_0 = BIT(0), - IMX8QM_PHY_MODE_SATA = BIT(19), - IMX8QM_PHY_MODE_MASK = (0xf << 17), - IMX8QM_PHY_PIPE_RSTN_0 = BIT(24), - IMX8QM_PHY_PIPE_RSTN_OVERRIDE_0 = BIT(25), - IMX8QM_PHY_PIPE_RSTN_1 = BIT(26), - IMX8QM_PHY_PIPE_RSTN_OVERRIDE_1 = BIT(27), - IMX8QM_STTS0_LANE0_TX_PLL_LOCK = BIT(4), - IMX8QM_MISC_IOB_RXENA = BIT(0), - IMX8QM_MISC_IOB_TXENA = BIT(1), - IMX8QM_MISC_PHYX1_EPCS_SEL = BIT(12), - IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_1 = BIT(24), - IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_0 = BIT(25), - IMX8QM_MISC_CLKREQN_IN_OVERRIDE_1 = BIT(28), - IMX8QM_MISC_CLKREQN_IN_OVERRIDE_0 = BIT(29), - IMX8QM_SATA_CTRL_RESET_N = BIT(12), - IMX8QM_SATA_CTRL_EPCS_PHYRESET_N = BIT(7), - IMX8QM_CTRL_BUTTON_RST_N = BIT(21), - IMX8QM_CTRL_POWER_UP_RST_N = BIT(23), - IMX8QM_CTRL_LTSSM_ENABLE = BIT(4), + /* IMX8QM SATA specific control registers */ + IMX8QM_SATA_AHCI_PTC = 0xc8, + IMX8QM_SATA_AHCI_PTC_RXWM_MASK = GENMASK(6, 0), + IMX8QM_SATA_AHCI_PTC_RXWM = 0x29, }; enum ahci_imx_type { @@ -95,14 +64,10 @@ struct imx_ahci_priv { struct clk *sata_clk; struct clk *sata_ref_clk; struct clk *ahb_clk; - struct clk *epcs_tx_clk; - struct clk *epcs_rx_clk; - struct clk *phy_apbclk; - struct clk *phy_pclk0; - struct clk *phy_pclk1; - void __iomem *phy_base; - struct gpio_desc *clkreq_gpiod; struct regmap *gpr; + struct phy *sata_phy; + struct phy *cali_phy0; + struct phy *cali_phy1; bool no_device; bool first_time; u32 phy_params; @@ -450,201 +415,79 @@ ATTRIBUTE_GROUPS(fsl_sata_ahci); static int imx8_sata_enable(struct ahci_host_priv *hpriv) { - u32 val, reg; - int i, ret; + u32 val; + int ret; struct imx_ahci_priv *imxpriv = hpriv->plat_data; struct device *dev = &imxpriv->ahci_pdev->dev; - /* configure the hsio for sata */ - ret = clk_prepare_enable(imxpriv->phy_pclk0); - if (ret < 0) { - dev_err(dev, "can't enable phy_pclk0.\n"); + /* + * Since "REXT" pin is only present for first lane of i.MX8QM + * PHY, its calibration results will be stored, passed through + * to the second lane PHY, and shared with all three lane PHYs. + * + * Initialize the first two lane PHYs here, although only the + * third lane PHY is used by SATA. + */ + ret = phy_init(imxpriv->cali_phy0); + if (ret) { + dev_err(dev, "cali PHY init failed\n"); return ret; } - ret = clk_prepare_enable(imxpriv->phy_pclk1); - if (ret < 0) { - dev_err(dev, "can't enable phy_pclk1.\n"); - goto disable_phy_pclk0; + ret = phy_power_on(imxpriv->cali_phy0); + if (ret) { + dev_err(dev, "cali PHY power on failed\n"); + goto err_cali_phy0_exit; } - ret = clk_prepare_enable(imxpriv->epcs_tx_clk); - if (ret < 0) { - dev_err(dev, "can't enable epcs_tx_clk.\n"); - goto disable_phy_pclk1; + ret = phy_init(imxpriv->cali_phy1); + if (ret) { + dev_err(dev, "cali PHY1 init failed\n"); + goto err_cali_phy0_off; } - ret = clk_prepare_enable(imxpriv->epcs_rx_clk); - if (ret < 0) { - dev_err(dev, "can't enable epcs_rx_clk.\n"); - goto disable_epcs_tx_clk; + ret = phy_power_on(imxpriv->cali_phy1); + if (ret) { + dev_err(dev, "cali PHY1 power on failed\n"); + goto err_cali_phy1_exit; } - ret = clk_prepare_enable(imxpriv->phy_apbclk); - if (ret < 0) { - dev_err(dev, "can't enable phy_apbclk.\n"); - goto disable_epcs_rx_clk; + ret = phy_init(imxpriv->sata_phy); + if (ret) { + dev_err(dev, "sata PHY init failed\n"); + goto err_cali_phy1_off; } - /* Configure PHYx2 PIPE_RSTN */ - regmap_read(imxpriv->gpr, IMX8QM_CSR_PCIEA_OFFSET + - IMX8QM_CSR_PCIE_CTRL2_OFFSET, &val); - if ((val & IMX8QM_CTRL_LTSSM_ENABLE) == 0) { - /* The link of the PCIEA of HSIO is down */ - regmap_update_bits(imxpriv->gpr, - IMX8QM_CSR_PHYX2_OFFSET, - IMX8QM_PHY_PIPE_RSTN_0 | - IMX8QM_PHY_PIPE_RSTN_OVERRIDE_0, - IMX8QM_PHY_PIPE_RSTN_0 | - IMX8QM_PHY_PIPE_RSTN_OVERRIDE_0); + ret = phy_set_mode(imxpriv->sata_phy, PHY_MODE_SATA); + if (ret) { + dev_err(dev, "unable to set SATA PHY mode\n"); + goto err_sata_phy_exit; } - regmap_read(imxpriv->gpr, IMX8QM_CSR_PCIEB_OFFSET + - IMX8QM_CSR_PCIE_CTRL2_OFFSET, ®); - if ((reg & IMX8QM_CTRL_LTSSM_ENABLE) == 0) { - /* The link of the PCIEB of HSIO is down */ - regmap_update_bits(imxpriv->gpr, - IMX8QM_CSR_PHYX2_OFFSET, - IMX8QM_PHY_PIPE_RSTN_1 | - IMX8QM_PHY_PIPE_RSTN_OVERRIDE_1, - IMX8QM_PHY_PIPE_RSTN_1 | - IMX8QM_PHY_PIPE_RSTN_OVERRIDE_1); + ret = phy_power_on(imxpriv->sata_phy); + if (ret) { + dev_err(dev, "sata PHY power up failed\n"); + goto err_sata_phy_exit; } - if (((reg | val) & IMX8QM_CTRL_LTSSM_ENABLE) == 0) { - /* The links of both PCIA and PCIEB of HSIO are down */ - regmap_update_bits(imxpriv->gpr, - IMX8QM_LPCG_PHYX2_OFFSET, - IMX8QM_LPCG_PHYX2_PCLK0_MASK | - IMX8QM_LPCG_PHYX2_PCLK1_MASK, - 0); - } - - /* set PWR_RST and BT_RST of csr_pciea */ - val = IMX8QM_CSR_PCIEA_OFFSET + IMX8QM_CSR_PCIE_CTRL2_OFFSET; - regmap_update_bits(imxpriv->gpr, - val, - IMX8QM_CTRL_BUTTON_RST_N, - IMX8QM_CTRL_BUTTON_RST_N); - regmap_update_bits(imxpriv->gpr, - val, - IMX8QM_CTRL_POWER_UP_RST_N, - IMX8QM_CTRL_POWER_UP_RST_N); - - /* PHYX1_MODE to SATA */ - regmap_update_bits(imxpriv->gpr, - IMX8QM_CSR_PHYX1_OFFSET, - IMX8QM_PHY_MODE_MASK, - IMX8QM_PHY_MODE_SATA); - /* - * BIT0 RXENA 1, BIT1 TXENA 0 - * BIT12 PHY_X1_EPCS_SEL 1. - */ - regmap_update_bits(imxpriv->gpr, - IMX8QM_CSR_MISC_OFFSET, - IMX8QM_MISC_IOB_RXENA, - IMX8QM_MISC_IOB_RXENA); - regmap_update_bits(imxpriv->gpr, - IMX8QM_CSR_MISC_OFFSET, - IMX8QM_MISC_IOB_TXENA, - 0); - regmap_update_bits(imxpriv->gpr, - IMX8QM_CSR_MISC_OFFSET, - IMX8QM_MISC_PHYX1_EPCS_SEL, - IMX8QM_MISC_PHYX1_EPCS_SEL); - /* - * It is possible, for PCIe and SATA are sharing - * the same clock source, HPLL or external oscillator. - * When PCIe is in low power modes (L1.X or L2 etc), - * the clock source can be turned off. In this case, - * if this clock source is required to be toggling by - * SATA, then SATA functions will be abnormal. - * Set the override here to avoid it. - */ - regmap_update_bits(imxpriv->gpr, - IMX8QM_CSR_MISC_OFFSET, - IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_1 | - IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_0 | - IMX8QM_MISC_CLKREQN_IN_OVERRIDE_1 | - IMX8QM_MISC_CLKREQN_IN_OVERRIDE_0, - IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_1 | - IMX8QM_MISC_CLKREQN_OUT_OVERRIDE_0 | - IMX8QM_MISC_CLKREQN_IN_OVERRIDE_1 | - IMX8QM_MISC_CLKREQN_IN_OVERRIDE_0); - - /* clear PHY RST, then set it */ - regmap_update_bits(imxpriv->gpr, - IMX8QM_CSR_SATA_OFFSET, - IMX8QM_SATA_CTRL_EPCS_PHYRESET_N, - 0); - - regmap_update_bits(imxpriv->gpr, - IMX8QM_CSR_SATA_OFFSET, - IMX8QM_SATA_CTRL_EPCS_PHYRESET_N, - IMX8QM_SATA_CTRL_EPCS_PHYRESET_N); - - /* CTRL RST: SET -> delay 1 us -> CLEAR -> SET */ - regmap_update_bits(imxpriv->gpr, - IMX8QM_CSR_SATA_OFFSET, - IMX8QM_SATA_CTRL_RESET_N, - IMX8QM_SATA_CTRL_RESET_N); - udelay(1); - regmap_update_bits(imxpriv->gpr, - IMX8QM_CSR_SATA_OFFSET, - IMX8QM_SATA_CTRL_RESET_N, - 0); - regmap_update_bits(imxpriv->gpr, - IMX8QM_CSR_SATA_OFFSET, - IMX8QM_SATA_CTRL_RESET_N, - IMX8QM_SATA_CTRL_RESET_N); - - /* APB reset */ - regmap_update_bits(imxpriv->gpr, - IMX8QM_CSR_PHYX1_OFFSET, - IMX8QM_PHY_APB_RSTN_0, - IMX8QM_PHY_APB_RSTN_0); - - for (i = 0; i < 100; i++) { - reg = IMX8QM_CSR_PHYX1_OFFSET + - IMX8QM_CSR_PHYX_STTS0_OFFSET; - regmap_read(imxpriv->gpr, reg, &val); - val &= IMX8QM_STTS0_LANE0_TX_PLL_LOCK; - if (val == IMX8QM_STTS0_LANE0_TX_PLL_LOCK) - break; - udelay(1); - } + /* The cali_phy# can be turned off after SATA PHY is initialized. */ + phy_power_off(imxpriv->cali_phy1); + phy_exit(imxpriv->cali_phy1); + phy_power_off(imxpriv->cali_phy0); + phy_exit(imxpriv->cali_phy0); - if (val != IMX8QM_STTS0_LANE0_TX_PLL_LOCK) { - dev_err(dev, "TX PLL of the PHY is not locked\n"); - ret = -ENODEV; - } else { - writeb(imxpriv->imped_ratio, imxpriv->phy_base + - IMX8QM_SATA_PHY_RX_IMPED_RATIO_OFFSET); - writeb(imxpriv->imped_ratio, imxpriv->phy_base + - IMX8QM_SATA_PHY_TX_IMPED_RATIO_OFFSET); - reg = readb(imxpriv->phy_base + - IMX8QM_SATA_PHY_RX_IMPED_RATIO_OFFSET); - if (unlikely(reg != imxpriv->imped_ratio)) - dev_info(dev, "Can't set PHY RX impedance ratio.\n"); - reg = readb(imxpriv->phy_base + - IMX8QM_SATA_PHY_TX_IMPED_RATIO_OFFSET); - if (unlikely(reg != imxpriv->imped_ratio)) - dev_info(dev, "Can't set PHY TX impedance ratio.\n"); - usleep_range(50, 100); + /* RxWaterMark setting */ + val = readl(hpriv->mmio + IMX8QM_SATA_AHCI_PTC); + val &= ~IMX8QM_SATA_AHCI_PTC_RXWM_MASK; + val |= IMX8QM_SATA_AHCI_PTC_RXWM; + writel(val, hpriv->mmio + IMX8QM_SATA_AHCI_PTC); - /* - * To reduce the power consumption, gate off - * the PHY clks - */ - clk_disable_unprepare(imxpriv->phy_apbclk); - clk_disable_unprepare(imxpriv->phy_pclk1); - clk_disable_unprepare(imxpriv->phy_pclk0); - return ret; - } + return 0; - clk_disable_unprepare(imxpriv->phy_apbclk); -disable_epcs_rx_clk: - clk_disable_unprepare(imxpriv->epcs_rx_clk); -disable_epcs_tx_clk: - clk_disable_unprepare(imxpriv->epcs_tx_clk); -disable_phy_pclk1: - clk_disable_unprepare(imxpriv->phy_pclk1); -disable_phy_pclk0: - clk_disable_unprepare(imxpriv->phy_pclk0); +err_sata_phy_exit: + phy_exit(imxpriv->sata_phy); +err_cali_phy1_off: + phy_power_off(imxpriv->cali_phy1); +err_cali_phy1_exit: + phy_exit(imxpriv->cali_phy1); +err_cali_phy0_off: + phy_power_off(imxpriv->cali_phy0); +err_cali_phy0_exit: + phy_exit(imxpriv->cali_phy0); return ret; } @@ -698,6 +541,9 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv) } } else if (imxpriv->type == AHCI_IMX8QM) { ret = imx8_sata_enable(hpriv); + if (ret) + goto disable_clk; + } usleep_range(1000, 2000); @@ -736,8 +582,10 @@ static void imx_sata_disable(struct ahci_host_priv *hpriv) break; case AHCI_IMX8QM: - clk_disable_unprepare(imxpriv->epcs_rx_clk); - clk_disable_unprepare(imxpriv->epcs_tx_clk); + if (imxpriv->sata_phy) { + phy_power_off(imxpriv->sata_phy); + phy_exit(imxpriv->sata_phy); + } break; default: @@ -760,6 +608,9 @@ static void ahci_imx_error_handler(struct ata_port *ap) ahci_error_handler(ap); + if (imxpriv->type == AHCI_IMX8QM) + return; + if (!(imxpriv->first_time) || ahci_imx_hotplug) return; @@ -986,65 +837,19 @@ static const struct scsi_host_template ahci_platform_sht = { static int imx8_sata_probe(struct device *dev, struct imx_ahci_priv *imxpriv) { - struct resource *phy_res; - struct platform_device *pdev = imxpriv->ahci_pdev; - struct device_node *np = dev->of_node; - - if (of_property_read_u32(np, "fsl,phy-imp", &imxpriv->imped_ratio)) - imxpriv->imped_ratio = IMX8QM_SATA_PHY_IMPED_RATIO_85OHM; - phy_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy"); - if (phy_res) { - imxpriv->phy_base = devm_ioremap(dev, phy_res->start, - resource_size(phy_res)); - if (!imxpriv->phy_base) { - dev_err(dev, "error with ioremap\n"); - return -ENOMEM; - } - } else { - dev_err(dev, "missing *phy* reg region.\n"); - return -ENOMEM; - } - imxpriv->gpr = - syscon_regmap_lookup_by_phandle(np, "hsio"); - if (IS_ERR(imxpriv->gpr)) { - dev_err(dev, "unable to find gpr registers\n"); - return PTR_ERR(imxpriv->gpr); - } - - imxpriv->epcs_tx_clk = devm_clk_get(dev, "epcs_tx"); - if (IS_ERR(imxpriv->epcs_tx_clk)) { - dev_err(dev, "can't get epcs_tx_clk clock.\n"); - return PTR_ERR(imxpriv->epcs_tx_clk); - } - imxpriv->epcs_rx_clk = devm_clk_get(dev, "epcs_rx"); - if (IS_ERR(imxpriv->epcs_rx_clk)) { - dev_err(dev, "can't get epcs_rx_clk clock.\n"); - return PTR_ERR(imxpriv->epcs_rx_clk); - } - imxpriv->phy_pclk0 = devm_clk_get(dev, "phy_pclk0"); - if (IS_ERR(imxpriv->phy_pclk0)) { - dev_err(dev, "can't get phy_pclk0 clock.\n"); - return PTR_ERR(imxpriv->phy_pclk0); - } - imxpriv->phy_pclk1 = devm_clk_get(dev, "phy_pclk1"); - if (IS_ERR(imxpriv->phy_pclk1)) { - dev_err(dev, "can't get phy_pclk1 clock.\n"); - return PTR_ERR(imxpriv->phy_pclk1); - } - imxpriv->phy_apbclk = devm_clk_get(dev, "phy_apbclk"); - if (IS_ERR(imxpriv->phy_apbclk)) { - dev_err(dev, "can't get phy_apbclk clock.\n"); - return PTR_ERR(imxpriv->phy_apbclk); - } - - /* Fetch GPIO, then enable the external OSC */ - imxpriv->clkreq_gpiod = devm_gpiod_get_optional(dev, "clkreq", - GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE); - if (IS_ERR(imxpriv->clkreq_gpiod)) - return PTR_ERR(imxpriv->clkreq_gpiod); - if (imxpriv->clkreq_gpiod) - gpiod_set_consumer_name(imxpriv->clkreq_gpiod, "SATA CLKREQ"); - + imxpriv->sata_phy = devm_phy_get(dev, "sata-phy"); + if (IS_ERR(imxpriv->sata_phy)) + return dev_err_probe(dev, PTR_ERR(imxpriv->sata_phy), + "Failed to get sata_phy\n"); + + imxpriv->cali_phy0 = devm_phy_get(dev, "cali-phy0"); + if (IS_ERR(imxpriv->cali_phy0)) + return dev_err_probe(dev, PTR_ERR(imxpriv->cali_phy0), + "Failed to get cali_phy0\n"); + imxpriv->cali_phy1 = devm_phy_get(dev, "cali-phy1"); + if (IS_ERR(imxpriv->cali_phy1)) + return dev_err_probe(dev, PTR_ERR(imxpriv->cali_phy1), + "Failed to get cali_phy1\n"); return 0; } @@ -1077,12 +882,6 @@ static int imx_ahci_probe(struct platform_device *pdev) return PTR_ERR(imxpriv->sata_ref_clk); } - imxpriv->ahb_clk = devm_clk_get(dev, "ahb"); - if (IS_ERR(imxpriv->ahb_clk)) { - dev_err(dev, "can't get ahb clock.\n"); - return PTR_ERR(imxpriv->ahb_clk); - } - if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) { u32 reg_value; @@ -1142,11 +941,8 @@ static int imx_ahci_probe(struct platform_device *pdev) goto disable_clk; /* - * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL, - * and IP vendor specific register IMX_TIMER1MS. - * Configure CAP_SSS (support stagered spin up). - * Implement the port0. - * Get the ahb clock rate, and configure the TIMER1MS register. + * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL. + * Set CAP_SSS (support stagered spin up) and Implement the port0. */ reg_val = readl(hpriv->mmio + HOST_CAP); if (!(reg_val & HOST_CAP_SSS)) { @@ -1159,8 +955,20 @@ static int imx_ahci_probe(struct platform_device *pdev) writel(reg_val, hpriv->mmio + HOST_PORTS_IMPL); } - reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000; - writel(reg_val, hpriv->mmio + IMX_TIMER1MS); + if (imxpriv->type != AHCI_IMX8QM) { + /* + * Get AHB clock rate and configure the vendor specified + * TIMER1MS register on i.MX53, i.MX6Q and i.MX6QP only. + */ + imxpriv->ahb_clk = devm_clk_get(dev, "ahb"); + if (IS_ERR(imxpriv->ahb_clk)) { + dev_err(dev, "Failed to get ahb clock\n"); + ret = PTR_ERR(imxpriv->ahb_clk); + goto disable_sata; + } + reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000; + writel(reg_val, hpriv->mmio + IMX_TIMER1MS); + } ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, &ahci_platform_sht); @@ -1229,6 +1037,6 @@ static struct platform_driver imx_ahci_driver = { module_platform_driver(imx_ahci_driver); MODULE_DESCRIPTION("Freescale i.MX AHCI SATA platform driver"); -MODULE_AUTHOR("Richard Zhu <Hong-Xing.Zhu@freescale.com>"); +MODULE_AUTHOR("Richard Zhu <hongxing.zhu@nxp.com>"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRV_NAME); diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index ec3c5bd1f813..093b940bc953 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -1446,7 +1446,6 @@ static int piix_init_sidpr(struct ata_host *host) if (hpriv->map[i] == IDE) return 0; - /* is it blacklisted? */ if (piix_no_sidpr(host)) return 0; diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 83431aae74d8..fdfa7b266218 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -2075,13 +2075,6 @@ static void ahci_qc_fill_rtf(struct ata_queued_cmd *qc) struct ahci_port_priv *pp = qc->ap->private_data; u8 *rx_fis = pp->rx_fis; - /* - * rtf may already be filled (e.g. for successful NCQ commands). - * If that is the case, we have nothing to do. - */ - if (qc->flags & ATA_QCFLAG_RTF_FILLED) - return; - if (pp->fbs_enabled) rx_fis += qc->dev->link->pmp * AHCI_RX_FIS_SZ; @@ -2095,7 +2088,6 @@ static void ahci_qc_fill_rtf(struct ata_queued_cmd *qc) !(qc->flags & ATA_QCFLAG_EH)) { ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf); qc->result_tf.status = (rx_fis + RX_FIS_PIO_SETUP)[15]; - qc->flags |= ATA_QCFLAG_RTF_FILLED; return; } @@ -2118,12 +2110,10 @@ static void ahci_qc_fill_rtf(struct ata_queued_cmd *qc) */ qc->result_tf.status = fis[2]; qc->result_tf.error = fis[3]; - qc->flags |= ATA_QCFLAG_RTF_FILLED; return; } ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf); - qc->flags |= ATA_QCFLAG_RTF_FILLED; } static void ahci_qc_ncq_fill_rtf(struct ata_port *ap, u64 done_mask) @@ -2158,6 +2148,7 @@ static void ahci_qc_ncq_fill_rtf(struct ata_port *ap, u64 done_mask) if (qc && ata_is_ncq(qc->tf.protocol)) { qc->result_tf.status = status; qc->result_tf.error = error; + qc->result_tf.flags = qc->tf.flags; qc->flags |= ATA_QCFLAG_RTF_FILLED; } done_mask &= ~(1ULL << tag); @@ -2182,6 +2173,7 @@ static void ahci_qc_ncq_fill_rtf(struct ata_port *ap, u64 done_mask) fis += RX_FIS_SDB; qc->result_tf.status = fis[2]; qc->result_tf.error = fis[3]; + qc->result_tf.flags = qc->tf.flags; qc->flags |= ATA_QCFLAG_RTF_FILLED; } done_mask &= ~(1ULL << tag); diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index 581704e61f28..7a8064520a35 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c @@ -410,7 +410,6 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port, static int ahci_platform_get_firmware(struct ahci_host_priv *hpriv, struct device *dev) { - struct device_node *child; u32 port; if (!of_property_read_u32(dev->of_node, "hba-cap", &hpriv->saved_cap)) @@ -419,14 +418,12 @@ static int ahci_platform_get_firmware(struct ahci_host_priv *hpriv, of_property_read_u32(dev->of_node, "ports-implemented", &hpriv->saved_port_map); - for_each_child_of_node(dev->of_node, child) { + for_each_child_of_node_scoped(dev->of_node, child) { if (!of_device_is_available(child)) continue; - if (of_property_read_u32(child, "reg", &port)) { - of_node_put(child); + if (of_property_read_u32(child, "reg", &port)) return -EINVAL; - } if (!of_property_read_u32(child, "hba-port-cap", &hpriv->saved_port_cap[port])) hpriv->saved_port_cap[port] &= PORT_CMD_CAP; @@ -460,7 +457,6 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev, int child_nodes, rc = -ENOMEM, enabled_ports = 0; struct device *dev = &pdev->dev; struct ahci_host_priv *hpriv; - struct device_node *child; u32 mask_port_map = 0; if (!devres_open_group(dev, NULL, GFP_KERNEL)) @@ -579,7 +575,7 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev, } if (child_nodes) { - for_each_child_of_node(dev->of_node, child) { + for_each_child_of_node_scoped(dev->of_node, child) { u32 port; struct platform_device *port_dev __maybe_unused; @@ -588,7 +584,6 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev, if (of_property_read_u32(child, "reg", &port)) { rc = -EINVAL; - of_node_put(child); goto err_out; } @@ -606,18 +601,14 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev, if (port_dev) { rc = ahci_platform_get_regulator(hpriv, port, &port_dev->dev); - if (rc == -EPROBE_DEFER) { - of_node_put(child); + if (rc == -EPROBE_DEFER) goto err_out; - } } #endif rc = ahci_platform_get_phy(hpriv, port, dev, child); - if (rc) { - of_node_put(child); + if (rc) goto err_out; - } enabled_ports++; } diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 74b59b78d278..c085dd81ebe7 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -50,7 +50,7 @@ #include <scsi/scsi_host.h> #include <linux/libata.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/cdrom.h> #include <linux/ratelimit.h> #include <linux/leds.h> @@ -72,21 +72,13 @@ const struct ata_port_operations ata_base_port_ops = { .end_eh = ata_std_end_eh, }; -const struct ata_port_operations sata_port_ops = { - .inherits = &ata_base_port_ops, - - .qc_defer = ata_std_qc_defer, - .hardreset = sata_std_hardreset, -}; -EXPORT_SYMBOL_GPL(sata_port_ops); - static unsigned int ata_dev_init_params(struct ata_device *dev, u16 heads, u16 sectors); static unsigned int ata_dev_set_xfermode(struct ata_device *dev); static void ata_dev_xfermask(struct ata_device *dev); -static unsigned long ata_dev_blacklisted(const struct ata_device *dev); +static unsigned int ata_dev_quirks(const struct ata_device *dev); -atomic_t ata_print_id = ATOMIC_INIT(0); +static DEFINE_IDA(ata_ida); #ifdef CONFIG_ATA_FORCE struct ata_force_param { @@ -94,8 +86,8 @@ struct ata_force_param { u8 cbl; u8 spd_limit; unsigned int xfer_mask; - unsigned int horkage_on; - unsigned int horkage_off; + unsigned int quirk_on; + unsigned int quirk_off; u16 lflags_on; u16 lflags_off; }; @@ -160,18 +152,13 @@ MODULE_DESCRIPTION("Library module for ATA devices"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); -static inline bool ata_dev_print_info(struct ata_device *dev) +static inline bool ata_dev_print_info(const struct ata_device *dev) { struct ata_eh_context *ehc = &dev->link->eh_context; return ehc->i.flags & ATA_EHI_PRINTINFO; } -static bool ata_sstatus_online(u32 sstatus) -{ - return (sstatus & 0xf) == 0x3; -} - /** * ata_link_next - link iteration helper * @link: the previous link, NULL to start @@ -457,17 +444,17 @@ static void ata_force_xfermask(struct ata_device *dev) } /** - * ata_force_horkage - force horkage according to libata.force + * ata_force_quirks - force quirks according to libata.force * @dev: ATA device of interest * - * Force horkage according to libata.force and whine about it. + * Force quirks according to libata.force and whine about it. * For consistency with link selection, device number 15 selects * the first device connected to the host link. * * LOCKING: * EH context. */ -static void ata_force_horkage(struct ata_device *dev) +static void ata_force_quirks(struct ata_device *dev) { int devno = dev->link->pmp + dev->devno; int alt_devno = devno; @@ -487,21 +474,21 @@ static void ata_force_horkage(struct ata_device *dev) fe->device != alt_devno) continue; - if (!(~dev->horkage & fe->param.horkage_on) && - !(dev->horkage & fe->param.horkage_off)) + if (!(~dev->quirks & fe->param.quirk_on) && + !(dev->quirks & fe->param.quirk_off)) continue; - dev->horkage |= fe->param.horkage_on; - dev->horkage &= ~fe->param.horkage_off; + dev->quirks |= fe->param.quirk_on; + dev->quirks &= ~fe->param.quirk_off; - ata_dev_notice(dev, "FORCE: horkage modified (%s)\n", + ata_dev_notice(dev, "FORCE: modified (%s)\n", fe->param.name); } } #else static inline void ata_force_link_limits(struct ata_link *link) { } static inline void ata_force_xfermask(struct ata_device *dev) { } -static inline void ata_force_horkage(struct ata_device *dev) { } +static inline void ata_force_quirks(struct ata_device *dev) { } #endif /** @@ -1221,7 +1208,7 @@ static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors) *max_sectors = ata_tf_to_lba48(&tf) + 1; else *max_sectors = ata_tf_to_lba(&tf) + 1; - if (dev->horkage & ATA_HORKAGE_HPA_SIZE) + if (dev->quirks & ATA_QUIRK_HPA_SIZE) (*max_sectors)--; return 0; } @@ -1306,7 +1293,7 @@ static int ata_hpa_resize(struct ata_device *dev) /* do we need to do it? */ if ((dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC) || !ata_id_has_lba(dev->id) || !ata_id_hpa_enabled(dev->id) || - (dev->horkage & ATA_HORKAGE_BROKEN_HPA)) + (dev->quirks & ATA_QUIRK_BROKEN_HPA)) return 0; /* read native max address */ @@ -1318,7 +1305,7 @@ static int ata_hpa_resize(struct ata_device *dev) if (rc == -EACCES || !unlock_hpa) { ata_dev_warn(dev, "HPA support seems broken, skipping HPA handling\n"); - dev->horkage |= ATA_HORKAGE_BROKEN_HPA; + dev->quirks |= ATA_QUIRK_BROKEN_HPA; /* we can continue if device aborted the command */ if (rc == -EACCES) @@ -1355,7 +1342,7 @@ static int ata_hpa_resize(struct ata_device *dev) "device aborted resize (%llu -> %llu), skipping HPA handling\n", (unsigned long long)sectors, (unsigned long long)native_sectors); - dev->horkage |= ATA_HORKAGE_BROKEN_HPA; + dev->quirks |= ATA_QUIRK_BROKEN_HPA; return 0; } else if (rc) return rc; @@ -1835,7 +1822,7 @@ retry: goto err_out; } - if (dev->horkage & ATA_HORKAGE_DUMP_ID) { + if (dev->quirks & ATA_QUIRK_DUMP_ID) { ata_dev_info(dev, "dumping IDENTIFY data, " "class=%d may_fallback=%d tried_spinup=%d\n", class, may_fallback, tried_spinup); @@ -2104,7 +2091,7 @@ unsigned int ata_read_log_page(struct ata_device *dev, u8 log, retry: ata_tf_init(dev, &tf); if (ata_dma_enabled(dev) && ata_id_has_read_log_dma_ext(dev->id) && - !(dev->horkage & ATA_HORKAGE_NO_DMA_LOG)) { + !(dev->quirks & ATA_QUIRK_NO_DMA_LOG)) { tf.command = ATA_CMD_READ_LOG_DMA_EXT; tf.protocol = ATA_PROT_DMA; dma = true; @@ -2124,7 +2111,7 @@ retry: if (err_mask) { if (dma) { - dev->horkage |= ATA_HORKAGE_NO_DMA_LOG; + dev->quirks |= ATA_QUIRK_NO_DMA_LOG; if (!ata_port_is_frozen(dev->link->ap)) goto retry; } @@ -2138,22 +2125,19 @@ retry: static int ata_log_supported(struct ata_device *dev, u8 log) { - struct ata_port *ap = dev->link->ap; - - if (dev->horkage & ATA_HORKAGE_NO_LOG_DIR) + if (dev->quirks & ATA_QUIRK_NO_LOG_DIR) return 0; - if (ata_read_log_page(dev, ATA_LOG_DIRECTORY, 0, ap->sector_buf, 1)) + if (ata_read_log_page(dev, ATA_LOG_DIRECTORY, 0, dev->sector_buf, 1)) return 0; - return get_unaligned_le16(&ap->sector_buf[log * 2]); + return get_unaligned_le16(&dev->sector_buf[log * 2]); } static bool ata_identify_page_supported(struct ata_device *dev, u8 page) { - struct ata_port *ap = dev->link->ap; unsigned int err, i; - if (dev->horkage & ATA_HORKAGE_NO_ID_DEV_LOG) + if (dev->quirks & ATA_QUIRK_NO_ID_DEV_LOG) return false; if (!ata_log_supported(dev, ATA_LOG_IDENTIFY_DEVICE)) { @@ -2165,7 +2149,7 @@ static bool ata_identify_page_supported(struct ata_device *dev, u8 page) if (ata_id_major_version(dev->id) >= 10) ata_dev_warn(dev, "ATA Identify Device Log not supported\n"); - dev->horkage |= ATA_HORKAGE_NO_ID_DEV_LOG; + dev->quirks |= ATA_QUIRK_NO_ID_DEV_LOG; return false; } @@ -2173,20 +2157,20 @@ static bool ata_identify_page_supported(struct ata_device *dev, u8 page) * Read IDENTIFY DEVICE data log, page 0, to figure out if the page is * supported. */ - err = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, 0, ap->sector_buf, - 1); + err = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, 0, + dev->sector_buf, 1); if (err) return false; - for (i = 0; i < ap->sector_buf[8]; i++) { - if (ap->sector_buf[9 + i] == page) + for (i = 0; i < dev->sector_buf[8]; i++) { + if (dev->sector_buf[9 + i] == page) return true; } return false; } -static int ata_do_link_spd_horkage(struct ata_device *dev) +static int ata_do_link_spd_quirk(struct ata_device *dev) { struct ata_link *plink = ata_dev_phys_link(dev); u32 target, target_limit; @@ -2194,7 +2178,7 @@ static int ata_do_link_spd_horkage(struct ata_device *dev) if (!sata_scr_valid(plink)) return 0; - if (dev->horkage & ATA_HORKAGE_1_5_GBPS) + if (dev->quirks & ATA_QUIRK_1_5_GBPS) target = 1; else return 0; @@ -2212,26 +2196,25 @@ static int ata_do_link_spd_horkage(struct ata_device *dev) * guaranteed by setting sata_spd_limit to target_limit above. */ if (plink->sata_spd > target) { - ata_dev_info(dev, "applying link speed limit horkage to %s\n", + ata_dev_info(dev, "applying link speed limit quirk to %s\n", sata_spd_string(target)); return -EAGAIN; } return 0; } -static inline u8 ata_dev_knobble(struct ata_device *dev) +static inline bool ata_dev_knobble(struct ata_device *dev) { struct ata_port *ap = dev->link->ap; - if (ata_dev_blacklisted(dev) & ATA_HORKAGE_BRIDGE_OK) - return 0; + if (ata_dev_quirks(dev) & ATA_QUIRK_BRIDGE_OK) + return false; return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id))); } static void ata_dev_config_ncq_send_recv(struct ata_device *dev) { - struct ata_port *ap = dev->link->ap; unsigned int err_mask; if (!ata_log_supported(dev, ATA_LOG_NCQ_SEND_RECV)) { @@ -2239,14 +2222,14 @@ static void ata_dev_config_ncq_send_recv(struct ata_device *dev) return; } err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_SEND_RECV, - 0, ap->sector_buf, 1); + 0, dev->sector_buf, 1); if (!err_mask) { u8 *cmds = dev->ncq_send_recv_cmds; dev->flags |= ATA_DFLAG_NCQ_SEND_RECV; - memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_SEND_RECV_SIZE); + memcpy(cmds, dev->sector_buf, ATA_LOG_NCQ_SEND_RECV_SIZE); - if (dev->horkage & ATA_HORKAGE_NO_NCQ_TRIM) { + if (dev->quirks & ATA_QUIRK_NO_NCQ_TRIM) { ata_dev_dbg(dev, "disabling queued TRIM support\n"); cmds[ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET] &= ~ATA_LOG_NCQ_SEND_RECV_DSM_TRIM; @@ -2256,7 +2239,6 @@ static void ata_dev_config_ncq_send_recv(struct ata_device *dev) static void ata_dev_config_ncq_non_data(struct ata_device *dev) { - struct ata_port *ap = dev->link->ap; unsigned int err_mask; if (!ata_log_supported(dev, ATA_LOG_NCQ_NON_DATA)) { @@ -2265,17 +2247,14 @@ static void ata_dev_config_ncq_non_data(struct ata_device *dev) return; } err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_NON_DATA, - 0, ap->sector_buf, 1); - if (!err_mask) { - u8 *cmds = dev->ncq_non_data_cmds; - - memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_NON_DATA_SIZE); - } + 0, dev->sector_buf, 1); + if (!err_mask) + memcpy(dev->ncq_non_data_cmds, dev->sector_buf, + ATA_LOG_NCQ_NON_DATA_SIZE); } static void ata_dev_config_ncq_prio(struct ata_device *dev) { - struct ata_port *ap = dev->link->ap; unsigned int err_mask; if (!ata_identify_page_supported(dev, ATA_LOG_SATA_SETTINGS)) @@ -2284,12 +2263,11 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev) err_mask = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, ATA_LOG_SATA_SETTINGS, - ap->sector_buf, - 1); + dev->sector_buf, 1); if (err_mask) goto not_supported; - if (!(ap->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3))) + if (!(dev->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3))) goto not_supported; dev->flags |= ATA_DFLAG_NCQ_PRIO; @@ -2334,12 +2312,12 @@ static int ata_dev_config_ncq(struct ata_device *dev, } if (!IS_ENABLED(CONFIG_SATA_HOST)) return 0; - if (dev->horkage & ATA_HORKAGE_NONCQ) { + if (dev->quirks & ATA_QUIRK_NONCQ) { snprintf(desc, desc_sz, "NCQ (not used)"); return 0; } - if (dev->horkage & ATA_HORKAGE_NO_NCQ_ON_ATI && + if (dev->quirks & ATA_QUIRK_NO_NCQ_ON_ATI && ata_dev_check_adapter(dev, PCI_VENDOR_ID_ATI)) { snprintf(desc, desc_sz, "NCQ (not used)"); return 0; @@ -2350,7 +2328,7 @@ static int ata_dev_config_ncq(struct ata_device *dev, dev->flags |= ATA_DFLAG_NCQ; } - if (!(dev->horkage & ATA_HORKAGE_BROKEN_FPDMA_AA) && + if (!(dev->quirks & ATA_QUIRK_BROKEN_FPDMA_AA) && (ap->flags & ATA_FLAG_FPDMA_AA) && ata_id_has_fpdma_aa(dev->id)) { err_mask = ata_dev_set_feature(dev, SETFEATURES_SATA_ENABLE, @@ -2360,7 +2338,7 @@ static int ata_dev_config_ncq(struct ata_device *dev, "failed to enable AA (error_mask=0x%x)\n", err_mask); if (err_mask != AC_ERR_DEV) { - dev->horkage |= ATA_HORKAGE_BROKEN_FPDMA_AA; + dev->quirks |= ATA_QUIRK_BROKEN_FPDMA_AA; return -EIO; } } else @@ -2405,9 +2383,8 @@ static void ata_dev_config_sense_reporting(struct ata_device *dev) static void ata_dev_config_zac(struct ata_device *dev) { - struct ata_port *ap = dev->link->ap; unsigned int err_mask; - u8 *identify_buf = ap->sector_buf; + u8 *identify_buf = dev->sector_buf; dev->zac_zones_optimal_open = U32_MAX; dev->zac_zones_optimal_nonseq = U32_MAX; @@ -2459,7 +2436,6 @@ static void ata_dev_config_zac(struct ata_device *dev) static void ata_dev_config_trusted(struct ata_device *dev) { - struct ata_port *ap = dev->link->ap; u64 trusted_cap; unsigned int err; @@ -2473,11 +2449,11 @@ static void ata_dev_config_trusted(struct ata_device *dev) } err = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, ATA_LOG_SECURITY, - ap->sector_buf, 1); + dev->sector_buf, 1); if (err) return; - trusted_cap = get_unaligned_le64(&ap->sector_buf[40]); + trusted_cap = get_unaligned_le64(&dev->sector_buf[40]); if (!(trusted_cap & (1ULL << 63))) { ata_dev_dbg(dev, "Trusted Computing capability qword not valid!\n"); @@ -2488,12 +2464,41 @@ static void ata_dev_config_trusted(struct ata_device *dev) dev->flags |= ATA_DFLAG_TRUSTED; } +void ata_dev_cleanup_cdl_resources(struct ata_device *dev) +{ + kfree(dev->cdl); + dev->cdl = NULL; +} + +static int ata_dev_init_cdl_resources(struct ata_device *dev) +{ + struct ata_cdl *cdl = dev->cdl; + unsigned int err_mask; + + if (!cdl) { + cdl = kzalloc(sizeof(*cdl), GFP_KERNEL); + if (!cdl) + return -ENOMEM; + dev->cdl = cdl; + } + + err_mask = ata_read_log_page(dev, ATA_LOG_CDL, 0, cdl->desc_log_buf, + ATA_LOG_CDL_SIZE / ATA_SECT_SIZE); + if (err_mask) { + ata_dev_warn(dev, "Read Command Duration Limits log failed\n"); + ata_dev_cleanup_cdl_resources(dev); + return -EIO; + } + + return 0; +} + static void ata_dev_config_cdl(struct ata_device *dev) { - struct ata_port *ap = dev->link->ap; unsigned int err_mask; bool cdl_enabled; u64 val; + int ret; if (ata_id_major_version(dev->id) < 11) goto not_supported; @@ -2505,12 +2510,12 @@ static void ata_dev_config_cdl(struct ata_device *dev) err_mask = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, ATA_LOG_SUPPORTED_CAPABILITIES, - ap->sector_buf, 1); + dev->sector_buf, 1); if (err_mask) goto not_supported; /* Check Command Duration Limit Supported bits */ - val = get_unaligned_le64(&ap->sector_buf[168]); + val = get_unaligned_le64(&dev->sector_buf[168]); if (!(val & BIT_ULL(63)) || !(val & BIT_ULL(0))) goto not_supported; @@ -2523,7 +2528,7 @@ static void ata_dev_config_cdl(struct ata_device *dev) * We must have support for the sense data for successful NCQ commands * log indicated by the successful NCQ command sense data supported bit. */ - val = get_unaligned_le64(&ap->sector_buf[8]); + val = get_unaligned_le64(&dev->sector_buf[8]); if (!(val & BIT_ULL(63)) || !(val & BIT_ULL(47))) { ata_dev_warn(dev, "CDL supported but Successful NCQ Command Sense Data is not supported\n"); @@ -2543,11 +2548,11 @@ static void ata_dev_config_cdl(struct ata_device *dev) */ err_mask = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, ATA_LOG_CURRENT_SETTINGS, - ap->sector_buf, 1); + dev->sector_buf, 1); if (err_mask) goto not_supported; - val = get_unaligned_le64(&ap->sector_buf[8]); + val = get_unaligned_le64(&dev->sector_buf[8]); cdl_enabled = val & BIT_ULL(63) && val & BIT_ULL(21); if (dev->flags & ATA_DFLAG_CDL_ENABLED) { if (!cdl_enabled) { @@ -2588,37 +2593,20 @@ static void ata_dev_config_cdl(struct ata_device *dev) } } - /* - * Allocate a buffer to handle reading the sense data for successful - * NCQ Commands log page for commands using a CDL with one of the limit - * policy set to 0xD (successful completion with sense data available - * bit set). - */ - if (!ap->ncq_sense_buf) { - ap->ncq_sense_buf = kmalloc(ATA_LOG_SENSE_NCQ_SIZE, GFP_KERNEL); - if (!ap->ncq_sense_buf) - goto not_supported; - } - - /* - * Command duration limits is supported: cache the CDL log page 18h - * (command duration descriptors). - */ - err_mask = ata_read_log_page(dev, ATA_LOG_CDL, 0, ap->sector_buf, 1); - if (err_mask) { - ata_dev_warn(dev, "Read Command Duration Limits log failed\n"); + /* CDL is supported: allocate and initialize needed resources. */ + ret = ata_dev_init_cdl_resources(dev); + if (ret) { + ata_dev_warn(dev, "Initialize CDL resources failed\n"); goto not_supported; } - memcpy(dev->cdl, ap->sector_buf, ATA_LOG_CDL_SIZE); dev->flags |= ATA_DFLAG_CDL; return; not_supported: dev->flags &= ~(ATA_DFLAG_CDL | ATA_DFLAG_CDL_ENABLED); - kfree(ap->ncq_sense_buf); - ap->ncq_sense_buf = NULL; + ata_dev_cleanup_cdl_resources(dev); } static int ata_dev_config_lba(struct ata_device *dev) @@ -2689,7 +2677,7 @@ static void ata_dev_config_fua(struct ata_device *dev) goto nofua; /* Ignore known bad devices and devices that lack NCQ support */ - if (!ata_ncq_supported(dev) || (dev->horkage & ATA_HORKAGE_NO_FUA)) + if (!ata_ncq_supported(dev) || (dev->quirks & ATA_QUIRK_NO_FUA)) goto nofua; dev->flags |= ATA_DFLAG_FUA; @@ -2702,7 +2690,7 @@ nofua: static void ata_dev_config_devslp(struct ata_device *dev) { - u8 *sata_setting = dev->link->ap->sector_buf; + u8 *sata_setting = dev->sector_buf; unsigned int err_mask; int i, j; @@ -2829,11 +2817,11 @@ int ata_dev_configure(struct ata_device *dev) return 0; } - /* set horkage */ - dev->horkage |= ata_dev_blacklisted(dev); - ata_force_horkage(dev); + /* Set quirks */ + dev->quirks |= ata_dev_quirks(dev); + ata_force_quirks(dev); - if (dev->horkage & ATA_HORKAGE_DISABLE) { + if (dev->quirks & ATA_QUIRK_DISABLE) { ata_dev_info(dev, "unsupported device, disabling\n"); ata_dev_disable(dev); return 0; @@ -2848,19 +2836,19 @@ int ata_dev_configure(struct ata_device *dev) return 0; } - rc = ata_do_link_spd_horkage(dev); + rc = ata_do_link_spd_quirk(dev); if (rc) return rc; /* some WD SATA-1 drives have issues with LPM, turn on NOLPM for them */ - if ((dev->horkage & ATA_HORKAGE_WD_BROKEN_LPM) && + if ((dev->quirks & ATA_QUIRK_WD_BROKEN_LPM) && (id[ATA_ID_SATA_CAPABILITY] & 0xe) == 0x2) - dev->horkage |= ATA_HORKAGE_NOLPM; + dev->quirks |= ATA_QUIRK_NOLPM; if (ap->flags & ATA_FLAG_NO_LPM) - dev->horkage |= ATA_HORKAGE_NOLPM; + dev->quirks |= ATA_QUIRK_NOLPM; - if (dev->horkage & ATA_HORKAGE_NOLPM) { + if (dev->quirks & ATA_QUIRK_NOLPM) { ata_dev_warn(dev, "LPM support broken, forcing max_power\n"); dev->link->ap->target_lpm_policy = ATA_LPM_MAX_POWER; } @@ -3006,7 +2994,8 @@ int ata_dev_configure(struct ata_device *dev) cdb_intr_string = ", CDB intr"; } - if (atapi_dmadir || (dev->horkage & ATA_HORKAGE_ATAPI_DMADIR) || atapi_id_dmadir(dev->id)) { + if (atapi_dmadir || (dev->quirks & ATA_QUIRK_ATAPI_DMADIR) || + atapi_id_dmadir(dev->id)) { dev->flags |= ATA_DFLAG_DMADIR; dma_dir_string = ", DMADIR"; } @@ -3043,24 +3032,24 @@ int ata_dev_configure(struct ata_device *dev) if ((dev->class == ATA_DEV_ATAPI) && (atapi_command_packet_set(id) == TYPE_TAPE)) { dev->max_sectors = ATA_MAX_SECTORS_TAPE; - dev->horkage |= ATA_HORKAGE_STUCK_ERR; + dev->quirks |= ATA_QUIRK_STUCK_ERR; } - if (dev->horkage & ATA_HORKAGE_MAX_SEC_128) + if (dev->quirks & ATA_QUIRK_MAX_SEC_128) dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128, dev->max_sectors); - if (dev->horkage & ATA_HORKAGE_MAX_SEC_1024) + if (dev->quirks & ATA_QUIRK_MAX_SEC_1024) dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_1024, dev->max_sectors); - if (dev->horkage & ATA_HORKAGE_MAX_SEC_LBA48) + if (dev->quirks & ATA_QUIRK_MAX_SEC_LBA48) dev->max_sectors = ATA_MAX_SECTORS_LBA48; if (ap->ops->dev_config) ap->ops->dev_config(dev); - if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) { + if (dev->quirks & ATA_QUIRK_DIAGNOSTIC) { /* Let the user know. We don't want to disallow opens for rescue purposes, or in case the vendor is just a blithering idiot. Do this after the dev_config call as some controllers @@ -3075,7 +3064,7 @@ int ata_dev_configure(struct ata_device *dev) } } - if ((dev->horkage & ATA_HORKAGE_FIRMWARE_WARN) && print_info) { + if ((dev->quirks & ATA_QUIRK_FIRMWARE_WARN) && print_info) { ata_dev_warn(dev, "WARNING: device requires firmware update to be fully functional\n"); ata_dev_warn(dev, " contact the vendor or visit http://ata.wiki.kernel.org\n"); } @@ -3199,86 +3188,6 @@ struct ata_device *ata_dev_pair(struct ata_device *adev) } EXPORT_SYMBOL_GPL(ata_dev_pair); -/** - * sata_down_spd_limit - adjust SATA spd limit downward - * @link: Link to adjust SATA spd limit for - * @spd_limit: Additional limit - * - * Adjust SATA spd limit of @link downward. Note that this - * function only adjusts the limit. The change must be applied - * using sata_set_spd(). - * - * If @spd_limit is non-zero, the speed is limited to equal to or - * lower than @spd_limit if such speed is supported. If - * @spd_limit is slower than any supported speed, only the lowest - * supported speed is allowed. - * - * LOCKING: - * Inherited from caller. - * - * RETURNS: - * 0 on success, negative errno on failure - */ -int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) -{ - u32 sstatus, spd, mask; - int rc, bit; - - if (!sata_scr_valid(link)) - return -EOPNOTSUPP; - - /* If SCR can be read, use it to determine the current SPD. - * If not, use cached value in link->sata_spd. - */ - rc = sata_scr_read(link, SCR_STATUS, &sstatus); - if (rc == 0 && ata_sstatus_online(sstatus)) - spd = (sstatus >> 4) & 0xf; - else - spd = link->sata_spd; - - mask = link->sata_spd_limit; - if (mask <= 1) - return -EINVAL; - - /* unconditionally mask off the highest bit */ - bit = fls(mask) - 1; - mask &= ~(1 << bit); - - /* - * Mask off all speeds higher than or equal to the current one. At - * this point, if current SPD is not available and we previously - * recorded the link speed from SStatus, the driver has already - * masked off the highest bit so mask should already be 1 or 0. - * Otherwise, we should not force 1.5Gbps on a link where we have - * not previously recorded speed from SStatus. Just return in this - * case. - */ - if (spd > 1) - mask &= (1 << (spd - 1)) - 1; - else if (link->sata_spd) - return -EINVAL; - - /* were we already at the bottom? */ - if (!mask) - return -EINVAL; - - if (spd_limit) { - if (mask & ((1 << spd_limit) - 1)) - mask &= (1 << spd_limit) - 1; - else { - bit = ffs(mask) - 1; - mask = 1 << bit; - } - } - - link->sata_spd_limit = mask; - - ata_link_warn(link, "limiting SATA link speed to %s\n", - sata_spd_string(fls(mask))); - - return 0; -} - #ifdef CONFIG_ATA_ACPI /** * ata_timing_cycle2mode - find xfer mode for the specified cycle duration @@ -3425,7 +3334,7 @@ static int ata_dev_set_mode(struct ata_device *dev) { struct ata_port *ap = dev->link->ap; struct ata_eh_context *ehc = &dev->link->eh_context; - const bool nosetxfer = dev->horkage & ATA_HORKAGE_NOSETXFER; + const bool nosetxfer = dev->quirks & ATA_QUIRK_NOSETXFER; const char *dev_err_whine = ""; int ign_dev_err = 0; unsigned int err_mask = 0; @@ -3761,33 +3670,6 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline) EXPORT_SYMBOL_GPL(ata_std_prereset); /** - * sata_std_hardreset - COMRESET w/o waiting or classification - * @link: link to reset - * @class: resulting class of attached device - * @deadline: deadline jiffies for the operation - * - * Standard SATA COMRESET w/o waiting or classification. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 if link offline, -EAGAIN if link online, -errno on errors. - */ -int sata_std_hardreset(struct ata_link *link, unsigned int *class, - unsigned long deadline) -{ - const unsigned int *timing = sata_ehc_deb_timing(&link->eh_context); - bool online; - int rc; - - /* do hardreset */ - rc = sata_link_hardreset(link, timing, deadline, &online, NULL); - return online ? -EAGAIN : rc; -} -EXPORT_SYMBOL_GPL(sata_std_hardreset); - -/** * ata_std_postreset - standard postreset callback * @link: the target ata_link * @classes: classes of attached devices @@ -3878,7 +3760,7 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags) { unsigned int class = dev->class; - u16 *id = (void *)dev->link->ap->sector_buf; + u16 *id = (void *)dev->sector_buf; int rc; /* read ID data */ @@ -3969,7 +3851,7 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, */ if (dev->n_native_sectors == n_native_sectors && dev->n_sectors < n_sectors && n_sectors == n_native_sectors && - !(dev->horkage & ATA_HORKAGE_BROKEN_HPA)) { + !(dev->quirks & ATA_QUIRK_BROKEN_HPA)) { ata_dev_warn(dev, "old n_sectors matches native, probably " "late HPA lock, will try to unlock HPA\n"); @@ -3987,223 +3869,292 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, return rc; } -struct ata_blacklist_entry { +static const char * const ata_quirk_names[] = { + [__ATA_QUIRK_DIAGNOSTIC] = "diagnostic", + [__ATA_QUIRK_NODMA] = "nodma", + [__ATA_QUIRK_NONCQ] = "noncq", + [__ATA_QUIRK_MAX_SEC_128] = "maxsec128", + [__ATA_QUIRK_BROKEN_HPA] = "brokenhpa", + [__ATA_QUIRK_DISABLE] = "disable", + [__ATA_QUIRK_HPA_SIZE] = "hpasize", + [__ATA_QUIRK_IVB] = "ivb", + [__ATA_QUIRK_STUCK_ERR] = "stuckerr", + [__ATA_QUIRK_BRIDGE_OK] = "bridgeok", + [__ATA_QUIRK_ATAPI_MOD16_DMA] = "atapimod16dma", + [__ATA_QUIRK_FIRMWARE_WARN] = "firmwarewarn", + [__ATA_QUIRK_1_5_GBPS] = "1.5gbps", + [__ATA_QUIRK_NOSETXFER] = "nosetxfer", + [__ATA_QUIRK_BROKEN_FPDMA_AA] = "brokenfpdmaaa", + [__ATA_QUIRK_DUMP_ID] = "dumpid", + [__ATA_QUIRK_MAX_SEC_LBA48] = "maxseclba48", + [__ATA_QUIRK_ATAPI_DMADIR] = "atapidmadir", + [__ATA_QUIRK_NO_NCQ_TRIM] = "noncqtrim", + [__ATA_QUIRK_NOLPM] = "nolpm", + [__ATA_QUIRK_WD_BROKEN_LPM] = "wdbrokenlpm", + [__ATA_QUIRK_ZERO_AFTER_TRIM] = "zeroaftertrim", + [__ATA_QUIRK_NO_DMA_LOG] = "nodmalog", + [__ATA_QUIRK_NOTRIM] = "notrim", + [__ATA_QUIRK_MAX_SEC_1024] = "maxsec1024", + [__ATA_QUIRK_MAX_TRIM_128M] = "maxtrim128m", + [__ATA_QUIRK_NO_NCQ_ON_ATI] = "noncqonati", + [__ATA_QUIRK_NO_ID_DEV_LOG] = "noiddevlog", + [__ATA_QUIRK_NO_LOG_DIR] = "nologdir", + [__ATA_QUIRK_NO_FUA] = "nofua", +}; + +static void ata_dev_print_quirks(const struct ata_device *dev, + const char *model, const char *rev, + unsigned int quirks) +{ + struct ata_eh_context *ehc = &dev->link->eh_context; + int n = 0, i; + size_t sz; + char *str; + + if (!ata_dev_print_info(dev) || ehc->i.flags & ATA_EHI_DID_PRINT_QUIRKS) + return; + + ehc->i.flags |= ATA_EHI_DID_PRINT_QUIRKS; + + if (!quirks) + return; + + sz = 64 + ARRAY_SIZE(ata_quirk_names) * 16; + str = kmalloc(sz, GFP_KERNEL); + if (!str) + return; + + n = snprintf(str, sz, "Model '%s', rev '%s', applying quirks:", + model, rev); + + for (i = 0; i < ARRAY_SIZE(ata_quirk_names); i++) { + if (quirks & (1U << i)) + n += snprintf(str + n, sz - n, + " %s", ata_quirk_names[i]); + } + + ata_dev_warn(dev, "%s\n", str); + + kfree(str); +} + +struct ata_dev_quirks_entry { const char *model_num; const char *model_rev; - unsigned long horkage; + unsigned int quirks; }; -static const struct ata_blacklist_entry ata_device_blacklist [] = { +static const struct ata_dev_quirks_entry __ata_dev_quirks[] = { /* Devices with DMA related problems under Linux */ - { "WDC AC11000H", NULL, ATA_HORKAGE_NODMA }, - { "WDC AC22100H", NULL, ATA_HORKAGE_NODMA }, - { "WDC AC32500H", NULL, ATA_HORKAGE_NODMA }, - { "WDC AC33100H", NULL, ATA_HORKAGE_NODMA }, - { "WDC AC31600H", NULL, ATA_HORKAGE_NODMA }, - { "WDC AC32100H", "24.09P07", ATA_HORKAGE_NODMA }, - { "WDC AC23200L", "21.10N21", ATA_HORKAGE_NODMA }, - { "Compaq CRD-8241B", NULL, ATA_HORKAGE_NODMA }, - { "CRD-8400B", NULL, ATA_HORKAGE_NODMA }, - { "CRD-848[02]B", NULL, ATA_HORKAGE_NODMA }, - { "CRD-84", NULL, ATA_HORKAGE_NODMA }, - { "SanDisk SDP3B", NULL, ATA_HORKAGE_NODMA }, - { "SanDisk SDP3B-64", NULL, ATA_HORKAGE_NODMA }, - { "SANYO CD-ROM CRD", NULL, ATA_HORKAGE_NODMA }, - { "HITACHI CDR-8", NULL, ATA_HORKAGE_NODMA }, - { "HITACHI CDR-8[34]35",NULL, ATA_HORKAGE_NODMA }, - { "Toshiba CD-ROM XM-6202B", NULL, ATA_HORKAGE_NODMA }, - { "TOSHIBA CD-ROM XM-1702BC", NULL, ATA_HORKAGE_NODMA }, - { "CD-532E-A", NULL, ATA_HORKAGE_NODMA }, - { "E-IDE CD-ROM CR-840",NULL, ATA_HORKAGE_NODMA }, - { "CD-ROM Drive/F5A", NULL, ATA_HORKAGE_NODMA }, - { "WPI CDD-820", NULL, ATA_HORKAGE_NODMA }, - { "SAMSUNG CD-ROM SC-148C", NULL, ATA_HORKAGE_NODMA }, - { "SAMSUNG CD-ROM SC", NULL, ATA_HORKAGE_NODMA }, - { "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,ATA_HORKAGE_NODMA }, - { "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA }, - { "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA }, - { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA }, - { " 2GB ATA Flash Disk", "ADMA428M", ATA_HORKAGE_NODMA }, - { "VRFDFC22048UCHC-TE*", NULL, ATA_HORKAGE_NODMA }, + { "WDC AC11000H", NULL, ATA_QUIRK_NODMA }, + { "WDC AC22100H", NULL, ATA_QUIRK_NODMA }, + { "WDC AC32500H", NULL, ATA_QUIRK_NODMA }, + { "WDC AC33100H", NULL, ATA_QUIRK_NODMA }, + { "WDC AC31600H", NULL, ATA_QUIRK_NODMA }, + { "WDC AC32100H", "24.09P07", ATA_QUIRK_NODMA }, + { "WDC AC23200L", "21.10N21", ATA_QUIRK_NODMA }, + { "Compaq CRD-8241B", NULL, ATA_QUIRK_NODMA }, + { "CRD-8400B", NULL, ATA_QUIRK_NODMA }, + { "CRD-848[02]B", NULL, ATA_QUIRK_NODMA }, + { "CRD-84", NULL, ATA_QUIRK_NODMA }, + { "SanDisk SDP3B", NULL, ATA_QUIRK_NODMA }, + { "SanDisk SDP3B-64", NULL, ATA_QUIRK_NODMA }, + { "SANYO CD-ROM CRD", NULL, ATA_QUIRK_NODMA }, + { "HITACHI CDR-8", NULL, ATA_QUIRK_NODMA }, + { "HITACHI CDR-8[34]35", NULL, ATA_QUIRK_NODMA }, + { "Toshiba CD-ROM XM-6202B", NULL, ATA_QUIRK_NODMA }, + { "TOSHIBA CD-ROM XM-1702BC", NULL, ATA_QUIRK_NODMA }, + { "CD-532E-A", NULL, ATA_QUIRK_NODMA }, + { "E-IDE CD-ROM CR-840", NULL, ATA_QUIRK_NODMA }, + { "CD-ROM Drive/F5A", NULL, ATA_QUIRK_NODMA }, + { "WPI CDD-820", NULL, ATA_QUIRK_NODMA }, + { "SAMSUNG CD-ROM SC-148C", NULL, ATA_QUIRK_NODMA }, + { "SAMSUNG CD-ROM SC", NULL, ATA_QUIRK_NODMA }, + { "ATAPI CD-ROM DRIVE 40X MAXIMUM", NULL, ATA_QUIRK_NODMA }, + { "_NEC DV5800A", NULL, ATA_QUIRK_NODMA }, + { "SAMSUNG CD-ROM SN-124", "N001", ATA_QUIRK_NODMA }, + { "Seagate STT20000A", NULL, ATA_QUIRK_NODMA }, + { " 2GB ATA Flash Disk", "ADMA428M", ATA_QUIRK_NODMA }, + { "VRFDFC22048UCHC-TE*", NULL, ATA_QUIRK_NODMA }, /* Odd clown on sil3726/4726 PMPs */ - { "Config Disk", NULL, ATA_HORKAGE_DISABLE }, + { "Config Disk", NULL, ATA_QUIRK_DISABLE }, /* Similar story with ASMedia 1092 */ - { "ASMT109x- Config", NULL, ATA_HORKAGE_DISABLE }, + { "ASMT109x- Config", NULL, ATA_QUIRK_DISABLE }, /* Weird ATAPI devices */ - { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, - { "QUANTUM DAT DAT72-000", NULL, ATA_HORKAGE_ATAPI_MOD16_DMA }, - { "Slimtype DVD A DS8A8SH", NULL, ATA_HORKAGE_MAX_SEC_LBA48 }, - { "Slimtype DVD A DS8A9SH", NULL, ATA_HORKAGE_MAX_SEC_LBA48 }, + { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_QUIRK_MAX_SEC_128 }, + { "QUANTUM DAT DAT72-000", NULL, ATA_QUIRK_ATAPI_MOD16_DMA }, + { "Slimtype DVD A DS8A8SH", NULL, ATA_QUIRK_MAX_SEC_LBA48 }, + { "Slimtype DVD A DS8A9SH", NULL, ATA_QUIRK_MAX_SEC_LBA48 }, /* * Causes silent data corruption with higher max sects. * http://lkml.kernel.org/g/x49wpy40ysk.fsf@segfault.boston.devel.redhat.com */ - { "ST380013AS", "3.20", ATA_HORKAGE_MAX_SEC_1024 }, + { "ST380013AS", "3.20", ATA_QUIRK_MAX_SEC_1024 }, /* * These devices time out with higher max sects. * https://bugzilla.kernel.org/show_bug.cgi?id=121671 */ - { "LITEON CX1-JB*-HP", NULL, ATA_HORKAGE_MAX_SEC_1024 }, - { "LITEON EP1-*", NULL, ATA_HORKAGE_MAX_SEC_1024 }, + { "LITEON CX1-JB*-HP", NULL, ATA_QUIRK_MAX_SEC_1024 }, + { "LITEON EP1-*", NULL, ATA_QUIRK_MAX_SEC_1024 }, /* Devices we expect to fail diagnostics */ /* Devices where NCQ should be avoided */ /* NCQ is slow */ - { "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ }, - { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ }, + { "WDC WD740ADFD-00", NULL, ATA_QUIRK_NONCQ }, + { "WDC WD740ADFD-00NLR1", NULL, ATA_QUIRK_NONCQ }, /* http://thread.gmane.org/gmane.linux.ide/14907 */ - { "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ }, + { "FUJITSU MHT2060BH", NULL, ATA_QUIRK_NONCQ }, /* NCQ is broken */ - { "Maxtor *", "BANC*", ATA_HORKAGE_NONCQ }, - { "Maxtor 7V300F0", "VA111630", ATA_HORKAGE_NONCQ }, - { "ST380817AS", "3.42", ATA_HORKAGE_NONCQ }, - { "ST3160023AS", "3.42", ATA_HORKAGE_NONCQ }, - { "OCZ CORE_SSD", "02.10104", ATA_HORKAGE_NONCQ }, + { "Maxtor *", "BANC*", ATA_QUIRK_NONCQ }, + { "Maxtor 7V300F0", "VA111630", ATA_QUIRK_NONCQ }, + { "ST380817AS", "3.42", ATA_QUIRK_NONCQ }, + { "ST3160023AS", "3.42", ATA_QUIRK_NONCQ }, + { "OCZ CORE_SSD", "02.10104", ATA_QUIRK_NONCQ }, /* Seagate NCQ + FLUSH CACHE firmware bug */ - { "ST31500341AS", "SD1[5-9]", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, + { "ST31500341AS", "SD1[5-9]", ATA_QUIRK_NONCQ | + ATA_QUIRK_FIRMWARE_WARN }, - { "ST31000333AS", "SD1[5-9]", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, + { "ST31000333AS", "SD1[5-9]", ATA_QUIRK_NONCQ | + ATA_QUIRK_FIRMWARE_WARN }, - { "ST3640[36]23AS", "SD1[5-9]", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, + { "ST3640[36]23AS", "SD1[5-9]", ATA_QUIRK_NONCQ | + ATA_QUIRK_FIRMWARE_WARN }, - { "ST3320[68]13AS", "SD1[5-9]", ATA_HORKAGE_NONCQ | - ATA_HORKAGE_FIRMWARE_WARN }, + { "ST3320[68]13AS", "SD1[5-9]", ATA_QUIRK_NONCQ | + ATA_QUIRK_FIRMWARE_WARN }, /* drives which fail FPDMA_AA activation (some may freeze afterwards) the ST disks also have LPM issues */ - { "ST1000LM024 HN-M101MBB", NULL, ATA_HORKAGE_BROKEN_FPDMA_AA | - ATA_HORKAGE_NOLPM }, - { "VB0250EAVER", "HPG7", ATA_HORKAGE_BROKEN_FPDMA_AA }, + { "ST1000LM024 HN-M101MBB", NULL, ATA_QUIRK_BROKEN_FPDMA_AA | + ATA_QUIRK_NOLPM }, + { "VB0250EAVER", "HPG7", ATA_QUIRK_BROKEN_FPDMA_AA }, /* Blacklist entries taken from Silicon Image 3124/3132 Windows driver .inf file - also several Linux problem reports */ - { "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ }, - { "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ }, - { "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ }, + { "HTS541060G9SA00", "MB3OC60D", ATA_QUIRK_NONCQ }, + { "HTS541080G9SA00", "MB4OC60D", ATA_QUIRK_NONCQ }, + { "HTS541010G9SA00", "MBZOC60D", ATA_QUIRK_NONCQ }, /* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */ - { "C300-CTFDDAC128MAG", "0001", ATA_HORKAGE_NONCQ }, + { "C300-CTFDDAC128MAG", "0001", ATA_QUIRK_NONCQ }, /* Sandisk SD7/8/9s lock up hard on large trims */ - { "SanDisk SD[789]*", NULL, ATA_HORKAGE_MAX_TRIM_128M }, + { "SanDisk SD[789]*", NULL, ATA_QUIRK_MAX_TRIM_128M }, /* devices which puke on READ_NATIVE_MAX */ - { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA }, - { "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA }, - { "WDC WD2500JD-00HBB0", "WD-WMAL71490727", ATA_HORKAGE_BROKEN_HPA }, - { "MAXTOR 6L080L4", "A93.0500", ATA_HORKAGE_BROKEN_HPA }, + { "HDS724040KLSA80", "KFAOA20N", ATA_QUIRK_BROKEN_HPA }, + { "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_QUIRK_BROKEN_HPA }, + { "WDC WD2500JD-00HBB0", "WD-WMAL71490727", ATA_QUIRK_BROKEN_HPA }, + { "MAXTOR 6L080L4", "A93.0500", ATA_QUIRK_BROKEN_HPA }, /* this one allows HPA unlocking but fails IOs on the area */ - { "OCZ-VERTEX", "1.30", ATA_HORKAGE_BROKEN_HPA }, + { "OCZ-VERTEX", "1.30", ATA_QUIRK_BROKEN_HPA }, /* Devices which report 1 sector over size HPA */ - { "ST340823A", NULL, ATA_HORKAGE_HPA_SIZE }, - { "ST320413A", NULL, ATA_HORKAGE_HPA_SIZE }, - { "ST310211A", NULL, ATA_HORKAGE_HPA_SIZE }, + { "ST340823A", NULL, ATA_QUIRK_HPA_SIZE }, + { "ST320413A", NULL, ATA_QUIRK_HPA_SIZE }, + { "ST310211A", NULL, ATA_QUIRK_HPA_SIZE }, /* Devices which get the IVB wrong */ - { "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_HORKAGE_IVB }, - /* Maybe we should just blacklist TSSTcorp... */ - { "TSSTcorp CDDVDW SH-S202[HJN]", "SB0[01]", ATA_HORKAGE_IVB }, + { "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_QUIRK_IVB }, + /* Maybe we should just add all TSSTcorp devices... */ + { "TSSTcorp CDDVDW SH-S202[HJN]", "SB0[01]", ATA_QUIRK_IVB }, /* Devices that do not need bridging limits applied */ - { "MTRON MSP-SATA*", NULL, ATA_HORKAGE_BRIDGE_OK }, - { "BUFFALO HD-QSU2/R5", NULL, ATA_HORKAGE_BRIDGE_OK }, + { "MTRON MSP-SATA*", NULL, ATA_QUIRK_BRIDGE_OK }, + { "BUFFALO HD-QSU2/R5", NULL, ATA_QUIRK_BRIDGE_OK }, /* Devices which aren't very happy with higher link speeds */ - { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS }, - { "Seagate FreeAgent GoFlex", NULL, ATA_HORKAGE_1_5_GBPS }, + { "WD My Book", NULL, ATA_QUIRK_1_5_GBPS }, + { "Seagate FreeAgent GoFlex", NULL, ATA_QUIRK_1_5_GBPS }, /* * Devices which choke on SETXFER. Applies only if both the * device and controller are SATA. */ - { "PIONEER DVD-RW DVRTD08", NULL, ATA_HORKAGE_NOSETXFER }, - { "PIONEER DVD-RW DVRTD08A", NULL, ATA_HORKAGE_NOSETXFER }, - { "PIONEER DVD-RW DVR-215", NULL, ATA_HORKAGE_NOSETXFER }, - { "PIONEER DVD-RW DVR-212D", NULL, ATA_HORKAGE_NOSETXFER }, - { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, + { "PIONEER DVD-RW DVRTD08", NULL, ATA_QUIRK_NOSETXFER }, + { "PIONEER DVD-RW DVRTD08A", NULL, ATA_QUIRK_NOSETXFER }, + { "PIONEER DVD-RW DVR-215", NULL, ATA_QUIRK_NOSETXFER }, + { "PIONEER DVD-RW DVR-212D", NULL, ATA_QUIRK_NOSETXFER }, + { "PIONEER DVD-RW DVR-216D", NULL, ATA_QUIRK_NOSETXFER }, /* These specific Pioneer models have LPM issues */ - { "PIONEER BD-RW BDR-207M", NULL, ATA_HORKAGE_NOLPM }, - { "PIONEER BD-RW BDR-205", NULL, ATA_HORKAGE_NOLPM }, + { "PIONEER BD-RW BDR-207M", NULL, ATA_QUIRK_NOLPM }, + { "PIONEER BD-RW BDR-205", NULL, ATA_QUIRK_NOLPM }, /* Crucial devices with broken LPM support */ - { "CT*0BX*00SSD1", NULL, ATA_HORKAGE_NOLPM }, + { "CT*0BX*00SSD1", NULL, ATA_QUIRK_NOLPM }, /* 512GB MX100 with MU01 firmware has both queued TRIM and LPM issues */ - { "Crucial_CT512MX100*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM | - ATA_HORKAGE_NOLPM }, + { "Crucial_CT512MX100*", "MU01", ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM | + ATA_QUIRK_NOLPM }, /* 512GB MX100 with newer firmware has only LPM issues */ - { "Crucial_CT512MX100*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM | - ATA_HORKAGE_NOLPM }, + { "Crucial_CT512MX100*", NULL, ATA_QUIRK_ZERO_AFTER_TRIM | + ATA_QUIRK_NOLPM }, /* 480GB+ M500 SSDs have both queued TRIM and LPM issues */ - { "Crucial_CT480M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM | - ATA_HORKAGE_NOLPM }, - { "Crucial_CT960M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM | - ATA_HORKAGE_NOLPM }, + { "Crucial_CT480M500*", NULL, ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM | + ATA_QUIRK_NOLPM }, + { "Crucial_CT960M500*", NULL, ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM | + ATA_QUIRK_NOLPM }, /* AMD Radeon devices with broken LPM support */ - { "R3SL240G", NULL, ATA_HORKAGE_NOLPM }, + { "R3SL240G", NULL, ATA_QUIRK_NOLPM }, /* Apacer models with LPM issues */ - { "Apacer AS340*", NULL, ATA_HORKAGE_NOLPM }, + { "Apacer AS340*", NULL, ATA_QUIRK_NOLPM }, /* These specific Samsung models/firmware-revs do not handle LPM well */ - { "SAMSUNG MZMPC128HBFU-000MV", "CXM14M1Q", ATA_HORKAGE_NOLPM }, - { "SAMSUNG SSD PM830 mSATA *", "CXM13D1Q", ATA_HORKAGE_NOLPM }, - { "SAMSUNG MZ7TD256HAFV-000L9", NULL, ATA_HORKAGE_NOLPM }, - { "SAMSUNG MZ7TE512HMHP-000L1", "EXT06L0Q", ATA_HORKAGE_NOLPM }, + { "SAMSUNG MZMPC128HBFU-000MV", "CXM14M1Q", ATA_QUIRK_NOLPM }, + { "SAMSUNG SSD PM830 mSATA *", "CXM13D1Q", ATA_QUIRK_NOLPM }, + { "SAMSUNG MZ7TD256HAFV-000L9", NULL, ATA_QUIRK_NOLPM }, + { "SAMSUNG MZ7TE512HMHP-000L1", "EXT06L0Q", ATA_QUIRK_NOLPM }, /* devices that don't properly handle queued TRIM commands */ - { "Micron_M500IT_*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "Micron_M500_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "Micron_M5[15]0_*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "Micron_1100_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM, }, - { "Crucial_CT*M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "Crucial_CT*M550*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "Crucial_CT*MX100*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "Samsung SSD 840 EVO*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_NO_DMA_LOG | - ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "Samsung SSD 840*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "Samsung SSD 850*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "Samsung SSD 860*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM | - ATA_HORKAGE_NO_NCQ_ON_ATI }, - { "Samsung SSD 870*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM | - ATA_HORKAGE_NO_NCQ_ON_ATI }, - { "SAMSUNG*MZ7LH*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM | - ATA_HORKAGE_NO_NCQ_ON_ATI, }, - { "FCCT*M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | - ATA_HORKAGE_ZERO_AFTER_TRIM }, + { "Micron_M500IT_*", "MU01", ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM }, + { "Micron_M500_*", NULL, ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM }, + { "Micron_M5[15]0_*", "MU01", ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM }, + { "Micron_1100_*", NULL, ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM, }, + { "Crucial_CT*M500*", NULL, ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM }, + { "Crucial_CT*M550*", "MU01", ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM }, + { "Crucial_CT*MX100*", "MU01", ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM }, + { "Samsung SSD 840 EVO*", NULL, ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_NO_DMA_LOG | + ATA_QUIRK_ZERO_AFTER_TRIM }, + { "Samsung SSD 840*", NULL, ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM }, + { "Samsung SSD 850*", NULL, ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM }, + { "Samsung SSD 860*", NULL, ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM | + ATA_QUIRK_NO_NCQ_ON_ATI }, + { "Samsung SSD 870*", NULL, ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM | + ATA_QUIRK_NO_NCQ_ON_ATI }, + { "SAMSUNG*MZ7LH*", NULL, ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM | + ATA_QUIRK_NO_NCQ_ON_ATI, }, + { "FCCT*M500*", NULL, ATA_QUIRK_NO_NCQ_TRIM | + ATA_QUIRK_ZERO_AFTER_TRIM }, /* devices that don't properly handle TRIM commands */ - { "SuperSSpeed S238*", NULL, ATA_HORKAGE_NOTRIM }, - { "M88V29*", NULL, ATA_HORKAGE_NOTRIM }, + { "SuperSSpeed S238*", NULL, ATA_QUIRK_NOTRIM }, + { "M88V29*", NULL, ATA_QUIRK_NOTRIM }, /* * As defined, the DRAT (Deterministic Read After Trim) and RZAT @@ -4223,14 +4174,14 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { */ { "INTEL*SSDSC2MH*", NULL, 0 }, - { "Micron*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "Crucial*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "INTEL*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "SSD*INTEL*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "Samsung*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "SAMSUNG*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "SAMSUNG*MZ7KM*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM }, - { "ST[1248][0248]0[FH]*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM }, + { "Micron*", NULL, ATA_QUIRK_ZERO_AFTER_TRIM }, + { "Crucial*", NULL, ATA_QUIRK_ZERO_AFTER_TRIM }, + { "INTEL*SSD*", NULL, ATA_QUIRK_ZERO_AFTER_TRIM }, + { "SSD*INTEL*", NULL, ATA_QUIRK_ZERO_AFTER_TRIM }, + { "Samsung*SSD*", NULL, ATA_QUIRK_ZERO_AFTER_TRIM }, + { "SAMSUNG*SSD*", NULL, ATA_QUIRK_ZERO_AFTER_TRIM }, + { "SAMSUNG*MZ7KM*", NULL, ATA_QUIRK_ZERO_AFTER_TRIM }, + { "ST[1248][0248]0[FH]*", NULL, ATA_QUIRK_ZERO_AFTER_TRIM }, /* * Some WD SATA-I drives spin up and down erratically when the link @@ -4241,62 +4192,66 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { * * https://bugzilla.kernel.org/show_bug.cgi?id=57211 */ - { "WDC WD800JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM }, - { "WDC WD1200JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM }, - { "WDC WD1600JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM }, - { "WDC WD2000JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM }, - { "WDC WD2500JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM }, - { "WDC WD3000JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM }, - { "WDC WD3200JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM }, + { "WDC WD800JD-*", NULL, ATA_QUIRK_WD_BROKEN_LPM }, + { "WDC WD1200JD-*", NULL, ATA_QUIRK_WD_BROKEN_LPM }, + { "WDC WD1600JD-*", NULL, ATA_QUIRK_WD_BROKEN_LPM }, + { "WDC WD2000JD-*", NULL, ATA_QUIRK_WD_BROKEN_LPM }, + { "WDC WD2500JD-*", NULL, ATA_QUIRK_WD_BROKEN_LPM }, + { "WDC WD3000JD-*", NULL, ATA_QUIRK_WD_BROKEN_LPM }, + { "WDC WD3200JD-*", NULL, ATA_QUIRK_WD_BROKEN_LPM }, /* * This sata dom device goes on a walkabout when the ATA_LOG_DIRECTORY * log page is accessed. Ensure we never ask for this log page with * these devices. */ - { "SATADOM-ML 3ME", NULL, ATA_HORKAGE_NO_LOG_DIR }, + { "SATADOM-ML 3ME", NULL, ATA_QUIRK_NO_LOG_DIR }, /* Buggy FUA */ - { "Maxtor", "BANC1G10", ATA_HORKAGE_NO_FUA }, - { "WDC*WD2500J*", NULL, ATA_HORKAGE_NO_FUA }, - { "OCZ-VERTEX*", NULL, ATA_HORKAGE_NO_FUA }, - { "INTEL*SSDSC2CT*", NULL, ATA_HORKAGE_NO_FUA }, + { "Maxtor", "BANC1G10", ATA_QUIRK_NO_FUA }, + { "WDC*WD2500J*", NULL, ATA_QUIRK_NO_FUA }, + { "OCZ-VERTEX*", NULL, ATA_QUIRK_NO_FUA }, + { "INTEL*SSDSC2CT*", NULL, ATA_QUIRK_NO_FUA }, /* End Marker */ { } }; -static unsigned long ata_dev_blacklisted(const struct ata_device *dev) +static unsigned int ata_dev_quirks(const struct ata_device *dev) { unsigned char model_num[ATA_ID_PROD_LEN + 1]; unsigned char model_rev[ATA_ID_FW_REV_LEN + 1]; - const struct ata_blacklist_entry *ad = ata_device_blacklist; + const struct ata_dev_quirks_entry *ad = __ata_dev_quirks; + + /* dev->quirks is an unsigned int. */ + BUILD_BUG_ON(__ATA_QUIRK_MAX > 32); ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num)); ata_id_c_string(dev->id, model_rev, ATA_ID_FW_REV, sizeof(model_rev)); while (ad->model_num) { - if (glob_match(ad->model_num, model_num)) { - if (ad->model_rev == NULL) - return ad->horkage; - if (glob_match(ad->model_rev, model_rev)) - return ad->horkage; + if (glob_match(ad->model_num, model_num) && + (!ad->model_rev || glob_match(ad->model_rev, model_rev))) { + ata_dev_print_quirks(dev, model_num, model_rev, + ad->quirks); + return ad->quirks; } ad++; } return 0; } -static int ata_dma_blacklisted(const struct ata_device *dev) +static bool ata_dev_nodma(const struct ata_device *dev) { - /* We don't support polling DMA. - * DMA blacklist those ATAPI devices with CDB-intr (and use PIO) - * if the LLDD handles only interrupts in the HSM_ST_LAST state. + /* + * We do not support polling DMA. Deny DMA for those ATAPI devices + * with CDB-intr (and use PIO) if the LLDD handles only interrupts in + * the HSM_ST_LAST state. */ if ((dev->link->ap->flags & ATA_FLAG_PIO_POLLING) && (dev->flags & ATA_DFLAG_CDB_INTR)) - return 1; - return (dev->horkage & ATA_HORKAGE_NODMA) ? 1 : 0; + return true; + return dev->quirks & ATA_QUIRK_NODMA; } /** @@ -4309,7 +4264,7 @@ static int ata_dma_blacklisted(const struct ata_device *dev) static int ata_is_40wire(struct ata_device *dev) { - if (dev->horkage & ATA_HORKAGE_IVB) + if (dev->quirks & ATA_QUIRK_IVB) return ata_drive_40wire_relaxed(dev->id); return ata_drive_40wire(dev->id); } @@ -4371,8 +4326,7 @@ static int cable_is_40wire(struct ata_port *ap) * * Compute supported xfermask of @dev and store it in * dev->*_mask. This function is responsible for applying all - * known limits including host controller limits, device - * blacklist, etc... + * known limits including host controller limits, device quirks, etc... * * LOCKING: * None. @@ -4404,10 +4358,10 @@ static void ata_dev_xfermask(struct ata_device *dev) xfer_mask &= ~(0x03 << (ATA_SHIFT_MWDMA + 3)); } - if (ata_dma_blacklisted(dev)) { + if (ata_dev_nodma(dev)) { xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); ata_dev_warn(dev, - "device is on DMA blacklist, disabling DMA\n"); + "device does not support DMA, disabling DMA\n"); } if ((host->flags & ATA_HOST_SIMPLEX) && @@ -4588,7 +4542,7 @@ int atapi_check_dma(struct ata_queued_cmd *qc) /* Don't allow DMA if it isn't multiple of 16 bytes. Quite a * few ATAPI devices choke on such DMA requests. */ - if (!(qc->dev->horkage & ATA_HORKAGE_ATAPI_MOD16_DMA) && + if (!(qc->dev->quirks & ATA_QUIRK_ATAPI_MOD16_DMA) && unlikely(qc->nbytes & 15)) return 1; @@ -4629,12 +4583,6 @@ int ata_std_qc_defer(struct ata_queued_cmd *qc) } EXPORT_SYMBOL_GPL(ata_std_qc_defer); -enum ata_completion_errors ata_noop_qc_prep(struct ata_queued_cmd *qc) -{ - return AC_ERR_OK; -} -EXPORT_SYMBOL_GPL(ata_noop_qc_prep); - /** * ata_sg_init - Associate command with scatter-gather table. * @qc: Command to be associated @@ -4762,8 +4710,9 @@ void __ata_qc_complete(struct ata_queued_cmd *qc) struct ata_port *ap; struct ata_link *link; - WARN_ON_ONCE(qc == NULL); /* ata_qc_from_tag _might_ return NULL */ - WARN_ON_ONCE(!(qc->flags & ATA_QCFLAG_ACTIVE)); + if (WARN_ON_ONCE(!(qc->flags & ATA_QCFLAG_ACTIVE))) + return; + ap = qc->ap; link = qc->dev->link; @@ -4785,9 +4734,10 @@ void __ata_qc_complete(struct ata_queued_cmd *qc) ap->excl_link == link)) ap->excl_link = NULL; - /* atapi: mark qc as inactive to prevent the interrupt handler - * from completing the command twice later, before the error handler - * is called. (when rc != 0 and atapi request sense is needed) + /* + * Mark qc as inactive to prevent the port interrupt handler from + * completing the command twice later, before the error handler is + * called. */ qc->flags &= ~ATA_QCFLAG_ACTIVE; ap->qc_active &= ~(1ULL << qc->tag); @@ -4800,8 +4750,16 @@ static void fill_result_tf(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; + /* + * rtf may already be filled (e.g. for successful NCQ commands). + * If that is the case, we have nothing to do. + */ + if (qc->flags & ATA_QCFLAG_RTF_FILLED) + return; + qc->result_tf.flags = qc->tf.flags; ap->ops->qc_fill_rtf(qc); + qc->flags |= ATA_QCFLAG_RTF_FILLED; } static void ata_verify_xfer(struct ata_queued_cmd *qc) @@ -5013,10 +4971,13 @@ void ata_qc_issue(struct ata_queued_cmd *qc) return; } - trace_ata_qc_prep(qc); - qc->err_mask |= ap->ops->qc_prep(qc); - if (unlikely(qc->err_mask)) - goto err; + if (ap->ops->qc_prep) { + trace_ata_qc_prep(qc); + qc->err_mask |= ap->ops->qc_prep(qc); + if (unlikely(qc->err_mask)) + goto err; + } + trace_ata_qc_issue(qc); qc->err_mask |= ap->ops->qc_issue(qc); if (unlikely(qc->err_mask)) @@ -5360,7 +5321,7 @@ void ata_dev_init(struct ata_device *dev) */ spin_lock_irqsave(ap->lock, flags); dev->flags &= ~ATA_DFLAG_INIT_MASK; - dev->horkage = 0; + dev->quirks = 0; spin_unlock_irqrestore(ap->lock, flags); memset((void *)dev + ATA_DEVICE_CLEAR_BEGIN, 0, @@ -5455,6 +5416,7 @@ int sata_link_init_spd(struct ata_link *link) struct ata_port *ata_port_alloc(struct ata_host *host) { struct ata_port *ap; + int id; ap = kzalloc(sizeof(*ap), GFP_KERNEL); if (!ap) @@ -5462,8 +5424,12 @@ struct ata_port *ata_port_alloc(struct ata_host *host) ap->pflags |= ATA_PFLAG_INITIALIZING | ATA_PFLAG_FROZEN; ap->lock = &host->lock; - ap->print_id = -1; - ap->local_port_no = -1; + id = ida_alloc_min(&ata_ida, 1, GFP_KERNEL); + if (id < 0) { + kfree(ap); + return NULL; + } + ap->print_id = id; ap->host = host; ap->dev = host->dev; @@ -5488,6 +5454,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host) return ap; } +EXPORT_SYMBOL_GPL(ata_port_alloc); void ata_port_free(struct ata_port *ap) { @@ -5496,7 +5463,7 @@ void ata_port_free(struct ata_port *ap) kfree(ap->pmp_link); kfree(ap->slave_link); - kfree(ap->ncq_sense_buf); + ida_free(&ata_ida, ap->print_id); kfree(ap); } EXPORT_SYMBOL_GPL(ata_port_free); @@ -5547,24 +5514,19 @@ EXPORT_SYMBOL_GPL(ata_host_put); /** * ata_host_alloc - allocate and init basic ATA host resources * @dev: generic device this host is associated with - * @max_ports: maximum number of ATA ports associated with this host + * @n_ports: the number of ATA ports associated with this host * * Allocate and initialize basic ATA host resources. LLD calls * this function to allocate a host, initializes it fully and * attaches it using ata_host_register(). * - * @max_ports ports are allocated and host->n_ports is - * initialized to @max_ports. The caller is allowed to decrease - * host->n_ports before calling ata_host_register(). The unused - * ports will be automatically freed on registration. - * * RETURNS: * Allocate ATA host on success, NULL on failure. * * LOCKING: * Inherited from calling layer (may sleep). */ -struct ata_host *ata_host_alloc(struct device *dev, int max_ports) +struct ata_host *ata_host_alloc(struct device *dev, int n_ports) { struct ata_host *host; size_t sz; @@ -5572,7 +5534,7 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports) void *dr; /* alloc a container for our list of ATA ports (buses) */ - sz = sizeof(struct ata_host) + (max_ports + 1) * sizeof(void *); + sz = sizeof(struct ata_host) + n_ports * sizeof(void *); host = kzalloc(sz, GFP_KERNEL); if (!host) return NULL; @@ -5583,8 +5545,10 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports) } dr = devres_alloc(ata_devres_release, 0, GFP_KERNEL); - if (!dr) + if (!dr) { + kfree(host); goto err_out; + } devres_add(dev, dr); dev_set_drvdata(dev, host); @@ -5592,11 +5556,11 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports) spin_lock_init(&host->lock); mutex_init(&host->eh_mutex); host->dev = dev; - host->n_ports = max_ports; + host->n_ports = n_ports; kref_init(&host->kref); /* allocate ports bound to this host */ - for (i = 0; i < max_ports; i++) { + for (i = 0; i < n_ports; i++) { struct ata_port *ap; ap = ata_port_alloc(host); @@ -5905,19 +5869,6 @@ int ata_host_register(struct ata_host *host, const struct scsi_host_template *sh return -EINVAL; } - /* Blow away unused ports. This happens when LLD can't - * determine the exact number of ports to allocate at - * allocation time. - */ - for (i = host->n_ports; host->ports[i]; i++) - ata_port_free(host->ports[i]); - - /* give ports names and add SCSI hosts */ - for (i = 0; i < host->n_ports; i++) { - host->ports[i]->print_id = atomic_inc_return(&ata_print_id); - host->ports[i]->local_port_no = i + 1; - } - /* Create associated sysfs transport objects */ for (i = 0; i < host->n_ports; i++) { rc = ata_tport_add(host->dev,host->ports[i]); @@ -6039,6 +5990,23 @@ int ata_host_activate(struct ata_host *host, int irq, EXPORT_SYMBOL_GPL(ata_host_activate); /** + * ata_dev_free_resources - Free a device resources + * @dev: Target ATA device + * + * Free resources allocated to support a device features. + * + * LOCKING: + * Kernel thread context (may sleep). + */ +void ata_dev_free_resources(struct ata_device *dev) +{ + if (zpodd_dev_enabled(dev)) + zpodd_exit(dev); + + ata_dev_cleanup_cdl_resources(dev); +} + +/** * ata_port_detach - Detach ATA port in preparation of device removal * @ap: ATA port to be detached * @@ -6092,19 +6060,15 @@ static void ata_port_detach(struct ata_port *ap) cancel_delayed_work_sync(&ap->hotplug_task); cancel_delayed_work_sync(&ap->scsi_rescan_task); - /* clean up zpodd on port removal */ - ata_for_each_link(link, ap, HOST_FIRST) { - ata_for_each_dev(dev, link, ALL) { - if (zpodd_dev_enabled(dev)) - zpodd_exit(dev); - } - } + /* Delete port multiplier link transport devices */ if (ap->pmp_link) { int i; + for (i = 0; i < SATA_PMP_MAX_PORTS; i++) ata_tlink_delete(&ap->pmp_link[i]); } - /* remove the associated SCSI host */ + + /* Remove the associated SCSI host */ scsi_remove_host(ap->scsi_host); ata_tport_delete(ap); } @@ -6300,12 +6264,12 @@ EXPORT_SYMBOL_GPL(ata_platform_remove_one); { "no" #name, .lflags_on = (flags) }, \ { #name, .lflags_off = (flags) } -#define force_horkage_on(name, flag) \ - { #name, .horkage_on = (flag) } +#define force_quirk_on(name, flag) \ + { #name, .quirk_on = (flag) } -#define force_horkage_onoff(name, flag) \ - { "no" #name, .horkage_on = (flag) }, \ - { #name, .horkage_off = (flag) } +#define force_quirk_onoff(name, flag) \ + { "no" #name, .quirk_on = (flag) }, \ + { #name, .quirk_off = (flag) } static const struct ata_force_param force_tbl[] __initconst = { force_cbl(40c, ATA_CBL_PATA40), @@ -6359,32 +6323,32 @@ static const struct ata_force_param force_tbl[] __initconst = { force_lflag_on(rstonce, ATA_LFLAG_RST_ONCE), force_lflag_onoff(dbdelay, ATA_LFLAG_NO_DEBOUNCE_DELAY), - force_horkage_onoff(ncq, ATA_HORKAGE_NONCQ), - force_horkage_onoff(ncqtrim, ATA_HORKAGE_NO_NCQ_TRIM), - force_horkage_onoff(ncqati, ATA_HORKAGE_NO_NCQ_ON_ATI), + force_quirk_onoff(ncq, ATA_QUIRK_NONCQ), + force_quirk_onoff(ncqtrim, ATA_QUIRK_NO_NCQ_TRIM), + force_quirk_onoff(ncqati, ATA_QUIRK_NO_NCQ_ON_ATI), - force_horkage_onoff(trim, ATA_HORKAGE_NOTRIM), - force_horkage_on(trim_zero, ATA_HORKAGE_ZERO_AFTER_TRIM), - force_horkage_on(max_trim_128m, ATA_HORKAGE_MAX_TRIM_128M), + force_quirk_onoff(trim, ATA_QUIRK_NOTRIM), + force_quirk_on(trim_zero, ATA_QUIRK_ZERO_AFTER_TRIM), + force_quirk_on(max_trim_128m, ATA_QUIRK_MAX_TRIM_128M), - force_horkage_onoff(dma, ATA_HORKAGE_NODMA), - force_horkage_on(atapi_dmadir, ATA_HORKAGE_ATAPI_DMADIR), - force_horkage_on(atapi_mod16_dma, ATA_HORKAGE_ATAPI_MOD16_DMA), + force_quirk_onoff(dma, ATA_QUIRK_NODMA), + force_quirk_on(atapi_dmadir, ATA_QUIRK_ATAPI_DMADIR), + force_quirk_on(atapi_mod16_dma, ATA_QUIRK_ATAPI_MOD16_DMA), - force_horkage_onoff(dmalog, ATA_HORKAGE_NO_DMA_LOG), - force_horkage_onoff(iddevlog, ATA_HORKAGE_NO_ID_DEV_LOG), - force_horkage_onoff(logdir, ATA_HORKAGE_NO_LOG_DIR), + force_quirk_onoff(dmalog, ATA_QUIRK_NO_DMA_LOG), + force_quirk_onoff(iddevlog, ATA_QUIRK_NO_ID_DEV_LOG), + force_quirk_onoff(logdir, ATA_QUIRK_NO_LOG_DIR), - force_horkage_on(max_sec_128, ATA_HORKAGE_MAX_SEC_128), - force_horkage_on(max_sec_1024, ATA_HORKAGE_MAX_SEC_1024), - force_horkage_on(max_sec_lba48, ATA_HORKAGE_MAX_SEC_LBA48), + force_quirk_on(max_sec_128, ATA_QUIRK_MAX_SEC_128), + force_quirk_on(max_sec_1024, ATA_QUIRK_MAX_SEC_1024), + force_quirk_on(max_sec_lba48, ATA_QUIRK_MAX_SEC_LBA48), - force_horkage_onoff(lpm, ATA_HORKAGE_NOLPM), - force_horkage_onoff(setxfer, ATA_HORKAGE_NOSETXFER), - force_horkage_on(dump_id, ATA_HORKAGE_DUMP_ID), - force_horkage_onoff(fua, ATA_HORKAGE_NO_FUA), + force_quirk_onoff(lpm, ATA_QUIRK_NOLPM), + force_quirk_onoff(setxfer, ATA_QUIRK_NOSETXFER), + force_quirk_on(dump_id, ATA_QUIRK_DUMP_ID), + force_quirk_onoff(fua, ATA_QUIRK_NO_FUA), - force_horkage_on(disable, ATA_HORKAGE_DISABLE), + force_quirk_on(disable, ATA_QUIRK_DISABLE), }; static int __init ata_parse_force_one(char **cur, @@ -6660,7 +6624,6 @@ static void ata_dummy_error_handler(struct ata_port *ap) } struct ata_port_operations ata_dummy_port_ops = { - .qc_prep = ata_noop_qc_prep, .qc_issue = ata_dummy_qc_issue, .error_handler = ata_dummy_error_handler, .sched_eh = ata_std_sched_eh, diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 214b935c2ced..3b303d4ae37a 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -500,10 +500,13 @@ static void ata_eh_dev_disable(struct ata_device *dev) ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET); dev->class++; - /* From now till the next successful probe, ering is used to + /* + * From now till the next successful probe, ering is used to * track probe failures. Clear accumulated device error info. */ ata_ering_clear(&dev->ering); + + ata_dev_free_resources(dev); } static void ata_eh_unload(struct ata_port *ap) @@ -630,6 +633,14 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, list_for_each_entry_safe(scmd, tmp, eh_work_q, eh_entry) { struct ata_queued_cmd *qc; + /* + * If the scmd was added to EH, via ata_qc_schedule_eh() -> + * scsi_timeout() -> scsi_eh_scmd_add(), scsi_timeout() will + * have set DID_TIME_OUT (since libata does not have an abort + * handler). Thus, to clear DID_TIME_OUT, clear the host byte. + */ + set_host_byte(scmd, DID_OK); + ata_qc_for_each_raw(ap, qc, i) { if (qc->flags & ATA_QCFLAG_ACTIVE && qc->scsicmd == scmd) @@ -640,6 +651,7 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, /* the scmd has an associated qc */ if (!(qc->flags & ATA_QCFLAG_EH)) { /* which hasn't failed yet, timeout */ + set_host_byte(scmd, DID_TIME_OUT); qc->err_mask |= AC_ERR_TIMEOUT; qc->flags |= ATA_QCFLAG_EH; nr_timedout++; @@ -1402,6 +1414,43 @@ unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key) } /** + * ata_eh_decide_disposition - Disposition a qc based on sense data + * @qc: qc to examine + * + * For a regular SCSI command, the SCSI completion callback (scsi_done()) + * will call scsi_complete(), which will call scsi_decide_disposition(), + * which will call scsi_check_sense(). scsi_complete() finally calls + * scsi_finish_command(). This is fine for SCSI, since any eventual sense + * data is usually returned in the completion itself (without invoking SCSI + * EH). However, for a QC, we always need to fetch the sense data + * explicitly using SCSI EH. + * + * A command that is completed via SCSI EH will instead be completed using + * scsi_eh_flush_done_q(), which will call scsi_finish_command() directly + * (without ever calling scsi_check_sense()). + * + * For a command that went through SCSI EH, it is the responsibility of the + * SCSI EH strategy handler to call scsi_decide_disposition(), see e.g. how + * scsi_eh_get_sense() calls scsi_decide_disposition() for SCSI LLDDs that + * do not get the sense data as part of the completion. + * + * Thus, for QC commands that went via SCSI EH, we need to call + * scsi_check_sense() ourselves, similar to how scsi_eh_get_sense() calls + * scsi_decide_disposition(), which calls scsi_check_sense(), in order to + * set the correct SCSI ML byte (if any). + * + * LOCKING: + * EH context. + * + * RETURNS: + * SUCCESS or FAILED or NEEDS_RETRY or ADD_TO_MLQUEUE + */ +enum scsi_disposition ata_eh_decide_disposition(struct ata_queued_cmd *qc) +{ + return scsi_check_sense(qc->scsicmd); +} + +/** * ata_eh_request_sense - perform REQUEST_SENSE_DATA_EXT * @qc: qc to perform REQUEST_SENSE_SENSE_DATA_EXT to * @@ -1627,7 +1676,8 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc) } if (qc->flags & ATA_QCFLAG_SENSE_VALID) { - enum scsi_disposition ret = scsi_check_sense(qc->scsicmd); + enum scsi_disposition ret = ata_eh_decide_disposition(qc); + /* * SUCCESS here means that the sense code could be * evaluated and should be passed to the upper layers @@ -1924,7 +1974,7 @@ static inline bool ata_eh_quiet(struct ata_queued_cmd *qc) return qc->flags & ATA_QCFLAG_QUIET; } -static int ata_eh_read_sense_success_non_ncq(struct ata_link *link) +static int ata_eh_get_non_ncq_success_sense(struct ata_link *link) { struct ata_port *ap = link->ap; struct ata_queued_cmd *qc; @@ -1942,11 +1992,10 @@ static int ata_eh_read_sense_success_non_ncq(struct ata_link *link) return -EIO; /* - * If we have sense data, call scsi_check_sense() in order to set the - * correct SCSI ML byte (if any). No point in checking the return value, - * since the command has already completed successfully. + * No point in checking the return value, since the command has already + * completed successfully. */ - scsi_check_sense(qc->scsicmd); + ata_eh_decide_disposition(qc); return 0; } @@ -1976,9 +2025,9 @@ static void ata_eh_get_success_sense(struct ata_link *link) * request sense ext command to retrieve the sense data. */ if (link->sactive) - ret = ata_eh_read_sense_success_ncq_log(link); + ret = ata_eh_get_ncq_success_sense(link); else - ret = ata_eh_read_sense_success_non_ncq(link); + ret = ata_eh_get_non_ncq_success_sense(link); if (ret) goto out; @@ -3247,7 +3296,7 @@ static int atapi_eh_clear_ua(struct ata_device *dev) int i; for (i = 0; i < ATA_EH_UA_TRIES; i++) { - u8 *sense_buffer = dev->link->ap->sector_buf; + u8 *sense_buffer = dev->sector_buf; u8 sense_key = 0; unsigned int err_mask; @@ -4051,10 +4100,20 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); - /* Set all devices attached to the port in standby mode */ - ata_for_each_link(link, ap, HOST_FIRST) { - ata_for_each_dev(dev, link, ENABLED) - ata_dev_power_set_standby(dev); + /* + * We will reach this point for all of the PM events: + * PM_EVENT_SUSPEND (if runtime pm, PM_EVENT_AUTO will also be set) + * PM_EVENT_FREEZE, and PM_EVENT_HIBERNATE. + * + * We do not want to perform disk spin down for PM_EVENT_FREEZE. + * (Spin down will be performed by the subsequent PM_EVENT_HIBERNATE.) + */ + if (!(ap->pm_mesg.event & PM_EVENT_FREEZE)) { + /* Set all devices attached to the port in standby mode */ + ata_for_each_link(link, ap, HOST_FIRST) { + ata_for_each_dev(dev, link, ENABLED) + ata_dev_power_set_standby(dev); + } } /* diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index e2e9cbd405fa..d5d189328ae6 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -648,8 +648,7 @@ static int sata_pmp_same_pmp(struct ata_device *dev, const u32 *new_gscr) static int sata_pmp_revalidate(struct ata_device *dev, unsigned int new_class) { struct ata_link *link = dev->link; - struct ata_port *ap = link->ap; - u32 *gscr = (void *)ap->sector_buf; + u32 *gscr = (void *)dev->sector_buf; int rc; ata_eh_about_to_do(link, NULL, ATA_EH_REVALIDATE); diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index 9e047bf912b1..9c76fb1ad2ec 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -13,7 +13,7 @@ #include <scsi/scsi_device.h> #include <scsi/scsi_eh.h> #include <linux/libata.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "libata.h" #include "libata-transport.h" @@ -518,6 +518,86 @@ int sata_set_spd(struct ata_link *link) EXPORT_SYMBOL_GPL(sata_set_spd); /** + * sata_down_spd_limit - adjust SATA spd limit downward + * @link: Link to adjust SATA spd limit for + * @spd_limit: Additional limit + * + * Adjust SATA spd limit of @link downward. Note that this + * function only adjusts the limit. The change must be applied + * using sata_set_spd(). + * + * If @spd_limit is non-zero, the speed is limited to equal to or + * lower than @spd_limit if such speed is supported. If + * @spd_limit is slower than any supported speed, only the lowest + * supported speed is allowed. + * + * LOCKING: + * Inherited from caller. + * + * RETURNS: + * 0 on success, negative errno on failure + */ +int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) +{ + u32 sstatus, spd, mask; + int rc, bit; + + if (!sata_scr_valid(link)) + return -EOPNOTSUPP; + + /* If SCR can be read, use it to determine the current SPD. + * If not, use cached value in link->sata_spd. + */ + rc = sata_scr_read(link, SCR_STATUS, &sstatus); + if (rc == 0 && ata_sstatus_online(sstatus)) + spd = (sstatus >> 4) & 0xf; + else + spd = link->sata_spd; + + mask = link->sata_spd_limit; + if (mask <= 1) + return -EINVAL; + + /* unconditionally mask off the highest bit */ + bit = fls(mask) - 1; + mask &= ~(1 << bit); + + /* + * Mask off all speeds higher than or equal to the current one. At + * this point, if current SPD is not available and we previously + * recorded the link speed from SStatus, the driver has already + * masked off the highest bit so mask should already be 1 or 0. + * Otherwise, we should not force 1.5Gbps on a link where we have + * not previously recorded speed from SStatus. Just return in this + * case. + */ + if (spd > 1) + mask &= (1 << (spd - 1)) - 1; + else if (link->sata_spd) + return -EINVAL; + + /* were we already at the bottom? */ + if (!mask) + return -EINVAL; + + if (spd_limit) { + if (mask & ((1 << spd_limit) - 1)) + mask &= (1 << spd_limit) - 1; + else { + bit = ffs(mask) - 1; + mask = 1 << bit; + } + } + + link->sata_spd_limit = mask; + + ata_link_warn(link, "limiting SATA link speed to %s\n", + sata_spd_string(fls(mask))); + + return 0; +} + +/** * sata_link_hardreset - reset link via SATA phy reset * @link: link to reset * @timing: timing parameters { interval, duration, timeout } in msec @@ -627,6 +707,34 @@ int sata_link_hardreset(struct ata_link *link, const unsigned int *timing, EXPORT_SYMBOL_GPL(sata_link_hardreset); /** + * sata_std_hardreset - COMRESET w/o waiting or classification + * @link: link to reset + * @class: resulting class of attached device + * @deadline: deadline jiffies for the operation + * + * Standard SATA COMRESET w/o waiting or classification. + * + * LOCKING: + * Kernel thread context (may sleep) + * + * RETURNS: + * 0 if link offline, -EAGAIN if link online, -errno on errors. + */ +int sata_std_hardreset(struct ata_link *link, unsigned int *class, + unsigned long deadline) +{ + const unsigned int *timing = sata_ehc_deb_timing(&link->eh_context); + bool online; + int rc; + + rc = sata_link_hardreset(link, timing, deadline, &online, NULL); + if (online) + return -EAGAIN; + return rc; +} +EXPORT_SYMBOL_GPL(sata_std_hardreset); + +/** * ata_qc_complete_multiple - Complete multiple qcs successfully * @ap: port in question * @qc_active: new qc_active mask @@ -818,7 +926,7 @@ static ssize_t ata_scsi_lpm_store(struct device *device, ata_for_each_link(link, ap, EDGE) { ata_for_each_dev(dev, &ap->link, ENABLED) { - if (dev->horkage & ATA_HORKAGE_NOLPM) { + if (dev->quirks & ATA_QUIRK_NOLPM) { count = -EOPNOTSUPP; goto out_unlock; } @@ -1205,55 +1313,6 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); /** - * ata_sas_port_alloc - Allocate port for a SAS attached SATA device - * @host: ATA host container for all SAS ports - * @port_info: Information from low-level host driver - * @shost: SCSI host that the scsi device is attached to - * - * LOCKING: - * PCI/etc. bus probe sem. - * - * RETURNS: - * ata_port pointer on success / NULL on failure. - */ - -struct ata_port *ata_sas_port_alloc(struct ata_host *host, - struct ata_port_info *port_info, - struct Scsi_Host *shost) -{ - struct ata_port *ap; - - ap = ata_port_alloc(host); - if (!ap) - return NULL; - - ap->port_no = 0; - ap->lock = &host->lock; - ap->pio_mask = port_info->pio_mask; - ap->mwdma_mask = port_info->mwdma_mask; - ap->udma_mask = port_info->udma_mask; - ap->flags |= port_info->flags; - ap->ops = port_info->port_ops; - ap->cbl = ATA_CBL_SATA; - ap->print_id = atomic_inc_return(&ata_print_id); - - return ap; -} -EXPORT_SYMBOL_GPL(ata_sas_port_alloc); - -int ata_sas_tport_add(struct device *parent, struct ata_port *ap) -{ - return ata_tport_add(parent, ap); -} -EXPORT_SYMBOL_GPL(ata_sas_tport_add); - -void ata_sas_tport_delete(struct ata_port *ap) -{ - ata_tport_delete(ap); -} -EXPORT_SYMBOL_GPL(ata_sas_tport_delete); - -/** * ata_sas_device_configure - Default device_configure routine for libata * devices * @sdev: SCSI device to configure @@ -1389,7 +1448,7 @@ EXPORT_SYMBOL_GPL(sata_async_notification); static int ata_eh_read_log_10h(struct ata_device *dev, int *tag, struct ata_taskfile *tf) { - u8 *buf = dev->link->ap->sector_buf; + u8 *buf = dev->sector_buf; unsigned int err_mask; u8 csum; int i; @@ -1428,8 +1487,8 @@ static int ata_eh_read_log_10h(struct ata_device *dev, } /** - * ata_eh_read_sense_success_ncq_log - Read the sense data for successful - * NCQ commands log + * ata_eh_get_ncq_success_sense - Read and process the sense data for + * successful NCQ commands log page * @link: ATA link to get sense data for * * Read the sense data for successful NCQ commands log page to obtain @@ -1442,11 +1501,11 @@ static int ata_eh_read_log_10h(struct ata_device *dev, * RETURNS: * 0 on success, -errno otherwise. */ -int ata_eh_read_sense_success_ncq_log(struct ata_link *link) +int ata_eh_get_ncq_success_sense(struct ata_link *link) { struct ata_device *dev = link->device; struct ata_port *ap = dev->link->ap; - u8 *buf = ap->ncq_sense_buf; + u8 *buf = dev->cdl->ncq_sense_log_buf; struct ata_queued_cmd *qc; unsigned int err_mask, tag; u8 *sense, sk = 0, asc = 0, ascq = 0; @@ -1504,17 +1563,14 @@ int ata_eh_read_sense_success_ncq_log(struct ata_link *link) qc->flags |= ATA_QCFLAG_SENSE_VALID; /* - * If we have sense data, call scsi_check_sense() in order to - * set the correct SCSI ML byte (if any). No point in checking - * the return value, since the command has already completed - * successfully. + * No point in checking the return value, since the command has + * already completed successfully. */ - scsi_check_sense(qc->scsicmd); + ata_eh_decide_disposition(qc); } return ret; } -EXPORT_SYMBOL_GPL(ata_eh_read_sense_success_ncq_log); /** * ata_eh_analyze_ncq_error - analyze NCQ error @@ -1625,3 +1681,11 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) ehc->i.err_mask &= ~AC_ERR_DEV; } EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error); + +const struct ata_port_operations sata_port_ops = { + .inherits = &ata_base_port_ops, + + .qc_defer = ata_std_qc_defer, + .hardreset = sata_std_hardreset, +}; +EXPORT_SYMBOL_GPL(sata_port_ops); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index bb4d30d377ae..f915e3df57a9 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -30,7 +30,7 @@ #include <linux/hdreg.h> #include <linux/uaccess.h> #include <linux/suspend.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/ioprio.h> #include <linux/of.h> @@ -230,6 +230,87 @@ void ata_scsi_set_sense_information(struct ata_device *dev, SCSI_SENSE_BUFFERSIZE, information); } +/** + * ata_scsi_set_passthru_sense_fields - Set ATA fields in sense buffer + * @qc: ATA PASS-THROUGH command. + * + * Populates "ATA Status Return sense data descriptor" / "Fixed format + * sense data" with ATA taskfile fields. + * + * LOCKING: + * None. + */ +static void ata_scsi_set_passthru_sense_fields(struct ata_queued_cmd *qc) +{ + struct ata_device *dev = qc->dev; + struct scsi_cmnd *cmd = qc->scsicmd; + struct ata_taskfile *tf = &qc->result_tf; + unsigned char *sb = cmd->sense_buffer; + + if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) { + ata_dev_dbg(dev, + "missing result TF: can't set ATA PT sense fields\n"); + return; + } + + if ((sb[0] & 0x7f) >= 0x72) { + unsigned char *desc; + u8 len; + + /* descriptor format */ + len = sb[7]; + desc = (char *)scsi_sense_desc_find(sb, len + 8, 9); + if (!desc) { + if (SCSI_SENSE_BUFFERSIZE < len + 14) + return; + sb[7] = len + 14; + desc = sb + 8 + len; + } + desc[0] = 9; + desc[1] = 12; + /* + * Copy registers into sense buffer. + */ + desc[2] = 0x00; + desc[3] = tf->error; + desc[5] = tf->nsect; + desc[7] = tf->lbal; + desc[9] = tf->lbam; + desc[11] = tf->lbah; + desc[12] = tf->device; + desc[13] = tf->status; + + /* + * Fill in Extend bit, and the high order bytes + * if applicable. + */ + if (tf->flags & ATA_TFLAG_LBA48) { + desc[2] |= 0x01; + desc[4] = tf->hob_nsect; + desc[6] = tf->hob_lbal; + desc[8] = tf->hob_lbam; + desc[10] = tf->hob_lbah; + } + } else { + /* Fixed sense format */ + sb[0] |= 0x80; + sb[3] = tf->error; + sb[4] = tf->status; + sb[5] = tf->device; + sb[6] = tf->nsect; + if (tf->flags & ATA_TFLAG_LBA48) { + sb[8] |= 0x80; + if (tf->hob_nsect) + sb[8] |= 0x40; + if (tf->hob_lbal || tf->hob_lbam || tf->hob_lbah) + sb[8] |= 0x20; + } + sb[9] = tf->lbal; + sb[10] = tf->lbam; + sb[11] = tf->lbah; + } +} + static void ata_scsi_set_invalid_field(struct ata_device *dev, struct scsi_cmnd *cmd, u16 field, u8 bit) { @@ -711,7 +792,6 @@ static void ata_qc_set_pc_nbytes(struct ata_queued_cmd *qc) /** * ata_to_sense_error - convert ATA error to SCSI error - * @id: ATA device number * @drv_stat: value contained in ATA status register * @drv_err: value contained in ATA error register * @sk: the sense key we'll fill out @@ -725,8 +805,8 @@ static void ata_qc_set_pc_nbytes(struct ata_queued_cmd *qc) * LOCKING: * spin_lock_irqsave(host lock) */ -static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, - u8 *asc, u8 *ascq) +static void ata_to_sense_error(u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, + u8 *ascq) { int i; @@ -837,10 +917,8 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, * ata_gen_passthru_sense - Generate check condition sense block. * @qc: Command that completed. * - * This function is specific to the ATA descriptor format sense - * block specified for the ATA pass through commands. Regardless - * of whether the command errored or not, return a sense - * block. Copy all controller registers into the sense + * This function is specific to the ATA pass through commands. + * Regardless of whether the command errored or not, return a sense * block. If there was no error, we get the request from an ATA * passthrough command, so we use the following sense data: * sk = RECOVERED ERROR @@ -852,13 +930,16 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, */ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) { + struct ata_device *dev = qc->dev; struct scsi_cmnd *cmd = qc->scsicmd; struct ata_taskfile *tf = &qc->result_tf; - unsigned char *sb = cmd->sense_buffer; - unsigned char *desc = sb + 8; u8 sense_key, asc, ascq; - memset(sb, 0, SCSI_SENSE_BUFFERSIZE); + if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) { + ata_dev_dbg(dev, + "missing result TF: can't generate ATA PT sense data\n"); + return; + } /* * Use ata_to_sense_error() to map status register bits @@ -866,72 +947,24 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) */ if (qc->err_mask || tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { - ata_to_sense_error(qc->ap->print_id, tf->status, tf->error, + ata_to_sense_error(tf->status, tf->error, &sense_key, &asc, &ascq); ata_scsi_set_sense(qc->dev, cmd, sense_key, asc, ascq); } else { /* * ATA PASS-THROUGH INFORMATION AVAILABLE - * Always in descriptor format sense. + * + * Note: we are supposed to call ata_scsi_set_sense(), which + * respects the D_SENSE bit, instead of unconditionally + * generating the sense data in descriptor format. However, + * because hdparm, hddtemp, and udisks incorrectly assume sense + * data in descriptor format, without even looking at the + * RESPONSE CODE field in the returned sense data (to see which + * format the returned sense data is in), we are stuck with + * being bug compatible with older kernels. */ scsi_build_sense(cmd, 1, RECOVERED_ERROR, 0, 0x1D); } - - if ((cmd->sense_buffer[0] & 0x7f) >= 0x72) { - u8 len; - - /* descriptor format */ - len = sb[7]; - desc = (char *)scsi_sense_desc_find(sb, len + 8, 9); - if (!desc) { - if (SCSI_SENSE_BUFFERSIZE < len + 14) - return; - sb[7] = len + 14; - desc = sb + 8 + len; - } - desc[0] = 9; - desc[1] = 12; - /* - * Copy registers into sense buffer. - */ - desc[2] = 0x00; - desc[3] = tf->error; - desc[5] = tf->nsect; - desc[7] = tf->lbal; - desc[9] = tf->lbam; - desc[11] = tf->lbah; - desc[12] = tf->device; - desc[13] = tf->status; - - /* - * Fill in Extend bit, and the high order bytes - * if applicable. - */ - if (tf->flags & ATA_TFLAG_LBA48) { - desc[2] |= 0x01; - desc[4] = tf->hob_nsect; - desc[6] = tf->hob_lbal; - desc[8] = tf->hob_lbam; - desc[10] = tf->hob_lbah; - } - } else { - /* Fixed sense format */ - desc[0] = tf->error; - desc[1] = tf->status; - desc[2] = tf->device; - desc[3] = tf->nsect; - desc[7] = 0; - if (tf->flags & ATA_TFLAG_LBA48) { - desc[8] |= 0x80; - if (tf->hob_nsect) - desc[8] |= 0x40; - if (tf->hob_lbal || tf->hob_lbam || tf->hob_lbah) - desc[8] |= 0x20; - } - desc[9] = tf->lbal; - desc[10] = tf->lbam; - desc[11] = tf->lbah; - } } /** @@ -953,20 +986,25 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) u64 block; u8 sense_key, asc, ascq; - memset(sb, 0, SCSI_SENSE_BUFFERSIZE); - if (ata_dev_disabled(dev)) { /* Device disabled after error recovery */ /* LOGICAL UNIT NOT READY, HARD RESET REQUIRED */ ata_scsi_set_sense(dev, cmd, NOT_READY, 0x04, 0x21); return; } + + if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) { + ata_dev_dbg(dev, + "missing result TF: can't generate sense data\n"); + return; + } + /* Use ata_to_sense_error() to map status register bits * onto sense key, asc & ascq. */ if (qc->err_mask || tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { - ata_to_sense_error(qc->ap->print_id, tf->status, tf->error, + ata_to_sense_error(tf->status, tf->error, &sense_key, &asc, &ascq); ata_scsi_set_sense(dev, cmd, sense_key, asc, ascq); } else { @@ -1024,7 +1062,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_dma_need_drain); int ata_scsi_dev_config(struct scsi_device *sdev, struct queue_limits *lim, struct ata_device *dev) { - struct request_queue *q = sdev->request_queue; int depth = 1; if (!ata_id_has_unload(dev->id)) @@ -1038,7 +1075,7 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct queue_limits *lim, sdev->sector_size = ATA_SECT_SIZE; /* set DMA padding */ - blk_queue_update_dma_pad(q, ATA_DMA_PAD_SZ - 1); + lim->dma_pad_mask = ATA_DMA_PAD_SZ - 1; /* make room for appending the drain */ lim->max_segments--; @@ -1632,26 +1669,29 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) { struct scsi_cmnd *cmd = qc->scsicmd; u8 *cdb = cmd->cmnd; - int need_sense = (qc->err_mask != 0) && - !(qc->flags & ATA_QCFLAG_SENSE_VALID); + bool have_sense = qc->flags & ATA_QCFLAG_SENSE_VALID; + bool is_ata_passthru = cdb[0] == ATA_16 || cdb[0] == ATA_12; + bool is_ck_cond_request = cdb[2] & 0x20; + bool is_error = qc->err_mask != 0; /* For ATA pass thru (SAT) commands, generate a sense block if * user mandated it or if there's an error. Note that if we - * generate because the user forced us to [CK_COND =1], a check + * generate because the user forced us to [CK_COND=1], a check * condition is generated and the ATA register values are returned * whether the command completed successfully or not. If there - * was no error, we use the following sense data: + * was no error, and CK_COND=1, we use the following sense data: * sk = RECOVERED ERROR * asc,ascq = ATA PASS-THROUGH INFORMATION AVAILABLE */ - if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && - ((cdb[2] & 0x20) || need_sense)) - ata_gen_passthru_sense(qc); - else if (need_sense) + if (is_ata_passthru && (is_ck_cond_request || is_error || have_sense)) { + if (!have_sense) + ata_gen_passthru_sense(qc); + ata_scsi_set_passthru_sense_fields(qc); + if (is_ck_cond_request) + set_status_byte(qc->scsicmd, SAM_STAT_CHECK_CONDITION); + } else if (is_error && !have_sense) { ata_gen_ata_sense(qc); - else - /* Keep the SCSI ML and status byte, clear host byte. */ - cmd->result &= 0x0000ffff; + } ata_qc_done(qc); } @@ -2051,7 +2091,7 @@ static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf) if (ata_id_has_trim(args->id)) { u64 max_blocks = 65535 * ATA_MAX_TRIM_RNUM; - if (dev->horkage & ATA_HORKAGE_MAX_TRIM_128M) + if (dev->quirks & ATA_QUIRK_MAX_TRIM_128M) max_blocks = 128 << (20 - SECTOR_SHIFT); put_unaligned_be64(max_blocks, &rbuf[36]); @@ -2216,10 +2256,15 @@ static inline u16 ata_xlat_cdl_limit(u8 *buf) static unsigned int ata_msense_control_spgt2(struct ata_device *dev, u8 *buf, u8 spg) { - u8 *b, *cdl = dev->cdl, *desc; + u8 *b, *cdl, *desc; u32 policy; int i; + if (!(dev->flags & ATA_DFLAG_CDL) || !dev->cdl) + return 0; + + cdl = dev->cdl->desc_log_buf; + /* * Fill the subpage. The first four bytes of the T2A/T2B mode pages * are a header. The PAGE LENGTH field is the size of the page @@ -2316,7 +2361,7 @@ static unsigned int ata_msense_control(struct ata_device *dev, u8 *buf, case ALL_SUB_MPAGES: n = ata_msense_control_spg0(dev, buf, changeable); n += ata_msense_control_spgt2(dev, buf + n, CDL_T2A_SUB_MPAGE); - n += ata_msense_control_spgt2(dev, buf + n, CDL_T2A_SUB_MPAGE); + n += ata_msense_control_spgt2(dev, buf + n, CDL_T2B_SUB_MPAGE); n += ata_msense_control_ata_feature(dev, buf + n); return n; default: @@ -2529,11 +2574,11 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf) rbuf[15] = lowest_aligned; if (ata_id_has_trim(args->id) && - !(dev->horkage & ATA_HORKAGE_NOTRIM)) { + !(dev->quirks & ATA_QUIRK_NOTRIM)) { rbuf[14] |= 0x80; /* LBPME */ if (ata_id_has_zero_after_trim(args->id) && - dev->horkage & ATA_HORKAGE_ZERO_AFTER_TRIM) { + dev->quirks & ATA_QUIRK_ZERO_AFTER_TRIM) { ata_dev_info(dev, "Enabling discard_zeroes_data\n"); rbuf[14] |= 0x40; /* LBPRZ */ } @@ -2590,14 +2635,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) /* handle completion from EH */ if (unlikely(err_mask || qc->flags & ATA_QCFLAG_SENSE_VALID)) { - if (!(qc->flags & ATA_QCFLAG_SENSE_VALID)) { - /* FIXME: not quite right; we don't want the - * translation of taskfile registers into a - * sense descriptors, since that's only - * correct for ATA, not ATAPI - */ + if (!(qc->flags & ATA_QCFLAG_SENSE_VALID)) ata_gen_passthru_sense(qc); - } /* SCSI EH automatically locks door if sdev->locked is * set. Sometimes door lock request continues to @@ -3203,8 +3242,7 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) } scsi_16_lba_len(cdb, &block, &n_block); - if (!unmap || - (dev->horkage & ATA_HORKAGE_NOTRIM) || + if (!unmap || (dev->quirks & ATA_QUIRK_NOTRIM) || !ata_id_has_trim(dev->id)) { fp = 1; bp = 3; @@ -4580,16 +4618,15 @@ static void ata_scsi_handle_link_detach(struct ata_link *link) ata_for_each_dev(dev, link, ALL) { unsigned long flags; - if (!(dev->flags & ATA_DFLAG_DETACHED)) + spin_lock_irqsave(ap->lock, flags); + if (!(dev->flags & ATA_DFLAG_DETACHED)) { + spin_unlock_irqrestore(ap->lock, flags); continue; + } - spin_lock_irqsave(ap->lock, flags); dev->flags &= ~ATA_DFLAG_DETACHED; spin_unlock_irqrestore(ap->lock, flags); - if (zpodd_dev_enabled(dev)) - zpodd_exit(dev); - ata_scsi_remove_dev(dev); } } diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 250f7dae05fd..67f277e1c3bf 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -26,7 +26,6 @@ static struct workqueue_struct *ata_sff_wq; const struct ata_port_operations ata_sff_port_ops = { .inherits = &ata_base_port_ops, - .qc_prep = ata_noop_qc_prep, .qc_issue = ata_sff_qc_issue, .qc_fill_rtf = ata_sff_qc_fill_rtf, @@ -970,7 +969,7 @@ fsm_start: * We ignore ERR here to workaround and proceed sending * the CDB. */ - if (!(qc->dev->horkage & ATA_HORKAGE_STUCK_ERR)) { + if (!(qc->dev->quirks & ATA_QUIRK_STUCK_ERR)) { ata_ehi_push_desc(ehi, "ST_FIRST: " "DRQ=1 with device error, " "dev_stat 0x%X", status); @@ -1045,8 +1044,8 @@ fsm_start: * IDENTIFY, it's likely a phantom * device. Mark hint. */ - if (qc->dev->horkage & - ATA_HORKAGE_DIAGNOSTIC) + if (qc->dev->quirks & + ATA_QUIRK_DIAGNOSTIC) qc->err_mask |= AC_ERR_NODEV_HINT; } else { @@ -1762,7 +1761,7 @@ unsigned int ata_sff_dev_classify(struct ata_device *dev, int present, /* see if device passed diags: continue and warn later */ if (err == 0) /* diagnostic fail : do nothing _YET_ */ - dev->horkage |= ATA_HORKAGE_DIAGNOSTIC; + dev->quirks |= ATA_QUIRK_DIAGNOSTIC; else if (err == 1) /* do nothing */ ; else if ((dev->devno == 0) && (err == 0x81)) @@ -1781,7 +1780,7 @@ unsigned int ata_sff_dev_classify(struct ata_device *dev, int present, * device signature is invalid with diagnostic * failure. */ - if (present && (dev->horkage & ATA_HORKAGE_DIAGNOSTIC)) + if (present && (dev->quirks & ATA_QUIRK_DIAGNOSTIC)) class = ATA_DEV_ATA; else class = ATA_DEV_NONE; diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c index 3e49a877500e..e898be49df6b 100644 --- a/drivers/ata/libata-transport.c +++ b/drivers/ata/libata-transport.c @@ -80,12 +80,6 @@ struct ata_internal { #define transport_class_to_port(dev) \ tdev_to_port((dev)->parent) - -/* Device objects are always created whit link objects */ -static int ata_tdev_add(struct ata_device *dev); -static void ata_tdev_delete(struct ata_device *dev); - - /* * Hack to allow attributes of the same name in different objects. */ @@ -217,7 +211,8 @@ static DEVICE_ATTR(name, S_IRUGO, show_ata_port_##name, NULL) ata_port_simple_attr(nr_pmp_links, nr_pmp_links, "%d\n", int); ata_port_simple_attr(stats.idle_irq, idle_irq, "%ld\n", unsigned long); -ata_port_simple_attr(local_port_no, port_no, "%u\n", unsigned int); +/* We want the port_no sysfs attibute to start at 1 (ap->port_no starts at 0) */ +ata_port_simple_attr(port_no + 1, port_no, "%u\n", unsigned int); static DECLARE_TRANSPORT_CLASS(ata_port_class, "ata_port", NULL, NULL, NULL); @@ -265,6 +260,7 @@ void ata_tport_delete(struct ata_port *ap) transport_destroy_device(dev); put_device(dev); } +EXPORT_SYMBOL_GPL(ata_tport_delete); static const struct device_type ata_port_sas_type = { .name = ATA_PORT_TYPE_NAME, @@ -329,6 +325,7 @@ int ata_tport_add(struct device *parent, put_device(dev); return error; } +EXPORT_SYMBOL_GPL(ata_tport_add); /** * ata_port_classify - determine device type based on ATA-spec signature @@ -362,135 +359,6 @@ unsigned int ata_port_classify(struct ata_port *ap, EXPORT_SYMBOL_GPL(ata_port_classify); /* - * ATA link attributes - */ -static int noop(int x) { return x; } - -#define ata_link_show_linkspeed(field, format) \ -static ssize_t \ -show_ata_link_##field(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct ata_link *link = transport_class_to_link(dev); \ - \ - return sprintf(buf, "%s\n", sata_spd_string(format(link->field))); \ -} - -#define ata_link_linkspeed_attr(field, format) \ - ata_link_show_linkspeed(field, format) \ -static DEVICE_ATTR(field, S_IRUGO, show_ata_link_##field, NULL) - -ata_link_linkspeed_attr(hw_sata_spd_limit, fls); -ata_link_linkspeed_attr(sata_spd_limit, fls); -ata_link_linkspeed_attr(sata_spd, noop); - - -static DECLARE_TRANSPORT_CLASS(ata_link_class, - "ata_link", NULL, NULL, NULL); - -static void ata_tlink_release(struct device *dev) -{ -} - -/** - * ata_is_link -- check if a struct device represents a ATA link - * @dev: device to check - * - * Returns: - * %1 if the device represents a ATA link, %0 else - */ -static int ata_is_link(const struct device *dev) -{ - return dev->release == ata_tlink_release; -} - -static int ata_tlink_match(struct attribute_container *cont, - struct device *dev) -{ - struct ata_internal* i = to_ata_internal(ata_scsi_transport_template); - if (!ata_is_link(dev)) - return 0; - return &i->link_attr_cont.ac == cont; -} - -/** - * ata_tlink_delete -- remove ATA LINK - * @link: ATA LINK to remove - * - * Removes the specified ATA LINK. remove associated ATA device(s) as well. - */ -void ata_tlink_delete(struct ata_link *link) -{ - struct device *dev = &link->tdev; - struct ata_device *ata_dev; - - ata_for_each_dev(ata_dev, link, ALL) { - ata_tdev_delete(ata_dev); - } - - transport_remove_device(dev); - device_del(dev); - transport_destroy_device(dev); - put_device(dev); -} - -/** - * ata_tlink_add -- initialize a transport ATA link structure - * @link: allocated ata_link structure. - * - * Initialize an ATA LINK structure for sysfs. It will be added in the - * device tree below the ATA PORT it belongs to. - * - * Returns %0 on success - */ -int ata_tlink_add(struct ata_link *link) -{ - struct device *dev = &link->tdev; - struct ata_port *ap = link->ap; - struct ata_device *ata_dev; - int error; - - device_initialize(dev); - dev->parent = &ap->tdev; - dev->release = ata_tlink_release; - if (ata_is_host_link(link)) - dev_set_name(dev, "link%d", ap->print_id); - else - dev_set_name(dev, "link%d.%d", ap->print_id, link->pmp); - - transport_setup_device(dev); - - error = device_add(dev); - if (error) { - goto tlink_err; - } - - error = transport_add_device(dev); - if (error) - goto tlink_transport_err; - transport_configure_device(dev); - - ata_for_each_dev(ata_dev, link, ALL) { - error = ata_tdev_add(ata_dev); - if (error) { - goto tlink_dev_err; - } - } - return 0; - tlink_dev_err: - while (--ata_dev >= link->device) { - ata_tdev_delete(ata_dev); - } - transport_remove_device(dev); - tlink_transport_err: - device_del(dev); - tlink_err: - transport_destroy_device(dev); - put_device(dev); - return error; -} - -/* * ATA device attributes */ @@ -614,10 +482,10 @@ show_ata_dev_trim(struct device *dev, if (!ata_id_has_trim(ata_dev->id)) mode = "unsupported"; - else if (ata_dev->horkage & ATA_HORKAGE_NOTRIM) + else if (ata_dev->quirks & ATA_QUIRK_NOTRIM) mode = "forced_unsupported"; - else if (ata_dev->horkage & ATA_HORKAGE_NO_NCQ_TRIM) - mode = "forced_unqueued"; + else if (ata_dev->quirks & ATA_QUIRK_NO_NCQ_TRIM) + mode = "forced_unqueued"; else if (ata_fpdma_dsm_supported(ata_dev)) mode = "queued"; else @@ -640,9 +508,9 @@ static void ata_tdev_release(struct device *dev) * @dev: device to check * * Returns: - * %1 if the device represents a ATA device, %0 else + * true if the device represents a ATA device, false otherwise */ -static int ata_is_ata_dev(const struct device *dev) +static bool ata_is_ata_dev(const struct device *dev) { return dev->release == ata_tdev_release; } @@ -650,21 +518,22 @@ static int ata_is_ata_dev(const struct device *dev) static int ata_tdev_match(struct attribute_container *cont, struct device *dev) { - struct ata_internal* i = to_ata_internal(ata_scsi_transport_template); + struct ata_internal *i = to_ata_internal(ata_scsi_transport_template); + if (!ata_is_ata_dev(dev)) return 0; return &i->dev_attr_cont.ac == cont; } /** - * ata_tdev_free -- free a ATA LINK - * @dev: ATA PHY to free + * ata_tdev_free -- free an ATA transport device + * @dev: struct ata_device owning the transport device to free * - * Frees the specified ATA PHY. + * Free the ATA transport device for the specified ATA device. * * Note: - * This function must only be called on a PHY that has not - * successfully been added using ata_tdev_add(). + * This function must only be called for a ATA transport device that has not + * yet successfully been added using ata_tdev_add(). */ static void ata_tdev_free(struct ata_device *dev) { @@ -673,10 +542,10 @@ static void ata_tdev_free(struct ata_device *dev) } /** - * ata_tdev_delete -- remove ATA device - * @ata_dev: ATA device to remove + * ata_tdev_delete -- remove an ATA transport device + * @ata_dev: struct ata_device owning the transport device to delete * - * Removes the specified ATA device. + * Removes the ATA transport device for the specified ATA device. */ static void ata_tdev_delete(struct ata_device *ata_dev) { @@ -687,15 +556,14 @@ static void ata_tdev_delete(struct ata_device *ata_dev) ata_tdev_free(ata_dev); } - /** - * ata_tdev_add -- initialize a transport ATA device structure. - * @ata_dev: ata_dev structure. + * ata_tdev_add -- initialize an ATA transport device + * @ata_dev: struct ata_device owning the transport device to add * - * Initialize an ATA device structure for sysfs. It will be added in the - * device tree below the ATA LINK device it belongs to. + * Initialize an ATA transport device for sysfs. It will be added in the + * device tree below the ATA link device it belongs to. * - * Returns %0 on success + * Returns %0 on success and a negative error code on error. */ static int ata_tdev_add(struct ata_device *ata_dev) { @@ -731,6 +599,136 @@ static int ata_tdev_add(struct ata_device *ata_dev) return 0; } +/* + * ATA link attributes + */ +static int noop(int x) +{ + return x; +} + +#define ata_link_show_linkspeed(field, format) \ +static ssize_t \ +show_ata_link_##field(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct ata_link *link = transport_class_to_link(dev); \ + \ + return sprintf(buf, "%s\n", \ + sata_spd_string(format(link->field))); \ +} + +#define ata_link_linkspeed_attr(field, format) \ + ata_link_show_linkspeed(field, format) \ +static DEVICE_ATTR(field, 0444, show_ata_link_##field, NULL) + +ata_link_linkspeed_attr(hw_sata_spd_limit, fls); +ata_link_linkspeed_attr(sata_spd_limit, fls); +ata_link_linkspeed_attr(sata_spd, noop); + +static DECLARE_TRANSPORT_CLASS(ata_link_class, + "ata_link", NULL, NULL, NULL); + +static void ata_tlink_release(struct device *dev) +{ +} + +/** + * ata_is_link -- check if a struct device represents a ATA link + * @dev: device to check + * + * Returns: + * true if the device represents a ATA link, false otherwise + */ +static bool ata_is_link(const struct device *dev) +{ + return dev->release == ata_tlink_release; +} + +static int ata_tlink_match(struct attribute_container *cont, + struct device *dev) +{ + struct ata_internal *i = to_ata_internal(ata_scsi_transport_template); + + if (!ata_is_link(dev)) + return 0; + return &i->link_attr_cont.ac == cont; +} + +/** + * ata_tlink_delete -- remove an ATA link transport device + * @link: struct ata_link owning the link transport device to remove + * + * Removes the link transport device of the specified ATA link. This also + * removes the ATA device(s) associated with the link as well. + */ +void ata_tlink_delete(struct ata_link *link) +{ + struct device *dev = &link->tdev; + struct ata_device *ata_dev; + + ata_for_each_dev(ata_dev, link, ALL) { + ata_tdev_delete(ata_dev); + } + + transport_remove_device(dev); + device_del(dev); + transport_destroy_device(dev); + put_device(dev); +} + +/** + * ata_tlink_add -- initialize an ATA link transport device + * @link: struct ata_link owning the link transport device to initialize + * + * Initialize an ATA link transport device for sysfs. It will be added in the + * device tree below the ATA port it belongs to. + * + * Returns %0 on success and a negative error code on error. + */ +int ata_tlink_add(struct ata_link *link) +{ + struct device *dev = &link->tdev; + struct ata_port *ap = link->ap; + struct ata_device *ata_dev; + int error; + + device_initialize(dev); + dev->parent = &ap->tdev; + dev->release = ata_tlink_release; + if (ata_is_host_link(link)) + dev_set_name(dev, "link%d", ap->print_id); + else + dev_set_name(dev, "link%d.%d", ap->print_id, link->pmp); + + transport_setup_device(dev); + + error = device_add(dev); + if (error) + goto tlink_err; + + error = transport_add_device(dev); + if (error) + goto tlink_transport_err; + transport_configure_device(dev); + + ata_for_each_dev(ata_dev, link, ALL) { + error = ata_tdev_add(ata_dev); + if (error) + goto tlink_dev_err; + } + return 0; + tlink_dev_err: + while (--ata_dev >= link->device) + ata_tdev_delete(ata_dev); + transport_remove_device(dev); + tlink_transport_err: + device_del(dev); + tlink_err: + transport_destroy_device(dev); + put_device(dev); + return error; +} /* * Setup / Teardown code diff --git a/drivers/ata/libata-transport.h b/drivers/ata/libata-transport.h index 08a57fb9dc61..50cd2cbe8eea 100644 --- a/drivers/ata/libata-transport.h +++ b/drivers/ata/libata-transport.h @@ -8,9 +8,6 @@ extern struct scsi_transport_template *ata_scsi_transport_template; int ata_tlink_add(struct ata_link *link); void ata_tlink_delete(struct ata_link *link); -int ata_tport_add(struct device *parent, struct ata_port *ap); -void ata_tport_delete(struct ata_port *ap); - struct scsi_transport_template *ata_attach_transport(void); void ata_release_transport(struct scsi_transport_template *t); diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c index eefda51f97d3..4b83b517caec 100644 --- a/drivers/ata/libata-zpodd.c +++ b/drivers/ata/libata-zpodd.c @@ -112,7 +112,7 @@ static bool zpready(struct ata_device *dev) if (!ret || sense_key != NOT_READY) return false; - sense_buf = dev->link->ap->sector_buf; + sense_buf = dev->sector_buf; ret = atapi_eh_request_sense(dev, sense_buf, sense_key); if (ret) return false; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 38ce13b55474..0337be4faec7 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -32,13 +32,18 @@ enum { #define ATA_PORT_TYPE_NAME "ata_port" -extern atomic_t ata_print_id; extern int atapi_passthru16; extern int libata_fua; extern int libata_noacpi; extern int libata_allow_tpm; extern const struct device_type ata_port_type; extern struct ata_link *ata_dev_phys_link(struct ata_device *dev); + +static inline bool ata_sstatus_online(u32 sstatus) +{ + return (sstatus & 0xf) == 0x3; +} + #ifdef CONFIG_ATA_FORCE extern void ata_force_cbl(struct ata_port *ap); #else @@ -66,7 +71,7 @@ extern bool ata_dev_power_init_tf(struct ata_device *dev, struct ata_taskfile *tf, bool set_active); extern void ata_dev_power_set_standby(struct ata_device *dev); extern void ata_dev_power_set_active(struct ata_device *dev); -extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); +void ata_dev_free_resources(struct ata_device *dev); 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 subcmd, u8 action); @@ -82,13 +87,28 @@ extern void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp); extern int sata_link_init_spd(struct ata_link *link); extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); -extern struct ata_port *ata_port_alloc(struct ata_host *host); extern const char *sata_spd_string(unsigned int spd); extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log, u8 page, void *buf, unsigned int sectors); +void ata_dev_cleanup_cdl_resources(struct ata_device *dev); #define to_ata_port(d) container_of(d, struct ata_port, tdev) +/* libata-sata.c */ +#ifdef CONFIG_SATA_HOST +int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); +int ata_eh_get_ncq_success_sense(struct ata_link *link); +#else +static inline int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) +{ + return -EOPNOTSUPP; +} +static inline int ata_eh_get_ncq_success_sense(struct ata_link *link) +{ + return -EOPNOTSUPP; +} +#endif + /* libata-acpi.c */ #ifdef CONFIG_ATA_ACPI extern unsigned int ata_acpi_gtf_filter; @@ -126,7 +146,6 @@ extern void ata_scsi_set_sense_information(struct ata_device *dev, const struct ata_taskfile *tf); extern void ata_scsi_media_change_notify(struct ata_device *dev); extern void ata_scsi_hotplug(struct work_struct *work); -extern void ata_schedule_scsi_eh(struct Scsi_Host *shost); extern void ata_scsi_dev_rescan(struct work_struct *work); extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, unsigned int id, u64 lun); @@ -164,6 +183,7 @@ extern void ata_eh_finish(struct ata_port *ap); extern int ata_ering_map(struct ata_ering *ering, int (*map_fn)(struct ata_ering_entry *, void *), void *arg); +enum scsi_disposition ata_eh_decide_disposition(struct ata_queued_cmd *qc); extern unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key); extern unsigned int atapi_eh_request_sense(struct ata_device *dev, u8 *sense_buf, u8 dfl_sense_key); diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 027cf67101ef..3163c8d9cef5 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c @@ -8,9 +8,9 @@ * PIO mode and smarter silicon. * * The practical upshot of this is that we must always tune the - * drive for the right PIO mode. We must also ignore all the blacklists - * and the drive bus mastering DMA information. Also to confuse matters - * further we can do DMA on PIO only drives. + * drive for the right PIO mode and ignore the drive bus mastering DMA + * information. Also to confuse matters further we can do DMA on PIO only + * drives. * * DMA on the 5510 also requires we disable_hlt() during DMA on early * revisions. diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c index c84a20892f1b..f3f5b2b0ecc9 100644 --- a/drivers/ata/pata_ep93xx.c +++ b/drivers/ata/pata_ep93xx.c @@ -44,8 +44,8 @@ #include <linux/delay.h> #include <linux/dmaengine.h> #include <linux/ktime.h> +#include <linux/mod_devicetable.h> -#include <linux/platform_data/dma-ep93xx.h> #include <linux/soc/cirrus/ep93xx.h> #define DRV_NAME "ep93xx-ide" @@ -126,7 +126,7 @@ enum { }; struct ep93xx_pata_data { - const struct platform_device *pdev; + struct platform_device *pdev; void __iomem *ide_base; struct ata_timing t; bool iordy; @@ -135,9 +135,7 @@ struct ep93xx_pata_data { unsigned long udma_out_phys; struct dma_chan *dma_rx_channel; - struct ep93xx_dma_data dma_rx_data; struct dma_chan *dma_tx_channel; - struct ep93xx_dma_data dma_tx_data; }; static void ep93xx_pata_clear_regs(void __iomem *base) @@ -637,20 +635,13 @@ static void ep93xx_pata_release_dma(struct ep93xx_pata_data *drv_data) } } -static bool ep93xx_pata_dma_filter(struct dma_chan *chan, void *filter_param) +static int ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data) { - if (ep93xx_dma_chan_is_m2p(chan)) - return false; - - chan->private = filter_param; - return true; -} - -static void ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data) -{ - const struct platform_device *pdev = drv_data->pdev; + struct platform_device *pdev = drv_data->pdev; + struct device *dev = &pdev->dev; dma_cap_mask_t mask; struct dma_slave_config conf; + int ret; dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); @@ -660,22 +651,16 @@ static void ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data) * to request only one channel, and reprogram it's direction at * start of new transfer. */ - drv_data->dma_rx_data.port = EP93XX_DMA_IDE; - drv_data->dma_rx_data.direction = DMA_DEV_TO_MEM; - drv_data->dma_rx_data.name = "ep93xx-pata-rx"; - drv_data->dma_rx_channel = dma_request_channel(mask, - ep93xx_pata_dma_filter, &drv_data->dma_rx_data); - if (!drv_data->dma_rx_channel) - return; - - drv_data->dma_tx_data.port = EP93XX_DMA_IDE; - drv_data->dma_tx_data.direction = DMA_MEM_TO_DEV; - drv_data->dma_tx_data.name = "ep93xx-pata-tx"; - drv_data->dma_tx_channel = dma_request_channel(mask, - ep93xx_pata_dma_filter, &drv_data->dma_tx_data); - if (!drv_data->dma_tx_channel) { - dma_release_channel(drv_data->dma_rx_channel); - return; + drv_data->dma_rx_channel = dma_request_chan(dev, "rx"); + if (IS_ERR(drv_data->dma_rx_channel)) + return dev_err_probe(dev, PTR_ERR(drv_data->dma_rx_channel), + "rx DMA setup failed\n"); + + drv_data->dma_tx_channel = dma_request_chan(&pdev->dev, "tx"); + if (IS_ERR(drv_data->dma_tx_channel)) { + ret = dev_err_probe(dev, PTR_ERR(drv_data->dma_tx_channel), + "tx DMA setup failed\n"); + goto fail_release_rx; } /* Configure receive channel direction and source address */ @@ -683,10 +668,10 @@ static void ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data) conf.direction = DMA_DEV_TO_MEM; conf.src_addr = drv_data->udma_in_phys; conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - if (dmaengine_slave_config(drv_data->dma_rx_channel, &conf)) { - dev_err(&pdev->dev, "failed to configure rx dma channel\n"); - ep93xx_pata_release_dma(drv_data); - return; + ret = dmaengine_slave_config(drv_data->dma_rx_channel, &conf); + if (ret) { + dev_err_probe(dev, ret, "failed to configure rx dma channel"); + goto fail_release_dma; } /* Configure transmit channel direction and destination address */ @@ -694,10 +679,20 @@ static void ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data) conf.direction = DMA_MEM_TO_DEV; conf.dst_addr = drv_data->udma_out_phys; conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - if (dmaengine_slave_config(drv_data->dma_tx_channel, &conf)) { - dev_err(&pdev->dev, "failed to configure tx dma channel\n"); - ep93xx_pata_release_dma(drv_data); + ret = dmaengine_slave_config(drv_data->dma_tx_channel, &conf); + if (ret) { + dev_err_probe(dev, ret, "failed to configure tx dma channel"); + goto fail_release_dma; } + + return 0; + +fail_release_rx: + dma_release_channel(drv_data->dma_rx_channel); +fail_release_dma: + ep93xx_pata_release_dma(drv_data); + + return ret; } static void ep93xx_pata_dma_start(struct ata_queued_cmd *qc) @@ -884,8 +879,6 @@ static const struct scsi_host_template ep93xx_pata_sht = { static struct ata_port_operations ep93xx_pata_port_ops = { .inherits = &ata_bmdma_port_ops, - .qc_prep = ata_noop_qc_prep, - .softreset = ep93xx_pata_softreset, .hardreset = ATA_OP_NULL, @@ -927,34 +920,26 @@ static int ep93xx_pata_probe(struct platform_device *pdev) void __iomem *ide_base; int err; - err = ep93xx_ide_acquire_gpio(pdev); - if (err) - return err; - /* INT[3] (IRQ_EP93XX_EXT3) line connected as pull down */ irq = platform_get_irq(pdev, 0); - if (irq < 0) { - err = irq; - goto err_rel_gpio; - } + if (irq < 0) + return irq; ide_base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem_res); - if (IS_ERR(ide_base)) { - err = PTR_ERR(ide_base); - goto err_rel_gpio; - } + if (IS_ERR(ide_base)) + return PTR_ERR(ide_base); drv_data = devm_kzalloc(&pdev->dev, sizeof(*drv_data), GFP_KERNEL); - if (!drv_data) { - err = -ENOMEM; - goto err_rel_gpio; - } + if (!drv_data) + return -ENOMEM; drv_data->pdev = pdev; drv_data->ide_base = ide_base; drv_data->udma_in_phys = mem_res->start + IDEUDMADATAIN; drv_data->udma_out_phys = mem_res->start + IDEUDMADATAOUT; - ep93xx_pata_dma_init(drv_data); + err = ep93xx_pata_dma_init(drv_data); + if (err) + return err; /* allocate host */ host = ata_host_alloc(&pdev->dev, 1); @@ -1005,8 +990,6 @@ static int ep93xx_pata_probe(struct platform_device *pdev) err_rel_dma: ep93xx_pata_release_dma(drv_data); -err_rel_gpio: - ep93xx_ide_release_gpio(pdev); return err; } @@ -1018,12 +1001,18 @@ static void ep93xx_pata_remove(struct platform_device *pdev) ata_host_detach(host); ep93xx_pata_release_dma(drv_data); ep93xx_pata_clear_regs(drv_data->ide_base); - ep93xx_ide_release_gpio(pdev); } +static const struct of_device_id ep93xx_pata_of_ids[] = { + { .compatible = "cirrus,ep9312-pata" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ep93xx_pata_of_ids); + static struct platform_driver ep93xx_pata_platform_driver = { .driver = { .name = DRV_NAME, + .of_match_table = ep93xx_pata_of_ids, }, .probe = ep93xx_pata_probe, .remove_new = ep93xx_pata_remove, diff --git a/drivers/ata/pata_ftide010.c b/drivers/ata/pata_ftide010.c index 4d6ef90ccc77..73a9a5109238 100644 --- a/drivers/ata/pata_ftide010.c +++ b/drivers/ata/pata_ftide010.c @@ -549,6 +549,7 @@ static const struct of_device_id pata_ftide010_of_match[] = { { .compatible = "faraday,ftide010", }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, pata_ftide010_of_match); static struct platform_driver pata_ftide010_driver = { .driver = { diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index bdccd1ba1524..5280e9960025 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -170,8 +170,8 @@ static const char * const bad_ata66_3[] = { NULL }; -static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, - const char * const list[]) +static int hpt_dma_broken(const struct ata_device *dev, char *modestr, + const char * const list[]) { unsigned char model_num[ATA_ID_PROD_LEN + 1]; int i; @@ -197,11 +197,11 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, static unsigned int hpt366_filter(struct ata_device *adev, unsigned int mask) { if (adev->class == ATA_DEV_ATA) { - if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) + if (hpt_dma_broken(adev, "UDMA", bad_ata33)) mask &= ~ATA_MASK_UDMA; - if (hpt_dma_blacklisted(adev, "UDMA3", bad_ata66_3)) + if (hpt_dma_broken(adev, "UDMA3", bad_ata66_3)) mask &= ~(0xF8 << ATA_SHIFT_UDMA); - if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4)) + if (hpt_dma_broken(adev, "UDMA4", bad_ata66_4)) mask &= ~(0xF0 << ATA_SHIFT_UDMA); } else if (adev->class == ATA_DEV_ATAPI) mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index c0329cf01135..4af22b819416 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -218,8 +218,8 @@ static u32 hpt37x_find_mode(struct ata_port *ap, int speed) return 0xffffffffU; /* silence compiler warning */ } -static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, - const char * const list[]) +static int hpt_dma_broken(const struct ata_device *dev, char *modestr, + const char * const list[]) { unsigned char model_num[ATA_ID_PROD_LEN + 1]; int i; @@ -281,9 +281,9 @@ static const char * const bad_ata100_5[] = { static unsigned int hpt370_filter(struct ata_device *adev, unsigned int mask) { if (adev->class == ATA_DEV_ATA) { - if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) + if (hpt_dma_broken(adev, "UDMA", bad_ata33)) mask &= ~ATA_MASK_UDMA; - if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) + if (hpt_dma_broken(adev, "UDMA100", bad_ata100_5)) mask &= ~(0xE0 << ATA_SHIFT_UDMA); } return mask; @@ -300,7 +300,7 @@ static unsigned int hpt370_filter(struct ata_device *adev, unsigned int mask) static unsigned int hpt370a_filter(struct ata_device *adev, unsigned int mask) { if (adev->class == ATA_DEV_ATA) { - if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) + if (hpt_dma_broken(adev, "UDMA100", bad_ata100_5)) mask &= ~(0xE0 << ATA_SHIFT_UDMA); } return mask; diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c index 9cfb064782c3..61d8760f09d9 100644 --- a/drivers/ata/pata_icside.c +++ b/drivers/ata/pata_icside.c @@ -328,8 +328,6 @@ static void pata_icside_postreset(struct ata_link *link, unsigned int *classes) static struct ata_port_operations pata_icside_port_ops = { .inherits = &ata_bmdma_port_ops, - /* no need to build any PRD tables for DMA */ - .qc_prep = ata_noop_qc_prep, .sff_data_xfer = ata_sff_data_xfer32, .bmdma_setup = pata_icside_bmdma_setup, .bmdma_start = pata_icside_bmdma_start, diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 2fe3fb6102ce..042f6ad1f7c6 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -519,9 +519,9 @@ static void it821x_dev_config(struct ata_device *adev) } /* This is a controller firmware triggered funny, don't report the drive faulty! */ - adev->horkage &= ~ATA_HORKAGE_DIAGNOSTIC; + adev->quirks &= ~ATA_QUIRK_DIAGNOSTIC; /* No HPA in 'smart' mode */ - adev->horkage |= ATA_HORKAGE_BROKEN_HPA; + adev->quirks |= ATA_QUIRK_BROKEN_HPA; } /** diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index 246bb4f8f1f7..8a9ee828478f 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -290,6 +290,7 @@ static const struct of_device_id ixp4xx_pata_of_match[] = { { .compatible = "intel,ixp4xx-compact-flash", }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, ixp4xx_pata_of_match); static struct platform_driver ixp4xx_pata_platform_driver = { .driver = { diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index 3cb455a32d92..f2f36e55a1f4 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -208,6 +208,19 @@ static const char* macio_ata_names[] = { /* Don't let a DMA segment go all the way to 64K */ #define MAX_DBDMA_SEG 0xff00 +#ifdef CONFIG_PAGE_SIZE_64KB +/* + * The SCSI core requires the segment size to cover at least a page, so + * for 64K page size kernels it must be at least 64K. However the + * hardware can't handle 64K, so pata_macio_qc_prep() will split large + * requests. To handle the split requests the tablesize must be halved. + */ +#define PATA_MACIO_MAX_SEGMENT_SIZE SZ_64K +#define PATA_MACIO_SG_TABLESIZE (MAX_DCMDS / 2) +#else +#define PATA_MACIO_MAX_SEGMENT_SIZE MAX_DBDMA_SEG +#define PATA_MACIO_SG_TABLESIZE MAX_DCMDS +#endif /* * Wait 1s for disk to answer on IDE bus after a hard reset @@ -541,7 +554,8 @@ static enum ata_completion_errors pata_macio_qc_prep(struct ata_queued_cmd *qc) while (sg_len) { /* table overflow should never happen */ - BUG_ON (pi++ >= MAX_DCMDS); + if (WARN_ON_ONCE(pi >= MAX_DCMDS)) + return AC_ERR_SYSTEM; len = (sg_len < MAX_DBDMA_SEG) ? sg_len : MAX_DBDMA_SEG; table->command = cpu_to_le16(write ? OUTPUT_MORE: INPUT_MORE); @@ -553,11 +567,13 @@ static enum ata_completion_errors pata_macio_qc_prep(struct ata_queued_cmd *qc) addr += len; sg_len -= len; ++table; + ++pi; } } /* Should never happen according to Tejun */ - BUG_ON(!pi); + if (WARN_ON_ONCE(!pi)) + return AC_ERR_SYSTEM; /* Convert the last command to an input/output */ table--; @@ -816,7 +832,7 @@ static int pata_macio_device_configure(struct scsi_device *sdev, /* OHare has issues with non cache aligned DMA on some chipsets */ if (priv->kind == controller_ohare) { lim->dma_alignment = 31; - blk_queue_update_dma_pad(sdev->request_queue, 31); + lim->dma_pad_mask = 31; /* Tell the world about it */ ata_dev_info(dev, "OHare alignment limits applied\n"); @@ -831,7 +847,7 @@ static int pata_macio_device_configure(struct scsi_device *sdev, if (priv->kind == controller_sh_ata6 || priv->kind == controller_k2_ata6) { /* Allright these are bad, apply restrictions */ lim->dma_alignment = 15; - blk_queue_update_dma_pad(sdev->request_queue, 15); + lim->dma_pad_mask = 15; /* We enable MWI and hack cache line size directly here, this * is specific to this chipset and not normal values, we happen @@ -912,16 +928,10 @@ static int pata_macio_do_resume(struct pata_macio_priv *priv) static const struct scsi_host_template pata_macio_sht = { __ATA_BASE_SHT(DRV_NAME), - .sg_tablesize = MAX_DCMDS, + .sg_tablesize = PATA_MACIO_SG_TABLESIZE, /* We may not need that strict one */ .dma_boundary = ATA_DMA_BOUNDARY, - /* - * The SCSI core requires the segment size to cover at least a page, so - * for 64K page size kernels this must be at least 64K. However the - * hardware can't handle 64K, so pata_macio_qc_prep() will split large - * requests. - */ - .max_segment_size = SZ_64K, + .max_segment_size = PATA_MACIO_MAX_SEGMENT_SIZE, .device_configure = pata_macio_device_configure, .sdev_groups = ata_common_sdev_groups, .can_queue = ATA_DEF_QUEUE, diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 6c317a461a1f..3f9258677915 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -620,7 +620,6 @@ static struct ata_port_operations mpc52xx_ata_port_ops = { .bmdma_start = mpc52xx_bmdma_start, .bmdma_stop = mpc52xx_bmdma_stop, .bmdma_status = mpc52xx_bmdma_status, - .qc_prep = ata_noop_qc_prep, }; static int mpc52xx_ata_init_one(struct device *dev, diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 2884acfc4863..0bb9607e7348 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -789,7 +789,6 @@ static unsigned int octeon_cf_qc_issue(struct ata_queued_cmd *qc) static struct ata_port_operations octeon_cf_ops = { .inherits = &ata_sff_port_ops, .check_atapi_dma = octeon_cf_check_atapi_dma, - .qc_prep = ata_noop_qc_prep, .qc_issue = octeon_cf_qc_issue, .sff_dev_select = octeon_cf_dev_select, .sff_irq_on = octeon_cf_ata_port_noaction, diff --git a/drivers/ata/pata_parport/pata_parport.c b/drivers/ata/pata_parport/pata_parport.c index 9a2cb9ca9d1d..93ebf566b54e 100644 --- a/drivers/ata/pata_parport/pata_parport.c +++ b/drivers/ata/pata_parport/pata_parport.c @@ -768,7 +768,6 @@ static struct parport_driver pata_parport_driver = { .name = DRV_NAME, .match_port = pata_parport_attach, .detach = pata_parport_detach, - .devmodel = true, }; static __init int pata_parport_init(void) diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index 549ff24a9823..4edddf6bcc15 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c @@ -46,10 +46,11 @@ #define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */ #define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */ -/* Seagate Barracuda ATA IV Family drives in UDMA mode 5 - * can overrun their FIFOs when used with the CSB5 */ - -static const char *csb_bad_ata100[] = { +/* + * Seagate Barracuda ATA IV Family drives in UDMA mode 5 + * can overrun their FIFOs when used with the CSB5. + */ +static const char * const csb_bad_ata100[] = { "ST320011A", "ST340016A", "ST360021A", @@ -163,10 +164,11 @@ static unsigned int serverworks_osb4_filter(struct ata_device *adev, unsigned in * @adev: ATA device * @mask: Mask of proposed modes * - * Check the blacklist and disable UDMA5 if matched + * Check the list of devices with broken UDMA5 and + * disable UDMA5 if matched. */ - -static unsigned int serverworks_csb_filter(struct ata_device *adev, unsigned int mask) +static unsigned int serverworks_csb_filter(struct ata_device *adev, + unsigned int mask) { const char *p; char model_num[ATA_ID_PROD_LEN + 1]; diff --git a/drivers/ata/sata_gemini.c b/drivers/ata/sata_gemini.c index 4c270999ba3c..f574e3c3f5b4 100644 --- a/drivers/ata/sata_gemini.c +++ b/drivers/ata/sata_gemini.c @@ -417,6 +417,7 @@ static const struct of_device_id gemini_sata_of_match[] = { { .compatible = "cortina,gemini-sata-bridge", }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, gemini_sata_of_match); static struct platform_driver gemini_sata_driver = { .driver = { diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index cc77c0248284..3a99f66198a9 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -128,7 +128,7 @@ static const struct pci_device_id sil_pci_tbl[] = { static const struct sil_drivelist { const char *product; unsigned int quirk; -} sil_blacklist [] = { +} sil_quirks[] = { { "ST320012AS", SIL_QUIRK_MOD15WRITE }, { "ST330013AS", SIL_QUIRK_MOD15WRITE }, { "ST340017AS", SIL_QUIRK_MOD15WRITE }, @@ -600,8 +600,8 @@ static void sil_thaw(struct ata_port *ap) * list, and apply the fixups to only the specific * devices/hosts/firmwares that need it. * - * 20040111 - Seagate drives affected by the Mod15Write bug are blacklisted - * The Maxtor quirk is in the blacklist, but I'm keeping the original + * 20040111 - Seagate drives affected by the Mod15Write bug are quirked + * The Maxtor quirk is in sil_quirks, but I'm keeping the original * pessimistic fix for the following reasons... * - There seems to be less info on it, only one device gleaned off the * Windows driver, maybe only one is affected. More info would be greatly @@ -616,13 +616,13 @@ static void sil_dev_config(struct ata_device *dev) unsigned char model_num[ATA_ID_PROD_LEN + 1]; /* This controller doesn't support trim */ - dev->horkage |= ATA_HORKAGE_NOTRIM; + dev->quirks |= ATA_QUIRK_NOTRIM; ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num)); - for (n = 0; sil_blacklist[n].product; n++) - if (!strcmp(sil_blacklist[n].product, model_num)) { - quirks = sil_blacklist[n].quirk; + for (n = 0; sil_quirks[n].product; n++) + if (!strcmp(sil_quirks[n].product, model_num)) { + quirks = sil_quirks[n].quirk; break; } |