target: remove the get_fabric_proto_ident method
[firefly-linux-kernel-4.4.55.git] / drivers / target / target_core_transport.c
index 3fe5cb240b6f6a5b4c8a3fb42396b77dd5701f74..85b021e749e6426710caa64a758fb66142d9eb5e 100644 (file)
@@ -533,7 +533,7 @@ void transport_deregister_session(struct se_session *se_sess)
                        spin_unlock_irqrestore(&se_tpg->acl_node_lock, flags);
                        core_tpg_wait_for_nacl_pr_ref(se_nacl);
                        core_free_device_list_for_node(se_nacl, se_tpg);
-                       se_tfo->tpg_release_fabric_acl(se_tpg, se_nacl);
+                       kfree(se_nacl);
 
                        comp_nacl = false;
                        spin_lock_irqsave(&se_tpg->acl_node_lock, flags);
@@ -1196,7 +1196,7 @@ transport_check_alloc_task_attr(struct se_cmd *cmd)
         * Check if SAM Task Attribute emulation is enabled for this
         * struct se_device storage object
         */
-       if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
+       if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH)
                return 0;
 
        if (cmd->sam_task_attr == TCM_ACA_TAG) {
@@ -1353,11 +1353,9 @@ transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *sgl,
 
        cmd->t_data_sg = sgl;
        cmd->t_data_nents = sgl_count;
+       cmd->t_bidi_data_sg = sgl_bidi;
+       cmd->t_bidi_data_nents = sgl_bidi_count;
 
-       if (sgl_bidi && sgl_bidi_count) {
-               cmd->t_bidi_data_sg = sgl_bidi;
-               cmd->t_bidi_data_nents = sgl_bidi_count;
-       }
        cmd->se_cmd_flags |= SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC;
        return 0;
 }
@@ -1419,7 +1417,7 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess
         * for fabrics using TARGET_SCF_ACK_KREF that expect a second
         * kref_put() to happen during fabric packet acknowledgement.
         */
-       ret = target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF));
+       ret = target_get_sess_cmd(se_cmd, flags & TARGET_SCF_ACK_KREF);
        if (ret)
                return ret;
        /*
@@ -1433,7 +1431,7 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess
        rc = transport_lookup_cmd_lun(se_cmd, unpacked_lun);
        if (rc) {
                transport_send_check_condition_and_sense(se_cmd, rc, 0);
-               target_put_sess_cmd(se_sess, se_cmd);
+               target_put_sess_cmd(se_cmd);
                return 0;
        }
 
@@ -1450,6 +1448,7 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess
        if (sgl_prot_count) {
                se_cmd->t_prot_sg = sgl_prot;
                se_cmd->t_prot_nents = sgl_prot_count;
+               se_cmd->se_cmd_flags |= SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC;
        }
 
        /*
@@ -1584,7 +1583,7 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess,
                se_cmd->se_tmr_req->ref_task_tag = tag;
 
        /* See target_submit_cmd for commentary */
