[PATCH 1/2] target: Add target_submit_cmd() for process context fabric submission

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>

This patch adds a target_submit_cmd() caller that can be used by fabrics
to submit an uninitialized se_cmd descriptor to an struct se_session +
unpacked_lun from workqueue process context.  This call will invoke the
following steps:

- transport_init_se_cmd() to setup se_cmd specific pointers
- Obtain se_cmd->cmd_kref references with target_get_sess_cmd()
- set se_cmd->t_tasks_bidi
- transport_lookup_cmd_lun() to setup struct se_cmd->se_lun from
  the passed unpacked_lun
- transport_generic_allocate_tasks() to setup the passed *cdb, and
- transport_handle_cdb_direct() handle READ dispatch or WRITE
  ready-to-transfer callback to fabric

Cc: Christoph Hellwig <hch@xxxxxx>
Cc: Roland Dreier <roland@xxxxxxxxxxxxxxx>
Signed-off-by: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>
---
 drivers/target/target_core_transport.c |   95 ++++++++++++++++++++++++++++++++
 include/target/target_core_transport.h |    2 +
 2 files changed, 97 insertions(+), 0 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 203d386..a307fbe 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1673,6 +1673,101 @@ int transport_handle_cdb_direct(
 }
 EXPORT_SYMBOL(transport_handle_cdb_direct);
 
+/**
+ * target_submit_cmd() - Lookup unpacked lun and submit a previously
+ * uninitialized se_cmd descriptor to struct se_lun->lun_se_dev
+ * backend using struct se_sess nexus.
+ *
+ * This may only be called from process context, and also currently
+ * assumes internal allocation of fabric payload buffer by target-core.
+ *
+ * @se_cmd: command descriptor to submit
+ * @se_sess: associated se_sess for endpoint
+ * @cdb: pointer to SCSI CDB
+ * @sense: pointer to SCSI sense buffer
+ * @unpacked_lun: unpacked LUN to reference for struct se_lun
+ * @data_length: fabric expected data transfer length
+ * @task_addr: SAM task attribute
+ * @data_dir: DMA data direction
+ * @bidi: signal bidirectional data payload
+ **/
+int target_submit_cmd(
+	struct se_cmd *se_cmd,
+	struct se_session *se_sess,
+	unsigned char *cdb,
+	unsigned char *sense,
+	u32 unpacked_lun,
+	u32 data_length,
+	int task_attr,
+	int data_dir,
+	int bidi)
+{
+	struct se_portal_group *se_tpg;	
+	int rc;
+
+	if (!se_cmd || !se_sess) {
+		pr_err("Missing se_cmd or se_sess descriptor\n");
+		return -EINVAL;
+	}
+	se_tpg = se_sess->se_tpg;
+	if (!se_tpg) {
+		pr_err("Unable to locate se_tpg in target_submit_cmd\n");	
+		return -EINVAL;
+	}
+	if (se_cmd->se_tfo || se_cmd->se_sess) {
+		pr_err("struct se_cmd already initialized\n");
+		return -EEXIST;
+	}
+	if (in_interrupt()) {
+		pr_err("target_submit_cmd() may only be used from process context\n");
+		return -ENOSYS;
+	}
+	/*
+ 	 * Initialize se_cmd for target operation.  From this point
+ 	 * exceptions are handled by sending exception status via
+ 	 * target_core_fabric_ops->queue_status() callback
+ 	 */
+	transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess,
+				data_length, data_dir, task_attr, sense);
+	/*
+	 * Obtain struct se_cmd->cmd_kref references and add new cmd to
+	 * se_sess->sess_cmd_list
+	 */
+	target_get_sess_cmd(se_sess, se_cmd);
+	/*
+	 * Signal bidirectional data payloads to target-core
+	 */
+	if (bidi)
+		se_cmd->t_tasks_bidi = 1;
+	/*
+ 	 * Locate se_lun pointer and attach it to struct se_cmd
+ 	 */
+	if (transport_lookup_cmd_lun(se_cmd, unpacked_lun) < 0) {
+		transport_send_check_condition_and_sense(se_cmd,
+				se_cmd->scsi_sense_reason, 0);
+		return 0;
+	}
+	/*
+	 * Sanitize CDBs via transport_generic_cmd_sequencer() and
+	 * allocate the necessary tasks to complete the received CDB+data
+	 */
+	rc = transport_generic_allocate_tasks(se_cmd, cdb);
+	if (rc != 0) {
+		transport_send_check_condition_and_sense(se_cmd,
+				se_cmd->scsi_sense_reason, 0);
+		return 0;
+	}
+	/*
+	 * Dispatch se_cmd descriptor to se_lun->lun_se_dev backend
+	 * for immediate execution of READs, otherwise wait for
+	 * transport_generic_handle_data() to be called for WRITEs
+	 * when fabric has filled the incoming buffer.
+	 */
+	transport_handle_cdb_direct(se_cmd);
+	return 0;
+}
+EXPORT_SYMBOL(target_submit_cmd);
+
 /*
  * Used by fabric module frontends defining a TFO->new_cmd_map() caller
  * to  queue up a newly setup se_cmd w/ TRANSPORT_NEW_CMD_MAP in order to
diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h
index dac4f2d..407aff9 100644
--- a/include/target/target_core_transport.h
+++ b/include/target/target_core_transport.h
@@ -132,6 +132,8 @@ extern void transport_init_se_cmd(struct se_cmd *,
 void *transport_kmap_first_data_page(struct se_cmd *cmd);
 void transport_kunmap_first_data_page(struct se_cmd *cmd);
 extern int transport_generic_allocate_tasks(struct se_cmd *, unsigned char *);
+extern int target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *,
+			unsigned char *, u32, u32, int, int, int);
 extern int transport_handle_cdb_direct(struct se_cmd *);
 extern int transport_generic_handle_cdb_map(struct se_cmd *);
 extern int transport_generic_handle_data(struct se_cmd *);
-- 
1.7.2.5

--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux