/*
 *	Functions to handle I2O devices
 *
 *	Copyright (C) 2004	Markus Lidel <Markus.Lidel@shadowconnect.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.
 *
 *	Fixes/additions:
 *		Markus Lidel <Markus.Lidel@shadowconnect.com>
 *			initial version.
 */

#include <linux/module.h>
#include <linux/i2o.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/slab.h>
#include "core.h"

/**
 *	i2o_device_issue_claim - claim or release a device
 *	@dev: I2O device to claim or release
 *	@cmd: claim or release command
 *	@type: type of claim
 *
 *	Issue I2O UTIL_CLAIM or UTIL_RELEASE messages. The message to be sent
 *	is set by cmd. dev is the I2O device which should be claim or
 *	released and the type is the claim type (see the I2O spec).
 *
 *	Returs 0 on success or negative error code on failure.
 */
static inline int i2o_device_issue_claim(struct i2o_device *dev, u32 cmd,
					 u32 type)
{
	struct i2o_message __iomem *msg;
	u32 m;

	m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET);
	if (m == I2O_QUEUE_EMPTY)
		return -ETIMEDOUT;

	writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
	writel(cmd << 24 | HOST_TID << 12 | dev->lct_data.tid, &msg->u.head[1]);
	writel(type, &msg->body[0]);

	return i2o_msg_post_wait(dev->iop, m, 60);
}

/**
 *	i2o_device_claim - claim a device for use by an OSM
 *	@dev: I2O device to claim
 *	@drv: I2O driver which wants to claim the device
 *
 *	Do the leg work to assign a device to a given OSM. If the claim succeed
 *	the owner of the rimary. If the attempt fails a negative errno code
 *	is returned. On success zero is returned.
 */
int i2o_device_claim(struct i2o_device *dev)
{
	int rc = 0;

	down(&dev->lock);

	rc = i2o_device_issue_claim(dev, I2O_CMD_UTIL_CLAIM, I2O_CLAIM_PRIMARY);
	if (!rc)
		pr_debug("i2o: claim of device %d succeded\n",
			 dev->lct_data.tid);
	else
		pr_debug("i2o: claim of device %d failed %d\n",
			 dev->lct_data.tid, rc);

	up(&dev->lock);

	return rc;
}

/**
 *	i2o_device_claim_release - release a device that the OSM is using
 *	@dev: device to release
 *	@drv: driver which claimed the device
 *
 *	Drop a claim by an OSM on a given I2O device.
 *
 *	AC - some devices seem to want to refuse an unclaim until they have
 *	finished internal processing. It makes sense since you don't want a
 *	new device to go reconfiguring the entire system until you are done.
 *	Thus we are prepared to wait briefly.
 *
 *	Returns 0 on success or negative error code on failure.
 */
int i2o_device_claim_release(struct i2o_device *dev)
{
	int tries;
	int rc = 0;

	down(&dev->lock);

	/*
	 *      If the controller takes a nonblocking approach to
	 *      releases we have to sleep/poll for a few times.
	 */
	for (tries = 0; tries < 10; tries++) {
		rc = i2o_device_issue_claim(dev, I2O_CMD_UTIL_RELEASE,
					    I2O_CLAIM_PRIMARY);
		if (!rc)
			break;

		ssleep(1);
	}

	if (!rc)
		pr_debug("i2o: claim release of device %d succeded\n",
			 dev->lct_data.tid);
	else
		pr_debug("i2o: claim release of device %d failed %d\n",
			 dev->lct_data.tid, rc);

	up(&dev->lock);

	return rc;
}


/**
 *	i2o_device_release - release the memory for a I2O device
 *	@dev: I2O device which should be released
 *
 *	Release the allocated memory. This function is called if refcount of
 *	device reaches 0 automatically.
 */
static void i2o_device_release(struct device *dev)
{
	struct i2o_device *i2o_dev = to_i2o_device(dev);

	pr_debug("i2o: device %s released\n", dev->bus_id);

	kfree(i2o_dev);
}


/**
 *	i2o_device_class_show_class_id - Displays class id of I2O device
 *	@cd: class device of which the class id should be displayed
 *	@buf: buffer into which the class id should be printed
 *
 *	Returns the number of bytes which are printed into the buffer.
 */
static ssize_t i2o_device_show_class_id(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
	struct i2o_device *i2o_dev = to_i2o_device(dev);

	sprintf(buf, "0x%03x\n", i2o_dev->lct_data.class_id);
	return strlen(buf) + 1;
}