-       ret = target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF));
+       ret = target_get_sess_cmd(se_cmd, flags & TARGET_SCF_ACK_KREF);
        if (ret) {
                core_tmr_release_req(se_cmd->se_tmr_req);
                return ret;
@@ -1766,11 +1765,11 @@ static int target_write_prot_action(struct se_cmd *cmd)
                        break;
 
                sectors = cmd->data_length >> ilog2(cmd->se_dev->dev_attrib.block_size);
-               cmd->pi_err = sbc_dif_verify_write(cmd, cmd->t_task_lba,
-                                                  sectors, 0, NULL, 0);
+               cmd->pi_err = sbc_dif_verify(cmd, cmd->t_task_lba,
+                                            sectors, 0, cmd->t_prot_sg, 0);
                if (unlikely(cmd->pi_err)) {
                        spin_lock_irq(&cmd->t_state_lock);
-                       cmd->transport_state &= ~CMD_T_BUSY|CMD_T_SENT;
+                       cmd->transport_state &= ~(CMD_T_BUSY|CMD_T_SENT);
                        spin_unlock_irq(&cmd->t_state_lock);
                        transport_generic_request_failure(cmd, cmd->pi_err);
                        return -1;
@@ -1787,7 +1786,7 @@ static bool target_handle_task_attr(struct se_cmd *cmd)
 {
        struct se_device *dev = cmd->se_dev;
 
-       if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
+       if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH)
                return false;
 
        /*
@@ -1868,7 +1867,7 @@ void target_execute_cmd(struct se_cmd *cmd)
 
        if (target_handle_task_attr(cmd)) {
                spin_lock_irq(&cmd->t_state_lock);
-               cmd->transport_state &= ~CMD_T_BUSY|CMD_T_SENT;
+               cmd->transport_state &= ~(CMD_T_BUSY | CMD_T_SENT);
                spin_unlock_irq(&cmd->t_state_lock);
                return;
        }
@@ -1912,7 +1911,7 @@ static void transport_complete_task_attr(struct se_cmd *cmd)
 {
        struct se_device *dev = cmd->se_dev;
 
-       if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
+       if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH)
                return;
 
        if (cmd->sam_task_attr == TCM_SIMPLE_TAG) {
@@ -1957,8 +1956,7 @@ static void transport_complete_qf(struct se_cmd *cmd)
        case DMA_TO_DEVICE:
                if (cmd->se_cmd_flags & SCF_BIDI) {
                        ret = cmd->se_tfo->queue_data_in(cmd);
-                       if (ret < 0)
-                               break;
+                       break;
                }
                /* Fall through for DMA_TO_DEVICE */
        case DMA_NONE:
@@ -1992,16 +1990,17 @@ static void transport_handle_queue_full(
 
 static bool target_read_prot_action(struct se_cmd *cmd)
 {
-       sense_reason_t rc;
-
        switch (cmd->prot_op) {
        case TARGET_PROT_DIN_STRIP:
                if (!(cmd->se_sess->sup_prot_ops & TARGET_PROT_DIN_STRIP)) {
-                       rc = sbc_dif_read_strip(cmd);
-                       if (rc) {
-                               cmd->pi_err = rc;
+                       u32 sectors = cmd->data_length >>
+                                 ilog2(cmd->se_dev->dev_attrib.block_size);
+
+                       cmd->pi_err = sbc_dif_verify(cmd, cmd->t_task_lba,
+                                                    sectors, 0, cmd->t_prot_sg,
+                                                    0);
+                       if (cmd->pi_err)
                                return true;
-                       }
                }
                break;
        case TARGET_PROT_DIN_INSERT:
@@ -2180,6 +2179,12 @@ static inline void transport_reset_sgl_orig(struct se_cmd *cmd)
 
 static inline void transport_free_pages(struct se_cmd *cmd)
 {
+       if (!(cmd->se_cmd_flags & SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC)) {
+               transport_free_sgl(cmd->t_prot_sg, cmd->t_prot_nents);
+               cmd->t_prot_sg = NULL;
+               cmd->t_prot_nents = 0;
+       }
+
        if (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC) {
                /*
                 * Release special case READ buffer payload required for
@@ -2203,10 +2208,6 @@ static inline void transport_free_pages(struct se_cmd *cmd)
        transport_free_sgl(cmd->t_bidi_data_sg, cmd->t_bidi_data_nents);
        cmd->t_bidi_data_sg = NULL;
        cmd->t_bidi_data_nents = 0;
-
-       transport_free_sgl(cmd->t_prot_sg, cmd->t_prot_nents);
-       cmd->t_prot_sg = NULL;
-       cmd->t_prot_nents = 0;
 }
 
 /**
@@ -2228,7 +2229,7 @@ static int transport_release_cmd(struct se_cmd *cmd)
         * If this cmd has been setup with target_get_sess_cmd(), drop
         * the kref and call ->release_cmd() in kref callback.
         */
-       return target_put_sess_cmd(cmd->se_sess, cmd);
+       return target_put_sess_cmd(cmd);
 }
 
 /**
@@ -2345,6 +2346,14 @@ transport_generic_new_cmd(struct se_cmd *cmd)
        int ret = 0;
        bool zero_flag = !(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB);
 
+       if (cmd->prot_op != TARGET_PROT_NORMAL &&
+           !(cmd->se_cmd_flags & SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC)) {
+               ret = target_alloc_sgl(&cmd->t_prot_sg, &cmd->t_prot_nents,
+                                      cmd->prot_length, true);
+               if (ret < 0)
+                       return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+       }
+
        /*
         * Determine is the TCM fabric module has already allocated physical
         * memory, and is directly calling transport_generic_map_mem_to_cmd()
@@ -2370,14 +2379,6 @@ transport_generic_new_cmd(struct se_cmd *cmd)
                                return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
                }
 
-               if (cmd->prot_op != TARGET_PROT_NORMAL) {
-                       ret = target_alloc_sgl(&cmd->t_prot_sg,
-                                              &cmd->t_prot_nents,
-                                              cmd->prot_length, true);
-                       if (ret < 0)
-                               return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-               }
-
                ret = target_alloc_sgl(&cmd->t_data_sg, &cmd->t_data_nents,
                                       cmd->data_length, zero_flag);
                if (ret < 0)
@@ -2472,13 +2473,12 @@ int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
 EXPORT_SYMBOL(transport_generic_free_cmd);
 
 /* target_get_sess_cmd - Add command to active ->sess_cmd_list
- * @se_sess:   session to reference
  * @se_cmd:    command descriptor to add
  * @ack_kref:  Signal that fabric will perform an ack target_put_sess_cmd()
  */
-int target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd,
-                              bool ack_kref)
+int target_get_sess_cmd(struct se_cmd *se_cmd, bool ack_kref)
 {
+       struct se_session *se_sess = se_cmd->se_sess;
        unsigned long flags;
        int ret = 0;
 
@@ -2500,7 +2500,7 @@ out:
        spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
 
        if (ret && ack_kref)
-               target_put_sess_cmd(se_sess, se_cmd);
+               target_put_sess_cmd(se_cmd);
 
        return ret;
 }
@@ -2529,11 +2529,12 @@ static void target_release_cmd_kref(struct kref *kref)
 }
 
 /* target_put_sess_cmd - Check for active I/O shutdown via kref_put
- * @se_sess:   session to reference
  * @se_cmd:    command descriptor to drop
  */
-int target_put_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd)
+int target_put_sess_cmd(struct se_cmd *se_cmd)
 {
+       struct se_session *se_sess = se_cmd->se_sess;
+
        if (!se_sess) {
                se_cmd->se_tfo->release_cmd(se_cmd);
                return 1;
@@ -3075,3 +3076,22 @@ int transport_generic_handle_tmr(
        return 0;
 }
 EXPORT_SYMBOL(transport_generic_handle_tmr);
+
+bool
+target_check_wce(struct se_device *dev)
+{
+       bool wce = false;
+
+       if (dev->transport->get_write_cache)
+               wce = dev->transport->get_write_cache(dev);
+       else if (dev->dev_attrib.emulate_write_cache > 0)
+               wce = true;
+
+       return wce;
+}
+
+bool
+target_check_fua(struct se_device *dev)
+{
+       return target_check_wce(dev) && dev->dev_attrib.emulate_fua_write > 0;
+}