aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ahci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r--drivers/ata/ahci.c48
1 files changed, 12 insertions, 36 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index abfb72aae3de..10bc3f64c453 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -239,8 +239,6 @@ static void ahci_freeze(struct ata_port *ap);
239static void ahci_thaw(struct ata_port *ap); 239static void ahci_thaw(struct ata_port *ap);
240static void ahci_pmp_attach(struct ata_port *ap); 240static void ahci_pmp_attach(struct ata_port *ap);
241static void ahci_pmp_detach(struct ata_port *ap); 241static void ahci_pmp_detach(struct ata_port *ap);
242static int ahci_pmp_read(struct ata_device *dev, int pmp, int reg, u32 *r_val);
243static int ahci_pmp_write(struct ata_device *dev, int pmp, int reg, u32 val);
244static void ahci_error_handler(struct ata_port *ap); 242static void ahci_error_handler(struct ata_port *ap);
245static void ahci_vt8251_error_handler(struct ata_port *ap); 243static void ahci_vt8251_error_handler(struct ata_port *ap);
246static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); 244static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
@@ -297,8 +295,6 @@ static const struct ata_port_operations ahci_ops = {
297 295
298 .pmp_attach = ahci_pmp_attach, 296 .pmp_attach = ahci_pmp_attach,
299 .pmp_detach = ahci_pmp_detach, 297 .pmp_detach = ahci_pmp_detach,
300 .pmp_read = ahci_pmp_read,
301 .pmp_write = ahci_pmp_write,
302 298
303#ifdef CONFIG_PM 299#ifdef CONFIG_PM
304 .port_suspend = ahci_port_suspend, 300 .port_suspend = ahci_port_suspend,
@@ -333,8 +329,6 @@ static const struct ata_port_operations ahci_vt8251_ops = {
333 329
334 .pmp_attach = ahci_pmp_attach, 330 .pmp_attach = ahci_pmp_attach,
335 .pmp_detach = ahci_pmp_detach, 331 .pmp_detach = ahci_pmp_detach,
336 .pmp_read = ahci_pmp_read,
337 .pmp_write = ahci_pmp_write,
338 332
339#ifdef CONFIG_PM 333#ifdef CONFIG_PM
340 .port_suspend = ahci_port_suspend, 334 .port_suspend = ahci_port_suspend,
@@ -1421,12 +1415,17 @@ static void ahci_port_intr(struct ata_port *ap)
1421 struct ata_eh_info *ehi = &ap->link.eh_info; 1415 struct ata_eh_info *ehi = &ap->link.eh_info;
1422 struct ahci_port_priv *pp = ap->private_data; 1416 struct ahci_port_priv *pp = ap->private_data;
1423 struct ahci_host_priv *hpriv = ap->host->private_data; 1417 struct ahci_host_priv *hpriv = ap->host->private_data;
1418 int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING);
1424 u32 status, qc_active; 1419 u32 status, qc_active;
1425 int rc, known_irq = 0; 1420 int rc, known_irq = 0;
1426 1421
1427 status = readl(port_mmio + PORT_IRQ_STAT); 1422 status = readl(port_mmio + PORT_IRQ_STAT);
1428 writel(status, port_mmio + PORT_IRQ_STAT); 1423 writel(status, port_mmio + PORT_IRQ_STAT);
1429 1424
1425 /* ignore BAD_PMP while resetting */
1426 if (unlikely(resetting))
1427 status &= ~PORT_IRQ_BAD_PMP;
1428
1430 if (unlikely(status & PORT_IRQ_ERROR)) { 1429 if (unlikely(status & PORT_IRQ_ERROR)) {
1431 ahci_error_intr(ap, status); 1430 ahci_error_intr(ap, status);
1432 return; 1431 return;
@@ -1464,6 +1463,13 @@ static void ahci_port_intr(struct ata_port *ap)
1464 qc_active = readl(port_mmio + PORT_CMD_ISSUE); 1463 qc_active = readl(port_mmio + PORT_CMD_ISSUE);
1465 1464
1466 rc = ata_qc_complete_multiple(ap, qc_active, NULL); 1465 rc = ata_qc_complete_multiple(ap, qc_active, NULL);
1466
1467 /* If resetting, spurious or invalid completions are expected,
1468 * return unconditionally.
1469 */
1470 if (resetting)
1471 return;
1472
1467 if (rc > 0) 1473 if (rc > 0)
1468 return; 1474 return;
1469 if (rc < 0) { 1475 if (rc < 0) {
@@ -1701,36 +1707,6 @@ static void ahci_pmp_detach(struct ata_port *ap)
1701 writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); 1707 writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
1702} 1708}
1703 1709
1704static int ahci_pmp_read(struct ata_device *dev, int pmp, int reg, u32 *r_val)
1705{
1706 struct ata_port *ap = dev->link->ap;
1707 struct ata_taskfile tf;
1708 int rc;
1709
1710 ahci_kick_engine(ap, 0);
1711
1712 sata_pmp_read_init_tf(&tf, dev, pmp, reg);
1713 rc = ahci_exec_polled_cmd(ap, SATA_PMP_CTRL_PORT, &tf, 1, 0,
1714 SATA_PMP_SCR_TIMEOUT);
1715 if (rc == 0) {
1716 ahci_tf_read(ap, &tf);
1717 *r_val = sata_pmp_read_val(&tf);
1718 }
1719 return rc;
1720}
1721
1722static int ahci_pmp_write(struct ata_device *dev, int pmp, int reg, u32 val)
1723{
1724 struct ata_port *ap = dev->link->ap;
1725 struct ata_taskfile tf;
1726
1727 ahci_kick_engine(ap, 0);
1728
1729 sata_pmp_write_init_tf(&tf, dev, pmp, reg, val);
1730 return ahci_exec_polled_cmd(ap, SATA_PMP_CTRL_PORT, &tf, 1, 0,
1731 SATA_PMP_SCR_TIMEOUT);
1732}
1733
1734static int ahci_port_resume(struct ata_port *ap) 1710static int ahci_port_resume(struct ata_port *ap)
1735{ 1711{
1736 ahci_power_up(ap); 1712 ahci_power_up(ap);