/**
 *	i2o_device_class_show_tid - Displays TID of I2O device
 *	@cd: class device of which the TID should be displayed
 *	@buf: buffer into which the class id should be printed
 *
 *	Returns the number of bytes which are printed into the buffer.
 */
static ssize_t i2o_device_show_tid(struct device *dev,
				   struct device_attribute *attr,
				   char *buf)
{
	struct i2o_device *i2o_dev = to_i2o_device(dev);

	sprintf(buf, "0x%03x\n", i2o_dev->lct_data.tid);
	return strlen(buf) + 1;
}

struct device_attribute i2o_device_attrs[] = {
	__ATTR(class_id, S_IRUGO, i2o_device_show_class_id, NULL),
	__ATTR(tid, S_IRUGO, i2o_device_show_tid, NULL),
	__ATTR_NULL
};

/**
 *	i2o_device_alloc - Allocate a I2O device and initialize it
 *
 *	Allocate the memory for a I2O device and initialize locks and lists
 *
 *	Returns the allocated I2O device or a negative error code if the device
 *	could not be allocated.
 */
static struct i2o_device *i2o_device_alloc(void)
{
	struct i2o_device *dev;

	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return ERR_PTR(-ENOMEM);

	memset(dev, 0, sizeof(*dev));

	INIT_LIST_HEAD(&dev->list);
	init_MUTEX(&dev->lock);

	dev->device.bus = &i2o_bus_type;
	dev->device.release = &i2o_device_release;

	return dev;
}

/**
 *	i2o_setup_sysfs_links - Adds attributes to the I2O device
 *	@cd: I2O class device which is added to the I2O device class
 *
 *	This function get called when a I2O device is added to the class. It
 *	creates the attributes for each device and creates user/parent symlink
 *	if necessary.
 *
 *	Returns 0 on success or negative error code on failure.
 */
static void i2o_setup_sysfs_links(struct i2o_device *i2o_dev)
{
	struct i2o_controller *c = i2o_dev->iop;
	struct i2o_device *tmp;

	/* create user entries for this device */
	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
	if (tmp && tmp != i2o_dev)
		sysfs_create_link(&i2o_dev->device.kobj,
				  &tmp->device.kobj, "user");

	/* create user entries refering to this device */
	list_for_each_entry(tmp, &c->devices, list)
		if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid &&
		    tmp != i2o_dev)
			sysfs_create_link(&tmp->device.kobj,
					  &i2o_dev->device.kobj, "user");

	/* create parent entries for this device */
	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
	if (tmp && tmp != i2o_dev)
		sysfs_create_link(&i2o_dev->device.kobj,
				  &tmp->device.kobj, "parent");

	/* create parent entries refering to this device */
	list_for_each_entry(tmp, &c->devices, list)
		if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid &&
		    tmp != i2o_dev)
		sysfs_create_link(&tmp->device.kobj,
				  &i2o_dev->device.kobj, "parent");
}

static void i2o_remove_sysfs_links(struct i2o_device *i2o_dev)
{
	struct i2o_controller *c = i2o_dev->iop;
	struct i2o_device *tmp;

	sysfs_remove_link(&i2o_dev->device.kobj, "parent");
	sysfs_remove_link(&i2o_dev->device.kobj, "user");

	list_for_each_entry(tmp, &c->devices, list) {
		if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
			sysfs_remove_link(&tmp->device.kobj, "parent");
		if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
			sysfs_remove_link(&tmp->device.kobj, "user");
	}
}



/**
 *	i2o_device_add - allocate a new I2O device and add it to the IOP
 *	@iop: I2O controller where the device is on
 *	@entry: LCT entry of the I2O device
 *
 *	Allocate a new I2O device and initialize it with the LCT entry. The
 *	device is appended to the device list of the controller.
 *
 *	Returns a pointer to the I2O device on success or negative error code
 *	on failure.
 */
static struct i2o_device *i2o_device_add(struct i2o_controller *c,
					 i2o_lct_entry * entry)
{
	struct i2o_device *dev;

	dev = i2o_device_alloc();
	if (IS_ERR(dev)) {
		printk(KERN_ERR "i2o: unable to allocate i2o device\n");
		return dev;
	}

	dev->lct_data = *entry;
	dev->iop = c;

	snprintf(dev->device.bus_id, BUS_ID_SIZE, "%d:%03x", c->unit,
		 dev->lct_data.tid);

	dev->device.parent = &c->device;

	device_register(&dev->device);

	list_add_tail(&dev->list, &c->devices);

	i2o_setup_sysfs_links(dev);

	i2o_driver_notify_device_add_all(dev);

	pr_debug("i2o: device %s added\n", dev->device.bus_id);

	return dev;
}

