/*
 * rio_cm - RapidIO Channelized Messaging Driver
 *
 * Copyright 2013-2016 Integrated Device Technology, Inc.
 * Copyright (c) 2015, Prodrive Technologies
 * Copyright (c) 2015, RapidIO Trade Association
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 *
 * 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.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/rio.h>
#include <linux/rio_drv.h>
#include <linux/slab.h>
#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/reboot.h>
#include <linux/bitops.h>
#include <linux/printk.h>
#include <linux/rio_cm_cdev.h>

#define DRV_NAME        "rio_cm"
#define DRV_VERSION     "1.0.0"
#define DRV_AUTHOR      "Alexandre Bounine <alexandre.bounine@idt.com>"
#define DRV_DESC        "RapidIO Channelized Messaging Driver"
#define DEV_NAME	"rio_cm"

/* Debug output filtering masks */
enum {
	DBG_NONE	= 0,
	DBG_INIT	= BIT(0), /* driver init */
	DBG_EXIT	= BIT(1), /* driver exit */
	DBG_MPORT	= BIT(2), /* mport add/remove */
	DBG_RDEV	= BIT(3), /* RapidIO device add/remove */
	DBG_CHOP	= BIT(4), /* channel operations */
	DBG_WAIT	= BIT(5), /* waiting for events */
	DBG_TX		= BIT(6), /* message TX */
	DBG_TX_EVENT	= BIT(7), /* message TX event */
	DBG_RX_DATA	= BIT(8), /* inbound data messages */
	DBG_RX_CMD	= BIT(9), /* inbound REQ/ACK/NACK messages */
	DBG_ALL		= ~0,
};

