// SPDX-License-Identifier: GPL-2.0+
/*
 * IBM Power Systems Virtual Management Channel Support.
 *
 * Copyright (c) 2004, 2018 IBM Corp.
 *   Dave Engebretsen engebret@us.ibm.com
 *   Steven Royer seroyer@linux.vnet.ibm.com
 *   Adam Reznechek adreznec@linux.vnet.ibm.com
 *   Bryant G. Ly <bryantly@linux.vnet.ibm.com>
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/major.h>
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/percpu.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/miscdevice.h>
#include <linux/sched/signal.h>

#include <asm/byteorder.h>
#include <asm/irq.h>
#include <asm/vio.h>

#include "ibmvmc.h"

#define IBMVMC_DRIVER_VERSION "1.0"

/*
 * Static global variables
 */
static DECLARE_WAIT_QUEUE_HEAD(ibmvmc_read_wait);

static const char ibmvmc_driver_name[] = "ibmvmc";

static struct ibmvmc_struct ibmvmc;
static struct ibmvmc_hmc hmcs[MAX_HMCS];
static struct crq_server_adapter ibmvmc_adapter;

static int ibmvmc_max_buf_pool_size = DEFAULT_BUF_POOL_SIZE;
static int ibmvmc_max_hmcs = DEFAULT_HMCS;
static int ibmvmc_max_mtu = DEFAULT_MTU;

static inline long h_copy_rdma(s64 length, u64 sliobn, u64 slioba,
			       u64 dliobn, u64 dlioba)
{
	long rc = 0;

	/* Ensure all writes to source memory are visible before hcall */
	dma_wmb();
	pr_debug("ibmvmc: h_copy_rdma(0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx\n",
		 length, sliobn, slioba, dliobn, dlioba);
	rc = plpar_hcall_norets(H_COPY_RDMA, length, sliobn, slioba,
				dliobn, dlioba);
	pr_debug("ibmvmc: h_copy_rdma rc = 0x%lx\n", rc);

	return rc;
}

static inline void h_free_crq(uint32_t unit_address)
{
	long rc = 0;

	do {
		if (H_IS_LONG_BUSY(rc))
			msleep(get_longbusy_msecs(rc));

		rc = plpar_hcall_norets(H_FREE_CRQ, unit_address);
	} while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
}

/**
 * h_request_vmc: - request a hypervisor virtual management channel device
 * @vmc_index: drc index of the vmc device created
 *
 * Requests the hypervisor create a new virtual management channel device,
 * allowing this partition to send hypervisor virtualization control
 * commands.
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static inline long h_request_vmc(u32 *vmc_index)
{
	long rc = 0;
	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];

	do {
		if (H_IS_LONG_BUSY(rc))
			msleep(get_longbusy_msecs(rc));

		/* Call to request the VMC device from phyp */
		rc = plpar_hcall(H_REQUEST_VMC, retbuf);
		pr_debug("ibmvmc: %s rc = 0x%lx\n", __func__, rc);
		*vmc_index = retbuf[0];
	} while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));

	return rc;
}

/* routines for managing a command/response queue */
/**
 * ibmvmc_handle_event: - Interrupt handler for crq events
 * @irq:        number of irq to handle, not used
 * @dev_instance: crq_server_adapter that received interrupt
 *
 * Disables interrupts and schedules ibmvmc_task
 *
 * Always returns IRQ_HANDLED
 */
static irqreturn_t ibmvmc_handle_event(int irq, void *dev_instance)
{
	struct crq_server_adapter *adapter =
		(struct crq_server_adapter *)dev_instance;

	vio_disable_interrupts(to_vio_dev(adapter->dev));
	tasklet_schedule(&adapter->work_task);

	return IRQ_HANDLED;
}

/**
 * ibmvmc_release_crq_queue - Release CRQ Queue
 *
 * @adapter:	crq_server_adapter struct
 *
 * Return:
 *	0 - Success
 *	Non-Zero - Failure
 */
static void ibmvmc_release_crq_queue(struct crq_server_adapter *adapter)
{
	struct vio_dev *vdev = to_vio_dev(adapter->dev);
	struct crq_queue *queue = &adapter->queue;

	free_irq(vdev->irq, (void *)adapter);
	tasklet_kill(&adapter->work_task);

	if (adapter->reset_task)
		kthread_stop(adapter->reset_task);

	h_free_crq(vdev->unit_address);
	dma_unmap_single(adapter->dev,
			 queue->msg_token,
			 queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL);
	free_page((unsigned long)queue->msgs);
}

/**
 * ibmvmc_reset_crq_queue - Reset CRQ Queue
 *
 * @adapter:	crq_server_adapter struct
 *
 * This function calls h_free_crq and then calls H_REG_CRQ and does all the
 * bookkeeping to get us back to where we can communicate.
 *
 * Return:
 *	0 - Success
 *	Non-Zero - Failure
 */
static int ibmvmc_reset_crq_queue(struct crq_server_adapter *adapter)
{
	struct vio_dev *vdev = to_vio_dev(adapter->dev);
	struct crq_queue *queue = &adapter->queue;
	int rc = 0;

	/* Close the CRQ */
	h_free_crq(vdev->unit_address);

	/* Clean out the queue */
	memset(queue->msgs, 0x00, PAGE_SIZE);
	queue->cur = 0;

	/* And re-open it again */
	rc = plpar_hcall_norets(H_REG_CRQ,
				vdev->unit_address,
				queue->msg_token, PAGE_SIZE);
	if (rc == 2)
		/* Adapter is good, but other end is not ready */
		dev_warn(adapter->dev, "Partner adapter not ready\n");
	else if (rc != 0)
		dev_err(adapter->dev, "couldn't register crq--rc 0x%x\n", rc);

	return rc;
}

/**
 * crq_queue_next_crq: - Returns the next entry in message queue
 * @queue:      crq_queue to use
 *
 * Returns pointer to next entry in queue, or NULL if there are no new
 * entried in the CRQ.
 */
static struct ibmvmc_crq_msg *crq_queue_next_crq(struct crq_queue *queue)
{
	struct ibmvmc_crq_msg *crq;
	unsigned long flags;

	spin_lock_irqsave(&queue->lock, flags);
	crq = &queue->msgs[queue->cur];
	if (crq->valid & 0x80) {
		if (++queue->cur == queue->size)
			queue->cur = 0;

		/* Ensure the read of the valid bit occurs before reading any
		 * other bits of the CRQ entry
		 */
		dma_rmb();
	} else {
		crq = NULL;
	}

	spin_unlock_irqrestore(&queue->lock, flags);

	return crq;
}

/**
 * ibmvmc_send_crq - Send CRQ
 *
 * @adapter:	crq_server_adapter struct
 * @word1:	Word1 Data field
 * @word2:	Word2 Data field
 *
 * Return:
 *	0 - Success
 *	Non-Zero - Failure
 */
static long ibmvmc_send_crq(struct crq_server_adapter *adapter,
			    u64 word1, u64 word2)
{
	struct vio_dev *vdev = to_vio_dev(adapter->dev);
	long rc = 0;

	dev_dbg(adapter->dev, "(0x%x, 0x%016llx, 0x%016llx)\n",
		vdev->unit_address, word1, word2);

	/*
	 * Ensure the command buffer is flushed to memory before handing it
	 * over to the other side to prevent it from fetching any stale data.
	 */
	dma_wmb();
	rc = plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, word1, word2);
	dev_dbg(adapter->dev, "rc = 0x%lx\n", rc);

	return rc;
}

/**
 * alloc_dma_buffer - Create DMA Buffer
 *
 * @vdev:	vio_dev struct
 * @size:	Size field
 * @dma_handle:	DMA address field
 *
 * Allocates memory for the command queue and maps remote memory into an
 * ioba.
 *
 * Returns a pointer to the buffer
 */
static void *alloc_dma_buffer(struct vio_dev *vdev, size_t size,
			      dma_addr_t *dma_handle)
{
	/* allocate memory */
	void *buffer = kzalloc(size, GFP_ATOMIC);

	if (!buffer) {
		*dma_handle = 0;
		return NULL;
	}

	/* DMA map */
	*dma_handle = dma_map_single(&vdev->dev, buffer, size,
				     DMA_BIDIRECTIONAL);

	if (dma_mapping_error(&vdev->dev, *dma_handle)) {
		*dma_handle = 0;
		kfree_sensitive(buffer);
		return NULL;
	}

	return buffer;
}

/**
 * free_dma_buffer - Free DMA Buffer
 *
 * @vdev:	vio_dev struct
 * @size:	Size field
 * @vaddr:	Address field
 * @dma_handle:	DMA address field
 *
 * Releases memory for a command queue and unmaps mapped remote memory.
 */
static void free_dma_buffer(struct vio_dev *vdev, size_t size, void *vaddr,
			    dma_addr_t dma_handle)
{
	/* DMA unmap */
	dma_unmap_single(&vdev->dev, dma_handle, size, DMA_BIDIRECTIONAL);

	/* deallocate memory */
	kfree_sensitive(vaddr);
}

/**
 * ibmvmc_get_valid_hmc_buffer - Retrieve Valid HMC Buffer
 *
 * @hmc_index:	HMC Index Field
 *
 * Return:
 *	Pointer to ibmvmc_buffer
 */
static struct ibmvmc_buffer *ibmvmc_get_valid_hmc_buffer(u8 hmc_index)
{
	struct ibmvmc_buffer *buffer;
	struct ibmvmc_buffer *ret_buf = NULL;
	unsigned long i;

	if (hmc_index > ibmvmc.max_hmc_index)
		return NULL;

	buffer = hmcs[hmc_index].buffer;

	for (i = 0; i < ibmvmc_max_buf_pool_size; i++) {
		if (buffer[i].valid && buffer[i].free &&
		    buffer[i].owner == VMC_BUF_OWNER_ALPHA) {
			buffer[i].free = 0;
			ret_buf = &buffer[i];
			break;
		}
	}

	return ret_buf;
}

