Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target...
[cascardo/linux.git] / drivers / scsi / qla2xxx / tcm_qla2xxx.c
index 4747d2c..73f9fee 100644 (file)
 #include "qla_target.h"
 #include "tcm_qla2xxx.h"
 
-struct workqueue_struct *tcm_qla2xxx_free_wq;
-struct workqueue_struct *tcm_qla2xxx_cmd_wq;
+static struct workqueue_struct *tcm_qla2xxx_free_wq;
+static struct workqueue_struct *tcm_qla2xxx_cmd_wq;
+
+/* Local pointer to allocated TCM configfs fabric module */
+static struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs;
+static struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs;
 
 /*
  * Parse WWN.
@@ -386,6 +390,11 @@ static void tcm_qla2xxx_complete_free(struct work_struct *work)
 {
        struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
 
+       cmd->cmd_in_wq = 0;
+
+       WARN_ON(cmd->cmd_flags &  BIT_16);
+
+       cmd->cmd_flags |= BIT_16;
        transport_generic_free_cmd(&cmd->se_cmd, 0);
 }
 
@@ -396,6 +405,7 @@ static void tcm_qla2xxx_complete_free(struct work_struct *work)
  */
 static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd)
 {
+       cmd->cmd_in_wq = 1;
        INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free);
        queue_work(tcm_qla2xxx_free_wq, &cmd->work);
 }
@@ -405,6 +415,13 @@ static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd)
  */
 static int tcm_qla2xxx_check_stop_free(struct se_cmd *se_cmd)
 {
+       struct qla_tgt_cmd *cmd;
+
+       if ((se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) == 0) {
+               cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
+               cmd->cmd_flags |= BIT_14;
+       }
+
        return target_put_sess_cmd(se_cmd->se_sess, se_cmd);
 }
 
@@ -511,8 +528,13 @@ static void tcm_qla2xxx_set_default_node_attrs(struct se_node_acl *nacl)
 
 static u32 tcm_qla2xxx_get_task_tag(struct se_cmd *se_cmd)
 {
-       struct qla_tgt_cmd *cmd = container_of(se_cmd,
-                               struct qla_tgt_cmd, se_cmd);
+       struct qla_tgt_cmd *cmd;
+
+       /* check for task mgmt cmd */
+       if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
+               return 0xffffffff;
+
+       cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
 
        return cmd->tag;
 }
@@ -562,6 +584,8 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
         * Ensure that the complete FCP WRITE payload has been received.
         * Otherwise return an exception via CHECK_CONDITION status.
         */
+       cmd->cmd_in_wq = 0;
+       cmd->cmd_flags |= BIT_11;
        if (!cmd->write_data_transferred) {
                /*
                 * Check if se_cmd has already been aborted via LUN_RESET, and
@@ -590,6 +614,8 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
  */
 static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd)
 {
+       cmd->cmd_flags |= BIT_10;
+       cmd->cmd_in_wq = 1;
        INIT_WORK(&cmd->work, tcm_qla2xxx_handle_data_work);
        queue_work(tcm_qla2xxx_free_wq, &cmd->work);
 }
@@ -633,6 +659,7 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
        struct qla_tgt_cmd *cmd = container_of(se_cmd,
                                struct qla_tgt_cmd, se_cmd);
 
+       cmd->cmd_flags |= BIT_4;
        cmd->bufflen = se_cmd->data_length;
        cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
        cmd->aborted = (se_cmd->transport_state & CMD_T_ABORTED);
@@ -640,6 +667,7 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
        cmd->sg_cnt = se_cmd->t_data_nents;
        cmd->sg = se_cmd->t_data_sg;
        cmd->offset = 0;
+       cmd->cmd_flags |= BIT_3;
 
        cmd->prot_sg_cnt = se_cmd->t_prot_nents;
        cmd->prot_sg = se_cmd->t_prot_sg;
@@ -665,6 +693,11 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd)
        cmd->offset = 0;
        cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
        cmd->aborted = (se_cmd->transport_state & CMD_T_ABORTED);
+       if (cmd->cmd_flags &  BIT_5) {
+               pr_crit("Bit_5 already set for cmd = %p.\n", cmd);
+               dump_stack();
+       }
+       cmd->cmd_flags |= BIT_5;
 
        if (se_cmd->data_direction == DMA_FROM_DEVICE) {
                /*
@@ -734,10 +767,6 @@ static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
        cmd->sg_mapped = 0;
 }
 
-/* Local pointer to allocated TCM configfs fabric module */
-struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs;
-struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs;
-
 static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,
                        struct tcm_qla2xxx_nacl *, struct qla_tgt_sess *);
 /*