/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * 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 version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see
 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 */

#define DEBUG_SUBSYSTEM S_LNET
#include "../../include/linux/lnet/lib-lnet.h"

static int config_on_load;
module_param(config_on_load, int, 0444);
MODULE_PARM_DESC(config_on_load, "configure network at module load");

static struct mutex lnet_config_mutex;

static int
lnet_configure(void *arg)
{
	/* 'arg' only there so I can be passed to cfs_create_thread() */
	int rc = 0;

	mutex_lock(&lnet_config_mutex);

	if (!the_lnet.ln_niinit_self) {
		rc = LNetNIInit(LUSTRE_SRV_LNET_PID);
		if (rc >= 0) {
			the_lnet.ln_niinit_self = 1;
			rc = 0;
		}
	}

	mutex_unlock(&lnet_config_mutex);
	return rc;
}

static int
lnet_unconfigure(void)
{
	int refcount;

	mutex_lock(&lnet_config_mutex);

	if (the_lnet.ln_niinit_self) {
		the_lnet.ln_niinit_self = 0;
		LNetNIFini();
	}

	mutex_lock(&the_lnet.ln_api_mutex);
	refcount = the_lnet.ln_refcount;
	mutex_unlock(&the_lnet.ln_api_mutex);

	mutex_unlock(&lnet_config_mutex);
	return (refcount == 0) ? 0 : -EBUSY;
}

static int
lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_data *data)
{
	int rc;

	switch (cmd) {
	case IOC_LIBCFS_CONFIGURE:
		return lnet_configure(NULL);

	case IOC_LIBCFS_UNCONFIGURE:
		return lnet_unconfigure();

	default:
		/* Passing LNET_PID_ANY only gives me a ref if the net is up
		 * already; I'll need it to ensure the net can't go down while
		 * I'm called into it */
		rc = LNetNIInit(LNET_PID_ANY);
		if (rc >= 0) {
			rc = LNetCtl(cmd, data);
			LNetNIFini();
		}
		return rc;
	}
}

static DECLARE_IOCTL_HANDLER(lnet_ioctl_handler, lnet_ioctl);

static int __init
init_lnet(void)
{
	int rc;

	mutex_init(&lnet_config_mutex);

	rc = lnet_init();
	if (rc != 0) {
		CERROR("lnet_init: error %d\n", rc);
		return rc;
	}

	rc = libcfs_register_ioctl(&lnet_ioctl_handler);
	LASSERT(rc == 0);

	if (config_on_load) {
		/* Have to schedule a separate thread to avoid deadlocking
		 * in modload */
		(void) kthread_run(lnet_configure, NULL, "lnet_initd");
	}

	return 0;
}

static void __exit
fini_lnet(void)
{
	int rc;

	rc = libcfs_deregister_ioctl(&lnet_ioctl_handler);
	LASSERT(rc == 0);

	lnet_fini();
}

MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
MODULE_DESCRIPTION("LNet v3.1");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0.0");

module_init(init_lnet);
module_exit(fini_lnet);
