/*
 * Copyright (c) 2006 QLogic, Inc. 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) */
	portinfo[10] = 	/* VLArbitrationLowCap is 0 (only one VL) */
		/* InitTypeReply is SMA decision */
		(5 << 16)	/* MTUCap 4096 */
		| (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);
}
