From 47422bf8562125c59dd46f97c5cc00c1cdbdda15 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Tue, 11 Nov 2008 11:56:18 +0000 Subject: [PATCH] Added possibility to coexist if both target driver and dev handler need custom memory allocation. Direct consequences: 1. scst_local can work with scst_user's devices 2. scst_user now compatible with iscsi-scst if put_page_callback not applied + some cosmetics git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@567 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/iscsi.c | 31 ++++---- iscsi-scst/kernel/nthread.c | 2 +- scst/include/scst.h | 95 ++++++++++++++++++----- scst/src/dev_handlers/scst_user.c | 11 +-- scst/src/scst_lib.c | 89 ++++++++++++++++++++- scst/src/scst_priv.h | 6 ++ scst/src/scst_targ.c | 123 +++++++++++++++++++----------- scst_local/scst_local.c | 12 +-- 8 files changed, 266 insertions(+), 103 deletions(-) diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index 3fed97c61..28d807545 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -1322,13 +1322,13 @@ static int scsi_cmnd_start(struct iscsi_cmnd *req) req->scst_cmd = scst_cmd; scst_cmd_set_tag(scst_cmd, req_hdr->itt); scst_cmd_set_tgt_priv(scst_cmd, req); -#if !defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION) - scst_cmd_set_data_buf_tgt_alloc(scst_cmd); -#endif - if (req_hdr->flags & ISCSI_CMD_READ) + if (req_hdr->flags & ISCSI_CMD_READ) { dir = SCST_DATA_READ; - else if (req_hdr->flags & ISCSI_CMD_WRITE) +#if !defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION) + scst_cmd_set_tgt_need_alloc_data_buf(scst_cmd); +#endif + } else if (req_hdr->flags & ISCSI_CMD_WRITE) dir = SCST_DATA_WRITE; else dir = SCST_DATA_NONE; @@ -2451,16 +2451,15 @@ out_rejected: #if !defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION) static int iscsi_alloc_data_buf(struct scst_cmd *cmd) { - if (scst_cmd_get_data_direction(cmd) == SCST_DATA_READ) { - /* - * sock->ops->sendpage() is async zero copy operation, - * so we must be sure not to free and reuse - * the command's buffer before the sending was completed - * by the network layers. It is possible only if we - * don't use SGV cache. - */ - scst_cmd_set_no_sgv(cmd); - } + /* + * sock->ops->sendpage() is async zero copy operation, + * so we must be sure not to free and reuse + * the command's buffer before the sending was completed + * by the network layers. It is possible only if we + * don't use SGV cache. + */ + EXTRACHECKS_BUG_ON(scst_cmd_get_data_direction(cmd) != SCST_DATA_READ); + scst_cmd_set_no_sgv(cmd); return 1; } #endif @@ -2982,9 +2981,9 @@ out_reg: out_callb: #if defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION) net_set_get_put_page_callbacks(NULL, NULL); -#endif out_free_dummy: +#endif __free_pages(dummy_page, 0); goto out; } diff --git a/iscsi-scst/kernel/nthread.c b/iscsi-scst/kernel/nthread.c index ce4a4f158..6515479ab 100644 --- a/iscsi-scst/kernel/nthread.c +++ b/iscsi-scst/kernel/nthread.c @@ -1046,7 +1046,7 @@ static int write_data(struct iscsi_conn *conn) sock_sendpage = sock->ops->sendpage; #else if ((write_cmnd->parent_req->scst_cmd != NULL) && - scst_cmd_get_data_buff_alloced(write_cmnd->parent_req->scst_cmd)) + scst_cmd_get_dh_data_buff_alloced(write_cmnd->parent_req->scst_cmd)) sock_sendpage = sock_no_sendpage; else sock_sendpage = sock->ops->sendpage; diff --git a/scst/include/scst.h b/scst/include/scst.h index 3b1fb3e39..0ef783554 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -548,9 +548,13 @@ struct scst_tgt_template { * * Shall return 0 in case of success or < 0 (preferrably -ENOMEM) * in case of error, or > 0 if the regular SCST allocation should be - * done. In case of returning successfully, scst_cmd->data_buf_alloced + * done. In case of returning successfully, scst_cmd->tgt_data_buf_alloced * will be set by SCST. * + * It is possible that both target driver and dev handler request own + * memory allocation. In this case, data will be memcpy() between + * buffers, where necessary. + * * If allocation in atomic context - cf. scst_cmd_atomic() - is not * desired or fails and consequently < 0 is returned, this function * will be re-called in thread context. @@ -1051,13 +1055,16 @@ struct scst_cmd { * In this case alloc_data_buf() must be provided in the target driver * template. */ - unsigned int data_buf_tgt_alloc:1; + unsigned int tgt_need_alloc_data_buf:1; /* * Set by SCST if the custom data buffer allocation by the target driver * succeeded. */ - unsigned int data_buf_alloced:1; + unsigned int tgt_data_buf_alloced:1; + + /* Set if custom data buffer allocated by dev handler */ + unsigned int dh_data_buf_alloced:1; /* Set if the target driver called scst_set_expected() */ unsigned int expected_values_set:1; @@ -1208,6 +1215,18 @@ struct scst_cmd { */ int resp_data_len; + /* + * Used if both target driver and dev handler request own memory + * allocation. In other cases, both are equal to sg and sg_cnt + * correspondingly. + * + * If target driver requests own memory allocations, it MUST use + * functions scst_cmd_get_tgt_sg*() to get sg and sg_cnt! Otherwise, + * it may use functions scst_cmd_get_sg*(). + */ + struct scatterlist *tgt_sg; + int tgt_sg_cnt; + /* * The status fields in case of errors must be set using * scst_set_cmd_error_status()! @@ -2073,6 +2092,17 @@ static inline struct scatterlist *scst_cmd_get_sg(struct scst_cmd *cmd) return cmd->sg; } +/* + * Returns cmd's sg_cnt. + * + * Usage of this function is not recommended, use scst_get_buf_*() + * family of functions instead. + */ +static inline unsigned int scst_cmd_get_sg_cnt(struct scst_cmd *cmd) +{ + return cmd->sg_cnt; +} + /* * Returns cmd's data buffer length. * @@ -2085,15 +2115,25 @@ static inline unsigned int scst_cmd_get_bufflen(struct scst_cmd *cmd) return cmd->bufflen; } -/* - * Returns cmd's sg_cnt. - * - * Usage of this function is not recommended, use scst_get_buf_*() - * family of functions instead. - */ -static inline unsigned short scst_cmd_get_sg_cnt(struct scst_cmd *cmd) +/* Returns pointer to cmd's target's SG data buffer */ +static inline struct scatterlist *scst_cmd_get_tgt_sg(struct scst_cmd *cmd) { - return cmd->sg_cnt; + return cmd->tgt_sg; +} + +/* Returns cmd's target's sg_cnt */ +static inline unsigned int scst_cmd_get_tgt_sg_cnt(struct scst_cmd *cmd) +{ + return cmd->tgt_sg_cnt; +} + +/* Sets cmd's target's SG data buffer */ +static inline void scst_cmd_set_tgt_sg(struct scst_cmd *cmd, + struct scatterlist *sg, unsigned int sg_cnt) +{ + cmd->tgt_sg = sg; + cmd->tgt_sg_cnt = sg_cnt; + cmd->tgt_data_buf_alloced = 1; } /* Returns cmd's data direction */ @@ -2172,29 +2212,42 @@ void *scst_cmd_get_tgt_priv_lock(struct scst_cmd *cmd); void scst_cmd_set_tgt_priv_lock(struct scst_cmd *cmd, void *val); /* - * Get/Set functions for data_buf_tgt_alloc flag + * Get/Set functions for tgt_need_alloc_data_buf flag */ -static inline int scst_cmd_get_data_buf_tgt_alloc(struct scst_cmd *cmd) +static inline int scst_cmd_get_tgt_need_alloc_data_buf(struct scst_cmd *cmd) { - return cmd->data_buf_tgt_alloc; + return cmd->tgt_need_alloc_data_buf; } -static inline void scst_cmd_set_data_buf_tgt_alloc(struct scst_cmd *cmd) +static inline void scst_cmd_set_tgt_need_alloc_data_buf(struct scst_cmd *cmd) { - cmd->data_buf_tgt_alloc = 1; + cmd->tgt_need_alloc_data_buf = 1; } /* - * Get/Set functions for data_buf_alloced flag + * Get/Set functions for tgt_data_buf_alloced flag */ -static inline int scst_cmd_get_data_buff_alloced(struct scst_cmd *cmd) +static inline int scst_cmd_get_tgt_data_buff_alloced(struct scst_cmd *cmd) { - return cmd->data_buf_alloced; + return cmd->tgt_data_buf_alloced; } -static inline void scst_cmd_set_data_buff_alloced(struct scst_cmd *cmd) +static inline void scst_cmd_set_tgt_data_buff_alloced(struct scst_cmd *cmd) { - cmd->data_buf_alloced = 1; + cmd->tgt_data_buf_alloced = 1; +} + +/* + * Get/Set functions for dh_data_buf_alloced flag + */ +static inline int scst_cmd_get_dh_data_buff_alloced(struct scst_cmd *cmd) +{ + return cmd->dh_data_buf_alloced; +} + +static inline void scst_cmd_set_dh_data_buff_alloced(struct scst_cmd *cmd) +{ + cmd->dh_data_buf_alloced = 1; } /* diff --git a/scst/src/dev_handlers/scst_user.c b/scst/src/dev_handlers/scst_user.c index 5a4f6ba76..edd490c37 100644 --- a/scst/src/dev_handlers/scst_user.c +++ b/scst/src/dev_handlers/scst_user.c @@ -609,17 +609,8 @@ static int dev_user_alloc_space(struct scst_user_cmd *ucmd) TRACE_ENTRY(); - if (unlikely(ucmd->cmd->data_buf_tgt_alloc)) { - PRINT_ERROR("Target driver %s requested own memory " - "allocation", ucmd->cmd->tgtt->name); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_hardw_error)); - res = scst_get_cmd_abnormal_done_state(cmd); - goto out; - } - ucmd->state = UCMD_STATE_BUF_ALLOCING; - cmd->data_buf_alloced = 1; + cmd->dh_data_buf_alloced = 1; rc = dev_user_alloc_sg(ucmd, is_buff_cached(ucmd)); if (rc == 0) diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 20eb0979a..d257e50c9 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -1700,8 +1700,8 @@ void scst_release_space(struct scst_cmd *cmd) if (cmd->sgv == NULL) goto out; - if (cmd->data_buf_alloced) { - TRACE_MEM("%s", "data_buf_alloced set, returning"); + if (cmd->tgt_data_buf_alloced || cmd->dh_data_buf_alloced) { + TRACE_MEM("%s", "*data_buf_alloced set, returning"); goto out; } @@ -1718,6 +1718,91 @@ out: return; } +void scst_copy_sg(struct scst_cmd *cmd, enum scst_sg_copy_dir copy_dir) +{ + struct scatterlist *src_sg, *dst_sg; + unsigned int src_sg_cnt, src_len, dst_len, src_offs, dst_offs; + struct page *src, *dst; + int s, d, to_copy; + + TRACE_ENTRY(); + + if (copy_dir == SCST_SG_COPY_FROM_TARGET) { + src_sg = cmd->tgt_sg; + src_sg_cnt = cmd->tgt_sg_cnt; + dst_sg = cmd->sg; + to_copy = cmd->bufflen; + } else { + src_sg = cmd->sg; + src_sg_cnt = cmd->sg_cnt; + dst_sg = cmd->tgt_sg; + to_copy = cmd->resp_data_len; + } + + TRACE_MEM("cmd %p, copy_dir %d, src_sg %p, src_sg_cnt %d, dst_sg %p, " + "to_copy %d", cmd, copy_dir, src_sg, src_sg_cnt, dst_sg, + to_copy); + + dst = sg_page(dst_sg); + dst_len = dst_sg->length; + dst_offs = dst_sg->offset; + + s = 0; + d = 0; + src_offs = 0; + while (s < src_sg_cnt) { + src = sg_page(&src_sg[s]); + src_len = src_sg[s].length; + src_offs += src_sg[s].offset; + + do { + unsigned int n; + + TRACE_MEM("cmd %p, to_copy %d, src %p, src_len %d, " + "src_offs %d, dst %p, dst_len %d, dst_offs %d", + cmd, to_copy, src, src_len, src_offs, dst, + dst_len, dst_offs); + + if ((src_offs == 0) && (dst_offs == 0) && + (src_len >= PAGE_SIZE) && (dst_len >= PAGE_SIZE) && + !PageHighMem(dst) && !PageHighMem(src)) { + copy_page(page_address(dst), page_address(src)); + n = PAGE_SIZE; + } else { + n = min(PAGE_SIZE - dst_offs, + PAGE_SIZE - src_offs); + n = min(n, src_len); + n = min(n, dst_len); + memcpy(page_address(dst) + dst_offs, + page_address(src) + src_offs, n); + dst_offs -= min(n, dst_offs); + src_offs -= min(n, src_offs); + } + + TRACE_MEM("cmd %p, n %d, s %d", cmd, n, s); + + to_copy -= n; + if (to_copy <= 0) + goto out; + + src_len -= n; + dst_len -= n; + if (dst_len == 0) { + d++; + dst = sg_page(&dst_sg[d]); + dst_len = dst_sg[d].length; + dst_offs += dst_sg[d].offset; + } + } while (src_len > 0); + + s++; + } + +out: + TRACE_EXIT(); + return; +} + static const int SCST_CDB_LENGTH[8] = { 6, 10, 10, -1, 16, 12, -1, -1 }; #define SCST_CDB_GROUP(opcode) ((opcode >> 5) & 0x7) diff --git a/scst/src/scst_priv.h b/scst/src/scst_priv.h index 391ced37b..dfecf2c6f 100644 --- a/scst/src/scst_priv.h +++ b/scst/src/scst_priv.h @@ -341,6 +341,12 @@ int scst_alloc_space(struct scst_cmd *cmd); void scst_release_space(struct scst_cmd *cmd); void scst_scsi_op_list_init(void); +enum scst_sg_copy_dir { + SCST_SG_COPY_FROM_TARGET, + SCST_SG_COPY_TO_TARGET +}; +void scst_copy_sg(struct scst_cmd *cmd, enum scst_sg_copy_dir); + uint64_t scst_unpack_lun(const uint8_t *lun, int len); struct scst_cmd *__scst_find_cmd_by_tag(struct scst_session *sess, diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 42a922ff7..e35a4abfe 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -199,10 +199,10 @@ void scst_cmd_init_done(struct scst_cmd *cmd, #endif TRACE_DBG("Preferred context: %d (cmd %p)", pref_context, cmd); - TRACE(TRACE_SCSI, "tag=%llu, lun=%lld, CDB len=%d", - (long long unsigned int)cmd->tag, - (long long unsigned int)cmd->lun, - cmd->cdb_len); + TRACE(TRACE_SCSI, "tag=%llu, lun=%lld, CDB len=%d, queue_type=%x " + "(cmd %p)", (long long unsigned int)cmd->tag, + (long long unsigned int)cmd->lun, cmd->cdb_len, + cmd->queue_type, cmd); PRINT_BUFF_FLAG(TRACE_SCSI|TRACE_RCV_BOT, "Recieving CDB", cmd->cdb, cmd->cdb_len); @@ -389,10 +389,10 @@ static int scst_pre_parse(struct scst_cmd *cmd) goto out_xmit; #endif } else { - TRACE(TRACE_SCSI, "op_name <%s>, direction=%d (expected %d, " - "set %s), transfer_len=%d (expected len %d), flags=%d", - cmd->op_name, cmd->data_direction, - cmd->expected_data_direction, + TRACE(TRACE_SCSI, "op_name <%s> (cmd %p), direction=%d " + "(expected %d, set %s), transfer_len=%d (expected " + "len %d), flags=%d", cmd->op_name, cmd, + cmd->data_direction, cmd->expected_data_direction, scst_cmd_is_expected_set(cmd) ? "yes" : "no", cmd->bufflen, cmd->expected_transfer_len, cmd->op_flags); @@ -521,7 +521,8 @@ static int scst_parse_cmd(struct scst_cmd *cmd) if (cmd->data_len == -1) cmd->data_len = cmd->bufflen; - if (cmd->data_buf_alloced && unlikely((orig_bufflen > cmd->bufflen))) { + if (cmd->dh_data_buf_alloced && + unlikely((orig_bufflen > cmd->bufflen))) { PRINT_ERROR("Dev handler supplied data buffer (size %d), " "is less, than required (size %d)", cmd->bufflen, orig_bufflen); @@ -688,10 +689,11 @@ static int scst_prepare_space(struct scst_cmd *cmd) if (cmd->data_direction == SCST_DATA_NONE) goto prep_done; - if (cmd->data_buf_tgt_alloc) { + if (cmd->tgt_need_alloc_data_buf) { int orig_bufflen = cmd->bufflen; - TRACE_MEM("%s", "Custom tgt data buf allocation requested"); + TRACE_MEM("Custom tgt data buf allocation requested (cmd %p)", + cmd); r = cmd->tgtt->alloc_data_buf(cmd); if (r > 0) @@ -702,7 +704,9 @@ static int scst_prepare_space(struct scst_cmd *cmd) if (cmd->sg == NULL) goto alloc; } - cmd->data_buf_alloced = 1; + + cmd->tgt_data_buf_alloced = 1; + if (unlikely(orig_bufflen < cmd->bufflen)) { PRINT_ERROR("Target driver allocated data " "buffer (size %d), is less, than " @@ -710,16 +714,32 @@ static int scst_prepare_space(struct scst_cmd *cmd) cmd->bufflen); goto out_error; } - TRACE_MEM("%s", "data_buf_alloced, returning"); - } - goto check; + TRACE_MEM("tgt_data_buf_alloced (cmd %p)", cmd); + } else + goto check; } alloc: - if (!cmd->data_buf_alloced) + if (!cmd->tgt_data_buf_alloced && !cmd->dh_data_buf_alloced) { r = scst_alloc_space(cmd); - else - TRACE_MEM("%s", "data_buf_alloced set, returning"); + cmd->tgt_sg = cmd->sg; + cmd->tgt_sg_cnt = cmd->sg_cnt; + } else if (cmd->dh_data_buf_alloced && !cmd->tgt_data_buf_alloced) { + TRACE_MEM("dh_data_buf_alloced set (cmd %p)", cmd); + cmd->tgt_sg = cmd->sg; + cmd->tgt_sg_cnt = cmd->sg_cnt; + r = 0; + } else if (cmd->tgt_data_buf_alloced && !cmd->dh_data_buf_alloced) { + TRACE_MEM("tgt_data_buf_alloced set (cmd %p)", cmd); + cmd->sg = cmd->tgt_sg; + cmd->sg_cnt = cmd->tgt_sg_cnt; + r = 0; + } else { + TRACE_MEM("Both *_data_buf_alloced set (cmd %p, sg %p, " + "sg_cnt %d, tgt_sg %p, tgt_sg_cnt %d)", cmd, cmd->sg, + cmd->sg_cnt, cmd->tgt_sg, cmd->tgt_sg_cnt); + r = 0; + } check: if (r != 0) { @@ -1049,9 +1069,7 @@ void scst_rx_data(struct scst_cmd *cmd, int status, TRACE_ENTRY(); TRACE_DBG("Preferred context: %d", pref_context); - TRACE(TRACE_SCSI, "tag=%llu status=%#x", - (long long unsigned int)scst_cmd_get_tag(cmd), - status); + TRACE(TRACE_SCSI, "cmd %p, status %#x", cmd, status); #ifdef CONFIG_SCST_EXTRACHECKS if ((in_irq() || irqs_disabled()) && @@ -1066,6 +1084,19 @@ void scst_rx_data(struct scst_cmd *cmd, int status, switch (status) { case SCST_RX_STATUS_SUCCESS: +#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) + if (cmd->tgt_sg) { + int i; + struct scatterlist *sg = cmd->tgt_sg; + TRACE_RECV_BOT("RX data for cmd %p " + "(sg_cnt %d, sg %p, sg[0].page %p)", cmd, + cmd->tgt_sg_cnt, sg, (void *)sg_page(&sg[0])); + for (i = 0; i < cmd->tgt_sg_cnt; ++i) { + PRINT_BUFF_FLAG(TRACE_RCV_BOT, "RX sg", + sg_virt(&sg[i]), sg[i].length); + } + } +#endif cmd->state = SCST_CMD_STATE_TGT_PRE_EXEC; /* Small context optimization */ if ((pref_context == SCST_CONTEXT_TASKLET) || @@ -1190,10 +1221,10 @@ static void scst_do_cmd_done(struct scst_cmd *cmd, int result, scst_alloc_set_sense(cmd, 1, rq_sense, rq_sense_len); } - TRACE(TRACE_SCSI, "cmd%p, result=%x, cmd->status=%x, resid=%d, " + TRACE(TRACE_SCSI, "cmd %p, result=%x, cmd->status=%x, resid=%d, " "cmd->msg_status=%x, cmd->host_status=%x, " - "cmd->driver_status=%x", cmd, result, cmd->status, resid, - cmd->msg_status, cmd->host_status, cmd->driver_status); + "cmd->driver_status=%x (cmd %p)",cmd, result, cmd->status, resid, + cmd->msg_status, cmd->host_status, cmd->driver_status, cmd); cmd->completed = 1; @@ -2041,6 +2072,10 @@ static int scst_exec(struct scst_cmd **active_cmd) cmd->scst_cmd_done = scst_cmd_done_local; cmd->state = SCST_CMD_STATE_LOCAL_EXEC; + if (cmd->tgt_data_buf_alloced && cmd->dh_data_buf_alloced && + (cmd->data_direction == SCST_DATA_WRITE)) + scst_copy_sg(cmd, SCST_SG_COPY_FROM_TARGET); + rc = scst_do_local_exec(cmd); if (likely(rc == SCST_EXEC_NOT_COMPLETED)) /* Nothing to do */; @@ -2272,8 +2307,9 @@ static int scst_check_auto_sense(struct scst_cmd *cmd) SCST_NO_SENSE(cmd->sense))) { TRACE(TRACE_SCSI|TRACE_MINOR, "CHECK_CONDITION, but no sense: " "cmd->status=%x, cmd->msg_status=%x, " - "cmd->host_status=%x, cmd->driver_status=%x", cmd->status, - cmd->msg_status, cmd->host_status, cmd->driver_status); + "cmd->host_status=%x, cmd->driver_status=%x (cmd %p)", + cmd->status, cmd->msg_status, cmd->host_status, + cmd->driver_status, cmd); res = 1; } else if (unlikely(cmd->host_status)) { if ((cmd->host_status == DID_REQUEUE) || @@ -2283,8 +2319,8 @@ static int scst_check_auto_sense(struct scst_cmd *cmd) scst_set_busy(cmd); } else { TRACE(TRACE_SCSI|TRACE_MINOR, "Host status %x " - "received, returning HARDWARE ERROR instead", - cmd->host_status); + "received, returning HARDWARE ERROR instead " + "(cmd %p)", cmd->host_status, cmd); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); } @@ -2685,6 +2721,10 @@ static int scst_pre_xmit_response(struct scst_cmd *cmd) goto out; } + if (cmd->tgt_data_buf_alloced && cmd->dh_data_buf_alloced && + (cmd->data_direction == SCST_DATA_READ)) + scst_copy_sg(cmd, SCST_SG_COPY_TO_TARGET); + cmd->state = SCST_CMD_STATE_XMIT_RESP; res = SCST_CMD_STATE_RES_CONT_SAME; @@ -2746,16 +2786,16 @@ static int scst_xmit_response(struct scst_cmd *cmd) TRACE_DBG("Calling xmit_response(%p)", cmd); -#if defined(CONFIG_SCST_DEBUG) - if (cmd->sg) { +#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) + if (cmd->tgt_sg) { int i; - struct scatterlist *sg = cmd->sg; - TRACE_SEND_BOT("Xmitting %d S/G(s) at %p sg[0].page at " - "%p", cmd->sg_cnt, sg, (void *)sg_page(&sg[0])); - for (i = 0; i < cmd->sg_cnt; ++i) { - TRACE_BUFF_FLAG(TRACE_SND_BOT, - "Xmitting sg", sg_virt(&sg[i]), - sg[i].length); + struct scatterlist *sg = cmd->tgt_sg; + TRACE(TRACE_SND_BOT, "Xmitting data for cmd %p " + "(sg_cnt %d, sg %p, sg[0].page %p)", cmd, + cmd->tgt_sg_cnt, sg, (void *)sg_page(&sg[0])); + for (i = 0; i < cmd->tgt_sg_cnt; ++i) { + PRINT_BUFF_FLAG(TRACE_SND_BOT, "Xmitting sg", + sg_virt(&sg[i]), sg[i].length); } } #endif @@ -2878,8 +2918,7 @@ static void scst_cmd_set_sn(struct scst_cmd *cmd) TRACE_ENTRY(); if (scst_is_implicit_hq(cmd)) { - TRACE(TRACE_SCSI|TRACE_SCSI_SERIALIZING, - "Implicit HQ cmd %p", cmd); + TRACE_SN("Implicit HQ cmd %p", cmd); cmd->queue_type = SCST_CMD_QUEUE_HEAD_OF_QUEUE; } @@ -2932,8 +2971,7 @@ static void scst_cmd_set_sn(struct scst_cmd *cmd) break; case SCST_CMD_QUEUE_ORDERED: - TRACE(TRACE_SCSI|TRACE_SCSI_SERIALIZING, "ORDERED cmd %p " - "(op %x)", cmd, cmd->cdb[0]); + TRACE_SN("ORDERED cmd %p (op %x)", cmd, cmd->cdb[0]); ordered: if (!tgt_dev->prev_cmd_ordered) { spin_lock_irqsave(&tgt_dev->sn_lock, flags); @@ -2969,8 +3007,7 @@ ordered: break; case SCST_CMD_QUEUE_HEAD_OF_QUEUE: - TRACE(TRACE_SCSI|TRACE_SCSI_SERIALIZING, "HQ cmd %p " - "(op %x)", cmd, cmd->cdb[0]); + TRACE_SN("HQ cmd %p (op %x)", cmd, cmd->cdb[0]); spin_lock_irqsave(&tgt_dev->sn_lock, flags); tgt_dev->hq_cmd_count++; spin_unlock_irqrestore(&tgt_dev->sn_lock, flags); diff --git a/scst_local/scst_local.c b/scst_local/scst_local.c index afa1ca62d..341b7b10d 100644 --- a/scst_local/scst_local.c +++ b/scst_local/scst_local.c @@ -490,11 +490,6 @@ static int scst_local_queuecommand(struct scsi_cmnd *SCpnt, break; } - /* - * We get given data buffers by the SML - */ - scst_cmd_set_data_buff_alloced(scst_cmd); - dir = SCST_DATA_NONE; switch (SCpnt->sc_data_direction) { case DMA_TO_DEVICE: @@ -517,11 +512,8 @@ static int scst_local_queuecommand(struct scsi_cmnd *SCpnt, } scst_cmd_set_expected(scst_cmd, dir, scsi_bufflen(SCpnt)); - /* - * Set the SGL things directly ... - */ - scst_cmd->sg_cnt = scsi_sg_count(SCpnt); - scst_cmd->sg = scsi_sglist(SCpnt); + /* Set the SGL things directly ... */ + scst_cmd_set_tgt_sg(scst_cmd, scsi_sglist(SCpnt), scsi_sg_count(SCpnt)); /* * Unfortunately, we called with IRQs disabled, so have no choice,