linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 08/22] tcm: Add HBA core infrastructure
@ 2010-08-30  9:21 Nicholas A. Bellinger
  0 siblings, 0 replies; only message in thread
From: Nicholas A. Bellinger @ 2010-08-30  9:21 UTC (permalink / raw)
  To: linux-scsi, linux-kernel
  Cc: FUJITA Tomonori, Mike Christie, Christoph Hellwig,
	Hannes Reinecke, James Bottomley, Jens Axboe, Boaz Harrosh,
	Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

This patch adds the core struct se_hba functionality that is used internally by
target_core_mod to group the same subsystem storage objects types until a single
/sys/kernel/config/target/core/$HBA directory.  The HBA code supports boths
physical storage objects (from Linux/SCSI) and virtual storage objects (from Linux/BLOCK,
Linux/VFS, RAMDISK)

Signed-off-by: Nicholas A. Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_hba.c |  211 ++++++++++++++++++++++++++++++++++++++
 drivers/target/target_core_hba.h |   14 +++
 2 files changed, 225 insertions(+), 0 deletions(-)
 create mode 100644 drivers/target/target_core_hba.c
 create mode 100644 drivers/target/target_core_hba.h

diff --git a/drivers/target/target_core_hba.c b/drivers/target/target_core_hba.c
new file mode 100644
index 0000000..d9e286c
--- /dev/null
+++ b/drivers/target/target_core_hba.c
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Filename:  target_core_hba.c
+ *
+ * This file copntains the iSCSI HBA Transport related functions.
+ *
+ * Copyright (c) 2003, 2004, 2005 PyX Technologies, Inc.
+ * Copyright (c) 2005, 2006, 2007 SBE, Inc.
+ * Copyright (c) 2007-2010 Rising Tide Systems
+ * Copyright (c) 2008-2010 Linux-iSCSI.org
+ *
+ * Nicholas A. Bellinger <nab@kernel.org>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ ******************************************************************************/
+
+#include <linux/net.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/in.h>
+#include <net/sock.h>
+#include <net/tcp.h>
+
+#include <target/target_core_base.h>
+#include <target/target_core_device.h>
+#include <target/target_core_device.h>
+#include <target/target_core_tpg.h>
+#include <target/target_core_transport.h>
+
+#include "target_core_hba.h"
+
+int core_get_hba(struct se_hba *hba)
+{
+	return ((mutex_lock_interruptible(&hba->hba_access_mutex) != 0) ?
+		-1 : 0);
+}
+
+struct se_hba *core_alloc_hba(void)
+{
+	struct se_hba *hba;
+
+	hba = kmem_cache_zalloc(se_hba_cache, GFP_KERNEL);
+	if (!(hba)) {
+		printk(KERN_ERR "Unable to allocate struct se_hba\n");
+		return NULL;
+	}
+
+	hba->hba_status |= HBA_STATUS_FREE;
+	INIT_LIST_HEAD(&hba->hba_dev_list);
+	spin_lock_init(&hba->device_lock);
+	spin_lock_init(&hba->hba_queue_lock);
+	mutex_init(&hba->hba_access_mutex);
+	hba->hba_index = scsi_get_new_index(SCSI_INST_INDEX);
+
+	return hba;
+}
+EXPORT_SYMBOL(core_alloc_hba);
+
+void core_put_hba(struct se_hba *hba)
+{
+	mutex_unlock(&hba->hba_access_mutex);
+}
+EXPORT_SYMBOL(core_put_hba);
+
+/*	se_core_add_hba():
+ *
+ *
+ */
+int se_core_add_hba(
+	struct se_hba *hba,
+	const char *plugin_name,
+	u32 plugin_dep_id)
+{
+	struct se_subsystem_api *t;
+	int ret = 0;
+
+	if (hba->hba_status & HBA_STATUS_ACTIVE)
+		return -EEXIST;
+
+	atomic_set(&hba->max_queue_depth, 0);
+	atomic_set(&hba->left_queue_depth, 0);
+
+	t = transport_core_get_sub_by_name(plugin_name);
+	if (!(t))
+		return -EINVAL;
+
+	hba->transport = t;
+	/*
+	 * Get TCM subsystem api struct module reference to struct se_hba
+	 */
+	if (t->external_submod) {
+		if (!(t->sub_owner)) {
+			printk(KERN_ERR "Pointer to struct module does not"
+				" exist for %s\n", t->name);
+			hba->transport = NULL;
+			transport_core_put_sub(t);
+			return -EINVAL;
+		}
+		/*
+		 * Grab a struct module reference count for subsystem plugin
+		 */
+		if (!(try_module_get(t->sub_owner))) {
+			printk(KERN_ERR "try_module_get() failed for"
+				" t->sub_owner\n");
+			hba->transport = NULL;
+			transport_core_put_sub(t);
+			return -EINVAL;
+		}
+	}
+
+	ret = t->attach_hba(hba, plugin_dep_id);
+	if (ret < 0) {
+		hba->transport = NULL;
+		if (t->external_submod)
+			module_put(t->sub_owner);
+		transport_core_put_sub(t);
+		return ret;
+	}
+
+	hba->hba_status &= ~HBA_STATUS_FREE;
+	hba->hba_status |= HBA_STATUS_ACTIVE;
+
+	spin_lock(&se_global->hba_lock);
+	hba->hba_id = se_global->g_hba_id_counter++;
+	list_add_tail(&hba->hba_list, &se_global->g_hba_list);
+	spin_unlock(&se_global->hba_lock);
+
+	printk(KERN_INFO "CORE_HBA[%d] - Attached HBA to Generic Target"
+			" Core\n", hba->hba_id);
+
+	return 0;
+}
+EXPORT_SYMBOL(se_core_add_hba);
+
+static int se_core_shutdown_hba(
+	struct se_hba *hba)
+{
+	struct se_subsystem_api *t = hba->transport;;
+
+	if (t->detach_hba(hba) < 0)
+		return -1;
+	/*
+	 * Release TCM subsystem api struct module reference from struct se_hba
+	 */
+	if (t->external_submod)
+		module_put(t->sub_owner);
+
+	return 0;
+}
+
+/*	se_core_del_hba():
+ *
+ *
+ */
+int se_core_del_hba(
+	struct se_hba *hba)
+{
+	struct se_device *dev, *dev_tmp;
+
+	if (!(hba->hba_status & HBA_STATUS_ACTIVE)) {
+		printk(KERN_ERR "HBA ID: %d Status: INACTIVE, ignoring"
+			" delhbafromtarget request\n", hba->hba_id);
+		return -EINVAL;
+	}
+
+	spin_lock(&hba->device_lock);
+	list_for_each_entry_safe(dev, dev_tmp, &hba->hba_dev_list, dev_list) {
+
+		se_clear_dev_ports(dev);
+		spin_unlock(&hba->device_lock);
+
+		se_release_device_for_hba(dev);
+
+		spin_lock(&hba->device_lock);
+	}
+	spin_unlock(&hba->device_lock);
+
+	se_core_shutdown_hba(hba);
+	if (!(hba->hba_flags & HBA_FLAGS_INTERNAL_USE))
+		transport_core_put_sub(hba->transport);
+
+	spin_lock(&se_global->hba_lock);
+	list_del(&hba->hba_list);
+	spin_unlock(&se_global->hba_lock);
+
+	hba->transport = NULL;
+	hba->hba_status &= ~HBA_STATUS_ACTIVE;
+	hba->hba_status |= HBA_STATUS_FREE;
+
+	printk(KERN_INFO "CORE_HBA[%d] - Detached HBA from Generic Target"
+			" Core\n", hba->hba_id);
+
+	kmem_cache_free(se_hba_cache, hba);
+	return 0;
+}
+EXPORT_SYMBOL(se_core_del_hba);
diff --git a/drivers/target/target_core_hba.h b/drivers/target/target_core_hba.h
new file mode 100644
index 0000000..01cf4fe
--- /dev/null
+++ b/drivers/target/target_core_hba.h
@@ -0,0 +1,14 @@
+#ifndef TARGET_CORE_HBA_H
+#define TARGET_CORE_HBA_H
+
+extern struct se_global *se_global;
+
+extern struct kmem_cache *se_hba_cache;
+
+extern int core_get_hba(struct se_hba *);
+extern struct se_hba *core_alloc_hba(void);
+extern void core_put_hba(struct se_hba *);
+extern int se_core_add_hba(struct se_hba *, const char *, u32);
+extern int se_core_del_hba(struct se_hba *);
+
+#endif /* TARGET_CORE_HBA_H */
-- 
1.7.2.2


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2010-08-30  9:25 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-30  9:21 [RFC 08/22] tcm: Add HBA core infrastructure Nicholas A. Bellinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).