Re: [RFC 3/6] bidi support: bidirectional request

2007-01-23 Thread Benny Halevy
James Bottomley wrote:
 On Mon, 2007-01-22 at 01:25 +0200, Boaz Harrosh wrote:
 - 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.
 
 Actually, this approach looks to be a bit too narrow.  You seem to be
 predicating on the idea that the bidirectional will transfer in and out
 of the same area.  For some of the frame in/frame out stuff, we probably
 need the read and write areas for the bidirectional request to be
 separated.

Hmm, our proposal introduces two separate and independent i/o areas.
One used for uni-directional transfers and for bidi data output, the
other is used for bidi data input so we're in agreement.

Benny

 

-
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 3/6] bidi support: bidirectional request

2007-01-22 Thread James Bottomley
On Mon, 2007-01-22 at 01:25 +0200, Boaz Harrosh wrote:
 - 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.

Actually, this approach looks to be a bit too narrow.  You seem to be
predicating on the idea that the bidirectional will transfer in and out
of the same area.  For some of the frame in/frame out stuff, we probably
need the read and write areas for the bidirectional request to be
separated.

James


-
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 3/6] bidi support: bidirectional request

2007-01-21 Thread Boaz Harrosh
- 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);
+}
+