/*
 *  scst_main.c
 *
 *  Copyright (C) 2004 - 2018 Vladislav Bolkhovitin <vst@vlnb.net>
 *  Copyright (C) 2004 - 2005 Leonid Stoljar
 *  Copyright (C) 2007 - 2018 Western Digital Corporation
 *
 *  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, version 2
 *  of the License.
 *
 *  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 for more details.
 */

#include <linux/module.h>

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/unistd.h>
#include <linux/string.h>
#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/lockdep.h>

#ifdef INSIDE_KERNEL_TREE
#include <scst/scst.h>
#else
#include "scst.h"
#endif
#include "scst_priv.h"
#include "scst_mem.h"
#include "scst_pres.h"

#if defined(CONFIG_HIGHMEM4G) || defined(CONFIG_HIGHMEM64G)
#warning HIGHMEM kernel configurations are fully supported, but not \
recommended for performance reasons. Consider changing VMSPLIT \
option or use a 64-bit configuration instead. See README file for \
details.
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30) && \
	!defined(CONFIG_SCST_STRICT_SERIALIZING)
#warning CONFIG_SCST_STRICT_SERIALIZING has not been defined. \
Pass-through dev handlers will not work.
#endif

/*
 ** SCST global variables. They are all uninitialized to have their layout in
 ** memory be exactly as specified. Otherwise compiler puts zero-initialized
 ** variable separately from nonzero-initialized ones.
 **/

/*
 * Main SCST mutex. All targets, devices and dev_types management is done
 * under this mutex.
 */
struct mutex scst_mutex;
EXPORT_SYMBOL_GPL(scst_mutex);

/*
 * Second level main mutex, inner to scst_mutex and dev_pr_mutex. Needed for
 * __scst_pr_register_all_tg_pt(), since we can't use scst_mutex there,
 * because its caller already holds dev_pr_mutex, hence circular locking
 * dependency is possible.
 */
struct mutex scst_mutex2;

/* Both protected by scst_mutex or scst_mutex2 on read and both on write */
struct list_head scst_template_list;
struct list_head scst_dev_list;

/* Protected by scst_mutex */
struct list_head scst_dev_type_list;
struct list_head scst_virtual_dev_type_list;

static struct kmem_cache *scst_mgmt_cachep;
mempool_t *scst_mgmt_mempool;
static struct kmem_cache *scst_mgmt_stub_cachep;
mempool_t *scst_mgmt_stub_mempool;
static struct kmem_cache *scst_ua_cachep;
mempool_t *scst_ua_mempool;
static struct kmem_cache *scst_sense_cachep;
mempool_t *scst_sense_mempool;
static struct kmem_cache *scst_aen_cachep;
mempool_t *scst_aen_mempool;
struct kmem_cache *scst_tgt_cachep;
struct kmem_cache *scst_dev_cachep;
struct kmem_cache *scst_tgtd_cachep;
struct kmem_cache *scst_sess_cachep;
struct kmem_cache *scst_acgd_cachep;
static struct kmem_cache *scst_thr_cachep;

unsigned int scst_setup_id;

spinlock_t scst_init_lock;
wait_queue_head_t scst_init_cmd_list_waitQ;
struct list_head scst_init_cmd_list;
unsigned int scst_init_poll_cnt;

struct kmem_cache *scst_cmd_cachep;

#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
unsigned long scst_trace_flag;
#endif

unsigned long scst_flags;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
unsigned long scst_poll_ns = SCST_DEF_POLL_NS;
#endif

int scst_max_tasklet_cmd = SCST_DEF_MAX_TASKLET_CMD;

struct scst_cmd_threads scst_main_cmd_threads;

struct scst_percpu_info scst_percpu_infos[NR_CPUS];

spinlock_t scst_mcmd_lock;
struct list_head scst_active_mgmt_cmd_list;
struct list_head scst_delayed_mgmt_cmd_list;
wait_queue_head_t scst_mgmt_cmd_list_waitQ;

wait_queue_head_t scst_mgmt_waitQ;
spinlock_t scst_mgmt_lock;
struct list_head scst_sess_init_list;
struct list_head scst_sess_shut_list;

wait_queue_head_t scst_dev_cmd_waitQ;

static struct mutex scst_cmd_threads_mutex;
/* protected by scst_cmd_threads_mutex */
static struct list_head scst_cmd_threads_list;

int scst_threads;
static struct task_struct *scst_init_cmd_thread;
static struct task_struct *scst_mgmt_thread;
static struct task_struct *scst_mgmt_cmd_thread;

/*
 * Protects global suspending and resuming from being initiated from
 * several threads simultaneously.
 */
static struct mutex scst_suspend_mutex;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
#ifdef CONFIG_LOCKDEP
static struct lock_class_key scst_suspend_key;
struct lockdep_map scst_suspend_dep_map =
	STATIC_LOCKDEP_MAP_INIT("scst_suspend_activity", &scst_suspend_key);
#endif
#endif

/* Protected by scst_suspend_mutex */
static int suspend_count;

static int scst_virt_dev_last_id; /* protected by scst_mutex */

cpumask_t default_cpu_mask;

static unsigned int scst_max_cmd_mem;
unsigned int scst_max_dev_cmd_mem;
int scst_forcibly_close_sessions;
int scst_auto_cm_assignment = false;

spinlock_t scst_measure_latency_lock;
atomic_t scst_measure_latency;

module_param_named(scst_threads, scst_threads, int, S_IRUGO);
MODULE_PARM_DESC(scst_threads, "SCSI target threads count");

module_param_named(scst_max_cmd_mem, scst_max_cmd_mem, int, S_IRUGO);
MODULE_PARM_DESC(scst_max_cmd_mem, "Maximum memory allowed to be consumed by "
	"all SCSI commands of all devices at any given time in MB");

module_param_named(scst_max_dev_cmd_mem, scst_max_dev_cmd_mem, int, S_IRUGO);
MODULE_PARM_DESC(scst_max_dev_cmd_mem, "Maximum memory allowed to be consumed "
	"by all SCSI commands of a device at any given time in MB");

module_param_named(forcibly_close_sessions, scst_forcibly_close_sessions, int,
		   S_IWUSR | S_IRUGO);
MODULE_PARM_DESC(forcibly_close_sessions,
"If enabled, close the sessions associated with an access control group (ACG)"
" when an ACG is deleted via sysfs instead of returning -EBUSY");

module_param_named(auto_cm_assignment, scst_auto_cm_assignment, int,
		   S_IWUSR | S_IRUGO);
MODULE_PARM_DESC(auto_cm_assignment, "Enables the copy managers auto registration");

struct scst_dev_type scst_null_devtype = {
	.name = "none",
	.threads_num = -1,
};

static void __scst_resume_activity(void);

/**
 * __scst_register_target_template() - register target template.
 * @vtt:	target template
 * @version:	SCST_INTERFACE_VERSION version string to ensure that
 *		SCST core and the target driver use the same version of
 *		the SCST interface
 *
 * Description:
 *    Registers a target template and returns 0 on success or appropriate
 *    error code otherwise.
 *
 *    Target drivers supposed to behave sanely and not call register()
 *    and unregister() randomly simultaneously.
 */
int __scst_register_target_template(struct scst_tgt_template *vtt,
	const char *version)
{
	int res = 0;
	struct scst_tgt_template *t;

	TRACE_ENTRY();

	INIT_LIST_HEAD(&vtt->tgt_list);

	if (strcmp(version, SCST_INTERFACE_VERSION) != 0) {
		PRINT_ERROR("Incorrect version of target %s", vtt->name);
		res = -EINVAL;
		goto out;
	}

	if (vtt->detect)
		PRINT_WARNING("detect() method is obsolete and scheduled for "
			"removal (target driver %s)", vtt->name);

	if (!vtt->release) {
		PRINT_ERROR("Target driver %s must have "
			"release() method.", vtt->name);
		res = -EINVAL;
		goto out;
	}

	if (!vtt->xmit_response) {
		PRINT_ERROR("Target driver %s must have "
			"xmit_response() method.", vtt->name);
		res = -EINVAL;
		goto out;
	}

	if (vtt->get_initiator_port_transport_id == NULL)
		PRINT_WARNING("Target driver %s doesn't support Persistent "
			"Reservations", vtt->name);

	if (vtt->threads_num < 0) {
		PRINT_ERROR("Wrong threads_num value %d for "
			"target \"%s\"", vtt->threads_num,
			vtt->name);
		res = -EINVAL;
		goto out;
	}

	if ((!vtt->enable_target || !vtt->is_target_enabled) &&
	    !vtt->enabled_attr_not_needed)
		PRINT_WARNING("Target driver %s doesn't have enable_target() "
			"and/or is_target_enabled() method(s). This is unsafe "
			"and can lead that initiators connected on the "
			"initialization time can see an unexpected set of "
			"devices or no devices at all!", vtt->name);

	if (((vtt->add_target != NULL) && (vtt->del_target == NULL)) ||
	    ((vtt->add_target == NULL) && (vtt->del_target != NULL))) {
		PRINT_ERROR("Target driver %s must either define both "
			"add_target() and del_target(), or none.", vtt->name);
		res = -EINVAL;
		goto out;
	}

	if (vtt->rdy_to_xfer == NULL)
		vtt->rdy_to_xfer_atomic = 1;

	res = mutex_lock_interruptible(&scst_mutex);
	if (res != 0)
		goto out;
	list_for_each_entry(t, &scst_template_list, scst_template_list_entry) {
		if (strcmp(t->name, vtt->name) == 0) {
			PRINT_ERROR("Target driver %s already registered",
				vtt->name);
			goto out_unlock;
		}
	}
	mutex_unlock(&scst_mutex);

	res = scst_tgtt_sysfs_create(vtt);
	if (res != 0)
		goto out;

	mutex_lock(&scst_mutex);
	mutex_lock(&scst_mutex2);
	list_add_tail(&vtt->scst_template_list_entry, &scst_template_list);
	mutex_unlock(&scst_mutex2);
	mutex_unlock(&scst_mutex);

	TRACE_DBG("%s", "Calling target driver's detect()");
	res = vtt->detect ? vtt->detect(vtt) : 0;
	TRACE_DBG("Target driver's detect() returned %d", res);
	if (res < 0) {
		PRINT_ERROR("%s", "The detect() routine failed");
		res = -EINVAL;
		goto out_del;
	}

	PRINT_INFO("Target template %s registered successfully", vtt->name);

out:
	TRACE_EXIT_RES(res);
	return res;

out_del:
	scst_tgtt_sysfs_del(vtt);

	mutex_lock(&scst_mutex);

	mutex_lock(&scst_mutex2);
	list_del(&vtt->scst_template_list_entry);
	mutex_unlock(&scst_mutex2);

out_unlock:
	mutex_unlock(&scst_mutex);
	goto out;
}
EXPORT_SYMBOL_GPL(__scst_register_target_template);

static int scst_check_non_gpl_target_template(struct scst_tgt_template *vtt)
{
	int res;

	TRACE_ENTRY();

	if (vtt->task_mgmt_affected_cmds_done || vtt->threads_num ||
	    vtt->on_hw_pending_cmd_timeout) {
		PRINT_ERROR("Not allowed functionality in non-GPL version for "
			"target template %s", vtt->name);
		res = -EPERM;
		goto out;
	}

	res = 0;

out:
	TRACE_EXIT_RES(res);
	return res;
}

