diff options
| -rw-r--r-- | drivers/ata/sata_mv.c | 84 |
1 files changed, 48 insertions, 36 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 31e42deb746f..803578ef22f8 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
| @@ -1591,25 +1591,22 @@ static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap) | |||
| 1591 | return qc; | 1591 | return qc; |
| 1592 | } | 1592 | } |
| 1593 | 1593 | ||
| 1594 | static void mv_unexpected_intr(struct ata_port *ap) | 1594 | static void mv_unexpected_intr(struct ata_port *ap, int edma_was_enabled) |
| 1595 | { | 1595 | { |
| 1596 | struct mv_port_priv *pp = ap->private_data; | ||
| 1597 | struct ata_eh_info *ehi = &ap->link.eh_info; | 1596 | struct ata_eh_info *ehi = &ap->link.eh_info; |
| 1598 | char *when = ""; | 1597 | char *when = "idle"; |
| 1599 | 1598 | ||
| 1600 | /* | ||
| 1601 | * We got a device interrupt from something that | ||
| 1602 | * was supposed to be using EDMA or polling. | ||
| 1603 | */ | ||
| 1604 | ata_ehi_clear_desc(ehi); | 1599 | ata_ehi_clear_desc(ehi); |
| 1605 | if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { | 1600 | if (!ap || (ap->flags & ATA_FLAG_DISABLED)) { |
| 1606 | when = " while EDMA enabled"; | 1601 | when = "disabled"; |
| 1602 | } else if (edma_was_enabled) { | ||
| 1603 | when = "EDMA enabled"; | ||
| 1607 | } else { | 1604 | } else { |
| 1608 | struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag); | 1605 | struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag); |
| 1609 | if (qc && (qc->tf.flags & ATA_TFLAG_POLLING)) | 1606 | if (qc && (qc->tf.flags & ATA_TFLAG_POLLING)) |
| 1610 | when = " while polling"; | 1607 | when = "polling"; |
| 1611 | } | 1608 | } |
| 1612 | ata_ehi_push_desc(ehi, "unexpected device interrupt%s", when); | 1609 | ata_ehi_push_desc(ehi, "unexpected device interrupt while %s", when); |
| 1613 | ehi->err_mask |= AC_ERR_OTHER; | 1610 | ehi->err_mask |= AC_ERR_OTHER; |
| 1614 | ehi->action |= ATA_EH_RESET; | 1611 | ehi->action |= ATA_EH_RESET; |
| 1615 | ata_port_freeze(ap); | 1612 | ata_port_freeze(ap); |
| @@ -1807,6 +1804,42 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp | |||
| 1807 | port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); | 1804 | port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); |
| 1808 | } | 1805 | } |
| 1809 | 1806 | ||
| 1807 | static void mv_port_intr(struct ata_port *ap, u32 port_cause) | ||
| 1808 | { | ||
| 1809 | struct mv_port_priv *pp; | ||
| 1810 | int edma_was_enabled; | ||
| 1811 | |||
| 1812 | if (!ap || (ap->flags & ATA_FLAG_DISABLED)) { | ||
| 1813 | mv_unexpected_intr(ap, 0); | ||
| 1814 | return; | ||
| 1815 | } | ||
| 1816 | /* | ||
| 1817 | * Grab a snapshot of the EDMA_EN flag setting, | ||
| 1818 | * so that we have a consistent view for this port, | ||
| 1819 | * even if something we call of our routines changes it. | ||
| 1820 | */ | ||
| 1821 | pp = ap->private_data; | ||
| 1822 | edma_was_enabled = (pp->pp_flags & MV_PP_FLAG_EDMA_EN); | ||
| 1823 | /* | ||
| 1824 | * Process completed CRPB response(s) before other events. | ||
| 1825 | */ | ||
| 1826 | if (edma_was_enabled && (port_cause & DONE_IRQ)) { | ||
| 1827 | mv_process_crpb_entries(ap, pp); | ||
| 1828 | } | ||
| 1829 | /* | ||
| 1830 | * Handle chip-reported errors, or continue on to handle PIO. | ||
| 1831 | */ | ||
| 1832 | if (unlikely(port_cause & ERR_IRQ)) { | ||
| 1833 | mv_err_intr(ap); | ||
| 1834 | } else if (!edma_was_enabled) { | ||
| 1835 | struct ata_queued_cmd *qc = mv_get_active_qc(ap); | ||
| 1836 | if (qc) | ||
| 1837 | ata_sff_host_intr(ap, qc); | ||
| 1838 | else | ||
| 1839 | mv_unexpected_intr(ap, edma_was_enabled); | ||
| 1840 | } | ||
| 1841 | } | ||
| 1842 | |||
| 1810 | /** | 1843 | /** |
| 1811 | * mv_host_intr - Handle all interrupts on the given host controller | 1844 | * mv_host_intr - Handle all interrupts on the given host controller |
| 1812 | * @host: host specific structure | 1845 | * @host: host specific structure |
| @@ -1823,7 +1856,6 @@ static int mv_host_intr(struct ata_host *host, u32 main_irq_cause) | |||
| 1823 | 1856 | ||
| 1824 | for (port = 0; port < hpriv->n_ports; port++) { | 1857 | for (port = 0; port < hpriv->n_ports; port++) { |
| 1825 | struct ata_port *ap = host->ports[port]; | 1858 | struct ata_port *ap = host->ports[port]; |
| 1826 | struct mv_port_priv *pp; | ||
| 1827 | unsigned int p, shift, hardport, port_cause; | 1859 | unsigned int p, shift, hardport, port_cause; |
| 1828 | 1860 | ||
| 1829 | MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); | 1861 | MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); |
| @@ -1865,32 +1897,12 @@ static int mv_host_intr(struct ata_host *host, u32 main_irq_cause) | |||
| 1865 | writelfl(~ack_irqs, hc_mmio + HC_IRQ_CAUSE_OFS); | 1897 | writelfl(~ack_irqs, hc_mmio + HC_IRQ_CAUSE_OFS); |
| 1866 | handled = 1; | 1898 | handled = 1; |
| 1867 | } | 1899 | } |
| 1868 | port_cause = (main_irq_cause >> shift) & (DONE_IRQ | ERR_IRQ); | ||
| 1869 | if (!port_cause) | ||
| 1870 | continue; | ||
| 1871 | /* | ||
| 1872 | * Process completed CRPB response(s) before other events. | ||
| 1873 | */ | ||
| 1874 | pp = ap->private_data; | ||
| 1875 | if (port_cause & DONE_IRQ) { | ||
| 1876 | if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) | ||
| 1877 | mv_process_crpb_entries(ap, pp); | ||
| 1878 | } | ||
| 1879 | /* | 1900 | /* |
| 1880 | * Handle chip-reported errors, or continue on to handle PIO. | 1901 | * Handle interrupts signalled for this port: |
| 1881 | */ | 1902 | */ |
| 1882 | if (unlikely(port_cause & ERR_IRQ)) { | 1903 | port_cause = (main_irq_cause >> shift) & (DONE_IRQ | ERR_IRQ); |
| 1883 | mv_err_intr(ap); | 1904 | if (port_cause) |
| 1884 | } else { | 1905 | mv_port_intr(ap, port_cause); |
| 1885 | if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) { | ||
| 1886 | struct ata_queued_cmd *qc = mv_get_active_qc(ap); | ||
| 1887 | if (qc) { | ||
| 1888 | ata_sff_host_intr(ap, qc); | ||
| 1889 | continue; | ||
| 1890 | } | ||
| 1891 | mv_unexpected_intr(ap); | ||
| 1892 | } | ||
| 1893 | } | ||
| 1894 | } | 1906 | } |
| 1895 | return handled; | 1907 | return handled; |
| 1896 | } | 1908 | } |