/**
 * ibmvmc_get_free_hmc_buffer - Get Free HMC Buffer
 *
 * @adapter:	crq_server_adapter struct
 * @hmc_index:	Hmc Index field
 *
 * Return:
 *	Pointer to ibmvmc_buffer
 */
static struct ibmvmc_buffer *ibmvmc_get_free_hmc_buffer(struct crq_server_adapter *adapter,
							u8 hmc_index)
{
	struct ibmvmc_buffer *buffer;
	struct ibmvmc_buffer *ret_buf = NULL;
	unsigned long i;

	if (hmc_index > ibmvmc.max_hmc_index) {
		dev_info(adapter->dev, "get_free_hmc_buffer: invalid hmc_index=0x%x\n",
			 hmc_index);
		return NULL;
	}

	buffer = hmcs[hmc_index].buffer;

	for (i = 0; i < ibmvmc_max_buf_pool_size; i++) {
		if (buffer[i].free &&
		    buffer[i].owner == VMC_BUF_OWNER_ALPHA) {
			buffer[i].free = 0;
			ret_buf = &buffer[i];
			break;
		}
	}

	return ret_buf;
}

/**
 * ibmvmc_free_hmc_buffer - Free an HMC Buffer
 *
 * @hmc:	ibmvmc_hmc struct
 * @buffer:	ibmvmc_buffer struct
 *
 */
static void ibmvmc_free_hmc_buffer(struct ibmvmc_hmc *hmc,
				   struct ibmvmc_buffer *buffer)
{
	unsigned long flags;

	spin_lock_irqsave(&hmc->lock, flags);
	buffer->free = 1;
	spin_unlock_irqrestore(&hmc->lock, flags);
}

/**
 * ibmvmc_count_hmc_buffers - Count HMC Buffers
 *
 * @hmc_index:	HMC Index field
 * @valid:	Valid number of buffers field
 * @free:	Free number of buffers field
 *
 */
static void ibmvmc_count_hmc_buffers(u8 hmc_index, unsigned int *valid,
				     unsigned int *free)
{
	struct ibmvmc_buffer *buffer;
	unsigned long i;
	unsigned long flags;

	if (hmc_index > ibmvmc.max_hmc_index)
		return;

	if (!valid || !free)
		return;

	*valid = 0; *free = 0;

	buffer = hmcs[hmc_index].buffer;
	spin_lock_irqsave(&hmcs[hmc_index].lock, flags);

	for (i = 0; i < ibmvmc_max_buf_pool_size; i++) {
		if (buffer[i].valid) {
			*valid = *valid + 1;
			if (buffer[i].free)
				*free = *free + 1;
		}
	}

	spin_unlock_irqrestore(&hmcs[hmc_index].lock, flags);
}

/**
 * ibmvmc_get_free_hmc - Get Free HMC
 *
 * Return:
 *	Pointer to an available HMC Connection
 *	Null otherwise
 */
static struct ibmvmc_hmc *ibmvmc_get_free_hmc(void)
{
	unsigned long i;
	unsigned long flags;

	/*
	 * Find an available HMC connection.
	 */
	for (i = 0; i <= ibmvmc.max_hmc_index; i++) {
		spin_lock_irqsave(&hmcs[i].lock, flags);
		if (hmcs[i].state == ibmhmc_state_free) {
			hmcs[i].index = i;
			hmcs[i].state = ibmhmc_state_initial;
			spin_unlock_irqrestore(&hmcs[i].lock, flags);
			return &hmcs[i];
		}
		spin_unlock_irqrestore(&hmcs[i].lock, flags);
	}

	return NULL;
}

/**
 * ibmvmc_return_hmc - Return an HMC Connection
 *
 * @hmc:		ibmvmc_hmc struct
 * @release_readers:	Number of readers connected to session
 *
 * This function releases the HMC connections back into the pool.
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static int ibmvmc_return_hmc(struct ibmvmc_hmc *hmc, bool release_readers)
{
	struct ibmvmc_buffer *buffer;
	struct crq_server_adapter *adapter;
	struct vio_dev *vdev;
	unsigned long i;
	unsigned long flags;

	if (!hmc || !hmc->adapter)
		return -EIO;

	if (release_readers) {
		if (hmc->file_session) {
			struct ibmvmc_file_session *session = hmc->file_session;

			session->valid = 0;
			wake_up_interruptible(&ibmvmc_read_wait);
		}
	}

	adapter = hmc->adapter;
	vdev = to_vio_dev(adapter->dev);

	spin_lock_irqsave(&hmc->lock, flags);
	hmc->index = 0;
	hmc->state = ibmhmc_state_free;
	hmc->queue_head = 0;
	hmc->queue_tail = 0;
	buffer = hmc->buffer;
	for (i = 0; i < ibmvmc_max_buf_pool_size; i++) {
		if (buffer[i].valid) {
			free_dma_buffer(vdev,
					ibmvmc.max_mtu,
					buffer[i].real_addr_local,
					buffer[i].dma_addr_local);
			dev_dbg(adapter->dev, "Forgot buffer id 0x%lx\n", i);
		}
		memset(&buffer[i], 0, sizeof(struct ibmvmc_buffer));

		hmc->queue_outbound_msgs[i] = VMC_INVALID_BUFFER_ID;
	}

	spin_unlock_irqrestore(&hmc->lock, flags);

	return 0;
}

/**
 * ibmvmc_send_open - Interface Open
 * @buffer: Pointer to ibmvmc_buffer struct
 * @hmc: Pointer to ibmvmc_hmc struct
 *
 * This command is sent by the management partition as the result of a
 * management partition device request. It causes the hypervisor to
 * prepare a set of data buffers for the management application connection
 * indicated HMC idx. A unique HMC Idx would be used if multiple management
 * applications running concurrently were desired. Before responding to this
 * command, the hypervisor must provide the management partition with at
 * least one of these new buffers via the Add Buffer. This indicates whether
 * the messages are inbound or outbound from the hypervisor.
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static int ibmvmc_send_open(struct ibmvmc_buffer *buffer,
			    struct ibmvmc_hmc *hmc)
{
	struct ibmvmc_crq_msg crq_msg;
	struct crq_server_adapter *adapter;
	__be64 *crq_as_u64 = (__be64 *)&crq_msg;
	int rc = 0;

	if (!hmc || !hmc->adapter)
		return -EIO;

	adapter = hmc->adapter;

	dev_dbg(adapter->dev, "send_open: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
		(unsigned long)buffer->size, (unsigned long)adapter->liobn,
		(unsigned long)buffer->dma_addr_local,
		(unsigned long)adapter->riobn,
		(unsigned long)buffer->dma_addr_remote);

	rc = h_copy_rdma(buffer->size,
			 adapter->liobn,
			 buffer->dma_addr_local,
			 adapter->riobn,
			 buffer->dma_addr_remote);
	if (rc) {
		dev_err(adapter->dev, "Error: In send_open, h_copy_rdma rc 0x%x\n",
			rc);
		return -EIO;
	}

	hmc->state = ibmhmc_state_opening;

	crq_msg.valid = 0x80;
	crq_msg.type = VMC_MSG_OPEN;
	crq_msg.status = 0;
	crq_msg.var1.rsvd = 0;
	crq_msg.hmc_session = hmc->session;
	crq_msg.hmc_index = hmc->index;
	crq_msg.var2.buffer_id = cpu_to_be16(buffer->id);
	crq_msg.rsvd = 0;
	crq_msg.var3.rsvd = 0;

	ibmvmc_send_crq(adapter, be64_to_cpu(crq_as_u64[0]),
			be64_to_cpu(crq_as_u64[1]));

	return rc;
}

/**
 * ibmvmc_send_close - Interface Close
 * @hmc: Pointer to ibmvmc_hmc struct
 *
 * This command is sent by the management partition to terminate a
 * management application to hypervisor connection. When this command is
 * sent, the management partition has quiesced all I/O operations to all
 * buffers associated with this management application connection, and
 * has freed any storage for these buffers.
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static int ibmvmc_send_close(struct ibmvmc_hmc *hmc)
{
	struct ibmvmc_crq_msg crq_msg;
	struct crq_server_adapter *adapter;
	__be64 *crq_as_u64 = (__be64 *)&crq_msg;
	int rc = 0;

	if (!hmc || !hmc->adapter)
		return -EIO;

	adapter = hmc->adapter;

	dev_info(adapter->dev, "CRQ send: close\n");

	crq_msg.valid = 0x80;
	crq_msg.type = VMC_MSG_CLOSE;
	crq_msg.status = 0;
	crq_msg.var1.rsvd = 0;
	crq_msg.hmc_session = hmc->session;
	crq_msg.hmc_index = hmc->index;
	crq_msg.var2.rsvd = 0;
	crq_msg.rsvd = 0;
	crq_msg.var3.rsvd = 0;

	ibmvmc_send_crq(adapter, be64_to_cpu(crq_as_u64[0]),
			be64_to_cpu(crq_as_u64[1]));

	return rc;
}

/**
 * ibmvmc_send_capabilities - Send VMC Capabilities
 *
 * @adapter:	crq_server_adapter struct
 *
 * The capabilities message is an administrative message sent after the CRQ
 * initialization sequence of messages and is used to exchange VMC capabilities
 * between the management partition and the hypervisor. The management
 * partition must send this message and the hypervisor must respond with VMC
 * capabilities Response message before HMC interface message can begin. Any
 * HMC interface messages received before the exchange of capabilities has
 * complete are dropped.
 *
 * Return:
 *	0 - Success
 */
static int ibmvmc_send_capabilities(struct crq_server_adapter *adapter)
{
	struct ibmvmc_admin_crq_msg crq_msg;
	__be64 *crq_as_u64 = (__be64 *)&crq_msg;

	dev_dbg(adapter->dev, "ibmvmc: CRQ send: capabilities\n");
	crq_msg.valid = 0x80;
	crq_msg.type = VMC_MSG_CAP;
	crq_msg.status = 0;
	crq_msg.rsvd[0] = 0;
	crq_msg.rsvd[1] = 0;
	crq_msg.max_hmc = ibmvmc_max_hmcs;
	crq_msg.max_mtu = cpu_to_be32(ibmvmc_max_mtu);
	crq_msg.pool_size = cpu_to_be16(ibmvmc_max_buf_pool_size);
	crq_msg.crq_size = cpu_to_be16(adapter->queue.size);
	crq_msg.version = cpu_to_be16(IBMVMC_PROTOCOL_VERSION);

	ibmvmc_send_crq(adapter, be64_to_cpu(crq_as_u64[0]),
			be64_to_cpu(crq_as_u64[1]));

	ibmvmc.state = ibmvmc_state_capabilities;

	return 0;
}