/**
 * __scst_register_target_template_non_gpl() - register target template,
 *					      non-GPL version
 * @vtt:	target template
 * @version:	SCST_INTERFACE_VERSION version string to ensure that
 *		SCST core and the target driver use the same version of
 *		the SCST interface
 *
 * Description:
 *    Registers a target template and returns 0 on success or appropriate
 *    error code otherwise.
 *
 *    Note: *vtt must be static!
 */
int __scst_register_target_template_non_gpl(struct scst_tgt_template *vtt,
	const char *version)
{
	int res;

	TRACE_ENTRY();

	res = scst_check_non_gpl_target_template(vtt);
	if (res != 0)
		goto out;

	res = __scst_register_target_template(vtt, version);

out:
	TRACE_EXIT_RES(res);
	return res;
}
EXPORT_SYMBOL(__scst_register_target_template_non_gpl);

/*
 * scst_unregister_target_template() - unregister target template
 *
 * Target drivers supposed to behave sanely and not call register()
 * and unregister() randomly simultaneously. Also it is supposed that
 * no attempts to create new targets for this vtt will be done in a race
 * with this function.
 */
void scst_unregister_target_template(struct scst_tgt_template *vtt)
{
	struct scst_tgt *tgt;
	struct scst_tgt_template *t;
	int found = 0;

	TRACE_ENTRY();

	mutex_lock(&scst_mutex);

	list_for_each_entry(t, &scst_template_list, scst_template_list_entry) {
		if (strcmp(t->name, vtt->name) == 0) {
			found = 1;
			break;
		}
	}
	if (!found) {
		PRINT_ERROR("Target driver %s isn't registered", vtt->name);
		goto out_err_up;
	}

	mutex_lock(&scst_mutex2);
	list_del(&vtt->scst_template_list_entry);
	mutex_unlock(&scst_mutex2);

	/* Wait for outstanding sysfs mgmt calls completed */
	while (vtt->tgtt_active_sysfs_works_count > 0) {
		mutex_unlock(&scst_mutex);
		msleep(100);
		mutex_lock(&scst_mutex);
	}

	while (!list_empty(&vtt->tgt_list)) {
		tgt = list_first_entry(&vtt->tgt_list, typeof(*tgt),
				       tgt_list_entry);
		mutex_unlock(&scst_mutex);
		scst_unregister_target(tgt);
		mutex_lock(&scst_mutex);
	}

	mutex_unlock(&scst_mutex);

	scst_tgtt_sysfs_del(vtt);

	PRINT_INFO("Target template %s unregistered successfully", vtt->name);

out:
	TRACE_EXIT();
	return;

out_err_up:
	mutex_unlock(&scst_mutex);
	goto out;
}
EXPORT_SYMBOL(scst_unregister_target_template);

/*
 * scst_register_target() - register target
 *
 * Registers a target for template vtt and returns new target structure on
 * success or NULL otherwise.
 */
struct scst_tgt *scst_register_target(struct scst_tgt_template *vtt,
	const char *target_name)
{
	struct scst_tgt *tgt, *t;
	int rc = 0;

	TRACE_ENTRY();

	BUG_ON(!target_name);

	rc = scst_alloc_tgt(vtt, &tgt);
	if (rc != 0)
		goto out;

	tgt->tgt_name = kstrdup(target_name, GFP_KERNEL);
	if (tgt->tgt_name == NULL) {
		PRINT_ERROR("Allocation of tgt name %s failed",
			    target_name);
		rc = -ENOMEM;
		goto out_free_tgt;
	}

	rc = mutex_lock_interruptible(&scst_mutex);
	if (rc != 0)
		goto out_free_tgt;

	list_for_each_entry(t, &vtt->tgt_list, tgt_list_entry) {
		if (strcmp(t->tgt_name, tgt->tgt_name) == 0) {
			PRINT_ERROR("target %s already exists", tgt->tgt_name);
			rc = -EEXIST;
			goto out_unlock;
		}
	}

	rc = scst_tgt_sysfs_create(tgt);
	if (rc < 0)
		goto out_unlock;

	rc = scst_alloc_add_acg(tgt, tgt->tgt_name, false, &tgt->default_acg);
	if (rc != 0)
		goto out_sysfs_del;

	mutex_lock(&scst_mutex2);
	list_add_tail(&tgt->tgt_list_entry, &vtt->tgt_list);
	mutex_unlock(&scst_mutex2);

	mutex_unlock(&scst_mutex);

	PRINT_INFO("Target %s for template %s registered successfully",
		tgt->tgt_name, vtt->name);

	TRACE_DBG("tgt %p", tgt);

out:
	TRACE_EXIT();
	return tgt;

out_sysfs_del:
	mutex_unlock(&scst_mutex);
	scst_tgt_sysfs_del(tgt);
	goto out_free_tgt;

out_unlock:
	mutex_unlock(&scst_mutex);

out_free_tgt:
	/* In case of error tgt_name will be freed in scst_free_tgt() */
	scst_free_tgt(tgt);
	tgt = NULL;
	goto out;
}
EXPORT_SYMBOL(scst_register_target);

/**
 * scst_unregister_target() - unregister a target
 * @tgt: Target to be unregistered.
 *
 * The caller is responsible for unregistration of all sessions associated
 * with @tgt. Additionally, the caller must guarantee that no new sessions
 * will be associated with @tgt while this function is in progress.
 */
void scst_unregister_target(struct scst_tgt *tgt)
{
	struct scst_tgt_template *vtt = tgt->tgtt;
	struct scst_acg *acg, *acg_tmp;
	int res;

	TRACE_ENTRY();

	/*
	 * Remove the sysfs attributes of a target before invoking
	 * tgt->tgtt->release(tgt) such that the "enabled" attribute can't be
	 * accessed during or after the tgt->tgtt->release(tgt) call.
	 */
	scst_tgt_sysfs_del(tgt);

	TRACE_DBG("%s", "Calling target driver's release()");
	tgt->tgtt->release(tgt);
	TRACE_DBG("%s", "Target driver's release() returned");

	/*
	 * Testing tgt->sysfs_sess_list below without holding scst_mutex
	 * is safe, because:
	 *
	 * - On the init path no attempts to create new sessions for this
	 * target can be done in a race with this function (see above)
	 *
	 * - On the shutdown path 'tgt' won't disappear until scst_free_tgt()
	 * is called below and because the mutex_lock(&scst_mutex) call below
	 * waits until scst_free_session() has finished accessing the 'tgt'
	 * object.
	 */
	TRACE_DBG("%s", "Waiting for sessions shutdown");
	while (!wait_event_timeout(tgt->unreg_waitQ,
				list_empty(&tgt->sysfs_sess_list), 60 * HZ)) {
		struct scst_session *sess;

		mutex_lock(&scst_mutex);
		list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) {
			PRINT_INFO("Still waiting for session %s/%s; state %ld; refcnt %#lx",
				   tgt->tgt_name, sess->sess_name,
				   sess->shut_phase,
				   percpu_ref_read(&sess->refcnt));
		}
		mutex_unlock(&scst_mutex);
	}
	TRACE_DBG("%s", "wait_event() returned");

	res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_UNLIMITED);
	WARN_ON_ONCE(res);

	mutex_lock(&scst_mutex);

	mutex_lock(&scst_mutex2);
	list_del(&tgt->tgt_list_entry);
	mutex_unlock(&scst_mutex2);

	del_timer_sync(&tgt->retry_timer);

	scst_tg_tgt_remove_by_tgt(tgt);

	scst_del_free_acg(tgt->default_acg, false);

	list_for_each_entry_safe(acg, acg_tmp, &tgt->tgt_acg_list,
					acg_list_entry) {
		scst_del_free_acg(acg, false);
	}

	mutex_unlock(&scst_mutex);
	scst_resume_activity();

	scst_tgt_sysfs_put(tgt);

	PRINT_INFO("Target %s for template %s unregistered successfully",
		tgt->tgt_name, vtt->name);

	scst_free_tgt(tgt);

	TRACE_DBG("Unregistering tgt %p finished", tgt);

	TRACE_EXIT();
	return;
}
EXPORT_SYMBOL(scst_unregister_target);

static const char *const scst_cmd_state_name[] = {
	[SCST_CMD_STATE_PARSE]				= "PARSE",
	[SCST_CMD_STATE_PREPARE_SPACE]			= "PREPARE_SPACE",
	[SCST_CMD_STATE_PREPROCESSING_DONE]		= "PREP_DONE",
	[SCST_CMD_STATE_RDY_TO_XFER]			= "RDY_TO_XFER",
	[SCST_CMD_STATE_TGT_PRE_EXEC]			= "TGT_PRE_EXEC",
	[SCST_CMD_STATE_EXEC_CHECK_SN]			= "EXEC_CHECK_SN",
	[SCST_CMD_STATE_PRE_DEV_DONE]			= "PRE_DEV_DONE",
	[SCST_CMD_STATE_MODE_SELECT_CHECKS]		= "MODE_SELECT_CHECKS",
	[SCST_CMD_STATE_DEV_DONE]			= "DEV_DONE",
	[SCST_CMD_STATE_PRE_XMIT_RESP]			= "PRE_XMIT_RESP",
	[SCST_CMD_STATE_PRE_XMIT_RESP1]			= "PRE_XMIT_RESP1",
	[SCST_CMD_STATE_CSW2]				= "CSW2",
	[SCST_CMD_STATE_PRE_XMIT_RESP2]			= "PRE_XMIT_RESP2",
	[SCST_CMD_STATE_XMIT_RESP]			= "XMIT_RESP",
	[SCST_CMD_STATE_FINISHED]			= "FINISHED",
	[SCST_CMD_STATE_FINISHED_INTERNAL]		= "FINISHED_INTERNAL",
	[SCST_CMD_STATE_INIT_WAIT]			= "INIT_WAIT",
	[SCST_CMD_STATE_INIT]				= "INIT",
	[SCST_CMD_STATE_CSW1]				= "CSW1",
	[SCST_CMD_STATE_PREPROCESSING_DONE_CALLED]	= "PREP_DONE_CALLED",
	[SCST_CMD_STATE_DATA_WAIT]			= "DATA_WAIT",
	[SCST_CMD_STATE_EXEC_CHECK_BLOCKING]		= "EXEC_CHECK_BLOCKING",
	[SCST_CMD_STATE_LOCAL_EXEC]			= "LOCAL_EXEC",
	[SCST_CMD_STATE_REAL_EXEC]			= "REAL_EXEC",
	[SCST_CMD_STATE_EXEC_WAIT]			= "EXEC_WAIT",
	[SCST_CMD_STATE_XMIT_WAIT]			= "XMIT_WAIT",
};

char *scst_get_cmd_state_name(char *name, int len, unsigned int state)
{
	if (state < ARRAY_SIZE(scst_cmd_state_name) &&
	    scst_cmd_state_name[state])
		strlcpy(name, scst_cmd_state_name[state], len);
	else
		snprintf(name, len, "%d", state);
	return name;
}

