/*
 *  Driver for the NXP SAA7164 PCIe bridge
 *
 *  Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com>
 *
 *  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.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/wait.h>

#include "saa7164.h"

static int saa7164_cmd_alloc_seqno(struct saa7164_dev *dev)
{
	int i, ret = -1;

	mutex_lock(&dev->lock);
	for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
		if (dev->cmds[i].inuse == 0) {
			dev->cmds[i].inuse = 1;
			dev->cmds[i].signalled = 0;
			dev->cmds[i].timeout = 0;
			ret = dev->cmds[i].seqno;
			break;
		}
	}
	mutex_unlock(&dev->lock);

	return ret;
}

static void saa7164_cmd_free_seqno(struct saa7164_dev *dev, u8 seqno)
{
	mutex_lock(&dev->lock);
	if ((dev->cmds[seqno].inuse == 1) &&
		(dev->cmds[seqno].seqno == seqno)) {
		dev->cmds[seqno].inuse = 0;
		dev->cmds[seqno].signalled = 0;
		dev->cmds[seqno].timeout = 0;
	}
	mutex_unlock(&dev->lock);
}

static void saa7164_cmd_timeout_seqno(struct saa7164_dev *dev, u8 seqno)
{
	mutex_lock(&dev->lock);
	if ((dev->cmds[seqno].inuse == 1) &&
		(dev->cmds[seqno].seqno == seqno)) {
		dev->cmds[seqno].timeout = 1;
	}
	mutex_unlock(&dev->lock);
}

static u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno)
{
	int ret = 0;

	mutex_lock(&dev->lock);
	if ((dev->cmds[seqno].inuse == 1) &&
		(dev->cmds[seqno].seqno == seqno)) {
		ret = dev->cmds[seqno].timeout;
	}
	mutex_unlock(&dev->lock);

	return ret;
}

/* Commands to the f/w get marshelled to/from this code then onto the PCI
 * -bus/c running buffer. */
int saa7164_irq_dequeue(struct saa7164_dev *dev)
{
	int ret = SAA_OK, i = 0;
	u32 timeout;
	wait_queue_head_t *q = NULL;
	u8 tmp[512];
	dprintk(DBGLVL_CMD, "%s()\n", __func__);

	/* While any outstand message on the bus exists... */
	do {

		/* Peek the msg bus */
		struct tmComResInfo tRsp = { 0, 0, 0, 0, 0, 0 };
		ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
		if (ret != SAA_OK)
			break;

		q = &dev->cmds[tRsp.seqno].wait;
		timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
		dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
		if (!timeout) {
			dprintk(DBGLVL_CMD,
				"%s() signalled seqno(%d) (for dequeue)\n",
				__func__, tRsp.seqno);
			dev->cmds[tRsp.seqno].signalled = 1;
			wake_up(q);
		} else {
			printk(KERN_ERR
				"%s() found timed out command on the bus\n",
					__func__);

			/* Clean the bus */
			ret = saa7164_bus_get(dev, &tRsp, &tmp, 0);
			printk(KERN_ERR "%s() ret = %x\n", __func__, ret);
			if (ret == SAA_ERR_EMPTY)
				/* Someone else already fetched the response */
				return SAA_OK;

			if (ret != SAA_OK)
				return ret;
		}

		/* It's unlikely to have more than 4 or 5 pending messages,
		 * ensure we exit at some point regardless.
		 */
	} while (i++ < 32);

	return ret;
}

/* Commands to the f/w get marshelled to/from this code then onto the PCI
 * -bus/c running buffer. */
static int saa7164_cmd_dequeue(struct saa7164_dev *dev)
{
	int loop = 1;
	int ret;
	u32 timeout;
	wait_queue_head_t *q = NULL;
	u8 tmp[512];
	dprintk(DBGLVL_CMD, "%s()\n", __func__);

	while (loop) {

		struct tmComResInfo tRsp = { 0, 0, 0, 0, 0, 0 };
		ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
		if (ret == SAA_ERR_EMPTY)
			return SAA_OK;

		if (ret != SAA_OK)
			return ret;

		q = &dev->cmds[tRsp.seqno].wait;
		timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
		dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
		if (timeout) {
			printk(KERN_ERR "found timed out command on the bus\n");

			/* Clean the bus */
			ret = saa7164_bus_get(dev, &tRsp, &tmp, 0);
			printk(KERN_ERR "ret = %x\n", ret);
			if (ret == SAA_ERR_EMPTY)
				/* Someone else already fetched the response */
				return SAA_OK;

			if (ret != SAA_OK)
				return ret;

			if (tRsp.flags & PVC_CMDFLAG_CONTINUE)
				printk(KERN_ERR "split response\n");
			else
				saa7164_cmd_free_seqno(dev, tRsp.seqno);

			printk(KERN_ERR " timeout continue\n");
			continue;
		}

		dprintk(DBGLVL_CMD, "%s() signalled seqno(%d) (for dequeue)\n",
			__func__, tRsp.seqno);
		dev->cmds[tRsp.seqno].signalled = 1;
		wake_up(q);
		return SAA_OK;
	}

	return SAA_OK;
}

static int saa7164_cmd_set(struct saa7164_dev *dev, struct tmComResInfo *msg,
			   void *buf)
{
	struct tmComResBusInfo *bus = &dev->bus;
	u8 cmd_sent;
	u16 size, idx;
	u32 cmds;
	void *tmp;
	int ret = -1;

	if (!msg) {
		printk(KERN_ERR "%s() !msg\n", __func__);
		return SAA_ERR_BAD_PARAMETER;
	}

	mutex_lock(&dev->cmds[msg->id].lock);

	size = msg->size;
	idx = 0;
	cmds = size / bus->m_wMaxReqSize;
	if (size % bus->m_wMaxReqSize == 0)
		cmds -= 1;

	cmd_sent = 0;

	/* Split the request into smaller chunks */
	for (idx = 0; idx < cmds; idx++) {

		msg->flags |= SAA_CMDFLAG_CONTINUE;
		msg->size = bus->m_wMaxReqSize;
		tmp = buf + idx * bus->m_wMaxReqSize;

		ret = saa7164_bus_set(dev, msg, tmp);
		if (ret != SAA_OK) {
			printk(KERN_ERR "%s() set failed %d\n", __func__, ret);

			if (cmd_sent) {
				ret = SAA_ERR_BUSY;
				goto out;
			}
			ret = SAA_ERR_OVERFLOW;
			goto out;
		}
		cmd_sent = 1;
	}

	/* If not the last command... */
	if (idx != 0)
		msg->flags &= ~SAA_CMDFLAG_CONTINUE;

	msg->size = size - idx * bus->m_wMaxReqSize;

	ret = saa7164_bus_set(dev, msg, buf + idx * bus->m_wMaxReqSize);
	if (ret != SAA_OK) {
		printk(KERN_ERR "%s() set last failed %d\n", __func__, ret);

		if (cmd_sent) {
			ret = SAA_ERR_BUSY;
			goto out;
		}
		ret = SAA_ERR_OVERFLOW;
		goto out;
	}
	ret = SAA_OK;

out:
	mutex_unlock(&dev->cmds[msg->id].lock);
	return ret;
}

/* Wait for a signal event, without holding a mutex. Either return TIMEOUT if
 * the event never occurred, or SAA_OK if it was signaled during the wait.
 */
static int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
{
	wait_queue_head_t *q = NULL;
	int ret = SAA_BUS_TIMEOUT;
	unsigned long stamp;
	int r;

	if (saa_debug >= 4)
		saa7164_bus_dump(dev);

	dprintk(DBGLVL_CMD, "%s(seqno=%d)\n", __func__, seqno);

	mutex_lock(&dev->lock);
	if ((dev->cmds[seqno].inuse == 1) &&
		(dev->cmds[seqno].seqno == seqno)) {
		q = &dev->cmds[seqno].wait;
	}
	mutex_unlock(&dev->lock);

	if (q) {
		/* If we haven't been signalled we need to wait */
		if (dev->cmds[seqno].signalled == 0) {
			stamp = jiffies;
			dprintk(DBGLVL_CMD,
				"%s(seqno=%d) Waiting (signalled=%d)\n",
				__func__, seqno, dev->cmds[seqno].signalled);

			/* Wait for signalled to be flagged or timeout */
			/* In a highly stressed system this can easily extend
			 * into multiple seconds before the deferred worker
			 * is scheduled, and we're woken up via signal.
			 * We typically are signalled in < 50ms but it can
			 * take MUCH longer.
			 */
			wait_event_timeout(*q, dev->cmds[seqno].signalled,
				(HZ * waitsecs));
			r = time_before(jiffies, stamp + (HZ * waitsecs));
			if (r)
				ret = SAA_OK;
			else
				saa7164_cmd_timeout_seqno(dev, seqno);

			dprintk(DBGLVL_CMD, "%s(seqno=%d) Waiting res = %d "
				"(signalled=%d)\n", __func__, seqno, r,
				dev->cmds[seqno].signalled);
		} else
			ret = SAA_OK;
	} else
		printk(KERN_ERR "%s(seqno=%d) seqno is invalid\n",
			__func__, seqno);

	return ret;
}

