/*
 * Intel MIC Platform Software Stack (MPSS)
 *
 * Copyright(c) 2015 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2, as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * Intel SCIF driver.
 *
 */
#include "scif_main.h"
#include "scif_map.h"

/*
 * struct scif_dma_comp_cb - SCIF DMA completion callback
 *
 * @dma_completion_func: DMA completion callback
 * @cb_cookie: DMA completion callback cookie
 * @temp_buf: Temporary buffer
 * @temp_buf_to_free: Temporary buffer to be freed
 * @is_cache: Is a kmem_cache allocated buffer
 * @dst_offset: Destination registration offset
 * @dst_window: Destination registration window
 * @len: Length of the temp buffer
 * @temp_phys: DMA address of the temp buffer
 * @sdev: The SCIF device
 * @header_padding: padding for cache line alignment
 */
struct scif_dma_comp_cb {
	void (*dma_completion_func)(void *cookie);
	void *cb_cookie;
	u8 *temp_buf;
	u8 *temp_buf_to_free;
	bool is_cache;
	s64 dst_offset;
	struct scif_window *dst_window;
	size_t len;
	dma_addr_t temp_phys;
	struct scif_dev *sdev;
	int header_padding;
};

/**
 * struct scif_copy_work - Work for DMA copy
 *
 * @src_offset: Starting source offset
 * @dst_offset: Starting destination offset
 * @src_window: Starting src registered window
 * @dst_window: Starting dst registered window
 * @loopback: true if this is a loopback DMA transfer
 * @len: Length of the transfer
 * @comp_cb: DMA copy completion callback
 * @remote_dev: The remote SCIF peer device
 * @fence_type: polling or interrupt based
 * @ordered: is this a tail byte ordered DMA transfer
 */
struct scif_copy_work {
	s64 src_offset;
	s64 dst_offset;
	struct scif_window *src_window;
	struct scif_window *dst_window;
	int loopback;
	size_t len;
	struct scif_dma_comp_cb   *comp_cb;
	struct scif_dev	*remote_dev;
	int fence_type;
	bool ordered;
};

/**
 * scif_reserve_dma_chan:
 * @ep: Endpoint Descriptor.
 *
 * This routine reserves a DMA channel for a particular
 * endpoint. All DMA transfers for an endpoint are always
 * programmed on the same DMA channel.
 */
int scif_reserve_dma_chan(struct scif_endpt *ep)
{
	int err = 0;
	struct scif_dev *scifdev;
	struct scif_hw_dev *sdev;
	struct dma_chan *chan;

	/* Loopback DMAs are not supported on the management node */
	if (!scif_info.nodeid && scifdev_self(ep->remote_dev))
		return 0;
	if (scif_info.nodeid)
		scifdev = &scif_dev[0];
	else
		scifdev = ep->remote_dev;
	sdev = scifdev->sdev;
	if (!sdev->num_dma_ch)
		return -ENODEV;
	chan = sdev->dma_ch[scifdev->dma_ch_idx];
	scifdev->dma_ch_idx = (scifdev->dma_ch_idx + 1) % sdev->num_dma_ch;
	mutex_lock(&ep->rma_info.rma_lock);
	ep->rma_info.dma_chan = chan;
	mutex_unlock(&ep->rma_info.rma_lock);
	return err;
}

#ifdef CONFIG_MMU_NOTIFIER
/**
 * scif_rma_destroy_tcw:
 *
 * This routine destroys temporary cached windows
 */
static
void __scif_rma_destroy_tcw(struct scif_mmu_notif *mmn,
			    u64 start, u64 len)
{
	struct list_head *item, *tmp;
	struct scif_window *window;
	u64 start_va, end_va;
	u64 end = start + len;

	if (end <= start)
		return;

	list_for_each_safe(item, tmp, &mmn->tc_reg_list) {
		window = list_entry(item, struct scif_window, list);
		if (!len)
			break;
		start_va = window->va_for_temp;
		end_va = start_va + (window->nr_pages << PAGE_SHIFT);
		if (start < start_va && end <= start_va)
			break;
		if (start >= end_va)
			continue;
		__scif_rma_destroy_tcw_helper(window);
	}
}

static void scif_rma_destroy_tcw(struct scif_mmu_notif *mmn, u64 start, u64 len)
{
	struct scif_endpt *ep = mmn->ep;

	spin_lock(&ep->rma_info.tc_lock);
	__scif_rma_destroy_tcw(mmn, start, len);
	spin_unlock(&ep->rma_info.tc_lock);
}

static void scif_rma_destroy_tcw_ep(struct scif_endpt *ep)
{
	struct list_head *item, *tmp;
	struct scif_mmu_notif *mmn;

	list_for_each_safe(item, tmp, &ep->rma_info.mmn_list) {
		mmn = list_entry(item, struct scif_mmu_notif, list);
		scif_rma_destroy_tcw(mmn, 0, ULONG_MAX);
	}
}

static void __scif_rma_destroy_tcw_ep(struct scif_endpt *ep)
{
	struct list_head *item, *tmp;
	struct scif_mmu_notif *mmn;

	spin_lock(&ep->rma_info.tc_lock);
	list_for_each_safe(item, tmp, &ep->rma_info.mmn_list) {
		mmn = list_entry(item, struct scif_mmu_notif, list);
		__scif_rma_destroy_tcw(mmn, 0, ULONG_MAX);
	}
	spin_unlock(&ep->rma_info.tc_lock);
}

static bool scif_rma_tc_can_cache(struct scif_endpt *ep, size_t cur_bytes)
{
	if ((cur_bytes >> PAGE_SHIFT) > scif_info.rma_tc_limit)
		return false;
	if ((atomic_read(&ep->rma_info.tcw_total_pages)
			+ (cur_bytes >> PAGE_SHIFT)) >
			scif_info.rma_tc_limit) {
		dev_info(scif_info.mdev.this_device,
			 "%s %d total=%d, current=%zu reached max\n",
			 __func__, __LINE__,
			 atomic_read(&ep->rma_info.tcw_total_pages),
			 (1 + (cur_bytes >> PAGE_SHIFT)));
		scif_rma_destroy_tcw_invalid();
		__scif_rma_destroy_tcw_ep(ep);
	}
	return true;
}

static void scif_mmu_notifier_release(struct mmu_notifier *mn,
				      struct mm_struct *mm)
{
	struct scif_mmu_notif	*mmn;

	mmn = container_of(mn, struct scif_mmu_notif, ep_mmu_notifier);
	scif_rma_destroy_tcw(mmn, 0, ULONG_MAX);
	schedule_work(&scif_info.misc_work);
}

static void scif_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
						     struct mm_struct *mm,
						     unsigned long start,
						     unsigned long end)
{
	struct scif_mmu_notif	*mmn;

	mmn = container_of(mn, struct scif_mmu_notif, ep_mmu_notifier);
	scif_rma_destroy_tcw(mmn, start, end - start);
}

static void scif_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
						   struct mm_struct *mm,
						   unsigned long start,
						   unsigned long end)
{
	/*
	 * Nothing to do here, everything needed was done in
	 * invalidate_range_start.
	 */
}

static const struct mmu_notifier_ops scif_mmu_notifier_ops = {
	.release = scif_mmu_notifier_release,
	.clear_flush_young = NULL,
	.invalidate_range_start = scif_mmu_notifier_invalidate_range_start,
	.invalidate_range_end = scif_mmu_notifier_invalidate_range_end};

static void scif_ep_unregister_mmu_notifier(struct scif_endpt *ep)
{
	struct scif_endpt_rma_info *rma = &ep->rma_info;
	struct scif_mmu_notif *mmn = NULL;
	struct list_head *item, *tmp;

	mutex_lock(&ep->rma_info.mmn_lock);
	list_for_each_safe(item, tmp, &rma->mmn_list) {
		mmn = list_entry(item, struct scif_mmu_notif, list);
		mmu_notifier_unregister(&mmn->ep_mmu_notifier, mmn->mm);
		list_del(item);
		kfree(mmn);
	}
	mutex_unlock(&ep->rma_info.mmn_lock);
}

static void scif_init_mmu_notifier(struct scif_mmu_notif *mmn,
				   struct mm_struct *mm, struct scif_endpt *ep)
{
	mmn->ep = ep;
	mmn->mm = mm;
	mmn->ep_mmu_notifier.ops = &scif_mmu_notifier_ops;
	INIT_LIST_HEAD(&mmn->list);
	INIT_LIST_HEAD(&mmn->tc_reg_list);
}

