aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJuergen Gross <jgross@suse.com>2014-08-28 00:44:11 -0400
committerStefano Stabellini <stefano.stabellini@eu.citrix.com>2014-09-23 09:36:19 -0400
commit8beb8d4c91d652617dc992de565ec9904361c33e (patch)
treed224ac744e751bea5b7454e5be20a3c8cf8c91a5 /drivers/scsi
parente124c9a2c3c4c51555fe6f0bc214fe1b5cce3666 (diff)
xen-scsifront: Add Xen PV SCSI frontend driver
Introduces the Xen pvSCSI frontend. With pvSCSI it is possible for a Xen domU to issue SCSI commands to a SCSI LUN assigned to that domU. The SCSI commands are passed to the pvSCSI backend in a driver domain (usually Dom0) which is owner of the physical device. This allows e.g. to use SCSI tape drives in a Xen domU. The code is taken from the pvSCSI implementation in Xen done by Fujitsu based on Linux kernel 2.6.18. Changes from the original version are: - port to upstream kernel - put all code in just one source file - move module to appropriate location in kernel tree - adapt to Linux style guide - some minor code simplifications - replace constants with defines - remove not used defines - add support for larger SG lists by putting them in a granted page Signed-off-by: Juergen Gross <jgross@suse.com> Acked-by: Christoph Hellwig <hch@lst.de> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/Kconfig9
-rw-r--r--drivers/scsi/Makefile1
-rw-r--r--drivers/scsi/xen-scsifront.c1024
3 files changed, 1034 insertions, 0 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 18a3358eb1d4..9130df14f742 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -576,6 +576,15 @@ config VMWARE_PVSCSI
576 To compile this driver as a module, choose M here: the 576 To compile this driver as a module, choose M here: the
577 module will be called vmw_pvscsi. 577 module will be called vmw_pvscsi.
578 578
579config XEN_SCSI_FRONTEND
580 tristate "XEN SCSI frontend driver"
581 depends on SCSI && XEN
582 help
583 The XEN SCSI frontend driver allows the kernel to access SCSI Devices
584 within another guest OS (usually Dom0).
585 Only needed if the kernel is running in a XEN guest and generic
586 SCSI access to a device is needed.
587
579config HYPERV_STORAGE 588config HYPERV_STORAGE
580 tristate "Microsoft Hyper-V virtual storage driver" 589 tristate "Microsoft Hyper-V virtual storage driver"
581 depends on SCSI && HYPERV 590 depends on SCSI && HYPERV
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 5f0d299b0093..59f1ce6df2d6 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -141,6 +141,7 @@ obj-$(CONFIG_SCSI_ESAS2R) += esas2r/
141obj-$(CONFIG_SCSI_PMCRAID) += pmcraid.o 141obj-$(CONFIG_SCSI_PMCRAID) += pmcraid.o
142obj-$(CONFIG_SCSI_VIRTIO) += virtio_scsi.o 142obj-$(CONFIG_SCSI_VIRTIO) += virtio_scsi.o
143obj-$(CONFIG_VMWARE_PVSCSI) += vmw_pvscsi.o 143obj-$(CONFIG_VMWARE_PVSCSI) += vmw_pvscsi.o
144obj-$(CONFIG_XEN_SCSI_FRONTEND) += xen-scsifront.o
144obj-$(CONFIG_HYPERV_STORAGE) += hv_storvsc.o 145obj-$(CONFIG_HYPERV_STORAGE) += hv_storvsc.o
145 146
146obj-$(CONFIG_ARM) += arm/ 147obj-$(CONFIG_ARM) += arm/
diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c
new file mode 100644
index 000000000000..0aceb70e1d83
--- /dev/null
+++ b/drivers/scsi/xen-scsifront.c
@@ -0,0 +1,1024 @@
1/*
2 * Xen SCSI frontend driver
3 *
4 * Copyright (c) 2008, FUJITSU Limited
5 *
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:
11 *
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:
18 *
19 * The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
21 *
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
28 * IN THE SOFTWARE.
29 */
30
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/device.h>
34#include <linux/wait.h>
35#include <linux/interrupt.h>
36#include <linux/mutex.h>
37#include <linux/spinlock.h>
38#include <linux/sched.h>
39#include <linux/blkdev.h>
40#include <linux/pfn.h>
41#include <linux/slab.h>
42#include <linux/bitops.h>
43
44#include <scsi/scsi_cmnd.h>
45#include <scsi/scsi_device.h>
46#include <scsi/scsi.h>
47#include <scsi/scsi_host.h>
48
49#include <xen/xen.h>
50#include <xen/xenbus.h>
51#include <xen/grant_table.h>
52#include <xen/events.h>
53#include <xen/page.h>
54
55#include <xen/interface/grant_table.h>
56#include <xen/interface/io/vscsiif.h>
57#include <xen/interface/io/protocols.h>
58
59#include <asm/xen/hypervisor.h>
60
61
62#define GRANT_INVALID_REF 0
63
64#define VSCSIFRONT_OP_ADD_LUN 1
65#define VSCSIFRONT_OP_DEL_LUN 2
66
67/* Tuning point. */
68#define VSCSIIF_DEFAULT_CMD_PER_LUN 10
69#define VSCSIIF_MAX_TARGET 64
70#define VSCSIIF_MAX_LUN 255
71
72#define VSCSIIF_RING_SIZE __CONST_RING_SIZE(vscsiif, PAGE_SIZE)
73#define VSCSIIF_MAX_REQS VSCSIIF_RING_SIZE
74
75#define vscsiif_grants_sg(_sg) (PFN_UP((_sg) * \
76 sizeof(struct scsiif_request_segment)))
77
78struct vscsifrnt_shadow {
79 /* command between backend and frontend */
80 unsigned char act;
81 uint16_t rqid;
82
83 unsigned int nr_grants; /* number of grants in gref[] */
84 struct scsiif_request_segment *sg; /* scatter/gather elements */
85
86 /* Do reset or abort function. */
87 wait_queue_head_t wq_reset; /* reset work queue */
88 int wait_reset; /* reset work queue condition */
89 int32_t rslt_reset; /* reset response status: */
90 /* SUCCESS or FAILED or: */
91#define RSLT_RESET_WAITING 0
92#define RSLT_RESET_ERR -1
93
94 /* Requested struct scsi_cmnd is stored from kernel. */
95 struct scsi_cmnd *sc;
96 int gref[vscsiif_grants_sg(SG_ALL) + SG_ALL];
97};
98
99struct vscsifrnt_info {
100 struct xenbus_device *dev;
101
102 struct Scsi_Host *host;
103 int host_active;
104
105 unsigned int evtchn;
106 unsigned int irq;
107
108 grant_ref_t ring_ref;
109 struct vscsiif_front_ring ring;
110 struct vscsiif_response ring_rsp;
111
112 spinlock_t shadow_lock;
113 DECLARE_BITMAP(shadow_free_bitmap, VSCSIIF_MAX_REQS);
114 struct vscsifrnt_shadow *shadow[VSCSIIF_MAX_REQS];
115
116 wait_queue_head_t wq_sync;
117 unsigned int wait_ring_available:1;
118
119 char dev_state_path[64];
120 struct task_struct *curr;
121};
122
123static DEFINE_MUTEX(scsifront_mutex);
124
125static void scsifront_wake_up(struct vscsifrnt_info *info)
126{
127 info->wait_ring_available = 0;
128 wake_up(&info->wq_sync);
129}
130
131static int scsifront_get_rqid(struct vscsifrnt_info *info)
132{
133 unsigned long flags;
134 int free;
135
136 spin_lock_irqsave(&info->shadow_lock, flags);
137
138 free = find_first_bit(info->shadow_free_bitmap, VSCSIIF_MAX_REQS);
139 __clear_bit(free, info->shadow_free_bitmap);
140
141 spin_unlock_irqrestore(&info->shadow_lock, flags);
142
143 return free;
144}
145
146static int _scsifront_put_rqid(struct vscsifrnt_info *info, uint32_t id)
147{
148 int empty = bitmap_empty(info->shadow_free_bitmap, VSCSIIF_MAX_REQS);
149
150 __set_bit(id, info->shadow_free_bitmap);
151 info->shadow[id] = NULL;
152
153 return empty || info->wait_ring_available;
154}
155
156static void scsifront_put_rqid(struct vscsifrnt_info *info, uint32_t id)
157{
158 unsigned long flags;
159 int kick;
160
161 spin_lock_irqsave(&info->shadow_lock, flags);
162 kick = _scsifront_put_rqid(info, id);
163 spin_unlock_irqrestore(&info->shadow_lock, flags);
164
165 if (kick)
166 scsifront_wake_up(info);
167}
168
169static struct vscsiif_request *scsifront_pre_req(struct vscsifrnt_info *info)
170{
171 struct vscsiif_front_ring *ring = &(info->ring);
172 struct vscsiif_request *ring_req;
173 uint32_t id;
174
175 id = scsifront_get_rqid(info); /* use id in response */
176 if (id >= VSCSIIF_MAX_REQS)
177 return NULL;
178
179 ring_req = RING_GET_REQUEST(&(info->ring), ring->req_prod_pvt);
180
181 ring->req_prod_pvt++;
182
183 ring_req->rqid = (uint16_t)id;
184
185 return ring_req;
186}
187
188static void scsifront_do_request(struct vscsifrnt_info *info)
189{
190 struct vscsiif_front_ring *ring = &(info->ring);
191 int notify;
192
193 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(ring, notify);
194 if (notify)
195 notify_remote_via_irq(info->irq);
196}
197
198static void scsifront_gnttab_done(struct vscsifrnt_info *info, uint32_t id)
199{
200 struct vscsifrnt_shadow *s = info->shadow[id];
201 int i;
202
203 if (s->sc->sc_data_direction == DMA_NONE)
204 return;
205
206 for (i = 0; i < s->nr_grants; i++) {
207 if (unlikely(gnttab_query_foreign_access(s->gref[i]) != 0)) {
208 shost_printk(KERN_ALERT, info->host, KBUILD_MODNAME
209 "grant still in use by backend\n");
210 BUG();
211 }
212 gnttab_end_foreign_access(s->gref[i], 0, 0UL);
213 }
214
215 kfree(s->sg);
216}
217
218static void scsifront_cdb_cmd_done(struct vscsifrnt_info *info,
219 struct vscsiif_response *ring_rsp)
220{
221 struct scsi_cmnd *sc;
222 uint32_t id;
223 uint8_t sense_len;
224
225 id = ring_rsp->rqid;
226 sc = info->shadow[id]->sc;
227
228 BUG_ON(sc == NULL);
229
230 scsifront_gnttab_done(info, id);
231 scsifront_put_rqid(info, id);
232
233 sc->result = ring_rsp->rslt;
234 scsi_set_resid(sc, ring_rsp->residual_len);
235
236 sense_len = min_t(uint8_t, VSCSIIF_SENSE_BUFFERSIZE,
237 ring_rsp->sense_len);
238
239 if (sense_len)
240 memcpy(sc->sense_buffer, ring_rsp->sense_buffer, sense_len);
241
242 sc->scsi_done(sc);
243}
244
245static void scsifront_sync_cmd_done(struct vscsifrnt_info *info,
246 struct vscsiif_response *ring_rsp)
247{
248 uint16_t id = ring_rsp->rqid;
249 unsigned long flags;
250 struct vscsifrnt_shadow *shadow = info->shadow[id];
251 int kick;
252
253 spin_lock_irqsave(&info->shadow_lock, flags);
254 shadow->wait_reset = 1;
255 switch (shadow->rslt_reset) {
256 case RSLT_RESET_WAITING:
257 shadow->rslt_reset = ring_rsp->rslt;
258 break;
259 case RSLT_RESET_ERR:
260 kick = _scsifront_put_rqid(info, id);
261 spin_unlock_irqrestore(&info->shadow_lock, flags);
262 kfree(shadow);
263 if (kick)
264 scsifront_wake_up(info);
265 return;
266 default:
267 shost_printk(KERN_ERR, info->host, KBUILD_MODNAME
268 "bad reset state %d, possibly leaking %u\n",
269 shadow->rslt_reset, id);
270 break;
271 }
272 spin_unlock_irqrestore(&info->shadow_lock, flags);
273
274 wake_up(&shadow->wq_reset);
275}
276
277static int scsifront_cmd_done(struct vscsifrnt_info *info)
278{
279 struct vscsiif_response *ring_rsp;
280 RING_IDX i, rp;
281 int more_to_do = 0;
282 unsigned long flags;
283
284 spin_lock_irqsave(info->host->host_lock, flags);
285
286 rp = info->ring.sring->rsp_prod;
287 rmb(); /* ordering required respective to dom0 */
288 for (i = info->ring.rsp_cons; i != rp; i++) {
289
290 ring_rsp = RING_GET_RESPONSE(&info->ring, i);
291
292 if (WARN(ring_rsp->rqid >= VSCSIIF_MAX_REQS ||
293 test_bit(ring_rsp->rqid, info->shadow_free_bitmap),
294 "illegal rqid %u returned by backend!\n",
295 ring_rsp->rqid))
296 continue;
297
298 if (info->shadow[ring_rsp->rqid]->act == VSCSIIF_ACT_SCSI_CDB)
299 scsifront_cdb_cmd_done(info, ring_rsp);
300 else
301 scsifront_sync_cmd_done(info, ring_rsp);
302 }
303
304 info->ring.rsp_cons = i;
305
306 if (i != info->ring.req_prod_pvt)
307 RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, more_to_do);
308 else
309 info->ring.sring->rsp_event = i + 1;
310
311 info->wait_ring_available = 0;
312
313 spin_unlock_irqrestore(info->host->host_lock, flags);
314
315 wake_up(&info->wq_sync);
316
317 return more_to_do;
318}
319
320static irqreturn_t scsifront_irq_fn(int irq, void *dev_id)
321{
322 struct vscsifrnt_info *info = dev_id;
323
324 while (scsifront_cmd_done(info))
325 /* Yield point for this unbounded loop. */
326 cond_resched();
327
328 return IRQ_HANDLED;
329}
330
331static int map_data_for_request(struct vscsifrnt_info *info,
332 struct scsi_cmnd *sc,
333 struct vscsiif_request *ring_req,
334 struct vscsifrnt_shadow *shadow)
335{
336 grant_ref_t gref_head;
337 struct page *page;
338 int err, ref, ref_cnt = 0;
339 int grant_ro = (sc->sc_data_direction == DMA_TO_DEVICE);
340 unsigned int i, off, len, bytes;
341 unsigned int data_len = scsi_bufflen(sc);
342 unsigned int data_grants = 0, seg_grants = 0;
343 struct scatterlist *sg;
344 unsigned long mfn;
345 struct scsiif_request_segment *seg;
346
347 ring_req->nr_segments = 0;
348 if (sc->sc_data_direction == DMA_NONE || !data_len)
349 return 0;
350
351 scsi_for_each_sg(sc, sg, scsi_sg_count(sc), i)
352 data_grants += PFN_UP(sg->offset + sg->length);
353
354 if (data_grants > VSCSIIF_SG_TABLESIZE) {
355 if (data_grants > info->host->sg_tablesize) {
356 shost_printk(KERN_ERR, info->host, KBUILD_MODNAME
357 "Unable to map request_buffer for command!\n");
358 return -E2BIG;
359 }
360 seg_grants = vscsiif_grants_sg(data_grants);
361 shadow->sg = kcalloc(data_grants,
362 sizeof(struct scsiif_request_segment), GFP_NOIO);
363 if (!shadow->sg)
364 return -ENOMEM;
365 }
366 seg = shadow->sg ? : ring_req->seg;
367
368 err = gnttab_alloc_grant_references(seg_grants + data_grants,
369 &gref_head);
370 if (err) {
371 kfree(shadow->sg);
372 shost_printk(KERN_ERR, info->host, KBUILD_MODNAME
373 "gnttab_alloc_grant_references() error\n");
374 return -ENOMEM;
375 }
376
377 if (seg_grants) {
378 page = virt_to_page(seg);
379 off = (unsigned long)seg & ~PAGE_MASK;
380 len = sizeof(struct scsiif_request_segment) * data_grants;
381 while (len > 0) {
382 bytes = min_t(unsigned int, len, PAGE_SIZE - off);
383
384 ref = gnttab_claim_grant_reference(&gref_head);
385 BUG_ON(ref == -ENOSPC);
386
387 mfn = pfn_to_mfn(page_to_pfn(page));
388 gnttab_grant_foreign_access_ref(ref,
389 info->dev->otherend_id, mfn, 1);
390 shadow->gref[ref_cnt] = ref;
391 ring_req->seg[ref_cnt].gref = ref;
392 ring_req->seg[ref_cnt].offset = (uint16_t)off;
393 ring_req->seg[ref_cnt].length = (uint16_t)bytes;
394
395 page++;
396 len -= bytes;
397 off = 0;
398 ref_cnt++;
399 }
400 BUG_ON(seg_grants < ref_cnt);
401 seg_grants = ref_cnt;
402 }
403
404 scsi_for_each_sg(sc, sg, scsi_sg_count(sc), i) {
405 page = sg_page(sg);
406 off = sg->offset;
407 len = sg->length;
408
409 while (len > 0 && data_len > 0) {
410 /*
411 * sg sends a scatterlist that is larger than
412 * the data_len it wants transferred for certain
413 * IO sizes.
414 */
415 bytes = min_t(unsigned int, len, PAGE_SIZE - off);
416 bytes = min(bytes, data_len);
417
418 ref = gnttab_claim_grant_reference(&gref_head);
419 BUG_ON(ref == -ENOSPC);
420
421 mfn = pfn_to_mfn(page_to_pfn(page));
422 gnttab_grant_foreign_access_ref(ref,
423 info->dev->otherend_id, mfn, grant_ro);
424
425 shadow->gref[ref_cnt] = ref;
426 seg->gref = ref;
427 seg->offset = (uint16_t)off;
428 seg->length = (uint16_t)bytes;
429
430 page++;
431 seg++;
432 len -= bytes;
433 data_len -= bytes;
434 off = 0;
435 ref_cnt++;
436 }
437 }
438
439 if (seg_grants)
440 ring_req->nr_segments = VSCSIIF_SG_GRANT | seg_grants;
441 else
442 ring_req->nr_segments = (uint8_t)ref_cnt;
443 shadow->nr_grants = ref_cnt;
444
445 return 0;
446}
447
448static struct vscsiif_request *scsifront_command2ring(
449 struct vscsifrnt_info *info, struct scsi_cmnd *sc,
450 struct vscsifrnt_shadow *shadow)
451{
452 struct vscsiif_request *ring_req;
453
454 memset(shadow, 0, sizeof(*shadow));
455
456 ring_req = scsifront_pre_req(info);
457 if (!ring_req)
458 return NULL;
459
460 info->shadow[ring_req->rqid] = shadow;
461 shadow->rqid = ring_req->rqid;
462
463 ring_req->id = sc->device->id;
464 ring_req->lun = sc->device->lun;
465 ring_req->channel = sc->device->channel;
466 ring_req->cmd_len = sc->cmd_len;
467
468 BUG_ON(sc->cmd_len > VSCSIIF_MAX_COMMAND_SIZE);
469
470 memcpy(ring_req->cmnd, sc->cmnd, sc->cmd_len);
471
472 ring_req->sc_data_direction = (uint8_t)sc->sc_data_direction;
473 ring_req->timeout_per_command = sc->request->timeout / HZ;
474
475 return ring_req;
476}
477
478static int scsifront_queuecommand(struct Scsi_Host *shost,
479 struct scsi_cmnd *sc)
480{
481 struct vscsifrnt_info *info = shost_priv(shost);
482 struct vscsiif_request *ring_req;
483 struct vscsifrnt_shadow *shadow = scsi_cmd_priv(sc);
484 unsigned long flags;
485 int err;
486 uint16_t rqid;
487
488 spin_lock_irqsave(shost->host_lock, flags);
489 if (RING_FULL(&info->ring))
490 goto busy;
491
492 ring_req = scsifront_command2ring(info, sc, shadow);
493 if (!ring_req)
494 goto busy;
495
496 sc->result = 0;
497
498 rqid = ring_req->rqid;
499 ring_req->act = VSCSIIF_ACT_SCSI_CDB;
500
501 shadow->sc = sc;
502 shadow->act = VSCSIIF_ACT_SCSI_CDB;
503
504 err = map_data_for_request(info, sc, ring_req, shadow);
505 if (err < 0) {
506 pr_debug("%s: err %d\n", __func__, err);
507 scsifront_put_rqid(info, rqid);
508 spin_unlock_irqrestore(shost->host_lock, flags);
509 if (err == -ENOMEM)
510 return SCSI_MLQUEUE_HOST_BUSY;
511 sc->result = DID_ERROR << 16;
512 sc->scsi_done(sc);
513 return 0;
514 }
515
516 scsifront_do_request(info);
517 spin_unlock_irqrestore(shost->host_lock, flags);
518
519 return 0;
520
521busy:
522 spin_unlock_irqrestore(shost->host_lock, flags);
523 pr_debug("%s: busy\n", __func__);
524 return SCSI_MLQUEUE_HOST_BUSY;
525}
526
527/*
528 * Any exception handling (reset or abort) must be forwarded to the backend.
529 * We have to wait until an answer is returned. This answer contains the
530 * result to be returned to the requestor.
531 */
532static int scsifront_action_handler(struct scsi_cmnd *sc, uint8_t act)
533{
534 struct Scsi_Host *host = sc->device->host;
535 struct vscsifrnt_info *info = shost_priv(host);
536 struct vscsifrnt_shadow *shadow, *s = scsi_cmd_priv(sc);
537 struct vscsiif_request *ring_req;
538 int err = 0;
539
540 shadow = kmalloc(sizeof(*shadow), GFP_NOIO);
541 if (!shadow)
542 return FAILED;
543
544 for (;;) {
545 spin_lock_irq(host->host_lock);
546 if (!RING_FULL(&info->ring)) {
547 ring_req = scsifront_command2ring(info, sc, shadow);
548 if (ring_req)
549 break;
550 }
551 if (err) {
552 spin_unlock_irq(host->host_lock);
553 kfree(shadow);
554 return FAILED;
555 }
556 info->wait_ring_available = 1;
557 spin_unlock_irq(host->host_lock);
558 err = wait_event_interruptible(info->wq_sync,
559 !info->wait_ring_available);
560 spin_lock_irq(host->host_lock);
561 }
562
563 ring_req->act = act;
564 ring_req->ref_rqid = s->rqid;
565
566 shadow->act = act;
567 shadow->rslt_reset = RSLT_RESET_WAITING;
568 init_waitqueue_head(&shadow->wq_reset);
569
570 ring_req->nr_segments = 0;
571
572 scsifront_do_request(info);
573
574 spin_unlock_irq(host->host_lock);
575 err = wait_event_interruptible(shadow->wq_reset, shadow->wait_reset);
576 spin_lock_irq(host->host_lock);
577
578 if (!err) {
579 err = shadow->rslt_reset;
580 scsifront_put_rqid(info, shadow->rqid);
581 kfree(shadow);
582 } else {
583 spin_lock(&info->shadow_lock);
584 shadow->rslt_reset = RSLT_RESET_ERR;
585 spin_unlock(&info->shadow_lock);
586 err = FAILED;
587 }
588
589 spin_unlock_irq(host->host_lock);
590 return err;
591}
592
593static int scsifront_eh_abort_handler(struct scsi_cmnd *sc)
594{
595 pr_debug("%s\n", __func__);
596 return scsifront_action_handler(sc, VSCSIIF_ACT_SCSI_ABORT);
597}
598
599static int scsifront_dev_reset_handler(struct scsi_cmnd *sc)
600{
601 pr_debug("%s\n", __func__);
602 return scsifront_action_handler(sc, VSCSIIF_ACT_SCSI_RESET);
603}
604
605static int scsifront_sdev_configure(struct scsi_device *sdev)
606{
607 struct vscsifrnt_info *info = shost_priv(sdev->host);
608
609 if (info && current == info->curr)
610 xenbus_printf(XBT_NIL, info->dev->nodename,
611 info->dev_state_path, "%d", XenbusStateConnected);
612
613 return 0;
614}
615
616static void scsifront_sdev_destroy(struct scsi_device *sdev)
617{
618 struct vscsifrnt_info *info = shost_priv(sdev->host);
619
620 if (info && current == info->curr)
621 xenbus_printf(XBT_NIL, info->dev->nodename,
622 info->dev_state_path, "%d", XenbusStateClosed);
623}
624
625static struct scsi_host_template scsifront_sht = {
626 .module = THIS_MODULE,
627 .name = "Xen SCSI frontend driver",
628 .queuecommand = scsifront_queuecommand,
629 .eh_abort_handler = scsifront_eh_abort_handler,
630 .eh_device_reset_handler = scsifront_dev_reset_handler,
631 .slave_configure = scsifront_sdev_configure,
632 .slave_destroy = scsifront_sdev_destroy,
633 .cmd_per_lun = VSCSIIF_DEFAULT_CMD_PER_LUN,
634 .can_queue = VSCSIIF_MAX_REQS,
635 .this_id = -1,
636 .cmd_size = sizeof(struct vscsifrnt_shadow),
637 .sg_tablesize = VSCSIIF_SG_TABLESIZE,
638 .use_clustering = DISABLE_CLUSTERING,
639 .proc_name = "scsifront",
640};
641
642static int scsifront_alloc_ring(struct vscsifrnt_info *info)
643{
644 struct xenbus_device *dev = info->dev;
645 struct vscsiif_sring *sring;
646 int err = -ENOMEM;
647
648 /***** Frontend to Backend ring start *****/
649 sring = (struct vscsiif_sring *)__get_free_page(GFP_KERNEL);
650 if (!sring) {
651 xenbus_dev_fatal(dev, err,
652 "fail to allocate shared ring (Front to Back)");
653 return err;
654 }
655 SHARED_RING_INIT(sring);
656 FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
657
658 err = xenbus_grant_ring(dev, virt_to_mfn(sring));
659 if (err < 0) {
660 free_page((unsigned long)sring);
661 xenbus_dev_fatal(dev, err,
662 "fail to grant shared ring (Front to Back)");
663 return err;
664 }
665 info->ring_ref = err;
666
667 err = xenbus_alloc_evtchn(dev, &info->evtchn);
668 if (err) {
669 xenbus_dev_fatal(dev, err, "xenbus_alloc_evtchn");
670 goto free_gnttab;
671 }
672
673 err = bind_evtchn_to_irq(info->evtchn);
674 if (err <= 0) {
675 xenbus_dev_fatal(dev, err, "bind_evtchn_to_irq");
676 goto free_gnttab;
677 }
678
679 info->irq = err;
680
681 err = request_threaded_irq(info->irq, NULL, scsifront_irq_fn,
682 IRQF_ONESHOT, "scsifront", info);
683 if (err) {
684 xenbus_dev_fatal(dev, err, "request_threaded_irq");
685 goto free_irq;
686 }
687
688 return 0;
689
690/* free resource */
691free_irq:
692 unbind_from_irqhandler(info->irq, info);
693free_gnttab:
694 gnttab_end_foreign_access(info->ring_ref, 0,
695 (unsigned long)info->ring.sring);
696
697 return err;
698}
699
700static int scsifront_init_ring(struct vscsifrnt_info *info)
701{
702 struct xenbus_device *dev = info->dev;
703 struct xenbus_transaction xbt;
704 int err;
705
706 pr_debug("%s\n", __func__);
707
708 err = scsifront_alloc_ring(info);
709 if (err)
710 return err;
711 pr_debug("%s: %u %u\n", __func__, info->ring_ref, info->evtchn);
712
713again:
714 err = xenbus_transaction_start(&xbt);
715 if (err)
716 xenbus_dev_fatal(dev, err, "starting transaction");
717
718 err = xenbus_printf(xbt, dev->nodename, "ring-ref", "%u",
719 info->ring_ref);
720 if (err) {
721 xenbus_dev_fatal(dev, err, "%s", "writing ring-ref");
722 goto fail;
723 }
724
725 err = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
726 info->evtchn);
727
728 if (err) {
729 xenbus_dev_fatal(dev, err, "%s", "writing event-channel");
730 goto fail;
731 }
732
733 err = xenbus_transaction_end(xbt, 0);
734 if (err) {
735 if (err == -EAGAIN)
736 goto again;
737 xenbus_dev_fatal(dev, err, "completing transaction");
738 goto free_sring;
739 }
740
741 return 0;
742
743fail:
744 xenbus_transaction_end(xbt, 1);
745free_sring:
746 unbind_from_irqhandler(info->irq, info);
747 gnttab_end_foreign_access(info->ring_ref, 0,
748 (unsigned long)info->ring.sring);
749
750 return err;
751}
752
753
754static int scsifront_probe(struct xenbus_device *dev,
755 const struct xenbus_device_id *id)
756{
757 struct vscsifrnt_info *info;
758 struct Scsi_Host *host;
759 int err = -ENOMEM;
760 char name[TASK_COMM_LEN];
761
762 host = scsi_host_alloc(&scsifront_sht, sizeof(*info));
763 if (!host) {
764 xenbus_dev_fatal(dev, err, "fail to allocate scsi host");
765 return err;
766 }
767 info = (struct vscsifrnt_info *)host->hostdata;
768
769 dev_set_drvdata(&dev->dev, info);
770 info->dev = dev;
771
772 bitmap_fill(info->shadow_free_bitmap, VSCSIIF_MAX_REQS);
773
774 err = scsifront_init_ring(info);
775 if (err) {
776 scsi_host_put(host);
777 return err;
778 }
779
780 init_waitqueue_head(&info->wq_sync);
781 spin_lock_init(&info->shadow_lock);
782
783 snprintf(name, TASK_COMM_LEN, "vscsiif.%d", host->host_no);
784
785 host->max_id = VSCSIIF_MAX_TARGET;
786 host->max_channel = 0;
787 host->max_lun = VSCSIIF_MAX_LUN;
788 host->max_sectors = (host->sg_tablesize - 1) * PAGE_SIZE / 512;
789 host->max_cmd_len = VSCSIIF_MAX_COMMAND_SIZE;
790
791 err = scsi_add_host(host, &dev->dev);
792 if (err) {
793 dev_err(&dev->dev, "fail to add scsi host %d\n", err);
794 goto free_sring;
795 }
796 info->host = host;
797 info->host_active = 1;
798
799 xenbus_switch_state(dev, XenbusStateInitialised);
800
801 return 0;
802
803free_sring:
804 unbind_from_irqhandler(info->irq, info);
805 gnttab_end_foreign_access(info->ring_ref, 0,
806 (unsigned long)info->ring.sring);
807 scsi_host_put(host);
808 return err;
809}
810
811static int scsifront_remove(struct xenbus_device *dev)
812{
813 struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev);
814
815 pr_debug("%s: %s removed\n", __func__, dev->nodename);
816
817 mutex_lock(&scsifront_mutex);
818 if (info->host_active) {
819 /* Scsi_host not yet removed */
820 scsi_remove_host(info->host);
821 info->host_active = 0;
822 }
823 mutex_unlock(&scsifront_mutex);
824
825 gnttab_end_foreign_access(info->ring_ref, 0,
826 (unsigned long)info->ring.sring);
827 unbind_from_irqhandler(info->irq, info);
828
829 scsi_host_put(info->host);
830
831 return 0;
832}
833
834static void scsifront_disconnect(struct vscsifrnt_info *info)
835{
836 struct xenbus_device *dev = info->dev;
837 struct Scsi_Host *host = info->host;
838
839 pr_debug("%s: %s disconnect\n", __func__, dev->nodename);
840
841 /*
842 * When this function is executed, all devices of
843 * Frontend have been deleted.
844 * Therefore, it need not block I/O before remove_host.
845 */
846
847 mutex_lock(&scsifront_mutex);
848 if (info->host_active) {
849 scsi_remove_host(host);
850 info->host_active = 0;
851 }
852 mutex_unlock(&scsifront_mutex);
853
854 xenbus_frontend_closed(dev);
855}
856
857static void scsifront_do_lun_hotplug(struct vscsifrnt_info *info, int op)
858{
859 struct xenbus_device *dev = info->dev;
860 int i, err = 0;
861 char str[64];
862 char **dir;
863 unsigned int dir_n = 0;
864 unsigned int device_state;
865 unsigned int hst, chn, tgt, lun;
866 struct scsi_device *sdev;
867
868 dir = xenbus_directory(XBT_NIL, dev->otherend, "vscsi-devs", &dir_n);
869 if (IS_ERR(dir))
870 return;
871
872 /* mark current task as the one allowed to modify device states */
873 BUG_ON(info->curr);
874 info->curr = current;
875
876 for (i = 0; i < dir_n; i++) {
877 /* read status */
878 snprintf(str, sizeof(str), "vscsi-devs/%s/state", dir[i]);
879 err = xenbus_scanf(XBT_NIL, dev->otherend, str, "%u",
880 &device_state);
881 if (XENBUS_EXIST_ERR(err))
882 continue;
883
884 /* virtual SCSI device */
885 snprintf(str, sizeof(str), "vscsi-devs/%s/v-dev", dir[i]);
886 err = xenbus_scanf(XBT_NIL, dev->otherend, str,
887 "%u:%u:%u:%u", &hst, &chn, &tgt, &lun);
888 if (XENBUS_EXIST_ERR(err))
889 continue;
890
891 /*
892 * Front device state path, used in slave_configure called
893 * on successfull scsi_add_device, and in slave_destroy called
894 * on remove of a device.
895 */
896 snprintf(info->dev_state_path, sizeof(info->dev_state_path),
897 "vscsi-devs/%s/state", dir[i]);
898
899 switch (op) {
900 case VSCSIFRONT_OP_ADD_LUN:
901 if (device_state != XenbusStateInitialised)
902 break;
903
904 if (scsi_add_device(info->host, chn, tgt, lun)) {
905 dev_err(&dev->dev, "scsi_add_device\n");
906 xenbus_printf(XBT_NIL, dev->nodename,
907 info->dev_state_path,
908 "%d", XenbusStateClosed);
909 }
910 break;
911 case VSCSIFRONT_OP_DEL_LUN:
912 if (device_state != XenbusStateClosing)
913 break;
914
915 sdev = scsi_device_lookup(info->host, chn, tgt, lun);
916 if (sdev) {
917 scsi_remove_device(sdev);
918 scsi_device_put(sdev);
919 }
920 break;
921 default:
922 break;
923 }
924 }
925
926 info->curr = NULL;
927
928 kfree(dir);
929}
930
931static void scsifront_read_backend_params(struct xenbus_device *dev,
932 struct vscsifrnt_info *info)
933{
934 unsigned int sg_grant;
935 int ret;
936 struct Scsi_Host *host = info->host;
937
938 ret = xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg-grant", "%u",
939 &sg_grant);
940 if (ret == 1 && sg_grant) {
941 sg_grant = min_t(unsigned int, sg_grant, SG_ALL);
942 sg_grant = max_t(unsigned int, sg_grant, VSCSIIF_SG_TABLESIZE);
943 host->sg_tablesize = min_t(unsigned int, sg_grant,
944 VSCSIIF_SG_TABLESIZE * PAGE_SIZE /
945 sizeof(struct scsiif_request_segment));
946 host->max_sectors = (host->sg_tablesize - 1) * PAGE_SIZE / 512;
947 }
948 dev_info(&dev->dev, "using up to %d SG entries\n", host->sg_tablesize);
949}
950
951static void scsifront_backend_changed(struct xenbus_device *dev,
952 enum xenbus_state backend_state)
953{
954 struct vscsifrnt_info *info = dev_get_drvdata(&dev->dev);
955
956 pr_debug("%s: %p %u %u\n", __func__, dev, dev->state, backend_state);
957
958 switch (backend_state) {
959 case XenbusStateUnknown:
960 case XenbusStateInitialising:
961 case XenbusStateInitWait:
962 case XenbusStateInitialised:
963 break;
964
965 case XenbusStateConnected:
966 scsifront_read_backend_params(dev, info);
967 if (xenbus_read_driver_state(dev->nodename) ==
968 XenbusStateInitialised)
969 scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_ADD_LUN);
970
971 if (dev->state != XenbusStateConnected)
972 xenbus_switch_state(dev, XenbusStateConnected);
973 break;
974
975 case XenbusStateClosed:
976 if (dev->state == XenbusStateClosed)
977 break;
978 /* Missed the backend's Closing state -- fallthrough */
979 case XenbusStateClosing:
980 scsifront_disconnect(info);
981 break;
982
983 case XenbusStateReconfiguring:
984 scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_DEL_LUN);
985 xenbus_switch_state(dev, XenbusStateReconfiguring);
986 break;
987
988 case XenbusStateReconfigured:
989 scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_ADD_LUN);
990 xenbus_switch_state(dev, XenbusStateConnected);
991 break;
992 }
993}
994
995static const struct xenbus_device_id scsifront_ids[] = {
996 { "vscsi" },
997 { "" }
998};
999
1000static DEFINE_XENBUS_DRIVER(scsifront, ,
1001 .probe = scsifront_probe,
1002 .remove = scsifront_remove,
1003 .otherend_changed = scsifront_backend_changed,
1004);
1005
1006static int __init scsifront_init(void)
1007{
1008 if (!xen_domain())
1009 return -ENODEV;
1010
1011 return xenbus_register_frontend(&scsifront_driver);
1012}
1013module_init(scsifront_init);
1014
1015static void __exit scsifront_exit(void)
1016{
1017 xenbus_unregister_driver(&scsifront_driver);
1018}
1019module_exit(scsifront_exit);
1020
1021MODULE_DESCRIPTION("Xen SCSI frontend driver");
1022MODULE_LICENSE("GPL");
1023MODULE_ALIAS("xen:vscsi");
1024MODULE_AUTHOR("Juergen Gross <jgross@suse.com>");