2 * Xen SCSI frontend driver
4 * Copyright (c) 2008, FUJITSU Limited
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation; or, when distributed
9 * separately from the Linux kernel or incorporated into other
10 * software packages, subject to the following license:
12 * Permission is hereby granted, free of charge, to any person obtaining a copy
13 * of this source file (the "Software"), to deal in the Software without
14 * restriction, including without limitation the rights to use, copy, modify,
15 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
16 * and to permit persons to whom the Software is furnished to do so, subject to
17 * the following conditions:
19 * The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
32 #include <linux/version.h>
35 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
36 #define DEFAULT_TASK_COMM_LEN 16
38 #define DEFAULT_TASK_COMM_LEN TASK_COMM_LEN
41 extern struct scsi_host_template scsifront_sht;
43 static void scsifront_free(struct vscsifrnt_info *info)
45 struct Scsi_Host *host = info->host;
47 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
48 if (host->shost_state != SHOST_DEL) {
50 if (!test_bit(SHOST_DEL, &host->shost_state)) {
52 scsi_remove_host(info->host);
55 if (info->ring_ref != GRANT_INVALID_REF) {
56 gnttab_end_foreign_access(info->ring_ref,
57 (unsigned long)info->ring.sring);
58 info->ring_ref = GRANT_INVALID_REF;
59 info->ring.sring = NULL;
63 unbind_from_irqhandler(info->irq, info);
66 scsi_host_put(info->host);
70 static int scsifront_alloc_ring(struct vscsifrnt_info *info)
72 struct xenbus_device *dev = info->dev;
73 struct vscsiif_sring *sring;
77 info->ring_ref = GRANT_INVALID_REF;
79 /***** Frontend to Backend ring start *****/
80 sring = (struct vscsiif_sring *) __get_free_page(GFP_KERNEL);
82 xenbus_dev_fatal(dev, err, "fail to allocate shared ring (Front to Back)");
85 SHARED_RING_INIT(sring);
86 FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
88 err = xenbus_grant_ring(dev, virt_to_mfn(sring));
90 free_page((unsigned long) sring);
91 info->ring.sring = NULL;
92 xenbus_dev_fatal(dev, err, "fail to grant shared ring (Front to Back)");
97 err = bind_listening_port_to_irqhandler(
98 dev->otherend_id, scsifront_intr,
99 IRQF_SAMPLE_RANDOM, "scsifront", info);
102 xenbus_dev_fatal(dev, err, "bind_listening_port_to_irqhandler");
111 scsifront_free(info);
117 static int scsifront_init_ring(struct vscsifrnt_info *info)
119 struct xenbus_device *dev = info->dev;
120 struct xenbus_transaction xbt;
123 DPRINTK("%s\n",__FUNCTION__);
125 err = scsifront_alloc_ring(info);
128 DPRINTK("%u %u\n", info->ring_ref, info->evtchn);
131 err = xenbus_transaction_start(&xbt);
133 xenbus_dev_fatal(dev, err, "starting transaction");
136 err = xenbus_printf(xbt, dev->nodename, "ring-ref", "%u",
139 xenbus_dev_fatal(dev, err, "%s", "writing ring-ref");
143 err = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
144 irq_to_evtchn_port(info->irq));
147 xenbus_dev_fatal(dev, err, "%s", "writing event-channel");
151 err = xenbus_transaction_end(xbt, 0);
155 xenbus_dev_fatal(dev, err, "completing transaction");
162 xenbus_transaction_end(xbt, 1);
165 scsifront_free(info);
171 static int scsifront_probe(struct xenbus_device *dev,
172 const struct xenbus_device_id *id)
174 struct vscsifrnt_info *info;
175 struct Scsi_Host *host;
176 int i, err = -ENOMEM;
177 char name[DEFAULT_TASK_COMM_LEN];
179 host = scsi_host_alloc(&scsifront_sht, sizeof(*info));
181 xenbus_dev_fatal(dev, err, "fail to allocate scsi host");
184 info = (struct vscsifrnt_info *) host->hostdata;
188 dev_set_drvdata(&dev->dev, info);
191 for (i = 0; i < VSCSIIF_MAX_REQS; i++) {
192 info->shadow[i].next_free = i + 1;
193 init_waitqueue_head(&(info->shadow[i].wq_reset));
194 info->shadow[i].wait_reset = 0;
196 info->shadow[VSCSIIF_MAX_REQS - 1].next_free = 0x0fff;
198 err = scsifront_init_ring(info);
204 init_waitqueue_head(&info->wq);
205 spin_lock_init(&info->io_lock);
206 spin_lock_init(&info->shadow_lock);
208 snprintf(name, DEFAULT_TASK_COMM_LEN, "vscsiif.%d", info->host->host_no);
210 info->kthread = kthread_run(scsifront_schedule, info, name);
211 if (IS_ERR(info->kthread)) {
212 err = PTR_ERR(info->kthread);
213 info->kthread = NULL;
214 printk(KERN_ERR "scsifront: kthread start err %d\n", err);
218 host->max_id = VSCSIIF_MAX_TARGET;
219 host->max_channel = 0;
220 host->max_lun = VSCSIIF_MAX_LUN;
221 host->max_sectors = (VSCSIIF_SG_TABLESIZE - 1) * PAGE_SIZE / 512;
223 err = scsi_add_host(host, &dev->dev);
225 printk(KERN_ERR "scsifront: fail to add scsi host %d\n", err);
229 xenbus_switch_state(dev, XenbusStateInitialised);
235 scsifront_free(info);
239 static int scsifront_remove(struct xenbus_device *dev)
241 struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev);
243 DPRINTK("%s: %s removed\n",__FUNCTION__ ,dev->nodename);
246 kthread_stop(info->kthread);
247 info->kthread = NULL;
250 scsifront_free(info);
256 static int scsifront_disconnect(struct vscsifrnt_info *info)
258 struct xenbus_device *dev = info->dev;
259 struct Scsi_Host *host = info->host;
261 DPRINTK("%s: %s disconnect\n",__FUNCTION__ ,dev->nodename);
264 When this function is executed, all devices of
265 Frontend have been deleted.
266 Therefore, it need not block I/O before remove_host.
269 scsi_remove_host(host);
270 xenbus_frontend_closed(dev);
275 #define VSCSIFRONT_OP_ADD_LUN 1
276 #define VSCSIFRONT_OP_DEL_LUN 2
278 static void scsifront_do_lun_hotplug(struct vscsifrnt_info *info, int op)
280 struct xenbus_device *dev = info->dev;
282 char str[64], state_str[64];
284 unsigned int dir_n = 0;
285 unsigned int device_state;
286 unsigned int hst, chn, tgt, lun;
287 struct scsi_device *sdev;
289 dir = xenbus_directory(XBT_NIL, dev->otherend, "vscsi-devs", &dir_n);
293 for (i = 0; i < dir_n; i++) {
295 snprintf(str, sizeof(str), "vscsi-devs/%s/state", dir[i]);
296 err = xenbus_scanf(XBT_NIL, dev->otherend, str, "%u",
298 if (XENBUS_EXIST_ERR(err))
301 /* virtual SCSI device */
302 snprintf(str, sizeof(str), "vscsi-devs/%s/v-dev", dir[i]);
303 err = xenbus_scanf(XBT_NIL, dev->otherend, str,
304 "%u:%u:%u:%u", &hst, &chn, &tgt, &lun);
305 if (XENBUS_EXIST_ERR(err))
308 /* front device state path */
309 snprintf(state_str, sizeof(state_str), "vscsi-devs/%s/state", dir[i]);
312 case VSCSIFRONT_OP_ADD_LUN:
313 if (device_state == XenbusStateInitialised) {
314 sdev = scsi_device_lookup(info->host, chn, tgt, lun);
316 printk(KERN_ERR "scsifront: Device already in use.\n");
317 scsi_device_put(sdev);
318 xenbus_printf(XBT_NIL, dev->nodename,
319 state_str, "%d", XenbusStateClosed);
321 scsi_add_device(info->host, chn, tgt, lun);
322 xenbus_printf(XBT_NIL, dev->nodename,
323 state_str, "%d", XenbusStateConnected);
327 case VSCSIFRONT_OP_DEL_LUN:
328 if (device_state == XenbusStateClosing) {
329 sdev = scsi_device_lookup(info->host, chn, tgt, lun);
331 scsi_remove_device(sdev);
332 scsi_device_put(sdev);
333 xenbus_printf(XBT_NIL, dev->nodename,
334 state_str, "%d", XenbusStateClosed);
350 static void scsifront_backend_changed(struct xenbus_device *dev,
351 enum xenbus_state backend_state)
353 struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev);
355 DPRINTK("%p %u %u\n", dev, dev->state, backend_state);
357 switch (backend_state) {
358 case XenbusStateUnknown:
359 case XenbusStateInitialising:
360 case XenbusStateInitWait:
361 case XenbusStateClosed:
364 case XenbusStateInitialised:
367 case XenbusStateConnected:
368 if (xenbus_read_driver_state(dev->nodename) ==
369 XenbusStateInitialised) {
370 scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_ADD_LUN);
373 if (dev->state == XenbusStateConnected)
376 xenbus_switch_state(dev, XenbusStateConnected);
379 case XenbusStateClosing:
380 scsifront_disconnect(info);
383 case XenbusStateReconfiguring:
384 scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_DEL_LUN);
385 xenbus_switch_state(dev, XenbusStateReconfiguring);
388 case XenbusStateReconfigured:
389 scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_ADD_LUN);
390 xenbus_switch_state(dev, XenbusStateConnected);
396 static struct xenbus_device_id scsifront_ids[] = {
402 static struct xenbus_driver scsifront_driver = {
404 .ids = scsifront_ids,
405 .probe = scsifront_probe,
406 .remove = scsifront_remove,
407 /* .resume = scsifront_resume, */
408 .otherend_changed = scsifront_backend_changed,
411 int scsifront_xenbus_init(void)
413 return xenbus_register_frontend(&scsifront_driver);
416 void scsifront_xenbus_unregister(void)
418 xenbus_unregister_driver(&scsifront_driver);