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 227c66ac9dbSNicholas Bellinger atomic_inc(&deve->pr_ref_count); 2284e857c58SPeter Zijlstra smp_mb__after_atomic(); 229c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 230c66ac9dbSNicholas Bellinger 231c66ac9dbSNicholas Bellinger return deve; 232c66ac9dbSNicholas Bellinger } 233c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 234c66ac9dbSNicholas Bellinger 235c66ac9dbSNicholas Bellinger return NULL; 236c66ac9dbSNicholas Bellinger } 237c66ac9dbSNicholas Bellinger 238c66ac9dbSNicholas Bellinger int core_free_device_list_for_node( 239c66ac9dbSNicholas Bellinger struct se_node_acl *nacl, 240c66ac9dbSNicholas Bellinger struct se_portal_group *tpg) 241c66ac9dbSNicholas Bellinger { 242c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 243c66ac9dbSNicholas Bellinger struct se_lun *lun; 244c66ac9dbSNicholas Bellinger u32 i; 245c66ac9dbSNicholas Bellinger 246c66ac9dbSNicholas Bellinger if (!nacl->device_list) 247c66ac9dbSNicholas Bellinger return 0; 248c66ac9dbSNicholas Bellinger 249c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 250c66ac9dbSNicholas Bellinger for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { 251f2083241SJörn Engel deve = nacl->device_list[i]; 252c66ac9dbSNicholas Bellinger 253c66ac9dbSNicholas Bellinger if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)) 254c66ac9dbSNicholas Bellinger continue; 255c66ac9dbSNicholas Bellinger 256c66ac9dbSNicholas Bellinger if (!deve->se_lun) { 2576708bb27SAndy Grover pr_err("%s device entries device pointer is" 258c66ac9dbSNicholas Bellinger " NULL, but Initiator has access.\n", 259e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 260c66ac9dbSNicholas Bellinger continue; 261c66ac9dbSNicholas Bellinger } 262c66ac9dbSNicholas Bellinger lun = deve->se_lun; 263c66ac9dbSNicholas Bellinger 264c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 265e80ac6c4SAndy Grover core_disable_device_list_for_node(lun, NULL, deve->mapped_lun, 266e80ac6c4SAndy Grover TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg); 267c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 268c66ac9dbSNicholas Bellinger } 269c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 270c66ac9dbSNicholas Bellinger 271f2083241SJörn Engel array_free(nacl->device_list, TRANSPORT_MAX_LUNS_PER_TPG); 272c66ac9dbSNicholas Bellinger nacl->device_list = NULL; 273c66ac9dbSNicholas Bellinger 274c66ac9dbSNicholas Bellinger return 0; 275c66ac9dbSNicholas Bellinger } 276c66ac9dbSNicholas Bellinger 277c66ac9dbSNicholas Bellinger void core_update_device_list_access( 278c66ac9dbSNicholas Bellinger u32 mapped_lun, 279c66ac9dbSNicholas Bellinger u32 lun_access, 280c66ac9dbSNicholas Bellinger struct se_node_acl *nacl) 281c66ac9dbSNicholas Bellinger { 282c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 283c66ac9dbSNicholas Bellinger 284c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 285f2083241SJörn Engel deve = nacl->device_list[mapped_lun]; 286c66ac9dbSNicholas Bellinger if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { 287c66ac9dbSNicholas Bellinger deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; 288c66ac9dbSNicholas Bellinger deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; 289c66ac9dbSNicholas Bellinger } else { 290c66ac9dbSNicholas Bellinger deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; 291c66ac9dbSNicholas Bellinger deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; 292c66ac9dbSNicholas Bellinger } 293c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 294c66ac9dbSNicholas Bellinger } 295c66ac9dbSNicholas Bellinger 296e80ac6c4SAndy Grover /* core_enable_device_list_for_node(): 297c66ac9dbSNicholas Bellinger * 298c66ac9dbSNicholas Bellinger * 299c66ac9dbSNicholas Bellinger */ 300e80ac6c4SAndy Grover int core_enable_device_list_for_node( 301c66ac9dbSNicholas Bellinger struct se_lun *lun, 302c66ac9dbSNicholas Bellinger struct se_lun_acl *lun_acl, 303c66ac9dbSNicholas Bellinger u32 mapped_lun, 304c66ac9dbSNicholas Bellinger u32 lun_access, 305c66ac9dbSNicholas Bellinger struct se_node_acl *nacl, 306e80ac6c4SAndy Grover struct se_portal_group *tpg) 307c66ac9dbSNicholas Bellinger { 308c66ac9dbSNicholas Bellinger struct se_port *port = lun->lun_sep; 309e80ac6c4SAndy Grover struct se_dev_entry *deve; 310c66ac9dbSNicholas Bellinger 311c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 312e80ac6c4SAndy Grover 313e80ac6c4SAndy Grover deve = nacl->device_list[mapped_lun]; 314e80ac6c4SAndy Grover 315c66ac9dbSNicholas Bellinger /* 316125d0119SHannes Reinecke * Check if the call is handling demo mode -> explicit LUN ACL 317c66ac9dbSNicholas Bellinger * transition. This transition must be for the same struct se_lun 318c66ac9dbSNicholas Bellinger * + mapped_lun that was setup in demo mode.. 319c66ac9dbSNicholas Bellinger */ 320c66ac9dbSNicholas Bellinger if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { 321c66ac9dbSNicholas Bellinger if (deve->se_lun_acl != NULL) { 3226708bb27SAndy Grover pr_err("struct se_dev_entry->se_lun_acl" 323125d0119SHannes Reinecke " already set for demo mode -> explicit" 324c66ac9dbSNicholas Bellinger " LUN ACL transition\n"); 32585dc98d9SFubo Chen spin_unlock_irq(&nacl->device_list_lock); 326e3d6f909SAndy Grover return -EINVAL; 327c66ac9dbSNicholas Bellinger } 328c66ac9dbSNicholas Bellinger if (deve->se_lun != lun) { 3296708bb27SAndy Grover pr_err("struct se_dev_entry->se_lun does" 330c66ac9dbSNicholas Bellinger " match passed struct se_lun for demo mode" 331125d0119SHannes Reinecke " -> explicit LUN ACL transition\n"); 33285dc98d9SFubo Chen spin_unlock_irq(&nacl->device_list_lock); 333e3d6f909SAndy Grover return -EINVAL; 334c66ac9dbSNicholas Bellinger } 335c66ac9dbSNicholas Bellinger deve->se_lun_acl = lun_acl; 336c66ac9dbSNicholas Bellinger 337c66ac9dbSNicholas Bellinger if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { 338c66ac9dbSNicholas Bellinger deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; 339c66ac9dbSNicholas Bellinger deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; 340c66ac9dbSNicholas Bellinger } else { 341c66ac9dbSNicholas Bellinger deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; 342c66ac9dbSNicholas Bellinger deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; 343c66ac9dbSNicholas Bellinger } 344c66ac9dbSNicholas Bellinger 345c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 346c66ac9dbSNicholas Bellinger return 0; 347c66ac9dbSNicholas Bellinger } 348e80ac6c4SAndy Grover 349e80ac6c4SAndy Grover deve->se_lun = lun; 350e80ac6c4SAndy Grover deve->se_lun_acl = lun_acl; 351e80ac6c4SAndy Grover deve->mapped_lun = mapped_lun; 352e80ac6c4SAndy Grover deve->lun_flags |= TRANSPORT_LUNFLAGS_INITIATOR_ACCESS; 353e80ac6c4SAndy Grover 354e80ac6c4SAndy Grover if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { 355e80ac6c4SAndy Grover deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; 356e80ac6c4SAndy Grover deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; 357e80ac6c4SAndy Grover } else { 358e80ac6c4SAndy Grover deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; 359e80ac6c4SAndy Grover deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; 360e80ac6c4SAndy Grover } 361e80ac6c4SAndy Grover 362c66ac9dbSNicholas Bellinger deve->creation_time = get_jiffies_64(); 363c66ac9dbSNicholas Bellinger deve->attach_count++; 364c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 365c66ac9dbSNicholas Bellinger 366c66ac9dbSNicholas Bellinger spin_lock_bh(&port->sep_alua_lock); 367c66ac9dbSNicholas Bellinger list_add_tail(&deve->alua_port_list, &port->sep_alua_list); 368c66ac9dbSNicholas Bellinger spin_unlock_bh(&port->sep_alua_lock); 369c66ac9dbSNicholas Bellinger 370c66ac9dbSNicholas Bellinger return 0; 371c66ac9dbSNicholas Bellinger } 372e80ac6c4SAndy Grover 373e80ac6c4SAndy Grover /* core_disable_device_list_for_node(): 374e80ac6c4SAndy Grover * 375e80ac6c4SAndy Grover * 376e80ac6c4SAndy Grover */ 377e80ac6c4SAndy Grover int core_disable_device_list_for_node( 378e80ac6c4SAndy Grover struct se_lun *lun, 379e80ac6c4SAndy Grover struct se_lun_acl *lun_acl, 380e80ac6c4SAndy Grover u32 mapped_lun, 381e80ac6c4SAndy Grover u32 lun_access, 382e80ac6c4SAndy Grover struct se_node_acl *nacl, 383e80ac6c4SAndy Grover struct se_portal_group *tpg) 384e80ac6c4SAndy Grover { 385e80ac6c4SAndy Grover struct se_port *port = lun->lun_sep; 38677d4c745SNicholas Bellinger struct se_dev_entry *deve = nacl->device_list[mapped_lun]; 387e80ac6c4SAndy Grover 388e80ac6c4SAndy Grover /* 389e80ac6c4SAndy Grover * If the MappedLUN entry is being disabled, the entry in 390e80ac6c4SAndy Grover * port->sep_alua_list must be removed now before clearing the 391e80ac6c4SAndy Grover * struct se_dev_entry pointers below as logic in 392e80ac6c4SAndy Grover * core_alua_do_transition_tg_pt() depends on these being present. 393e80ac6c4SAndy Grover * 394e80ac6c4SAndy Grover * deve->se_lun_acl will be NULL for demo-mode created LUNs 395e80ac6c4SAndy Grover * that have not been explicitly converted to MappedLUNs -> 396e80ac6c4SAndy Grover * struct se_lun_acl, but we remove deve->alua_port_list from 397e80ac6c4SAndy Grover * port->sep_alua_list. This also means that active UAs and 398e80ac6c4SAndy Grover * NodeACL context specific PR metadata for demo-mode 399e80ac6c4SAndy Grover * MappedLUN *deve will be released below.. 400e80ac6c4SAndy Grover */ 401e80ac6c4SAndy Grover spin_lock_bh(&port->sep_alua_lock); 402e80ac6c4SAndy Grover list_del(&deve->alua_port_list); 403e80ac6c4SAndy Grover spin_unlock_bh(&port->sep_alua_lock); 404c66ac9dbSNicholas Bellinger /* 405c66ac9dbSNicholas Bellinger * Wait for any in process SPEC_I_PT=1 or REGISTER_AND_MOVE 406c66ac9dbSNicholas Bellinger * PR operation to complete. 407c66ac9dbSNicholas Bellinger */ 408c66ac9dbSNicholas Bellinger while (atomic_read(&deve->pr_ref_count) != 0) 409c66ac9dbSNicholas Bellinger cpu_relax(); 41077d4c745SNicholas Bellinger 411c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 412c66ac9dbSNicholas Bellinger /* 413c66ac9dbSNicholas Bellinger * Disable struct se_dev_entry LUN ACL mapping 414c66ac9dbSNicholas Bellinger */ 415c66ac9dbSNicholas Bellinger core_scsi3_ua_release_all(deve); 416c66ac9dbSNicholas Bellinger deve->se_lun = NULL; 417c66ac9dbSNicholas Bellinger deve->se_lun_acl = NULL; 418c66ac9dbSNicholas Bellinger deve->lun_flags = 0; 419c66ac9dbSNicholas Bellinger deve->creation_time = 0; 420c66ac9dbSNicholas Bellinger deve->attach_count--; 421c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 422c66ac9dbSNicholas Bellinger 423c66ac9dbSNicholas Bellinger core_scsi3_free_pr_reg_from_nacl(lun->lun_se_dev, nacl); 424c66ac9dbSNicholas Bellinger return 0; 425c66ac9dbSNicholas Bellinger } 426c66ac9dbSNicholas Bellinger 427c66ac9dbSNicholas Bellinger /* core_clear_lun_from_tpg(): 428c66ac9dbSNicholas Bellinger * 429c66ac9dbSNicholas Bellinger * 430c66ac9dbSNicholas Bellinger */ 431c66ac9dbSNicholas Bellinger void core_clear_lun_from_tpg(struct se_lun *lun, struct se_portal_group *tpg) 432c66ac9dbSNicholas Bellinger { 433c66ac9dbSNicholas Bellinger struct se_node_acl *nacl; 434c66ac9dbSNicholas Bellinger struct se_dev_entry *deve; 435c66ac9dbSNicholas Bellinger u32 i; 436c66ac9dbSNicholas Bellinger 43728638887SRoland Dreier spin_lock_irq(&tpg->acl_node_lock); 438c66ac9dbSNicholas Bellinger list_for_each_entry(nacl, &tpg->acl_node_list, acl_list) { 43928638887SRoland Dreier spin_unlock_irq(&tpg->acl_node_lock); 440c66ac9dbSNicholas Bellinger 441c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 442c66ac9dbSNicholas Bellinger for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { 443f2083241SJörn Engel deve = nacl->device_list[i]; 444c66ac9dbSNicholas Bellinger if (lun != deve->se_lun) 445c66ac9dbSNicholas Bellinger continue; 446c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 447c66ac9dbSNicholas Bellinger 448e80ac6c4SAndy Grover core_disable_device_list_for_node(lun, NULL, 449c66ac9dbSNicholas Bellinger deve->mapped_lun, TRANSPORT_LUNFLAGS_NO_ACCESS, 450e80ac6c4SAndy Grover nacl, tpg); 451c66ac9dbSNicholas Bellinger 452c66ac9dbSNicholas Bellinger spin_lock_irq(&nacl->device_list_lock); 453c66ac9dbSNicholas Bellinger } 454c66ac9dbSNicholas Bellinger spin_unlock_irq(&nacl->device_list_lock); 455c66ac9dbSNicholas Bellinger 45628638887SRoland Dreier spin_lock_irq(&tpg->acl_node_lock); 457c66ac9dbSNicholas Bellinger } 45828638887SRoland Dreier spin_unlock_irq(&tpg->acl_node_lock); 459c66ac9dbSNicholas Bellinger } 460c66ac9dbSNicholas Bellinger 461c66ac9dbSNicholas Bellinger static struct se_port *core_alloc_port(struct se_device *dev) 462c66ac9dbSNicholas Bellinger { 463c66ac9dbSNicholas Bellinger struct se_port *port, *port_tmp; 464c66ac9dbSNicholas Bellinger 465c66ac9dbSNicholas Bellinger port = kzalloc(sizeof(struct se_port), GFP_KERNEL); 4666708bb27SAndy Grover if (!port) { 4676708bb27SAndy Grover pr_err("Unable to allocate struct se_port\n"); 468e3d6f909SAndy Grover return ERR_PTR(-ENOMEM); 469c66ac9dbSNicholas Bellinger } 470c66ac9dbSNicholas Bellinger INIT_LIST_HEAD(&port->sep_alua_list); 471c66ac9dbSNicholas Bellinger INIT_LIST_HEAD(&port->sep_list); 472c66ac9dbSNicholas Bellinger atomic_set(&port->sep_tg_pt_secondary_offline, 0); 473c66ac9dbSNicholas Bellinger spin_lock_init(&port->sep_alua_lock); 474c66ac9dbSNicholas Bellinger mutex_init(&port->sep_tg_pt_md_mutex); 475c66ac9dbSNicholas Bellinger 476c66ac9dbSNicholas Bellinger spin_lock(&dev->se_port_lock); 477c66ac9dbSNicholas Bellinger if (dev->dev_port_count == 0x0000ffff) { 4786708bb27SAndy Grover pr_warn("Reached dev->dev_port_count ==" 479c66ac9dbSNicholas Bellinger " 0x0000ffff\n"); 480c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 481e3d6f909SAndy Grover return ERR_PTR(-ENOSPC); 482c66ac9dbSNicholas Bellinger } 483c66ac9dbSNicholas Bellinger again: 484c66ac9dbSNicholas Bellinger /* 48535d1efe8SMasanari Iida * Allocate the next RELATIVE TARGET PORT IDENTIFIER for this struct se_device 486c66ac9dbSNicholas Bellinger * Here is the table from spc4r17 section 7.7.3.8. 487c66ac9dbSNicholas Bellinger * 488c66ac9dbSNicholas Bellinger * Table 473 -- RELATIVE TARGET PORT IDENTIFIER field 489c66ac9dbSNicholas Bellinger * 490c66ac9dbSNicholas Bellinger * Code Description 491c66ac9dbSNicholas Bellinger * 0h Reserved 492c66ac9dbSNicholas Bellinger * 1h Relative port 1, historically known as port A 493c66ac9dbSNicholas Bellinger * 2h Relative port 2, historically known as port B 494c66ac9dbSNicholas Bellinger * 3h to FFFFh Relative port 3 through 65 535 495c66ac9dbSNicholas Bellinger */ 496c66ac9dbSNicholas Bellinger port->sep_rtpi = dev->dev_rpti_counter++; 4976708bb27SAndy Grover if (!port->sep_rtpi) 498c66ac9dbSNicholas Bellinger goto again; 499c66ac9dbSNicholas Bellinger 500c66ac9dbSNicholas Bellinger list_for_each_entry(port_tmp, &dev->dev_sep_list, sep_list) { 501c66ac9dbSNicholas Bellinger /* 50235d1efe8SMasanari Iida * Make sure RELATIVE TARGET PORT IDENTIFIER is unique 503c66ac9dbSNicholas Bellinger * for 16-bit wrap.. 504c66ac9dbSNicholas Bellinger */ 505c66ac9dbSNicholas Bellinger if (port->sep_rtpi == port_tmp->sep_rtpi) 506c66ac9dbSNicholas Bellinger goto again; 507c66ac9dbSNicholas Bellinger } 508c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 509c66ac9dbSNicholas Bellinger 510c66ac9dbSNicholas Bellinger return port; 511c66ac9dbSNicholas Bellinger } 512c66ac9dbSNicholas Bellinger 513c66ac9dbSNicholas Bellinger static void core_export_port( 514c66ac9dbSNicholas Bellinger struct se_device *dev, 515c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 516c66ac9dbSNicholas Bellinger struct se_port *port, 517c66ac9dbSNicholas Bellinger struct se_lun *lun) 518c66ac9dbSNicholas Bellinger { 519c66ac9dbSNicholas Bellinger struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem = NULL; 520c66ac9dbSNicholas Bellinger 521c66ac9dbSNicholas Bellinger spin_lock(&dev->se_port_lock); 522c66ac9dbSNicholas Bellinger spin_lock(&lun->lun_sep_lock); 523c66ac9dbSNicholas Bellinger port->sep_tpg = tpg; 524c66ac9dbSNicholas Bellinger port->sep_lun = lun; 525c66ac9dbSNicholas Bellinger lun->lun_sep = port; 526c66ac9dbSNicholas Bellinger spin_unlock(&lun->lun_sep_lock); 527c66ac9dbSNicholas Bellinger 528c66ac9dbSNicholas Bellinger list_add_tail(&port->sep_list, &dev->dev_sep_list); 529c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 530c66ac9dbSNicholas Bellinger 531c87fbd56SChristoph Hellwig if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV && 532c87fbd56SChristoph Hellwig !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) { 533c66ac9dbSNicholas Bellinger tg_pt_gp_mem = core_alua_allocate_tg_pt_gp_mem(port); 534c66ac9dbSNicholas Bellinger if (IS_ERR(tg_pt_gp_mem) || !tg_pt_gp_mem) { 5356708bb27SAndy Grover pr_err("Unable to allocate t10_alua_tg_pt" 536c66ac9dbSNicholas Bellinger "_gp_member_t\n"); 537c66ac9dbSNicholas Bellinger return; 538c66ac9dbSNicholas Bellinger } 539c66ac9dbSNicholas Bellinger spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 540c66ac9dbSNicholas Bellinger __core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem, 5410fd97ccfSChristoph Hellwig dev->t10_alua.default_tg_pt_gp); 542c66ac9dbSNicholas Bellinger spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 5436708bb27SAndy Grover pr_debug("%s/%s: Adding to default ALUA Target Port" 544c66ac9dbSNicholas Bellinger " Group: alua/default_tg_pt_gp\n", 545e3d6f909SAndy Grover dev->transport->name, tpg->se_tpg_tfo->get_fabric_name()); 546c66ac9dbSNicholas Bellinger } 547c66ac9dbSNicholas Bellinger 548c66ac9dbSNicholas Bellinger dev->dev_port_count++; 54935d1efe8SMasanari Iida port->sep_index = port->sep_rtpi; /* RELATIVE TARGET PORT IDENTIFIER */ 550c66ac9dbSNicholas Bellinger } 551c66ac9dbSNicholas Bellinger 552c66ac9dbSNicholas Bellinger /* 553c66ac9dbSNicholas Bellinger * Called with struct se_device->se_port_lock spinlock held. 554c66ac9dbSNicholas Bellinger */ 555c66ac9dbSNicholas Bellinger static void core_release_port(struct se_device *dev, struct se_port *port) 5565dd7ed2eSDan Carpenter __releases(&dev->se_port_lock) __acquires(&dev->se_port_lock) 557c66ac9dbSNicholas Bellinger { 558c66ac9dbSNicholas Bellinger /* 559c66ac9dbSNicholas Bellinger * Wait for any port reference for PR ALL_TG_PT=1 operation 560c66ac9dbSNicholas Bellinger * to complete in __core_scsi3_alloc_registration() 561c66ac9dbSNicholas Bellinger */ 562c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 563c66ac9dbSNicholas Bellinger if (atomic_read(&port->sep_tg_pt_ref_cnt)) 564c66ac9dbSNicholas Bellinger cpu_relax(); 565c66ac9dbSNicholas Bellinger spin_lock(&dev->se_port_lock); 566c66ac9dbSNicholas Bellinger 567c66ac9dbSNicholas Bellinger core_alua_free_tg_pt_gp_mem(port); 568c66ac9dbSNicholas Bellinger 569c66ac9dbSNicholas Bellinger list_del(&port->sep_list); 570c66ac9dbSNicholas Bellinger dev->dev_port_count--; 571c66ac9dbSNicholas Bellinger kfree(port); 572c66ac9dbSNicholas Bellinger } 573c66ac9dbSNicholas Bellinger 574c66ac9dbSNicholas Bellinger int core_dev_export( 575c66ac9dbSNicholas Bellinger struct se_device *dev, 576c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 577c66ac9dbSNicholas Bellinger struct se_lun *lun) 578c66ac9dbSNicholas Bellinger { 5790fd97ccfSChristoph Hellwig struct se_hba *hba = dev->se_hba; 580c66ac9dbSNicholas Bellinger struct se_port *port; 581c66ac9dbSNicholas Bellinger 582c66ac9dbSNicholas Bellinger port = core_alloc_port(dev); 583e3d6f909SAndy Grover if (IS_ERR(port)) 584e3d6f909SAndy Grover return PTR_ERR(port); 585c66ac9dbSNicholas Bellinger 586c66ac9dbSNicholas Bellinger lun->lun_se_dev = dev; 587c66ac9dbSNicholas Bellinger 5880fd97ccfSChristoph Hellwig spin_lock(&hba->device_lock); 5890fd97ccfSChristoph Hellwig dev->export_count++; 5900fd97ccfSChristoph Hellwig spin_unlock(&hba->device_lock); 5910fd97ccfSChristoph Hellwig 592c66ac9dbSNicholas Bellinger core_export_port(dev, tpg, port, lun); 593c66ac9dbSNicholas Bellinger return 0; 594c66ac9dbSNicholas Bellinger } 595c66ac9dbSNicholas Bellinger 596c66ac9dbSNicholas Bellinger void core_dev_unexport( 597c66ac9dbSNicholas Bellinger struct se_device *dev, 598c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 599c66ac9dbSNicholas Bellinger struct se_lun *lun) 600c66ac9dbSNicholas Bellinger { 6010fd97ccfSChristoph Hellwig struct se_hba *hba = dev->se_hba; 602c66ac9dbSNicholas Bellinger struct se_port *port = lun->lun_sep; 603c66ac9dbSNicholas Bellinger 604c66ac9dbSNicholas Bellinger spin_lock(&lun->lun_sep_lock); 605c66ac9dbSNicholas Bellinger if (lun->lun_se_dev == NULL) { 606c66ac9dbSNicholas Bellinger spin_unlock(&lun->lun_sep_lock); 607c66ac9dbSNicholas Bellinger return; 608c66ac9dbSNicholas Bellinger } 609c66ac9dbSNicholas Bellinger spin_unlock(&lun->lun_sep_lock); 610c66ac9dbSNicholas Bellinger 611c66ac9dbSNicholas Bellinger spin_lock(&dev->se_port_lock); 612c66ac9dbSNicholas Bellinger core_release_port(dev, port); 613c66ac9dbSNicholas Bellinger spin_unlock(&dev->se_port_lock); 614c66ac9dbSNicholas Bellinger 6150fd97ccfSChristoph Hellwig spin_lock(&hba->device_lock); 6160fd97ccfSChristoph Hellwig dev->export_count--; 6170fd97ccfSChristoph Hellwig spin_unlock(&hba->device_lock); 6180fd97ccfSChristoph Hellwig 61983ff42fcSNicholas Bellinger lun->lun_sep = NULL; 620c66ac9dbSNicholas Bellinger lun->lun_se_dev = NULL; 621c66ac9dbSNicholas Bellinger } 622c66ac9dbSNicholas Bellinger 6230fd97ccfSChristoph Hellwig static void se_release_vpd_for_dev(struct se_device *dev) 624c66ac9dbSNicholas Bellinger { 625c66ac9dbSNicholas Bellinger struct t10_vpd *vpd, *vpd_tmp; 626c66ac9dbSNicholas Bellinger 6270fd97ccfSChristoph Hellwig spin_lock(&dev->t10_wwn.t10_vpd_lock); 628c66ac9dbSNicholas Bellinger list_for_each_entry_safe(vpd, vpd_tmp, 6290fd97ccfSChristoph Hellwig &dev->t10_wwn.t10_vpd_list, vpd_list) { 630c66ac9dbSNicholas Bellinger list_del(&vpd->vpd_list); 631c66ac9dbSNicholas Bellinger kfree(vpd); 632c66ac9dbSNicholas Bellinger } 6330fd97ccfSChristoph Hellwig spin_unlock(&dev->t10_wwn.t10_vpd_lock); 634c66ac9dbSNicholas Bellinger } 635c66ac9dbSNicholas Bellinger 636c8045372SRoland Dreier static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) 637525a48a2SNicholas Bellinger { 6383e03989bSRoland Dreier u32 aligned_max_sectors; 6393e03989bSRoland Dreier u32 alignment; 640525a48a2SNicholas Bellinger /* 641525a48a2SNicholas Bellinger * Limit max_sectors to a PAGE_SIZE aligned value for modern 642525a48a2SNicholas Bellinger * transport_allocate_data_tasks() operation. 643525a48a2SNicholas Bellinger */ 6443e03989bSRoland Dreier alignment = max(1ul, PAGE_SIZE / block_size); 6453e03989bSRoland Dreier aligned_max_sectors = rounddown(max_sectors, alignment); 646525a48a2SNicholas Bellinger 6473e03989bSRoland Dreier if (max_sectors != aligned_max_sectors) 6483e03989bSRoland Dreier pr_info("Rounding down aligned max_sectors from %u to %u\n", 6493e03989bSRoland Dreier max_sectors, aligned_max_sectors); 6503e03989bSRoland Dreier 6513e03989bSRoland Dreier return aligned_max_sectors; 652525a48a2SNicholas Bellinger } 653525a48a2SNicholas Bellinger 654c66ac9dbSNicholas Bellinger int se_dev_set_max_unmap_lba_count( 655c66ac9dbSNicholas Bellinger struct se_device *dev, 656c66ac9dbSNicholas Bellinger u32 max_unmap_lba_count) 657c66ac9dbSNicholas Bellinger { 6580fd97ccfSChristoph Hellwig dev->dev_attrib.max_unmap_lba_count = max_unmap_lba_count; 6596708bb27SAndy Grover pr_debug("dev[%p]: Set max_unmap_lba_count: %u\n", 6600fd97ccfSChristoph Hellwig dev, dev->dev_attrib.max_unmap_lba_count); 661c66ac9dbSNicholas Bellinger return 0; 662c66ac9dbSNicholas Bellinger } 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 } 674c66ac9dbSNicholas Bellinger 675c66ac9dbSNicholas Bellinger int se_dev_set_unmap_granularity( 676c66ac9dbSNicholas Bellinger struct se_device *dev, 677c66ac9dbSNicholas Bellinger u32 unmap_granularity) 678c66ac9dbSNicholas Bellinger { 6790fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity = unmap_granularity; 6806708bb27SAndy Grover pr_debug("dev[%p]: Set unmap_granularity: %u\n", 6810fd97ccfSChristoph Hellwig dev, dev->dev_attrib.unmap_granularity); 682c66ac9dbSNicholas Bellinger return 0; 683c66ac9dbSNicholas Bellinger } 684c66ac9dbSNicholas Bellinger 685c66ac9dbSNicholas Bellinger int se_dev_set_unmap_granularity_alignment( 686c66ac9dbSNicholas Bellinger struct se_device *dev, 687c66ac9dbSNicholas Bellinger u32 unmap_granularity_alignment) 688c66ac9dbSNicholas Bellinger { 6890fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity_alignment = unmap_granularity_alignment; 6906708bb27SAndy Grover pr_debug("dev[%p]: Set unmap_granularity_alignment: %u\n", 6910fd97ccfSChristoph Hellwig dev, dev->dev_attrib.unmap_granularity_alignment); 692c66ac9dbSNicholas Bellinger return 0; 693c66ac9dbSNicholas Bellinger } 694c66ac9dbSNicholas Bellinger 695773cbaf7SNicholas Bellinger int se_dev_set_max_write_same_len( 696773cbaf7SNicholas Bellinger struct se_device *dev, 697773cbaf7SNicholas Bellinger u32 max_write_same_len) 698773cbaf7SNicholas Bellinger { 699773cbaf7SNicholas Bellinger dev->dev_attrib.max_write_same_len = max_write_same_len; 700773cbaf7SNicholas Bellinger pr_debug("dev[%p]: Set max_write_same_len: %u\n", 701773cbaf7SNicholas Bellinger dev, dev->dev_attrib.max_write_same_len); 702773cbaf7SNicholas Bellinger return 0; 703773cbaf7SNicholas Bellinger } 704773cbaf7SNicholas Bellinger 705adfa9570STregaron Bayly static void dev_set_t10_wwn_model_alias(struct se_device *dev) 706adfa9570STregaron Bayly { 707adfa9570STregaron Bayly const char *configname; 708adfa9570STregaron Bayly 709adfa9570STregaron Bayly configname = config_item_name(&dev->dev_group.cg_item); 710adfa9570STregaron Bayly if (strlen(configname) >= 16) { 711adfa9570STregaron Bayly pr_warn("dev[%p]: Backstore name '%s' is too long for " 712adfa9570STregaron Bayly "INQUIRY_MODEL, truncating to 16 bytes\n", dev, 713adfa9570STregaron Bayly configname); 714adfa9570STregaron Bayly } 715adfa9570STregaron Bayly snprintf(&dev->t10_wwn.model[0], 16, "%s", configname); 716adfa9570STregaron Bayly } 717adfa9570STregaron Bayly 718adfa9570STregaron Bayly int se_dev_set_emulate_model_alias(struct se_device *dev, int flag) 719adfa9570STregaron Bayly { 720adfa9570STregaron Bayly if (dev->export_count) { 721adfa9570STregaron Bayly pr_err("dev[%p]: Unable to change model alias" 722adfa9570STregaron Bayly " while export_count is %d\n", 723adfa9570STregaron Bayly dev, dev->export_count); 724adfa9570STregaron Bayly return -EINVAL; 725adfa9570STregaron Bayly } 726adfa9570STregaron Bayly 727adfa9570STregaron Bayly if (flag != 0 && flag != 1) { 728adfa9570STregaron Bayly pr_err("Illegal value %d\n", flag); 729adfa9570STregaron Bayly return -EINVAL; 730adfa9570STregaron Bayly } 731adfa9570STregaron Bayly 732adfa9570STregaron Bayly if (flag) { 733adfa9570STregaron Bayly dev_set_t10_wwn_model_alias(dev); 734adfa9570STregaron Bayly } else { 735adfa9570STregaron Bayly strncpy(&dev->t10_wwn.model[0], 736adfa9570STregaron Bayly dev->transport->inquiry_prod, 16); 737adfa9570STregaron Bayly } 738adfa9570STregaron Bayly dev->dev_attrib.emulate_model_alias = flag; 739adfa9570STregaron Bayly 740adfa9570STregaron Bayly return 0; 741adfa9570STregaron Bayly } 742adfa9570STregaron Bayly 743c66ac9dbSNicholas Bellinger int se_dev_set_emulate_dpo(struct se_device *dev, int flag) 744c66ac9dbSNicholas Bellinger { 745f55918faSChristoph Hellwig if (flag != 0 && flag != 1) { 7466708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 747e3d6f909SAndy Grover return -EINVAL; 748c66ac9dbSNicholas Bellinger } 749f55918faSChristoph Hellwig 750c638830dSAndy Grover if (flag) { 751f55918faSChristoph Hellwig pr_err("dpo_emulated not supported\n"); 752e3d6f909SAndy Grover return -EINVAL; 753c66ac9dbSNicholas Bellinger } 754c66ac9dbSNicholas Bellinger 755c638830dSAndy Grover return 0; 756c638830dSAndy Grover } 757c638830dSAndy Grover 758c66ac9dbSNicholas Bellinger int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) 759c66ac9dbSNicholas Bellinger { 760f55918faSChristoph Hellwig if (flag != 0 && flag != 1) { 7616708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 762e3d6f909SAndy Grover return -EINVAL; 763c66ac9dbSNicholas Bellinger } 764f55918faSChristoph Hellwig 765fd30e931SNicholas Bellinger if (flag && 766fd30e931SNicholas Bellinger dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { 767fd30e931SNicholas Bellinger pr_err("emulate_fua_write not supported for pSCSI\n"); 768e3d6f909SAndy Grover return -EINVAL; 769c66ac9dbSNicholas Bellinger } 7700fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_fua_write = flag; 7716708bb27SAndy Grover pr_debug("dev[%p]: SE Device Forced Unit Access WRITEs: %d\n", 7720fd97ccfSChristoph Hellwig dev, dev->dev_attrib.emulate_fua_write); 773c66ac9dbSNicholas Bellinger return 0; 774c66ac9dbSNicholas Bellinger } 775c66ac9dbSNicholas Bellinger 776c66ac9dbSNicholas Bellinger int se_dev_set_emulate_fua_read(struct se_device *dev, int flag) 777c66ac9dbSNicholas Bellinger { 778f55918faSChristoph Hellwig if (flag != 0 && flag != 1) { 7796708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 780e3d6f909SAndy Grover return -EINVAL; 781c66ac9dbSNicholas Bellinger } 782f55918faSChristoph Hellwig 783c638830dSAndy Grover if (flag) { 784f55918faSChristoph Hellwig pr_err("ua read emulated not supported\n"); 785e3d6f909SAndy Grover return -EINVAL; 786c66ac9dbSNicholas Bellinger } 787c66ac9dbSNicholas Bellinger 788c638830dSAndy Grover return 0; 789c638830dSAndy Grover } 790c638830dSAndy Grover 791c66ac9dbSNicholas Bellinger int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) 792c66ac9dbSNicholas Bellinger { 793f55918faSChristoph Hellwig if (flag != 0 && flag != 1) { 7946708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 795e3d6f909SAndy Grover return -EINVAL; 796c66ac9dbSNicholas Bellinger } 797fd30e931SNicholas Bellinger if (flag && 798fd30e931SNicholas Bellinger dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { 799fd30e931SNicholas Bellinger pr_err("emulate_write_cache not supported for pSCSI\n"); 800e3d6f909SAndy Grover return -EINVAL; 801c66ac9dbSNicholas Bellinger } 80207b8dae3SAndy Grover if (flag && 80307b8dae3SAndy Grover dev->transport->get_write_cache) { 80407b8dae3SAndy Grover pr_err("emulate_write_cache not supported for this device\n"); 80507b8dae3SAndy Grover return -EINVAL; 806d0c8b259SNicholas Bellinger } 807d0c8b259SNicholas Bellinger 8080fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_write_cache = flag; 8096708bb27SAndy Grover pr_debug("dev[%p]: SE Device WRITE_CACHE_EMULATION flag: %d\n", 8100fd97ccfSChristoph Hellwig dev, dev->dev_attrib.emulate_write_cache); 811c66ac9dbSNicholas Bellinger return 0; 812c66ac9dbSNicholas Bellinger } 813c66ac9dbSNicholas Bellinger 814c66ac9dbSNicholas Bellinger int se_dev_set_emulate_ua_intlck_ctrl(struct se_device *dev, int flag) 815c66ac9dbSNicholas Bellinger { 816c66ac9dbSNicholas Bellinger if ((flag != 0) && (flag != 1) && (flag != 2)) { 8176708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 818e3d6f909SAndy Grover return -EINVAL; 819c66ac9dbSNicholas Bellinger } 820c66ac9dbSNicholas Bellinger 8210fd97ccfSChristoph Hellwig if (dev->export_count) { 8226708bb27SAndy Grover pr_err("dev[%p]: Unable to change SE Device" 8230fd97ccfSChristoph Hellwig " UA_INTRLCK_CTRL while export_count is %d\n", 8240fd97ccfSChristoph Hellwig dev, dev->export_count); 825e3d6f909SAndy Grover return -EINVAL; 826c66ac9dbSNicholas Bellinger } 8270fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_ua_intlck_ctrl = flag; 8286708bb27SAndy Grover pr_debug("dev[%p]: SE Device UA_INTRLCK_CTRL flag: %d\n", 8290fd97ccfSChristoph Hellwig dev, dev->dev_attrib.emulate_ua_intlck_ctrl); 830c66ac9dbSNicholas Bellinger 831c66ac9dbSNicholas Bellinger return 0; 832c66ac9dbSNicholas Bellinger } 833c66ac9dbSNicholas Bellinger 834c66ac9dbSNicholas Bellinger int se_dev_set_emulate_tas(struct se_device *dev, int flag) 835c66ac9dbSNicholas Bellinger { 836c66ac9dbSNicholas Bellinger if ((flag != 0) && (flag != 1)) { 8376708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 838e3d6f909SAndy Grover return -EINVAL; 839c66ac9dbSNicholas Bellinger } 840c66ac9dbSNicholas Bellinger 8410fd97ccfSChristoph Hellwig if (dev->export_count) { 8426708bb27SAndy Grover pr_err("dev[%p]: Unable to change SE Device TAS while" 8430fd97ccfSChristoph Hellwig " export_count is %d\n", 8440fd97ccfSChristoph Hellwig dev, dev->export_count); 845e3d6f909SAndy Grover return -EINVAL; 846c66ac9dbSNicholas Bellinger } 8470fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tas = flag; 8486708bb27SAndy Grover pr_debug("dev[%p]: SE Device TASK_ABORTED status bit: %s\n", 8490fd97ccfSChristoph Hellwig dev, (dev->dev_attrib.emulate_tas) ? "Enabled" : "Disabled"); 850c66ac9dbSNicholas Bellinger 851c66ac9dbSNicholas Bellinger return 0; 852c66ac9dbSNicholas Bellinger } 853c66ac9dbSNicholas Bellinger 854c66ac9dbSNicholas Bellinger int se_dev_set_emulate_tpu(struct se_device *dev, int flag) 855c66ac9dbSNicholas Bellinger { 856c66ac9dbSNicholas Bellinger if ((flag != 0) && (flag != 1)) { 8576708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 858e3d6f909SAndy Grover return -EINVAL; 859c66ac9dbSNicholas Bellinger } 860c66ac9dbSNicholas Bellinger /* 861c66ac9dbSNicholas Bellinger * We expect this value to be non-zero when generic Block Layer 862c66ac9dbSNicholas Bellinger * Discard supported is detected iblock_create_virtdevice(). 863c66ac9dbSNicholas Bellinger */ 8640fd97ccfSChristoph Hellwig if (flag && !dev->dev_attrib.max_unmap_block_desc_count) { 8656708bb27SAndy Grover pr_err("Generic Block Discard not supported\n"); 866c66ac9dbSNicholas Bellinger return -ENOSYS; 867c66ac9dbSNicholas Bellinger } 868c66ac9dbSNicholas Bellinger 8690fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tpu = flag; 8706708bb27SAndy Grover pr_debug("dev[%p]: SE Device Thin Provisioning UNMAP bit: %d\n", 871c66ac9dbSNicholas Bellinger dev, flag); 872c66ac9dbSNicholas Bellinger return 0; 873c66ac9dbSNicholas Bellinger } 874c66ac9dbSNicholas Bellinger 875c66ac9dbSNicholas Bellinger int se_dev_set_emulate_tpws(struct se_device *dev, int flag) 876c66ac9dbSNicholas Bellinger { 877c66ac9dbSNicholas Bellinger if ((flag != 0) && (flag != 1)) { 8786708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 879e3d6f909SAndy Grover return -EINVAL; 880c66ac9dbSNicholas Bellinger } 881c66ac9dbSNicholas Bellinger /* 882c66ac9dbSNicholas Bellinger * We expect this value to be non-zero when generic Block Layer 883c66ac9dbSNicholas Bellinger * Discard supported is detected iblock_create_virtdevice(). 884c66ac9dbSNicholas Bellinger */ 8850fd97ccfSChristoph Hellwig if (flag && !dev->dev_attrib.max_unmap_block_desc_count) { 8866708bb27SAndy Grover pr_err("Generic Block Discard not supported\n"); 887c66ac9dbSNicholas Bellinger return -ENOSYS; 888c66ac9dbSNicholas Bellinger } 889c66ac9dbSNicholas Bellinger 8900fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tpws = flag; 8916708bb27SAndy Grover pr_debug("dev[%p]: SE Device Thin Provisioning WRITE_SAME: %d\n", 892c66ac9dbSNicholas Bellinger dev, flag); 893c66ac9dbSNicholas Bellinger return 0; 894c66ac9dbSNicholas Bellinger } 895c66ac9dbSNicholas Bellinger 8960123a9ecSNicholas Bellinger int se_dev_set_emulate_caw(struct se_device *dev, int flag) 8970123a9ecSNicholas Bellinger { 8980123a9ecSNicholas Bellinger if (flag != 0 && flag != 1) { 8990123a9ecSNicholas Bellinger pr_err("Illegal value %d\n", flag); 9000123a9ecSNicholas Bellinger return -EINVAL; 9010123a9ecSNicholas Bellinger } 9020123a9ecSNicholas Bellinger dev->dev_attrib.emulate_caw = flag; 9030123a9ecSNicholas Bellinger pr_debug("dev[%p]: SE Device CompareAndWrite (AtomicTestandSet): %d\n", 9040123a9ecSNicholas Bellinger dev, flag); 9050123a9ecSNicholas Bellinger 9060123a9ecSNicholas Bellinger return 0; 9070123a9ecSNicholas Bellinger } 9080123a9ecSNicholas Bellinger 909d397a445SNicholas Bellinger int se_dev_set_emulate_3pc(struct se_device *dev, int flag) 910d397a445SNicholas Bellinger { 911d397a445SNicholas Bellinger if (flag != 0 && flag != 1) { 912d397a445SNicholas Bellinger pr_err("Illegal value %d\n", flag); 913d397a445SNicholas Bellinger return -EINVAL; 914d397a445SNicholas Bellinger } 915d397a445SNicholas Bellinger dev->dev_attrib.emulate_3pc = flag; 916d397a445SNicholas Bellinger pr_debug("dev[%p]: SE Device 3rd Party Copy (EXTENDED_COPY): %d\n", 917d397a445SNicholas Bellinger dev, flag); 918d397a445SNicholas Bellinger 919d397a445SNicholas Bellinger return 0; 920d397a445SNicholas Bellinger } 921d397a445SNicholas Bellinger 9222ed22c9cSNicholas Bellinger int se_dev_set_pi_prot_type(struct se_device *dev, int flag) 9232ed22c9cSNicholas Bellinger { 9242ed22c9cSNicholas Bellinger int rc, old_prot = dev->dev_attrib.pi_prot_type; 9252ed22c9cSNicholas Bellinger 9262ed22c9cSNicholas Bellinger if (flag != 0 && flag != 1 && flag != 2 && flag != 3) { 9272ed22c9cSNicholas Bellinger pr_err("Illegal value %d for pi_prot_type\n", flag); 9282ed22c9cSNicholas Bellinger return -EINVAL; 9292ed22c9cSNicholas Bellinger } 9302ed22c9cSNicholas Bellinger if (flag == 2) { 9312ed22c9cSNicholas Bellinger pr_err("DIF TYPE2 protection currently not supported\n"); 9322ed22c9cSNicholas Bellinger return -ENOSYS; 9332ed22c9cSNicholas Bellinger } 9342ed22c9cSNicholas Bellinger if (dev->dev_attrib.hw_pi_prot_type) { 9352ed22c9cSNicholas Bellinger pr_warn("DIF protection enabled on underlying hardware," 9362ed22c9cSNicholas Bellinger " ignoring\n"); 9372ed22c9cSNicholas Bellinger return 0; 9382ed22c9cSNicholas Bellinger } 9392ed22c9cSNicholas Bellinger if (!dev->transport->init_prot || !dev->transport->free_prot) { 940448ba904SAndy Grover /* 0 is only allowed value for non-supporting backends */ 941448ba904SAndy Grover if (flag == 0) 942448ba904SAndy Grover return 0; 943448ba904SAndy Grover 9442ed22c9cSNicholas Bellinger pr_err("DIF protection not supported by backend: %s\n", 9452ed22c9cSNicholas Bellinger dev->transport->name); 9462ed22c9cSNicholas Bellinger return -ENOSYS; 9472ed22c9cSNicholas Bellinger } 9482ed22c9cSNicholas Bellinger if (!(dev->dev_flags & DF_CONFIGURED)) { 9492ed22c9cSNicholas Bellinger pr_err("DIF protection requires device to be configured\n"); 9502ed22c9cSNicholas Bellinger return -ENODEV; 9512ed22c9cSNicholas Bellinger } 9522ed22c9cSNicholas Bellinger if (dev->export_count) { 9532ed22c9cSNicholas Bellinger pr_err("dev[%p]: Unable to change SE Device PROT type while" 9542ed22c9cSNicholas Bellinger " export_count is %d\n", dev, dev->export_count); 9552ed22c9cSNicholas Bellinger return -EINVAL; 9562ed22c9cSNicholas Bellinger } 9572ed22c9cSNicholas Bellinger 9582ed22c9cSNicholas Bellinger dev->dev_attrib.pi_prot_type = flag; 9592ed22c9cSNicholas Bellinger 9602ed22c9cSNicholas Bellinger if (flag && !old_prot) { 9612ed22c9cSNicholas Bellinger rc = dev->transport->init_prot(dev); 9622ed22c9cSNicholas Bellinger if (rc) { 9632ed22c9cSNicholas Bellinger dev->dev_attrib.pi_prot_type = old_prot; 9642ed22c9cSNicholas Bellinger return rc; 9652ed22c9cSNicholas Bellinger } 9662ed22c9cSNicholas Bellinger 9672ed22c9cSNicholas Bellinger } else if (!flag && old_prot) { 9682ed22c9cSNicholas Bellinger dev->transport->free_prot(dev); 9692ed22c9cSNicholas Bellinger } 9702ed22c9cSNicholas Bellinger pr_debug("dev[%p]: SE Device Protection Type: %d\n", dev, flag); 9712ed22c9cSNicholas Bellinger 9722ed22c9cSNicholas Bellinger return 0; 9732ed22c9cSNicholas Bellinger } 9742ed22c9cSNicholas Bellinger 9752ed22c9cSNicholas Bellinger int se_dev_set_pi_prot_format(struct se_device *dev, int flag) 9762ed22c9cSNicholas Bellinger { 9772ed22c9cSNicholas Bellinger int rc; 9782ed22c9cSNicholas Bellinger 9792ed22c9cSNicholas Bellinger if (!flag) 9802ed22c9cSNicholas Bellinger return 0; 9812ed22c9cSNicholas Bellinger 9822ed22c9cSNicholas Bellinger if (flag != 1) { 9832ed22c9cSNicholas Bellinger pr_err("Illegal value %d for pi_prot_format\n", flag); 9842ed22c9cSNicholas Bellinger return -EINVAL; 9852ed22c9cSNicholas Bellinger } 9862ed22c9cSNicholas Bellinger if (!dev->transport->format_prot) { 9872ed22c9cSNicholas Bellinger pr_err("DIF protection format not supported by backend %s\n", 9882ed22c9cSNicholas Bellinger dev->transport->name); 9892ed22c9cSNicholas Bellinger return -ENOSYS; 9902ed22c9cSNicholas Bellinger } 9912ed22c9cSNicholas Bellinger if (!(dev->dev_flags & DF_CONFIGURED)) { 9922ed22c9cSNicholas Bellinger pr_err("DIF protection format requires device to be configured\n"); 9932ed22c9cSNicholas Bellinger return -ENODEV; 9942ed22c9cSNicholas Bellinger } 9952ed22c9cSNicholas Bellinger if (dev->export_count) { 9962ed22c9cSNicholas Bellinger pr_err("dev[%p]: Unable to format SE Device PROT type while" 9972ed22c9cSNicholas Bellinger " export_count is %d\n", dev, dev->export_count); 9982ed22c9cSNicholas Bellinger return -EINVAL; 9992ed22c9cSNicholas Bellinger } 10002ed22c9cSNicholas Bellinger 10012ed22c9cSNicholas Bellinger rc = dev->transport->format_prot(dev); 10022ed22c9cSNicholas Bellinger if (rc) 10032ed22c9cSNicholas Bellinger return rc; 10042ed22c9cSNicholas Bellinger 10052ed22c9cSNicholas Bellinger pr_debug("dev[%p]: SE Device Protection Format complete\n", dev); 10062ed22c9cSNicholas Bellinger 10072ed22c9cSNicholas Bellinger return 0; 10082ed22c9cSNicholas Bellinger } 10092ed22c9cSNicholas Bellinger 1010c66ac9dbSNicholas Bellinger int se_dev_set_enforce_pr_isids(struct se_device *dev, int flag) 1011c66ac9dbSNicholas Bellinger { 1012c66ac9dbSNicholas Bellinger if ((flag != 0) && (flag != 1)) { 10136708bb27SAndy Grover pr_err("Illegal value %d\n", flag); 1014e3d6f909SAndy Grover return -EINVAL; 1015c66ac9dbSNicholas Bellinger } 10160fd97ccfSChristoph Hellwig dev->dev_attrib.enforce_pr_isids = flag; 10176708bb27SAndy Grover pr_debug("dev[%p]: SE Device enforce_pr_isids bit: %s\n", dev, 10180fd97ccfSChristoph Hellwig (dev->dev_attrib.enforce_pr_isids) ? "Enabled" : "Disabled"); 1019c66ac9dbSNicholas Bellinger return 0; 1020c66ac9dbSNicholas Bellinger } 1021c66ac9dbSNicholas Bellinger 1022e22a7f07SRoland Dreier int se_dev_set_is_nonrot(struct se_device *dev, int flag) 1023e22a7f07SRoland Dreier { 1024e22a7f07SRoland Dreier if ((flag != 0) && (flag != 1)) { 1025e22a7f07SRoland Dreier printk(KERN_ERR "Illegal value %d\n", flag); 1026e22a7f07SRoland Dreier return -EINVAL; 1027e22a7f07SRoland Dreier } 10280fd97ccfSChristoph Hellwig dev->dev_attrib.is_nonrot = flag; 10295de619a3SNicholas Bellinger pr_debug("dev[%p]: SE Device is_nonrot bit: %d\n", 1030e22a7f07SRoland Dreier dev, flag); 1031e22a7f07SRoland Dreier return 0; 1032e22a7f07SRoland Dreier } 1033e22a7f07SRoland Dreier 10345de619a3SNicholas Bellinger int se_dev_set_emulate_rest_reord(struct se_device *dev, int flag) 10355de619a3SNicholas Bellinger { 10365de619a3SNicholas Bellinger if (flag != 0) { 10375de619a3SNicholas Bellinger printk(KERN_ERR "dev[%p]: SE Device emulatation of restricted" 10385de619a3SNicholas Bellinger " reordering not implemented\n", dev); 10395de619a3SNicholas Bellinger return -ENOSYS; 10405de619a3SNicholas Bellinger } 10410fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_rest_reord = flag; 10425de619a3SNicholas Bellinger pr_debug("dev[%p]: SE Device emulate_rest_reord: %d\n", dev, flag); 10435de619a3SNicholas Bellinger return 0; 10445de619a3SNicholas Bellinger } 10455de619a3SNicholas Bellinger 1046c66ac9dbSNicholas Bellinger /* 1047c66ac9dbSNicholas Bellinger * Note, this can only be called on unexported SE Device Object. 1048c66ac9dbSNicholas Bellinger */ 1049c66ac9dbSNicholas Bellinger int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth) 1050c66ac9dbSNicholas Bellinger { 10510fd97ccfSChristoph Hellwig if (dev->export_count) { 10526708bb27SAndy Grover pr_err("dev[%p]: Unable to change SE Device TCQ while" 10530fd97ccfSChristoph Hellwig " export_count is %d\n", 10540fd97ccfSChristoph Hellwig dev, dev->export_count); 1055e3d6f909SAndy Grover return -EINVAL; 1056c66ac9dbSNicholas Bellinger } 10576708bb27SAndy Grover if (!queue_depth) { 10586708bb27SAndy Grover pr_err("dev[%p]: Illegal ZERO value for queue" 1059c66ac9dbSNicholas Bellinger "_depth\n", dev); 1060e3d6f909SAndy Grover return -EINVAL; 1061c66ac9dbSNicholas Bellinger } 1062c66ac9dbSNicholas Bellinger 1063e3d6f909SAndy Grover if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { 10640fd97ccfSChristoph Hellwig if (queue_depth > dev->dev_attrib.hw_queue_depth) { 10656708bb27SAndy Grover pr_err("dev[%p]: Passed queue_depth: %u" 1066c66ac9dbSNicholas Bellinger " exceeds TCM/SE_Device TCQ: %u\n", 1067c66ac9dbSNicholas Bellinger dev, queue_depth, 10680fd97ccfSChristoph Hellwig dev->dev_attrib.hw_queue_depth); 1069e3d6f909SAndy Grover return -EINVAL; 1070c66ac9dbSNicholas Bellinger } 1071c66ac9dbSNicholas Bellinger } else { 10720fd97ccfSChristoph Hellwig if (queue_depth > dev->dev_attrib.queue_depth) { 10730fd97ccfSChristoph Hellwig if (queue_depth > dev->dev_attrib.hw_queue_depth) { 10746708bb27SAndy Grover pr_err("dev[%p]: Passed queue_depth:" 1075c66ac9dbSNicholas Bellinger " %u exceeds TCM/SE_Device MAX" 1076c66ac9dbSNicholas Bellinger " TCQ: %u\n", dev, queue_depth, 10770fd97ccfSChristoph Hellwig dev->dev_attrib.hw_queue_depth); 1078e3d6f909SAndy Grover return -EINVAL; 1079c66ac9dbSNicholas Bellinger } 1080c66ac9dbSNicholas Bellinger } 1081c66ac9dbSNicholas Bellinger } 1082c66ac9dbSNicholas Bellinger 10830fd97ccfSChristoph Hellwig dev->dev_attrib.queue_depth = dev->queue_depth = queue_depth; 10846708bb27SAndy Grover pr_debug("dev[%p]: SE Device TCQ Depth changed to: %u\n", 1085c66ac9dbSNicholas Bellinger dev, queue_depth); 1086c66ac9dbSNicholas Bellinger return 0; 1087c66ac9dbSNicholas Bellinger } 1088c66ac9dbSNicholas Bellinger 1089015487b8SRoland Dreier int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors) 1090015487b8SRoland Dreier { 10917a3cf6caSNicholas Bellinger int block_size = dev->dev_attrib.block_size; 10927a3cf6caSNicholas Bellinger 10930fd97ccfSChristoph Hellwig if (dev->export_count) { 1094015487b8SRoland Dreier pr_err("dev[%p]: Unable to change SE Device" 10950fd97ccfSChristoph Hellwig " fabric_max_sectors while export_count is %d\n", 10960fd97ccfSChristoph Hellwig dev, dev->export_count); 1097015487b8SRoland Dreier return -EINVAL; 1098015487b8SRoland Dreier } 1099015487b8SRoland Dreier if (!fabric_max_sectors) { 1100015487b8SRoland Dreier pr_err("dev[%p]: Illegal ZERO value for" 1101015487b8SRoland Dreier " fabric_max_sectors\n", dev); 1102015487b8SRoland Dreier return -EINVAL; 1103015487b8SRoland Dreier } 1104015487b8SRoland Dreier if (fabric_max_sectors < DA_STATUS_MAX_SECTORS_MIN) { 1105015487b8SRoland Dreier pr_err("dev[%p]: Passed fabric_max_sectors: %u less than" 1106015487b8SRoland Dreier " DA_STATUS_MAX_SECTORS_MIN: %u\n", dev, fabric_max_sectors, 1107015487b8SRoland Dreier DA_STATUS_MAX_SECTORS_MIN); 1108015487b8SRoland Dreier return -EINVAL; 1109015487b8SRoland Dreier } 1110015487b8SRoland Dreier if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { 11110fd97ccfSChristoph Hellwig if (fabric_max_sectors > dev->dev_attrib.hw_max_sectors) { 1112015487b8SRoland Dreier pr_err("dev[%p]: Passed fabric_max_sectors: %u" 1113015487b8SRoland Dreier " greater than TCM/SE_Device max_sectors:" 1114015487b8SRoland Dreier " %u\n", dev, fabric_max_sectors, 11150fd97ccfSChristoph Hellwig dev->dev_attrib.hw_max_sectors); 1116015487b8SRoland Dreier return -EINVAL; 1117015487b8SRoland Dreier } 1118015487b8SRoland Dreier } else { 1119015487b8SRoland Dreier if (fabric_max_sectors > DA_STATUS_MAX_SECTORS_MAX) { 1120015487b8SRoland Dreier pr_err("dev[%p]: Passed fabric_max_sectors: %u" 1121015487b8SRoland Dreier " greater than DA_STATUS_MAX_SECTORS_MAX:" 1122015487b8SRoland Dreier " %u\n", dev, fabric_max_sectors, 1123015487b8SRoland Dreier DA_STATUS_MAX_SECTORS_MAX); 1124015487b8SRoland Dreier return -EINVAL; 1125015487b8SRoland Dreier } 1126015487b8SRoland Dreier } 1127015487b8SRoland Dreier /* 1128015487b8SRoland Dreier * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks() 1129015487b8SRoland Dreier */ 11307a3cf6caSNicholas Bellinger if (!block_size) { 11317a3cf6caSNicholas Bellinger block_size = 512; 11327a3cf6caSNicholas Bellinger pr_warn("Defaulting to 512 for zero block_size\n"); 11337a3cf6caSNicholas Bellinger } 1134015487b8SRoland Dreier fabric_max_sectors = se_dev_align_max_sectors(fabric_max_sectors, 11357a3cf6caSNicholas Bellinger block_size); 1136015487b8SRoland Dreier 11370fd97ccfSChristoph Hellwig dev->dev_attrib.fabric_max_sectors = fabric_max_sectors; 1138015487b8SRoland Dreier pr_debug("dev[%p]: SE Device max_sectors changed to %u\n", 1139015487b8SRoland Dreier dev, fabric_max_sectors); 1140015487b8SRoland Dreier return 0; 1141015487b8SRoland Dreier } 1142015487b8SRoland Dreier 1143c66ac9dbSNicholas Bellinger int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) 1144c66ac9dbSNicholas Bellinger { 11450fd97ccfSChristoph Hellwig if (dev->export_count) { 11466708bb27SAndy Grover pr_err("dev[%p]: Unable to change SE Device" 11470fd97ccfSChristoph Hellwig " optimal_sectors while export_count is %d\n", 11480fd97ccfSChristoph Hellwig dev, dev->export_count); 1149c66ac9dbSNicholas Bellinger return -EINVAL; 1150c66ac9dbSNicholas Bellinger } 1151e3d6f909SAndy Grover if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { 11526708bb27SAndy Grover pr_err("dev[%p]: Passed optimal_sectors cannot be" 1153c66ac9dbSNicholas Bellinger " changed for TCM/pSCSI\n", dev); 1154c66ac9dbSNicholas Bellinger return -EINVAL; 1155c66ac9dbSNicholas Bellinger } 11560fd97ccfSChristoph Hellwig if (optimal_sectors > dev->dev_attrib.fabric_max_sectors) { 11576708bb27SAndy Grover pr_err("dev[%p]: Passed optimal_sectors %u cannot be" 1158015487b8SRoland Dreier " greater than fabric_max_sectors: %u\n", dev, 11590fd97ccfSChristoph Hellwig optimal_sectors, dev->dev_attrib.fabric_max_sectors); 1160c66ac9dbSNicholas Bellinger return -EINVAL; 1161c66ac9dbSNicholas Bellinger } 1162c66ac9dbSNicholas Bellinger 11630fd97ccfSChristoph Hellwig dev->dev_attrib.optimal_sectors = optimal_sectors; 11646708bb27SAndy Grover pr_debug("dev[%p]: SE Device optimal_sectors changed to %u\n", 1165c66ac9dbSNicholas Bellinger dev, optimal_sectors); 1166c66ac9dbSNicholas Bellinger return 0; 1167c66ac9dbSNicholas Bellinger } 1168c66ac9dbSNicholas Bellinger 1169c66ac9dbSNicholas Bellinger int se_dev_set_block_size(struct se_device *dev, u32 block_size) 1170c66ac9dbSNicholas Bellinger { 11710fd97ccfSChristoph Hellwig if (dev->export_count) { 11726708bb27SAndy Grover pr_err("dev[%p]: Unable to change SE Device block_size" 11730fd97ccfSChristoph Hellwig " while export_count is %d\n", 11740fd97ccfSChristoph Hellwig dev, dev->export_count); 1175e3d6f909SAndy Grover return -EINVAL; 1176c66ac9dbSNicholas Bellinger } 1177c66ac9dbSNicholas Bellinger 1178c66ac9dbSNicholas Bellinger if ((block_size != 512) && 1179c66ac9dbSNicholas Bellinger (block_size != 1024) && 1180c66ac9dbSNicholas Bellinger (block_size != 2048) && 1181c66ac9dbSNicholas Bellinger (block_size != 4096)) { 11826708bb27SAndy Grover pr_err("dev[%p]: Illegal value for block_device: %u" 1183c66ac9dbSNicholas Bellinger " for SE device, must be 512, 1024, 2048 or 4096\n", 1184c66ac9dbSNicholas Bellinger dev, block_size); 1185e3d6f909SAndy Grover return -EINVAL; 1186c66ac9dbSNicholas Bellinger } 1187c66ac9dbSNicholas Bellinger 1188e3d6f909SAndy Grover if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { 11896708bb27SAndy Grover pr_err("dev[%p]: Not allowed to change block_size for" 1190c66ac9dbSNicholas Bellinger " Physical Device, use for Linux/SCSI to change" 1191c66ac9dbSNicholas Bellinger " block_size for underlying hardware\n", dev); 1192e3d6f909SAndy Grover return -EINVAL; 1193c66ac9dbSNicholas Bellinger } 1194c66ac9dbSNicholas Bellinger 11950fd97ccfSChristoph Hellwig dev->dev_attrib.block_size = block_size; 11966708bb27SAndy Grover pr_debug("dev[%p]: SE Device block_size changed to %u\n", 1197c66ac9dbSNicholas Bellinger dev, block_size); 119895cadaceSNicholas Bellinger 119995cadaceSNicholas Bellinger if (dev->dev_attrib.max_bytes_per_io) 120095cadaceSNicholas Bellinger dev->dev_attrib.hw_max_sectors = 120195cadaceSNicholas Bellinger dev->dev_attrib.max_bytes_per_io / block_size; 120295cadaceSNicholas Bellinger 1203c66ac9dbSNicholas Bellinger return 0; 1204c66ac9dbSNicholas Bellinger } 1205c66ac9dbSNicholas Bellinger 1206c66ac9dbSNicholas Bellinger struct se_lun *core_dev_add_lun( 1207c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1208c66ac9dbSNicholas Bellinger struct se_device *dev, 12092af7973aSAndy Grover u32 unpacked_lun) 1210c66ac9dbSNicholas Bellinger { 12112af7973aSAndy Grover struct se_lun *lun; 12128d9efe53SSebastian Andrzej Siewior int rc; 1213c66ac9dbSNicholas Bellinger 1214d344f8a1SAndy Grover lun = core_tpg_alloc_lun(tpg, unpacked_lun); 12152af7973aSAndy Grover if (IS_ERR(lun)) 12162af7973aSAndy Grover return lun; 1217c66ac9dbSNicholas Bellinger 1218d344f8a1SAndy Grover rc = core_tpg_add_lun(tpg, lun, 121958d92618SNicholas Bellinger TRANSPORT_LUNFLAGS_READ_WRITE, dev); 12208d9efe53SSebastian Andrzej Siewior if (rc < 0) 12218d9efe53SSebastian Andrzej Siewior return ERR_PTR(rc); 1222c66ac9dbSNicholas Bellinger 12236708bb27SAndy Grover pr_debug("%s_TPG[%u]_LUN[%u] - Activated %s Logical Unit from" 1224e3d6f909SAndy Grover " CORE HBA: %u\n", tpg->se_tpg_tfo->get_fabric_name(), 12252af7973aSAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, 12262dca673bSAndy Grover tpg->se_tpg_tfo->get_fabric_name(), dev->se_hba->hba_id); 1227c66ac9dbSNicholas Bellinger /* 1228c66ac9dbSNicholas Bellinger * Update LUN maps for dynamically added initiators when 1229c66ac9dbSNicholas Bellinger * generate_node_acl is enabled. 1230c66ac9dbSNicholas Bellinger */ 1231e3d6f909SAndy Grover if (tpg->se_tpg_tfo->tpg_check_demo_mode(tpg)) { 1232c66ac9dbSNicholas Bellinger struct se_node_acl *acl; 123328638887SRoland Dreier spin_lock_irq(&tpg->acl_node_lock); 1234c66ac9dbSNicholas Bellinger list_for_each_entry(acl, &tpg->acl_node_list, acl_list) { 1235052605c6SNicholas Bellinger if (acl->dynamic_node_acl && 1236052605c6SNicholas Bellinger (!tpg->se_tpg_tfo->tpg_check_demo_mode_login_only || 1237052605c6SNicholas Bellinger !tpg->se_tpg_tfo->tpg_check_demo_mode_login_only(tpg))) { 123828638887SRoland Dreier spin_unlock_irq(&tpg->acl_node_lock); 1239c66ac9dbSNicholas Bellinger core_tpg_add_node_to_devs(acl, tpg); 124028638887SRoland Dreier spin_lock_irq(&tpg->acl_node_lock); 1241c66ac9dbSNicholas Bellinger } 1242c66ac9dbSNicholas Bellinger } 124328638887SRoland Dreier spin_unlock_irq(&tpg->acl_node_lock); 1244c66ac9dbSNicholas Bellinger } 1245c66ac9dbSNicholas Bellinger 12462af7973aSAndy Grover return lun; 1247c66ac9dbSNicholas Bellinger } 1248c66ac9dbSNicholas Bellinger 1249c66ac9dbSNicholas Bellinger /* core_dev_del_lun(): 1250c66ac9dbSNicholas Bellinger * 1251c66ac9dbSNicholas Bellinger * 1252c66ac9dbSNicholas Bellinger */ 1253cd9d7cbaSAndy Grover void core_dev_del_lun( 1254c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1255cd9d7cbaSAndy Grover struct se_lun *lun) 1256c66ac9dbSNicholas Bellinger { 1257cd9d7cbaSAndy Grover pr_debug("%s_TPG[%u]_LUN[%u] - Deactivating %s Logical Unit from" 1258e3d6f909SAndy Grover " device object\n", tpg->se_tpg_tfo->get_fabric_name(), 1259cd9d7cbaSAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, 1260e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 1261c66ac9dbSNicholas Bellinger 1262cd9d7cbaSAndy Grover core_tpg_remove_lun(tpg, lun); 1263c66ac9dbSNicholas Bellinger } 1264c66ac9dbSNicholas Bellinger 1265c66ac9dbSNicholas Bellinger struct se_lun *core_get_lun_from_tpg(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" 1272c66ac9dbSNicholas Bellinger "_PER_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_FREE) { 12826708bb27SAndy Grover pr_err("%s Logical Unit Number: %u is not free 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 /* core_dev_get_lun(): 1295c66ac9dbSNicholas Bellinger * 1296c66ac9dbSNicholas Bellinger * 1297c66ac9dbSNicholas Bellinger */ 1298c66ac9dbSNicholas Bellinger static struct se_lun *core_dev_get_lun(struct se_portal_group *tpg, u32 unpacked_lun) 1299c66ac9dbSNicholas Bellinger { 1300c66ac9dbSNicholas Bellinger struct se_lun *lun; 1301c66ac9dbSNicholas Bellinger 1302c66ac9dbSNicholas Bellinger spin_lock(&tpg->tpg_lun_lock); 1303c66ac9dbSNicholas Bellinger if (unpacked_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) { 13046708bb27SAndy Grover pr_err("%s LUN: %u exceeds TRANSPORT_MAX_LUNS_PER" 1305c66ac9dbSNicholas Bellinger "_TPG-1: %u for Target Portal Group: %hu\n", 1306e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, 1307c66ac9dbSNicholas Bellinger TRANSPORT_MAX_LUNS_PER_TPG-1, 1308e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg)); 1309c66ac9dbSNicholas Bellinger spin_unlock(&tpg->tpg_lun_lock); 1310c66ac9dbSNicholas Bellinger return NULL; 1311c66ac9dbSNicholas Bellinger } 13124a5a75f3SJörn Engel lun = tpg->tpg_lun_list[unpacked_lun]; 1313c66ac9dbSNicholas Bellinger 1314c66ac9dbSNicholas Bellinger if (lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE) { 13156708bb27SAndy Grover pr_err("%s Logical Unit Number: %u is not active on" 1316c66ac9dbSNicholas Bellinger " Target Portal Group: %hu, ignoring request.\n", 1317e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, 1318e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg)); 1319c66ac9dbSNicholas Bellinger spin_unlock(&tpg->tpg_lun_lock); 1320c66ac9dbSNicholas Bellinger return NULL; 1321c66ac9dbSNicholas Bellinger } 1322c66ac9dbSNicholas Bellinger spin_unlock(&tpg->tpg_lun_lock); 1323c66ac9dbSNicholas Bellinger 1324c66ac9dbSNicholas Bellinger return lun; 1325c66ac9dbSNicholas Bellinger } 1326c66ac9dbSNicholas Bellinger 1327c66ac9dbSNicholas Bellinger struct se_lun_acl *core_dev_init_initiator_node_lun_acl( 1328c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1329fcf29481SNicholas Bellinger struct se_node_acl *nacl, 1330c66ac9dbSNicholas Bellinger u32 mapped_lun, 1331c66ac9dbSNicholas Bellinger int *ret) 1332c66ac9dbSNicholas Bellinger { 1333c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl; 1334c66ac9dbSNicholas Bellinger 1335fcf29481SNicholas Bellinger if (strlen(nacl->initiatorname) >= TRANSPORT_IQN_LEN) { 13366708bb27SAndy Grover pr_err("%s InitiatorName exceeds maximum size.\n", 1337e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name()); 1338c66ac9dbSNicholas Bellinger *ret = -EOVERFLOW; 1339c66ac9dbSNicholas Bellinger return NULL; 1340c66ac9dbSNicholas Bellinger } 1341c66ac9dbSNicholas Bellinger lacl = kzalloc(sizeof(struct se_lun_acl), GFP_KERNEL); 13426708bb27SAndy Grover if (!lacl) { 13436708bb27SAndy Grover pr_err("Unable to allocate memory for struct se_lun_acl.\n"); 1344c66ac9dbSNicholas Bellinger *ret = -ENOMEM; 1345c66ac9dbSNicholas Bellinger return NULL; 1346c66ac9dbSNicholas Bellinger } 1347c66ac9dbSNicholas Bellinger 1348c66ac9dbSNicholas Bellinger INIT_LIST_HEAD(&lacl->lacl_list); 1349c66ac9dbSNicholas Bellinger lacl->mapped_lun = mapped_lun; 1350c66ac9dbSNicholas Bellinger lacl->se_lun_nacl = nacl; 1351fcf29481SNicholas Bellinger snprintf(lacl->initiatorname, TRANSPORT_IQN_LEN, "%s", 1352fcf29481SNicholas Bellinger nacl->initiatorname); 1353c66ac9dbSNicholas Bellinger 1354c66ac9dbSNicholas Bellinger return lacl; 1355c66ac9dbSNicholas Bellinger } 1356c66ac9dbSNicholas Bellinger 1357c66ac9dbSNicholas Bellinger int core_dev_add_initiator_node_lun_acl( 1358c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1359c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl, 1360c66ac9dbSNicholas Bellinger u32 unpacked_lun, 1361c66ac9dbSNicholas Bellinger u32 lun_access) 1362c66ac9dbSNicholas Bellinger { 1363c66ac9dbSNicholas Bellinger struct se_lun *lun; 1364c66ac9dbSNicholas Bellinger struct se_node_acl *nacl; 1365c66ac9dbSNicholas Bellinger 1366c66ac9dbSNicholas Bellinger lun = core_dev_get_lun(tpg, unpacked_lun); 13676708bb27SAndy Grover if (!lun) { 13686708bb27SAndy Grover pr_err("%s Logical Unit Number: %u is not active on" 1369c66ac9dbSNicholas Bellinger " Target Portal Group: %hu, ignoring request.\n", 1370e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), unpacked_lun, 1371e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg)); 1372c66ac9dbSNicholas Bellinger return -EINVAL; 1373c66ac9dbSNicholas Bellinger } 1374c66ac9dbSNicholas Bellinger 1375c66ac9dbSNicholas Bellinger nacl = lacl->se_lun_nacl; 13766708bb27SAndy Grover if (!nacl) 1377c66ac9dbSNicholas Bellinger return -EINVAL; 1378c66ac9dbSNicholas Bellinger 1379c66ac9dbSNicholas Bellinger if ((lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) && 1380c66ac9dbSNicholas Bellinger (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE)) 1381c66ac9dbSNicholas Bellinger lun_access = TRANSPORT_LUNFLAGS_READ_ONLY; 1382c66ac9dbSNicholas Bellinger 1383c66ac9dbSNicholas Bellinger lacl->se_lun = lun; 1384c66ac9dbSNicholas Bellinger 1385e80ac6c4SAndy Grover if (core_enable_device_list_for_node(lun, lacl, lacl->mapped_lun, 1386e80ac6c4SAndy Grover lun_access, nacl, tpg) < 0) 1387c66ac9dbSNicholas Bellinger return -EINVAL; 1388c66ac9dbSNicholas Bellinger 1389c66ac9dbSNicholas Bellinger spin_lock(&lun->lun_acl_lock); 1390c66ac9dbSNicholas Bellinger list_add_tail(&lacl->lacl_list, &lun->lun_acl_list); 1391c66ac9dbSNicholas Bellinger atomic_inc(&lun->lun_acl_count); 13924e857c58SPeter Zijlstra smp_mb__after_atomic(); 1393c66ac9dbSNicholas Bellinger spin_unlock(&lun->lun_acl_lock); 1394c66ac9dbSNicholas Bellinger 13956708bb27SAndy Grover pr_debug("%s_TPG[%hu]_LUN[%u->%u] - Added %s ACL for " 1396e3d6f909SAndy Grover " InitiatorNode: %s\n", tpg->se_tpg_tfo->get_fabric_name(), 1397e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), unpacked_lun, lacl->mapped_lun, 1398c66ac9dbSNicholas Bellinger (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) ? "RW" : "RO", 1399c66ac9dbSNicholas Bellinger lacl->initiatorname); 1400c66ac9dbSNicholas Bellinger /* 1401c66ac9dbSNicholas Bellinger * Check to see if there are any existing persistent reservation APTPL 1402c66ac9dbSNicholas Bellinger * pre-registrations that need to be enabled for this LUN ACL.. 1403c66ac9dbSNicholas Bellinger */ 1404c66ac9dbSNicholas Bellinger core_scsi3_check_aptpl_registration(lun->lun_se_dev, tpg, lun, lacl); 1405c66ac9dbSNicholas Bellinger return 0; 1406c66ac9dbSNicholas Bellinger } 1407c66ac9dbSNicholas Bellinger 1408c66ac9dbSNicholas Bellinger /* core_dev_del_initiator_node_lun_acl(): 1409c66ac9dbSNicholas Bellinger * 1410c66ac9dbSNicholas Bellinger * 1411c66ac9dbSNicholas Bellinger */ 1412c66ac9dbSNicholas Bellinger int core_dev_del_initiator_node_lun_acl( 1413c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1414c66ac9dbSNicholas Bellinger struct se_lun *lun, 1415c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl) 1416c66ac9dbSNicholas Bellinger { 1417c66ac9dbSNicholas Bellinger struct se_node_acl *nacl; 1418c66ac9dbSNicholas Bellinger 1419c66ac9dbSNicholas Bellinger nacl = lacl->se_lun_nacl; 14206708bb27SAndy Grover if (!nacl) 1421c66ac9dbSNicholas Bellinger return -EINVAL; 1422c66ac9dbSNicholas Bellinger 1423c66ac9dbSNicholas Bellinger spin_lock(&lun->lun_acl_lock); 1424c66ac9dbSNicholas Bellinger list_del(&lacl->lacl_list); 1425c66ac9dbSNicholas Bellinger atomic_dec(&lun->lun_acl_count); 14264e857c58SPeter Zijlstra smp_mb__after_atomic(); 1427c66ac9dbSNicholas Bellinger spin_unlock(&lun->lun_acl_lock); 1428c66ac9dbSNicholas Bellinger 1429e80ac6c4SAndy Grover core_disable_device_list_for_node(lun, NULL, lacl->mapped_lun, 1430e80ac6c4SAndy Grover TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg); 1431c66ac9dbSNicholas Bellinger 1432c66ac9dbSNicholas Bellinger lacl->se_lun = NULL; 1433c66ac9dbSNicholas Bellinger 14346708bb27SAndy Grover pr_debug("%s_TPG[%hu]_LUN[%u] - Removed ACL for" 1435c66ac9dbSNicholas Bellinger " InitiatorNode: %s Mapped LUN: %u\n", 1436e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), 1437e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, 1438c66ac9dbSNicholas Bellinger lacl->initiatorname, lacl->mapped_lun); 1439c66ac9dbSNicholas Bellinger 1440c66ac9dbSNicholas Bellinger return 0; 1441c66ac9dbSNicholas Bellinger } 1442c66ac9dbSNicholas Bellinger 1443c66ac9dbSNicholas Bellinger void core_dev_free_initiator_node_lun_acl( 1444c66ac9dbSNicholas Bellinger struct se_portal_group *tpg, 1445c66ac9dbSNicholas Bellinger struct se_lun_acl *lacl) 1446c66ac9dbSNicholas Bellinger { 14476708bb27SAndy Grover pr_debug("%s_TPG[%hu] - Freeing ACL for %s InitiatorNode: %s" 1448e3d6f909SAndy Grover " Mapped LUN: %u\n", tpg->se_tpg_tfo->get_fabric_name(), 1449e3d6f909SAndy Grover tpg->se_tpg_tfo->tpg_get_tag(tpg), 1450e3d6f909SAndy Grover tpg->se_tpg_tfo->get_fabric_name(), 1451c66ac9dbSNicholas Bellinger lacl->initiatorname, lacl->mapped_lun); 1452c66ac9dbSNicholas Bellinger 1453c66ac9dbSNicholas Bellinger kfree(lacl); 1454c66ac9dbSNicholas Bellinger } 1455c66ac9dbSNicholas Bellinger 14560fd97ccfSChristoph Hellwig static void scsi_dump_inquiry(struct se_device *dev) 14570fd97ccfSChristoph Hellwig { 14580fd97ccfSChristoph Hellwig struct t10_wwn *wwn = &dev->t10_wwn; 14590fd97ccfSChristoph Hellwig char buf[17]; 14600fd97ccfSChristoph Hellwig int i, device_type; 14610fd97ccfSChristoph Hellwig /* 14620fd97ccfSChristoph Hellwig * Print Linux/SCSI style INQUIRY formatting to the kernel ring buffer 14630fd97ccfSChristoph Hellwig */ 14640fd97ccfSChristoph Hellwig for (i = 0; i < 8; i++) 14650fd97ccfSChristoph Hellwig if (wwn->vendor[i] >= 0x20) 14660fd97ccfSChristoph Hellwig buf[i] = wwn->vendor[i]; 14670fd97ccfSChristoph Hellwig else 14680fd97ccfSChristoph Hellwig buf[i] = ' '; 14690fd97ccfSChristoph Hellwig buf[i] = '\0'; 14700fd97ccfSChristoph Hellwig pr_debug(" Vendor: %s\n", buf); 14710fd97ccfSChristoph Hellwig 14720fd97ccfSChristoph Hellwig for (i = 0; i < 16; i++) 14730fd97ccfSChristoph Hellwig if (wwn->model[i] >= 0x20) 14740fd97ccfSChristoph Hellwig buf[i] = wwn->model[i]; 14750fd97ccfSChristoph Hellwig else 14760fd97ccfSChristoph Hellwig buf[i] = ' '; 14770fd97ccfSChristoph Hellwig buf[i] = '\0'; 14780fd97ccfSChristoph Hellwig pr_debug(" Model: %s\n", buf); 14790fd97ccfSChristoph Hellwig 14800fd97ccfSChristoph Hellwig for (i = 0; i < 4; i++) 14810fd97ccfSChristoph Hellwig if (wwn->revision[i] >= 0x20) 14820fd97ccfSChristoph Hellwig buf[i] = wwn->revision[i]; 14830fd97ccfSChristoph Hellwig else 14840fd97ccfSChristoph Hellwig buf[i] = ' '; 14850fd97ccfSChristoph Hellwig buf[i] = '\0'; 14860fd97ccfSChristoph Hellwig pr_debug(" Revision: %s\n", buf); 14870fd97ccfSChristoph Hellwig 14880fd97ccfSChristoph Hellwig device_type = dev->transport->get_device_type(dev); 14890fd97ccfSChristoph Hellwig pr_debug(" Type: %s ", scsi_device_type(device_type)); 14900fd97ccfSChristoph Hellwig } 14910fd97ccfSChristoph Hellwig 14920fd97ccfSChristoph Hellwig struct se_device *target_alloc_device(struct se_hba *hba, const char *name) 14930fd97ccfSChristoph Hellwig { 14940fd97ccfSChristoph Hellwig struct se_device *dev; 14954863e525SNicholas Bellinger struct se_lun *xcopy_lun; 14960fd97ccfSChristoph Hellwig 14970fd97ccfSChristoph Hellwig dev = hba->transport->alloc_device(hba, name); 14980fd97ccfSChristoph Hellwig if (!dev) 14990fd97ccfSChristoph Hellwig return NULL; 15000fd97ccfSChristoph Hellwig 15010ff87549SNicholas Bellinger dev->dev_link_magic = SE_DEV_LINK_MAGIC; 15020fd97ccfSChristoph Hellwig dev->se_hba = hba; 15030fd97ccfSChristoph Hellwig dev->transport = hba->transport; 15042ed22c9cSNicholas Bellinger dev->prot_length = sizeof(struct se_dif_v1_tuple); 15050fd97ccfSChristoph Hellwig 15060fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->dev_list); 15070fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->dev_sep_list); 15080fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->dev_tmr_list); 15090fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->delayed_cmd_list); 15100fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->state_list); 15110fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->qf_cmd_list); 1512d9ea32bfSNicholas Bellinger INIT_LIST_HEAD(&dev->g_dev_node); 15130fd97ccfSChristoph Hellwig spin_lock_init(&dev->execute_task_lock); 15140fd97ccfSChristoph Hellwig spin_lock_init(&dev->delayed_cmd_lock); 15150fd97ccfSChristoph Hellwig spin_lock_init(&dev->dev_reservation_lock); 15160fd97ccfSChristoph Hellwig spin_lock_init(&dev->se_port_lock); 15170fd97ccfSChristoph Hellwig spin_lock_init(&dev->se_tmr_lock); 15180fd97ccfSChristoph Hellwig spin_lock_init(&dev->qf_cmd_lock); 151968ff9b9bSNicholas Bellinger sema_init(&dev->caw_sem, 1); 15200fd97ccfSChristoph Hellwig atomic_set(&dev->dev_ordered_id, 0); 15210fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_wwn.t10_vpd_list); 15220fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_wwn.t10_vpd_lock); 15230fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_pr.registration_list); 15240fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_pr.aptpl_reg_list); 15250fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_pr.registration_lock); 15260fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_pr.aptpl_reg_lock); 15270fd97ccfSChristoph Hellwig INIT_LIST_HEAD(&dev->t10_alua.tg_pt_gps_list); 15280fd97ccfSChristoph Hellwig spin_lock_init(&dev->t10_alua.tg_pt_gps_lock); 1529c66094bfSHannes Reinecke INIT_LIST_HEAD(&dev->t10_alua.lba_map_list); 1530c66094bfSHannes Reinecke spin_lock_init(&dev->t10_alua.lba_map_lock); 15310fd97ccfSChristoph Hellwig 15320fd97ccfSChristoph Hellwig dev->t10_wwn.t10_dev = dev; 15330fd97ccfSChristoph Hellwig dev->t10_alua.t10_dev = dev; 15340fd97ccfSChristoph Hellwig 15350fd97ccfSChristoph Hellwig dev->dev_attrib.da_dev = dev; 1536adfa9570STregaron Bayly dev->dev_attrib.emulate_model_alias = DA_EMULATE_MODEL_ALIAS; 15370fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_dpo = DA_EMULATE_DPO; 15380fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_fua_write = DA_EMULATE_FUA_WRITE; 15390fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_fua_read = DA_EMULATE_FUA_READ; 15400fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_write_cache = DA_EMULATE_WRITE_CACHE; 15410fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_ua_intlck_ctrl = DA_EMULATE_UA_INTLLCK_CTRL; 15420fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tas = DA_EMULATE_TAS; 15430fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tpu = DA_EMULATE_TPU; 15440fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_tpws = DA_EMULATE_TPWS; 15450123a9ecSNicholas Bellinger dev->dev_attrib.emulate_caw = DA_EMULATE_CAW; 1546d397a445SNicholas Bellinger dev->dev_attrib.emulate_3pc = DA_EMULATE_3PC; 15472ed22c9cSNicholas Bellinger dev->dev_attrib.pi_prot_type = TARGET_DIF_TYPE0_PROT; 15480fd97ccfSChristoph Hellwig dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS; 15490fd97ccfSChristoph Hellwig dev->dev_attrib.is_nonrot = DA_IS_NONROT; 15500fd97ccfSChristoph Hellwig dev->dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD; 15510fd97ccfSChristoph Hellwig dev->dev_attrib.max_unmap_lba_count = DA_MAX_UNMAP_LBA_COUNT; 15520fd97ccfSChristoph Hellwig dev->dev_attrib.max_unmap_block_desc_count = 15530fd97ccfSChristoph Hellwig DA_MAX_UNMAP_BLOCK_DESC_COUNT; 15540fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity = DA_UNMAP_GRANULARITY_DEFAULT; 15550fd97ccfSChristoph Hellwig dev->dev_attrib.unmap_granularity_alignment = 15560fd97ccfSChristoph Hellwig DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT; 1557773cbaf7SNicholas Bellinger dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN; 15580fd97ccfSChristoph Hellwig dev->dev_attrib.fabric_max_sectors = DA_FABRIC_MAX_SECTORS; 15590fd97ccfSChristoph Hellwig dev->dev_attrib.optimal_sectors = DA_FABRIC_MAX_SECTORS; 15600fd97ccfSChristoph Hellwig 15614863e525SNicholas Bellinger xcopy_lun = &dev->xcopy_lun; 15624863e525SNicholas Bellinger xcopy_lun->lun_se_dev = dev; 15634863e525SNicholas Bellinger init_completion(&xcopy_lun->lun_shutdown_comp); 15644863e525SNicholas Bellinger INIT_LIST_HEAD(&xcopy_lun->lun_acl_list); 15654863e525SNicholas Bellinger spin_lock_init(&xcopy_lun->lun_acl_lock); 15664863e525SNicholas Bellinger spin_lock_init(&xcopy_lun->lun_sep_lock); 15674863e525SNicholas Bellinger init_completion(&xcopy_lun->lun_ref_comp); 15684863e525SNicholas Bellinger 15690fd97ccfSChristoph Hellwig return dev; 15700fd97ccfSChristoph Hellwig } 15710fd97ccfSChristoph Hellwig 15720fd97ccfSChristoph Hellwig int target_configure_device(struct se_device *dev) 15730fd97ccfSChristoph Hellwig { 15740fd97ccfSChristoph Hellwig struct se_hba *hba = dev->se_hba; 15750fd97ccfSChristoph Hellwig int ret; 15760fd97ccfSChristoph Hellwig 15770fd97ccfSChristoph Hellwig if (dev->dev_flags & DF_CONFIGURED) { 15780fd97ccfSChristoph Hellwig pr_err("se_dev->se_dev_ptr already set for storage" 15790fd97ccfSChristoph Hellwig " object\n"); 15800fd97ccfSChristoph Hellwig return -EEXIST; 15810fd97ccfSChristoph Hellwig } 15820fd97ccfSChristoph Hellwig 15830fd97ccfSChristoph Hellwig ret = dev->transport->configure_device(dev); 15840fd97ccfSChristoph Hellwig if (ret) 15850fd97ccfSChristoph Hellwig goto out; 15860fd97ccfSChristoph Hellwig dev->dev_flags |= DF_CONFIGURED; 15870fd97ccfSChristoph Hellwig 15880fd97ccfSChristoph Hellwig /* 15890fd97ccfSChristoph Hellwig * XXX: there is not much point to have two different values here.. 15900fd97ccfSChristoph Hellwig */ 15910fd97ccfSChristoph Hellwig dev->dev_attrib.block_size = dev->dev_attrib.hw_block_size; 15920fd97ccfSChristoph Hellwig dev->dev_attrib.queue_depth = dev->dev_attrib.hw_queue_depth; 15930fd97ccfSChristoph Hellwig 15940fd97ccfSChristoph Hellwig /* 15950fd97ccfSChristoph Hellwig * Align max_hw_sectors down to PAGE_SIZE I/O transfers 15960fd97ccfSChristoph Hellwig */ 15970fd97ccfSChristoph Hellwig dev->dev_attrib.hw_max_sectors = 15980fd97ccfSChristoph Hellwig se_dev_align_max_sectors(dev->dev_attrib.hw_max_sectors, 15990fd97ccfSChristoph Hellwig dev->dev_attrib.hw_block_size); 16000fd97ccfSChristoph Hellwig 16010fd97ccfSChristoph Hellwig dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX); 16020fd97ccfSChristoph Hellwig dev->creation_time = get_jiffies_64(); 16030fd97ccfSChristoph Hellwig 16040fd97ccfSChristoph Hellwig ret = core_setup_alua(dev); 16050fd97ccfSChristoph Hellwig if (ret) 16060fd97ccfSChristoph Hellwig goto out; 16070fd97ccfSChristoph Hellwig 16080fd97ccfSChristoph Hellwig /* 16090fd97ccfSChristoph Hellwig * Startup the struct se_device processing thread 16100fd97ccfSChristoph Hellwig */ 16110fd97ccfSChristoph Hellwig dev->tmr_wq = alloc_workqueue("tmr-%s", WQ_MEM_RECLAIM | WQ_UNBOUND, 1, 16120fd97ccfSChristoph Hellwig dev->transport->name); 16130fd97ccfSChristoph Hellwig if (!dev->tmr_wq) { 16140fd97ccfSChristoph Hellwig pr_err("Unable to create tmr workqueue for %s\n", 16150fd97ccfSChristoph Hellwig dev->transport->name); 16160fd97ccfSChristoph Hellwig ret = -ENOMEM; 16170fd97ccfSChristoph Hellwig goto out_free_alua; 16180fd97ccfSChristoph Hellwig } 16190fd97ccfSChristoph Hellwig 16200fd97ccfSChristoph Hellwig /* 16210fd97ccfSChristoph Hellwig * Setup work_queue for QUEUE_FULL 16220fd97ccfSChristoph Hellwig */ 16230fd97ccfSChristoph Hellwig INIT_WORK(&dev->qf_work_queue, target_qf_do_work); 16240fd97ccfSChristoph Hellwig 16250fd97ccfSChristoph Hellwig /* 16260fd97ccfSChristoph Hellwig * Preload the initial INQUIRY const values if we are doing 16270fd97ccfSChristoph Hellwig * anything virtual (IBLOCK, FILEIO, RAMDISK), but not for TCM/pSCSI 16280fd97ccfSChristoph Hellwig * passthrough because this is being provided by the backend LLD. 16290fd97ccfSChristoph Hellwig */ 16300fd97ccfSChristoph Hellwig if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) { 16310fd97ccfSChristoph Hellwig strncpy(&dev->t10_wwn.vendor[0], "LIO-ORG", 8); 16320fd97ccfSChristoph Hellwig strncpy(&dev->t10_wwn.model[0], 16330fd97ccfSChristoph Hellwig dev->transport->inquiry_prod, 16); 16340fd97ccfSChristoph Hellwig strncpy(&dev->t10_wwn.revision[0], 16350fd97ccfSChristoph Hellwig dev->transport->inquiry_rev, 4); 16360fd97ccfSChristoph Hellwig } 16370fd97ccfSChristoph Hellwig 16380fd97ccfSChristoph Hellwig scsi_dump_inquiry(dev); 16390fd97ccfSChristoph Hellwig 16400fd97ccfSChristoph Hellwig spin_lock(&hba->device_lock); 16410fd97ccfSChristoph Hellwig hba->dev_count++; 16420fd97ccfSChristoph Hellwig spin_unlock(&hba->device_lock); 1643d9ea32bfSNicholas Bellinger 1644d9ea32bfSNicholas Bellinger mutex_lock(&g_device_mutex); 1645d9ea32bfSNicholas Bellinger list_add_tail(&dev->g_dev_node, &g_device_list); 1646d9ea32bfSNicholas Bellinger mutex_unlock(&g_device_mutex); 1647d9ea32bfSNicholas Bellinger 16480fd97ccfSChristoph Hellwig return 0; 16490fd97ccfSChristoph Hellwig 16500fd97ccfSChristoph Hellwig out_free_alua: 16510fd97ccfSChristoph Hellwig core_alua_free_lu_gp_mem(dev); 16520fd97ccfSChristoph Hellwig out: 16530fd97ccfSChristoph Hellwig se_release_vpd_for_dev(dev); 16540fd97ccfSChristoph Hellwig return ret; 16550fd97ccfSChristoph Hellwig } 16560fd97ccfSChristoph Hellwig 16570fd97ccfSChristoph Hellwig void target_free_device(struct se_device *dev) 16580fd97ccfSChristoph Hellwig { 16590fd97ccfSChristoph Hellwig struct se_hba *hba = dev->se_hba; 16600fd97ccfSChristoph Hellwig 16610fd97ccfSChristoph Hellwig WARN_ON(!list_empty(&dev->dev_sep_list)); 16620fd97ccfSChristoph Hellwig 16630fd97ccfSChristoph Hellwig if (dev->dev_flags & DF_CONFIGURED) { 16640fd97ccfSChristoph Hellwig destroy_workqueue(dev->tmr_wq); 16650fd97ccfSChristoph Hellwig 1666d9ea32bfSNicholas Bellinger mutex_lock(&g_device_mutex); 1667d9ea32bfSNicholas Bellinger list_del(&dev->g_dev_node); 1668d9ea32bfSNicholas Bellinger mutex_unlock(&g_device_mutex); 1669d9ea32bfSNicholas Bellinger 16700fd97ccfSChristoph Hellwig spin_lock(&hba->device_lock); 16710fd97ccfSChristoph Hellwig hba->dev_count--; 16720fd97ccfSChristoph Hellwig spin_unlock(&hba->device_lock); 16730fd97ccfSChristoph Hellwig } 16740fd97ccfSChristoph Hellwig 16750fd97ccfSChristoph Hellwig core_alua_free_lu_gp_mem(dev); 1676229d4f11SHannes Reinecke core_alua_set_lba_map(dev, NULL, 0, 0); 16770fd97ccfSChristoph Hellwig core_scsi3_free_all_registrations(dev); 16780fd97ccfSChristoph Hellwig se_release_vpd_for_dev(dev); 16790fd97ccfSChristoph Hellwig 16802ed22c9cSNicholas Bellinger if (dev->transport->free_prot) 16812ed22c9cSNicholas Bellinger dev->transport->free_prot(dev); 16822ed22c9cSNicholas Bellinger 16830fd97ccfSChristoph Hellwig dev->transport->free_device(dev); 16840fd97ccfSChristoph Hellwig } 16850fd97ccfSChristoph Hellwig 1686c66ac9dbSNicholas Bellinger int core_dev_setup_virtual_lun0(void) 1687c66ac9dbSNicholas Bellinger { 1688c66ac9dbSNicholas Bellinger struct se_hba *hba; 1689c66ac9dbSNicholas Bellinger struct se_device *dev; 1690db5d1c3cSAndy Grover char buf[] = "rd_pages=8,rd_nullio=1"; 1691c66ac9dbSNicholas Bellinger int ret; 1692c66ac9dbSNicholas Bellinger 16936708bb27SAndy Grover hba = core_alloc_hba("rd_mcp", 0, HBA_FLAGS_INTERNAL_USE); 1694c66ac9dbSNicholas Bellinger if (IS_ERR(hba)) 1695c66ac9dbSNicholas Bellinger return PTR_ERR(hba); 1696c66ac9dbSNicholas Bellinger 16970fd97ccfSChristoph Hellwig dev = target_alloc_device(hba, "virt_lun0"); 16980fd97ccfSChristoph Hellwig if (!dev) { 1699c66ac9dbSNicholas Bellinger ret = -ENOMEM; 17000fd97ccfSChristoph Hellwig goto out_free_hba; 1701c66ac9dbSNicholas Bellinger } 1702c66ac9dbSNicholas Bellinger 17030fd97ccfSChristoph Hellwig hba->transport->set_configfs_dev_params(dev, buf, sizeof(buf)); 1704c66ac9dbSNicholas Bellinger 17050fd97ccfSChristoph Hellwig ret = target_configure_device(dev); 17060fd97ccfSChristoph Hellwig if (ret) 17070fd97ccfSChristoph Hellwig goto out_free_se_dev; 17080fd97ccfSChristoph Hellwig 17090fd97ccfSChristoph Hellwig lun0_hba = hba; 1710e3d6f909SAndy Grover g_lun0_dev = dev; 1711c66ac9dbSNicholas Bellinger return 0; 17120fd97ccfSChristoph Hellwig 17130fd97ccfSChristoph Hellwig out_free_se_dev: 17140fd97ccfSChristoph Hellwig target_free_device(dev); 17150fd97ccfSChristoph Hellwig out_free_hba: 17160fd97ccfSChristoph Hellwig core_delete_hba(hba); 1717c66ac9dbSNicholas Bellinger return ret; 1718c66ac9dbSNicholas Bellinger } 1719c66ac9dbSNicholas Bellinger 1720c66ac9dbSNicholas Bellinger 1721c66ac9dbSNicholas Bellinger void core_dev_release_virtual_lun0(void) 1722c66ac9dbSNicholas Bellinger { 1723e3d6f909SAndy Grover struct se_hba *hba = lun0_hba; 1724c66ac9dbSNicholas Bellinger 17256708bb27SAndy Grover if (!hba) 1726c66ac9dbSNicholas Bellinger return; 1727c66ac9dbSNicholas Bellinger 1728e3d6f909SAndy Grover if (g_lun0_dev) 17290fd97ccfSChristoph Hellwig target_free_device(g_lun0_dev); 1730c66ac9dbSNicholas Bellinger core_delete_hba(hba); 1731c66ac9dbSNicholas Bellinger } 1732