/**
 * ibmvmc_send_add_buffer_resp - Add Buffer Response
 *
 * @adapter:	crq_server_adapter struct
 * @status:	Status field
 * @hmc_session: HMC Session field
 * @hmc_index:	HMC Index field
 * @buffer_id:	Buffer Id field
 *
 * This command is sent by the management partition to the hypervisor in
 * response to the Add Buffer message. The Status field indicates the result of
 * the command.
 *
 * Return:
 *	0 - Success
 */
static int ibmvmc_send_add_buffer_resp(struct crq_server_adapter *adapter,
				       u8 status, u8 hmc_session,
				       u8 hmc_index, u16 buffer_id)
{
	struct ibmvmc_crq_msg crq_msg;
	__be64 *crq_as_u64 = (__be64 *)&crq_msg;

	dev_dbg(adapter->dev, "CRQ send: add_buffer_resp\n");
	crq_msg.valid = 0x80;
	crq_msg.type = VMC_MSG_ADD_BUF_RESP;
	crq_msg.status = status;
	crq_msg.var1.rsvd = 0;
	crq_msg.hmc_session = hmc_session;
	crq_msg.hmc_index = hmc_index;
	crq_msg.var2.buffer_id = cpu_to_be16(buffer_id);
	crq_msg.rsvd = 0;
	crq_msg.var3.rsvd = 0;

	ibmvmc_send_crq(adapter, be64_to_cpu(crq_as_u64[0]),
			be64_to_cpu(crq_as_u64[1]));

	return 0;
}

/**
 * ibmvmc_send_rem_buffer_resp - Remove Buffer Response
 *
 * @adapter:	crq_server_adapter struct
 * @status:	Status field
 * @hmc_session: HMC Session field
 * @hmc_index:	HMC Index field
 * @buffer_id:	Buffer Id field
 *
 * This command is sent by the management partition to the hypervisor in
 * response to the Remove Buffer message. The Buffer ID field indicates
 * which buffer the management partition selected to remove. The Status
 * field indicates the result of the command.
 *
 * Return:
 *	0 - Success
 */
static int ibmvmc_send_rem_buffer_resp(struct crq_server_adapter *adapter,
				       u8 status, u8 hmc_session,
				       u8 hmc_index, u16 buffer_id)
{
	struct ibmvmc_crq_msg crq_msg;
	__be64 *crq_as_u64 = (__be64 *)&crq_msg;

	dev_dbg(adapter->dev, "CRQ send: rem_buffer_resp\n");
	crq_msg.valid = 0x80;
	crq_msg.type = VMC_MSG_REM_BUF_RESP;
	crq_msg.status = status;
	crq_msg.var1.rsvd = 0;
	crq_msg.hmc_session = hmc_session;
	crq_msg.hmc_index = hmc_index;
	crq_msg.var2.buffer_id = cpu_to_be16(buffer_id);
	crq_msg.rsvd = 0;
	crq_msg.var3.rsvd = 0;

	ibmvmc_send_crq(adapter, be64_to_cpu(crq_as_u64[0]),
			be64_to_cpu(crq_as_u64[1]));

	return 0;
}

/**
 * ibmvmc_send_msg - Signal Message
 *
 * @adapter:	crq_server_adapter struct
 * @buffer:	ibmvmc_buffer struct
 * @hmc:	ibmvmc_hmc struct
 * @msg_len:	message length field
 *
 * This command is sent between the management partition and the hypervisor
 * in order to signal the arrival of an HMC protocol message. The command
 * can be sent by both the management partition and the hypervisor. It is
 * used for all traffic between the management application and the hypervisor,
 * regardless of who initiated the communication.
 *
 * There is no response to this message.
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static int ibmvmc_send_msg(struct crq_server_adapter *adapter,
			   struct ibmvmc_buffer *buffer,
			   struct ibmvmc_hmc *hmc, int msg_len)
{
	struct ibmvmc_crq_msg crq_msg;
	__be64 *crq_as_u64 = (__be64 *)&crq_msg;
	int rc = 0;

	dev_dbg(adapter->dev, "CRQ send: rdma to HV\n");
	rc = h_copy_rdma(msg_len,
			 adapter->liobn,
			 buffer->dma_addr_local,
			 adapter->riobn,
			 buffer->dma_addr_remote);
	if (rc) {
		dev_err(adapter->dev, "Error in send_msg, h_copy_rdma rc 0x%x\n",
			rc);
		return rc;
	}

	crq_msg.valid = 0x80;
	crq_msg.type = VMC_MSG_SIGNAL;
	crq_msg.status = 0;
	crq_msg.var1.rsvd = 0;
	crq_msg.hmc_session = hmc->session;
	crq_msg.hmc_index = hmc->index;
	crq_msg.var2.buffer_id = cpu_to_be16(buffer->id);
	crq_msg.var3.msg_len = cpu_to_be32(msg_len);
	dev_dbg(adapter->dev, "CRQ send: msg to HV 0x%llx 0x%llx\n",
		be64_to_cpu(crq_as_u64[0]), be64_to_cpu(crq_as_u64[1]));

	buffer->owner = VMC_BUF_OWNER_HV;
	ibmvmc_send_crq(adapter, be64_to_cpu(crq_as_u64[0]),
			be64_to_cpu(crq_as_u64[1]));

	return rc;
}

/**
 * ibmvmc_open - Open Session
 *
 * @inode:	inode struct
 * @file:	file struct
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static int ibmvmc_open(struct inode *inode, struct file *file)
{
	struct ibmvmc_file_session *session;

	pr_debug("%s: inode = 0x%lx, file = 0x%lx, state = 0x%x\n", __func__,
		 (unsigned long)inode, (unsigned long)file,
		 ibmvmc.state);

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

	session->file = file;
	file->private_data = session;

	return 0;
}

/**
 * ibmvmc_close - Close Session
 *
 * @inode:	inode struct
 * @file:	file struct
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static int ibmvmc_close(struct inode *inode, struct file *file)
{
	struct ibmvmc_file_session *session;
	struct ibmvmc_hmc *hmc;
	int rc = 0;
	unsigned long flags;

	pr_debug("%s: file = 0x%lx, state = 0x%x\n", __func__,
		 (unsigned long)file, ibmvmc.state);

	session = file->private_data;
	if (!session)
		return -EIO;

	hmc = session->hmc;
	if (hmc) {
		if (!hmc->adapter)
			return -EIO;

		if (ibmvmc.state == ibmvmc_state_failed) {
			dev_warn(hmc->adapter->dev, "close: state_failed\n");
			return -EIO;
		}

		spin_lock_irqsave(&hmc->lock, flags);
		if (hmc->state >= ibmhmc_state_opening) {
			rc = ibmvmc_send_close(hmc);
			if (rc)
				dev_warn(hmc->adapter->dev, "close: send_close failed.\n");
		}
		spin_unlock_irqrestore(&hmc->lock, flags);
	}

	kfree_sensitive(session);

	return rc;
}

/**
 * ibmvmc_read - Read
 *
 * @file:	file struct
 * @buf:	Character buffer
 * @nbytes:	Size in bytes
 * @ppos:	Offset
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static ssize_t ibmvmc_read(struct file *file, char *buf, size_t nbytes,
			   loff_t *ppos)
{
	struct ibmvmc_file_session *session;
	struct ibmvmc_hmc *hmc;
	struct crq_server_adapter *adapter;
	struct ibmvmc_buffer *buffer;
	ssize_t n;
	ssize_t retval = 0;
	unsigned long flags;
	DEFINE_WAIT(wait);

	pr_debug("ibmvmc: read: file = 0x%lx, buf = 0x%lx, nbytes = 0x%lx\n",
		 (unsigned long)file, (unsigned long)buf,
		 (unsigned long)nbytes);

	if (nbytes == 0)
		return 0;

	if (nbytes > ibmvmc.max_mtu) {
		pr_warn("ibmvmc: read: nbytes invalid 0x%x\n",
			(unsigned int)nbytes);
		return -EINVAL;
	}

	session = file->private_data;
	if (!session) {
		pr_warn("ibmvmc: read: no session\n");
		return -EIO;
	}

	hmc = session->hmc;
	if (!hmc) {
		pr_warn("ibmvmc: read: no hmc\n");
		return -EIO;
	}

	adapter = hmc->adapter;
	if (!adapter) {
		pr_warn("ibmvmc: read: no adapter\n");
		return -EIO;
	}

	do {
		prepare_to_wait(&ibmvmc_read_wait, &wait, TASK_INTERRUPTIBLE);

		spin_lock_irqsave(&hmc->lock, flags);
		if (hmc->queue_tail != hmc->queue_head)
			/* Data is available */
			break;

		spin_unlock_irqrestore(&hmc->lock, flags);

		if (!session->valid) {
			retval = -EBADFD;
			goto out;
		}
		if (file->f_flags & O_NONBLOCK) {
			retval = -EAGAIN;
			goto out;
		}

		schedule();

		if (signal_pending(current)) {
			retval = -ERESTARTSYS;
			goto out;
		}
	} while (1);

	buffer = &(hmc->buffer[hmc->queue_outbound_msgs[hmc->queue_tail]]);
	hmc->queue_tail++;
	if (hmc->queue_tail == ibmvmc_max_buf_pool_size)
		hmc->queue_tail = 0;
	spin_unlock_irqrestore(&hmc->lock, flags);

	nbytes = min_t(size_t, nbytes, buffer->msg_len);
	n = copy_to_user((void *)buf, buffer->real_addr_local, nbytes);
	dev_dbg(adapter->dev, "read: copy to user nbytes = 0x%lx.\n", nbytes);
	ibmvmc_free_hmc_buffer(hmc, buffer);
	retval = nbytes;

	if (n) {
		dev_warn(adapter->dev, "read: copy to user failed.\n");
		retval = -EFAULT;
	}

 out:
	finish_wait(&ibmvmc_read_wait, &wait);
	dev_dbg(adapter->dev, "read: out %ld\n", retval);
	return retval;
}