/**
 *	i2o_device_remove - remove an I2O device from the I2O core
 *	@dev: I2O device which should be released
 *
 *	Is used on I2O controller removal or LCT modification, when the device
 *	is removed from the system. Note that the device could still hang
 *	around until the refcount reaches 0.
 */
void i2o_device_remove(struct i2o_device *i2o_dev)
{
	i2o_driver_notify_device_remove_all(i2o_dev);
	i2o_remove_sysfs_links(i2o_dev);
	list_del(&i2o_dev->list);
	device_unregister(&i2o_dev->device);
}

/**
 *	i2o_device_parse_lct - Parse a previously fetched LCT and create devices
 *	@c: I2O controller from which the LCT should be parsed.
 *
 *	The Logical Configuration Table tells us what we can talk to on the
 *	board. For every entry we create an I2O device, which is registered in
 *	the I2O core.
 *
 *	Returns 0 on success or negative error code on failure.
 */
int i2o_device_parse_lct(struct i2o_controller *c)
{
	struct i2o_device *dev, *tmp;
	i2o_lct *lct;
	int i;
	int max;

	down(&c->lct_lock);

	kfree(c->lct);

	lct = c->dlct.virt;

	c->lct = kmalloc(lct->table_size * 4, GFP_KERNEL);
	if (!c->lct) {
		up(&c->lct_lock);
		return -ENOMEM;
	}

	if (lct->table_size * 4 > c->dlct.len) {
		memcpy(c->lct, c->dlct.virt, c->dlct.len);
		up(&c->lct_lock);
		return -EAGAIN;
	}

	memcpy(c->lct, c->dlct.virt, lct->table_size * 4);

	lct = c->lct;

	max = (lct->table_size - 3) / 9;

	pr_debug("%s: LCT has %d entries (LCT size: %d)\n", c->name, max,
		 lct->table_size);

	/* remove devices, which are not in the LCT anymore */
	list_for_each_entry_safe(dev, tmp, &c->devices, list) {
		int found = 0;

		for (i = 0; i < max; i++) {
			if (lct->lct_entry[i].tid == dev->lct_data.tid) {
				found = 1;
				break;
			}
		}

		if (!found)
			i2o_device_remove(dev);
	}

	/* add new devices, which are new in the LCT */
	for (i = 0; i < max; i++) {
		int found = 0;

		list_for_each_entry_safe(dev, tmp, &c->devices, list) {
			if (lct->lct_entry[i].tid == dev->lct_data.tid) {
				found = 1;
				break;
			}
		}

		if (!found)
			i2o_device_add(c, &lct->lct_entry[i]);
	}
	up(&c->lct_lock);

	return 0;
}


/*
 *	Run time support routines
 */

/*	Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET
 *
 *	This function can be used for all UtilParamsGet/Set operations.
 *	The OperationList is given in oplist-buffer,
 *	and results are returned in reslist-buffer.
 *	Note that the minimum sized reslist is 8 bytes and contains
 *	ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
 */
