diff options
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r-- | drivers/ata/ahci.c | 48 |
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); | |||
239 | static void ahci_thaw(struct ata_port *ap); | 239 | static void ahci_thaw(struct ata_port *ap); |
240 | static void ahci_pmp_attach(struct ata_port *ap); | 240 | static void ahci_pmp_attach(struct ata_port *ap); |
241 | static void ahci_pmp_detach(struct ata_port *ap); | 241 | static void ahci_pmp_detach(struct ata_port *ap); |
242 | static int ahci_pmp_read(struct ata_device *dev, int pmp, int reg, u32 *r_val); | ||
243 | static int ahci_pmp_write(struct ata_device *dev, int pmp, int reg, u32 val); | ||
244 | static void ahci_error_handler(struct ata_port *ap); | 242 | static void ahci_error_handler(struct ata_port *ap); |
245 | static void ahci_vt8251_error_handler(struct ata_port *ap); | 243 | static void ahci_vt8251_error_handler(struct ata_port *ap); |
246 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); | 244 | static 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 | ||
1704 | static 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 | |||
1722 | static 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 | |||
1734 | static int ahci_port_resume(struct ata_port *ap) | 1710 | static int ahci_port_resume(struct ata_port *ap) |
1735 | { | 1711 | { |
1736 | ahci_power_up(ap); | 1712 | ahci_power_up(ap); |