aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2013-01-07 09:51:51 -0500
committerMarcelo Tosatti <mtosatti@redhat.com>2013-01-09 15:40:18 -0500
commit73fa21ea4fc662a2e8e85f84c4ca3fcb55fa4da2 (patch)
tree8bc6c22fd9d2e3db42b95b4aede95dfde8bc8a75 /drivers/s390
parentfb864fbc72fd4e2175fb64072fe9134d3a3ab89a (diff)
KVM: s390: Dynamic allocation of virtio-ccw I/O data.
Dynamically allocate any data structures like ccw used when doing channel I/O. Otherwise, we'd need to add extra serialization for the different callbacks using the same data structures. Reported-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/kvm/virtio_ccw.c280
1 files changed, 174 insertions, 106 deletions
diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c
index 1a5aff31d752..70419a75d0e0 100644
--- a/drivers/s390/kvm/virtio_ccw.c
+++ b/drivers/s390/kvm/virtio_ccw.c
@@ -46,11 +46,9 @@ struct vq_config_block {
46 46
47struct virtio_ccw_device { 47struct virtio_ccw_device {
48 struct virtio_device vdev; 48 struct virtio_device vdev;
49 __u8 status; 49 __u8 *status;
50 __u8 config[VIRTIO_CCW_CONFIG_SIZE]; 50 __u8 config[VIRTIO_CCW_CONFIG_SIZE];
51 struct ccw_device *cdev; 51 struct ccw_device *cdev;
52 struct ccw1 *ccw;
53 __u32 area;
54 __u32 curr_io; 52 __u32 curr_io;
55 int err; 53 int err;
56 wait_queue_head_t wait_q; 54 wait_queue_head_t wait_q;
@@ -127,14 +125,15 @@ static int doing_io(struct virtio_ccw_device *vcdev, __u32 flag)
127 return ret; 125 return ret;
128} 126}
129 127
130static int ccw_io_helper(struct virtio_ccw_device *vcdev, __u32 intparm) 128static int ccw_io_helper(struct virtio_ccw_device *vcdev,
129 struct ccw1 *ccw, __u32 intparm)
131{ 130{
132 int ret; 131 int ret;
133 unsigned long flags; 132 unsigned long flags;
134 int flag = intparm & VIRTIO_CCW_INTPARM_MASK; 133 int flag = intparm & VIRTIO_CCW_INTPARM_MASK;
135 134
136 spin_lock_irqsave(get_ccwdev_lock(vcdev->cdev), flags); 135 spin_lock_irqsave(get_ccwdev_lock(vcdev->cdev), flags);
137 ret = ccw_device_start(vcdev->cdev, vcdev->ccw, intparm, 0, 0); 136 ret = ccw_device_start(vcdev->cdev, ccw, intparm, 0, 0);
138 if (!ret) 137 if (!ret)
139 vcdev->curr_io |= flag; 138 vcdev->curr_io |= flag;
140 spin_unlock_irqrestore(get_ccwdev_lock(vcdev->cdev), flags); 139 spin_unlock_irqrestore(get_ccwdev_lock(vcdev->cdev), flags);
@@ -167,18 +166,19 @@ static void virtio_ccw_kvm_notify(struct virtqueue *vq)
167 do_kvm_notify(schid, virtqueue_get_queue_index(vq)); 166 do_kvm_notify(schid, virtqueue_get_queue_index(vq));
168} 167}
169 168
170static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev, int index) 169static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev,
170 struct ccw1 *ccw, int index)
171{ 171{
172 vcdev->config_block->index = index; 172 vcdev->config_block->index = index;
173 vcdev->ccw->cmd_code = CCW_CMD_READ_VQ_CONF; 173 ccw->cmd_code = CCW_CMD_READ_VQ_CONF;
174 vcdev->ccw->flags = 0; 174 ccw->flags = 0;
175 vcdev->ccw->count = sizeof(struct vq_config_block); 175 ccw->count = sizeof(struct vq_config_block);
176 vcdev->ccw->cda = (__u32)(unsigned long)(vcdev->config_block); 176 ccw->cda = (__u32)(unsigned long)(vcdev->config_block);
177 ccw_io_helper(vcdev, VIRTIO_CCW_DOING_READ_VQ_CONF); 177 ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_VQ_CONF);
178 return vcdev->config_block->num; 178 return vcdev->config_block->num;
179} 179}
180 180
181static void virtio_ccw_del_vq(struct virtqueue *vq) 181static void virtio_ccw_del_vq(struct virtqueue *vq, struct ccw1 *ccw)
182{ 182{
183 struct virtio_ccw_device *vcdev = to_vc_device(vq->vdev); 183 struct virtio_ccw_device *vcdev = to_vc_device(vq->vdev);
184 struct virtio_ccw_vq_info *info = vq->priv; 184 struct virtio_ccw_vq_info *info = vq->priv;
@@ -197,11 +197,12 @@ static void virtio_ccw_del_vq(struct virtqueue *vq)
197 info->info_block->align = 0; 197 info->info_block->align = 0;
198 info->info_block->index = index; 198 info->info_block->index = index;
199 info->info_block->num = 0; 199 info->info_block->num = 0;
200 vcdev->ccw->cmd_code = CCW_CMD_SET_VQ; 200 ccw->cmd_code = CCW_CMD_SET_VQ;
201 vcdev->ccw->flags = 0; 201 ccw->flags = 0;
202 vcdev->ccw->count = sizeof(*info->info_block); 202 ccw->count = sizeof(*info->info_block);
203 vcdev->ccw->cda = (__u32)(unsigned long)(info->info_block); 203 ccw->cda = (__u32)(unsigned long)(info->info_block);
204 ret = ccw_io_helper(vcdev, VIRTIO_CCW_DOING_SET_VQ | index); 204 ret = ccw_io_helper(vcdev, ccw,
205 VIRTIO_CCW_DOING_SET_VQ | index);
205 /* 206 /*
206 * -ENODEV isn't considered an error: The device is gone anyway. 207 * -ENODEV isn't considered an error: The device is gone anyway.
207 * This may happen on device detach. 208 * This may happen on device detach.
@@ -220,14 +221,23 @@ static void virtio_ccw_del_vq(struct virtqueue *vq)
220static void virtio_ccw_del_vqs(struct virtio_device *vdev) 221static void virtio_ccw_del_vqs(struct virtio_device *vdev)
221{ 222{
222 struct virtqueue *vq, *n; 223 struct virtqueue *vq, *n;
224 struct ccw1 *ccw;
225
226 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
227 if (!ccw)
228 return;
229
223 230
224 list_for_each_entry_safe(vq, n, &vdev->vqs, list) 231 list_for_each_entry_safe(vq, n, &vdev->vqs, list)
225 virtio_ccw_del_vq(vq); 232 virtio_ccw_del_vq(vq, ccw);
233
234 kfree(ccw);
226} 235}
227 236
228static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, 237static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
229 int i, vq_callback_t *callback, 238 int i, vq_callback_t *callback,
230 const char *name) 239 const char *name,
240 struct ccw1 *ccw)
231{ 241{
232 struct virtio_ccw_device *vcdev = to_vc_device(vdev); 242 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
233 int err; 243 int err;
@@ -250,7 +260,7 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
250 err = -ENOMEM; 260 err = -ENOMEM;
251 goto out_err; 261 goto out_err;
252 } 262 }
253 info->num = virtio_ccw_read_vq_conf(vcdev, i); 263 info->num = virtio_ccw_read_vq_conf(vcdev, ccw, i);
254 size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN)); 264 size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN));
255 info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); 265 info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
256 if (info->queue == NULL) { 266 if (info->queue == NULL) {
@@ -277,11 +287,11 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
277 info->info_block->align = KVM_VIRTIO_CCW_RING_ALIGN; 287 info->info_block->align = KVM_VIRTIO_CCW_RING_ALIGN;
278 info->info_block->index = i; 288 info->info_block->index = i;
279 info->info_block->num = info->num; 289 info->info_block->num = info->num;
280 vcdev->ccw->cmd_code = CCW_CMD_SET_VQ; 290 ccw->cmd_code = CCW_CMD_SET_VQ;
281 vcdev->ccw->flags = 0; 291 ccw->flags = 0;
282 vcdev->ccw->count = sizeof(*info->info_block); 292 ccw->count = sizeof(*info->info_block);
283 vcdev->ccw->cda = (__u32)(unsigned long)(info->info_block); 293 ccw->cda = (__u32)(unsigned long)(info->info_block);
284 err = ccw_io_helper(vcdev, VIRTIO_CCW_DOING_SET_VQ | i); 294 err = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_SET_VQ | i);
285 if (err) { 295 if (err) {
286 dev_warn(&vcdev->cdev->dev, "SET_VQ failed\n"); 296 dev_warn(&vcdev->cdev->dev, "SET_VQ failed\n");
287 free_pages_exact(info->queue, size); 297 free_pages_exact(info->queue, size);
@@ -312,9 +322,15 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs,
312 struct virtio_ccw_device *vcdev = to_vc_device(vdev); 322 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
313 unsigned long *indicatorp = NULL; 323 unsigned long *indicatorp = NULL;
314 int ret, i; 324 int ret, i;
325 struct ccw1 *ccw;
326
327 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
328 if (!ccw)
329 return -ENOMEM;
315 330
316 for (i = 0; i < nvqs; ++i) { 331 for (i = 0; i < nvqs; ++i) {
317 vqs[i] = virtio_ccw_setup_vq(vdev, i, callbacks[i], names[i]); 332 vqs[i] = virtio_ccw_setup_vq(vdev, i, callbacks[i], names[i],
333 ccw);
318 if (IS_ERR(vqs[i])) { 334 if (IS_ERR(vqs[i])) {
319 ret = PTR_ERR(vqs[i]); 335 ret = PTR_ERR(vqs[i]);
320 vqs[i] = NULL; 336 vqs[i] = NULL;
@@ -329,28 +345,30 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs,
329 *indicatorp = (unsigned long) &vcdev->indicators; 345 *indicatorp = (unsigned long) &vcdev->indicators;
330 /* Register queue indicators with host. */ 346 /* Register queue indicators with host. */
331 vcdev->indicators = 0; 347 vcdev->indicators = 0;
332 vcdev->ccw->cmd_code = CCW_CMD_SET_IND; 348 ccw->cmd_code = CCW_CMD_SET_IND;
333 vcdev->ccw->flags = 0; 349 ccw->flags = 0;
334 vcdev->ccw->count = sizeof(vcdev->indicators); 350 ccw->count = sizeof(vcdev->indicators);
335 vcdev->ccw->cda = (__u32)(unsigned long) indicatorp; 351 ccw->cda = (__u32)(unsigned long) indicatorp;
336 ret = ccw_io_helper(vcdev, VIRTIO_CCW_DOING_SET_IND); 352 ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_SET_IND);
337 if (ret) 353 if (ret)
338 goto out; 354 goto out;
339 /* Register indicators2 with host for config changes */ 355 /* Register indicators2 with host for config changes */
340 *indicatorp = (unsigned long) &vcdev->indicators2; 356 *indicatorp = (unsigned long) &vcdev->indicators2;
341 vcdev->indicators2 = 0; 357 vcdev->indicators2 = 0;
342 vcdev->ccw->cmd_code = CCW_CMD_SET_CONF_IND; 358 ccw->cmd_code = CCW_CMD_SET_CONF_IND;
343 vcdev->ccw->flags = 0; 359 ccw->flags = 0;
344 vcdev->ccw->count = sizeof(vcdev->indicators2); 360 ccw->count = sizeof(vcdev->indicators2);
345 vcdev->ccw->cda = (__u32)(unsigned long) indicatorp; 361 ccw->cda = (__u32)(unsigned long) indicatorp;
346 ret = ccw_io_helper(vcdev, VIRTIO_CCW_DOING_SET_CONF_IND); 362 ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_SET_CONF_IND);
347 if (ret) 363 if (ret)
348 goto out; 364 goto out;
349 365
350 kfree(indicatorp); 366 kfree(indicatorp);
367 kfree(ccw);
351 return 0; 368 return 0;
352out: 369out:
353 kfree(indicatorp); 370 kfree(indicatorp);
371 kfree(ccw);
354 virtio_ccw_del_vqs(vdev); 372 virtio_ccw_del_vqs(vdev);
355 return ret; 373 return ret;
356} 374}
@@ -358,64 +376,95 @@ out:
358static void virtio_ccw_reset(struct virtio_device *vdev) 376static void virtio_ccw_reset(struct virtio_device *vdev)
359{ 377{
360 struct virtio_ccw_device *vcdev = to_vc_device(vdev); 378 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
379 struct ccw1 *ccw;
380
381 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
382 if (!ccw)
383 return;
361 384
362 /* Zero status bits. */ 385 /* Zero status bits. */
363 vcdev->status = 0; 386 *vcdev->status = 0;
364 387
365 /* Send a reset ccw on device. */ 388 /* Send a reset ccw on device. */
366 vcdev->ccw->cmd_code = CCW_CMD_VDEV_RESET; 389 ccw->cmd_code = CCW_CMD_VDEV_RESET;
367 vcdev->ccw->flags = 0; 390 ccw->flags = 0;
368 vcdev->ccw->count = 0; 391 ccw->count = 0;
369 vcdev->ccw->cda = 0; 392 ccw->cda = 0;
370 ccw_io_helper(vcdev, VIRTIO_CCW_DOING_RESET); 393 ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_RESET);
394 kfree(ccw);
371} 395}
372 396
373static u32 virtio_ccw_get_features(struct virtio_device *vdev) 397static u32 virtio_ccw_get_features(struct virtio_device *vdev)
374{ 398{
375 struct virtio_ccw_device *vcdev = to_vc_device(vdev); 399 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
376 struct virtio_feature_desc features; 400 struct virtio_feature_desc *features;
377 int ret; 401 int ret, rc;
402 struct ccw1 *ccw;
378 403
404 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
405 if (!ccw)
406 return 0;
407
408 features = kzalloc(sizeof(*features), GFP_DMA | GFP_KERNEL);
409 if (!features) {
410 rc = 0;
411 goto out_free;
412 }
379 /* Read the feature bits from the host. */ 413 /* Read the feature bits from the host. */
380 /* TODO: Features > 32 bits */ 414 /* TODO: Features > 32 bits */
381 features.index = 0; 415 features->index = 0;
382 vcdev->ccw->cmd_code = CCW_CMD_READ_FEAT; 416 ccw->cmd_code = CCW_CMD_READ_FEAT;
383 vcdev->ccw->flags = 0; 417 ccw->flags = 0;
384 vcdev->ccw->count = sizeof(features); 418 ccw->count = sizeof(*features);
385 vcdev->ccw->cda = vcdev->area; 419 ccw->cda = (__u32)(unsigned long)features;
386 ret = ccw_io_helper(vcdev, VIRTIO_CCW_DOING_READ_FEAT); 420 ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_FEAT);
387 if (ret) 421 if (ret) {
388 return 0; 422 rc = 0;
423 goto out_free;
424 }
425
426 rc = le32_to_cpu(features->features);
389 427
390 memcpy(&features, (void *)(unsigned long)vcdev->area, 428out_free:
391 sizeof(features)); 429 kfree(features);
392 return le32_to_cpu(features.features); 430 kfree(ccw);
431 return rc;
393} 432}
394 433
395static void virtio_ccw_finalize_features(struct virtio_device *vdev) 434static void virtio_ccw_finalize_features(struct virtio_device *vdev)
396{ 435{
397 struct virtio_ccw_device *vcdev = to_vc_device(vdev); 436 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
398 struct virtio_feature_desc features; 437 struct virtio_feature_desc *features;
399 int i; 438 int i;
439 struct ccw1 *ccw;
440
441 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
442 if (!ccw)
443 return;
444
445 features = kzalloc(sizeof(*features), GFP_DMA | GFP_KERNEL);
446 if (!features)
447 goto out_free;
400 448
401 /* Give virtio_ring a chance to accept features. */ 449 /* Give virtio_ring a chance to accept features. */
402 vring_transport_features(vdev); 450 vring_transport_features(vdev);
403 451
404 for (i = 0; i < sizeof(*vdev->features) / sizeof(features.features); 452 for (i = 0; i < sizeof(*vdev->features) / sizeof(features->features);
405 i++) { 453 i++) {
406 int highbits = i % 2 ? 32 : 0; 454 int highbits = i % 2 ? 32 : 0;
407 features.index = i; 455 features->index = i;
408 features.features = cpu_to_le32(vdev->features[i / 2] 456 features->features = cpu_to_le32(vdev->features[i / 2]
409 >> highbits); 457 >> highbits);
410 memcpy((void *)(unsigned long)vcdev->area, &features,
411 sizeof(features));
412 /* Write the feature bits to the host. */ 458 /* Write the feature bits to the host. */
413 vcdev->ccw->cmd_code = CCW_CMD_WRITE_FEAT; 459 ccw->cmd_code = CCW_CMD_WRITE_FEAT;
414 vcdev->ccw->flags = 0; 460 ccw->flags = 0;
415 vcdev->ccw->count = sizeof(features); 461 ccw->count = sizeof(*features);
416 vcdev->ccw->cda = vcdev->area; 462 ccw->cda = (__u32)(unsigned long)features;
417 ccw_io_helper(vcdev, VIRTIO_CCW_DOING_WRITE_FEAT); 463 ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_FEAT);
418 } 464 }
465out_free:
466 kfree(features);
467 kfree(ccw);
419} 468}
420 469
421static void virtio_ccw_get_config(struct virtio_device *vdev, 470static void virtio_ccw_get_config(struct virtio_device *vdev,
@@ -423,19 +472,32 @@ static void virtio_ccw_get_config(struct virtio_device *vdev,
423{ 472{
424 struct virtio_ccw_device *vcdev = to_vc_device(vdev); 473 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
425 int ret; 474 int ret;
475 struct ccw1 *ccw;
476 void *config_area;
477
478 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
479 if (!ccw)
480 return;
481
482 config_area = kzalloc(VIRTIO_CCW_CONFIG_SIZE, GFP_DMA | GFP_KERNEL);
483 if (!config_area)
484 goto out_free;
426 485
427 /* Read the config area from the host. */ 486 /* Read the config area from the host. */
428 vcdev->ccw->cmd_code = CCW_CMD_READ_CONF; 487 ccw->cmd_code = CCW_CMD_READ_CONF;
429 vcdev->ccw->flags = 0; 488 ccw->flags = 0;
430 vcdev->ccw->count = offset + len; 489 ccw->count = offset + len;
431 vcdev->ccw->cda = vcdev->area; 490 ccw->cda = (__u32)(unsigned long)config_area;
432 ret = ccw_io_helper(vcdev, VIRTIO_CCW_DOING_READ_CONFIG); 491 ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_CONFIG);
433 if (ret) 492 if (ret)
434 return; 493 goto out_free;
435 494
436 memcpy(vcdev->config, (void *)(unsigned long)vcdev->area, 495 memcpy(vcdev->config, config_area, sizeof(vcdev->config));
437 sizeof(vcdev->config));
438 memcpy(buf, &vcdev->config[offset], len); 496 memcpy(buf, &vcdev->config[offset], len);
497
498out_free:
499 kfree(config_area);
500 kfree(ccw);
439} 501}
440 502
441static void virtio_ccw_set_config(struct virtio_device *vdev, 503static void virtio_ccw_set_config(struct virtio_device *vdev,
@@ -443,37 +505,55 @@ static void virtio_ccw_set_config(struct virtio_device *vdev,
443 unsigned len) 505 unsigned len)
444{ 506{
445 struct virtio_ccw_device *vcdev = to_vc_device(vdev); 507 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
508 struct ccw1 *ccw;
509 void *config_area;
510
511 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
512 if (!ccw)
513 return;
514
515 config_area = kzalloc(VIRTIO_CCW_CONFIG_SIZE, GFP_DMA | GFP_KERNEL);
516 if (!config_area)
517 goto out_free;
446 518
447 memcpy(&vcdev->config[offset], buf, len); 519 memcpy(&vcdev->config[offset], buf, len);
448 /* Write the config area to the host. */ 520 /* Write the config area to the host. */
449 memcpy((void *)(unsigned long)vcdev->area, vcdev->config, 521 memcpy(config_area, vcdev->config, sizeof(vcdev->config));
450 sizeof(vcdev->config)); 522 ccw->cmd_code = CCW_CMD_WRITE_CONF;
451 vcdev->ccw->cmd_code = CCW_CMD_WRITE_CONF; 523 ccw->flags = 0;
452 vcdev->ccw->flags = 0; 524 ccw->count = offset + len;
453 vcdev->ccw->count = offset + len; 525 ccw->cda = (__u32)(unsigned long)config_area;
454 vcdev->ccw->cda = vcdev->area; 526 ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_CONFIG);
455 ccw_io_helper(vcdev, VIRTIO_CCW_DOING_WRITE_CONFIG); 527
528out_free:
529 kfree(config_area);
530 kfree(ccw);
456} 531}
457 532
458static u8 virtio_ccw_get_status(struct virtio_device *vdev) 533static u8 virtio_ccw_get_status(struct virtio_device *vdev)
459{ 534{
460 struct virtio_ccw_device *vcdev = to_vc_device(vdev); 535 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
461 536
462 return vcdev->status; 537 return *vcdev->status;
463} 538}
464 539
465static void virtio_ccw_set_status(struct virtio_device *vdev, u8 status) 540static void virtio_ccw_set_status(struct virtio_device *vdev, u8 status)
466{ 541{
467 struct virtio_ccw_device *vcdev = to_vc_device(vdev); 542 struct virtio_ccw_device *vcdev = to_vc_device(vdev);
543 struct ccw1 *ccw;
544
545 ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
546 if (!ccw)
547 return;
468 548
469 /* Write the status to the host. */ 549 /* Write the status to the host. */
470 vcdev->status = status; 550 *vcdev->status = status;
471 memcpy((void *)(unsigned long)vcdev->area, &status, sizeof(status)); 551 ccw->cmd_code = CCW_CMD_WRITE_STATUS;
472 vcdev->ccw->cmd_code = CCW_CMD_WRITE_STATUS; 552 ccw->flags = 0;
473 vcdev->ccw->flags = 0; 553 ccw->count = sizeof(status);
474 vcdev->ccw->count = sizeof(status); 554 ccw->cda = (__u32)(unsigned long)vcdev->status;
475 vcdev->ccw->cda = vcdev->area; 555 ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_STATUS);
476 ccw_io_helper(vcdev, VIRTIO_CCW_DOING_WRITE_STATUS); 556 kfree(ccw);
477} 557}
478 558
479static struct virtio_config_ops virtio_ccw_config_ops = { 559static struct virtio_config_ops virtio_ccw_config_ops = {
@@ -499,9 +579,8 @@ static void virtio_ccw_release_dev(struct device *_d)
499 dev); 579 dev);
500 struct virtio_ccw_device *vcdev = to_vc_device(dev); 580 struct virtio_ccw_device *vcdev = to_vc_device(dev);
501 581
502 kfree((void *)(unsigned long)vcdev->area); 582 kfree(vcdev->status);
503 kfree(vcdev->config_block); 583 kfree(vcdev->config_block);
504 kfree(vcdev->ccw);
505 kfree(vcdev); 584 kfree(vcdev);
506} 585}
507 586
@@ -657,9 +736,6 @@ static int virtio_ccw_offline(struct ccw_device *cdev)
657} 736}
658 737
659 738
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) 739static int virtio_ccw_online(struct ccw_device *cdev)
664{ 740{
665 int ret; 741 int ret;
@@ -671,21 +747,14 @@ static int virtio_ccw_online(struct ccw_device *cdev)
671 ret = -ENOMEM; 747 ret = -ENOMEM;
672 goto out_free; 748 goto out_free;
673 } 749 }
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), 750 vcdev->config_block = kzalloc(sizeof(*vcdev->config_block),
682 GFP_DMA | GFP_KERNEL); 751 GFP_DMA | GFP_KERNEL);
683 if (!vcdev->config_block) { 752 if (!vcdev->config_block) {
684 ret = -ENOMEM; 753 ret = -ENOMEM;
685 goto out_free; 754 goto out_free;
686 } 755 }
687 vcdev->ccw = kzalloc(sizeof(*vcdev->ccw), GFP_DMA | GFP_KERNEL); 756 vcdev->status = kzalloc(sizeof(*vcdev->status), GFP_DMA | GFP_KERNEL);
688 if (!vcdev->ccw) { 757 if (!vcdev->status) {
689 ret = -ENOMEM; 758 ret = -ENOMEM;
690 goto out_free; 759 goto out_free;
691 } 760 }
@@ -714,9 +783,8 @@ out_put:
714 return ret; 783 return ret;
715out_free: 784out_free:
716 if (vcdev) { 785 if (vcdev) {
717 kfree((void *)(unsigned long)vcdev->area); 786 kfree(vcdev->status);
718 kfree(vcdev->config_block); 787 kfree(vcdev->config_block);
719 kfree(vcdev->ccw);
720 } 788 }
721 kfree(vcdev); 789 kfree(vcdev);
722 return ret; 790 return ret;