/*
 * 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 "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_guts() - 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
 */
static struct visorchannel *visorchannel_create_guts(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;
}

struct visorchannel *visorchannel_create(u64 physaddr, gfp_t gfp,
					 const guid_t *guid)
{
	return visorchannel_create_guts(physaddr, gfp, guid, false);
}

struct visorchannel *visorchannel_create_with_lock(u64 physaddr, gfp_t gfp,
						   const guid_t *guid)
{
	return visorchannel_create_guts(physaddr, gfp, guid, true);
}

/**
 * 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);
