From 1b516fab15c270ae258f6de5f2dc7eeff733d706 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 8 Aug 2009 11:52:46 +0000 Subject: [PATCH] Implemented SRPT command state management. The SRPT target code does no longer rely on the struct scst_cmd state managed by the SCST core. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1026 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- srpt/ToDo | 13 ++----------- srpt/src/ib_srpt.c | 35 +++++++++++++++++++++++++++++------ srpt/src/ib_srpt.h | 11 +++++++++++ 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/srpt/ToDo b/srpt/ToDo index 9353ef270..cd6d64cef 100644 --- a/srpt/ToDo +++ b/srpt/ToDo @@ -3,19 +3,10 @@ * https://wiki.openfabrics.org/tiki-index.php?page=SRPT+Installation -2. The SRPT driver directly uses the internal state of the SCST core target - state machine (scmnd->state field / SCST_CMD_STATE_* values), which is bad, - bad, bad and generally not acceptable. Only dev handler are allowed to use - them. This should be fixed: the SRPT driver should keep its internal state - in an SRPT-specific variable. For an example, see also the "Q2T_STATE_" - constants in the qla2x00t driver, and especially the function - q2t_do_ctio_completion(). - - -3. The initiator names supplied to the SCST core contain the target port name, +2. The initiator names supplied to the SCST core contain the target port name, which is wrong. Nobody identifies a man by the door through which he entered. Instead, a man has a name by which he is identified through his whole life. -4. Analyze and document the implications of +3. Analyze and document the implications of sdev->mr = ib_get_dma_mr(sdev->pd, IB_ACCESS_LOCAL_WRITE). diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index f0392f0ec..90ca5a679 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -861,8 +861,11 @@ static void srpt_abort_scst_cmd(struct srpt_device *sdev, struct scst_cmd *scmnd, bool tell_initiator) { + struct srpt_ioctx *ioctx; scst_data_direction dir; + ioctx = scst_cmd_get_tgt_priv(scmnd); + BUG_ON(!ioctx); dir = scst_cmd_get_data_direction(scmnd); if (dir != SCST_DATA_NONE) { dma_unmap_sg(sdev->device->dma_device, @@ -870,14 +873,20 @@ static void srpt_abort_scst_cmd(struct srpt_device *sdev, scst_cmd_get_sg_cnt(scmnd), scst_to_tgt_dma_dir(dir)); - if (scmnd->state == SCST_CMD_STATE_DATA_WAIT) { + if (ioctx->state == SRPT_STATE_NEED_DATA) { scst_rx_data(scmnd, tell_initiator ? SCST_RX_STATUS_ERROR : SCST_RX_STATUS_ERROR_FATAL, SCST_CONTEXT_THREAD); goto out; - } else if (scmnd->state == SCST_CMD_STATE_XMIT_WAIT) + } else if (ioctx->state == SRPT_STATE_PROCESSED) ; + else { + printk(KERN_ERR PFX + "unexpected cmd state %d (SCST) %d (SRPT)\n", + scmnd->state, ioctx->state); + WARN_ON("unexpected cmd state"); + } } scst_set_delivery_status(scmnd, SCST_CMD_DELIVERY_FAILED); @@ -1028,14 +1037,14 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, struct srpt_ioctx *ioctx) srpt_build_cmd_rsp(ch, ioctx, NO_SENSE, NO_ADD_SENSE, srp_cmd->tag); srp_rsp->status = SAM_STAT_TASK_SET_FULL; - goto send_rsp; + goto err; } if (indirect_desc) { srpt_build_cmd_rsp(ch, ioctx, NO_SENSE, NO_ADD_SENSE, srp_cmd->tag); srp_rsp->status = SAM_STAT_TASK_SET_FULL; - goto send_rsp; + goto err; } if (srp_cmd->buf_fmt & 0xf) @@ -1054,7 +1063,7 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, struct srpt_ioctx *ioctx) srpt_build_cmd_rsp(ch, ioctx, NO_SENSE, NO_ADD_SENSE, srp_cmd->tag); srp_rsp->status = SAM_STAT_TASK_SET_FULL; - goto send_rsp; + goto err; } ioctx->scmnd = scmnd; @@ -1088,9 +1097,13 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch, struct srpt_ioctx *ioctx) scst_cmd_init_done(scmnd, scst_estimate_context()); + WARN_ON(srp_rsp->opcode == SRP_RSP); + return 0; -send_rsp: +err: + WARN_ON(srp_rsp->opcode != SRP_RSP); + return -1; } @@ -1202,9 +1215,13 @@ static int srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch, goto err; } + WARN_ON(srp_tsk->opcode == SRP_RSP); + return 0; err: + WARN_ON(srp_tsk->opcode != SRP_RSP); + return -1; } @@ -1245,6 +1262,7 @@ static void srpt_handle_new_iu(struct srpt_rdma_ch *ch, ioctx->n_rdma_ius = 0; ioctx->rdma_ius = NULL; ioctx->scmnd = NULL; + ioctx->state = SRPT_STATE_NEW; srp_cmd = ioctx->buf; srp_rsp = ioctx->buf; @@ -2156,6 +2174,8 @@ static int srpt_rdy_to_xfer(struct scst_cmd *scmnd) else if (ch->state == RDMA_CHANNEL_CONNECTING) return SCST_TGT_RES_QUEUE_FULL; + ioctx->state = SRPT_STATE_NEED_DATA; + return srpt_xfer_data(ch, ioctx, scmnd); } @@ -2244,6 +2264,8 @@ static int srpt_xmit_response(struct scst_cmd *scmnd) } } + ioctx->state = SRPT_STATE_PROCESSED; + if (srpt_post_send(ch, ioctx, sizeof *srp_rsp + be32_to_cpu(srp_rsp->sense_data_len))) { @@ -2259,6 +2281,7 @@ out: out_aborted: ret = SCST_TGT_RES_SUCCESS; scst_set_delivery_status(scmnd, SCST_CMD_DELIVERY_ABORTED); + ioctx->state = SRPT_STATE_ABORTED; scst_tgt_cmd_done(scmnd, SCST_CONTEXT_SAME); goto out; } diff --git a/srpt/src/ib_srpt.h b/srpt/src/ib_srpt.h index 3f6253ba7..88989a197 100644 --- a/srpt/src/ib_srpt.h +++ b/srpt/src/ib_srpt.h @@ -106,6 +106,16 @@ struct rdma_iu { int mem_id; }; +/* Command states. */ +enum srpt_command_state { + SRPT_STATE_NEW = 0, /* New command being processed. */ + SRPT_STATE_PROCESSED = 1, /* Processing finished. */ + SRPT_STATE_NEED_DATA = 2, /* Data needed to continue. */ + SRPT_STATE_DATA_IN = 3, /* Data arrived and being processed. */ + SRPT_STATE_ABORTED = 4, /* Command aborted. */ +}; + +/* SRPT I/O context: SRPT-private data associated with a struct scst_cmd. */ struct srpt_ioctx { int index; void *buf; @@ -127,6 +137,7 @@ struct srpt_ioctx { struct srpt_rdma_ch *ch; struct scst_cmd *scmnd; u64 data_len; + enum srpt_command_state state; }; struct srpt_mgmt_ioctx {