target: Use TCM_NO_SENSE for initialisation
[firefly-linux-kernel-4.4.55.git] / drivers / target / target_core_alua.c
index 9a5f9a7aecd2b9a5d7d4b6f99c6bd5023359d778..7d4ec02e29a9773d3eb1ddbcd1fc404e5ee334e8 100644 (file)
@@ -3,8 +3,7 @@
  *
  * This file contains SPC-3 compliant asymmetric logical unit assigntment (ALUA)
  *
- * Copyright (c) 2009-2010 Rising Tide Systems
- * Copyright (c) 2009-2010 Linux-iSCSI.org
+ * (c) Copyright 2009-2012 RisingTide Systems LLC.
  *
  * Nicholas A. Bellinger <nab@kernel.org>
  *
@@ -41,7 +40,7 @@
 #include "target_core_alua.h"
 #include "target_core_ua.h"
 
-static int core_alua_check_transition(int state, int *primary);
+static sense_reason_t core_alua_check_transition(int state, int *primary);
 static int core_alua_set_tg_pt_secondary_state(
                struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem,
                struct se_port *port, int explict, int offline);
@@ -59,15 +58,17 @@ struct t10_alua_lu_gp *default_lu_gp;
  *
  * See spc4r17 section 6.27
  */
-int target_emulate_report_target_port_groups(struct se_cmd *cmd)
+sense_reason_t
+target_emulate_report_target_port_groups(struct se_cmd *cmd)
 {
-       struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
+       struct se_device *dev = cmd->se_dev;
        struct se_port *port;
        struct t10_alua_tg_pt_gp *tg_pt_gp;
        struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
        unsigned char *buf;
        u32 rd_len = 0, off;
        int ext_hdr = (cmd->t_task_cdb[1] & 0x20);
+
        /*
         * Skip over RESERVED area to first Target port group descriptor
         * depending on the PARAMETER DATA FORMAT type..
@@ -81,13 +82,14 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd)
                pr_warn("REPORT TARGET PORT GROUPS allocation length %u too"
                        " small for %s header\n", cmd->data_length,
                        (ext_hdr) ? "extended" : "normal");
-               cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
-               return -EINVAL;
+               return TCM_INVALID_CDB_FIELD;
        }
        buf = transport_kmap_data_sg(cmd);
+       if (!buf)
+               return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 
-       spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
-       list_for_each_entry(tg_pt_gp, &su_dev->t10_alua.tg_pt_gps_list,
+       spin_lock(&dev->t10_alua.tg_pt_gps_lock);
+       list_for_each_entry(tg_pt_gp, &dev->t10_alua.tg_pt_gps_list,
                        tg_pt_gp_list) {
                /*
                 * Check if the Target port group and Target port descriptor list
@@ -160,7 +162,7 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd)
                }
                spin_unlock(&tg_pt_gp->tg_pt_gp_lock);
        }
-       spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+       spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
        /*
         * Set the RETURN DATA LENGTH set in the header of the DataIN Payload
         */
@@ -200,32 +202,33 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd)
  *
  * See spc4r17 section 6.35
  */