static char *scst_dump_cdb(char *buf, int buf_len, struct scst_cmd *cmd)
{
	char *p = buf, *end = buf + buf_len;
	int i;

	for (i = 0; i < cmd->cdb_len && p < end; i++)
		p += scnprintf(p, end - p, "%s%02x", i ? " " : "", cmd->cdb[i]);

	return buf;
}

void scst_trace_cmds(scst_show_fn show, void *arg)
{
	struct scst_tgt_template *t;
	struct scst_tgt *tgt;
	struct scst_session *sess;
	struct scst_cmd *cmd;
	struct scst_tgt_dev *tgt_dev;
	char state_name[32];
	char cdb[64];

	mutex_lock(&scst_mutex);
	list_for_each_entry(t, &scst_template_list, scst_template_list_entry) {
		list_for_each_entry(tgt, &t->tgt_list, tgt_list_entry) {
			list_for_each_entry(sess, &tgt->sess_list,
					    sess_list_entry) {
				spin_lock_irq(&sess->sess_list_lock);
				list_for_each_entry(cmd, &sess->sess_cmd_list,
						    sess_cmd_list_entry) {
					tgt_dev = cmd->tgt_dev;
					scst_dump_cdb(cdb, sizeof(cdb), cmd);
					scst_get_cmd_state_name(state_name,
							    sizeof(state_name),
							    cmd->state);
					show(arg, "cmd %p: state %s; op %s; "
						"proc time %ld sec; tgtt %s; "
						"tgt %s; session %s; grp %s; "
						"LUN %lld; ini %s; cdb %s\n",
						cmd, state_name,
						scst_get_opcode_name(cmd),
						(long)(jiffies - cmd->start_time) / HZ,
						t->name, tgt->tgt_name, sess->sess_name,
						tgt_dev ? (tgt_dev->acg_dev->acg->acg_name ?
								: "(default)") : "?",
						cmd->lun, sess->initiator_name, cdb);
				}
				spin_unlock_irq(&sess->sess_list_lock);
			}
		}
	}
	mutex_unlock(&scst_mutex);
	return;
}

static const char *const scst_tm_fn_name[] = {
	[SCST_ABORT_TASK]	= "ABORT_TASK",
	[SCST_ABORT_TASK_SET]	= "ABORT_TASK_SET",
	[SCST_CLEAR_ACA]	= "CLEAR_ACA",
	[SCST_CLEAR_TASK_SET]	= "CLEAR_TASK_SET",
	[SCST_LUN_RESET]	= "LUN_RESET",
	[SCST_TARGET_RESET]	= "TARGET_RESET",
	[SCST_NEXUS_LOSS_SESS]	= "NEXUS_LOSS_SESS",
	[SCST_ABORT_ALL_TASKS_SESS] = "ABORT_ALL_TASKS_SESS",
	[SCST_NEXUS_LOSS] =	"NEXUS_LOSS",
	[SCST_ABORT_ALL_TASKS] = "ABORT_ALL_TASKS",
	[SCST_UNREG_SESS_TM] =	"UNREG_SESS_TM",
	[SCST_PR_ABORT_ALL] =	"PR_ABORT_ALL",
};

char *scst_get_tm_fn_name(char *name, int len, unsigned int fn)
{
	if (fn < ARRAY_SIZE(scst_tm_fn_name) && scst_tm_fn_name[fn])
		strlcpy(name, scst_tm_fn_name[fn], len);
	else
		snprintf(name, len, "%d", fn);
	return name;
}

static const char *const scst_mcmd_state_name[] = {
	[SCST_MCMD_STATE_INIT] =	"INIT",
	[SCST_MCMD_STATE_EXEC] =	"EXEC",
	[SCST_MCMD_STATE_WAITING_AFFECTED_CMDS_DONE] = "WAITING_AFFECTED_CMDS_DONE",
	[SCST_MCMD_STATE_AFFECTED_CMDS_DONE] = "AFFECTED_CMDS_DONE",
	[SCST_MCMD_STATE_WAITING_AFFECTED_CMDS_FINISHED] = "WAITING_AFFECTED_CMDS_FINISHED",
	[SCST_MCMD_STATE_DONE] =	"DONE",
	[SCST_MCMD_STATE_FINISHED] =	"FINISHED",
};

char *scst_get_mcmd_state_name(char *name, int len, unsigned int state)
{
	if (state < ARRAY_SIZE(scst_mcmd_state_name) &&
	    scst_mcmd_state_name[state])
		strlcpy(name, scst_mcmd_state_name[state], len);
	else
		snprintf(name, len, "%d", state);
	return name;
}

void scst_trace_mcmds(scst_show_fn show, void *arg)
{
	struct scst_mgmt_cmd *mcmd;
	char fn_name[16], state_name[32];

	spin_lock_irq(&scst_mcmd_lock);
	list_for_each_entry(mcmd, &scst_active_mgmt_cmd_list,
			    mgmt_cmd_list_entry) {
		scst_get_tm_fn_name(fn_name, sizeof(fn_name), mcmd->fn);
		scst_get_mcmd_state_name(state_name, sizeof(state_name),
					 mcmd->state);
		show(arg, "mcmd %p: state %s; tgtt %s; tgt %s; session %s; fn %s;"
		     " LUN %lld; tag %lld; cmd_done_wait_count %d\n",
		     mcmd, state_name, mcmd->sess->tgt->tgtt->name,
		     mcmd->sess->tgt->tgt_name, mcmd->sess->sess_name, fn_name,
		     mcmd->lun, mcmd->tag, mcmd->cmd_done_wait_count);
	}
	spin_unlock_irq(&scst_mcmd_lock);
	return;
}

static void __printf(2, 3) scst_to_syslog(void *arg, const char *fmt, ...)
{
	bool *header_printed = arg;
	va_list args;

	if (!*header_printed) {
		PRINT_INFO("Pending commands:");
		*header_printed = true;
	}

	va_start(args, fmt);
	pr_info("    ");
	vprintk(fmt, args);
	va_end(args);
	return;
}

int scst_get_cmd_counter(void)
{
	int i, res = 0;

	for (i = 0; i < ARRAY_SIZE(scst_percpu_infos); i++)
		res += atomic_read(&scst_percpu_infos[i].cpu_cmd_count);
	return res;
}

static int scst_susp_wait(unsigned long timeout)
{
	int res;
	unsigned long t;
	bool hp = false;
#define SCST_SUSP_WAIT_REPORT_TIMEOUT (5UL * HZ)

	TRACE_ENTRY();

	if (timeout == SCST_SUSPEND_TIMEOUT_UNLIMITED)
		t = SCST_SUSP_WAIT_REPORT_TIMEOUT;
	else
		t = min(timeout, SCST_SUSP_WAIT_REPORT_TIMEOUT);

	res = wait_event_interruptible_timeout(scst_dev_cmd_waitQ,
			(scst_get_cmd_counter() == 0), t);
	if (res > 0) {
		res = 0;
		goto out;
	} else if ((res < 0) && (timeout != SCST_SUSPEND_TIMEOUT_UNLIMITED))
		goto out;

	if (res == 0) {
		PRINT_INFO("%d active commands to still not completed. See "
			"README for possible reasons.", scst_get_cmd_counter());
		scst_trace_cmds(scst_to_syslog, &hp);
		scst_trace_mcmds(scst_to_syslog, &hp);
	}

	if (timeout != SCST_SUSPEND_TIMEOUT_UNLIMITED) {
		res = wait_event_interruptible_timeout(scst_dev_cmd_waitQ,
			(scst_get_cmd_counter() == 0), timeout - t);
		if (res == 0)
			res = -EBUSY;
		else if (res > 0)
			res = 0;
	} else {
		wait_event(scst_dev_cmd_waitQ, scst_get_cmd_counter() == 0);
		res = 0;
	}

out:
	TRACE_MGMT_DBG("wait_event() returned %d", res);

	TRACE_EXIT_RES(res);
	return res;
#undef SCST_SUSP_WAIT_REPORT_TIMEOUT
}

/*
 * scst_suspend_activity() - globally suspend any activity
 *
 * Description:
 *    Globally suspends any activity and doesn't return, until there are any
 *    active commands (state after SCST_CMD_STATE_INIT). Timeout parameter sets
 *    max time this function will wait for suspending or interrupted by a
 *    signal with the corresponding error status < 0. If timeout is
 *    SCST_SUSPEND_TIMEOUT_UNLIMITED, then it will wait virtually forever.
 *    On success returns 0.
 *
 *    New arriving commands stay in the suspended state until
 *    scst_resume_activity() is called.
 */
int scst_suspend_activity(unsigned long timeout)
{
	int res = 0;
	bool rep = false;
	unsigned long cur_time = jiffies, wait_time;

	TRACE_ENTRY();

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
	rwlock_acquire_read(&scst_suspend_dep_map, 0, 0, _RET_IP_);
#endif

	if (timeout != SCST_SUSPEND_TIMEOUT_UNLIMITED) {
		res = mutex_lock_interruptible(&scst_suspend_mutex);
		if (res != 0)
			goto out;
	} else
		mutex_lock(&scst_suspend_mutex);

	TRACE_MGMT_DBG("suspend_count %d", suspend_count);
	suspend_count++;
	if (suspend_count > 1)
		goto out_up;

	set_bit(SCST_FLAG_SUSPENDING, &scst_flags);
	set_bit(SCST_FLAG_SUSPENDED, &scst_flags);
	/*
	 * Assignment of SCST_FLAG_SUSPENDING and SCST_FLAG_SUSPENDED must be
	 * ordered with cpu_cmd_count in scst_get(). Otherwise, lockless logic
	 * of scst_get() users won't work.
	 */
	smp_mb__after_set_bit();

	/*
	 * See comment in scst_user.c::dev_user_task_mgmt_fn() for more
	 * information about scst_user behavior.
	 *
	 * ToDo: make the global suspending unneeded (switch to per-device
	 * reference counting? That would mean to switch off from lockless
	 * implementation of scst_translate_lun().. )
	 */

	if (scst_get_cmd_counter() != 0) {
		PRINT_INFO("Waiting for %d active commands to complete...",
			scst_get_cmd_counter());
		rep = true;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
		lock_contended(&scst_suspend_dep_map, _RET_IP_);
#endif
	}

	res = scst_susp_wait(timeout);
	if (res != 0)
		goto out_clear;

	clear_bit(SCST_FLAG_SUSPENDING, &scst_flags);
	/* See comment about smp_mb() above */
	smp_mb__after_clear_bit();

	if (scst_get_cmd_counter() != 0)
		TRACE_MGMT_DBG("Waiting for %d active commands finally to "
			"complete", scst_get_cmd_counter());

	if (timeout != SCST_SUSPEND_TIMEOUT_UNLIMITED) {
		wait_time = jiffies - cur_time;
		/* just in case */
		if (wait_time >= timeout) {
			res = -EBUSY;
			goto out_resume;
		}
		wait_time = timeout - wait_time;
	} else
		wait_time = SCST_SUSPEND_TIMEOUT_UNLIMITED;

	res = scst_susp_wait(wait_time);
	if (res != 0)
		goto out_resume;

	if (rep)
		PRINT_INFO("%s", "All active commands completed");

out_up:
	mutex_unlock(&scst_suspend_mutex);

out:
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
	if (res == 0)
		lock_acquired(&scst_suspend_dep_map, _RET_IP_);
	else
		rwlock_release(&scst_suspend_dep_map, _RET_IP_);
#endif

	TRACE_EXIT_RES(res);
	return res;

out_clear:
	clear_bit(SCST_FLAG_SUSPENDING, &scst_flags);
	/* See comment about smp_mb() above */
	smp_mb__after_clear_bit();

out_resume:
	__scst_resume_activity();
	EXTRACHECKS_BUG_ON(suspend_count != 0);
	goto out_up;
}
EXPORT_SYMBOL_GPL(scst_suspend_activity);

