/*
 * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
 * Copyright (c) 2006 PathScale, Inc. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <linux/version.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/mount.h>
#include <linux/pagemap.h>
#include <linux/init.h>
#include <linux/namei.h>

#include "ipath_kernel.h"

#define IPATHFS_MAGIC 0x726a77

static struct super_block *ipath_super;

static int ipathfs_mknod(struct inode *dir, struct dentry *dentry,
			 int mode, const struct file_operations *fops,
			 void *data)
{
	int error;
	struct inode *inode = new_inode(dir->i_sb);

	if (!inode) {
		error = -EPERM;
		goto bail;
	}

	inode->i_mode = mode;
	inode->i_uid = 0;
	inode->i_gid = 0;
	inode->i_blocks = 0;
	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
	inode->i_private = data;
	if ((mode & S_IFMT) == S_IFDIR) {
		inode->i_op = &simple_dir_inode_operations;
		inc_nlink(inode);
		inc_nlink(dir);
	}

	inode->i_fop = fops;

	d_instantiate(dentry, inode);
	error = 0;

bail:
	return error;
}

static int create_file(const char *name, mode_t mode,
		       struct dentry *parent, struct dentry **dentry,
		       const struct file_operations *fops, void *data)
{
	int error;

	*dentry = NULL;
	mutex_lock(&parent->d_inode->i_mutex);
	*dentry = lookup_one_len(name, parent, strlen(name));
	if (!IS_ERR(dentry))
		error = ipathfs_mknod(parent->d_inode, *dentry,
				      mode, fops, data);
	else
		error = PTR_ERR(dentry);
	mutex_unlock(&parent->d_inode->i_mutex);

	return error;
}

static ssize_t atomic_stats_read(struct file *file, char __user *buf,
				 size_t count, loff_t *ppos)
{
	return simple_read_from_buffer(buf, count, ppos, &ipath_stats,
				       sizeof ipath_stats);
}

static const struct file_operations atomic_stats_ops = {
	.read = atomic_stats_read,
};

#define NUM_COUNTERS sizeof(struct infinipath_counters) / sizeof(u64)

static ssize_t atomic_counters_read(struct file *file, char __user *buf,
				    size_t count, loff_t *ppos)
{
	u64 counters[NUM_COUNTERS];
	u16 i;
	struct ipath_devdata *dd;

	dd = file->f_path.dentry->d_inode->i_private;

	for (i = 0; i < NUM_COUNTERS; i++)
		counters[i] = ipath_snap_cntr(dd, i);

	return simple_read_from_buffer(buf, count, ppos, counters,
				       sizeof counters);
}

static const struct file_operations atomic_counters_ops = {
	.read = atomic_counters_read,
};

static ssize_t atomic_node_info_read(struct file *file, char __user *buf,
				     size_t count, loff_t *ppos)
{
	u32 nodeinfo[10];
	struct ipath_devdata *dd;
	u64 guid;

	dd = file->f_path.dentry->d_inode->i_private;

	guid = be64_to_cpu(dd->ipath_guid);

	nodeinfo[0] =			/* BaseVersion is SMA */
		/* ClassVersion is SMA */
		(1 << 8)		/* NodeType  */
		| (1 << 0);		/* NumPorts */
	nodeinfo[1] = (u32) (guid >> 32);
	nodeinfo[2] = (u32) (guid & 0xffffffff);
	/* PortGUID == SystemImageGUID for us */
	nodeinfo[3] = nodeinfo[1];
	/* PortGUID == SystemImageGUID for us */
	nodeinfo[4] = nodeinfo[2];
	/* PortGUID == NodeGUID for us */
	nodeinfo[5] = nodeinfo[3];
	/* PortGUID == NodeGUID for us */
	nodeinfo[6] = nodeinfo[4];
	nodeinfo[7] = (4 << 16) /* we support 4 pkeys */
		| (dd->ipath_deviceid << 0);
	/* our chip version as 16 bits major, 16 bits minor */
	nodeinfo[8] = dd->ipath_minrev | (dd->ipath_majrev << 16);
	nodeinfo[9] = (dd->ipath_unit << 24) | (dd->ipath_vendorid << 0);

	return simple_read_from_buffer(buf, count, ppos, nodeinfo,
				       sizeof nodeinfo);
}

static const struct file_operations atomic_node_info_ops = {
	.read = atomic_node_info_read,
};