/**
 * ibmvmc_poll - Poll
 *
 * @file:	file struct
 * @wait:	Poll Table
 *
 * Return:
 *	poll.h return values
 */
static unsigned int ibmvmc_poll(struct file *file, poll_table *wait)
{
	struct ibmvmc_file_session *session;
	struct ibmvmc_hmc *hmc;
	unsigned int mask = 0;

	session = file->private_data;
	if (!session)
		return 0;

	hmc = session->hmc;
	if (!hmc)
		return 0;

	poll_wait(file, &ibmvmc_read_wait, wait);

	if (hmc->queue_head != hmc->queue_tail)
		mask |= POLLIN | POLLRDNORM;

	return mask;
}

/**
 * ibmvmc_write - Write
 *
 * @file:	file struct
 * @buffer:	Character buffer
 * @count:	Count field
 * @ppos:	Offset
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static ssize_t ibmvmc_write(struct file *file, const char *buffer,
			    size_t count, loff_t *ppos)
{
	struct ibmvmc_buffer *vmc_buffer;
	struct ibmvmc_file_session *session;
	struct crq_server_adapter *adapter;
	struct ibmvmc_hmc *hmc;
	unsigned char *buf;
	unsigned long flags;
	size_t bytes;
	const char *p = buffer;
	size_t c = count;
	int ret = 0;

	session = file->private_data;
	if (!session)
		return -EIO;

	hmc = session->hmc;
	if (!hmc)
		return -EIO;

	spin_lock_irqsave(&hmc->lock, flags);
	if (hmc->state == ibmhmc_state_free) {
		/* HMC connection is not valid (possibly was reset under us). */
		ret = -EIO;
		goto out;
	}

	adapter = hmc->adapter;
	if (!adapter) {
		ret = -EIO;
		goto out;
	}

	if (count > ibmvmc.max_mtu) {
		dev_warn(adapter->dev, "invalid buffer size 0x%lx\n",
			 (unsigned long)count);
		ret = -EIO;
		goto out;
	}

	/* Waiting for the open resp message to the ioctl(1) - retry */
	if (hmc->state == ibmhmc_state_opening) {
		ret = -EBUSY;
		goto out;
	}

	/* Make sure the ioctl() was called & the open msg sent, and that
	 * the HMC connection has not failed.
	 */
	if (hmc->state != ibmhmc_state_ready) {
		ret = -EIO;
		goto out;
	}

	vmc_buffer = ibmvmc_get_valid_hmc_buffer(hmc->index);
	if (!vmc_buffer) {
		/* No buffer available for the msg send, or we have not yet
		 * completed the open/open_resp sequence.  Retry until this is
		 * complete.
		 */
		ret = -EBUSY;
		goto out;
	}
	if (!vmc_buffer->real_addr_local) {
		dev_err(adapter->dev, "no buffer storage assigned\n");
		ret = -EIO;
		goto out;
	}
	buf = vmc_buffer->real_addr_local;

	while (c > 0) {
		bytes = min_t(size_t, c, vmc_buffer->size);

		bytes -= copy_from_user(buf, p, bytes);
		if (!bytes) {
			ret = -EFAULT;
			goto out;
		}
		c -= bytes;
		p += bytes;
	}
	if (p == buffer)
		goto out;

	file->f_path.dentry->d_inode->i_mtime = current_time(file_inode(file));
	mark_inode_dirty(file->f_path.dentry->d_inode);

	dev_dbg(adapter->dev, "write: file = 0x%lx, count = 0x%lx\n",
		(unsigned long)file, (unsigned long)count);

	ibmvmc_send_msg(adapter, vmc_buffer, hmc, count);
	ret = p - buffer;
 out:
	spin_unlock_irqrestore(&hmc->lock, flags);
	return (ssize_t)(ret);
}

/**
 * ibmvmc_setup_hmc - Setup the HMC
 *
 * @session:	ibmvmc_file_session struct
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static long ibmvmc_setup_hmc(struct ibmvmc_file_session *session)
{
	struct ibmvmc_hmc *hmc;
	unsigned int valid, free, index;

	if (ibmvmc.state == ibmvmc_state_failed) {
		pr_warn("ibmvmc: Reserve HMC: state_failed\n");
		return -EIO;
	}

	if (ibmvmc.state < ibmvmc_state_ready) {
		pr_warn("ibmvmc: Reserve HMC: not state_ready\n");
		return -EAGAIN;
	}

	/* Device is busy until capabilities have been exchanged and we
	 * have a generic buffer for each possible HMC connection.
	 */
	for (index = 0; index <= ibmvmc.max_hmc_index; index++) {
		valid = 0;
		ibmvmc_count_hmc_buffers(index, &valid, &free);
		if (valid == 0) {
			pr_warn("ibmvmc: buffers not ready for index %d\n",
				index);
			return -ENOBUFS;
		}
	}

	/* Get an hmc object, and transition to ibmhmc_state_initial */
	hmc = ibmvmc_get_free_hmc();
	if (!hmc) {
		pr_warn("%s: free hmc not found\n", __func__);
		return -EBUSY;
	}

	hmc->session = hmc->session + 1;
	if (hmc->session == 0xff)
		hmc->session = 1;

	session->hmc = hmc;
	hmc->adapter = &ibmvmc_adapter;
	hmc->file_session = session;
	session->valid = 1;

	return 0;
}

/**
 * ibmvmc_ioctl_sethmcid - IOCTL Set HMC ID
 *
 * @session:	ibmvmc_file_session struct
 * @new_hmc_id:	HMC id field
 *
 * IOCTL command to setup the hmc id
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static long ibmvmc_ioctl_sethmcid(struct ibmvmc_file_session *session,
				  unsigned char __user *new_hmc_id)
{
	struct ibmvmc_hmc *hmc;
	struct ibmvmc_buffer *buffer;
	size_t bytes;
	char print_buffer[HMC_ID_LEN + 1];
	unsigned long flags;
	long rc = 0;

	/* Reserve HMC session */
	hmc = session->hmc;
	if (!hmc) {
		rc = ibmvmc_setup_hmc(session);
		if (rc)
			return rc;

		hmc = session->hmc;
		if (!hmc) {
			pr_err("ibmvmc: setup_hmc success but no hmc\n");
			return -EIO;
		}
	}

	if (hmc->state != ibmhmc_state_initial) {
		pr_warn("ibmvmc: sethmcid: invalid state to send open 0x%x\n",
			hmc->state);
		return -EIO;
	}

	bytes = copy_from_user(hmc->hmc_id, new_hmc_id, HMC_ID_LEN);
	if (bytes)
		return -EFAULT;

	/* Send Open Session command */
	spin_lock_irqsave(&hmc->lock, flags);
	buffer = ibmvmc_get_valid_hmc_buffer(hmc->index);
	spin_unlock_irqrestore(&hmc->lock, flags);

	if (!buffer || !buffer->real_addr_local) {
		pr_warn("ibmvmc: sethmcid: no buffer available\n");
		return -EIO;
	}

	/* Make sure buffer is NULL terminated before trying to print it */
	memset(print_buffer, 0, HMC_ID_LEN + 1);
	strncpy(print_buffer, hmc->hmc_id, HMC_ID_LEN);
	pr_info("ibmvmc: sethmcid: Set HMC ID: \"%s\"\n", print_buffer);

	memcpy(buffer->real_addr_local, hmc->hmc_id, HMC_ID_LEN);
	/* RDMA over ID, send open msg, change state to ibmhmc_state_opening */
	rc = ibmvmc_send_open(buffer, hmc);

	return rc;
}

/**
 * ibmvmc_ioctl_query - IOCTL Query
 *
 * @session:	ibmvmc_file_session struct
 * @ret_struct:	ibmvmc_query_struct
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static long ibmvmc_ioctl_query(struct ibmvmc_file_session *session,
			       struct ibmvmc_query_struct __user *ret_struct)
{
	struct ibmvmc_query_struct query_struct;
	size_t bytes;

	memset(&query_struct, 0, sizeof(query_struct));
	query_struct.have_vmc = (ibmvmc.state > ibmvmc_state_initial);
	query_struct.state = ibmvmc.state;
	query_struct.vmc_drc_index = ibmvmc.vmc_drc_index;

	bytes = copy_to_user(ret_struct, &query_struct,
			     sizeof(query_struct));
	if (bytes)
		return -EFAULT;

	return 0;
}

/**
 * ibmvmc_ioctl_requestvmc - IOCTL Request VMC
 *
 * @session:	ibmvmc_file_session struct
 * @ret_vmc_index:	VMC Index
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static long ibmvmc_ioctl_requestvmc(struct ibmvmc_file_session *session,
				    u32 __user *ret_vmc_index)
{
	/* TODO: (adreznec) Add locking to control multiple process access */
	size_t bytes;
	long rc;
	u32 vmc_drc_index;

	/* Call to request the VMC device from phyp*/
	rc = h_request_vmc(&vmc_drc_index);
	pr_debug("ibmvmc: requestvmc: H_REQUEST_VMC rc = 0x%lx\n", rc);

	if (rc == H_SUCCESS) {
		rc = 0;
	} else if (rc == H_FUNCTION) {
		pr_err("ibmvmc: requestvmc: h_request_vmc not supported\n");
		return -EPERM;
	} else if (rc == H_AUTHORITY) {
		pr_err("ibmvmc: requestvmc: hypervisor denied vmc request\n");
		return -EPERM;
	} else if (rc == H_HARDWARE) {
		pr_err("ibmvmc: requestvmc: hypervisor hardware fault\n");
		return -EIO;
	} else if (rc == H_RESOURCE) {
		pr_err("ibmvmc: requestvmc: vmc resource unavailable\n");
		return -ENODEV;
	} else if (rc == H_NOT_AVAILABLE) {
		pr_err("ibmvmc: requestvmc: system cannot be vmc managed\n");
		return -EPERM;
	} else if (rc == H_PARAMETER) {
		pr_err("ibmvmc: requestvmc: invalid parameter\n");
		return -EINVAL;
	}

	/* Success, set the vmc index in global struct */
	ibmvmc.vmc_drc_index = vmc_drc_index;

	bytes = copy_to_user(ret_vmc_index, &vmc_drc_index,
			     sizeof(*ret_vmc_index));
	if (bytes) {
		pr_warn("ibmvmc: requestvmc: copy to user failed.\n");
		return -EFAULT;
	}
	return rc;
}

