diff options
author | Mark Lord <mlord@pobox.com> | 2006-03-21 21:11:53 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-03-21 21:11:53 -0500 |
commit | 806a6e7a9904d4a1dfd3fd79d373bf31d71d34cb (patch) | |
tree | a88aa5b3e7aa20fb144686b5b36ce88282f923ad | |
parent | a6cce2a79deefb33354561a064f0609a3b342829 (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.c | 5 |
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 | /** |