static ssize_t atomic_port_info_read(struct file *file, char __user *buf,
				     size_t count, loff_t *ppos)
{
	u32 portinfo[13];
	u32 tmp, tmp2;
	struct ipath_devdata *dd;

	dd = file->f_path.dentry->d_inode->i_private;

	/* so we only initialize non-zero fields. */
	memset(portinfo, 0, sizeof portinfo);

	/*
	 * Notimpl yet M_Key (64)
	 * Notimpl yet GID (64)
	 */

	portinfo[4] = (dd->ipath_lid << 16);

	/*
	 * Notimpl yet SMLID.
	 * CapabilityMask is 0, we don't support any of these
	 * DiagCode is 0; we don't store any diag info for now Notimpl yet
	 * M_KeyLeasePeriod (we don't support M_Key)
	 */

	/* LocalPortNum is whichever port number they ask for */
	portinfo[7] = (dd->ipath_unit << 24)
		/* LinkWidthEnabled */
		| (2 << 16)
		/* LinkWidthSupported (really 2, but not IB valid) */
		| (3 << 8)
		/* LinkWidthActive */
		| (2 << 0);
	tmp = dd->ipath_lastibcstat & IPATH_IBSTATE_MASK;
	tmp2 = 5;
	if (tmp == IPATH_IBSTATE_INIT)
		tmp = 2;
	else if (tmp == IPATH_IBSTATE_ARM)
		tmp = 3;
	else if (tmp == IPATH_IBSTATE_ACTIVE)
		tmp = 4;
	else {
		tmp = 0;	/* down */
		tmp2 = tmp & 0xf;
	}

	portinfo[8] = (1 << 28)	/* LinkSpeedSupported */
		| (tmp << 24)	/* PortState */
		| (tmp2 << 20)	/* PortPhysicalState */
		| (2 << 16)

		/* LinkDownDefaultState */
		/* M_KeyProtectBits == 0 */
		/* NotImpl yet LMC == 0 (we can support all values) */
		| (1 << 4)	/* LinkSpeedActive */
		| (1 << 0);	/* LinkSpeedEnabled */
	switch (dd->ipath_ibmtu) {
	case 4096:
		tmp = 5;
		break;
	case 2048:
		tmp = 4;
		break;
	case 1024:
		tmp = 3;
		break;
	case 512:
		tmp = 2;
		break;
	case 256:
		tmp = 1;
		break;
	default:		/* oops, something is wrong */
		ipath_dbg("Problem, ipath_ibmtu 0x%x not a valid IB MTU, "
			  "treat as 2048\n", dd->ipath_ibmtu);
		tmp = 4;
		break;
	}
	portinfo[9] = (tmp << 28)
		/* NeighborMTU */
		/* Notimpl MasterSMSL */
		| (1 << 20)

		/* VLCap */
		/* Notimpl InitType (actually, an SMA decision) */
		/* VLHighLimit is 0 (only one VL) */
		; /* VLArbitrationHighCap is 0 (only one VL) */
	/*
	 * Note: the chips support a maximum MTU of 4096, but the driver
	 * hasn't implemented this feature yet, so set the maximum
	 * to 2048.
	 */
	portinfo[10] = 	/* VLArbitrationLowCap is 0 (only one VL) */
		/* InitTypeReply is SMA decision */
		(4 << 16)	/* MTUCap 2048 */
		| (7 << 13)	/* VLStallCount */
		| (0x1f << 8)	/* HOQLife */
		| (1 << 4)

		/* OperationalVLs 0 */
		/* PartitionEnforcementInbound */
		/* PartitionEnforcementOutbound not enforced */
		/* FilterRawinbound not enforced */
		;		/* FilterRawOutbound not enforced */
	/* M_KeyViolations are not counted by hardware, SMA can count */
	tmp = ipath_read_creg32(dd, dd->ipath_cregs->cr_errpkey);
	/* P_KeyViolations are counted by hardware. */
	portinfo[11] = ((tmp & 0xffff) << 0);
	portinfo[12] =
		/* Q_KeyViolations are not counted by hardware */
		(1 << 8)

		/* GUIDCap */
		/* SubnetTimeOut handled by SMA */
		/* RespTimeValue handled by SMA */
		;
	/* LocalPhyErrors are programmed to max */
	portinfo[12] |= (0xf << 20)
		| (0xf << 16)   /* OverRunErrors are programmed to max */
		;

	return simple_read_from_buffer(buf, count, ppos, portinfo,
				       sizeof portinfo);
}

