^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Xen SCSI frontend 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) * This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * modify it under the terms of the GNU General Public License version 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * as published by the Free Software Foundation; or, when distributed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * separately from the Linux kernel or incorporated into other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * software packages, subject to the following license:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Permission is hereby granted, free of charge, to any person obtaining a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * of this source file (the "Software"), to deal in the Software without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * restriction, including without limitation the rights to use, copy, modify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * merge, publish, distribute, sublicense, and/or sell copies of the Software,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * and to permit persons to whom the Software is furnished to do so, subject to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * the following conditions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * The above copyright notice and this permission notice shall be included in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * all copies or substantial portions of the Software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * IN THE SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/pfn.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/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <xen/xen.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <xen/xenbus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <xen/grant_table.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <xen/events.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <xen/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <xen/interface/grant_table.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <xen/interface/io/vscsiif.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <xen/interface/io/protocols.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include <asm/xen/hypervisor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define GRANT_INVALID_REF 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define VSCSIFRONT_OP_ADD_LUN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define VSCSIFRONT_OP_DEL_LUN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define VSCSIFRONT_OP_READD_LUN 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* Tuning point. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define VSCSIIF_DEFAULT_CMD_PER_LUN 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define VSCSIIF_MAX_TARGET 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define VSCSIIF_MAX_LUN 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define VSCSIIF_RING_SIZE __CONST_RING_SIZE(vscsiif, PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define VSCSIIF_MAX_REQS VSCSIIF_RING_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define vscsiif_grants_sg(_sg) (PFN_UP((_sg) * \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) sizeof(struct scsiif_request_segment)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct vscsifrnt_shadow {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* command between backend and frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) unsigned char act;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) uint8_t nr_segments;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) uint16_t rqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) uint16_t ref_rqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned int nr_grants; /* number of grants in gref[] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct scsiif_request_segment *sg; /* scatter/gather elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct scsiif_request_segment seg[VSCSIIF_SG_TABLESIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* Do reset or abort function. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) wait_queue_head_t wq_reset; /* reset work queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) int wait_reset; /* reset work queue condition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int32_t rslt_reset; /* reset response status: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* SUCCESS or FAILED or: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define RSLT_RESET_WAITING 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define RSLT_RESET_ERR -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* Requested struct scsi_cmnd is stored from kernel. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct scsi_cmnd *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int gref[vscsiif_grants_sg(SG_ALL) + SG_ALL];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct vscsifrnt_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct xenbus_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int host_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned int evtchn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) grant_ref_t ring_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct vscsiif_front_ring ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct vscsiif_response ring_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) spinlock_t shadow_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) DECLARE_BITMAP(shadow_free_bitmap, VSCSIIF_MAX_REQS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct vscsifrnt_shadow *shadow[VSCSIIF_MAX_REQS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* Following items are protected by the host lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) wait_queue_head_t wq_sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) wait_queue_head_t wq_pause;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) unsigned int wait_ring_available:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned int waiting_pause:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned int pause:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned callers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) char dev_state_path[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct task_struct *curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static DEFINE_MUTEX(scsifront_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static void scsifront_wake_up(struct vscsifrnt_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) info->wait_ring_available = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) wake_up(&info->wq_sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static int scsifront_get_rqid(struct vscsifrnt_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) spin_lock_irqsave(&info->shadow_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) free = find_first_bit(info->shadow_free_bitmap, VSCSIIF_MAX_REQS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) __clear_bit(free, info->shadow_free_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) spin_unlock_irqrestore(&info->shadow_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static int _scsifront_put_rqid(struct vscsifrnt_info *info, uint32_t id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int empty = bitmap_empty(info->shadow_free_bitmap, VSCSIIF_MAX_REQS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) __set_bit(id, info->shadow_free_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) info->shadow[id] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return empty || info->wait_ring_available;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static void scsifront_put_rqid(struct vscsifrnt_info *info, uint32_t id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int kick;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) spin_lock_irqsave(&info->shadow_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) kick = _scsifront_put_rqid(info, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) spin_unlock_irqrestore(&info->shadow_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (kick)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) scsifront_wake_up(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static int scsifront_do_request(struct vscsifrnt_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct vscsifrnt_shadow *shadow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct vscsiif_front_ring *ring = &(info->ring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct vscsiif_request *ring_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct scsi_cmnd *sc = shadow->sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) uint32_t id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) int i, notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (RING_FULL(&info->ring))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) id = scsifront_get_rqid(info); /* use id in response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (id >= VSCSIIF_MAX_REQS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) info->shadow[id] = shadow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) shadow->rqid = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ring_req = RING_GET_REQUEST(&(info->ring), ring->req_prod_pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ring->req_prod_pvt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) ring_req->rqid = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ring_req->act = shadow->act;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) ring_req->ref_rqid = shadow->ref_rqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ring_req->nr_segments = shadow->nr_segments;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ring_req->id = sc->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ring_req->lun = sc->device->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ring_req->channel = sc->device->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ring_req->cmd_len = sc->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) BUG_ON(sc->cmd_len > VSCSIIF_MAX_COMMAND_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) memcpy(ring_req->cmnd, sc->cmnd, sc->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ring_req->sc_data_direction = (uint8_t)sc->sc_data_direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ring_req->timeout_per_command = sc->request->timeout / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) for (i = 0; i < (shadow->nr_segments & ~VSCSIIF_SG_GRANT); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ring_req->seg[i] = shadow->seg[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(ring, notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (notify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) notify_remote_via_irq(info->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static void scsifront_gnttab_done(struct vscsifrnt_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct vscsifrnt_shadow *shadow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (shadow->sc->sc_data_direction == DMA_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) for (i = 0; i < shadow->nr_grants; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (unlikely(!gnttab_try_end_foreign_access(shadow->gref[i]))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) shost_printk(KERN_ALERT, info->host, KBUILD_MODNAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) "grant still in use by backend\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) kfree(shadow->sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static void scsifront_cdb_cmd_done(struct vscsifrnt_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct vscsiif_response *ring_rsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct vscsifrnt_shadow *shadow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct scsi_cmnd *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) uint32_t id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) uint8_t sense_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) id = ring_rsp->rqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) shadow = info->shadow[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) sc = shadow->sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) BUG_ON(sc == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) scsifront_gnttab_done(info, shadow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) scsifront_put_rqid(info, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) sc->result = ring_rsp->rslt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) scsi_set_resid(sc, ring_rsp->residual_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) sense_len = min_t(uint8_t, VSCSIIF_SENSE_BUFFERSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ring_rsp->sense_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (sense_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) memcpy(sc->sense_buffer, ring_rsp->sense_buffer, sense_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) sc->scsi_done(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static void scsifront_sync_cmd_done(struct vscsifrnt_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct vscsiif_response *ring_rsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) uint16_t id = ring_rsp->rqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct vscsifrnt_shadow *shadow = info->shadow[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int kick;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) spin_lock_irqsave(&info->shadow_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) shadow->wait_reset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) switch (shadow->rslt_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) case RSLT_RESET_WAITING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) shadow->rslt_reset = ring_rsp->rslt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) case RSLT_RESET_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) kick = _scsifront_put_rqid(info, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) spin_unlock_irqrestore(&info->shadow_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) kfree(shadow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (kick)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) scsifront_wake_up(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) shost_printk(KERN_ERR, info->host, KBUILD_MODNAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) "bad reset state %d, possibly leaking %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) shadow->rslt_reset, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) spin_unlock_irqrestore(&info->shadow_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) wake_up(&shadow->wq_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static void scsifront_do_response(struct vscsifrnt_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct vscsiif_response *ring_rsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (WARN(ring_rsp->rqid >= VSCSIIF_MAX_REQS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) test_bit(ring_rsp->rqid, info->shadow_free_bitmap),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) "illegal rqid %u returned by backend!\n", ring_rsp->rqid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (info->shadow[ring_rsp->rqid]->act == VSCSIIF_ACT_SCSI_CDB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) scsifront_cdb_cmd_done(info, ring_rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) scsifront_sync_cmd_done(info, ring_rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static int scsifront_ring_drain(struct vscsifrnt_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct vscsiif_response *ring_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) RING_IDX i, rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int more_to_do = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) rp = info->ring.sring->rsp_prod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) rmb(); /* ordering required respective to dom0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) for (i = info->ring.rsp_cons; i != rp; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) ring_rsp = RING_GET_RESPONSE(&info->ring, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) scsifront_do_response(info, ring_rsp);
^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) info->ring.rsp_cons = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (i != info->ring.req_prod_pvt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, more_to_do);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) info->ring.sring->rsp_event = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return more_to_do;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static int scsifront_cmd_done(struct vscsifrnt_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int more_to_do;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) spin_lock_irqsave(info->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) more_to_do = scsifront_ring_drain(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) info->wait_ring_available = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) spin_unlock_irqrestore(info->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) wake_up(&info->wq_sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return more_to_do;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static irqreturn_t scsifront_irq_fn(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct vscsifrnt_info *info = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) while (scsifront_cmd_done(info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* Yield point for this unbounded loop. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static void scsifront_finish_all(struct vscsifrnt_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct vscsiif_response resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) scsifront_ring_drain(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) for (i = 0; i < VSCSIIF_MAX_REQS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (test_bit(i, info->shadow_free_bitmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) resp.rqid = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) resp.sense_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) resp.rslt = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) resp.residual_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) scsifront_do_response(info, &resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static int map_data_for_request(struct vscsifrnt_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct scsi_cmnd *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct vscsifrnt_shadow *shadow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) grant_ref_t gref_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) int err, ref, ref_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) int grant_ro = (sc->sc_data_direction == DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) unsigned int i, off, len, bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) unsigned int data_len = scsi_bufflen(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) unsigned int data_grants = 0, seg_grants = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct scsiif_request_segment *seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (sc->sc_data_direction == DMA_NONE || !data_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) scsi_for_each_sg(sc, sg, scsi_sg_count(sc), i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) data_grants += PFN_UP(sg->offset + sg->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (data_grants > VSCSIIF_SG_TABLESIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (data_grants > info->host->sg_tablesize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) shost_printk(KERN_ERR, info->host, KBUILD_MODNAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) "Unable to map request_buffer for command!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) seg_grants = vscsiif_grants_sg(data_grants);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) shadow->sg = kcalloc(data_grants,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) sizeof(struct scsiif_request_segment), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (!shadow->sg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) seg = shadow->sg ? : shadow->seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) err = gnttab_alloc_grant_references(seg_grants + data_grants,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) &gref_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) kfree(shadow->sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) shost_printk(KERN_ERR, info->host, KBUILD_MODNAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) "gnttab_alloc_grant_references() error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (seg_grants) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) page = virt_to_page(seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) off = offset_in_page(seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) len = sizeof(struct scsiif_request_segment) * data_grants;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) while (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) bytes = min_t(unsigned int, len, PAGE_SIZE - off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) ref = gnttab_claim_grant_reference(&gref_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) BUG_ON(ref == -ENOSPC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) gnttab_grant_foreign_access_ref(ref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) info->dev->otherend_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) xen_page_to_gfn(page), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) shadow->gref[ref_cnt] = ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) shadow->seg[ref_cnt].gref = ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) shadow->seg[ref_cnt].offset = (uint16_t)off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) shadow->seg[ref_cnt].length = (uint16_t)bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) page++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) len -= bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) ref_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) BUG_ON(seg_grants < ref_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) seg_grants = ref_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) scsi_for_each_sg(sc, sg, scsi_sg_count(sc), i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) page = sg_page(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) off = sg->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) len = sg->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) while (len > 0 && data_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * sg sends a scatterlist that is larger than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * the data_len it wants transferred for certain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * IO sizes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) bytes = min_t(unsigned int, len, PAGE_SIZE - off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) bytes = min(bytes, data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ref = gnttab_claim_grant_reference(&gref_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) BUG_ON(ref == -ENOSPC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) gnttab_grant_foreign_access_ref(ref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) info->dev->otherend_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) xen_page_to_gfn(page),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) grant_ro);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) shadow->gref[ref_cnt] = ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) seg->gref = ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) seg->offset = (uint16_t)off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) seg->length = (uint16_t)bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) page++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) seg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) len -= bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) data_len -= bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ref_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (seg_grants)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) shadow->nr_segments = VSCSIIF_SG_GRANT | seg_grants;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) shadow->nr_segments = (uint8_t)ref_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) shadow->nr_grants = ref_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) static int scsifront_enter(struct vscsifrnt_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (info->pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) info->callers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static void scsifront_return(struct vscsifrnt_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) info->callers--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (info->callers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (!info->waiting_pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) info->waiting_pause = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) wake_up(&info->wq_pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) static int scsifront_queuecommand(struct Scsi_Host *shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct scsi_cmnd *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct vscsifrnt_info *info = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct vscsifrnt_shadow *shadow = scsi_cmd_priv(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) sc->result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) shadow->sc = sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) shadow->act = VSCSIIF_ACT_SCSI_CDB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) spin_lock_irqsave(shost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (scsifront_enter(info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) spin_unlock_irqrestore(shost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return SCSI_MLQUEUE_HOST_BUSY;
^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) err = map_data_for_request(info, sc, shadow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) pr_debug("%s: err %d\n", __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) scsifront_return(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) spin_unlock_irqrestore(shost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (err == -ENOMEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return SCSI_MLQUEUE_HOST_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) sc->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) sc->scsi_done(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (scsifront_do_request(info, shadow)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) scsifront_gnttab_done(info, shadow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) goto busy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) scsifront_return(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) spin_unlock_irqrestore(shost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) busy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) scsifront_return(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) spin_unlock_irqrestore(shost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) pr_debug("%s: busy\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return SCSI_MLQUEUE_HOST_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * Any exception handling (reset or abort) must be forwarded to the backend.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * We have to wait until an answer is returned. This answer contains the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * result to be returned to the requestor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static int scsifront_action_handler(struct scsi_cmnd *sc, uint8_t act)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct Scsi_Host *host = sc->device->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct vscsifrnt_info *info = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct vscsifrnt_shadow *shadow, *s = scsi_cmd_priv(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) shadow = kzalloc(sizeof(*shadow), GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (!shadow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) shadow->act = act;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) shadow->rslt_reset = RSLT_RESET_WAITING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) shadow->sc = sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) shadow->ref_rqid = s->rqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) init_waitqueue_head(&shadow->wq_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) spin_lock_irq(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (scsifront_enter(info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (!scsifront_do_request(info, shadow))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) scsifront_return(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) info->wait_ring_available = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) spin_unlock_irq(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) err = wait_event_interruptible(info->wq_sync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) !info->wait_ring_available);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) spin_lock_irq(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) spin_unlock_irq(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) err = wait_event_interruptible(shadow->wq_reset, shadow->wait_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) spin_lock_irq(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) err = shadow->rslt_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) scsifront_put_rqid(info, shadow->rqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) kfree(shadow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) spin_lock(&info->shadow_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) shadow->rslt_reset = RSLT_RESET_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) spin_unlock(&info->shadow_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) err = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) scsifront_return(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) spin_unlock_irq(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) spin_unlock_irq(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) kfree(shadow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static int scsifront_eh_abort_handler(struct scsi_cmnd *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) pr_debug("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return scsifront_action_handler(sc, VSCSIIF_ACT_SCSI_ABORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static int scsifront_dev_reset_handler(struct scsi_cmnd *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) pr_debug("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return scsifront_action_handler(sc, VSCSIIF_ACT_SCSI_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static int scsifront_sdev_configure(struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct vscsifrnt_info *info = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (info && current == info->curr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) err = xenbus_printf(XBT_NIL, info->dev->nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) info->dev_state_path, "%d", XenbusStateConnected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) xenbus_dev_error(info->dev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) "%s: writing dev_state_path", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) static void scsifront_sdev_destroy(struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct vscsifrnt_info *info = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (info && current == info->curr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) err = xenbus_printf(XBT_NIL, info->dev->nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) info->dev_state_path, "%d", XenbusStateClosed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) xenbus_dev_error(info->dev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) "%s: writing dev_state_path", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static struct scsi_host_template scsifront_sht = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) .name = "Xen SCSI frontend driver",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) .queuecommand = scsifront_queuecommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) .eh_abort_handler = scsifront_eh_abort_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) .eh_device_reset_handler = scsifront_dev_reset_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) .slave_configure = scsifront_sdev_configure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) .slave_destroy = scsifront_sdev_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) .cmd_per_lun = VSCSIIF_DEFAULT_CMD_PER_LUN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) .can_queue = VSCSIIF_MAX_REQS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) .this_id = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) .cmd_size = sizeof(struct vscsifrnt_shadow),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) .sg_tablesize = VSCSIIF_SG_TABLESIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) .proc_name = "scsifront",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static int scsifront_alloc_ring(struct vscsifrnt_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct xenbus_device *dev = info->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct vscsiif_sring *sring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) grant_ref_t gref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) int err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /***** Frontend to Backend ring start *****/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) sring = (struct vscsiif_sring *)__get_free_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (!sring) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) xenbus_dev_fatal(dev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) "fail to allocate shared ring (Front to Back)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) SHARED_RING_INIT(sring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) err = xenbus_grant_ring(dev, sring, 1, &gref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) free_page((unsigned long)sring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) xenbus_dev_fatal(dev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) "fail to grant shared ring (Front to Back)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) info->ring_ref = gref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) err = xenbus_alloc_evtchn(dev, &info->evtchn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) xenbus_dev_fatal(dev, err, "xenbus_alloc_evtchn");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) goto free_gnttab;
^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) err = bind_evtchn_to_irq(info->evtchn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (err <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) xenbus_dev_fatal(dev, err, "bind_evtchn_to_irq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) goto free_gnttab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) info->irq = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) err = request_threaded_irq(info->irq, NULL, scsifront_irq_fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) IRQF_ONESHOT, "scsifront", info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) xenbus_dev_fatal(dev, err, "request_threaded_irq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) goto free_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) /* free resource */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) free_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) unbind_from_irqhandler(info->irq, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) free_gnttab:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) gnttab_end_foreign_access(info->ring_ref, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) (unsigned long)info->ring.sring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static void scsifront_free_ring(struct vscsifrnt_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) unbind_from_irqhandler(info->irq, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) gnttab_end_foreign_access(info->ring_ref, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) (unsigned long)info->ring.sring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) static int scsifront_init_ring(struct vscsifrnt_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) struct xenbus_device *dev = info->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) struct xenbus_transaction xbt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) pr_debug("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) err = scsifront_alloc_ring(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) pr_debug("%s: %u %u\n", __func__, info->ring_ref, info->evtchn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) err = xenbus_transaction_start(&xbt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) xenbus_dev_fatal(dev, err, "starting transaction");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) err = xenbus_printf(xbt, dev->nodename, "ring-ref", "%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) info->ring_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) xenbus_dev_fatal(dev, err, "%s", "writing ring-ref");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) err = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) info->evtchn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) xenbus_dev_fatal(dev, err, "%s", "writing event-channel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) err = xenbus_transaction_end(xbt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (err == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) xenbus_dev_fatal(dev, err, "completing transaction");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) goto free_sring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) xenbus_transaction_end(xbt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) free_sring:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) scsifront_free_ring(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) static int scsifront_probe(struct xenbus_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) const struct xenbus_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct vscsifrnt_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) int err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) char name[TASK_COMM_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) host = scsi_host_alloc(&scsifront_sht, sizeof(*info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (!host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) xenbus_dev_fatal(dev, err, "fail to allocate scsi host");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) info = (struct vscsifrnt_info *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) dev_set_drvdata(&dev->dev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) info->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) bitmap_fill(info->shadow_free_bitmap, VSCSIIF_MAX_REQS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) err = scsifront_init_ring(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) init_waitqueue_head(&info->wq_sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) init_waitqueue_head(&info->wq_pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) spin_lock_init(&info->shadow_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) snprintf(name, TASK_COMM_LEN, "vscsiif.%d", host->host_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) host->max_id = VSCSIIF_MAX_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) host->max_channel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) host->max_lun = VSCSIIF_MAX_LUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) host->max_sectors = (host->sg_tablesize - 1) * PAGE_SIZE / 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) host->max_cmd_len = VSCSIIF_MAX_COMMAND_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) err = scsi_add_host(host, &dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) dev_err(&dev->dev, "fail to add scsi host %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) goto free_sring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) info->host = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) info->host_active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) xenbus_switch_state(dev, XenbusStateInitialised);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) free_sring:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) scsifront_free_ring(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) static int scsifront_resume(struct xenbus_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) struct Scsi_Host *host = info->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) spin_lock_irq(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) /* Finish all still pending commands. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) scsifront_finish_all(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) spin_unlock_irq(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) /* Reconnect to dom0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) scsifront_free_ring(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) err = scsifront_init_ring(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) dev_err(&dev->dev, "fail to resume %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) xenbus_switch_state(dev, XenbusStateInitialised);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) return 0;
^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) static int scsifront_suspend(struct xenbus_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) struct Scsi_Host *host = info->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) /* No new commands for the backend. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) spin_lock_irq(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) info->pause = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) while (info->callers && !err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) info->waiting_pause = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) info->wait_ring_available = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) spin_unlock_irq(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) wake_up(&info->wq_sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) err = wait_event_interruptible(info->wq_pause,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) !info->waiting_pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) spin_lock_irq(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) spin_unlock_irq(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return err;
^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) static int scsifront_remove(struct xenbus_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) pr_debug("%s: %s removed\n", __func__, dev->nodename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) mutex_lock(&scsifront_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (info->host_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) /* Scsi_host not yet removed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) scsi_remove_host(info->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) info->host_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) mutex_unlock(&scsifront_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) scsifront_free_ring(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) scsi_host_put(info->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) static void scsifront_disconnect(struct vscsifrnt_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) struct xenbus_device *dev = info->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) struct Scsi_Host *host = info->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) pr_debug("%s: %s disconnect\n", __func__, dev->nodename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) * When this function is executed, all devices of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) * Frontend have been deleted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) * Therefore, it need not block I/O before remove_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) mutex_lock(&scsifront_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (info->host_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) scsi_remove_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) info->host_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) mutex_unlock(&scsifront_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) xenbus_frontend_closed(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) static void scsifront_do_lun_hotplug(struct vscsifrnt_info *info, int op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct xenbus_device *dev = info->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) int i, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) char str[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) char **dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) unsigned int dir_n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) unsigned int device_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) unsigned int hst, chn, tgt, lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) struct scsi_device *sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) dir = xenbus_directory(XBT_NIL, dev->otherend, "vscsi-devs", &dir_n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (IS_ERR(dir))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) /* mark current task as the one allowed to modify device states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) BUG_ON(info->curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) info->curr = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) for (i = 0; i < dir_n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) /* read status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) snprintf(str, sizeof(str), "vscsi-devs/%s/state", dir[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) err = xenbus_scanf(XBT_NIL, dev->otherend, str, "%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) &device_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (XENBUS_EXIST_ERR(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /* virtual SCSI device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) snprintf(str, sizeof(str), "vscsi-devs/%s/v-dev", dir[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) err = xenbus_scanf(XBT_NIL, dev->otherend, str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) "%u:%u:%u:%u", &hst, &chn, &tgt, &lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (XENBUS_EXIST_ERR(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * Front device state path, used in slave_configure called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) * on successfull scsi_add_device, and in slave_destroy called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) * on remove of a device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) snprintf(info->dev_state_path, sizeof(info->dev_state_path),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) "vscsi-devs/%s/state", dir[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) case VSCSIFRONT_OP_ADD_LUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (device_state != XenbusStateInitialised)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (scsi_add_device(info->host, chn, tgt, lun)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) dev_err(&dev->dev, "scsi_add_device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) err = xenbus_printf(XBT_NIL, dev->nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) info->dev_state_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) "%d", XenbusStateClosed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) xenbus_dev_error(dev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) "%s: writing dev_state_path", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) case VSCSIFRONT_OP_DEL_LUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (device_state != XenbusStateClosing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) sdev = scsi_device_lookup(info->host, chn, tgt, lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (sdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) scsi_remove_device(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) scsi_device_put(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) case VSCSIFRONT_OP_READD_LUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (device_state == XenbusStateConnected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) err = xenbus_printf(XBT_NIL, dev->nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) info->dev_state_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) "%d", XenbusStateConnected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) xenbus_dev_error(dev, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) "%s: writing dev_state_path", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) info->curr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) kfree(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) static void scsifront_read_backend_params(struct xenbus_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) struct vscsifrnt_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) unsigned int sg_grant, nr_segs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) struct Scsi_Host *host = info->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) sg_grant = xenbus_read_unsigned(dev->otherend, "feature-sg-grant", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) nr_segs = min_t(unsigned int, sg_grant, SG_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) nr_segs = max_t(unsigned int, nr_segs, VSCSIIF_SG_TABLESIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) nr_segs = min_t(unsigned int, nr_segs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) VSCSIIF_SG_TABLESIZE * PAGE_SIZE /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) sizeof(struct scsiif_request_segment));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (!info->pause && sg_grant)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) dev_info(&dev->dev, "using up to %d SG entries\n", nr_segs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) else if (info->pause && nr_segs < host->sg_tablesize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) dev_warn(&dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) "SG entries decreased from %d to %u - device may not work properly anymore\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) host->sg_tablesize, nr_segs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) host->sg_tablesize = nr_segs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) host->max_sectors = (nr_segs - 1) * PAGE_SIZE / 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) static void scsifront_backend_changed(struct xenbus_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) enum xenbus_state backend_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) pr_debug("%s: %p %u %u\n", __func__, dev, dev->state, backend_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) switch (backend_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) case XenbusStateUnknown:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) case XenbusStateInitialising:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) case XenbusStateInitWait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) case XenbusStateInitialised:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) case XenbusStateConnected:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) scsifront_read_backend_params(dev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (info->pause) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_READD_LUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) xenbus_switch_state(dev, XenbusStateConnected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) info->pause = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (xenbus_read_driver_state(dev->nodename) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) XenbusStateInitialised)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_ADD_LUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (dev->state != XenbusStateConnected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) xenbus_switch_state(dev, XenbusStateConnected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) case XenbusStateClosed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) if (dev->state == XenbusStateClosed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) fallthrough; /* Missed the backend's Closing state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) case XenbusStateClosing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) scsifront_disconnect(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) case XenbusStateReconfiguring:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_DEL_LUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) xenbus_switch_state(dev, XenbusStateReconfiguring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) case XenbusStateReconfigured:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_ADD_LUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) xenbus_switch_state(dev, XenbusStateConnected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) static const struct xenbus_device_id scsifront_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) { "vscsi" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) { "" }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static struct xenbus_driver scsifront_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) .ids = scsifront_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) .probe = scsifront_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) .remove = scsifront_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) .resume = scsifront_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) .suspend = scsifront_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) .otherend_changed = scsifront_backend_changed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) static int __init scsifront_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) if (!xen_domain())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) return xenbus_register_frontend(&scsifront_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) module_init(scsifront_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) static void __exit scsifront_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) xenbus_unregister_driver(&scsifront_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) module_exit(scsifront_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) MODULE_DESCRIPTION("Xen SCSI frontend driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) MODULE_ALIAS("xen:vscsi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) MODULE_AUTHOR("Juergen Gross <jgross@suse.com>");