diff options
Diffstat (limited to 'drivers/ata/libahci.c')
| -rw-r--r-- | drivers/ata/libahci.c | 91 |
1 files changed, 50 insertions, 41 deletions
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 06aec35f88f2..c79abdfcd7a9 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -111,6 +111,7 @@ static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL); static struct attribute *ahci_shost_attrs[] = { + &dev_attr_link_power_management_supported.attr, &dev_attr_link_power_management_policy.attr, &dev_attr_em_message_type.attr, &dev_attr_em_message.attr, @@ -162,10 +163,10 @@ struct ata_port_operations ahci_ops = { .freeze = ahci_freeze, .thaw = ahci_thaw, - .softreset = ahci_softreset, - .hardreset = ahci_hardreset, - .postreset = ahci_postreset, - .pmp_softreset = ahci_softreset, + .reset.softreset = ahci_softreset, + .reset.hardreset = ahci_hardreset, + .reset.postreset = ahci_postreset, + .pmp_reset.softreset = ahci_softreset, .error_handler = ahci_error_handler, .post_internal_cmd = ahci_post_internal_cmd, .dev_config = ahci_dev_config, @@ -192,7 +193,7 @@ EXPORT_SYMBOL_GPL(ahci_ops); struct ata_port_operations ahci_pmp_retry_srst_ops = { .inherits = &ahci_ops, - .softreset = ahci_pmp_retry_softreset, + .reset.softreset = ahci_pmp_retry_softreset, }; EXPORT_SYMBOL_GPL(ahci_pmp_retry_srst_ops); @@ -541,6 +542,7 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) hpriv->saved_port_map = port_map; } + /* mask_port_map not set means that all ports are available */ if (hpriv->mask_port_map) { dev_warn(dev, "masking port_map 0x%lx -> 0x%lx\n", port_map, @@ -1033,7 +1035,7 @@ static void ahci_sw_activity(struct ata_link *link) static void ahci_sw_activity_blink(struct timer_list *t) { - struct ahci_em_priv *emp = from_timer(emp, t, timer); + struct ahci_em_priv *emp = timer_container_of(emp, t, timer); struct ata_link *link = emp->link; struct ata_port *ap = link->ap; @@ -1256,37 +1258,39 @@ static ssize_t ahci_activity_show(struct ata_device *dev, char *buf) return sprintf(buf, "%d\n", emp->blink_policy); } -static void ahci_port_init(struct device *dev, struct ata_port *ap, - int port_no, void __iomem *mmio, - void __iomem *port_mmio) +static void ahci_port_clear_pending_irq(struct ata_port *ap) { struct ahci_host_priv *hpriv = ap->host->private_data; - const char *emsg = NULL; - int rc; + void __iomem *port_mmio = ahci_port_base(ap); u32 tmp; - /* make sure port is not active */ - rc = ahci_deinit_port(ap, &emsg); - if (rc) - dev_warn(dev, "%s (%d)\n", emsg, rc); - /* clear SError */ tmp = readl(port_mmio + PORT_SCR_ERR); - dev_dbg(dev, "PORT_SCR_ERR 0x%x\n", tmp); + dev_dbg(ap->host->dev, "PORT_SCR_ERR 0x%x\n", tmp); writel(tmp, port_mmio + PORT_SCR_ERR); /* clear port IRQ */ tmp = readl(port_mmio + PORT_IRQ_STAT); - dev_dbg(dev, "PORT_IRQ_STAT 0x%x\n", tmp); + dev_dbg(ap->host->dev, "PORT_IRQ_STAT 0x%x\n", tmp); if (tmp) writel(tmp, port_mmio + PORT_IRQ_STAT); - writel(1 << port_no, mmio + HOST_IRQ_STAT); + writel(1 << ap->port_no, hpriv->mmio + HOST_IRQ_STAT); +} - /* mark esata ports */ - tmp = readl(port_mmio + PORT_CMD); - if ((tmp & PORT_CMD_ESP) && (hpriv->cap & HOST_CAP_SXS)) - ap->pflags |= ATA_PFLAG_EXTERNAL; +static void ahci_port_init(struct device *dev, struct ata_port *ap, + int port_no, void __iomem *mmio, + void __iomem *port_mmio) +{ + const char *emsg = NULL; + int rc; + + /* make sure port is not active */ + rc = ahci_deinit_port(ap, &emsg); + if (rc) + dev_warn(dev, "%s (%d)\n", emsg, rc); + + ahci_port_clear_pending_irq(ap); } void ahci_init_controller(struct ata_host *host) @@ -1319,6 +1323,10 @@ static void ahci_dev_config(struct ata_device *dev) { struct ahci_host_priv *hpriv = dev->link->ap->host->private_data; + if ((dev->class == ATA_DEV_ATAPI) && + (hpriv->flags & AHCI_HFLAG_ATAPI_DMA_QUIRK)) + dev->quirks |= ATA_QUIRK_ATAPI_MOD16_DMA; + if (hpriv->flags & AHCI_HFLAG_SECT255) { dev->max_sectors = 255; ata_dev_info(dev, @@ -1403,7 +1411,7 @@ EXPORT_SYMBOL_GPL(ahci_kick_engine); static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp, struct ata_taskfile *tf, int is_cmd, u16 flags, - unsigned long timeout_msec) + unsigned int timeout_msec) { const u32 cmd_fis_len = 5; /* five dwords */ struct ahci_port_priv *pp = ap->private_data; @@ -1448,7 +1456,8 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class, struct ahci_host_priv *hpriv = ap->host->private_data; struct ahci_port_priv *pp = ap->private_data; const char *reason = NULL; - unsigned long now, msecs; + unsigned long now; + unsigned int msecs; struct ata_taskfile tf; bool fbs_disabled = false; int rc; @@ -1587,7 +1596,7 @@ static int ahci_pmp_retry_softreset(struct ata_link *link, unsigned int *class, int ahci_do_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline, bool *online) { - const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); + const unsigned int *timing = sata_ehc_deb_timing(&link->eh_context); struct ata_port *ap = link->ap; struct ahci_port_priv *pp = ap->private_data; struct ahci_host_priv *hpriv = ap->host->private_data; @@ -1602,6 +1611,8 @@ int ahci_do_hardreset(struct ata_link *link, unsigned int *class, tf.status = ATA_BUSY; ata_tf_to_fis(&tf, 0, 0, d2h_fis); + ahci_port_clear_pending_irq(ap); + rc = sata_link_hardreset(link, timing, deadline, online, ahci_check_ready); @@ -2070,13 +2081,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; @@ -2090,7 +2094,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; } @@ -2113,12 +2116,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) @@ -2153,6 +2154,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); @@ -2177,6 +2179,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); @@ -2615,8 +2618,8 @@ void ahci_print_info(struct ata_host *host, const char *scc_s) speed_s = "?"; dev_info(host->dev, - "AHCI %02x%02x.%02x%02x " - "%u slots %u ports %s Gbps 0x%x impl %s mode\n" + "AHCI vers %02x%02x.%02x%02x, " + "%u command slots, %s Gbps, %s mode\n" , (vers >> 24) & 0xff, @@ -2625,12 +2628,18 @@ void ahci_print_info(struct ata_host *host, const char *scc_s) vers & 0xff, ((cap >> 8) & 0x1f) + 1, - (cap & 0x1f) + 1, speed_s, - impl, scc_s); dev_info(host->dev, + "%u/%u ports implemented (port mask 0x%x)\n" + , + + hweight32(impl), + (cap & 0x1f) + 1, + impl); + + dev_info(host->dev, "flags: " "%s%s%s%s%s%s%s" "%s%s%s%s%s%s%s" @@ -2718,7 +2727,7 @@ static int ahci_host_activate_multi_irqs(struct ata_host *host, if (rc) return rc; - ata_port_desc(host->ports[i], "irq %d", irq); + ata_port_desc_misc(host->ports[i], irq); } return ata_host_register(host, sht); |
