aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Lord <mlord@pobox.com>2006-03-21 21:11:53 -0500
committerJeff Garzik <jeff@garzik.org>2006-03-21 21:11:53 -0500
commit806a6e7a9904d4a1dfd3fd79d373bf31d71d34cb (patch)
treea88aa5b3e7aa20fb144686b5b36ce88282f923ad
parenta6cce2a79deefb33354561a064f0609a3b342829 (diff)
[libata] sata_mv: off-by-1 fix
This patch addresses a number of weird behaviours observed for the sata_mv driver, by fixing an "off by one" bug in processing of the EDMA response queue. Basically, sata_mv was looking in the wrong place for command results, and this produced a lot of unpredictable behaviour. Signed-off-by: Mark Lord <mlord@pobox.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/scsi/sata_mv.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index e561281967dd..eed67ae2dc08 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -1263,6 +1263,7 @@ static u8 mv_get_crpb_status(struct ata_port *ap)
1263 void __iomem *port_mmio = mv_ap_base(ap); 1263 void __iomem *port_mmio = mv_ap_base(ap);
1264 struct mv_port_priv *pp = ap->private_data; 1264 struct mv_port_priv *pp = ap->private_data;
1265 u32 out_ptr; 1265 u32 out_ptr;
1266 u8 ata_status;
1266 1267
1267 out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); 1268 out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
1268 1269
@@ -1270,6 +1271,8 @@ static u8 mv_get_crpb_status(struct ata_port *ap)
1270 WARN_ON(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) != 1271 WARN_ON(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) !=
1271 pp->rsp_consumer); 1272 pp->rsp_consumer);
1272 1273
1274 ata_status = pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT;
1275
1273 /* increment our consumer index... */ 1276 /* increment our consumer index... */
1274 pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer); 1277 pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer);
1275 1278
@@ -1284,7 +1287,7 @@ static u8 mv_get_crpb_status(struct ata_port *ap)
1284 writelfl(out_ptr, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); 1287 writelfl(out_ptr, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
1285 1288
1286 /* Return ATA status register for completed CRPB */ 1289 /* Return ATA status register for completed CRPB */
1287 return (pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT); 1290 return ata_status;
1288} 1291}
1289 1292
1290/** 1293/**