static const struct file_operations atomic_port_info_ops = {
	.read = atomic_port_info_read,
};

static ssize_t flash_read(struct file *file, char __user *buf,
			  size_t count, loff_t *ppos)
{
	struct ipath_devdata *dd;
	ssize_t ret;
	loff_t pos;
	char *tmp;

	pos = *ppos;

	if ( pos < 0) {
		ret = -EINVAL;
		goto bail;
	}

	if (pos >= sizeof(struct ipath_flash)) {
		ret = 0;
		goto bail;
	}

	if (count > sizeof(struct ipath_flash) - pos)
		count = sizeof(struct ipath_flash) - pos;

	tmp = kmalloc(count, GFP_KERNEL);
	if (!tmp) {
		ret = -ENOMEM;
		goto bail;
	}

	dd = file->f_path.dentry->d_inode->i_private;
	if (ipath_eeprom_read(dd, pos, tmp, count)) {
		ipath_dev_err(dd, "failed to read from flash\n");
		ret = -ENXIO;
		goto bail_tmp;
	}

	if (copy_to_user(buf, tmp, count)) {
		ret = -EFAULT;
		goto bail_tmp;
	}

	*ppos = pos + count;
	ret = count;

bail_tmp:
	kfree(tmp);

bail:
	return ret;
}

static ssize_t flash_write(struct file *file, const char __user *buf,
			   size_t count, loff_t *ppos)
{
	struct ipath_devdata *dd;
	ssize_t ret;
	loff_t pos;
	char *tmp;

	pos = *ppos;

	if (pos != 0) {
		ret = -EINVAL;
		goto bail;
	}

	if (count != sizeof(struct ipath_flash)) {
		ret = -EINVAL;
		goto bail;
	}

	tmp = kmalloc(count, GFP_KERNEL);
	if (!tmp) {
		ret = -ENOMEM;
		goto bail;
	}

	if (copy_from_user(tmp, buf, count)) {
		ret = -EFAULT;
		goto bail_tmp;
	}

	dd = file->f_path.dentry->d_inode->i_private;
	if (ipath_eeprom_write(dd, pos, tmp, count)) {
		ret = -ENXIO;
		ipath_dev_err(dd, "failed to write to flash\n");
		goto bail_tmp;
	}

	*ppos = pos + count;
	ret = count;

bail_tmp:
	kfree(tmp);

bail:
	return ret;
}

static const struct file_operations flash_ops = {
	.read = flash_read,
	.write = flash_write,
};

static int create_device_files(struct super_block *sb,
			       struct ipath_devdata *dd)
{
	struct dentry *dir, *tmp;
	char unit[10];
	int ret;

	snprintf(unit, sizeof unit, "%02d", dd->ipath_unit);
	ret = create_file(unit, S_IFDIR|S_IRUGO|S_IXUGO, sb->s_root, &dir,
			  (struct file_operations *) &simple_dir_operations,
			  dd);
	if (ret) {
		printk(KERN_ERR "create_file(%s) failed: %d\n", unit, ret);
		goto bail;
	}

	ret = create_file("atomic_counters", S_IFREG|S_IRUGO, dir, &tmp,
			  &atomic_counters_ops, dd);
	if (ret) {
		printk(KERN_ERR "create_file(%s/atomic_counters) "
		       "failed: %d\n", unit, ret);
		goto bail;
	}

	ret = create_file("node_info", S_IFREG|S_IRUGO, dir, &tmp,
			  &atomic_node_info_ops, dd);
	if (ret) {
		printk(KERN_ERR "create_file(%s/node_info) "
		       "failed: %d\n", unit, ret);
		goto bail;
	}

	ret = create_file("port_info", S_IFREG|S_IRUGO, dir, &tmp,
			  &atomic_port_info_ops, dd);
	if (ret) {
		printk(KERN_ERR "create_file(%s/port_info) "
		       "failed: %d\n", unit, ret);
		goto bail;
	}

	ret = create_file("flash", S_IFREG|S_IWUSR|S_IRUGO, dir, &tmp,
			  &flash_ops, dd);
	if (ret) {
		printk(KERN_ERR "create_file(%s/flash) "
		       "failed: %d\n", unit, ret);
		goto bail;
	}

bail:
	return ret;
}

