diff options
Diffstat (limited to 'drivers/misc/mic/vop/vop_vringh.c')
-rw-r--r-- | drivers/misc/mic/vop/vop_vringh.c | 51 |
1 files changed, 30 insertions, 21 deletions
diff --git a/drivers/misc/mic/vop/vop_vringh.c b/drivers/misc/mic/vop/vop_vringh.c index cbc8ebcff5cf..3632fce40590 100644 --- a/drivers/misc/mic/vop/vop_vringh.c +++ b/drivers/misc/mic/vop/vop_vringh.c @@ -80,7 +80,7 @@ static void vop_virtio_init_post(struct vop_vdev *vdev) continue; } vdev->vvr[i].vrh.vring.used = - (void __force *)vpdev->hw_ops->ioremap( + (void __force *)vpdev->hw_ops->remap( vpdev, le64_to_cpu(vqconfig[i].used_address), used_size); @@ -528,15 +528,15 @@ static int vop_virtio_copy_to_user(struct vop_vdev *vdev, void __user *ubuf, int vr_idx) { struct vop_device *vpdev = vdev->vpdev; - void __iomem *dbuf = vpdev->hw_ops->ioremap(vpdev, daddr, len); + void __iomem *dbuf = vpdev->hw_ops->remap(vpdev, daddr, len); struct vop_vringh *vvr = &vdev->vvr[vr_idx]; struct vop_info *vi = dev_get_drvdata(&vpdev->dev); - size_t dma_alignment = 1 << vi->dma_ch->device->copy_align; - bool x200 = is_dma_copy_aligned(vi->dma_ch->device, 1, 1, 1); + size_t dma_alignment; + bool x200; size_t dma_offset, partlen; int err; - if (!VOP_USE_DMA) { + if (!VOP_USE_DMA || !vi->dma_ch) { if (copy_to_user(ubuf, (void __force *)dbuf, len)) { err = -EFAULT; dev_err(vop_dev(vdev), "%s %d err %d\n", @@ -548,6 +548,9 @@ static int vop_virtio_copy_to_user(struct vop_vdev *vdev, void __user *ubuf, goto err; } + dma_alignment = 1 << vi->dma_ch->device->copy_align; + x200 = is_dma_copy_aligned(vi->dma_ch->device, 1, 1, 1); + dma_offset = daddr - round_down(daddr, dma_alignment); daddr -= dma_offset; len += dma_offset; @@ -585,9 +588,9 @@ static int vop_virtio_copy_to_user(struct vop_vdev *vdev, void __user *ubuf, } err = 0; err: - vpdev->hw_ops->iounmap(vpdev, dbuf); + vpdev->hw_ops->unmap(vpdev, dbuf); dev_dbg(vop_dev(vdev), - "%s: ubuf %p dbuf %p len 0x%lx vr_idx 0x%x\n", + "%s: ubuf %p dbuf %p len 0x%zx vr_idx 0x%x\n", __func__, ubuf, dbuf, len, vr_idx); return err; } @@ -603,21 +606,26 @@ static int vop_virtio_copy_from_user(struct vop_vdev *vdev, void __user *ubuf, int vr_idx) { struct vop_device *vpdev = vdev->vpdev; - void __iomem *dbuf = vpdev->hw_ops->ioremap(vpdev, daddr, len); + void __iomem *dbuf = vpdev->hw_ops->remap(vpdev, daddr, len); struct vop_vringh *vvr = &vdev->vvr[vr_idx]; struct vop_info *vi = dev_get_drvdata(&vdev->vpdev->dev); - size_t dma_alignment = 1 << vi->dma_ch->device->copy_align; - bool x200 = is_dma_copy_aligned(vi->dma_ch->device, 1, 1, 1); + size_t dma_alignment; + bool x200; size_t partlen; - bool dma = VOP_USE_DMA; + bool dma = VOP_USE_DMA && vi->dma_ch; int err = 0; - if (daddr & (dma_alignment - 1)) { - vdev->tx_dst_unaligned += len; - dma = false; - } else if (ALIGN(len, dma_alignment) > dlen) { - vdev->tx_len_unaligned += len; - dma = false; + if (dma) { + dma_alignment = 1 << vi->dma_ch->device->copy_align; + x200 = is_dma_copy_aligned(vi->dma_ch->device, 1, 1, 1); + + if (daddr & (dma_alignment - 1)) { + vdev->tx_dst_unaligned += len; + dma = false; + } else if (ALIGN(len, dma_alignment) > dlen) { + vdev->tx_len_unaligned += len; + dma = false; + } } if (!dma) @@ -668,9 +676,9 @@ memcpy: vdev->out_bytes += len; err = 0; err: - vpdev->hw_ops->iounmap(vpdev, dbuf); + vpdev->hw_ops->unmap(vpdev, dbuf); dev_dbg(vop_dev(vdev), - "%s: ubuf %p dbuf %p len 0x%lx vr_idx 0x%x\n", + "%s: ubuf %p dbuf %p len 0x%zx vr_idx 0x%x\n", __func__, ubuf, dbuf, len, vr_idx); return err; } @@ -704,16 +712,17 @@ static int vop_vringh_copy(struct vop_vdev *vdev, struct vringh_kiov *iov, while (len && iov->i < iov->used) { struct kvec *kiov = &iov->iov[iov->i]; + unsigned long daddr = (unsigned long)kiov->iov_base; partlen = min(kiov->iov_len, len); if (read) ret = vop_virtio_copy_to_user(vdev, ubuf, partlen, - (u64)kiov->iov_base, + daddr, kiov->iov_len, vr_idx); else ret = vop_virtio_copy_from_user(vdev, ubuf, partlen, - (u64)kiov->iov_base, + daddr, kiov->iov_len, vr_idx); if (ret) { |