static struct scif_mmu_notif *
scif_find_mmu_notifier(struct mm_struct *mm, struct scif_endpt_rma_info *rma)
{
	struct scif_mmu_notif *mmn;

	list_for_each_entry(mmn, &rma->mmn_list, list)
		if (mmn->mm == mm)
			return mmn;
	return NULL;
}

static struct scif_mmu_notif *
scif_add_mmu_notifier(struct mm_struct *mm, struct scif_endpt *ep)
{
	struct scif_mmu_notif *mmn
		 = kzalloc(sizeof(*mmn), GFP_KERNEL);

	if (!mmn)
		return ERR_PTR(-ENOMEM);

	scif_init_mmu_notifier(mmn, current->mm, ep);
	if (mmu_notifier_register(&mmn->ep_mmu_notifier, current->mm)) {
		kfree(mmn);
		return ERR_PTR(-EBUSY);
	}
	list_add(&mmn->list, &ep->rma_info.mmn_list);
	return mmn;
}

/*
 * Called from the misc thread to destroy temporary cached windows and
 * unregister the MMU notifier for the SCIF endpoint.
 */
void scif_mmu_notif_handler(struct work_struct *work)
{
	struct list_head *pos, *tmpq;
	struct scif_endpt *ep;
restart:
	scif_rma_destroy_tcw_invalid();
	spin_lock(&scif_info.rmalock);
	list_for_each_safe(pos, tmpq, &scif_info.mmu_notif_cleanup) {
		ep = list_entry(pos, struct scif_endpt, mmu_list);
		list_del(&ep->mmu_list);
		spin_unlock(&scif_info.rmalock);
		scif_rma_destroy_tcw_ep(ep);
		scif_ep_unregister_mmu_notifier(ep);
		goto restart;
	}
	spin_unlock(&scif_info.rmalock);
}

static bool scif_is_set_reg_cache(int flags)
{
	return !!(flags & SCIF_RMA_USECACHE);
}
#else
static struct scif_mmu_notif *
scif_find_mmu_notifier(struct mm_struct *mm,
		       struct scif_endpt_rma_info *rma)
{
	return NULL;
}

static struct scif_mmu_notif *
scif_add_mmu_notifier(struct mm_struct *mm, struct scif_endpt *ep)
{
	return NULL;
}

void scif_mmu_notif_handler(struct work_struct *work)
{
}

static bool scif_is_set_reg_cache(int flags)
{
	return false;
}

static bool scif_rma_tc_can_cache(struct scif_endpt *ep, size_t cur_bytes)
{
	return false;
}
#endif

/**
 * scif_register_temp:
 * @epd: End Point Descriptor.
 * @addr: virtual address to/from which to copy
 * @len: length of range to copy
 * @out_offset: computed offset returned by reference.
 * @out_window: allocated registered window returned by reference.
 *
 * Create a temporary registered window. The peer will not know about this
 * window. This API is used for scif_vreadfrom()/scif_vwriteto() API's.
 */
static int
scif_register_temp(scif_epd_t epd, unsigned long addr, size_t len, int prot,
		   off_t *out_offset, struct scif_window **out_window)
{
	struct scif_endpt *ep = (struct scif_endpt *)epd;
	int err;
	scif_pinned_pages_t pinned_pages;
	size_t aligned_len;

	aligned_len = ALIGN(len, PAGE_SIZE);

	err = __scif_pin_pages((void *)(addr & PAGE_MASK),
			       aligned_len, &prot, 0, &pinned_pages);
	if (err)
		return err;

	pinned_pages->prot = prot;

	/* Compute the offset for this registration */
	err = scif_get_window_offset(ep, 0, 0,
				     aligned_len >> PAGE_SHIFT,
				     (s64 *)out_offset);
	if (err)
		goto error_unpin;

	/* Allocate and prepare self registration window */
	*out_window = scif_create_window(ep, aligned_len >> PAGE_SHIFT,
					*out_offset, true);
	if (!*out_window) {
		scif_free_window_offset(ep, NULL, *out_offset);
		err = -ENOMEM;
		goto error_unpin;
	}

	(*out_window)->pinned_pages = pinned_pages;
	(*out_window)->nr_pages = pinned_pages->nr_pages;
	(*out_window)->prot = pinned_pages->prot;

	(*out_window)->va_for_temp = addr & PAGE_MASK;
	err = scif_map_window(ep->remote_dev, *out_window);
	if (err) {
		/* Something went wrong! Rollback */
		scif_destroy_window(ep, *out_window);
		*out_window = NULL;
	} else {
		*out_offset |= (addr - (*out_window)->va_for_temp);
	}
	return err;
error_unpin:
	if (err)
		dev_err(&ep->remote_dev->sdev->dev,
			"%s %d err %d\n", __func__, __LINE__, err);
	scif_unpin_pages(pinned_pages);
	return err;
}

#define SCIF_DMA_TO (3 * HZ)

/*
 * scif_sync_dma - Program a DMA without an interrupt descriptor
 *
 * @dev - The address of the pointer to the device instance used
 * for DMA registration.
 * @chan - DMA channel to be used.
 * @sync_wait: Wait for DMA to complete?
 *
 * Return 0 on success and -errno on error.
 */