/**
 * ibmvmc_ioctl - IOCTL
 *
 * @file:	file information
 * @cmd:	cmd field
 * @arg:	Argument field
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static long ibmvmc_ioctl(struct file *file,
			 unsigned int cmd, unsigned long arg)
{
	struct ibmvmc_file_session *session = file->private_data;

	pr_debug("ibmvmc: ioctl file=0x%lx, cmd=0x%x, arg=0x%lx, ses=0x%lx\n",
		 (unsigned long)file, cmd, arg,
		 (unsigned long)session);

	if (!session) {
		pr_warn("ibmvmc: ioctl: no session\n");
		return -EIO;
	}

	switch (cmd) {
	case VMC_IOCTL_SETHMCID:
		return ibmvmc_ioctl_sethmcid(session,
			(unsigned char __user *)arg);
	case VMC_IOCTL_QUERY:
		return ibmvmc_ioctl_query(session,
			(struct ibmvmc_query_struct __user *)arg);
	case VMC_IOCTL_REQUESTVMC:
		return ibmvmc_ioctl_requestvmc(session,
			(unsigned int __user *)arg);
	default:
		pr_warn("ibmvmc: unknown ioctl 0x%x\n", cmd);
		return -EINVAL;
	}
}

static const struct file_operations ibmvmc_fops = {
	.owner		= THIS_MODULE,
	.read		= ibmvmc_read,
	.write		= ibmvmc_write,
	.poll		= ibmvmc_poll,
	.unlocked_ioctl	= ibmvmc_ioctl,
	.open           = ibmvmc_open,
	.release        = ibmvmc_close,
};

/**
 * ibmvmc_add_buffer - Add Buffer
 *
 * @adapter: crq_server_adapter struct
 * @crq:	ibmvmc_crq_msg struct
 *
 * This message transfers a buffer from hypervisor ownership to management
 * partition ownership. The LIOBA is obtained from the virtual TCE table
 * associated with the hypervisor side of the VMC device, and points to a
 * buffer of size MTU (as established in the capabilities exchange).
 *
 * Typical flow for ading buffers:
 * 1. A new management application connection is opened by the management
 *	partition.
 * 2. The hypervisor assigns new buffers for the traffic associated with
 *	that connection.
 * 3. The hypervisor sends VMC Add Buffer messages to the management
 *	partition, informing it of the new buffers.
 * 4. The hypervisor sends an HMC protocol message (to the management
 *	application) notifying it of the new buffers. This informs the
 *	application that it has buffers available for sending HMC
 *	commands.
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static int ibmvmc_add_buffer(struct crq_server_adapter *adapter,
			     struct ibmvmc_crq_msg *crq)
{
	struct ibmvmc_buffer *buffer;
	u8 hmc_index;
	u8 hmc_session;
	u16 buffer_id;
	unsigned long flags;
	int rc = 0;

	if (!crq)
		return -1;

	hmc_session = crq->hmc_session;
	hmc_index = crq->hmc_index;
	buffer_id = be16_to_cpu(crq->var2.buffer_id);

	if (hmc_index > ibmvmc.max_hmc_index) {
		dev_err(adapter->dev, "add_buffer: invalid hmc_index = 0x%x\n",
			hmc_index);
		ibmvmc_send_add_buffer_resp(adapter, VMC_MSG_INVALID_HMC_INDEX,
					    hmc_session, hmc_index, buffer_id);
		return -1;
	}

	if (buffer_id >= ibmvmc.max_buffer_pool_size) {
		dev_err(adapter->dev, "add_buffer: invalid buffer_id = 0x%x\n",
			buffer_id);
		ibmvmc_send_add_buffer_resp(adapter, VMC_MSG_INVALID_BUFFER_ID,
					    hmc_session, hmc_index, buffer_id);
		return -1;
	}

	spin_lock_irqsave(&hmcs[hmc_index].lock, flags);
	buffer = &hmcs[hmc_index].buffer[buffer_id];

	if (buffer->real_addr_local || buffer->dma_addr_local) {
		dev_warn(adapter->dev, "add_buffer: already allocated id = 0x%lx\n",
			 (unsigned long)buffer_id);
		spin_unlock_irqrestore(&hmcs[hmc_index].lock, flags);
		ibmvmc_send_add_buffer_resp(adapter, VMC_MSG_INVALID_BUFFER_ID,
					    hmc_session, hmc_index, buffer_id);
		return -1;
	}

	buffer->real_addr_local = alloc_dma_buffer(to_vio_dev(adapter->dev),
						   ibmvmc.max_mtu,
						   &buffer->dma_addr_local);

	if (!buffer->real_addr_local) {
		dev_err(adapter->dev, "add_buffer: alloc_dma_buffer failed.\n");
		spin_unlock_irqrestore(&hmcs[hmc_index].lock, flags);
		ibmvmc_send_add_buffer_resp(adapter, VMC_MSG_INTERFACE_FAILURE,
					    hmc_session, hmc_index, buffer_id);
		return -1;
	}

	buffer->dma_addr_remote = be32_to_cpu(crq->var3.lioba);
	buffer->size = ibmvmc.max_mtu;
	buffer->owner = crq->var1.owner;
	buffer->free = 1;
	/* Must ensure valid==1 is observable only after all other fields are */
	dma_wmb();
	buffer->valid = 1;
	buffer->id = buffer_id;

	dev_dbg(adapter->dev, "add_buffer: successfully added a buffer:\n");
	dev_dbg(adapter->dev, "   index: %d, session: %d, buffer: 0x%x, owner: %d\n",
		hmc_index, hmc_session, buffer_id, buffer->owner);
	dev_dbg(adapter->dev, "   local: 0x%x, remote: 0x%x\n",
		(u32)buffer->dma_addr_local,
		(u32)buffer->dma_addr_remote);
	spin_unlock_irqrestore(&hmcs[hmc_index].lock, flags);

	ibmvmc_send_add_buffer_resp(adapter, VMC_MSG_SUCCESS, hmc_session,
				    hmc_index, buffer_id);

	return rc;
}

/**
 * ibmvmc_rem_buffer - Remove Buffer
 *
 * @adapter: crq_server_adapter struct
 * @crq:	ibmvmc_crq_msg struct
 *
 * This message requests an HMC buffer to be transferred from management
 * partition ownership to hypervisor ownership. The management partition may
 * not be able to satisfy the request at a particular point in time if all its
 * buffers are in use. The management partition requires a depth of at least
 * one inbound buffer to allow management application commands to flow to the
 * hypervisor. It is, therefore, an interface error for the hypervisor to
 * attempt to remove the management partition's last buffer.
 *
 * The hypervisor is expected to manage buffer usage with the management
 * application directly and inform the management partition when buffers may be
 * removed. The typical flow for removing buffers:
 *
 * 1. The management application no longer needs a communication path to a
 *	particular hypervisor function. That function is closed.
 * 2. The hypervisor and the management application quiesce all traffic to that
 *	function. The hypervisor requests a reduction in buffer pool size.
 * 3. The management application acknowledges the reduction in buffer pool size.
 * 4. The hypervisor sends a Remove Buffer message to the management partition,
 *	informing it of the reduction in buffers.
 * 5. The management partition verifies it can remove the buffer. This is
 *	possible if buffers have been quiesced.
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
/*
 * The hypervisor requested that we pick an unused buffer, and return it.
 * Before sending the buffer back, we free any storage associated with the
 * buffer.
 */
static int ibmvmc_rem_buffer(struct crq_server_adapter *adapter,
			     struct ibmvmc_crq_msg *crq)
{
	struct ibmvmc_buffer *buffer;
	u8 hmc_index;
	u8 hmc_session;
	u16 buffer_id = 0;
	unsigned long flags;
	int rc = 0;

	if (!crq)
		return -1;

	hmc_session = crq->hmc_session;
	hmc_index = crq->hmc_index;

	if (hmc_index > ibmvmc.max_hmc_index) {
		dev_warn(adapter->dev, "rem_buffer: invalid hmc_index = 0x%x\n",
			 hmc_index);
		ibmvmc_send_rem_buffer_resp(adapter, VMC_MSG_INVALID_HMC_INDEX,
					    hmc_session, hmc_index, buffer_id);
		return -1;
	}

	spin_lock_irqsave(&hmcs[hmc_index].lock, flags);
	buffer = ibmvmc_get_free_hmc_buffer(adapter, hmc_index);
	if (!buffer) {
		dev_info(adapter->dev, "rem_buffer: no buffer to remove\n");
		spin_unlock_irqrestore(&hmcs[hmc_index].lock, flags);
		ibmvmc_send_rem_buffer_resp(adapter, VMC_MSG_NO_BUFFER,
					    hmc_session, hmc_index,
					    VMC_INVALID_BUFFER_ID);
		return -1;
	}

	buffer_id = buffer->id;

	if (buffer->valid)
		free_dma_buffer(to_vio_dev(adapter->dev),
				ibmvmc.max_mtu,
				buffer->real_addr_local,
				buffer->dma_addr_local);

	memset(buffer, 0, sizeof(struct ibmvmc_buffer));
	spin_unlock_irqrestore(&hmcs[hmc_index].lock, flags);

	dev_dbg(adapter->dev, "rem_buffer: removed buffer 0x%x.\n", buffer_id);
	ibmvmc_send_rem_buffer_resp(adapter, VMC_MSG_SUCCESS, hmc_session,
				    hmc_index, buffer_id);

