- Instantiate another request_io_part in request for bidi_read.
- Define Implement new API for accessing bidi parts.
- API to Build bidi requests and map to sglists.
- Define new end_that_request_block() function to end a complete request.
Signed-off-by: Benny Halevy [EMAIL PROTECTED]
Signed-off-by: Boaz Harrosh [EMAIL PROTECTED]
---
block/elevator.c |7 +---
block/ll_rw_blk.c | 113 ++--
include/linux/blkdev.h | 49 -
3 files changed, 149 insertions(+), 20 deletions(-)
diff --git a/block/elevator.c b/block/elevator.c
index 0e9ea69..53b552e 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -741,14 +741,9 @@ struct request *elv_next_request(request
rq = NULL;
break;
} else if (ret == BLKPREP_KILL) {
- int nr_bytes = rq_uni(rq)-hard_nr_sectors 9;
-
- if (!nr_bytes)
- nr_bytes = rq_uni(rq)-data_len;
-
blkdev_dequeue_request(rq);
rq-cmd_flags |= REQ_QUIET;
- end_that_request_chunk(rq, 0, nr_bytes);
+ end_that_request_block(rq, 0);
end_that_request_last(rq, 0);
} else {
printk(KERN_ERR %s: bad return=%d\n, __FUNCTION__,
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 7d46f6a..1358b35 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -261,6 +261,7 @@ static void rq_init(request_queue_t *q,
rq-end_io_data = NULL;
rq-completion_data = NULL;
rq_init_io_part(rq-uni);
+ rq_init_io_part(rq-bidi_read);
}
/**
@@ -1312,15 +1313,16 @@ static int blk_hw_contig_segment(request
}
/*
- * map a request to scatterlist, return number of sg entries setup. Caller
- * must make sure sg can hold rq-nr_phys_segments entries
+ * map a request_io_part to scatterlist, return number of sg entries setup.
+ * Caller must make sure sg can hold rq_io(rq, dir)-nr_phys_segments entries
*/
-int blk_rq_map_sg(request_queue_t *q, struct request *rq, struct scatterlist
*sg)
+int blk_rq_map_sg_bidi(request_queue_t *q, struct request *rq,
+ struct scatterlist *sg, enum dma_data_direction dir)
{
struct bio_vec *bvec, *bvprv;
struct bio *bio;
int nsegs, i, cluster;
- struct request_io_part* req_io = rq_uni(rq);
+ struct request_io_part* req_io = rq_io(rq, dir);
nsegs = 0;
cluster = q-queue_flags (1 QUEUE_FLAG_CLUSTER);
@@ -1362,6 +1364,17 @@ new_segment:
return nsegs;
}
+EXPORT_SYMBOL(blk_rq_map_sg_bidi);
+
+/*
+ * map a request to scatterlist, return number of sg entries setup. Caller
+ * must make sure sg can hold rq-nr_phys_segments entries
+ */
+int blk_rq_map_sg(request_queue_t *q, struct request *rq, struct scatterlist
*sg)
+{
+ return blk_rq_map_sg_bidi(q, rq, sg, rq-data_dir);
+}
+
EXPORT_SYMBOL(blk_rq_map_sg);
/*
@@ -2561,15 +2574,18 @@ int blk_rq_unmap_user(struct bio *bio)
EXPORT_SYMBOL(blk_rq_unmap_user);
/**
- * blk_rq_map_kern - map kernel data to a request, for REQ_BLOCK_PC usage
+ * blk_rq_map_kern_bidi - maps kernel data to a request_io_part, for BIDI usage
* @q: request queue where request should be inserted
* @rq:request to fill
* @kbuf: the kernel buffer
* @len: length of user data
* @gfp_mask: memory allocation flags
+ * @dir:if it is a BIDIRECTIONAL request than DMA_TO_DEVICE to prepare
+ * the bidi_write side or DMA_FROM_DEVICE to prepare the bidi_read
+ * side, else it should be same as req-data_dir
*/
-int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf,
- unsigned int len, gfp_t gfp_mask)
+int blk_rq_map_kern_bidi(request_queue_t *q, struct request *rq, void *kbuf,
+ unsigned int len, gfp_t gfp_mask, enum dma_data_direction dir)
{
struct bio *bio;
@@ -2582,14 +2598,30 @@ int blk_rq_map_kern(request_queue_t *q,
if (IS_ERR(bio))
return PTR_ERR(bio);
- if (rq_uni_write_dir(rq) == WRITE)
+ if (dma_write_dir(dir))
bio-bi_rw |= (1 BIO_RW);
- blk_rq_bio_prep(q, rq, bio);
+ blk_rq_bio_prep_bidi(q, rq, bio ,dir);
rq-buffer = rq-data = NULL;
return 0;
}
+EXPORT_SYMBOL(blk_rq_map_kern_bidi);
+
+/**
+ * blk_rq_map_kern - map kernel data to a request, for REQ_BLOCK_PC usage
+ * @q: request queue where request should be inserted
+ * @rq:request to fill
+ * @kbuf: the kernel buffer
+ * @len: length of user data
+ * @gfp_mask: memory allocation flags
+ */
+int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf,
+ unsigned int len, gfp_t gfp_mask)
+{
+ return blk_rq_map_kern_bidi( q, rq, kbuf, len, gfp_mask, rq-data_dir);
+}
+