summaryrefslogtreecommitdiff
path: root/drivers/misc/mic/scif/scif_fence.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mic/scif/scif_fence.c')
-rw-r--r--drivers/misc/mic/scif/scif_fence.c783
1 files changed, 0 insertions, 783 deletions
diff --git a/drivers/misc/mic/scif/scif_fence.c b/drivers/misc/mic/scif/scif_fence.c
deleted file mode 100644
index 4fedf6183951..000000000000
--- a/drivers/misc/mic/scif/scif_fence.c
+++ /dev/null
@@ -1,783 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Intel MIC Platform Software Stack (MPSS)
- *
- * Copyright(c) 2015 Intel Corporation.
- *
- * Intel SCIF driver.
- */
-
-#include "scif_main.h"
-
-/**
- * scif_recv_mark: Handle SCIF_MARK request
- * @scifdev: SCIF device
- * @msg: Interrupt message
- *
- * The peer has requested a mark.
- */
-void scif_recv_mark(struct scif_dev *scifdev, struct scifmsg *msg)
-{
- struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
- int mark = 0;
- int err;
-
- err = _scif_fence_mark(ep, &mark);
- if (err)
- msg->uop = SCIF_MARK_NACK;
- else
- msg->uop = SCIF_MARK_ACK;
- msg->payload[0] = ep->remote_ep;
- msg->payload[2] = mark;
- scif_nodeqp_send(ep->remote_dev, msg);
-}
-
-/**
- * scif_recv_mark_resp: Handle SCIF_MARK_(N)ACK messages.
- * @scifdev: SCIF device
- * @msg: Interrupt message
- *
- * The peer has responded to a SCIF_MARK message.
- */
-void scif_recv_mark_resp(struct scif_dev *scifdev, struct scifmsg *msg)
-{
- struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
- struct scif_fence_info *fence_req =
- (struct scif_fence_info *)msg->payload[1];
-
- mutex_lock(&ep->rma_info.rma_lock);
- if (msg->uop == SCIF_MARK_ACK) {
- fence_req->state = OP_COMPLETED;
- fence_req->dma_mark = (int)msg->payload[2];
- } else {
- fence_req->state = OP_FAILED;
- }
- mutex_unlock(&ep->rma_info.rma_lock);
- complete(&fence_req->comp);
-}
-
-/**
- * scif_recv_wait: Handle SCIF_WAIT request
- * @scifdev: SCIF device
- * @msg: Interrupt message
- *
- * The peer has requested waiting on a fence.
- */
-void scif_recv_wait(struct scif_dev *scifdev, struct scifmsg *msg)
-{
- struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
- struct scif_remote_fence_info *fence;
-
- /*
- * Allocate structure for remote fence information and
- * send a NACK if the allocation failed. The peer will
- * return ENOMEM upon receiving a NACK.
- */
- fence = kmalloc(sizeof(*fence), GFP_KERNEL);
- if (!fence) {
- msg->payload[0] = ep->remote_ep;
- msg->uop = SCIF_WAIT_NACK;
- scif_nodeqp_send(ep->remote_dev, msg);
- return;
- }
-
- /* Prepare the fence request */
- memcpy(&fence->msg, msg, sizeof(struct scifmsg));
- INIT_LIST_HEAD(&fence->list);
-
- /* Insert to the global remote fence request list */
- mutex_lock(&scif_info.fencelock);
- atomic_inc(&ep->rma_info.fence_refcount);
- list_add_tail(&fence->list, &scif_info.fence);
- mutex_unlock(&scif_info.fencelock);
-
- schedule_work(&scif_info.misc_work);
-}
-
-/**
- * scif_recv_wait_resp: Handle SCIF_WAIT_(N)ACK messages.
- * @scifdev: SCIF device
- * @msg: Interrupt message
- *
- * The peer has responded to a SCIF_WAIT message.
- */
-void scif_recv_wait_resp(struct scif_dev *scifdev, struct scifmsg *msg)
-{
- struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
- struct scif_fence_info *fence_req =
- (struct scif_fence_info *)msg->payload[1];
-
- mutex_lock(&ep->rma_info.rma_lock);
- if (msg->uop == SCIF_WAIT_ACK)
- fence_req->state = OP_COMPLETED;
- else
- fence_req->state = OP_FAILED;
- mutex_unlock(&ep->rma_info.rma_lock);
- complete(&fence_req->comp);
-}
-
-/**
- * scif_recv_sig_local: Handle SCIF_SIG_LOCAL request
- * @scifdev: SCIF device
- * @msg: Interrupt message
- *
- * The peer has requested a signal on a local offset.
- */
-void scif_recv_sig_local(struct scif_dev *scifdev, struct scifmsg *msg)
-{
- struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
- int err;
-
- err = scif_prog_signal(ep, msg->payload[1], msg->payload[2],
- SCIF_WINDOW_SELF);
- if (err)
- msg->uop = SCIF_SIG_NACK;
- else
- msg->uop = SCIF_SIG_ACK;
- msg->payload[0] = ep->remote_ep;
- scif_nodeqp_send(ep->remote_dev, msg);
-}
-
-/**
- * scif_recv_sig_remote: Handle SCIF_SIGNAL_REMOTE request
- * @scifdev: SCIF device
- * @msg: Interrupt message
- *
- * The peer has requested a signal on a remote offset.
- */
-void scif_recv_sig_remote(struct scif_dev *scifdev, struct scifmsg *msg)
-{
- struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
- int err;
-
- err = scif_prog_signal(ep, msg->payload[1], msg->payload[2],
- SCIF_WINDOW_PEER);
- if (err)
- msg->uop = SCIF_SIG_NACK;
- else
- msg->uop = SCIF_SIG_ACK;
- msg->payload[0] = ep->remote_ep;
- scif_nodeqp_send(ep->remote_dev, msg);
-}
-
-/**
- * scif_recv_sig_resp: Handle SCIF_SIG_(N)ACK messages.
- * @scifdev: SCIF device
- * @msg: Interrupt message
- *
- * The peer has responded to a signal request.
- */
-void scif_recv_sig_resp(struct scif_dev *scifdev, struct scifmsg *msg)
-{
- struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
- struct scif_fence_info *fence_req =
- (struct scif_fence_info *)msg->payload[3];
-
- mutex_lock(&ep->rma_info.rma_lock);
- if (msg->uop == SCIF_SIG_ACK)
- fence_req->state = OP_COMPLETED;
- else
- fence_req->state = OP_FAILED;
- mutex_unlock(&ep->rma_info.rma_lock);
- complete(&fence_req->comp);
-}
-
-static inline void *scif_get_local_va(off_t off, struct scif_window *window)
-{
- struct page **pages = window->pinned_pages->pages;
- int page_nr = (off - window->offset) >> PAGE_SHIFT;
- off_t page_off = off & ~PAGE_MASK;
-
- return page_address(pages[page_nr]) + page_off;
-}
-
-static void scif_prog_signal_cb(void *arg)
-{
- struct scif_cb_arg *cb_arg = arg;
-
- dma_pool_free(cb_arg->ep->remote_dev->signal_pool, cb_arg->status,
- cb_arg->src_dma_addr);
- kfree(cb_arg);
-}
-
-static int _scif_prog_signal(scif_epd_t epd, dma_addr_t dst, u64 val)
-{
- struct scif_endpt *ep = (struct scif_endpt *)epd;
- struct dma_chan *chan = ep->rma_info.dma_chan;
- struct dma_device *ddev = chan->device;
- bool x100 = !is_dma_copy_aligned(chan->device, 1, 1, 1);
- struct dma_async_tx_descriptor *tx;
- struct scif_status *status = NULL;
- struct scif_cb_arg *cb_arg = NULL;
- dma_addr_t src;
- dma_cookie_t cookie;
- int err;
-
- tx = ddev->device_prep_dma_memcpy(chan, 0, 0, 0, DMA_PREP_FENCE);
- if (!tx) {
- err = -ENOMEM;
- dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
- __func__, __LINE__, err);
- goto alloc_fail;
- }
- cookie = tx->tx_submit(tx);
- if (dma_submit_error(cookie)) {
- err = (int)cookie;
- dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
- __func__, __LINE__, err);
- goto alloc_fail;
- }
- dma_async_issue_pending(chan);
- if (x100) {
- /*
- * For X100 use the status descriptor to write the value to
- * the destination.
- */
- tx = ddev->device_prep_dma_imm_data(chan, dst, val, 0);
- } else {
- status = dma_pool_alloc(ep->remote_dev->signal_pool, GFP_KERNEL,
- &src);
- if (!status) {
- err = -ENOMEM;
- dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
- __func__, __LINE__, err);
- goto alloc_fail;
- }
- status->val = val;
- status->src_dma_addr = src;
- status->ep = ep;
- src += offsetof(struct scif_status, val);
- tx = ddev->device_prep_dma_memcpy(chan, dst, src, sizeof(val),
- DMA_PREP_INTERRUPT);
- }
- if (!tx) {
- err = -ENOMEM;
- dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
- __func__, __LINE__, err);
- goto dma_fail;
- }
- if (!x100) {
- cb_arg = kmalloc(sizeof(*cb_arg), GFP_KERNEL);
- if (!cb_arg) {
- err = -ENOMEM;
- goto dma_fail;
- }
- cb_arg->src_dma_addr = src;
- cb_arg->status = status;
- cb_arg->ep = ep;
- tx->callback = scif_prog_signal_cb;
- tx->callback_param = cb_arg;
- }
- cookie = tx->tx_submit(tx);
- if (dma_submit_error(cookie)) {
- err = -EIO;
- dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
- __func__, __LINE__, err);
- goto dma_fail;
- }
- dma_async_issue_pending(chan);
- return 0;
-dma_fail:
- if (!x100) {
- dma_pool_free(ep->remote_dev->signal_pool, status,
- src - offsetof(struct scif_status, val));
- kfree(cb_arg);
- }
-alloc_fail:
- return err;
-}
-
-/**
- * scif_prog_signal:
- * @epd: Endpoint Descriptor
- * @offset: registered address to write @val to
- * @val: Value to be written at @offset
- * @type: Type of the window.
- *
- * Arrange to write a value to the registered offset after ensuring that the
- * offset provided is indeed valid.
- */
-int scif_prog_signal(scif_epd_t epd, off_t offset, u64 val,
- enum scif_window_type type)
-{
- struct scif_endpt *ep = (struct scif_endpt *)epd;
- struct scif_window *window = NULL;
- struct scif_rma_req req;
- dma_addr_t dst_dma_addr;
- int err;
-
- mutex_lock(&ep->rma_info.rma_lock);
- req.out_window = &window;
- req.offset = offset;
- req.nr_bytes = sizeof(u64);
- req.prot = SCIF_PROT_WRITE;
- req.type = SCIF_WINDOW_SINGLE;
- if (type == SCIF_WINDOW_SELF)
- req.head = &ep->rma_info.reg_list;
- else
- req.head = &ep->rma_info.remote_reg_list;
- /* Does a valid window exist? */
- err = scif_query_window(&req);
- if (err) {
- dev_err(scif_info.mdev.this_device,
- "%s %d err %d\n", __func__, __LINE__, err);
- goto unlock_ret;
- }
-
- if (scif_is_mgmt_node() && scifdev_self(ep->remote_dev)) {
- u64 *dst_virt;
-
- if (type == SCIF_WINDOW_SELF)
- dst_virt = scif_get_local_va(offset, window);
- else
- dst_virt =
- scif_get_local_va(offset, (struct scif_window *)
- window->peer_window);
- *dst_virt = val;
- } else {
- dst_dma_addr = __scif_off_to_dma_addr(window, offset);
- err = _scif_prog_signal(epd, dst_dma_addr, val);
- }
-unlock_ret:
- mutex_unlock(&ep->rma_info.rma_lock);
- return err;
-}
-
-static int _scif_fence_wait(scif_epd_t epd, int mark)
-{
- struct scif_endpt *ep = (struct scif_endpt *)epd;
- dma_cookie_t cookie = mark & ~SCIF_REMOTE_FENCE;
- int err;
-
- /* Wait for DMA callback in scif_fence_mark_cb(..) */
- err = wait_event_interruptible_timeout(ep->rma_info.markwq,
- dma_async_is_tx_complete(
- ep->rma_info.dma_chan,
- cookie, NULL, NULL) ==
- DMA_COMPLETE,
- SCIF_NODE_ALIVE_TIMEOUT);
- if (!err)
- err = -ETIMEDOUT;
- else if (err > 0)
- err = 0;
- return err;
-}
-
-/**
- * scif_rma_handle_remote_fences:
- *
- * This routine services remote fence requests.
- */
-void scif_rma_handle_remote_fences(void)
-{
- struct list_head *item, *tmp;
- struct scif_remote_fence_info *fence;
- struct scif_endpt *ep;
- int mark, err;
-
- might_sleep();
- mutex_lock(&scif_info.fencelock);
- list_for_each_safe(item, tmp, &scif_info.fence) {
- fence = list_entry(item, struct scif_remote_fence_info,
- list);
- /* Remove fence from global list */
- list_del(&fence->list);
-
- /* Initiate the fence operation */
- ep = (struct scif_endpt *)fence->msg.payload[0];
- mark = fence->msg.payload[2];
- err = _scif_fence_wait(ep, mark);
- if (err)
- fence->msg.uop = SCIF_WAIT_NACK;
- else
- fence->msg.uop = SCIF_WAIT_ACK;
- fence->msg.payload[0] = ep->remote_ep;
- scif_nodeqp_send(ep->remote_dev, &fence->msg);
- kfree(fence);
- if (!atomic_sub_return(1, &ep->rma_info.fence_refcount))
- schedule_work(&scif_info.misc_work);
- }
- mutex_unlock(&scif_info.fencelock);
-}
-
-static int _scif_send_fence(scif_epd_t epd, int uop, int mark, int *out_mark)
-{
- int err;
- struct scifmsg msg;
- struct scif_fence_info *fence_req;
- struct scif_endpt *ep = (struct scif_endpt *)epd;
-
- fence_req = kmalloc(sizeof(*fence_req), GFP_KERNEL);
- if (!fence_req) {
- err = -ENOMEM;
- goto error;
- }
-
- fence_req->state = OP_IN_PROGRESS;
- init_completion(&fence_req->comp);
-
- msg.src = ep->port;
- msg.uop = uop;
- msg.payload[0] = ep->remote_ep;
- msg.payload[1] = (u64)fence_req;
- if (uop == SCIF_WAIT)
- msg.payload[2] = mark;
- spin_lock(&ep->lock);
- if (ep->state == SCIFEP_CONNECTED)
- err = scif_nodeqp_send(ep->remote_dev, &msg);
- else
- err = -ENOTCONN;
- spin_unlock(&ep->lock);
- if (err)
- goto error_free;
-retry:
- /* Wait for a SCIF_WAIT_(N)ACK message */
- err = wait_for_completion_timeout(&fence_req->comp,
- SCIF_NODE_ALIVE_TIMEOUT);
- if (!err && scifdev_alive(ep))
- goto retry;
- if (!err)
- err = -ENODEV;
- if (err > 0)
- err = 0;
- mutex_lock(&ep->rma_info.rma_lock);
- if (err < 0) {
- if (fence_req->state == OP_IN_PROGRESS)
- fence_req->state = OP_FAILED;
- }
- if (fence_req->state == OP_FAILED && !err)
- err = -ENOMEM;
- if (uop == SCIF_MARK && fence_req->state == OP_COMPLETED)
- *out_mark = SCIF_REMOTE_FENCE | fence_req->dma_mark;
- mutex_unlock(&ep->rma_info.rma_lock);
-error_free:
- kfree(fence_req);
-error:
- return err;
-}
-
-/**
- * scif_send_fence_mark:
- * @epd: end point descriptor.
- * @out_mark: Output DMA mark reported by peer.
- *
- * Send a remote fence mark request.
- */
-static int scif_send_fence_mark(scif_epd_t epd, int *out_mark)
-{
- return _scif_send_fence(epd, SCIF_MARK, 0, out_mark);
-}
-
-/**
- * scif_send_fence_wait:
- * @epd: end point descriptor.
- * @mark: DMA mark to wait for.
- *
- * Send a remote fence wait request.
- */
-static int scif_send_fence_wait(scif_epd_t epd, int mark)
-{
- return _scif_send_fence(epd, SCIF_WAIT, mark, NULL);
-}
-
-static int _scif_send_fence_signal_wait(struct scif_endpt *ep,
- struct scif_fence_info *fence_req)
-{
- int err;
-
-retry:
- /* Wait for a SCIF_SIG_(N)ACK message */
- err = wait_for_completion_timeout(&fence_req->comp,
- SCIF_NODE_ALIVE_TIMEOUT);
- if (!err && scifdev_alive(ep))
- goto retry;
- if (!err)
- err = -ENODEV;
- if (err > 0)
- err = 0;
- if (err < 0) {
- mutex_lock(&ep->rma_info.rma_lock);
- if (fence_req->state == OP_IN_PROGRESS)
- fence_req->state = OP_FAILED;
- mutex_unlock(&ep->rma_info.rma_lock);
- }
- if (fence_req->state == OP_FAILED && !err)
- err = -ENXIO;
- return err;
-}
-
-/**
- * scif_send_fence_signal:
- * @epd: endpoint descriptor
- * @loff: local offset
- * @lval: local value to write to loffset
- * @roff: remote offset
- * @rval: remote value to write to roffset
- * @flags: flags
- *
- * Sends a remote fence signal request
- */
-static int scif_send_fence_signal(scif_epd_t epd, off_t roff, u64 rval,
- off_t loff, u64 lval, int flags)
-{
- int err = 0;
- struct scifmsg msg;
- struct scif_fence_info *fence_req;
- struct scif_endpt *ep = (struct scif_endpt *)epd;
-
- fence_req = kmalloc(sizeof(*fence_req), GFP_KERNEL);
- if (!fence_req) {
- err = -ENOMEM;
- goto error;
- }
-
- fence_req->state = OP_IN_PROGRESS;
- init_completion(&fence_req->comp);
- msg.src = ep->port;
- if (flags & SCIF_SIGNAL_LOCAL) {
- msg.uop = SCIF_SIG_LOCAL;
- msg.payload[0] = ep->remote_ep;
- msg.payload[1] = roff;
- msg.payload[2] = rval;
- msg.payload[3] = (u64)fence_req;
- spin_lock(&ep->lock);
- if (ep->state == SCIFEP_CONNECTED)
- err = scif_nodeqp_send(ep->remote_dev, &msg);
- else
- err = -ENOTCONN;
- spin_unlock(&ep->lock);
- if (err)
- goto error_free;
- err = _scif_send_fence_signal_wait(ep, fence_req);
- if (err)
- goto error_free;
- }
- fence_req->state = OP_IN_PROGRESS;
-
- if (flags & SCIF_SIGNAL_REMOTE) {
- msg.uop = SCIF_SIG_REMOTE;
- msg.payload[0] = ep->remote_ep;
- msg.payload[1] = loff;
- msg.payload[2] = lval;
- msg.payload[3] = (u64)fence_req;
- spin_lock(&ep->lock);
- if (ep->state == SCIFEP_CONNECTED)
- err = scif_nodeqp_send(ep->remote_dev, &msg);
- else
- err = -ENOTCONN;
- spin_unlock(&ep->lock);
- if (err)
- goto error_free;
- err = _scif_send_fence_signal_wait(ep, fence_req);
- }
-error_free:
- kfree(fence_req);
-error:
- return err;
-}
-
-static void scif_fence_mark_cb(void *arg)
-{
- struct scif_endpt *ep = (struct scif_endpt *)arg;
-
- wake_up_interruptible(&ep->rma_info.markwq);
- atomic_dec(&ep->rma_info.fence_refcount);
-}
-
-/**
- * _scif_fence_mark:
- * @epd: endpoint descriptor
- * @mark: DMA mark to set-up
- *
- * Set up a mark for this endpoint and return the value of the mark.
- */
-int _scif_fence_mark(scif_epd_t epd, int *mark)
-{
- struct scif_endpt *ep = (struct scif_endpt *)epd;
- struct dma_chan *chan = ep->rma_info.dma_chan;
- struct dma_device *ddev = chan->device;
- struct dma_async_tx_descriptor *tx;
- dma_cookie_t cookie;
- int err;
-
- tx = ddev->device_prep_dma_memcpy(chan, 0, 0, 0, DMA_PREP_FENCE);
- if (!tx) {
- err = -ENOMEM;
- dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
- __func__, __LINE__, err);
- return err;
- }
- cookie = tx->tx_submit(tx);
- if (dma_submit_error(cookie)) {
- err = (int)cookie;
- dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
- __func__, __LINE__, err);
- return err;
- }
- dma_async_issue_pending(chan);
- tx = ddev->device_prep_dma_interrupt(chan, DMA_PREP_INTERRUPT);
- if (!tx) {
- err = -ENOMEM;
- dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
- __func__, __LINE__, err);
- return err;
- }
- tx->callback = scif_fence_mark_cb;
- tx->callback_param = ep;
- *mark = cookie = tx->tx_submit(tx);
- if (dma_submit_error(cookie)) {
- err = (int)cookie;
- dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n",
- __func__, __LINE__, err);
- return err;
- }
- atomic_inc(&ep->rma_info.fence_refcount);
- dma_async_issue_pending(chan);
- return 0;
-}
-
-#define SCIF_LOOPB_MAGIC_MARK 0xdead
-
-int scif_fence_mark(scif_epd_t epd, int flags, int *mark)
-{
- struct scif_endpt *ep = (struct scif_endpt *)epd;
- int err = 0;
-
- dev_dbg(scif_info.mdev.this_device,
- "SCIFAPI fence_mark: ep %p flags 0x%x mark 0x%x\n",
- ep, flags, *mark);
- err = scif_verify_epd(ep);
- if (err)
- return err;
-
- /* Invalid flags? */
- if (flags & ~(SCIF_FENCE_INIT_SELF | SCIF_FENCE_INIT_PEER))
- return -EINVAL;
-
- /* At least one of init self or peer RMA should be set */
- if (!(flags & (SCIF_FENCE_INIT_SELF | SCIF_FENCE_INIT_PEER)))
- return -EINVAL;
-
- /* Exactly one of init self or peer RMA should be set but not both */
- if ((flags & SCIF_FENCE_INIT_SELF) && (flags & SCIF_FENCE_INIT_PEER))
- return -EINVAL;
-
- /*
- * Management node loopback does not need to use DMA.
- * Return a valid mark to be symmetric.
- */
- if (scifdev_self(ep->remote_dev) && scif_is_mgmt_node()) {
- *mark = SCIF_LOOPB_MAGIC_MARK;
- return 0;
- }
-
- if (flags & SCIF_FENCE_INIT_SELF)
- err = _scif_fence_mark(epd, mark);
- else
- err = scif_send_fence_mark(ep, mark);
-
- if (err)
- dev_err(scif_info.mdev.this_device,
- "%s %d err %d\n", __func__, __LINE__, err);
- dev_dbg(scif_info.mdev.this_device,
- "SCIFAPI fence_mark: ep %p flags 0x%x mark 0x%x err %d\n",
- ep, flags, *mark, err);
- return err;
-}
-EXPORT_SYMBOL_GPL(scif_fence_mark);
-
-int scif_fence_wait(scif_epd_t epd, int mark)
-{
- struct scif_endpt *ep = (struct scif_endpt *)epd;
- int err = 0;
-
- dev_dbg(scif_info.mdev.this_device,
- "SCIFAPI fence_wait: ep %p mark 0x%x\n",
- ep, mark);
- err = scif_verify_epd(ep);
- if (err)
- return err;
- /*
- * Management node loopback does not need to use DMA.
- * The only valid mark provided is 0 so simply
- * return success if the mark is valid.
- */
- if (scifdev_self(ep->remote_dev) && scif_is_mgmt_node()) {
- if (mark == SCIF_LOOPB_MAGIC_MARK)
- return 0;
- else
- return -EINVAL;
- }
- if (mark & SCIF_REMOTE_FENCE)
- err = scif_send_fence_wait(epd, mark);
- else
- err = _scif_fence_wait(epd, mark);
- if (err < 0)
- dev_err(scif_info.mdev.this_device,
- "%s %d err %d\n", __func__, __LINE__, err);
- return err;
-}
-EXPORT_SYMBOL_GPL(scif_fence_wait);
-
-int scif_fence_signal(scif_epd_t epd, off_t loff, u64 lval,
- off_t roff, u64 rval, int flags)
-{
- struct scif_endpt *ep = (struct scif_endpt *)epd;
- int err = 0;
-
- dev_dbg(scif_info.mdev.this_device,
- "SCIFAPI fence_signal: ep %p loff 0x%lx lval 0x%llx roff 0x%lx rval 0x%llx flags 0x%x\n",
- ep, loff, lval, roff, rval, flags);
- err = scif_verify_epd(ep);
- if (err)
- return err;
-
- /* Invalid flags? */
- if (flags & ~(SCIF_FENCE_INIT_SELF | SCIF_FENCE_INIT_PEER |
- SCIF_SIGNAL_LOCAL | SCIF_SIGNAL_REMOTE))
- return -EINVAL;
-
- /* At least one of init self or peer RMA should be set */
- if (!(flags & (SCIF_FENCE_INIT_SELF | SCIF_FENCE_INIT_PEER)))
- return -EINVAL;
-
- /* Exactly one of init self or peer RMA should be set but not both */
- if ((flags & SCIF_FENCE_INIT_SELF) && (flags & SCIF_FENCE_INIT_PEER))
- return -EINVAL;
-
- /* At least one of SCIF_SIGNAL_LOCAL or SCIF_SIGNAL_REMOTE required */
- if (!(flags & (SCIF_SIGNAL_LOCAL | SCIF_SIGNAL_REMOTE)))
- return -EINVAL;
-
- /* Only Dword offsets allowed */
- if ((flags & SCIF_SIGNAL_LOCAL) && (loff & (sizeof(u32) - 1)))
- return -EINVAL;
-
- /* Only Dword aligned offsets allowed */
- if ((flags & SCIF_SIGNAL_REMOTE) && (roff & (sizeof(u32) - 1)))
- return -EINVAL;
-
- if (flags & SCIF_FENCE_INIT_PEER) {
- err = scif_send_fence_signal(epd, roff, rval, loff,
- lval, flags);
- } else {
- /* Local Signal in Local RAS */
- if (flags & SCIF_SIGNAL_LOCAL) {
- err = scif_prog_signal(epd, loff, lval,
- SCIF_WINDOW_SELF);
- if (err)
- goto error_ret;
- }
-
- /* Signal in Remote RAS */
- if (flags & SCIF_SIGNAL_REMOTE)
- err = scif_prog_signal(epd, roff,
- rval, SCIF_WINDOW_PEER);
- }
-error_ret:
- if (err)
- dev_err(scif_info.mdev.this_device,
- "%s %d err %d\n", __func__, __LINE__, err);
- return err;
-}
-EXPORT_SYMBOL_GPL(scif_fence_signal);