blob: 42d507c4e06bdd2bd4cf8f50e81cee5c97f04ea8 [file] [log] [blame]
Cornelia Huck7e64e052012-12-14 17:02:18 +01001/*
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>
Cornelia Huck6a773cb2013-02-28 12:33:17 +010034#include <asm/virtio-ccw.h>
Cornelia Huck7e64e052012-12-14 17:02:18 +010035
36/*
37 * virtio related functions
38 */
39
40struct vq_config_block {
41 __u16 index;
42 __u16 num;
43} __packed;
44
45#define VIRTIO_CCW_CONFIG_SIZE 0x100
46/* same as PCI config space size, should be enough for all drivers */
47
48struct virtio_ccw_device {
49 struct virtio_device vdev;
Cornelia Huck73fa21e2013-01-07 15:51:51 +010050 __u8 *status;
Cornelia Huck7e64e052012-12-14 17:02:18 +010051 __u8 config[VIRTIO_CCW_CONFIG_SIZE];
52 struct ccw_device *cdev;
Cornelia Huck7e64e052012-12-14 17:02:18 +010053 __u32 curr_io;
54 int err;
55 wait_queue_head_t wait_q;
56 spinlock_t lock;
57 struct list_head virtqueues;
58 unsigned long indicators;
59 unsigned long indicators2;
60 struct vq_config_block *config_block;
61};
62
63struct vq_info_block {
64 __u64 queue;
65 __u32 align;
66 __u16 index;
67 __u16 num;
68} __packed;
69
70struct virtio_feature_desc {
71 __u32 features;
72 __u8 index;
73} __packed;
74
75struct virtio_ccw_vq_info {
76 struct virtqueue *vq;
77 int num;
78 void *queue;
79 struct vq_info_block *info_block;
80 struct list_head node;
Michael S. Tsirkin07e16932013-02-28 12:33:16 +010081 long cookie;
Cornelia Huck7e64e052012-12-14 17:02:18 +010082};
83
Cornelia Huck7e64e052012-12-14 17:02:18 +010084#define CCW_CMD_SET_VQ 0x13
85#define CCW_CMD_VDEV_RESET 0x33
86#define CCW_CMD_SET_IND 0x43
87#define CCW_CMD_SET_CONF_IND 0x53
88#define CCW_CMD_READ_FEAT 0x12
89#define CCW_CMD_WRITE_FEAT 0x11
90#define CCW_CMD_READ_CONF 0x22
91#define CCW_CMD_WRITE_CONF 0x21
92#define CCW_CMD_WRITE_STATUS 0x31
93#define CCW_CMD_READ_VQ_CONF 0x32
94
95#define VIRTIO_CCW_DOING_SET_VQ 0x00010000
96#define VIRTIO_CCW_DOING_RESET 0x00040000
97#define VIRTIO_CCW_DOING_READ_FEAT 0x00080000
98#define VIRTIO_CCW_DOING_WRITE_FEAT 0x00100000
99#define VIRTIO_CCW_DOING_READ_CONFIG 0x00200000
100#define VIRTIO_CCW_DOING_WRITE_CONFIG 0x00400000
101#define VIRTIO_CCW_DOING_WRITE_STATUS 0x00800000
102#define VIRTIO_CCW_DOING_SET_IND 0x01000000
103#define VIRTIO_CCW_DOING_READ_VQ_CONF 0x02000000
104#define VIRTIO_CCW_DOING_SET_CONF_IND 0x04000000
105#define VIRTIO_CCW_INTPARM_MASK 0xffff0000
106
107static struct virtio_ccw_device *to_vc_device(struct virtio_device *vdev)
108{
109 return container_of(vdev, struct virtio_ccw_device, vdev);
110}
111
112static int doing_io(struct virtio_ccw_device *vcdev, __u32 flag)
113{
114 unsigned long flags;
115 __u32 ret;
116
117 spin_lock_irqsave(get_ccwdev_lock(vcdev->cdev), flags);
118 if (vcdev->err)
119 ret = 0;
120 else
121 ret = vcdev->curr_io & flag;
122 spin_unlock_irqrestore(get_ccwdev_lock(vcdev->cdev), flags);
123 return ret;
124}
125
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100126static int ccw_io_helper(struct virtio_ccw_device *vcdev,
127 struct ccw1 *ccw, __u32 intparm)
Cornelia Huck7e64e052012-12-14 17:02:18 +0100128{
129 int ret;
130 unsigned long flags;
131 int flag = intparm & VIRTIO_CCW_INTPARM_MASK;
132
Christian Borntraegerb26ba222013-01-07 15:51:52 +0100133 do {
134 spin_lock_irqsave(get_ccwdev_lock(vcdev->cdev), flags);
135 ret = ccw_device_start(vcdev->cdev, ccw, intparm, 0, 0);
136 if (!ret)
137 vcdev->curr_io |= flag;
138 spin_unlock_irqrestore(get_ccwdev_lock(vcdev->cdev), flags);
139 cpu_relax();
140 } while (ret == -EBUSY);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100141 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,
Michael S. Tsirkin07e16932013-02-28 12:33:16 +0100146 unsigned long queue_index,
147 long cookie)
Cornelia Huck7e64e052012-12-14 17:02:18 +0100148{
149 register unsigned long __nr asm("1") = KVM_S390_VIRTIO_CCW_NOTIFY;
150 register struct subchannel_id __schid asm("2") = schid;
151 register unsigned long __index asm("3") = queue_index;
152 register long __rc asm("2");
Michael S. Tsirkin07e16932013-02-28 12:33:16 +0100153 register long __cookie asm("4") = cookie;
Cornelia Huck7e64e052012-12-14 17:02:18 +0100154
155 asm volatile ("diag 2,4,0x500\n"
Michael S. Tsirkin07e16932013-02-28 12:33:16 +0100156 : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index),
157 "d"(__cookie)
Cornelia Huck7e64e052012-12-14 17:02:18 +0100158 : "memory", "cc");
159 return __rc;
160}
161
162static void virtio_ccw_kvm_notify(struct virtqueue *vq)
163{
164 struct virtio_ccw_vq_info *info = vq->priv;
165 struct virtio_ccw_device *vcdev;
166 struct subchannel_id schid;
167
168 vcdev = to_vc_device(info->vq->vdev);
169 ccw_device_get_schid(vcdev->cdev, &schid);
Michael S. Tsirkin07e16932013-02-28 12:33:16 +0100170 info->cookie = do_kvm_notify(schid, virtqueue_get_queue_index(vq),
171 info->cookie);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100172}
173
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100174static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev,
175 struct ccw1 *ccw, int index)
Cornelia Huck7e64e052012-12-14 17:02:18 +0100176{
177 vcdev->config_block->index = index;
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100178 ccw->cmd_code = CCW_CMD_READ_VQ_CONF;
179 ccw->flags = 0;
180 ccw->count = sizeof(struct vq_config_block);
181 ccw->cda = (__u32)(unsigned long)(vcdev->config_block);
182 ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_VQ_CONF);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100183 return vcdev->config_block->num;
184}
185
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100186static void virtio_ccw_del_vq(struct virtqueue *vq, struct ccw1 *ccw)
Cornelia Huck7e64e052012-12-14 17:02:18 +0100187{
188 struct virtio_ccw_device *vcdev = to_vc_device(vq->vdev);
189 struct virtio_ccw_vq_info *info = vq->priv;
190 unsigned long flags;
191 unsigned long size;
192 int ret;
193 unsigned int index = virtqueue_get_queue_index(vq);
194
195 /* Remove from our list. */
196 spin_lock_irqsave(&vcdev->lock, flags);
197 list_del(&info->node);
198 spin_unlock_irqrestore(&vcdev->lock, flags);
199
200 /* Release from host. */
201 info->info_block->queue = 0;
202 info->info_block->align = 0;
203 info->info_block->index = index;
204 info->info_block->num = 0;
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100205 ccw->cmd_code = CCW_CMD_SET_VQ;
206 ccw->flags = 0;
207 ccw->count = sizeof(*info->info_block);
208 ccw->cda = (__u32)(unsigned long)(info->info_block);
209 ret = ccw_io_helper(vcdev, ccw,
210 VIRTIO_CCW_DOING_SET_VQ | index);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100211 /*
212 * -ENODEV isn't considered an error: The device is gone anyway.
213 * This may happen on device detach.
214 */
215 if (ret && (ret != -ENODEV))
216 dev_warn(&vq->vdev->dev, "Error %d while deleting queue %d",
217 ret, index);
218
219 vring_del_virtqueue(vq);
220 size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN));
221 free_pages_exact(info->queue, size);
222 kfree(info->info_block);
223 kfree(info);
224}
225
226static void virtio_ccw_del_vqs(struct virtio_device *vdev)
227{
228 struct virtqueue *vq, *n;
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100229 struct ccw1 *ccw;
230
231 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
232 if (!ccw)
233 return;
234
Cornelia Huck7e64e052012-12-14 17:02:18 +0100235
236 list_for_each_entry_safe(vq, n, &vdev->vqs, list)
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100237 virtio_ccw_del_vq(vq, ccw);
238
239 kfree(ccw);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100240}
241
242static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
243 int i, vq_callback_t *callback,
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100244 const char *name,
245 struct ccw1 *ccw)
Cornelia Huck7e64e052012-12-14 17:02:18 +0100246{
247 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
248 int err;
Cornelia Huckc98d3682013-01-25 15:34:16 +0100249 struct virtqueue *vq = NULL;
Cornelia Huck7e64e052012-12-14 17:02:18 +0100250 struct virtio_ccw_vq_info *info;
Cornelia Huckc98d3682013-01-25 15:34:16 +0100251 unsigned long size = 0; /* silence the compiler */
Cornelia Huck7e64e052012-12-14 17:02:18 +0100252 unsigned long flags;
253
254 /* Allocate queue. */
255 info = kzalloc(sizeof(struct virtio_ccw_vq_info), GFP_KERNEL);
256 if (!info) {
257 dev_warn(&vcdev->cdev->dev, "no info\n");
258 err = -ENOMEM;
259 goto out_err;
260 }
261 info->info_block = kzalloc(sizeof(*info->info_block),
262 GFP_DMA | GFP_KERNEL);
263 if (!info->info_block) {
264 dev_warn(&vcdev->cdev->dev, "no info block\n");
265 err = -ENOMEM;
266 goto out_err;
267 }
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100268 info->num = virtio_ccw_read_vq_conf(vcdev, ccw, i);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100269 size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN));
270 info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
271 if (info->queue == NULL) {
272 dev_warn(&vcdev->cdev->dev, "no queue\n");
273 err = -ENOMEM;
274 goto out_err;
275 }
276
277 vq = vring_new_virtqueue(i, info->num, KVM_VIRTIO_CCW_RING_ALIGN, vdev,
278 true, info->queue, virtio_ccw_kvm_notify,
279 callback, name);
280 if (!vq) {
281 /* For now, we fail if we can't get the requested size. */
282 dev_warn(&vcdev->cdev->dev, "no vq\n");
283 err = -ENOMEM;
Cornelia Huck7e64e052012-12-14 17:02:18 +0100284 goto out_err;
285 }
Cornelia Huck7e64e052012-12-14 17:02:18 +0100286
287 /* Register it with the host. */
288 info->info_block->queue = (__u64)info->queue;
289 info->info_block->align = KVM_VIRTIO_CCW_RING_ALIGN;
290 info->info_block->index = i;
291 info->info_block->num = info->num;
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100292 ccw->cmd_code = CCW_CMD_SET_VQ;
293 ccw->flags = 0;
294 ccw->count = sizeof(*info->info_block);
295 ccw->cda = (__u32)(unsigned long)(info->info_block);
296 err = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_SET_VQ | i);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100297 if (err) {
298 dev_warn(&vcdev->cdev->dev, "SET_VQ failed\n");
Cornelia Huck7e64e052012-12-14 17:02:18 +0100299 goto out_err;
300 }
301
Cornelia Huckc98d3682013-01-25 15:34:16 +0100302 info->vq = vq;
303 vq->priv = info;
304
Cornelia Huck7e64e052012-12-14 17:02:18 +0100305 /* Save it to our list. */
306 spin_lock_irqsave(&vcdev->lock, flags);
307 list_add(&info->node, &vcdev->virtqueues);
308 spin_unlock_irqrestore(&vcdev->lock, flags);
309
310 return vq;
311
312out_err:
Cornelia Huckc98d3682013-01-25 15:34:16 +0100313 if (vq)
314 vring_del_virtqueue(vq);
315 if (info) {
316 if (info->queue)
317 free_pages_exact(info->queue, size);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100318 kfree(info->info_block);
Cornelia Huckc98d3682013-01-25 15:34:16 +0100319 }
Cornelia Huck7e64e052012-12-14 17:02:18 +0100320 kfree(info);
321 return ERR_PTR(err);
322}
323
324static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs,
325 struct virtqueue *vqs[],
326 vq_callback_t *callbacks[],
327 const char *names[])
328{
329 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
330 unsigned long *indicatorp = NULL;
331 int ret, i;
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100332 struct ccw1 *ccw;
333
334 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
335 if (!ccw)
336 return -ENOMEM;
Cornelia Huck7e64e052012-12-14 17:02:18 +0100337
338 for (i = 0; i < nvqs; ++i) {
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100339 vqs[i] = virtio_ccw_setup_vq(vdev, i, callbacks[i], names[i],
340 ccw);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100341 if (IS_ERR(vqs[i])) {
342 ret = PTR_ERR(vqs[i]);
343 vqs[i] = NULL;
344 goto out;
345 }
346 }
347 ret = -ENOMEM;
348 /* We need a data area under 2G to communicate. */
349 indicatorp = kmalloc(sizeof(&vcdev->indicators), GFP_DMA | GFP_KERNEL);
350 if (!indicatorp)
351 goto out;
352 *indicatorp = (unsigned long) &vcdev->indicators;
353 /* Register queue indicators with host. */
354 vcdev->indicators = 0;
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100355 ccw->cmd_code = CCW_CMD_SET_IND;
356 ccw->flags = 0;
357 ccw->count = sizeof(vcdev->indicators);
358 ccw->cda = (__u32)(unsigned long) indicatorp;
359 ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_SET_IND);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100360 if (ret)
361 goto out;
362 /* Register indicators2 with host for config changes */
363 *indicatorp = (unsigned long) &vcdev->indicators2;
364 vcdev->indicators2 = 0;
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100365 ccw->cmd_code = CCW_CMD_SET_CONF_IND;
366 ccw->flags = 0;
367 ccw->count = sizeof(vcdev->indicators2);
368 ccw->cda = (__u32)(unsigned long) indicatorp;
369 ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_SET_CONF_IND);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100370 if (ret)
371 goto out;
372
373 kfree(indicatorp);
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100374 kfree(ccw);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100375 return 0;
376out:
377 kfree(indicatorp);
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100378 kfree(ccw);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100379 virtio_ccw_del_vqs(vdev);
380 return ret;
381}
382
383static void virtio_ccw_reset(struct virtio_device *vdev)
384{
385 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100386 struct ccw1 *ccw;
387
388 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
389 if (!ccw)
390 return;
Cornelia Huck7e64e052012-12-14 17:02:18 +0100391
392 /* Zero status bits. */
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100393 *vcdev->status = 0;
Cornelia Huck7e64e052012-12-14 17:02:18 +0100394
395 /* Send a reset ccw on device. */
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100396 ccw->cmd_code = CCW_CMD_VDEV_RESET;
397 ccw->flags = 0;
398 ccw->count = 0;
399 ccw->cda = 0;
400 ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_RESET);
401 kfree(ccw);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100402}
403
404static u32 virtio_ccw_get_features(struct virtio_device *vdev)
405{
406 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100407 struct virtio_feature_desc *features;
408 int ret, rc;
409 struct ccw1 *ccw;
Cornelia Huck7e64e052012-12-14 17:02:18 +0100410
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100411 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
412 if (!ccw)
Cornelia Huck7e64e052012-12-14 17:02:18 +0100413 return 0;
414
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100415 features = kzalloc(sizeof(*features), GFP_DMA | GFP_KERNEL);
416 if (!features) {
417 rc = 0;
418 goto out_free;
419 }
420 /* Read the feature bits from the host. */
421 /* TODO: Features > 32 bits */
422 features->index = 0;
423 ccw->cmd_code = CCW_CMD_READ_FEAT;
424 ccw->flags = 0;
425 ccw->count = sizeof(*features);
426 ccw->cda = (__u32)(unsigned long)features;
427 ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_FEAT);
428 if (ret) {
429 rc = 0;
430 goto out_free;
431 }
432
433 rc = le32_to_cpu(features->features);
434
435out_free:
436 kfree(features);
437 kfree(ccw);
438 return rc;
Cornelia Huck7e64e052012-12-14 17:02:18 +0100439}
440
441static void virtio_ccw_finalize_features(struct virtio_device *vdev)
442{
443 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100444 struct virtio_feature_desc *features;
Cornelia Huck7e64e052012-12-14 17:02:18 +0100445 int i;
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100446 struct ccw1 *ccw;
447
448 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
449 if (!ccw)
450 return;
451
452 features = kzalloc(sizeof(*features), GFP_DMA | GFP_KERNEL);
453 if (!features)
454 goto out_free;
Cornelia Huck7e64e052012-12-14 17:02:18 +0100455
456 /* Give virtio_ring a chance to accept features. */
457 vring_transport_features(vdev);
458
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100459 for (i = 0; i < sizeof(*vdev->features) / sizeof(features->features);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100460 i++) {
461 int highbits = i % 2 ? 32 : 0;
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100462 features->index = i;
463 features->features = cpu_to_le32(vdev->features[i / 2]
464 >> highbits);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100465 /* Write the feature bits to the host. */
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100466 ccw->cmd_code = CCW_CMD_WRITE_FEAT;
467 ccw->flags = 0;
468 ccw->count = sizeof(*features);
469 ccw->cda = (__u32)(unsigned long)features;
470 ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_FEAT);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100471 }
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100472out_free:
473 kfree(features);
474 kfree(ccw);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100475}
476
477static void virtio_ccw_get_config(struct virtio_device *vdev,
478 unsigned int offset, void *buf, unsigned len)
479{
480 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
481 int ret;
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100482 struct ccw1 *ccw;
483 void *config_area;
Cornelia Huck7e64e052012-12-14 17:02:18 +0100484
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100485 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
486 if (!ccw)
Cornelia Huck7e64e052012-12-14 17:02:18 +0100487 return;
488
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100489 config_area = kzalloc(VIRTIO_CCW_CONFIG_SIZE, GFP_DMA | GFP_KERNEL);
490 if (!config_area)
491 goto out_free;
492
493 /* Read the config area from the host. */
494 ccw->cmd_code = CCW_CMD_READ_CONF;
495 ccw->flags = 0;
496 ccw->count = offset + len;
497 ccw->cda = (__u32)(unsigned long)config_area;
498 ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_CONFIG);
499 if (ret)
500 goto out_free;
501
502 memcpy(vcdev->config, config_area, sizeof(vcdev->config));
Cornelia Huck7e64e052012-12-14 17:02:18 +0100503 memcpy(buf, &vcdev->config[offset], len);
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100504
505out_free:
506 kfree(config_area);
507 kfree(ccw);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100508}
509
510static void virtio_ccw_set_config(struct virtio_device *vdev,
511 unsigned int offset, const void *buf,
512 unsigned len)
513{
514 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100515 struct ccw1 *ccw;
516 void *config_area;
517
518 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
519 if (!ccw)
520 return;
521
522 config_area = kzalloc(VIRTIO_CCW_CONFIG_SIZE, GFP_DMA | GFP_KERNEL);
523 if (!config_area)
524 goto out_free;
Cornelia Huck7e64e052012-12-14 17:02:18 +0100525
526 memcpy(&vcdev->config[offset], buf, len);
527 /* Write the config area to the host. */
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100528 memcpy(config_area, vcdev->config, sizeof(vcdev->config));
529 ccw->cmd_code = CCW_CMD_WRITE_CONF;
530 ccw->flags = 0;
531 ccw->count = offset + len;
532 ccw->cda = (__u32)(unsigned long)config_area;
533 ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_CONFIG);
534
535out_free:
536 kfree(config_area);
537 kfree(ccw);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100538}
539
540static u8 virtio_ccw_get_status(struct virtio_device *vdev)
541{
542 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
543
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100544 return *vcdev->status;
Cornelia Huck7e64e052012-12-14 17:02:18 +0100545}
546
547static void virtio_ccw_set_status(struct virtio_device *vdev, u8 status)
548{
549 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100550 struct ccw1 *ccw;
551
552 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
553 if (!ccw)
554 return;
Cornelia Huck7e64e052012-12-14 17:02:18 +0100555
556 /* Write the status to the host. */
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100557 *vcdev->status = status;
558 ccw->cmd_code = CCW_CMD_WRITE_STATUS;
559 ccw->flags = 0;
560 ccw->count = sizeof(status);
561 ccw->cda = (__u32)(unsigned long)vcdev->status;
562 ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_STATUS);
563 kfree(ccw);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100564}
565
566static struct virtio_config_ops virtio_ccw_config_ops = {
567 .get_features = virtio_ccw_get_features,
568 .finalize_features = virtio_ccw_finalize_features,
569 .get = virtio_ccw_get_config,
570 .set = virtio_ccw_set_config,
571 .get_status = virtio_ccw_get_status,
572 .set_status = virtio_ccw_set_status,
573 .reset = virtio_ccw_reset,
574 .find_vqs = virtio_ccw_find_vqs,
575 .del_vqs = virtio_ccw_del_vqs,
576};
577
578
579/*
580 * ccw bus driver related functions
581 */
582
583static void virtio_ccw_release_dev(struct device *_d)
584{
585 struct virtio_device *dev = container_of(_d, struct virtio_device,
586 dev);
587 struct virtio_ccw_device *vcdev = to_vc_device(dev);
588
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100589 kfree(vcdev->status);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100590 kfree(vcdev->config_block);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100591 kfree(vcdev);
592}
593
594static int irb_is_error(struct irb *irb)
595{
596 if (scsw_cstat(&irb->scsw) != 0)
597 return 1;
598 if (scsw_dstat(&irb->scsw) & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END))
599 return 1;
600 if (scsw_cc(&irb->scsw) != 0)
601 return 1;
602 return 0;
603}
604
605static struct virtqueue *virtio_ccw_vq_by_ind(struct virtio_ccw_device *vcdev,
606 int index)
607{
608 struct virtio_ccw_vq_info *info;
609 unsigned long flags;
610 struct virtqueue *vq;
611
612 vq = NULL;
613 spin_lock_irqsave(&vcdev->lock, flags);
614 list_for_each_entry(info, &vcdev->virtqueues, node) {
615 if (virtqueue_get_queue_index(info->vq) == index) {
616 vq = info->vq;
617 break;
618 }
619 }
620 spin_unlock_irqrestore(&vcdev->lock, flags);
621 return vq;
622}
623
624static void virtio_ccw_int_handler(struct ccw_device *cdev,
625 unsigned long intparm,
626 struct irb *irb)
627{
628 __u32 activity = intparm & VIRTIO_CCW_INTPARM_MASK;
629 struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev);
630 int i;
631 struct virtqueue *vq;
632 struct virtio_driver *drv;
633
634 /* Check if it's a notification from the host. */
635 if ((intparm == 0) &&
636 (scsw_stctl(&irb->scsw) ==
637 (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND))) {
638 /* OK */
639 }
640 if (irb_is_error(irb))
641 vcdev->err = -EIO; /* XXX - use real error */
642 if (vcdev->curr_io & activity) {
643 switch (activity) {
644 case VIRTIO_CCW_DOING_READ_FEAT:
645 case VIRTIO_CCW_DOING_WRITE_FEAT:
646 case VIRTIO_CCW_DOING_READ_CONFIG:
647 case VIRTIO_CCW_DOING_WRITE_CONFIG:
648 case VIRTIO_CCW_DOING_WRITE_STATUS:
649 case VIRTIO_CCW_DOING_SET_VQ:
650 case VIRTIO_CCW_DOING_SET_IND:
651 case VIRTIO_CCW_DOING_SET_CONF_IND:
652 case VIRTIO_CCW_DOING_RESET:
653 case VIRTIO_CCW_DOING_READ_VQ_CONF:
654 vcdev->curr_io &= ~activity;
655 wake_up(&vcdev->wait_q);
656 break;
657 default:
658 /* don't know what to do... */
659 dev_warn(&cdev->dev, "Suspicious activity '%08x'\n",
660 activity);
661 WARN_ON(1);
662 break;
663 }
664 }
665 for_each_set_bit(i, &vcdev->indicators,
666 sizeof(vcdev->indicators) * BITS_PER_BYTE) {
667 /* The bit clear must happen before the vring kick. */
668 clear_bit(i, &vcdev->indicators);
669 barrier();
670 vq = virtio_ccw_vq_by_ind(vcdev, i);
671 vring_interrupt(0, vq);
672 }
673 if (test_bit(0, &vcdev->indicators2)) {
674 drv = container_of(vcdev->vdev.dev.driver,
675 struct virtio_driver, driver);
676
677 if (drv && drv->config_changed)
678 drv->config_changed(&vcdev->vdev);
679 clear_bit(0, &vcdev->indicators2);
680 }
681}
682
683/*
684 * We usually want to autoonline all devices, but give the admin
685 * a way to exempt devices from this.
686 */
687#define __DEV_WORDS ((__MAX_SUBCHANNEL + (8*sizeof(long) - 1)) / \
688 (8*sizeof(long)))
689static unsigned long devs_no_auto[__MAX_SSID + 1][__DEV_WORDS];
690
691static char *no_auto = "";
692
693module_param(no_auto, charp, 0444);
694MODULE_PARM_DESC(no_auto, "list of ccw bus id ranges not to be auto-onlined");
695
696static int virtio_ccw_check_autoonline(struct ccw_device *cdev)
697{
698 struct ccw_dev_id id;
699
700 ccw_device_get_id(cdev, &id);
701 if (test_bit(id.devno, devs_no_auto[id.ssid]))
702 return 0;
703 return 1;
704}
705
706static void virtio_ccw_auto_online(void *data, async_cookie_t cookie)
707{
708 struct ccw_device *cdev = data;
709 int ret;
710
711 ret = ccw_device_set_online(cdev);
712 if (ret)
713 dev_warn(&cdev->dev, "Failed to set online: %d\n", ret);
714}
715
716static int virtio_ccw_probe(struct ccw_device *cdev)
717{
718 cdev->handler = virtio_ccw_int_handler;
719
720 if (virtio_ccw_check_autoonline(cdev))
721 async_schedule(virtio_ccw_auto_online, cdev);
722 return 0;
723}
724
725static void virtio_ccw_remove(struct ccw_device *cdev)
726{
727 struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev);
728
729 if (cdev->online) {
730 unregister_virtio_device(&vcdev->vdev);
731 dev_set_drvdata(&cdev->dev, NULL);
732 }
733 cdev->handler = NULL;
734}
735
736static int virtio_ccw_offline(struct ccw_device *cdev)
737{
738 struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev);
739
740 unregister_virtio_device(&vcdev->vdev);
741 dev_set_drvdata(&cdev->dev, NULL);
742 return 0;
743}
744
745
Cornelia Huck7e64e052012-12-14 17:02:18 +0100746static int virtio_ccw_online(struct ccw_device *cdev)
747{
748 int ret;
749 struct virtio_ccw_device *vcdev;
750
751 vcdev = kzalloc(sizeof(*vcdev), GFP_KERNEL);
752 if (!vcdev) {
753 dev_warn(&cdev->dev, "Could not get memory for virtio\n");
754 ret = -ENOMEM;
755 goto out_free;
756 }
Cornelia Huck7e64e052012-12-14 17:02:18 +0100757 vcdev->config_block = kzalloc(sizeof(*vcdev->config_block),
758 GFP_DMA | GFP_KERNEL);
759 if (!vcdev->config_block) {
760 ret = -ENOMEM;
761 goto out_free;
762 }
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100763 vcdev->status = kzalloc(sizeof(*vcdev->status), GFP_DMA | GFP_KERNEL);
764 if (!vcdev->status) {
Cornelia Huck7e64e052012-12-14 17:02:18 +0100765 ret = -ENOMEM;
766 goto out_free;
767 }
768
769 vcdev->vdev.dev.parent = &cdev->dev;
770 vcdev->vdev.dev.release = virtio_ccw_release_dev;
771 vcdev->vdev.config = &virtio_ccw_config_ops;
772 vcdev->cdev = cdev;
773 init_waitqueue_head(&vcdev->wait_q);
774 INIT_LIST_HEAD(&vcdev->virtqueues);
775 spin_lock_init(&vcdev->lock);
776
777 dev_set_drvdata(&cdev->dev, vcdev);
778 vcdev->vdev.id.vendor = cdev->id.cu_type;
779 vcdev->vdev.id.device = cdev->id.cu_model;
780 ret = register_virtio_device(&vcdev->vdev);
781 if (ret) {
782 dev_warn(&cdev->dev, "Failed to register virtio device: %d\n",
783 ret);
784 goto out_put;
785 }
786 return 0;
787out_put:
788 dev_set_drvdata(&cdev->dev, NULL);
789 put_device(&vcdev->vdev.dev);
790 return ret;
791out_free:
792 if (vcdev) {
Cornelia Huck73fa21e2013-01-07 15:51:51 +0100793 kfree(vcdev->status);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100794 kfree(vcdev->config_block);
Cornelia Huck7e64e052012-12-14 17:02:18 +0100795 }
796 kfree(vcdev);
797 return ret;
798}
799
800static int virtio_ccw_cio_notify(struct ccw_device *cdev, int event)
801{
802 /* TODO: Check whether we need special handling here. */
803 return 0;
804}
805
806static struct ccw_device_id virtio_ids[] = {
807 { CCW_DEVICE(0x3832, 0) },
808 {},
809};
810MODULE_DEVICE_TABLE(ccw, virtio_ids);
811
812static struct ccw_driver virtio_ccw_driver = {
813 .driver = {
814 .owner = THIS_MODULE,
815 .name = "virtio_ccw",
816 },
817 .ids = virtio_ids,
818 .probe = virtio_ccw_probe,
819 .remove = virtio_ccw_remove,
820 .set_offline = virtio_ccw_offline,
821 .set_online = virtio_ccw_online,
822 .notify = virtio_ccw_cio_notify,
Linus Torvalds89f88332013-02-24 13:07:18 -0800823 .int_class = IRQIO_VIR,
Cornelia Huck7e64e052012-12-14 17:02:18 +0100824};
825
826static int __init pure_hex(char **cp, unsigned int *val, int min_digit,
827 int max_digit, int max_val)
828{
829 int diff;
830
831 diff = 0;
832 *val = 0;
833
834 while (diff <= max_digit) {
835 int value = hex_to_bin(**cp);
836
837 if (value < 0)
838 break;
839 *val = *val * 16 + value;
840 (*cp)++;
841 diff++;
842 }
843
844 if ((diff < min_digit) || (diff > max_digit) || (*val > max_val))
845 return 1;
846
847 return 0;
848}
849
850static int __init parse_busid(char *str, unsigned int *cssid,
851 unsigned int *ssid, unsigned int *devno)
852{
853 char *str_work;
854 int rc, ret;
855
856 rc = 1;
857
858 if (*str == '\0')
859 goto out;
860
861 str_work = str;
862 ret = pure_hex(&str_work, cssid, 1, 2, __MAX_CSSID);
863 if (ret || (str_work[0] != '.'))
864 goto out;
865 str_work++;
866 ret = pure_hex(&str_work, ssid, 1, 1, __MAX_SSID);
867 if (ret || (str_work[0] != '.'))
868 goto out;
869 str_work++;
870 ret = pure_hex(&str_work, devno, 4, 4, __MAX_SUBCHANNEL);
871 if (ret || (str_work[0] != '\0'))
872 goto out;
873
874 rc = 0;
875out:
876 return rc;
877}
878
879static void __init no_auto_parse(void)
880{
881 unsigned int from_cssid, to_cssid, from_ssid, to_ssid, from, to;
882 char *parm, *str;
883 int rc;
884
885 str = no_auto;
886 while ((parm = strsep(&str, ","))) {
887 rc = parse_busid(strsep(&parm, "-"), &from_cssid,
888 &from_ssid, &from);
889 if (rc)
890 continue;
891 if (parm != NULL) {
892 rc = parse_busid(parm, &to_cssid,
893 &to_ssid, &to);
894 if ((from_ssid > to_ssid) ||
895 ((from_ssid == to_ssid) && (from > to)))
896 rc = -EINVAL;
897 } else {
898 to_cssid = from_cssid;
899 to_ssid = from_ssid;
900 to = from;
901 }
902 if (rc)
903 continue;
904 while ((from_ssid < to_ssid) ||
905 ((from_ssid == to_ssid) && (from <= to))) {
906 set_bit(from, devs_no_auto[from_ssid]);
907 from++;
908 if (from > __MAX_SUBCHANNEL) {
909 from_ssid++;
910 from = 0;
911 }
912 }
913 }
914}
915
916static int __init virtio_ccw_init(void)
917{
918 /* parse no_auto string before we do anything further */
919 no_auto_parse();
920 return ccw_driver_register(&virtio_ccw_driver);
921}
922module_init(virtio_ccw_init);
923
924static void __exit virtio_ccw_exit(void)
925{
926 ccw_driver_unregister(&virtio_ccw_driver);
927}
928module_exit(virtio_ccw_exit);