1c66ac9dbSNicholas Bellinger /******************************************************************************* 2c66ac9dbSNicholas Bellinger * Filename: target_core_tmr.c 3c66ac9dbSNicholas Bellinger * 4c66ac9dbSNicholas Bellinger * This file contains SPC-3 task management infrastructure 5c66ac9dbSNicholas Bellinger * 64c76251eSNicholas Bellinger * (c) Copyright 2009-2013 Datera, Inc. 7c66ac9dbSNicholas Bellinger * 8c66ac9dbSNicholas Bellinger * Nicholas A. Bellinger <nab@kernel.org> 9c66ac9dbSNicholas Bellinger * 10c66ac9dbSNicholas Bellinger * This program is free software; you can redistribute it and/or modify 11c66ac9dbSNicholas Bellinger * it under the terms of the GNU General Public License as published by 12c66ac9dbSNicholas Bellinger * the Free Software Foundation; either version 2 of the License, or 13c66ac9dbSNicholas Bellinger * (at your option) any later version. 14c66ac9dbSNicholas Bellinger * 15c66ac9dbSNicholas Bellinger * This program is distributed in the hope that it will be useful, 16c66ac9dbSNicholas Bellinger * but WITHOUT ANY WARRANTY; without even the implied warranty of 17c66ac9dbSNicholas Bellinger * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18c66ac9dbSNicholas Bellinger * GNU General Public License for more details. 19c66ac9dbSNicholas Bellinger * 20c66ac9dbSNicholas Bellinger * You should have received a copy of the GNU General Public License 21c66ac9dbSNicholas Bellinger * along with this program; if not, write to the Free Software 22c66ac9dbSNicholas Bellinger * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23c66ac9dbSNicholas Bellinger * 24c66ac9dbSNicholas Bellinger ******************************************************************************/ 25c66ac9dbSNicholas Bellinger 26c66ac9dbSNicholas Bellinger #include <linux/slab.h> 27c66ac9dbSNicholas Bellinger #include <linux/spinlock.h> 28c66ac9dbSNicholas Bellinger #include <linux/list.h> 29c53181afSPaul Gortmaker #include <linux/export.h> 30c66ac9dbSNicholas Bellinger 31c66ac9dbSNicholas Bellinger #include <target/target_core_base.h> 32c4795fb2SChristoph Hellwig #include <target/target_core_backend.h> 33c4795fb2SChristoph Hellwig #include <target/target_core_fabric.h> 34c66ac9dbSNicholas Bellinger 35e26d99aeSChristoph Hellwig #include "target_core_internal.h" 36c66ac9dbSNicholas Bellinger #include "target_core_alua.h" 37c66ac9dbSNicholas Bellinger #include "target_core_pr.h" 38c66ac9dbSNicholas Bellinger 39c8e31f26SAndy Grover int core_tmr_alloc_req( 40c66ac9dbSNicholas Bellinger struct se_cmd *se_cmd, 41c66ac9dbSNicholas Bellinger void *fabric_tmr_ptr, 42dd503a5fSRoland Dreier u8 function, 43dd503a5fSRoland Dreier gfp_t gfp_flags) 44c66ac9dbSNicholas Bellinger { 45c66ac9dbSNicholas Bellinger struct se_tmr_req *tmr; 46c66ac9dbSNicholas Bellinger 47c8e31f26SAndy Grover tmr = kzalloc(sizeof(struct se_tmr_req), gfp_flags); 486708bb27SAndy Grover if (!tmr) { 496708bb27SAndy Grover pr_err("Unable to allocate struct se_tmr_req\n"); 50c8e31f26SAndy Grover return -ENOMEM; 51c66ac9dbSNicholas Bellinger } 52c8e31f26SAndy Grover 53c8e31f26SAndy Grover se_cmd->se_cmd_flags |= SCF_SCSI_TMR_CDB; 54c8e31f26SAndy Grover se_cmd->se_tmr_req = tmr; 55c66ac9dbSNicholas Bellinger tmr->task_cmd = se_cmd; 56c66ac9dbSNicholas Bellinger tmr->fabric_tmr_ptr = fabric_tmr_ptr; 57c66ac9dbSNicholas Bellinger tmr->function = function; 58c66ac9dbSNicholas Bellinger INIT_LIST_HEAD(&tmr->tmr_list); 59c66ac9dbSNicholas Bellinger 60c8e31f26SAndy Grover return 0; 61c66ac9dbSNicholas Bellinger } 62c66ac9dbSNicholas Bellinger EXPORT_SYMBOL(core_tmr_alloc_req); 63c66ac9dbSNicholas Bellinger 648f832690SJoern Engel void core_tmr_release_req(struct se_tmr_req *tmr) 65c66ac9dbSNicholas Bellinger { 66c66ac9dbSNicholas Bellinger struct se_device *dev = tmr->tmr_dev; 67d050ffb9SNicholas Bellinger unsigned long flags; 68c66ac9dbSNicholas Bellinger 698f832690SJoern Engel if (dev) { 70d050ffb9SNicholas Bellinger spin_lock_irqsave(&dev->se_tmr_lock, flags); 71a6d9bb1cSNicholas Bellinger list_del_init(&tmr->tmr_list); 72d050ffb9SNicholas Bellinger spin_unlock_irqrestore(&dev->se_tmr_lock, flags); 738f832690SJoern Engel } 747fd29aa9SNicholas Bellinger 75c8e31f26SAndy Grover kfree(tmr); 76c66ac9dbSNicholas Bellinger } 77c66ac9dbSNicholas Bellinger 78feae8564SJörn Engel static int target_check_cdb_and_preempt(struct list_head *list, 79c165f69cSJörn Engel struct se_cmd *cmd) 80c165f69cSJörn Engel { 81feae8564SJörn Engel struct t10_pr_registration *reg; 82c165f69cSJörn Engel 83feae8564SJörn Engel if (!list) 84feae8564SJörn Engel return 0; 85feae8564SJörn Engel list_for_each_entry(reg, list, pr_reg_abort_list) { 86feae8564SJörn Engel if (reg->pr_res_key == cmd->pr_res_key) 87c165f69cSJörn Engel return 0; 88c165f69cSJörn Engel } 89c165f69cSJörn Engel 90c165f69cSJörn Engel return 1; 91c165f69cSJörn Engel } 92c165f69cSJörn Engel 930f4a9431SNicholas Bellinger static bool __target_check_io_state(struct se_cmd *se_cmd, 940f4a9431SNicholas Bellinger struct se_session *tmr_sess, int tas) 95febe562cSNicholas Bellinger { 96febe562cSNicholas Bellinger struct se_session *sess = se_cmd->se_sess; 97febe562cSNicholas Bellinger 98febe562cSNicholas Bellinger assert_spin_locked(&sess->sess_cmd_lock); 99febe562cSNicholas Bellinger WARN_ON_ONCE(!irqs_disabled()); 100febe562cSNicholas Bellinger /* 101febe562cSNicholas Bellinger * If command already reached CMD_T_COMPLETE state within 1020f4a9431SNicholas Bellinger * target_complete_cmd() or CMD_T_FABRIC_STOP due to shutdown, 1030f4a9431SNicholas Bellinger * this se_cmd has been passed to fabric driver and will 1040f4a9431SNicholas Bellinger * not be aborted. 105febe562cSNicholas Bellinger * 106febe562cSNicholas Bellinger * Otherwise, obtain a local se_cmd->cmd_kref now for TMR 107febe562cSNicholas Bellinger * ABORT_TASK + LUN_RESET for CMD_T_ABORTED processing as 108febe562cSNicholas Bellinger * long as se_cmd->cmd_kref is still active unless zero. 109febe562cSNicholas Bellinger */ 110febe562cSNicholas Bellinger spin_lock(&se_cmd->t_state_lock); 1110f4a9431SNicholas Bellinger if (se_cmd->transport_state & (CMD_T_COMPLETE | CMD_T_FABRIC_STOP)) { 1120f4a9431SNicholas Bellinger pr_debug("Attempted to abort io tag: %llu already complete or" 1130f4a9431SNicholas Bellinger " fabric stop, skipping\n", se_cmd->tag); 1140f4a9431SNicholas Bellinger spin_unlock(&se_cmd->t_state_lock); 1150f4a9431SNicholas Bellinger return false; 1160f4a9431SNicholas Bellinger } 117febe562cSNicholas Bellinger se_cmd->transport_state |= CMD_T_ABORTED; 1180f4a9431SNicholas Bellinger 1190f4a9431SNicholas Bellinger if ((tmr_sess != se_cmd->se_sess) && tas) 1200f4a9431SNicholas Bellinger se_cmd->transport_state |= CMD_T_TAS; 1210f4a9431SNicholas Bellinger 122febe562cSNicholas Bellinger spin_unlock(&se_cmd->t_state_lock); 123febe562cSNicholas Bellinger 124febe562cSNicholas Bellinger return kref_get_unless_zero(&se_cmd->cmd_kref); 125febe562cSNicholas Bellinger } 126febe562cSNicholas Bellinger 1273d28934aSNicholas Bellinger void core_tmr_abort_task( 1283d28934aSNicholas Bellinger struct se_device *dev, 1293d28934aSNicholas Bellinger struct se_tmr_req *tmr, 1303d28934aSNicholas Bellinger struct se_session *se_sess) 1313d28934aSNicholas Bellinger { 132f81ccb48SJoern Engel struct se_cmd *se_cmd; 1333d28934aSNicholas Bellinger unsigned long flags; 134649ee054SBart Van Assche u64 ref_tag; 1353d28934aSNicholas Bellinger 1363d28934aSNicholas Bellinger spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); 137f81ccb48SJoern Engel list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list) { 1383d28934aSNicholas Bellinger 1393d28934aSNicholas Bellinger if (dev != se_cmd->se_dev) 1403d28934aSNicholas Bellinger continue; 14147b1584cSAlex Leung 142dc0fafdaSBart Van Assche /* skip task management functions, including tmr->task_cmd */ 143dc0fafdaSBart Van Assche if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) 14447b1584cSAlex Leung continue; 14547b1584cSAlex Leung 146649ee054SBart Van Assche ref_tag = se_cmd->tag; 1473d28934aSNicholas Bellinger if (tmr->ref_task_tag != ref_tag) 1483d28934aSNicholas Bellinger continue; 1493d28934aSNicholas Bellinger 150649ee054SBart Van Assche printk("ABORT_TASK: Found referenced %s task_tag: %llu\n", 15130c7ca93SDavid Disseldorp se_cmd->se_tfo->fabric_name, ref_tag); 1523d28934aSNicholas Bellinger 153aaa00cc9SBart Van Assche if (!__target_check_io_state(se_cmd, se_sess, 154aaa00cc9SBart Van Assche dev->dev_attrib.emulate_tas)) 1553a1e7ca6SBart Van Assche continue; 1563a1e7ca6SBart Van Assche 1573d28934aSNicholas Bellinger spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); 1583d28934aSNicholas Bellinger 1592c9fa49eSBart Van Assche /* 1602c9fa49eSBart Van Assche * Ensure that this ABORT request is visible to the LU RESET 1612c9fa49eSBart Van Assche * code. 1622c9fa49eSBart Van Assche */ 1632c9fa49eSBart Van Assche if (!tmr->tmr_dev) 1642c9fa49eSBart Van Assche WARN_ON_ONCE(transport_lookup_tmr_lun(tmr->task_cmd, 1652c9fa49eSBart Van Assche se_cmd->orig_fe_lun) < 0); 1663d28934aSNicholas Bellinger 1672c9fa49eSBart Van Assche target_put_cmd_and_wait(se_cmd); 1683d28934aSNicholas Bellinger 1693d28934aSNicholas Bellinger printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for" 170649ee054SBart Van Assche " ref_tag: %llu\n", ref_tag); 1713d28934aSNicholas Bellinger tmr->response = TMR_FUNCTION_COMPLETE; 172c87ba9c4SNicholas Bellinger atomic_long_inc(&dev->aborts_complete); 1733d28934aSNicholas Bellinger return; 1743d28934aSNicholas Bellinger } 1753d28934aSNicholas Bellinger spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); 1763d28934aSNicholas Bellinger 177649ee054SBart Van Assche printk("ABORT_TASK: Sending TMR_TASK_DOES_NOT_EXIST for ref_tag: %lld\n", 1783d28934aSNicholas Bellinger tmr->ref_task_tag); 1793d28934aSNicholas Bellinger tmr->response = TMR_TASK_DOES_NOT_EXIST; 180c87ba9c4SNicholas Bellinger atomic_long_inc(&dev->aborts_no_task); 1813d28934aSNicholas Bellinger } 1823d28934aSNicholas Bellinger 183d050ffb9SNicholas Bellinger static void core_tmr_drain_tmr_list( 184c66ac9dbSNicholas Bellinger struct se_device *dev, 185c66ac9dbSNicholas Bellinger struct se_tmr_req *tmr, 186d050ffb9SNicholas Bellinger struct list_head *preempt_and_abort_list) 187c66ac9dbSNicholas Bellinger { 188d050ffb9SNicholas Bellinger LIST_HEAD(drain_tmr_list); 189a6d9bb1cSNicholas Bellinger struct se_session *sess; 190c66ac9dbSNicholas Bellinger struct se_tmr_req *tmr_p, *tmr_pp; 191d050ffb9SNicholas Bellinger struct se_cmd *cmd; 192c66ac9dbSNicholas Bellinger unsigned long flags; 193a6d9bb1cSNicholas Bellinger bool rc; 194c66ac9dbSNicholas Bellinger /* 195c66ac9dbSNicholas Bellinger * Release all pending and outgoing TMRs aside from the received 196c66ac9dbSNicholas Bellinger * LUN_RESET tmr.. 197c66ac9dbSNicholas Bellinger */ 198d050ffb9SNicholas Bellinger spin_lock_irqsave(&dev->se_tmr_lock, flags); 19988fb2fa7Stangwenji if (tmr) 20051ec502aSBart Van Assche list_del_init(&tmr->tmr_list); 201c66ac9dbSNicholas Bellinger list_for_each_entry_safe(tmr_p, tmr_pp, &dev->dev_tmr_list, tmr_list) { 202c66ac9dbSNicholas Bellinger cmd = tmr_p->task_cmd; 2036708bb27SAndy Grover if (!cmd) { 2046708bb27SAndy Grover pr_err("Unable to locate struct se_cmd for TMR\n"); 205c66ac9dbSNicholas Bellinger continue; 206c66ac9dbSNicholas Bellinger } 207c66ac9dbSNicholas Bellinger /* 208c66ac9dbSNicholas Bellinger * If this function was called with a valid pr_res_key 209c66ac9dbSNicholas Bellinger * parameter (eg: for PROUT PREEMPT_AND_ABORT service action 210ac75d8beSBart Van Assche * skip non registration key matching TMRs. 211c66ac9dbSNicholas Bellinger */ 212feae8564SJörn Engel if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd)) 213c66ac9dbSNicholas Bellinger continue; 214c66ac9dbSNicholas Bellinger 215a6d9bb1cSNicholas Bellinger sess = cmd->se_sess; 216a6d9bb1cSNicholas Bellinger if (WARN_ON_ONCE(!sess)) 217a6d9bb1cSNicholas Bellinger continue; 218a6d9bb1cSNicholas Bellinger 219a6d9bb1cSNicholas Bellinger spin_lock(&sess->sess_cmd_lock); 2202281c95fSBart Van Assche rc = __target_check_io_state(cmd, sess, 0); 221a6d9bb1cSNicholas Bellinger spin_unlock(&sess->sess_cmd_lock); 222d050ffb9SNicholas Bellinger 223a6d9bb1cSNicholas Bellinger if (!rc) { 224a6d9bb1cSNicholas Bellinger printk("LUN_RESET TMR: non-zero kref_get_unless_zero\n"); 225a6d9bb1cSNicholas Bellinger continue; 226a6d9bb1cSNicholas Bellinger } 2270f4a9431SNicholas Bellinger 2286eb40b2aSJoern Engel list_move_tail(&tmr_p->tmr_list, &drain_tmr_list); 229d050ffb9SNicholas Bellinger } 230d050ffb9SNicholas Bellinger spin_unlock_irqrestore(&dev->se_tmr_lock, flags); 231d050ffb9SNicholas Bellinger 232abc1fd4fSJoern Engel list_for_each_entry_safe(tmr_p, tmr_pp, &drain_tmr_list, tmr_list) { 233b8a11d73SJoern Engel list_del_init(&tmr_p->tmr_list); 234abc1fd4fSJoern Engel cmd = tmr_p->task_cmd; 235d050ffb9SNicholas Bellinger 2366708bb27SAndy Grover pr_debug("LUN_RESET: %s releasing TMR %p Function: 0x%02x," 237c66ac9dbSNicholas Bellinger " Response: 0x%02x, t_state: %d\n", 238abc1fd4fSJoern Engel (preempt_and_abort_list) ? "Preempt" : "", tmr_p, 239abc1fd4fSJoern Engel tmr_p->function, tmr_p->response, cmd->t_state); 240c66ac9dbSNicholas Bellinger 2412c9fa49eSBart Van Assche target_put_cmd_and_wait(cmd); 242c66ac9dbSNicholas Bellinger } 243d050ffb9SNicholas Bellinger } 244d050ffb9SNicholas Bellinger 2452c9fa49eSBart Van Assche /** 2462c9fa49eSBart Van Assche * core_tmr_drain_state_list() - abort SCSI commands associated with a device 2472c9fa49eSBart Van Assche * 2482c9fa49eSBart Van Assche * @dev: Device for which to abort outstanding SCSI commands. 2492c9fa49eSBart Van Assche * @prout_cmd: Pointer to the SCSI PREEMPT AND ABORT if this function is called 2502c9fa49eSBart Van Assche * to realize the PREEMPT AND ABORT functionality. 2512c9fa49eSBart Van Assche * @tmr_sess: Session through which the LUN RESET has been received. 2522c9fa49eSBart Van Assche * @tas: Task Aborted Status (TAS) bit from the SCSI control mode page. 2532c9fa49eSBart Van Assche * A quote from SPC-4, paragraph "7.5.10 Control mode page": 2542c9fa49eSBart Van Assche * "A task aborted status (TAS) bit set to zero specifies that 2552c9fa49eSBart Van Assche * aborted commands shall be terminated by the device server 2562c9fa49eSBart Van Assche * without any response to the application client. A TAS bit set 2572c9fa49eSBart Van Assche * to one specifies that commands aborted by the actions of an I_T 2582c9fa49eSBart Van Assche * nexus other than the I_T nexus on which the command was 2592c9fa49eSBart Van Assche * received shall be completed with TASK ABORTED status." 2602c9fa49eSBart Van Assche * @preempt_and_abort_list: For the PREEMPT AND ABORT functionality, a list 2612c9fa49eSBart Van Assche * with registrations that will be preempted. 2622c9fa49eSBart Van Assche */ 263cf572a96SChristoph Hellwig static void core_tmr_drain_state_list( 264d050ffb9SNicholas Bellinger struct se_device *dev, 265d050ffb9SNicholas Bellinger struct se_cmd *prout_cmd, 266ebde1ca5SNicholas Bellinger struct se_session *tmr_sess, 267d050ffb9SNicholas Bellinger int tas, 268d050ffb9SNicholas Bellinger struct list_head *preempt_and_abort_list) 269d050ffb9SNicholas Bellinger { 270d050ffb9SNicholas Bellinger LIST_HEAD(drain_task_list); 271febe562cSNicholas Bellinger struct se_session *sess; 272cf572a96SChristoph Hellwig struct se_cmd *cmd, *next; 273d050ffb9SNicholas Bellinger unsigned long flags; 274febe562cSNicholas Bellinger int rc; 275cf572a96SChristoph Hellwig 276c66ac9dbSNicholas Bellinger /* 277cf572a96SChristoph Hellwig * Complete outstanding commands with TASK_ABORTED SAM status. 278cf572a96SChristoph Hellwig * 279c66ac9dbSNicholas Bellinger * This is following sam4r17, section 5.6 Aborting commands, Table 38 280c66ac9dbSNicholas Bellinger * for TMR LUN_RESET: 281c66ac9dbSNicholas Bellinger * 282c66ac9dbSNicholas Bellinger * a) "Yes" indicates that each command that is aborted on an I_T nexus 283c66ac9dbSNicholas Bellinger * other than the one that caused the SCSI device condition is 284c66ac9dbSNicholas Bellinger * completed with TASK ABORTED status, if the TAS bit is set to one in 285c66ac9dbSNicholas Bellinger * the Control mode page (see SPC-4). "No" indicates that no status is 286c66ac9dbSNicholas Bellinger * returned for aborted commands. 287c66ac9dbSNicholas Bellinger * 288c66ac9dbSNicholas Bellinger * d) If the logical unit reset is caused by a particular I_T nexus 289c66ac9dbSNicholas Bellinger * (e.g., by a LOGICAL UNIT RESET task management function), then "yes" 290c66ac9dbSNicholas Bellinger * (TASK_ABORTED status) applies. 291c66ac9dbSNicholas Bellinger * 292c66ac9dbSNicholas Bellinger * Otherwise (e.g., if triggered by a hard reset), "no" 293c66ac9dbSNicholas Bellinger * (no TASK_ABORTED SAM status) applies. 294c66ac9dbSNicholas Bellinger * 295c66ac9dbSNicholas Bellinger * Note that this seems to be independent of TAS (Task Aborted Status) 296c66ac9dbSNicholas Bellinger * in the Control Mode Page. 297c66ac9dbSNicholas Bellinger */ 298c66ac9dbSNicholas Bellinger spin_lock_irqsave(&dev->execute_task_lock, flags); 299cf572a96SChristoph Hellwig list_for_each_entry_safe(cmd, next, &dev->state_list, state_list) { 300c66ac9dbSNicholas Bellinger /* 301c66ac9dbSNicholas Bellinger * For PREEMPT_AND_ABORT usage, only process commands 302c66ac9dbSNicholas Bellinger * with a matching reservation key. 303c66ac9dbSNicholas Bellinger */ 304feae8564SJörn Engel if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd)) 305c66ac9dbSNicholas Bellinger continue; 306cf572a96SChristoph Hellwig 307c66ac9dbSNicholas Bellinger /* 308c66ac9dbSNicholas Bellinger * Not aborting PROUT PREEMPT_AND_ABORT CDB.. 309c66ac9dbSNicholas Bellinger */ 310c66ac9dbSNicholas Bellinger if (prout_cmd == cmd) 311c66ac9dbSNicholas Bellinger continue; 312c66ac9dbSNicholas Bellinger 313febe562cSNicholas Bellinger sess = cmd->se_sess; 314febe562cSNicholas Bellinger if (WARN_ON_ONCE(!sess)) 315febe562cSNicholas Bellinger continue; 316febe562cSNicholas Bellinger 317febe562cSNicholas Bellinger spin_lock(&sess->sess_cmd_lock); 3180f4a9431SNicholas Bellinger rc = __target_check_io_state(cmd, tmr_sess, tas); 319febe562cSNicholas Bellinger spin_unlock(&sess->sess_cmd_lock); 320febe562cSNicholas Bellinger if (!rc) 321febe562cSNicholas Bellinger continue; 322febe562cSNicholas Bellinger 323cf572a96SChristoph Hellwig list_move_tail(&cmd->state_list, &drain_task_list); 324cf572a96SChristoph Hellwig cmd->state_active = false; 325d050ffb9SNicholas Bellinger } 326c66ac9dbSNicholas Bellinger spin_unlock_irqrestore(&dev->execute_task_lock, flags); 327c66ac9dbSNicholas Bellinger 328d050ffb9SNicholas Bellinger while (!list_empty(&drain_task_list)) { 329cf572a96SChristoph Hellwig cmd = list_entry(drain_task_list.next, struct se_cmd, state_list); 330febe562cSNicholas Bellinger list_del_init(&cmd->state_list); 331d050ffb9SNicholas Bellinger 332c00e6220SBart Van Assche target_show_cmd("LUN_RESET: ", cmd); 333c00e6220SBart Van Assche pr_debug("LUN_RESET: ITT[0x%08llx] - %s pr_res_key: 0x%016Lx\n", 334c00e6220SBart Van Assche cmd->tag, (preempt_and_abort_list) ? "preempt" : "", 335c00e6220SBart Van Assche cmd->pr_res_key); 336c66ac9dbSNicholas Bellinger 3372c9fa49eSBart Van Assche target_put_cmd_and_wait(cmd); 338c66ac9dbSNicholas Bellinger } 339d050ffb9SNicholas Bellinger } 340d050ffb9SNicholas Bellinger 341d050ffb9SNicholas Bellinger int core_tmr_lun_reset( 342d050ffb9SNicholas Bellinger struct se_device *dev, 343d050ffb9SNicholas Bellinger struct se_tmr_req *tmr, 344d050ffb9SNicholas Bellinger struct list_head *preempt_and_abort_list, 345d050ffb9SNicholas Bellinger struct se_cmd *prout_cmd) 346d050ffb9SNicholas Bellinger { 347d050ffb9SNicholas Bellinger struct se_node_acl *tmr_nacl = NULL; 348d050ffb9SNicholas Bellinger struct se_portal_group *tmr_tpg = NULL; 349ebde1ca5SNicholas Bellinger struct se_session *tmr_sess = NULL; 350d050ffb9SNicholas Bellinger int tas; 351d050ffb9SNicholas Bellinger /* 352d050ffb9SNicholas Bellinger * TASK_ABORTED status bit, this is configurable via ConfigFS 353d050ffb9SNicholas Bellinger * struct se_device attributes. spc4r17 section 7.4.6 Control mode page 354d050ffb9SNicholas Bellinger * 355d050ffb9SNicholas Bellinger * A task aborted status (TAS) bit set to zero specifies that aborted 356d050ffb9SNicholas Bellinger * tasks shall be terminated by the device server without any response 357d050ffb9SNicholas Bellinger * to the application client. A TAS bit set to one specifies that tasks 358d050ffb9SNicholas Bellinger * aborted by the actions of an I_T nexus other than the I_T nexus on 359d050ffb9SNicholas Bellinger * which the command was received shall be completed with TASK ABORTED 360d050ffb9SNicholas Bellinger * status (see SAM-4). 361d050ffb9SNicholas Bellinger */ 3620fd97ccfSChristoph Hellwig tas = dev->dev_attrib.emulate_tas; 363d050ffb9SNicholas Bellinger /* 364d050ffb9SNicholas Bellinger * Determine if this se_tmr is coming from a $FABRIC_MOD 365d050ffb9SNicholas Bellinger * or struct se_device passthrough.. 366d050ffb9SNicholas Bellinger */ 367d050ffb9SNicholas Bellinger if (tmr && tmr->task_cmd && tmr->task_cmd->se_sess) { 368ebde1ca5SNicholas Bellinger tmr_sess = tmr->task_cmd->se_sess; 369ebde1ca5SNicholas Bellinger tmr_nacl = tmr_sess->se_node_acl; 370ebde1ca5SNicholas Bellinger tmr_tpg = tmr_sess->se_tpg; 371d050ffb9SNicholas Bellinger if (tmr_nacl && tmr_tpg) { 372d050ffb9SNicholas Bellinger pr_debug("LUN_RESET: TMR caller fabric: %s" 373d050ffb9SNicholas Bellinger " initiator port %s\n", 37430c7ca93SDavid Disseldorp tmr_tpg->se_tpg_tfo->fabric_name, 375d050ffb9SNicholas Bellinger tmr_nacl->initiatorname); 376d050ffb9SNicholas Bellinger } 377d050ffb9SNicholas Bellinger } 378d050ffb9SNicholas Bellinger pr_debug("LUN_RESET: %s starting for [%s], tas: %d\n", 379d050ffb9SNicholas Bellinger (preempt_and_abort_list) ? "Preempt" : "TMR", 380d050ffb9SNicholas Bellinger dev->transport->name, tas); 381d050ffb9SNicholas Bellinger 382d050ffb9SNicholas Bellinger core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list); 383ebde1ca5SNicholas Bellinger core_tmr_drain_state_list(dev, prout_cmd, tmr_sess, tas, 384d050ffb9SNicholas Bellinger preempt_and_abort_list); 385af877292SChristoph Hellwig 386c66ac9dbSNicholas Bellinger /* 387c66ac9dbSNicholas Bellinger * Clear any legacy SPC-2 reservation when called during 388c66ac9dbSNicholas Bellinger * LOGICAL UNIT RESET 389c66ac9dbSNicholas Bellinger */ 3906708bb27SAndy Grover if (!preempt_and_abort_list && 3910fd97ccfSChristoph Hellwig (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)) { 392c66ac9dbSNicholas Bellinger spin_lock(&dev->dev_reservation_lock); 393fae43461SBart Van Assche dev->reservation_holder = NULL; 3940fd97ccfSChristoph Hellwig dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS; 395c66ac9dbSNicholas Bellinger spin_unlock(&dev->dev_reservation_lock); 3966708bb27SAndy Grover pr_debug("LUN_RESET: SCSI-2 Released reservation\n"); 397c66ac9dbSNicholas Bellinger } 398c66ac9dbSNicholas Bellinger 399ee480683SNicholas Bellinger atomic_long_inc(&dev->num_resets); 400c66ac9dbSNicholas Bellinger 4016708bb27SAndy Grover pr_debug("LUN_RESET: %s for [%s] Complete\n", 402c66ac9dbSNicholas Bellinger (preempt_and_abort_list) ? "Preempt" : "TMR", 403e3d6f909SAndy Grover dev->transport->name); 404c66ac9dbSNicholas Bellinger return 0; 405c66ac9dbSNicholas Bellinger } 406d050ffb9SNicholas Bellinger 407