diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/Kconfig | 3 | ||||
-rw-r--r-- | drivers/ata/ahci.c | 38 | ||||
-rw-r--r-- | drivers/ata/ahci_da850.c | 33 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 2 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 6 | ||||
-rw-r--r-- | drivers/ata/libata-transport.c | 9 | ||||
-rw-r--r-- | drivers/ata/pata_amd.c | 1 | ||||
-rw-r--r-- | drivers/ata/pata_cs5536.c | 1 | ||||
-rw-r--r-- | drivers/ata/sata_via.c | 18 |
9 files changed, 93 insertions, 18 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 2c8be74f401d..5d16fc4fa46c 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -289,6 +289,7 @@ config SATA_SX4 config ATA_BMDMA bool "ATA BMDMA support" + depends on HAS_DMA default y help This option adds support for SFF ATA controllers with BMDMA @@ -344,6 +345,7 @@ config SATA_DWC_VDEBUG config SATA_HIGHBANK tristate "Calxeda Highbank SATA support" + depends on HAS_DMA depends on ARCH_HIGHBANK || COMPILE_TEST help This option enables support for the Calxeda Highbank SoC's @@ -353,6 +355,7 @@ config SATA_HIGHBANK config SATA_MV tristate "Marvell SATA support" + depends on HAS_DMA depends on PCI || ARCH_DOVE || ARCH_MV78XX0 || \ ARCH_MVEBU || ARCH_ORION5X || COMPILE_TEST select GENERIC_PHY diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 74f4c662f776..c94038206c3a 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1362,6 +1362,40 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) {} #endif +/* + * On the Acer Aspire Switch Alpha 12, sometimes all SATA ports are detected + * as DUMMY, or detected but eventually get a "link down" and never get up + * again. When this happens, CAP.NP may hold a value of 0x00 or 0x01, and the + * port_map may hold a value of 0x00. + * + * Overriding CAP.NP to 0x02 and the port_map to 0x7 will reveal all 3 ports + * and can significantly reduce the occurrence of the problem. + * + * https://bugzilla.kernel.org/show_bug.cgi?id=189471 + */ +static void acer_sa5_271_workaround(struct ahci_host_priv *hpriv, + struct pci_dev *pdev) +{ + static const struct dmi_system_id sysids[] = { + { + .ident = "Acer Switch Alpha 12", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Switch SA5-271") + }, + }, + { } + }; + + if (dmi_check_system(sysids)) { + dev_info(&pdev->dev, "enabling Acer Switch Alpha 12 workaround\n"); + if ((hpriv->saved_cap & 0xC734FF00) == 0xC734FF00) { + hpriv->port_map = 0x7; + hpriv->cap = 0xC734FF02; + } + } +} + #ifdef CONFIG_ARM64 /* * Due to ERRATA#22536, ThunderX needs to handle HOST_IRQ_STAT differently. @@ -1597,6 +1631,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) "online status unreliable, applying workaround\n"); } + + /* Acer SA5-271 workaround modifies private_data */ + acer_sa5_271_workaround(hpriv, pdev); + /* CAP.NP sometimes indicate the index of the last enabled * port, at other times, that of the last possible port, so * determining the maximum port number requires looking at diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c index 267a3d3e79f4..52f2674d5e89 100644 --- a/drivers/ata/ahci_da850.c +++ b/drivers/ata/ahci_da850.c @@ -54,11 +54,42 @@ static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg, writel(val, ahci_base + SATA_P0PHYCR_REG); } +static int ahci_da850_softreset(struct ata_link *link, + unsigned int *class, unsigned long deadline) +{ + int pmp, ret; + + pmp = sata_srst_pmp(link); + + /* + * There's an issue with the SATA controller on da850 SoCs: if we + * enable Port Multiplier support, but the drive is connected directly + * to the board, it can't be detected. As a workaround: if PMP is + * enabled, we first call ahci_do_softreset() and pass it the result of + * sata_srst_pmp(). If this call fails, we retry with pmp = 0. + */ + ret = ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready); + if (pmp && ret == -EBUSY) + return ahci_do_softreset(link, class, 0, + deadline, ahci_check_ready); + + return ret; +} + +static struct ata_port_operations ahci_da850_port_ops = { + .inherits = &ahci_platform_ops, + .softreset = ahci_da850_softreset, + /* + * No need to override .pmp_softreset - it's only used for actual + * PMP-enabled ports. + */ +}; + static const struct ata_port_info ahci_da850_port_info = { .flags = AHCI_FLAG_COMMON, .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, - .port_ops = &ahci_platform_ops, + .port_ops = &ahci_da850_port_ops, }; static struct scsi_host_template ahci_platform_sht = { diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 0e1ec37070d1..6475a1343483 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2329,8 +2329,8 @@ static void ata_eh_link_autopsy(struct ata_link *link) if (dev->flags & ATA_DFLAG_DUBIOUS_XFER) eflags |= ATA_EFLAG_DUBIOUS_XFER; ehc->i.action |= ata_eh_speed_down(dev, eflags, all_err_mask); + trace_ata_eh_link_autopsy(dev, ehc->i.action, all_err_mask); } - trace_ata_eh_link_autopsy(dev, ehc->i.action, all_err_mask); DPRINTK("EXIT\n"); } diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 8e575fbdf31d..e3e10e8f6f6a 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2971,10 +2971,12 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) static struct ata_device *ata_find_dev(struct ata_port *ap, int devno) { if (!sata_pmp_attached(ap)) { - if (likely(devno < ata_link_max_devices(&ap->link))) + if (likely(devno >= 0 && + devno < ata_link_max_devices(&ap->link))) return &ap->link.device[devno]; } else { - if (likely(devno < ap->nr_pmp_links)) + if (likely(devno >= 0 && + devno < ap->nr_pmp_links)) return &ap->pmp_link[devno].device[0]; } diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c index 7ef16c085058..20e2b7ad8925 100644 --- a/drivers/ata/libata-transport.c +++ b/drivers/ata/libata-transport.c @@ -224,7 +224,6 @@ static DECLARE_TRANSPORT_CLASS(ata_port_class, static void ata_tport_release(struct device *dev) { - put_device(dev->parent); } /** @@ -284,7 +283,7 @@ int ata_tport_add(struct device *parent, device_initialize(dev); dev->type = &ata_port_type; - dev->parent = get_device(parent); + dev->parent = parent; dev->release = ata_tport_release; dev_set_name(dev, "ata%d", ap->print_id); transport_setup_device(dev); @@ -348,7 +347,6 @@ static DECLARE_TRANSPORT_CLASS(ata_link_class, static void ata_tlink_release(struct device *dev) { - put_device(dev->parent); } /** @@ -410,7 +408,7 @@ int ata_tlink_add(struct ata_link *link) int error; device_initialize(dev); - dev->parent = get_device(&ap->tdev); + dev->parent = &ap->tdev; dev->release = ata_tlink_release; if (ata_is_host_link(link)) dev_set_name(dev, "link%d", ap->print_id); @@ -589,7 +587,6 @@ static DECLARE_TRANSPORT_CLASS(ata_dev_class, static void ata_tdev_release(struct device *dev) { - put_device(dev->parent); } /** @@ -662,7 +659,7 @@ static int ata_tdev_add(struct ata_device *ata_dev) int error; device_initialize(dev); - dev->parent = get_device(&link->tdev); + dev->parent = &link->tdev; dev->release = ata_tdev_release; if (ata_is_host_link(link)) dev_set_name(dev, "dev%d.%d", ap->print_id,ata_dev->devno); diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 8d4d959a821c..8706533db57b 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -616,6 +616,7 @@ static const struct pci_device_id amd[] = { { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE), 8 }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE), 8 }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), 9 }, + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_DEV_IDE), 9 }, { }, }; diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index 6c15a554efbe..dc1255294628 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c @@ -289,6 +289,7 @@ static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id) static const struct pci_device_id cs5536[] = { { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), }, + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_DEV_IDE), }, { }, }; diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 0636d84fbefe..f3f538eec7b3 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -644,14 +644,16 @@ static void svia_configure(struct pci_dev *pdev, int board_id, pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); } - /* enable IRQ on hotplug */ - pci_read_config_byte(pdev, SVIA_MISC_3, &tmp8); - if ((tmp8 & SATA_HOTPLUG) != SATA_HOTPLUG) { - dev_dbg(&pdev->dev, - "enabling SATA hotplug (0x%x)\n", - (int) tmp8); - tmp8 |= SATA_HOTPLUG; - pci_write_config_byte(pdev, SVIA_MISC_3, tmp8); + if (board_id == vt6421) { + /* enable IRQ on hotplug */ + pci_read_config_byte(pdev, SVIA_MISC_3, &tmp8); + if ((tmp8 & SATA_HOTPLUG) != SATA_HOTPLUG) { + dev_dbg(&pdev->dev, + "enabling SATA hotplug (0x%x)\n", + (int) tmp8); + tmp8 |= SATA_HOTPLUG; + pci_write_config_byte(pdev, SVIA_MISC_3, tmp8); + } } /* |