diff options
author | Halil Pasic <pasic@linux.ibm.com> | 2024-03-07 13:28:08 +0100 |
---|---|---|
committer | Heiko Carstens <hca@linux.ibm.com> | 2024-03-13 09:23:46 +0100 |
commit | e3e9bda38e6d9f2af50b521741071d6406b40152 (patch) | |
tree | a08f3d97ded95c352b24cea3c03f8d681482b59d /drivers/s390 | |
parent | s390/virtio_ccw: fix virtual vs physical address confusion (diff) | |
download | linux-e3e9bda38e6d9f2af50b521741071d6406b40152.tar.xz linux-e3e9bda38e6d9f2af50b521741071d6406b40152.zip |
s390/virtio_ccw: use DMA handle from DMA API
Change and use ccw_device_dma_zalloc() so it returns a virtual address like
before, which can be used to access data. However also pass a new dma32_t
pointer type handle, which correlates to the returned virtual address.
This pointer is used to directly pass/set the DMA handle as returned by the
DMA API.
Signed-off-by: Halil Pasic <pasic@linux.ibm.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/cio/css.c | 25 | ||||
-rw-r--r-- | drivers/s390/cio/device_ops.c | 5 | ||||
-rw-r--r-- | drivers/s390/virtio/virtio_ccw.c | 69 |
3 files changed, 53 insertions, 46 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 094431a62ad5..1d68db1a3d4e 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -1114,26 +1114,33 @@ static int cio_dma_pool_init(void) return 0; } -void *cio_gp_dma_zalloc(struct gen_pool *gp_dma, struct device *dma_dev, - size_t size) +void *__cio_gp_dma_zalloc(struct gen_pool *gp_dma, struct device *dma_dev, + size_t size, dma32_t *dma_handle) { dma_addr_t dma_addr; - unsigned long addr; size_t chunk_size; + void *addr; if (!gp_dma) return NULL; - addr = gen_pool_alloc(gp_dma, size); + addr = gen_pool_dma_alloc(gp_dma, size, &dma_addr); while (!addr) { chunk_size = round_up(size, PAGE_SIZE); - addr = (unsigned long) dma_alloc_coherent(dma_dev, - chunk_size, &dma_addr, CIO_DMA_GFP); + addr = dma_alloc_coherent(dma_dev, chunk_size, &dma_addr, CIO_DMA_GFP); if (!addr) return NULL; - gen_pool_add_virt(gp_dma, addr, dma_addr, chunk_size, -1); - addr = gen_pool_alloc(gp_dma, size); + gen_pool_add_virt(gp_dma, (unsigned long)addr, dma_addr, chunk_size, -1); + addr = gen_pool_dma_alloc(gp_dma, size, dma_handle ? &dma_addr : NULL); } - return (void *) addr; + if (dma_handle) + *dma_handle = (__force dma32_t)dma_addr; + return addr; +} + +void *cio_gp_dma_zalloc(struct gen_pool *gp_dma, struct device *dma_dev, + size_t size) +{ + return __cio_gp_dma_zalloc(gp_dma, dma_dev, size, NULL); } void cio_gp_dma_free(struct gen_pool *gp_dma, void *cpu_addr, size_t size) diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index a5dba3829769..40c97f873075 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c @@ -823,13 +823,14 @@ EXPORT_SYMBOL_GPL(ccw_device_get_chid); * the subchannels dma pool. Maximal size of allocation supported * is PAGE_SIZE. */ -void *ccw_device_dma_zalloc(struct ccw_device *cdev, size_t size) +void *ccw_device_dma_zalloc(struct ccw_device *cdev, size_t size, + dma32_t *dma_handle) { void *addr; if (!get_device(&cdev->dev)) return NULL; - addr = cio_gp_dma_zalloc(cdev->private->dma_pool, &cdev->dev, size); + addr = __cio_gp_dma_zalloc(cdev->private->dma_pool, &cdev->dev, size, dma_handle); if (IS_ERR_OR_NULL(addr)) put_device(&cdev->dev); return addr; diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c index ac77951c30c4..ee9c82721a7e 100644 --- a/drivers/s390/virtio/virtio_ccw.c +++ b/drivers/s390/virtio/virtio_ccw.c @@ -123,6 +123,7 @@ struct virtio_rev_info { struct virtio_ccw_vq_info { struct virtqueue *vq; + dma32_t info_block_addr; int num; union { struct vq_info_block s; @@ -354,7 +355,8 @@ static void virtio_ccw_drop_indicator(struct virtio_ccw_device *vcdev, if (vcdev->is_thinint) { thinint_area = ccw_device_dma_zalloc(vcdev->cdev, - sizeof(*thinint_area)); + sizeof(*thinint_area), + &ccw->cda); if (!thinint_area) return; thinint_area->summary_indicator = @@ -362,17 +364,16 @@ static void virtio_ccw_drop_indicator(struct virtio_ccw_device *vcdev, thinint_area->isc = VIRTIO_AIRQ_ISC; ccw->cmd_code = CCW_CMD_SET_IND_ADAPTER; ccw->count = sizeof(*thinint_area); - ccw->cda = virt_to_dma32(thinint_area); } else { /* payload is the address of the indicators */ indicatorp = ccw_device_dma_zalloc(vcdev->cdev, - sizeof(indicators(vcdev))); + sizeof(indicators(vcdev)), + &ccw->cda); if (!indicatorp) return; *indicatorp = 0; ccw->cmd_code = CCW_CMD_SET_IND; ccw->count = sizeof(indicators(vcdev)); - ccw->cda = virt_to_dma32(indicatorp); } /* Deregister indicators from host. */ *indicators(vcdev) = 0; @@ -463,7 +464,7 @@ static void virtio_ccw_del_vq(struct virtqueue *vq, struct ccw1 *ccw) } ccw->cmd_code = CCW_CMD_SET_VQ; ccw->flags = 0; - ccw->cda = virt_to_dma32(info->info_block); + ccw->cda = info->info_block_addr; ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_SET_VQ | index); /* @@ -486,7 +487,7 @@ static void virtio_ccw_del_vqs(struct virtio_device *vdev) struct ccw1 *ccw; struct virtio_ccw_device *vcdev = to_vc_device(vdev); - ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw)); + ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw), NULL); if (!ccw) return; @@ -525,7 +526,8 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, goto out_err; } info->info_block = ccw_device_dma_zalloc(vcdev->cdev, - sizeof(*info->info_block)); + sizeof(*info->info_block), + &info->info_block_addr); if (!info->info_block) { dev_warn(&vcdev->cdev->dev, "no info block\n"); err = -ENOMEM; @@ -571,7 +573,7 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, } ccw->cmd_code = CCW_CMD_SET_VQ; ccw->flags = 0; - ccw->cda = virt_to_dma32(info->info_block); + ccw->cda = info->info_block_addr; err = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_SET_VQ | i); if (err) { dev_warn(&vcdev->cdev->dev, "SET_VQ failed\n"); @@ -609,7 +611,8 @@ static int virtio_ccw_register_adapter_ind(struct virtio_ccw_device *vcdev, struct airq_info *info; thinint_area = ccw_device_dma_zalloc(vcdev->cdev, - sizeof(*thinint_area)); + sizeof(*thinint_area), + &ccw->cda); if (!thinint_area) { ret = -ENOMEM; goto out; @@ -630,7 +633,6 @@ static int virtio_ccw_register_adapter_ind(struct virtio_ccw_device *vcdev, ccw->cmd_code = CCW_CMD_SET_IND_ADAPTER; ccw->flags = CCW_FLAG_SLI; ccw->count = sizeof(*thinint_area); - ccw->cda = virt_to_dma32(thinint_area); ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_SET_IND_ADAPTER); if (ret) { if (ret == -EOPNOTSUPP) { @@ -662,7 +664,7 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs, int ret, i, queue_idx = 0; struct ccw1 *ccw; - ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw)); + ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw), NULL); if (!ccw) return -ENOMEM; @@ -687,7 +689,8 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs, * the address of the indicators. */ indicatorp = ccw_device_dma_zalloc(vcdev->cdev, - sizeof(indicators(vcdev))); + sizeof(indicators(vcdev)), + &ccw->cda); if (!indicatorp) goto out; *indicatorp = virt_to_dma64(indicators(vcdev)); @@ -703,7 +706,6 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs, ccw->cmd_code = CCW_CMD_SET_IND; ccw->flags = 0; ccw->count = sizeof(indicators(vcdev)); - ccw->cda = virt_to_dma32(indicatorp); ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_SET_IND); if (ret) goto out; @@ -714,7 +716,6 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs, ccw->cmd_code = CCW_CMD_SET_CONF_IND; ccw->flags = 0; ccw->count = sizeof(indicators2(vcdev)); - ccw->cda = virt_to_dma32(indicatorp); ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_SET_CONF_IND); if (ret) goto out; @@ -738,7 +739,7 @@ static void virtio_ccw_reset(struct virtio_device *vdev) struct virtio_ccw_device *vcdev = to_vc_device(vdev); struct ccw1 *ccw; - ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw)); + ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw), NULL); if (!ccw) return; @@ -762,11 +763,12 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev) u64 rc; struct ccw1 *ccw; - ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw)); + ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw), NULL); if (!ccw) return 0; - features = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*features)); + features = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*features), + &ccw->cda); if (!features) { rc = 0; goto out_free; @@ -776,7 +778,6 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev) ccw->cmd_code = CCW_CMD_READ_FEAT; ccw->flags = 0; ccw->count = sizeof(*features); - ccw->cda = virt_to_dma32(features); ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_FEAT); if (ret) { rc = 0; @@ -793,7 +794,6 @@ static u64 virtio_ccw_get_features(struct virtio_device *vdev) ccw->cmd_code = CCW_CMD_READ_FEAT; ccw->flags = 0; ccw->count = sizeof(*features); - ccw->cda = virt_to_dma32(features); ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_FEAT); if (ret == 0) rc |= (u64)le32_to_cpu(features->features) << 32; @@ -825,11 +825,12 @@ static int virtio_ccw_finalize_features(struct virtio_device *vdev) return -EINVAL; } - ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw)); + ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw), NULL); if (!ccw) return -ENOMEM; - features = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*features)); + features = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*features), + &ccw->cda); if (!features) { ret = -ENOMEM; goto out_free; @@ -846,7 +847,6 @@ static int virtio_ccw_finalize_features(struct virtio_device *vdev) ccw->cmd_code = CCW_CMD_WRITE_FEAT; ccw->flags = 0; ccw->count = sizeof(*features); - ccw->cda = virt_to_dma32(features); ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_FEAT); if (ret) goto out_free; @@ -860,7 +860,6 @@ static int virtio_ccw_finalize_features(struct virtio_device *vdev) ccw->cmd_code = CCW_CMD_WRITE_FEAT; ccw->flags = 0; ccw->count = sizeof(*features); - ccw->cda = virt_to_dma32(features); ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_FEAT); out_free: @@ -879,12 +878,13 @@ static void virtio_ccw_get_config(struct virtio_device *vdev, void *config_area; unsigned long flags; - ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw)); + ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw), NULL); if (!ccw) return; config_area = ccw_device_dma_zalloc(vcdev->cdev, - VIRTIO_CCW_CONFIG_SIZE); + VIRTIO_CCW_CONFIG_SIZE, + &ccw->cda); if (!config_area) goto out_free; @@ -892,7 +892,6 @@ static void virtio_ccw_get_config(struct virtio_device *vdev, ccw->cmd_code = CCW_CMD_READ_CONF; ccw->flags = 0; ccw->count = offset + len; - ccw->cda = virt_to_dma32(config_area); ret = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_READ_CONFIG); if (ret) goto out_free; @@ -919,12 +918,13 @@ static void virtio_ccw_set_config(struct virtio_device *vdev, void *config_area; unsigned long flags; - ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw)); + ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw), NULL); if (!ccw) return; config_area = ccw_device_dma_zalloc(vcdev->cdev, - VIRTIO_CCW_CONFIG_SIZE); + VIRTIO_CCW_CONFIG_SIZE, + &ccw->cda); if (!config_area) goto out_free; @@ -939,7 +939,6 @@ static void virtio_ccw_set_config(struct virtio_device *vdev, ccw->cmd_code = CCW_CMD_WRITE_CONF; ccw->flags = 0; ccw->count = offset + len; - ccw->cda = virt_to_dma32(config_area); ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_WRITE_CONFIG); out_free: @@ -956,7 +955,7 @@ static u8 virtio_ccw_get_status(struct virtio_device *vdev) if (vcdev->revision < 2) return vcdev->dma_area->status; - ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw)); + ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw), NULL); if (!ccw) return old_status; @@ -983,7 +982,7 @@ static void virtio_ccw_set_status(struct virtio_device *vdev, u8 status) struct ccw1 *ccw; int ret; - ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw)); + ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw), NULL); if (!ccw) return; @@ -1278,10 +1277,10 @@ static int virtio_ccw_set_transport_rev(struct virtio_ccw_device *vcdev) struct ccw1 *ccw; int ret; - ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw)); + ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw), NULL); if (!ccw) return -ENOMEM; - rev = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*rev)); + rev = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*rev), &ccw->cda); if (!rev) { ccw_device_dma_free(vcdev->cdev, ccw, sizeof(*ccw)); return -ENOMEM; @@ -1291,7 +1290,6 @@ static int virtio_ccw_set_transport_rev(struct virtio_ccw_device *vcdev) ccw->cmd_code = CCW_CMD_SET_VIRTIO_REV; ccw->flags = 0; ccw->count = sizeof(*rev); - ccw->cda = virt_to_dma32(rev); vcdev->revision = VIRTIO_CCW_REV_MAX; do { @@ -1333,7 +1331,8 @@ static int virtio_ccw_online(struct ccw_device *cdev) vcdev->vdev.dev.parent = &cdev->dev; vcdev->cdev = cdev; vcdev->dma_area = ccw_device_dma_zalloc(vcdev->cdev, - sizeof(*vcdev->dma_area)); + sizeof(*vcdev->dma_area), + NULL); if (!vcdev->dma_area) { ret = -ENOMEM; goto out_free; |