/* scst_suspend_mutex supposed to be locked */
static void __scst_resume_activity(void)
{
	struct scst_cmd_threads *l;
	struct scst_mgmt_cmd *m;

	TRACE_ENTRY();

	if (suspend_count == 0) {
		PRINT_WARNING("Resume without suspend");
		goto out;
	}

	suspend_count--;
	TRACE_MGMT_DBG("suspend_count %d left", suspend_count);
	if (suspend_count > 0)
		goto out;

	clear_bit(SCST_FLAG_SUSPENDED, &scst_flags);

	mutex_lock(&scst_cmd_threads_mutex);
	list_for_each_entry(l, &scst_cmd_threads_list, lists_list_entry) {
		wake_up_all(&l->cmd_list_waitQ);
	}
	mutex_unlock(&scst_cmd_threads_mutex);

	/*
	 * Wait until scst_init_thread() either is waiting or has reexamined
	 * scst_flags.
	 */
	spin_lock_irq(&scst_init_lock);
	spin_unlock_irq(&scst_init_lock);

	wake_up_all(&scst_init_cmd_list_waitQ);

	spin_lock_irq(&scst_mcmd_lock);
	list_for_each_entry(m, &scst_delayed_mgmt_cmd_list,
			    mgmt_cmd_list_entry) {
		TRACE_MGMT_DBG("Moving delayed mgmt cmd %p to head of active "
			"mgmt cmd list", m);
	}
	list_splice_init(&scst_delayed_mgmt_cmd_list,
			 &scst_active_mgmt_cmd_list);
	spin_unlock_irq(&scst_mcmd_lock);

	wake_up_all(&scst_mgmt_cmd_list_waitQ);

out:
	TRACE_EXIT();
	return;
}

/**
 * scst_resume_activity() - globally resume all activities
 *
 * Resumes suspended by scst_suspend_activity() activities.
 */
void scst_resume_activity(void)
{
	TRACE_ENTRY();

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
	rwlock_release(&scst_suspend_dep_map, _RET_IP_);
#endif

	mutex_lock(&scst_suspend_mutex);
	__scst_resume_activity();
	mutex_unlock(&scst_suspend_mutex);

	TRACE_EXIT();
	return;
}
EXPORT_SYMBOL_GPL(scst_resume_activity);

int scst_get_suspend_count(void)
{
	return suspend_count;
}

static int scst_register_device(struct scsi_device *scsidp)
{
	DECLARE_COMPLETION_ONSTACK(c);
	struct scst_device *dev, *d;
	int res;

	TRACE_ENTRY();


	res = mutex_lock_interruptible(&scst_mutex);
	if (res != 0)
		goto out;

	res = scst_alloc_device(GFP_KERNEL, NUMA_NO_NODE, &dev);
	if (res != 0)
		goto out_unlock;

	dev->type = scsidp->type;

	dev->virt_name = kasprintf(GFP_KERNEL, "%d:%d:%d:%lld",
				   scsidp->host->host_no, scsidp->channel,
				   scsidp->id, (u64)scsidp->lun);
	if (dev->virt_name == NULL) {
		PRINT_ERROR("%s", "Unable to alloc device name");
		res = -ENOMEM;
		goto out_free_dev;
	}

	list_for_each_entry(d, &scst_dev_list, dev_list_entry) {
		if (strcmp(d->virt_name, dev->virt_name) == 0) {
			PRINT_ERROR("Device %s already exists", dev->virt_name);
			res = -EEXIST;
			goto out_free_dev;
		}
	}

	dev->scsi_dev = scsidp;

	/* For target ports that function as forwarding source. */
	res = scst_pr_set_file_name(dev, NULL, "%s/%s", SCST_PR_DIR,
				    dev->virt_name);
	if (res != 0)
		goto out_free_dev;

	res = scst_pr_init_dev(dev);
	if (res != 0)
		goto out_free_dev;

	list_add_tail(&dev->dev_list_entry, &scst_dev_list);

	mutex_unlock(&scst_mutex);

	res = scst_dev_sysfs_create(dev);
	if (res != 0)
		goto out_del_unlocked;

	percpu_ref_get(&dev->refcnt);

	PRINT_INFO("Attached to scsi%d, channel %d, id %d, lun %lld, type %d",
		   scsidp->host->host_no, scsidp->channel, scsidp->id,
		   (u64)scsidp->lun, scsidp->type);

out:
	TRACE_EXIT_RES(res);
	return res;

out_del_unlocked:
	mutex_lock(&scst_mutex);
	list_del_init(&dev->dev_list_entry);

	/* If used as a forwarding source (see also tgt_forward_src). */
	scst_pr_clear_dev(dev);

out_free_dev:
	dev->remove_completion = &c;
	percpu_ref_kill(&dev->refcnt);
	wait_for_completion(&c);
	scst_free_device(dev);

out_unlock:
	mutex_unlock(&scst_mutex);
	goto out;
}

static struct scst_device *__scst_lookup_device(struct scsi_device *scsidp)
{
	struct scst_device *d;

	lockdep_assert_held(&scst_mutex);

	list_for_each_entry(d, &scst_dev_list, dev_list_entry)
		if (d->scsi_dev == scsidp)
			return d;

	return NULL;
}

static void scst_unregister_device(struct scsi_device *scsidp)
{
	struct scst_device *dev;
	struct scst_acg_dev *acg_dev, *aa;
	DECLARE_COMPLETION_ONSTACK(c);

	TRACE_ENTRY();

	mutex_lock(&scst_mutex);

	dev = __scst_lookup_device(scsidp);
	if (dev == NULL) {
		PRINT_ERROR("SCST device for SCSI device %d:%d:%d:%lld not found",
			    scsidp->host->host_no, scsidp->channel, scsidp->id,
			    (u64)scsidp->lun);
		goto out_unlock;
	}

	dev->dev_unregistering = 1;

	list_del_init(&dev->dev_list_entry);

	/* For forwarding sources (see also tgt_forward_src). */
	scst_pr_clear_dev(dev);

	scst_dg_dev_remove_by_dev(dev);

	list_for_each_entry_safe(acg_dev, aa, &dev->dev_acg_dev_list,
				 dev_acg_dev_list_entry) {
		scst_acg_del_lun(acg_dev->acg, acg_dev->lun, true);
	}

	dev->remove_completion = &c;

	mutex_unlock(&scst_mutex);

	PRINT_INFO("Detached from scsi%d, channel %d, id %d, lun %lld, type %d",
		   scsidp->host->host_no, scsidp->channel, scsidp->id,
		   (u64)scsidp->lun, scsidp->type);

	percpu_ref_kill(&dev->refcnt);
	percpu_ref_put(&dev->refcnt);

	wait_for_completion(&c);

	mutex_lock(&scst_mutex);
	scst_assign_dev_handler(dev, &scst_null_devtype);
	mutex_unlock(&scst_mutex);

	scst_dev_sysfs_del(dev);

	scst_free_device(dev);

out:
	TRACE_EXIT();
	return;

out_unlock:
	mutex_unlock(&scst_mutex);
	goto out;
}

static int scst_dev_handler_check(struct scst_dev_type *dev_handler)
{
	int res = 0;

	if (dev_handler->parse == NULL) {
		PRINT_ERROR("scst dev handler %s must have "
			"parse() method.", dev_handler->name);
		res = -EINVAL;
		goto out;
	}

	if (((dev_handler->add_device != NULL) &&
	     (dev_handler->del_device == NULL)) ||
	    ((dev_handler->add_device == NULL) &&
	     (dev_handler->del_device != NULL))) {
		PRINT_ERROR("Dev handler %s must either define both "
			"add_device() and del_device(), or none.",
			dev_handler->name);
		res = -EINVAL;
		goto out;
	}

	if (dev_handler->dev_alloc_data_buf == NULL)
		dev_handler->dev_alloc_data_buf_atomic = 1;

	if (dev_handler->dev_done == NULL)
		dev_handler->dev_done_atomic = 1;

	if (dev_handler->max_tgt_dev_commands == 0)
		dev_handler->max_tgt_dev_commands = SCST_MAX_TGT_DEV_COMMANDS;

out:
	TRACE_EXIT_RES(res);
	return res;
}

static int scst_check_device_name(const char *dev_name)
{
	int res = 0;

	if (strchr(dev_name, '/') != NULL) {
		PRINT_ERROR("Dev name %s contains illegal character '/'",
			dev_name);
		res = -EINVAL;
		goto out;
	}

	/* To prevent collision with saved PR and mode pages backup files */
	if (strchr(dev_name, '.') != NULL) {
		PRINT_ERROR("Dev name %s contains illegal character '.'",
			dev_name);
		res = -EINVAL;
		goto out;
	}

out:
	TRACE_EXIT_RES(res);
	return res;
}

/**
 * scst_register_virtual_device_node() - register a virtual device.
 * @dev_handler: the device's device handler
 * @dev_name:	the new device name, NULL-terminated string. Must be uniq
 *              among all virtual devices in the system.
 * @nodeid:	NUMA node id this device belongs to or NUMA_NO_NODE.
 *
 * Registers a virtual device and returns ID assigned to the device on
 * success, or negative value otherwise
 */
