From ac44e5b2ed62bf4acf9df84575d3f18c7a6fdf22 Mon Sep 17 00:00:00 2001
From: Jens Axboe <jens.axboe@oracle.com>
Date: Fri, 27 Mar 2009 10:43:52 +0100
Subject: [PATCH] cciss: fix residual count for block pc requests

We must complete the full request, so store the request count and then set
the ->data_len to the residual count from the hardware.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
---
 drivers/block/cciss.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 5d0e135824f9..f15b17708537 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1287,6 +1287,7 @@ static void cciss_softirq_done(struct request *rq)
 {
 	CommandList_struct *cmd = rq->completion_data;
 	ctlr_info_t *h = hba[cmd->ctlr];
+	unsigned int nr_bytes;
 	unsigned long flags;
 	u64bit temp64;
 	int i, ddir;
@@ -1308,7 +1309,14 @@ static void cciss_softirq_done(struct request *rq)
 	printk("Done with %p\n", rq);
 #endif				/* CCISS_DEBUG */
 
-	if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, blk_rq_bytes(rq)))
+	/*
+	 * Store the full size and set the residual count for pc requests
+	 */
+	nr_bytes = blk_rq_bytes(rq);
+	if (blk_pc_request(rq))
+		rq->data_len = cmd->err_info->ResidualCnt;
+
+	if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, nr_bytes))
 		BUG();
 
 	spin_lock_irqsave(&h->lock, flags);