bsg bidirectional and variable length commands
Subsystems (4)
cover bsg bidirectional and variable length commands
There are three patches here to enable using BSG to send SCSI commands across iscsi TCP that are bidirectional and/or use variable length CDBs. They sit on top of 2.6.23-rc2 plus Mike's iscsi git plus the 12 core patches that Boaz has for bidirectional support.
They apply to stock 2.6.23-rc2 but I don't think it is worth anybody's time to take them yet. Instead, I think it makes sense for Boaz to hang onto these and submit them along as part of the bigger bidirectional support picture.
-- Pete
PATCH 1/3 bsg bidi block pc
Set cmd_type on rq->next_rq to BLOCK_PC so that scsi_init_sgtable knows to look at req->data_len rather than nr_sectors.
--- block/bsg.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
block/bsg.c +1 -0
@@ -278,6 +278,7 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr) ret = -ENOMEM ; goto out; } + next_rq->cmd_type =REQ_TYPE_BLOCK_PC ; rq->next_rq = next_rq; dxferp = (void *)(unsigned long )hdr->din_xferp;
Signature · 1 line
1.5.2.4
PATCH 2/3 iscsi tcp queue bidi
In reply to Pete WyckoffMark queue_flags that bidirectional is acceptable for iscsi_tcp, as BSG will check to make sure this bit is set.
--- drivers/scsi/iscsi_tcp.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
drivers/scsi/iscsi_tcp.c +7 -0
@@ -2205,6 +2205,12 @@ static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session)iscsi_session_teardown (cls_session); } +static int iscsi_tcp_slave_alloc (struct scsi_device *sdev) +{ +set_bit (QUEUE_FLAG_BIDI , &sdev->request_queue->queue_flags); +return 0 ; +} +static int iscsi_tcp_slave_configure (struct scsi_device *sdev) {blk_queue_bounce_limit (sdev->request_queue,BLK_BOUNCE_ANY );
@@ -2224,6 +2230,7 @@ static struct scsi_host_template iscsi_sht = { .eh_abort_handler = iscsi_eh_abort, .eh_host_reset_handler = iscsi_eh_host_reset, .use_clustering = DISABLE_CLUSTERING, + .slave_alloc = iscsi_tcp_slave_alloc, .slave_configure = iscsi_tcp_slave_configure, .proc_name = "iscsi_tcp", .this_id = -1,
Signature · 1 line
1.5.2.4
PATCH 3/3 varlen bsg submit
In reply to Pete WyckoffAccept variable length SCSI commands through BSG.
--- block/bsg.c | 19 +++++++++++++++---- 1 files changed, 15 insertions(+), 4 deletions(-)
block/bsg.c +15 -4
@@ -175,11 +175,22 @@ unlock:static int blk_fill_sgv4_hdr_rq (struct request_queue *q,struct request *rq,struct sg_io_v4 *hdr,int has_write_perm) { +int len = hdr->request_len; +memset (rq->cmd,0 ,BLK_MAX_CDB );/* ATAPI hates garbage after CDB */ if (copy_from_user (rq->cmd, (void *)(unsigned long )hdr->request, - hdr->request_len)) +min (len,BLK_MAX_CDB )))return -EFAULT ; +if (len >BLK_MAX_CDB ) { + rq->varlen_cdb_len = len; + rq->varlen_cdb =kmalloc (len,GFP_KERNEL ); +if (rq->varlen_cdb ==NULL ) +return -ENOMEM ; +if (copy_from_user (rq->varlen_cdb, + (void *)(unsigned long )hdr->request, len)) +return -EFAULT ; + }if (hdr->subprotocol ==BSG_SUB_PROTOCOL_SCSI_CMD ) {if (blk_verify_command (rq->cmd, has_write_perm))
@@ -190,7 +201,7 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,/* * fill in request structure */ - rq->cmd_len = hdr->request_len; + rq->cmd_len =min (len,BLK_MAX_CDB ); rq->cmd_type =REQ_TYPE_BLOCK_PC ; rq->timeout = (hdr->timeout *HZ ) /1000 ;
@@ -212,8 +223,6 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw)if (hdr->guard !='Q' )return -EINVAL ; -if (hdr->request_len >BLK_MAX_CDB ) -return -EINVAL ;if (hdr->dout_xfer_len > (q->max_sectors <<9 ) || hdr->din_xfer_len > (q->max_sectors <<9 ))return -EIO ;
@@ -303,6 +312,7 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr) }return rq; out: +kfree (rq->varlen_cdb);blk_put_request (rq);if (next_rq) {blk_rq_unmap_user (next_rq->bio);
@@ -443,6 +453,7 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, }blk_rq_unmap_user (bio); +kfree (rq->varlen_cdb);blk_put_request (rq);return ret;
Signature · 1 line
1.5.2.4