static int remove_file(struct dentry *parent, char *name)
{
	struct dentry *tmp;
	int ret;

	tmp = lookup_one_len(name, parent, strlen(name));

	if (IS_ERR(tmp)) {
		ret = PTR_ERR(tmp);
		goto bail;
	}

	spin_lock(&dcache_lock);
	spin_lock(&tmp->d_lock);
	if (!(d_unhashed(tmp) && tmp->d_inode)) {
		dget_locked(tmp);
		__d_drop(tmp);
		spin_unlock(&tmp->d_lock);
		spin_unlock(&dcache_lock);
		simple_unlink(parent->d_inode, tmp);
	} else {
		spin_unlock(&tmp->d_lock);
		spin_unlock(&dcache_lock);
	}

	ret = 0;
bail:
	/*
	 * We don't expect clients to care about the return value, but
	 * it's there if they need it.
	 */
	return ret;
}

static int remove_device_files(struct super_block *sb,
			       struct ipath_devdata *dd)
{
	struct dentry *dir, *root;
	char unit[10];
	int ret;

	root = dget(sb->s_root);
	mutex_lock(&root->d_inode->i_mutex);
	snprintf(unit, sizeof unit, "%02d", dd->ipath_unit);
	dir = lookup_one_len(unit, root, strlen(unit));

	if (IS_ERR(dir)) {
		ret = PTR_ERR(dir);
		printk(KERN_ERR "Lookup of %s failed\n", unit);
		goto bail;
	}

	remove_file(dir, "flash");
	remove_file(dir, "port_info");
	remove_file(dir, "node_info");
	remove_file(dir, "atomic_counters");
	d_delete(dir);
	ret = simple_rmdir(root->d_inode, dir);

bail:
	mutex_unlock(&root->d_inode->i_mutex);
	dput(root);
	return ret;
}

static int ipathfs_fill_super(struct super_block *sb, void *data,
			      int silent)
{
	struct ipath_devdata *dd, *tmp;
	unsigned long flags;
	int ret;

	static struct tree_descr files[] = {
		[2] = {"atomic_stats", &atomic_stats_ops, S_IRUGO},
		{""},
	};

	ret = simple_fill_super(sb, IPATHFS_MAGIC, files);
	if (ret) {
		printk(KERN_ERR "simple_fill_super failed: %d\n", ret);
		goto bail;
	}

	spin_lock_irqsave(&ipath_devs_lock, flags);

	list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) {
		spin_unlock_irqrestore(&ipath_devs_lock, flags);
		ret = create_device_files(sb, dd);
		if (ret) {
			deactivate_super(sb);
			goto bail;
		}
		spin_lock_irqsave(&ipath_devs_lock, flags);
	}

	spin_unlock_irqrestore(&ipath_devs_lock, flags);

bail:
	return ret;
}

static int ipathfs_get_sb(struct file_system_type *fs_type, int flags,
			const char *dev_name, void *data, struct vfsmount *mnt)
{
	int ret = get_sb_single(fs_type, flags, data,
				    ipathfs_fill_super, mnt);
	if (ret >= 0)
		ipath_super = mnt->mnt_sb;
	return ret;
}

static void ipathfs_kill_super(struct super_block *s)
{
	kill_litter_super(s);
	ipath_super = NULL;
}

int ipathfs_add_device(struct ipath_devdata *dd)
{
	int ret;

	if (ipath_super == NULL) {
		ret = 0;
		goto bail;
	}

	ret = create_device_files(ipath_super, dd);

bail:
	return ret;
}

int ipathfs_remove_device(struct ipath_devdata *dd)
{
	int ret;

	if (ipath_super == NULL) {
		ret = 0;
		goto bail;
	}

	ret = remove_device_files(ipath_super, dd);

bail:
	return ret;
}

static struct file_system_type ipathfs_fs_type = {
	.owner =	THIS_MODULE,
	.name =		"ipathfs",
	.get_sb =	ipathfs_get_sb,
	.kill_sb =	ipathfs_kill_super,
};

int __init ipath_init_ipathfs(void)
{
	return register_filesystem(&ipathfs_fs_type);
}

void __exit ipath_exit_ipathfs(void)
{
	unregister_filesystem(&ipathfs_fs_type);
}
