11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 2c66ac9dbSNicholas Bellinger /******************************************************************************* 3c66ac9dbSNicholas Bellinger * Filename: target_core_ua.c 4c66ac9dbSNicholas Bellinger * 5c66ac9dbSNicholas Bellinger * This file contains logic for SPC-3 Unit Attention emulation 6c66ac9dbSNicholas Bellinger * 74c76251eSNicholas Bellinger * (c) Copyright 2009-2013 Datera, Inc. 8c66ac9dbSNicholas Bellinger * 9c66ac9dbSNicholas Bellinger * Nicholas A. Bellinger <nab@kernel.org> 10c66ac9dbSNicholas Bellinger * 11c66ac9dbSNicholas Bellinger ******************************************************************************/ 12c66ac9dbSNicholas Bellinger 13c66ac9dbSNicholas Bellinger #include <linux/slab.h> 14c66ac9dbSNicholas Bellinger #include <linux/spinlock.h> 15ba929992SBart Van Assche #include <scsi/scsi_proto.h> 16c66ac9dbSNicholas Bellinger 17c66ac9dbSNicholas Bellinger #include <target/target_core_base.h> 18c4795fb2SChristoph Hellwig #include <target/target_core_fabric.h> 19c66ac9dbSNicholas Bellinger 20e26d99aeSChristoph Hellwig #include "target_core_internal.h" 21c66ac9dbSNicholas Bellinger #include "target_core_alua.h" 22c66ac9dbSNicholas Bellinger #include "target_core_pr.h" 23c66ac9dbSNicholas Bellinger #include "target_core_ua.h" 24c66ac9dbSNicholas Bellinger 25de103c93SChristoph Hellwig sense_reason_t 26de103c93SChristoph Hellwig target_scsi3_ua_check(struct se_cmd *cmd) 27c66ac9dbSNicholas Bellinger { 28c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 29c66ac9dbSNicholas Bellinger struct se_session *sess = cmd->se_sess; 30c66ac9dbSNicholas Bellinger struct se_node_acl *nacl; 31c66ac9dbSNicholas Bellinger 326708bb27SAndy Grover if (!sess) 33c66ac9dbSNicholas Bellinger return 0; 34c66ac9dbSNicholas Bellinger 35c66ac9dbSNicholas Bellinger nacl = sess->se_node_acl; 366708bb27SAndy Grover if (!nacl) 37c66ac9dbSNicholas Bellinger return 0; 38c66ac9dbSNicholas Bellinger 3929a05deeSNicholas Bellinger rcu_read_lock(); 4029a05deeSNicholas Bellinger deve = target_nacl_find_deve(nacl, cmd->orig_fe_lun); 4129a05deeSNicholas Bellinger if (!deve) { 4229a05deeSNicholas Bellinger rcu_read_unlock(); 43c66ac9dbSNicholas Bellinger return 0; 4429a05deeSNicholas Bellinger } 45e936a38aSBart Van Assche if (list_empty_careful(&deve->ua_list)) { 4629a05deeSNicholas Bellinger rcu_read_unlock(); 4729a05deeSNicholas Bellinger return 0; 4829a05deeSNicholas Bellinger } 4929a05deeSNicholas Bellinger rcu_read_unlock(); 50c66ac9dbSNicholas Bellinger /* 51c66ac9dbSNicholas Bellinger * From sam4r14, section 5.14 Unit attention condition: 52c66ac9dbSNicholas Bellinger * 53c66ac9dbSNicholas Bellinger * a) if an INQUIRY command enters the enabled command state, the 54c66ac9dbSNicholas Bellinger * device server shall process the INQUIRY command and shall neither 55c66ac9dbSNicholas Bellinger * report nor clear any unit attention condition; 56c66ac9dbSNicholas Bellinger * b) if a REPORT LUNS command enters the enabled command state, the 57c66ac9dbSNicholas Bellinger * device server shall process the REPORT LUNS command and shall not 58c66ac9dbSNicholas Bellinger * report any unit attention condition; 59c66ac9dbSNicholas Bellinger * e) if a REQUEST SENSE command enters the enabled command state while 60c66ac9dbSNicholas Bellinger * a unit attention condition exists for the SCSI initiator port 61c66ac9dbSNicholas Bellinger * associated with the I_T nexus on which the REQUEST SENSE command 62c66ac9dbSNicholas Bellinger * was received, then the device server shall process the command 63c66ac9dbSNicholas Bellinger * and either: 64c66ac9dbSNicholas Bellinger */ 65de103c93SChristoph Hellwig switch (cmd->t_task_cdb[0]) { 66c66ac9dbSNicholas Bellinger case INQUIRY: 67c66ac9dbSNicholas Bellinger case REPORT_LUNS: 68c66ac9dbSNicholas Bellinger case REQUEST_SENSE: 69c66ac9dbSNicholas Bellinger return 0; 70c66ac9dbSNicholas Bellinger default: 71de103c93SChristoph Hellwig return TCM_CHECK_CONDITION_UNIT_ATTENTION; 72c66ac9dbSNicholas Bellinger } 73c66ac9dbSNicholas Bellinger } 74c66ac9dbSNicholas Bellinger 75c66ac9dbSNicholas Bellinger int core_scsi3_ua_allocate( 76c51c8e7bSHannes Reinecke struct se_dev_entry *deve, 77c66ac9dbSNicholas Bellinger u8 asc, 78c66ac9dbSNicholas Bellinger u8 ascq) 79c66ac9dbSNicholas Bellinger { 80c66ac9dbSNicholas Bellinger struct se_ua *ua, *ua_p, *ua_tmp; 81c66ac9dbSNicholas Bellinger 82c66ac9dbSNicholas Bellinger ua = kmem_cache_zalloc(se_ua_cache, GFP_ATOMIC); 836708bb27SAndy Grover if (!ua) { 846708bb27SAndy Grover pr_err("Unable to allocate struct se_ua\n"); 85e3d6f909SAndy Grover return -ENOMEM; 86c66ac9dbSNicholas Bellinger } 87c66ac9dbSNicholas Bellinger INIT_LIST_HEAD(&ua->ua_nacl_list); 88c66ac9dbSNicholas Bellinger 89c66ac9dbSNicholas Bellinger ua->ua_asc = asc; 90c66ac9dbSNicholas Bellinger ua->ua_ascq = ascq; 91c66ac9dbSNicholas Bellinger 92c66ac9dbSNicholas Bellinger spin_lock(&deve->ua_lock); 93c66ac9dbSNicholas Bellinger list_for_each_entry_safe(ua_p, ua_tmp, &deve->ua_list, ua_nacl_list) { 94c66ac9dbSNicholas Bellinger /* 95c66ac9dbSNicholas Bellinger * Do not report the same UNIT ATTENTION twice.. 96c66ac9dbSNicholas Bellinger */ 97c66ac9dbSNicholas Bellinger if ((ua_p->ua_asc == asc) && (ua_p->ua_ascq == ascq)) { 98c66ac9dbSNicholas Bellinger spin_unlock(&deve->ua_lock); 99c66ac9dbSNicholas Bellinger kmem_cache_free(se_ua_cache, ua); 100c66ac9dbSNicholas Bellinger return 0; 101c66ac9dbSNicholas Bellinger } 102c66ac9dbSNicholas Bellinger /* 103c66ac9dbSNicholas Bellinger * Attach the highest priority Unit Attention to 104c66ac9dbSNicholas Bellinger * the head of the list following sam4r14, 105c66ac9dbSNicholas Bellinger * Section 5.14 Unit Attention Condition: 106c66ac9dbSNicholas Bellinger * 107c66ac9dbSNicholas Bellinger * POWER ON, RESET, OR BUS DEVICE RESET OCCURRED highest 108c66ac9dbSNicholas Bellinger * POWER ON OCCURRED or 109c66ac9dbSNicholas Bellinger * DEVICE INTERNAL RESET 110c66ac9dbSNicholas Bellinger * SCSI BUS RESET OCCURRED or 111c66ac9dbSNicholas Bellinger * MICROCODE HAS BEEN CHANGED or 112c66ac9dbSNicholas Bellinger * protocol specific 113c66ac9dbSNicholas Bellinger * BUS DEVICE RESET FUNCTION OCCURRED 114c66ac9dbSNicholas Bellinger * I_T NEXUS LOSS OCCURRED 115c66ac9dbSNicholas Bellinger * COMMANDS CLEARED BY POWER LOSS NOTIFICATION 116c66ac9dbSNicholas Bellinger * all others Lowest 117c66ac9dbSNicholas Bellinger * 118c66ac9dbSNicholas Bellinger * Each of the ASCQ codes listed above are defined in 119c66ac9dbSNicholas Bellinger * the 29h ASC family, see spc4r17 Table D.1 120c66ac9dbSNicholas Bellinger */ 121c66ac9dbSNicholas Bellinger if (ua_p->ua_asc == 0x29) { 122c66ac9dbSNicholas Bellinger if ((asc == 0x29) && (ascq > ua_p->ua_ascq)) 123c66ac9dbSNicholas Bellinger list_add(&ua->ua_nacl_list, 124c66ac9dbSNicholas Bellinger &deve->ua_list); 125c66ac9dbSNicholas Bellinger else 126c66ac9dbSNicholas Bellinger list_add_tail(&ua->ua_nacl_list, 127c66ac9dbSNicholas Bellinger &deve->ua_list); 128c66ac9dbSNicholas Bellinger } else if (ua_p->ua_asc == 0x2a) { 129c66ac9dbSNicholas Bellinger /* 130c66ac9dbSNicholas Bellinger * Incoming Family 29h ASCQ codes will override 131c66ac9dbSNicholas Bellinger * Family 2AHh ASCQ codes for Unit Attention condition. 132c66ac9dbSNicholas Bellinger */ 133c66ac9dbSNicholas Bellinger if ((asc == 0x29) || (ascq > ua_p->ua_asc)) 134c66ac9dbSNicholas Bellinger list_add(&ua->ua_nacl_list, 135c66ac9dbSNicholas Bellinger &deve->ua_list); 136c66ac9dbSNicholas Bellinger else 137c66ac9dbSNicholas Bellinger list_add_tail(&ua->ua_nacl_list, 138c66ac9dbSNicholas Bellinger &deve->ua_list); 139c66ac9dbSNicholas Bellinger } else 140c66ac9dbSNicholas Bellinger list_add_tail(&ua->ua_nacl_list, 141c66ac9dbSNicholas Bellinger &deve->ua_list); 142c66ac9dbSNicholas Bellinger spin_unlock(&deve->ua_lock); 143c66ac9dbSNicholas Bellinger 144c66ac9dbSNicholas Bellinger return 0; 145c66ac9dbSNicholas Bellinger } 146c66ac9dbSNicholas Bellinger list_add_tail(&ua->ua_nacl_list, &deve->ua_list); 147c66ac9dbSNicholas Bellinger spin_unlock(&deve->ua_lock); 148c66ac9dbSNicholas Bellinger 149c51c8e7bSHannes Reinecke pr_debug("Allocated UNIT ATTENTION, mapped LUN: %llu, ASC:" 150c51c8e7bSHannes Reinecke " 0x%02x, ASCQ: 0x%02x\n", deve->mapped_lun, 151c66ac9dbSNicholas Bellinger asc, ascq); 152c66ac9dbSNicholas Bellinger 153c66ac9dbSNicholas Bellinger return 0; 154c66ac9dbSNicholas Bellinger } 155c66ac9dbSNicholas Bellinger 156c51c8e7bSHannes Reinecke void target_ua_allocate_lun(struct se_node_acl *nacl, 157c51c8e7bSHannes Reinecke u32 unpacked_lun, u8 asc, u8 ascq) 158c51c8e7bSHannes Reinecke { 159c51c8e7bSHannes Reinecke struct se_dev_entry *deve; 160c51c8e7bSHannes Reinecke 161c51c8e7bSHannes Reinecke if (!nacl) 162c51c8e7bSHannes Reinecke return; 163c51c8e7bSHannes Reinecke 164c51c8e7bSHannes Reinecke rcu_read_lock(); 165c51c8e7bSHannes Reinecke deve = target_nacl_find_deve(nacl, unpacked_lun); 166c51c8e7bSHannes Reinecke if (!deve) { 167c51c8e7bSHannes Reinecke rcu_read_unlock(); 168c51c8e7bSHannes Reinecke return; 169c51c8e7bSHannes Reinecke } 170c51c8e7bSHannes Reinecke 171c51c8e7bSHannes Reinecke core_scsi3_ua_allocate(deve, asc, ascq); 172c51c8e7bSHannes Reinecke rcu_read_unlock(); 173c51c8e7bSHannes Reinecke } 174c51c8e7bSHannes Reinecke 175c66ac9dbSNicholas Bellinger void core_scsi3_ua_release_all( 176c66ac9dbSNicholas Bellinger struct se_dev_entry *deve) 177c66ac9dbSNicholas Bellinger { 178c66ac9dbSNicholas Bellinger struct se_ua *ua, *ua_p; 179c66ac9dbSNicholas Bellinger 180c66ac9dbSNicholas Bellinger spin_lock(&deve->ua_lock); 181c66ac9dbSNicholas Bellinger list_for_each_entry_safe(ua, ua_p, &deve->ua_list, ua_nacl_list) { 182c66ac9dbSNicholas Bellinger list_del(&ua->ua_nacl_list); 183c66ac9dbSNicholas Bellinger kmem_cache_free(se_ua_cache, ua); 184c66ac9dbSNicholas Bellinger } 185c66ac9dbSNicholas Bellinger spin_unlock(&deve->ua_lock); 186c66ac9dbSNicholas Bellinger } 187c66ac9dbSNicholas Bellinger 188325c1e8bSBart Van Assche /* 189325c1e8bSBart Van Assche * Dequeue a unit attention from the unit attention list. This function 190325c1e8bSBart Van Assche * returns true if the dequeuing succeeded and if *@key, *@asc and *@ascq have 191325c1e8bSBart Van Assche * been set. 192325c1e8bSBart Van Assche */ 193325c1e8bSBart Van Assche bool core_scsi3_ua_for_check_condition(struct se_cmd *cmd, u8 *key, u8 *asc, 194c66ac9dbSNicholas Bellinger u8 *ascq) 195c66ac9dbSNicholas Bellinger { 1965951146dSAndy Grover struct se_device *dev = cmd->se_dev; 197c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 198c66ac9dbSNicholas Bellinger struct se_session *sess = cmd->se_sess; 199c66ac9dbSNicholas Bellinger struct se_node_acl *nacl; 200c66ac9dbSNicholas Bellinger struct se_ua *ua = NULL, *ua_p; 201c66ac9dbSNicholas Bellinger int head = 1; 202c66ac9dbSNicholas Bellinger 203325c1e8bSBart Van Assche if (WARN_ON_ONCE(!sess)) 204325c1e8bSBart Van Assche return false; 205c66ac9dbSNicholas Bellinger 206c66ac9dbSNicholas Bellinger nacl = sess->se_node_acl; 207325c1e8bSBart Van Assche if (WARN_ON_ONCE(!nacl)) 208325c1e8bSBart Van Assche return false; 209c66ac9dbSNicholas Bellinger 21029a05deeSNicholas Bellinger rcu_read_lock(); 21129a05deeSNicholas Bellinger deve = target_nacl_find_deve(nacl, cmd->orig_fe_lun); 21229a05deeSNicholas Bellinger if (!deve) { 21329a05deeSNicholas Bellinger rcu_read_unlock(); 214325c1e8bSBart Van Assche *key = ILLEGAL_REQUEST; 215325c1e8bSBart Van Assche *asc = 0x25; /* LOGICAL UNIT NOT SUPPORTED */ 216325c1e8bSBart Van Assche *ascq = 0; 217325c1e8bSBart Van Assche return true; 21829a05deeSNicholas Bellinger } 219325c1e8bSBart Van Assche *key = UNIT_ATTENTION; 220c66ac9dbSNicholas Bellinger /* 221c66ac9dbSNicholas Bellinger * The highest priority Unit Attentions are placed at the head of the 222c66ac9dbSNicholas Bellinger * struct se_dev_entry->ua_list, and will be returned in CHECK_CONDITION + 223c66ac9dbSNicholas Bellinger * sense data for the received CDB. 224c66ac9dbSNicholas Bellinger */ 225c66ac9dbSNicholas Bellinger spin_lock(&deve->ua_lock); 226c66ac9dbSNicholas Bellinger list_for_each_entry_safe(ua, ua_p, &deve->ua_list, ua_nacl_list) { 227c66ac9dbSNicholas Bellinger /* 228c66ac9dbSNicholas Bellinger * For ua_intlck_ctrl code not equal to 00b, only report the 229c66ac9dbSNicholas Bellinger * highest priority UNIT_ATTENTION and ASC/ASCQ without 230c66ac9dbSNicholas Bellinger * clearing it. 231c66ac9dbSNicholas Bellinger */ 2320fd97ccfSChristoph Hellwig if (dev->dev_attrib.emulate_ua_intlck_ctrl != 0) { 233c66ac9dbSNicholas Bellinger *asc = ua->ua_asc; 234c66ac9dbSNicholas Bellinger *ascq = ua->ua_ascq; 235c66ac9dbSNicholas Bellinger break; 236c66ac9dbSNicholas Bellinger } 237c66ac9dbSNicholas Bellinger /* 238c66ac9dbSNicholas Bellinger * Otherwise for the default 00b, release the UNIT ATTENTION 23925985edcSLucas De Marchi * condition. Return the ASC/ASCQ of the highest priority UA 240c66ac9dbSNicholas Bellinger * (head of the list) in the outgoing CHECK_CONDITION + sense. 241c66ac9dbSNicholas Bellinger */ 242c66ac9dbSNicholas Bellinger if (head) { 243c66ac9dbSNicholas Bellinger *asc = ua->ua_asc; 244c66ac9dbSNicholas Bellinger *ascq = ua->ua_ascq; 245c66ac9dbSNicholas Bellinger head = 0; 246c66ac9dbSNicholas Bellinger } 247c66ac9dbSNicholas Bellinger list_del(&ua->ua_nacl_list); 248c66ac9dbSNicholas Bellinger kmem_cache_free(se_ua_cache, ua); 249c66ac9dbSNicholas Bellinger } 250c66ac9dbSNicholas Bellinger spin_unlock(&deve->ua_lock); 25129a05deeSNicholas Bellinger rcu_read_unlock(); 252c66ac9dbSNicholas Bellinger 2536708bb27SAndy Grover pr_debug("[%s]: %s UNIT ATTENTION condition with" 254f2d30680SHannes Reinecke " INTLCK_CTRL: %d, mapped LUN: %llu, got CDB: 0x%02x" 255c66ac9dbSNicholas Bellinger " reported ASC: 0x%02x, ASCQ: 0x%02x\n", 25630c7ca93SDavid Disseldorp nacl->se_tpg->se_tpg_tfo->fabric_name, 2570fd97ccfSChristoph Hellwig (dev->dev_attrib.emulate_ua_intlck_ctrl != 0) ? "Reporting" : 2580fd97ccfSChristoph Hellwig "Releasing", dev->dev_attrib.emulate_ua_intlck_ctrl, 259a1d8b49aSAndy Grover cmd->orig_fe_lun, cmd->t_task_cdb[0], *asc, *ascq); 260325c1e8bSBart Van Assche 261325c1e8bSBart Van Assche return head == 0; 262c66ac9dbSNicholas Bellinger } 263c66ac9dbSNicholas Bellinger 264c66ac9dbSNicholas Bellinger int core_scsi3_ua_clear_for_request_sense( 265c66ac9dbSNicholas Bellinger struct se_cmd *cmd, 266c66ac9dbSNicholas Bellinger u8 *asc, 267c66ac9dbSNicholas Bellinger u8 *ascq) 268c66ac9dbSNicholas Bellinger { 269c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 270c66ac9dbSNicholas Bellinger struct se_session *sess = cmd->se_sess; 271c66ac9dbSNicholas Bellinger struct se_node_acl *nacl; 272c66ac9dbSNicholas Bellinger struct se_ua *ua = NULL, *ua_p; 273c66ac9dbSNicholas Bellinger int head = 1; 274c66ac9dbSNicholas Bellinger 2756708bb27SAndy Grover if (!sess) 276e3d6f909SAndy Grover return -EINVAL; 277c66ac9dbSNicholas Bellinger 278c66ac9dbSNicholas Bellinger nacl = sess->se_node_acl; 2796708bb27SAndy Grover if (!nacl) 280e3d6f909SAndy Grover return -EINVAL; 281c66ac9dbSNicholas Bellinger 28229a05deeSNicholas Bellinger rcu_read_lock(); 28329a05deeSNicholas Bellinger deve = target_nacl_find_deve(nacl, cmd->orig_fe_lun); 28429a05deeSNicholas Bellinger if (!deve) { 28529a05deeSNicholas Bellinger rcu_read_unlock(); 28629a05deeSNicholas Bellinger return -EINVAL; 28729a05deeSNicholas Bellinger } 288e936a38aSBart Van Assche if (list_empty_careful(&deve->ua_list)) { 28929a05deeSNicholas Bellinger rcu_read_unlock(); 290e3d6f909SAndy Grover return -EPERM; 291c66ac9dbSNicholas Bellinger } 292c66ac9dbSNicholas Bellinger /* 293c66ac9dbSNicholas Bellinger * The highest priority Unit Attentions are placed at the head of the 294c66ac9dbSNicholas Bellinger * struct se_dev_entry->ua_list. The First (and hence highest priority) 295c66ac9dbSNicholas Bellinger * ASC/ASCQ will be returned in REQUEST_SENSE payload data for the 296c66ac9dbSNicholas Bellinger * matching struct se_lun. 297c66ac9dbSNicholas Bellinger * 298c66ac9dbSNicholas Bellinger * Once the returning ASC/ASCQ values are set, we go ahead and 29925985edcSLucas De Marchi * release all of the Unit Attention conditions for the associated 300c66ac9dbSNicholas Bellinger * struct se_lun. 301c66ac9dbSNicholas Bellinger */ 302c66ac9dbSNicholas Bellinger spin_lock(&deve->ua_lock); 303c66ac9dbSNicholas Bellinger list_for_each_entry_safe(ua, ua_p, &deve->ua_list, ua_nacl_list) { 304c66ac9dbSNicholas Bellinger if (head) { 305c66ac9dbSNicholas Bellinger *asc = ua->ua_asc; 306c66ac9dbSNicholas Bellinger *ascq = ua->ua_ascq; 307c66ac9dbSNicholas Bellinger head = 0; 308c66ac9dbSNicholas Bellinger } 309c66ac9dbSNicholas Bellinger list_del(&ua->ua_nacl_list); 310c66ac9dbSNicholas Bellinger kmem_cache_free(se_ua_cache, ua); 311c66ac9dbSNicholas Bellinger } 312c66ac9dbSNicholas Bellinger spin_unlock(&deve->ua_lock); 31329a05deeSNicholas Bellinger rcu_read_unlock(); 314c66ac9dbSNicholas Bellinger 3156708bb27SAndy Grover pr_debug("[%s]: Released UNIT ATTENTION condition, mapped" 316f2d30680SHannes Reinecke " LUN: %llu, got REQUEST_SENSE reported ASC: 0x%02x," 31730c7ca93SDavid Disseldorp " ASCQ: 0x%02x\n", nacl->se_tpg->se_tpg_tfo->fabric_name, 318c66ac9dbSNicholas Bellinger cmd->orig_fe_lun, *asc, *ascq); 319c66ac9dbSNicholas Bellinger 320e3d6f909SAndy Grover return (head) ? -EPERM : 0; 321c66ac9dbSNicholas Bellinger } 322