	return rc;
}

static int ibmvmc_recv_msg(struct crq_server_adapter *adapter,
			   struct ibmvmc_crq_msg *crq)
{
	struct ibmvmc_buffer *buffer;
	struct ibmvmc_hmc *hmc;
	unsigned long msg_len;
	u8 hmc_index;
	u8 hmc_session;
	u16 buffer_id;
	unsigned long flags;
	int rc = 0;

	if (!crq)
		return -1;

	/* Hypervisor writes CRQs directly into our memory in big endian */
	dev_dbg(adapter->dev, "Recv_msg: msg from HV 0x%016llx 0x%016llx\n",
		be64_to_cpu(*((unsigned long *)crq)),
		be64_to_cpu(*(((unsigned long *)crq) + 1)));

	hmc_session = crq->hmc_session;
	hmc_index = crq->hmc_index;
	buffer_id = be16_to_cpu(crq->var2.buffer_id);
	msg_len = be32_to_cpu(crq->var3.msg_len);

	if (hmc_index > ibmvmc.max_hmc_index) {
		dev_err(adapter->dev, "Recv_msg: invalid hmc_index = 0x%x\n",
			hmc_index);
		ibmvmc_send_add_buffer_resp(adapter, VMC_MSG_INVALID_HMC_INDEX,
					    hmc_session, hmc_index, buffer_id);
		return -1;
	}

	if (buffer_id >= ibmvmc.max_buffer_pool_size) {
		dev_err(adapter->dev, "Recv_msg: invalid buffer_id = 0x%x\n",
			buffer_id);
		ibmvmc_send_add_buffer_resp(adapter, VMC_MSG_INVALID_BUFFER_ID,
					    hmc_session, hmc_index, buffer_id);
		return -1;
	}

	hmc = &hmcs[hmc_index];
	spin_lock_irqsave(&hmc->lock, flags);

	if (hmc->state == ibmhmc_state_free) {
		dev_err(adapter->dev, "Recv_msg: invalid hmc state = 0x%x\n",
			hmc->state);
		/* HMC connection is not valid (possibly was reset under us). */
		spin_unlock_irqrestore(&hmc->lock, flags);
		return -1;
	}

	buffer = &hmc->buffer[buffer_id];

	if (buffer->valid == 0 || buffer->owner == VMC_BUF_OWNER_ALPHA) {
		dev_err(adapter->dev, "Recv_msg: not valid, or not HV.  0x%x 0x%x\n",
			buffer->valid, buffer->owner);
		spin_unlock_irqrestore(&hmc->lock, flags);
		return -1;
	}

	/* RDMA the data into the partition. */
	rc = h_copy_rdma(msg_len,
			 adapter->riobn,
			 buffer->dma_addr_remote,
			 adapter->liobn,
			 buffer->dma_addr_local);

	dev_dbg(adapter->dev, "Recv_msg: msg_len = 0x%x, buffer_id = 0x%x, queue_head = 0x%x, hmc_idx = 0x%x\n",
		(unsigned int)msg_len, (unsigned int)buffer_id,
		(unsigned int)hmc->queue_head, (unsigned int)hmc_index);
	buffer->msg_len = msg_len;
	buffer->free = 0;
	buffer->owner = VMC_BUF_OWNER_ALPHA;

	if (rc) {
		dev_err(adapter->dev, "Failure in recv_msg: h_copy_rdma = 0x%x\n",
			rc);
		spin_unlock_irqrestore(&hmc->lock, flags);
		return -1;
	}

	/* Must be locked because read operates on the same data */
	hmc->queue_outbound_msgs[hmc->queue_head] = buffer_id;
	hmc->queue_head++;
	if (hmc->queue_head == ibmvmc_max_buf_pool_size)
		hmc->queue_head = 0;

	if (hmc->queue_head == hmc->queue_tail)
		dev_err(adapter->dev, "outbound buffer queue wrapped.\n");

	spin_unlock_irqrestore(&hmc->lock, flags);

	wake_up_interruptible(&ibmvmc_read_wait);

	return 0;
}

/**
 * ibmvmc_process_capabilities - Process Capabilities
 *
 * @adapter:	crq_server_adapter struct
 * @crqp:	ibmvmc_crq_msg struct
 *
 */
static void ibmvmc_process_capabilities(struct crq_server_adapter *adapter,
					struct ibmvmc_crq_msg *crqp)
{
	struct ibmvmc_admin_crq_msg *crq = (struct ibmvmc_admin_crq_msg *)crqp;

	if ((be16_to_cpu(crq->version) >> 8) !=
			(IBMVMC_PROTOCOL_VERSION >> 8)) {
		dev_err(adapter->dev, "init failed, incompatible versions 0x%x 0x%x\n",
			be16_to_cpu(crq->version),
			IBMVMC_PROTOCOL_VERSION);
		ibmvmc.state = ibmvmc_state_failed;
		return;
	}

	ibmvmc.max_mtu = min_t(u32, ibmvmc_max_mtu, be32_to_cpu(crq->max_mtu));
	ibmvmc.max_buffer_pool_size = min_t(u16, ibmvmc_max_buf_pool_size,
					    be16_to_cpu(crq->pool_size));
	ibmvmc.max_hmc_index = min_t(u8, ibmvmc_max_hmcs, crq->max_hmc) - 1;
	ibmvmc.state = ibmvmc_state_ready;

	dev_info(adapter->dev, "Capabilities: mtu=0x%x, pool_size=0x%x, max_hmc=0x%x\n",
		 ibmvmc.max_mtu, ibmvmc.max_buffer_pool_size,
		 ibmvmc.max_hmc_index);
}

/**
 * ibmvmc_validate_hmc_session - Validate HMC Session
 *
 * @adapter:	crq_server_adapter struct
 * @crq:	ibmvmc_crq_msg struct
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static int ibmvmc_validate_hmc_session(struct crq_server_adapter *adapter,
				       struct ibmvmc_crq_msg *crq)
{
	unsigned char hmc_index;

	hmc_index = crq->hmc_index;

	if (crq->hmc_session == 0)
		return 0;

	if (hmc_index > ibmvmc.max_hmc_index)
		return -1;

	if (hmcs[hmc_index].session != crq->hmc_session) {
		dev_warn(adapter->dev, "Drop, bad session: expected 0x%x, recv 0x%x\n",
			 hmcs[hmc_index].session, crq->hmc_session);
		return -1;
	}

	return 0;
}

/**
 * ibmvmc_reset - Reset
 *
 * @adapter:	crq_server_adapter struct
 * @xport_event:	export_event field
 *
 * Closes all HMC sessions and conditionally schedules a CRQ reset.
 * @xport_event: If true, the partner closed their CRQ; we don't need to reset.
 *               If false, we need to schedule a CRQ reset.
 */
static void ibmvmc_reset(struct crq_server_adapter *adapter, bool xport_event)
{
	int i;

	if (ibmvmc.state != ibmvmc_state_sched_reset) {
		dev_info(adapter->dev, "*** Reset to initial state.\n");
		for (i = 0; i < ibmvmc_max_hmcs; i++)
			ibmvmc_return_hmc(&hmcs[i], xport_event);

		if (xport_event) {
			/* CRQ was closed by the partner.  We don't need to do
			 * anything except set ourself to the correct state to
			 * handle init msgs.
			 */
			ibmvmc.state = ibmvmc_state_crqinit;
		} else {
			/* The partner did not close their CRQ - instead, we're
			 * closing the CRQ on our end. Need to schedule this
			 * for process context, because CRQ reset may require a
			 * sleep.
			 *
			 * Setting ibmvmc.state here immediately prevents
			 * ibmvmc_open from completing until the reset
			 * completes in process context.
			 */
			ibmvmc.state = ibmvmc_state_sched_reset;
			dev_dbg(adapter->dev, "Device reset scheduled");
			wake_up_interruptible(&adapter->reset_wait_queue);
		}
	}
}

/**
 * ibmvmc_reset_task - Reset Task
 *
 * @data:	Data field
 *
 * Performs a CRQ reset of the VMC device in process context.
 * NOTE: This function should not be called directly, use ibmvmc_reset.
 */
static int ibmvmc_reset_task(void *data)
{
	struct crq_server_adapter *adapter = data;
	int rc;

	set_user_nice(current, -20);

	while (!kthread_should_stop()) {
		wait_event_interruptible(adapter->reset_wait_queue,
			(ibmvmc.state == ibmvmc_state_sched_reset) ||
			kthread_should_stop());

		if (kthread_should_stop())
			break;

		dev_dbg(adapter->dev, "CRQ resetting in process context");
		tasklet_disable(&adapter->work_task);

		rc = ibmvmc_reset_crq_queue(adapter);

		if (rc != H_SUCCESS && rc != H_RESOURCE) {
			dev_err(adapter->dev, "Error initializing CRQ.  rc = 0x%x\n",
				rc);
			ibmvmc.state = ibmvmc_state_failed;
		} else {
			ibmvmc.state = ibmvmc_state_crqinit;

			if (ibmvmc_send_crq(adapter, 0xC001000000000000LL, 0)
			    != 0 && rc != H_RESOURCE)
				dev_warn(adapter->dev, "Failed to send initialize CRQ message\n");
		}

		vio_enable_interrupts(to_vio_dev(adapter->dev));
		tasklet_enable(&adapter->work_task);
	}

	return 0;
}

/**
 * ibmvmc_process_open_resp - Process Open Response
 *
 * @crq: ibmvmc_crq_msg struct
 * @adapter:    crq_server_adapter struct
 *
 * This command is sent by the hypervisor in response to the Interface
 * Open message. When this message is received, the indicated buffer is
 * again available for management partition use.
 */
static void ibmvmc_process_open_resp(struct ibmvmc_crq_msg *crq,
				     struct crq_server_adapter *adapter)
{
	unsigned char hmc_index;
	unsigned short buffer_id;

	hmc_index = crq->hmc_index;
	if (hmc_index > ibmvmc.max_hmc_index) {
		/* Why would PHYP give an index > max negotiated? */
		ibmvmc_reset(adapter, false);
		return;
	}

