}
 EXPORT_SYMBOL(transport_handle_cdb_direct);
 
-/**
- * target_submit_cmd - lookup unpacked lun and submit uninitialized se_cmd
+/*
+ * target_submit_cmd_map_sgls - lookup unpacked lun and submit uninitialized
+ *                      se_cmd + use pre-allocated SGL memory.
  *
  * @se_cmd: command descriptor to submit
  * @se_sess: associated se_sess for endpoint
  * @task_addr: SAM task attribute
  * @data_dir: DMA data direction
  * @flags: flags for command submission from target_sc_flags_tables
+ * @sgl: struct scatterlist memory for unidirectional mapping
+ * @sgl_count: scatterlist count for unidirectional mapping
+ * @sgl_bidi: struct scatterlist memory for bidirectional READ mapping
+ * @sgl_bidi_count: scatterlist count for bidirectional READ mapping
  *
  * Returns non zero to signal active I/O shutdown failure.  All other
  * setup exceptions will be returned as a SCSI CHECK_CONDITION response,
  *
  * This may only be called from process context, and also currently
  * assumes internal allocation of fabric payload buffer by target-core.
- **/
-int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
+ */
+int target_submit_cmd_map_sgls(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 flags)
+               u32 data_length, int task_attr, int data_dir, int flags,
+               struct scatterlist *sgl, u32 sgl_count,
+               struct scatterlist *sgl_bidi, u32 sgl_bidi_count)
 {
        struct se_portal_group *se_tpg;
        int rc;
                transport_generic_request_failure(se_cmd);
                return 0;
        }
-
+       /*
+        * When a non zero sgl_count has been passed perform SGL passthrough
+        * mapping for pre-allocated fabric memory instead of having target
+        * core perform an internal SGL allocation..
+        */
+       if (sgl_count != 0) {
+               BUG_ON(!sgl);
+
+               rc = transport_generic_map_mem_to_cmd(se_cmd, sgl, sgl_count,
+                               sgl_bidi, sgl_bidi_count);
+               if (rc != 0) {
+                       transport_generic_request_failure(se_cmd);
+                       return 0;
+               }
+       }
        /*
         * Check if we need to delay processing because of ALUA
         * Active/NonOptimized primary access state..
        transport_handle_cdb_direct(se_cmd);
        return 0;
 }
+EXPORT_SYMBOL(target_submit_cmd_map_sgls);
+
+/*
+ * target_submit_cmd - lookup unpacked lun and submit uninitialized se_cmd
+ *
+ * @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
+ * @flags: flags for command submission from target_sc_flags_tables
+ *
+ * Returns non zero to signal active I/O shutdown failure.  All other
+ * setup exceptions will be returned as a SCSI CHECK_CONDITION response,
+ * but still return zero here.
+ *
+ * This may only be called from process context, and also currently
+ * assumes internal allocation of fabric payload buffer by target-core.
+ *
+ * It also assumes interal target core SGL memory allocation.
+ */
+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 flags)
+{
+       return target_submit_cmd_map_sgls(se_cmd, se_sess, cdb, sense,
+                       unpacked_lun, data_length, task_attr, data_dir,
+                       flags, NULL, 0, NULL, 0);
+}
 EXPORT_SYMBOL(target_submit_cmd);
 
 static void target_complete_tmr_failure(struct work_struct *work)
 
                struct se_session *, u32, int, int, unsigned char *);
 int    transport_lookup_cmd_lun(struct se_cmd *, u32);
 int    target_setup_cmd_from_cdb(struct se_cmd *, unsigned char *);
+int    target_submit_cmd_map_sgls(struct se_cmd *, struct se_session *,
+               unsigned char *, unsigned char *, u32, u32, int, int, int,
+               struct scatterlist *, u32, struct scatterlist *, u32);
 int    target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *,
                unsigned char *, u32, u32, int, int, int);
 int    target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess,