/*
 *  Driver for the NXP SAA7164 PCIe bridge
 *
 *  Copyright (c) 2009 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"

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;
}

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);
}

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);
}

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;
	u32 timeout;
	wait_queue_head_t *q = 0;
	dprintk(DBGLVL_CMD, "%s()\n", __func__);

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

		/* Peek the msg bus */
		tmComResInfo_t 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__);
		}
	} while (0);

	return ret;
}

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

	while (loop) {

		tmComResInfo_t 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;
}

int saa7164_cmd_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
{
	tmComResBusInfo_t *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 occured, or SAA_OK if it was signaled during the wait.
 */
int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
{
	wait_queue_head_t *q = 0;
	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, tmComResCmd_t command,
	u16 controlselector, u16 size, void *buf)
{
	tmComResInfo_t command_t, *pcommand_t;
	tmComResInfo_t 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 == 0)) {
		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, 0, 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;
}

