11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 2c66ac9dbSNicholas Bellinger /******************************************************************************* 3c66ac9dbSNicholas Bellinger * Filename: target_core_tmr.c 4c66ac9dbSNicholas Bellinger * 5c66ac9dbSNicholas Bellinger * This file contains SPC-3 task management infrastructure 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> 15c66ac9dbSNicholas Bellinger #include <linux/list.h> 16c53181afSPaul Gortmaker #include <linux/export.h> 17c66ac9dbSNicholas Bellinger 18c66ac9dbSNicholas Bellinger #include <target/target_core_base.h> 19c4795fb2SChristoph Hellwig #include <target/target_core_backend.h> 20c4795fb2SChristoph Hellwig #include <target/target_core_fabric.h> 21c66ac9dbSNicholas Bellinger 22e26d99aeSChristoph Hellwig #include "target_core_internal.h" 23c66ac9dbSNicholas Bellinger #include "target_core_alua.h" 24c66ac9dbSNicholas Bellinger #include "target_core_pr.h" 25c66ac9dbSNicholas Bellinger 26c8e31f26SAndy Grover int core_tmr_alloc_req( 27c66ac9dbSNicholas Bellinger struct se_cmd *se_cmd, 28c66ac9dbSNicholas Bellinger void *fabric_tmr_ptr, 29dd503a5fSRoland Dreier u8 function, 30dd503a5fSRoland Dreier gfp_t gfp_flags) 31c66ac9dbSNicholas Bellinger { 32c66ac9dbSNicholas Bellinger struct se_tmr_req *tmr; 33c66ac9dbSNicholas Bellinger 34c8e31f26SAndy Grover tmr = kzalloc(sizeof(struct se_tmr_req), gfp_flags); 356708bb27SAndy Grover if (!tmr) { 366708bb27SAndy Grover pr_err("Unable to allocate struct se_tmr_req\n"); 37c8e31f26SAndy Grover return -ENOMEM; 38c66ac9dbSNicholas Bellinger } 39c8e31f26SAndy Grover 40c8e31f26SAndy Grover se_cmd->se_cmd_flags |= SCF_SCSI_TMR_CDB; 41c8e31f26SAndy Grover se_cmd->se_tmr_req = tmr; 42c66ac9dbSNicholas Bellinger tmr->task_cmd = se_cmd; 43c66ac9dbSNicholas Bellinger tmr->fabric_tmr_ptr = fabric_tmr_ptr; 44c66ac9dbSNicholas Bellinger tmr->function = function; 45c66ac9dbSNicholas Bellinger INIT_LIST_HEAD(&tmr->tmr_list); 46c66ac9dbSNicholas Bellinger 47c8e31f26SAndy Grover return 0; 48c66ac9dbSNicholas Bellinger } 49c66ac9dbSNicholas Bellinger EXPORT_SYMBOL(core_tmr_alloc_req); 50c66ac9dbSNicholas Bellinger 518f832690SJoern Engel void core_tmr_release_req(struct se_tmr_req *tmr) 52c66ac9dbSNicholas Bellinger { 53c66ac9dbSNicholas Bellinger struct se_device *dev = tmr->tmr_dev; 54d050ffb9SNicholas Bellinger unsigned long flags; 55c66ac9dbSNicholas Bellinger 568f832690SJoern Engel if (dev) { 57d050ffb9SNicholas Bellinger spin_lock_irqsave(&dev->se_tmr_lock, flags); 58a6d9bb1cSNicholas Bellinger list_del_init(&tmr->tmr_list); 59d050ffb9SNicholas Bellinger spin_unlock_irqrestore(&dev->se_tmr_lock, flags); 608f832690SJoern Engel } 617fd29aa9SNicholas Bellinger 62c8e31f26SAndy Grover kfree(tmr); 63c66ac9dbSNicholas Bellinger } 64c66ac9dbSNicholas Bellinger 65feae8564SJörn Engel static int target_check_cdb_and_preempt(struct list_head *list, 66c165f69cSJörn Engel struct se_cmd *cmd) 67c165f69cSJörn Engel { 68feae8564SJörn Engel struct t10_pr_registration *reg; 69c165f69cSJörn Engel 70feae8564SJörn Engel if (!list) 71feae8564SJörn Engel return 0; 72feae8564SJörn Engel list_for_each_entry(reg, list, pr_reg_abort_list) { 73feae8564SJörn Engel if (reg->pr_res_key == cmd->pr_res_key) 74c165f69cSJörn Engel return 0; 75c165f69cSJörn Engel } 76c165f69cSJörn Engel 77c165f69cSJörn Engel return 1; 78c165f69cSJörn Engel } 79c165f69cSJörn Engel 800f4a9431SNicholas Bellinger static bool __target_check_io_state(struct se_cmd *se_cmd, 8187310c9fSDavid Disseldorp struct se_session *tmr_sess, bool tas) 82febe562cSNicholas Bellinger { 83febe562cSNicholas Bellinger struct se_session *sess = se_cmd->se_sess; 84febe562cSNicholas Bellinger 85febe562cSNicholas Bellinger assert_spin_locked(&sess->sess_cmd_lock); 86febe562cSNicholas Bellinger WARN_ON_ONCE(!irqs_disabled()); 87febe562cSNicholas Bellinger /* 88febe562cSNicholas Bellinger * If command already reached CMD_T_COMPLETE state within 890f4a9431SNicholas Bellinger * target_complete_cmd() or CMD_T_FABRIC_STOP due to shutdown, 900f4a9431SNicholas Bellinger * this se_cmd has been passed to fabric driver and will 910f4a9431SNicholas Bellinger * not be aborted. 92febe562cSNicholas Bellinger * 93febe562cSNicholas Bellinger * Otherwise, obtain a local se_cmd->cmd_kref now for TMR 94febe562cSNicholas Bellinger * ABORT_TASK + LUN_RESET for CMD_T_ABORTED processing as 95febe562cSNicholas Bellinger * long as se_cmd->cmd_kref is still active unless zero. 96febe562cSNicholas Bellinger */ 97febe562cSNicholas Bellinger spin_lock(&se_cmd->t_state_lock); 980f4a9431SNicholas Bellinger if (se_cmd->transport_state & (CMD_T_COMPLETE | CMD_T_FABRIC_STOP)) { 990f4a9431SNicholas Bellinger pr_debug("Attempted to abort io tag: %llu already complete or" 1000f4a9431SNicholas Bellinger " fabric stop, skipping\n", se_cmd->tag); 1010f4a9431SNicholas Bellinger spin_unlock(&se_cmd->t_state_lock); 1020f4a9431SNicholas Bellinger return false; 1030f4a9431SNicholas Bellinger } 104febe562cSNicholas Bellinger se_cmd->transport_state |= CMD_T_ABORTED; 1050f4a9431SNicholas Bellinger 1060f4a9431SNicholas Bellinger if ((tmr_sess != se_cmd->se_sess) && tas) 1070f4a9431SNicholas Bellinger se_cmd->transport_state |= CMD_T_TAS; 1080f4a9431SNicholas Bellinger 109febe562cSNicholas Bellinger spin_unlock(&se_cmd->t_state_lock); 110febe562cSNicholas Bellinger 111febe562cSNicholas Bellinger return kref_get_unless_zero(&se_cmd->cmd_kref); 112febe562cSNicholas Bellinger } 113febe562cSNicholas Bellinger 1143d28934aSNicholas Bellinger void core_tmr_abort_task( 1153d28934aSNicholas Bellinger struct se_device *dev, 1163d28934aSNicholas Bellinger struct se_tmr_req *tmr, 1173d28934aSNicholas Bellinger struct se_session *se_sess) 1183d28934aSNicholas Bellinger { 119f5e2714aSBodo Stroesser struct se_cmd *se_cmd, *next; 1203d28934aSNicholas Bellinger unsigned long flags; 121f5e2714aSBodo Stroesser bool rc; 122649ee054SBart Van Assche u64 ref_tag; 1233d28934aSNicholas Bellinger 124f5e2714aSBodo Stroesser spin_lock_irqsave(&dev->execute_task_lock, flags); 125f5e2714aSBodo Stroesser list_for_each_entry_safe(se_cmd, next, &dev->state_list, state_list) { 1263d28934aSNicholas Bellinger 127f5e2714aSBodo Stroesser if (se_sess != se_cmd->se_sess) 1283d28934aSNicholas Bellinger continue; 12947b1584cSAlex Leung 130dc0fafdaSBart Van Assche /* skip task management functions, including tmr->task_cmd */ 131dc0fafdaSBart Van Assche if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) 13247b1584cSAlex Leung continue; 13347b1584cSAlex Leung 134649ee054SBart Van Assche ref_tag = se_cmd->tag; 1353d28934aSNicholas Bellinger if (tmr->ref_task_tag != ref_tag) 1363d28934aSNicholas Bellinger continue; 1373d28934aSNicholas Bellinger 138649ee054SBart Van Assche printk("ABORT_TASK: Found referenced %s task_tag: %llu\n", 13930c7ca93SDavid Disseldorp se_cmd->se_tfo->fabric_name, ref_tag); 1403d28934aSNicholas Bellinger 141f5e2714aSBodo Stroesser spin_lock(&se_sess->sess_cmd_lock); 142f5e2714aSBodo Stroesser rc = __target_check_io_state(se_cmd, se_sess, 0); 143f5e2714aSBodo Stroesser spin_unlock(&se_sess->sess_cmd_lock); 144f5e2714aSBodo Stroesser if (!rc) 1453a1e7ca6SBart Van Assche continue; 1463a1e7ca6SBart Van Assche 147f5e2714aSBodo Stroesser list_del_init(&se_cmd->state_list); 148f5e2714aSBodo Stroesser se_cmd->state_active = false; 149f5e2714aSBodo Stroesser 150f5e2714aSBodo Stroesser spin_unlock_irqrestore(&dev->execute_task_lock, flags); 1513d28934aSNicholas Bellinger 1522c9fa49eSBart Van Assche /* 1532c9fa49eSBart Van Assche * Ensure that this ABORT request is visible to the LU RESET 1542c9fa49eSBart Van Assche * code. 1552c9fa49eSBart Van Assche */ 1562c9fa49eSBart Van Assche if (!tmr->tmr_dev) 157a36840d8SSudhakar Panneerselvam WARN_ON_ONCE(transport_lookup_tmr_lun(tmr->task_cmd) < 158a36840d8SSudhakar Panneerselvam 0); 1593d28934aSNicholas Bellinger 1602c9fa49eSBart Van Assche target_put_cmd_and_wait(se_cmd); 1613d28934aSNicholas Bellinger 1623d28934aSNicholas Bellinger printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for" 163649ee054SBart Van Assche " ref_tag: %llu\n", ref_tag); 1643d28934aSNicholas Bellinger tmr->response = TMR_FUNCTION_COMPLETE; 165c87ba9c4SNicholas Bellinger atomic_long_inc(&dev->aborts_complete); 1663d28934aSNicholas Bellinger return; 1673d28934aSNicholas Bellinger } 168f5e2714aSBodo Stroesser spin_unlock_irqrestore(&dev->execute_task_lock, flags); 1693d28934aSNicholas Bellinger 170649ee054SBart Van Assche printk("ABORT_TASK: Sending TMR_TASK_DOES_NOT_EXIST for ref_tag: %lld\n", 1713d28934aSNicholas Bellinger tmr->ref_task_tag); 1723d28934aSNicholas Bellinger tmr->response = TMR_TASK_DOES_NOT_EXIST; 173c87ba9c4SNicholas Bellinger atomic_long_inc(&dev->aborts_no_task); 1743d28934aSNicholas Bellinger } 1753d28934aSNicholas Bellinger 176d050ffb9SNicholas Bellinger static void core_tmr_drain_tmr_list( 177c66ac9dbSNicholas Bellinger struct se_device *dev, 178c66ac9dbSNicholas Bellinger struct se_tmr_req *tmr, 179d050ffb9SNicholas Bellinger struct list_head *preempt_and_abort_list) 180c66ac9dbSNicholas Bellinger { 181d050ffb9SNicholas Bellinger LIST_HEAD(drain_tmr_list); 182a6d9bb1cSNicholas Bellinger struct se_session *sess; 183c66ac9dbSNicholas Bellinger struct se_tmr_req *tmr_p, *tmr_pp; 184d050ffb9SNicholas Bellinger struct se_cmd *cmd; 185c66ac9dbSNicholas Bellinger unsigned long flags; 186a6d9bb1cSNicholas Bellinger bool rc; 187c66ac9dbSNicholas Bellinger /* 188c66ac9dbSNicholas Bellinger * Release all pending and outgoing TMRs aside from the received 189c66ac9dbSNicholas Bellinger * LUN_RESET tmr.. 190c66ac9dbSNicholas Bellinger */ 191d050ffb9SNicholas Bellinger spin_lock_irqsave(&dev->se_tmr_lock, flags); 19288fb2fa7Stangwenji if (tmr) 19351ec502aSBart Van Assche list_del_init(&tmr->tmr_list); 194c66ac9dbSNicholas Bellinger list_for_each_entry_safe(tmr_p, tmr_pp, &dev->dev_tmr_list, tmr_list) { 195c66ac9dbSNicholas Bellinger cmd = tmr_p->task_cmd; 1966708bb27SAndy Grover if (!cmd) { 1976708bb27SAndy Grover pr_err("Unable to locate struct se_cmd for TMR\n"); 198c66ac9dbSNicholas Bellinger continue; 199c66ac9dbSNicholas Bellinger } 200c66ac9dbSNicholas Bellinger /* 201c66ac9dbSNicholas Bellinger * If this function was called with a valid pr_res_key 202c66ac9dbSNicholas Bellinger * parameter (eg: for PROUT PREEMPT_AND_ABORT service action 203ac75d8beSBart Van Assche * skip non registration key matching TMRs. 204c66ac9dbSNicholas Bellinger */ 205feae8564SJörn Engel if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd)) 206c66ac9dbSNicholas Bellinger continue; 207c66ac9dbSNicholas Bellinger 208a6d9bb1cSNicholas Bellinger sess = cmd->se_sess; 209a6d9bb1cSNicholas Bellinger if (WARN_ON_ONCE(!sess)) 210a6d9bb1cSNicholas Bellinger continue; 211a6d9bb1cSNicholas Bellinger 212a6d9bb1cSNicholas Bellinger spin_lock(&sess->sess_cmd_lock); 2132281c95fSBart Van Assche rc = __target_check_io_state(cmd, sess, 0); 214a6d9bb1cSNicholas Bellinger spin_unlock(&sess->sess_cmd_lock); 215d050ffb9SNicholas Bellinger 216a6d9bb1cSNicholas Bellinger if (!rc) { 217a6d9bb1cSNicholas Bellinger printk("LUN_RESET TMR: non-zero kref_get_unless_zero\n"); 218a6d9bb1cSNicholas Bellinger continue; 219a6d9bb1cSNicholas Bellinger } 2200f4a9431SNicholas Bellinger 2216eb40b2aSJoern Engel list_move_tail(&tmr_p->tmr_list, &drain_tmr_list); 222d050ffb9SNicholas Bellinger } 223d050ffb9SNicholas Bellinger spin_unlock_irqrestore(&dev->se_tmr_lock, flags); 224d050ffb9SNicholas Bellinger 225abc1fd4fSJoern Engel list_for_each_entry_safe(tmr_p, tmr_pp, &drain_tmr_list, tmr_list) { 226b8a11d73SJoern Engel list_del_init(&tmr_p->tmr_list); 227abc1fd4fSJoern Engel cmd = tmr_p->task_cmd; 228d050ffb9SNicholas Bellinger 2296708bb27SAndy Grover pr_debug("LUN_RESET: %s releasing TMR %p Function: 0x%02x," 230c66ac9dbSNicholas Bellinger " Response: 0x%02x, t_state: %d\n", 231abc1fd4fSJoern Engel (preempt_and_abort_list) ? "Preempt" : "", tmr_p, 232abc1fd4fSJoern Engel tmr_p->function, tmr_p->response, cmd->t_state); 233c66ac9dbSNicholas Bellinger 2342c9fa49eSBart Van Assche target_put_cmd_and_wait(cmd); 235c66ac9dbSNicholas Bellinger } 236d050ffb9SNicholas Bellinger } 237d050ffb9SNicholas Bellinger 2382c9fa49eSBart Van Assche /** 2392c9fa49eSBart Van Assche * core_tmr_drain_state_list() - abort SCSI commands associated with a device 2402c9fa49eSBart Van Assche * 2412c9fa49eSBart Van Assche * @dev: Device for which to abort outstanding SCSI commands. 2422c9fa49eSBart Van Assche * @prout_cmd: Pointer to the SCSI PREEMPT AND ABORT if this function is called 2432c9fa49eSBart Van Assche * to realize the PREEMPT AND ABORT functionality. 2442c9fa49eSBart Van Assche * @tmr_sess: Session through which the LUN RESET has been received. 2452c9fa49eSBart Van Assche * @tas: Task Aborted Status (TAS) bit from the SCSI control mode page. 2462c9fa49eSBart Van Assche * A quote from SPC-4, paragraph "7.5.10 Control mode page": 2472c9fa49eSBart Van Assche * "A task aborted status (TAS) bit set to zero specifies that 2482c9fa49eSBart Van Assche * aborted commands shall be terminated by the device server 2492c9fa49eSBart Van Assche * without any response to the application client. A TAS bit set 2502c9fa49eSBart Van Assche * to one specifies that commands aborted by the actions of an I_T 2512c9fa49eSBart Van Assche * nexus other than the I_T nexus on which the command was 2522c9fa49eSBart Van Assche * received shall be completed with TASK ABORTED status." 2532c9fa49eSBart Van Assche * @preempt_and_abort_list: For the PREEMPT AND ABORT functionality, a list 2542c9fa49eSBart Van Assche * with registrations that will be preempted. 2552c9fa49eSBart Van Assche */ 256cf572a96SChristoph Hellwig static void core_tmr_drain_state_list( 257d050ffb9SNicholas Bellinger struct se_device *dev, 258d050ffb9SNicholas Bellinger struct se_cmd *prout_cmd, 259ebde1ca5SNicholas Bellinger struct se_session *tmr_sess, 26087310c9fSDavid Disseldorp bool tas, 261d050ffb9SNicholas Bellinger struct list_head *preempt_and_abort_list) 262d050ffb9SNicholas Bellinger { 263d050ffb9SNicholas Bellinger LIST_HEAD(drain_task_list); 264febe562cSNicholas Bellinger struct se_session *sess; 265cf572a96SChristoph Hellwig struct se_cmd *cmd, *next; 266d050ffb9SNicholas Bellinger unsigned long flags; 267febe562cSNicholas Bellinger int rc; 268cf572a96SChristoph Hellwig 269c66ac9dbSNicholas Bellinger /* 270cf572a96SChristoph Hellwig * Complete outstanding commands with TASK_ABORTED SAM status. 271cf572a96SChristoph Hellwig * 272c66ac9dbSNicholas Bellinger * This is following sam4r17, section 5.6 Aborting commands, Table 38 273c66ac9dbSNicholas Bellinger * for TMR LUN_RESET: 274c66ac9dbSNicholas Bellinger * 275c66ac9dbSNicholas Bellinger * a) "Yes" indicates that each command that is aborted on an I_T nexus 276c66ac9dbSNicholas Bellinger * other than the one that caused the SCSI device condition is 277c66ac9dbSNicholas Bellinger * completed with TASK ABORTED status, if the TAS bit is set to one in 278c66ac9dbSNicholas Bellinger * the Control mode page (see SPC-4). "No" indicates that no status is 279c66ac9dbSNicholas Bellinger * returned for aborted commands. 280c66ac9dbSNicholas Bellinger * 281c66ac9dbSNicholas Bellinger * d) If the logical unit reset is caused by a particular I_T nexus 282c66ac9dbSNicholas Bellinger * (e.g., by a LOGICAL UNIT RESET task management function), then "yes" 283c66ac9dbSNicholas Bellinger * (TASK_ABORTED status) applies. 284c66ac9dbSNicholas Bellinger * 285c66ac9dbSNicholas Bellinger * Otherwise (e.g., if triggered by a hard reset), "no" 286c66ac9dbSNicholas Bellinger * (no TASK_ABORTED SAM status) applies. 287c66ac9dbSNicholas Bellinger * 288c66ac9dbSNicholas Bellinger * Note that this seems to be independent of TAS (Task Aborted Status) 289c66ac9dbSNicholas Bellinger * in the Control Mode Page. 290c66ac9dbSNicholas Bellinger */ 291c66ac9dbSNicholas Bellinger spin_lock_irqsave(&dev->execute_task_lock, flags); 292cf572a96SChristoph Hellwig list_for_each_entry_safe(cmd, next, &dev->state_list, state_list) { 293c66ac9dbSNicholas Bellinger /* 294c66ac9dbSNicholas Bellinger * For PREEMPT_AND_ABORT usage, only process commands 295c66ac9dbSNicholas Bellinger * with a matching reservation key. 296c66ac9dbSNicholas Bellinger */ 297feae8564SJörn Engel if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd)) 298c66ac9dbSNicholas Bellinger continue; 299cf572a96SChristoph Hellwig 300c66ac9dbSNicholas Bellinger /* 301c66ac9dbSNicholas Bellinger * Not aborting PROUT PREEMPT_AND_ABORT CDB.. 302c66ac9dbSNicholas Bellinger */ 303c66ac9dbSNicholas Bellinger if (prout_cmd == cmd) 304c66ac9dbSNicholas Bellinger continue; 305c66ac9dbSNicholas Bellinger 306febe562cSNicholas Bellinger sess = cmd->se_sess; 307febe562cSNicholas Bellinger if (WARN_ON_ONCE(!sess)) 308febe562cSNicholas Bellinger continue; 309febe562cSNicholas Bellinger 310febe562cSNicholas Bellinger spin_lock(&sess->sess_cmd_lock); 3110f4a9431SNicholas Bellinger rc = __target_check_io_state(cmd, tmr_sess, tas); 312febe562cSNicholas Bellinger spin_unlock(&sess->sess_cmd_lock); 313febe562cSNicholas Bellinger if (!rc) 314febe562cSNicholas Bellinger continue; 315febe562cSNicholas Bellinger 316cf572a96SChristoph Hellwig list_move_tail(&cmd->state_list, &drain_task_list); 317cf572a96SChristoph Hellwig cmd->state_active = false; 318d050ffb9SNicholas Bellinger } 319c66ac9dbSNicholas Bellinger spin_unlock_irqrestore(&dev->execute_task_lock, flags); 320c66ac9dbSNicholas Bellinger 321d050ffb9SNicholas Bellinger while (!list_empty(&drain_task_list)) { 322cf572a96SChristoph Hellwig cmd = list_entry(drain_task_list.next, struct se_cmd, state_list); 323febe562cSNicholas Bellinger list_del_init(&cmd->state_list); 324d050ffb9SNicholas Bellinger 325c00e6220SBart Van Assche target_show_cmd("LUN_RESET: ", cmd); 326c00e6220SBart Van Assche pr_debug("LUN_RESET: ITT[0x%08llx] - %s pr_res_key: 0x%016Lx\n", 327c00e6220SBart Van Assche cmd->tag, (preempt_and_abort_list) ? "preempt" : "", 328c00e6220SBart Van Assche cmd->pr_res_key); 329c66ac9dbSNicholas Bellinger 3302c9fa49eSBart Van Assche target_put_cmd_and_wait(cmd); 331c66ac9dbSNicholas Bellinger } 332d050ffb9SNicholas Bellinger } 333d050ffb9SNicholas Bellinger 334d050ffb9SNicholas Bellinger int core_tmr_lun_reset( 335d050ffb9SNicholas Bellinger struct se_device *dev, 336d050ffb9SNicholas Bellinger struct se_tmr_req *tmr, 337d050ffb9SNicholas Bellinger struct list_head *preempt_and_abort_list, 338d050ffb9SNicholas Bellinger struct se_cmd *prout_cmd) 339d050ffb9SNicholas Bellinger { 340d050ffb9SNicholas Bellinger struct se_node_acl *tmr_nacl = NULL; 341d050ffb9SNicholas Bellinger struct se_portal_group *tmr_tpg = NULL; 342ebde1ca5SNicholas Bellinger struct se_session *tmr_sess = NULL; 34387310c9fSDavid Disseldorp bool tas; 344d050ffb9SNicholas Bellinger /* 345d050ffb9SNicholas Bellinger * TASK_ABORTED status bit, this is configurable via ConfigFS 346d050ffb9SNicholas Bellinger * struct se_device attributes. spc4r17 section 7.4.6 Control mode page 347d050ffb9SNicholas Bellinger * 348d050ffb9SNicholas Bellinger * A task aborted status (TAS) bit set to zero specifies that aborted 349d050ffb9SNicholas Bellinger * tasks shall be terminated by the device server without any response 350d050ffb9SNicholas Bellinger * to the application client. A TAS bit set to one specifies that tasks 351d050ffb9SNicholas Bellinger * aborted by the actions of an I_T nexus other than the I_T nexus on 352d050ffb9SNicholas Bellinger * which the command was received shall be completed with TASK ABORTED 353d050ffb9SNicholas Bellinger * status (see SAM-4). 354d050ffb9SNicholas Bellinger */ 3550fd97ccfSChristoph Hellwig tas = dev->dev_attrib.emulate_tas; 356d050ffb9SNicholas Bellinger /* 357d050ffb9SNicholas Bellinger * Determine if this se_tmr is coming from a $FABRIC_MOD 358d050ffb9SNicholas Bellinger * or struct se_device passthrough.. 359d050ffb9SNicholas Bellinger */ 360d050ffb9SNicholas Bellinger if (tmr && tmr->task_cmd && tmr->task_cmd->se_sess) { 361ebde1ca5SNicholas Bellinger tmr_sess = tmr->task_cmd->se_sess; 362ebde1ca5SNicholas Bellinger tmr_nacl = tmr_sess->se_node_acl; 363ebde1ca5SNicholas Bellinger tmr_tpg = tmr_sess->se_tpg; 364d050ffb9SNicholas Bellinger if (tmr_nacl && tmr_tpg) { 365d050ffb9SNicholas Bellinger pr_debug("LUN_RESET: TMR caller fabric: %s" 366d050ffb9SNicholas Bellinger " initiator port %s\n", 36730c7ca93SDavid Disseldorp tmr_tpg->se_tpg_tfo->fabric_name, 368d050ffb9SNicholas Bellinger tmr_nacl->initiatorname); 369d050ffb9SNicholas Bellinger } 370d050ffb9SNicholas Bellinger } 371d050ffb9SNicholas Bellinger pr_debug("LUN_RESET: %s starting for [%s], tas: %d\n", 372d050ffb9SNicholas Bellinger (preempt_and_abort_list) ? "Preempt" : "TMR", 373d050ffb9SNicholas Bellinger dev->transport->name, tas); 374d050ffb9SNicholas Bellinger 375d050ffb9SNicholas Bellinger core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list); 376ebde1ca5SNicholas Bellinger core_tmr_drain_state_list(dev, prout_cmd, tmr_sess, tas, 377d050ffb9SNicholas Bellinger preempt_and_abort_list); 378af877292SChristoph Hellwig 379c66ac9dbSNicholas Bellinger /* 380c66ac9dbSNicholas Bellinger * Clear any legacy SPC-2 reservation when called during 381c66ac9dbSNicholas Bellinger * LOGICAL UNIT RESET 382c66ac9dbSNicholas Bellinger */ 3836708bb27SAndy Grover if (!preempt_and_abort_list && 3840fd97ccfSChristoph Hellwig (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)) { 385c66ac9dbSNicholas Bellinger spin_lock(&dev->dev_reservation_lock); 386fae43461SBart Van Assche dev->reservation_holder = NULL; 3870fd97ccfSChristoph Hellwig dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS; 388c66ac9dbSNicholas Bellinger spin_unlock(&dev->dev_reservation_lock); 3896708bb27SAndy Grover pr_debug("LUN_RESET: SCSI-2 Released reservation\n"); 390c66ac9dbSNicholas Bellinger } 391c66ac9dbSNicholas Bellinger 392ee480683SNicholas Bellinger atomic_long_inc(&dev->num_resets); 393c66ac9dbSNicholas Bellinger 3946708bb27SAndy Grover pr_debug("LUN_RESET: %s for [%s] Complete\n", 395c66ac9dbSNicholas Bellinger (preempt_and_abort_list) ? "Preempt" : "TMR", 396e3d6f909SAndy Grover dev->transport->name); 397c66ac9dbSNicholas Bellinger return 0; 398c66ac9dbSNicholas Bellinger } 399d050ffb9SNicholas Bellinger 400