int scst_register_virtual_device_node(struct scst_dev_type *dev_handler,
	const char *dev_name, int nodeid)
{
	DECLARE_COMPLETION_ONSTACK(c);
	struct scst_device *dev, *d;
	bool sysfs_del = false;
	int res;

	TRACE_ENTRY();

	if (dev_handler == NULL) {
		PRINT_ERROR("%s: valid device handler must be supplied",
			    __func__);
		res = -EINVAL;
		goto out;
	}

	if (dev_name == NULL) {
		PRINT_ERROR("%s: device name must be non-NULL", __func__);
		res = -EINVAL;
		goto out;
	}

	res = scst_check_device_name(dev_name);
	if (res != 0)
		goto out;

	res = scst_dev_handler_check(dev_handler);
	if (res != 0)
		goto out;

	res = mutex_lock_interruptible(&scst_mutex);
	if (res != 0)
		goto out;

	res = scst_alloc_device(GFP_KERNEL, nodeid, &dev);
	if (res != 0)
		goto out_unlock;

	dev->type = dev_handler->type;
	dev->scsi_dev = NULL;
	dev->virt_name = kstrdup(dev_name, GFP_KERNEL);
	if (dev->virt_name == NULL) {
		PRINT_ERROR("Unable to allocate virt_name for dev %s",
			dev_name);
		res = -ENOMEM;
		goto out_free_dev;
	}

	while (1) {
		dev->virt_id = scst_virt_dev_last_id++;
		if (dev->virt_id > 0)
			break;
		scst_virt_dev_last_id = 1;
	}

	res = scst_pr_set_file_name(dev, NULL, "%s/%s", SCST_PR_DIR,
				    dev->virt_name);
	if (res != 0)
		goto out_free_dev;

	res = scst_pr_init_dev(dev);
	if (res != 0)
		goto out_free_dev;

	/*
	 * We can drop scst_mutex, because we have not yet added the dev in
	 * scst_dev_list, so it "doesn't exist" yet.
	 */
	mutex_unlock(&scst_mutex);

	res = scst_dev_sysfs_create(dev);
	if (res != 0)
		goto out_lock_pr_clear_dev;

	mutex_lock(&scst_mutex);

	list_for_each_entry(d, &scst_dev_list, dev_list_entry) {
		if (strcmp(d->virt_name, dev_name) == 0) {
			PRINT_ERROR("Device %s already exists", dev_name);
			res = -EEXIST;
			sysfs_del = true;
			goto out_pr_clear_dev;
		}
	}

	res = scst_assign_dev_handler(dev, dev_handler);
	if (res != 0) {
		sysfs_del = true;
		goto out_pr_clear_dev;
	}

	list_add_tail(&dev->dev_list_entry, &scst_dev_list);

	res = scst_cm_on_dev_register(dev);
	if (res != 0)
		goto out_unreg;

	mutex_unlock(&scst_mutex);

	percpu_ref_get(&dev->refcnt);

	res = dev->virt_id;

	scst_event_queue_reg_vdev(dev_name);
	PRINT_INFO("Attached to virtual device %s (id %d)", dev_name, res);

out:
	TRACE_EXIT_RES(res);
	return res;

out_unreg:
	dev->dev_unregistering = 1;
	list_del(&dev->dev_list_entry);
	scst_assign_dev_handler(dev, &scst_null_devtype);
	goto out_pr_clear_dev;

out_lock_pr_clear_dev:
	mutex_lock(&scst_mutex);

out_pr_clear_dev:
	scst_pr_clear_dev(dev);

out_free_dev:
	mutex_unlock(&scst_mutex);
	if (sysfs_del)
		scst_dev_sysfs_del(dev);
	dev->remove_completion = &c;
	percpu_ref_kill(&dev->refcnt);
	wait_for_completion(&c);
	scst_free_device(dev);
	goto out;

out_unlock:
	mutex_unlock(&scst_mutex);
	goto out;
}
EXPORT_SYMBOL_GPL(scst_register_virtual_device_node);

/*
 * scst_unregister_virtual_device() - unegister a virtual device.
 * @id:		the device's ID, returned by the registration function
 */
void scst_unregister_virtual_device(int id,
				    void (*on_free)(struct scst_device *dev,
						    void *arg),
				    void *arg)
{
	struct scst_device *d, *dev = NULL;
	struct scst_acg_dev *acg_dev, *aa;
	DECLARE_COMPLETION_ONSTACK(c);

	TRACE_ENTRY();

	mutex_lock(&scst_mutex);

	list_for_each_entry(d, &scst_dev_list, dev_list_entry) {
		if (d->virt_id == id) {
			dev = d;
			TRACE_DBG("Virtual device %p (id %d) found", dev, id);
			break;
		}
	}
	if (dev == NULL) {
		PRINT_ERROR("Virtual device (id %d) not found", id);
		goto out_unlock;
	}

	dev->dev_unregistering = 1;

	scst_cm_on_dev_unregister(dev);

	list_del_init(&dev->dev_list_entry);

	scst_pr_clear_dev(dev);

	scst_dg_dev_remove_by_dev(dev);

	list_for_each_entry_safe(acg_dev, aa, &dev->dev_acg_dev_list,
				 dev_acg_dev_list_entry) {
		scst_acg_del_lun(acg_dev->acg, acg_dev->lun, true);
	}

	dev->remove_completion = &c;

	mutex_unlock(&scst_mutex);

	PRINT_INFO("Detached from virtual device %s (id %d)",
		dev->virt_name, dev->virt_id);

	if (on_free)
		on_free(dev, arg);

	percpu_ref_kill(&dev->refcnt);
	percpu_ref_put(&dev->refcnt);

	wait_for_completion(&c);

	mutex_lock(&scst_mutex);
	scst_assign_dev_handler(dev, &scst_null_devtype);
	mutex_unlock(&scst_mutex);

	scst_dev_sysfs_del(dev);

	scst_free_device(dev);

out:
	TRACE_EXIT();
	return;

out_unlock:
	mutex_unlock(&scst_mutex);
	scst_resume_activity();
	goto out;
}
EXPORT_SYMBOL_GPL(scst_unregister_virtual_device);

/**
 * __scst_register_dev_driver() - register pass-through dev handler driver
 * @dev_type:	dev handler template
 * @version:	SCST_INTERFACE_VERSION version string to ensure that
 *		SCST core and the dev handler use the same version of
 *		the SCST interface
 *
 * Description:
 *    Registers a pass-through dev handler driver. Returns 0 on success
 *    or appropriate error code otherwise.
 */
int __scst_register_dev_driver(struct scst_dev_type *dev_type,
	const char *version)
{
	int res, exist;
	struct scst_dev_type *dt;

	TRACE_ENTRY();

	res = -EINVAL;
	if (strcmp(version, SCST_INTERFACE_VERSION) != 0) {
		PRINT_ERROR("Incorrect version of dev handler %s",
			dev_type->name);
		goto out;
	}

	res = scst_dev_handler_check(dev_type);
	if (res != 0)
		goto out;

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30) && \
	!defined(CONFIG_SCST_STRICT_SERIALIZING)
	if (dev_type->exec == NULL) {
		PRINT_ERROR("Pass-through dev handlers (handler \"%s\") not "
			"supported. Consider applying on your kernel patch "
			"scst_exec_req_fifo-<kernel-version> or define "
			"CONFIG_SCST_STRICT_SERIALIZING", dev_type->name);
		res = -EINVAL;
		goto out;
	}
#endif


	res = mutex_lock_interruptible(&scst_mutex);
	if (res != 0)
		goto out;

	exist = 0;
	list_for_each_entry(dt, &scst_dev_type_list, dev_type_list_entry) {
		if (strcmp(dt->name, dev_type->name) == 0) {
			PRINT_ERROR("Device type handler \"%s\" already "
				    "exists", dt->name);
			exist = 1;
			break;
		}
	}
	if (exist)
		goto out_unlock;

	list_add_tail(&dev_type->dev_type_list_entry, &scst_dev_type_list);

	mutex_unlock(&scst_mutex);

	res = scst_devt_sysfs_create(dev_type);
	if (res < 0)
		goto out;

	PRINT_INFO("Device handler \"%s\" for type %d registered "
		"successfully", dev_type->name, dev_type->type);

out:
	TRACE_EXIT_RES(res);
	return res;

out_unlock:
	mutex_unlock(&scst_mutex);
	goto out;
}
EXPORT_SYMBOL_GPL(__scst_register_dev_driver);

/*
 * scst_unregister_dev_driver() - unregister pass-through dev handler driver
 */
void scst_unregister_dev_driver(struct scst_dev_type *dev_type)
{
	struct scst_device *dev;
	struct scst_dev_type *dt;
	int res, found = 0;

	TRACE_ENTRY();

	res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_UNLIMITED);
	WARN_ON_ONCE(res);

	mutex_lock(&scst_mutex);

	list_for_each_entry(dt, &scst_dev_type_list, dev_type_list_entry) {
		if (strcmp(dt->name, dev_type->name) == 0) {
			found = 1;
			break;
		}
	}
	if (!found) {
		PRINT_ERROR("Dev handler \"%s\" isn't registered",
			dev_type->name);
		goto out_up;
	}

	list_for_each_entry(dev, &scst_dev_list, dev_list_entry) {
		if (dev->handler == dev_type) {
			scst_assign_dev_handler(dev, &scst_null_devtype);
			TRACE_DBG("Dev handler removed from device %p", dev);
		}
	}

	list_del(&dev_type->dev_type_list_entry);

	mutex_unlock(&scst_mutex);
	scst_resume_activity();

	scst_devt_sysfs_del(dev_type);

	PRINT_INFO("Device handler \"%s\" for type %d unloaded",
		   dev_type->name, dev_type->type);

out:
	TRACE_EXIT();
	return;

out_up:
	mutex_unlock(&scst_mutex);
	scst_resume_activity();
	goto out;
}
EXPORT_SYMBOL_GPL(scst_unregister_dev_driver);

/**
 * __scst_register_virtual_dev_driver() - register virtual dev handler driver
 * @dev_type:	dev handler template
 * @version:	SCST_INTERFACE_VERSION version string to ensure that
 *		SCST core and the dev handler use the same version of
 *		the SCST interface
 *
 * Description:
 *    Registers a virtual dev handler driver. Returns 0 on success or
 *    appropriate error code otherwise.
 */
int __scst_register_virtual_dev_driver(struct scst_dev_type *dev_type,
	const char *version)
{
	int res;

	TRACE_ENTRY();

	if (strcmp(version, SCST_INTERFACE_VERSION) != 0) {
		PRINT_ERROR("Incorrect version of virtual dev handler %s",
			dev_type->name);
		res = -EINVAL;
		goto out;
	}

	res = scst_dev_handler_check(dev_type);
	if (res != 0)
		goto out;

	res = mutex_lock_interruptible(&scst_mutex);
	if (res != 0)
		goto out;
	list_add_tail(&dev_type->dev_type_list_entry, &scst_virtual_dev_type_list);
	mutex_unlock(&scst_mutex);

	res = scst_devt_sysfs_create(dev_type);
	if (res < 0)
		goto out;

	if (dev_type->type != -1) {
		PRINT_INFO("Virtual device handler %s for type %d "
			"registered successfully", dev_type->name,
			dev_type->type);
	} else {
		PRINT_INFO("Virtual device handler \"%s\" registered "
			"successfully", dev_type->name);
	}

out:
	TRACE_EXIT_RES(res);
	return res;
}
EXPORT_SYMBOL_GPL(__scst_register_virtual_dev_driver);

/*
 * scst_unregister_virtual_dev_driver() - unregister virtual dev driver
 */
void scst_unregister_virtual_dev_driver(struct scst_dev_type *dev_type)
{
	TRACE_ENTRY();

	mutex_lock(&scst_mutex);

	/* Disable sysfs mgmt calls (e.g. addition of new devices) */
	list_del(&dev_type->dev_type_list_entry);

	/* Wait for outstanding sysfs mgmt calls completed */
	while (dev_type->devt_active_sysfs_works_count > 0) {
		mutex_unlock(&scst_mutex);
		msleep(100);
		mutex_lock(&scst_mutex);
	}

	mutex_unlock(&scst_mutex);

	scst_devt_sysfs_del(dev_type);

	PRINT_INFO("Device handler \"%s\" unloaded", dev_type->name);

	TRACE_EXIT();
	return;
}
EXPORT_SYMBOL_GPL(scst_unregister_virtual_dev_driver);

