/*
 * 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) 2007, 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 "selftest.h"

enum {
	LST_INIT_NONE		= 0,
	LST_INIT_WI_SERIAL,
	LST_INIT_WI_TEST,
	LST_INIT_RPC,
	LST_INIT_FW,
	LST_INIT_CONSOLE
};

extern int lstcon_console_init(void);
extern int lstcon_console_fini(void);

static int lst_init_step = LST_INIT_NONE;

struct cfs_wi_sched *lst_sched_serial;
struct cfs_wi_sched **lst_sched_test;

void
lnet_selftest_fini(void)
{
	int	i;

	switch (lst_init_step) {
		case LST_INIT_CONSOLE:
			lstcon_console_fini();
		case LST_INIT_FW:
			sfw_shutdown();
		case LST_INIT_RPC:
			srpc_shutdown();
		case LST_INIT_WI_TEST:
			for (i = 0;
			     i < cfs_cpt_number(lnet_cpt_table()); i++) {
				if (lst_sched_test[i] == NULL)
					continue;
				cfs_wi_sched_destroy(lst_sched_test[i]);
			}
			LIBCFS_FREE(lst_sched_test,
				    sizeof(lst_sched_test[0]) *
				    cfs_cpt_number(lnet_cpt_table()));
			lst_sched_test = NULL;

		case LST_INIT_WI_SERIAL:
			cfs_wi_sched_destroy(lst_sched_serial);
			lst_sched_serial = NULL;
		case LST_INIT_NONE:
			break;
		default:
			LBUG();
	}
	return;
}

void
lnet_selftest_structure_assertion(void)
{
	CLASSERT(sizeof(srpc_msg_t) == 160);
	CLASSERT(sizeof(srpc_test_reqst_t) == 70);
	CLASSERT(offsetof(srpc_msg_t, msg_body.tes_reqst.tsr_concur) == 72);
	CLASSERT(offsetof(srpc_msg_t, msg_body.tes_reqst.tsr_ndest) == 78);
	CLASSERT(sizeof(srpc_stat_reply_t) == 136);
	CLASSERT(sizeof(srpc_stat_reqst_t) == 28);
}

int
lnet_selftest_init(void)
{
	int	nscheds;
	int	rc;
	int	i;

	rc = cfs_wi_sched_create("lst_s", lnet_cpt_table(), CFS_CPT_ANY,
				 1, &lst_sched_serial);
	if (rc != 0) {
		CERROR("Failed to create serial WI scheduler for LST\n");
		return rc;
	}
	lst_init_step = LST_INIT_WI_SERIAL;

	nscheds = cfs_cpt_number(lnet_cpt_table());
	LIBCFS_ALLOC(lst_sched_test, sizeof(lst_sched_test[0]) * nscheds);
	if (lst_sched_test == NULL)
		goto error;

	lst_init_step = LST_INIT_WI_TEST;
	for (i = 0; i < nscheds; i++) {
		int nthrs = cfs_cpt_weight(lnet_cpt_table(), i);

		/* reserve at least one CPU for LND */
		nthrs = max(nthrs - 1, 1);
		rc = cfs_wi_sched_create("lst_t", lnet_cpt_table(), i,
					 nthrs, &lst_sched_test[i]);
		if (rc != 0) {
			CERROR("Failed to create CPT affinity WI scheduler "
			       "%d for LST\n", i);
			goto error;
		}
	}

	rc = srpc_startup();
	if (rc != 0) {
		CERROR("LST can't startup rpc\n");
		goto error;
	}
	lst_init_step = LST_INIT_RPC;

	rc = sfw_startup();
	if (rc != 0) {
		CERROR("LST can't startup framework\n");
		goto error;
	}
	lst_init_step = LST_INIT_FW;

	rc = lstcon_console_init();
	if (rc != 0) {
		CERROR("LST can't startup console\n");
		goto error;
	}
	lst_init_step = LST_INIT_CONSOLE;
	return 0;
error:
	lnet_selftest_fini();
	return rc;
}


MODULE_DESCRIPTION("LNet Selftest");
MODULE_LICENSE("GPL");
MODULE_VERSION("0.9.0");

module_init(lnet_selftest_init);
module_exit(lnet_selftest_fini);
