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 * 7fd9a11d7SNicholas Bellinger * (c) Copyright 2003-2012 RisingTide Systems LLC. 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> 36c66ac9dbSNicholas Bellinger #include <net/sock.h> 37c66ac9dbSNicholas Bellinger #include <net/tcp.h> 38c66ac9dbSNicholas Bellinger #include <scsi/scsi.h> 391078da16SNicholas Bellinger #include <scsi/scsi_device.h> 40c66ac9dbSNicholas Bellinger 41c66ac9dbSNicholas Bellinger #include <target/target_core_base.h> 42c4795fb2SChristoph Hellwig #include <target/target_core_backend.h> 43c4795fb2SChristoph Hellwig #include <target/target_core_fabric.h> 44c66ac9dbSNicholas Bellinger 45e26d99aeSChristoph Hellwig #include "target_core_internal.h" 46c66ac9dbSNicholas Bellinger #include "target_core_alua.h" 47c66ac9dbSNicholas Bellinger #include "target_core_pr.h" 48c66ac9dbSNicholas Bellinger #include "target_core_ua.h" 49c66ac9dbSNicholas Bellinger 50e3d6f909SAndy Grover static struct se_hba *lun0_hba; 51e3d6f909SAndy Grover /* not static, needed by tpg.c */ 52e3d6f909SAndy Grover struct se_device *g_lun0_dev; 53e3d6f909SAndy Grover 54de103c93SChristoph Hellwig sense_reason_t 55de103c93SChristoph Hellwig transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) 56c66ac9dbSNicholas Bellinger { 57c66ac9dbSNicholas Bellinger struct se_lun *se_lun = NULL; 58e3d6f909SAndy Grover struct se_session *se_sess = se_cmd->se_sess; 595951146dSAndy Grover struct se_device *dev; 60c66ac9dbSNicholas Bellinger unsigned long flags; 61c66ac9dbSNicholas Bellinger 62de103c93SChristoph Hellwig if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) 63de103c93SChristoph Hellwig return TCM_NON_EXISTENT_LUN; 64d8144955SFubo Chen 6578faae37SRoland Dreier spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags); 66f2083241SJörn Engel se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun]; 675951146dSAndy Grover if (se_cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { 685951146dSAndy Grover struct se_dev_entry *deve = se_cmd->se_deve; 695951146dSAndy Grover 70c66ac9dbSNicholas Bellinger deve->total_cmds++; 71c66ac9dbSNicholas Bellinger 725951146dSAndy Grover if ((se_cmd->data_direction == DMA_TO_DEVICE) && 735951146dSAndy Grover (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)) { 746708bb27SAndy Grover pr_err("TARGET_CORE[%s]: Detected WRITE_PROTECTED LUN" 75c66ac9dbSNicholas Bellinger " Access for 0x%08x\n", 76e3d6f909SAndy Grover se_cmd->se_tfo->get_fabric_name(), 77c66ac9dbSNicholas Bellinger unpacked_lun); 7878faae37SRoland Dreier spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); 79de103c93SChristoph Hellwig return TCM_WRITE_PROTECTED; 805951146dSAndy Grover } 815951146dSAndy Grover 825951146dSAndy Grover if (se_cmd->data_direction == DMA_TO_DEVICE) 835951146dSAndy Grover deve->write_bytes += se_cmd->data_length; 845951146dSAndy Grover else if (se_cmd->data_direction == DMA_FROM_DEVICE) 855951146dSAndy Grover deve->read_bytes += se_cmd->data_length; 865951146dSAndy Grover 875951146dSAndy Grover se_lun = deve->se_lun; 885951146dSAndy Grover se_cmd->se_lun = deve->se_lun; 895951146dSAndy Grover se_cmd->pr_res_key = deve->pr_res_key; 905951146dSAndy Grover se_cmd->orig_fe_lun = unpacked_lun; 915951146dSAndy Grover se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; 925951146dSAndy Grover } 9378faae37SRoland Dreier spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); 945951146dSAndy Grover 955951146dSAndy Grover if (!se_lun) { 96c66ac9dbSNicholas Bellinger /* 97c66ac9dbSNicholas Bellinger * Use the se_portal_group->tpg_virt_lun0 to allow for 98c66ac9dbSNicholas Bellinger * REPORT_LUNS, et al to be returned when no active 99c66ac9dbSNicholas Bellinger * MappedLUN=0 exists for this Initiator Port. 100c66ac9dbSNicholas Bellinger */ 101c66ac9dbSNicholas Bellinger if (unpacked_lun != 0) { 1026708bb27SAndy Grover pr_err("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN" 103c66ac9dbSNicholas Bellinger " Access for 0x%08x\n", 104e3d6f909SAndy Grover se_cmd->se_tfo->get_fabric_name(), 105c66ac9dbSNicholas Bellinger unpacked_lun); 106de103c93SChristoph Hellwig return TCM_NON_EXISTENT_LUN; 107c66ac9dbSNicholas Bellinger } 108c66ac9dbSNicholas Bellinger /* 109c66ac9dbSNicholas Bellinger * Force WRITE PROTECT for virtual LUN 0 110c66ac9dbSNicholas Bellinger */ 111c66ac9dbSNicholas Bellinger if ((se_cmd->data_direction != DMA_FROM_DEVICE) && 112de103c93SChristoph Hellwig (se_cmd->data_direction != DMA_NONE)) 113de103c93SChristoph Hellwig return TCM_WRITE_PROTECTED; 1145951146dSAndy Grover 1155951146dSAndy Grover se_lun = &se_sess->se_tpg->tpg_virt_lun0; 1165951146dSAndy Grover se_cmd->se_lun = &se_sess->se_tpg->tpg_virt_lun0; 117c66ac9dbSNicholas Bellinger se_cmd->orig_fe_lun = 0; 118c66ac9dbSNicholas Bellinger se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; 119c66ac9dbSNicholas Bellinger } 120c66ac9dbSNicholas Bellinger 1215951146dSAndy Grover /* Directly associate cmd with se_dev */ 1225951146dSAndy Grover se_cmd->se_dev = se_lun->lun_se_dev; 1235951146dSAndy Grover 1245951146dSAndy Grover /* TODO: get rid of this and use atomics for stats */ 1255951146dSAndy Grover dev = se_lun->lun_se_dev; 12678faae37SRoland Dreier spin_lock_irqsave(&dev->stats_lock, flags); 127c66ac9dbSNicholas Bellinger dev->num_cmds++; 128c66ac9dbSNicholas Bellinger if (se_cmd->data_direction == DMA_TO_DEVICE) 129c66ac9dbSNicholas Bellinger dev->write_bytes += se_cmd->data_length; 130c66ac9dbSNicholas Bellinger else if (se_cmd->data_direction == DMA_FROM_DEVICE) 131c66ac9dbSNicholas Bellinger dev->read_bytes += se_cmd->data_length; 13278faae37SRoland Dreier spin_unlock_irqrestore(&dev->stats_lock, flags); 133c66ac9dbSNicholas Bellinger 134c66ac9dbSNicholas Bellinger spin_lock_irqsave(&se_lun->lun_cmd_lock, flags); 1355951146dSAndy Grover list_add_tail(&se_cmd->se_lun_node, &se_lun->lun_cmd_list); 136c66ac9dbSNicholas Bellinger spin_unlock_irqrestore(&se_lun->lun_cmd_lock, flags); 137c66ac9dbSNicholas Bellinger 138c66ac9dbSNicholas Bellinger return 0; 139c66ac9dbSNicholas Bellinger } 1405951146dSAndy Grover EXPORT_SYMBOL(transport_lookup_cmd_lun); 141c66ac9dbSNicholas Bellinger 1425951146dSAndy Grover int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun) 143c66ac9dbSNicholas Bellinger { 144c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 145c66ac9dbSNicholas Bellinger struct se_lun *se_lun = NULL; 146e3d6f909SAndy Grover struct se_session *se_sess = se_cmd->se_sess; 147c66ac9dbSNicholas Bellinger struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; 1485e1be919SRoland Dreier unsigned long flags; 149c66ac9dbSNicholas Bellinger 150de103c93SChristoph Hellwig if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) 151e3d6f909SAndy Grover return -ENODEV; 152d8144955SFubo Chen 1535e1be919SRoland Dreier spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags); 154f2083241SJörn Engel se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun]; 1555951146dSAndy Grover deve = se_cmd->se_deve; 1565951146dSAndy Grover 157c66ac9dbSNicholas Bellinger if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { 1585951146dSAndy Grover se_tmr->tmr_lun = deve->se_lun; 1595951146dSAndy Grover se_cmd->se_lun = deve->se_lun; 1605951146dSAndy Grover se_lun = deve->se_lun; 161c66ac9dbSNicholas Bellinger se_cmd->pr_res_key = deve->pr_res_key; 162c66ac9dbSNicholas Bellinger se_cmd->orig_fe_lun = unpacked_lun; 163c66ac9dbSNicholas Bellinger } 1645e1be919SRoland Dreier spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); 165c66ac9dbSNicholas Bellinger 166c66ac9dbSNicholas Bellinger if (!se_lun) { 1676708bb27SAndy Grover pr_debug("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN" 168c66ac9dbSNicholas Bellinger " Access for 0x%08x\n", 169e3d6f909SAndy Grover se_cmd->se_tfo->get_fabric_name(), 170c66ac9dbSNicholas Bellinger unpacked_lun); 171e3d6f909SAndy Grover return -ENODEV; 172c66ac9dbSNicholas Bellinger } 173c66ac9dbSNicholas Bellinger 1745951146dSAndy Grover /* Directly associate cmd with se_dev */ 1755951146dSAndy Grover se_cmd->se_dev = se_lun->lun_se_dev; 1765951146dSAndy Grover se_tmr->tmr_dev = se_lun->lun_se_dev; 1775951146dSAndy Grover 1785e1be919SRoland Dreier spin_lock_irqsave(&se_tmr->tmr_dev->se_tmr_lock, flags); 1795951146dSAndy Grover list_add_tail(&se_tmr->tmr_list, &se_tmr->tmr_dev->dev_tmr_list); 1805e1be919SRoland Dreier spin_unlock_irqrestore(&se_tmr->tmr_dev->se_tmr_lock, flags); 181c66ac9dbSNicholas Bellinger 182c66ac9dbSNicholas Bellinger return 0; 183c66ac9dbSNicholas Bellinger } 1845951146dSAndy Grover EXPORT_SYMBOL(transport_lookup_tmr_lun); 185c66ac9dbSNicholas Bellinger 186c66ac9dbSNicholas Bellinger /* 187c66ac9dbSNicholas Bellinger * This function is called from core_scsi3_emulate_pro_register_and_move() 188c66ac9dbSNicholas Bellinger * and core_scsi3_decode_spec_i_port(), and will increment &deve->pr_ref_count 189c66ac9dbSNicholas Bellinger * when a matching rtpi is found. 190c66ac9dbSNicholas Bellinger */ 191c66ac9dbSNicholas Bellinger struct se_dev_entry *core_get_se_deve_from_rtpi( 192c66ac9dbSNicholas Bellinger struct se_node_acl *nacl, 193c66ac9dbSNicholas Bellinger u16 rtpi) 194c66ac9dbSNicholas Bellinger { 195c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 196c66ac9dbSNicholas Bellinger struct se_lun *lun; 197c66ac9dbSNicholas Bellinger struct se_port *port; 198c66ac9dbSNicholas Bellinger struct se_portal_group *tpg = nacl->se_tpg; 199c66ac9dbSNicholas Bellinger u32 i; 200c66ac9dbSNicholas Bellinger 201c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 202c66ac9dbSNicholas Bellinger for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { 203f2083241SJörn Engel deve = nacl->device_list[i]; 204c66ac9dbSNicholas Bellinger 205c66ac9dbSNicholas Bellinger if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)) 206c66ac9dbSNicholas Bellinger continue; 207c66ac9dbSNicholas Bellinger 208c66ac9dbSNicholas Bellinger lun = deve->se_lun; 2096708bb27SAndy Grover if (!lun) { 2106708bb27SAndy Grover pr_err("%s device entries device pointer is" 211c66ac9dbSNicholas Bellinger " NULL, but Initiator has access.\n", 212e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 213c66ac9dbSNicholas Bellinger continue; 214c66ac9dbSNicholas Bellinger } 215c66ac9dbSNicholas Bellinger port = lun->lun_sep; 2166708bb27SAndy Grover if (!port) { 2176708bb27SAndy Grover pr_err("%s device entries device pointer is" 218c66ac9dbSNicholas Bellinger " NULL, but Initiator has access.\n", 219e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 220c66ac9dbSNicholas Bellinger continue; 221c66ac9dbSNicholas Bellinger } 222c66ac9dbSNicholas Bellinger if (port->sep_rtpi != rtpi) 223c66ac9dbSNicholas Bellinger continue; 224c66ac9dbSNicholas Bellinger 225c66ac9dbSNicholas Bellinger atomic_inc(&deve->pr_ref_count); 226c66ac9dbSNicholas Bellinger smp_mb__after_atomic_inc(); 227c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 228c66ac9dbSNicholas Bellinger 229c66ac9dbSNicholas Bellinger return deve; 230c66ac9dbSNicholas Bellinger } 231c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 232c66ac9dbSNicholas Bellinger 233c66ac9dbSNicholas Bellinger return NULL; 234c66ac9dbSNicholas Bellinger } 235c66ac9dbSNicholas Bellinger 236c66ac9dbSNicholas Bellinger int core_free_device_list_for_node( 237c66ac9dbSNicholas Bellinger struct se_node_acl *nacl, 238c66ac9dbSNicholas Bellinger struct se_portal_group *tpg) 239c66ac9dbSNicholas Bellinger { 240c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 241c66ac9dbSNicholas Bellinger struct se_lun *lun; 242c66ac9dbSNicholas Bellinger u32 i; 243c66ac9dbSNicholas Bellinger 244c66ac9dbSNicholas Bellinger if (!nacl->device_list) 245c66ac9dbSNicholas Bellinger return 0; 246c66ac9dbSNicholas Bellinger 247c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 248c66ac9dbSNicholas Bellinger for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { 249f2083241SJörn Engel deve = nacl->device_list[i]; 250c66ac9dbSNicholas Bellinger 251c66ac9dbSNicholas Bellinger if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)) 252c66ac9dbSNicholas Bellinger continue; 253c66ac9dbSNicholas Bellinger 254c66ac9dbSNicholas Bellinger if (!deve->se_lun) { 2556708bb27SAndy Grover pr_err("%s device entries device pointer is" 256c66ac9dbSNicholas Bellinger " NULL, but Initiator has access.\n", 257e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 258c66ac9dbSNicholas Bellinger continue; 259c66ac9dbSNicholas Bellinger } 260c66ac9dbSNicholas Bellinger lun = deve->se_lun; 261c66ac9dbSNicholas Bellinger 262c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 263e80ac6c4SAndy Grover core_disable_device_list_for_node(lun, NULL, deve->mapped_lun, 264e80ac6c4SAndy Grover TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg); 265c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 266c66ac9dbSNicholas Bellinger } 267c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 268c66ac9dbSNicholas Bellinger 269f2083241SJörn Engel array_free(nacl->device_list, TRANSPORT_MAX_LUNS_PER_TPG); 270c66ac9dbSNicholas Bellinger nacl->device_list = NULL; 271c66ac9dbSNicholas Bellinger 272c66ac9dbSNicholas Bellinger return 0; 273c66ac9dbSNicholas Bellinger } 274c66ac9dbSNicholas Bellinger 275c66ac9dbSNicholas Bellinger void core_update_device_list_access( 276c66ac9dbSNicholas Bellinger u32 mapped_lun, 277c66ac9dbSNicholas Bellinger u32 lun_access, 278c66ac9dbSNicholas Bellinger struct se_node_acl *nacl) 279c66ac9dbSNicholas Bellinger { 280c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 281c66ac9dbSNicholas Bellinger 282c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 283f2083241SJörn Engel deve = nacl->device_list[mapped_lun]; 284c66ac9dbSNicholas Bellinger if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { 285c66ac9dbSNicholas Bellinger deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; 286c66ac9dbSNicholas Bellinger deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; 287c66ac9dbSNicholas Bellinger } else { 288c66ac9dbSNicholas Bellinger deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; 289c66ac9dbSNicholas Bellinger deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; 290c66ac9dbSNicholas Bellinger } 291c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 292c66ac9dbSNicholas Bellinger } 293c66ac9dbSNicholas Bellinger 294e80ac6c4SAndy Grover /* core_enable_device_list_for_node(): 295c66ac9dbSNicholas Bellinger * 296c66ac9dbSNicholas Bellinger * 297c66ac9dbSNicholas Bellinger */ 298e80ac6c4SAndy Grover int core_enable_device_list_for_node( 299c66ac9dbSNicholas Bellinger struct se_lun *lun, 300c66ac9dbSNicholas Bellinger struct se_lun_acl *lun_acl, 301c66ac9dbSNicholas Bellinger u32 mapped_lun, 302c66ac9dbSNicholas Bellinger u32 lun_access, 303c66ac9dbSNicholas Bellinger struct se_node_acl *nacl, 304e80ac6c4SAndy Grover struct se_portal_group *tpg) 305c66ac9dbSNicholas Bellinger { 306c66ac9dbSNicholas Bellinger struct se_port *port = lun->lun_sep; 307e80ac6c4SAndy Grover struct se_dev_entry *deve; 308c66ac9dbSNicholas Bellinger 309c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 310e80ac6c4SAndy Grover 311e80ac6c4SAndy Grover deve = nacl->device_list[mapped_lun]; 312e80ac6c4SAndy Grover 313c66ac9dbSNicholas Bellinger /* 314c66ac9dbSNicholas Bellinger * Check if the call is handling demo mode -> explict LUN ACL 315c66ac9dbSNicholas Bellinger * transition. This transition must be for the same struct se_lun 316c66ac9dbSNicholas Bellinger * + mapped_lun that was setup in demo mode.. 317c66ac9dbSNicholas Bellinger */ 318c66ac9dbSNicholas Bellinger if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { 319c66ac9dbSNicholas Bellinger if (deve->se_lun_acl != NULL) { 3206708bb27SAndy Grover pr_err("struct se_dev_entry->se_lun_acl" 321c66ac9dbSNicholas Bellinger " already set for demo mode -> explict" 322c66ac9dbSNicholas Bellinger " LUN ACL transition\n"); 32385dc98d9SFubo Chen spin_unlock_irq(&nacl->device_list_lock); 324e3d6f909SAndy Grover return -EINVAL; 325c66ac9dbSNicholas Bellinger } 326c66ac9dbSNicholas Bellinger if (deve->se_lun != lun) { 3276708bb27SAndy Grover pr_err("struct se_dev_entry->se_lun does" 328c66ac9dbSNicholas Bellinger " match passed struct se_lun for demo mode" 329c66ac9dbSNicholas Bellinger " -> explict LUN ACL transition\n"); 33085dc98d9SFubo Chen spin_unlock_irq(&nacl->device_list_lock); 331e3d6f909SAndy Grover return -EINVAL; 332c66ac9dbSNicholas Bellinger } 333c66ac9dbSNicholas Bellinger deve->se_lun_acl = lun_acl; 334c66ac9dbSNicholas Bellinger 335c66ac9dbSNicholas Bellinger if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { 336c66ac9dbSNicholas Bellinger deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; 337c66ac9dbSNicholas Bellinger deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; 338c66ac9dbSNicholas Bellinger } else { 339c66ac9dbSNicholas Bellinger deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; 340c66ac9dbSNicholas Bellinger deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; 341c66ac9dbSNicholas Bellinger } 342c66ac9dbSNicholas Bellinger 343c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 344c66ac9dbSNicholas Bellinger return 0; 345c66ac9dbSNicholas Bellinger } 346e80ac6c4SAndy Grover 347e80ac6c4SAndy Grover deve->se_lun = lun; 348e80ac6c4SAndy Grover deve->se_lun_acl = lun_acl; 349e80ac6c4SAndy Grover deve->mapped_lun = mapped_lun; 350e80ac6c4SAndy Grover deve->lun_flags |= TRANSPORT_LUNFLAGS_INITIATOR_ACCESS; 351e80ac6c4SAndy Grover 352e80ac6c4SAndy Grover if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { 353e80ac6c4SAndy Grover deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; 354e80ac6c4SAndy Grover deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; 355e80ac6c4SAndy Grover } else { 356e80ac6c4SAndy Grover deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; 357e80ac6c4SAndy Grover deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; 358e80ac6c4SAndy Grover } 359e80ac6c4SAndy Grover 360c66ac9dbSNicholas Bellinger deve->creation_time = get_jiffies_64(); 361c66ac9dbSNicholas Bellinger deve->attach_count++; 362c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 363c66ac9dbSNicholas Bellinger 364c66ac9dbSNicholas Bellinger spin_lock_bh(&port->sep_alua_lock); 365c66ac9dbSNicholas Bellinger list_add_tail(&deve->alua_port_list, &port->sep_alua_list); 366c66ac9dbSNicholas Bellinger spin_unlock_bh(&port->sep_alua_lock); 367c66ac9dbSNicholas Bellinger 368c66ac9dbSNicholas Bellinger return 0; 369c66ac9dbSNicholas Bellinger } 370e80ac6c4SAndy Grover 371e80ac6c4SAndy Grover /* core_disable_device_list_for_node(): 372e80ac6c4SAndy Grover * 373e80ac6c4SAndy Grover * 374e80ac6c4SAndy Grover */ 375e80ac6c4SAndy Grover int core_disable_device_list_for_node( 376e80ac6c4SAndy Grover struct se_lun *lun, 377e80ac6c4SAndy Grover struct se_lun_acl *lun_acl, 378e80ac6c4SAndy Grover u32 mapped_lun, 379e80ac6c4SAndy Grover u32 lun_access, 380e80ac6c4SAndy Grover struct se_node_acl *nacl, 381e80ac6c4SAndy Grover struct se_portal_group *tpg) 382e80ac6c4SAndy Grover { 383e80ac6c4SAndy Grover struct se_port *port = lun->lun_sep; 38477d4c745SNicholas Bellinger struct se_dev_entry *deve = nacl->device_list[mapped_lun]; 385e80ac6c4SAndy Grover 386e80ac6c4SAndy Grover /* 387e80ac6c4SAndy Grover * If the MappedLUN entry is being disabled, the entry in 388e80ac6c4SAndy Grover * port->sep_alua_list must be removed now before clearing the 389e80ac6c4SAndy Grover * struct se_dev_entry pointers below as logic in 390e80ac6c4SAndy Grover * core_alua_do_transition_tg_pt() depends on these being present. 391e80ac6c4SAndy Grover * 392e80ac6c4SAndy Grover * deve->se_lun_acl will be NULL for demo-mode created LUNs 393e80ac6c4SAndy Grover * that have not been explicitly converted to MappedLUNs -> 394e80ac6c4SAndy Grover * struct se_lun_acl, but we remove deve->alua_port_list from 395e80ac6c4SAndy Grover * port->sep_alua_list. This also means that active UAs and 396e80ac6c4SAndy Grover * NodeACL context specific PR metadata for demo-mode 397e80ac6c4SAndy Grover * MappedLUN *deve will be released below.. 398e80ac6c4SAndy Grover */ 399e80ac6c4SAndy Grover spin_lock_bh(&port->sep_alua_lock); 400e80ac6c4SAndy Grover list_del(&deve->alua_port_list); 401e80ac6c4SAndy Grover spin_unlock_bh(&port->sep_alua_lock); 402c66ac9dbSNicholas Bellinger /* 403c66ac9dbSNicholas Bellinger * Wait for any in process SPEC_I_PT=1 or REGISTER_AND_MOVE 404c66ac9dbSNicholas Bellinger * PR operation to complete. 405c66ac9dbSNicholas Bellinger */ 406c66ac9dbSNicholas Bellinger while (atomic_read(&deve->pr_ref_count) != 0) 407c66ac9dbSNicholas Bellinger cpu_relax(); 40877d4c745SNicholas Bellinger 409c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 410c66ac9dbSNicholas Bellinger /* 411c66ac9dbSNicholas Bellinger * Disable struct se_dev_entry LUN ACL mapping 412c66ac9dbSNicholas Bellinger */ 413c66ac9dbSNicholas Bellinger core_scsi3_ua_release_all(deve); 414c66ac9dbSNicholas Bellinger deve->se_lun = NULL; 415c66ac9dbSNicholas Bellinger deve->se_lun_acl = NULL; 416c66ac9dbSNicholas Bellinger deve->lun_flags = 0; 417c66ac9dbSNicholas Bellinger deve->creation_time = 0; 418c66ac9dbSNicholas Bellinger deve->attach_count--; 419c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 420c66ac9dbSNicholas Bellinger 421c66ac9dbSNicholas Bellinger core_scsi3_free_pr_reg_from_nacl(lun->lun_se_dev, nacl); 422c66ac9dbSNicholas Bellinger return 0; 423c66ac9dbSNicholas Bellinger } 424c66ac9dbSNicholas Bellinger 425c66ac9dbSNicholas Bellinger /* core_clear_lun_from_tpg(): 426c66ac9dbSNicholas Bellinger * 427c66ac9dbSNicholas Bellinger * 428c66ac9dbSNicholas Bellinger */ 429c66ac9dbSNicholas Bellinger void core_clear_lun_from_tpg(struct se_lun *lun, struct se_portal_group *tpg) 430c66ac9dbSNicholas Bellinger { 431c66ac9dbSNicholas Bellinger struct se_node_acl *nacl; 432c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 433c66ac9dbSNicholas Bellinger u32 i; 434c66ac9dbSNicholas Bellinger 43528638887SRoland Dreier spin_lock_irq(&tpg->acl_node_lock); 436c66ac9dbSNicholas Bellinger list_for_each_entry(nacl, &tpg->acl_node_list, acl_list) { 43728638887SRoland Dreier spin_unlock_irq(&tpg->acl_node_lock); 438c66ac9dbSNicholas Bellinger 439c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 440c66ac9dbSNicholas Bellinger for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { 441f2083241SJörn Engel deve = nacl->device_list[i]; 442c66ac9dbSNicholas Bellinger if (lun != deve->se_lun) 443c66ac9dbSNicholas Bellinger continue; 444c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 445c66ac9dbSNicholas Bellinger 446e80ac6c4SAndy Grover core_disable_device_list_for_node(lun, NULL, 447c66ac9dbSNicholas Bellinger deve->mapped_lun, TRANSPORT_LUNFLAGS_NO_ACCESS, 448e80ac6c4SAndy Grover nacl, tpg); 449c66ac9dbSNicholas Bellinger 450c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 451c66ac9dbSNicholas Bellinger } 452c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 453c66ac9dbSNicholas Bellinger 45428638887SRoland Dreier spin_lock_irq(&tpg->acl_node_lock); 455c66ac9dbSNicholas Bellinger } 45628638887SRoland Dreier spin_unlock_irq(&tpg->acl_node_lock); 457c66ac9dbSNicholas Bellinger } 458c66ac9dbSNicholas Bellinger 459c66ac9dbSNicholas Bellinger static struct se_port *core_alloc_port(struct se_device *dev) 460c66ac9dbSNicholas Bellinger { 461c66ac9dbSNicholas Bellinger struct se_port *port, *port_tmp; 462c66ac9dbSNicholas Bellinger 463c66ac9dbSNicholas Bellinger port = kzalloc(sizeof(struct se_port), GFP_KERNEL); 4646708bb27SAndy Grover if (!port) { 4656708bb27SAndy Grover pr_err("Unable to allocate struct se_port\n"); 466e3d6f909SAndy Grover return ERR_PTR(-ENOMEM); 467c66ac9dbSNicholas Bellinger } 468c66ac9dbSNicholas Bellinger INIT_LIST_HEAD(&port->sep_alua_list); 469c66ac9dbSNicholas Bellinger INIT_LIST_HEAD(&port->sep_list); 470c66ac9dbSNicholas Bellinger atomic_set(&port->sep_tg_pt_secondary_offline, 0); 471c66ac9dbSNicholas Bellinger spin_lock_init(&port->sep_alua_lock); 472c66ac9dbSNicholas Bellinger mutex_init(&port->sep_tg_pt_md_mutex); 473c66ac9dbSNicholas Bellinger 474c66ac9dbSNicholas Bellinger spin_lock(&dev->se_port_lock); 475c66ac9dbSNicholas Bellinger if (dev->dev_port_count == 0x0000ffff) { 4766708bb27SAndy Grover pr_warn("Reached dev->dev_port_count ==" 477c66ac9dbSNicholas Bellinger " 0x0000ffff\n"); 478c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 479e3d6f909SAndy Grover return ERR_PTR(-ENOSPC); 480c66ac9dbSNicholas Bellinger } 481c66ac9dbSNicholas Bellinger again: 482c66ac9dbSNicholas Bellinger /* 48335d1efe8SMasanari Iida * Allocate the next RELATIVE TARGET PORT IDENTIFIER for this struct se_device 484c66ac9dbSNicholas Bellinger * Here is the table from spc4r17 section 7.7.3.8. 485c66ac9dbSNicholas Bellinger * 486c66ac9dbSNicholas Bellinger * Table 473 -- RELATIVE TARGET PORT IDENTIFIER field 487c66ac9dbSNicholas Bellinger * 488c66ac9dbSNicholas Bellinger * Code Description 489c66ac9dbSNicholas Bellinger * 0h Reserved 490c66ac9dbSNicholas Bellinger * 1h Relative port 1, historically known as port A 491c66ac9dbSNicholas Bellinger * 2h Relative port 2, historically known as port B 492c66ac9dbSNicholas Bellinger * 3h to FFFFh Relative port 3 through 65 535 493c66ac9dbSNicholas Bellinger */ 494c66ac9dbSNicholas Bellinger port->sep_rtpi = dev->dev_rpti_counter++; 4956708bb27SAndy Grover if (!port->sep_rtpi) 496c66ac9dbSNicholas Bellinger goto again; 497c66ac9dbSNicholas Bellinger 498c66ac9dbSNicholas Bellinger list_for_each_entry(port_tmp, &dev->dev_sep_list, sep_list) { 499c66ac9dbSNicholas Bellinger /* 50035d1efe8SMasanari Iida * Make sure RELATIVE TARGET PORT IDENTIFIER is unique 501c66ac9dbSNicholas Bellinger * for 16-bit wrap.. 502c66ac9dbSNicholas Bellinger */ 503c66ac9dbSNicholas Bellinger if (port->sep_rtpi == port_tmp->sep_rtpi) 504c66ac9dbSNicholas Bellinger goto again; 505c66ac9dbSNicholas Bellinger } 506c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 507c66ac9dbSNicholas Bellinger 508c66ac9dbSNicholas Bellinger return port; 509c66ac9dbSNicholas Bellinger } 510c66ac9dbSNicholas Bellinger 511c66ac9dbSNicholas Bellinger static void core_export_port( 512c66ac9dbSNicholas Bellinger struct se_device *dev, 513c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 514c66ac9dbSNicholas Bellinger struct se_port *port, 515c66ac9dbSNicholas Bellinger struct se_lun *lun) 516c66ac9dbSNicholas Bellinger { 517c66ac9dbSNicholas Bellinger struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem = NULL; 518c66ac9dbSNicholas Bellinger 519c66ac9dbSNicholas Bellinger spin_lock(&dev->se_port_lock); 520c66ac9dbSNicholas Bellinger spin_lock(&lun->lun_sep_lock); 521c66ac9dbSNicholas Bellinger port->sep_tpg = tpg; 522c66ac9dbSNicholas Bellinger port->sep_lun = lun; 523c66ac9dbSNicholas Bellinger lun->lun_sep = port; 524c66ac9dbSNicholas Bellinger spin_unlock(&lun->lun_sep_lock); 525c66ac9dbSNicholas Bellinger 526c66ac9dbSNicholas Bellinger list_add_tail(&port->sep_list, &dev->dev_sep_list); 527c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 528c66ac9dbSNicholas Bellinger 529c87fbd56SChristoph Hellwig if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV && 530c87fbd56SChristoph Hellwig !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) { 531c66ac9dbSNicholas Bellinger tg_pt_gp_mem = core_alua_allocate_tg_pt_gp_mem(port); 532c66ac9dbSNicholas Bellinger if (IS_ERR(tg_pt_gp_mem) || !tg_pt_gp_mem) { 5336708bb27SAndy Grover pr_err("Unable to allocate t10_alua_tg_pt" 534c66ac9dbSNicholas Bellinger "_gp_member_t\n"); 535c66ac9dbSNicholas Bellinger return; 536c66ac9dbSNicholas Bellinger } 537c66ac9dbSNicholas Bellinger spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 538c66ac9dbSNicholas Bellinger __core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem, 5390fd97ccfSChristoph Hellwig dev->t10_alua.default_tg_pt_gp); 540c66ac9dbSNicholas Bellinger spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 5416708bb27SAndy Grover pr_debug("%s/%s: Adding to default ALUA Target Port" 542c66ac9dbSNicholas Bellinger " Group: alua/default_tg_pt_gp\n", 543e3d6f909SAndy Grover dev->transport->name, tpg->se_tpg_tfo->get_fabric_name()); 544c66ac9dbSNicholas Bellinger } 545c66ac9dbSNicholas Bellinger 546c66ac9dbSNicholas Bellinger dev->dev_port_count++; 54735d1efe8SMasanari Iida port->sep_index = port->sep_rtpi; /* RELATIVE TARGET PORT IDENTIFIER */ 548c66ac9dbSNicholas Bellinger } 549c66ac9dbSNicholas Bellinger 550c66ac9dbSNicholas Bellinger /* 551c66ac9dbSNicholas Bellinger * Called with struct se_device->se_port_lock spinlock held. 552c66ac9dbSNicholas Bellinger */ 553c66ac9dbSNicholas Bellinger static void core_release_port(struct se_device *dev, struct se_port *port) 5545dd7ed2eSDan Carpenter __releases(&dev->se_port_lock) __acquires(&dev->se_port_lock) 555c66ac9dbSNicholas Bellinger { 556c66ac9dbSNicholas Bellinger /* 557c66ac9dbSNicholas Bellinger * Wait for any port reference for PR ALL_TG_PT=1 operation 558c66ac9dbSNicholas Bellinger * to complete in __core_scsi3_alloc_registration() 559c66ac9dbSNicholas Bellinger */ 560c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 561c66ac9dbSNicholas Bellinger if (atomic_read(&port->sep_tg_pt_ref_cnt)) 562c66ac9dbSNicholas Bellinger cpu_relax(); 563c66ac9dbSNicholas Bellinger spin_lock(&dev->se_port_lock); 564c66ac9dbSNicholas Bellinger 565c66ac9dbSNicholas Bellinger core_alua_free_tg_pt_gp_mem(port); 566c66ac9dbSNicholas Bellinger 567c66ac9dbSNicholas Bellinger list_del(&port->sep_list); 568c66ac9dbSNicholas Bellinger dev->dev_port_count--; 569c66ac9dbSNicholas Bellinger kfree(port); 570c66ac9dbSNicholas Bellinger } 571c66ac9dbSNicholas Bellinger 572c66ac9dbSNicholas Bellinger int core_dev_export( 573c66ac9dbSNicholas Bellinger struct se_device *dev, 574c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 575c66ac9dbSNicholas Bellinger struct se_lun *lun) 576c66ac9dbSNicholas Bellinger { 5770fd97ccfSChristoph Hellwig struct se_hba *hba = dev->se_hba; 578c66ac9dbSNicholas Bellinger struct se_port *port; 579c66ac9dbSNicholas Bellinger 580c66ac9dbSNicholas Bellinger port = core_alloc_port(dev); 581e3d6f909SAndy Grover if (IS_ERR(port)) 582e3d6f909SAndy Grover return PTR_ERR(port); 583c66ac9dbSNicholas Bellinger 584c66ac9dbSNicholas Bellinger lun->lun_se_dev = dev; 585c66ac9dbSNicholas Bellinger 5860fd97ccfSChristoph Hellwig spin_lock(&hba->device_lock); 5870fd97ccfSChristoph Hellwig dev->export_count++; 5880fd97ccfSChristoph Hellwig spin_unlock(&hba->device_lock); 5890fd97ccfSChristoph Hellwig 590c66ac9dbSNicholas Bellinger core_export_port(dev, tpg, port, lun); 591c66ac9dbSNicholas Bellinger return 0; 592c66ac9dbSNicholas Bellinger } 593c66ac9dbSNicholas Bellinger 594c66ac9dbSNicholas Bellinger void core_dev_unexport( 595c66ac9dbSNicholas Bellinger struct se_device *dev, 596c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 597c66ac9dbSNicholas Bellinger struct se_lun *lun) 598c66ac9dbSNicholas Bellinger { 5990fd97ccfSChristoph Hellwig struct se_hba *hba = dev->se_hba; 600c66ac9dbSNicholas Bellinger struct se_port *port = lun->lun_sep; 601c66ac9dbSNicholas Bellinger 602c66ac9dbSNicholas Bellinger spin_lock(&lun->lun_sep_lock); 603c66ac9dbSNicholas Bellinger if (lun->lun_se_dev == NULL) { 604c66ac9dbSNicholas Bellinger spin_unlock(&lun->lun_sep_lock); 605c66ac9dbSNicholas Bellinger return; 606c66ac9dbSNicholas Bellinger } 607c66ac9dbSNicholas Bellinger spin_unlock(&lun->lun_sep_lock); 608c66ac9dbSNicholas Bellinger 609c66ac9dbSNicholas Bellinger spin_lock(&dev->se_port_lock); 610c66ac9dbSNicholas Bellinger core_release_port(dev, port); 611c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 612c66ac9dbSNicholas Bellinger 6130fd97ccfSChristoph Hellwig spin_lock(&hba->device_lock); 6140fd97ccfSChristoph Hellwig dev->export_count--; 6150fd97ccfSChristoph Hellwig spin_unlock(&hba->device_lock); 6160fd97ccfSChristoph Hellwig 617c66ac9dbSNicholas Bellinger lun->lun_se_dev = NULL; 618c66ac9dbSNicholas Bellinger } 619c66ac9dbSNicholas Bellinger 6200fd97ccfSChristoph Hellwig static void se_release_vpd_for_dev(struct se_device *dev) 621c66ac9dbSNicholas Bellinger { 622c66ac9dbSNicholas Bellinger struct t10_vpd *vpd, *vpd_tmp; 623c66ac9dbSNicholas Bellinger 6240fd97ccfSChristoph Hellwig spin_lock(&dev->t10_wwn.t10_vpd_lock); 625c66ac9dbSNicholas Bellinger list_for_each_entry_safe(vpd, vpd_tmp, 6260fd97ccfSChristoph Hellwig &dev->t10_wwn.t10_vpd_list, vpd_list) { 627c66ac9dbSNicholas Bellinger list_del(&vpd->vpd_list); 628c66ac9dbSNicholas Bellinger kfree(vpd); 629c66ac9dbSNicholas Bellinger } 6300fd97ccfSChristoph Hellwig spin_unlock(&dev->t10_wwn.t10_vpd_lock); 631c66ac9dbSNicholas Bellinger } 632c66ac9dbSNicholas Bellinger 633c8045372SRoland Dreier static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) 634525a48a2SNicholas Bellinger { 6353e03989bSRoland Dreier u32 aligned_max_sectors; 6363e03989bSRoland Dreier u32 alignment; 637525a48a2SNicholas Bellinger /* 638525a48a2SNicholas Bellinger * Limit max_sectors to a PAGE_SIZE aligned value for modern 639525a48a2SNicholas Bellinger * transport_allocate_data_tasks() operation. 640525a48a2SNicholas Bellinger */ 6413e03989bSRoland Dreier alignment = max(1ul, PAGE_SIZE / block_size); 6423e03989bSRoland Dreier aligned_max_sectors = rounddown(max_sectors, alignment); 643525a48a2SNicholas Bellinger 6443e03989bSRoland Dreier if (max_sectors != aligned_max_sectors) 6453e03989bSRoland Dreier pr_info("Rounding down aligned max_sectors from %u to %u\n", 6463e03989bSRoland Dreier max_sectors, aligned_max_sectors); 6473e03989bSRoland Dreier 6483e03989bSRoland Dreier return aligned_max_sectors; 649525a48a2SNicholas Bellinger } 650525a48a2SNicholas Bellinger 651c66ac9dbSNicholas Bellinger int se_dev_set_max_unmap_lba_count( 652c66ac9dbSNicholas Bellinger struct se_device *dev, 653c66ac9dbSNicholas Bellinger u32 max_unmap_lba_count) 654c66ac9dbSNicholas Bellinger { 6550fd97ccfSChristoph Hellwig dev->dev_attrib.max_unmap_lba_count = max_unmap_lba_count; 6566708bb27SAndy Grover pr_debug("dev[%p]: Set max_unmap_lba_count: %u\n", 6570fd97ccfSChristoph Hellwig dev, dev->dev_attrib.max_unmap_lba_count); 658c66ac9dbSNicholas Bellinger return 0; 659c66ac9dbSNicholas Bellinger } 660c66ac9dbSNicholas Bellinger 661c66ac9dbSNicholas Bellinger int se_dev_set_max_unmap_block_desc_count( 662c66ac9dbSNicholas Bellinger struct se_device *dev, 663c66ac9dbSNicholas Bellinger u32 max_unmap_block_desc_count) 664c66ac9dbSNicholas Bellinger { 6650fd97ccfSChristoph Hellwig dev->dev_attrib.max_unmap_block_desc_count = 666e3d6f909SAndy Grover max_unmap_block_desc_count; 6676708bb27SAndy Grover pr_debug("dev[%p]: Set max_unmap_block_desc_count: %u\n", 6680fd97ccfSChristoph Hellwig dev, dev->dev_attrib.max_unmap_block_desc_count); 669c66ac9dbSNicholas Bellinger return 0; 670c66ac9dbSNicholas Bellinger } 671c66ac9dbSNicholas Bellinger 672c66ac9dbSNicholas Bellinger int se_dev_set_unmap_granularity( 673c66ac9dbSNicholas Bellinger struct se_device *dev, 674c66ac9dbSNicholas Bellinger u32 unmap_granularity) 675c66ac9dbSNicholas Bellinger { 6760fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity = unmap_granularity; 6776708bb27SAndy Grover pr_debug("dev[%p]: Set unmap_granularity: %u\n", 6780fd97ccfSChristoph Hellwig dev, dev->dev_attrib.unmap_granularity); 679c66ac9dbSNicholas Bellinger return 0; 680c66ac9dbSNicholas Bellinger } 681c66ac9dbSNicholas Bellinger 682c66ac9dbSNicholas Bellinger int se_dev_set_unmap_granularity_alignment( 683c66ac9dbSNicholas Bellinger struct se_device *dev, 684c66ac9dbSNicholas Bellinger u32 unmap_granularity_alignment) 685c66ac9dbSNicholas Bellinger { 6860fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity_alignment = unmap_granularity_alignment; 6876708bb27SAndy Grover pr_debug("dev[%p]: Set unmap_granularity_alignment: %u\n", 6880fd97ccfSChristoph Hellwig dev, dev->dev_attrib.unmap_granularity_alignment); 689c66ac9dbSNicholas Bellinger return 0; 690c66ac9dbSNicholas Bellinger } 691c66ac9dbSNicholas Bellinger 692773cbaf7SNicholas Bellinger int se_dev_set_max_write_same_len( 693773cbaf7SNicholas Bellinger struct se_device *dev, 694773cbaf7SNicholas Bellinger u32 max_write_same_len) 695773cbaf7SNicholas Bellinger { 696773cbaf7SNicholas Bellinger dev->dev_attrib.max_write_same_len = max_write_same_len; 697773cbaf7SNicholas Bellinger pr_debug("dev[%p]: Set max_write_same_len: %u\n", 698773cbaf7SNicholas Bellinger dev, dev->dev_attrib.max_write_same_len); 699773cbaf7SNicholas Bellinger return 0; 700773cbaf7SNicholas Bellinger } 701773cbaf7SNicholas Bellinger 702adfa9570STregaron Bayly static void dev_set_t10_wwn_model_alias(struct se_device *dev) 703adfa9570STregaron Bayly { 704adfa9570STregaron Bayly const char *configname; 705adfa9570STregaron Bayly 706adfa9570STregaron Bayly configname = config_item_name(&dev->dev_group.cg_item); 707adfa9570STregaron Bayly if (strlen(configname) >= 16) { 708adfa9570STregaron Bayly pr_warn("dev[%p]: Backstore name '%s' is too long for " 709adfa9570STregaron Bayly "INQUIRY_MODEL, truncating to 16 bytes\n", dev, 710adfa9570STregaron Bayly configname); 711adfa9570STregaron Bayly } 712adfa9570STregaron Bayly snprintf(&dev->t10_wwn.model[0], 16, "%s", configname); 713adfa9570STregaron Bayly } 714adfa9570STregaron Bayly 715adfa9570STregaron Bayly int se_dev_set_emulate_model_alias(struct se_device *dev, int flag) 716adfa9570STregaron Bayly { 717adfa9570STregaron Bayly if (dev->export_count) { 718adfa9570STregaron Bayly pr_err("dev[%p]: Unable to change model alias" 719adfa9570STregaron Bayly " while export_count is %d\n", 720adfa9570STregaron Bayly dev, dev->export_count); 721adfa9570STregaron Bayly return -EINVAL; 722adfa9570STregaron Bayly } 723adfa9570STregaron Bayly 724adfa9570STregaron Bayly if (flag != 0 && flag != 1) { 725adfa9570STregaron Bayly pr_err("Illegal value %d\n", flag); 726adfa9570STregaron Bayly return -EINVAL; 727adfa9570STregaron Bayly } 728adfa9570STregaron Bayly 729adfa9570STregaron Bayly if (flag) { 730adfa9570STregaron Bayly dev_set_t10_wwn_model_alias(dev); 731adfa9570STregaron Bayly } else { 732adfa9570STregaron Bayly strncpy(&dev->t10_wwn.model[0], 733adfa9570STregaron Bayly dev->transport->inquiry_prod, 16); 734adfa9570STregaron Bayly } 735adfa9570STregaron Bayly dev->dev_attrib.emulate_model_alias = flag; 736adfa9570STregaron Bayly 737adfa9570STregaron Bayly return 0; 738adfa9570STregaron Bayly } 739adfa9570STregaron Bayly 740c66ac9dbSNicholas Bellinger int se_dev_set_emulate_dpo(struct se_device *dev, int flag) 741c66ac9dbSNicholas Bellinger { 742f55918faSChristoph Hellwig if (flag != 0 && flag != 1) { 7436708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 744e3d6f909SAndy Grover return -EINVAL; 745c66ac9dbSNicholas Bellinger } 746f55918faSChristoph Hellwig 747c638830dSAndy Grover if (flag) { 748f55918faSChristoph Hellwig pr_err("dpo_emulated not supported\n"); 749e3d6f909SAndy Grover return -EINVAL; 750c66ac9dbSNicholas Bellinger } 751c66ac9dbSNicholas Bellinger 752c638830dSAndy Grover return 0; 753c638830dSAndy Grover } 754c638830dSAndy Grover 755c66ac9dbSNicholas Bellinger int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) 756c66ac9dbSNicholas Bellinger { 757f55918faSChristoph Hellwig if (flag != 0 && flag != 1) { 7586708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 759e3d6f909SAndy Grover return -EINVAL; 760c66ac9dbSNicholas Bellinger } 761f55918faSChristoph Hellwig 762fd30e931SNicholas Bellinger if (flag && 763fd30e931SNicholas Bellinger dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { 764fd30e931SNicholas Bellinger pr_err("emulate_fua_write not supported for pSCSI\n"); 765e3d6f909SAndy Grover return -EINVAL; 766c66ac9dbSNicholas Bellinger } 7670fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_fua_write = flag; 7686708bb27SAndy Grover pr_debug("dev[%p]: SE Device Forced Unit Access WRITEs: %d\n", 7690fd97ccfSChristoph Hellwig dev, dev->dev_attrib.emulate_fua_write); 770c66ac9dbSNicholas Bellinger return 0; 771c66ac9dbSNicholas Bellinger } 772c66ac9dbSNicholas Bellinger 773c66ac9dbSNicholas Bellinger int se_dev_set_emulate_fua_read(struct se_device *dev, int flag) 774c66ac9dbSNicholas Bellinger { 775f55918faSChristoph Hellwig if (flag != 0 && flag != 1) { 7766708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 777e3d6f909SAndy Grover return -EINVAL; 778c66ac9dbSNicholas Bellinger } 779f55918faSChristoph Hellwig 780c638830dSAndy Grover if (flag) { 781f55918faSChristoph Hellwig pr_err("ua read emulated not supported\n"); 782e3d6f909SAndy Grover return -EINVAL; 783c66ac9dbSNicholas Bellinger } 784c66ac9dbSNicholas Bellinger 785c638830dSAndy Grover return 0; 786c638830dSAndy Grover } 787c638830dSAndy Grover 788c66ac9dbSNicholas Bellinger int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) 789c66ac9dbSNicholas Bellinger { 790f55918faSChristoph Hellwig if (flag != 0 && flag != 1) { 7916708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 792e3d6f909SAndy Grover return -EINVAL; 793c66ac9dbSNicholas Bellinger } 794fd30e931SNicholas Bellinger if (flag && 795fd30e931SNicholas Bellinger dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { 796fd30e931SNicholas Bellinger pr_err("emulate_write_cache not supported for pSCSI\n"); 797e3d6f909SAndy Grover return -EINVAL; 798c66ac9dbSNicholas Bellinger } 799d0c8b259SNicholas Bellinger if (dev->transport->get_write_cache) { 800d0c8b259SNicholas Bellinger pr_warn("emulate_write_cache cannot be changed when underlying" 801d0c8b259SNicholas Bellinger " HW reports WriteCacheEnabled, ignoring request\n"); 802d0c8b259SNicholas Bellinger return 0; 803d0c8b259SNicholas Bellinger } 804d0c8b259SNicholas Bellinger 8050fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_write_cache = flag; 8066708bb27SAndy Grover pr_debug("dev[%p]: SE Device WRITE_CACHE_EMULATION flag: %d\n", 8070fd97ccfSChristoph Hellwig dev, dev->dev_attrib.emulate_write_cache); 808c66ac9dbSNicholas Bellinger return 0; 809c66ac9dbSNicholas Bellinger } 810c66ac9dbSNicholas Bellinger 811c66ac9dbSNicholas Bellinger int se_dev_set_emulate_ua_intlck_ctrl(struct se_device *dev, int flag) 812c66ac9dbSNicholas Bellinger { 813c66ac9dbSNicholas Bellinger if ((flag != 0) && (flag != 1) && (flag != 2)) { 8146708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 815e3d6f909SAndy Grover return -EINVAL; 816c66ac9dbSNicholas Bellinger } 817c66ac9dbSNicholas Bellinger 8180fd97ccfSChristoph Hellwig if (dev->export_count) { 8196708bb27SAndy Grover pr_err("dev[%p]: Unable to change SE Device" 8200fd97ccfSChristoph Hellwig " UA_INTRLCK_CTRL while export_count is %d\n", 8210fd97ccfSChristoph Hellwig dev, dev->export_count); 822e3d6f909SAndy Grover return -EINVAL; 823c66ac9dbSNicholas Bellinger } 8240fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_ua_intlck_ctrl = flag; 8256708bb27SAndy Grover pr_debug("dev[%p]: SE Device UA_INTRLCK_CTRL flag: %d\n", 8260fd97ccfSChristoph Hellwig dev, dev->dev_attrib.emulate_ua_intlck_ctrl); 827c66ac9dbSNicholas Bellinger 828c66ac9dbSNicholas Bellinger return 0; 829c66ac9dbSNicholas Bellinger } 830c66ac9dbSNicholas Bellinger 831c66ac9dbSNicholas Bellinger int se_dev_set_emulate_tas(struct se_device *dev, int flag) 832c66ac9dbSNicholas Bellinger { 833c66ac9dbSNicholas Bellinger if ((flag != 0) && (flag != 1)) { 8346708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 835e3d6f909SAndy Grover return -EINVAL; 836c66ac9dbSNicholas Bellinger } 837c66ac9dbSNicholas Bellinger 8380fd97ccfSChristoph Hellwig if (dev->export_count) { 8396708bb27SAndy Grover pr_err("dev[%p]: Unable to change SE Device TAS while" 8400fd97ccfSChristoph Hellwig " export_count is %d\n", 8410fd97ccfSChristoph Hellwig dev, dev->export_count); 842e3d6f909SAndy Grover return -EINVAL; 843c66ac9dbSNicholas Bellinger } 8440fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tas = flag; 8456708bb27SAndy Grover pr_debug("dev[%p]: SE Device TASK_ABORTED status bit: %s\n", 8460fd97ccfSChristoph Hellwig dev, (dev->dev_attrib.emulate_tas) ? "Enabled" : "Disabled"); 847c66ac9dbSNicholas Bellinger 848c66ac9dbSNicholas Bellinger return 0; 849c66ac9dbSNicholas Bellinger } 850c66ac9dbSNicholas Bellinger 851c66ac9dbSNicholas Bellinger int se_dev_set_emulate_tpu(struct se_device *dev, int flag) 852c66ac9dbSNicholas Bellinger { 853c66ac9dbSNicholas Bellinger if ((flag != 0) && (flag != 1)) { 8546708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 855e3d6f909SAndy Grover return -EINVAL; 856c66ac9dbSNicholas Bellinger } 857c66ac9dbSNicholas Bellinger /* 858c66ac9dbSNicholas Bellinger * We expect this value to be non-zero when generic Block Layer 859c66ac9dbSNicholas Bellinger * Discard supported is detected iblock_create_virtdevice(). 860c66ac9dbSNicholas Bellinger */ 8610fd97ccfSChristoph Hellwig if (flag && !dev->dev_attrib.max_unmap_block_desc_count) { 8626708bb27SAndy Grover pr_err("Generic Block Discard not supported\n"); 863c66ac9dbSNicholas Bellinger return -ENOSYS; 864c66ac9dbSNicholas Bellinger } 865c66ac9dbSNicholas Bellinger 8660fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tpu = flag; 8676708bb27SAndy Grover pr_debug("dev[%p]: SE Device Thin Provisioning UNMAP bit: %d\n", 868c66ac9dbSNicholas Bellinger dev, flag); 869c66ac9dbSNicholas Bellinger return 0; 870c66ac9dbSNicholas Bellinger } 871c66ac9dbSNicholas Bellinger 872c66ac9dbSNicholas Bellinger int se_dev_set_emulate_tpws(struct se_device *dev, int flag) 873c66ac9dbSNicholas Bellinger { 874c66ac9dbSNicholas Bellinger if ((flag != 0) && (flag != 1)) { 8756708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 876e3d6f909SAndy Grover return -EINVAL; 877c66ac9dbSNicholas Bellinger } 878c66ac9dbSNicholas Bellinger /* 879c66ac9dbSNicholas Bellinger * We expect this value to be non-zero when generic Block Layer 880c66ac9dbSNicholas Bellinger * Discard supported is detected iblock_create_virtdevice(). 881c66ac9dbSNicholas Bellinger */ 8820fd97ccfSChristoph Hellwig if (flag && !dev->dev_attrib.max_unmap_block_desc_count) { 8836708bb27SAndy Grover pr_err("Generic Block Discard not supported\n"); 884c66ac9dbSNicholas Bellinger return -ENOSYS; 885c66ac9dbSNicholas Bellinger } 886c66ac9dbSNicholas Bellinger 8870fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tpws = flag; 8886708bb27SAndy Grover pr_debug("dev[%p]: SE Device Thin Provisioning WRITE_SAME: %d\n", 889c66ac9dbSNicholas Bellinger dev, flag); 890c66ac9dbSNicholas Bellinger return 0; 891c66ac9dbSNicholas Bellinger } 892c66ac9dbSNicholas Bellinger 8930123a9ecSNicholas Bellinger int se_dev_set_emulate_caw(struct se_device *dev, int flag) 8940123a9ecSNicholas Bellinger { 8950123a9ecSNicholas Bellinger if (flag != 0 && flag != 1) { 8960123a9ecSNicholas Bellinger pr_err("Illegal value %d\n", flag); 8970123a9ecSNicholas Bellinger return -EINVAL; 8980123a9ecSNicholas Bellinger } 8990123a9ecSNicholas Bellinger dev->dev_attrib.emulate_caw = flag; 9000123a9ecSNicholas Bellinger pr_debug("dev[%p]: SE Device CompareAndWrite (AtomicTestandSet): %d\n", 9010123a9ecSNicholas Bellinger dev, flag); 9020123a9ecSNicholas Bellinger 9030123a9ecSNicholas Bellinger return 0; 9040123a9ecSNicholas Bellinger } 9050123a9ecSNicholas Bellinger 906c66ac9dbSNicholas Bellinger int se_dev_set_enforce_pr_isids(struct se_device *dev, int flag) 907c66ac9dbSNicholas Bellinger { 908c66ac9dbSNicholas Bellinger if ((flag != 0) && (flag != 1)) { 9096708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 910e3d6f909SAndy Grover return -EINVAL; 911c66ac9dbSNicholas Bellinger } 9120fd97ccfSChristoph Hellwig dev->dev_attrib.enforce_pr_isids = flag; 9136708bb27SAndy Grover pr_debug("dev[%p]: SE Device enforce_pr_isids bit: %s\n", dev, 9140fd97ccfSChristoph Hellwig (dev->dev_attrib.enforce_pr_isids) ? "Enabled" : "Disabled"); 915c66ac9dbSNicholas Bellinger return 0; 916c66ac9dbSNicholas Bellinger } 917c66ac9dbSNicholas Bellinger 918e22a7f07SRoland Dreier int se_dev_set_is_nonrot(struct se_device *dev, int flag) 919e22a7f07SRoland Dreier { 920e22a7f07SRoland Dreier if ((flag != 0) && (flag != 1)) { 921e22a7f07SRoland Dreier printk(KERN_ERR "Illegal value %d\n", flag); 922e22a7f07SRoland Dreier return -EINVAL; 923e22a7f07SRoland Dreier } 9240fd97ccfSChristoph Hellwig dev->dev_attrib.is_nonrot = flag; 9255de619a3SNicholas Bellinger pr_debug("dev[%p]: SE Device is_nonrot bit: %d\n", 926e22a7f07SRoland Dreier dev, flag); 927e22a7f07SRoland Dreier return 0; 928e22a7f07SRoland Dreier } 929e22a7f07SRoland Dreier 9305de619a3SNicholas Bellinger int se_dev_set_emulate_rest_reord(struct se_device *dev, int flag) 9315de619a3SNicholas Bellinger { 9325de619a3SNicholas Bellinger if (flag != 0) { 9335de619a3SNicholas Bellinger printk(KERN_ERR "dev[%p]: SE Device emulatation of restricted" 9345de619a3SNicholas Bellinger " reordering not implemented\n", dev); 9355de619a3SNicholas Bellinger return -ENOSYS; 9365de619a3SNicholas Bellinger } 9370fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_rest_reord = flag; 9385de619a3SNicholas Bellinger pr_debug("dev[%p]: SE Device emulate_rest_reord: %d\n", dev, flag); 9395de619a3SNicholas Bellinger return 0; 9405de619a3SNicholas Bellinger } 9415de619a3SNicholas Bellinger 942c66ac9dbSNicholas Bellinger /* 943c66ac9dbSNicholas Bellinger * Note, this can only be called on unexported SE Device Object. 944c66ac9dbSNicholas Bellinger */ 945c66ac9dbSNicholas Bellinger int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth) 946c66ac9dbSNicholas Bellinger { 9470fd97ccfSChristoph Hellwig if (dev->export_count) { 9486708bb27SAndy Grover pr_err("dev[%p]: Unable to change SE Device TCQ while" 9490fd97ccfSChristoph Hellwig " export_count is %d\n", 9500fd97ccfSChristoph Hellwig dev, dev->export_count); 951e3d6f909SAndy Grover return -EINVAL; 952c66ac9dbSNicholas Bellinger } 9536708bb27SAndy Grover if (!queue_depth) { 9546708bb27SAndy Grover pr_err("dev[%p]: Illegal ZERO value for queue" 955c66ac9dbSNicholas Bellinger "_depth\n", dev); 956e3d6f909SAndy Grover return -EINVAL; 957c66ac9dbSNicholas Bellinger } 958c66ac9dbSNicholas Bellinger 959e3d6f909SAndy Grover if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { 9600fd97ccfSChristoph Hellwig if (queue_depth > dev->dev_attrib.hw_queue_depth) { 9616708bb27SAndy Grover pr_err("dev[%p]: Passed queue_depth: %u" 962c66ac9dbSNicholas Bellinger " exceeds TCM/SE_Device TCQ: %u\n", 963c66ac9dbSNicholas Bellinger dev, queue_depth, 9640fd97ccfSChristoph Hellwig dev->dev_attrib.hw_queue_depth); 965e3d6f909SAndy Grover return -EINVAL; 966c66ac9dbSNicholas Bellinger } 967c66ac9dbSNicholas Bellinger } else { 9680fd97ccfSChristoph Hellwig if (queue_depth > dev->dev_attrib.queue_depth) { 9690fd97ccfSChristoph Hellwig if (queue_depth > dev->dev_attrib.hw_queue_depth) { 9706708bb27SAndy Grover pr_err("dev[%p]: Passed queue_depth:" 971c66ac9dbSNicholas Bellinger " %u exceeds TCM/SE_Device MAX" 972c66ac9dbSNicholas Bellinger " TCQ: %u\n", dev, queue_depth, 9730fd97ccfSChristoph Hellwig dev->dev_attrib.hw_queue_depth); 974e3d6f909SAndy Grover return -EINVAL; 975c66ac9dbSNicholas Bellinger } 976c66ac9dbSNicholas Bellinger } 977c66ac9dbSNicholas Bellinger } 978c66ac9dbSNicholas Bellinger 9790fd97ccfSChristoph Hellwig dev->dev_attrib.queue_depth = dev->queue_depth = queue_depth; 9806708bb27SAndy Grover pr_debug("dev[%p]: SE Device TCQ Depth changed to: %u\n", 981c66ac9dbSNicholas Bellinger dev, queue_depth); 982c66ac9dbSNicholas Bellinger return 0; 983c66ac9dbSNicholas Bellinger } 984c66ac9dbSNicholas Bellinger 985015487b8SRoland Dreier int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors) 986015487b8SRoland Dreier { 9877a3cf6caSNicholas Bellinger int block_size = dev->dev_attrib.block_size; 9887a3cf6caSNicholas Bellinger 9890fd97ccfSChristoph Hellwig if (dev->export_count) { 990015487b8SRoland Dreier pr_err("dev[%p]: Unable to change SE Device" 9910fd97ccfSChristoph Hellwig " fabric_max_sectors while export_count is %d\n", 9920fd97ccfSChristoph Hellwig dev, dev->export_count); 993015487b8SRoland Dreier return -EINVAL; 994015487b8SRoland Dreier } 995015487b8SRoland Dreier if (!fabric_max_sectors) { 996015487b8SRoland Dreier pr_err("dev[%p]: Illegal ZERO value for" 997015487b8SRoland Dreier " fabric_max_sectors\n", dev); 998015487b8SRoland Dreier return -EINVAL; 999015487b8SRoland Dreier } 1000015487b8SRoland Dreier if (fabric_max_sectors < DA_STATUS_MAX_SECTORS_MIN) { 1001015487b8SRoland Dreier pr_err("dev[%p]: Passed fabric_max_sectors: %u less than" 1002015487b8SRoland Dreier " DA_STATUS_MAX_SECTORS_MIN: %u\n", dev, fabric_max_sectors, 1003015487b8SRoland Dreier DA_STATUS_MAX_SECTORS_MIN); 1004015487b8SRoland Dreier return -EINVAL; 1005015487b8SRoland Dreier } 1006015487b8SRoland Dreier if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { 10070fd97ccfSChristoph Hellwig if (fabric_max_sectors > dev->dev_attrib.hw_max_sectors) { 1008015487b8SRoland Dreier pr_err("dev[%p]: Passed fabric_max_sectors: %u" 1009015487b8SRoland Dreier " greater than TCM/SE_Device max_sectors:" 1010015487b8SRoland Dreier " %u\n", dev, fabric_max_sectors, 10110fd97ccfSChristoph Hellwig dev->dev_attrib.hw_max_sectors); 1012015487b8SRoland Dreier return -EINVAL; 1013015487b8SRoland Dreier } 1014015487b8SRoland Dreier } else { 1015015487b8SRoland Dreier if (fabric_max_sectors > DA_STATUS_MAX_SECTORS_MAX) { 1016015487b8SRoland Dreier pr_err("dev[%p]: Passed fabric_max_sectors: %u" 1017015487b8SRoland Dreier " greater than DA_STATUS_MAX_SECTORS_MAX:" 1018015487b8SRoland Dreier " %u\n", dev, fabric_max_sectors, 1019015487b8SRoland Dreier DA_STATUS_MAX_SECTORS_MAX); 1020015487b8SRoland Dreier return -EINVAL; 1021015487b8SRoland Dreier } 1022015487b8SRoland Dreier } 1023015487b8SRoland Dreier /* 1024015487b8SRoland Dreier * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks() 1025015487b8SRoland Dreier */ 10267a3cf6caSNicholas Bellinger if (!block_size) { 10277a3cf6caSNicholas Bellinger block_size = 512; 10287a3cf6caSNicholas Bellinger pr_warn("Defaulting to 512 for zero block_size\n"); 10297a3cf6caSNicholas Bellinger } 1030015487b8SRoland Dreier fabric_max_sectors = se_dev_align_max_sectors(fabric_max_sectors, 10317a3cf6caSNicholas Bellinger block_size); 1032015487b8SRoland Dreier 10330fd97ccfSChristoph Hellwig dev->dev_attrib.fabric_max_sectors = fabric_max_sectors; 1034015487b8SRoland Dreier pr_debug("dev[%p]: SE Device max_sectors changed to %u\n", 1035015487b8SRoland Dreier dev, fabric_max_sectors); 1036015487b8SRoland Dreier return 0; 1037015487b8SRoland Dreier } 1038015487b8SRoland Dreier 1039c66ac9dbSNicholas Bellinger int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) 1040c66ac9dbSNicholas Bellinger { 10410fd97ccfSChristoph Hellwig if (dev->export_count) { 10426708bb27SAndy Grover pr_err("dev[%p]: Unable to change SE Device" 10430fd97ccfSChristoph Hellwig " optimal_sectors while export_count is %d\n", 10440fd97ccfSChristoph Hellwig dev, dev->export_count); 1045c66ac9dbSNicholas Bellinger return -EINVAL; 1046c66ac9dbSNicholas Bellinger } 1047e3d6f909SAndy Grover if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { 10486708bb27SAndy Grover pr_err("dev[%p]: Passed optimal_sectors cannot be" 1049c66ac9dbSNicholas Bellinger " changed for TCM/pSCSI\n", dev); 1050c66ac9dbSNicholas Bellinger return -EINVAL; 1051c66ac9dbSNicholas Bellinger } 10520fd97ccfSChristoph Hellwig if (optimal_sectors > dev->dev_attrib.fabric_max_sectors) { 10536708bb27SAndy Grover pr_err("dev[%p]: Passed optimal_sectors %u cannot be" 1054015487b8SRoland Dreier " greater than fabric_max_sectors: %u\n", dev, 10550fd97ccfSChristoph Hellwig optimal_sectors, dev->dev_attrib.fabric_max_sectors); 1056c66ac9dbSNicholas Bellinger return -EINVAL; 1057c66ac9dbSNicholas Bellinger } 1058c66ac9dbSNicholas Bellinger 10590fd97ccfSChristoph Hellwig dev->dev_attrib.optimal_sectors = optimal_sectors; 10606708bb27SAndy Grover pr_debug("dev[%p]: SE Device optimal_sectors changed to %u\n", 1061c66ac9dbSNicholas Bellinger dev, optimal_sectors); 1062c66ac9dbSNicholas Bellinger return 0; 1063c66ac9dbSNicholas Bellinger } 1064c66ac9dbSNicholas Bellinger 1065c66ac9dbSNicholas Bellinger int se_dev_set_block_size(struct se_device *dev, u32 block_size) 1066c66ac9dbSNicholas Bellinger { 10670fd97ccfSChristoph Hellwig if (dev->export_count) { 10686708bb27SAndy Grover pr_err("dev[%p]: Unable to change SE Device block_size" 10690fd97ccfSChristoph Hellwig " while export_count is %d\n", 10700fd97ccfSChristoph Hellwig dev, dev->export_count); 1071e3d6f909SAndy Grover return -EINVAL; 1072c66ac9dbSNicholas Bellinger } 1073c66ac9dbSNicholas Bellinger 1074c66ac9dbSNicholas Bellinger if ((block_size != 512) && 1075c66ac9dbSNicholas Bellinger (block_size != 1024) && 1076c66ac9dbSNicholas Bellinger (block_size != 2048) && 1077c66ac9dbSNicholas Bellinger (block_size != 4096)) { 10786708bb27SAndy Grover pr_err("dev[%p]: Illegal value for block_device: %u" 1079c66ac9dbSNicholas Bellinger " for SE device, must be 512, 1024, 2048 or 4096\n", 1080c66ac9dbSNicholas Bellinger dev, block_size); 1081e3d6f909SAndy Grover return -EINVAL; 1082c66ac9dbSNicholas Bellinger } 1083c66ac9dbSNicholas Bellinger 1084e3d6f909SAndy Grover if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { 10856708bb27SAndy Grover pr_err("dev[%p]: Not allowed to change block_size for" 1086c66ac9dbSNicholas Bellinger " Physical Device, use for Linux/SCSI to change" 1087c66ac9dbSNicholas Bellinger " block_size for underlying hardware\n", dev); 1088e3d6f909SAndy Grover return -EINVAL; 1089c66ac9dbSNicholas Bellinger } 1090c66ac9dbSNicholas Bellinger 10910fd97ccfSChristoph Hellwig dev->dev_attrib.block_size = block_size; 10926708bb27SAndy Grover pr_debug("dev[%p]: SE Device block_size changed to %u\n", 1093c66ac9dbSNicholas Bellinger dev, block_size); 1094c66ac9dbSNicholas Bellinger return 0; 1095c66ac9dbSNicholas Bellinger } 1096c66ac9dbSNicholas Bellinger 1097c66ac9dbSNicholas Bellinger struct se_lun *core_dev_add_lun( 1098c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1099c66ac9dbSNicholas Bellinger struct se_device *dev, 1100c66ac9dbSNicholas Bellinger u32 lun) 1101c66ac9dbSNicholas Bellinger { 1102c66ac9dbSNicholas Bellinger struct se_lun *lun_p; 11038d9efe53SSebastian Andrzej Siewior int rc; 1104c66ac9dbSNicholas Bellinger 1105c66ac9dbSNicholas Bellinger lun_p = core_tpg_pre_addlun(tpg, lun); 11068d9efe53SSebastian Andrzej Siewior if (IS_ERR(lun_p)) 11078d9efe53SSebastian Andrzej Siewior return lun_p; 1108c66ac9dbSNicholas Bellinger 110958d92618SNicholas Bellinger rc = core_tpg_post_addlun(tpg, lun_p, 111058d92618SNicholas Bellinger TRANSPORT_LUNFLAGS_READ_WRITE, dev); 11118d9efe53SSebastian Andrzej Siewior if (rc < 0) 11128d9efe53SSebastian Andrzej Siewior return ERR_PTR(rc); 1113c66ac9dbSNicholas Bellinger 11146708bb27SAndy Grover pr_debug("%s_TPG[%u]_LUN[%u] - Activated %s Logical Unit from" 1115e3d6f909SAndy Grover " CORE HBA: %u\n", tpg->se_tpg_tfo->get_fabric_name(), 1116e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), lun_p->unpacked_lun, 11172dca673bSAndy Grover tpg->se_tpg_tfo->get_fabric_name(), dev->se_hba->hba_id); 1118c66ac9dbSNicholas Bellinger /* 1119c66ac9dbSNicholas Bellinger * Update LUN maps for dynamically added initiators when 1120c66ac9dbSNicholas Bellinger * generate_node_acl is enabled. 1121c66ac9dbSNicholas Bellinger */ 1122e3d6f909SAndy Grover if (tpg->se_tpg_tfo->tpg_check_demo_mode(tpg)) { 1123c66ac9dbSNicholas Bellinger struct se_node_acl *acl; 112428638887SRoland Dreier spin_lock_irq(&tpg->acl_node_lock); 1125c66ac9dbSNicholas Bellinger list_for_each_entry(acl, &tpg->acl_node_list, acl_list) { 1126052605c6SNicholas Bellinger if (acl->dynamic_node_acl && 1127052605c6SNicholas Bellinger (!tpg->se_tpg_tfo->tpg_check_demo_mode_login_only || 1128052605c6SNicholas Bellinger !tpg->se_tpg_tfo->tpg_check_demo_mode_login_only(tpg))) { 112928638887SRoland Dreier spin_unlock_irq(&tpg->acl_node_lock); 1130c66ac9dbSNicholas Bellinger core_tpg_add_node_to_devs(acl, tpg); 113128638887SRoland Dreier spin_lock_irq(&tpg->acl_node_lock); 1132c66ac9dbSNicholas Bellinger } 1133c66ac9dbSNicholas Bellinger } 113428638887SRoland Dreier spin_unlock_irq(&tpg->acl_node_lock); 1135c66ac9dbSNicholas Bellinger } 1136c66ac9dbSNicholas Bellinger 1137c66ac9dbSNicholas Bellinger return lun_p; 1138c66ac9dbSNicholas Bellinger } 1139c66ac9dbSNicholas Bellinger 1140c66ac9dbSNicholas Bellinger /* core_dev_del_lun(): 1141c66ac9dbSNicholas Bellinger * 1142c66ac9dbSNicholas Bellinger * 1143c66ac9dbSNicholas Bellinger */ 1144c66ac9dbSNicholas Bellinger int core_dev_del_lun( 1145c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1146c66ac9dbSNicholas Bellinger u32 unpacked_lun) 1147c66ac9dbSNicholas Bellinger { 1148c66ac9dbSNicholas Bellinger struct se_lun *lun; 1149c66ac9dbSNicholas Bellinger 11508d9efe53SSebastian Andrzej Siewior lun = core_tpg_pre_dellun(tpg, unpacked_lun); 11518d9efe53SSebastian Andrzej Siewior if (IS_ERR(lun)) 11528d9efe53SSebastian Andrzej Siewior return PTR_ERR(lun); 1153c66ac9dbSNicholas Bellinger 1154c66ac9dbSNicholas Bellinger core_tpg_post_dellun(tpg, lun); 1155c66ac9dbSNicholas Bellinger 11566708bb27SAndy Grover pr_debug("%s_TPG[%u]_LUN[%u] - Deactivated %s Logical Unit from" 1157e3d6f909SAndy Grover " device object\n", tpg->se_tpg_tfo->get_fabric_name(), 1158e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), unpacked_lun, 1159e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 1160c66ac9dbSNicholas Bellinger 1161c66ac9dbSNicholas Bellinger return 0; 1162c66ac9dbSNicholas Bellinger } 1163c66ac9dbSNicholas Bellinger 1164c66ac9dbSNicholas Bellinger struct se_lun *core_get_lun_from_tpg(struct se_portal_group *tpg, u32 unpacked_lun) 1165c66ac9dbSNicholas Bellinger { 1166c66ac9dbSNicholas Bellinger struct se_lun *lun; 1167c66ac9dbSNicholas Bellinger 1168c66ac9dbSNicholas Bellinger spin_lock(&tpg->tpg_lun_lock); 1169c66ac9dbSNicholas Bellinger if (unpacked_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) { 11706708bb27SAndy Grover pr_err("%s LUN: %u exceeds TRANSPORT_MAX_LUNS" 1171c66ac9dbSNicholas Bellinger "_PER_TPG-1: %u for Target Portal Group: %hu\n", 1172e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, 1173c66ac9dbSNicholas Bellinger TRANSPORT_MAX_LUNS_PER_TPG-1, 1174e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg)); 1175c66ac9dbSNicholas Bellinger spin_unlock(&tpg->tpg_lun_lock); 1176c66ac9dbSNicholas Bellinger return NULL; 1177c66ac9dbSNicholas Bellinger } 11784a5a75f3SJörn Engel lun = tpg->tpg_lun_list[unpacked_lun]; 1179c66ac9dbSNicholas Bellinger 1180c66ac9dbSNicholas Bellinger if (lun->lun_status != TRANSPORT_LUN_STATUS_FREE) { 11816708bb27SAndy Grover pr_err("%s Logical Unit Number: %u is not free on" 1182c66ac9dbSNicholas Bellinger " Target Portal Group: %hu, ignoring request.\n", 1183e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, 1184e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg)); 1185c66ac9dbSNicholas Bellinger spin_unlock(&tpg->tpg_lun_lock); 1186c66ac9dbSNicholas Bellinger return NULL; 1187c66ac9dbSNicholas Bellinger } 1188c66ac9dbSNicholas Bellinger spin_unlock(&tpg->tpg_lun_lock); 1189c66ac9dbSNicholas Bellinger 1190c66ac9dbSNicholas Bellinger return lun; 1191c66ac9dbSNicholas Bellinger } 1192c66ac9dbSNicholas Bellinger 1193c66ac9dbSNicholas Bellinger /* core_dev_get_lun(): 1194c66ac9dbSNicholas Bellinger * 1195c66ac9dbSNicholas Bellinger * 1196c66ac9dbSNicholas Bellinger */ 1197c66ac9dbSNicholas Bellinger static struct se_lun *core_dev_get_lun(struct se_portal_group *tpg, u32 unpacked_lun) 1198c66ac9dbSNicholas Bellinger { 1199c66ac9dbSNicholas Bellinger struct se_lun *lun; 1200c66ac9dbSNicholas Bellinger 1201c66ac9dbSNicholas Bellinger spin_lock(&tpg->tpg_lun_lock); 1202c66ac9dbSNicholas Bellinger if (unpacked_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) { 12036708bb27SAndy Grover pr_err("%s LUN: %u exceeds TRANSPORT_MAX_LUNS_PER" 1204c66ac9dbSNicholas Bellinger "_TPG-1: %u for Target Portal Group: %hu\n", 1205e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, 1206c66ac9dbSNicholas Bellinger TRANSPORT_MAX_LUNS_PER_TPG-1, 1207e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg)); 1208c66ac9dbSNicholas Bellinger spin_unlock(&tpg->tpg_lun_lock); 1209c66ac9dbSNicholas Bellinger return NULL; 1210c66ac9dbSNicholas Bellinger } 12114a5a75f3SJörn Engel lun = tpg->tpg_lun_list[unpacked_lun]; 1212c66ac9dbSNicholas Bellinger 1213c66ac9dbSNicholas Bellinger if (lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE) { 12146708bb27SAndy Grover pr_err("%s Logical Unit Number: %u is not active on" 1215c66ac9dbSNicholas Bellinger " Target Portal Group: %hu, ignoring request.\n", 1216e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, 1217e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg)); 1218c66ac9dbSNicholas Bellinger spin_unlock(&tpg->tpg_lun_lock); 1219c66ac9dbSNicholas Bellinger return NULL; 1220c66ac9dbSNicholas Bellinger } 1221c66ac9dbSNicholas Bellinger spin_unlock(&tpg->tpg_lun_lock); 1222c66ac9dbSNicholas Bellinger 1223c66ac9dbSNicholas Bellinger return lun; 1224c66ac9dbSNicholas Bellinger } 1225c66ac9dbSNicholas Bellinger 1226c66ac9dbSNicholas Bellinger struct se_lun_acl *core_dev_init_initiator_node_lun_acl( 1227c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1228fcf29481SNicholas Bellinger struct se_node_acl *nacl, 1229c66ac9dbSNicholas Bellinger u32 mapped_lun, 1230c66ac9dbSNicholas Bellinger int *ret) 1231c66ac9dbSNicholas Bellinger { 1232c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl; 1233c66ac9dbSNicholas Bellinger 1234fcf29481SNicholas Bellinger if (strlen(nacl->initiatorname) >= TRANSPORT_IQN_LEN) { 12356708bb27SAndy Grover pr_err("%s InitiatorName exceeds maximum size.\n", 1236e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 1237c66ac9dbSNicholas Bellinger *ret = -EOVERFLOW; 1238c66ac9dbSNicholas Bellinger return NULL; 1239c66ac9dbSNicholas Bellinger } 1240c66ac9dbSNicholas Bellinger lacl = kzalloc(sizeof(struct se_lun_acl), GFP_KERNEL); 12416708bb27SAndy Grover if (!lacl) { 12426708bb27SAndy Grover pr_err("Unable to allocate memory for struct se_lun_acl.\n"); 1243c66ac9dbSNicholas Bellinger *ret = -ENOMEM; 1244c66ac9dbSNicholas Bellinger return NULL; 1245c66ac9dbSNicholas Bellinger } 1246c66ac9dbSNicholas Bellinger 1247c66ac9dbSNicholas Bellinger INIT_LIST_HEAD(&lacl->lacl_list); 1248c66ac9dbSNicholas Bellinger lacl->mapped_lun = mapped_lun; 1249c66ac9dbSNicholas Bellinger lacl->se_lun_nacl = nacl; 1250fcf29481SNicholas Bellinger snprintf(lacl->initiatorname, TRANSPORT_IQN_LEN, "%s", 1251fcf29481SNicholas Bellinger nacl->initiatorname); 1252c66ac9dbSNicholas Bellinger 1253c66ac9dbSNicholas Bellinger return lacl; 1254c66ac9dbSNicholas Bellinger } 1255c66ac9dbSNicholas Bellinger 1256c66ac9dbSNicholas Bellinger int core_dev_add_initiator_node_lun_acl( 1257c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1258c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl, 1259c66ac9dbSNicholas Bellinger u32 unpacked_lun, 1260c66ac9dbSNicholas Bellinger u32 lun_access) 1261c66ac9dbSNicholas Bellinger { 1262c66ac9dbSNicholas Bellinger struct se_lun *lun; 1263c66ac9dbSNicholas Bellinger struct se_node_acl *nacl; 1264c66ac9dbSNicholas Bellinger 1265c66ac9dbSNicholas Bellinger lun = core_dev_get_lun(tpg, unpacked_lun); 12666708bb27SAndy Grover if (!lun) { 12676708bb27SAndy Grover pr_err("%s Logical Unit Number: %u is not active on" 1268c66ac9dbSNicholas Bellinger " Target Portal Group: %hu, ignoring request.\n", 1269e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, 1270e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg)); 1271c66ac9dbSNicholas Bellinger return -EINVAL; 1272c66ac9dbSNicholas Bellinger } 1273c66ac9dbSNicholas Bellinger 1274c66ac9dbSNicholas Bellinger nacl = lacl->se_lun_nacl; 12756708bb27SAndy Grover if (!nacl) 1276c66ac9dbSNicholas Bellinger return -EINVAL; 1277c66ac9dbSNicholas Bellinger 1278c66ac9dbSNicholas Bellinger if ((lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) && 1279c66ac9dbSNicholas Bellinger (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE)) 1280c66ac9dbSNicholas Bellinger lun_access = TRANSPORT_LUNFLAGS_READ_ONLY; 1281c66ac9dbSNicholas Bellinger 1282c66ac9dbSNicholas Bellinger lacl->se_lun = lun; 1283c66ac9dbSNicholas Bellinger 1284e80ac6c4SAndy Grover if (core_enable_device_list_for_node(lun, lacl, lacl->mapped_lun, 1285e80ac6c4SAndy Grover lun_access, nacl, tpg) < 0) 1286c66ac9dbSNicholas Bellinger return -EINVAL; 1287c66ac9dbSNicholas Bellinger 1288c66ac9dbSNicholas Bellinger spin_lock(&lun->lun_acl_lock); 1289c66ac9dbSNicholas Bellinger list_add_tail(&lacl->lacl_list, &lun->lun_acl_list); 1290c66ac9dbSNicholas Bellinger atomic_inc(&lun->lun_acl_count); 1291c66ac9dbSNicholas Bellinger smp_mb__after_atomic_inc(); 1292c66ac9dbSNicholas Bellinger spin_unlock(&lun->lun_acl_lock); 1293c66ac9dbSNicholas Bellinger 12946708bb27SAndy Grover pr_debug("%s_TPG[%hu]_LUN[%u->%u] - Added %s ACL for " 1295e3d6f909SAndy Grover " InitiatorNode: %s\n", tpg->se_tpg_tfo->get_fabric_name(), 1296e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), unpacked_lun, lacl->mapped_lun, 1297c66ac9dbSNicholas Bellinger (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) ? "RW" : "RO", 1298c66ac9dbSNicholas Bellinger lacl->initiatorname); 1299c66ac9dbSNicholas Bellinger /* 1300c66ac9dbSNicholas Bellinger * Check to see if there are any existing persistent reservation APTPL 1301c66ac9dbSNicholas Bellinger * pre-registrations that need to be enabled for this LUN ACL.. 1302c66ac9dbSNicholas Bellinger */ 1303c66ac9dbSNicholas Bellinger core_scsi3_check_aptpl_registration(lun->lun_se_dev, tpg, lun, lacl); 1304c66ac9dbSNicholas Bellinger return 0; 1305c66ac9dbSNicholas Bellinger } 1306c66ac9dbSNicholas Bellinger 1307c66ac9dbSNicholas Bellinger /* core_dev_del_initiator_node_lun_acl(): 1308c66ac9dbSNicholas Bellinger * 1309c66ac9dbSNicholas Bellinger * 1310c66ac9dbSNicholas Bellinger */ 1311c66ac9dbSNicholas Bellinger int core_dev_del_initiator_node_lun_acl( 1312c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1313c66ac9dbSNicholas Bellinger struct se_lun *lun, 1314c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl) 1315c66ac9dbSNicholas Bellinger { 1316c66ac9dbSNicholas Bellinger struct se_node_acl *nacl; 1317c66ac9dbSNicholas Bellinger 1318c66ac9dbSNicholas Bellinger nacl = lacl->se_lun_nacl; 13196708bb27SAndy Grover if (!nacl) 1320c66ac9dbSNicholas Bellinger return -EINVAL; 1321c66ac9dbSNicholas Bellinger 1322c66ac9dbSNicholas Bellinger spin_lock(&lun->lun_acl_lock); 1323c66ac9dbSNicholas Bellinger list_del(&lacl->lacl_list); 1324c66ac9dbSNicholas Bellinger atomic_dec(&lun->lun_acl_count); 1325c66ac9dbSNicholas Bellinger smp_mb__after_atomic_dec(); 1326c66ac9dbSNicholas Bellinger spin_unlock(&lun->lun_acl_lock); 1327c66ac9dbSNicholas Bellinger 1328e80ac6c4SAndy Grover core_disable_device_list_for_node(lun, NULL, lacl->mapped_lun, 1329e80ac6c4SAndy Grover TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg); 1330c66ac9dbSNicholas Bellinger 1331c66ac9dbSNicholas Bellinger lacl->se_lun = NULL; 1332c66ac9dbSNicholas Bellinger 13336708bb27SAndy Grover pr_debug("%s_TPG[%hu]_LUN[%u] - Removed ACL for" 1334c66ac9dbSNicholas Bellinger " InitiatorNode: %s Mapped LUN: %u\n", 1335e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), 1336e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, 1337c66ac9dbSNicholas Bellinger lacl->initiatorname, lacl->mapped_lun); 1338c66ac9dbSNicholas Bellinger 1339c66ac9dbSNicholas Bellinger return 0; 1340c66ac9dbSNicholas Bellinger } 1341c66ac9dbSNicholas Bellinger 1342c66ac9dbSNicholas Bellinger void core_dev_free_initiator_node_lun_acl( 1343c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1344c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl) 1345c66ac9dbSNicholas Bellinger { 13466708bb27SAndy Grover pr_debug("%s_TPG[%hu] - Freeing ACL for %s InitiatorNode: %s" 1347e3d6f909SAndy Grover " Mapped LUN: %u\n", tpg->se_tpg_tfo->get_fabric_name(), 1348e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), 1349e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), 1350c66ac9dbSNicholas Bellinger lacl->initiatorname, lacl->mapped_lun); 1351c66ac9dbSNicholas Bellinger 1352c66ac9dbSNicholas Bellinger kfree(lacl); 1353c66ac9dbSNicholas Bellinger } 1354c66ac9dbSNicholas Bellinger 13550fd97ccfSChristoph Hellwig static void scsi_dump_inquiry(struct se_device *dev) 13560fd97ccfSChristoph Hellwig { 13570fd97ccfSChristoph Hellwig struct t10_wwn *wwn = &dev->t10_wwn; 13580fd97ccfSChristoph Hellwig char buf[17]; 13590fd97ccfSChristoph Hellwig int i, device_type; 13600fd97ccfSChristoph Hellwig /* 13610fd97ccfSChristoph Hellwig * Print Linux/SCSI style INQUIRY formatting to the kernel ring buffer 13620fd97ccfSChristoph Hellwig */ 13630fd97ccfSChristoph Hellwig for (i = 0; i < 8; i++) 13640fd97ccfSChristoph Hellwig if (wwn->vendor[i] >= 0x20) 13650fd97ccfSChristoph Hellwig buf[i] = wwn->vendor[i]; 13660fd97ccfSChristoph Hellwig else 13670fd97ccfSChristoph Hellwig buf[i] = ' '; 13680fd97ccfSChristoph Hellwig buf[i] = '\0'; 13690fd97ccfSChristoph Hellwig pr_debug(" Vendor: %s\n", buf); 13700fd97ccfSChristoph Hellwig 13710fd97ccfSChristoph Hellwig for (i = 0; i < 16; i++) 13720fd97ccfSChristoph Hellwig if (wwn->model[i] >= 0x20) 13730fd97ccfSChristoph Hellwig buf[i] = wwn->model[i]; 13740fd97ccfSChristoph Hellwig else 13750fd97ccfSChristoph Hellwig buf[i] = ' '; 13760fd97ccfSChristoph Hellwig buf[i] = '\0'; 13770fd97ccfSChristoph Hellwig pr_debug(" Model: %s\n", buf); 13780fd97ccfSChristoph Hellwig 13790fd97ccfSChristoph Hellwig for (i = 0; i < 4; i++) 13800fd97ccfSChristoph Hellwig if (wwn->revision[i] >= 0x20) 13810fd97ccfSChristoph Hellwig buf[i] = wwn->revision[i]; 13820fd97ccfSChristoph Hellwig else 13830fd97ccfSChristoph Hellwig buf[i] = ' '; 13840fd97ccfSChristoph Hellwig buf[i] = '\0'; 13850fd97ccfSChristoph Hellwig pr_debug(" Revision: %s\n", buf); 13860fd97ccfSChristoph Hellwig 13870fd97ccfSChristoph Hellwig device_type = dev->transport->get_device_type(dev); 13880fd97ccfSChristoph Hellwig pr_debug(" Type: %s ", scsi_device_type(device_type)); 13890fd97ccfSChristoph Hellwig } 13900fd97ccfSChristoph Hellwig 13910fd97ccfSChristoph Hellwig struct se_device *target_alloc_device(struct se_hba *hba, const char *name) 13920fd97ccfSChristoph Hellwig { 13930fd97ccfSChristoph Hellwig struct se_device *dev; 13940fd97ccfSChristoph Hellwig 13950fd97ccfSChristoph Hellwig dev = hba->transport->alloc_device(hba, name); 13960fd97ccfSChristoph Hellwig if (!dev) 13970fd97ccfSChristoph Hellwig return NULL; 13980fd97ccfSChristoph Hellwig 13990ff87549SNicholas Bellinger dev->dev_link_magic = SE_DEV_LINK_MAGIC; 14000fd97ccfSChristoph Hellwig dev->se_hba = hba; 14010fd97ccfSChristoph Hellwig dev->transport = hba->transport; 14020fd97ccfSChristoph Hellwig 14030fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->dev_list); 14040fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->dev_sep_list); 14050fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->dev_tmr_list); 14060fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->delayed_cmd_list); 14070fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->state_list); 14080fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->qf_cmd_list); 14090fd97ccfSChristoph Hellwig spin_lock_init(&dev->stats_lock); 14100fd97ccfSChristoph Hellwig spin_lock_init(&dev->execute_task_lock); 14110fd97ccfSChristoph Hellwig spin_lock_init(&dev->delayed_cmd_lock); 14120fd97ccfSChristoph Hellwig spin_lock_init(&dev->dev_reservation_lock); 14130fd97ccfSChristoph Hellwig spin_lock_init(&dev->se_port_lock); 14140fd97ccfSChristoph Hellwig spin_lock_init(&dev->se_tmr_lock); 14150fd97ccfSChristoph Hellwig spin_lock_init(&dev->qf_cmd_lock); 14160fd97ccfSChristoph Hellwig atomic_set(&dev->dev_ordered_id, 0); 14170fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_wwn.t10_vpd_list); 14180fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_wwn.t10_vpd_lock); 14190fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_pr.registration_list); 14200fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_pr.aptpl_reg_list); 14210fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_pr.registration_lock); 14220fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_pr.aptpl_reg_lock); 14230fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_alua.tg_pt_gps_list); 14240fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_alua.tg_pt_gps_lock); 14250fd97ccfSChristoph Hellwig 14260fd97ccfSChristoph Hellwig dev->t10_wwn.t10_dev = dev; 14270fd97ccfSChristoph Hellwig dev->t10_alua.t10_dev = dev; 14280fd97ccfSChristoph Hellwig 14290fd97ccfSChristoph Hellwig dev->dev_attrib.da_dev = dev; 1430adfa9570STregaron Bayly dev->dev_attrib.emulate_model_alias = DA_EMULATE_MODEL_ALIAS; 14310fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_dpo = DA_EMULATE_DPO; 14320fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_fua_write = DA_EMULATE_FUA_WRITE; 14330fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_fua_read = DA_EMULATE_FUA_READ; 14340fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_write_cache = DA_EMULATE_WRITE_CACHE; 14350fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_ua_intlck_ctrl = DA_EMULATE_UA_INTLLCK_CTRL; 14360fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tas = DA_EMULATE_TAS; 14370fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tpu = DA_EMULATE_TPU; 14380fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tpws = DA_EMULATE_TPWS; 14390123a9ecSNicholas Bellinger dev->dev_attrib.emulate_caw = DA_EMULATE_CAW; 14400fd97ccfSChristoph Hellwig dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS; 14410fd97ccfSChristoph Hellwig dev->dev_attrib.is_nonrot = DA_IS_NONROT; 14420fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD; 14430fd97ccfSChristoph Hellwig dev->dev_attrib.max_unmap_lba_count = DA_MAX_UNMAP_LBA_COUNT; 14440fd97ccfSChristoph Hellwig dev->dev_attrib.max_unmap_block_desc_count = 14450fd97ccfSChristoph Hellwig DA_MAX_UNMAP_BLOCK_DESC_COUNT; 14460fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity = DA_UNMAP_GRANULARITY_DEFAULT; 14470fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity_alignment = 14480fd97ccfSChristoph Hellwig DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT; 1449773cbaf7SNicholas Bellinger dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN; 14500fd97ccfSChristoph Hellwig dev->dev_attrib.fabric_max_sectors = DA_FABRIC_MAX_SECTORS; 14510fd97ccfSChristoph Hellwig dev->dev_attrib.optimal_sectors = DA_FABRIC_MAX_SECTORS; 14520fd97ccfSChristoph Hellwig 14530fd97ccfSChristoph Hellwig return dev; 14540fd97ccfSChristoph Hellwig } 14550fd97ccfSChristoph Hellwig 14560fd97ccfSChristoph Hellwig int target_configure_device(struct se_device *dev) 14570fd97ccfSChristoph Hellwig { 14580fd97ccfSChristoph Hellwig struct se_hba *hba = dev->se_hba; 14590fd97ccfSChristoph Hellwig int ret; 14600fd97ccfSChristoph Hellwig 14610fd97ccfSChristoph Hellwig if (dev->dev_flags & DF_CONFIGURED) { 14620fd97ccfSChristoph Hellwig pr_err("se_dev->se_dev_ptr already set for storage" 14630fd97ccfSChristoph Hellwig " object\n"); 14640fd97ccfSChristoph Hellwig return -EEXIST; 14650fd97ccfSChristoph Hellwig } 14660fd97ccfSChristoph Hellwig 14670fd97ccfSChristoph Hellwig ret = dev->transport->configure_device(dev); 14680fd97ccfSChristoph Hellwig if (ret) 14690fd97ccfSChristoph Hellwig goto out; 14700fd97ccfSChristoph Hellwig dev->dev_flags |= DF_CONFIGURED; 14710fd97ccfSChristoph Hellwig 14720fd97ccfSChristoph Hellwig /* 14730fd97ccfSChristoph Hellwig * XXX: there is not much point to have two different values here.. 14740fd97ccfSChristoph Hellwig */ 14750fd97ccfSChristoph Hellwig dev->dev_attrib.block_size = dev->dev_attrib.hw_block_size; 14760fd97ccfSChristoph Hellwig dev->dev_attrib.queue_depth = dev->dev_attrib.hw_queue_depth; 14770fd97ccfSChristoph Hellwig 14780fd97ccfSChristoph Hellwig /* 14790fd97ccfSChristoph Hellwig * Align max_hw_sectors down to PAGE_SIZE I/O transfers 14800fd97ccfSChristoph Hellwig */ 14810fd97ccfSChristoph Hellwig dev->dev_attrib.hw_max_sectors = 14820fd97ccfSChristoph Hellwig se_dev_align_max_sectors(dev->dev_attrib.hw_max_sectors, 14830fd97ccfSChristoph Hellwig dev->dev_attrib.hw_block_size); 14840fd97ccfSChristoph Hellwig 14850fd97ccfSChristoph Hellwig dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX); 14860fd97ccfSChristoph Hellwig dev->creation_time = get_jiffies_64(); 14870fd97ccfSChristoph Hellwig 14880fd97ccfSChristoph Hellwig ret = core_setup_alua(dev); 14890fd97ccfSChristoph Hellwig if (ret) 14900fd97ccfSChristoph Hellwig goto out; 14910fd97ccfSChristoph Hellwig 14920fd97ccfSChristoph Hellwig /* 14930fd97ccfSChristoph Hellwig * Startup the struct se_device processing thread 14940fd97ccfSChristoph Hellwig */ 14950fd97ccfSChristoph Hellwig dev->tmr_wq = alloc_workqueue("tmr-%s", WQ_MEM_RECLAIM | WQ_UNBOUND, 1, 14960fd97ccfSChristoph Hellwig dev->transport->name); 14970fd97ccfSChristoph Hellwig if (!dev->tmr_wq) { 14980fd97ccfSChristoph Hellwig pr_err("Unable to create tmr workqueue for %s\n", 14990fd97ccfSChristoph Hellwig dev->transport->name); 15000fd97ccfSChristoph Hellwig ret = -ENOMEM; 15010fd97ccfSChristoph Hellwig goto out_free_alua; 15020fd97ccfSChristoph Hellwig } 15030fd97ccfSChristoph Hellwig 15040fd97ccfSChristoph Hellwig /* 15050fd97ccfSChristoph Hellwig * Setup work_queue for QUEUE_FULL 15060fd97ccfSChristoph Hellwig */ 15070fd97ccfSChristoph Hellwig INIT_WORK(&dev->qf_work_queue, target_qf_do_work); 15080fd97ccfSChristoph Hellwig 15090fd97ccfSChristoph Hellwig /* 15100fd97ccfSChristoph Hellwig * Preload the initial INQUIRY const values if we are doing 15110fd97ccfSChristoph Hellwig * anything virtual (IBLOCK, FILEIO, RAMDISK), but not for TCM/pSCSI 15120fd97ccfSChristoph Hellwig * passthrough because this is being provided by the backend LLD. 15130fd97ccfSChristoph Hellwig */ 15140fd97ccfSChristoph Hellwig if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) { 15150fd97ccfSChristoph Hellwig strncpy(&dev->t10_wwn.vendor[0], "LIO-ORG", 8); 15160fd97ccfSChristoph Hellwig strncpy(&dev->t10_wwn.model[0], 15170fd97ccfSChristoph Hellwig dev->transport->inquiry_prod, 16); 15180fd97ccfSChristoph Hellwig strncpy(&dev->t10_wwn.revision[0], 15190fd97ccfSChristoph Hellwig dev->transport->inquiry_rev, 4); 15200fd97ccfSChristoph Hellwig } 15210fd97ccfSChristoph Hellwig 15220fd97ccfSChristoph Hellwig scsi_dump_inquiry(dev); 15230fd97ccfSChristoph Hellwig 15240fd97ccfSChristoph Hellwig spin_lock(&hba->device_lock); 15250fd97ccfSChristoph Hellwig hba->dev_count++; 15260fd97ccfSChristoph Hellwig spin_unlock(&hba->device_lock); 15270fd97ccfSChristoph Hellwig return 0; 15280fd97ccfSChristoph Hellwig 15290fd97ccfSChristoph Hellwig out_free_alua: 15300fd97ccfSChristoph Hellwig core_alua_free_lu_gp_mem(dev); 15310fd97ccfSChristoph Hellwig out: 15320fd97ccfSChristoph Hellwig se_release_vpd_for_dev(dev); 15330fd97ccfSChristoph Hellwig return ret; 15340fd97ccfSChristoph Hellwig } 15350fd97ccfSChristoph Hellwig 15360fd97ccfSChristoph Hellwig void target_free_device(struct se_device *dev) 15370fd97ccfSChristoph Hellwig { 15380fd97ccfSChristoph Hellwig struct se_hba *hba = dev->se_hba; 15390fd97ccfSChristoph Hellwig 15400fd97ccfSChristoph Hellwig WARN_ON(!list_empty(&dev->dev_sep_list)); 15410fd97ccfSChristoph Hellwig 15420fd97ccfSChristoph Hellwig if (dev->dev_flags & DF_CONFIGURED) { 15430fd97ccfSChristoph Hellwig destroy_workqueue(dev->tmr_wq); 15440fd97ccfSChristoph Hellwig 15450fd97ccfSChristoph Hellwig spin_lock(&hba->device_lock); 15460fd97ccfSChristoph Hellwig hba->dev_count--; 15470fd97ccfSChristoph Hellwig spin_unlock(&hba->device_lock); 15480fd97ccfSChristoph Hellwig } 15490fd97ccfSChristoph Hellwig 15500fd97ccfSChristoph Hellwig core_alua_free_lu_gp_mem(dev); 15510fd97ccfSChristoph Hellwig core_scsi3_free_all_registrations(dev); 15520fd97ccfSChristoph Hellwig se_release_vpd_for_dev(dev); 15530fd97ccfSChristoph Hellwig 15540fd97ccfSChristoph Hellwig dev->transport->free_device(dev); 15550fd97ccfSChristoph Hellwig } 15560fd97ccfSChristoph Hellwig 1557c66ac9dbSNicholas Bellinger int core_dev_setup_virtual_lun0(void) 1558c66ac9dbSNicholas Bellinger { 1559c66ac9dbSNicholas Bellinger struct se_hba *hba; 1560c66ac9dbSNicholas Bellinger struct se_device *dev; 1561db5d1c3cSAndy Grover char buf[] = "rd_pages=8,rd_nullio=1"; 1562c66ac9dbSNicholas Bellinger int ret; 1563c66ac9dbSNicholas Bellinger 15646708bb27SAndy Grover hba = core_alloc_hba("rd_mcp", 0, HBA_FLAGS_INTERNAL_USE); 1565c66ac9dbSNicholas Bellinger if (IS_ERR(hba)) 1566c66ac9dbSNicholas Bellinger return PTR_ERR(hba); 1567c66ac9dbSNicholas Bellinger 15680fd97ccfSChristoph Hellwig dev = target_alloc_device(hba, "virt_lun0"); 15690fd97ccfSChristoph Hellwig if (!dev) { 1570c66ac9dbSNicholas Bellinger ret = -ENOMEM; 15710fd97ccfSChristoph Hellwig goto out_free_hba; 1572c66ac9dbSNicholas Bellinger } 1573c66ac9dbSNicholas Bellinger 15740fd97ccfSChristoph Hellwig hba->transport->set_configfs_dev_params(dev, buf, sizeof(buf)); 1575c66ac9dbSNicholas Bellinger 15760fd97ccfSChristoph Hellwig ret = target_configure_device(dev); 15770fd97ccfSChristoph Hellwig if (ret) 15780fd97ccfSChristoph Hellwig goto out_free_se_dev; 15790fd97ccfSChristoph Hellwig 15800fd97ccfSChristoph Hellwig lun0_hba = hba; 1581e3d6f909SAndy Grover g_lun0_dev = dev; 1582c66ac9dbSNicholas Bellinger return 0; 15830fd97ccfSChristoph Hellwig 15840fd97ccfSChristoph Hellwig out_free_se_dev: 15850fd97ccfSChristoph Hellwig target_free_device(dev); 15860fd97ccfSChristoph Hellwig out_free_hba: 15870fd97ccfSChristoph Hellwig core_delete_hba(hba); 1588c66ac9dbSNicholas Bellinger return ret; 1589c66ac9dbSNicholas Bellinger } 1590c66ac9dbSNicholas Bellinger 1591c66ac9dbSNicholas Bellinger 1592c66ac9dbSNicholas Bellinger void core_dev_release_virtual_lun0(void) 1593c66ac9dbSNicholas Bellinger { 1594e3d6f909SAndy Grover struct se_hba *hba = lun0_hba; 1595c66ac9dbSNicholas Bellinger 15966708bb27SAndy Grover if (!hba) 1597c66ac9dbSNicholas Bellinger return; 1598c66ac9dbSNicholas Bellinger 1599e3d6f909SAndy Grover if (g_lun0_dev) 16000fd97ccfSChristoph Hellwig target_free_device(g_lun0_dev); 1601c66ac9dbSNicholas Bellinger core_delete_hba(hba); 1602c66ac9dbSNicholas Bellinger } 1603