int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
			  int oplen, void *reslist, int reslen)
{
	struct i2o_message __iomem *msg;
	u32 m;
	u32 *res32 = (u32 *) reslist;
	u32 *restmp = (u32 *) reslist;
	int len = 0;
	int i = 0;
	int rc;
	struct i2o_dma res;
	struct i2o_controller *c = i2o_dev->iop;
	struct device *dev = &c->pdev->dev;

	res.virt = NULL;

	if (i2o_dma_alloc(dev, &res, reslen, GFP_KERNEL))
		return -ENOMEM;

	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
	if (m == I2O_QUEUE_EMPTY) {
		i2o_dma_free(dev, &res);
		return -ETIMEDOUT;
	}

	i = 0;
	writel(cmd << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid,
	       &msg->u.head[1]);
	writel(0, &msg->body[i++]);
	writel(0x4C000000 | oplen, &msg->body[i++]);	/* OperationList */
	memcpy_toio(&msg->body[i], oplist, oplen);
	i += (oplen / 4 + (oplen % 4 ? 1 : 0));
	writel(0xD0000000 | res.len, &msg->body[i++]);	/* ResultList */
	writel(res.phys, &msg->body[i++]);

	writel(I2O_MESSAGE_SIZE(i + sizeof(struct i2o_message) / 4) |
	       SGL_OFFSET_5, &msg->u.head[0]);

	rc = i2o_msg_post_wait_mem(c, m, 10, &res);

	/* This only looks like a memory leak - don't "fix" it. */
	if (rc == -ETIMEDOUT)
		return rc;

	memcpy(reslist, res.virt, res.len);
	i2o_dma_free(dev, &res);

	/* Query failed */
	if (rc)
		return rc;
	/*
	 * Calculate number of bytes of Result LIST
	 * We need to loop through each Result BLOCK and grab the length
	 */
	restmp = res32 + 1;
	len = 1;
	for (i = 0; i < (res32[0] & 0X0000FFFF); i++) {
		if (restmp[0] & 0x00FF0000) {	/* BlockStatus != SUCCESS */
			printk(KERN_WARNING
			       "%s - Error:\n  ErrorInfoSize = 0x%02x, "
			       "BlockStatus = 0x%02x, BlockSize = 0x%04x\n",
			       (cmd ==
				I2O_CMD_UTIL_PARAMS_SET) ? "PARAMS_SET" :
			       "PARAMS_GET", res32[1] >> 24,
			       (res32[1] >> 16) & 0xFF, res32[1] & 0xFFFF);

			/*
			 *      If this is the only request,than we return an error
			 */
			if ((res32[0] & 0x0000FFFF) == 1) {
				return -((res32[1] >> 16) & 0xFF);	/* -BlockStatus */
			}
		}
		len += restmp[0] & 0x0000FFFF;	/* Length of res BLOCK */
		restmp += restmp[0] & 0x0000FFFF;	/* Skip to next BLOCK */
	}
	return (len << 2);	/* bytes used by result list */
}

/*
 *	 Query one field group value or a whole scalar group.
 */
int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field,
		       void *buf, int buflen)
{
	u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
	u8 *resblk;		/* 8 bytes for header */
	int size;

	if (field == -1)	/* whole group */
		opblk[4] = -1;

	resblk = kmalloc(buflen + 8, GFP_KERNEL | GFP_ATOMIC);
	if (!resblk)
		return -ENOMEM;

	size = i2o_parm_issue(i2o_dev, I2O_CMD_UTIL_PARAMS_GET, opblk,
			      sizeof(opblk), resblk, buflen + 8);

	memcpy(buf, resblk + 8, buflen);	/* cut off header */

	kfree(resblk);

	if (size > buflen)
		return buflen;

	return size;
}

/*
 *	if oper == I2O_PARAMS_TABLE_GET, get from all rows
 *		if fieldcount == -1 return all fields
 *			ibuf and ibuflen are unused (use NULL, 0)
 *		else return specific fields
 *			ibuf contains fieldindexes
 *
 * 	if oper == I2O_PARAMS_LIST_GET, get from specific rows
 * 		if fieldcount == -1 return all fields
 *			ibuf contains rowcount, keyvalues
 * 		else return specific fields
 *			fieldcount is # of fieldindexes
 *  			ibuf contains fieldindexes, rowcount, keyvalues
 *
 *	You could also use directly function i2o_issue_params().
 */
int i2o_parm_table_get(struct i2o_device *dev, int oper, int group,
		       int fieldcount, void *ibuf, int ibuflen, void *resblk,
		       int reslen)
{
	u16 *opblk;
	int size;

	size = 10 + ibuflen;
	if (size % 4)
		size += 4 - size % 4;

	opblk = kmalloc(size, GFP_KERNEL);
	if (opblk == NULL) {
		printk(KERN_ERR "i2o: no memory for query buffer.\n");
		return -ENOMEM;
	}

	opblk[0] = 1;		/* operation count */
	opblk[1] = 0;		/* pad */
	opblk[2] = oper;
	opblk[3] = group;
	opblk[4] = fieldcount;
	memcpy(opblk + 5, ibuf, ibuflen);	/* other params */

	size = i2o_parm_issue(dev, I2O_CMD_UTIL_PARAMS_GET, opblk,
			      size, resblk, reslen);

	kfree(opblk);
	if (size > reslen)
		return reslen;

	return size;
}

EXPORT_SYMBOL(i2o_device_claim);
EXPORT_SYMBOL(i2o_device_claim_release);
EXPORT_SYMBOL(i2o_parm_field_get);
EXPORT_SYMBOL(i2o_parm_table_get);
EXPORT_SYMBOL(i2o_parm_issue);
