1c66ac9dbSNicholas Bellinger /******************************************************************************* 2c66ac9dbSNicholas Bellinger * Filename: target_core_device.c (based on iscsi_target_device.c) 3c66ac9dbSNicholas Bellinger * 4e3d6f909SAndy Grover * This file contains the TCM Virtual Device and Disk Transport 5c66ac9dbSNicholas Bellinger * agnostic related functions. 6c66ac9dbSNicholas Bellinger * 74c76251eSNicholas Bellinger * (c) Copyright 2003-2013 Datera, Inc. 8c66ac9dbSNicholas Bellinger * 9c66ac9dbSNicholas Bellinger * Nicholas A. Bellinger <nab@kernel.org> 10c66ac9dbSNicholas Bellinger * 11c66ac9dbSNicholas Bellinger * This program is free software; you can redistribute it and/or modify 12c66ac9dbSNicholas Bellinger * it under the terms of the GNU General Public License as published by 13c66ac9dbSNicholas Bellinger * the Free Software Foundation; either version 2 of the License, or 14c66ac9dbSNicholas Bellinger * (at your option) any later version. 15c66ac9dbSNicholas Bellinger * 16c66ac9dbSNicholas Bellinger * This program is distributed in the hope that it will be useful, 17c66ac9dbSNicholas Bellinger * but WITHOUT ANY WARRANTY; without even the implied warranty of 18c66ac9dbSNicholas Bellinger * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19c66ac9dbSNicholas Bellinger * GNU General Public License for more details. 20c66ac9dbSNicholas Bellinger * 21c66ac9dbSNicholas Bellinger * You should have received a copy of the GNU General Public License 22c66ac9dbSNicholas Bellinger * along with this program; if not, write to the Free Software 23c66ac9dbSNicholas Bellinger * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 24c66ac9dbSNicholas Bellinger * 25c66ac9dbSNicholas Bellinger ******************************************************************************/ 26c66ac9dbSNicholas Bellinger 27c66ac9dbSNicholas Bellinger #include <linux/net.h> 28c66ac9dbSNicholas Bellinger #include <linux/string.h> 29c66ac9dbSNicholas Bellinger #include <linux/delay.h> 30c66ac9dbSNicholas Bellinger #include <linux/timer.h> 31c66ac9dbSNicholas Bellinger #include <linux/slab.h> 32c66ac9dbSNicholas Bellinger #include <linux/spinlock.h> 33c66ac9dbSNicholas Bellinger #include <linux/kthread.h> 34c66ac9dbSNicholas Bellinger #include <linux/in.h> 35c53181afSPaul Gortmaker #include <linux/export.h> 367bfea53bSAndy Grover #include <asm/unaligned.h> 37c66ac9dbSNicholas Bellinger #include <net/sock.h> 38c66ac9dbSNicholas Bellinger #include <net/tcp.h> 39ba929992SBart Van Assche #include <scsi/scsi_common.h> 40ba929992SBart Van Assche #include <scsi/scsi_proto.h> 41c66ac9dbSNicholas Bellinger 42c66ac9dbSNicholas Bellinger #include <target/target_core_base.h> 43c4795fb2SChristoph Hellwig #include <target/target_core_backend.h> 44c4795fb2SChristoph Hellwig #include <target/target_core_fabric.h> 45c66ac9dbSNicholas Bellinger 46e26d99aeSChristoph Hellwig #include "target_core_internal.h" 47c66ac9dbSNicholas Bellinger #include "target_core_alua.h" 48c66ac9dbSNicholas Bellinger #include "target_core_pr.h" 49c66ac9dbSNicholas Bellinger #include "target_core_ua.h" 50c66ac9dbSNicholas Bellinger 51d9ea32bfSNicholas Bellinger DEFINE_MUTEX(g_device_mutex); 52d9ea32bfSNicholas Bellinger LIST_HEAD(g_device_list); 53d9ea32bfSNicholas Bellinger 54e3d6f909SAndy Grover static struct se_hba *lun0_hba; 55e3d6f909SAndy Grover /* not static, needed by tpg.c */ 56e3d6f909SAndy Grover struct se_device *g_lun0_dev; 57e3d6f909SAndy Grover 58de103c93SChristoph Hellwig sense_reason_t 59f2d30680SHannes Reinecke transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun) 60c66ac9dbSNicholas Bellinger { 61c66ac9dbSNicholas Bellinger struct se_lun *se_lun = NULL; 62e3d6f909SAndy Grover struct se_session *se_sess = se_cmd->se_sess; 6329a05deeSNicholas Bellinger struct se_node_acl *nacl = se_sess->se_node_acl; 6429a05deeSNicholas Bellinger struct se_dev_entry *deve; 65c66ac9dbSNicholas Bellinger 6629a05deeSNicholas Bellinger rcu_read_lock(); 6729a05deeSNicholas Bellinger deve = target_nacl_find_deve(nacl, unpacked_lun); 6829a05deeSNicholas Bellinger if (deve) { 6929a05deeSNicholas Bellinger atomic_long_inc(&deve->total_cmds); 70c66ac9dbSNicholas Bellinger 715951146dSAndy Grover if ((se_cmd->data_direction == DMA_TO_DEVICE) && 725951146dSAndy Grover (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)) { 736708bb27SAndy Grover pr_err("TARGET_CORE[%s]: Detected WRITE_PROTECTED LUN" 74f2d30680SHannes Reinecke " Access for 0x%08llx\n", 75e3d6f909SAndy Grover se_cmd->se_tfo->get_fabric_name(), 76c66ac9dbSNicholas Bellinger unpacked_lun); 7729a05deeSNicholas Bellinger rcu_read_unlock(); 78de103c93SChristoph Hellwig return TCM_WRITE_PROTECTED; 795951146dSAndy Grover } 805951146dSAndy Grover 815951146dSAndy Grover if (se_cmd->data_direction == DMA_TO_DEVICE) 8229a05deeSNicholas Bellinger atomic_long_add(se_cmd->data_length, 8329a05deeSNicholas Bellinger &deve->write_bytes); 845951146dSAndy Grover else if (se_cmd->data_direction == DMA_FROM_DEVICE) 8529a05deeSNicholas Bellinger atomic_long_add(se_cmd->data_length, 8629a05deeSNicholas Bellinger &deve->read_bytes); 875951146dSAndy Grover 8829a05deeSNicholas Bellinger se_lun = rcu_dereference(deve->se_lun); 8929a05deeSNicholas Bellinger se_cmd->se_lun = rcu_dereference(deve->se_lun); 905951146dSAndy Grover se_cmd->pr_res_key = deve->pr_res_key; 915951146dSAndy Grover se_cmd->orig_fe_lun = unpacked_lun; 925951146dSAndy Grover se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; 935277797dSNicholas Bellinger 945277797dSNicholas Bellinger percpu_ref_get(&se_lun->lun_ref); 955277797dSNicholas Bellinger se_cmd->lun_ref_active = true; 965951146dSAndy Grover } 9729a05deeSNicholas Bellinger rcu_read_unlock(); 985951146dSAndy Grover 995951146dSAndy Grover if (!se_lun) { 100c66ac9dbSNicholas Bellinger /* 101c66ac9dbSNicholas Bellinger * Use the se_portal_group->tpg_virt_lun0 to allow for 102c66ac9dbSNicholas Bellinger * REPORT_LUNS, et al to be returned when no active 103c66ac9dbSNicholas Bellinger * MappedLUN=0 exists for this Initiator Port. 104c66ac9dbSNicholas Bellinger */ 105c66ac9dbSNicholas Bellinger if (unpacked_lun != 0) { 1066708bb27SAndy Grover pr_err("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN" 107f2d30680SHannes Reinecke " Access for 0x%08llx\n", 108e3d6f909SAndy Grover se_cmd->se_tfo->get_fabric_name(), 109c66ac9dbSNicholas Bellinger unpacked_lun); 110de103c93SChristoph Hellwig return TCM_NON_EXISTENT_LUN; 111c66ac9dbSNicholas Bellinger } 112c66ac9dbSNicholas Bellinger /* 113c66ac9dbSNicholas Bellinger * Force WRITE PROTECT for virtual LUN 0 114c66ac9dbSNicholas Bellinger */ 115c66ac9dbSNicholas Bellinger if ((se_cmd->data_direction != DMA_FROM_DEVICE) && 116de103c93SChristoph Hellwig (se_cmd->data_direction != DMA_NONE)) 117de103c93SChristoph Hellwig return TCM_WRITE_PROTECTED; 1185951146dSAndy Grover 119adf653f9SChristoph Hellwig se_lun = se_sess->se_tpg->tpg_virt_lun0; 120adf653f9SChristoph Hellwig se_cmd->se_lun = se_sess->se_tpg->tpg_virt_lun0; 121c66ac9dbSNicholas Bellinger se_cmd->orig_fe_lun = 0; 122c66ac9dbSNicholas Bellinger se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; 1235277797dSNicholas Bellinger 1245277797dSNicholas Bellinger percpu_ref_get(&se_lun->lun_ref); 1255277797dSNicholas Bellinger se_cmd->lun_ref_active = true; 126c66ac9dbSNicholas Bellinger } 1274cc987eaSNicholas Bellinger /* 1284cc987eaSNicholas Bellinger * RCU reference protected by percpu se_lun->lun_ref taken above that 1294cc987eaSNicholas Bellinger * must drop to zero (including initial reference) before this se_lun 1304cc987eaSNicholas Bellinger * pointer can be kfree_rcu() by the final se_lun->lun_group put via 1314cc987eaSNicholas Bellinger * target_core_fabric_configfs.c:target_fabric_port_release 1324cc987eaSNicholas Bellinger */ 1334cc987eaSNicholas Bellinger se_cmd->se_dev = rcu_dereference_raw(se_lun->lun_se_dev); 1344cc987eaSNicholas Bellinger atomic_long_inc(&se_cmd->se_dev->num_cmds); 135c66ac9dbSNicholas Bellinger 136c66ac9dbSNicholas Bellinger if (se_cmd->data_direction == DMA_TO_DEVICE) 1374cc987eaSNicholas Bellinger atomic_long_add(se_cmd->data_length, 1384cc987eaSNicholas Bellinger &se_cmd->se_dev->write_bytes); 139c66ac9dbSNicholas Bellinger else if (se_cmd->data_direction == DMA_FROM_DEVICE) 1404cc987eaSNicholas Bellinger atomic_long_add(se_cmd->data_length, 1414cc987eaSNicholas Bellinger &se_cmd->se_dev->read_bytes); 142c66ac9dbSNicholas Bellinger 143c66ac9dbSNicholas Bellinger return 0; 144c66ac9dbSNicholas Bellinger } 1455951146dSAndy Grover EXPORT_SYMBOL(transport_lookup_cmd_lun); 146c66ac9dbSNicholas Bellinger 147f2d30680SHannes Reinecke int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u64 unpacked_lun) 148c66ac9dbSNicholas Bellinger { 149c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 150c66ac9dbSNicholas Bellinger struct se_lun *se_lun = NULL; 151e3d6f909SAndy Grover struct se_session *se_sess = se_cmd->se_sess; 15229a05deeSNicholas Bellinger struct se_node_acl *nacl = se_sess->se_node_acl; 153c66ac9dbSNicholas Bellinger struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; 1545e1be919SRoland Dreier unsigned long flags; 155c66ac9dbSNicholas Bellinger 15629a05deeSNicholas Bellinger rcu_read_lock(); 15729a05deeSNicholas Bellinger deve = target_nacl_find_deve(nacl, unpacked_lun); 15829a05deeSNicholas Bellinger if (deve) { 15929a05deeSNicholas Bellinger se_tmr->tmr_lun = rcu_dereference(deve->se_lun); 16029a05deeSNicholas Bellinger se_cmd->se_lun = rcu_dereference(deve->se_lun); 16129a05deeSNicholas Bellinger se_lun = rcu_dereference(deve->se_lun); 162c66ac9dbSNicholas Bellinger se_cmd->pr_res_key = deve->pr_res_key; 163c66ac9dbSNicholas Bellinger se_cmd->orig_fe_lun = unpacked_lun; 164c66ac9dbSNicholas Bellinger } 16529a05deeSNicholas Bellinger rcu_read_unlock(); 166c66ac9dbSNicholas Bellinger 167c66ac9dbSNicholas Bellinger if (!se_lun) { 1686708bb27SAndy Grover pr_debug("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN" 169f2d30680SHannes Reinecke " Access for 0x%08llx\n", 170e3d6f909SAndy Grover se_cmd->se_tfo->get_fabric_name(), 171c66ac9dbSNicholas Bellinger unpacked_lun); 172e3d6f909SAndy Grover return -ENODEV; 173c66ac9dbSNicholas Bellinger } 1744cc987eaSNicholas Bellinger /* 1754cc987eaSNicholas Bellinger * XXX: Add percpu se_lun->lun_ref reference count for TMR 1764cc987eaSNicholas Bellinger */ 1774cc987eaSNicholas Bellinger se_cmd->se_dev = rcu_dereference_raw(se_lun->lun_se_dev); 1784cc987eaSNicholas Bellinger se_tmr->tmr_dev = rcu_dereference_raw(se_lun->lun_se_dev); 1795951146dSAndy Grover 1805e1be919SRoland Dreier spin_lock_irqsave(&se_tmr->tmr_dev->se_tmr_lock, flags); 1815951146dSAndy Grover list_add_tail(&se_tmr->tmr_list, &se_tmr->tmr_dev->dev_tmr_list); 1825e1be919SRoland Dreier spin_unlock_irqrestore(&se_tmr->tmr_dev->se_tmr_lock, flags); 183c66ac9dbSNicholas Bellinger 184c66ac9dbSNicholas Bellinger return 0; 185c66ac9dbSNicholas Bellinger } 1865951146dSAndy Grover EXPORT_SYMBOL(transport_lookup_tmr_lun); 187c66ac9dbSNicholas Bellinger 18829a05deeSNicholas Bellinger bool target_lun_is_rdonly(struct se_cmd *cmd) 18929a05deeSNicholas Bellinger { 19029a05deeSNicholas Bellinger struct se_session *se_sess = cmd->se_sess; 19129a05deeSNicholas Bellinger struct se_dev_entry *deve; 19229a05deeSNicholas Bellinger bool ret; 19329a05deeSNicholas Bellinger 19429a05deeSNicholas Bellinger rcu_read_lock(); 19529a05deeSNicholas Bellinger deve = target_nacl_find_deve(se_sess->se_node_acl, cmd->orig_fe_lun); 19629a05deeSNicholas Bellinger ret = (deve && deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY); 19729a05deeSNicholas Bellinger rcu_read_unlock(); 19829a05deeSNicholas Bellinger 19929a05deeSNicholas Bellinger return ret; 20029a05deeSNicholas Bellinger } 20129a05deeSNicholas Bellinger EXPORT_SYMBOL(target_lun_is_rdonly); 20229a05deeSNicholas Bellinger 203c66ac9dbSNicholas Bellinger /* 204c66ac9dbSNicholas Bellinger * This function is called from core_scsi3_emulate_pro_register_and_move() 20529a05deeSNicholas Bellinger * and core_scsi3_decode_spec_i_port(), and will increment &deve->pr_kref 206c66ac9dbSNicholas Bellinger * when a matching rtpi is found. 207c66ac9dbSNicholas Bellinger */ 208c66ac9dbSNicholas Bellinger struct se_dev_entry *core_get_se_deve_from_rtpi( 209c66ac9dbSNicholas Bellinger struct se_node_acl *nacl, 210c66ac9dbSNicholas Bellinger u16 rtpi) 211c66ac9dbSNicholas Bellinger { 212c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 213c66ac9dbSNicholas Bellinger struct se_lun *lun; 214c66ac9dbSNicholas Bellinger struct se_portal_group *tpg = nacl->se_tpg; 215c66ac9dbSNicholas Bellinger 21629a05deeSNicholas Bellinger rcu_read_lock(); 21729a05deeSNicholas Bellinger hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) { 21829a05deeSNicholas Bellinger lun = rcu_dereference(deve->se_lun); 2196708bb27SAndy Grover if (!lun) { 2206708bb27SAndy Grover pr_err("%s device entries device pointer is" 221c66ac9dbSNicholas Bellinger " NULL, but Initiator has access.\n", 222e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 223c66ac9dbSNicholas Bellinger continue; 224c66ac9dbSNicholas Bellinger } 22529a05deeSNicholas Bellinger if (lun->lun_rtpi != rtpi) 226c66ac9dbSNicholas Bellinger continue; 227c66ac9dbSNicholas Bellinger 22829a05deeSNicholas Bellinger kref_get(&deve->pr_kref); 22929a05deeSNicholas Bellinger rcu_read_unlock(); 230c66ac9dbSNicholas Bellinger 231c66ac9dbSNicholas Bellinger return deve; 232c66ac9dbSNicholas Bellinger } 23329a05deeSNicholas Bellinger rcu_read_unlock(); 234c66ac9dbSNicholas Bellinger 235c66ac9dbSNicholas Bellinger return NULL; 236c66ac9dbSNicholas Bellinger } 237c66ac9dbSNicholas Bellinger 23829a05deeSNicholas Bellinger void core_free_device_list_for_node( 239c66ac9dbSNicholas Bellinger struct se_node_acl *nacl, 240c66ac9dbSNicholas Bellinger struct se_portal_group *tpg) 241c66ac9dbSNicholas Bellinger { 242c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 243c66ac9dbSNicholas Bellinger 24429a05deeSNicholas Bellinger mutex_lock(&nacl->lun_entry_mutex); 24529a05deeSNicholas Bellinger hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) { 24629a05deeSNicholas Bellinger struct se_lun *lun = rcu_dereference_check(deve->se_lun, 24729a05deeSNicholas Bellinger lockdep_is_held(&nacl->lun_entry_mutex)); 24829a05deeSNicholas Bellinger core_disable_device_list_for_node(lun, deve, nacl, tpg); 249c66ac9dbSNicholas Bellinger } 25029a05deeSNicholas Bellinger mutex_unlock(&nacl->lun_entry_mutex); 251c66ac9dbSNicholas Bellinger } 252c66ac9dbSNicholas Bellinger 253c66ac9dbSNicholas Bellinger void core_update_device_list_access( 254f2d30680SHannes Reinecke u64 mapped_lun, 255c66ac9dbSNicholas Bellinger u32 lun_access, 256c66ac9dbSNicholas Bellinger struct se_node_acl *nacl) 257c66ac9dbSNicholas Bellinger { 258c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 259c66ac9dbSNicholas Bellinger 26029a05deeSNicholas Bellinger mutex_lock(&nacl->lun_entry_mutex); 26129a05deeSNicholas Bellinger deve = target_nacl_find_deve(nacl, mapped_lun); 26229a05deeSNicholas Bellinger if (deve) { 263c66ac9dbSNicholas Bellinger if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { 264c66ac9dbSNicholas Bellinger deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; 265c66ac9dbSNicholas Bellinger deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; 266c66ac9dbSNicholas Bellinger } else { 267c66ac9dbSNicholas Bellinger deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; 268c66ac9dbSNicholas Bellinger deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; 269c66ac9dbSNicholas Bellinger } 27029a05deeSNicholas Bellinger } 27129a05deeSNicholas Bellinger mutex_unlock(&nacl->lun_entry_mutex); 272c66ac9dbSNicholas Bellinger } 273c66ac9dbSNicholas Bellinger 27429a05deeSNicholas Bellinger /* 27529a05deeSNicholas Bellinger * Called with rcu_read_lock or nacl->device_list_lock held. 276c66ac9dbSNicholas Bellinger */ 277f2d30680SHannes Reinecke struct se_dev_entry *target_nacl_find_deve(struct se_node_acl *nacl, u64 mapped_lun) 27829a05deeSNicholas Bellinger { 27929a05deeSNicholas Bellinger struct se_dev_entry *deve; 28029a05deeSNicholas Bellinger 28129a05deeSNicholas Bellinger hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) 28229a05deeSNicholas Bellinger if (deve->mapped_lun == mapped_lun) 28329a05deeSNicholas Bellinger return deve; 28429a05deeSNicholas Bellinger 28529a05deeSNicholas Bellinger return NULL; 28629a05deeSNicholas Bellinger } 28729a05deeSNicholas Bellinger EXPORT_SYMBOL(target_nacl_find_deve); 28829a05deeSNicholas Bellinger 28929a05deeSNicholas Bellinger void target_pr_kref_release(struct kref *kref) 29029a05deeSNicholas Bellinger { 29129a05deeSNicholas Bellinger struct se_dev_entry *deve = container_of(kref, struct se_dev_entry, 29229a05deeSNicholas Bellinger pr_kref); 29329a05deeSNicholas Bellinger complete(&deve->pr_comp); 294c66ac9dbSNicholas Bellinger } 295c66ac9dbSNicholas Bellinger 2967c0d0d51SHannes Reinecke static void 2977c0d0d51SHannes Reinecke target_luns_data_has_changed(struct se_node_acl *nacl, struct se_dev_entry *new, 2987c0d0d51SHannes Reinecke bool skip_new) 2997c0d0d51SHannes Reinecke { 3007c0d0d51SHannes Reinecke struct se_dev_entry *tmp; 3017c0d0d51SHannes Reinecke 3027c0d0d51SHannes Reinecke rcu_read_lock(); 3037c0d0d51SHannes Reinecke hlist_for_each_entry_rcu(tmp, &nacl->lun_entry_hlist, link) { 3047c0d0d51SHannes Reinecke if (skip_new && tmp == new) 3057c0d0d51SHannes Reinecke continue; 3067c0d0d51SHannes Reinecke core_scsi3_ua_allocate(tmp, 0x3F, 3077c0d0d51SHannes Reinecke ASCQ_3FH_REPORTED_LUNS_DATA_HAS_CHANGED); 3087c0d0d51SHannes Reinecke } 3097c0d0d51SHannes Reinecke rcu_read_unlock(); 3107c0d0d51SHannes Reinecke } 3117c0d0d51SHannes Reinecke 312e80ac6c4SAndy Grover int core_enable_device_list_for_node( 313c66ac9dbSNicholas Bellinger struct se_lun *lun, 314c66ac9dbSNicholas Bellinger struct se_lun_acl *lun_acl, 315f2d30680SHannes Reinecke u64 mapped_lun, 316c66ac9dbSNicholas Bellinger u32 lun_access, 317c66ac9dbSNicholas Bellinger struct se_node_acl *nacl, 318e80ac6c4SAndy Grover struct se_portal_group *tpg) 319c66ac9dbSNicholas Bellinger { 32029a05deeSNicholas Bellinger struct se_dev_entry *orig, *new; 321c66ac9dbSNicholas Bellinger 32229a05deeSNicholas Bellinger new = kzalloc(sizeof(*new), GFP_KERNEL); 32329a05deeSNicholas Bellinger if (!new) { 32429a05deeSNicholas Bellinger pr_err("Unable to allocate se_dev_entry memory\n"); 32529a05deeSNicholas Bellinger return -ENOMEM; 32629a05deeSNicholas Bellinger } 327e80ac6c4SAndy Grover 32829a05deeSNicholas Bellinger atomic_set(&new->ua_count, 0); 32929a05deeSNicholas Bellinger spin_lock_init(&new->ua_lock); 33029a05deeSNicholas Bellinger INIT_LIST_HEAD(&new->ua_list); 331adf653f9SChristoph Hellwig INIT_LIST_HEAD(&new->lun_link); 332e80ac6c4SAndy Grover 33329a05deeSNicholas Bellinger new->mapped_lun = mapped_lun; 33429a05deeSNicholas Bellinger kref_init(&new->pr_kref); 33529a05deeSNicholas Bellinger init_completion(&new->pr_comp); 33629a05deeSNicholas Bellinger 33729a05deeSNicholas Bellinger if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) 33829a05deeSNicholas Bellinger new->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; 33929a05deeSNicholas Bellinger else 34029a05deeSNicholas Bellinger new->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; 34129a05deeSNicholas Bellinger 34229a05deeSNicholas Bellinger new->creation_time = get_jiffies_64(); 34329a05deeSNicholas Bellinger new->attach_count++; 34429a05deeSNicholas Bellinger 34529a05deeSNicholas Bellinger mutex_lock(&nacl->lun_entry_mutex); 34629a05deeSNicholas Bellinger orig = target_nacl_find_deve(nacl, mapped_lun); 34729a05deeSNicholas Bellinger if (orig && orig->se_lun) { 34829a05deeSNicholas Bellinger struct se_lun *orig_lun = rcu_dereference_check(orig->se_lun, 34929a05deeSNicholas Bellinger lockdep_is_held(&nacl->lun_entry_mutex)); 35029a05deeSNicholas Bellinger 35129a05deeSNicholas Bellinger if (orig_lun != lun) { 35229a05deeSNicholas Bellinger pr_err("Existing orig->se_lun doesn't match new lun" 35329a05deeSNicholas Bellinger " for dynamic -> explicit NodeACL conversion:" 35429a05deeSNicholas Bellinger " %s\n", nacl->initiatorname); 35529a05deeSNicholas Bellinger mutex_unlock(&nacl->lun_entry_mutex); 35629a05deeSNicholas Bellinger kfree(new); 357e3d6f909SAndy Grover return -EINVAL; 358c66ac9dbSNicholas Bellinger } 35929a05deeSNicholas Bellinger BUG_ON(orig->se_lun_acl != NULL); 360c66ac9dbSNicholas Bellinger 36129a05deeSNicholas Bellinger rcu_assign_pointer(new->se_lun, lun); 36229a05deeSNicholas Bellinger rcu_assign_pointer(new->se_lun_acl, lun_acl); 36329a05deeSNicholas Bellinger hlist_del_rcu(&orig->link); 36429a05deeSNicholas Bellinger hlist_add_head_rcu(&new->link, &nacl->lun_entry_hlist); 36529a05deeSNicholas Bellinger mutex_unlock(&nacl->lun_entry_mutex); 366c66ac9dbSNicholas Bellinger 3671adff1b3SNicholas Bellinger spin_lock(&lun->lun_deve_lock); 368adf653f9SChristoph Hellwig list_del(&orig->lun_link); 369adf653f9SChristoph Hellwig list_add_tail(&new->lun_link, &lun->lun_deve_list); 3701adff1b3SNicholas Bellinger spin_unlock(&lun->lun_deve_lock); 37129a05deeSNicholas Bellinger 37229a05deeSNicholas Bellinger kref_put(&orig->pr_kref, target_pr_kref_release); 37329a05deeSNicholas Bellinger wait_for_completion(&orig->pr_comp); 37429a05deeSNicholas Bellinger 3757c0d0d51SHannes Reinecke target_luns_data_has_changed(nacl, new, true); 37629a05deeSNicholas Bellinger kfree_rcu(orig, rcu_head); 377c66ac9dbSNicholas Bellinger return 0; 378c66ac9dbSNicholas Bellinger } 379e80ac6c4SAndy Grover 38029a05deeSNicholas Bellinger rcu_assign_pointer(new->se_lun, lun); 38129a05deeSNicholas Bellinger rcu_assign_pointer(new->se_lun_acl, lun_acl); 38229a05deeSNicholas Bellinger hlist_add_head_rcu(&new->link, &nacl->lun_entry_hlist); 38329a05deeSNicholas Bellinger mutex_unlock(&nacl->lun_entry_mutex); 384c66ac9dbSNicholas Bellinger 3851adff1b3SNicholas Bellinger spin_lock(&lun->lun_deve_lock); 386adf653f9SChristoph Hellwig list_add_tail(&new->lun_link, &lun->lun_deve_list); 3871adff1b3SNicholas Bellinger spin_unlock(&lun->lun_deve_lock); 388c66ac9dbSNicholas Bellinger 3897c0d0d51SHannes Reinecke target_luns_data_has_changed(nacl, new, true); 390c66ac9dbSNicholas Bellinger return 0; 391c66ac9dbSNicholas Bellinger } 392c66ac9dbSNicholas Bellinger 393c66ac9dbSNicholas Bellinger /* 39429a05deeSNicholas Bellinger * Called with se_node_acl->lun_entry_mutex held. 395c66ac9dbSNicholas Bellinger */ 39629a05deeSNicholas Bellinger void core_disable_device_list_for_node( 397e80ac6c4SAndy Grover struct se_lun *lun, 39829a05deeSNicholas Bellinger struct se_dev_entry *orig, 399e80ac6c4SAndy Grover struct se_node_acl *nacl, 400e80ac6c4SAndy Grover struct se_portal_group *tpg) 401e80ac6c4SAndy Grover { 402e80ac6c4SAndy Grover /* 4034cc987eaSNicholas Bellinger * rcu_dereference_raw protected by se_lun->lun_group symlink 4044cc987eaSNicholas Bellinger * reference to se_device->dev_group. 4054cc987eaSNicholas Bellinger */ 4064cc987eaSNicholas Bellinger struct se_device *dev = rcu_dereference_raw(lun->lun_se_dev); 407e80ac6c4SAndy Grover /* 408e80ac6c4SAndy Grover * If the MappedLUN entry is being disabled, the entry in 409adf653f9SChristoph Hellwig * lun->lun_deve_list must be removed now before clearing the 410e80ac6c4SAndy Grover * struct se_dev_entry pointers below as logic in 411e80ac6c4SAndy Grover * core_alua_do_transition_tg_pt() depends on these being present. 412e80ac6c4SAndy Grover * 413e80ac6c4SAndy Grover * deve->se_lun_acl will be NULL for demo-mode created LUNs 414e80ac6c4SAndy Grover * that have not been explicitly converted to MappedLUNs -> 415adf653f9SChristoph Hellwig * struct se_lun_acl, but we remove deve->lun_link from 416adf653f9SChristoph Hellwig * lun->lun_deve_list. This also means that active UAs and 417e80ac6c4SAndy Grover * NodeACL context specific PR metadata for demo-mode 418e80ac6c4SAndy Grover * MappedLUN *deve will be released below.. 419e80ac6c4SAndy Grover */ 4201adff1b3SNicholas Bellinger spin_lock(&lun->lun_deve_lock); 421adf653f9SChristoph Hellwig list_del(&orig->lun_link); 4221adff1b3SNicholas Bellinger spin_unlock(&lun->lun_deve_lock); 423c66ac9dbSNicholas Bellinger /* 424c66ac9dbSNicholas Bellinger * Disable struct se_dev_entry LUN ACL mapping 425c66ac9dbSNicholas Bellinger */ 42629a05deeSNicholas Bellinger core_scsi3_ua_release_all(orig); 427c66ac9dbSNicholas Bellinger 42829a05deeSNicholas Bellinger hlist_del_rcu(&orig->link); 42980bfdfa9SNicholas Bellinger clear_bit(DEF_PR_REG_ACTIVE, &orig->deve_flags); 43029a05deeSNicholas Bellinger rcu_assign_pointer(orig->se_lun, NULL); 43129a05deeSNicholas Bellinger rcu_assign_pointer(orig->se_lun_acl, NULL); 43229a05deeSNicholas Bellinger orig->lun_flags = 0; 43329a05deeSNicholas Bellinger orig->creation_time = 0; 43429a05deeSNicholas Bellinger orig->attach_count--; 43529a05deeSNicholas Bellinger /* 43629a05deeSNicholas Bellinger * Before firing off RCU callback, wait for any in process SPEC_I_PT=1 43729a05deeSNicholas Bellinger * or REGISTER_AND_MOVE PR operation to complete. 43829a05deeSNicholas Bellinger */ 43929a05deeSNicholas Bellinger kref_put(&orig->pr_kref, target_pr_kref_release); 44029a05deeSNicholas Bellinger wait_for_completion(&orig->pr_comp); 44129a05deeSNicholas Bellinger 44229a05deeSNicholas Bellinger kfree_rcu(orig, rcu_head); 443c66ac9dbSNicholas Bellinger 4444cc987eaSNicholas Bellinger core_scsi3_free_pr_reg_from_nacl(dev, nacl); 4457c0d0d51SHannes Reinecke target_luns_data_has_changed(nacl, NULL, false); 446c66ac9dbSNicholas Bellinger } 447c66ac9dbSNicholas Bellinger 448c66ac9dbSNicholas Bellinger /* core_clear_lun_from_tpg(): 449c66ac9dbSNicholas Bellinger * 450c66ac9dbSNicholas Bellinger * 451c66ac9dbSNicholas Bellinger */ 452c66ac9dbSNicholas Bellinger void core_clear_lun_from_tpg(struct se_lun *lun, struct se_portal_group *tpg) 453c66ac9dbSNicholas Bellinger { 454c66ac9dbSNicholas Bellinger struct se_node_acl *nacl; 455c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 456c66ac9dbSNicholas Bellinger 457403edd78SNicholas Bellinger mutex_lock(&tpg->acl_node_mutex); 458c66ac9dbSNicholas Bellinger list_for_each_entry(nacl, &tpg->acl_node_list, acl_list) { 459c66ac9dbSNicholas Bellinger 46029a05deeSNicholas Bellinger mutex_lock(&nacl->lun_entry_mutex); 46129a05deeSNicholas Bellinger hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) { 46229a05deeSNicholas Bellinger struct se_lun *tmp_lun = rcu_dereference_check(deve->se_lun, 46329a05deeSNicholas Bellinger lockdep_is_held(&nacl->lun_entry_mutex)); 46429a05deeSNicholas Bellinger 46529a05deeSNicholas Bellinger if (lun != tmp_lun) 466c66ac9dbSNicholas Bellinger continue; 467c66ac9dbSNicholas Bellinger 46829a05deeSNicholas Bellinger core_disable_device_list_for_node(lun, deve, nacl, tpg); 469c66ac9dbSNicholas Bellinger } 47029a05deeSNicholas Bellinger mutex_unlock(&nacl->lun_entry_mutex); 471c66ac9dbSNicholas Bellinger } 472403edd78SNicholas Bellinger mutex_unlock(&tpg->acl_node_mutex); 473c66ac9dbSNicholas Bellinger } 474c66ac9dbSNicholas Bellinger 475adf653f9SChristoph Hellwig int core_alloc_rtpi(struct se_lun *lun, struct se_device *dev) 476c66ac9dbSNicholas Bellinger { 477adf653f9SChristoph Hellwig struct se_lun *tmp; 478c66ac9dbSNicholas Bellinger 479c66ac9dbSNicholas Bellinger spin_lock(&dev->se_port_lock); 480adf653f9SChristoph Hellwig if (dev->export_count == 0x0000ffff) { 4816708bb27SAndy Grover pr_warn("Reached dev->dev_port_count ==" 482c66ac9dbSNicholas Bellinger " 0x0000ffff\n"); 483c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 484adf653f9SChristoph Hellwig return -ENOSPC; 485c66ac9dbSNicholas Bellinger } 486c66ac9dbSNicholas Bellinger again: 487c66ac9dbSNicholas Bellinger /* 48835d1efe8SMasanari Iida * Allocate the next RELATIVE TARGET PORT IDENTIFIER for this struct se_device 489c66ac9dbSNicholas Bellinger * Here is the table from spc4r17 section 7.7.3.8. 490c66ac9dbSNicholas Bellinger * 491c66ac9dbSNicholas Bellinger * Table 473 -- RELATIVE TARGET PORT IDENTIFIER field 492c66ac9dbSNicholas Bellinger * 493c66ac9dbSNicholas Bellinger * Code Description 494c66ac9dbSNicholas Bellinger * 0h Reserved 495c66ac9dbSNicholas Bellinger * 1h Relative port 1, historically known as port A 496c66ac9dbSNicholas Bellinger * 2h Relative port 2, historically known as port B 497c66ac9dbSNicholas Bellinger * 3h to FFFFh Relative port 3 through 65 535 498c66ac9dbSNicholas Bellinger */ 499adf653f9SChristoph Hellwig lun->lun_rtpi = dev->dev_rpti_counter++; 500adf653f9SChristoph Hellwig if (!lun->lun_rtpi) 501c66ac9dbSNicholas Bellinger goto again; 502c66ac9dbSNicholas Bellinger 503adf653f9SChristoph Hellwig list_for_each_entry(tmp, &dev->dev_sep_list, lun_dev_link) { 504c66ac9dbSNicholas Bellinger /* 50535d1efe8SMasanari Iida * Make sure RELATIVE TARGET PORT IDENTIFIER is unique 506c66ac9dbSNicholas Bellinger * for 16-bit wrap.. 507c66ac9dbSNicholas Bellinger */ 508adf653f9SChristoph Hellwig if (lun->lun_rtpi == tmp->lun_rtpi) 509c66ac9dbSNicholas Bellinger goto again; 510c66ac9dbSNicholas Bellinger } 511c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 512c66ac9dbSNicholas Bellinger 513c66ac9dbSNicholas Bellinger return 0; 514c66ac9dbSNicholas Bellinger } 515c66ac9dbSNicholas Bellinger 5160fd97ccfSChristoph Hellwig static void se_release_vpd_for_dev(struct se_device *dev) 517c66ac9dbSNicholas Bellinger { 518c66ac9dbSNicholas Bellinger struct t10_vpd *vpd, *vpd_tmp; 519c66ac9dbSNicholas Bellinger 5200fd97ccfSChristoph Hellwig spin_lock(&dev->t10_wwn.t10_vpd_lock); 521c66ac9dbSNicholas Bellinger list_for_each_entry_safe(vpd, vpd_tmp, 5220fd97ccfSChristoph Hellwig &dev->t10_wwn.t10_vpd_list, vpd_list) { 523c66ac9dbSNicholas Bellinger list_del(&vpd->vpd_list); 524c66ac9dbSNicholas Bellinger kfree(vpd); 525c66ac9dbSNicholas Bellinger } 5260fd97ccfSChristoph Hellwig spin_unlock(&dev->t10_wwn.t10_vpd_lock); 527c66ac9dbSNicholas Bellinger } 528c66ac9dbSNicholas Bellinger 529c8045372SRoland Dreier static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) 530525a48a2SNicholas Bellinger { 5313e03989bSRoland Dreier u32 aligned_max_sectors; 5323e03989bSRoland Dreier u32 alignment; 533525a48a2SNicholas Bellinger /* 534525a48a2SNicholas Bellinger * Limit max_sectors to a PAGE_SIZE aligned value for modern 535525a48a2SNicholas Bellinger * transport_allocate_data_tasks() operation. 536525a48a2SNicholas Bellinger */ 5373e03989bSRoland Dreier alignment = max(1ul, PAGE_SIZE / block_size); 5383e03989bSRoland Dreier aligned_max_sectors = rounddown(max_sectors, alignment); 539525a48a2SNicholas Bellinger 5403e03989bSRoland Dreier if (max_sectors != aligned_max_sectors) 5413e03989bSRoland Dreier pr_info("Rounding down aligned max_sectors from %u to %u\n", 5423e03989bSRoland Dreier max_sectors, aligned_max_sectors); 5433e03989bSRoland Dreier 5443e03989bSRoland Dreier return aligned_max_sectors; 545525a48a2SNicholas Bellinger } 546525a48a2SNicholas Bellinger 5476bb82612SNicholas Bellinger int core_dev_add_lun( 548c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 549c66ac9dbSNicholas Bellinger struct se_device *dev, 5506bb82612SNicholas Bellinger struct se_lun *lun) 551c66ac9dbSNicholas Bellinger { 5528d9efe53SSebastian Andrzej Siewior int rc; 553c66ac9dbSNicholas Bellinger 554d344f8a1SAndy Grover rc = core_tpg_add_lun(tpg, lun, 55558d92618SNicholas Bellinger TRANSPORT_LUNFLAGS_READ_WRITE, dev); 5568d9efe53SSebastian Andrzej Siewior if (rc < 0) 5576bb82612SNicholas Bellinger return rc; 558c66ac9dbSNicholas Bellinger 559f2d30680SHannes Reinecke pr_debug("%s_TPG[%u]_LUN[%llu] - Activated %s Logical Unit from" 560e3d6f909SAndy Grover " CORE HBA: %u\n", tpg->se_tpg_tfo->get_fabric_name(), 5612af7973aSAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, 5622dca673bSAndy Grover tpg->se_tpg_tfo->get_fabric_name(), dev->se_hba->hba_id); 563c66ac9dbSNicholas Bellinger /* 564c66ac9dbSNicholas Bellinger * Update LUN maps for dynamically added initiators when 565c66ac9dbSNicholas Bellinger * generate_node_acl is enabled. 566c66ac9dbSNicholas Bellinger */ 567e3d6f909SAndy Grover if (tpg->se_tpg_tfo->tpg_check_demo_mode(tpg)) { 568c66ac9dbSNicholas Bellinger struct se_node_acl *acl; 569403edd78SNicholas Bellinger 570403edd78SNicholas Bellinger mutex_lock(&tpg->acl_node_mutex); 571c66ac9dbSNicholas Bellinger list_for_each_entry(acl, &tpg->acl_node_list, acl_list) { 572052605c6SNicholas Bellinger if (acl->dynamic_node_acl && 573052605c6SNicholas Bellinger (!tpg->se_tpg_tfo->tpg_check_demo_mode_login_only || 574052605c6SNicholas Bellinger !tpg->se_tpg_tfo->tpg_check_demo_mode_login_only(tpg))) { 575df9766caSNicholas Bellinger core_tpg_add_node_to_devs(acl, tpg, lun); 576c66ac9dbSNicholas Bellinger } 577c66ac9dbSNicholas Bellinger } 578403edd78SNicholas Bellinger mutex_unlock(&tpg->acl_node_mutex); 579c66ac9dbSNicholas Bellinger } 580c66ac9dbSNicholas Bellinger 5816bb82612SNicholas Bellinger return 0; 582c66ac9dbSNicholas Bellinger } 583c66ac9dbSNicholas Bellinger 584c66ac9dbSNicholas Bellinger /* core_dev_del_lun(): 585c66ac9dbSNicholas Bellinger * 586c66ac9dbSNicholas Bellinger * 587c66ac9dbSNicholas Bellinger */ 588cd9d7cbaSAndy Grover void core_dev_del_lun( 589c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 590cd9d7cbaSAndy Grover struct se_lun *lun) 591c66ac9dbSNicholas Bellinger { 592f2d30680SHannes Reinecke pr_debug("%s_TPG[%u]_LUN[%llu] - Deactivating %s Logical Unit from" 593e3d6f909SAndy Grover " device object\n", tpg->se_tpg_tfo->get_fabric_name(), 594cd9d7cbaSAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, 595e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 596c66ac9dbSNicholas Bellinger 597cd9d7cbaSAndy Grover core_tpg_remove_lun(tpg, lun); 598c66ac9dbSNicholas Bellinger } 599c66ac9dbSNicholas Bellinger 600c66ac9dbSNicholas Bellinger struct se_lun_acl *core_dev_init_initiator_node_lun_acl( 601c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 602fcf29481SNicholas Bellinger struct se_node_acl *nacl, 603f2d30680SHannes Reinecke u64 mapped_lun, 604c66ac9dbSNicholas Bellinger int *ret) 605c66ac9dbSNicholas Bellinger { 606c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl; 607c66ac9dbSNicholas Bellinger 608fcf29481SNicholas Bellinger if (strlen(nacl->initiatorname) >= TRANSPORT_IQN_LEN) { 6096708bb27SAndy Grover pr_err("%s InitiatorName exceeds maximum size.\n", 610e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 611c66ac9dbSNicholas Bellinger *ret = -EOVERFLOW; 612c66ac9dbSNicholas Bellinger return NULL; 613c66ac9dbSNicholas Bellinger } 614c66ac9dbSNicholas Bellinger lacl = kzalloc(sizeof(struct se_lun_acl), GFP_KERNEL); 6156708bb27SAndy Grover if (!lacl) { 6166708bb27SAndy Grover pr_err("Unable to allocate memory for struct se_lun_acl.\n"); 617c66ac9dbSNicholas Bellinger *ret = -ENOMEM; 618c66ac9dbSNicholas Bellinger return NULL; 619c66ac9dbSNicholas Bellinger } 620c66ac9dbSNicholas Bellinger 621c66ac9dbSNicholas Bellinger lacl->mapped_lun = mapped_lun; 622c66ac9dbSNicholas Bellinger lacl->se_lun_nacl = nacl; 623c66ac9dbSNicholas Bellinger 624c66ac9dbSNicholas Bellinger return lacl; 625c66ac9dbSNicholas Bellinger } 626c66ac9dbSNicholas Bellinger 627c66ac9dbSNicholas Bellinger int core_dev_add_initiator_node_lun_acl( 628c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 629c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl, 6306bb82612SNicholas Bellinger struct se_lun *lun, 631c66ac9dbSNicholas Bellinger u32 lun_access) 632c66ac9dbSNicholas Bellinger { 6336bb82612SNicholas Bellinger struct se_node_acl *nacl = lacl->se_lun_nacl; 6344cc987eaSNicholas Bellinger /* 6354cc987eaSNicholas Bellinger * rcu_dereference_raw protected by se_lun->lun_group symlink 6364cc987eaSNicholas Bellinger * reference to se_device->dev_group. 6374cc987eaSNicholas Bellinger */ 6384cc987eaSNicholas Bellinger struct se_device *dev = rcu_dereference_raw(lun->lun_se_dev); 639c66ac9dbSNicholas Bellinger 6406708bb27SAndy Grover if (!nacl) 641c66ac9dbSNicholas Bellinger return -EINVAL; 642c66ac9dbSNicholas Bellinger 643c66ac9dbSNicholas Bellinger if ((lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) && 644c66ac9dbSNicholas Bellinger (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE)) 645c66ac9dbSNicholas Bellinger lun_access = TRANSPORT_LUNFLAGS_READ_ONLY; 646c66ac9dbSNicholas Bellinger 647c66ac9dbSNicholas Bellinger lacl->se_lun = lun; 648c66ac9dbSNicholas Bellinger 649e80ac6c4SAndy Grover if (core_enable_device_list_for_node(lun, lacl, lacl->mapped_lun, 650e80ac6c4SAndy Grover lun_access, nacl, tpg) < 0) 651c66ac9dbSNicholas Bellinger return -EINVAL; 652c66ac9dbSNicholas Bellinger 653f2d30680SHannes Reinecke pr_debug("%s_TPG[%hu]_LUN[%llu->%llu] - Added %s ACL for " 654e3d6f909SAndy Grover " InitiatorNode: %s\n", tpg->se_tpg_tfo->get_fabric_name(), 6556bb82612SNicholas Bellinger tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, lacl->mapped_lun, 656c66ac9dbSNicholas Bellinger (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) ? "RW" : "RO", 657b6a54b8dSChris Zankel nacl->initiatorname); 658c66ac9dbSNicholas Bellinger /* 659c66ac9dbSNicholas Bellinger * Check to see if there are any existing persistent reservation APTPL 660c66ac9dbSNicholas Bellinger * pre-registrations that need to be enabled for this LUN ACL.. 661c66ac9dbSNicholas Bellinger */ 6624cc987eaSNicholas Bellinger core_scsi3_check_aptpl_registration(dev, tpg, lun, nacl, 663e2480563SNicholas Bellinger lacl->mapped_lun); 664c66ac9dbSNicholas Bellinger return 0; 665c66ac9dbSNicholas Bellinger } 666c66ac9dbSNicholas Bellinger 667c66ac9dbSNicholas Bellinger int core_dev_del_initiator_node_lun_acl( 668c66ac9dbSNicholas Bellinger struct se_lun *lun, 669c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl) 670c66ac9dbSNicholas Bellinger { 671adf653f9SChristoph Hellwig struct se_portal_group *tpg = lun->lun_tpg; 672c66ac9dbSNicholas Bellinger struct se_node_acl *nacl; 67329a05deeSNicholas Bellinger struct se_dev_entry *deve; 674c66ac9dbSNicholas Bellinger 675c66ac9dbSNicholas Bellinger nacl = lacl->se_lun_nacl; 6766708bb27SAndy Grover if (!nacl) 677c66ac9dbSNicholas Bellinger return -EINVAL; 678c66ac9dbSNicholas Bellinger 67929a05deeSNicholas Bellinger mutex_lock(&nacl->lun_entry_mutex); 68029a05deeSNicholas Bellinger deve = target_nacl_find_deve(nacl, lacl->mapped_lun); 68129a05deeSNicholas Bellinger if (deve) 68229a05deeSNicholas Bellinger core_disable_device_list_for_node(lun, deve, nacl, tpg); 68329a05deeSNicholas Bellinger mutex_unlock(&nacl->lun_entry_mutex); 684c66ac9dbSNicholas Bellinger 685f2d30680SHannes Reinecke pr_debug("%s_TPG[%hu]_LUN[%llu] - Removed ACL for" 686f2d30680SHannes Reinecke " InitiatorNode: %s Mapped LUN: %llu\n", 687e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), 688e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, 689b6a54b8dSChris Zankel nacl->initiatorname, lacl->mapped_lun); 690c66ac9dbSNicholas Bellinger 691c66ac9dbSNicholas Bellinger return 0; 692c66ac9dbSNicholas Bellinger } 693c66ac9dbSNicholas Bellinger 694c66ac9dbSNicholas Bellinger void core_dev_free_initiator_node_lun_acl( 695c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 696c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl) 697c66ac9dbSNicholas Bellinger { 6986708bb27SAndy Grover pr_debug("%s_TPG[%hu] - Freeing ACL for %s InitiatorNode: %s" 699f2d30680SHannes Reinecke " Mapped LUN: %llu\n", tpg->se_tpg_tfo->get_fabric_name(), 700e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), 701e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), 702b6a54b8dSChris Zankel lacl->se_lun_nacl->initiatorname, lacl->mapped_lun); 703c66ac9dbSNicholas Bellinger 704c66ac9dbSNicholas Bellinger kfree(lacl); 705c66ac9dbSNicholas Bellinger } 706c66ac9dbSNicholas Bellinger 7070fd97ccfSChristoph Hellwig static void scsi_dump_inquiry(struct se_device *dev) 7080fd97ccfSChristoph Hellwig { 7090fd97ccfSChristoph Hellwig struct t10_wwn *wwn = &dev->t10_wwn; 7100fd97ccfSChristoph Hellwig char buf[17]; 7110fd97ccfSChristoph Hellwig int i, device_type; 7120fd97ccfSChristoph Hellwig /* 7130fd97ccfSChristoph Hellwig * Print Linux/SCSI style INQUIRY formatting to the kernel ring buffer 7140fd97ccfSChristoph Hellwig */ 7150fd97ccfSChristoph Hellwig for (i = 0; i < 8; i++) 7160fd97ccfSChristoph Hellwig if (wwn->vendor[i] >= 0x20) 7170fd97ccfSChristoph Hellwig buf[i] = wwn->vendor[i]; 7180fd97ccfSChristoph Hellwig else 7190fd97ccfSChristoph Hellwig buf[i] = ' '; 7200fd97ccfSChristoph Hellwig buf[i] = '\0'; 7210fd97ccfSChristoph Hellwig pr_debug(" Vendor: %s\n", buf); 7220fd97ccfSChristoph Hellwig 7230fd97ccfSChristoph Hellwig for (i = 0; i < 16; i++) 7240fd97ccfSChristoph Hellwig if (wwn->model[i] >= 0x20) 7250fd97ccfSChristoph Hellwig buf[i] = wwn->model[i]; 7260fd97ccfSChristoph Hellwig else 7270fd97ccfSChristoph Hellwig buf[i] = ' '; 7280fd97ccfSChristoph Hellwig buf[i] = '\0'; 7290fd97ccfSChristoph Hellwig pr_debug(" Model: %s\n", buf); 7300fd97ccfSChristoph Hellwig 7310fd97ccfSChristoph Hellwig for (i = 0; i < 4; i++) 7320fd97ccfSChristoph Hellwig if (wwn->revision[i] >= 0x20) 7330fd97ccfSChristoph Hellwig buf[i] = wwn->revision[i]; 7340fd97ccfSChristoph Hellwig else 7350fd97ccfSChristoph Hellwig buf[i] = ' '; 7360fd97ccfSChristoph Hellwig buf[i] = '\0'; 7370fd97ccfSChristoph Hellwig pr_debug(" Revision: %s\n", buf); 7380fd97ccfSChristoph Hellwig 7390fd97ccfSChristoph Hellwig device_type = dev->transport->get_device_type(dev); 7400fd97ccfSChristoph Hellwig pr_debug(" Type: %s ", scsi_device_type(device_type)); 7410fd97ccfSChristoph Hellwig } 7420fd97ccfSChristoph Hellwig 7430fd97ccfSChristoph Hellwig struct se_device *target_alloc_device(struct se_hba *hba, const char *name) 7440fd97ccfSChristoph Hellwig { 7450fd97ccfSChristoph Hellwig struct se_device *dev; 7464863e525SNicholas Bellinger struct se_lun *xcopy_lun; 7470fd97ccfSChristoph Hellwig 7480a06d430SChristoph Hellwig dev = hba->backend->ops->alloc_device(hba, name); 7490fd97ccfSChristoph Hellwig if (!dev) 7500fd97ccfSChristoph Hellwig return NULL; 7510fd97ccfSChristoph Hellwig 7520ff87549SNicholas Bellinger dev->dev_link_magic = SE_DEV_LINK_MAGIC; 7530fd97ccfSChristoph Hellwig dev->se_hba = hba; 7540a06d430SChristoph Hellwig dev->transport = hba->backend->ops; 755fe052a18SSagi Grimberg dev->prot_length = sizeof(struct t10_pi_tuple); 7564cc987eaSNicholas Bellinger dev->hba_index = hba->hba_index; 7570fd97ccfSChristoph Hellwig 7580fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->dev_list); 7590fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->dev_sep_list); 7600fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->dev_tmr_list); 7610fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->delayed_cmd_list); 7620fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->state_list); 7630fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->qf_cmd_list); 764d9ea32bfSNicholas Bellinger INIT_LIST_HEAD(&dev->g_dev_node); 7650fd97ccfSChristoph Hellwig spin_lock_init(&dev->execute_task_lock); 7660fd97ccfSChristoph Hellwig spin_lock_init(&dev->delayed_cmd_lock); 7670fd97ccfSChristoph Hellwig spin_lock_init(&dev->dev_reservation_lock); 7680fd97ccfSChristoph Hellwig spin_lock_init(&dev->se_port_lock); 7690fd97ccfSChristoph Hellwig spin_lock_init(&dev->se_tmr_lock); 7700fd97ccfSChristoph Hellwig spin_lock_init(&dev->qf_cmd_lock); 77168ff9b9bSNicholas Bellinger sema_init(&dev->caw_sem, 1); 7720fd97ccfSChristoph Hellwig atomic_set(&dev->dev_ordered_id, 0); 7730fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_wwn.t10_vpd_list); 7740fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_wwn.t10_vpd_lock); 7750fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_pr.registration_list); 7760fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_pr.aptpl_reg_list); 7770fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_pr.registration_lock); 7780fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_pr.aptpl_reg_lock); 7790fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_alua.tg_pt_gps_list); 7800fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_alua.tg_pt_gps_lock); 781c66094bfSHannes Reinecke INIT_LIST_HEAD(&dev->t10_alua.lba_map_list); 782c66094bfSHannes Reinecke spin_lock_init(&dev->t10_alua.lba_map_lock); 7830fd97ccfSChristoph Hellwig 7840fd97ccfSChristoph Hellwig dev->t10_wwn.t10_dev = dev; 7850fd97ccfSChristoph Hellwig dev->t10_alua.t10_dev = dev; 7860fd97ccfSChristoph Hellwig 7870fd97ccfSChristoph Hellwig dev->dev_attrib.da_dev = dev; 788adfa9570STregaron Bayly dev->dev_attrib.emulate_model_alias = DA_EMULATE_MODEL_ALIAS; 789814e5b45SChristoph Hellwig dev->dev_attrib.emulate_dpo = 1; 790814e5b45SChristoph Hellwig dev->dev_attrib.emulate_fua_write = 1; 791814e5b45SChristoph Hellwig dev->dev_attrib.emulate_fua_read = 1; 7920fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_write_cache = DA_EMULATE_WRITE_CACHE; 7930fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_ua_intlck_ctrl = DA_EMULATE_UA_INTLLCK_CTRL; 7940fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tas = DA_EMULATE_TAS; 7950fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tpu = DA_EMULATE_TPU; 7960fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tpws = DA_EMULATE_TPWS; 7970123a9ecSNicholas Bellinger dev->dev_attrib.emulate_caw = DA_EMULATE_CAW; 798d397a445SNicholas Bellinger dev->dev_attrib.emulate_3pc = DA_EMULATE_3PC; 7992ed22c9cSNicholas Bellinger dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE0_PROT; 8000fd97ccfSChristoph Hellwig dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS; 80192404e60SNicholas Bellinger dev->dev_attrib.force_pr_aptpl = DA_FORCE_PR_APTPL; 8020fd97ccfSChristoph Hellwig dev->dev_attrib.is_nonrot = DA_IS_NONROT; 8030fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD; 8040fd97ccfSChristoph Hellwig dev->dev_attrib.max_unmap_lba_count = DA_MAX_UNMAP_LBA_COUNT; 8050fd97ccfSChristoph Hellwig dev->dev_attrib.max_unmap_block_desc_count = 8060fd97ccfSChristoph Hellwig DA_MAX_UNMAP_BLOCK_DESC_COUNT; 8070fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity = DA_UNMAP_GRANULARITY_DEFAULT; 8080fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity_alignment = 8090fd97ccfSChristoph Hellwig DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT; 810773cbaf7SNicholas Bellinger dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN; 8110fd97ccfSChristoph Hellwig 8124863e525SNicholas Bellinger xcopy_lun = &dev->xcopy_lun; 8134cc987eaSNicholas Bellinger rcu_assign_pointer(xcopy_lun->lun_se_dev, dev); 8144863e525SNicholas Bellinger init_completion(&xcopy_lun->lun_ref_comp); 815adf653f9SChristoph Hellwig INIT_LIST_HEAD(&xcopy_lun->lun_deve_list); 816adf653f9SChristoph Hellwig INIT_LIST_HEAD(&xcopy_lun->lun_dev_link); 817adf653f9SChristoph Hellwig mutex_init(&xcopy_lun->lun_tg_pt_md_mutex); 818adf653f9SChristoph Hellwig xcopy_lun->lun_tpg = &xcopy_pt_tpg; 8194863e525SNicholas Bellinger 8200fd97ccfSChristoph Hellwig return dev; 8210fd97ccfSChristoph Hellwig } 8220fd97ccfSChristoph Hellwig 8230fd97ccfSChristoph Hellwig int target_configure_device(struct se_device *dev) 8240fd97ccfSChristoph Hellwig { 8250fd97ccfSChristoph Hellwig struct se_hba *hba = dev->se_hba; 8260fd97ccfSChristoph Hellwig int ret; 8270fd97ccfSChristoph Hellwig 8280fd97ccfSChristoph Hellwig if (dev->dev_flags & DF_CONFIGURED) { 8290fd97ccfSChristoph Hellwig pr_err("se_dev->se_dev_ptr already set for storage" 8300fd97ccfSChristoph Hellwig " object\n"); 8310fd97ccfSChristoph Hellwig return -EEXIST; 8320fd97ccfSChristoph Hellwig } 8330fd97ccfSChristoph Hellwig 8340fd97ccfSChristoph Hellwig ret = dev->transport->configure_device(dev); 8350fd97ccfSChristoph Hellwig if (ret) 8360fd97ccfSChristoph Hellwig goto out; 8370fd97ccfSChristoph Hellwig /* 8380fd97ccfSChristoph Hellwig * XXX: there is not much point to have two different values here.. 8390fd97ccfSChristoph Hellwig */ 8400fd97ccfSChristoph Hellwig dev->dev_attrib.block_size = dev->dev_attrib.hw_block_size; 8410fd97ccfSChristoph Hellwig dev->dev_attrib.queue_depth = dev->dev_attrib.hw_queue_depth; 8420fd97ccfSChristoph Hellwig 8430fd97ccfSChristoph Hellwig /* 8440fd97ccfSChristoph Hellwig * Align max_hw_sectors down to PAGE_SIZE I/O transfers 8450fd97ccfSChristoph Hellwig */ 8460fd97ccfSChristoph Hellwig dev->dev_attrib.hw_max_sectors = 8470fd97ccfSChristoph Hellwig se_dev_align_max_sectors(dev->dev_attrib.hw_max_sectors, 8480fd97ccfSChristoph Hellwig dev->dev_attrib.hw_block_size); 849046ba642SNicholas Bellinger dev->dev_attrib.optimal_sectors = dev->dev_attrib.hw_max_sectors; 8500fd97ccfSChristoph Hellwig 8510fd97ccfSChristoph Hellwig dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX); 8520fd97ccfSChristoph Hellwig dev->creation_time = get_jiffies_64(); 8530fd97ccfSChristoph Hellwig 8540fd97ccfSChristoph Hellwig ret = core_setup_alua(dev); 8550fd97ccfSChristoph Hellwig if (ret) 8560fd97ccfSChristoph Hellwig goto out; 8570fd97ccfSChristoph Hellwig 8580fd97ccfSChristoph Hellwig /* 8590fd97ccfSChristoph Hellwig * Startup the struct se_device processing thread 8600fd97ccfSChristoph Hellwig */ 8610fd97ccfSChristoph Hellwig dev->tmr_wq = alloc_workqueue("tmr-%s", WQ_MEM_RECLAIM | WQ_UNBOUND, 1, 8620fd97ccfSChristoph Hellwig dev->transport->name); 8630fd97ccfSChristoph Hellwig if (!dev->tmr_wq) { 8640fd97ccfSChristoph Hellwig pr_err("Unable to create tmr workqueue for %s\n", 8650fd97ccfSChristoph Hellwig dev->transport->name); 8660fd97ccfSChristoph Hellwig ret = -ENOMEM; 8670fd97ccfSChristoph Hellwig goto out_free_alua; 8680fd97ccfSChristoph Hellwig } 8690fd97ccfSChristoph Hellwig 8700fd97ccfSChristoph Hellwig /* 8710fd97ccfSChristoph Hellwig * Setup work_queue for QUEUE_FULL 8720fd97ccfSChristoph Hellwig */ 8730fd97ccfSChristoph Hellwig INIT_WORK(&dev->qf_work_queue, target_qf_do_work); 8740fd97ccfSChristoph Hellwig 8750fd97ccfSChristoph Hellwig /* 8760fd97ccfSChristoph Hellwig * Preload the initial INQUIRY const values if we are doing 8770fd97ccfSChristoph Hellwig * anything virtual (IBLOCK, FILEIO, RAMDISK), but not for TCM/pSCSI 8780fd97ccfSChristoph Hellwig * passthrough because this is being provided by the backend LLD. 8790fd97ccfSChristoph Hellwig */ 880a3541703SAndy Grover if (!(dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH)) { 8810fd97ccfSChristoph Hellwig strncpy(&dev->t10_wwn.vendor[0], "LIO-ORG", 8); 8820fd97ccfSChristoph Hellwig strncpy(&dev->t10_wwn.model[0], 8830fd97ccfSChristoph Hellwig dev->transport->inquiry_prod, 16); 8840fd97ccfSChristoph Hellwig strncpy(&dev->t10_wwn.revision[0], 8850fd97ccfSChristoph Hellwig dev->transport->inquiry_rev, 4); 8860fd97ccfSChristoph Hellwig } 8870fd97ccfSChristoph Hellwig 8880fd97ccfSChristoph Hellwig scsi_dump_inquiry(dev); 8890fd97ccfSChristoph Hellwig 8900fd97ccfSChristoph Hellwig spin_lock(&hba->device_lock); 8910fd97ccfSChristoph Hellwig hba->dev_count++; 8920fd97ccfSChristoph Hellwig spin_unlock(&hba->device_lock); 893d9ea32bfSNicholas Bellinger 894d9ea32bfSNicholas Bellinger mutex_lock(&g_device_mutex); 895d9ea32bfSNicholas Bellinger list_add_tail(&dev->g_dev_node, &g_device_list); 896d9ea32bfSNicholas Bellinger mutex_unlock(&g_device_mutex); 897d9ea32bfSNicholas Bellinger 8985f7da044SNicholas Bellinger dev->dev_flags |= DF_CONFIGURED; 8995f7da044SNicholas Bellinger 9000fd97ccfSChristoph Hellwig return 0; 9010fd97ccfSChristoph Hellwig 9020fd97ccfSChristoph Hellwig out_free_alua: 9030fd97ccfSChristoph Hellwig core_alua_free_lu_gp_mem(dev); 9040fd97ccfSChristoph Hellwig out: 9050fd97ccfSChristoph Hellwig se_release_vpd_for_dev(dev); 9060fd97ccfSChristoph Hellwig return ret; 9070fd97ccfSChristoph Hellwig } 9080fd97ccfSChristoph Hellwig 9090fd97ccfSChristoph Hellwig void target_free_device(struct se_device *dev) 9100fd97ccfSChristoph Hellwig { 9110fd97ccfSChristoph Hellwig struct se_hba *hba = dev->se_hba; 9120fd97ccfSChristoph Hellwig 9130fd97ccfSChristoph Hellwig WARN_ON(!list_empty(&dev->dev_sep_list)); 9140fd97ccfSChristoph Hellwig 9150fd97ccfSChristoph Hellwig if (dev->dev_flags & DF_CONFIGURED) { 9160fd97ccfSChristoph Hellwig destroy_workqueue(dev->tmr_wq); 9170fd97ccfSChristoph Hellwig 918d9ea32bfSNicholas Bellinger mutex_lock(&g_device_mutex); 919d9ea32bfSNicholas Bellinger list_del(&dev->g_dev_node); 920d9ea32bfSNicholas Bellinger mutex_unlock(&g_device_mutex); 921d9ea32bfSNicholas Bellinger 9220fd97ccfSChristoph Hellwig spin_lock(&hba->device_lock); 9230fd97ccfSChristoph Hellwig hba->dev_count--; 9240fd97ccfSChristoph Hellwig spin_unlock(&hba->device_lock); 9250fd97ccfSChristoph Hellwig } 9260fd97ccfSChristoph Hellwig 9270fd97ccfSChristoph Hellwig core_alua_free_lu_gp_mem(dev); 928229d4f11SHannes Reinecke core_alua_set_lba_map(dev, NULL, 0, 0); 9290fd97ccfSChristoph Hellwig core_scsi3_free_all_registrations(dev); 9300fd97ccfSChristoph Hellwig se_release_vpd_for_dev(dev); 9310fd97ccfSChristoph Hellwig 9322ed22c9cSNicholas Bellinger if (dev->transport->free_prot) 9332ed22c9cSNicholas Bellinger dev->transport->free_prot(dev); 9342ed22c9cSNicholas Bellinger 9350fd97ccfSChristoph Hellwig dev->transport->free_device(dev); 9360fd97ccfSChristoph Hellwig } 9370fd97ccfSChristoph Hellwig 938c66ac9dbSNicholas Bellinger int core_dev_setup_virtual_lun0(void) 939c66ac9dbSNicholas Bellinger { 940c66ac9dbSNicholas Bellinger struct se_hba *hba; 941c66ac9dbSNicholas Bellinger struct se_device *dev; 942db5d1c3cSAndy Grover char buf[] = "rd_pages=8,rd_nullio=1"; 943c66ac9dbSNicholas Bellinger int ret; 944c66ac9dbSNicholas Bellinger 9456708bb27SAndy Grover hba = core_alloc_hba("rd_mcp", 0, HBA_FLAGS_INTERNAL_USE); 946c66ac9dbSNicholas Bellinger if (IS_ERR(hba)) 947c66ac9dbSNicholas Bellinger return PTR_ERR(hba); 948c66ac9dbSNicholas Bellinger 9490fd97ccfSChristoph Hellwig dev = target_alloc_device(hba, "virt_lun0"); 9500fd97ccfSChristoph Hellwig if (!dev) { 951c66ac9dbSNicholas Bellinger ret = -ENOMEM; 9520fd97ccfSChristoph Hellwig goto out_free_hba; 953c66ac9dbSNicholas Bellinger } 954c66ac9dbSNicholas Bellinger 9550a06d430SChristoph Hellwig hba->backend->ops->set_configfs_dev_params(dev, buf, sizeof(buf)); 956c66ac9dbSNicholas Bellinger 9570fd97ccfSChristoph Hellwig ret = target_configure_device(dev); 9580fd97ccfSChristoph Hellwig if (ret) 9590fd97ccfSChristoph Hellwig goto out_free_se_dev; 9600fd97ccfSChristoph Hellwig 9610fd97ccfSChristoph Hellwig lun0_hba = hba; 962e3d6f909SAndy Grover g_lun0_dev = dev; 963c66ac9dbSNicholas Bellinger return 0; 9640fd97ccfSChristoph Hellwig 9650fd97ccfSChristoph Hellwig out_free_se_dev: 9660fd97ccfSChristoph Hellwig target_free_device(dev); 9670fd97ccfSChristoph Hellwig out_free_hba: 9680fd97ccfSChristoph Hellwig core_delete_hba(hba); 969c66ac9dbSNicholas Bellinger return ret; 970c66ac9dbSNicholas Bellinger } 971c66ac9dbSNicholas Bellinger 972c66ac9dbSNicholas Bellinger 973c66ac9dbSNicholas Bellinger void core_dev_release_virtual_lun0(void) 974c66ac9dbSNicholas Bellinger { 975e3d6f909SAndy Grover struct se_hba *hba = lun0_hba; 976c66ac9dbSNicholas Bellinger 9776708bb27SAndy Grover if (!hba) 978c66ac9dbSNicholas Bellinger return; 979c66ac9dbSNicholas Bellinger 980e3d6f909SAndy Grover if (g_lun0_dev) 9810fd97ccfSChristoph Hellwig target_free_device(g_lun0_dev); 982c66ac9dbSNicholas Bellinger core_delete_hba(hba); 983c66ac9dbSNicholas Bellinger } 9847bfea53bSAndy Grover 9857bfea53bSAndy Grover /* 9867bfea53bSAndy Grover * Common CDB parsing for kernel and user passthrough. 9877bfea53bSAndy Grover */ 9887bfea53bSAndy Grover sense_reason_t 9897bfea53bSAndy Grover passthrough_parse_cdb(struct se_cmd *cmd, 9907bfea53bSAndy Grover sense_reason_t (*exec_cmd)(struct se_cmd *cmd)) 9917bfea53bSAndy Grover { 9927bfea53bSAndy Grover unsigned char *cdb = cmd->t_task_cdb; 9937bfea53bSAndy Grover 9947bfea53bSAndy Grover /* 9957bfea53bSAndy Grover * Clear a lun set in the cdb if the initiator talking to use spoke 9967bfea53bSAndy Grover * and old standards version, as we can't assume the underlying device 9977bfea53bSAndy Grover * won't choke up on it. 9987bfea53bSAndy Grover */ 9997bfea53bSAndy Grover switch (cdb[0]) { 10007bfea53bSAndy Grover case READ_10: /* SBC - RDProtect */ 10017bfea53bSAndy Grover case READ_12: /* SBC - RDProtect */ 10027bfea53bSAndy Grover case READ_16: /* SBC - RDProtect */ 10037bfea53bSAndy Grover case SEND_DIAGNOSTIC: /* SPC - SELF-TEST Code */ 10047bfea53bSAndy Grover case VERIFY: /* SBC - VRProtect */ 10057bfea53bSAndy Grover case VERIFY_16: /* SBC - VRProtect */ 10067bfea53bSAndy Grover case WRITE_VERIFY: /* SBC - VRProtect */ 10077bfea53bSAndy Grover case WRITE_VERIFY_12: /* SBC - VRProtect */ 10087bfea53bSAndy Grover case MAINTENANCE_IN: /* SPC - Parameter Data Format for SA RTPG */ 10097bfea53bSAndy Grover break; 10107bfea53bSAndy Grover default: 10117bfea53bSAndy Grover cdb[1] &= 0x1f; /* clear logical unit number */ 10127bfea53bSAndy Grover break; 10137bfea53bSAndy Grover } 10147bfea53bSAndy Grover 10157bfea53bSAndy Grover /* 10167bfea53bSAndy Grover * For REPORT LUNS we always need to emulate the response, for everything 10177bfea53bSAndy Grover * else, pass it up. 10187bfea53bSAndy Grover */ 10197bfea53bSAndy Grover if (cdb[0] == REPORT_LUNS) { 10207bfea53bSAndy Grover cmd->execute_cmd = spc_emulate_report_luns; 10217bfea53bSAndy Grover return TCM_NO_SENSE; 10227bfea53bSAndy Grover } 10237bfea53bSAndy Grover 10247bfea53bSAndy Grover /* Set DATA_CDB flag for ops that should have it */ 10257bfea53bSAndy Grover switch (cdb[0]) { 10267bfea53bSAndy Grover case READ_6: 10277bfea53bSAndy Grover case READ_10: 10287bfea53bSAndy Grover case READ_12: 10297bfea53bSAndy Grover case READ_16: 10307bfea53bSAndy Grover case WRITE_6: 10317bfea53bSAndy Grover case WRITE_10: 10327bfea53bSAndy Grover case WRITE_12: 10337bfea53bSAndy Grover case WRITE_16: 10347bfea53bSAndy Grover case WRITE_VERIFY: 10357bfea53bSAndy Grover case WRITE_VERIFY_12: 10367bfea53bSAndy Grover case 0x8e: /* WRITE_VERIFY_16 */ 10377bfea53bSAndy Grover case COMPARE_AND_WRITE: 10387bfea53bSAndy Grover case XDWRITEREAD_10: 10397bfea53bSAndy Grover cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; 10407bfea53bSAndy Grover break; 10417bfea53bSAndy Grover case VARIABLE_LENGTH_CMD: 10427bfea53bSAndy Grover switch (get_unaligned_be16(&cdb[8])) { 10437bfea53bSAndy Grover case READ_32: 10447bfea53bSAndy Grover case WRITE_32: 10457bfea53bSAndy Grover case 0x0c: /* WRITE_VERIFY_32 */ 10467bfea53bSAndy Grover case XDWRITEREAD_32: 10477bfea53bSAndy Grover cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; 10487bfea53bSAndy Grover break; 10497bfea53bSAndy Grover } 10507bfea53bSAndy Grover } 10517bfea53bSAndy Grover 10527bfea53bSAndy Grover cmd->execute_cmd = exec_cmd; 10537bfea53bSAndy Grover 10547bfea53bSAndy Grover return TCM_NO_SENSE; 10557bfea53bSAndy Grover } 10567bfea53bSAndy Grover EXPORT_SYMBOL(passthrough_parse_cdb); 1057