	if (crq->status) {
		dev_warn(adapter->dev, "open_resp: failed - status 0x%x\n",
			 crq->status);
		ibmvmc_return_hmc(&hmcs[hmc_index], false);
		return;
	}

	if (hmcs[hmc_index].state == ibmhmc_state_opening) {
		buffer_id = be16_to_cpu(crq->var2.buffer_id);
		if (buffer_id >= ibmvmc.max_buffer_pool_size) {
			dev_err(adapter->dev, "open_resp: invalid buffer_id = 0x%x\n",
				buffer_id);
			hmcs[hmc_index].state = ibmhmc_state_failed;
		} else {
			ibmvmc_free_hmc_buffer(&hmcs[hmc_index],
					       &hmcs[hmc_index].buffer[buffer_id]);
			hmcs[hmc_index].state = ibmhmc_state_ready;
			dev_dbg(adapter->dev, "open_resp: set hmc state = ready\n");
		}
	} else {
		dev_warn(adapter->dev, "open_resp: invalid hmc state (0x%x)\n",
			 hmcs[hmc_index].state);
	}
}

/**
 * ibmvmc_process_close_resp - Process Close Response
 *
 * @crq: ibmvmc_crq_msg struct
 * @adapter:    crq_server_adapter struct
 *
 * This command is sent by the hypervisor in response to the managemant
 * application Interface Close message.
 *
 * If the close fails, simply reset the entire driver as the state of the VMC
 * must be in tough shape.
 */
static void ibmvmc_process_close_resp(struct ibmvmc_crq_msg *crq,
				      struct crq_server_adapter *adapter)
{
	unsigned char hmc_index;

	hmc_index = crq->hmc_index;
	if (hmc_index > ibmvmc.max_hmc_index) {
		ibmvmc_reset(adapter, false);
		return;
	}

	if (crq->status) {
		dev_warn(adapter->dev, "close_resp: failed - status 0x%x\n",
			 crq->status);
		ibmvmc_reset(adapter, false);
		return;
	}

	ibmvmc_return_hmc(&hmcs[hmc_index], false);
}

/**
 * ibmvmc_crq_process - Process CRQ
 *
 * @adapter:    crq_server_adapter struct
 * @crq:	ibmvmc_crq_msg struct
 *
 * Process the CRQ message based upon the type of message received.
 *
 */
static void ibmvmc_crq_process(struct crq_server_adapter *adapter,
			       struct ibmvmc_crq_msg *crq)
{
	switch (crq->type) {
	case VMC_MSG_CAP_RESP:
		dev_dbg(adapter->dev, "CRQ recv: capabilities resp (0x%x)\n",
			crq->type);
		if (ibmvmc.state == ibmvmc_state_capabilities)
			ibmvmc_process_capabilities(adapter, crq);
		else
			dev_warn(adapter->dev, "caps msg invalid in state 0x%x\n",
				 ibmvmc.state);
		break;
	case VMC_MSG_OPEN_RESP:
		dev_dbg(adapter->dev, "CRQ recv: open resp (0x%x)\n",
			crq->type);
		if (ibmvmc_validate_hmc_session(adapter, crq) == 0)
			ibmvmc_process_open_resp(crq, adapter);
		break;
	case VMC_MSG_ADD_BUF:
		dev_dbg(adapter->dev, "CRQ recv: add buf (0x%x)\n",
			crq->type);
		if (ibmvmc_validate_hmc_session(adapter, crq) == 0)
			ibmvmc_add_buffer(adapter, crq);
		break;
	case VMC_MSG_REM_BUF:
		dev_dbg(adapter->dev, "CRQ recv: rem buf (0x%x)\n",
			crq->type);
		if (ibmvmc_validate_hmc_session(adapter, crq) == 0)
			ibmvmc_rem_buffer(adapter, crq);
		break;
	case VMC_MSG_SIGNAL:
		dev_dbg(adapter->dev, "CRQ recv: signal msg (0x%x)\n",
			crq->type);
		if (ibmvmc_validate_hmc_session(adapter, crq) == 0)
			ibmvmc_recv_msg(adapter, crq);
		break;
	case VMC_MSG_CLOSE_RESP:
		dev_dbg(adapter->dev, "CRQ recv: close resp (0x%x)\n",
			crq->type);
		if (ibmvmc_validate_hmc_session(adapter, crq) == 0)
			ibmvmc_process_close_resp(crq, adapter);
		break;
	case VMC_MSG_CAP:
	case VMC_MSG_OPEN:
	case VMC_MSG_CLOSE:
	case VMC_MSG_ADD_BUF_RESP:
	case VMC_MSG_REM_BUF_RESP:
		dev_warn(adapter->dev, "CRQ recv: unexpected msg (0x%x)\n",
			 crq->type);
		break;
	default:
		dev_warn(adapter->dev, "CRQ recv: unknown msg (0x%x)\n",
			 crq->type);
		break;
	}
}

/**
 * ibmvmc_handle_crq_init - Handle CRQ Init
 *
 * @crq:	ibmvmc_crq_msg struct
 * @adapter:	crq_server_adapter struct
 *
 * Handle the type of crq initialization based on whether
 * it is a message or a response.
 *
 */
static void ibmvmc_handle_crq_init(struct ibmvmc_crq_msg *crq,
				   struct crq_server_adapter *adapter)
{
	switch (crq->type) {
	case 0x01:	/* Initialization message */
		dev_dbg(adapter->dev, "CRQ recv: CRQ init msg - state 0x%x\n",
			ibmvmc.state);
		if (ibmvmc.state == ibmvmc_state_crqinit) {
			/* Send back a response */
			if (ibmvmc_send_crq(adapter, 0xC002000000000000,
					    0) == 0)
				ibmvmc_send_capabilities(adapter);
			else
				dev_err(adapter->dev, " Unable to send init rsp\n");
		} else {
			dev_err(adapter->dev, "Invalid state 0x%x mtu = 0x%x\n",
				ibmvmc.state, ibmvmc.max_mtu);
		}

		break;
	case 0x02:	/* Initialization response */
		dev_dbg(adapter->dev, "CRQ recv: initialization resp msg - state 0x%x\n",
			ibmvmc.state);
		if (ibmvmc.state == ibmvmc_state_crqinit)
			ibmvmc_send_capabilities(adapter);
		break;
	default:
		dev_warn(adapter->dev, "Unknown crq message type 0x%lx\n",
			 (unsigned long)crq->type);
	}
}

/**
 * ibmvmc_handle_crq - Handle CRQ
 *
 * @crq:	ibmvmc_crq_msg struct
 * @adapter:	crq_server_adapter struct
 *
 * Read the command elements from the command queue and execute the
 * requests based upon the type of crq message.
 *
 */
static void ibmvmc_handle_crq(struct ibmvmc_crq_msg *crq,
			      struct crq_server_adapter *adapter)
{
	switch (crq->valid) {
	case 0xC0:		/* initialization */
		ibmvmc_handle_crq_init(crq, adapter);
		break;
	case 0xFF:	/* Hypervisor telling us the connection is closed */
		dev_warn(adapter->dev, "CRQ recv: virtual adapter failed - resetting.\n");
		ibmvmc_reset(adapter, true);
		break;
	case 0x80:	/* real payload */
		ibmvmc_crq_process(adapter, crq);
		break;
	default:
		dev_warn(adapter->dev, "CRQ recv: unknown msg 0x%02x.\n",
			 crq->valid);
		break;
	}
}

static void ibmvmc_task(unsigned long data)
{
	struct crq_server_adapter *adapter =
		(struct crq_server_adapter *)data;
	struct vio_dev *vdev = to_vio_dev(adapter->dev);
	struct ibmvmc_crq_msg *crq;
	int done = 0;

	while (!done) {
		/* Pull all the valid messages off the CRQ */
		while ((crq = crq_queue_next_crq(&adapter->queue)) != NULL) {
			ibmvmc_handle_crq(crq, adapter);
			crq->valid = 0x00;
			/* CRQ reset was requested, stop processing CRQs.
			 * Interrupts will be re-enabled by the reset task.
			 */
			if (ibmvmc.state == ibmvmc_state_sched_reset)
				return;
		}

		vio_enable_interrupts(vdev);
		crq = crq_queue_next_crq(&adapter->queue);
		if (crq) {
			vio_disable_interrupts(vdev);
			ibmvmc_handle_crq(crq, adapter);
			crq->valid = 0x00;
			/* CRQ reset was requested, stop processing CRQs.
			 * Interrupts will be re-enabled by the reset task.
			 */
			if (ibmvmc.state == ibmvmc_state_sched_reset)
				return;
		} else {
			done = 1;
		}
	}
}

/**
 * ibmvmc_init_crq_queue - Init CRQ Queue
 *
 * @adapter:	crq_server_adapter struct
 *
 * Return:
 *	0 - Success
 *	Non-zero - Failure
 */
static int ibmvmc_init_crq_queue(struct crq_server_adapter *adapter)
{
	struct vio_dev *vdev = to_vio_dev(adapter->dev);
	struct crq_queue *queue = &adapter->queue;
	int rc = 0;
	int retrc = 0;

	queue->msgs = (struct ibmvmc_crq_msg *)get_zeroed_page(GFP_KERNEL);

	if (!queue->msgs)
		goto malloc_failed;

	queue->size = PAGE_SIZE / sizeof(*queue->msgs);

	queue->msg_token = dma_map_single(adapter->dev, queue->msgs,
					  queue->size * sizeof(*queue->msgs),
					  DMA_BIDIRECTIONAL);

	if (dma_mapping_error(adapter->dev, queue->msg_token))
		goto map_failed;

	retrc = plpar_hcall_norets(H_REG_CRQ,
				   vdev->unit_address,
				   queue->msg_token, PAGE_SIZE);
	rc = retrc;

	if (rc == H_RESOURCE)
		rc = ibmvmc_reset_crq_queue(adapter);

	if (rc == 2) {
		dev_warn(adapter->dev, "Partner adapter not ready\n");
		retrc = 0;
	} else if (rc != 0) {
		dev_err(adapter->dev, "Error %d opening adapter\n", rc);
		goto reg_crq_failed;
	}

	queue->cur = 0;
	spin_lock_init(&queue->lock);

	tasklet_init(&adapter->work_task, ibmvmc_task, (unsigned long)adapter);

	if (request_irq(vdev->irq,
			ibmvmc_handle_event,
			0, "ibmvmc", (void *)adapter) != 0) {
		dev_err(adapter->dev, "couldn't register irq 0x%x\n",
			vdev->irq);
		goto req_irq_failed;
	}

	rc = vio_enable_interrupts(vdev);
	if (rc != 0) {
		dev_err(adapter->dev, "Error %d enabling interrupts!!!\n", rc);
		goto req_irq_failed;
	}

	return retrc;

req_irq_failed:
	/* Cannot have any work since we either never got our IRQ registered,
	 * or never got interrupts enabled
	 */
	tasklet_kill(&adapter->work_task);
	h_free_crq(vdev->unit_address);
reg_crq_failed:
	dma_unmap_single(adapter->dev,
			 queue->msg_token,
			 queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL);
map_failed:
	free_page((unsigned long)queue->msgs);
malloc_failed:
	return -ENOMEM;
}