int scst_add_threads(struct scst_cmd_threads *cmd_threads,
	struct scst_device *dev, struct scst_tgt_dev *tgt_dev, int num)
{
	int res = 0, i;
	struct scst_cmd_thread_t *thr;
	int n = 0, tgt_dev_num = 0, nodeid = NUMA_NO_NODE;

	TRACE_ENTRY();

	if (num == 0) {
		res = 0;
		goto out;
	}

	spin_lock(&cmd_threads->thr_lock);
	n = cmd_threads->nr_threads;
	spin_unlock(&cmd_threads->thr_lock);

	TRACE_DBG("cmd_threads %p, dev %s, tgt_dev %p, num %d, n %d",
		cmd_threads, dev ? dev->virt_name : "NULL", tgt_dev, num, n);

	if (tgt_dev != NULL) {
		struct scst_tgt_dev *t;

		list_for_each_entry(t, &tgt_dev->dev->dev_tgt_dev_list,
				dev_tgt_dev_list_entry) {
			if (t == tgt_dev)
				break;
			tgt_dev_num++;
		}
		tgt_dev->thread_index = tgt_dev_num;

		nodeid = tgt_dev->dev->dev_numa_node_id;
	} else if (dev != NULL)
		nodeid = dev->dev_numa_node_id;

	for (i = 0; i < num; i++) {
		thr = kmem_cache_alloc_node(scst_thr_cachep, GFP_KERNEL, nodeid);
		if (!thr) {
			res = -ENOMEM;
			PRINT_ERROR("Fail to allocate thr %d", res);
			goto out_wait;
		}
		memset(thr, 0, sizeof(*thr));
		INIT_LIST_HEAD(&thr->thr_active_cmd_list);
		spin_lock_init(&thr->thr_cmd_list_lock);
		thr->thr_cmd_threads = cmd_threads;

		if (dev != NULL) {
			thr->cmd_thread = kthread_create_on_node(scst_cmd_thread,
				thr, nodeid, "%.13s%d", dev->virt_name, n++);
		} else if (tgt_dev != NULL) {
			thr->cmd_thread = kthread_create_on_node(scst_cmd_thread,
				thr, nodeid, "%.10s%d_%d",
				tgt_dev->dev->virt_name, tgt_dev_num, n++);
		} else
			thr->cmd_thread = kthread_create_on_node(scst_cmd_thread,
				thr, nodeid, "scstd%d", n++);

		if (IS_ERR(thr->cmd_thread)) {
			res = PTR_ERR(thr->cmd_thread);
			PRINT_ERROR("kthread_create() failed: %d", res);
			kfree(thr);
			goto out_wait;
		}

		if (tgt_dev != NULL) {
			int rc;
			/*
			 * sess->acg can be NULL here, if called from
			 * scst_check_reassign_sess()!
			 */
			rc = set_cpus_allowed_ptr(thr->cmd_thread,
				&tgt_dev->acg_dev->acg->acg_cpu_mask);
			if (rc != 0)
				PRINT_ERROR("Setting CPU affinity failed: "
					"%d", rc);
		}

		spin_lock(&cmd_threads->thr_lock);
		list_add(&thr->thread_list_entry, &cmd_threads->threads_list);
		cmd_threads->nr_threads++;
		spin_unlock(&cmd_threads->thr_lock);

		TRACE_DBG("Added thr %p to threads list (nr_threads %d, n %d)",
			thr, cmd_threads->nr_threads, n);

		wake_up_process(thr->cmd_thread);
	}

out_wait:
	if (i > 0 && cmd_threads != &scst_main_cmd_threads) {
		/*
		 * Wait for io_context gets initialized to avoid possible races
		 * for it from the sharing it tgt_devs.
		 */
		wait_event(cmd_threads->ioctx_wq,
			   cmd_threads->io_context_ready);
		smp_rmb();
	}

	if (res != 0)
		scst_del_threads(cmd_threads, i);

out:
	TRACE_EXIT_RES(res);
	return res;
}

/*
 * The being stopped threads must not have assigned commands, which usually
 * means suspended activities.
 */
void scst_del_threads(struct scst_cmd_threads *cmd_threads, int num)
{
	TRACE_ENTRY();

	for ( ; num != 0; num--) {
		struct scst_cmd_thread_t *ct = NULL, *ct2;
		int rc;

		spin_lock(&cmd_threads->thr_lock);
		list_for_each_entry_reverse(ct2, &cmd_threads->threads_list,
					    thread_list_entry) {
			if (!ct2->being_stopped) {
				ct = ct2;
				list_del(&ct->thread_list_entry);
				ct->being_stopped = true;
				cmd_threads->nr_threads--;
				break;
			}
		}
		spin_unlock(&cmd_threads->thr_lock);

		if (!ct)
			break;

		rc = kthread_stop(ct->cmd_thread);
		if (rc != 0 && rc != -EINTR)
			TRACE_MGMT_DBG("kthread_stop() failed: %d", rc);

		kmem_cache_free(scst_thr_cachep, ct);
	}

	EXTRACHECKS_BUG_ON((cmd_threads->nr_threads == 0) &&
		(cmd_threads->io_context != NULL));

	TRACE_EXIT();
	return;
}

/* scst_mutex supposed to be held */
int scst_set_thr_cpu_mask(struct scst_cmd_threads *cmd_threads,
			  cpumask_t *cpu_mask)
{
	struct scst_cmd_thread_t *thr;
	int rc = 0;

	spin_lock(&cmd_threads->thr_lock);
	list_for_each_entry(thr, &cmd_threads->threads_list,
			    thread_list_entry) {
		rc = set_cpus_allowed_ptr(thr->cmd_thread, cpu_mask);
		if (rc)
			break;
	}
	spin_unlock(&cmd_threads->thr_lock);

	return rc;
}
EXPORT_SYMBOL(scst_set_thr_cpu_mask);

/* The activity supposed to be suspended and scst_mutex held */
void scst_stop_dev_threads(struct scst_device *dev)
{
	struct scst_tgt_dev *tgt_dev;

	TRACE_ENTRY();

	list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
				dev_tgt_dev_list_entry) {
		scst_tgt_dev_stop_threads(tgt_dev);
	}

	if ((dev->threads_num > 0) &&
	    (dev->threads_pool_type == SCST_THREADS_POOL_SHARED))
		scst_del_threads(&dev->dev_cmd_threads, -1);

	TRACE_EXIT();
	return;
}

/* The activity supposed to be suspended and scst_mutex held */
int scst_create_dev_threads(struct scst_device *dev)
{
	int res = 0;
	struct scst_tgt_dev *tgt_dev;

	TRACE_ENTRY();

	list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
			dev_tgt_dev_list_entry) {
		res = scst_tgt_dev_setup_threads(tgt_dev);
		if (res != 0)
			goto out_err;
	}

	if ((dev->threads_num > 0) &&
	    (dev->threads_pool_type == SCST_THREADS_POOL_SHARED)) {
		res = scst_add_threads(&dev->dev_cmd_threads, dev, NULL,
			dev->threads_num);
		if (res != 0)
			goto out_err;
	}

out:
	TRACE_EXIT_RES(res);
	return res;

out_err:
	scst_stop_dev_threads(dev);
	goto out;
}

/*
 * The caller must hold scst_mutex. No commands must be in progress for @dev.
 * There are two ways to achieve this: either make sure no device handler is
 * assigned before this function is called or remove all associated LUNs and
 * wait until the commands associated with these LUNs have finished before this
 * function is called.
 */
int scst_assign_dev_handler(struct scst_device *dev,
	struct scst_dev_type *handler)
{
	int res = 0;
	struct scst_tgt_dev *tgt_dev;
	LIST_HEAD(attached_tgt_devs);

	TRACE_ENTRY();

	lockdep_assert_held(&scst_mutex);

	sBUG_ON(handler == NULL);

	if (dev->handler == handler)
		goto out;

	if (dev->handler == NULL)
		goto assign;

	if (dev->handler->detach_tgt) {
		list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
				dev_tgt_dev_list_entry) {
			TRACE_DBG("Calling dev handler's detach_tgt(%p)",
				tgt_dev);
			dev->handler->detach_tgt(tgt_dev);
			TRACE_DBG("%s", "Dev handler's detach_tgt() returned");
		}
	}

	/*
	 * devt_dev sysfs must be created AFTER attach() and deleted BEFORE
	 * detach() to avoid calls from sysfs for not yet ready or already dead
	 * objects.
	 */
	scst_devt_dev_sysfs_del(dev);

	if (dev->handler->detach) {
		TRACE_DBG("%s", "Calling dev handler's detach()");
		dev->handler->detach(dev);
		TRACE_DBG("%s", "Old handler's detach() returned");
	}

	scst_stop_dev_threads(dev);

assign:
	dev->handler = handler;
	dev->threads_num = handler->threads_num;
	dev->threads_pool_type = handler->threads_pool_type;
	dev->max_tgt_dev_commands = handler->max_tgt_dev_commands;
	dev->max_write_same_len = 256 * 1024 * 1024; /* 256 MB */

	if (handler->attach) {
		TRACE_DBG("Calling new dev handler's attach(%p)", dev);
		res = handler->attach(dev);
		TRACE_DBG("New dev handler's attach() returned %d", res);
		if (res != 0) {
			PRINT_ERROR("New device handler's %s attach() "
				"failed: %d", handler->name, res);
			goto out;
		}
	}

	res = scst_devt_dev_sysfs_create(dev);
	if (res != 0)
		goto out_detach;

	if (handler->attach_tgt) {
		list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
				dev_tgt_dev_list_entry) {
			TRACE_DBG("Calling dev handler's attach_tgt(%p)",
				tgt_dev);
			res = handler->attach_tgt(tgt_dev);
			TRACE_DBG("%s", "Dev handler's attach_tgt() returned");
			if (res != 0) {
				PRINT_ERROR("Device handler's %s attach_tgt() "
				    "failed: %d", handler->name, res);
				goto out_err_detach_tgt;
			}
			list_add_tail(&tgt_dev->extra_tgt_dev_list_entry,
				&attached_tgt_devs);
		}
	}

	res = scst_create_dev_threads(dev);
	if (res != 0)
		goto out_err_detach_tgt;

out:
	TRACE_EXIT_RES(res);
	return res;

out_err_detach_tgt:
	if (handler->detach_tgt) {
		list_for_each_entry(tgt_dev, &attached_tgt_devs,
				 extra_tgt_dev_list_entry) {
			TRACE_DBG("Calling handler's detach_tgt(%p)",
				tgt_dev);
			handler->detach_tgt(tgt_dev);
			TRACE_DBG("%s", "Handler's detach_tgt() returned");
		}
	}

	scst_devt_dev_sysfs_del(dev);

out_detach:
	if (handler->detach) {
		TRACE_DBG("%s", "Calling handler's detach()");
		handler->detach(dev);
		TRACE_DBG("%s", "Handler's detach() returned");
	}

	dev->handler = &scst_null_devtype;
	dev->threads_num = scst_null_devtype.threads_num;
	dev->threads_pool_type = scst_null_devtype.threads_pool_type;
	goto out;
}

