X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fscsi%2Fscsi_tgt_lib.c;h=93ece8f4e5dea391c07c8a4241df9d180489c869;hb=4a03d90e35bc5273d27301fa669d4b2103196f94;hp=371b69c110bcc5403b81d4b046ba31dc9888cc9e;hpb=e8b495fe09bc793ae26774e7b2667f7f658d56e2;p=linux-2.6-omap-h63xx.git diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index 371b69c110b..93ece8f4e5d 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "scsi_tgt_priv.h" @@ -46,6 +47,7 @@ struct scsi_tgt_cmd { struct list_head hash_list; struct request *rq; + u64 itn_id; u64 tag; }; @@ -178,19 +180,20 @@ static void scsi_tgt_cmd_destroy(struct work_struct *work) container_of(work, struct scsi_tgt_cmd, work); struct scsi_cmnd *cmd = tcmd->rq->special; - dprintk("cmd %p %d %lu\n", cmd, cmd->sc_data_direction, + dprintk("cmd %p %d %u\n", cmd, cmd->sc_data_direction, rq_data_dir(cmd->request)); scsi_unmap_user_pages(tcmd); scsi_host_put_command(scsi_tgt_cmd_to_host(cmd), cmd); } static void init_scsi_tgt_cmd(struct request *rq, struct scsi_tgt_cmd *tcmd, - u64 tag) + u64 itn_id, u64 tag) { struct scsi_tgt_queuedata *qdata = rq->q->queuedata; unsigned long flags; struct list_head *head; + tcmd->itn_id = itn_id; tcmd->tag = tag; tcmd->bio = NULL; INIT_WORK(&tcmd->work, scsi_tgt_cmd_destroy); @@ -234,7 +237,7 @@ int scsi_tgt_alloc_queue(struct Scsi_Host *shost) * command as is recvd to userspace. uspace can then make * sure we do not overload the HBA */ - q->nr_requests = shost->hostt->can_queue; + q->nr_requests = shost->can_queue; /* * We currently only support software LLDs so this does * not matter for now. Do we need this for the cards we support? @@ -301,14 +304,14 @@ EXPORT_SYMBOL_GPL(scsi_tgt_cmd_to_host); * @scsilun: scsi lun * @tag: unique value to identify this command for tmf */ -int scsi_tgt_queue_command(struct scsi_cmnd *cmd, struct scsi_lun *scsilun, - u64 tag) +int scsi_tgt_queue_command(struct scsi_cmnd *cmd, u64 itn_id, + struct scsi_lun *scsilun, u64 tag) { struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; int err; - init_scsi_tgt_cmd(cmd->request, tcmd, tag); - err = scsi_tgt_uspace_send_cmd(cmd, scsilun, tag); + init_scsi_tgt_cmd(cmd->request, tcmd, itn_id, tag); + err = scsi_tgt_uspace_send_cmd(cmd, itn_id, scsilun, tag); if (err) cmd_hashlist_del(cmd); @@ -324,12 +327,12 @@ static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd) { struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; - dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); + dprintk("cmd %p %u\n", cmd, rq_data_dir(cmd->request)); - scsi_tgt_uspace_send_status(cmd, tcmd->tag); + scsi_tgt_uspace_send_status(cmd, tcmd->itn_id, tcmd->tag); - if (cmd->request_buffer) - scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); + if (scsi_sglist(cmd)) + scsi_free_sgtable(cmd); queue_work(scsi_tgtd, &tcmd->work); } @@ -339,7 +342,7 @@ static int scsi_tgt_transfer_response(struct scsi_cmnd *cmd) struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); int err; - dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); + dprintk("cmd %p %u\n", cmd, rq_data_dir(cmd->request)); err = shost->hostt->transfer_response(cmd, scsi_tgt_cmd_done); switch (err) { @@ -362,16 +365,12 @@ static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask) cmd->request_bufflen = rq->data_len; - dprintk("cmd %p cnt %d %lu\n", cmd, cmd->use_sg, rq_data_dir(rq)); - count = blk_rq_map_sg(rq->q, rq, cmd->request_buffer); - if (likely(count <= cmd->use_sg)) { - cmd->use_sg = count; - return 0; - } - - eprintk("cmd %p cnt %d\n", cmd, cmd->use_sg); - scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); - return -EINVAL; + dprintk("cmd %p cnt %d %lu\n", cmd, scsi_sg_count(cmd), + rq_data_dir(rq)); + count = blk_rq_map_sg(rq->q, rq, scsi_sglist(cmd)); + BUG_ON(count > cmd->use_sg); + cmd->use_sg = count; + return 0; } /* TODO: test this crap and replace bio_map_user with new interface maybe */ @@ -459,7 +458,7 @@ static struct request *tgt_cmd_hash_lookup(struct request_queue *q, u64 tag) return rq; } -int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, +int scsi_tgt_kspace_exec(int host_no, u64 itn_id, int result, u64 tag, unsigned long uaddr, u32 len, unsigned long sense_uaddr, u32 sense_len, u8 rw) { @@ -493,8 +492,8 @@ int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, } cmd = rq->special; - dprintk("cmd %p scb %x result %d len %d bufflen %u %lu %x\n", - cmd, cmd->cmnd[0], result, len, cmd->request_bufflen, + dprintk("cmd %p scb %x result %d len %d bufflen %u %u %x\n", + cmd, cmd->cmnd[0], result, len, scsi_bufflen(cmd), rq_data_dir(rq), cmd->cmnd[0]); if (result == TASK_ABORTED) { @@ -541,21 +540,22 @@ done: return err; } -int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *shost, int function, u64 tag, - struct scsi_lun *scsilun, void *data) +int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *shost, u64 itn_id, + int function, u64 tag, struct scsi_lun *scsilun, + void *data) { int err; /* TODO: need to retry if this fails. */ - err = scsi_tgt_uspace_send_tsk_mgmt(shost->host_no, function, - tag, scsilun, data); + err = scsi_tgt_uspace_send_tsk_mgmt(shost->host_no, itn_id, + function, tag, scsilun, data); if (err < 0) eprintk("The task management request lost!\n"); return err; } EXPORT_SYMBOL_GPL(scsi_tgt_tsk_mgmt_request); -int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result) +int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 itn_id, u64 mid, int result) { struct Scsi_Host *shost; int err = -EINVAL; @@ -573,7 +573,60 @@ int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result) goto done; } - err = shost->hostt->tsk_mgmt_response(mid, result); + err = shost->transportt->tsk_mgmt_response(shost, itn_id, mid, result); +done: + scsi_host_put(shost); + return err; +} + +int scsi_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id, + char *initiator) +{ + int err; + + /* TODO: need to retry if this fails. */ + err = scsi_tgt_uspace_send_it_nexus_request(shost->host_no, itn_id, 0, + initiator); + if (err < 0) + eprintk("The i_t_neuxs request lost, %d %llx!\n", + shost->host_no, (unsigned long long)itn_id); + return err; +} +EXPORT_SYMBOL_GPL(scsi_tgt_it_nexus_create); + +int scsi_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id) +{ + int err; + + /* TODO: need to retry if this fails. */ + err = scsi_tgt_uspace_send_it_nexus_request(shost->host_no, + itn_id, 1, NULL); + if (err < 0) + eprintk("The i_t_neuxs request lost, %d %llx!\n", + shost->host_no, (unsigned long long)itn_id); + return err; +} +EXPORT_SYMBOL_GPL(scsi_tgt_it_nexus_destroy); + +int scsi_tgt_kspace_it_nexus_rsp(int host_no, u64 itn_id, int result) +{ + struct Scsi_Host *shost; + int err = -EINVAL; + + dprintk("%d %d%llx\n", host_no, result, (unsigned long long)itn_id); + + shost = scsi_host_lookup(host_no); + if (IS_ERR(shost)) { + printk(KERN_ERR "Could not find host no %d\n", host_no); + return err; + } + + if (!shost->uspace_req_q) { + printk(KERN_ERR "Not target scsi host %d\n", host_no); + goto done; + } + + err = shost->transportt->it_nexus_response(shost, itn_id, result); done: scsi_host_put(shost); return err;