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> 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 50d9ea32bfSNicholas Bellinger DEFINE_MUTEX(g_device_mutex); 51d9ea32bfSNicholas Bellinger LIST_HEAD(g_device_list); 52d9ea32bfSNicholas Bellinger 53e3d6f909SAndy Grover static struct se_hba *lun0_hba; 54e3d6f909SAndy Grover /* not static, needed by tpg.c */ 55e3d6f909SAndy Grover struct se_device *g_lun0_dev; 56e3d6f909SAndy Grover 57de103c93SChristoph Hellwig sense_reason_t 58de103c93SChristoph Hellwig transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) 59c66ac9dbSNicholas Bellinger { 60c66ac9dbSNicholas Bellinger struct se_lun *se_lun = NULL; 61e3d6f909SAndy Grover struct se_session *se_sess = se_cmd->se_sess; 625951146dSAndy Grover struct se_device *dev; 63c66ac9dbSNicholas Bellinger unsigned long flags; 64c66ac9dbSNicholas Bellinger 65de103c93SChristoph Hellwig if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) 66de103c93SChristoph Hellwig return TCM_NON_EXISTENT_LUN; 67d8144955SFubo Chen 6878faae37SRoland Dreier spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags); 69f2083241SJörn Engel se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun]; 705951146dSAndy Grover if (se_cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { 715951146dSAndy Grover struct se_dev_entry *deve = se_cmd->se_deve; 725951146dSAndy Grover 73c66ac9dbSNicholas Bellinger deve->total_cmds++; 74c66ac9dbSNicholas Bellinger 755951146dSAndy Grover if ((se_cmd->data_direction == DMA_TO_DEVICE) && 765951146dSAndy Grover (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)) { 776708bb27SAndy Grover pr_err("TARGET_CORE[%s]: Detected WRITE_PROTECTED LUN" 78c66ac9dbSNicholas Bellinger " Access for 0x%08x\n", 79e3d6f909SAndy Grover se_cmd->se_tfo->get_fabric_name(), 80c66ac9dbSNicholas Bellinger unpacked_lun); 8178faae37SRoland Dreier spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); 82de103c93SChristoph Hellwig return TCM_WRITE_PROTECTED; 835951146dSAndy Grover } 845951146dSAndy Grover 855951146dSAndy Grover if (se_cmd->data_direction == DMA_TO_DEVICE) 865951146dSAndy Grover deve->write_bytes += se_cmd->data_length; 875951146dSAndy Grover else if (se_cmd->data_direction == DMA_FROM_DEVICE) 885951146dSAndy Grover deve->read_bytes += se_cmd->data_length; 895951146dSAndy Grover 905951146dSAndy Grover se_lun = deve->se_lun; 915951146dSAndy Grover se_cmd->se_lun = deve->se_lun; 925951146dSAndy Grover se_cmd->pr_res_key = deve->pr_res_key; 935951146dSAndy Grover se_cmd->orig_fe_lun = unpacked_lun; 945951146dSAndy Grover se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; 955277797dSNicholas Bellinger 965277797dSNicholas Bellinger percpu_ref_get(&se_lun->lun_ref); 975277797dSNicholas Bellinger se_cmd->lun_ref_active = true; 985951146dSAndy Grover } 9978faae37SRoland Dreier spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); 1005951146dSAndy Grover 1015951146dSAndy Grover if (!se_lun) { 102c66ac9dbSNicholas Bellinger /* 103c66ac9dbSNicholas Bellinger * Use the se_portal_group->tpg_virt_lun0 to allow for 104c66ac9dbSNicholas Bellinger * REPORT_LUNS, et al to be returned when no active 105c66ac9dbSNicholas Bellinger * MappedLUN=0 exists for this Initiator Port. 106c66ac9dbSNicholas Bellinger */ 107c66ac9dbSNicholas Bellinger if (unpacked_lun != 0) { 1086708bb27SAndy Grover pr_err("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN" 109c66ac9dbSNicholas Bellinger " Access for 0x%08x\n", 110e3d6f909SAndy Grover se_cmd->se_tfo->get_fabric_name(), 111c66ac9dbSNicholas Bellinger unpacked_lun); 112de103c93SChristoph Hellwig return TCM_NON_EXISTENT_LUN; 113c66ac9dbSNicholas Bellinger } 114c66ac9dbSNicholas Bellinger /* 115c66ac9dbSNicholas Bellinger * Force WRITE PROTECT for virtual LUN 0 116c66ac9dbSNicholas Bellinger */ 117c66ac9dbSNicholas Bellinger if ((se_cmd->data_direction != DMA_FROM_DEVICE) && 118de103c93SChristoph Hellwig (se_cmd->data_direction != DMA_NONE)) 119de103c93SChristoph Hellwig return TCM_WRITE_PROTECTED; 1205951146dSAndy Grover 1215951146dSAndy Grover se_lun = &se_sess->se_tpg->tpg_virt_lun0; 1225951146dSAndy Grover se_cmd->se_lun = &se_sess->se_tpg->tpg_virt_lun0; 123c66ac9dbSNicholas Bellinger se_cmd->orig_fe_lun = 0; 124c66ac9dbSNicholas Bellinger se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; 1255277797dSNicholas Bellinger 1265277797dSNicholas Bellinger percpu_ref_get(&se_lun->lun_ref); 1275277797dSNicholas Bellinger se_cmd->lun_ref_active = true; 128c66ac9dbSNicholas Bellinger } 129c66ac9dbSNicholas Bellinger 1305951146dSAndy Grover /* Directly associate cmd with se_dev */ 1315951146dSAndy Grover se_cmd->se_dev = se_lun->lun_se_dev; 1325951146dSAndy Grover 1335951146dSAndy Grover dev = se_lun->lun_se_dev; 134ee480683SNicholas Bellinger atomic_long_inc(&dev->num_cmds); 135c66ac9dbSNicholas Bellinger if (se_cmd->data_direction == DMA_TO_DEVICE) 136ee480683SNicholas Bellinger atomic_long_add(se_cmd->data_length, &dev->write_bytes); 137c66ac9dbSNicholas Bellinger else if (se_cmd->data_direction == DMA_FROM_DEVICE) 138ee480683SNicholas Bellinger atomic_long_add(se_cmd->data_length, &dev->read_bytes); 139c66ac9dbSNicholas Bellinger 140c66ac9dbSNicholas Bellinger return 0; 141c66ac9dbSNicholas Bellinger } 1425951146dSAndy Grover EXPORT_SYMBOL(transport_lookup_cmd_lun); 143c66ac9dbSNicholas Bellinger 1445951146dSAndy Grover int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun) 145c66ac9dbSNicholas Bellinger { 146c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 147c66ac9dbSNicholas Bellinger struct se_lun *se_lun = NULL; 148e3d6f909SAndy Grover struct se_session *se_sess = se_cmd->se_sess; 149c66ac9dbSNicholas Bellinger struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; 1505e1be919SRoland Dreier unsigned long flags; 151c66ac9dbSNicholas Bellinger 152de103c93SChristoph Hellwig if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) 153e3d6f909SAndy Grover return -ENODEV; 154d8144955SFubo Chen 1555e1be919SRoland Dreier spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags); 156f2083241SJörn Engel se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun]; 1575951146dSAndy Grover deve = se_cmd->se_deve; 1585951146dSAndy Grover 159c66ac9dbSNicholas Bellinger if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { 1605951146dSAndy Grover se_tmr->tmr_lun = deve->se_lun; 1615951146dSAndy Grover se_cmd->se_lun = deve->se_lun; 1625951146dSAndy Grover se_lun = deve->se_lun; 163c66ac9dbSNicholas Bellinger se_cmd->pr_res_key = deve->pr_res_key; 164c66ac9dbSNicholas Bellinger se_cmd->orig_fe_lun = unpacked_lun; 165c66ac9dbSNicholas Bellinger } 1665e1be919SRoland Dreier spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); 167c66ac9dbSNicholas Bellinger 168c66ac9dbSNicholas Bellinger if (!se_lun) { 1696708bb27SAndy Grover pr_debug("TARGET_CORE[%s]: Detected NON_EXISTENT_LUN" 170c66ac9dbSNicholas Bellinger " Access for 0x%08x\n", 171e3d6f909SAndy Grover se_cmd->se_tfo->get_fabric_name(), 172c66ac9dbSNicholas Bellinger unpacked_lun); 173e3d6f909SAndy Grover return -ENODEV; 174c66ac9dbSNicholas Bellinger } 175c66ac9dbSNicholas Bellinger 1765951146dSAndy Grover /* Directly associate cmd with se_dev */ 1775951146dSAndy Grover se_cmd->se_dev = se_lun->lun_se_dev; 1785951146dSAndy Grover se_tmr->tmr_dev = 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 188c66ac9dbSNicholas Bellinger /* 189c66ac9dbSNicholas Bellinger * This function is called from core_scsi3_emulate_pro_register_and_move() 190c66ac9dbSNicholas Bellinger * and core_scsi3_decode_spec_i_port(), and will increment &deve->pr_ref_count 191c66ac9dbSNicholas Bellinger * when a matching rtpi is found. 192c66ac9dbSNicholas Bellinger */ 193c66ac9dbSNicholas Bellinger struct se_dev_entry *core_get_se_deve_from_rtpi( 194c66ac9dbSNicholas Bellinger struct se_node_acl *nacl, 195c66ac9dbSNicholas Bellinger u16 rtpi) 196c66ac9dbSNicholas Bellinger { 197c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 198c66ac9dbSNicholas Bellinger struct se_lun *lun; 199c66ac9dbSNicholas Bellinger struct se_port *port; 200c66ac9dbSNicholas Bellinger struct se_portal_group *tpg = nacl->se_tpg; 201c66ac9dbSNicholas Bellinger u32 i; 202c66ac9dbSNicholas Bellinger 203c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 204c66ac9dbSNicholas Bellinger for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { 205f2083241SJörn Engel deve = nacl->device_list[i]; 206c66ac9dbSNicholas Bellinger 207c66ac9dbSNicholas Bellinger if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)) 208c66ac9dbSNicholas Bellinger continue; 209c66ac9dbSNicholas Bellinger 210c66ac9dbSNicholas Bellinger lun = deve->se_lun; 2116708bb27SAndy Grover if (!lun) { 2126708bb27SAndy Grover pr_err("%s device entries device pointer is" 213c66ac9dbSNicholas Bellinger " NULL, but Initiator has access.\n", 214e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 215c66ac9dbSNicholas Bellinger continue; 216c66ac9dbSNicholas Bellinger } 217c66ac9dbSNicholas Bellinger port = lun->lun_sep; 2186708bb27SAndy Grover if (!port) { 2196708bb27SAndy Grover pr_err("%s device entries device pointer is" 220c66ac9dbSNicholas Bellinger " NULL, but Initiator has access.\n", 221e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 222c66ac9dbSNicholas Bellinger continue; 223c66ac9dbSNicholas Bellinger } 224c66ac9dbSNicholas Bellinger if (port->sep_rtpi != rtpi) 225c66ac9dbSNicholas Bellinger continue; 226c66ac9dbSNicholas Bellinger 22733940d09SJoern Engel atomic_inc_mb(&deve->pr_ref_count); 228c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 229c66ac9dbSNicholas Bellinger 230c66ac9dbSNicholas Bellinger return deve; 231c66ac9dbSNicholas Bellinger } 232c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 233c66ac9dbSNicholas Bellinger 234c66ac9dbSNicholas Bellinger return NULL; 235c66ac9dbSNicholas Bellinger } 236c66ac9dbSNicholas Bellinger 237c66ac9dbSNicholas Bellinger int core_free_device_list_for_node( 238c66ac9dbSNicholas Bellinger struct se_node_acl *nacl, 239c66ac9dbSNicholas Bellinger struct se_portal_group *tpg) 240c66ac9dbSNicholas Bellinger { 241c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 242c66ac9dbSNicholas Bellinger struct se_lun *lun; 243c66ac9dbSNicholas Bellinger u32 i; 244c66ac9dbSNicholas Bellinger 245c66ac9dbSNicholas Bellinger if (!nacl->device_list) 246c66ac9dbSNicholas Bellinger return 0; 247c66ac9dbSNicholas Bellinger 248c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 249c66ac9dbSNicholas Bellinger for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { 250f2083241SJörn Engel deve = nacl->device_list[i]; 251c66ac9dbSNicholas Bellinger 252c66ac9dbSNicholas Bellinger if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)) 253c66ac9dbSNicholas Bellinger continue; 254c66ac9dbSNicholas Bellinger 255c66ac9dbSNicholas Bellinger if (!deve->se_lun) { 2566708bb27SAndy Grover pr_err("%s device entries device pointer is" 257c66ac9dbSNicholas Bellinger " NULL, but Initiator has access.\n", 258e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 259c66ac9dbSNicholas Bellinger continue; 260c66ac9dbSNicholas Bellinger } 261c66ac9dbSNicholas Bellinger lun = deve->se_lun; 262c66ac9dbSNicholas Bellinger 263c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 264e80ac6c4SAndy Grover core_disable_device_list_for_node(lun, NULL, deve->mapped_lun, 265e80ac6c4SAndy Grover TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg); 266c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 267c66ac9dbSNicholas Bellinger } 268c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 269c66ac9dbSNicholas Bellinger 270f2083241SJörn Engel array_free(nacl->device_list, TRANSPORT_MAX_LUNS_PER_TPG); 271c66ac9dbSNicholas Bellinger nacl->device_list = NULL; 272c66ac9dbSNicholas Bellinger 273c66ac9dbSNicholas Bellinger return 0; 274c66ac9dbSNicholas Bellinger } 275c66ac9dbSNicholas Bellinger 276c66ac9dbSNicholas Bellinger void core_update_device_list_access( 277c66ac9dbSNicholas Bellinger u32 mapped_lun, 278c66ac9dbSNicholas Bellinger u32 lun_access, 279c66ac9dbSNicholas Bellinger struct se_node_acl *nacl) 280c66ac9dbSNicholas Bellinger { 281c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 282c66ac9dbSNicholas Bellinger 283c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 284f2083241SJörn Engel deve = nacl->device_list[mapped_lun]; 285c66ac9dbSNicholas Bellinger if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { 286c66ac9dbSNicholas Bellinger deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; 287c66ac9dbSNicholas Bellinger deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; 288c66ac9dbSNicholas Bellinger } else { 289c66ac9dbSNicholas Bellinger deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; 290c66ac9dbSNicholas Bellinger deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; 291c66ac9dbSNicholas Bellinger } 292c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 293c66ac9dbSNicholas Bellinger } 294c66ac9dbSNicholas Bellinger 295e80ac6c4SAndy Grover /* core_enable_device_list_for_node(): 296c66ac9dbSNicholas Bellinger * 297c66ac9dbSNicholas Bellinger * 298c66ac9dbSNicholas Bellinger */ 299e80ac6c4SAndy Grover int core_enable_device_list_for_node( 300c66ac9dbSNicholas Bellinger struct se_lun *lun, 301c66ac9dbSNicholas Bellinger struct se_lun_acl *lun_acl, 302c66ac9dbSNicholas Bellinger u32 mapped_lun, 303c66ac9dbSNicholas Bellinger u32 lun_access, 304c66ac9dbSNicholas Bellinger struct se_node_acl *nacl, 305e80ac6c4SAndy Grover struct se_portal_group *tpg) 306c66ac9dbSNicholas Bellinger { 307c66ac9dbSNicholas Bellinger struct se_port *port = lun->lun_sep; 308e80ac6c4SAndy Grover struct se_dev_entry *deve; 309c66ac9dbSNicholas Bellinger 310c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 311e80ac6c4SAndy Grover 312e80ac6c4SAndy Grover deve = nacl->device_list[mapped_lun]; 313e80ac6c4SAndy Grover 314c66ac9dbSNicholas Bellinger /* 315125d0119SHannes Reinecke * Check if the call is handling demo mode -> explicit LUN ACL 316c66ac9dbSNicholas Bellinger * transition. This transition must be for the same struct se_lun 317c66ac9dbSNicholas Bellinger * + mapped_lun that was setup in demo mode.. 318c66ac9dbSNicholas Bellinger */ 319c66ac9dbSNicholas Bellinger if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { 320c66ac9dbSNicholas Bellinger if (deve->se_lun_acl != NULL) { 3216708bb27SAndy Grover pr_err("struct se_dev_entry->se_lun_acl" 322125d0119SHannes Reinecke " already set for demo mode -> explicit" 323c66ac9dbSNicholas Bellinger " LUN ACL transition\n"); 32485dc98d9SFubo Chen spin_unlock_irq(&nacl->device_list_lock); 325e3d6f909SAndy Grover return -EINVAL; 326c66ac9dbSNicholas Bellinger } 327c66ac9dbSNicholas Bellinger if (deve->se_lun != lun) { 3286708bb27SAndy Grover pr_err("struct se_dev_entry->se_lun does" 329c66ac9dbSNicholas Bellinger " match passed struct se_lun for demo mode" 330125d0119SHannes Reinecke " -> explicit LUN ACL transition\n"); 33185dc98d9SFubo Chen spin_unlock_irq(&nacl->device_list_lock); 332e3d6f909SAndy Grover return -EINVAL; 333c66ac9dbSNicholas Bellinger } 334c66ac9dbSNicholas Bellinger deve->se_lun_acl = lun_acl; 335c66ac9dbSNicholas Bellinger 336c66ac9dbSNicholas Bellinger if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { 337c66ac9dbSNicholas Bellinger deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; 338c66ac9dbSNicholas Bellinger deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; 339c66ac9dbSNicholas Bellinger } else { 340c66ac9dbSNicholas Bellinger deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; 341c66ac9dbSNicholas Bellinger deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; 342c66ac9dbSNicholas Bellinger } 343c66ac9dbSNicholas Bellinger 344c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 345c66ac9dbSNicholas Bellinger return 0; 346c66ac9dbSNicholas Bellinger } 347e80ac6c4SAndy Grover 348e80ac6c4SAndy Grover deve->se_lun = lun; 349e80ac6c4SAndy Grover deve->se_lun_acl = lun_acl; 350e80ac6c4SAndy Grover deve->mapped_lun = mapped_lun; 351e80ac6c4SAndy Grover deve->lun_flags |= TRANSPORT_LUNFLAGS_INITIATOR_ACCESS; 352e80ac6c4SAndy Grover 353e80ac6c4SAndy Grover if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { 354e80ac6c4SAndy Grover deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; 355e80ac6c4SAndy Grover deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; 356e80ac6c4SAndy Grover } else { 357e80ac6c4SAndy Grover deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; 358e80ac6c4SAndy Grover deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; 359e80ac6c4SAndy Grover } 360e80ac6c4SAndy Grover 361c66ac9dbSNicholas Bellinger deve->creation_time = get_jiffies_64(); 362c66ac9dbSNicholas Bellinger deve->attach_count++; 363c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 364c66ac9dbSNicholas Bellinger 365c66ac9dbSNicholas Bellinger spin_lock_bh(&port->sep_alua_lock); 366c66ac9dbSNicholas Bellinger list_add_tail(&deve->alua_port_list, &port->sep_alua_list); 367c66ac9dbSNicholas Bellinger spin_unlock_bh(&port->sep_alua_lock); 368c66ac9dbSNicholas Bellinger 369c66ac9dbSNicholas Bellinger return 0; 370c66ac9dbSNicholas Bellinger } 371e80ac6c4SAndy Grover 372e80ac6c4SAndy Grover /* core_disable_device_list_for_node(): 373e80ac6c4SAndy Grover * 374e80ac6c4SAndy Grover * 375e80ac6c4SAndy Grover */ 376e80ac6c4SAndy Grover int core_disable_device_list_for_node( 377e80ac6c4SAndy Grover struct se_lun *lun, 378e80ac6c4SAndy Grover struct se_lun_acl *lun_acl, 379e80ac6c4SAndy Grover u32 mapped_lun, 380e80ac6c4SAndy Grover u32 lun_access, 381e80ac6c4SAndy Grover struct se_node_acl *nacl, 382e80ac6c4SAndy Grover struct se_portal_group *tpg) 383e80ac6c4SAndy Grover { 384e80ac6c4SAndy Grover struct se_port *port = lun->lun_sep; 38577d4c745SNicholas Bellinger struct se_dev_entry *deve = nacl->device_list[mapped_lun]; 386e80ac6c4SAndy Grover 387e80ac6c4SAndy Grover /* 388e80ac6c4SAndy Grover * If the MappedLUN entry is being disabled, the entry in 389e80ac6c4SAndy Grover * port->sep_alua_list must be removed now before clearing the 390e80ac6c4SAndy Grover * struct se_dev_entry pointers below as logic in 391e80ac6c4SAndy Grover * core_alua_do_transition_tg_pt() depends on these being present. 392e80ac6c4SAndy Grover * 393e80ac6c4SAndy Grover * deve->se_lun_acl will be NULL for demo-mode created LUNs 394e80ac6c4SAndy Grover * that have not been explicitly converted to MappedLUNs -> 395e80ac6c4SAndy Grover * struct se_lun_acl, but we remove deve->alua_port_list from 396e80ac6c4SAndy Grover * port->sep_alua_list. This also means that active UAs and 397e80ac6c4SAndy Grover * NodeACL context specific PR metadata for demo-mode 398e80ac6c4SAndy Grover * MappedLUN *deve will be released below.. 399e80ac6c4SAndy Grover */ 400e80ac6c4SAndy Grover spin_lock_bh(&port->sep_alua_lock); 401e80ac6c4SAndy Grover list_del(&deve->alua_port_list); 402e80ac6c4SAndy Grover spin_unlock_bh(&port->sep_alua_lock); 403c66ac9dbSNicholas Bellinger /* 404c66ac9dbSNicholas Bellinger * Wait for any in process SPEC_I_PT=1 or REGISTER_AND_MOVE 405c66ac9dbSNicholas Bellinger * PR operation to complete. 406c66ac9dbSNicholas Bellinger */ 407c66ac9dbSNicholas Bellinger while (atomic_read(&deve->pr_ref_count) != 0) 408c66ac9dbSNicholas Bellinger cpu_relax(); 40977d4c745SNicholas Bellinger 410c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 411c66ac9dbSNicholas Bellinger /* 412c66ac9dbSNicholas Bellinger * Disable struct se_dev_entry LUN ACL mapping 413c66ac9dbSNicholas Bellinger */ 414c66ac9dbSNicholas Bellinger core_scsi3_ua_release_all(deve); 415c66ac9dbSNicholas Bellinger deve->se_lun = NULL; 416c66ac9dbSNicholas Bellinger deve->se_lun_acl = NULL; 417c66ac9dbSNicholas Bellinger deve->lun_flags = 0; 418c66ac9dbSNicholas Bellinger deve->creation_time = 0; 419c66ac9dbSNicholas Bellinger deve->attach_count--; 420c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 421c66ac9dbSNicholas Bellinger 422c66ac9dbSNicholas Bellinger core_scsi3_free_pr_reg_from_nacl(lun->lun_se_dev, nacl); 423c66ac9dbSNicholas Bellinger return 0; 424c66ac9dbSNicholas Bellinger } 425c66ac9dbSNicholas Bellinger 426c66ac9dbSNicholas Bellinger /* core_clear_lun_from_tpg(): 427c66ac9dbSNicholas Bellinger * 428c66ac9dbSNicholas Bellinger * 429c66ac9dbSNicholas Bellinger */ 430c66ac9dbSNicholas Bellinger void core_clear_lun_from_tpg(struct se_lun *lun, struct se_portal_group *tpg) 431c66ac9dbSNicholas Bellinger { 432c66ac9dbSNicholas Bellinger struct se_node_acl *nacl; 433c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 434c66ac9dbSNicholas Bellinger u32 i; 435c66ac9dbSNicholas Bellinger 43628638887SRoland Dreier spin_lock_irq(&tpg->acl_node_lock); 437c66ac9dbSNicholas Bellinger list_for_each_entry(nacl, &tpg->acl_node_list, acl_list) { 43828638887SRoland Dreier spin_unlock_irq(&tpg->acl_node_lock); 439c66ac9dbSNicholas Bellinger 440c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 441c66ac9dbSNicholas Bellinger for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { 442f2083241SJörn Engel deve = nacl->device_list[i]; 443c66ac9dbSNicholas Bellinger if (lun != deve->se_lun) 444c66ac9dbSNicholas Bellinger continue; 445c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 446c66ac9dbSNicholas Bellinger 447e80ac6c4SAndy Grover core_disable_device_list_for_node(lun, NULL, 448c66ac9dbSNicholas Bellinger deve->mapped_lun, TRANSPORT_LUNFLAGS_NO_ACCESS, 449e80ac6c4SAndy Grover nacl, tpg); 450c66ac9dbSNicholas Bellinger 451c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 452c66ac9dbSNicholas Bellinger } 453c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 454c66ac9dbSNicholas Bellinger 45528638887SRoland Dreier spin_lock_irq(&tpg->acl_node_lock); 456c66ac9dbSNicholas Bellinger } 45728638887SRoland Dreier spin_unlock_irq(&tpg->acl_node_lock); 458c66ac9dbSNicholas Bellinger } 459c66ac9dbSNicholas Bellinger 460c66ac9dbSNicholas Bellinger static struct se_port *core_alloc_port(struct se_device *dev) 461c66ac9dbSNicholas Bellinger { 462c66ac9dbSNicholas Bellinger struct se_port *port, *port_tmp; 463c66ac9dbSNicholas Bellinger 464c66ac9dbSNicholas Bellinger port = kzalloc(sizeof(struct se_port), GFP_KERNEL); 4656708bb27SAndy Grover if (!port) { 4666708bb27SAndy Grover pr_err("Unable to allocate struct se_port\n"); 467e3d6f909SAndy Grover return ERR_PTR(-ENOMEM); 468c66ac9dbSNicholas Bellinger } 469c66ac9dbSNicholas Bellinger INIT_LIST_HEAD(&port->sep_alua_list); 470c66ac9dbSNicholas Bellinger INIT_LIST_HEAD(&port->sep_list); 471c66ac9dbSNicholas Bellinger atomic_set(&port->sep_tg_pt_secondary_offline, 0); 472c66ac9dbSNicholas Bellinger spin_lock_init(&port->sep_alua_lock); 473c66ac9dbSNicholas Bellinger mutex_init(&port->sep_tg_pt_md_mutex); 474c66ac9dbSNicholas Bellinger 475c66ac9dbSNicholas Bellinger spin_lock(&dev->se_port_lock); 476c66ac9dbSNicholas Bellinger if (dev->dev_port_count == 0x0000ffff) { 4776708bb27SAndy Grover pr_warn("Reached dev->dev_port_count ==" 478c66ac9dbSNicholas Bellinger " 0x0000ffff\n"); 479c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 480e3d6f909SAndy Grover return ERR_PTR(-ENOSPC); 481c66ac9dbSNicholas Bellinger } 482c66ac9dbSNicholas Bellinger again: 483c66ac9dbSNicholas Bellinger /* 48435d1efe8SMasanari Iida * Allocate the next RELATIVE TARGET PORT IDENTIFIER for this struct se_device 485c66ac9dbSNicholas Bellinger * Here is the table from spc4r17 section 7.7.3.8. 486c66ac9dbSNicholas Bellinger * 487c66ac9dbSNicholas Bellinger * Table 473 -- RELATIVE TARGET PORT IDENTIFIER field 488c66ac9dbSNicholas Bellinger * 489c66ac9dbSNicholas Bellinger * Code Description 490c66ac9dbSNicholas Bellinger * 0h Reserved 491c66ac9dbSNicholas Bellinger * 1h Relative port 1, historically known as port A 492c66ac9dbSNicholas Bellinger * 2h Relative port 2, historically known as port B 493c66ac9dbSNicholas Bellinger * 3h to FFFFh Relative port 3 through 65 535 494c66ac9dbSNicholas Bellinger */ 495c66ac9dbSNicholas Bellinger port->sep_rtpi = dev->dev_rpti_counter++; 4966708bb27SAndy Grover if (!port->sep_rtpi) 497c66ac9dbSNicholas Bellinger goto again; 498c66ac9dbSNicholas Bellinger 499c66ac9dbSNicholas Bellinger list_for_each_entry(port_tmp, &dev->dev_sep_list, sep_list) { 500c66ac9dbSNicholas Bellinger /* 50135d1efe8SMasanari Iida * Make sure RELATIVE TARGET PORT IDENTIFIER is unique 502c66ac9dbSNicholas Bellinger * for 16-bit wrap.. 503c66ac9dbSNicholas Bellinger */ 504c66ac9dbSNicholas Bellinger if (port->sep_rtpi == port_tmp->sep_rtpi) 505c66ac9dbSNicholas Bellinger goto again; 506c66ac9dbSNicholas Bellinger } 507c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 508c66ac9dbSNicholas Bellinger 509c66ac9dbSNicholas Bellinger return port; 510c66ac9dbSNicholas Bellinger } 511c66ac9dbSNicholas Bellinger 512c66ac9dbSNicholas Bellinger static void core_export_port( 513c66ac9dbSNicholas Bellinger struct se_device *dev, 514c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 515c66ac9dbSNicholas Bellinger struct se_port *port, 516c66ac9dbSNicholas Bellinger struct se_lun *lun) 517c66ac9dbSNicholas Bellinger { 518c66ac9dbSNicholas Bellinger struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem = NULL; 519c66ac9dbSNicholas Bellinger 520c66ac9dbSNicholas Bellinger spin_lock(&dev->se_port_lock); 521c66ac9dbSNicholas Bellinger spin_lock(&lun->lun_sep_lock); 522c66ac9dbSNicholas Bellinger port->sep_tpg = tpg; 523c66ac9dbSNicholas Bellinger port->sep_lun = lun; 524c66ac9dbSNicholas Bellinger lun->lun_sep = port; 525c66ac9dbSNicholas Bellinger spin_unlock(&lun->lun_sep_lock); 526c66ac9dbSNicholas Bellinger 527c66ac9dbSNicholas Bellinger list_add_tail(&port->sep_list, &dev->dev_sep_list); 528c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 529c66ac9dbSNicholas Bellinger 530c87fbd56SChristoph Hellwig if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV && 531c87fbd56SChristoph Hellwig !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) { 532c66ac9dbSNicholas Bellinger tg_pt_gp_mem = core_alua_allocate_tg_pt_gp_mem(port); 533c66ac9dbSNicholas Bellinger if (IS_ERR(tg_pt_gp_mem) || !tg_pt_gp_mem) { 5346708bb27SAndy Grover pr_err("Unable to allocate t10_alua_tg_pt" 535c66ac9dbSNicholas Bellinger "_gp_member_t\n"); 536c66ac9dbSNicholas Bellinger return; 537c66ac9dbSNicholas Bellinger } 538c66ac9dbSNicholas Bellinger spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 539c66ac9dbSNicholas Bellinger __core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem, 5400fd97ccfSChristoph Hellwig dev->t10_alua.default_tg_pt_gp); 541c66ac9dbSNicholas Bellinger spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 5426708bb27SAndy Grover pr_debug("%s/%s: Adding to default ALUA Target Port" 543c66ac9dbSNicholas Bellinger " Group: alua/default_tg_pt_gp\n", 544e3d6f909SAndy Grover dev->transport->name, tpg->se_tpg_tfo->get_fabric_name()); 545c66ac9dbSNicholas Bellinger } 546c66ac9dbSNicholas Bellinger 547c66ac9dbSNicholas Bellinger dev->dev_port_count++; 54835d1efe8SMasanari Iida port->sep_index = port->sep_rtpi; /* RELATIVE TARGET PORT IDENTIFIER */ 549c66ac9dbSNicholas Bellinger } 550c66ac9dbSNicholas Bellinger 551c66ac9dbSNicholas Bellinger /* 552c66ac9dbSNicholas Bellinger * Called with struct se_device->se_port_lock spinlock held. 553c66ac9dbSNicholas Bellinger */ 554c66ac9dbSNicholas Bellinger static void core_release_port(struct se_device *dev, struct se_port *port) 5555dd7ed2eSDan Carpenter __releases(&dev->se_port_lock) __acquires(&dev->se_port_lock) 556c66ac9dbSNicholas Bellinger { 557c66ac9dbSNicholas Bellinger /* 558c66ac9dbSNicholas Bellinger * Wait for any port reference for PR ALL_TG_PT=1 operation 559c66ac9dbSNicholas Bellinger * to complete in __core_scsi3_alloc_registration() 560c66ac9dbSNicholas Bellinger */ 561c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 562c66ac9dbSNicholas Bellinger if (atomic_read(&port->sep_tg_pt_ref_cnt)) 563c66ac9dbSNicholas Bellinger cpu_relax(); 564c66ac9dbSNicholas Bellinger spin_lock(&dev->se_port_lock); 565c66ac9dbSNicholas Bellinger 566c66ac9dbSNicholas Bellinger core_alua_free_tg_pt_gp_mem(port); 567c66ac9dbSNicholas Bellinger 568c66ac9dbSNicholas Bellinger list_del(&port->sep_list); 569c66ac9dbSNicholas Bellinger dev->dev_port_count--; 570c66ac9dbSNicholas Bellinger kfree(port); 571c66ac9dbSNicholas Bellinger } 572c66ac9dbSNicholas Bellinger 573c66ac9dbSNicholas Bellinger int core_dev_export( 574c66ac9dbSNicholas Bellinger struct se_device *dev, 575c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 576c66ac9dbSNicholas Bellinger struct se_lun *lun) 577c66ac9dbSNicholas Bellinger { 5780fd97ccfSChristoph Hellwig struct se_hba *hba = dev->se_hba; 579c66ac9dbSNicholas Bellinger struct se_port *port; 580c66ac9dbSNicholas Bellinger 581c66ac9dbSNicholas Bellinger port = core_alloc_port(dev); 582e3d6f909SAndy Grover if (IS_ERR(port)) 583e3d6f909SAndy Grover return PTR_ERR(port); 584c66ac9dbSNicholas Bellinger 585c66ac9dbSNicholas Bellinger lun->lun_se_dev = dev; 586c66ac9dbSNicholas Bellinger 5870fd97ccfSChristoph Hellwig spin_lock(&hba->device_lock); 5880fd97ccfSChristoph Hellwig dev->export_count++; 5890fd97ccfSChristoph Hellwig spin_unlock(&hba->device_lock); 5900fd97ccfSChristoph Hellwig 591c66ac9dbSNicholas Bellinger core_export_port(dev, tpg, port, lun); 592c66ac9dbSNicholas Bellinger return 0; 593c66ac9dbSNicholas Bellinger } 594c66ac9dbSNicholas Bellinger 595c66ac9dbSNicholas Bellinger void core_dev_unexport( 596c66ac9dbSNicholas Bellinger struct se_device *dev, 597c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 598c66ac9dbSNicholas Bellinger struct se_lun *lun) 599c66ac9dbSNicholas Bellinger { 6000fd97ccfSChristoph Hellwig struct se_hba *hba = dev->se_hba; 601c66ac9dbSNicholas Bellinger struct se_port *port = lun->lun_sep; 602c66ac9dbSNicholas Bellinger 603c66ac9dbSNicholas Bellinger spin_lock(&lun->lun_sep_lock); 604c66ac9dbSNicholas Bellinger if (lun->lun_se_dev == NULL) { 605c66ac9dbSNicholas Bellinger spin_unlock(&lun->lun_sep_lock); 606c66ac9dbSNicholas Bellinger return; 607c66ac9dbSNicholas Bellinger } 608c66ac9dbSNicholas Bellinger spin_unlock(&lun->lun_sep_lock); 609c66ac9dbSNicholas Bellinger 610c66ac9dbSNicholas Bellinger spin_lock(&dev->se_port_lock); 611c66ac9dbSNicholas Bellinger core_release_port(dev, port); 612c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 613c66ac9dbSNicholas Bellinger 6140fd97ccfSChristoph Hellwig spin_lock(&hba->device_lock); 6150fd97ccfSChristoph Hellwig dev->export_count--; 6160fd97ccfSChristoph Hellwig spin_unlock(&hba->device_lock); 6170fd97ccfSChristoph Hellwig 61883ff42fcSNicholas Bellinger lun->lun_sep = NULL; 619c66ac9dbSNicholas Bellinger lun->lun_se_dev = NULL; 620c66ac9dbSNicholas Bellinger } 621c66ac9dbSNicholas Bellinger 6220fd97ccfSChristoph Hellwig static void se_release_vpd_for_dev(struct se_device *dev) 623c66ac9dbSNicholas Bellinger { 624c66ac9dbSNicholas Bellinger struct t10_vpd *vpd, *vpd_tmp; 625c66ac9dbSNicholas Bellinger 6260fd97ccfSChristoph Hellwig spin_lock(&dev->t10_wwn.t10_vpd_lock); 627c66ac9dbSNicholas Bellinger list_for_each_entry_safe(vpd, vpd_tmp, 6280fd97ccfSChristoph Hellwig &dev->t10_wwn.t10_vpd_list, vpd_list) { 629c66ac9dbSNicholas Bellinger list_del(&vpd->vpd_list); 630c66ac9dbSNicholas Bellinger kfree(vpd); 631c66ac9dbSNicholas Bellinger } 6320fd97ccfSChristoph Hellwig spin_unlock(&dev->t10_wwn.t10_vpd_lock); 633c66ac9dbSNicholas Bellinger } 634c66ac9dbSNicholas Bellinger 635c8045372SRoland Dreier static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) 636525a48a2SNicholas Bellinger { 6373e03989bSRoland Dreier u32 aligned_max_sectors; 6383e03989bSRoland Dreier u32 alignment; 639525a48a2SNicholas Bellinger /* 640525a48a2SNicholas Bellinger * Limit max_sectors to a PAGE_SIZE aligned value for modern 641525a48a2SNicholas Bellinger * transport_allocate_data_tasks() operation. 642525a48a2SNicholas Bellinger */ 6433e03989bSRoland Dreier alignment = max(1ul, PAGE_SIZE / block_size); 6443e03989bSRoland Dreier aligned_max_sectors = rounddown(max_sectors, alignment); 645525a48a2SNicholas Bellinger 6463e03989bSRoland Dreier if (max_sectors != aligned_max_sectors) 6473e03989bSRoland Dreier pr_info("Rounding down aligned max_sectors from %u to %u\n", 6483e03989bSRoland Dreier max_sectors, aligned_max_sectors); 6493e03989bSRoland Dreier 6503e03989bSRoland Dreier return aligned_max_sectors; 651525a48a2SNicholas Bellinger } 652525a48a2SNicholas Bellinger 653c66ac9dbSNicholas Bellinger int se_dev_set_max_unmap_lba_count( 654c66ac9dbSNicholas Bellinger struct se_device *dev, 655c66ac9dbSNicholas Bellinger u32 max_unmap_lba_count) 656c66ac9dbSNicholas Bellinger { 6570fd97ccfSChristoph Hellwig dev->dev_attrib.max_unmap_lba_count = max_unmap_lba_count; 6586708bb27SAndy Grover pr_debug("dev[%p]: Set max_unmap_lba_count: %u\n", 6590fd97ccfSChristoph Hellwig dev, dev->dev_attrib.max_unmap_lba_count); 660c66ac9dbSNicholas Bellinger return 0; 661c66ac9dbSNicholas Bellinger } 662d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_max_unmap_lba_count); 663c66ac9dbSNicholas Bellinger 664c66ac9dbSNicholas Bellinger int se_dev_set_max_unmap_block_desc_count( 665c66ac9dbSNicholas Bellinger struct se_device *dev, 666c66ac9dbSNicholas Bellinger u32 max_unmap_block_desc_count) 667c66ac9dbSNicholas Bellinger { 6680fd97ccfSChristoph Hellwig dev->dev_attrib.max_unmap_block_desc_count = 669e3d6f909SAndy Grover max_unmap_block_desc_count; 6706708bb27SAndy Grover pr_debug("dev[%p]: Set max_unmap_block_desc_count: %u\n", 6710fd97ccfSChristoph Hellwig dev, dev->dev_attrib.max_unmap_block_desc_count); 672c66ac9dbSNicholas Bellinger return 0; 673c66ac9dbSNicholas Bellinger } 674d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_max_unmap_block_desc_count); 675c66ac9dbSNicholas Bellinger 676c66ac9dbSNicholas Bellinger int se_dev_set_unmap_granularity( 677c66ac9dbSNicholas Bellinger struct se_device *dev, 678c66ac9dbSNicholas Bellinger u32 unmap_granularity) 679c66ac9dbSNicholas Bellinger { 6800fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity = unmap_granularity; 6816708bb27SAndy Grover pr_debug("dev[%p]: Set unmap_granularity: %u\n", 6820fd97ccfSChristoph Hellwig dev, dev->dev_attrib.unmap_granularity); 683c66ac9dbSNicholas Bellinger return 0; 684c66ac9dbSNicholas Bellinger } 685d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_unmap_granularity); 686c66ac9dbSNicholas Bellinger 687c66ac9dbSNicholas Bellinger int se_dev_set_unmap_granularity_alignment( 688c66ac9dbSNicholas Bellinger struct se_device *dev, 689c66ac9dbSNicholas Bellinger u32 unmap_granularity_alignment) 690c66ac9dbSNicholas Bellinger { 6910fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity_alignment = unmap_granularity_alignment; 6926708bb27SAndy Grover pr_debug("dev[%p]: Set unmap_granularity_alignment: %u\n", 6930fd97ccfSChristoph Hellwig dev, dev->dev_attrib.unmap_granularity_alignment); 694c66ac9dbSNicholas Bellinger return 0; 695c66ac9dbSNicholas Bellinger } 696d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_unmap_granularity_alignment); 697c66ac9dbSNicholas Bellinger 698773cbaf7SNicholas Bellinger int se_dev_set_max_write_same_len( 699773cbaf7SNicholas Bellinger struct se_device *dev, 700773cbaf7SNicholas Bellinger u32 max_write_same_len) 701773cbaf7SNicholas Bellinger { 702773cbaf7SNicholas Bellinger dev->dev_attrib.max_write_same_len = max_write_same_len; 703773cbaf7SNicholas Bellinger pr_debug("dev[%p]: Set max_write_same_len: %u\n", 704773cbaf7SNicholas Bellinger dev, dev->dev_attrib.max_write_same_len); 705773cbaf7SNicholas Bellinger return 0; 706773cbaf7SNicholas Bellinger } 707d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_max_write_same_len); 708773cbaf7SNicholas Bellinger 709adfa9570STregaron Bayly static void dev_set_t10_wwn_model_alias(struct se_device *dev) 710adfa9570STregaron Bayly { 711adfa9570STregaron Bayly const char *configname; 712adfa9570STregaron Bayly 713adfa9570STregaron Bayly configname = config_item_name(&dev->dev_group.cg_item); 714adfa9570STregaron Bayly if (strlen(configname) >= 16) { 715adfa9570STregaron Bayly pr_warn("dev[%p]: Backstore name '%s' is too long for " 716adfa9570STregaron Bayly "INQUIRY_MODEL, truncating to 16 bytes\n", dev, 717adfa9570STregaron Bayly configname); 718adfa9570STregaron Bayly } 719adfa9570STregaron Bayly snprintf(&dev->t10_wwn.model[0], 16, "%s", configname); 720adfa9570STregaron Bayly } 721adfa9570STregaron Bayly 722adfa9570STregaron Bayly int se_dev_set_emulate_model_alias(struct se_device *dev, int flag) 723adfa9570STregaron Bayly { 724adfa9570STregaron Bayly if (dev->export_count) { 725adfa9570STregaron Bayly pr_err("dev[%p]: Unable to change model alias" 726adfa9570STregaron Bayly " while export_count is %d\n", 727adfa9570STregaron Bayly dev, dev->export_count); 728adfa9570STregaron Bayly return -EINVAL; 729adfa9570STregaron Bayly } 730adfa9570STregaron Bayly 731adfa9570STregaron Bayly if (flag != 0 && flag != 1) { 732adfa9570STregaron Bayly pr_err("Illegal value %d\n", flag); 733adfa9570STregaron Bayly return -EINVAL; 734adfa9570STregaron Bayly } 735adfa9570STregaron Bayly 736adfa9570STregaron Bayly if (flag) { 737adfa9570STregaron Bayly dev_set_t10_wwn_model_alias(dev); 738adfa9570STregaron Bayly } else { 739adfa9570STregaron Bayly strncpy(&dev->t10_wwn.model[0], 740adfa9570STregaron Bayly dev->transport->inquiry_prod, 16); 741adfa9570STregaron Bayly } 742adfa9570STregaron Bayly dev->dev_attrib.emulate_model_alias = flag; 743adfa9570STregaron Bayly 744adfa9570STregaron Bayly return 0; 745adfa9570STregaron Bayly } 746d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_emulate_model_alias); 747adfa9570STregaron Bayly 748c66ac9dbSNicholas Bellinger int se_dev_set_emulate_dpo(struct se_device *dev, int flag) 749c66ac9dbSNicholas Bellinger { 750f55918faSChristoph Hellwig if (flag != 0 && flag != 1) { 7516708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 752e3d6f909SAndy Grover return -EINVAL; 753c66ac9dbSNicholas Bellinger } 754f55918faSChristoph Hellwig 755c638830dSAndy Grover if (flag) { 756f55918faSChristoph Hellwig pr_err("dpo_emulated not supported\n"); 757e3d6f909SAndy Grover return -EINVAL; 758c66ac9dbSNicholas Bellinger } 759c66ac9dbSNicholas Bellinger 760c638830dSAndy Grover return 0; 761c638830dSAndy Grover } 762d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_emulate_dpo); 763c638830dSAndy Grover 764c66ac9dbSNicholas Bellinger int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) 765c66ac9dbSNicholas Bellinger { 766f55918faSChristoph Hellwig if (flag != 0 && flag != 1) { 7676708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 768e3d6f909SAndy Grover return -EINVAL; 769c66ac9dbSNicholas Bellinger } 7704b36b68cSNicholas Bellinger if (flag && 7714b36b68cSNicholas Bellinger dev->transport->get_write_cache) { 7724b36b68cSNicholas Bellinger pr_err("emulate_fua_write not supported for this device\n"); 7734b36b68cSNicholas Bellinger return -EINVAL; 7744b36b68cSNicholas Bellinger } 7754b36b68cSNicholas Bellinger if (dev->export_count) { 7764b36b68cSNicholas Bellinger pr_err("emulate_fua_write cannot be changed with active" 7774b36b68cSNicholas Bellinger " exports: %d\n", dev->export_count); 7784b36b68cSNicholas Bellinger return -EINVAL; 7794b36b68cSNicholas Bellinger } 7800fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_fua_write = flag; 7816708bb27SAndy Grover pr_debug("dev[%p]: SE Device Forced Unit Access WRITEs: %d\n", 7820fd97ccfSChristoph Hellwig dev, dev->dev_attrib.emulate_fua_write); 783c66ac9dbSNicholas Bellinger return 0; 784c66ac9dbSNicholas Bellinger } 785d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_emulate_fua_write); 786c66ac9dbSNicholas Bellinger 787c66ac9dbSNicholas Bellinger int se_dev_set_emulate_fua_read(struct se_device *dev, int flag) 788c66ac9dbSNicholas Bellinger { 789f55918faSChristoph Hellwig if (flag != 0 && flag != 1) { 7906708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 791e3d6f909SAndy Grover return -EINVAL; 792c66ac9dbSNicholas Bellinger } 793f55918faSChristoph Hellwig 794c638830dSAndy Grover if (flag) { 795f55918faSChristoph Hellwig pr_err("ua read emulated not supported\n"); 796e3d6f909SAndy Grover return -EINVAL; 797c66ac9dbSNicholas Bellinger } 798c66ac9dbSNicholas Bellinger 799c638830dSAndy Grover return 0; 800c638830dSAndy Grover } 801d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_emulate_fua_read); 802c638830dSAndy Grover 803c66ac9dbSNicholas Bellinger int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) 804c66ac9dbSNicholas Bellinger { 805f55918faSChristoph Hellwig if (flag != 0 && flag != 1) { 8066708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 807e3d6f909SAndy Grover return -EINVAL; 808c66ac9dbSNicholas Bellinger } 809fd30e931SNicholas Bellinger if (flag && 81007b8dae3SAndy Grover dev->transport->get_write_cache) { 81107b8dae3SAndy Grover pr_err("emulate_write_cache not supported for this device\n"); 81207b8dae3SAndy Grover return -EINVAL; 813d0c8b259SNicholas Bellinger } 8144b36b68cSNicholas Bellinger if (dev->export_count) { 8154b36b68cSNicholas Bellinger pr_err("emulate_write_cache cannot be changed with active" 8164b36b68cSNicholas Bellinger " exports: %d\n", dev->export_count); 8174b36b68cSNicholas Bellinger return -EINVAL; 8184b36b68cSNicholas Bellinger } 8190fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_write_cache = flag; 8206708bb27SAndy Grover pr_debug("dev[%p]: SE Device WRITE_CACHE_EMULATION flag: %d\n", 8210fd97ccfSChristoph Hellwig dev, dev->dev_attrib.emulate_write_cache); 822c66ac9dbSNicholas Bellinger return 0; 823c66ac9dbSNicholas Bellinger } 824d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_emulate_write_cache); 825c66ac9dbSNicholas Bellinger 826c66ac9dbSNicholas Bellinger int se_dev_set_emulate_ua_intlck_ctrl(struct se_device *dev, int flag) 827c66ac9dbSNicholas Bellinger { 828c66ac9dbSNicholas Bellinger if ((flag != 0) && (flag != 1) && (flag != 2)) { 8296708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 830e3d6f909SAndy Grover return -EINVAL; 831c66ac9dbSNicholas Bellinger } 832c66ac9dbSNicholas Bellinger 8330fd97ccfSChristoph Hellwig if (dev->export_count) { 8346708bb27SAndy Grover pr_err("dev[%p]: Unable to change SE Device" 8350fd97ccfSChristoph Hellwig " UA_INTRLCK_CTRL while export_count is %d\n", 8360fd97ccfSChristoph Hellwig dev, dev->export_count); 837e3d6f909SAndy Grover return -EINVAL; 838c66ac9dbSNicholas Bellinger } 8390fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_ua_intlck_ctrl = flag; 8406708bb27SAndy Grover pr_debug("dev[%p]: SE Device UA_INTRLCK_CTRL flag: %d\n", 8410fd97ccfSChristoph Hellwig dev, dev->dev_attrib.emulate_ua_intlck_ctrl); 842c66ac9dbSNicholas Bellinger 843c66ac9dbSNicholas Bellinger return 0; 844c66ac9dbSNicholas Bellinger } 845d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_emulate_ua_intlck_ctrl); 846c66ac9dbSNicholas Bellinger 847c66ac9dbSNicholas Bellinger int se_dev_set_emulate_tas(struct se_device *dev, int flag) 848c66ac9dbSNicholas Bellinger { 849c66ac9dbSNicholas Bellinger if ((flag != 0) && (flag != 1)) { 8506708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 851e3d6f909SAndy Grover return -EINVAL; 852c66ac9dbSNicholas Bellinger } 853c66ac9dbSNicholas Bellinger 8540fd97ccfSChristoph Hellwig if (dev->export_count) { 8556708bb27SAndy Grover pr_err("dev[%p]: Unable to change SE Device TAS while" 8560fd97ccfSChristoph Hellwig " export_count is %d\n", 8570fd97ccfSChristoph Hellwig dev, dev->export_count); 858e3d6f909SAndy Grover return -EINVAL; 859c66ac9dbSNicholas Bellinger } 8600fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tas = flag; 8616708bb27SAndy Grover pr_debug("dev[%p]: SE Device TASK_ABORTED status bit: %s\n", 8620fd97ccfSChristoph Hellwig dev, (dev->dev_attrib.emulate_tas) ? "Enabled" : "Disabled"); 863c66ac9dbSNicholas Bellinger 864c66ac9dbSNicholas Bellinger return 0; 865c66ac9dbSNicholas Bellinger } 866d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_emulate_tas); 867c66ac9dbSNicholas Bellinger 868c66ac9dbSNicholas Bellinger int se_dev_set_emulate_tpu(struct se_device *dev, int flag) 869c66ac9dbSNicholas Bellinger { 870c66ac9dbSNicholas Bellinger if ((flag != 0) && (flag != 1)) { 8716708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 872e3d6f909SAndy Grover return -EINVAL; 873c66ac9dbSNicholas Bellinger } 874c66ac9dbSNicholas Bellinger /* 875c66ac9dbSNicholas Bellinger * We expect this value to be non-zero when generic Block Layer 876c66ac9dbSNicholas Bellinger * Discard supported is detected iblock_create_virtdevice(). 877c66ac9dbSNicholas Bellinger */ 8780fd97ccfSChristoph Hellwig if (flag && !dev->dev_attrib.max_unmap_block_desc_count) { 8796708bb27SAndy Grover pr_err("Generic Block Discard not supported\n"); 880c66ac9dbSNicholas Bellinger return -ENOSYS; 881c66ac9dbSNicholas Bellinger } 882c66ac9dbSNicholas Bellinger 8830fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tpu = flag; 8846708bb27SAndy Grover pr_debug("dev[%p]: SE Device Thin Provisioning UNMAP bit: %d\n", 885c66ac9dbSNicholas Bellinger dev, flag); 886c66ac9dbSNicholas Bellinger return 0; 887c66ac9dbSNicholas Bellinger } 888d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_emulate_tpu); 889c66ac9dbSNicholas Bellinger 890c66ac9dbSNicholas Bellinger int se_dev_set_emulate_tpws(struct se_device *dev, int flag) 891c66ac9dbSNicholas Bellinger { 892c66ac9dbSNicholas Bellinger if ((flag != 0) && (flag != 1)) { 8936708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 894e3d6f909SAndy Grover return -EINVAL; 895c66ac9dbSNicholas Bellinger } 896c66ac9dbSNicholas Bellinger /* 897c66ac9dbSNicholas Bellinger * We expect this value to be non-zero when generic Block Layer 898c66ac9dbSNicholas Bellinger * Discard supported is detected iblock_create_virtdevice(). 899c66ac9dbSNicholas Bellinger */ 9000fd97ccfSChristoph Hellwig if (flag && !dev->dev_attrib.max_unmap_block_desc_count) { 9016708bb27SAndy Grover pr_err("Generic Block Discard not supported\n"); 902c66ac9dbSNicholas Bellinger return -ENOSYS; 903c66ac9dbSNicholas Bellinger } 904c66ac9dbSNicholas Bellinger 9050fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tpws = flag; 9066708bb27SAndy Grover pr_debug("dev[%p]: SE Device Thin Provisioning WRITE_SAME: %d\n", 907c66ac9dbSNicholas Bellinger dev, flag); 908c66ac9dbSNicholas Bellinger return 0; 909c66ac9dbSNicholas Bellinger } 910d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_emulate_tpws); 911c66ac9dbSNicholas Bellinger 9120123a9ecSNicholas Bellinger int se_dev_set_emulate_caw(struct se_device *dev, int flag) 9130123a9ecSNicholas Bellinger { 9140123a9ecSNicholas Bellinger if (flag != 0 && flag != 1) { 9150123a9ecSNicholas Bellinger pr_err("Illegal value %d\n", flag); 9160123a9ecSNicholas Bellinger return -EINVAL; 9170123a9ecSNicholas Bellinger } 9180123a9ecSNicholas Bellinger dev->dev_attrib.emulate_caw = flag; 9190123a9ecSNicholas Bellinger pr_debug("dev[%p]: SE Device CompareAndWrite (AtomicTestandSet): %d\n", 9200123a9ecSNicholas Bellinger dev, flag); 9210123a9ecSNicholas Bellinger 9220123a9ecSNicholas Bellinger return 0; 9230123a9ecSNicholas Bellinger } 924d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_emulate_caw); 9250123a9ecSNicholas Bellinger 926d397a445SNicholas Bellinger int se_dev_set_emulate_3pc(struct se_device *dev, int flag) 927d397a445SNicholas Bellinger { 928d397a445SNicholas Bellinger if (flag != 0 && flag != 1) { 929d397a445SNicholas Bellinger pr_err("Illegal value %d\n", flag); 930d397a445SNicholas Bellinger return -EINVAL; 931d397a445SNicholas Bellinger } 932d397a445SNicholas Bellinger dev->dev_attrib.emulate_3pc = flag; 933d397a445SNicholas Bellinger pr_debug("dev[%p]: SE Device 3rd Party Copy (EXTENDED_COPY): %d\n", 934d397a445SNicholas Bellinger dev, flag); 935d397a445SNicholas Bellinger 936d397a445SNicholas Bellinger return 0; 937d397a445SNicholas Bellinger } 938d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_emulate_3pc); 939d397a445SNicholas Bellinger 9402ed22c9cSNicholas Bellinger int se_dev_set_pi_prot_type(struct se_device *dev, int flag) 9412ed22c9cSNicholas Bellinger { 9422ed22c9cSNicholas Bellinger int rc, old_prot = dev->dev_attrib.pi_prot_type; 9432ed22c9cSNicholas Bellinger 9442ed22c9cSNicholas Bellinger if (flag != 0 && flag != 1 && flag != 2 && flag != 3) { 9452ed22c9cSNicholas Bellinger pr_err("Illegal value %d for pi_prot_type\n", flag); 9462ed22c9cSNicholas Bellinger return -EINVAL; 9472ed22c9cSNicholas Bellinger } 9482ed22c9cSNicholas Bellinger if (flag == 2) { 9492ed22c9cSNicholas Bellinger pr_err("DIF TYPE2 protection currently not supported\n"); 9502ed22c9cSNicholas Bellinger return -ENOSYS; 9512ed22c9cSNicholas Bellinger } 9522ed22c9cSNicholas Bellinger if (dev->dev_attrib.hw_pi_prot_type) { 9532ed22c9cSNicholas Bellinger pr_warn("DIF protection enabled on underlying hardware," 9542ed22c9cSNicholas Bellinger " ignoring\n"); 9552ed22c9cSNicholas Bellinger return 0; 9562ed22c9cSNicholas Bellinger } 9572ed22c9cSNicholas Bellinger if (!dev->transport->init_prot || !dev->transport->free_prot) { 958448ba904SAndy Grover /* 0 is only allowed value for non-supporting backends */ 959448ba904SAndy Grover if (flag == 0) 960448ba904SAndy Grover return 0; 961448ba904SAndy Grover 9622ed22c9cSNicholas Bellinger pr_err("DIF protection not supported by backend: %s\n", 9632ed22c9cSNicholas Bellinger dev->transport->name); 9642ed22c9cSNicholas Bellinger return -ENOSYS; 9652ed22c9cSNicholas Bellinger } 9662ed22c9cSNicholas Bellinger if (!(dev->dev_flags & DF_CONFIGURED)) { 9672ed22c9cSNicholas Bellinger pr_err("DIF protection requires device to be configured\n"); 9682ed22c9cSNicholas Bellinger return -ENODEV; 9692ed22c9cSNicholas Bellinger } 9702ed22c9cSNicholas Bellinger if (dev->export_count) { 9712ed22c9cSNicholas Bellinger pr_err("dev[%p]: Unable to change SE Device PROT type while" 9722ed22c9cSNicholas Bellinger " export_count is %d\n", dev, dev->export_count); 9732ed22c9cSNicholas Bellinger return -EINVAL; 9742ed22c9cSNicholas Bellinger } 9752ed22c9cSNicholas Bellinger 9762ed22c9cSNicholas Bellinger dev->dev_attrib.pi_prot_type = flag; 9772ed22c9cSNicholas Bellinger 9782ed22c9cSNicholas Bellinger if (flag && !old_prot) { 9792ed22c9cSNicholas Bellinger rc = dev->transport->init_prot(dev); 9802ed22c9cSNicholas Bellinger if (rc) { 9812ed22c9cSNicholas Bellinger dev->dev_attrib.pi_prot_type = old_prot; 9822ed22c9cSNicholas Bellinger return rc; 9832ed22c9cSNicholas Bellinger } 9842ed22c9cSNicholas Bellinger 9852ed22c9cSNicholas Bellinger } else if (!flag && old_prot) { 9862ed22c9cSNicholas Bellinger dev->transport->free_prot(dev); 9872ed22c9cSNicholas Bellinger } 9882ed22c9cSNicholas Bellinger pr_debug("dev[%p]: SE Device Protection Type: %d\n", dev, flag); 9892ed22c9cSNicholas Bellinger 9902ed22c9cSNicholas Bellinger return 0; 9912ed22c9cSNicholas Bellinger } 992d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_pi_prot_type); 9932ed22c9cSNicholas Bellinger 9942ed22c9cSNicholas Bellinger int se_dev_set_pi_prot_format(struct se_device *dev, int flag) 9952ed22c9cSNicholas Bellinger { 9962ed22c9cSNicholas Bellinger int rc; 9972ed22c9cSNicholas Bellinger 9982ed22c9cSNicholas Bellinger if (!flag) 9992ed22c9cSNicholas Bellinger return 0; 10002ed22c9cSNicholas Bellinger 10012ed22c9cSNicholas Bellinger if (flag != 1) { 10022ed22c9cSNicholas Bellinger pr_err("Illegal value %d for pi_prot_format\n", flag); 10032ed22c9cSNicholas Bellinger return -EINVAL; 10042ed22c9cSNicholas Bellinger } 10052ed22c9cSNicholas Bellinger if (!dev->transport->format_prot) { 10062ed22c9cSNicholas Bellinger pr_err("DIF protection format not supported by backend %s\n", 10072ed22c9cSNicholas Bellinger dev->transport->name); 10082ed22c9cSNicholas Bellinger return -ENOSYS; 10092ed22c9cSNicholas Bellinger } 10102ed22c9cSNicholas Bellinger if (!(dev->dev_flags & DF_CONFIGURED)) { 10112ed22c9cSNicholas Bellinger pr_err("DIF protection format requires device to be configured\n"); 10122ed22c9cSNicholas Bellinger return -ENODEV; 10132ed22c9cSNicholas Bellinger } 10142ed22c9cSNicholas Bellinger if (dev->export_count) { 10152ed22c9cSNicholas Bellinger pr_err("dev[%p]: Unable to format SE Device PROT type while" 10162ed22c9cSNicholas Bellinger " export_count is %d\n", dev, dev->export_count); 10172ed22c9cSNicholas Bellinger return -EINVAL; 10182ed22c9cSNicholas Bellinger } 10192ed22c9cSNicholas Bellinger 10202ed22c9cSNicholas Bellinger rc = dev->transport->format_prot(dev); 10212ed22c9cSNicholas Bellinger if (rc) 10222ed22c9cSNicholas Bellinger return rc; 10232ed22c9cSNicholas Bellinger 10242ed22c9cSNicholas Bellinger pr_debug("dev[%p]: SE Device Protection Format complete\n", dev); 10252ed22c9cSNicholas Bellinger 10262ed22c9cSNicholas Bellinger return 0; 10272ed22c9cSNicholas Bellinger } 1028d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_pi_prot_format); 10292ed22c9cSNicholas Bellinger 1030c66ac9dbSNicholas Bellinger int se_dev_set_enforce_pr_isids(struct se_device *dev, int flag) 1031c66ac9dbSNicholas Bellinger { 1032c66ac9dbSNicholas Bellinger if ((flag != 0) && (flag != 1)) { 10336708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 1034e3d6f909SAndy Grover return -EINVAL; 1035c66ac9dbSNicholas Bellinger } 10360fd97ccfSChristoph Hellwig dev->dev_attrib.enforce_pr_isids = flag; 10376708bb27SAndy Grover pr_debug("dev[%p]: SE Device enforce_pr_isids bit: %s\n", dev, 10380fd97ccfSChristoph Hellwig (dev->dev_attrib.enforce_pr_isids) ? "Enabled" : "Disabled"); 1039c66ac9dbSNicholas Bellinger return 0; 1040c66ac9dbSNicholas Bellinger } 1041d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_enforce_pr_isids); 1042c66ac9dbSNicholas Bellinger 104392404e60SNicholas Bellinger int se_dev_set_force_pr_aptpl(struct se_device *dev, int flag) 104492404e60SNicholas Bellinger { 104592404e60SNicholas Bellinger if ((flag != 0) && (flag != 1)) { 104692404e60SNicholas Bellinger printk(KERN_ERR "Illegal value %d\n", flag); 104792404e60SNicholas Bellinger return -EINVAL; 104892404e60SNicholas Bellinger } 104992404e60SNicholas Bellinger if (dev->export_count) { 105092404e60SNicholas Bellinger pr_err("dev[%p]: Unable to set force_pr_aptpl while" 105192404e60SNicholas Bellinger " export_count is %d\n", dev, dev->export_count); 105292404e60SNicholas Bellinger return -EINVAL; 105392404e60SNicholas Bellinger } 105492404e60SNicholas Bellinger 105592404e60SNicholas Bellinger dev->dev_attrib.force_pr_aptpl = flag; 105692404e60SNicholas Bellinger pr_debug("dev[%p]: SE Device force_pr_aptpl: %d\n", dev, flag); 105792404e60SNicholas Bellinger return 0; 105892404e60SNicholas Bellinger } 1059d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_force_pr_aptpl); 106092404e60SNicholas Bellinger 1061e22a7f07SRoland Dreier int se_dev_set_is_nonrot(struct se_device *dev, int flag) 1062e22a7f07SRoland Dreier { 1063e22a7f07SRoland Dreier if ((flag != 0) && (flag != 1)) { 1064e22a7f07SRoland Dreier printk(KERN_ERR "Illegal value %d\n", flag); 1065e22a7f07SRoland Dreier return -EINVAL; 1066e22a7f07SRoland Dreier } 10670fd97ccfSChristoph Hellwig dev->dev_attrib.is_nonrot = flag; 10685de619a3SNicholas Bellinger pr_debug("dev[%p]: SE Device is_nonrot bit: %d\n", 1069e22a7f07SRoland Dreier dev, flag); 1070e22a7f07SRoland Dreier return 0; 1071e22a7f07SRoland Dreier } 1072d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_is_nonrot); 1073e22a7f07SRoland Dreier 10745de619a3SNicholas Bellinger int se_dev_set_emulate_rest_reord(struct se_device *dev, int flag) 10755de619a3SNicholas Bellinger { 10765de619a3SNicholas Bellinger if (flag != 0) { 10775de619a3SNicholas Bellinger printk(KERN_ERR "dev[%p]: SE Device emulatation of restricted" 10785de619a3SNicholas Bellinger " reordering not implemented\n", dev); 10795de619a3SNicholas Bellinger return -ENOSYS; 10805de619a3SNicholas Bellinger } 10810fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_rest_reord = flag; 10825de619a3SNicholas Bellinger pr_debug("dev[%p]: SE Device emulate_rest_reord: %d\n", dev, flag); 10835de619a3SNicholas Bellinger return 0; 10845de619a3SNicholas Bellinger } 1085d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_emulate_rest_reord); 10865de619a3SNicholas Bellinger 1087c66ac9dbSNicholas Bellinger /* 1088c66ac9dbSNicholas Bellinger * Note, this can only be called on unexported SE Device Object. 1089c66ac9dbSNicholas Bellinger */ 1090c66ac9dbSNicholas Bellinger int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth) 1091c66ac9dbSNicholas Bellinger { 10920fd97ccfSChristoph Hellwig if (dev->export_count) { 10936708bb27SAndy Grover pr_err("dev[%p]: Unable to change SE Device TCQ while" 10940fd97ccfSChristoph Hellwig " export_count is %d\n", 10950fd97ccfSChristoph Hellwig dev, dev->export_count); 1096e3d6f909SAndy Grover return -EINVAL; 1097c66ac9dbSNicholas Bellinger } 10986708bb27SAndy Grover if (!queue_depth) { 10996708bb27SAndy Grover pr_err("dev[%p]: Illegal ZERO value for queue" 1100c66ac9dbSNicholas Bellinger "_depth\n", dev); 1101e3d6f909SAndy Grover return -EINVAL; 1102c66ac9dbSNicholas Bellinger } 1103c66ac9dbSNicholas Bellinger 11040fd97ccfSChristoph Hellwig if (queue_depth > dev->dev_attrib.queue_depth) { 11050fd97ccfSChristoph Hellwig if (queue_depth > dev->dev_attrib.hw_queue_depth) { 11066708bb27SAndy Grover pr_err("dev[%p]: Passed queue_depth:" 1107c66ac9dbSNicholas Bellinger " %u exceeds TCM/SE_Device MAX" 1108c66ac9dbSNicholas Bellinger " TCQ: %u\n", dev, queue_depth, 11090fd97ccfSChristoph Hellwig dev->dev_attrib.hw_queue_depth); 1110e3d6f909SAndy Grover return -EINVAL; 1111c66ac9dbSNicholas Bellinger } 1112c66ac9dbSNicholas Bellinger } 11130fd97ccfSChristoph Hellwig dev->dev_attrib.queue_depth = dev->queue_depth = queue_depth; 11146708bb27SAndy Grover pr_debug("dev[%p]: SE Device TCQ Depth changed to: %u\n", 1115c66ac9dbSNicholas Bellinger dev, queue_depth); 1116c66ac9dbSNicholas Bellinger return 0; 1117c66ac9dbSNicholas Bellinger } 1118d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_queue_depth); 1119c66ac9dbSNicholas Bellinger 1120c66ac9dbSNicholas Bellinger int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) 1121c66ac9dbSNicholas Bellinger { 11220fd97ccfSChristoph Hellwig if (dev->export_count) { 11236708bb27SAndy Grover pr_err("dev[%p]: Unable to change SE Device" 11240fd97ccfSChristoph Hellwig " optimal_sectors while export_count is %d\n", 11250fd97ccfSChristoph Hellwig dev, dev->export_count); 1126c66ac9dbSNicholas Bellinger return -EINVAL; 1127c66ac9dbSNicholas Bellinger } 1128046ba642SNicholas Bellinger if (optimal_sectors > dev->dev_attrib.hw_max_sectors) { 11296708bb27SAndy Grover pr_err("dev[%p]: Passed optimal_sectors %u cannot be" 1130046ba642SNicholas Bellinger " greater than hw_max_sectors: %u\n", dev, 1131046ba642SNicholas Bellinger optimal_sectors, dev->dev_attrib.hw_max_sectors); 1132c66ac9dbSNicholas Bellinger return -EINVAL; 1133c66ac9dbSNicholas Bellinger } 1134c66ac9dbSNicholas Bellinger 11350fd97ccfSChristoph Hellwig dev->dev_attrib.optimal_sectors = optimal_sectors; 11366708bb27SAndy Grover pr_debug("dev[%p]: SE Device optimal_sectors changed to %u\n", 1137c66ac9dbSNicholas Bellinger dev, optimal_sectors); 1138c66ac9dbSNicholas Bellinger return 0; 1139c66ac9dbSNicholas Bellinger } 1140d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_optimal_sectors); 1141c66ac9dbSNicholas Bellinger 1142c66ac9dbSNicholas Bellinger int se_dev_set_block_size(struct se_device *dev, u32 block_size) 1143c66ac9dbSNicholas Bellinger { 11440fd97ccfSChristoph Hellwig if (dev->export_count) { 11456708bb27SAndy Grover pr_err("dev[%p]: Unable to change SE Device block_size" 11460fd97ccfSChristoph Hellwig " while export_count is %d\n", 11470fd97ccfSChristoph Hellwig dev, dev->export_count); 1148e3d6f909SAndy Grover return -EINVAL; 1149c66ac9dbSNicholas Bellinger } 1150c66ac9dbSNicholas Bellinger 1151c66ac9dbSNicholas Bellinger if ((block_size != 512) && 1152c66ac9dbSNicholas Bellinger (block_size != 1024) && 1153c66ac9dbSNicholas Bellinger (block_size != 2048) && 1154c66ac9dbSNicholas Bellinger (block_size != 4096)) { 11556708bb27SAndy Grover pr_err("dev[%p]: Illegal value for block_device: %u" 1156c66ac9dbSNicholas Bellinger " for SE device, must be 512, 1024, 2048 or 4096\n", 1157c66ac9dbSNicholas Bellinger dev, block_size); 1158e3d6f909SAndy Grover return -EINVAL; 1159c66ac9dbSNicholas Bellinger } 1160c66ac9dbSNicholas Bellinger 11610fd97ccfSChristoph Hellwig dev->dev_attrib.block_size = block_size; 11626708bb27SAndy Grover pr_debug("dev[%p]: SE Device block_size changed to %u\n", 1163c66ac9dbSNicholas Bellinger dev, block_size); 116495cadaceSNicholas Bellinger 116595cadaceSNicholas Bellinger if (dev->dev_attrib.max_bytes_per_io) 116695cadaceSNicholas Bellinger dev->dev_attrib.hw_max_sectors = 116795cadaceSNicholas Bellinger dev->dev_attrib.max_bytes_per_io / block_size; 116895cadaceSNicholas Bellinger 1169c66ac9dbSNicholas Bellinger return 0; 1170c66ac9dbSNicholas Bellinger } 1171d30cd123SNicholas Bellinger EXPORT_SYMBOL(se_dev_set_block_size); 1172c66ac9dbSNicholas Bellinger 1173c66ac9dbSNicholas Bellinger struct se_lun *core_dev_add_lun( 1174c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1175c66ac9dbSNicholas Bellinger struct se_device *dev, 11762af7973aSAndy Grover u32 unpacked_lun) 1177c66ac9dbSNicholas Bellinger { 11782af7973aSAndy Grover struct se_lun *lun; 11798d9efe53SSebastian Andrzej Siewior int rc; 1180c66ac9dbSNicholas Bellinger 1181d344f8a1SAndy Grover lun = core_tpg_alloc_lun(tpg, unpacked_lun); 11822af7973aSAndy Grover if (IS_ERR(lun)) 11832af7973aSAndy Grover return lun; 1184c66ac9dbSNicholas Bellinger 1185d344f8a1SAndy Grover rc = core_tpg_add_lun(tpg, lun, 118658d92618SNicholas Bellinger TRANSPORT_LUNFLAGS_READ_WRITE, dev); 11878d9efe53SSebastian Andrzej Siewior if (rc < 0) 11888d9efe53SSebastian Andrzej Siewior return ERR_PTR(rc); 1189c66ac9dbSNicholas Bellinger 11906708bb27SAndy Grover pr_debug("%s_TPG[%u]_LUN[%u] - Activated %s Logical Unit from" 1191e3d6f909SAndy Grover " CORE HBA: %u\n", tpg->se_tpg_tfo->get_fabric_name(), 11922af7973aSAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, 11932dca673bSAndy Grover tpg->se_tpg_tfo->get_fabric_name(), dev->se_hba->hba_id); 1194c66ac9dbSNicholas Bellinger /* 1195c66ac9dbSNicholas Bellinger * Update LUN maps for dynamically added initiators when 1196c66ac9dbSNicholas Bellinger * generate_node_acl is enabled. 1197c66ac9dbSNicholas Bellinger */ 1198e3d6f909SAndy Grover if (tpg->se_tpg_tfo->tpg_check_demo_mode(tpg)) { 1199c66ac9dbSNicholas Bellinger struct se_node_acl *acl; 120028638887SRoland Dreier spin_lock_irq(&tpg->acl_node_lock); 1201c66ac9dbSNicholas Bellinger list_for_each_entry(acl, &tpg->acl_node_list, acl_list) { 1202052605c6SNicholas Bellinger if (acl->dynamic_node_acl && 1203052605c6SNicholas Bellinger (!tpg->se_tpg_tfo->tpg_check_demo_mode_login_only || 1204052605c6SNicholas Bellinger !tpg->se_tpg_tfo->tpg_check_demo_mode_login_only(tpg))) { 120528638887SRoland Dreier spin_unlock_irq(&tpg->acl_node_lock); 1206c66ac9dbSNicholas Bellinger core_tpg_add_node_to_devs(acl, tpg); 120728638887SRoland Dreier spin_lock_irq(&tpg->acl_node_lock); 1208c66ac9dbSNicholas Bellinger } 1209c66ac9dbSNicholas Bellinger } 121028638887SRoland Dreier spin_unlock_irq(&tpg->acl_node_lock); 1211c66ac9dbSNicholas Bellinger } 1212c66ac9dbSNicholas Bellinger 12132af7973aSAndy Grover return lun; 1214c66ac9dbSNicholas Bellinger } 1215c66ac9dbSNicholas Bellinger 1216c66ac9dbSNicholas Bellinger /* core_dev_del_lun(): 1217c66ac9dbSNicholas Bellinger * 1218c66ac9dbSNicholas Bellinger * 1219c66ac9dbSNicholas Bellinger */ 1220cd9d7cbaSAndy Grover void core_dev_del_lun( 1221c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1222cd9d7cbaSAndy Grover struct se_lun *lun) 1223c66ac9dbSNicholas Bellinger { 1224cd9d7cbaSAndy Grover pr_debug("%s_TPG[%u]_LUN[%u] - Deactivating %s Logical Unit from" 1225e3d6f909SAndy Grover " device object\n", tpg->se_tpg_tfo->get_fabric_name(), 1226cd9d7cbaSAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, 1227e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 1228c66ac9dbSNicholas Bellinger 1229cd9d7cbaSAndy Grover core_tpg_remove_lun(tpg, lun); 1230c66ac9dbSNicholas Bellinger } 1231c66ac9dbSNicholas Bellinger 1232c66ac9dbSNicholas Bellinger struct se_lun *core_get_lun_from_tpg(struct se_portal_group *tpg, u32 unpacked_lun) 1233c66ac9dbSNicholas Bellinger { 1234c66ac9dbSNicholas Bellinger struct se_lun *lun; 1235c66ac9dbSNicholas Bellinger 1236c66ac9dbSNicholas Bellinger spin_lock(&tpg->tpg_lun_lock); 1237c66ac9dbSNicholas Bellinger if (unpacked_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) { 12386708bb27SAndy Grover pr_err("%s LUN: %u exceeds TRANSPORT_MAX_LUNS" 1239c66ac9dbSNicholas Bellinger "_PER_TPG-1: %u for Target Portal Group: %hu\n", 1240e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, 1241c66ac9dbSNicholas Bellinger TRANSPORT_MAX_LUNS_PER_TPG-1, 1242e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg)); 1243c66ac9dbSNicholas Bellinger spin_unlock(&tpg->tpg_lun_lock); 1244c66ac9dbSNicholas Bellinger return NULL; 1245c66ac9dbSNicholas Bellinger } 12464a5a75f3SJörn Engel lun = tpg->tpg_lun_list[unpacked_lun]; 1247c66ac9dbSNicholas Bellinger 1248c66ac9dbSNicholas Bellinger if (lun->lun_status != TRANSPORT_LUN_STATUS_FREE) { 12496708bb27SAndy Grover pr_err("%s Logical Unit Number: %u is not free on" 1250c66ac9dbSNicholas Bellinger " Target Portal Group: %hu, ignoring request.\n", 1251e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, 1252e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg)); 1253c66ac9dbSNicholas Bellinger spin_unlock(&tpg->tpg_lun_lock); 1254c66ac9dbSNicholas Bellinger return NULL; 1255c66ac9dbSNicholas Bellinger } 1256c66ac9dbSNicholas Bellinger spin_unlock(&tpg->tpg_lun_lock); 1257c66ac9dbSNicholas Bellinger 1258c66ac9dbSNicholas Bellinger return lun; 1259c66ac9dbSNicholas Bellinger } 1260c66ac9dbSNicholas Bellinger 1261c66ac9dbSNicholas Bellinger /* core_dev_get_lun(): 1262c66ac9dbSNicholas Bellinger * 1263c66ac9dbSNicholas Bellinger * 1264c66ac9dbSNicholas Bellinger */ 1265c66ac9dbSNicholas Bellinger static struct se_lun *core_dev_get_lun(struct se_portal_group *tpg, u32 unpacked_lun) 1266c66ac9dbSNicholas Bellinger { 1267c66ac9dbSNicholas Bellinger struct se_lun *lun; 1268c66ac9dbSNicholas Bellinger 1269c66ac9dbSNicholas Bellinger spin_lock(&tpg->tpg_lun_lock); 1270c66ac9dbSNicholas Bellinger if (unpacked_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) { 12716708bb27SAndy Grover pr_err("%s LUN: %u exceeds TRANSPORT_MAX_LUNS_PER" 1272c66ac9dbSNicholas Bellinger "_TPG-1: %u for Target Portal Group: %hu\n", 1273e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, 1274c66ac9dbSNicholas Bellinger TRANSPORT_MAX_LUNS_PER_TPG-1, 1275e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg)); 1276c66ac9dbSNicholas Bellinger spin_unlock(&tpg->tpg_lun_lock); 1277c66ac9dbSNicholas Bellinger return NULL; 1278c66ac9dbSNicholas Bellinger } 12794a5a75f3SJörn Engel lun = tpg->tpg_lun_list[unpacked_lun]; 1280c66ac9dbSNicholas Bellinger 1281c66ac9dbSNicholas Bellinger if (lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE) { 12826708bb27SAndy Grover pr_err("%s Logical Unit Number: %u is not active on" 1283c66ac9dbSNicholas Bellinger " Target Portal Group: %hu, ignoring request.\n", 1284e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, 1285e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg)); 1286c66ac9dbSNicholas Bellinger spin_unlock(&tpg->tpg_lun_lock); 1287c66ac9dbSNicholas Bellinger return NULL; 1288c66ac9dbSNicholas Bellinger } 1289c66ac9dbSNicholas Bellinger spin_unlock(&tpg->tpg_lun_lock); 1290c66ac9dbSNicholas Bellinger 1291c66ac9dbSNicholas Bellinger return lun; 1292c66ac9dbSNicholas Bellinger } 1293c66ac9dbSNicholas Bellinger 1294c66ac9dbSNicholas Bellinger struct se_lun_acl *core_dev_init_initiator_node_lun_acl( 1295c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1296fcf29481SNicholas Bellinger struct se_node_acl *nacl, 1297c66ac9dbSNicholas Bellinger u32 mapped_lun, 1298c66ac9dbSNicholas Bellinger int *ret) 1299c66ac9dbSNicholas Bellinger { 1300c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl; 1301c66ac9dbSNicholas Bellinger 1302fcf29481SNicholas Bellinger if (strlen(nacl->initiatorname) >= TRANSPORT_IQN_LEN) { 13036708bb27SAndy Grover pr_err("%s InitiatorName exceeds maximum size.\n", 1304e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 1305c66ac9dbSNicholas Bellinger *ret = -EOVERFLOW; 1306c66ac9dbSNicholas Bellinger return NULL; 1307c66ac9dbSNicholas Bellinger } 1308c66ac9dbSNicholas Bellinger lacl = kzalloc(sizeof(struct se_lun_acl), GFP_KERNEL); 13096708bb27SAndy Grover if (!lacl) { 13106708bb27SAndy Grover pr_err("Unable to allocate memory for struct se_lun_acl.\n"); 1311c66ac9dbSNicholas Bellinger *ret = -ENOMEM; 1312c66ac9dbSNicholas Bellinger return NULL; 1313c66ac9dbSNicholas Bellinger } 1314c66ac9dbSNicholas Bellinger 1315c66ac9dbSNicholas Bellinger INIT_LIST_HEAD(&lacl->lacl_list); 1316c66ac9dbSNicholas Bellinger lacl->mapped_lun = mapped_lun; 1317c66ac9dbSNicholas Bellinger lacl->se_lun_nacl = nacl; 1318fcf29481SNicholas Bellinger snprintf(lacl->initiatorname, TRANSPORT_IQN_LEN, "%s", 1319fcf29481SNicholas Bellinger nacl->initiatorname); 1320c66ac9dbSNicholas Bellinger 1321c66ac9dbSNicholas Bellinger return lacl; 1322c66ac9dbSNicholas Bellinger } 1323c66ac9dbSNicholas Bellinger 1324c66ac9dbSNicholas Bellinger int core_dev_add_initiator_node_lun_acl( 1325c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1326c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl, 1327c66ac9dbSNicholas Bellinger u32 unpacked_lun, 1328c66ac9dbSNicholas Bellinger u32 lun_access) 1329c66ac9dbSNicholas Bellinger { 1330c66ac9dbSNicholas Bellinger struct se_lun *lun; 1331c66ac9dbSNicholas Bellinger struct se_node_acl *nacl; 1332c66ac9dbSNicholas Bellinger 1333c66ac9dbSNicholas Bellinger lun = core_dev_get_lun(tpg, unpacked_lun); 13346708bb27SAndy Grover if (!lun) { 13356708bb27SAndy Grover pr_err("%s Logical Unit Number: %u is not active on" 1336c66ac9dbSNicholas Bellinger " Target Portal Group: %hu, ignoring request.\n", 1337e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, 1338e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg)); 1339c66ac9dbSNicholas Bellinger return -EINVAL; 1340c66ac9dbSNicholas Bellinger } 1341c66ac9dbSNicholas Bellinger 1342c66ac9dbSNicholas Bellinger nacl = lacl->se_lun_nacl; 13436708bb27SAndy Grover if (!nacl) 1344c66ac9dbSNicholas Bellinger return -EINVAL; 1345c66ac9dbSNicholas Bellinger 1346c66ac9dbSNicholas Bellinger if ((lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) && 1347c66ac9dbSNicholas Bellinger (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE)) 1348c66ac9dbSNicholas Bellinger lun_access = TRANSPORT_LUNFLAGS_READ_ONLY; 1349c66ac9dbSNicholas Bellinger 1350c66ac9dbSNicholas Bellinger lacl->se_lun = lun; 1351c66ac9dbSNicholas Bellinger 1352e80ac6c4SAndy Grover if (core_enable_device_list_for_node(lun, lacl, lacl->mapped_lun, 1353e80ac6c4SAndy Grover lun_access, nacl, tpg) < 0) 1354c66ac9dbSNicholas Bellinger return -EINVAL; 1355c66ac9dbSNicholas Bellinger 1356c66ac9dbSNicholas Bellinger spin_lock(&lun->lun_acl_lock); 1357c66ac9dbSNicholas Bellinger list_add_tail(&lacl->lacl_list, &lun->lun_acl_list); 135833940d09SJoern Engel atomic_inc_mb(&lun->lun_acl_count); 1359c66ac9dbSNicholas Bellinger spin_unlock(&lun->lun_acl_lock); 1360c66ac9dbSNicholas Bellinger 13616708bb27SAndy Grover pr_debug("%s_TPG[%hu]_LUN[%u->%u] - Added %s ACL for " 1362e3d6f909SAndy Grover " InitiatorNode: %s\n", tpg->se_tpg_tfo->get_fabric_name(), 1363e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), unpacked_lun, lacl->mapped_lun, 1364c66ac9dbSNicholas Bellinger (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) ? "RW" : "RO", 1365c66ac9dbSNicholas Bellinger lacl->initiatorname); 1366c66ac9dbSNicholas Bellinger /* 1367c66ac9dbSNicholas Bellinger * Check to see if there are any existing persistent reservation APTPL 1368c66ac9dbSNicholas Bellinger * pre-registrations that need to be enabled for this LUN ACL.. 1369c66ac9dbSNicholas Bellinger */ 1370e2480563SNicholas Bellinger core_scsi3_check_aptpl_registration(lun->lun_se_dev, tpg, lun, nacl, 1371e2480563SNicholas Bellinger lacl->mapped_lun); 1372c66ac9dbSNicholas Bellinger return 0; 1373c66ac9dbSNicholas Bellinger } 1374c66ac9dbSNicholas Bellinger 1375c66ac9dbSNicholas Bellinger /* core_dev_del_initiator_node_lun_acl(): 1376c66ac9dbSNicholas Bellinger * 1377c66ac9dbSNicholas Bellinger * 1378c66ac9dbSNicholas Bellinger */ 1379c66ac9dbSNicholas Bellinger int core_dev_del_initiator_node_lun_acl( 1380c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1381c66ac9dbSNicholas Bellinger struct se_lun *lun, 1382c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl) 1383c66ac9dbSNicholas Bellinger { 1384c66ac9dbSNicholas Bellinger struct se_node_acl *nacl; 1385c66ac9dbSNicholas Bellinger 1386c66ac9dbSNicholas Bellinger nacl = lacl->se_lun_nacl; 13876708bb27SAndy Grover if (!nacl) 1388c66ac9dbSNicholas Bellinger return -EINVAL; 1389c66ac9dbSNicholas Bellinger 1390c66ac9dbSNicholas Bellinger spin_lock(&lun->lun_acl_lock); 1391c66ac9dbSNicholas Bellinger list_del(&lacl->lacl_list); 139233940d09SJoern Engel atomic_dec_mb(&lun->lun_acl_count); 1393c66ac9dbSNicholas Bellinger spin_unlock(&lun->lun_acl_lock); 1394c66ac9dbSNicholas Bellinger 1395e80ac6c4SAndy Grover core_disable_device_list_for_node(lun, NULL, lacl->mapped_lun, 1396e80ac6c4SAndy Grover TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg); 1397c66ac9dbSNicholas Bellinger 1398c66ac9dbSNicholas Bellinger lacl->se_lun = NULL; 1399c66ac9dbSNicholas Bellinger 14006708bb27SAndy Grover pr_debug("%s_TPG[%hu]_LUN[%u] - Removed ACL for" 1401c66ac9dbSNicholas Bellinger " InitiatorNode: %s Mapped LUN: %u\n", 1402e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), 1403e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, 1404c66ac9dbSNicholas Bellinger lacl->initiatorname, lacl->mapped_lun); 1405c66ac9dbSNicholas Bellinger 1406c66ac9dbSNicholas Bellinger return 0; 1407c66ac9dbSNicholas Bellinger } 1408c66ac9dbSNicholas Bellinger 1409c66ac9dbSNicholas Bellinger void core_dev_free_initiator_node_lun_acl( 1410c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1411c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl) 1412c66ac9dbSNicholas Bellinger { 14136708bb27SAndy Grover pr_debug("%s_TPG[%hu] - Freeing ACL for %s InitiatorNode: %s" 1414e3d6f909SAndy Grover " Mapped LUN: %u\n", tpg->se_tpg_tfo->get_fabric_name(), 1415e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), 1416e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), 1417c66ac9dbSNicholas Bellinger lacl->initiatorname, lacl->mapped_lun); 1418c66ac9dbSNicholas Bellinger 1419c66ac9dbSNicholas Bellinger kfree(lacl); 1420c66ac9dbSNicholas Bellinger } 1421c66ac9dbSNicholas Bellinger 14220fd97ccfSChristoph Hellwig static void scsi_dump_inquiry(struct se_device *dev) 14230fd97ccfSChristoph Hellwig { 14240fd97ccfSChristoph Hellwig struct t10_wwn *wwn = &dev->t10_wwn; 14250fd97ccfSChristoph Hellwig char buf[17]; 14260fd97ccfSChristoph Hellwig int i, device_type; 14270fd97ccfSChristoph Hellwig /* 14280fd97ccfSChristoph Hellwig * Print Linux/SCSI style INQUIRY formatting to the kernel ring buffer 14290fd97ccfSChristoph Hellwig */ 14300fd97ccfSChristoph Hellwig for (i = 0; i < 8; i++) 14310fd97ccfSChristoph Hellwig if (wwn->vendor[i] >= 0x20) 14320fd97ccfSChristoph Hellwig buf[i] = wwn->vendor[i]; 14330fd97ccfSChristoph Hellwig else 14340fd97ccfSChristoph Hellwig buf[i] = ' '; 14350fd97ccfSChristoph Hellwig buf[i] = '\0'; 14360fd97ccfSChristoph Hellwig pr_debug(" Vendor: %s\n", buf); 14370fd97ccfSChristoph Hellwig 14380fd97ccfSChristoph Hellwig for (i = 0; i < 16; i++) 14390fd97ccfSChristoph Hellwig if (wwn->model[i] >= 0x20) 14400fd97ccfSChristoph Hellwig buf[i] = wwn->model[i]; 14410fd97ccfSChristoph Hellwig else 14420fd97ccfSChristoph Hellwig buf[i] = ' '; 14430fd97ccfSChristoph Hellwig buf[i] = '\0'; 14440fd97ccfSChristoph Hellwig pr_debug(" Model: %s\n", buf); 14450fd97ccfSChristoph Hellwig 14460fd97ccfSChristoph Hellwig for (i = 0; i < 4; i++) 14470fd97ccfSChristoph Hellwig if (wwn->revision[i] >= 0x20) 14480fd97ccfSChristoph Hellwig buf[i] = wwn->revision[i]; 14490fd97ccfSChristoph Hellwig else 14500fd97ccfSChristoph Hellwig buf[i] = ' '; 14510fd97ccfSChristoph Hellwig buf[i] = '\0'; 14520fd97ccfSChristoph Hellwig pr_debug(" Revision: %s\n", buf); 14530fd97ccfSChristoph Hellwig 14540fd97ccfSChristoph Hellwig device_type = dev->transport->get_device_type(dev); 14550fd97ccfSChristoph Hellwig pr_debug(" Type: %s ", scsi_device_type(device_type)); 14560fd97ccfSChristoph Hellwig } 14570fd97ccfSChristoph Hellwig 14580fd97ccfSChristoph Hellwig struct se_device *target_alloc_device(struct se_hba *hba, const char *name) 14590fd97ccfSChristoph Hellwig { 14600fd97ccfSChristoph Hellwig struct se_device *dev; 14614863e525SNicholas Bellinger struct se_lun *xcopy_lun; 14620fd97ccfSChristoph Hellwig 14630fd97ccfSChristoph Hellwig dev = hba->transport->alloc_device(hba, name); 14640fd97ccfSChristoph Hellwig if (!dev) 14650fd97ccfSChristoph Hellwig return NULL; 14660fd97ccfSChristoph Hellwig 14670ff87549SNicholas Bellinger dev->dev_link_magic = SE_DEV_LINK_MAGIC; 14680fd97ccfSChristoph Hellwig dev->se_hba = hba; 14690fd97ccfSChristoph Hellwig dev->transport = hba->transport; 14702ed22c9cSNicholas Bellinger dev->prot_length = sizeof(struct se_dif_v1_tuple); 14710fd97ccfSChristoph Hellwig 14720fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->dev_list); 14730fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->dev_sep_list); 14740fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->dev_tmr_list); 14750fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->delayed_cmd_list); 14760fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->state_list); 14770fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->qf_cmd_list); 1478d9ea32bfSNicholas Bellinger INIT_LIST_HEAD(&dev->g_dev_node); 14790fd97ccfSChristoph Hellwig spin_lock_init(&dev->execute_task_lock); 14800fd97ccfSChristoph Hellwig spin_lock_init(&dev->delayed_cmd_lock); 14810fd97ccfSChristoph Hellwig spin_lock_init(&dev->dev_reservation_lock); 14820fd97ccfSChristoph Hellwig spin_lock_init(&dev->se_port_lock); 14830fd97ccfSChristoph Hellwig spin_lock_init(&dev->se_tmr_lock); 14840fd97ccfSChristoph Hellwig spin_lock_init(&dev->qf_cmd_lock); 148568ff9b9bSNicholas Bellinger sema_init(&dev->caw_sem, 1); 14860fd97ccfSChristoph Hellwig atomic_set(&dev->dev_ordered_id, 0); 14870fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_wwn.t10_vpd_list); 14880fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_wwn.t10_vpd_lock); 14890fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_pr.registration_list); 14900fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_pr.aptpl_reg_list); 14910fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_pr.registration_lock); 14920fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_pr.aptpl_reg_lock); 14930fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_alua.tg_pt_gps_list); 14940fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_alua.tg_pt_gps_lock); 1495c66094bfSHannes Reinecke INIT_LIST_HEAD(&dev->t10_alua.lba_map_list); 1496c66094bfSHannes Reinecke spin_lock_init(&dev->t10_alua.lba_map_lock); 14970fd97ccfSChristoph Hellwig 14980fd97ccfSChristoph Hellwig dev->t10_wwn.t10_dev = dev; 14990fd97ccfSChristoph Hellwig dev->t10_alua.t10_dev = dev; 15000fd97ccfSChristoph Hellwig 15010fd97ccfSChristoph Hellwig dev->dev_attrib.da_dev = dev; 1502adfa9570STregaron Bayly dev->dev_attrib.emulate_model_alias = DA_EMULATE_MODEL_ALIAS; 15030fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_dpo = DA_EMULATE_DPO; 15040fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_fua_write = DA_EMULATE_FUA_WRITE; 15050fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_fua_read = DA_EMULATE_FUA_READ; 15060fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_write_cache = DA_EMULATE_WRITE_CACHE; 15070fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_ua_intlck_ctrl = DA_EMULATE_UA_INTLLCK_CTRL; 15080fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tas = DA_EMULATE_TAS; 15090fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tpu = DA_EMULATE_TPU; 15100fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tpws = DA_EMULATE_TPWS; 15110123a9ecSNicholas Bellinger dev->dev_attrib.emulate_caw = DA_EMULATE_CAW; 1512d397a445SNicholas Bellinger dev->dev_attrib.emulate_3pc = DA_EMULATE_3PC; 15132ed22c9cSNicholas Bellinger dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE0_PROT; 15140fd97ccfSChristoph Hellwig dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS; 151592404e60SNicholas Bellinger dev->dev_attrib.force_pr_aptpl = DA_FORCE_PR_APTPL; 15160fd97ccfSChristoph Hellwig dev->dev_attrib.is_nonrot = DA_IS_NONROT; 15170fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD; 15180fd97ccfSChristoph Hellwig dev->dev_attrib.max_unmap_lba_count = DA_MAX_UNMAP_LBA_COUNT; 15190fd97ccfSChristoph Hellwig dev->dev_attrib.max_unmap_block_desc_count = 15200fd97ccfSChristoph Hellwig DA_MAX_UNMAP_BLOCK_DESC_COUNT; 15210fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity = DA_UNMAP_GRANULARITY_DEFAULT; 15220fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity_alignment = 15230fd97ccfSChristoph Hellwig DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT; 1524773cbaf7SNicholas Bellinger dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN; 15250fd97ccfSChristoph Hellwig 15264863e525SNicholas Bellinger xcopy_lun = &dev->xcopy_lun; 15274863e525SNicholas Bellinger xcopy_lun->lun_se_dev = dev; 15284863e525SNicholas Bellinger init_completion(&xcopy_lun->lun_shutdown_comp); 15294863e525SNicholas Bellinger INIT_LIST_HEAD(&xcopy_lun->lun_acl_list); 15304863e525SNicholas Bellinger spin_lock_init(&xcopy_lun->lun_acl_lock); 15314863e525SNicholas Bellinger spin_lock_init(&xcopy_lun->lun_sep_lock); 15324863e525SNicholas Bellinger init_completion(&xcopy_lun->lun_ref_comp); 15334863e525SNicholas Bellinger 15340fd97ccfSChristoph Hellwig return dev; 15350fd97ccfSChristoph Hellwig } 15360fd97ccfSChristoph Hellwig 15370fd97ccfSChristoph Hellwig int target_configure_device(struct se_device *dev) 15380fd97ccfSChristoph Hellwig { 15390fd97ccfSChristoph Hellwig struct se_hba *hba = dev->se_hba; 15400fd97ccfSChristoph Hellwig int ret; 15410fd97ccfSChristoph Hellwig 15420fd97ccfSChristoph Hellwig if (dev->dev_flags & DF_CONFIGURED) { 15430fd97ccfSChristoph Hellwig pr_err("se_dev->se_dev_ptr already set for storage" 15440fd97ccfSChristoph Hellwig " object\n"); 15450fd97ccfSChristoph Hellwig return -EEXIST; 15460fd97ccfSChristoph Hellwig } 15470fd97ccfSChristoph Hellwig 15480fd97ccfSChristoph Hellwig ret = dev->transport->configure_device(dev); 15490fd97ccfSChristoph Hellwig if (ret) 15500fd97ccfSChristoph Hellwig goto out; 15510fd97ccfSChristoph Hellwig /* 15520fd97ccfSChristoph Hellwig * XXX: there is not much point to have two different values here.. 15530fd97ccfSChristoph Hellwig */ 15540fd97ccfSChristoph Hellwig dev->dev_attrib.block_size = dev->dev_attrib.hw_block_size; 15550fd97ccfSChristoph Hellwig dev->dev_attrib.queue_depth = dev->dev_attrib.hw_queue_depth; 15560fd97ccfSChristoph Hellwig 15570fd97ccfSChristoph Hellwig /* 15580fd97ccfSChristoph Hellwig * Align max_hw_sectors down to PAGE_SIZE I/O transfers 15590fd97ccfSChristoph Hellwig */ 15600fd97ccfSChristoph Hellwig dev->dev_attrib.hw_max_sectors = 15610fd97ccfSChristoph Hellwig se_dev_align_max_sectors(dev->dev_attrib.hw_max_sectors, 15620fd97ccfSChristoph Hellwig dev->dev_attrib.hw_block_size); 1563046ba642SNicholas Bellinger dev->dev_attrib.optimal_sectors = dev->dev_attrib.hw_max_sectors; 15640fd97ccfSChristoph Hellwig 15650fd97ccfSChristoph Hellwig dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX); 15660fd97ccfSChristoph Hellwig dev->creation_time = get_jiffies_64(); 15670fd97ccfSChristoph Hellwig 15680fd97ccfSChristoph Hellwig ret = core_setup_alua(dev); 15690fd97ccfSChristoph Hellwig if (ret) 15700fd97ccfSChristoph Hellwig goto out; 15710fd97ccfSChristoph Hellwig 15720fd97ccfSChristoph Hellwig /* 15730fd97ccfSChristoph Hellwig * Startup the struct se_device processing thread 15740fd97ccfSChristoph Hellwig */ 15750fd97ccfSChristoph Hellwig dev->tmr_wq = alloc_workqueue("tmr-%s", WQ_MEM_RECLAIM | WQ_UNBOUND, 1, 15760fd97ccfSChristoph Hellwig dev->transport->name); 15770fd97ccfSChristoph Hellwig if (!dev->tmr_wq) { 15780fd97ccfSChristoph Hellwig pr_err("Unable to create tmr workqueue for %s\n", 15790fd97ccfSChristoph Hellwig dev->transport->name); 15800fd97ccfSChristoph Hellwig ret = -ENOMEM; 15810fd97ccfSChristoph Hellwig goto out_free_alua; 15820fd97ccfSChristoph Hellwig } 15830fd97ccfSChristoph Hellwig 15840fd97ccfSChristoph Hellwig /* 15850fd97ccfSChristoph Hellwig * Setup work_queue for QUEUE_FULL 15860fd97ccfSChristoph Hellwig */ 15870fd97ccfSChristoph Hellwig INIT_WORK(&dev->qf_work_queue, target_qf_do_work); 15880fd97ccfSChristoph Hellwig 15890fd97ccfSChristoph Hellwig /* 15900fd97ccfSChristoph Hellwig * Preload the initial INQUIRY const values if we are doing 15910fd97ccfSChristoph Hellwig * anything virtual (IBLOCK, FILEIO, RAMDISK), but not for TCM/pSCSI 15920fd97ccfSChristoph Hellwig * passthrough because this is being provided by the backend LLD. 15930fd97ccfSChristoph Hellwig */ 15940fd97ccfSChristoph Hellwig if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) { 15950fd97ccfSChristoph Hellwig strncpy(&dev->t10_wwn.vendor[0], "LIO-ORG", 8); 15960fd97ccfSChristoph Hellwig strncpy(&dev->t10_wwn.model[0], 15970fd97ccfSChristoph Hellwig dev->transport->inquiry_prod, 16); 15980fd97ccfSChristoph Hellwig strncpy(&dev->t10_wwn.revision[0], 15990fd97ccfSChristoph Hellwig dev->transport->inquiry_rev, 4); 16000fd97ccfSChristoph Hellwig } 16010fd97ccfSChristoph Hellwig 16020fd97ccfSChristoph Hellwig scsi_dump_inquiry(dev); 16030fd97ccfSChristoph Hellwig 16040fd97ccfSChristoph Hellwig spin_lock(&hba->device_lock); 16050fd97ccfSChristoph Hellwig hba->dev_count++; 16060fd97ccfSChristoph Hellwig spin_unlock(&hba->device_lock); 1607d9ea32bfSNicholas Bellinger 1608d9ea32bfSNicholas Bellinger mutex_lock(&g_device_mutex); 1609d9ea32bfSNicholas Bellinger list_add_tail(&dev->g_dev_node, &g_device_list); 1610d9ea32bfSNicholas Bellinger mutex_unlock(&g_device_mutex); 1611d9ea32bfSNicholas Bellinger 16125f7da044SNicholas Bellinger dev->dev_flags |= DF_CONFIGURED; 16135f7da044SNicholas Bellinger 16140fd97ccfSChristoph Hellwig return 0; 16150fd97ccfSChristoph Hellwig 16160fd97ccfSChristoph Hellwig out_free_alua: 16170fd97ccfSChristoph Hellwig core_alua_free_lu_gp_mem(dev); 16180fd97ccfSChristoph Hellwig out: 16190fd97ccfSChristoph Hellwig se_release_vpd_for_dev(dev); 16200fd97ccfSChristoph Hellwig return ret; 16210fd97ccfSChristoph Hellwig } 16220fd97ccfSChristoph Hellwig 16230fd97ccfSChristoph Hellwig void target_free_device(struct se_device *dev) 16240fd97ccfSChristoph Hellwig { 16250fd97ccfSChristoph Hellwig struct se_hba *hba = dev->se_hba; 16260fd97ccfSChristoph Hellwig 16270fd97ccfSChristoph Hellwig WARN_ON(!list_empty(&dev->dev_sep_list)); 16280fd97ccfSChristoph Hellwig 16290fd97ccfSChristoph Hellwig if (dev->dev_flags & DF_CONFIGURED) { 16300fd97ccfSChristoph Hellwig destroy_workqueue(dev->tmr_wq); 16310fd97ccfSChristoph Hellwig 1632d9ea32bfSNicholas Bellinger mutex_lock(&g_device_mutex); 1633d9ea32bfSNicholas Bellinger list_del(&dev->g_dev_node); 1634d9ea32bfSNicholas Bellinger mutex_unlock(&g_device_mutex); 1635d9ea32bfSNicholas Bellinger 16360fd97ccfSChristoph Hellwig spin_lock(&hba->device_lock); 16370fd97ccfSChristoph Hellwig hba->dev_count--; 16380fd97ccfSChristoph Hellwig spin_unlock(&hba->device_lock); 16390fd97ccfSChristoph Hellwig } 16400fd97ccfSChristoph Hellwig 16410fd97ccfSChristoph Hellwig core_alua_free_lu_gp_mem(dev); 1642229d4f11SHannes Reinecke core_alua_set_lba_map(dev, NULL, 0, 0); 16430fd97ccfSChristoph Hellwig core_scsi3_free_all_registrations(dev); 16440fd97ccfSChristoph Hellwig se_release_vpd_for_dev(dev); 16450fd97ccfSChristoph Hellwig 16462ed22c9cSNicholas Bellinger if (dev->transport->free_prot) 16472ed22c9cSNicholas Bellinger dev->transport->free_prot(dev); 16482ed22c9cSNicholas Bellinger 16490fd97ccfSChristoph Hellwig dev->transport->free_device(dev); 16500fd97ccfSChristoph Hellwig } 16510fd97ccfSChristoph Hellwig 1652c66ac9dbSNicholas Bellinger int core_dev_setup_virtual_lun0(void) 1653c66ac9dbSNicholas Bellinger { 1654c66ac9dbSNicholas Bellinger struct se_hba *hba; 1655c66ac9dbSNicholas Bellinger struct se_device *dev; 1656db5d1c3cSAndy Grover char buf[] = "rd_pages=8,rd_nullio=1"; 1657c66ac9dbSNicholas Bellinger int ret; 1658c66ac9dbSNicholas Bellinger 16596708bb27SAndy Grover hba = core_alloc_hba("rd_mcp", 0, HBA_FLAGS_INTERNAL_USE); 1660c66ac9dbSNicholas Bellinger if (IS_ERR(hba)) 1661c66ac9dbSNicholas Bellinger return PTR_ERR(hba); 1662c66ac9dbSNicholas Bellinger 16630fd97ccfSChristoph Hellwig dev = target_alloc_device(hba, "virt_lun0"); 16640fd97ccfSChristoph Hellwig if (!dev) { 1665c66ac9dbSNicholas Bellinger ret = -ENOMEM; 16660fd97ccfSChristoph Hellwig goto out_free_hba; 1667c66ac9dbSNicholas Bellinger } 1668c66ac9dbSNicholas Bellinger 16690fd97ccfSChristoph Hellwig hba->transport->set_configfs_dev_params(dev, buf, sizeof(buf)); 1670c66ac9dbSNicholas Bellinger 16710fd97ccfSChristoph Hellwig ret = target_configure_device(dev); 16720fd97ccfSChristoph Hellwig if (ret) 16730fd97ccfSChristoph Hellwig goto out_free_se_dev; 16740fd97ccfSChristoph Hellwig 16750fd97ccfSChristoph Hellwig lun0_hba = hba; 1676e3d6f909SAndy Grover g_lun0_dev = dev; 1677c66ac9dbSNicholas Bellinger return 0; 16780fd97ccfSChristoph Hellwig 16790fd97ccfSChristoph Hellwig out_free_se_dev: 16800fd97ccfSChristoph Hellwig target_free_device(dev); 16810fd97ccfSChristoph Hellwig out_free_hba: 16820fd97ccfSChristoph Hellwig core_delete_hba(hba); 1683c66ac9dbSNicholas Bellinger return ret; 1684c66ac9dbSNicholas Bellinger } 1685c66ac9dbSNicholas Bellinger 1686c66ac9dbSNicholas Bellinger 1687c66ac9dbSNicholas Bellinger void core_dev_release_virtual_lun0(void) 1688c66ac9dbSNicholas Bellinger { 1689e3d6f909SAndy Grover struct se_hba *hba = lun0_hba; 1690c66ac9dbSNicholas Bellinger 16916708bb27SAndy Grover if (!hba) 1692c66ac9dbSNicholas Bellinger return; 1693c66ac9dbSNicholas Bellinger 1694e3d6f909SAndy Grover if (g_lun0_dev) 16950fd97ccfSChristoph Hellwig target_free_device(g_lun0_dev); 1696c66ac9dbSNicholas Bellinger core_delete_hba(hba); 1697c66ac9dbSNicholas Bellinger } 1698