aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorMark Lord <liml@rtr.ca>2008-05-19 09:01:24 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-05-19 17:30:28 -0400
commit06aaca3f6301d04463b1ee0eb75c0352147159f2 (patch)
treee4057424492a9237c736ed216c6df95a03da34ca /drivers/ata
parent96e2c487933e5f69e98fffdcae2c35c78a671c07 (diff)
sata_mv: ensure empty request queue for FBS-NCQ EH
Check for an empty request queue before stopping EDMA after a FBS-NCQ error, as per recommendation from the Marvell datasheet. This ensures that the EDMA won't suddenly become active again just after our subsequent check of the empty/idle bits. Also bump DRV_VERSION. Signed-off-by: Mark Lord <mlord@pobox.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/sata_mv.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 2d8a7e894b7b..fb81f0c7a8c2 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -72,7 +72,7 @@
72#include <linux/libata.h> 72#include <linux/libata.h>
73 73
74#define DRV_NAME "sata_mv" 74#define DRV_NAME "sata_mv"
75#define DRV_VERSION "1.20" 75#define DRV_VERSION "1.21"
76 76
77enum { 77enum {
78 /* BAR's are enumerated in terms of pci_resource_start() terms */ 78 /* BAR's are enumerated in terms of pci_resource_start() terms */
@@ -1695,6 +1695,18 @@ static void mv_pmp_eh_prep(struct ata_port *ap, unsigned int pmp_map)
1695 } 1695 }
1696} 1696}
1697 1697
1698static int mv_req_q_empty(struct ata_port *ap)
1699{
1700 void __iomem *port_mmio = mv_ap_base(ap);
1701 u32 in_ptr, out_ptr;
1702
1703 in_ptr = (readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS)
1704 >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
1705 out_ptr = (readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS)
1706 >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
1707 return (in_ptr == out_ptr); /* 1 == queue_is_empty */
1708}
1709
1698static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap) 1710static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap)
1699{ 1711{
1700 struct mv_port_priv *pp = ap->private_data; 1712 struct mv_port_priv *pp = ap->private_data;
@@ -1728,7 +1740,7 @@ static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap)
1728 ap->qc_active, failed_links, 1740 ap->qc_active, failed_links,
1729 ap->nr_active_links); 1741 ap->nr_active_links);
1730 1742
1731 if (ap->nr_active_links <= failed_links) { 1743 if (ap->nr_active_links <= failed_links && mv_req_q_empty(ap)) {
1732 mv_process_crpb_entries(ap, pp); 1744 mv_process_crpb_entries(ap, pp);
1733 mv_stop_edma(ap); 1745 mv_stop_edma(ap);
1734 mv_eh_freeze(ap); 1746 mv_eh_freeze(ap);