static int scif_sync_dma(struct scif_hw_dev *sdev, struct dma_chan *chan,
			 bool sync_wait)
{
	int err = 0;
	struct dma_async_tx_descriptor *tx = NULL;
	enum dma_ctrl_flags flags = DMA_PREP_FENCE;
	dma_cookie_t cookie;
	struct dma_device *ddev;

	if (!chan) {
		err = -EIO;
		dev_err(&sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		return err;
	}
	ddev = chan->device;

	tx = ddev->device_prep_dma_memcpy(chan, 0, 0, 0, flags);
	if (!tx) {
		err = -ENOMEM;
		dev_err(&sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		goto release;
	}
	cookie = tx->tx_submit(tx);

	if (dma_submit_error(cookie)) {
		err = -ENOMEM;
		dev_err(&sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		goto release;
	}
	if (!sync_wait) {
		dma_async_issue_pending(chan);
	} else {
		if (dma_sync_wait(chan, cookie) == DMA_COMPLETE) {
			err = 0;
		} else {
			err = -EIO;
			dev_err(&sdev->dev, "%s %d err %d\n",
				__func__, __LINE__, err);
		}
	}
release:
	return err;
}

static void scif_dma_callback(void *arg)
{
	struct completion *done = (struct completion *)arg;

	complete(done);
}

#define SCIF_DMA_SYNC_WAIT true
#define SCIF_DMA_POLL BIT(0)
#define SCIF_DMA_INTR BIT(1)

/*
 * scif_async_dma - Program a DMA with an interrupt descriptor
 *
 * @dev - The address of the pointer to the device instance used
 * for DMA registration.
 * @chan - DMA channel to be used.
 * Return 0 on success and -errno on error.
 */
static int scif_async_dma(struct scif_hw_dev *sdev, struct dma_chan *chan)
{
	int err = 0;
	struct dma_device *ddev;
	struct dma_async_tx_descriptor *tx = NULL;
	enum dma_ctrl_flags flags = DMA_PREP_INTERRUPT | DMA_PREP_FENCE;
	DECLARE_COMPLETION_ONSTACK(done_wait);
	dma_cookie_t cookie;
	enum dma_status status;

	if (!chan) {
		err = -EIO;
		dev_err(&sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		return err;
	}
	ddev = chan->device;

	tx = ddev->device_prep_dma_memcpy(chan, 0, 0, 0, flags);
	if (!tx) {
		err = -ENOMEM;
		dev_err(&sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		goto release;
	}
	reinit_completion(&done_wait);
	tx->callback = scif_dma_callback;
	tx->callback_param = &done_wait;
	cookie = tx->tx_submit(tx);

	if (dma_submit_error(cookie)) {
		err = -ENOMEM;
		dev_err(&sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		goto release;
	}
	dma_async_issue_pending(chan);

	err = wait_for_completion_timeout(&done_wait, SCIF_DMA_TO);
	if (!err) {
		err = -EIO;
		dev_err(&sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		goto release;
	}
	err = 0;
	status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
	if (status != DMA_COMPLETE) {
		err = -EIO;
		dev_err(&sdev->dev, "%s %d err %d\n",
			__func__, __LINE__, err);
		goto release;
	}
release:
	return err;
}

/*
 * scif_drain_dma_poll - Drain all outstanding DMA operations for a particular
 * DMA channel via polling.
 *
 * @sdev - The SCIF device
 * @chan - DMA channel
 * Return 0 on success and -errno on error.
 */
static int scif_drain_dma_poll(struct scif_hw_dev *sdev, struct dma_chan *chan)
{
	if (!chan)
		return -EINVAL;
	return scif_sync_dma(sdev, chan, SCIF_DMA_SYNC_WAIT);
}

/*
 * scif_drain_dma_intr - Drain all outstanding DMA operations for a particular
 * DMA channel via interrupt based blocking wait.
 *
 * @sdev - The SCIF device
 * @chan - DMA channel
 * Return 0 on success and -errno on error.
 */
int scif_drain_dma_intr(struct scif_hw_dev *sdev, struct dma_chan *chan)
{
	if (!chan)
		return -EINVAL;
	return scif_async_dma(sdev, chan);
}

/**
 * scif_rma_destroy_windows:
 *
 * This routine destroys all windows queued for cleanup
 */
void scif_rma_destroy_windows(void)
{
	struct list_head *item, *tmp;
	struct scif_window *window;
	struct scif_endpt *ep;
	struct dma_chan *chan;

	might_sleep();
restart:
	spin_lock(&scif_info.rmalock);
	list_for_each_safe(item, tmp, &scif_info.rma) {
		window = list_entry(item, struct scif_window,
				    list);
		ep = (struct scif_endpt *)window->ep;
		chan = ep->rma_info.dma_chan;

		list_del_init(&window->list);
		spin_unlock(&scif_info.rmalock);
		if (!chan || !scifdev_alive(ep) ||
		    !scif_drain_dma_intr(ep->remote_dev->sdev,
					 ep->rma_info.dma_chan))
			/* Remove window from global list */
			window->unreg_state = OP_COMPLETED;
		else
			dev_warn(&ep->remote_dev->sdev->dev,
				 "DMA engine hung?\n");
		if (window->unreg_state == OP_COMPLETED) {
			if (window->type == SCIF_WINDOW_SELF)
				scif_destroy_window(ep, window);
			else
				scif_destroy_remote_window(window);
			atomic_dec(&ep->rma_info.tw_refcount);
		}
		goto restart;
	}
	spin_unlock(&scif_info.rmalock);
}

/**
 * scif_rma_destroy_tcw:
 *
 * This routine destroys temporary cached registered windows
 * which have been queued for cleanup.
 */
void scif_rma_destroy_tcw_invalid(void)
{
	struct list_head *item, *tmp;
	struct scif_window *window;
	struct scif_endpt *ep;
	struct dma_chan *chan;

	might_sleep();
restart:
	spin_lock(&scif_info.rmalock);
	list_for_each_safe(item, tmp, &scif_info.rma_tc) {
		window = list_entry(item, struct scif_window, list);
		ep = (struct scif_endpt *)window->ep;
		chan = ep->rma_info.dma_chan;
		list_del_init(&window->list);
		spin_unlock(&scif_info.rmalock);
		mutex_lock(&ep->rma_info.rma_lock);
		if (!chan || !scifdev_alive(ep) ||
		    !scif_drain_dma_intr(ep->remote_dev->sdev,
					 ep->rma_info.dma_chan)) {
			atomic_sub(window->nr_pages,
				   &ep->rma_info.tcw_total_pages);
			scif_destroy_window(ep, window);
			atomic_dec(&ep->rma_info.tcw_refcount);
		} else {
			dev_warn(&ep->remote_dev->sdev->dev,
				 "DMA engine hung?\n");
		}
		mutex_unlock(&ep->rma_info.rma_lock);
		goto restart;
	}
	spin_unlock(&scif_info.rmalock);
}

static inline
void *_get_local_va(off_t off, struct scif_window *window, size_t len)
{
	int page_nr = (off - window->offset) >> PAGE_SHIFT;
	off_t page_off = off & ~PAGE_MASK;
	void *va = NULL;

	if (window->type == SCIF_WINDOW_SELF) {
		struct page **pages = window->pinned_pages->pages;

		va = page_address(pages[page_nr]) + page_off;
	}
	return va;
}

static inline
void *ioremap_remote(off_t off, struct scif_window *window,
		     size_t len, struct scif_dev *dev,
		     struct scif_window_iter *iter)
{
	dma_addr_t phys = scif_off_to_dma_addr(window, off, NULL, iter);

	/*
	 * If the DMA address is not card relative then we need the DMA
	 * addresses to be an offset into the bar. The aperture base was already
	 * added so subtract it here since scif_ioremap is going to add it again
	 */
	if (!scifdev_self(dev) && window->type == SCIF_WINDOW_PEER &&
	    dev->sdev->aper && !dev->sdev->card_rel_da)
		phys = phys - dev->sdev->aper->pa;
	return scif_ioremap(phys, len, dev);
}

static inline void
iounmap_remote(void *virt, size_t size, struct scif_copy_work *work)
{
	scif_iounmap(virt, size, work->remote_dev);
}

/*
 * Takes care of ordering issue caused by
 * 1. Hardware:  Only in the case of cpu copy from mgmt node to card
 * because of WC memory.
 * 2. Software: If memcpy reorders copy instructions for optimization.
 * This could happen at both mgmt node and card.
 */
static inline void
scif_ordered_memcpy_toio(char *dst, const char *src, size_t count)
{
	if (!count)
		return;

	memcpy_toio((void __iomem __force *)dst, src, --count);
	/* Order the last byte with the previous stores */
	wmb();
	*(dst + count) = *(src + count);
}

static inline void scif_unaligned_cpy_toio(char *dst, const char *src,
					   size_t count, bool ordered)
{
	if (ordered)
		scif_ordered_memcpy_toio(dst, src, count);
	else
		memcpy_toio((void __iomem __force *)dst, src, count);
}

static inline
void scif_ordered_memcpy_fromio(char *dst, const char *src, size_t count)
{
	if (!count)
		return;

	memcpy_fromio(dst, (void __iomem __force *)src, --count);
	/* Order the last byte with the previous loads */
	rmb();
	*(dst + count) = *(src + count);
}

static inline void scif_unaligned_cpy_fromio(char *dst, const char *src,
					     size_t count, bool ordered)
{
	if (ordered)
		scif_ordered_memcpy_fromio(dst, src, count);
	else
		memcpy_fromio(dst, (void __iomem __force *)src, count);
}

#define SCIF_RMA_ERROR_CODE (~(dma_addr_t)0x0)

/*
 * scif_off_to_dma_addr:
 * Obtain the dma_addr given the window and the offset.
 * @window: Registered window.
 * @off: Window offset.
 * @nr_bytes: Return the number of contiguous bytes till next DMA addr index.
 * @index: Return the index of the dma_addr array found.
 * @start_off: start offset of index of the dma addr array found.
 * The nr_bytes provides the callee an estimate of the maximum possible
 * DMA xfer possible while the index/start_off provide faster lookups
 * for the next iteration.
 */
dma_addr_t scif_off_to_dma_addr(struct scif_window *window, s64 off,
				size_t *nr_bytes, struct scif_window_iter *iter)
{
	int i, page_nr;
	s64 start, end;
	off_t page_off;

	if (window->nr_pages == window->nr_contig_chunks) {
		page_nr = (off - window->offset) >> PAGE_SHIFT;
		page_off = off & ~PAGE_MASK;

		if (nr_bytes)
			*nr_bytes = PAGE_SIZE - page_off;
		return window->dma_addr[page_nr] | page_off;
	}
	if (iter) {
		i = iter->index;
		start = iter->offset;
	} else {
		i =  0;
		start =  window->offset;
	}
	for (; i < window->nr_contig_chunks; i++) {
		end = start + (window->num_pages[i] << PAGE_SHIFT);
		if (off >= start && off < end) {
			if (iter) {
				iter->index = i;
				iter->offset = start;
			}
			if (nr_bytes)
				*nr_bytes = end - off;
			return (window->dma_addr[i] + (off - start));
		}
		start += (window->num_pages[i] << PAGE_SHIFT);
	}
	dev_err(scif_info.mdev.this_device,
		"%s %d BUG. Addr not found? window %p off 0x%llx\n",
		__func__, __LINE__, window, off);
	return SCIF_RMA_ERROR_CODE;
}

/*
 * Copy between rma window and temporary buffer
 */
static void scif_rma_local_cpu_copy(s64 offset, struct scif_window *window,
				    u8 *temp, size_t rem_len, bool to_temp)
{
	void *window_virt;
	size_t loop_len;
	int offset_in_page;
	s64 end_offset;

	offset_in_page = offset & ~PAGE_MASK;
	loop_len = PAGE_SIZE - offset_in_page;

	if (rem_len < loop_len)
		loop_len = rem_len;

	window_virt = _get_local_va(offset, window, loop_len);
	if (!window_virt)
		return;
	if (to_temp)
		memcpy(temp, window_virt, loop_len);
	else
		memcpy(window_virt, temp, loop_len);

	offset += loop_len;
	temp += loop_len;
	rem_len -= loop_len;

	end_offset = window->offset +
		(window->nr_pages << PAGE_SHIFT);
	while (rem_len) {
		if (offset == end_offset) {
			window = list_next_entry(window, list);
			end_offset = window->offset +
				(window->nr_pages << PAGE_SHIFT);
		}
		loop_len = min(PAGE_SIZE, rem_len);
		window_virt = _get_local_va(offset, window, loop_len);
		if (!window_virt)
			return;
		if (to_temp)
			memcpy(temp, window_virt, loop_len);
		else
			memcpy(window_virt, temp, loop_len);
		offset	+= loop_len;
		temp	+= loop_len;
		rem_len	-= loop_len;
	}
}

/**
 * scif_rma_completion_cb:
 * @data: RMA cookie
 *
 * RMA interrupt completion callback.
 */
static void scif_rma_completion_cb(void *data)
{
	struct scif_dma_comp_cb *comp_cb = data;

	/* Free DMA Completion CB. */
	if (comp_cb->dst_window)
		scif_rma_local_cpu_copy(comp_cb->dst_offset,
					comp_cb->dst_window,
					comp_cb->temp_buf +
					comp_cb->header_padding,
					comp_cb->len, false);
	scif_unmap_single(comp_cb->temp_phys, comp_cb->sdev,
			  SCIF_KMEM_UNALIGNED_BUF_SIZE);
	if (comp_cb->is_cache)
		kmem_cache_free(unaligned_cache,
				comp_cb->temp_buf_to_free);
	else
		kfree(comp_cb->temp_buf_to_free);
}

/* Copies between temporary buffer and offsets provided in work */
static int
scif_rma_list_dma_copy_unaligned(struct scif_copy_work *work,
				 u8 *temp, struct dma_chan *chan,
				 bool src_local)
{
	struct scif_dma_comp_cb *comp_cb = work->comp_cb;
	dma_addr_t window_dma_addr, temp_dma_addr;
	dma_addr_t temp_phys = comp_cb->temp_phys;
	size_t loop_len, nr_contig_bytes = 0, remaining_len = work->len;
	int offset_in_ca, ret = 0;
	s64 end_offset, offset;
	struct scif_window *window;
	void *window_virt_addr;
	size_t tail_len;
	struct dma_async_tx_descriptor *tx;
	struct dma_device *dev = chan->device;
	dma_cookie_t cookie;

	if (src_local) {
		offset = work->dst_offset;
		window = work->dst_window;
	} else {
		offset = work->src_offset;
		window = work->src_window;
	}

	offset_in_ca = offset & (L1_CACHE_BYTES - 1);
	if (offset_in_ca) {
		loop_len = L1_CACHE_BYTES - offset_in_ca;
		loop_len = min(loop_len, remaining_len);
		window_virt_addr = ioremap_remote(offset, window,
						  loop_len,
						  work->remote_dev,
						  NULL);
		if (!window_virt_addr)
			return -ENOMEM;
		if (src_local)
			scif_unaligned_cpy_toio(window_virt_addr, temp,
						loop_len,
						work->ordered &&
						!(remaining_len - loop_len));
		else
			scif_unaligned_cpy_fromio(temp, window_virt_addr,
						  loop_len, work->ordered &&
						  !(remaining_len - loop_len));
		iounmap_remote(window_virt_addr, loop_len, work);

		offset += loop_len;
		temp += loop_len;
		temp_phys += loop_len;
		remaining_len -= loop_len;
	}

	offset_in_ca = offset & ~PAGE_MASK;
	end_offset = window->offset +
		(window->nr_pages << PAGE_SHIFT);

	tail_len = remaining_len & (L1_CACHE_BYTES - 1);
	remaining_len -= tail_len;
	while (remaining_len) {
		if (offset == end_offset) {
			window = list_next_entry(window, list);
			end_offset = window->offset +
				(window->nr_pages << PAGE_SHIFT);
		}
		if (scif_is_mgmt_node())
			temp_dma_addr = temp_phys;
		else
			/* Fix if we ever enable IOMMU on the card */
			temp_dma_addr = (dma_addr_t)virt_to_phys(temp);
		window_dma_addr = scif_off_to_dma_addr(window, offset,
						       &nr_contig_bytes,
						       NULL);
		loop_len = min(nr_contig_bytes, remaining_len);
		if (src_local) {
			if (work->ordered && !tail_len &&
			    !(remaining_len - loop_len) &&
			    loop_len != L1_CACHE_BYTES) {
				/*
				 * Break up the last chunk of the transfer into
				 * two steps. if there is no tail to guarantee
				 * DMA ordering. SCIF_DMA_POLLING inserts
				 * a status update descriptor in step 1 which
				 * acts as a double sided synchronization fence
				 * for the DMA engine to ensure that the last
				 * cache line in step 2 is updated last.
				 */
				/* Step 1) DMA: Body Length - L1_CACHE_BYTES. */
				tx =
				dev->device_prep_dma_memcpy(chan,
							    window_dma_addr,
							    temp_dma_addr,
							    loop_len -
							    L1_CACHE_BYTES,
							    DMA_PREP_FENCE);
				if (!tx) {
					ret = -ENOMEM;
					goto err;
				}
				cookie = tx->tx_submit(tx);
				if (dma_submit_error(cookie)) {
					ret = -ENOMEM;
					goto err;
				}
				dma_async_issue_pending(chan);
				offset += (loop_len - L1_CACHE_BYTES);
				temp_dma_addr += (loop_len - L1_CACHE_BYTES);
				window_dma_addr += (loop_len - L1_CACHE_BYTES);
				remaining_len -= (loop_len - L1_CACHE_BYTES);
				loop_len = remaining_len;

				/* Step 2) DMA: L1_CACHE_BYTES */
				tx =
				dev->device_prep_dma_memcpy(chan,
							    window_dma_addr,
							    temp_dma_addr,
							    loop_len, 0);
				if (!tx) {
					ret = -ENOMEM;
					goto err;
				}
				cookie = tx->tx_submit(tx);
				if (dma_submit_error(cookie)) {
					ret = -ENOMEM;
					goto err;
				}
				dma_async_issue_pending(chan);
			} else {
				tx =
				dev->device_prep_dma_memcpy(chan,
							    window_dma_addr,
							    temp_dma_addr,
							    loop_len, 0);
				if (!tx) {
					ret = -ENOMEM;
					goto err;
				}
				cookie = tx->tx_submit(tx);
				if (dma_submit_error(cookie)) {
					ret = -ENOMEM;
					goto err;
				}
				dma_async_issue_pending(chan);
			}
		} else {
			tx = dev->device_prep_dma_memcpy(chan, temp_dma_addr,
					window_dma_addr, loop_len, 0);
			if (!tx) {
				ret = -ENOMEM;
				goto err;
			}
			cookie = tx->tx_submit(tx);
			if (dma_submit_error(cookie)) {
				ret = -ENOMEM;
				goto err;
			}
			dma_async_issue_pending(chan);
		}
		if (ret < 0)
			goto err;
		offset += loop_len;
		temp += loop_len;
		temp_phys += loop_len;
		remaining_len -= loop_len;
		offset_in_ca = 0;
	}
	if (tail_len) {
		if (offset == end_offset) {
			window = list_next_entry(window, list);
			end_offset = window->offset +
				(window->nr_pages << PAGE_SHIFT);
		}
		window_virt_addr = ioremap_remote(offset, window, tail_len,
						  work->remote_dev,
						  NULL);
		if (!window_virt_addr)
			return -ENOMEM;
		/*
		 * The CPU copy for the tail bytes must be initiated only once
		 * previous DMA transfers for this endpoint have completed
		 * to guarantee ordering.
		 */
		if (work->ordered) {
			struct scif_dev *rdev = work->remote_dev;

			ret = scif_drain_dma_intr(rdev->sdev, chan);
			if (ret)
				return ret;
		}
		if (src_local)
			scif_unaligned_cpy_toio(window_virt_addr, temp,
						tail_len, work->ordered);
		else
			scif_unaligned_cpy_fromio(temp, window_virt_addr,
						  tail_len, work->ordered);
		iounmap_remote(window_virt_addr, tail_len, work);
	}
	tx = dev->device_prep_dma_memcpy(chan, 0, 0, 0, DMA_PREP_INTERRUPT);
	if (!tx) {
		ret = -ENOMEM;
		return ret;
	}
	tx->callback = &scif_rma_completion_cb;
	tx->callback_param = comp_cb;
	cookie = tx->tx_submit(tx);

	if (dma_submit_error(cookie)) {
		ret = -ENOMEM;
		return ret;
	}
	dma_async_issue_pending(chan);
	return 0;
err:
	dev_err(scif_info.mdev.this_device,
		"%s %d Desc Prog Failed ret %d\n",
		__func__, __LINE__, ret);
	return ret;
}

/*
 * _scif_rma_list_dma_copy_aligned:
 *
 * Traverse all the windows and perform DMA copy.
 */
static int _scif_rma_list_dma_copy_aligned(struct scif_copy_work *work,
					   struct dma_chan *chan)
{
	dma_addr_t src_dma_addr, dst_dma_addr;
	size_t loop_len, remaining_len, src_contig_bytes = 0;
	size_t dst_contig_bytes = 0;
	struct scif_window_iter src_win_iter;
	struct scif_window_iter dst_win_iter;
	s64 end_src_offset, end_dst_offset;
	struct scif_window *src_window = work->src_window;
	struct scif_window *dst_window = work->dst_window;
	s64 src_offset = work->src_offset, dst_offset = work->dst_offset;
	int ret = 0;
	struct dma_async_tx_descriptor *tx;
	struct dma_device *dev = chan->device;
	dma_cookie_t cookie;

	remaining_len = work->len;

	scif_init_window_iter(src_window, &src_win_iter);
	scif_init_window_iter(dst_window, &dst_win_iter);
	end_src_offset = src_window->offset +
		(src_window->nr_pages << PAGE_SHIFT);
	end_dst_offset = dst_window->offset +
		(dst_window->nr_pages << PAGE_SHIFT);
	while (remaining_len) {
		if (src_offset == end_src_offset) {
			src_window = list_next_entry(src_window, list);
			end_src_offset = src_window->offset +
				(src_window->nr_pages << PAGE_SHIFT);
			scif_init_window_iter(src_window, &src_win_iter);
		}
		if (dst_offset == end_dst_offset) {
			dst_window = list_next_entry(dst_window, list);
			end_dst_offset = dst_window->offset +
				(dst_window->nr_pages << PAGE_SHIFT);
			scif_init_window_iter(dst_window, &dst_win_iter);
		}

		/* compute dma addresses for transfer */
		src_dma_addr = scif_off_to_dma_addr(src_window, src_offset,
						    &src_contig_bytes,
						    &src_win_iter);
		dst_dma_addr = scif_off_to_dma_addr(dst_window, dst_offset,
						    &dst_contig_bytes,
						    &dst_win_iter);
		loop_len = min(src_contig_bytes, dst_contig_bytes);
		loop_len = min(loop_len, remaining_len);
		if (work->ordered && !(remaining_len - loop_len)) {
			/*
			 * Break up the last chunk of the transfer into two
			 * steps to ensure that the last byte in step 2 is
			 * updated last.
			 */
			/* Step 1) DMA: Body Length - 1 */
			tx = dev->device_prep_dma_memcpy(chan, dst_dma_addr,
							 src_dma_addr,
							 loop_len - 1,
							 DMA_PREP_FENCE);
			if (!tx) {
				ret = -ENOMEM;
				goto err;
			}
			cookie = tx->tx_submit(tx);
			if (dma_submit_error(cookie)) {
				ret = -ENOMEM;
				goto err;
			}
			src_offset += (loop_len - 1);
			dst_offset += (loop_len - 1);
			src_dma_addr += (loop_len - 1);
			dst_dma_addr += (loop_len - 1);
			remaining_len -= (loop_len - 1);
			loop_len = remaining_len;

			/* Step 2) DMA: 1 BYTES */
			tx = dev->device_prep_dma_memcpy(chan, dst_dma_addr,
					src_dma_addr, loop_len, 0);
			if (!tx) {
				ret = -ENOMEM;
				goto err;
			}
			cookie = tx->tx_submit(tx);
			if (dma_submit_error(cookie)) {
				ret = -ENOMEM;
				goto err;
			}
			dma_async_issue_pending(chan);
		} else {
			tx = dev->device_prep_dma_memcpy(chan, dst_dma_addr,
					src_dma_addr, loop_len, 0);
			if (!tx) {
				ret = -ENOMEM;
				goto err;
			}
			cookie = tx->tx_submit(tx);
			if (dma_submit_error(cookie)) {
				ret = -ENOMEM;
				goto err;
			}
		}
		src_offset += loop_len;
		dst_offset += loop_len;
		remaining_len -= loop_len;
	}
	return ret;
err:
	dev_err(scif_info.mdev.this_device,
		"%s %d Desc Prog Failed ret %d\n",
		__func__, __LINE__, ret);
	return ret;
}

/*
 * scif_rma_list_dma_copy_aligned:
 *
 * Traverse all the windows and perform DMA copy.
 */
static int scif_rma_list_dma_copy_aligned(struct scif_copy_work *work,
					  struct dma_chan *chan)
{
	dma_addr_t src_dma_addr, dst_dma_addr;
	size_t loop_len, remaining_len, tail_len, src_contig_bytes = 0;
	size_t dst_contig_bytes = 0;
	int src_cache_off;
	s64 end_src_offset, end_dst_offset;
	struct scif_window_iter src_win_iter;
	struct scif_window_iter dst_win_iter;
	void *src_virt, *dst_virt;
	struct scif_window *src_window = work->src_window;
	struct scif_window *dst_window = work->dst_window;
	s64 src_offset = work->src_offset, dst_offset = work->dst_offset;
	int ret = 0;
	struct dma_async_tx_descriptor *tx;
	struct dma_device *dev = chan->device;
	dma_cookie_t cookie;

	remaining_len = work->len;
	scif_init_window_iter(src_window, &src_win_iter);
	scif_init_window_iter(dst_window, &dst_win_iter);

	src_cache_off = src_offset & (L1_CACHE_BYTES - 1);
	if (src_cache_off != 0) {
		/* Head */
		loop_len = L1_CACHE_BYTES - src_cache_off;
		loop_len = min(loop_len, remaining_len);
		src_dma_addr = __scif_off_to_dma_addr(src_window, src_offset);
		dst_dma_addr = __scif_off_to_dma_addr(dst_window, dst_offset);
		if (src_window->type == SCIF_WINDOW_SELF)
			src_virt = _get_local_va(src_offset, src_window,
						 loop_len);
		else
			src_virt = ioremap_remote(src_offset, src_window,
						  loop_len,
						  work->remote_dev, NULL);
		if (!src_virt)
			return -ENOMEM;
		if (dst_window->type == SCIF_WINDOW_SELF)
			dst_virt = _get_local_va(dst_offset, dst_window,
						 loop_len);
		else
			dst_virt = ioremap_remote(dst_offset, dst_window,
						  loop_len,
						  work->remote_dev, NULL);
		if (!dst_virt) {
			if (src_window->type != SCIF_WINDOW_SELF)
				iounmap_remote(src_virt, loop_len, work);
			return -ENOMEM;
		}
		if (src_window->type == SCIF_WINDOW_SELF)
			scif_unaligned_cpy_toio(dst_virt, src_virt, loop_len,
						remaining_len == loop_len ?
						work->ordered : false);
		else
			scif_unaligned_cpy_fromio(dst_virt, src_virt, loop_len,
						  remaining_len == loop_len ?
						  work->ordered : false);
		if (src_window->type != SCIF_WINDOW_SELF)
			iounmap_remote(src_virt, loop_len, work);
		if (dst_window->type != SCIF_WINDOW_SELF)
			iounmap_remote(dst_virt, loop_len, work);
		src_offset += loop_len;
		dst_offset += loop_len;
		remaining_len -= loop_len;
	}

	end_src_offset = src_window->offset +
		(src_window->nr_pages << PAGE_SHIFT);
	end_dst_offset = dst_window->offset +
		(dst_window->nr_pages << PAGE_SHIFT);
	tail_len = remaining_len & (L1_CACHE_BYTES - 1);
	remaining_len -= tail_len;
	while (remaining_len) {
		if (src_offset == end_src_offset) {
			src_window = list_next_entry(src_window, list);
			end_src_offset = src_window->offset +
				(src_window->nr_pages << PAGE_SHIFT);
			scif_init_window_iter(src_window, &src_win_iter);
		}
		if (dst_offset == end_dst_offset) {
			dst_window = list_next_entry(dst_window, list);
			end_dst_offset = dst_window->offset +
				(dst_window->nr_pages << PAGE_SHIFT);
			scif_init_window_iter(dst_window, &dst_win_iter);
		}

		/* compute dma addresses for transfer */
		src_dma_addr = scif_off_to_dma_addr(src_window, src_offset,
						    &src_contig_bytes,
						    &src_win_iter);
		dst_dma_addr = scif_off_to_dma_addr(dst_window, dst_offset,
						    &dst_contig_bytes,
						    &dst_win_iter);
		loop_len = min(src_contig_bytes, dst_contig_bytes);
		loop_len = min(loop_len, remaining_len);
		if (work->ordered && !tail_len &&
		    !(remaining_len - loop_len)) {
			/*
			 * Break up the last chunk of the transfer into two
			 * steps. if there is no tail to gurantee DMA ordering.
			 * Passing SCIF_DMA_POLLING inserts a status update
			 * descriptor in step 1 which acts as a double sided
			 * synchronization fence for the DMA engine to ensure
			 * that the last cache line in step 2 is updated last.
			 */
			/* Step 1) DMA: Body Length - L1_CACHE_BYTES. */
			tx = dev->device_prep_dma_memcpy(chan, dst_dma_addr,
							 src_dma_addr,
							 loop_len -
							 L1_CACHE_BYTES,
							 DMA_PREP_FENCE);
			if (!tx) {
				ret = -ENOMEM;
				goto err;
			}
			cookie = tx->tx_submit(tx);
			if (dma_submit_error(cookie)) {
				ret = -ENOMEM;
				goto err;
			}
			dma_async_issue_pending(chan);
			src_offset += (loop_len - L1_CACHE_BYTES);
			dst_offset += (loop_len - L1_CACHE_BYTES);
			src_dma_addr += (loop_len - L1_CACHE_BYTES);
			dst_dma_addr += (loop_len - L1_CACHE_BYTES);
			remaining_len -= (loop_len - L1_CACHE_BYTES);
			loop_len = remaining_len;

			/* Step 2) DMA: L1_CACHE_BYTES */
			tx = dev->device_prep_dma_memcpy(chan, dst_dma_addr,
							 src_dma_addr,
							 loop_len, 0);
			if (!tx) {
				ret = -ENOMEM;
				goto err;
			}
			cookie = tx->tx_submit(tx);
			if (dma_submit_error(cookie)) {
				ret = -ENOMEM;
				goto err;
			}
			dma_async_issue_pending(chan);
		} else {
			tx = dev->device_prep_dma_memcpy(chan, dst_dma_addr,
							 src_dma_addr,
							 loop_len, 0);
			if (!tx) {
				ret = -ENOMEM;
				goto err;
			}
			cookie = tx->tx_submit(tx);
			if (dma_submit_error(cookie)) {
				ret = -ENOMEM;
				goto err;
			}
			dma_async_issue_pending(chan);
		}
		src_offset += loop_len;
		dst_offset += loop_len;
		remaining_len -= loop_len;
	}
	remaining_len = tail_len;
	if (remaining_len) {
		loop_len = remaining_len;
		if (src_offset == end_src_offset)
			src_window = list_next_entry(src_window, list);
		if (dst_offset == end_dst_offset)
			dst_window = list_next_entry(dst_window, list);

		src_dma_addr = __scif_off_to_dma_addr(src_window, src_offset);
		dst_dma_addr = __scif_off_to_dma_addr(dst_window, dst_offset);
		/*
		 * The CPU copy for the tail bytes must be initiated only once
		 * previous DMA transfers for this endpoint have completed to
		 * guarantee ordering.
		 */
		if (work->ordered) {
			struct scif_dev *rdev = work->remote_dev;

			ret = scif_drain_dma_poll(rdev->sdev, chan);
			if (ret)
				return ret;
		}
		if (src_window->type == SCIF_WINDOW_SELF)
			src_virt = _get_local_va(src_offset, src_window,
						 loop_len);
		else
			src_virt = ioremap_remote(src_offset, src_window,
						  loop_len,
						  work->remote_dev, NULL);
		if (!src_virt)
			return -ENOMEM;

		if (dst_window->type == SCIF_WINDOW_SELF)
			dst_virt = _get_local_va(dst_offset, dst_window,
						 loop_len);
		else
			dst_virt = ioremap_remote(dst_offset, dst_window,
						  loop_len,
						  work->remote_dev, NULL);
		if (!dst_virt) {
			if (src_window->type != SCIF_WINDOW_SELF)
				iounmap_remote(src_virt, loop_len, work);
			return -ENOMEM;
		}

		if (src_window->type == SCIF_WINDOW_SELF)
			scif_unaligned_cpy_toio(dst_virt, src_virt, loop_len,
						work->ordered);
		else
			scif_unaligned_cpy_fromio(dst_virt, src_virt,
						  loop_len, work->ordered);
		if (src_window->type != SCIF_WINDOW_SELF)
			iounmap_remote(src_virt, loop_len, work);

		if (dst_window->type != SCIF_WINDOW_SELF)
			iounmap_remote(dst_virt, loop_len, work);
		remaining_len -= loop_len;
	}
	return ret;
err:
	dev_err(scif_info.mdev.this_device,
		"%s %d Desc Prog Failed ret %d\n",
		__func__, __LINE__, ret);
	return ret;
}

/*
 * scif_rma_list_cpu_copy:
 *
 * Traverse all the windows and perform CPU copy.
 */
static int scif_rma_list_cpu_copy(struct scif_copy_work *work)
{
	void *src_virt, *dst_virt;
	size_t loop_len, remaining_len;
	int src_page_off, dst_page_off;
	s64 src_offset = work->src_offset, dst_offset = work->dst_offset;
	struct scif_window *src_window = work->src_window;
	struct scif_window *dst_window = work->dst_window;
	s64 end_src_offset, end_dst_offset;
	int ret = 0;
	struct scif_window_iter src_win_iter;
	struct scif_window_iter dst_win_iter;

	remaining_len = work->len;

	scif_init_window_iter(src_window, &src_win_iter);
	scif_init_window_iter(dst_window, &dst_win_iter);
	while (remaining_len) {
		src_page_off = src_offset & ~PAGE_MASK;
		dst_page_off = dst_offset & ~PAGE_MASK;
		loop_len = min(PAGE_SIZE -
			       max(src_page_off, dst_page_off),
			       remaining_len);

		if (src_window->type == SCIF_WINDOW_SELF)
			src_virt = _get_local_va(src_offset, src_window,
						 loop_len);
		else
			src_virt = ioremap_remote(src_offset, src_window,
						  loop_len,
						  work->remote_dev,
						  &src_win_iter);
		if (!src_virt) {
			ret = -ENOMEM;
			goto error;
		}

		if (dst_window->type == SCIF_WINDOW_SELF)
			dst_virt = _get_local_va(dst_offset, dst_window,
						 loop_len);
		else
			dst_virt = ioremap_remote(dst_offset, dst_window,
						  loop_len,
						  work->remote_dev,
						  &dst_win_iter);
		if (!dst_virt) {
			if (src_window->type == SCIF_WINDOW_PEER)
				iounmap_remote(src_virt, loop_len, work);
			ret = -ENOMEM;
			goto error;
		}

		if (work->loopback) {
			memcpy(dst_virt, src_virt, loop_len);
		} else {
			if (src_window->type == SCIF_WINDOW_SELF)
				memcpy_toio((void __iomem __force *)dst_virt,
					    src_virt, loop_len);
			else
				memcpy_fromio(dst_virt,
					      (void __iomem __force *)src_virt,
					      loop_len);
		}
		if (src_window->type == SCIF_WINDOW_PEER)
			iounmap_remote(src_virt, loop_len, work);

		if (dst_window->type == SCIF_WINDOW_PEER)
			iounmap_remote(dst_virt, loop_len, work);

		src_offset += loop_len;
		dst_offset += loop_len;
		remaining_len -= loop_len;
		if (remaining_len) {
			end_src_offset = src_window->offset +
				(src_window->nr_pages << PAGE_SHIFT);
			end_dst_offset = dst_window->offset +
				(dst_window->nr_pages << PAGE_SHIFT);
			if (src_offset == end_src_offset) {
				src_window = list_next_entry(src_window, list);
				scif_init_window_iter(src_window,
						      &src_win_iter);
			}
			if (dst_offset == end_dst_offset) {
				dst_window = list_next_entry(dst_window, list);
				scif_init_window_iter(dst_window,
						      &dst_win_iter);
			}
		}
	}
error:
	return ret;
}

static int scif_rma_list_dma_copy_wrapper(struct scif_endpt *epd,
					  struct scif_copy_work *work,
					  struct dma_chan *chan, off_t loffset)
{
	int src_cache_off, dst_cache_off;
	s64 src_offset = work->src_offset, dst_offset = work->dst_offset;
	u8 *temp = NULL;
	bool src_local = true, dst_local = false;
	struct scif_dma_comp_cb *comp_cb;
	dma_addr_t src_dma_addr, dst_dma_addr;
	int err;

	if (is_dma_copy_aligned(chan->device, 1, 1, 1))
		return _scif_rma_list_dma_copy_aligned(work, chan);

	src_cache_off = src_offset & (L1_CACHE_BYTES - 1);
	dst_cache_off = dst_offset & (L1_CACHE_BYTES - 1);

	if (dst_cache_off == src_cache_off)
		return scif_rma_list_dma_copy_aligned(work, chan);

	if (work->loopback)
		return scif_rma_list_cpu_copy(work);
	src_dma_addr = __scif_off_to_dma_addr(work->src_window, src_offset);
	dst_dma_addr = __scif_off_to_dma_addr(work->dst_window, dst_offset);
	src_local = work->src_window->type == SCIF_WINDOW_SELF;
	dst_local = work->dst_window->type == SCIF_WINDOW_SELF;

	dst_local = dst_local;
	/* Allocate dma_completion cb */
	comp_cb = kzalloc(sizeof(*comp_cb), GFP_KERNEL);
	if (!comp_cb)
		goto error;

	work->comp_cb = comp_cb;
	comp_cb->cb_cookie = comp_cb;
	comp_cb->dma_completion_func = &scif_rma_completion_cb;

	if (work->len + (L1_CACHE_BYTES << 1) < SCIF_KMEM_UNALIGNED_BUF_SIZE) {
		comp_cb->is_cache = false;
		/* Allocate padding bytes to align to a cache line */
		temp = kmalloc(work->len + (L1_CACHE_BYTES << 1),
			       GFP_KERNEL);
		if (!temp)
			goto free_comp_cb;
		comp_cb->temp_buf_to_free = temp;
		/* kmalloc(..) does not guarantee cache line alignment */
		if (!IS_ALIGNED((u64)temp, L1_CACHE_BYTES))
			temp = PTR_ALIGN(temp, L1_CACHE_BYTES);
	} else {
		comp_cb->is_cache = true;
		temp = kmem_cache_alloc(unaligned_cache, GFP_KERNEL);
		if (!temp)
			goto free_comp_cb;
		comp_cb->temp_buf_to_free = temp;
	}

	if (src_local) {
		temp += dst_cache_off;
		scif_rma_local_cpu_copy(work->src_offset, work->src_window,
					temp, work->len, true);
	} else {
		comp_cb->dst_window = work->dst_window;
		comp_cb->dst_offset = work->dst_offset;
		work->src_offset = work->src_offset - src_cache_off;
		comp_cb->len = work->len;
		work->len = ALIGN(work->len + src_cache_off, L1_CACHE_BYTES);
		comp_cb->header_padding = src_cache_off;
	}
	comp_cb->temp_buf = temp;

	err = scif_map_single(&comp_cb->temp_phys, temp,
			      work->remote_dev, SCIF_KMEM_UNALIGNED_BUF_SIZE);
	if (err)
		goto free_temp_buf;
	comp_cb->sdev = work->remote_dev;
	if (scif_rma_list_dma_copy_unaligned(work, temp, chan, src_local) < 0)
		goto free_temp_buf;
	if (!src_local)
		work->fence_type = SCIF_DMA_INTR;
	return 0;
free_temp_buf:
	if (comp_cb->is_cache)
		kmem_cache_free(unaligned_cache, comp_cb->temp_buf_to_free);
	else
		kfree(comp_cb->temp_buf_to_free);
free_comp_cb:
	kfree(comp_cb);
error:
	return -ENOMEM;
}

/**
 * scif_rma_copy:
 * @epd: end point descriptor.
 * @loffset: offset in local registered address space to/from which to copy
 * @addr: user virtual address to/from which to copy
 * @len: length of range to copy
 * @roffset: offset in remote registered address space to/from which to copy
 * @flags: flags
 * @dir: LOCAL->REMOTE or vice versa.
 * @last_chunk: true if this is the last chunk of a larger transfer
 *
 * Validate parameters, check if src/dst registered ranges requested for copy
 * are valid and initiate either CPU or DMA copy.
 */
static int scif_rma_copy(scif_epd_t epd, off_t loffset, unsigned long addr,
			 size_t len, off_t roffset, int flags,
			 enum scif_rma_dir dir, bool last_chunk)
{
	struct scif_endpt *ep = (struct scif_endpt *)epd;
	struct scif_rma_req remote_req;
	struct scif_rma_req req;
	struct scif_window *local_window = NULL;
	struct scif_window *remote_window = NULL;
	struct scif_copy_work copy_work;
	bool loopback;
	int err = 0;
	struct dma_chan *chan;
	struct scif_mmu_notif *mmn = NULL;
	bool cache = false;
	struct device *spdev;

	err = scif_verify_epd(ep);
	if (err)
		return err;

	if (flags && !(flags & (SCIF_RMA_USECPU | SCIF_RMA_USECACHE |
				SCIF_RMA_SYNC | SCIF_RMA_ORDERED)))
		return -EINVAL;

	loopback = scifdev_self(ep->remote_dev) ? true : false;
	copy_work.fence_type = ((flags & SCIF_RMA_SYNC) && last_chunk) ?
				SCIF_DMA_POLL : 0;
	copy_work.ordered = !!((flags & SCIF_RMA_ORDERED) && last_chunk);

	/* Use CPU for Mgmt node <-> Mgmt node copies */
	if (loopback && scif_is_mgmt_node()) {
		flags |= SCIF_RMA_USECPU;
		copy_work.fence_type = 0x0;
	}

	cache = scif_is_set_reg_cache(flags);

	remote_req.out_window = &remote_window;
	remote_req.offset = roffset;
	remote_req.nr_bytes = len;
	/*
	 * If transfer is from local to remote then the remote window
	 * must be writeable and vice versa.
	 */
	remote_req.prot = dir == SCIF_LOCAL_TO_REMOTE ? VM_WRITE : VM_READ;
	remote_req.type = SCIF_WINDOW_PARTIAL;
	remote_req.head = &ep->rma_info.remote_reg_list;

	spdev = scif_get_peer_dev(ep->remote_dev);
	if (IS_ERR(spdev)) {
		err = PTR_ERR(spdev);
		return err;
	}

	if (addr && cache) {
		mutex_lock(&ep->rma_info.mmn_lock);
		mmn = scif_find_mmu_notifier(current->mm, &ep->rma_info);
		if (!mmn)
			mmn = scif_add_mmu_notifier(current->mm, ep);
		mutex_unlock(&ep->rma_info.mmn_lock);
		if (IS_ERR(mmn)) {
			scif_put_peer_dev(spdev);
			return PTR_ERR(mmn);
		}
		cache = cache && !scif_rma_tc_can_cache(ep, len);
	}
	mutex_lock(&ep->rma_info.rma_lock);
	if (addr) {
		req.out_window = &local_window;
		req.nr_bytes = ALIGN(len + (addr & ~PAGE_MASK),
				     PAGE_SIZE);
		req.va_for_temp = addr & PAGE_MASK;
		req.prot = (dir == SCIF_LOCAL_TO_REMOTE ?
			    VM_READ : VM_WRITE | VM_READ);
		/* Does a valid local window exist? */
		if (mmn) {
			spin_lock(&ep->rma_info.tc_lock);
			req.head = &mmn->tc_reg_list;
			err = scif_query_tcw(ep, &req);
			spin_unlock(&ep->rma_info.tc_lock);
		}
		if (!mmn || err) {
			err = scif_register_temp(epd, req.va_for_temp,
						 req.nr_bytes, req.prot,
						 &loffset, &local_window);
			if (err) {
				mutex_unlock(&ep->rma_info.rma_lock);
				goto error;
			}
			if (!cache)
				goto skip_cache;
			atomic_inc(&ep->rma_info.tcw_refcount);
			atomic_add_return(local_window->nr_pages,
					  &ep->rma_info.tcw_total_pages);
			if (mmn) {
				spin_lock(&ep->rma_info.tc_lock);
				scif_insert_tcw(local_window,
						&mmn->tc_reg_list);
				spin_unlock(&ep->rma_info.tc_lock);
			}
		}
skip_cache:
		loffset = local_window->offset +
				(addr - local_window->va_for_temp);
	} else {
		req.out_window = &local_window;
		req.offset = loffset;
		/*
		 * If transfer is from local to remote then the self window
		 * must be readable and vice versa.
		 */
		req.prot = dir == SCIF_LOCAL_TO_REMOTE ? VM_READ : VM_WRITE;
		req.nr_bytes = len;
		req.type = SCIF_WINDOW_PARTIAL;
		req.head = &ep->rma_info.reg_list;
		/* Does a valid local window exist? */
		err = scif_query_window(&req);
		if (err) {
			mutex_unlock(&ep->rma_info.rma_lock);
			goto error;
		}
	}

	/* Does a valid remote window exist? */
	err = scif_query_window(&remote_req);
	if (err) {
		mutex_unlock(&ep->rma_info.rma_lock);
		goto error;
	}

	/*
	 * Prepare copy_work for submitting work to the DMA kernel thread
	 * or CPU copy routine.
	 */
	copy_work.len = len;
	copy_work.loopback = loopback;
	copy_work.remote_dev = ep->remote_dev;
	if (dir == SCIF_LOCAL_TO_REMOTE) {
		copy_work.src_offset = loffset;
		copy_work.src_window = local_window;
		copy_work.dst_offset = roffset;
		copy_work.dst_window = remote_window;
	} else {
		copy_work.src_offset = roffset;
		copy_work.src_window = remote_window;
		copy_work.dst_offset = loffset;
		copy_work.dst_window = local_window;
	}

	if (flags & SCIF_RMA_USECPU) {
		scif_rma_list_cpu_copy(&copy_work);
	} else {
		chan = ep->rma_info.dma_chan;
		err = scif_rma_list_dma_copy_wrapper(epd, &copy_work,
						     chan, loffset);
	}
	if (addr && !cache)
		atomic_inc(&ep->rma_info.tw_refcount);

	mutex_unlock(&ep->rma_info.rma_lock);

	if (last_chunk) {
		struct scif_dev *rdev = ep->remote_dev;

		if (copy_work.fence_type == SCIF_DMA_POLL)
			err = scif_drain_dma_poll(rdev->sdev,
						  ep->rma_info.dma_chan);
		else if (copy_work.fence_type == SCIF_DMA_INTR)
			err = scif_drain_dma_intr(rdev->sdev,
						  ep->rma_info.dma_chan);
	}

	if (addr && !cache)
		scif_queue_for_cleanup(local_window, &scif_info.rma);
	scif_put_peer_dev(spdev);
	return err;
error:
	if (err) {
		if (addr && local_window && !cache)
			scif_destroy_window(ep, local_window);
		dev_err(scif_info.mdev.this_device,
			"%s %d err %d len 0x%lx\n",
			__func__, __LINE__, err, len);
	}
	scif_put_peer_dev(spdev);
	return err;
}

int scif_readfrom(scif_epd_t epd, off_t loffset, size_t len,
		  off_t roffset, int flags)
{
	int err;

	dev_dbg(scif_info.mdev.this_device,
		"SCIFAPI readfrom: ep %p loffset 0x%lx len 0x%lx offset 0x%lx flags 0x%x\n",
		epd, loffset, len, roffset, flags);
	if (scif_unaligned(loffset, roffset)) {
		while (len > SCIF_MAX_UNALIGNED_BUF_SIZE) {
			err = scif_rma_copy(epd, loffset, 0x0,
					    SCIF_MAX_UNALIGNED_BUF_SIZE,
					    roffset, flags,
					    SCIF_REMOTE_TO_LOCAL, false);
			if (err)
				goto readfrom_err;
			loffset += SCIF_MAX_UNALIGNED_BUF_SIZE;
			roffset += SCIF_MAX_UNALIGNED_BUF_SIZE;
			len -= SCIF_MAX_UNALIGNED_BUF_SIZE;
		}
	}
	err = scif_rma_copy(epd, loffset, 0x0, len,
			    roffset, flags, SCIF_REMOTE_TO_LOCAL, true);
readfrom_err:
	return err;
}
EXPORT_SYMBOL_GPL(scif_readfrom);

int scif_writeto(scif_epd_t epd, off_t loffset, size_t len,
		 off_t roffset, int flags)
{
	int err;

	dev_dbg(scif_info.mdev.this_device,
		"SCIFAPI writeto: ep %p loffset 0x%lx len 0x%lx roffset 0x%lx flags 0x%x\n",
		epd, loffset, len, roffset, flags);
	if (scif_unaligned(loffset, roffset)) {
		while (len > SCIF_MAX_UNALIGNED_BUF_SIZE) {
			err = scif_rma_copy(epd, loffset, 0x0,
					    SCIF_MAX_UNALIGNED_BUF_SIZE,
					    roffset, flags,
					    SCIF_LOCAL_TO_REMOTE, false);
			if (err)
				goto writeto_err;
			loffset += SCIF_MAX_UNALIGNED_BUF_SIZE;
			roffset += SCIF_MAX_UNALIGNED_BUF_SIZE;
			len -= SCIF_MAX_UNALIGNED_BUF_SIZE;
		}
	}
	err = scif_rma_copy(epd, loffset, 0x0, len,
			    roffset, flags, SCIF_LOCAL_TO_REMOTE, true);
writeto_err:
	return err;
}
EXPORT_SYMBOL_GPL(scif_writeto);

int scif_vreadfrom(scif_epd_t epd, void *addr, size_t len,
		   off_t roffset, int flags)
{
	int err;

	dev_dbg(scif_info.mdev.this_device,
		"SCIFAPI vreadfrom: ep %p addr %p len 0x%lx roffset 0x%lx flags 0x%x\n",
		epd, addr, len, roffset, flags);
	if (scif_unaligned((off_t __force)addr, roffset)) {
		if (len > SCIF_MAX_UNALIGNED_BUF_SIZE)
			flags &= ~SCIF_RMA_USECACHE;

		while (len > SCIF_MAX_UNALIGNED_BUF_SIZE) {
			err = scif_rma_copy(epd, 0, (u64)addr,
					    SCIF_MAX_UNALIGNED_BUF_SIZE,
					    roffset, flags,
					    SCIF_REMOTE_TO_LOCAL, false);
			if (err)
				goto vreadfrom_err;
			addr += SCIF_MAX_UNALIGNED_BUF_SIZE;
			roffset += SCIF_MAX_UNALIGNED_BUF_SIZE;
			len -= SCIF_MAX_UNALIGNED_BUF_SIZE;
		}
	}
	err = scif_rma_copy(epd, 0, (u64)addr, len,
			    roffset, flags, SCIF_REMOTE_TO_LOCAL, true);
vreadfrom_err:
	return err;
}
EXPORT_SYMBOL_GPL(scif_vreadfrom);

int scif_vwriteto(scif_epd_t epd, void *addr, size_t len,
		  off_t roffset, int flags)
{
	int err;

	dev_dbg(scif_info.mdev.this_device,
		"SCIFAPI vwriteto: ep %p addr %p len 0x%lx roffset 0x%lx flags 0x%x\n",
		epd, addr, len, roffset, flags);
	if (scif_unaligned((off_t __force)addr, roffset)) {
		if (len > SCIF_MAX_UNALIGNED_BUF_SIZE)
			flags &= ~SCIF_RMA_USECACHE;

		while (len > SCIF_MAX_UNALIGNED_BUF_SIZE) {
			err = scif_rma_copy(epd, 0, (u64)addr,
					    SCIF_MAX_UNALIGNED_BUF_SIZE,
					    roffset, flags,
					    SCIF_LOCAL_TO_REMOTE, false);
			if (err)
				goto vwriteto_err;
			addr += SCIF_MAX_UNALIGNED_BUF_SIZE;
			roffset += SCIF_MAX_UNALIGNED_BUF_SIZE;
			len -= SCIF_MAX_UNALIGNED_BUF_SIZE;
		}
	}
	err = scif_rma_copy(epd, 0, (u64)addr, len,
			    roffset, flags, SCIF_LOCAL_TO_REMOTE, true);
vwriteto_err:
	return err;
}
EXPORT_SYMBOL_GPL(scif_vwriteto);
