/*
 * Copyright (C) 2010 - 2015 UNISYS CORPORATION
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 * NON INFRINGEMENT.  See the GNU General Public License for more
 * details.
 */

/*
 *  This provides s-Par channel communication primitives, which are
 *  independent of the mechanism used to access the channel data.
 */

#include <linux/uuid.h>
#include <linux/io.h>
#include <linux/slab.h>

#include "visorbus.h"
#include "visorbus_private.h"
#include "controlvmchannel.h"

#define VISOR_DRV_NAME "visorchannel"

#define VISOR_CONSOLEVIDEO_CHANNEL_GUID \
	GUID_INIT(0x3cd6e705, 0xd6a2, 0x4aa5, \
		  0xad, 0x5c, 0x7b, 0x8, 0x88, 0x9d, 0xff, 0xe2)

static const guid_t visor_video_guid = VISOR_CONSOLEVIDEO_CHANNEL_GUID;

struct visorchannel {
	u64 physaddr;
	ulong nbytes;
	void *mapped;
	bool requested;
	struct channel_header chan_hdr;
	guid_t guid;
	/*
	 * channel creator knows if more than one thread will be inserting or
	 * removing
	 */
	bool needs_lock;
	/* protect head writes in chan_hdr */
	spinlock_t insert_lock;
	/* protect tail writes in chan_hdr */
	spinlock_t remove_lock;
	guid_t type;
	guid_t inst;
};

void visorchannel_destroy(struct visorchannel *channel)
{
	if (!channel)
		return;

	if (channel->mapped) {
		memunmap(channel->mapped);
		if (channel->requested)
			release_mem_region(channel->physaddr, channel->nbytes);
	}
	kfree(channel);
}

u64 visorchannel_get_physaddr(struct visorchannel *channel)
{
	return channel->physaddr;
}

ulong visorchannel_get_nbytes(struct visorchannel *channel)
{
	return channel->nbytes;
}

char *visorchannel_guid_id(const guid_t *guid, char *s)
{
	sprintf(s, "%pUL", guid);
	return s;
}

char *visorchannel_id(struct visorchannel *channel, char *s)
{
	return visorchannel_guid_id(&channel->guid, s);
}

char *visorchannel_zoneid(struct visorchannel *channel, char *s)
{
	return visorchannel_guid_id(&channel->chan_hdr.zone_guid, s);
}

u64 visorchannel_get_clientpartition(struct visorchannel *channel)
{
	return channel->chan_hdr.partition_handle;
}

int visorchannel_set_clientpartition(struct visorchannel *channel,
				     u64 partition_handle)
{
	channel->chan_hdr.partition_handle = partition_handle;
	return 0;
}

/**
 * visorchannel_get_guid() - queries the GUID of the designated channel
 * @channel: the channel to query
 *
 * Return: the GUID of the provided channel
 */
const guid_t *visorchannel_get_guid(struct visorchannel *channel)
{
	return &channel->guid;
}
EXPORT_SYMBOL_GPL(visorchannel_get_guid);

int visorchannel_read(struct visorchannel *channel, ulong offset, void *dest,
		      ulong nbytes)
{
	if (offset + nbytes > channel->nbytes)
		return -EIO;

	memcpy(dest, channel->mapped + offset, nbytes);
	return 0;
}

int visorchannel_write(struct visorchannel *channel, ulong offset, void *dest,
		       ulong nbytes)
{
	size_t chdr_size = sizeof(struct channel_header);
	size_t copy_size;

	if (offset + nbytes > channel->nbytes)
		return -EIO;

	if (offset < chdr_size) {
		copy_size = min(chdr_size - offset, nbytes);
		memcpy(((char *)(&channel->chan_hdr)) + offset,
		       dest, copy_size);
	}
	memcpy(channel->mapped + offset, dest, nbytes);
	return 0;
}

void *visorchannel_get_header(struct visorchannel *channel)
{
	return &channel->chan_hdr;
}

/*
 * Return offset of a specific SIGNAL_QUEUE_HEADER from the beginning of a
 * channel header
 */
static int sig_queue_offset(struct channel_header *chan_hdr, int q)
{
	return ((chan_hdr)->ch_space_offset +
	       ((q) * sizeof(struct signal_queue_header)));
}

/*
 * Return offset of a specific queue entry (data) from the beginning of a
 * channel header
 */