-int target_emulate_set_target_port_groups(struct se_cmd *cmd)
+sense_reason_t
+target_emulate_set_target_port_groups(struct se_cmd *cmd)
 {
        struct se_device *dev = cmd->se_dev;
-       struct se_subsystem_dev *su_dev = dev->se_sub_dev;
        struct se_port *port, *l_port = cmd->se_lun->lun_sep;
        struct se_node_acl *nacl = cmd->se_sess->se_node_acl;
        struct t10_alua_tg_pt_gp *tg_pt_gp = NULL, *l_tg_pt_gp;
        struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, *l_tg_pt_gp_mem;
        unsigned char *buf;
        unsigned char *ptr;
+       sense_reason_t rc = TCM_NO_SENSE;
        u32 len = 4; /* Skip over RESERVED area in header */
-       int alua_access_state, primary = 0, rc;
+       int alua_access_state, primary = 0;
        u16 tg_pt_id, rtpi;
 
-       if (!l_port) {
-               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-               return -EINVAL;
-       }
+       if (!l_port)
+               return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+
        if (cmd->data_length < 4) {
                pr_warn("SET TARGET PORT GROUPS parameter list length %u too"
                        " small\n", cmd->data_length);
-               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
-               return -EINVAL;
+               return TCM_INVALID_PARAMETER_LIST;
        }
 
        buf = transport_kmap_data_sg(cmd);
+       if (!buf)
+               return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 
        /*
         * Determine if explict ALUA via SET_TARGET_PORT_GROUPS is allowed
@@ -234,8 +237,7 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd)
        l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem;
        if (!l_tg_pt_gp_mem) {
                pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n");
-               cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
-               rc = -EINVAL;
+               rc = TCM_UNSUPPORTED_SCSI_OPCODE;
                goto out;
        }
        spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock);
@@ -243,24 +245,22 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd)
        if (!l_tg_pt_gp) {
                spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock);
                pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n");
-               cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
-               rc = -EINVAL;
+               rc = TCM_UNSUPPORTED_SCSI_OPCODE;
                goto out;
        }
-       rc = (l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA);
        spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock);
 
-       if (!rc) {
+       if (!(l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA)) {
                pr_debug("Unable to process SET_TARGET_PORT_GROUPS"
                                " while TPGS_EXPLICT_ALUA is disabled\n");
-               cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
-               rc = -EINVAL;
+               rc = TCM_UNSUPPORTED_SCSI_OPCODE;
                goto out;
        }
 
        ptr = &buf[4]; /* Skip over RESERVED area in header */
 
        while (len < cmd->data_length) {
+               bool found = false;
                alua_access_state = (ptr[0] & 0x0f);
                /*
                 * Check the received ALUA access state, and determine if
@@ -268,7 +268,7 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd)
                 * access state.
                 */
                rc = core_alua_check_transition(alua_access_state, &primary);
-               if (rc != 0) {
+               if (rc) {
                        /*
                         * If the SET TARGET PORT GROUPS attempts to establish
                         * an invalid combination of target port asymmetric
@@ -279,11 +279,9 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd)
                         * REQUEST, and the additional sense code set to INVALID
                         * FIELD IN PARAMETER LIST.
                         */
-                       cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
-                       rc = -EINVAL;
                        goto out;
                }
-               rc = -1;
+
                /*
                 * If the ASYMMETRIC ACCESS STATE field (see table 267)
                 * specifies a primary target port asymmetric access state,
@@ -303,9 +301,9 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd)
                         * Locate the matching target port group ID from
                         * the global tg_pt_gp list
                         */
-                       spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
+                       spin_lock(&dev->t10_alua.tg_pt_gps_lock);
                        list_for_each_entry(tg_pt_gp,
-                                       &su_dev->t10_alua.tg_pt_gps_list,
+                                       &dev->t10_alua.tg_pt_gps_list,
                                        tg_pt_gp_list) {
                                if (!tg_pt_gp->tg_pt_gp_valid_id)
                                        continue;
@@ -315,27 +313,20 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd)
 
                                atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt);
                                smp_mb__after_atomic_inc();
-                               spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
 
-                               rc = core_alua_do_port_transition(tg_pt_gp,
+                               spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
+
+                               if (!core_alua_do_port_transition(tg_pt_gp,
                                                dev, l_port, nacl,
-                                               alua_access_state, 1);
+                                               alua_access_state, 1))
+                                       found = true;
 
-                               spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
+                               spin_lock(&dev->t10_alua.tg_pt_gps_lock);
                                atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt);
                                smp_mb__after_atomic_dec();
                                break;
                        }