#ifdef DEBUG
#define riocm_debug(level, fmt, arg...) \
	do { \
		if (DBG_##level & dbg_level) \
			pr_debug(DRV_NAME ": %s " fmt "\n", \
				__func__, ##arg); \
	} while (0)
#else
#define riocm_debug(level, fmt, arg...) \
		no_printk(KERN_DEBUG pr_fmt(DRV_NAME fmt "\n"), ##arg)
#endif

#define riocm_warn(fmt, arg...) \
	pr_warn(DRV_NAME ": %s WARNING " fmt "\n", __func__, ##arg)

#define riocm_error(fmt, arg...) \
	pr_err(DRV_NAME ": %s ERROR " fmt "\n", __func__, ##arg)


static int cmbox = 1;
module_param(cmbox, int, S_IRUGO);
MODULE_PARM_DESC(cmbox, "RapidIO Mailbox number (default 1)");

static int chstart = 256;
module_param(chstart, int, S_IRUGO);
MODULE_PARM_DESC(chstart,
		 "Start channel number for dynamic allocation (default 256)");

#ifdef DEBUG
static u32 dbg_level = DBG_NONE;
module_param(dbg_level, uint, S_IWUSR | S_IRUGO);
MODULE_PARM_DESC(dbg_level, "Debugging output level (default 0 = none)");
#endif

MODULE_AUTHOR(DRV_AUTHOR);
MODULE_DESCRIPTION(DRV_DESC);
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

#define RIOCM_TX_RING_SIZE	128
#define RIOCM_RX_RING_SIZE	128
#define RIOCM_CONNECT_TO	3 /* connect response TO (in sec) */

#define RIOCM_MAX_CHNUM		0xffff /* Use full range of u16 field */
#define RIOCM_CHNUM_AUTO	0
#define RIOCM_MAX_EP_COUNT	0x10000 /* Max number of endpoints */

enum rio_cm_state {
	RIO_CM_IDLE,
	RIO_CM_CONNECT,
	RIO_CM_CONNECTED,
	RIO_CM_DISCONNECT,
	RIO_CM_CHAN_BOUND,
	RIO_CM_LISTEN,
	RIO_CM_DESTROYING,
};

enum rio_cm_pkt_type {
	RIO_CM_SYS	= 0xaa,
	RIO_CM_CHAN	= 0x55,
};

enum rio_cm_chop {
	CM_CONN_REQ,
	CM_CONN_ACK,
	CM_CONN_CLOSE,
	CM_DATA_MSG,
};

struct rio_ch_base_bhdr {
	u32 src_id;
	u32 dst_id;
#define RIO_HDR_LETTER_MASK 0xffff0000
#define RIO_HDR_MBOX_MASK   0x0000ffff
	u8  src_mbox;
	u8  dst_mbox;
	u8  type;
} __attribute__((__packed__));

struct rio_ch_chan_hdr {
	struct rio_ch_base_bhdr bhdr;
	u8 ch_op;
	u16 dst_ch;
	u16 src_ch;
	u16 msg_len;
	u16 rsrvd;
} __attribute__((__packed__));

struct tx_req {
	struct list_head node;
	struct rio_dev   *rdev;
	void		 *buffer;
	size_t		 len;
};

struct cm_dev {
	struct list_head	list;
	struct rio_mport	*mport;
	void			*rx_buf[RIOCM_RX_RING_SIZE];
	int			rx_slots;
	struct mutex		rx_lock;

	void			*tx_buf[RIOCM_TX_RING_SIZE];
	int			tx_slot;
	int			tx_cnt;
	int			tx_ack_slot;
	struct list_head	tx_reqs;
	spinlock_t		tx_lock;

	struct list_head	peers;
	u32			npeers;
	struct workqueue_struct *rx_wq;
	struct work_struct	rx_work;
};

struct chan_rx_ring {
	void	*buf[RIOCM_RX_RING_SIZE];
	int	head;
	int	tail;
	int	count;

	/* Tracking RX buffers reported to upper level */
	void	*inuse[RIOCM_RX_RING_SIZE];
	int	inuse_cnt;
};

struct rio_channel {
	u16			id;	/* local channel ID */
	struct kref		ref;	/* channel refcount */
	struct file		*filp;
	struct cm_dev		*cmdev;	/* associated CM device object */
	struct rio_dev		*rdev;	/* remote RapidIO device */
	enum rio_cm_state	state;
	int			error;
	spinlock_t		lock;
	void			*context;
	u32			loc_destid;	/* local destID */
	u32			rem_destid;	/* remote destID */
	u16			rem_channel;	/* remote channel ID */
	struct list_head	accept_queue;
	struct list_head	ch_node;
	struct completion	comp;
	struct completion	comp_close;
	struct chan_rx_ring	rx_ring;
};

struct cm_peer {
	struct list_head node;
	struct rio_dev *rdev;
};

struct rio_cm_work {
	struct work_struct work;
	struct cm_dev *cm;
	void *data;
};

struct conn_req {
	struct list_head node;
	u32 destid;	/* requester destID */
	u16 chan;	/* requester channel ID */
	struct cm_dev *cmdev;
};

/*
 * A channel_dev structure represents a CM_CDEV
 * @cdev	Character device
 * @dev		Associated device object
 */
struct channel_dev {
	struct cdev	cdev;
	struct device	*dev;
};

static struct rio_channel *riocm_ch_alloc(u16 ch_num);
static void riocm_ch_free(struct kref *ref);
static int riocm_post_send(struct cm_dev *cm, struct rio_dev *rdev,
			   void *buffer, size_t len);
static int riocm_ch_close(struct rio_channel *ch);

static DEFINE_SPINLOCK(idr_lock);
static DEFINE_IDR(ch_idr);

static LIST_HEAD(cm_dev_list);
static DECLARE_RWSEM(rdev_sem);

static struct class *dev_class;
static unsigned int dev_major;
static unsigned int dev_minor_base;
static dev_t dev_number;
static struct channel_dev riocm_cdev;

#define is_msg_capable(src_ops, dst_ops)			\
			((src_ops & RIO_SRC_OPS_DATA_MSG) &&	\
			 (dst_ops & RIO_DST_OPS_DATA_MSG))
#define dev_cm_capable(dev) \
	is_msg_capable(dev->src_ops, dev->dst_ops)

static int riocm_cmp(struct rio_channel *ch, enum rio_cm_state cmp)
{
	int ret;

	spin_lock_bh(&ch->lock);
	ret = (ch->state == cmp);
	spin_unlock_bh(&ch->lock);
	return ret;
}

static int riocm_cmp_exch(struct rio_channel *ch,
			   enum rio_cm_state cmp, enum rio_cm_state exch)
{
	int ret;

	spin_lock_bh(&ch->lock);
	ret = (ch->state == cmp);
	if (ret)
		ch->state = exch;
	spin_unlock_bh(&ch->lock);
	return ret;
}

static enum rio_cm_state riocm_exch(struct rio_channel *ch,
				    enum rio_cm_state exch)
{
	enum rio_cm_state old;

	spin_lock_bh(&ch->lock);
	old = ch->state;
	ch->state = exch;
	spin_unlock_bh(&ch->lock);
	return old;
}

static struct rio_channel *riocm_get_channel(u16 nr)
{
	struct rio_channel *ch;

	spin_lock_bh(&idr_lock);
	ch = idr_find(&ch_idr, nr);
	if (ch)
		kref_get(&ch->ref);
	spin_unlock_bh(&idr_lock);
	return ch;
}

static void riocm_put_channel(struct rio_channel *ch)
{
	kref_put(&ch->ref, riocm_ch_free);
}

static void *riocm_rx_get_msg(struct cm_dev *cm)
{
	void *msg;
	int i;

	msg = rio_get_inb_message(cm->mport, cmbox);
	if (msg) {
		for (i = 0; i < RIOCM_RX_RING_SIZE; i++) {
			if (cm->rx_buf[i] == msg) {
				cm->rx_buf[i] = NULL;
				cm->rx_slots++;
				break;
			}
		}

		if (i == RIOCM_RX_RING_SIZE)
			riocm_warn("no record for buffer 0x%p", msg);
	}

	return msg;
}

/*
 * riocm_rx_fill - fills a ring of receive buffers for given cm device
 * @cm: cm_dev object
 * @nent: max number of entries to fill
 *
 * Returns: none
 */
static void riocm_rx_fill(struct cm_dev *cm, int nent)
{
	int i;

	if (cm->rx_slots == 0)
		return;

	for (i = 0; i < RIOCM_RX_RING_SIZE && cm->rx_slots && nent; i++) {
		if (cm->rx_buf[i] == NULL) {
			cm->rx_buf[i] = kmalloc(RIO_MAX_MSG_SIZE, GFP_KERNEL);
			if (cm->rx_buf[i] == NULL)
				break;
			rio_add_inb_buffer(cm->mport, cmbox, cm->rx_buf[i]);
			cm->rx_slots--;
			nent--;
		}
	}
}

/*
 * riocm_rx_free - frees all receive buffers associated with given cm device
 * @cm: cm_dev object
 *
 * Returns: none
 */
static void riocm_rx_free(struct cm_dev *cm)
{
	int i;

	for (i = 0; i < RIOCM_RX_RING_SIZE; i++) {
		if (cm->rx_buf[i] != NULL) {
			kfree(cm->rx_buf[i]);
			cm->rx_buf[i] = NULL;
		}
	}
}

/*
 * riocm_req_handler - connection request handler
 * @cm: cm_dev object
 * @req_data: pointer to the request packet
 *
 * Returns: 0 if success, or
 *          -EINVAL if channel is not in correct state,
 *          -ENODEV if cannot find a channel with specified ID,
 *          -ENOMEM if unable to allocate memory to store the request
 */
static int riocm_req_handler(struct cm_dev *cm, void *req_data)
{
	struct rio_channel *ch;
	struct conn_req *req;
	struct rio_ch_chan_hdr *hh = req_data;
	u16 chnum;

	chnum = ntohs(hh->dst_ch);

	ch = riocm_get_channel(chnum);

	if (!ch)
		return -ENODEV;

	if (ch->state != RIO_CM_LISTEN) {
		riocm_debug(RX_CMD, "channel %d is not in listen state", chnum);
		riocm_put_channel(ch);
		return -EINVAL;
	}

	req = kzalloc(sizeof(*req), GFP_KERNEL);
	if (!req) {
		riocm_put_channel(ch);
		return -ENOMEM;
	}

	req->destid = ntohl(hh->bhdr.src_id);
	req->chan = ntohs(hh->src_ch);
	req->cmdev = cm;

	spin_lock_bh(&ch->lock);
	list_add_tail(&req->node, &ch->accept_queue);
	spin_unlock_bh(&ch->lock);
	complete(&ch->comp);
	riocm_put_channel(ch);

	return 0;
}

/*
 * riocm_resp_handler - response to connection request handler
 * @resp_data: pointer to the response packet
 *
 * Returns: 0 if success, or
 *          -EINVAL if channel is not in correct state,
 *          -ENODEV if cannot find a channel with specified ID,
 */
static int riocm_resp_handler(void *resp_data)
{
	struct rio_channel *ch;
	struct rio_ch_chan_hdr *hh = resp_data;
	u16 chnum;

	chnum = ntohs(hh->dst_ch);
	ch = riocm_get_channel(chnum);
	if (!ch)
		return -ENODEV;

	if (ch->state != RIO_CM_CONNECT) {
		riocm_put_channel(ch);
		return -EINVAL;
	}

	riocm_exch(ch, RIO_CM_CONNECTED);
	ch->rem_channel = ntohs(hh->src_ch);
	complete(&ch->comp);
	riocm_put_channel(ch);

	return 0;
}

/*
 * riocm_close_handler - channel close request handler
 * @req_data: pointer to the request packet
 *
 * Returns: 0 if success, or
 *          -ENODEV if cannot find a channel with specified ID,
 *            + error codes returned by riocm_ch_close.
 */
static int riocm_close_handler(void *data)
{
	struct rio_channel *ch;
	struct rio_ch_chan_hdr *hh = data;
	int ret;

	riocm_debug(RX_CMD, "for ch=%d", ntohs(hh->dst_ch));

	spin_lock_bh(&idr_lock);
	ch = idr_find(&ch_idr, ntohs(hh->dst_ch));
	if (!ch) {
		spin_unlock_bh(&idr_lock);
		return -ENODEV;
	}
	idr_remove(&ch_idr, ch->id);
	spin_unlock_bh(&idr_lock);

	riocm_exch(ch, RIO_CM_DISCONNECT);

	ret = riocm_ch_close(ch);
	if (ret)
		riocm_debug(RX_CMD, "riocm_ch_close() returned %d", ret);

	return 0;
}

/*
 * rio_cm_handler - function that services request (non-data) packets
 * @cm: cm_dev object
 * @data: pointer to the packet
 */
static void rio_cm_handler(struct cm_dev *cm, void *data)
{
	struct rio_ch_chan_hdr *hdr;

	if (!rio_mport_is_running(cm->mport))
		goto out;

	hdr = data;

	riocm_debug(RX_CMD, "OP=%x for ch=%d from %d",
		    hdr->ch_op, ntohs(hdr->dst_ch), ntohs(hdr->src_ch));

	switch (hdr->ch_op) {
	case CM_CONN_REQ:
		riocm_req_handler(cm, data);
		break;
	case CM_CONN_ACK:
		riocm_resp_handler(data);
		break;
	case CM_CONN_CLOSE:
		riocm_close_handler(data);
		break;
	default:
		riocm_error("Invalid packet header");
		break;
	}
out:
	kfree(data);
}

/*
 * rio_rx_data_handler - received data packet handler
 * @cm: cm_dev object
 * @buf: data packet
 *
 * Returns: 0 if success, or
 *          -ENODEV if cannot find a channel with specified ID,
 *          -EIO if channel is not in CONNECTED state,
 *          -ENOMEM if channel RX queue is full (packet discarded)
 */
static int rio_rx_data_handler(struct cm_dev *cm, void *buf)
{
	struct rio_ch_chan_hdr *hdr;
	struct rio_channel *ch;

	hdr = buf;

	riocm_debug(RX_DATA, "for ch=%d", ntohs(hdr->dst_ch));

	ch = riocm_get_channel(ntohs(hdr->dst_ch));
	if (!ch) {
		/* Discard data message for non-existing channel */
		kfree(buf);
		return -ENODEV;
	}

	/* Place pointer to the buffer into channel's RX queue */
	spin_lock(&ch->lock);

	if (ch->state != RIO_CM_CONNECTED) {
		/* Channel is not ready to receive data, discard a packet */
		riocm_debug(RX_DATA, "ch=%d is in wrong state=%d",
			    ch->id, ch->state);
		spin_unlock(&ch->lock);
		kfree(buf);
		riocm_put_channel(ch);
		return -EIO;
	}

	if (ch->rx_ring.count == RIOCM_RX_RING_SIZE) {
		/* If RX ring is full, discard a packet */
		riocm_debug(RX_DATA, "ch=%d is full", ch->id);
		spin_unlock(&ch->lock);
		kfree(buf);
		riocm_put_channel(ch);
		return -ENOMEM;
	}

	ch->rx_ring.buf[ch->rx_ring.head] = buf;
	ch->rx_ring.head++;
	ch->rx_ring.count++;
	ch->rx_ring.head %= RIOCM_RX_RING_SIZE;

	complete(&ch->comp);

	spin_unlock(&ch->lock);
	riocm_put_channel(ch);

	return 0;
}

/*
 * rio_ibmsg_handler - inbound message packet handler
 */
static void rio_ibmsg_handler(struct work_struct *work)
{
	struct cm_dev *cm = container_of(work, struct cm_dev, rx_work);
	void *data;
	struct rio_ch_chan_hdr *hdr;

	if (!rio_mport_is_running(cm->mport))
		return;

	while (1) {
		mutex_lock(&cm->rx_lock);
		data = riocm_rx_get_msg(cm);
		if (data)
			riocm_rx_fill(cm, 1);
		mutex_unlock(&cm->rx_lock);

		if (data == NULL)
			break;

		hdr = data;

		if (hdr->bhdr.type != RIO_CM_CHAN) {
			/* For now simply discard packets other than channel */
			riocm_error("Unsupported TYPE code (0x%x). Msg dropped",
				    hdr->bhdr.type);
			kfree(data);
			continue;
		}

		/* Process a channel message */
		if (hdr->ch_op == CM_DATA_MSG)
			rio_rx_data_handler(cm, data);
		else
			rio_cm_handler(cm, data);
	}
}

static void riocm_inb_msg_event(struct rio_mport *mport, void *dev_id,
				int mbox, int slot)
{
	struct cm_dev *cm = dev_id;

	if (rio_mport_is_running(cm->mport) && !work_pending(&cm->rx_work))
		queue_work(cm->rx_wq, &cm->rx_work);
}

/*
 * rio_txcq_handler - TX completion handler
 * @cm: cm_dev object
 * @slot: TX queue slot
 *
 * TX completion handler also ensures that pending request packets are placed
 * into transmit queue as soon as a free slot becomes available. This is done
 * to give higher priority to request packets during high intensity data flow.
 */
static void rio_txcq_handler(struct cm_dev *cm, int slot)
{
	int ack_slot;

	/* ATTN: Add TX completion notification if/when direct buffer
	 * transfer is implemented. At this moment only correct tracking
	 * of tx_count is important.
	 */
	riocm_debug(TX_EVENT, "for mport_%d slot %d tx_cnt %d",
		    cm->mport->id, slot, cm->tx_cnt);

	spin_lock(&cm->tx_lock);
	ack_slot = cm->tx_ack_slot;

	if (ack_slot == slot)
		riocm_debug(TX_EVENT, "slot == ack_slot");

	while (cm->tx_cnt && ((ack_slot != slot) ||
	       (cm->tx_cnt == RIOCM_TX_RING_SIZE))) {

		cm->tx_buf[ack_slot] = NULL;
		++ack_slot;
		ack_slot &= (RIOCM_TX_RING_SIZE - 1);
		cm->tx_cnt--;
	}

	if (cm->tx_cnt < 0 || cm->tx_cnt > RIOCM_TX_RING_SIZE)
		riocm_error("tx_cnt %d out of sync", cm->tx_cnt);

	WARN_ON((cm->tx_cnt < 0) || (cm->tx_cnt > RIOCM_TX_RING_SIZE));

	cm->tx_ack_slot = ack_slot;

	/*
	 * If there are pending requests, insert them into transmit queue
	 */
	if (!list_empty(&cm->tx_reqs) && (cm->tx_cnt < RIOCM_TX_RING_SIZE)) {
		struct tx_req *req, *_req;
		int rc;

		list_for_each_entry_safe(req, _req, &cm->tx_reqs, node) {
			list_del(&req->node);
			cm->tx_buf[cm->tx_slot] = req->buffer;
			rc = rio_add_outb_message(cm->mport, req->rdev, cmbox,
						  req->buffer, req->len);
			kfree(req->buffer);
			kfree(req);

			++cm->tx_cnt;
			++cm->tx_slot;
			cm->tx_slot &= (RIOCM_TX_RING_SIZE - 1);
			if (cm->tx_cnt == RIOCM_TX_RING_SIZE)
				break;
		}
	}

	spin_unlock(&cm->tx_lock);
}

static void riocm_outb_msg_event(struct rio_mport *mport, void *dev_id,
				 int mbox, int slot)
{
	struct cm_dev *cm = dev_id;

	if (cm && rio_mport_is_running(cm->mport))
		rio_txcq_handler(cm, slot);
}

static int riocm_queue_req(struct cm_dev *cm, struct rio_dev *rdev,
			   void *buffer, size_t len)
{
	unsigned long flags;
	struct tx_req *treq;

	treq = kzalloc(sizeof(*treq), GFP_KERNEL);
	if (treq == NULL)
		return -ENOMEM;

	treq->rdev = rdev;
	treq->buffer = buffer;
	treq->len = len;

	spin_lock_irqsave(&cm->tx_lock, flags);
	list_add_tail(&treq->node, &cm->tx_reqs);
	spin_unlock_irqrestore(&cm->tx_lock, flags);
	return 0;
}

/*
 * riocm_post_send - helper function that places packet into msg TX queue
 * @cm: cm_dev object
 * @rdev: target RapidIO device object (required by outbound msg interface)
 * @buffer: pointer to a packet buffer to send
 * @len: length of data to transfer
 * @req: request priority flag
 *
 * Returns: 0 if success, or error code otherwise.
 */
static int riocm_post_send(struct cm_dev *cm, struct rio_dev *rdev,
			   void *buffer, size_t len)
{
	int rc;
	unsigned long flags;

	spin_lock_irqsave(&cm->tx_lock, flags);

	if (cm->mport == NULL) {
		rc = -ENODEV;
		goto err_out;
	}

	if (cm->tx_cnt == RIOCM_TX_RING_SIZE) {
		riocm_debug(TX, "Tx Queue is full");
		rc = -EBUSY;
		goto err_out;
	}

	cm->tx_buf[cm->tx_slot] = buffer;
	rc = rio_add_outb_message(cm->mport, rdev, cmbox, buffer, len);

	riocm_debug(TX, "Add buf@%p destid=%x tx_slot=%d tx_cnt=%d",
		 buffer, rdev->destid, cm->tx_slot, cm->tx_cnt);

	++cm->tx_cnt;
	++cm->tx_slot;
	cm->tx_slot &= (RIOCM_TX_RING_SIZE - 1);

err_out:
	spin_unlock_irqrestore(&cm->tx_lock, flags);
	return rc;
}

/*
 * riocm_ch_send - sends a data packet to a remote device
 * @ch_id: local channel ID
 * @buf: pointer to a data buffer to send (including CM header)
 * @len: length of data to transfer (including CM header)
 *
 * ATTN: ASSUMES THAT THE HEADER SPACE IS RESERVED PART OF THE DATA PACKET
 *
 * Returns: 0 if success, or
 *          -EINVAL if one or more input parameters is/are not valid,
 *          -ENODEV if cannot find a channel with specified ID,
 *          -EAGAIN if a channel is not in CONNECTED state,
 *	    + error codes returned by HW send routine.
 */
static int riocm_ch_send(u16 ch_id, void *buf, int len)
{
	struct rio_channel *ch;
	struct rio_ch_chan_hdr *hdr;
	int ret;

	if (buf == NULL || ch_id == 0 || len == 0 || len > RIO_MAX_MSG_SIZE)
		return -EINVAL;

	ch = riocm_get_channel(ch_id);
	if (!ch) {
		riocm_error("%s(%d) ch_%d not found", current->comm,
			    task_pid_nr(current), ch_id);
		return -ENODEV;
	}

	if (!riocm_cmp(ch, RIO_CM_CONNECTED)) {
		ret = -EAGAIN;
		goto err_out;
	}

	/*
	 * Fill buffer header section with corresponding channel data
	 */
	hdr = buf;

	hdr->bhdr.src_id = htonl(ch->loc_destid);
	hdr->bhdr.dst_id = htonl(ch->rem_destid);
	hdr->bhdr.src_mbox = cmbox;
	hdr->bhdr.dst_mbox = cmbox;
	hdr->bhdr.type = RIO_CM_CHAN;
	hdr->ch_op = CM_DATA_MSG;
	hdr->dst_ch = htons(ch->rem_channel);
	hdr->src_ch = htons(ch->id);
	hdr->msg_len = htons((u16)len);

	/* ATTN: the function call below relies on the fact that underlying
	 * HW-specific add_outb_message() routine copies TX data into its own
	 * internal transfer buffer (true for all RIONET compatible mport
	 * drivers). Must be reviewed if mport driver uses the buffer directly.
	 */

	ret = riocm_post_send(ch->cmdev, ch->rdev, buf, len);
	if (ret)
		riocm_debug(TX, "ch %d send_err=%d", ch->id, ret);
err_out:
	riocm_put_channel(ch);
	return ret;
}

static int riocm_ch_free_rxbuf(struct rio_channel *ch, void *buf)
{
	int i, ret = -EINVAL;

	spin_lock_bh(&ch->lock);

	for (i = 0; i < RIOCM_RX_RING_SIZE; i++) {
		if (ch->rx_ring.inuse[i] == buf) {
			ch->rx_ring.inuse[i] = NULL;
			ch->rx_ring.inuse_cnt--;
			ret = 0;
			break;
		}
	}

	spin_unlock_bh(&ch->lock);

	if (!ret)
		kfree(buf);

	return ret;
}

/*
 * riocm_ch_receive - fetch a data packet received for the specified channel
 * @ch: local channel ID
 * @buf: pointer to a packet buffer
 * @timeout: timeout to wait for incoming packet (in jiffies)
 *
 * Returns: 0 and valid buffer pointer if success, or NULL pointer and one of:
 *          -EAGAIN if a channel is not in CONNECTED state,
 *          -ENOMEM if in-use tracking queue is full,
 *          -ETIME if wait timeout expired,
 *	    -EINTR if wait was interrupted.
 */
static int riocm_ch_receive(struct rio_channel *ch, void **buf, long timeout)
{
	void *rxmsg = NULL;
	int i, ret = 0;
	long wret;

	if (!riocm_cmp(ch, RIO_CM_CONNECTED)) {
		ret = -EAGAIN;
		goto out;
	}

	if (ch->rx_ring.inuse_cnt == RIOCM_RX_RING_SIZE) {
		/* If we do not have entries to track buffers given to upper
		 * layer, reject request.
		 */
		ret = -ENOMEM;
		goto out;
	}

	wret = wait_for_completion_interruptible_timeout(&ch->comp, timeout);

	riocm_debug(WAIT, "wait on %d returned %ld", ch->id, wret);

	if (!wret)
		ret = -ETIME;
	else if (wret == -ERESTARTSYS)
		ret = -EINTR;
	else
		ret = riocm_cmp(ch, RIO_CM_CONNECTED) ? 0 : -ECONNRESET;

	if (ret)
		goto out;

	spin_lock_bh(&ch->lock);

	rxmsg = ch->rx_ring.buf[ch->rx_ring.tail];
	ch->rx_ring.buf[ch->rx_ring.tail] = NULL;
	ch->rx_ring.count--;
	ch->rx_ring.tail++;
	ch->rx_ring.tail %= RIOCM_RX_RING_SIZE;
	ret = -ENOMEM;

	for (i = 0; i < RIOCM_RX_RING_SIZE; i++) {
		if (ch->rx_ring.inuse[i] == NULL) {
			ch->rx_ring.inuse[i] = rxmsg;
			ch->rx_ring.inuse_cnt++;
			ret = 0;
			break;
		}
	}

	if (ret) {
		/* We have no entry to store pending message: drop it */
		kfree(rxmsg);
		rxmsg = NULL;
	}

	spin_unlock_bh(&ch->lock);
out:
	*buf = rxmsg;
	return ret;
}

/*
 * riocm_ch_connect - sends a connect request to a remote device
 * @loc_ch: local channel ID
 * @cm: CM device to send connect request
 * @peer: target RapidIO device
 * @rem_ch: remote channel ID
 *
 * Returns: 0 if success, or
 *          -EINVAL if the channel is not in IDLE state,
 *          -EAGAIN if no connection request available immediately,
 *          -ETIME if ACK response timeout expired,
 *          -EINTR if wait for response was interrupted.
 */
static int riocm_ch_connect(u16 loc_ch, struct cm_dev *cm,
			    struct cm_peer *peer, u16 rem_ch)
{
	struct rio_channel *ch = NULL;
	struct rio_ch_chan_hdr *hdr;
	int ret;
	long wret;

	ch = riocm_get_channel(loc_ch);
	if (!ch)
		return -ENODEV;

	if (!riocm_cmp_exch(ch, RIO_CM_IDLE, RIO_CM_CONNECT)) {
		ret = -EINVAL;
		goto conn_done;
	}

	ch->cmdev = cm;
	ch->rdev = peer->rdev;
	ch->context = NULL;
	ch->loc_destid = cm->mport->host_deviceid;
	ch->rem_channel = rem_ch;

	/*
	 * Send connect request to the remote RapidIO device
	 */

	hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
	if (hdr == NULL) {
		ret = -ENOMEM;
		goto conn_done;
	}

	hdr->bhdr.src_id = htonl(ch->loc_destid);
	hdr->bhdr.dst_id = htonl(peer->rdev->destid);
	hdr->bhdr.src_mbox = cmbox;
	hdr->bhdr.dst_mbox = cmbox;
	hdr->bhdr.type = RIO_CM_CHAN;
	hdr->ch_op = CM_CONN_REQ;
	hdr->dst_ch = htons(rem_ch);
	hdr->src_ch = htons(loc_ch);

	/* ATTN: the function call below relies on the fact that underlying
	 * HW-specific add_outb_message() routine copies TX data into its
	 * internal transfer buffer. Must be reviewed if mport driver uses
	 * this buffer directly.
	 */
	ret = riocm_post_send(cm, peer->rdev, hdr, sizeof(*hdr));

	if (ret != -EBUSY) {
		kfree(hdr);
	} else {
		ret = riocm_queue_req(cm, peer->rdev, hdr, sizeof(*hdr));
		if (ret)
			kfree(hdr);
	}

	if (ret) {
		riocm_cmp_exch(ch, RIO_CM_CONNECT, RIO_CM_IDLE);
		goto conn_done;
	}

	/* Wait for connect response from the remote device */
	wret = wait_for_completion_interruptible_timeout(&ch->comp,
							 RIOCM_CONNECT_TO * HZ);
	riocm_debug(WAIT, "wait on %d returns %ld", ch->id, wret);

	if (!wret)
		ret = -ETIME;
	else if (wret == -ERESTARTSYS)
		ret = -EINTR;
	else
		ret = riocm_cmp(ch, RIO_CM_CONNECTED) ? 0 : -1;

conn_done:
	riocm_put_channel(ch);
	return ret;
}

static int riocm_send_ack(struct rio_channel *ch)
{
	struct rio_ch_chan_hdr *hdr;
	int ret;

	hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
	if (hdr == NULL)
		return -ENOMEM;

	hdr->bhdr.src_id = htonl(ch->loc_destid);
	hdr->bhdr.dst_id = htonl(ch->rem_destid);
	hdr->dst_ch = htons(ch->rem_channel);
	hdr->src_ch = htons(ch->id);
	hdr->bhdr.src_mbox = cmbox;
	hdr->bhdr.dst_mbox = cmbox;
	hdr->bhdr.type = RIO_CM_CHAN;
	hdr->ch_op = CM_CONN_ACK;

	/* ATTN: the function call below relies on the fact that underlying
	 * add_outb_message() routine copies TX data into its internal transfer
	 * buffer. Review if switching to direct buffer version.
	 */
	ret = riocm_post_send(ch->cmdev, ch->rdev, hdr, sizeof(*hdr));

	if (ret == -EBUSY && !riocm_queue_req(ch->cmdev,
					      ch->rdev, hdr, sizeof(*hdr)))
		return 0;
	kfree(hdr);

	if (ret)
		riocm_error("send ACK to ch_%d on %s failed (ret=%d)",
			    ch->id, rio_name(ch->rdev), ret);
	return ret;
}

/*
 * riocm_ch_accept - accept incoming connection request
 * @ch_id: channel ID
 * @new_ch_id: local mport device
 * @timeout: wait timeout (if 0 non-blocking call, do not wait if connection
 *           request is not available).
 *
 * Returns: pointer to new channel struct if success, or error-valued pointer:
 *          -ENODEV - cannot find specified channel or mport,
 *          -EINVAL - the channel is not in IDLE state,
 *          -EAGAIN - no connection request available immediately (timeout=0),
 *          -ENOMEM - unable to allocate new channel,
 *          -ETIME - wait timeout expired,
 *          -EINTR - wait was interrupted.
 */
static struct rio_channel *riocm_ch_accept(u16 ch_id, u16 *new_ch_id,
					   long timeout)
{
	struct rio_channel *ch = NULL;
	struct rio_channel *new_ch = NULL;
	struct conn_req *req;
	struct cm_peer *peer;
	int found = 0;
	int err = 0;
	long wret;

	ch = riocm_get_channel(ch_id);
	if (!ch)
		return ERR_PTR(-EINVAL);

	if (!riocm_cmp(ch, RIO_CM_LISTEN)) {
		err = -EINVAL;
		goto err_put;
	}

	/* Don't sleep if this is a non blocking call */
	if (!timeout) {
		if (!try_wait_for_completion(&ch->comp)) {
			err = -EAGAIN;
			goto err_put;
		}
	} else {
		riocm_debug(WAIT, "on %d", ch->id);

		wret = wait_for_completion_interruptible_timeout(&ch->comp,
								 timeout);
		if (!wret) {
			err = -ETIME;
			goto err_put;
		} else if (wret == -ERESTARTSYS) {
			err = -EINTR;
			goto err_put;
		}
	}

	spin_lock_bh(&ch->lock);

	if (ch->state != RIO_CM_LISTEN) {
		err = -ECANCELED;
	} else if (list_empty(&ch->accept_queue)) {
		riocm_debug(WAIT, "on %d accept_queue is empty on completion",
			    ch->id);
		err = -EIO;
	}

	spin_unlock_bh(&ch->lock);

	if (err) {
		riocm_debug(WAIT, "on %d returns %d", ch->id, err);
		goto err_put;
	}

	/* Create new channel for this connection */
	new_ch = riocm_ch_alloc(RIOCM_CHNUM_AUTO);

	if (IS_ERR(new_ch)) {
		riocm_error("failed to get channel for new req (%ld)",
			PTR_ERR(new_ch));
		err = -ENOMEM;
		goto err_put;
	}

	spin_lock_bh(&ch->lock);

	req = list_first_entry(&ch->accept_queue, struct conn_req, node);
	list_del(&req->node);
	new_ch->cmdev = ch->cmdev;
	new_ch->loc_destid = ch->loc_destid;
	new_ch->rem_destid = req->destid;
	new_ch->rem_channel = req->chan;

	spin_unlock_bh(&ch->lock);
	riocm_put_channel(ch);
	kfree(req);

	down_read(&rdev_sem);
	/* Find requester's device object */
	list_for_each_entry(peer, &new_ch->cmdev->peers, node) {
		if (peer->rdev->destid == new_ch->rem_destid) {
			riocm_debug(RX_CMD, "found matching device(%s)",
				    rio_name(peer->rdev));
			found = 1;
			break;
		}
	}
	up_read(&rdev_sem);

	if (!found) {
		/* If peer device object not found, simply ignore the request */
		err = -ENODEV;
		goto err_nodev;
	}

	new_ch->rdev = peer->rdev;
	new_ch->state = RIO_CM_CONNECTED;
	spin_lock_init(&new_ch->lock);

	/* Acknowledge the connection request. */
	riocm_send_ack(new_ch);

	*new_ch_id = new_ch->id;
	return new_ch;
err_put:
	riocm_put_channel(ch);
err_nodev:
	if (new_ch) {
		spin_lock_bh(&idr_lock);
		idr_remove(&ch_idr, new_ch->id);
		spin_unlock_bh(&idr_lock);
		riocm_put_channel(new_ch);
	}
	*new_ch_id = 0;
	return ERR_PTR(err);
}

/*
 * riocm_ch_listen - puts a channel into LISTEN state
 * @ch_id: channel ID
 *
 * Returns: 0 if success, or
 *          -EINVAL if the specified channel does not exists or
 *                  is not in CHAN_BOUND state.
 */
static int riocm_ch_listen(u16 ch_id)
{
	struct rio_channel *ch = NULL;
	int ret = 0;

	riocm_debug(CHOP, "(ch_%d)", ch_id);

	ch = riocm_get_channel(ch_id);
	if (!ch || !riocm_cmp_exch(ch, RIO_CM_CHAN_BOUND, RIO_CM_LISTEN))
		ret = -EINVAL;
	riocm_put_channel(ch);
	return ret;
}

/*
 * riocm_ch_bind - associate a channel object and an mport device
 * @ch_id: channel ID
 * @mport_id: local mport device ID
 * @context: pointer to the additional caller's context
 *
 * Returns: 0 if success, or
 *          -ENODEV if cannot find specified mport,
 *          -EINVAL if the specified channel does not exist or
 *                  is not in IDLE state.
 */
static int riocm_ch_bind(u16 ch_id, u8 mport_id, void *context)
{
	struct rio_channel *ch = NULL;
	struct cm_dev *cm;
	int rc = -ENODEV;

	riocm_debug(CHOP, "ch_%d to mport_%d", ch_id, mport_id);

	/* Find matching cm_dev object */
	down_read(&rdev_sem);
	list_for_each_entry(cm, &cm_dev_list, list) {
		if ((cm->mport->id == mport_id) &&
		     rio_mport_is_running(cm->mport)) {
			rc = 0;
			break;
		}
	}

	if (rc)
		goto exit;

	ch = riocm_get_channel(ch_id);
	if (!ch) {
		rc = -EINVAL;
		goto exit;
	}

	spin_lock_bh(&ch->lock);
	if (ch->state != RIO_CM_IDLE) {
		spin_unlock_bh(&ch->lock);
		rc = -EINVAL;
		goto err_put;
	}

	ch->cmdev = cm;
	ch->loc_destid = cm->mport->host_deviceid;
	ch->context = context;
	ch->state = RIO_CM_CHAN_BOUND;
	spin_unlock_bh(&ch->lock);
err_put:
	riocm_put_channel(ch);
exit:
	up_read(&rdev_sem);
	return rc;
}

/*
 * riocm_ch_alloc - channel object allocation helper routine
 * @ch_num: channel ID (1 ... RIOCM_MAX_CHNUM, 0 = automatic)
 *
 * Return value: pointer to newly created channel object,
 *               or error-valued pointer
 */
static struct rio_channel *riocm_ch_alloc(u16 ch_num)
{
	int id;
	int start, end;
	struct rio_channel *ch;

	ch = kzalloc(sizeof(*ch), GFP_KERNEL);
	if (!ch)
		return ERR_PTR(-ENOMEM);

	if (ch_num) {
		/* If requested, try to obtain the specified channel ID */
		start = ch_num;
		end = ch_num + 1;
	} else {
		/* Obtain channel ID from the dynamic allocation range */
		start = chstart;
		end = RIOCM_MAX_CHNUM + 1;
	}

	idr_preload(GFP_KERNEL);
	spin_lock_bh(&idr_lock);
	id = idr_alloc_cyclic(&ch_idr, ch, start, end, GFP_NOWAIT);
	spin_unlock_bh(&idr_lock);
	idr_preload_end();

	if (id < 0) {
		kfree(ch);
		return ERR_PTR(id == -ENOSPC ? -EBUSY : id);
	}

	ch->id = (u16)id;
	ch->state = RIO_CM_IDLE;
	spin_lock_init(&ch->lock);
	INIT_LIST_HEAD(&ch->accept_queue);
	INIT_LIST_HEAD(&ch->ch_node);
	init_completion(&ch->comp);
	init_completion(&ch->comp_close);
	kref_init(&ch->ref);
	ch->rx_ring.head = 0;
	ch->rx_ring.tail = 0;
	ch->rx_ring.count = 0;
	ch->rx_ring.inuse_cnt = 0;

	return ch;
}

/*
 * riocm_ch_create - creates a new channel object and allocates ID for it
 * @ch_num: channel ID (1 ... RIOCM_MAX_CHNUM, 0 = automatic)
 *
 * Allocates and initializes a new channel object. If the parameter ch_num > 0
 * and is within the valid range, riocm_ch_create tries to allocate the
 * specified ID for the new channel. If ch_num = 0, channel ID will be assigned
 * automatically from the range (chstart ... RIOCM_MAX_CHNUM).
 * Module parameter 'chstart' defines start of an ID range available for dynamic
 * allocation. Range below 'chstart' is reserved for pre-defined ID numbers.
 * Available channel numbers are limited by 16-bit size of channel numbers used
 * in the packet header.
 *
 * Return value: PTR to rio_channel structure if successful (with channel number
 *               updated via pointer) or error-valued pointer if error.
 */
static struct rio_channel *riocm_ch_create(u16 *ch_num)
{
	struct rio_channel *ch = NULL;

	ch = riocm_ch_alloc(*ch_num);

	if (IS_ERR(ch))
		riocm_debug(CHOP, "Failed to allocate channel %d (err=%ld)",
			    *ch_num, PTR_ERR(ch));
	else
		*ch_num = ch->id;

	return ch;
}

/*
 * riocm_ch_free - channel object release routine
 * @ref: pointer to a channel's kref structure
 */
static void riocm_ch_free(struct kref *ref)
{
	struct rio_channel *ch = container_of(ref, struct rio_channel, ref);
	int i;

	riocm_debug(CHOP, "(ch_%d)", ch->id);

	if (ch->rx_ring.inuse_cnt) {
		for (i = 0;
		     i < RIOCM_RX_RING_SIZE && ch->rx_ring.inuse_cnt; i++) {
			if (ch->rx_ring.inuse[i] != NULL) {
				kfree(ch->rx_ring.inuse[i]);
				ch->rx_ring.inuse_cnt--;
			}
		}
	}

	if (ch->rx_ring.count)
		for (i = 0; i < RIOCM_RX_RING_SIZE && ch->rx_ring.count; i++) {
			if (ch->rx_ring.buf[i] != NULL) {
				kfree(ch->rx_ring.buf[i]);
				ch->rx_ring.count--;
			}
		}

	complete(&ch->comp_close);
}

static int riocm_send_close(struct rio_channel *ch)
{
	struct rio_ch_chan_hdr *hdr;
	int ret;

	/*
	 * Send CH_CLOSE notification to the remote RapidIO device
	 */

	hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
	if (hdr == NULL)
		return -ENOMEM;

	hdr->bhdr.src_id = htonl(ch->loc_destid);
	hdr->bhdr.dst_id = htonl(ch->rem_destid);
	hdr->bhdr.src_mbox = cmbox;
	hdr->bhdr.dst_mbox = cmbox;
	hdr->bhdr.type = RIO_CM_CHAN;
	hdr->ch_op = CM_CONN_CLOSE;
	hdr->dst_ch = htons(ch->rem_channel);
	hdr->src_ch = htons(ch->id);

	/* ATTN: the function call below relies on the fact that underlying
	 * add_outb_message() routine copies TX data into its internal transfer
	 * buffer. Needs to be reviewed if switched to direct buffer mode.
	 */
	ret = riocm_post_send(ch->cmdev, ch->rdev, hdr, sizeof(*hdr));

	if (ret == -EBUSY && !riocm_queue_req(ch->cmdev, ch->rdev,
					      hdr, sizeof(*hdr)))
		return 0;
	kfree(hdr);

	if (ret)
		riocm_error("ch(%d) send CLOSE failed (ret=%d)", ch->id, ret);

	return ret;
}

/*
 * riocm_ch_close - closes a channel object with specified ID (by local request)
 * @ch: channel to be closed
 */
static int riocm_ch_close(struct rio_channel *ch)
{
	unsigned long tmo = msecs_to_jiffies(3000);
	enum rio_cm_state state;
	long wret;
	int ret = 0;

	riocm_debug(CHOP, "ch_%d by %s(%d)",
		    ch->id, current->comm, task_pid_nr(current));

	state = riocm_exch(ch, RIO_CM_DESTROYING);
	if (state == RIO_CM_CONNECTED)
		riocm_send_close(ch);

	complete_all(&ch->comp);

	riocm_put_channel(ch);
	wret = wait_for_completion_interruptible_timeout(&ch->comp_close, tmo);

	riocm_debug(WAIT, "wait on %d returns %ld", ch->id, wret);

	if (wret == 0) {
		/* Timeout on wait occurred */
		riocm_debug(CHOP, "%s(%d) timed out waiting for ch %d",
		       current->comm, task_pid_nr(current), ch->id);
		ret = -ETIMEDOUT;
	} else if (wret == -ERESTARTSYS) {
		/* Wait_for_completion was interrupted by a signal */
		riocm_debug(CHOP, "%s(%d) wait for ch %d was interrupted",
			current->comm, task_pid_nr(current), ch->id);
		ret = -EINTR;
	}

	if (!ret) {
		riocm_debug(CHOP, "ch_%d resources released", ch->id);
		kfree(ch);
	} else {
		riocm_debug(CHOP, "failed to release ch_%d resources", ch->id);
	}

	return ret;
}

/*
 * riocm_cdev_open() - Open character device
 */
static int riocm_cdev_open(struct inode *inode, struct file *filp)
{
	riocm_debug(INIT, "by %s(%d) filp=%p ",
		    current->comm, task_pid_nr(current), filp);

	if (list_empty(&cm_dev_list))
		return -ENODEV;

	return 0;
}

/*
 * riocm_cdev_release() - Release character device
 */
static int riocm_cdev_release(struct inode *inode, struct file *filp)
{
	struct rio_channel *ch, *_c;
	unsigned int i;
	LIST_HEAD(list);

	riocm_debug(EXIT, "by %s(%d) filp=%p",
		    current->comm, task_pid_nr(current), filp);

	/* Check if there are channels associated with this file descriptor */
	spin_lock_bh(&idr_lock);
	idr_for_each_entry(&ch_idr, ch, i) {
		if (ch && ch->filp == filp) {
			riocm_debug(EXIT, "ch_%d not released by %s(%d)",
				    ch->id, current->comm,
				    task_pid_nr(current));
			idr_remove(&ch_idr, ch->id);
			list_add(&ch->ch_node, &list);
		}
	}
	spin_unlock_bh(&idr_lock);

	if (!list_empty(&list)) {
		list_for_each_entry_safe(ch, _c, &list, ch_node) {
			list_del(&ch->ch_node);
			riocm_ch_close(ch);
		}
	}

	return 0;
}

/*
 * cm_ep_get_list_size() - Reports number of endpoints in the network
 */
static int cm_ep_get_list_size(void __user *arg)
{
	u32 __user *p = arg;
	u32 mport_id;
	u32 count = 0;
	struct cm_dev *cm;

	if (get_user(mport_id, p))
		return -EFAULT;
	if (mport_id >= RIO_MAX_MPORTS)
		return -EINVAL;

	/* Find a matching cm_dev object */
	down_read(&rdev_sem);
	list_for_each_entry(cm, &cm_dev_list, list) {
		if (cm->mport->id == mport_id) {
			count = cm->npeers;
			up_read(&rdev_sem);
			if (copy_to_user(arg, &count, sizeof(u32)))
				return -EFAULT;
			return 0;
		}
	}
	up_read(&rdev_sem);

	return -ENODEV;
}

/*
 * cm_ep_get_list() - Returns list of attached endpoints
 */
static int cm_ep_get_list(void __user *arg)
{
	struct cm_dev *cm;
	struct cm_peer *peer;
	u32 info[2];
	void *buf;
	u32 nent;
	u32 *entry_ptr;
	u32 i = 0;
	int ret = 0;

	if (copy_from_user(&info, arg, sizeof(info)))
		return -EFAULT;

	if (info[1] >= RIO_MAX_MPORTS || info[0] > RIOCM_MAX_EP_COUNT)
		return -EINVAL;

	/* Find a matching cm_dev object */
	down_read(&rdev_sem);
	list_for_each_entry(cm, &cm_dev_list, list)
		if (cm->mport->id == (u8)info[1])
			goto found;

	up_read(&rdev_sem);
	return -ENODEV;

found:
	nent = min(info[0], cm->npeers);
	buf = kcalloc(nent + 2, sizeof(u32), GFP_KERNEL);
	if (!buf) {
		up_read(&rdev_sem);
		return -ENOMEM;
	}

	entry_ptr = (u32 *)((uintptr_t)buf + 2*sizeof(u32));

	list_for_each_entry(peer, &cm->peers, node) {
		*entry_ptr = (u32)peer->rdev->destid;
		entry_ptr++;
		if (++i == nent)
			break;
	}
	up_read(&rdev_sem);

	((u32 *)buf)[0] = i; /* report an updated number of entries */
	((u32 *)buf)[1] = info[1]; /* put back an mport ID */
	if (copy_to_user(arg, buf, sizeof(u32) * (info[0] + 2)))
		ret = -EFAULT;

	kfree(buf);
	return ret;
}

/*
 * cm_mport_get_list() - Returns list of available local mport devices
 */
static int cm_mport_get_list(void __user *arg)
{
	int ret = 0;
	u32 entries;
	void *buf;
	struct cm_dev *cm;
	u32 *entry_ptr;
	int count = 0;

	if (copy_from_user(&entries, arg, sizeof(entries)))
		return -EFAULT;
	if (entries == 0 || entries > RIO_MAX_MPORTS)
		return -EINVAL;
	buf = kcalloc(entries + 1, sizeof(u32), GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	/* Scan all registered cm_dev objects */
	entry_ptr = (u32 *)((uintptr_t)buf + sizeof(u32));
	down_read(&rdev_sem);
	list_for_each_entry(cm, &cm_dev_list, list) {
		if (count++ < entries) {
			*entry_ptr = (cm->mport->id << 16) |
				      cm->mport->host_deviceid;
			entry_ptr++;
		}
	}
	up_read(&rdev_sem);

	*((u32 *)buf) = count; /* report a real number of entries */
	if (copy_to_user(arg, buf, sizeof(u32) * (count + 1)))
		ret = -EFAULT;

	kfree(buf);
	return ret;
}

/*
 * cm_chan_create() - Create a message exchange channel
 */
static int cm_chan_create(struct file *filp, void __user *arg)
{
	u16 __user *p = arg;
	u16 ch_num;
	struct rio_channel *ch;

	if (get_user(ch_num, p))
		return -EFAULT;

	riocm_debug(CHOP, "ch_%d requested by %s(%d)",
		    ch_num, current->comm, task_pid_nr(current));
	ch = riocm_ch_create(&ch_num);
	if (IS_ERR(ch))
		return PTR_ERR(ch);

	ch->filp = filp;
	riocm_debug(CHOP, "ch_%d created by %s(%d)",
		    ch_num, current->comm, task_pid_nr(current));
	return put_user(ch_num, p);
}

/*
 * cm_chan_close() - Close channel
 * @filp:	Pointer to file object
 * @arg:	Channel to close
 */
static int cm_chan_close(struct file *filp, void __user *arg)
{
	u16 __user *p = arg;
	u16 ch_num;
	struct rio_channel *ch;

	if (get_user(ch_num, p))
		return -EFAULT;

	riocm_debug(CHOP, "ch_%d by %s(%d)",
		    ch_num, current->comm, task_pid_nr(current));

	spin_lock_bh(&idr_lock);
	ch = idr_find(&ch_idr, ch_num);
	if (!ch) {
		spin_unlock_bh(&idr_lock);
		return 0;
	}
	if (ch->filp != filp) {
		spin_unlock_bh(&idr_lock);
		return -EINVAL;
	}
	idr_remove(&ch_idr, ch->id);
	spin_unlock_bh(&idr_lock);

	return riocm_ch_close(ch);
}

/*
 * cm_chan_bind() - Bind channel
 * @arg:	Channel number
 */
static int cm_chan_bind(void __user *arg)
{
	struct rio_cm_channel chan;

	if (copy_from_user(&chan, arg, sizeof(chan)))
		return -EFAULT;
	if (chan.mport_id >= RIO_MAX_MPORTS)
		return -EINVAL;

	return riocm_ch_bind(chan.id, chan.mport_id, NULL);
}

/*
 * cm_chan_listen() - Listen on channel
 * @arg:	Channel number
 */
static int cm_chan_listen(void __user *arg)
{
	u16 __user *p = arg;
	u16 ch_num;

	if (get_user(ch_num, p))
		return -EFAULT;

	return riocm_ch_listen(ch_num);
}

/*
 * cm_chan_accept() - Accept incoming connection
 * @filp:	Pointer to file object
 * @arg:	Channel number
 */
static int cm_chan_accept(struct file *filp, void __user *arg)
{
	struct rio_cm_accept param;
	long accept_to;
	struct rio_channel *ch;

	if (copy_from_user(&param, arg, sizeof(param)))
		return -EFAULT;

	riocm_debug(CHOP, "on ch_%d by %s(%d)",
		    param.ch_num, current->comm, task_pid_nr(current));

	accept_to = param.wait_to ?
			msecs_to_jiffies(param.wait_to) : 0;

	ch = riocm_ch_accept(param.ch_num, &param.ch_num, accept_to);
	if (IS_ERR(ch))
		return PTR_ERR(ch);
	ch->filp = filp;

	riocm_debug(CHOP, "new ch_%d for %s(%d)",
		    ch->id, current->comm, task_pid_nr(current));

	if (copy_to_user(arg, &param, sizeof(param)))
		return -EFAULT;
	return 0;
}

/*
 * cm_chan_connect() - Connect on channel
 * @arg:	Channel information
 */
static int cm_chan_connect(void __user *arg)
{
	struct rio_cm_channel chan;
	struct cm_dev *cm;
	struct cm_peer *peer;
	int ret = -ENODEV;

	if (copy_from_user(&chan, arg, sizeof(chan)))
		return -EFAULT;
	if (chan.mport_id >= RIO_MAX_MPORTS)
		return -EINVAL;

	down_read(&rdev_sem);

	/* Find matching cm_dev object */
	list_for_each_entry(cm, &cm_dev_list, list) {
		if (cm->mport->id == chan.mport_id) {
			ret = 0;
			break;
		}
	}

	if (ret)
		goto err_out;

	if (chan.remote_destid >= RIO_ANY_DESTID(cm->mport->sys_size)) {
		ret = -EINVAL;
		goto err_out;
	}

	/* Find corresponding RapidIO endpoint device object */
	ret = -ENODEV;

	list_for_each_entry(peer, &cm->peers, node) {
		if (peer->rdev->destid == chan.remote_destid) {
			ret = 0;
			break;
		}
	}

	if (ret)
		goto err_out;

	up_read(&rdev_sem);

	return riocm_ch_connect(chan.id, cm, peer, chan.remote_channel);
err_out:
	up_read(&rdev_sem);
	return ret;
}

/*
 * cm_chan_msg_send() - Send a message through channel
 * @arg:	Outbound message information
 */
static int cm_chan_msg_send(void __user *arg)
{
	struct rio_cm_msg msg;
	void *buf;
	int ret = 0;

	if (copy_from_user(&msg, arg, sizeof(msg)))
		return -EFAULT;
	if (msg.size > RIO_MAX_MSG_SIZE)
		return -EINVAL;

	buf = kmalloc(msg.size, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	if (copy_from_user(buf, (void __user *)(uintptr_t)msg.msg, msg.size)) {
		ret = -EFAULT;
		goto out;
	}

	ret = riocm_ch_send(msg.ch_num, buf, msg.size);
out:
	kfree(buf);
	return ret;
}

/*
 * cm_chan_msg_rcv() - Receive a message through channel
 * @arg:	Inbound message information
 */
static int cm_chan_msg_rcv(void __user *arg)
{
	struct rio_cm_msg msg;
	struct rio_channel *ch;
	void *buf;
	long rxto;
	int ret = 0, msg_size;

	if (copy_from_user(&msg, arg, sizeof(msg)))
		return -EFAULT;

	if (msg.ch_num == 0 || msg.size == 0)
		return -EINVAL;

	ch = riocm_get_channel(msg.ch_num);
	if (!ch)
		return -ENODEV;

	rxto = msg.rxto ? msecs_to_jiffies(msg.rxto) : MAX_SCHEDULE_TIMEOUT;

	ret = riocm_ch_receive(ch, &buf, rxto);
	if (ret)
		goto out;

	msg_size = min(msg.size, (u16)(RIO_MAX_MSG_SIZE));

	if (copy_to_user((void __user *)(uintptr_t)msg.msg, buf, msg_size))
		ret = -EFAULT;

	riocm_ch_free_rxbuf(ch, buf);
out:
	riocm_put_channel(ch);
	return ret;
}

/*
 * riocm_cdev_ioctl() - IOCTL requests handler
 */
static long
riocm_cdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	switch (cmd) {
	case RIO_CM_EP_GET_LIST_SIZE:
		return cm_ep_get_list_size((void __user *)arg);
	case RIO_CM_EP_GET_LIST:
		return cm_ep_get_list((void __user *)arg);
	case RIO_CM_CHAN_CREATE:
		return cm_chan_create(filp, (void __user *)arg);
	case RIO_CM_CHAN_CLOSE:
		return cm_chan_close(filp, (void __user *)arg);
	case RIO_CM_CHAN_BIND:
		return cm_chan_bind((void __user *)arg);
	case RIO_CM_CHAN_LISTEN:
		return cm_chan_listen((void __user *)arg);
	case RIO_CM_CHAN_ACCEPT:
		return cm_chan_accept(filp, (void __user *)arg);
	case RIO_CM_CHAN_CONNECT:
		return cm_chan_connect((void __user *)arg);
	case RIO_CM_CHAN_SEND:
		return cm_chan_msg_send((void __user *)arg);
	case RIO_CM_CHAN_RECEIVE:
		return cm_chan_msg_rcv((void __user *)arg);
	case RIO_CM_MPORT_GET_LIST:
		return cm_mport_get_list((void __user *)arg);
	default:
		break;
	}

	return -EINVAL;
}

static const struct file_operations riocm_cdev_fops = {
	.owner		= THIS_MODULE,
	.open		= riocm_cdev_open,
	.release	= riocm_cdev_release,
	.unlocked_ioctl = riocm_cdev_ioctl,
};

/*
 * riocm_add_dev - add new remote RapidIO device into channel management core
 * @dev: device object associated with RapidIO device
 * @sif: subsystem interface
 *
 * Adds the specified RapidIO device (if applicable) into peers list of
 * the corresponding channel management device (cm_dev).
 */
static int riocm_add_dev(struct device *dev, struct subsys_interface *sif)
{
	struct cm_peer *peer;
	struct rio_dev *rdev = to_rio_dev(dev);
	struct cm_dev *cm;

	/* Check if the remote device has capabilities required to support CM */
	if (!dev_cm_capable(rdev))
		return 0;

	riocm_debug(RDEV, "(%s)", rio_name(rdev));

	peer = kmalloc(sizeof(*peer), GFP_KERNEL);
	if (!peer)
		return -ENOMEM;

	/* Find a corresponding cm_dev object */
	down_write(&rdev_sem);
	list_for_each_entry(cm, &cm_dev_list, list) {
		if (cm->mport == rdev->net->hport)
			goto found;
	}

	up_write(&rdev_sem);
	kfree(peer);
	return -ENODEV;

found:
	peer->rdev = rdev;
	list_add_tail(&peer->node, &cm->peers);
	cm->npeers++;

	up_write(&rdev_sem);
	return 0;
}

/*
 * riocm_remove_dev - remove remote RapidIO device from channel management core
 * @dev: device object associated with RapidIO device
 * @sif: subsystem interface
 *
 * Removes the specified RapidIO device (if applicable) from peers list of
 * the corresponding channel management device (cm_dev).
 */
static void riocm_remove_dev(struct device *dev, struct subsys_interface *sif)
{
	struct rio_dev *rdev = to_rio_dev(dev);
	struct cm_dev *cm;
	struct cm_peer *peer;
	struct rio_channel *ch, *_c;
	unsigned int i;
	bool found = false;
	LIST_HEAD(list);

	/* Check if the remote device has capabilities required to support CM */
	if (!dev_cm_capable(rdev))
		return;

	riocm_debug(RDEV, "(%s)", rio_name(rdev));

	/* Find matching cm_dev object */
	down_write(&rdev_sem);
	list_for_each_entry(cm, &cm_dev_list, list) {
		if (cm->mport == rdev->net->hport) {
			found = true;
			break;
		}
	}

	if (!found) {
		up_write(&rdev_sem);
		return;
	}

	/* Remove remote device from the list of peers */
	found = false;
	list_for_each_entry(peer, &cm->peers, node) {
		if (peer->rdev == rdev) {
			riocm_debug(RDEV, "removing peer %s", rio_name(rdev));
			found = true;
			list_del(&peer->node);
			cm->npeers--;
			kfree(peer);
			break;
		}
	}

	up_write(&rdev_sem);

	if (!found)
		return;

	/*
	 * Release channels associated with this peer
	 */

	spin_lock_bh(&idr_lock);
	idr_for_each_entry(&ch_idr, ch, i) {
		if (ch && ch->rdev == rdev) {
			if (atomic_read(&rdev->state) != RIO_DEVICE_SHUTDOWN)
				riocm_exch(ch, RIO_CM_DISCONNECT);
			idr_remove(&ch_idr, ch->id);
			list_add(&ch->ch_node, &list);
		}
	}
	spin_unlock_bh(&idr_lock);

	if (!list_empty(&list)) {
		list_for_each_entry_safe(ch, _c, &list, ch_node) {
			list_del(&ch->ch_node);
			riocm_ch_close(ch);
		}
	}
}

/*
 * riocm_cdev_add() - Create rio_cm char device
 * @devno: device number assigned to device (MAJ + MIN)
 */
static int riocm_cdev_add(dev_t devno)
{
	int ret;

	cdev_init(&riocm_cdev.cdev, &riocm_cdev_fops);
	riocm_cdev.cdev.owner = THIS_MODULE;
	ret = cdev_add(&riocm_cdev.cdev, devno, 1);
	if (ret < 0) {
		riocm_error("Cannot register a device with error %d", ret);
		return ret;
	}

	riocm_cdev.dev = device_create(dev_class, NULL, devno, NULL, DEV_NAME);
	if (IS_ERR(riocm_cdev.dev)) {
		cdev_del(&riocm_cdev.cdev);
		return PTR_ERR(riocm_cdev.dev);
	}

	riocm_debug(MPORT, "Added %s cdev(%d:%d)",
		    DEV_NAME, MAJOR(devno), MINOR(devno));

	return 0;
}

/*
 * riocm_add_mport - add new local mport device into channel management core
 * @dev: device object associated with mport
 * @class_intf: class interface
 *
 * When a new mport device is added, CM immediately reserves inbound and
 * outbound RapidIO mailboxes that will be used.
 */
static int riocm_add_mport(struct device *dev,
			   struct class_interface *class_intf)
{
	int rc;
	int i;
	struct cm_dev *cm;
	struct rio_mport *mport = to_rio_mport(dev);

	riocm_debug(MPORT, "add mport %s", mport->name);

	cm = kzalloc(sizeof(*cm), GFP_KERNEL);
	if (!cm)
		return -ENOMEM;

	cm->mport = mport;

	rc = rio_request_outb_mbox(mport, cm, cmbox,
				   RIOCM_TX_RING_SIZE, riocm_outb_msg_event);
	if (rc) {
		riocm_error("failed to allocate OBMBOX_%d on %s",
			    cmbox, mport->name);
		kfree(cm);
		return -ENODEV;
	}

	rc = rio_request_inb_mbox(mport, cm, cmbox,
				  RIOCM_RX_RING_SIZE, riocm_inb_msg_event);
	if (rc) {
		riocm_error("failed to allocate IBMBOX_%d on %s",
			    cmbox, mport->name);
		rio_release_outb_mbox(mport, cmbox);
		kfree(cm);
		return -ENODEV;
	}

	/*
	 * Allocate and register inbound messaging buffers to be ready
	 * to receive channel and system management requests
	 */
	for (i = 0; i < RIOCM_RX_RING_SIZE; i++)
		cm->rx_buf[i] = NULL;

	cm->rx_slots = RIOCM_RX_RING_SIZE;
	mutex_init(&cm->rx_lock);
	riocm_rx_fill(cm, RIOCM_RX_RING_SIZE);
	cm->rx_wq = create_workqueue(DRV_NAME "/rxq");
	INIT_WORK(&cm->rx_work, rio_ibmsg_handler);

	cm->tx_slot = 0;
	cm->tx_cnt = 0;
	cm->tx_ack_slot = 0;
	spin_lock_init(&cm->tx_lock);

	INIT_LIST_HEAD(&cm->peers);
	cm->npeers = 0;
	INIT_LIST_HEAD(&cm->tx_reqs);

	down_write(&rdev_sem);
	list_add_tail(&cm->list, &cm_dev_list);
	up_write(&rdev_sem);

	return 0;
}

/*
 * riocm_remove_mport - remove local mport device from channel management core
 * @dev: device object associated with mport
 * @class_intf: class interface
 *
 * Removes a local mport device from the list of registered devices that provide
 * channel management services. Returns an error if the specified mport is not
 * registered with the CM core.
 */
static void riocm_remove_mport(struct device *dev,
			       struct class_interface *class_intf)
{
	struct rio_mport *mport = to_rio_mport(dev);
	struct cm_dev *cm;
	struct cm_peer *peer, *temp;
	struct rio_channel *ch, *_c;
	unsigned int i;
	bool found = false;
	LIST_HEAD(list);

	riocm_debug(MPORT, "%s", mport->name);

	/* Find a matching cm_dev object */
	down_write(&rdev_sem);
	list_for_each_entry(cm, &cm_dev_list, list) {
		if (cm->mport == mport) {
			list_del(&cm->list);
			found = true;
			break;
		}
	}
	up_write(&rdev_sem);
	if (!found)
		return;

	flush_workqueue(cm->rx_wq);
	destroy_workqueue(cm->rx_wq);

	/* Release channels bound to this mport */
	spin_lock_bh(&idr_lock);
	idr_for_each_entry(&ch_idr, ch, i) {
		if (ch->cmdev == cm) {
			riocm_debug(RDEV, "%s drop ch_%d",
				    mport->name, ch->id);
			idr_remove(&ch_idr, ch->id);
			list_add(&ch->ch_node, &list);
		}
	}
	spin_unlock_bh(&idr_lock);

	if (!list_empty(&list)) {
		list_for_each_entry_safe(ch, _c, &list, ch_node) {
			list_del(&ch->ch_node);
			riocm_ch_close(ch);
		}
	}

	rio_release_inb_mbox(mport, cmbox);
	rio_release_outb_mbox(mport, cmbox);

	/* Remove and free peer entries */
	if (!list_empty(&cm->peers))
		riocm_debug(RDEV, "ATTN: peer list not empty");
	list_for_each_entry_safe(peer, temp, &cm->peers, node) {
		riocm_debug(RDEV, "removing peer %s", rio_name(peer->rdev));
		list_del(&peer->node);
		kfree(peer);
	}

	riocm_rx_free(cm);
	kfree(cm);
	riocm_debug(MPORT, "%s done", mport->name);
}

static int rio_cm_shutdown(struct notifier_block *nb, unsigned long code,
	void *unused)
{
	struct rio_channel *ch;
	unsigned int i;

	riocm_debug(EXIT, ".");

	spin_lock_bh(&idr_lock);
	idr_for_each_entry(&ch_idr, ch, i) {
		riocm_debug(EXIT, "close ch %d", ch->id);
		if (ch->state == RIO_CM_CONNECTED)
			riocm_send_close(ch);
	}
	spin_unlock_bh(&idr_lock);

	return NOTIFY_DONE;
}

/*
 * riocm_interface handles addition/removal of remote RapidIO devices
 */
static struct subsys_interface riocm_interface = {
	.name		= "rio_cm",
	.subsys		= &rio_bus_type,
	.add_dev	= riocm_add_dev,
	.remove_dev	= riocm_remove_dev,
};

/*
 * rio_mport_interface handles addition/removal local mport devices
 */
static struct class_interface rio_mport_interface __refdata = {
	.class = &rio_mport_class,
	.add_dev = riocm_add_mport,
	.remove_dev = riocm_remove_mport,
};

static struct notifier_block rio_cm_notifier = {
	.notifier_call = rio_cm_shutdown,
};

static int __init riocm_init(void)
{
	int ret;

	/* Create device class needed by udev */
	dev_class = class_create(THIS_MODULE, DRV_NAME);
	if (IS_ERR(dev_class)) {
		riocm_error("Cannot create " DRV_NAME " class");
		return PTR_ERR(dev_class);
	}

	ret = alloc_chrdev_region(&dev_number, 0, 1, DRV_NAME);
	if (ret) {
		class_destroy(dev_class);
		return ret;
	}

	dev_major = MAJOR(dev_number);
	dev_minor_base = MINOR(dev_number);
	riocm_debug(INIT, "Registered class with %d major", dev_major);

	/*
	 * Register as rapidio_port class interface to get notifications about
	 * mport additions and removals.
	 */
	ret = class_interface_register(&rio_mport_interface);
	if (ret) {
		riocm_error("class_interface_register error: %d", ret);
		goto err_reg;
	}

	/*
	 * Register as RapidIO bus interface to get notifications about
	 * addition/removal of remote RapidIO devices.
	 */
	ret = subsys_interface_register(&riocm_interface);
	if (ret) {
		riocm_error("subsys_interface_register error: %d", ret);
		goto err_cl;
	}

	ret = register_reboot_notifier(&rio_cm_notifier);
	if (ret) {
		riocm_error("failed to register reboot notifier (err=%d)", ret);
		goto err_sif;
	}

	ret = riocm_cdev_add(dev_number);
	if (ret) {
		unregister_reboot_notifier(&rio_cm_notifier);
		ret = -ENODEV;
		goto err_sif;
	}

	return 0;
err_sif:
	subsys_interface_unregister(&riocm_interface);
err_cl:
	class_interface_unregister(&rio_mport_interface);
err_reg:
	unregister_chrdev_region(dev_number, 1);
	class_destroy(dev_class);
	return ret;
}

static void __exit riocm_exit(void)
{
	riocm_debug(EXIT, "enter");
	unregister_reboot_notifier(&rio_cm_notifier);
	subsys_interface_unregister(&riocm_interface);
	class_interface_unregister(&rio_mport_interface);
	idr_destroy(&ch_idr);

	device_unregister(riocm_cdev.dev);
	cdev_del(&(riocm_cdev.cdev));

	class_destroy(dev_class);
	unregister_chrdev_region(dev_number, 1);
}

late_initcall(riocm_init);
module_exit(riocm_exit);