/* Fill in the liobn and riobn fields on the adapter */
static int read_dma_window(struct vio_dev *vdev,
			   struct crq_server_adapter *adapter)
{
	const __be32 *dma_window;
	const __be32 *prop;

	/* TODO Using of_parse_dma_window would be better, but it doesn't give
	 * a way to read multiple windows without already knowing the size of
	 * a window or the number of windows
	 */
	dma_window =
		(const __be32 *)vio_get_attribute(vdev, "ibm,my-dma-window",
						NULL);
	if (!dma_window) {
		dev_warn(adapter->dev, "Couldn't find ibm,my-dma-window property\n");
		return -1;
	}

	adapter->liobn = be32_to_cpu(*dma_window);
	dma_window++;

	prop = (const __be32 *)vio_get_attribute(vdev, "ibm,#dma-address-cells",
						NULL);
	if (!prop) {
		dev_warn(adapter->dev, "Couldn't find ibm,#dma-address-cells property\n");
		dma_window++;
	} else {
		dma_window += be32_to_cpu(*prop);
	}

	prop = (const __be32 *)vio_get_attribute(vdev, "ibm,#dma-size-cells",
						NULL);
	if (!prop) {
		dev_warn(adapter->dev, "Couldn't find ibm,#dma-size-cells property\n");
		dma_window++;
	} else {
		dma_window += be32_to_cpu(*prop);
	}

	/* dma_window should point to the second window now */
	adapter->riobn = be32_to_cpu(*dma_window);

	return 0;
}

static int ibmvmc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
{
	struct crq_server_adapter *adapter = &ibmvmc_adapter;
	int rc;

	dev_set_drvdata(&vdev->dev, NULL);
	memset(adapter, 0, sizeof(*adapter));
	adapter->dev = &vdev->dev;

	dev_info(adapter->dev, "Probe for UA 0x%x\n", vdev->unit_address);

	rc = read_dma_window(vdev, adapter);
	if (rc != 0) {
		ibmvmc.state = ibmvmc_state_failed;
		return -1;
	}

	dev_dbg(adapter->dev, "Probe: liobn 0x%x, riobn 0x%x\n",
		adapter->liobn, adapter->riobn);

	init_waitqueue_head(&adapter->reset_wait_queue);
	adapter->reset_task = kthread_run(ibmvmc_reset_task, adapter, "ibmvmc");
	if (IS_ERR(adapter->reset_task)) {
		dev_err(adapter->dev, "Failed to start reset thread\n");
		ibmvmc.state = ibmvmc_state_failed;
		rc = PTR_ERR(adapter->reset_task);
		adapter->reset_task = NULL;
		return rc;
	}

	rc = ibmvmc_init_crq_queue(adapter);
	if (rc != 0 && rc != H_RESOURCE) {
		dev_err(adapter->dev, "Error initializing CRQ.  rc = 0x%x\n",
			rc);
		ibmvmc.state = ibmvmc_state_failed;
		goto crq_failed;
	}

	ibmvmc.state = ibmvmc_state_crqinit;

	/* Try to send an initialization message.  Note that this is allowed
	 * to fail if the other end is not acive.  In that case we just wait
	 * for the other side to initialize.
	 */
	if (ibmvmc_send_crq(adapter, 0xC001000000000000LL, 0) != 0 &&
	    rc != H_RESOURCE)
		dev_warn(adapter->dev, "Failed to send initialize CRQ message\n");

	dev_set_drvdata(&vdev->dev, adapter);

	return 0;

crq_failed:
	kthread_stop(adapter->reset_task);
	adapter->reset_task = NULL;
	return -EPERM;
}

static void ibmvmc_remove(struct vio_dev *vdev)
{
	struct crq_server_adapter *adapter = dev_get_drvdata(&vdev->dev);

	dev_info(adapter->dev, "Entering remove for UA 0x%x\n",
		 vdev->unit_address);
	ibmvmc_release_crq_queue(adapter);
}

static struct vio_device_id ibmvmc_device_table[] = {
	{ "ibm,vmc", "IBM,vmc" },
	{ "", "" }
};
MODULE_DEVICE_TABLE(vio, ibmvmc_device_table);

static struct vio_driver ibmvmc_driver = {
	.name        = ibmvmc_driver_name,
	.id_table    = ibmvmc_device_table,
	.probe       = ibmvmc_probe,
	.remove      = ibmvmc_remove,
};

static void __init ibmvmc_scrub_module_parms(void)
{
	if (ibmvmc_max_mtu > MAX_MTU) {
		pr_warn("ibmvmc: Max MTU reduced to %d\n", MAX_MTU);
		ibmvmc_max_mtu = MAX_MTU;
	} else if (ibmvmc_max_mtu < MIN_MTU) {
		pr_warn("ibmvmc: Max MTU increased to %d\n", MIN_MTU);
		ibmvmc_max_mtu = MIN_MTU;
	}

	if (ibmvmc_max_buf_pool_size > MAX_BUF_POOL_SIZE) {
		pr_warn("ibmvmc: Max buffer pool size reduced to %d\n",
			MAX_BUF_POOL_SIZE);
		ibmvmc_max_buf_pool_size = MAX_BUF_POOL_SIZE;
	} else if (ibmvmc_max_buf_pool_size < MIN_BUF_POOL_SIZE) {
		pr_warn("ibmvmc: Max buffer pool size increased to %d\n",
			MIN_BUF_POOL_SIZE);
		ibmvmc_max_buf_pool_size = MIN_BUF_POOL_SIZE;
	}

	if (ibmvmc_max_hmcs > MAX_HMCS) {
		pr_warn("ibmvmc: Max HMCs reduced to %d\n", MAX_HMCS);
		ibmvmc_max_hmcs = MAX_HMCS;
	} else if (ibmvmc_max_hmcs < MIN_HMCS) {
		pr_warn("ibmvmc: Max HMCs increased to %d\n", MIN_HMCS);
		ibmvmc_max_hmcs = MIN_HMCS;
	}
}

static struct miscdevice ibmvmc_miscdev = {
	.name = ibmvmc_driver_name,
	.minor = MISC_DYNAMIC_MINOR,
	.fops = &ibmvmc_fops,
};

static int __init ibmvmc_module_init(void)
{
	int rc, i, j;

	ibmvmc.state = ibmvmc_state_initial;
	pr_info("ibmvmc: version %s\n", IBMVMC_DRIVER_VERSION);

	rc = misc_register(&ibmvmc_miscdev);
	if (rc) {
		pr_err("ibmvmc: misc registration failed\n");
		goto misc_register_failed;
	}
	pr_info("ibmvmc: node %d:%d\n", MISC_MAJOR,
		ibmvmc_miscdev.minor);

	/* Initialize data structures */
	memset(hmcs, 0, sizeof(struct ibmvmc_hmc) * MAX_HMCS);
	for (i = 0; i < MAX_HMCS; i++) {
		spin_lock_init(&hmcs[i].lock);
		hmcs[i].state = ibmhmc_state_free;
		for (j = 0; j < MAX_BUF_POOL_SIZE; j++)
			hmcs[i].queue_outbound_msgs[j] = VMC_INVALID_BUFFER_ID;
	}

	/* Sanity check module parms */
	ibmvmc_scrub_module_parms();

	/*
	 * Initialize some reasonable values.  Might be negotiated smaller
	 * values during the capabilities exchange.
	 */
	ibmvmc.max_mtu = ibmvmc_max_mtu;
	ibmvmc.max_buffer_pool_size = ibmvmc_max_buf_pool_size;
	ibmvmc.max_hmc_index = ibmvmc_max_hmcs - 1;

	rc = vio_register_driver(&ibmvmc_driver);

	if (rc) {
		pr_err("ibmvmc: rc %d from vio_register_driver\n", rc);
		goto vio_reg_failed;
	}

	return 0;

vio_reg_failed:
	misc_deregister(&ibmvmc_miscdev);
misc_register_failed:
	return rc;
}

static void __exit ibmvmc_module_exit(void)
{
	pr_info("ibmvmc: module exit\n");
	vio_unregister_driver(&ibmvmc_driver);
	misc_deregister(&ibmvmc_miscdev);
}

module_init(ibmvmc_module_init);
module_exit(ibmvmc_module_exit);

module_param_named(buf_pool_size, ibmvmc_max_buf_pool_size,
		   int, 0644);
MODULE_PARM_DESC(buf_pool_size, "Buffer pool size");
module_param_named(max_hmcs, ibmvmc_max_hmcs, int, 0644);
MODULE_PARM_DESC(max_hmcs, "Max HMCs");
module_param_named(max_mtu, ibmvmc_max_mtu, int, 0644);
MODULE_PARM_DESC(max_mtu, "Max MTU");

MODULE_AUTHOR("Steven Royer <seroyer@linux.vnet.ibm.com>");
MODULE_DESCRIPTION("IBM VMC");
MODULE_VERSION(IBMVMC_DRIVER_VERSION);
MODULE_LICENSE("GPL v2");