/*
 * scst_init_threads() - initialize SCST processing threads pool
 *
 * Initializes scst_cmd_threads structure
 */
void scst_init_threads(struct scst_cmd_threads *cmd_threads)
{
	TRACE_ENTRY();

	spin_lock_init(&cmd_threads->cmd_list_lock);
	INIT_LIST_HEAD(&cmd_threads->active_cmd_list);
	init_waitqueue_head(&cmd_threads->cmd_list_waitQ);
	init_waitqueue_head(&cmd_threads->ioctx_wq);
	INIT_LIST_HEAD(&cmd_threads->threads_list);
	mutex_init(&cmd_threads->io_context_mutex);
	spin_lock_init(&cmd_threads->thr_lock);

	mutex_lock(&scst_cmd_threads_mutex);
	list_add_tail(&cmd_threads->lists_list_entry,
		&scst_cmd_threads_list);
	mutex_unlock(&scst_cmd_threads_mutex);

	TRACE_EXIT();
	return;
}
EXPORT_SYMBOL_GPL(scst_init_threads);

/*
 * scst_deinit_threads() - deinitialize SCST processing threads pool
 *
 * Deinitializes scst_cmd_threads structure
 */
void scst_deinit_threads(struct scst_cmd_threads *cmd_threads)
{
	TRACE_ENTRY();

	mutex_lock(&scst_cmd_threads_mutex);
	list_del(&cmd_threads->lists_list_entry);
	mutex_unlock(&scst_cmd_threads_mutex);

	sBUG_ON(cmd_threads->io_context);

	TRACE_EXIT();
	return;
}
EXPORT_SYMBOL_GPL(scst_deinit_threads);

static void scst_stop_global_threads(void)
{
	TRACE_ENTRY();

	mutex_lock(&scst_mutex);

	scst_del_threads(&scst_main_cmd_threads, -1);

	if (scst_mgmt_cmd_thread)
		kthread_stop(scst_mgmt_cmd_thread);
	if (scst_mgmt_thread)
		kthread_stop(scst_mgmt_thread);
	if (scst_init_cmd_thread)
		kthread_stop(scst_init_cmd_thread);

	mutex_unlock(&scst_mutex);

	TRACE_EXIT();
	return;
}

/* It does NOT stop ran threads on error! */
static int scst_start_global_threads(int num)
{
	int res;

	TRACE_ENTRY();

	mutex_lock(&scst_mutex);

	res = scst_add_threads(&scst_main_cmd_threads, NULL, NULL, num);
	if (res < 0)
		goto out_unlock;

	scst_init_cmd_thread = kthread_run(scst_init_thread,
		NULL, "scst_initd");
	if (IS_ERR(scst_init_cmd_thread)) {
		res = PTR_ERR(scst_init_cmd_thread);
		PRINT_ERROR("kthread_create() for init cmd failed: %d", res);
		scst_init_cmd_thread = NULL;
		goto out_unlock;
	}

	scst_mgmt_cmd_thread = kthread_run(scst_tm_thread,
		NULL, "scsi_tm");
	if (IS_ERR(scst_mgmt_cmd_thread)) {
		res = PTR_ERR(scst_mgmt_cmd_thread);
		PRINT_ERROR("kthread_create() for TM failed: %d", res);
		scst_mgmt_cmd_thread = NULL;
		goto out_unlock;
	}

	scst_mgmt_thread = kthread_run(scst_global_mgmt_thread,
		NULL, "scst_mgmtd");
	if (IS_ERR(scst_mgmt_thread)) {
		res = PTR_ERR(scst_mgmt_thread);
		PRINT_ERROR("kthread_create() for mgmt failed: %d", res);
		scst_mgmt_thread = NULL;
		goto out_unlock;
	}

out_unlock:
	mutex_unlock(&scst_mutex);

	TRACE_EXIT_RES(res);
	return res;
}

/**
 * scst_get_setup_id() - return SCST setup ID
 *
 * Returns SCST setup ID. This ID can be used for multiple
 * setups with the same configuration.
 */
unsigned int scst_get_setup_id(void)
{
	return scst_setup_id;
}
EXPORT_SYMBOL_GPL(scst_get_setup_id);

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
static int scst_add(struct class_device *cdev, struct class_interface *intf)
#else
static int scst_add(struct device *cdev, struct class_interface *intf)
#endif
{
	struct scsi_device *scsidp;
	int res = 0;

	TRACE_ENTRY();

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
	scsidp = to_scsi_device(cdev->dev);
#else
	scsidp = to_scsi_device(cdev->parent);
#endif

	if ((scsidp->host->hostt->name == NULL) ||
	    (strcmp(scsidp->host->hostt->name, SCST_LOCAL_NAME) != 0))
		res = scst_register_device(scsidp);

	TRACE_EXIT();
	return res;
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
static void scst_remove(struct class_device *cdev, struct class_interface *intf)
#else
static void scst_remove(struct device *cdev, struct class_interface *intf)
#endif
{
	struct scsi_device *scsidp;

	TRACE_ENTRY();

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
	scsidp = to_scsi_device(cdev->dev);
#else
	scsidp = to_scsi_device(cdev->parent);
#endif

	if ((scsidp->host->hostt->name == NULL) ||
	    (strcmp(scsidp->host->hostt->name, SCST_LOCAL_NAME) != 0))
		scst_unregister_device(scsidp);

	TRACE_EXIT();
	return;
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
static struct class_interface scst_interface = {
	.add = scst_add,
	.remove = scst_remove,
};
#else
static struct class_interface scst_interface = {
	.add_dev = scst_add,
	.remove_dev = scst_remove,
};
#endif

static void __init scst_print_config(void)
{
	char buf[128];
	int i, j;

	i = snprintf(buf, sizeof(buf), "Enabled features: ");
	j = i;

#ifdef CONFIG_SCST_STRICT_SERIALIZING
	i += snprintf(&buf[i], sizeof(buf) - i, "STRICT_SERIALIZING");
#endif

#ifdef CONFIG_SCST_EXTRACHECKS
	i += snprintf(&buf[i], sizeof(buf) - i, "%sEXTRACHECKS",
		(j == i) ? "" : ", ");
#endif

#ifdef CONFIG_SCST_TRACING
	i += snprintf(&buf[i], sizeof(buf) - i, "%sTRACING",
		(j == i) ? "" : ", ");
#endif

#ifdef CONFIG_SCST_DEBUG
	i += snprintf(&buf[i], sizeof(buf) - i, "%sDEBUG",
		(j == i) ? "" : ", ");
#endif

#ifdef CONFIG_SCST_DEBUG_TM
	i += snprintf(&buf[i], sizeof(buf) - i, "%sDEBUG_TM",
		(j == i) ? "" : ", ");
#endif

#ifdef CONFIG_SCST_DEBUG_RETRY
	i += snprintf(&buf[i], sizeof(buf) - i, "%sDEBUG_RETRY",
		(j == i) ? "" : ", ");
#endif

#ifdef CONFIG_SCST_DEBUG_OOM
	i += snprintf(&buf[i], sizeof(buf) - i, "%sDEBUG_OOM",
		(j == i) ? "" : ", ");
#endif

#ifdef CONFIG_SCST_DEBUG_SN
	i += snprintf(&buf[i], sizeof(buf) - i, "%sDEBUG_SN",
		(j == i) ? "" : ", ");
#endif

#ifdef CONFIG_SCST_USE_EXPECTED_VALUES
	i += snprintf(&buf[i], sizeof(buf) - i, "%sUSE_EXPECTED_VALUES",
		(j == i) ? "" : ", ");
#endif

#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
	i += snprintf(&buf[i], sizeof(buf) - i,
		"%sTEST_IO_IN_SIRQ",
		(j == i) ? "" : ", ");
#endif

#ifdef CONFIG_SCST_STRICT_SECURITY
	i += snprintf(&buf[i], sizeof(buf) - i, "%sSTRICT_SECURITY",
		(j == i) ? "" : ", ");
#endif

	if (j != i)
		PRINT_INFO("%s", buf);
}

static int __init init_scst(void)
{
	int res, i;
	int scst_num_cpus;

	TRACE_ENTRY();

	{
		struct scsi_sense_hdr *shdr;
		struct scst_order_data *o;
		struct scst_cmd *c;

		BUILD_BUG_ON(sizeof(*shdr) > SCST_SENSE_BUFFERSIZE);
		BUILD_BUG_ON(sizeof(o->curr_sn) != sizeof(o->expected_sn));
		BUILD_BUG_ON(sizeof(c->sn) != sizeof(o->expected_sn));
	}

	mutex_init(&scst_mutex);
	mutex_init(&scst_mutex2);
	INIT_LIST_HEAD(&scst_template_list);
	INIT_LIST_HEAD(&scst_dev_list);
	INIT_LIST_HEAD(&scst_dev_type_list);
	INIT_LIST_HEAD(&scst_virtual_dev_type_list);
	spin_lock_init(&scst_init_lock);
	init_waitqueue_head(&scst_init_cmd_list_waitQ);
	INIT_LIST_HEAD(&scst_init_cmd_list);
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
	scst_trace_flag = SCST_DEFAULT_LOG_FLAGS;
#endif
	spin_lock_init(&scst_mcmd_lock);
	INIT_LIST_HEAD(&scst_active_mgmt_cmd_list);
	INIT_LIST_HEAD(&scst_delayed_mgmt_cmd_list);
	init_waitqueue_head(&scst_mgmt_cmd_list_waitQ);
	init_waitqueue_head(&scst_mgmt_waitQ);
	spin_lock_init(&scst_mgmt_lock);
	INIT_LIST_HEAD(&scst_sess_init_list);
	INIT_LIST_HEAD(&scst_sess_shut_list);
	init_waitqueue_head(&scst_dev_cmd_waitQ);
	mutex_init(&scst_suspend_mutex);
	mutex_init(&scst_cmd_threads_mutex);
	INIT_LIST_HEAD(&scst_cmd_threads_list);
	cpumask_setall(&default_cpu_mask);
	spin_lock_init(&scst_measure_latency_lock);

	scst_init_threads(&scst_main_cmd_threads);

	res = scst_lib_init();
	if (res != 0)
		goto out_deinit_threads;

	scst_num_cpus = num_online_cpus();

	/* ToDo: register_cpu_notifier() */

	if (scst_threads == 0)
		scst_threads = scst_num_cpus;

	if (scst_threads < 1) {
		PRINT_ERROR("%s", "scst_threads can not be less than 1");
		scst_threads = scst_num_cpus;
	}

/* Used for rarely used or read-mostly on fast path structures */
#define INIT_CACHEP(p, s) ({						\
		(p) = KMEM_CACHE(s, SCST_SLAB_FLAGS);			\
		TRACE_MEM("Slab create: %s at %p size %zd", #s, (p),	\
			  sizeof(struct s));				\
		(p);							\
	})

#define INIT_CACHEP_USERCOPY(p, s, f) ({				\
		(p) = KMEM_CACHE_USERCOPY(s, SCST_SLAB_FLAGS, f);	\
		TRACE_MEM("Slab create: %s at %p size %zd", #s, (p),	\
			  sizeof(struct s));				\
		(p);							\
	})