void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno)
{
	int i;
	dprintk(DBGLVL_CMD, "%s()\n", __func__);

	mutex_lock(&dev->lock);
	for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
		if (dev->cmds[i].inuse == 1) {
			dprintk(DBGLVL_CMD,
				"seqno %d inuse, sig = %d, t/out = %d\n",
				dev->cmds[i].seqno,
				dev->cmds[i].signalled,
				dev->cmds[i].timeout);
		}
	}

	for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
		if ((dev->cmds[i].inuse == 1) && ((i == 0) ||
			(dev->cmds[i].signalled) || (dev->cmds[i].timeout))) {
			dprintk(DBGLVL_CMD, "%s(seqno=%d) calling wake_up\n",
				__func__, i);
			dev->cmds[i].signalled = 1;
			wake_up(&dev->cmds[i].wait);
		}
	}
	mutex_unlock(&dev->lock);
}

int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command,
	u16 controlselector, u16 size, void *buf)
{
	struct tmComResInfo command_t, *pcommand_t;
	struct tmComResInfo response_t, *presponse_t;
	u8 errdata[256];
	u16 resp_dsize;
	u16 data_recd;
	u32 loop;
	int ret;
	int safety = 0;

	dprintk(DBGLVL_CMD, "%s(unitid = %s (%d) , command = 0x%x, "
		"sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id,
		command, controlselector);

	if ((size == 0) || (buf == NULL)) {
		printk(KERN_ERR "%s() Invalid param\n", __func__);
		return SAA_ERR_BAD_PARAMETER;
	}

	/* Prepare some basic command/response structures */
	memset(&command_t, 0, sizeof(command_t));
	memset(&response_t, 0, sizeof(response_t));
	pcommand_t = &command_t;
	presponse_t = &response_t;
	command_t.id = id;
	command_t.command = command;
	command_t.controlselector = controlselector;
	command_t.size = size;

	/* Allocate a unique sequence number */
	ret = saa7164_cmd_alloc_seqno(dev);
	if (ret < 0) {
		printk(KERN_ERR "%s() No free sequences\n", __func__);
		ret = SAA_ERR_NO_RESOURCES;
		goto out;
	}

	command_t.seqno = (u8)ret;

	/* Send Command */
	resp_dsize = size;
	pcommand_t->size = size;

	dprintk(DBGLVL_CMD, "%s() pcommand_t.seqno = %d\n",
		__func__, pcommand_t->seqno);

	dprintk(DBGLVL_CMD, "%s() pcommand_t.size = %d\n",
		__func__, pcommand_t->size);

	ret = saa7164_cmd_set(dev, pcommand_t, buf);
	if (ret != SAA_OK) {
		printk(KERN_ERR "%s() set command failed %d\n", __func__, ret);

		if (ret != SAA_ERR_BUSY)
			saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
		else
			/* Flag a timeout, because at least one
			 * command was sent */
			saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);

		goto out;
	}

	/* With split responses we have to collect the msgs piece by piece */
	data_recd = 0;
	loop = 1;
	while (loop) {
		dprintk(DBGLVL_CMD, "%s() loop\n", __func__);

		ret = saa7164_cmd_wait(dev, pcommand_t->seqno);
		dprintk(DBGLVL_CMD, "%s() loop ret = %d\n", __func__, ret);

		/* if power is down and this is not a power command ... */

		if (ret == SAA_BUS_TIMEOUT) {
			printk(KERN_ERR "Event timed out\n");
			saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
			return ret;
		}

		if (ret != SAA_OK) {
			printk(KERN_ERR "spurious error\n");
			return ret;
		}

		/* Peek response */
		ret = saa7164_bus_get(dev, presponse_t, NULL, 1);
		if (ret == SAA_ERR_EMPTY) {
			dprintk(4, "%s() SAA_ERR_EMPTY\n", __func__);
			continue;
		}
		if (ret != SAA_OK) {
			printk(KERN_ERR "peek failed\n");
			return ret;
		}

		dprintk(DBGLVL_CMD, "%s() presponse_t->seqno = %d\n",
			__func__, presponse_t->seqno);

		dprintk(DBGLVL_CMD, "%s() presponse_t->flags = 0x%x\n",
			__func__, presponse_t->flags);

		dprintk(DBGLVL_CMD, "%s() presponse_t->size = %d\n",
			__func__, presponse_t->size);

		/* Check if the response was for our command */
		if (presponse_t->seqno != pcommand_t->seqno) {

			dprintk(DBGLVL_CMD,
				"wrong event: seqno = %d, "
				"expected seqno = %d, "
				"will dequeue regardless\n",
				presponse_t->seqno, pcommand_t->seqno);

			ret = saa7164_cmd_dequeue(dev);
			if (ret != SAA_OK) {
				printk(KERN_ERR "dequeue failed, ret = %d\n",
					ret);
				if (safety++ > 16) {
					printk(KERN_ERR
					"dequeue exceeded, safety exit\n");
					return SAA_ERR_BUSY;
				}
			}

			continue;
		}

		if ((presponse_t->flags & PVC_RESPONSEFLAG_ERROR) != 0) {

			memset(&errdata[0], 0, sizeof(errdata));

			ret = saa7164_bus_get(dev, presponse_t, &errdata[0], 0);
			if (ret != SAA_OK) {
				printk(KERN_ERR "get error(2)\n");
				return ret;
			}

			saa7164_cmd_free_seqno(dev, pcommand_t->seqno);

			dprintk(DBGLVL_CMD, "%s() errdata %02x%02x%02x%02x\n",
				__func__, errdata[0], errdata[1], errdata[2],
				errdata[3]);

			/* Map error codes */
			dprintk(DBGLVL_CMD, "%s() cmd, error code  = 0x%x\n",
				__func__, errdata[0]);

			switch (errdata[0]) {
			case PVC_ERRORCODE_INVALID_COMMAND:
				dprintk(DBGLVL_CMD, "%s() INVALID_COMMAND\n",
					__func__);
				ret = SAA_ERR_INVALID_COMMAND;
				break;
			case PVC_ERRORCODE_INVALID_DATA:
				dprintk(DBGLVL_CMD, "%s() INVALID_DATA\n",
					__func__);
				ret = SAA_ERR_BAD_PARAMETER;
				break;
			case PVC_ERRORCODE_TIMEOUT:
				dprintk(DBGLVL_CMD, "%s() TIMEOUT\n", __func__);
				ret = SAA_ERR_TIMEOUT;
				break;
			case PVC_ERRORCODE_NAK:
				dprintk(DBGLVL_CMD, "%s() NAK\n", __func__);
				ret = SAA_ERR_NULL_PACKET;
				break;
			case PVC_ERRORCODE_UNKNOWN:
			case PVC_ERRORCODE_INVALID_CONTROL:
				dprintk(DBGLVL_CMD,
					"%s() UNKNOWN OR INVALID CONTROL\n",
					__func__);
			default:
				dprintk(DBGLVL_CMD, "%s() UNKNOWN\n", __func__);
				ret = SAA_ERR_NOT_SUPPORTED;
			}

			/* See of other commands are on the bus */
			if (saa7164_cmd_dequeue(dev) != SAA_OK)
				printk(KERN_ERR "dequeue(2) failed\n");

			return ret;
		}

		/* If response is invalid */
		if ((presponse_t->id != pcommand_t->id) ||
			(presponse_t->command != pcommand_t->command) ||
			(presponse_t->controlselector !=
				pcommand_t->controlselector) ||
			(((resp_dsize - data_recd) != presponse_t->size) &&
				!(presponse_t->flags & PVC_CMDFLAG_CONTINUE)) ||
			((resp_dsize - data_recd) < presponse_t->size)) {

			/* Invalid */
			dprintk(DBGLVL_CMD, "%s() Invalid\n", __func__);
			ret = saa7164_bus_get(dev, presponse_t, NULL, 0);
			if (ret != SAA_OK) {
				printk(KERN_ERR "get failed\n");
				return ret;
			}

			/* See of other commands are on the bus */
			if (saa7164_cmd_dequeue(dev) != SAA_OK)
				printk(KERN_ERR "dequeue(3) failed\n");
			continue;
		}

		/* OK, now we're actually getting out correct response */
		ret = saa7164_bus_get(dev, presponse_t, buf + data_recd, 0);
		if (ret != SAA_OK) {
			printk(KERN_ERR "get failed\n");
			return ret;
		}

		data_recd = presponse_t->size + data_recd;
		if (resp_dsize == data_recd) {
			dprintk(DBGLVL_CMD, "%s() Resp recd\n", __func__);
			break;
		}

		/* See of other commands are on the bus */
		if (saa7164_cmd_dequeue(dev) != SAA_OK)
			printk(KERN_ERR "dequeue(3) failed\n");

		continue;

	} /* (loop) */

	/* Release the sequence number allocation */
	saa7164_cmd_free_seqno(dev, pcommand_t->seqno);

	/* if powerdown signal all pending commands */

	dprintk(DBGLVL_CMD, "%s() Calling dequeue then exit\n", __func__);

	/* See of other commands are on the bus */
	if (saa7164_cmd_dequeue(dev) != SAA_OK)
		printk(KERN_ERR "dequeue(4) failed\n");

	ret = SAA_OK;
out:
	return ret;
}

