diff -ur --exclude-from /home/axboe/exclude /kt/linux-2.4.1-pre9/drivers/block/DAC960.c linux/drivers/block/DAC960.c
--- /kt/linux-2.4.1-pre9/drivers/block/DAC960.c	Sat Jan 20 04:14:06 2001
+++ linux/drivers/block/DAC960.c	Sat Jan 20 17:43:36 2001
@@ -1862,13 +1862,9 @@
   DAC960_Controller_T *Controller =
     (DAC960_Controller_T *) RequestQueue->queuedata;
   int TotalSegments = Request->nr_segments + NextRequest->nr_segments;
-  int SameSegment = 0;
   if (Request->bhtail->b_data + Request->bhtail->b_size
       == NextRequest->bh->b_data)
-    {
       TotalSegments--;
-      SameSegment = 1;
-    }
   if (TotalSegments > MaxSegments ||
       TotalSegments > Controller->DriverScatterGatherLimit)
     return false;
@@ -2831,6 +2827,7 @@
 static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader,
 						 boolean SuccessfulIO)
 {
+  blk_finished_io(BufferHeader->b_size >> 9);
   BufferHeader->b_end_io(BufferHeader, SuccessfulIO);
 }
 
diff -ur --exclude-from /home/axboe/exclude /kt/linux-2.4.1-pre9/drivers/block/cciss.c linux/drivers/block/cciss.c
--- /kt/linux-2.4.1-pre9/drivers/block/cciss.c	Thu Jan  4 21:50:12 2001
+++ linux/drivers/block/cciss.c	Sat Jan 20 17:43:54 2001
@@ -1086,6 +1086,7 @@
 	{
 		xbh = bh->b_reqnext; 
 		bh->b_reqnext = NULL; 
+		blk_finished_io(bh->b_size >> 9);
 		bh->b_end_io(bh, status);
 		bh = xbh;
 	}
diff -ur --exclude-from /home/axboe/exclude /kt/linux-2.4.1-pre9/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c
--- /kt/linux-2.4.1-pre9/drivers/block/cpqarray.c	Sat Jan 20 04:14:06 2001
+++ linux/drivers/block/cpqarray.c	Sat Jan 20 17:43:44 2001
@@ -376,12 +376,9 @@
 				 struct request *nxt, int max_segments)
 {
 	int total_segments = rq->nr_segments + nxt->nr_segments;
-	int same_segment = 0;
 
-	if (rq->bhtail->b_data + rq->bhtail->b_size == nxt->bh->b_data) {
+	if (rq->bhtail->b_data + rq->bhtail->b_size == nxt->bh->b_data)
 		total_segments--;
-		same_segment = 1;
-	}
 
 	if (total_segments > SG_MAX)
 		return 0;
@@ -909,17 +906,12 @@
 	struct buffer_head *bh;
 	struct request *creq;
 
-	if (!q)
-		BUG();
-	if (!h)
-		BUG();
-
-	if (q->plugged || list_empty(queue_head))
+	if (q->plugged || list_empty(queue_head)) {
+		start_io(h);
 		return;
+	}
 
 	creq = blkdev_entry_next_request(queue_head);
-	if (creq->rq_status != RQ_ACTIVE)
-		BUG();
 	if (creq->nr_segments > SG_MAX)
 		BUG();
 
@@ -927,6 +919,7 @@
 	{
 		printk(KERN_WARNING "doreq cmd for %d, %x at %p\n",
 				h->ctlr, creq->rq_dev, creq);
+		blkdev_dequeue_request(creq);
 		complete_buffers(creq->bh, 0);
 		start_io(h);
                 return;
@@ -961,11 +954,12 @@
 			c->req.sg[seg-1].size += bh->b_size;
 			lastdataend += bh->b_size;
 		} else {
+			if (seg == SG_MAX)
+				BUG();
 			c->req.sg[seg].size = bh->b_size;
 			c->req.sg[seg].addr = (__u32)virt_to_bus(bh->b_data);
 			lastdataend = bh->b_data + bh->b_size;
-			if (++seg == SG_MAX)
-				break;
+			seg++;
 		}
 		bh = bh->b_reqnext;
 	}
@@ -978,7 +972,7 @@
 	 * is now fully setup and there's nothing left.
          */
 	if (creq->nr_sectors != sect) {
-		printk("ida: %ld sectors remain\n", creq->nr_sectors);
+		printk("ida: %ld != %d sectors\n", creq->nr_sectors, sect);
 		BUG();
 	}
 
@@ -1037,6 +1031,7 @@
 		xbh = bh->b_reqnext;
 		bh->b_reqnext = NULL;
 		
+		blk_finished_io(bh->b_size >> 9);
 		bh->b_end_io(bh, ok);
 
 		bh = xbh;
diff -ur --exclude-from /home/axboe/exclude /kt/linux-2.4.1-pre9/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- /kt/linux-2.4.1-pre9/drivers/block/ll_rw_blk.c	Sat Jan 20 04:14:06 2001
+++ linux/drivers/block/ll_rw_blk.c	Sat Jan 20 19:26:33 2001
@@ -328,13 +328,9 @@
 				struct request *next, int max_segments)
 {
 	int total_segments = req->nr_segments + next->nr_segments;
-	int same_segment;
 
-	same_segment = 0;
-	if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) {
+	if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data)
 		total_segments--;
-		same_segment = 1;
-	}
     
 	if (total_segments > max_segments)
 		return 0;
@@ -1131,12 +1127,25 @@
 extern int stram_device_init (void);
 #endif
 
-/*
- * First step of what used to be end_request
+
+/**
+ * end_that_request_first - end I/O on one buffer.
+ * @req:      the request being processed
+ * @uptodate: 0 for I/O error
+ * @name:     the name printed for an I/O error
  *
- * 0 means continue with end_that_request_last,
- * 1 means we are done
- */
+ * Description:
+ *     Ends I/O on the first buffer attached to @req, and sets it up
+ *     for the next buffer_head (if any) in the cluster.
+ *     
+ * Return:
+ *     0 - we are done with this request, call end_that_request_last()
+ *     1 - still buffers pending for this request
+ *
+ * Caveat: 
+ *     Drivers implementing their own end_request handling must call
+ *     blk_finished_io() appropriately.
+ **/
 
 int end_that_request_first (struct request *req, int uptodate, char *name)
 {
