aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2012-12-14 11:02:18 -0500
committerGleb Natapov <gleb@redhat.com>2012-12-18 07:37:13 -0500
commit7e64e0597fd67c975bfa3e76401bfbcdd5ae0ff9 (patch)
tree8af50236372d9db8679e9cbf10fad40766fedf4e /drivers/s390
parent0abbe448eddb2263db3fb776757f480b34accd88 (diff)
KVM: s390: Add a channel I/O based virtio transport driver.
Add a driver for kvm guests that matches virtual ccw devices provided by the host as virtio bridge devices. These virtio-ccw devices use a special set of channel commands in order to perform virtio functions. Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com> Reviewed-by: Alexander Graf <agraf@suse.de> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/kvm/Makefile2
-rw-r--r--drivers/s390/kvm/virtio_ccw.c853
2 files changed, 854 insertions, 1 deletions
diff --git a/drivers/s390/kvm/Makefile b/drivers/s390/kvm/Makefile
index 0815690ac1e0..241891a57caf 100644
--- a/drivers/s390/kvm/Makefile
+++ b/drivers/s390/kvm/Makefile
@@ -6,4 +6,4 @@
6# it under the terms of the GNU General Public License (version 2 only) 6# it under the terms of the GNU General Public License (version 2 only)
7# as published by the Free Software Foundation. 7# as published by the Free Software Foundation.
8 8
9obj-$(CONFIG_S390_GUEST) += kvm_virtio.o 9obj-$(CONFIG_S390_GUEST) += kvm_virtio.o virtio_ccw.o
diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c
new file mode 100644
index 000000000000..1a5aff31d752
--- /dev/null
+++ b/drivers/s390/kvm/virtio_ccw.c
@@ -0,0 +1,853 @@
1/*
2 * ccw based virtio transport
3 *
4 * Copyright IBM Corp. 2012
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only)
8 * as published by the Free Software Foundation.
9 *
10 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
11 */
12
13#include <linux/kernel_stat.h>
14#include <linux/init.h>
15#include <linux/bootmem.h>
16#include <linux/err.h>
17#include <linux/virtio.h>
18#include <linux/virtio_config.h>
19#include <linux/slab.h>
20#include <linux/interrupt.h>
21#include <linux/virtio_ring.h>
22#include <linux/pfn.h>
23#include <linux/async.h>
24#include <linux/wait.h>
25#include <linux/list.h>
26#include <linux/bitops.h>
27#include <linux/module.h>
28#include <linux/io.h>
29#include <linux/kvm_para.h>
30#include <asm/setup.h>
31#include <asm/irq.h>
32#include <asm/cio.h>
33#include <asm/ccwdev.h>
34
35/*
36 * virtio related functions
37 */
38
39struct vq_config_block {
40 __u16 index;
41 __u16 num;
42} __packed;
43
44#define VIRTIO_CCW_CONFIG_SIZE 0x100
45/* same as PCI config space size, should be enough for all drivers */
46
47struct virtio_ccw_device {
48 struct virtio_device vdev;
49 __u8 status;
50 __u8 config[VIRTIO_CCW_CONFIG_SIZE];
51 struct ccw_device *cdev;
52 struct ccw1 *ccw;
53 __u32 area;
54 __u32 curr_io;
55 int err;
56 wait_queue_head_t wait_q;
57 spinlock_t lock;
58 struct list_head virtqueues;
59 unsigned long indicators;
60 unsigned long indicators2;
61 struct vq_config_block *config_block;
62};
63
64struct vq_info_block {
65 __u64 queue;
66 __u32 align;
67 __u16 index;
68 __u16 num;
69} __packed;
70
71struct virtio_feature_desc {
72 __u32 features;
73 __u8 index;
74} __packed;
75
76struct virtio_ccw_vq_info {
77 struct virtqueue *vq;
78 int num;
79 void *queue;
80 struct vq_info_block *info_block;
81 struct list_head node;
82};
83
84#define KVM_VIRTIO_CCW_RING_ALIGN 4096
85
86#define KVM_S390_VIRTIO_CCW_NOTIFY 3
87
88#define CCW_CMD_SET_VQ 0x13
89#define CCW_CMD_VDEV_RESET 0x33
90#define CCW_CMD_SET_IND 0x43
91#define CCW_CMD_SET_CONF_IND 0x53
92#define CCW_CMD_READ_FEAT 0x12
93#define CCW_CMD_WRITE_FEAT 0x11
94#define CCW_CMD_READ_CONF 0x22
95#define CCW_CMD_WRITE_CONF 0x21
96#define CCW_CMD_WRITE_STATUS 0x31
97#define CCW_CMD_READ_VQ_CONF 0x32
98
99#define VIRTIO_CCW_DOING_SET_VQ 0x00010000
100#define VIRTIO_CCW_DOING_RESET 0x00040000
101#define VIRTIO_CCW_DOING_READ_FEAT 0x00080000
102#define VIRTIO_CCW_DOING_WRITE_FEAT 0x00100000
103#define VIRTIO_CCW_DOING_READ_CONFIG 0x00200000
104#define VIRTIO_CCW_DOING_WRITE_CONFIG 0x00400000
105#define VIRTIO_CCW_DOING_WRITE_STATUS 0x00800000
106#define VIRTIO_CCW_DOING_SET_IND 0x01000000
107#define VIRTIO_CCW_DOING_READ_VQ_CONF 0x02000000
108#define VIRTIO_CCW_DOING_SET_CONF_IND 0x04000000
109#define VIRTIO_CCW_INTPARM_MASK 0xffff0000
110
111static struct virtio_ccw_device *to_vc_device(struct virtio_device *vdev)
112{
113 return container_of(vdev, struct virtio_ccw_device, vdev);
114}
115
116static int doing_io(struct virtio_ccw_device *vcdev, __u32 flag)
117{
118 unsigned long flags;
119 __u32 ret;
120
121 spin_lock_irqsave(get_ccwdev_lock(vcdev->cdev), flags);
122 if (vcdev->err)
123 ret = 0;
124 else
125 ret = vcdev->curr_io & flag;
126 spin_unlock_irqrestore(get_ccwdev_lock(vcdev->cdev), flags);
127 return ret;
128}
129
130static int ccw_io_helper(struct virtio_ccw_device *vcdev, __u32 intparm)
131{
132 int ret;
133 unsigned long flags;
134 int flag = intparm & VIRTIO_CCW_INTPARM_MASK;
135
136 spin_lock_irqsave(get_ccwdev_lock(vcdev->cdev), flags);
137 ret = ccw_device_start(vcdev->cdev, vcdev->ccw, intparm, 0, 0);
138 if (!ret)
139 vcdev->curr_io |= flag;
140 spin_unlock_irqrestore(get_ccwdev_lock(vcdev->cdev), flags);
141 wait_event(vcdev->wait_q, doing_io(vcdev, flag) == 0);
142 return ret ? ret : vcdev->err;
143}
144
145static inline long do_kvm_notify(struct subchannel_id schid,
146 unsigned long queue_index)
147{
148 register unsigned long __nr asm("1") = KVM_S390_VIRTIO_CCW_NOTIFY;
149 register struct subchannel_id __schid asm("2") = schid;
150 register unsigned long __index asm("3") = queue_index;
151 register long __rc asm("2");
152
153 asm volatile ("diag 2,4,0x500\n"
154 : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index)
155 : "memory", "cc");
156 return __rc;
157}
158
159static void virtio_ccw_kvm_notify(struct virtqueue *vq)
160{
161 struct virtio_ccw_vq_info *info = vq->priv;
162 struct virtio_ccw_device *vcdev;
163 struct subchannel_id schid;
164
165 vcdev = to_vc_device(info->vq->vdev);
166 ccw_device_get_schid(vcdev->cdev, &schid);
167 do_kvm_notify(schid, virtqueue_get_queue_index(vq));
168}
169
170static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev, int index)
171{
172 vcdev->config_block->index = index;
173 vcdev->ccw->cmd_code = CCW_CMD_READ_VQ_CONF;
174 vcdev->ccw->flags = 0;
175 vcdev->ccw->count = sizeof(struct vq_config_block);
176 vcdev->ccw->cda = (__u32)(unsigned long)(vcdev->config_block);
177 ccw_io_helper(vcdev, VIRTIO_CCW_DOING_READ_VQ_CONF);
178 return vcdev->config_block->num;
179}
180
181static void virtio_ccw_del_vq(struct virtqueue *vq)
182{
183 struct virtio_ccw_device *vcdev = to_vc_device(vq->vdev);
184 struct virtio_ccw_vq_info *info = vq->priv;
185 unsigned long flags;
186 unsigned long size;
187 int ret;
188 unsigned int index = virtqueue_get_queue_index(vq);
189
190 /* Remove from our list. */
191 spin_lock_irqsave(&vcdev->lock, flags);
192 list_del(&info->node);
193 spin_unlock_irqrestore(&vcdev->lock, flags);
194
195 /* Release from host. */
196 info->info_block->queue = 0;
197 info->info_block->align = 0;
198 info->info_block->index = index;
199 info->info_block->num = 0;
200 vcdev->ccw->cmd_code = CCW_CMD_SET_VQ;
201 vcdev->ccw->flags = 0;
202 vcdev->ccw->count = sizeof(*info->info_block);
203 vcdev->ccw->cda = (__u32)(unsigned long)(info->info_block);
204 ret = ccw_io_helper(vcdev, VIRTIO_CCW_DOING_SET_VQ | index);
205 /*
206 * -ENODEV isn't considered an error: The device is gone anyway.
207 * This may happen on device detach.
208 */
209 if (ret && (ret != -ENODEV))
210 dev_warn(&vq->vdev->dev, "Error %d while deleting queue %d",
211 ret, index);
212
213 vring_del_virtqueue(vq);
214 size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN));
215 free_pages_exact(info->queue, size);
216 kfree(info->info_block);
217 kfree(info);
218}
219
220static void virtio_ccw_del_vqs(struct virtio_device *vdev)
221{
222 struct virtqueue *vq, *n;
223
224 list_for_each_entry_safe(vq, n, &vdev->vqs, list)
225 virtio_ccw_del_vq(vq);
226}
227
228static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
229 int i, vq_callback_t *callback,
230 const char *name)
231{
232 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
233 int err;
234 struct virtqueue *vq;
235 struct virtio_ccw_vq_info *info;
236 unsigned long size;
237 unsigned long flags;
238
239 /* Allocate queue. */
240 info = kzalloc(sizeof(struct virtio_ccw_vq_info), GFP_KERNEL);
241 if (!info) {
242 dev_warn(&vcdev->cdev->dev, "no info\n");
243 err = -ENOMEM;
244 goto out_err;
245 }
246 info->info_block = kzalloc(sizeof(*info->info_block),
247 GFP_DMA | GFP_KERNEL);
248 if (!info->info_block) {
249 dev_warn(&vcdev->cdev->dev, "no info block\n");
250 err = -ENOMEM;
251 goto out_err;
252 }
253 info->num = virtio_ccw_read_vq_conf(vcdev, i);
254 size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN));
255 info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
256 if (info->queue == NULL) {
257 dev_warn(&vcdev->cdev->dev, "no queue\n");
258 err = -ENOMEM;
259 goto out_err;
260 }
261
262 vq = vring_new_virtqueue(i, info->num, KVM_VIRTIO_CCW_RING_ALIGN, vdev,
263 true, info->queue, virtio_ccw_kvm_notify,
264 callback, name);
265 if (!vq) {
266 /* For now, we fail if we can't get the requested size. */
267 dev_warn(&vcdev->cdev->dev, "no vq\n");
268 err = -ENOMEM;
269 free_pages_exact(info->queue, size);
270 goto out_err;
271 }
272 info->vq = vq;
273 vq->priv = info;
274
275 /* Register it with the host. */
276 info->info_block->queue = (__u64)info->queue;
277 info->info_block->align = KVM_VIRTIO_CCW_RING_ALIGN;
278 info->info_block->index = i;
279 info->info_block->num = info->num;
280 vcdev->ccw->cmd_code = CCW_CMD_SET_VQ;
281 vcdev->ccw->flags = 0;
282 vcdev->ccw->count = sizeof(*info->info_block);
283 vcdev->ccw->cda = (__u32)(unsigned long)(info->info_block);
284 err = ccw_io_helper(vcdev, VIRTIO_CCW_DOING_SET_VQ | i);
285 if (err) {
286 dev_warn(&vcdev->cdev->dev, "SET_VQ failed\n");
287 free_pages_exact(info->queue, size);
288 info->vq = NULL;
289 vq->priv = NULL;
290 goto out_err;
291 }
292
293 /* Save it to our list. */
294 spin_lock_irqsave(&vcdev->lock, flags);
295 list_add(&info->node, &vcdev->virtqueues);
296 spin_unlock_irqrestore(&vcdev->lock, flags);
297
298 return vq;
299
300out_err:
301 if (info)
302 kfree(info->info_block);
303 kfree(info);
304 return ERR_PTR(err);
305}
306
307static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs,
308 struct virtqueue *vqs[],
309 vq_callback_t *callbacks[],
310 const char *names[])
311{
312 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
313 unsigned long *indicatorp = NULL;
314 int ret, i;
315
316 for (i = 0; i < nvqs; ++i) {
317 vqs[i] = virtio_ccw_setup_vq(vdev, i, callbacks[i], names[i]);
318 if (IS_ERR(vqs[i])) {
319 ret = PTR_ERR(vqs[i]);
320 vqs[i] = NULL;
321 goto out;
322 }
323 }
324 ret = -ENOMEM;
325 /* We need a data area under 2G to communicate. */
326 indicatorp = kmalloc(sizeof(&vcdev->indicators), GFP_DMA | GFP_KERNEL);
327 if (!indicatorp)
328 goto out;
329 *indicatorp = (unsigned long) &vcdev->indicators;
330 /* Register queue indicators with host. */
331 vcdev->indicators = 0;
332 vcdev->ccw->cmd_code = CCW_CMD_SET_IND;
333 vcdev->ccw->flags = 0;
334 vcdev->ccw->count = sizeof(vcdev->indicators);
335 vcdev->ccw->cda = (__u32)(unsigned long) indicatorp;
336 ret = ccw_io_helper(vcdev, VIRTIO_CCW_DOING_SET_IND);
337 if (ret)
338 goto out;
339 /* Register indicators2 with host for config changes */
340 *indicatorp = (unsigned long) &vcdev->indicators2;
341 vcdev->indicators2 = 0;
342 vcdev->ccw->cmd_code = CCW_CMD_SET_CONF_IND;
343 vcdev->ccw->flags = 0;
344 vcdev->ccw->count = sizeof(vcdev->indicators2);
345 vcdev->ccw->cda = (__u32)(unsigned long) indicatorp;
346 ret = ccw_io_helper(vcdev, VIRTIO_CCW_DOING_SET_CONF_IND);
347 if (ret)
348 goto out;
349
350 kfree(indicatorp);
351 return 0;
352out:
353 kfree(indicatorp);
354 virtio_ccw_del_vqs(vdev);
355 return ret;
356}
357
358static void virtio_ccw_reset(struct virtio_device *vdev)
359{
360 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
361
362 /* Zero status bits. */
363 vcdev->status = 0;
364
365 /* Send a reset ccw on device. */
366 vcdev->ccw->cmd_code = CCW_CMD_VDEV_RESET;
367 vcdev->ccw->flags = 0;
368 vcdev->ccw->count = 0;
369 vcdev->ccw->cda = 0;
370 ccw_io_helper(vcdev, VIRTIO_CCW_DOING_RESET);
371}
372
373static u32 virtio_ccw_get_features(struct virtio_device *vdev)
374{
375 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
376 struct virtio_feature_desc features;
377 int ret;
378
379 /* Read the feature bits from the host. */
380 /* TODO: Features > 32 bits */
381 features.index = 0;
382 vcdev->ccw->cmd_code = CCW_CMD_READ_FEAT;
383 vcdev->ccw->flags = 0;
384 vcdev->ccw->count = sizeof(features);
385 vcdev->ccw->cda = vcdev->area;
386 ret = ccw_io_helper(vcdev, VIRTIO_CCW_DOING_READ_FEAT);
387 if (ret)
388 return 0;
389
390 memcpy(&features, (void *)(unsigned long)vcdev->area,
391 sizeof(features));
392 return le32_to_cpu(features.features);
393}
394
395static void virtio_ccw_finalize_features(struct virtio_device *vdev)
396{
397 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
398 struct virtio_feature_desc features;
399 int i;
400
401 /* Give virtio_ring a chance to accept features. */
402 vring_transport_features(vdev);
403
404 for (i = 0; i < sizeof(*vdev->features) / sizeof(features.features);
405 i++) {
406 int highbits = i % 2 ? 32 : 0;
407 features.index = i;
408 features.features = cpu_to_le32(vdev->features[i / 2]
409 >> highbits);
410 memcpy((void *)(unsigned long)vcdev->area, &features,
411 sizeof(features));
412 /* Write the feature bits to the host. */
413 vcdev->ccw->cmd_code = CCW_CMD_WRITE_FEAT;
414 vcdev->ccw->flags = 0;
415 vcdev->ccw->count = sizeof(features);
416 vcdev->ccw->cda = vcdev->area;
417 ccw_io_helper(vcdev, VIRTIO_CCW_DOING_WRITE_FEAT);
418 }
419}
420
421static void virtio_ccw_get_config(struct virtio_device *vdev,
422 unsigned int offset, void *buf, unsigned len)
423{
424 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
425 int ret;
426
427 /* Read the config area from the host. */
428 vcdev->ccw->cmd_code = CCW_CMD_READ_CONF;
429 vcdev->ccw->flags = 0;
430 vcdev->ccw->count = offset + len;
431 vcdev->ccw->cda = vcdev->area;
432 ret = ccw_io_helper(vcdev, VIRTIO_CCW_DOING_READ_CONFIG);
433 if (ret)
434 return;
435
436 memcpy(vcdev->config, (void *)(unsigned long)vcdev->area,
437 sizeof(vcdev->config));
438 memcpy(buf, &vcdev->config[offset], len);
439}
440
441static void virtio_ccw_set_config(struct virtio_device *vdev,
442 unsigned int offset, const void *buf,
443 unsigned len)
444{
445 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
446
447 memcpy(&vcdev->config[offset], buf, len);
448 /* Write the config area to the host. */
449 memcpy((void *)(unsigned long)vcdev->area, vcdev->config,
450 sizeof(vcdev->config));
451 vcdev->ccw->cmd_code = CCW_CMD_WRITE_CONF;
452 vcdev->ccw->flags = 0;
453 vcdev->ccw->count = offset + len;
454 vcdev->ccw->cda = vcdev->area;
455 ccw_io_helper(vcdev, VIRTIO_CCW_DOING_WRITE_CONFIG);
456}
457
458static u8 virtio_ccw_get_status(struct virtio_device *vdev)
459{
460 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
461
462 return vcdev->status;
463}
464
465static void virtio_ccw_set_status(struct virtio_device *vdev, u8 status)
466{
467 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
468
469 /* Write the status to the host. */
470 vcdev->status = status;
471 memcpy((void *)(unsigned long)vcdev->area, &status, sizeof(status));
472 vcdev->ccw->cmd_code = CCW_CMD_WRITE_STATUS;
473 vcdev->ccw->flags = 0;
474 vcdev->ccw->count = sizeof(status);
475 vcdev->ccw->cda = vcdev->area;
476 ccw_io_helper(vcdev, VIRTIO_CCW_DOING_WRITE_STATUS);
477}
478
479static struct virtio_config_ops virtio_ccw_config_ops = {
480 .get_features = virtio_ccw_get_features,
481 .finalize_features = virtio_ccw_finalize_features,
482 .get = virtio_ccw_get_config,
483 .set = virtio_ccw_set_config,
484 .get_status = virtio_ccw_get_status,
485 .set_status = virtio_ccw_set_status,
486 .reset = virtio_ccw_reset,
487 .find_vqs = virtio_ccw_find_vqs,
488 .del_vqs = virtio_ccw_del_vqs,
489};
490
491
492/*
493 * ccw bus driver related functions
494 */
495
496static void virtio_ccw_release_dev(struct device *_d)
497{
498 struct virtio_device *dev = container_of(_d, struct virtio_device,
499 dev);
500 struct virtio_ccw_device *vcdev = to_vc_device(dev);
501
502 kfree((void *)(unsigned long)vcdev->area);
503 kfree(vcdev->config_block);
504 kfree(vcdev->ccw);
505 kfree(vcdev);
506}
507
508static int irb_is_error(struct irb *irb)
509{
510 if (scsw_cstat(&irb->scsw) != 0)
511 return 1;
512 if (scsw_dstat(&irb->scsw) & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END))
513 return 1;
514 if (scsw_cc(&irb->scsw) != 0)
515 return 1;
516 return 0;
517}
518
519static struct virtqueue *virtio_ccw_vq_by_ind(struct virtio_ccw_device *vcdev,
520 int index)
521{
522 struct virtio_ccw_vq_info *info;
523 unsigned long flags;
524 struct virtqueue *vq;
525
526 vq = NULL;
527 spin_lock_irqsave(&vcdev->lock, flags);
528 list_for_each_entry(info, &vcdev->virtqueues, node) {
529 if (virtqueue_get_queue_index(info->vq) == index) {
530 vq = info->vq;
531 break;
532 }
533 }
534 spin_unlock_irqrestore(&vcdev->lock, flags);
535 return vq;
536}
537
538static void virtio_ccw_int_handler(struct ccw_device *cdev,
539 unsigned long intparm,
540 struct irb *irb)
541{
542 __u32 activity = intparm & VIRTIO_CCW_INTPARM_MASK;
543 struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev);
544 int i;
545 struct virtqueue *vq;
546 struct virtio_driver *drv;
547
548 /* Check if it's a notification from the host. */
549 if ((intparm == 0) &&
550 (scsw_stctl(&irb->scsw) ==
551 (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND))) {
552 /* OK */
553 }
554 if (irb_is_error(irb))
555 vcdev->err = -EIO; /* XXX - use real error */
556 if (vcdev->curr_io & activity) {
557 switch (activity) {
558 case VIRTIO_CCW_DOING_READ_FEAT:
559 case VIRTIO_CCW_DOING_WRITE_FEAT:
560 case VIRTIO_CCW_DOING_READ_CONFIG:
561 case VIRTIO_CCW_DOING_WRITE_CONFIG:
562 case VIRTIO_CCW_DOING_WRITE_STATUS:
563 case VIRTIO_CCW_DOING_SET_VQ:
564 case VIRTIO_CCW_DOING_SET_IND:
565 case VIRTIO_CCW_DOING_SET_CONF_IND:
566 case VIRTIO_CCW_DOING_RESET:
567 case VIRTIO_CCW_DOING_READ_VQ_CONF:
568 vcdev->curr_io &= ~activity;
569 wake_up(&vcdev->wait_q);
570 break;
571 default:
572 /* don't know what to do... */
573 dev_warn(&cdev->dev, "Suspicious activity '%08x'\n",
574 activity);
575 WARN_ON(1);
576 break;
577 }
578 }
579 for_each_set_bit(i, &vcdev->indicators,
580 sizeof(vcdev->indicators) * BITS_PER_BYTE) {
581 /* The bit clear must happen before the vring kick. */
582 clear_bit(i, &vcdev->indicators);
583 barrier();
584 vq = virtio_ccw_vq_by_ind(vcdev, i);
585 vring_interrupt(0, vq);
586 }
587 if (test_bit(0, &vcdev->indicators2)) {
588 drv = container_of(vcdev->vdev.dev.driver,
589 struct virtio_driver, driver);
590
591 if (drv && drv->config_changed)
592 drv->config_changed(&vcdev->vdev);
593 clear_bit(0, &vcdev->indicators2);
594 }
595}
596
597/*
598 * We usually want to autoonline all devices, but give the admin
599 * a way to exempt devices from this.
600 */
601#define __DEV_WORDS ((__MAX_SUBCHANNEL + (8*sizeof(long) - 1)) / \
602 (8*sizeof(long)))
603static unsigned long devs_no_auto[__MAX_SSID + 1][__DEV_WORDS];
604
605static char *no_auto = "";
606
607module_param(no_auto, charp, 0444);
608MODULE_PARM_DESC(no_auto, "list of ccw bus id ranges not to be auto-onlined");
609
610static int virtio_ccw_check_autoonline(struct ccw_device *cdev)
611{
612 struct ccw_dev_id id;
613
614 ccw_device_get_id(cdev, &id);
615 if (test_bit(id.devno, devs_no_auto[id.ssid]))
616 return 0;
617 return 1;
618}
619
620static void virtio_ccw_auto_online(void *data, async_cookie_t cookie)
621{
622 struct ccw_device *cdev = data;
623 int ret;
624
625 ret = ccw_device_set_online(cdev);
626 if (ret)
627 dev_warn(&cdev->dev, "Failed to set online: %d\n", ret);
628}
629
630static int virtio_ccw_probe(struct ccw_device *cdev)
631{
632 cdev->handler = virtio_ccw_int_handler;
633
634 if (virtio_ccw_check_autoonline(cdev))
635 async_schedule(virtio_ccw_auto_online, cdev);
636 return 0;
637}
638
639static void virtio_ccw_remove(struct ccw_device *cdev)
640{
641 struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev);
642
643 if (cdev->online) {
644 unregister_virtio_device(&vcdev->vdev);
645 dev_set_drvdata(&cdev->dev, NULL);
646 }
647 cdev->handler = NULL;
648}
649
650static int virtio_ccw_offline(struct ccw_device *cdev)
651{
652 struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev);
653
654 unregister_virtio_device(&vcdev->vdev);
655 dev_set_drvdata(&cdev->dev, NULL);
656 return 0;
657}
658
659
660/* Area needs to be big enough to fit status, features or configuration. */
661#define VIRTIO_AREA_SIZE VIRTIO_CCW_CONFIG_SIZE /* biggest possible use */
662
663static int virtio_ccw_online(struct ccw_device *cdev)
664{
665 int ret;
666 struct virtio_ccw_device *vcdev;
667
668 vcdev = kzalloc(sizeof(*vcdev), GFP_KERNEL);
669 if (!vcdev) {
670 dev_warn(&cdev->dev, "Could not get memory for virtio\n");
671 ret = -ENOMEM;
672 goto out_free;
673 }
674 vcdev->area = (__u32)(unsigned long)kzalloc(VIRTIO_AREA_SIZE,
675 GFP_DMA | GFP_KERNEL);
676 if (!vcdev->area) {
677 dev_warn(&cdev->dev, "Cound not get memory for virtio\n");
678 ret = -ENOMEM;
679 goto out_free;
680 }
681 vcdev->config_block = kzalloc(sizeof(*vcdev->config_block),
682 GFP_DMA | GFP_KERNEL);
683 if (!vcdev->config_block) {
684 ret = -ENOMEM;
685 goto out_free;
686 }
687 vcdev->ccw = kzalloc(sizeof(*vcdev->ccw), GFP_DMA | GFP_KERNEL);
688 if (!vcdev->ccw) {
689 ret = -ENOMEM;
690 goto out_free;
691 }
692
693 vcdev->vdev.dev.parent = &cdev->dev;
694 vcdev->vdev.dev.release = virtio_ccw_release_dev;
695 vcdev->vdev.config = &virtio_ccw_config_ops;
696 vcdev->cdev = cdev;
697 init_waitqueue_head(&vcdev->wait_q);
698 INIT_LIST_HEAD(&vcdev->virtqueues);
699 spin_lock_init(&vcdev->lock);
700
701 dev_set_drvdata(&cdev->dev, vcdev);
702 vcdev->vdev.id.vendor = cdev->id.cu_type;
703 vcdev->vdev.id.device = cdev->id.cu_model;
704 ret = register_virtio_device(&vcdev->vdev);
705 if (ret) {
706 dev_warn(&cdev->dev, "Failed to register virtio device: %d\n",
707 ret);
708 goto out_put;
709 }
710 return 0;
711out_put:
712 dev_set_drvdata(&cdev->dev, NULL);
713 put_device(&vcdev->vdev.dev);
714 return ret;
715out_free:
716 if (vcdev) {
717 kfree((void *)(unsigned long)vcdev->area);
718 kfree(vcdev->config_block);
719 kfree(vcdev->ccw);
720 }
721 kfree(vcdev);
722 return ret;
723}
724
725static int virtio_ccw_cio_notify(struct ccw_device *cdev, int event)
726{
727 /* TODO: Check whether we need special handling here. */
728 return 0;
729}
730
731static struct ccw_device_id virtio_ids[] = {
732 { CCW_DEVICE(0x3832, 0) },
733 {},
734};
735MODULE_DEVICE_TABLE(ccw, virtio_ids);
736
737static struct ccw_driver virtio_ccw_driver = {
738 .driver = {
739 .owner = THIS_MODULE,
740 .name = "virtio_ccw",
741 },
742 .ids = virtio_ids,
743 .probe = virtio_ccw_probe,
744 .remove = virtio_ccw_remove,
745 .set_offline = virtio_ccw_offline,
746 .set_online = virtio_ccw_online,
747 .notify = virtio_ccw_cio_notify,
748 .int_class = IOINT_VIR,
749};
750
751static int __init pure_hex(char **cp, unsigned int *val, int min_digit,
752 int max_digit, int max_val)
753{
754 int diff;
755
756 diff = 0;
757 *val = 0;
758
759 while (diff <= max_digit) {
760 int value = hex_to_bin(**cp);
761
762 if (value < 0)
763 break;
764 *val = *val * 16 + value;
765 (*cp)++;
766 diff++;
767 }
768
769 if ((diff < min_digit) || (diff > max_digit) || (*val > max_val))
770 return 1;
771
772 return 0;
773}
774
775static int __init parse_busid(char *str, unsigned int *cssid,
776 unsigned int *ssid, unsigned int *devno)
777{
778 char *str_work;
779 int rc, ret;
780
781 rc = 1;
782
783 if (*str == '\0')
784 goto out;
785
786 str_work = str;
787 ret = pure_hex(&str_work, cssid, 1, 2, __MAX_CSSID);
788 if (ret || (str_work[0] != '.'))
789 goto out;
790 str_work++;
791 ret = pure_hex(&str_work, ssid, 1, 1, __MAX_SSID);
792 if (ret || (str_work[0] != '.'))
793 goto out;
794 str_work++;
795 ret = pure_hex(&str_work, devno, 4, 4, __MAX_SUBCHANNEL);
796 if (ret || (str_work[0] != '\0'))
797 goto out;
798
799 rc = 0;
800out:
801 return rc;
802}
803
804static void __init no_auto_parse(void)
805{
806 unsigned int from_cssid, to_cssid, from_ssid, to_ssid, from, to;
807 char *parm, *str;
808 int rc;
809
810 str = no_auto;
811 while ((parm = strsep(&str, ","))) {
812 rc = parse_busid(strsep(&parm, "-"), &from_cssid,
813 &from_ssid, &from);
814 if (rc)
815 continue;
816 if (parm != NULL) {
817 rc = parse_busid(parm, &to_cssid,
818 &to_ssid, &to);
819 if ((from_ssid > to_ssid) ||
820 ((from_ssid == to_ssid) && (from > to)))
821 rc = -EINVAL;
822 } else {
823 to_cssid = from_cssid;
824 to_ssid = from_ssid;
825 to = from;
826 }
827 if (rc)
828 continue;
829 while ((from_ssid < to_ssid) ||
830 ((from_ssid == to_ssid) && (from <= to))) {
831 set_bit(from, devs_no_auto[from_ssid]);
832 from++;
833 if (from > __MAX_SUBCHANNEL) {
834 from_ssid++;
835 from = 0;
836 }
837 }
838 }
839}
840
841static int __init virtio_ccw_init(void)
842{
843 /* parse no_auto string before we do anything further */
844 no_auto_parse();
845 return ccw_driver_register(&virtio_ccw_driver);
846}
847module_init(virtio_ccw_init);
848
849static void __exit virtio_ccw_exit(void)
850{
851 ccw_driver_unregister(&virtio_ccw_driver);
852}
853module_exit(virtio_ccw_exit);