^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Xen SCSI backend driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2008, FUJITSU Limited
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Based on the blkback driver code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Adaption to kernel taget core infrastructure taken from vhost/scsi.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * modify it under the terms of the GNU General Public License version 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * as published by the Free Software Foundation; or, when distributed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * separately from the Linux kernel or incorporated into other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * software packages, subject to the following license:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Permission is hereby granted, free of charge, to any person obtaining a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * of this source file (the "Software"), to deal in the Software without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * restriction, including without limitation the rights to use, copy, modify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * merge, publish, distribute, sublicense, and/or sell copies of the Software,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * and to permit persons to whom the Software is furnished to do so, subject to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * the following conditions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * The above copyright notice and this permission notice shall be included in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * all copies or substantial portions of the Software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * IN THE SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define pr_fmt(fmt) "xen-pvscsi: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <stdarg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/utsname.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/configfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <generated/utsrelease.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <scsi/scsi_host.h> /* SG_ALL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <target/target_core_base.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <target/target_core_fabric.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <asm/hypervisor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include <xen/xen.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include <xen/balloon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #include <xen/events.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #include <xen/xenbus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include <xen/grant_table.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include <xen/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #include <xen/interface/grant_table.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #include <xen/interface/io/vscsiif.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define VSCSI_VERSION "v0.1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define VSCSI_NAMELEN 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct ids_tuple {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) unsigned int hst; /* host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) unsigned int chn; /* channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) unsigned int tgt; /* target */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) unsigned int lun; /* LUN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct v2p_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct ids_tuple v; /* translate from */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct scsiback_tpg *tpg; /* translate to */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) unsigned int lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct kref kref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct list_head l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct vscsibk_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct xenbus_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) domid_t domid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) unsigned int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct vscsiif_back_ring ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) spinlock_t ring_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) atomic_t nr_unreplied_reqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) spinlock_t v2p_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct list_head v2p_entry_lists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) wait_queue_head_t waiting_to_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct gnttab_page_cache free_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* theoretical maximum of grants for one request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define VSCSI_MAX_GRANTS (SG_ALL + VSCSIIF_SG_TABLESIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * VSCSI_GRANT_BATCH is the maximum number of grants to be processed in one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * call to map/unmap grants. Don't choose it too large, as there are arrays
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * with VSCSI_GRANT_BATCH elements allocated on the stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define VSCSI_GRANT_BATCH 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct vscsibk_pend {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) uint16_t rqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) uint8_t cmnd[VSCSIIF_MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) uint8_t cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) uint8_t sc_data_direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) uint16_t n_sg; /* real length of SG list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) uint16_t n_grants; /* SG pages and potentially SG list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) uint32_t data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) uint32_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct vscsibk_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct v2p_entry *v2p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct scatterlist *sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) uint8_t sense_buffer[VSCSIIF_SENSE_BUFFERSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) grant_handle_t grant_handles[VSCSI_MAX_GRANTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct page *pages[VSCSI_MAX_GRANTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct se_cmd se_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct completion tmr_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define VSCSI_DEFAULT_SESSION_TAGS 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct scsiback_nexus {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* Pointer to TCM session for I_T Nexus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct se_session *tvn_se_sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct scsiback_tport {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* SCSI protocol the tport is providing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) u8 tport_proto_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* Binary World Wide unique Port Name for pvscsi Target port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u64 tport_wwpn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* ASCII formatted WWPN for pvscsi Target port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) char tport_name[VSCSI_NAMELEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* Returned by scsiback_make_tport() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct se_wwn tport_wwn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct scsiback_tpg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* scsiback port target portal group tag for TCM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) u16 tport_tpgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* track number of TPG Port/Lun Links wrt explicit I_T Nexus shutdown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int tv_tpg_port_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* xen-pvscsi references to tpg_nexus, protected by tv_tpg_mutex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int tv_tpg_fe_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* list for scsiback_list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct list_head tv_tpg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* Used to protect access for tpg_nexus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct mutex tv_tpg_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* Pointer to the TCM pvscsi I_T Nexus for this TPG endpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct scsiback_nexus *tpg_nexus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* Pointer back to scsiback_tport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct scsiback_tport *tport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* Returned by scsiback_make_tpg() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct se_portal_group se_tpg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* alias used in xenstore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) char param_alias[VSCSI_NAMELEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* list of info structures related to this target portal group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct list_head info_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define SCSIBACK_INVALID_HANDLE (~0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static bool log_print_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) module_param(log_print_stat, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static int scsiback_max_buffer_pages = 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) module_param_named(max_buffer_pages, scsiback_max_buffer_pages, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) MODULE_PARM_DESC(max_buffer_pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) "Maximum number of free pages to keep in backend buffer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* Global spinlock to protect scsiback TPG list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static DEFINE_MUTEX(scsiback_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static LIST_HEAD(scsiback_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static void scsiback_get(struct vscsibk_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) atomic_inc(&info->nr_unreplied_reqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static void scsiback_put(struct vscsibk_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (atomic_dec_and_test(&info->nr_unreplied_reqs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) wake_up(&info->waiting_to_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static unsigned long vaddr_page(struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) unsigned long pfn = page_to_pfn(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return (unsigned long)pfn_to_kaddr(pfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static unsigned long vaddr(struct vscsibk_pend *req, int seg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return vaddr_page(req->pages[seg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static void scsiback_print_status(char *sense_buffer, int errors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct vscsibk_pend *pending_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct scsiback_tpg *tpg = pending_req->v2p->tpg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) pr_err("[%s:%d] cmnd[0]=%02x -> st=%02x msg=%02x host=%02x drv=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) tpg->tport->tport_name, pending_req->v2p->lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) pending_req->cmnd[0], status_byte(errors), msg_byte(errors),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) host_byte(errors), driver_byte(errors));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static void scsiback_fast_flush_area(struct vscsibk_pend *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct gnttab_unmap_grant_ref unmap[VSCSI_GRANT_BATCH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct page *pages[VSCSI_GRANT_BATCH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) unsigned int i, invcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) grant_handle_t handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) kfree(req->sgl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) req->sgl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) req->n_sg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (!req->n_grants)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) for (i = 0; i < req->n_grants; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) handle = req->grant_handles[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (handle == SCSIBACK_INVALID_HANDLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) GNTMAP_host_map, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) req->grant_handles[i] = SCSIBACK_INVALID_HANDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) pages[invcount] = req->pages[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) put_page(pages[invcount]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) invcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (invcount < VSCSI_GRANT_BATCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) err = gnttab_unmap_refs(unmap, NULL, pages, invcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) BUG_ON(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) invcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (invcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) err = gnttab_unmap_refs(unmap, NULL, pages, invcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) BUG_ON(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) gnttab_page_cache_put(&req->info->free_pages, req->pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) req->n_grants);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) req->n_grants = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static void scsiback_free_translation_entry(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct v2p_entry *entry = container_of(kref, struct v2p_entry, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct scsiback_tpg *tpg = entry->tpg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) mutex_lock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) tpg->tv_tpg_fe_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) mutex_unlock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) kfree(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static void scsiback_send_response(struct vscsibk_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) char *sense_buffer, int32_t result, uint32_t resid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) uint16_t rqid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct vscsiif_response *ring_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) int notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct scsi_sense_hdr sshdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) unsigned len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) spin_lock_irqsave(&info->ring_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ring_res = RING_GET_RESPONSE(&info->ring, info->ring.rsp_prod_pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) info->ring.rsp_prod_pvt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) ring_res->rslt = result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ring_res->rqid = rqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (sense_buffer != NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) scsi_normalize_sense(sense_buffer, VSCSIIF_SENSE_BUFFERSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) &sshdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) len = min_t(unsigned, 8 + sense_buffer[7],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) VSCSIIF_SENSE_BUFFERSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) memcpy(ring_res->sense_buffer, sense_buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ring_res->sense_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ring_res->sense_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ring_res->residual_len = resid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&info->ring, notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) spin_unlock_irqrestore(&info->ring_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (notify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) notify_remote_via_irq(info->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) uint32_t resid, struct vscsibk_pend *pending_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) scsiback_send_response(pending_req->info, sense_buffer, result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) resid, pending_req->rqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (pending_req->v2p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) kref_put(&pending_req->v2p->kref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) scsiback_free_translation_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static void scsiback_cmd_done(struct vscsibk_pend *pending_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct vscsibk_info *info = pending_req->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) unsigned char *sense_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) unsigned int resid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) int errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) sense_buffer = pending_req->sense_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) resid = pending_req->se_cmd.residual_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) errors = pending_req->result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (errors && log_print_stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) scsiback_print_status(sense_buffer, errors, pending_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) scsiback_fast_flush_area(pending_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) scsiback_do_resp_with_sense(sense_buffer, errors, resid, pending_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) scsiback_put(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * Drop the extra KREF_ACK reference taken by target_submit_cmd_map_sgls()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * ahead of scsiback_check_stop_free() -> transport_generic_free_cmd()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * final se_cmd->cmd_kref put.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) target_put_sess_cmd(&pending_req->se_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static void scsiback_cmd_exec(struct vscsibk_pend *pending_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct se_cmd *se_cmd = &pending_req->se_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct se_session *sess = pending_req->v2p->tpg->tpg_nexus->tvn_se_sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) scsiback_get(pending_req->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) se_cmd->tag = pending_req->rqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) rc = target_submit_cmd_map_sgls(se_cmd, sess, pending_req->cmnd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) pending_req->sense_buffer, pending_req->v2p->lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) pending_req->data_len, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) pending_req->sc_data_direction, TARGET_SCF_ACK_KREF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) pending_req->sgl, pending_req->n_sg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) NULL, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) transport_send_check_condition_and_sense(se_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) transport_generic_free_cmd(se_cmd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static int scsiback_gnttab_data_map_batch(struct gnttab_map_grant_ref *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) struct page **pg, grant_handle_t *grant, int cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (!cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) err = gnttab_map_refs(map, NULL, pg, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) for (i = 0; i < cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (unlikely(map[i].status != GNTST_okay)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) pr_err("invalid buffer -- could not remap it\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) map[i].handle = SCSIBACK_INVALID_HANDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) get_page(pg[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) grant[i] = map[i].handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static int scsiback_gnttab_data_map_list(struct vscsibk_pend *pending_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct scsiif_request_segment *seg, struct page **pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) grant_handle_t *grant, int cnt, u32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int mapcount = 0, i, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct gnttab_map_grant_ref map[VSCSI_GRANT_BATCH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct vscsibk_info *info = pending_req->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) for (i = 0; i < cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (gnttab_page_cache_get(&info->free_pages, pg + mapcount)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) gnttab_page_cache_put(&info->free_pages, pg, mapcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) pr_err("no grant page\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) gnttab_set_map_op(&map[mapcount], vaddr_page(pg[mapcount]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) flags, seg[i].gref, info->domid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) mapcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (mapcount < VSCSI_GRANT_BATCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) err = scsiback_gnttab_data_map_batch(map, pg, grant, mapcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) pg += mapcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) grant += mapcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) pending_req->n_grants += mapcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) mapcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) err = scsiback_gnttab_data_map_batch(map, pg, grant, mapcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) pending_req->n_grants += mapcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static int scsiback_gnttab_data_map(struct vscsiif_request *ring_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct vscsibk_pend *pending_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) int i, err, n_segs, i_seg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct page **pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct scsiif_request_segment *seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) unsigned long end_seg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) unsigned int nr_segments = (unsigned int)ring_req->nr_segments;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) unsigned int nr_sgl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) grant_handle_t *grant;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) pending_req->n_sg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) pending_req->n_grants = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) pending_req->data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) nr_segments &= ~VSCSIIF_SG_GRANT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (!nr_segments)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (nr_segments > VSCSIIF_SG_TABLESIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) pr_debug("invalid parameter nr_seg = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) ring_req->nr_segments);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (ring_req->nr_segments & VSCSIIF_SG_GRANT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) err = scsiback_gnttab_data_map_list(pending_req, ring_req->seg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) pending_req->pages, pending_req->grant_handles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) nr_segments, GNTMAP_host_map | GNTMAP_readonly);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) nr_sgl = nr_segments;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) nr_segments = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) for (i = 0; i < nr_sgl; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) n_segs = ring_req->seg[i].length /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) sizeof(struct scsiif_request_segment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if ((unsigned)ring_req->seg[i].offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) (unsigned)ring_req->seg[i].length > PAGE_SIZE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) n_segs * sizeof(struct scsiif_request_segment) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ring_req->seg[i].length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) nr_segments += n_segs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (nr_segments > SG_ALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) pr_debug("invalid nr_seg = %d\n", nr_segments);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* free of (sgl) in fast_flush_area() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) pending_req->sgl = kmalloc_array(nr_segments,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) sizeof(struct scatterlist), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (!pending_req->sgl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) sg_init_table(pending_req->sgl, nr_segments);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) pending_req->n_sg = nr_segments;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) flags = GNTMAP_host_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (pending_req->sc_data_direction == DMA_TO_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) flags |= GNTMAP_readonly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) pg = pending_req->pages + nr_sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) grant = pending_req->grant_handles + nr_sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (!nr_sgl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) seg = ring_req->seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) err = scsiback_gnttab_data_map_list(pending_req, seg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) pg, grant, nr_segments, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) for (i = 0; i < nr_sgl; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) seg = (struct scsiif_request_segment *)(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) vaddr(pending_req, i) + ring_req->seg[i].offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) n_segs = ring_req->seg[i].length /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) sizeof(struct scsiif_request_segment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) err = scsiback_gnttab_data_map_list(pending_req, seg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) pg, grant, n_segs, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) pg += n_segs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) grant += n_segs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) end_seg = vaddr(pending_req, 0) + ring_req->seg[0].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) seg = (struct scsiif_request_segment *)end_seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) end_seg += ring_req->seg[0].length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) pg = pending_req->pages + nr_sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) for_each_sg(pending_req->sgl, sg, nr_segments, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) sg_set_page(sg, pg[i], seg->length, seg->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) pending_req->data_len += seg->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) seg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (nr_sgl && (unsigned long)seg >= end_seg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) i_seg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) end_seg = vaddr(pending_req, i_seg) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) ring_req->seg[i_seg].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) seg = (struct scsiif_request_segment *)end_seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) end_seg += ring_req->seg[i_seg].length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (sg->offset >= PAGE_SIZE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) sg->length > PAGE_SIZE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) sg->offset + sg->length > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static void scsiback_disconnect(struct vscsibk_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) wait_event(info->waiting_to_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) atomic_read(&info->nr_unreplied_reqs) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) unbind_from_irqhandler(info->irq, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) info->irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) xenbus_unmap_ring_vfree(info->dev, info->ring.sring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static void scsiback_device_action(struct vscsibk_pend *pending_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) enum tcm_tmreq_table act, int tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) struct scsiback_tpg *tpg = pending_req->v2p->tpg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct scsiback_nexus *nexus = tpg->tpg_nexus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct se_cmd *se_cmd = &pending_req->se_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) u64 unpacked_lun = pending_req->v2p->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) int rc, err = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) init_completion(&pending_req->tmr_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) rc = target_submit_tmr(&pending_req->se_cmd, nexus->tvn_se_sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) &pending_req->sense_buffer[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) unpacked_lun, NULL, act, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) tag, TARGET_SCF_ACK_KREF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) wait_for_completion(&pending_req->tmr_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) err = (se_cmd->se_tmr_req->response == TMR_FUNCTION_COMPLETE) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) SUCCESS : FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) scsiback_do_resp_with_sense(NULL, err, 0, pending_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) transport_generic_free_cmd(&pending_req->se_cmd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) scsiback_do_resp_with_sense(NULL, err, 0, pending_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) Perform virtual to physical translation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) static struct v2p_entry *scsiback_do_translation(struct vscsibk_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct ids_tuple *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct v2p_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct list_head *head = &(info->v2p_entry_lists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) spin_lock_irqsave(&info->v2p_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) list_for_each_entry(entry, head, l) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if ((entry->v.chn == v->chn) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) (entry->v.tgt == v->tgt) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) (entry->v.lun == v->lun)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) kref_get(&entry->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) spin_unlock_irqrestore(&info->v2p_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static struct vscsibk_pend *scsiback_get_pend_req(struct vscsiif_back_ring *ring,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct v2p_entry *v2p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) struct scsiback_tpg *tpg = v2p->tpg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) struct scsiback_nexus *nexus = tpg->tpg_nexus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) struct se_session *se_sess = nexus->tvn_se_sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct vscsibk_pend *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) int tag, cpu, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) tag = sbitmap_queue_get(&se_sess->sess_tag_pool, &cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (tag < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) pr_err("Unable to obtain tag for vscsiif_request\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) req = &((struct vscsibk_pend *)se_sess->sess_cmd_map)[tag];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) memset(req, 0, sizeof(*req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) req->se_cmd.map_tag = tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) req->se_cmd.map_cpu = cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) for (i = 0; i < VSCSI_MAX_GRANTS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) req->grant_handles[i] = SCSIBACK_INVALID_HANDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) static struct vscsibk_pend *prepare_pending_reqs(struct vscsibk_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct vscsiif_back_ring *ring,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct vscsiif_request *ring_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct vscsibk_pend *pending_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) struct v2p_entry *v2p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) struct ids_tuple vir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) /* request range check from frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if ((ring_req->sc_data_direction != DMA_BIDIRECTIONAL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) (ring_req->sc_data_direction != DMA_TO_DEVICE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) (ring_req->sc_data_direction != DMA_FROM_DEVICE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) (ring_req->sc_data_direction != DMA_NONE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) pr_debug("invalid parameter data_dir = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) ring_req->sc_data_direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (ring_req->cmd_len > VSCSIIF_MAX_COMMAND_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) pr_debug("invalid parameter cmd_len = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) ring_req->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) vir.chn = ring_req->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) vir.tgt = ring_req->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) vir.lun = ring_req->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) v2p = scsiback_do_translation(info, &vir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (!v2p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) pr_debug("the v2p of (chn:%d, tgt:%d, lun:%d) doesn't exist.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) vir.chn, vir.tgt, vir.lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) pending_req = scsiback_get_pend_req(ring, v2p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (IS_ERR(pending_req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) kref_put(&v2p->kref, scsiback_free_translation_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) pending_req->rqid = ring_req->rqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) pending_req->info = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) pending_req->v2p = v2p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) pending_req->sc_data_direction = ring_req->sc_data_direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) pending_req->cmd_len = ring_req->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) memcpy(pending_req->cmnd, ring_req->cmnd, pending_req->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return pending_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static int scsiback_do_cmd_fn(struct vscsibk_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) unsigned int *eoi_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) struct vscsiif_back_ring *ring = &info->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct vscsiif_request ring_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct vscsibk_pend *pending_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) RING_IDX rc, rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) int more_to_do;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) uint32_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) rc = ring->req_cons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) rp = ring->sring->req_prod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) rmb(); /* guest system is accessing ring, too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (RING_REQUEST_PROD_OVERFLOW(ring, rp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) rc = ring->rsp_prod_pvt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) pr_warn("Dom%d provided bogus ring requests (%#x - %#x = %u). Halting ring processing\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) info->domid, rp, rc, rp - rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) while ((rc != rp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) *eoi_flags &= ~XEN_EOI_FLAG_SPURIOUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (RING_REQUEST_CONS_OVERFLOW(ring, rc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) RING_COPY_REQUEST(ring, rc, &ring_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) ring->req_cons = ++rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) pending_req = prepare_pending_reqs(info, ring, &ring_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (IS_ERR(pending_req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) switch (PTR_ERR(pending_req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) case -ENODEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) result = DID_NO_CONNECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) result = DRIVER_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) scsiback_send_response(info, NULL, result << 24, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) ring_req.rqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) switch (ring_req.act) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) case VSCSIIF_ACT_SCSI_CDB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (scsiback_gnttab_data_map(&ring_req, pending_req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) scsiback_fast_flush_area(pending_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) scsiback_do_resp_with_sense(NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) DRIVER_ERROR << 24, 0, pending_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) transport_generic_free_cmd(&pending_req->se_cmd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) scsiback_cmd_exec(pending_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) case VSCSIIF_ACT_SCSI_ABORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) scsiback_device_action(pending_req, TMR_ABORT_TASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) ring_req.ref_rqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) case VSCSIIF_ACT_SCSI_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) scsiback_device_action(pending_req, TMR_LUN_RESET, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) pr_err_ratelimited("invalid request\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) scsiback_do_resp_with_sense(NULL, DRIVER_ERROR << 24, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) pending_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) transport_generic_free_cmd(&pending_req->se_cmd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) /* Yield point for this unbounded loop. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) gnttab_page_cache_shrink(&info->free_pages, scsiback_max_buffer_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) RING_FINAL_CHECK_FOR_REQUESTS(&info->ring, more_to_do);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return more_to_do;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static irqreturn_t scsiback_irq_fn(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct vscsibk_info *info = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) unsigned int eoi_flags = XEN_EOI_FLAG_SPURIOUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) while ((rc = scsiback_do_cmd_fn(info, &eoi_flags)) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) /* In case of a ring error we keep the event channel masked. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) xen_irq_lateeoi(irq, eoi_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) static int scsiback_init_sring(struct vscsibk_info *info, grant_ref_t ring_ref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) evtchn_port_t evtchn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) void *area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) struct vscsiif_sring *sring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (info->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) err = xenbus_map_ring_valloc(info->dev, &ring_ref, 1, &area);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) sring = (struct vscsiif_sring *)area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) BACK_RING_INIT(&info->ring, sring, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) err = bind_interdomain_evtchn_to_irq_lateeoi(info->domid, evtchn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) goto unmap_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) info->irq = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) err = request_threaded_irq(info->irq, NULL, scsiback_irq_fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) IRQF_ONESHOT, "vscsiif-backend", info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) goto free_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) free_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) unbind_from_irqhandler(info->irq, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) info->irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) unmap_page:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) xenbus_unmap_ring_vfree(info->dev, area);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) static int scsiback_map(struct vscsibk_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) struct xenbus_device *dev = info->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) unsigned int ring_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) evtchn_port_t evtchn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) err = xenbus_gather(XBT_NIL, dev->otherend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) "ring-ref", "%u", &ring_ref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) "event-channel", "%u", &evtchn, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) xenbus_dev_fatal(dev, err, "reading %s ring", dev->otherend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return scsiback_init_sring(info, ring_ref, evtchn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) Check for a translation entry being present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) static struct v2p_entry *scsiback_chk_translation_entry(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct vscsibk_info *info, struct ids_tuple *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct list_head *head = &(info->v2p_entry_lists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) struct v2p_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) list_for_each_entry(entry, head, l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if ((entry->v.chn == v->chn) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) (entry->v.tgt == v->tgt) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) (entry->v.lun == v->lun))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) Add a new translation entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) static int scsiback_add_translation_entry(struct vscsibk_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) char *phy, struct ids_tuple *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) struct v2p_entry *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) char *lunp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) unsigned long long unpacked_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) struct se_lun *se_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) struct scsiback_tpg *tpg_entry, *tpg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) char *error = "doesn't exist";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) lunp = strrchr(phy, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (!lunp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) pr_err("illegal format of physical device %s\n", phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) *lunp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) lunp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) err = kstrtoull(lunp, 10, &unpacked_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) pr_err("lun number not valid: %s\n", lunp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) mutex_lock(&scsiback_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) list_for_each_entry(tpg_entry, &scsiback_list, tv_tpg_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (!strcmp(phy, tpg_entry->tport->tport_name) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) !strcmp(phy, tpg_entry->param_alias)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) mutex_lock(&tpg_entry->se_tpg.tpg_lun_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) hlist_for_each_entry(se_lun, &tpg_entry->se_tpg.tpg_lun_hlist, link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (se_lun->unpacked_lun == unpacked_lun) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (!tpg_entry->tpg_nexus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) error = "nexus undefined";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) tpg = tpg_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) mutex_unlock(&tpg_entry->se_tpg.tpg_lun_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (tpg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) mutex_lock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) tpg->tv_tpg_fe_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) mutex_unlock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) mutex_unlock(&scsiback_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (!tpg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) pr_err("%s:%llu %s\n", phy, unpacked_lun, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) new = kmalloc(sizeof(struct v2p_entry), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) if (new == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) spin_lock_irqsave(&info->v2p_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) /* Check double assignment to identical virtual ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (scsiback_chk_translation_entry(info, v)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) pr_warn("Virtual ID is already used. Assignment was not performed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) err = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) /* Create a new translation entry and add to the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) kref_init(&new->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) new->v = *v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) new->tpg = tpg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) new->lun = unpacked_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) list_add_tail(&new->l, &info->v2p_entry_lists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) spin_unlock_irqrestore(&info->v2p_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) mutex_lock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) tpg->tv_tpg_fe_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) mutex_unlock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) kfree(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) static void __scsiback_del_translation_entry(struct v2p_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) list_del(&entry->l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) kref_put(&entry->kref, scsiback_free_translation_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) Delete the translation entry specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static int scsiback_del_translation_entry(struct vscsibk_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) struct ids_tuple *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) struct v2p_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) spin_lock_irqsave(&info->v2p_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) /* Find out the translation entry specified */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) entry = scsiback_chk_translation_entry(info, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) __scsiback_del_translation_entry(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) spin_unlock_irqrestore(&info->v2p_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) static void scsiback_do_add_lun(struct vscsibk_info *info, const char *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) char *phy, struct ids_tuple *vir, int try)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) struct v2p_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (try) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) spin_lock_irqsave(&info->v2p_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) entry = scsiback_chk_translation_entry(info, vir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) spin_unlock_irqrestore(&info->v2p_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (!scsiback_add_translation_entry(info, phy, vir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) if (xenbus_printf(XBT_NIL, info->dev->nodename, state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) "%d", XenbusStateInitialised)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) pr_err("xenbus_printf error %s\n", state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) scsiback_del_translation_entry(info, vir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) } else if (!try) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) err = xenbus_printf(XBT_NIL, info->dev->nodename, state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) "%d", XenbusStateClosed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) xenbus_dev_error(info->dev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) "%s: writing %s", __func__, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) static void scsiback_do_del_lun(struct vscsibk_info *info, const char *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) struct ids_tuple *vir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (!scsiback_del_translation_entry(info, vir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (xenbus_printf(XBT_NIL, info->dev->nodename, state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) "%d", XenbusStateClosed))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) pr_err("xenbus_printf error %s\n", state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) #define VSCSIBACK_OP_ADD_OR_DEL_LUN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) #define VSCSIBACK_OP_UPDATEDEV_STATE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) static void scsiback_do_1lun_hotplug(struct vscsibk_info *info, int op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) char *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) struct ids_tuple vir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) char *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) int device_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) char phy[VSCSI_NAMELEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) char str[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) char state[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) struct xenbus_device *dev = info->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) /* read status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) snprintf(state, sizeof(state), "vscsi-devs/%s/state", ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) err = xenbus_scanf(XBT_NIL, dev->nodename, state, "%u", &device_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (XENBUS_EXIST_ERR(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) /* physical SCSI device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) snprintf(str, sizeof(str), "vscsi-devs/%s/p-dev", ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) val = xenbus_read(XBT_NIL, dev->nodename, str, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (IS_ERR(val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) err = xenbus_printf(XBT_NIL, dev->nodename, state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) "%d", XenbusStateClosed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) xenbus_dev_error(info->dev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) "%s: writing %s", __func__, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) strlcpy(phy, val, VSCSI_NAMELEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) kfree(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) /* virtual SCSI device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) snprintf(str, sizeof(str), "vscsi-devs/%s/v-dev", ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) err = xenbus_scanf(XBT_NIL, dev->nodename, str, "%u:%u:%u:%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) &vir.hst, &vir.chn, &vir.tgt, &vir.lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (XENBUS_EXIST_ERR(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) err = xenbus_printf(XBT_NIL, dev->nodename, state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) "%d", XenbusStateClosed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) xenbus_dev_error(info->dev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) "%s: writing %s", __func__, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) case VSCSIBACK_OP_ADD_OR_DEL_LUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) switch (device_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) case XenbusStateInitialising:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) scsiback_do_add_lun(info, state, phy, &vir, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) case XenbusStateConnected:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) scsiback_do_add_lun(info, state, phy, &vir, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) case XenbusStateClosing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) scsiback_do_del_lun(info, state, &vir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) case VSCSIBACK_OP_UPDATEDEV_STATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (device_state == XenbusStateInitialised) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) /* modify vscsi-devs/dev-x/state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (xenbus_printf(XBT_NIL, dev->nodename, state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) "%d", XenbusStateConnected)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) pr_err("xenbus_printf error %s\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) scsiback_del_translation_entry(info, &vir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) xenbus_printf(XBT_NIL, dev->nodename, state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) "%d", XenbusStateClosed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) /* When it is necessary, processing is added here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) static void scsiback_do_lun_hotplug(struct vscsibk_info *info, int op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) char **dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) unsigned int ndir = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) dir = xenbus_directory(XBT_NIL, info->dev->nodename, "vscsi-devs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) &ndir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (IS_ERR(dir))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) for (i = 0; i < ndir; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) scsiback_do_1lun_hotplug(info, op, dir[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) kfree(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) static void scsiback_frontend_changed(struct xenbus_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) enum xenbus_state frontend_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) struct vscsibk_info *info = dev_get_drvdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) switch (frontend_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) case XenbusStateInitialising:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) case XenbusStateInitialised:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (scsiback_map(info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) scsiback_do_lun_hotplug(info, VSCSIBACK_OP_ADD_OR_DEL_LUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) xenbus_switch_state(dev, XenbusStateConnected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) case XenbusStateConnected:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) scsiback_do_lun_hotplug(info, VSCSIBACK_OP_UPDATEDEV_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (dev->state == XenbusStateConnected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) xenbus_switch_state(dev, XenbusStateConnected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) case XenbusStateClosing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (info->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) scsiback_disconnect(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) xenbus_switch_state(dev, XenbusStateClosing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) case XenbusStateClosed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) xenbus_switch_state(dev, XenbusStateClosed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (xenbus_dev_is_online(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) fallthrough; /* if not online */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) case XenbusStateUnknown:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) device_unregister(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) case XenbusStateReconfiguring:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) scsiback_do_lun_hotplug(info, VSCSIBACK_OP_ADD_OR_DEL_LUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) xenbus_switch_state(dev, XenbusStateReconfigured);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) frontend_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) Release the translation entry specfied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) static void scsiback_release_translation_entry(struct vscsibk_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) struct v2p_entry *entry, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) struct list_head *head = &(info->v2p_entry_lists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) spin_lock_irqsave(&info->v2p_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) list_for_each_entry_safe(entry, tmp, head, l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) __scsiback_del_translation_entry(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) spin_unlock_irqrestore(&info->v2p_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) static int scsiback_remove(struct xenbus_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) struct vscsibk_info *info = dev_get_drvdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (info->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) scsiback_disconnect(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) scsiback_release_translation_entry(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) gnttab_page_cache_shrink(&info->free_pages, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) dev_set_drvdata(&dev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) static int scsiback_probe(struct xenbus_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) const struct xenbus_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) struct vscsibk_info *info = kzalloc(sizeof(struct vscsibk_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) if (!info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) xenbus_dev_fatal(dev, -ENOMEM, "allocating backend structure");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) info->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) dev_set_drvdata(&dev->dev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) info->domid = dev->otherend_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) spin_lock_init(&info->ring_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) atomic_set(&info->nr_unreplied_reqs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) init_waitqueue_head(&info->waiting_to_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) info->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) info->irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) INIT_LIST_HEAD(&info->v2p_entry_lists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) spin_lock_init(&info->v2p_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) gnttab_page_cache_init(&info->free_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) err = xenbus_printf(XBT_NIL, dev->nodename, "feature-sg-grant", "%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) SG_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) xenbus_dev_error(dev, err, "writing feature-sg-grant");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) err = xenbus_switch_state(dev, XenbusStateInitWait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) pr_warn("%s failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) scsiback_remove(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) static char *scsiback_dump_proto_id(struct scsiback_tport *tport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) switch (tport->tport_proto_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) case SCSI_PROTOCOL_SAS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) return "SAS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) case SCSI_PROTOCOL_FCP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) return "FCP";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) case SCSI_PROTOCOL_ISCSI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return "iSCSI";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) return "Unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) static char *scsiback_get_fabric_wwn(struct se_portal_group *se_tpg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) struct scsiback_tpg *tpg = container_of(se_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) struct scsiback_tpg, se_tpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) struct scsiback_tport *tport = tpg->tport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) return &tport->tport_name[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) static u16 scsiback_get_tag(struct se_portal_group *se_tpg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) struct scsiback_tpg *tpg = container_of(se_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) struct scsiback_tpg, se_tpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) return tpg->tport_tpgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) static struct se_wwn *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) scsiback_make_tport(struct target_fabric_configfs *tf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) struct config_group *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) struct scsiback_tport *tport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) u64 wwpn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) int off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) tport = kzalloc(sizeof(struct scsiback_tport), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (!tport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) tport->tport_wwpn = wwpn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) * Determine the emulated Protocol Identifier and Target Port Name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) * based on the incoming configfs directory name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) ptr = strstr(name, "naa.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) tport->tport_proto_id = SCSI_PROTOCOL_SAS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) goto check_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) ptr = strstr(name, "fc.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) tport->tport_proto_id = SCSI_PROTOCOL_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) off = 3; /* Skip over "fc." */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) goto check_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) ptr = strstr(name, "iqn.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) tport->tport_proto_id = SCSI_PROTOCOL_ISCSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) goto check_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) pr_err("Unable to locate prefix for emulated Target Port: %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) kfree(tport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) check_len:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) if (strlen(name) >= VSCSI_NAMELEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) pr_err("Emulated %s Address: %s, exceeds max: %d\n", name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) scsiback_dump_proto_id(tport), VSCSI_NAMELEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) kfree(tport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) snprintf(&tport->tport_name[0], VSCSI_NAMELEN, "%s", &name[off]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) pr_debug("Allocated emulated Target %s Address: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) scsiback_dump_proto_id(tport), name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) return &tport->tport_wwn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) static void scsiback_drop_tport(struct se_wwn *wwn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) struct scsiback_tport *tport = container_of(wwn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) struct scsiback_tport, tport_wwn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) pr_debug("Deallocating emulated Target %s Address: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) scsiback_dump_proto_id(tport), tport->tport_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) kfree(tport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) static u32 scsiback_tpg_get_inst_index(struct se_portal_group *se_tpg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) static int scsiback_check_stop_free(struct se_cmd *se_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) return transport_generic_free_cmd(se_cmd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) static void scsiback_release_cmd(struct se_cmd *se_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) target_free_tag(se_cmd->se_sess, se_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) static u32 scsiback_sess_get_index(struct se_session *se_sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) static int scsiback_write_pending(struct se_cmd *se_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) /* Go ahead and process the write immediately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) target_execute_cmd(se_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) static void scsiback_set_default_node_attrs(struct se_node_acl *nacl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) static int scsiback_get_cmd_state(struct se_cmd *se_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) static int scsiback_queue_data_in(struct se_cmd *se_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) struct vscsibk_pend *pending_req = container_of(se_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) struct vscsibk_pend, se_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) pending_req->result = SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) scsiback_cmd_done(pending_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) static int scsiback_queue_status(struct se_cmd *se_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) struct vscsibk_pend *pending_req = container_of(se_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) struct vscsibk_pend, se_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) if (se_cmd->sense_buffer &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) ((se_cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) (se_cmd->se_cmd_flags & SCF_EMULATED_TASK_SENSE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) pending_req->result = (DRIVER_SENSE << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) pending_req->result = se_cmd->scsi_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) scsiback_cmd_done(pending_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) static void scsiback_queue_tm_rsp(struct se_cmd *se_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) struct vscsibk_pend *pending_req = container_of(se_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) struct vscsibk_pend, se_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) complete(&pending_req->tmr_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) static void scsiback_aborted_task(struct se_cmd *se_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) static ssize_t scsiback_tpg_param_alias_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) struct se_portal_group *se_tpg = param_to_tpg(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) struct scsiback_tpg *tpg = container_of(se_tpg, struct scsiback_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) se_tpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) ssize_t rb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) mutex_lock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) rb = snprintf(page, PAGE_SIZE, "%s\n", tpg->param_alias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) mutex_unlock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) return rb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) static ssize_t scsiback_tpg_param_alias_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) struct se_portal_group *se_tpg = param_to_tpg(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) struct scsiback_tpg *tpg = container_of(se_tpg, struct scsiback_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) se_tpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) if (strlen(page) >= VSCSI_NAMELEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) pr_err("param alias: %s, exceeds max: %d\n", page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) VSCSI_NAMELEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) mutex_lock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) len = snprintf(tpg->param_alias, VSCSI_NAMELEN, "%s", page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (tpg->param_alias[len - 1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) tpg->param_alias[len - 1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) mutex_unlock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) CONFIGFS_ATTR(scsiback_tpg_param_, alias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) static struct configfs_attribute *scsiback_param_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) &scsiback_tpg_param_attr_alias,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) static int scsiback_alloc_sess_cb(struct se_portal_group *se_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) struct se_session *se_sess, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) struct scsiback_tpg *tpg = container_of(se_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) struct scsiback_tpg, se_tpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) tpg->tpg_nexus = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) static int scsiback_make_nexus(struct scsiback_tpg *tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) struct scsiback_nexus *tv_nexus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) mutex_lock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) if (tpg->tpg_nexus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) pr_debug("tpg->tpg_nexus already exists\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) ret = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) tv_nexus = kzalloc(sizeof(struct scsiback_nexus), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) if (!tv_nexus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) tv_nexus->tvn_se_sess = target_setup_session(&tpg->se_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) VSCSI_DEFAULT_SESSION_TAGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) sizeof(struct vscsibk_pend),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) TARGET_PROT_NORMAL, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) tv_nexus, scsiback_alloc_sess_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) if (IS_ERR(tv_nexus->tvn_se_sess)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) kfree(tv_nexus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) mutex_unlock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) static int scsiback_drop_nexus(struct scsiback_tpg *tpg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) struct se_session *se_sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) struct scsiback_nexus *tv_nexus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) mutex_lock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) tv_nexus = tpg->tpg_nexus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (!tv_nexus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) mutex_unlock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) se_sess = tv_nexus->tvn_se_sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) if (!se_sess) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) mutex_unlock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) if (tpg->tv_tpg_port_count != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) mutex_unlock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) pr_err("Unable to remove xen-pvscsi I_T Nexus with active TPG port count: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) tpg->tv_tpg_port_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) if (tpg->tv_tpg_fe_count != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) mutex_unlock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) pr_err("Unable to remove xen-pvscsi I_T Nexus with active TPG frontend count: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) tpg->tv_tpg_fe_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) pr_debug("Removing I_T Nexus to emulated %s Initiator Port: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) scsiback_dump_proto_id(tpg->tport),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) tv_nexus->tvn_se_sess->se_node_acl->initiatorname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) * Release the SCSI I_T Nexus to the emulated xen-pvscsi Target Port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) target_remove_session(se_sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) tpg->tpg_nexus = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) mutex_unlock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) kfree(tv_nexus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) static ssize_t scsiback_tpg_nexus_show(struct config_item *item, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) struct se_portal_group *se_tpg = to_tpg(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) struct scsiback_tpg *tpg = container_of(se_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) struct scsiback_tpg, se_tpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) struct scsiback_nexus *tv_nexus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) mutex_lock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) tv_nexus = tpg->tpg_nexus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) if (!tv_nexus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) mutex_unlock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) ret = snprintf(page, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) tv_nexus->tvn_se_sess->se_node_acl->initiatorname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) mutex_unlock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) static ssize_t scsiback_tpg_nexus_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) struct se_portal_group *se_tpg = to_tpg(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) struct scsiback_tpg *tpg = container_of(se_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) struct scsiback_tpg, se_tpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) struct scsiback_tport *tport_wwn = tpg->tport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) unsigned char i_port[VSCSI_NAMELEN], *ptr, *port_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) * Shutdown the active I_T nexus if 'NULL' is passed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) if (!strncmp(page, "NULL", 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) ret = scsiback_drop_nexus(tpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) return (!ret) ? count : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) * Otherwise make sure the passed virtual Initiator port WWN matches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) * the fabric protocol_id set in scsiback_make_tport(), and call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) * scsiback_make_nexus().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) if (strlen(page) >= VSCSI_NAMELEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) pr_err("Emulated NAA Sas Address: %s, exceeds max: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) page, VSCSI_NAMELEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) snprintf(&i_port[0], VSCSI_NAMELEN, "%s", page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) ptr = strstr(i_port, "naa.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) if (ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_SAS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) pr_err("Passed SAS Initiator Port %s does not match target port protoid: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) i_port, scsiback_dump_proto_id(tport_wwn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) port_ptr = &i_port[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) goto check_newline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) ptr = strstr(i_port, "fc.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) if (ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_FCP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) pr_err("Passed FCP Initiator Port %s does not match target port protoid: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) i_port, scsiback_dump_proto_id(tport_wwn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) port_ptr = &i_port[3]; /* Skip over "fc." */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) goto check_newline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) ptr = strstr(i_port, "iqn.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) if (ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_ISCSI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) pr_err("Passed iSCSI Initiator Port %s does not match target port protoid: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) i_port, scsiback_dump_proto_id(tport_wwn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) port_ptr = &i_port[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) goto check_newline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) pr_err("Unable to locate prefix for emulated Initiator Port: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) i_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) * Clear any trailing newline for the NAA WWN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) check_newline:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) if (i_port[strlen(i_port) - 1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) i_port[strlen(i_port) - 1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) ret = scsiback_make_nexus(tpg, port_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) CONFIGFS_ATTR(scsiback_tpg_, nexus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) static struct configfs_attribute *scsiback_tpg_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) &scsiback_tpg_attr_nexus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) scsiback_wwn_version_show(struct config_item *item, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) return sprintf(page, "xen-pvscsi fabric module %s on %s/%s on "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) UTS_RELEASE"\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) VSCSI_VERSION, utsname()->sysname, utsname()->machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) CONFIGFS_ATTR_RO(scsiback_wwn_, version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) static struct configfs_attribute *scsiback_wwn_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) &scsiback_wwn_attr_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) static int scsiback_port_link(struct se_portal_group *se_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) struct se_lun *lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) struct scsiback_tpg *tpg = container_of(se_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) struct scsiback_tpg, se_tpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) mutex_lock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) tpg->tv_tpg_port_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) mutex_unlock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) static void scsiback_port_unlink(struct se_portal_group *se_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) struct se_lun *lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) struct scsiback_tpg *tpg = container_of(se_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) struct scsiback_tpg, se_tpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) mutex_lock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) tpg->tv_tpg_port_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) mutex_unlock(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) static struct se_portal_group *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) scsiback_make_tpg(struct se_wwn *wwn, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) struct scsiback_tport *tport = container_of(wwn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) struct scsiback_tport, tport_wwn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) struct scsiback_tpg *tpg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) u16 tpgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) if (strstr(name, "tpgt_") != name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) ret = kstrtou16(name + 5, 10, &tpgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) tpg = kzalloc(sizeof(struct scsiback_tpg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) if (!tpg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) mutex_init(&tpg->tv_tpg_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) INIT_LIST_HEAD(&tpg->tv_tpg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) INIT_LIST_HEAD(&tpg->info_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) tpg->tport = tport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) tpg->tport_tpgt = tpgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) ret = core_tpg_register(wwn, &tpg->se_tpg, tport->tport_proto_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) kfree(tpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) mutex_lock(&scsiback_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) list_add_tail(&tpg->tv_tpg_list, &scsiback_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) mutex_unlock(&scsiback_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) return &tpg->se_tpg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) static void scsiback_drop_tpg(struct se_portal_group *se_tpg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) struct scsiback_tpg *tpg = container_of(se_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) struct scsiback_tpg, se_tpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) mutex_lock(&scsiback_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) list_del(&tpg->tv_tpg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) mutex_unlock(&scsiback_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) * Release the virtual I_T Nexus for this xen-pvscsi TPG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) scsiback_drop_nexus(tpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) * Deregister the se_tpg from TCM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) core_tpg_deregister(se_tpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) kfree(tpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) static int scsiback_check_true(struct se_portal_group *se_tpg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) static int scsiback_check_false(struct se_portal_group *se_tpg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) static const struct target_core_fabric_ops scsiback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) .fabric_name = "xen-pvscsi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) .tpg_get_wwn = scsiback_get_fabric_wwn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) .tpg_get_tag = scsiback_get_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) .tpg_check_demo_mode = scsiback_check_true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) .tpg_check_demo_mode_cache = scsiback_check_true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) .tpg_check_demo_mode_write_protect = scsiback_check_false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) .tpg_check_prod_mode_write_protect = scsiback_check_false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) .tpg_get_inst_index = scsiback_tpg_get_inst_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) .check_stop_free = scsiback_check_stop_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) .release_cmd = scsiback_release_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) .sess_get_index = scsiback_sess_get_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) .sess_get_initiator_sid = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) .write_pending = scsiback_write_pending,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) .set_default_node_attributes = scsiback_set_default_node_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) .get_cmd_state = scsiback_get_cmd_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) .queue_data_in = scsiback_queue_data_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) .queue_status = scsiback_queue_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) .queue_tm_rsp = scsiback_queue_tm_rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) .aborted_task = scsiback_aborted_task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) * Setup callers for generic logic in target_core_fabric_configfs.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) .fabric_make_wwn = scsiback_make_tport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) .fabric_drop_wwn = scsiback_drop_tport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) .fabric_make_tpg = scsiback_make_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) .fabric_drop_tpg = scsiback_drop_tpg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) .fabric_post_link = scsiback_port_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) .fabric_pre_unlink = scsiback_port_unlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) .tfc_wwn_attrs = scsiback_wwn_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) .tfc_tpg_base_attrs = scsiback_tpg_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) .tfc_tpg_param_attrs = scsiback_param_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) static const struct xenbus_device_id scsiback_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) { "vscsi" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) { "" }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) static struct xenbus_driver scsiback_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) .ids = scsiback_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) .probe = scsiback_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) .remove = scsiback_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) .otherend_changed = scsiback_frontend_changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) static int __init scsiback_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) if (!xen_domain())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) pr_debug("xen-pvscsi: fabric module %s on %s/%s on "UTS_RELEASE"\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) VSCSI_VERSION, utsname()->sysname, utsname()->machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) ret = xenbus_register_backend(&scsiback_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) ret = target_register_template(&scsiback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) goto out_unregister_xenbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) out_unregister_xenbus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) xenbus_unregister_driver(&scsiback_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) pr_err("%s: error %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) static void __exit scsiback_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) target_unregister_template(&scsiback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) xenbus_unregister_driver(&scsiback_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) module_init(scsiback_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) module_exit(scsiback_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) MODULE_DESCRIPTION("Xen SCSI backend driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) MODULE_LICENSE("Dual BSD/GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) MODULE_ALIAS("xen-backend:vscsi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) MODULE_AUTHOR("Juergen Gross <jgross@suse.com>");