static int sig_data_offset(struct channel_header *chan_hdr, int q,
			   struct signal_queue_header *sig_hdr, int slot)
{
	return (sig_queue_offset(chan_hdr, q) + sig_hdr->sig_base_offset +
	       (slot * sig_hdr->signal_size));
}

/*
 * Write the contents of a specific field within a SIGNAL_QUEUE_HEADER back into
 * host memory
 */
#define SIG_WRITE_FIELD(channel, queue, sig_hdr, FIELD) \
	visorchannel_write(channel, \
			   sig_queue_offset(&channel->chan_hdr, queue) + \
			   offsetof(struct signal_queue_header, FIELD), \
			   &((sig_hdr)->FIELD), \
			   sizeof((sig_hdr)->FIELD))

static int sig_read_header(struct visorchannel *channel, u32 queue,
			   struct signal_queue_header *sig_hdr)
{
	if (channel->chan_hdr.ch_space_offset < sizeof(struct channel_header))
		return -EINVAL;

	/* Read the appropriate SIGNAL_QUEUE_HEADER into local memory. */
	return visorchannel_read(channel,
				 sig_queue_offset(&channel->chan_hdr, queue),
				 sig_hdr, sizeof(struct signal_queue_header));
}

static int sig_read_data(struct visorchannel *channel, u32 queue,
			 struct signal_queue_header *sig_hdr, u32 slot,
			 void *data)
{
	int signal_data_offset = sig_data_offset(&channel->chan_hdr, queue,
						 sig_hdr, slot);

	return visorchannel_read(channel, signal_data_offset,
				 data, sig_hdr->signal_size);
}

static int sig_write_data(struct visorchannel *channel, u32 queue,
			  struct signal_queue_header *sig_hdr, u32 slot,
			  void *data)
{
	int signal_data_offset = sig_data_offset(&channel->chan_hdr, queue,
						 sig_hdr, slot);

	return visorchannel_write(channel, signal_data_offset,
				  data, sig_hdr->signal_size);
}

static int signalremove_inner(struct visorchannel *channel, u32 queue,
			      void *msg)
{
	struct signal_queue_header sig_hdr;
	int error;

	error = sig_read_header(channel, queue, &sig_hdr);
	if (error)
		return error;
	/* No signals to remove; have caller try again. */
	if (sig_hdr.head == sig_hdr.tail)
		return -EAGAIN;
	sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots;
	error = sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg);
	if (error)
		return error;
	sig_hdr.num_received++;
	/*
	 * For each data field in SIGNAL_QUEUE_HEADER that was modified, update
	 * host memory. Required for channel sync.
	 */
	mb();
	error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail);
	if (error)
		return error;
	error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received);
	if (error)
		return error;
	return 0;
}

/**
 * visorchannel_signalremove() - removes a message from the designated
 *                               channel/queue
 * @channel: the channel the message will be removed from
 * @queue:   the queue the message will be removed from
 * @msg:     the message to remove
 *
 * Return: integer error code indicating the status of the removal
 */
int visorchannel_signalremove(struct visorchannel *channel, u32 queue,
			      void *msg)
{
	int rc;
	unsigned long flags;

	if (channel->needs_lock) {
		spin_lock_irqsave(&channel->remove_lock, flags);
		rc = signalremove_inner(channel, queue, msg);
		spin_unlock_irqrestore(&channel->remove_lock, flags);
	} else {
		rc = signalremove_inner(channel, queue, msg);
	}

	return rc;
}
EXPORT_SYMBOL_GPL(visorchannel_signalremove);

static bool queue_empty(struct visorchannel *channel, u32 queue)
{
	struct signal_queue_header sig_hdr;

	if (sig_read_header(channel, queue, &sig_hdr))
		return true;
	return (sig_hdr.head == sig_hdr.tail);
}

/**
 * visorchannel_signalempty() - checks if the designated channel/queue contains
 *				any messages
 * @channel: the channel to query
 * @queue:   the queue in the channel to query
 *
 * Return: boolean indicating whether any messages in the designated
 *         channel/queue are present
 */
bool visorchannel_signalempty(struct visorchannel *channel, u32 queue)
{
	bool rc;
	unsigned long flags;

	if (!channel->needs_lock)
		return queue_empty(channel, queue);
	spin_lock_irqsave(&channel->remove_lock, flags);
	rc = queue_empty(channel, queue);
	spin_unlock_irqrestore(&channel->remove_lock, flags);
	return rc;
}
EXPORT_SYMBOL_GPL(visorchannel_signalempty);