/* Used for structures with fast path write access */
#define INIT_CACHEP_ALIGN(p, s) ({					\
		(p) = KMEM_CACHE(s, SCST_SLAB_FLAGS|SLAB_HWCACHE_ALIGN);\
		TRACE_MEM("Slab create: %s at %p size %zd", #s, (p),	\
			  sizeof(struct s));				\
		(p);							\
	})
#define INIT_CACHEP_ALIGN_USERCOPY(p, s, f) ({				\
		(p) = KMEM_CACHE_USERCOPY(s, SCST_SLAB_FLAGS |		\
					  SLAB_HWCACHE_ALIGN, f);	\
		TRACE_MEM("Slab create: %s at %p size %zd", #s, (p),	\
			  sizeof(struct s));				\
		(p);							\
	})

	res = -ENOMEM;
	if (!INIT_CACHEP(scst_mgmt_cachep, scst_mgmt_cmd))
		goto out_lib_exit;
	if (!INIT_CACHEP(scst_mgmt_stub_cachep, scst_mgmt_cmd_stub))
		goto out_destroy_mgmt_cache;
	if (!INIT_CACHEP(scst_ua_cachep, scst_tgt_dev_UA))
		goto out_destroy_mgmt_stub_cache;
	{
		struct scst_sense { uint8_t s[SCST_SENSE_BUFFERSIZE]; };
		if (!INIT_CACHEP_USERCOPY(scst_sense_cachep, scst_sense, s))
			goto out_destroy_ua_cache;
	}
	if (!INIT_CACHEP(scst_aen_cachep, scst_aen)) /* read-mostly */
		goto out_destroy_sense_cache;
	if (!INIT_CACHEP_ALIGN_USERCOPY(scst_cmd_cachep, scst_cmd, cdb_buf))
		goto out_destroy_aen_cache;
	/* Big enough with read-mostly head and tail */
	if (!INIT_CACHEP(scst_sess_cachep, scst_session))
		goto out_destroy_cmd_cache;
	if (!INIT_CACHEP(scst_dev_cachep, scst_device)) /* big enough */
		goto out_destroy_sess_cache;
	if (!INIT_CACHEP(scst_tgt_cachep, scst_tgt)) /* read-mostly */
		goto out_destroy_dev_cache;
	/* Big enough with read-mostly head and tail */
	if (!INIT_CACHEP(scst_tgtd_cachep, scst_tgt_dev)) /* big enough */
		goto out_destroy_tgt_cache;
	if (!INIT_CACHEP(scst_acgd_cachep, scst_acg_dev)) /* read-mostly */
		goto out_destroy_tgtd_cache;
	if (!INIT_CACHEP_ALIGN(scst_thr_cachep, scst_cmd_thread_t))
		goto out_destroy_acg_cache;

	scst_mgmt_mempool = mempool_create(64, mempool_alloc_slab,
		mempool_free_slab, scst_mgmt_cachep);
	if (scst_mgmt_mempool == NULL) {
		res = -ENOMEM;
		goto out_destroy_thr_cache;
	}

	/*
	 * All mgmt stubs, UAs and sense buffers are bursty and losing them
	 * may have fatal consequences, so let's have big pools for them.
	 */

	scst_mgmt_stub_mempool = mempool_create(1024, mempool_alloc_slab,
		mempool_free_slab, scst_mgmt_stub_cachep);
	if (scst_mgmt_stub_mempool == NULL) {
		res = -ENOMEM;
		goto out_destroy_mgmt_mempool;
	}

	scst_ua_mempool = mempool_create(512, mempool_alloc_slab,
		mempool_free_slab, scst_ua_cachep);
	if (scst_ua_mempool == NULL) {
		res = -ENOMEM;
		goto out_destroy_mgmt_stub_mempool;
	}

	scst_sense_mempool = mempool_create(1024, mempool_alloc_slab,
		mempool_free_slab, scst_sense_cachep);
	if (scst_sense_mempool == NULL) {
		res = -ENOMEM;
		goto out_destroy_ua_mempool;
	}

	scst_aen_mempool = mempool_create(100, mempool_alloc_slab,
		mempool_free_slab, scst_aen_cachep);
	if (scst_aen_mempool == NULL) {
		res = -ENOMEM;
		goto out_destroy_sense_mempool;
	}

	res = scst_event_init();
	if (res != 0)
		goto out_destroy_aen_mempool;

	res = scst_sysfs_init();
	if (res != 0)
		goto out_event_exit;

	scst_tg_init();

	if (scst_max_cmd_mem == 0) {
		struct sysinfo si;

		si_meminfo(&si);
#if BITS_PER_LONG == 32
		scst_max_cmd_mem = min(
			(((uint64_t)(si.totalram - si.totalhigh) << PAGE_SHIFT)
				>> 20) >> 2, (uint64_t)1 << 30);
#else
		scst_max_cmd_mem = (((si.totalram - si.totalhigh) << PAGE_SHIFT)
					>> 20) >> 2;
#endif
	}

	if (scst_max_dev_cmd_mem != 0) {
		if (scst_max_dev_cmd_mem > scst_max_cmd_mem) {
			PRINT_ERROR("scst_max_dev_cmd_mem (%d) > "
				"scst_max_cmd_mem (%d)",
				scst_max_dev_cmd_mem,
				scst_max_cmd_mem);
			scst_max_dev_cmd_mem = scst_max_cmd_mem;
		}
	} else
		scst_max_dev_cmd_mem = scst_max_cmd_mem * 2 / 5;

	res = scst_sgv_pools_init(
		((uint64_t)scst_max_cmd_mem << 10) >> (PAGE_SHIFT - 10), 0);
	if (res != 0)
		goto out_sysfs_cleanup;


	res = scsi_register_interface(&scst_interface);
	if (res != 0)
		goto out_destroy_sgv_pool;

	for (i = 0; i < ARRAY_SIZE(scst_percpu_infos); i++) {
		atomic_set(&scst_percpu_infos[i].cpu_cmd_count, 0);
		spin_lock_init(&scst_percpu_infos[i].tasklet_lock);
		INIT_LIST_HEAD(&scst_percpu_infos[i].tasklet_cmd_list);
		tasklet_init(&scst_percpu_infos[i].tasklet,
			     (void *)scst_cmd_tasklet,
			     (unsigned long)&scst_percpu_infos[i]);
	}

	TRACE_DBG("%d CPUs found, starting %d threads", scst_num_cpus,
		scst_threads);

	res = scst_start_global_threads(scst_threads);
	if (res < 0)
		goto out_thread_free;


	res = scst_cm_init();
	if (res != 0)
		goto out_thread_free;

#ifdef CONFIG_SCST_NO_TOTAL_MEM_CHECKS
	PRINT_INFO("SCST version %s loaded successfully (global max mem for commands "
		"ignored, per device %dMB)", SCST_VERSION_STRING, scst_max_dev_cmd_mem);
#else
	PRINT_INFO("SCST version %s loaded successfully (max mem for "
		"commands %dMB, per device %dMB)", SCST_VERSION_STRING,
		scst_max_cmd_mem, scst_max_dev_cmd_mem);
#endif

	scst_print_config();

out:
	TRACE_EXIT_RES(res);
	return res;


out_thread_free:
	scst_stop_global_threads();

	scsi_unregister_interface(&scst_interface);


out_destroy_sgv_pool:
	scst_sgv_pools_deinit();
	scst_tg_cleanup();

out_sysfs_cleanup:
	scst_sysfs_cleanup();

out_event_exit:
	scst_event_exit();

out_destroy_aen_mempool:
	mempool_destroy(scst_aen_mempool);

out_destroy_sense_mempool:
	mempool_destroy(scst_sense_mempool);

out_destroy_ua_mempool:
	mempool_destroy(scst_ua_mempool);

out_destroy_mgmt_stub_mempool:
	mempool_destroy(scst_mgmt_stub_mempool);

out_destroy_mgmt_mempool:
	mempool_destroy(scst_mgmt_mempool);

out_destroy_thr_cache:
	kmem_cache_destroy(scst_thr_cachep);

out_destroy_acg_cache:
	kmem_cache_destroy(scst_acgd_cachep);

out_destroy_tgtd_cache:
	kmem_cache_destroy(scst_tgtd_cachep);

out_destroy_tgt_cache:
	kmem_cache_destroy(scst_tgt_cachep);

out_destroy_dev_cache:
	kmem_cache_destroy(scst_dev_cachep);

out_destroy_sess_cache:
	kmem_cache_destroy(scst_sess_cachep);

out_destroy_cmd_cache:
	kmem_cache_destroy(scst_cmd_cachep);

out_destroy_aen_cache:
	kmem_cache_destroy(scst_aen_cachep);

out_destroy_sense_cache:
	kmem_cache_destroy(scst_sense_cachep);

out_destroy_ua_cache:
	kmem_cache_destroy(scst_ua_cachep);

out_destroy_mgmt_stub_cache:
	kmem_cache_destroy(scst_mgmt_stub_cachep);

out_destroy_mgmt_cache:
	kmem_cache_destroy(scst_mgmt_cachep);

out_lib_exit:
	scst_lib_exit();

out_deinit_threads:
	scst_deinit_threads(&scst_main_cmd_threads);
	goto out;
}

static void __exit exit_scst(void)
{
	TRACE_ENTRY();

	/* ToDo: unregister_cpu_notifier() */

	scst_cm_exit();


	scst_stop_global_threads();

	scst_deinit_threads(&scst_main_cmd_threads);

	scsi_unregister_interface(&scst_interface);


	scst_sgv_pools_deinit();

	scst_tg_cleanup();

	scst_sysfs_cleanup();

	scst_event_exit();

	rcu_barrier();

#define DEINIT_CACHEP(p) do {		\
		kmem_cache_destroy(p);	\
		p = NULL;		\
	} while (0)

	mempool_destroy(scst_mgmt_mempool);
	mempool_destroy(scst_mgmt_stub_mempool);
	mempool_destroy(scst_ua_mempool);
	mempool_destroy(scst_sense_mempool);
	mempool_destroy(scst_aen_mempool);

	DEINIT_CACHEP(scst_mgmt_cachep);
	DEINIT_CACHEP(scst_mgmt_stub_cachep);
	DEINIT_CACHEP(scst_ua_cachep);
	DEINIT_CACHEP(scst_sense_cachep);
	DEINIT_CACHEP(scst_aen_cachep);
	DEINIT_CACHEP(scst_cmd_cachep);
	DEINIT_CACHEP(scst_sess_cachep);
	DEINIT_CACHEP(scst_tgtd_cachep);
	DEINIT_CACHEP(scst_dev_cachep);
	DEINIT_CACHEP(scst_tgt_cachep);
	DEINIT_CACHEP(scst_acgd_cachep);
	DEINIT_CACHEP(scst_thr_cachep);

	scst_lib_exit();

	PRINT_INFO("%s", "SCST unloaded");

	TRACE_EXIT();
	return;
}

module_init(init_scst);
module_exit(exit_scst);

MODULE_AUTHOR("Vladislav Bolkhovitin");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SCSI target core");
MODULE_VERSION(SCST_VERSION_STRING);
