2 * interface management.
4 * Copyright (c) 2008, FUJITSU Limited
6 * Based on the blkback driver code.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation; or, when distributed
11 * separately from the Linux kernel or incorporated into other
12 * software packages, subject to the following license:
14 * Permission is hereby granted, free of charge, to any person obtaining a copy
15 * of this source file (the "Software"), to deal in the Software without
16 * restriction, including without limitation the rights to use, copy, modify,
17 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
18 * and to permit persons to whom the Software is furnished to do so, subject to
19 * the following conditions:
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
33 #include <scsi/scsi.h>
34 #include <scsi/scsi_host.h>
35 #include <scsi/scsi_device.h>
38 #include <xen/evtchn.h>
39 #include <linux/kthread.h>
40 #include <linux/delay.h>
41 #include <linux/vmalloc.h>
44 static struct kmem_cache *scsiback_cachep;
46 struct vscsibk_info *vscsibk_info_alloc(domid_t domid)
48 struct vscsibk_info *info;
50 info = kmem_cache_zalloc(scsiback_cachep, GFP_KERNEL);
52 return ERR_PTR(-ENOMEM);
55 spin_lock_init(&info->ring_lock);
56 atomic_set(&info->nr_unreplied_reqs, 0);
57 init_waitqueue_head(&info->wq);
58 init_waitqueue_head(&info->waiting_to_free);
63 int scsiback_init_sring(struct vscsibk_info *info, grant_ref_t ring_ref,
66 struct vm_struct *area;
67 struct vscsiif_sring *sring;
71 pr_err("scsiback: Already connected through?\n");
75 area = xenbus_map_ring_valloc(info->dev, ring_ref);
78 info->ring_area = area;
80 sring = (struct vscsiif_sring *)area->addr;
81 BACK_RING_INIT(&info->ring, sring, PAGE_SIZE);
83 err = bind_interdomain_evtchn_to_irqhandler(
85 scsiback_intr, 0, "vscsiif-backend", info);
95 xenbus_unmap_ring_vfree(info->dev, area);
100 void scsiback_disconnect(struct vscsibk_info *info)
103 kthread_stop(info->kthread);
104 info->kthread = NULL;
107 wait_event(info->waiting_to_free,
108 atomic_read(&info->nr_unreplied_reqs) == 0);
111 unbind_from_irqhandler(info->irq, info);
115 if (info->ring.sring) {
116 xenbus_unmap_ring_vfree(info->dev, info->ring_area);
117 info->ring.sring = NULL;
121 void scsiback_free(struct vscsibk_info *info)
123 kmem_cache_free(scsiback_cachep, info);
126 int __init scsiback_interface_init(void)
128 scsiback_cachep = kmem_cache_create("vscsiif_cache",
129 sizeof(struct vscsibk_info), 0, 0, NULL);
130 if (!scsiback_cachep) {
131 pr_err("scsiback: can't init scsi cache\n");
138 void scsiback_interface_exit(void)
140 kmem_cache_destroy(scsiback_cachep);