diff options
author | Eric Farman <farman@linux.ibm.com> | 2019-06-06 16:28:30 -0400 |
---|---|---|
committer | Cornelia Huck <cohuck@redhat.com> | 2019-06-17 07:31:17 -0400 |
commit | e8573b39a81b9933bb8b3fffcc7533b27d82231d (patch) | |
tree | c21958caa7540cbe23f95c015e6416a17cff951a /drivers/s390/cio | |
parent | e7eaf91b0aad276b164277dd6d20cdf3ee1c77e6 (diff) |
vfio-ccw: Rearrange IDAL allocation in direct CCW
This is purely deck furniture, to help understand the merge of the
direct and indirect handlers.
Signed-off-by: Eric Farman <farman@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Message-Id: <20190606202831.44135-9-farman@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r-- | drivers/s390/cio/vfio_ccw_cp.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c index 76ffcc823944..8205d0b527fc 100644 --- a/drivers/s390/cio/vfio_ccw_cp.c +++ b/drivers/s390/cio/vfio_ccw_cp.c | |||
@@ -537,13 +537,21 @@ static int ccwchain_fetch_direct(struct ccwchain *chain, | |||
537 | unsigned long *idaws; | 537 | unsigned long *idaws; |
538 | int ret; | 538 | int ret; |
539 | int bytes = 1; | 539 | int bytes = 1; |
540 | int idaw_nr = 1; | 540 | int idaw_nr; |
541 | 541 | ||
542 | ccw = chain->ch_ccw + idx; | 542 | ccw = chain->ch_ccw + idx; |
543 | 543 | ||
544 | if (ccw->count) { | 544 | if (ccw->count) |
545 | bytes = ccw->count; | 545 | bytes = ccw->count; |
546 | idaw_nr = idal_nr_words((void *)(u64)ccw->cda, ccw->count); | 546 | |
547 | /* Calculate size of IDAL */ | ||
548 | idaw_nr = idal_nr_words((void *)(u64)ccw->cda, bytes); | ||
549 | |||
550 | /* Allocate an IDAL from host storage */ | ||
551 | idaws = kcalloc(idaw_nr, sizeof(*idaws), GFP_DMA | GFP_KERNEL); | ||
552 | if (!idaws) { | ||
553 | ret = -ENOMEM; | ||
554 | goto out_init; | ||
547 | } | 555 | } |
548 | 556 | ||
549 | /* | 557 | /* |
@@ -554,7 +562,7 @@ static int ccwchain_fetch_direct(struct ccwchain *chain, | |||
554 | pa = chain->ch_pa + idx; | 562 | pa = chain->ch_pa + idx; |
555 | ret = pfn_array_alloc(pa, ccw->cda, bytes); | 563 | ret = pfn_array_alloc(pa, ccw->cda, bytes); |
556 | if (ret < 0) | 564 | if (ret < 0) |
557 | goto out_unpin; | 565 | goto out_free_idaws; |
558 | 566 | ||
559 | if (ccw_does_data_transfer(ccw)) { | 567 | if (ccw_does_data_transfer(ccw)) { |
560 | ret = pfn_array_pin(pa, cp->mdev); | 568 | ret = pfn_array_pin(pa, cp->mdev); |
@@ -564,21 +572,18 @@ static int ccwchain_fetch_direct(struct ccwchain *chain, | |||
564 | pa->pa_nr = 0; | 572 | pa->pa_nr = 0; |
565 | } | 573 | } |
566 | 574 | ||
567 | /* Translate this direct ccw to a idal ccw. */ | ||
568 | idaws = kcalloc(idaw_nr, sizeof(*idaws), GFP_DMA | GFP_KERNEL); | ||
569 | if (!idaws) { | ||
570 | ret = -ENOMEM; | ||
571 | goto out_unpin; | ||
572 | } | ||
573 | ccw->cda = (__u32) virt_to_phys(idaws); | 575 | ccw->cda = (__u32) virt_to_phys(idaws); |
574 | ccw->flags |= CCW_FLAG_IDA; | 576 | ccw->flags |= CCW_FLAG_IDA; |
575 | 577 | ||
578 | /* Populate the IDAL with pinned/translated addresses from pfn */ | ||
576 | pfn_array_idal_create_words(pa, idaws); | 579 | pfn_array_idal_create_words(pa, idaws); |
577 | 580 | ||
578 | return 0; | 581 | return 0; |
579 | 582 | ||
580 | out_unpin: | 583 | out_unpin: |
581 | pfn_array_unpin_free(pa, cp->mdev); | 584 | pfn_array_unpin_free(pa, cp->mdev); |
585 | out_free_idaws: | ||
586 | kfree(idaws); | ||
582 | out_init: | 587 | out_init: |
583 | ccw->cda = 0; | 588 | ccw->cda = 0; |
584 | return ret; | 589 | return ret; |