aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_mv.c
diff options
context:
space:
mode:
authorMark Lord <liml@rtr.ca>2008-05-02 02:14:02 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-05-06 11:37:42 -0400
commita90103298fd5ccd9a9df6d47bde9a3f371707037 (patch)
tree66ae5e04f34edbb8760b0e0cc64846bd462e759b /drivers/ata/sata_mv.c
parenteabd5eb1cb59bfb162e7aa23007248f2bb480816 (diff)
sata_mv new mv_port_intr function
Separate out the inner loop body of mv_host_intr() into it's own function called mv_port_intr(). This should help maintainabilty. Signed-off-by: Mark Lord <mlord@pobox.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r--drivers/ata/sata_mv.c84
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
1594static void mv_unexpected_intr(struct ata_port *ap) 1594static 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
1807static 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}