patch-2.3.99-pre4 linux/drivers/block/paride/pf.c

Next file: linux/drivers/block/rd.c
Previous file: linux/drivers/block/paride/pd.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre3/linux/drivers/block/paride/pf.c linux/drivers/block/paride/pf.c
@@ -339,9 +339,62 @@
         }
 } 
 
+static inline int pf_new_segment(request_queue_t *q, struct request *req, int max_segments)
+{
+	if (max_segments > cluster)
+		max_segments = cluster;
+
+	if (req->nr_segments < max_segments) {
+		req->nr_segments++;
+		q->elevator.nr_segments++;
+		return 1;
+	}
+	return 0;
+}
+
+static int pf_back_merge_fn(request_queue_t *q, struct request *req, 
+			    struct buffer_head *bh, int max_segments)
+{
+	if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data)
+		return 1;
+	return pf_new_segment(q, req, max_segments);
+}
+
+static int pf_front_merge_fn(request_queue_t *q, struct request *req, 
+			     struct buffer_head *bh, int max_segments)
+{
+	if (bh->b_data + bh->b_size == req->bh->b_data)
+		return 1;
+	return pf_new_segment(q, req, max_segments);
+}
+
+static int pf_merge_requests_fn(request_queue_t *q, struct request *req,
+				struct request *next, int max_segments)
+{
+	int total_segments = req->nr_segments + next->nr_segments;
+	int same_segment;
+
+	if (max_segments > cluster)
+		max_segments = cluster;
+
+	same_segment = 0;
+	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;
+
+	q->elevator.nr_segments -= same_segment;
+	req->nr_segments = total_segments;
+	return 1;
+}
+
 int pf_init (void)      /* preliminary initialisation */
 
 {       int i;
+	request_queue_t * q; 
 
 	if (disable) return -1;
 
@@ -355,7 +408,11 @@
                         major);
                 return -1;
         }
-	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
+	q = BLK_DEFAULT_QUEUE(MAJOR_NR);
+	blk_init_queue(q, DEVICE_REQUEST);
+	q->back_merge_fn = pf_back_merge_fn;
+	q->front_merge_fn = pf_front_merge_fn;
+	q->merge_requests_fn = pf_merge_requests_fn;
         read_ahead[MAJOR_NR] = 8;       /* 8 sector (4kB) read ahead */
         
 	for (i=0;i<PF_UNITS;i++) pf_blocksizes[i] = 1024;
@@ -849,7 +906,6 @@
 static void do_pf_request (request_queue_t * q)
 
 {       struct buffer_head * bh;
-	struct request * req;
 	int unit;
 
         if (pf_busy) return;
@@ -859,12 +915,10 @@
 
         pf_unit = unit = DEVICE_NR(CURRENT->rq_dev);
         pf_block = CURRENT->sector;
-        pf_count = CURRENT->nr_sectors;
+        pf_run = CURRENT->nr_sectors;
+        pf_count = CURRENT->current_nr_sectors;
 
 	bh = CURRENT->bh;
-	req = CURRENT;
-	if (bh->b_reqnext)
-		printk("%s: OUCH: b_reqnext != NULL\n",PF.name);
 
         if ((pf_unit >= PF_UNITS) || (pf_block+pf_count > PF.capacity)) {
                 end_request(0);
@@ -872,14 +926,6 @@
         }
 
 	pf_cmd = CURRENT->cmd;
-	pf_run = pf_count;
-        while ((pf_run <= cluster) &&
-	       (req = blkdev_next_request(req)) && 
-	       (pf_block+pf_run == req->sector) &&
-	       (pf_cmd == req->cmd) &&
-	       (pf_unit == DEVICE_NR(req->rq_dev)))
-			pf_run += req->nr_sectors;
-
         pf_buf = CURRENT->buffer;
         pf_retries = 0;
 
@@ -912,7 +958,7 @@
 		printk("%s: OUCH: request list changed unexpectedly\n",
 			PF.name);
 
-	pf_count = CURRENT->nr_sectors;
+	pf_count = CURRENT->current_nr_sectors;
 	pf_buf = CURRENT->buffer;
 	spin_unlock_irqrestore(&io_request_lock,saved_flags);
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)