-                       spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
-                       /*
-                        * If not matching target port group ID can be located
-                        * throw an exception with ASCQ: INVALID_PARAMETER_LIST
-                        */
-                       if (rc != 0) {
-                               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
-                               rc = -EINVAL;
-                               goto out;
-                       }
+                       spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
                } else {
                        /*
                         * Extact the RELATIVE TARGET PORT IDENTIFIER to identify
@@ -354,25 +345,22 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd)
                                        continue;
 
                                tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
+
                                spin_unlock(&dev->se_port_lock);
 
-                               rc = core_alua_set_tg_pt_secondary_state(
-                                               tg_pt_gp_mem, port, 1, 1);
+                               if (!core_alua_set_tg_pt_secondary_state(
+                                               tg_pt_gp_mem, port, 1, 1))
+                                       found = true;
 
                                spin_lock(&dev->se_port_lock);
                                break;
                        }
                        spin_unlock(&dev->se_port_lock);
-                       /*
-                        * If not matching relative target port identifier can
-                        * be located, throw an exception with ASCQ:
-                        * INVALID_PARAMETER_LIST
-                        */
-                       if (rc != 0) {
-                               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
-                               rc = -EINVAL;
-                               goto out;
-                       }
+               }
+
+               if (!found) {
+                       rc = TCM_INVALID_PARAMETER_LIST;
+                       goto out;
                }
 
                ptr += 4;
@@ -523,40 +511,27 @@ static inline int core_alua_state_transition(
 }
 
 /*
- * Used for alua_type SPC_ALUA_PASSTHROUGH and SPC2_ALUA_DISABLED
- * in transport_cmd_sequencer().  This function is assigned to
- * struct t10_alua *->state_check() in core_setup_alua()
- */
-static int core_alua_state_check_nop(
-       struct se_cmd *cmd,
-       unsigned char *cdb,
-       u8 *alua_ascq)
-{
-       return 0;
-}
-
-/*
- * Used for alua_type SPC3_ALUA_EMULATED in transport_cmd_sequencer().
- * This function is assigned to struct t10_alua *->state_check() in
- * core_setup_alua()
- *
- * Also, this function can return three different return codes to
- * signal transport_generic_cmd_sequencer()
- *
  * return 1: Is used to signal LUN not accecsable, and check condition/not ready
  * return 0: Used to signal success
  * reutrn -1: Used to signal failure, and invalid cdb field
  */
-static int core_alua_state_check(
-       struct se_cmd *cmd,
-       unsigned char *cdb,
-       u8 *alua_ascq)
+sense_reason_t
+target_alua_state_check(struct se_cmd *cmd)
 {
+       struct se_device *dev = cmd->se_dev;
+       unsigned char *cdb = cmd->t_task_cdb;
        struct se_lun *lun = cmd->se_lun;
        struct se_port *port = lun->lun_sep;
        struct t10_alua_tg_pt_gp *tg_pt_gp;
        struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
        int out_alua_state, nonop_delay_msecs;
+       u8 alua_ascq;
+       int ret;
+
+       if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)
+               return 0;
+       if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
+               return 0;
 
        if (!port)
                return 0;
@@ -565,11 +540,11 @@ static int core_alua_state_check(
         * access state: OFFLINE
         */
        if (atomic_read(&port->sep_tg_pt_secondary_offline)) {
-               *alua_ascq = ASCQ_04H_ALUA_OFFLINE;
                pr_debug("ALUA: Got secondary offline status for local"
                                " target port\n");
-               *alua_ascq = ASCQ_04H_ALUA_OFFLINE;
-               return 1;
+               alua_ascq = ASCQ_04H_ALUA_OFFLINE;
+               ret = 1;
+               goto out;
        }
         /*
         * Second, obtain the struct t10_alua_tg_pt_gp_member pointer to the
@@ -594,14 +569,18 @@ static int core_alua_state_check(
 
        switch (out_alua_state) {
        case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
-               return core_alua_state_nonoptimized(cmd, cdb,
-                                       nonop_delay_msecs, alua_ascq);
+               ret = core_alua_state_nonoptimized(cmd, cdb,
+                                       nonop_delay_msecs, &alua_ascq);
+               break;
        case ALUA_ACCESS_STATE_STANDBY:
-               return core_alua_state_standby(cmd, cdb, alua_ascq);
+               ret = core_alua_state_standby(cmd, cdb, &alua_ascq);
+               break;
        case ALUA_ACCESS_STATE_UNAVAILABLE:
-               return core_alua_state_unavailable(cmd, cdb, alua_ascq);
+               ret = core_alua_state_unavailable(cmd, cdb, &alua_ascq);
+               break;
        case ALUA_ACCESS_STATE_TRANSITION:
-               return core_alua_state_transition(cmd, cdb, alua_ascq);
+               ret = core_alua_state_transition(cmd, cdb, &alua_ascq);
+               break;
        /*
         * OFFLINE is a secondary ALUA target port group access state, that is
         * handled above with struct se_port->sep_tg_pt_secondary_offline=1
@@ -610,7 +589,24 @@ static int core_alua_state_check(
        default:
                pr_err("Unknown ALUA access state: 0x%02x\n",
                                out_alua_state);
-               return -EINVAL;
+               return TCM_INVALID_CDB_FIELD;
+       }
+
+out:
+       if (ret > 0) {
+               /*
+                * Set SCSI additional sense code (ASC) to 'LUN Not Accessible';
+                * The ALUA additional sense code qualifier (ASCQ) is determined
+                * by the ALUA primary or secondary access state..
+                */
+               pr_debug("[%s]: ALUA TG Port not available, "
+                       "SenseKey: NOT_READY, ASC/ASCQ: "
+                       "0x04/0x%02x\n",
+                       cmd->se_tfo->get_fabric_name(), alua_ascq);
+
+               cmd->scsi_asc = 0x04;
+               cmd->scsi_ascq = alua_ascq;
+               return TCM_CHECK_CONDITION_NOT_READY;
        }
 
        return 0;