static int signalinsert_inner(struct visorchannel *channel, u32 queue,
			      void *msg)
{
	struct signal_queue_header sig_hdr;
	int err;

	err = sig_read_header(channel, queue, &sig_hdr);
	if (err)
		return err;
	sig_hdr.head = (sig_hdr.head + 1) % sig_hdr.max_slots;
	if (sig_hdr.head == sig_hdr.tail) {
		sig_hdr.num_overflows++;
		err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows);
		if (err)
			return err;
		return -EIO;
	}
	err = sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg);
	if (err)
		return err;
	sig_hdr.num_sent++;
	/*
	 * For each data field in SIGNAL_QUEUE_HEADER that was modified, update
	 * host memory. Required for channel sync.
	 */
	mb();
	err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, head);
	if (err)
		return err;
	err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent);
	if (err)
		return err;
	return 0;
}

/*
 * visorchannel_create() - creates the struct visorchannel abstraction for a
 *                         data area in memory, but does NOT modify this data
 *                         area
 * @physaddr:      physical address of start of channel
 * @gfp:           gfp_t to use when allocating memory for the data struct
 * @guid:          GUID that identifies channel type;
 * @needs_lock:    must specify true if you have multiple threads of execution
 *                 that will be calling visorchannel methods of this
 *                 visorchannel at the same time
 *
 * Return: pointer to visorchannel that was created if successful,
 *         otherwise NULL
 */
struct visorchannel *visorchannel_create(u64 physaddr, gfp_t gfp,
					 const guid_t *guid, bool needs_lock)
{
	struct visorchannel *channel;
	int err;
	size_t size = sizeof(struct channel_header);

	if (physaddr == 0)
		return NULL;

	channel = kzalloc(sizeof(*channel), gfp);
	if (!channel)
		return NULL;
	channel->needs_lock = needs_lock;
	spin_lock_init(&channel->insert_lock);
	spin_lock_init(&channel->remove_lock);
	/*
	 * Video driver constains the efi framebuffer so it will get a conflict
	 * resource when requesting its full mem region. Since we are only
	 * using the efi framebuffer for video we can ignore this. Remember that
	 * we haven't requested it so we don't try to release later on.
	 */
	channel->requested = request_mem_region(physaddr, size, VISOR_DRV_NAME);
	if (!channel->requested && !guid_equal(guid, &visor_video_guid))
		/* we only care about errors if this is not the video channel */
		goto err_destroy_channel;
	channel->mapped = memremap(physaddr, size, MEMREMAP_WB);
	if (!channel->mapped) {
		release_mem_region(physaddr, size);
		goto err_destroy_channel;
	}
	channel->physaddr = physaddr;
	channel->nbytes = size;
	err = visorchannel_read(channel, 0, &channel->chan_hdr, size);
	if (err)
		goto err_destroy_channel;
	size = (ulong)channel->chan_hdr.size;
	memunmap(channel->mapped);
	if (channel->requested)
		release_mem_region(channel->physaddr, channel->nbytes);
	channel->mapped = NULL;
	channel->requested = request_mem_region(channel->physaddr, size,
						VISOR_DRV_NAME);
	if (!channel->requested && !guid_equal(guid, &visor_video_guid))
		/* we only care about errors if this is not the video channel */
		goto err_destroy_channel;
	channel->mapped = memremap(channel->physaddr, size, MEMREMAP_WB);
	if (!channel->mapped) {
		release_mem_region(channel->physaddr, size);
		goto err_destroy_channel;
	}
	channel->nbytes = size;
	guid_copy(&channel->guid, guid);
	return channel;

err_destroy_channel:
	visorchannel_destroy(channel);
	return NULL;
}

/**
 * visorchannel_signalinsert() - inserts a message into the designated
 *                               channel/queue
 * @channel: the channel the message will be added to
 * @queue:   the queue the message will be added to
 * @msg:     the message to insert
 *
 * Return: integer error code indicating the status of the insertion
 */
int visorchannel_signalinsert(struct visorchannel *channel, u32 queue,
			      void *msg)
{
	int rc;
	unsigned long flags;

	if (channel->needs_lock) {
		spin_lock_irqsave(&channel->insert_lock, flags);
		rc = signalinsert_inner(channel, queue, msg);
		spin_unlock_irqrestore(&channel->insert_lock, flags);
	} else {
		rc = signalinsert_inner(channel, queue, msg);
	}

	return rc;
}
EXPORT_SYMBOL_GPL(visorchannel_signalinsert);