@@ -619,7 +615,8 @@ static int core_alua_state_check(
 /*
  * Check implict and explict ALUA state change request.
  */
-static int core_alua_check_transition(int state, int *primary)
+static sense_reason_t
+core_alua_check_transition(int state, int *primary)
 {
        switch (state) {
        case ALUA_ACCESS_STATE_ACTIVE_OPTMIZED:
@@ -641,7 +638,7 @@ static int core_alua_check_transition(int state, int *primary)
                break;
        default:
                pr_err("Unknown ALUA access state: 0x%02x\n", state);
-               return -EINVAL;
+               return TCM_INVALID_PARAMETER_LIST;
        }
 
        return 0;
@@ -758,8 +755,7 @@ static int core_alua_update_tpg_primary_metadata(
        int primary_state,
        unsigned char *md_buf)
 {
-       struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev;
-       struct t10_wwn *wwn = &su_dev->t10_wwn;
+       struct t10_wwn *wwn = &tg_pt_gp->tg_pt_gp_dev->t10_wwn;
        char path[ALUA_METADATA_PATH_LEN];
        int len;
 
@@ -899,7 +895,6 @@ int core_alua_do_port_transition(
 {
        struct se_device *dev;
        struct se_port *port;
-       struct se_subsystem_dev *su_dev;
        struct se_node_acl *nacl;
        struct t10_alua_lu_gp *lu_gp;
        struct t10_alua_lu_gp_member *lu_gp_mem, *local_lu_gp_mem;
@@ -949,14 +944,13 @@ int core_alua_do_port_transition(
                                lu_gp_mem_list) {
 
                dev = lu_gp_mem->lu_gp_mem_dev;
-               su_dev = dev->se_sub_dev;
                atomic_inc(&lu_gp_mem->lu_gp_mem_ref_cnt);
                smp_mb__after_atomic_inc();
                spin_unlock(&lu_gp->lu_gp_lock);
 
-               spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
+               spin_lock(&dev->t10_alua.tg_pt_gps_lock);
                list_for_each_entry(tg_pt_gp,
-                               &su_dev->t10_alua.tg_pt_gps_list,
+                               &dev->t10_alua.tg_pt_gps_list,
                                tg_pt_gp_list) {
 
                        if (!tg_pt_gp->tg_pt_gp_valid_id)
@@ -981,7 +975,7 @@ int core_alua_do_port_transition(
                        }
                        atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt);
                        smp_mb__after_atomic_inc();
-                       spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+                       spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
                        /*
                         * core_alua_do_transition_tg_pt() will always return
                         * success.
@@ -989,11 +983,11 @@ int core_alua_do_port_transition(
                        core_alua_do_transition_tg_pt(tg_pt_gp, port,
                                        nacl, md_buf, new_state, explict);
 
-                       spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
+                       spin_lock(&dev->t10_alua.tg_pt_gps_lock);
                        atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt);
                        smp_mb__after_atomic_dec();
                }
-               spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+               spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 
                spin_lock(&lu_gp->lu_gp_lock);
                atomic_dec(&lu_gp_mem->lu_gp_mem_ref_cnt);
@@ -1268,14 +1262,9 @@ void core_alua_free_lu_gp(struct t10_alua_lu_gp *lu_gp)
 
 void core_alua_free_lu_gp_mem(struct se_device *dev)
 {
-       struct se_subsystem_dev *su_dev = dev->se_sub_dev;
-       struct t10_alua *alua = &su_dev->t10_alua;
        struct t10_alua_lu_gp *lu_gp;
        struct t10_alua_lu_gp_member *lu_gp_mem;
 
-       if (alua->alua_type != SPC3_ALUA_EMULATED)
-               return;
-
        lu_gp_mem = dev->dev_alua_lu_gp_mem;
        if (!lu_gp_mem)
                return;
@@ -1358,10 +1347,8 @@ void __core_alua_drop_lu_gp_mem(
        spin_unlock(&lu_gp->lu_gp_lock);
 }
 
-struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(
-       struct se_subsystem_dev *su_dev,
-       const char *name,
-       int def_group)
+struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(struct se_device *dev,
+               const char *name, int def_group)
 {
        struct t10_alua_tg_pt_gp *tg_pt_gp;
 
@@ -1375,7 +1362,7 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(
        mutex_init(&tg_pt_gp->tg_pt_gp_md_mutex);
        spin_lock_init(&tg_pt_gp->tg_pt_gp_lock);
        atomic_set(&tg_pt_gp->tg_pt_gp_ref_cnt, 0);
-       tg_pt_gp->tg_pt_gp_su_dev = su_dev;
+       tg_pt_gp->tg_pt_gp_dev = dev;
        tg_pt_gp->tg_pt_gp_md_buf_len = ALUA_MD_BUF_LEN;
        atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state,
                ALUA_ACCESS_STATE_ACTIVE_OPTMIZED);
@@ -1392,14 +1379,14 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(
        tg_pt_gp->tg_pt_gp_implict_trans_secs = ALUA_DEFAULT_IMPLICT_TRANS_SECS;
 
        if (def_group) {
-               spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
+               spin_lock(&dev->t10_alua.tg_pt_gps_lock);
                tg_pt_gp->tg_pt_gp_id =
-                               su_dev->t10_alua.alua_tg_pt_gps_counter++;
+                               dev->t10_alua.alua_tg_pt_gps_counter++;
                tg_pt_gp->tg_pt_gp_valid_id = 1;
-               su_dev->t10_alua.alua_tg_pt_gps_count++;
+               dev->t10_alua.alua_tg_pt_gps_count++;
                list_add_tail(&tg_pt_gp->tg_pt_gp_list,
-                             &su_dev->t10_alua.tg_pt_gps_list);
-               spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+                             &dev->t10_alua.tg_pt_gps_list);
+               spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
        }
 
        return tg_pt_gp;
@@ -1409,9 +1396,10 @@ int core_alua_set_tg_pt_gp_id(
        struct t10_alua_tg_pt_gp *tg_pt_gp,
        u16 tg_pt_gp_id)
 {
-       struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev;
+       struct se_device *dev = tg_pt_gp->tg_pt_gp_dev;
        struct t10_alua_tg_pt_gp *tg_pt_gp_tmp;
        u16 tg_pt_gp_id_tmp;
+
        /*
         * The tg_pt_gp->tg_pt_gp_id may only be set once..
         */
@@ -1421,19 +1409,19 @@ int core_alua_set_tg_pt_gp_id(
                return -EINVAL;
        }
 
-       spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
-       if (su_dev->t10_alua.alua_tg_pt_gps_count == 0x0000ffff) {
+       spin_lock(&dev->t10_alua.tg_pt_gps_lock);
+       if (dev->t10_alua.alua_tg_pt_gps_count == 0x0000ffff) {
                pr_err("Maximum ALUA alua_tg_pt_gps_count:"
                        " 0x0000ffff reached\n");
-               spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+               spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
                kmem_cache_free(t10_alua_tg_pt_gp_cache, tg_pt_gp);
                return -ENOSPC;
        }
 again:
        tg_pt_gp_id_tmp = (tg_pt_gp_id != 0) ? tg_pt_gp_id :
-                       su_dev->t10_alua.alua_tg_pt_gps_counter++;
+                       dev->t10_alua.alua_tg_pt_gps_counter++;
 
-       list_for_each_entry(tg_pt_gp_tmp, &su_dev->t10_alua.tg_pt_gps_list,
+       list_for_each_entry(tg_pt_gp_tmp, &dev->t10_alua.tg_pt_gps_list,
                        tg_pt_gp_list) {
                if (tg_pt_gp_tmp->tg_pt_gp_id == tg_pt_gp_id_tmp) {
                        if (!tg_pt_gp_id)
@@ -1441,7 +1429,7 @@ again:
 
                        pr_err("ALUA Target Port Group ID: %hu already"
                                " exists, ignoring request\n", tg_pt_gp_id);
-                       spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+                       spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
                        return -EINVAL;
                }
        }
@@ -1449,9 +1437,9 @@ again:
        tg_pt_gp->tg_pt_gp_id = tg_pt_gp_id_tmp;
        tg_pt_gp->tg_pt_gp_valid_id = 1;
        list_add_tail(&tg_pt_gp->tg_pt_gp_list,
-                       &su_dev->t10_alua.tg_pt_gps_list);
-       su_dev->t10_alua.alua_tg_pt_gps_count++;
-       spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+                       &dev->t10_alua.tg_pt_gps_list);
+       dev->t10_alua.alua_tg_pt_gps_count++;
+       spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 
        return 0;
 }
@@ -1480,8 +1468,9 @@ struct t10_alua_tg_pt_gp_member *core_alua_allocate_tg_pt_gp_mem(
 void core_alua_free_tg_pt_gp(
        struct t10_alua_tg_pt_gp *tg_pt_gp)
 {
-       struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev;
+       struct se_device *dev = tg_pt_gp->tg_pt_gp_dev;
        struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, *tg_pt_gp_mem_tmp;
+
        /*
         * Once we have reached this point, config_item_put() has already
         * been called from target_core_alua_drop_tg_pt_gp().
@@ -1490,10 +1479,11 @@ void core_alua_free_tg_pt_gp(
         * no assications *OR* explict ALUA via SET_TARGET_PORT_GROUPS
         * can be made while we are releasing struct t10_alua_tg_pt_gp.
         */
-       spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
+       spin_lock(&dev->t10_alua.tg_pt_gps_lock);
        list_del(&tg_pt_gp->tg_pt_gp_list);
-       su_dev->t10_alua.alua_tg_pt_gps_counter--;
-       spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+       dev->t10_alua.alua_tg_pt_gps_counter--;
+       spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
+
        /*
         * Allow a struct t10_alua_tg_pt_gp_member * referenced by
         * core_alua_get_tg_pt_gp_by_name() in
@@ -1502,6 +1492,7 @@ void core_alua_free_tg_pt_gp(
         */
        while (atomic_read(&tg_pt_gp->tg_pt_gp_ref_cnt))
                cpu_relax();
+
        /*
         * Release reference to struct t10_alua_tg_pt_gp from all associated
         * struct se_port.
@@ -1525,9 +1516,9 @@ void core_alua_free_tg_pt_gp(
                 * default_tg_pt_gp.
                 */
                spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
-               if (tg_pt_gp != su_dev->t10_alua.default_tg_pt_gp) {
+               if (tg_pt_gp != dev->t10_alua.default_tg_pt_gp) {
                        __core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem,
-                                       su_dev->t10_alua.default_tg_pt_gp);
+                                       dev->t10_alua.default_tg_pt_gp);
                } else
                        tg_pt_gp_mem->tg_pt_gp = NULL;
                spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
@@ -1541,14 +1532,9 @@ void core_alua_free_tg_pt_gp(
 
 void core_alua_free_tg_pt_gp_mem(struct se_port *port)
 {
-       struct se_subsystem_dev *su_dev = port->sep_lun->lun_se_dev->se_sub_dev;
-       struct t10_alua *alua = &su_dev->t10_alua;
        struct t10_alua_tg_pt_gp *tg_pt_gp;
        struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
 
-       if (alua->alua_type != SPC3_ALUA_EMULATED)
-               return;
-
        tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
        if (!tg_pt_gp_mem)
                return;
@@ -1574,25 +1560,24 @@ void core_alua_free_tg_pt_gp_mem(struct se_port *port)
 }
 
 static struct t10_alua_tg_pt_gp *core_alua_get_tg_pt_gp_by_name(
-       struct se_subsystem_dev *su_dev,
-       const char *name)
+               struct se_device *dev, const char *name)
 {
        struct t10_alua_tg_pt_gp *tg_pt_gp;
        struct config_item *ci;
 
-       spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
-       list_for_each_entry(tg_pt_gp, &su_dev->t10_alua.tg_pt_gps_list,
+       spin_lock(&dev->t10_alua.tg_pt_gps_lock);
+       list_for_each_entry(tg_pt_gp, &dev->t10_alua.tg_pt_gps_list,
                        tg_pt_gp_list) {
                if (!tg_pt_gp->tg_pt_gp_valid_id)
                        continue;
                ci = &tg_pt_gp->tg_pt_gp_group.cg_item;
                if (!strcmp(config_item_name(ci), name)) {
                        atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt);
-                       spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+                       spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
                        return tg_pt_gp;
                }
        }
-       spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+       spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 
        return NULL;
 }
@@ -1600,11 +1585,11 @@ static struct t10_alua_tg_pt_gp *core_alua_get_tg_pt_gp_by_name(
 static void core_alua_put_tg_pt_gp_from_name(
        struct t10_alua_tg_pt_gp *tg_pt_gp)
 {
-       struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev;
+       struct se_device *dev = tg_pt_gp->tg_pt_gp_dev;
 
-       spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
+       spin_lock(&dev->t10_alua.tg_pt_gps_lock);
        atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt);
-       spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+       spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 }
 
 /*
@@ -1640,16 +1625,11 @@ static void __core_alua_drop_tg_pt_gp_mem(
 
 ssize_t core_alua_show_tg_pt_gp_info(struct se_port *port, char *page)
 {
-       struct se_subsystem_dev *su_dev = port->sep_lun->lun_se_dev->se_sub_dev;
        struct config_item *tg_pt_ci;
-       struct t10_alua *alua = &su_dev->t10_alua;
        struct t10_alua_tg_pt_gp *tg_pt_gp;
        struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
        ssize_t len = 0;
 
-       if (alua->alua_type != SPC3_ALUA_EMULATED)
-               return len;
-
        tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
        if (!tg_pt_gp_mem)
                return len;
@@ -1683,7 +1663,7 @@ ssize_t core_alua_store_tg_pt_gp_info(
 {
        struct se_portal_group *tpg;
        struct se_lun *lun;
-       struct se_subsystem_dev *su_dev = port->sep_lun->lun_se_dev->se_sub_dev;
+       struct se_device *dev = port->sep_lun->lun_se_dev;
        struct t10_alua_tg_pt_gp *tg_pt_gp = NULL, *tg_pt_gp_new = NULL;
        struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
        unsigned char buf[TG_PT_GROUP_NAME_BUF];
@@ -1692,13 +1672,9 @@ ssize_t core_alua_store_tg_pt_gp_info(
        tpg = port->sep_tpg;
        lun = port->sep_lun;
 
-       if (su_dev->t10_alua.alua_type != SPC3_ALUA_EMULATED) {
-               pr_warn("SPC3_ALUA_EMULATED not enabled for"
-                       " %s/tpgt_%hu/%s\n", tpg->se_tpg_tfo->tpg_get_wwn(tpg),
-                       tpg->se_tpg_tfo->tpg_get_tag(tpg),
-                       config_item_name(&lun->lun_group.cg_item));
-               return -EINVAL;
-       }
+       tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
+       if (!tg_pt_gp_mem)
+               return 0;
 
        if (count > TG_PT_GROUP_NAME_BUF) {
                pr_err("ALUA Target Port Group alias too large!\n");
@@ -1716,18 +1692,11 @@ ssize_t core_alua_store_tg_pt_gp_info(
                 * struct t10_alua_tg_pt_gp.  This reference is released with
                 * core_alua_put_tg_pt_gp_from_name() below.
                 */
-               tg_pt_gp_new = core_alua_get_tg_pt_gp_by_name(su_dev,
+               tg_pt_gp_new = core_alua_get_tg_pt_gp_by_name(dev,
                                        strstrip(buf));
                if (!tg_pt_gp_new)
                        return -ENODEV;
        }
-       tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
-       if (!tg_pt_gp_mem) {
-               if (tg_pt_gp_new)
-                       core_alua_put_tg_pt_gp_from_name(tg_pt_gp_new);
-               pr_err("NULL struct se_port->sep_alua_tg_pt_gp_mem pointer\n");
-               return -EINVAL;
-       }
 
        spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
        tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
@@ -1750,7 +1719,7 @@ ssize_t core_alua_store_tg_pt_gp_info(
 
                        __core_alua_drop_tg_pt_gp_mem(tg_pt_gp_mem, tg_pt_gp);
                        __core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem,
-                                       su_dev->t10_alua.default_tg_pt_gp);
+                                       dev->t10_alua.default_tg_pt_gp);
                        spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
 
                        return count;
@@ -2054,32 +2023,12 @@ ssize_t core_alua_store_secondary_write_metadata(
        return count;
 }
 
-int core_setup_alua(struct se_device *dev, int force_pt)
+int core_setup_alua(struct se_device *dev)
 {
-       struct se_subsystem_dev *su_dev = dev->se_sub_dev;
-       struct t10_alua *alua = &su_dev->t10_alua;
-       struct t10_alua_lu_gp_member *lu_gp_mem;
-       /*
-        * If this device is from Target_Core_Mod/pSCSI, use the ALUA logic
-        * of the Underlying SCSI hardware.  In Linux/SCSI terms, this can
-        * cause a problem because libata and some SATA RAID HBAs appear
-        * under Linux/SCSI, but emulate SCSI logic themselves.
-        */
-       if (((dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) &&
-           !(dev->se_sub_dev->se_dev_attrib.emulate_alua)) || force_pt) {
-               alua->alua_type = SPC_ALUA_PASSTHROUGH;
-               alua->alua_state_check = &core_alua_state_check_nop;
-               pr_debug("%s: Using SPC_ALUA_PASSTHROUGH, no ALUA"
-                       " emulation\n", dev->transport->name);
-               return 0;
-       }
-       /*
-        * If SPC-3 or above is reported by real or emulated struct se_device,
-        * use emulated ALUA.
-        */
-       if (dev->transport->get_device_rev(dev) >= SCSI_3) {
-               pr_debug("%s: Enabling ALUA Emulation for SPC-3"
-                       " device\n", dev->transport->name);
+       if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV &&
+           !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) {
+               struct t10_alua_lu_gp_member *lu_gp_mem;
+
                /*
                 * Associate this struct se_device with the default ALUA
                 * LUN Group.
@@ -2088,8 +2037,6 @@ int core_setup_alua(struct se_device *dev, int force_pt)
                if (IS_ERR(lu_gp_mem))
                        return PTR_ERR(lu_gp_mem);
 
-               alua->alua_type = SPC3_ALUA_EMULATED;
-               alua->alua_state_check = &core_alua_state_check;
                spin_lock(&lu_gp_mem->lu_gp_mem_lock);
                __core_alua_attach_lu_gp_mem(lu_gp_mem,
                                default_lu_gp);
@@ -2098,11 +2045,6 @@ int core_setup_alua(struct se_device *dev, int force_pt)
                pr_debug("%s: Adding to default ALUA LU Group:"
                        " core/alua/lu_gps/default_lu_gp\n",
                        dev->transport->name);
-       } else {
-               alua->alua_type = SPC2_ALUA_DISABLED;
-               alua->alua_state_check = &core_alua_state_check_nop;
-               pr_debug("%s: Disabling ALUA Emulation for SPC-2"
-                       " device\n", dev->transport->name);
        }
 
        return 0;