mirror of
https://github.com/SCST-project/scst.git
synced 2026-07-25 01:23:14 +00:00
Merge of the sysfs branch. To enable the sysfs interface you should run "make disable_proc". To switch back on the procfs interface you should run "make disable_proc".
The sysfs intarface is mostly finished. Only initiators-oriented access control not implemented and not all target drivers are updated. Only qla2x00t has been fully updated. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1229 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -301,38 +301,63 @@ mvsas_clean:
|
||||
mvsas_extraclean:
|
||||
cd $(MVSAS_DIR) && $(MAKE) extraclean
|
||||
|
||||
|
||||
debug2perf:
|
||||
echo "Changing current debug state from full debug to full performance"
|
||||
patch -p0 <scst-full_perf.patch
|
||||
patch -p0 <usr-full_perf.patch
|
||||
patch -p0 <qla2x00t-full_perf.patch
|
||||
patch -p0 <iscsi-full_perf.patch
|
||||
patch -p0 <qla_isp-release.patch
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
@if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi
|
||||
# patch -p0 <qla_isp-release.patch
|
||||
# @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi
|
||||
# @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi
|
||||
@if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi
|
||||
@if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi
|
||||
# @if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi
|
||||
|
||||
debug2release:
|
||||
echo "Changing current debug state from full debug to release"
|
||||
patch -p0 <scst-release.patch
|
||||
patch -p0 <usr-release.patch
|
||||
patch -p0 <qla2x00t-release.patch
|
||||
patch -p0 <iscsi-release.patch
|
||||
patch -p0 <qla_isp-release.patch
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
@if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi
|
||||
# patch -p0 <qla_isp-release.patch
|
||||
# @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi
|
||||
# @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi
|
||||
@if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi
|
||||
@if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi
|
||||
# @if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi
|
||||
|
||||
perf2debug:
|
||||
echo "Changing current debug state from full performance to full debug"
|
||||
patch -p0 -R <scst-full_perf.patch
|
||||
patch -p0 -R <usr-full_perf.patch
|
||||
patch -p0 -R <qla2x00t-full_perf.patch
|
||||
patch -p0 -R <iscsi-full_perf.patch
|
||||
patch -p0 -R <qla_isp-release.patch
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
@if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi
|
||||
# patch -p0 -R <qla_isp-release.patch
|
||||
# @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi
|
||||
# @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi
|
||||
@if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi
|
||||
@if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi
|
||||
# @if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi
|
||||
|
||||
release2debug:
|
||||
echo "Changing current debug state from release to full debug"
|
||||
patch -p0 -R <scst-release.patch
|
||||
patch -p0 -R <usr-release.patch
|
||||
patch -p0 -R <qla2x00t-release.patch
|
||||
patch -p0 -R <iscsi-release.patch
|
||||
patch -p0 -R <qla_isp-release.patch
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
@if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi
|
||||
# patch -p0 -R <qla_isp-release.patch
|
||||
# @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi
|
||||
# @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi
|
||||
@if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi
|
||||
@if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi
|
||||
# @if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi
|
||||
|
||||
enable_proc:
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
@if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi
|
||||
# patch -p0 -R <qla_isp-release.patch
|
||||
# @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi
|
||||
# @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi
|
||||
@if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi
|
||||
# @if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi
|
||||
|
||||
disable_proc:
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
@if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi
|
||||
# patch -p0 -R <qla_isp-release.patch
|
||||
# @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi
|
||||
# @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi
|
||||
@if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi
|
||||
# @if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi
|
||||
|
||||
.PHONY: all install uninstall clean extraclean help \
|
||||
qla qla_install qla_uninstall qla_clean qla_extraclean \
|
||||
@@ -345,4 +370,5 @@ release2debug:
|
||||
usr usr_install usr_uninstall usr_clean usr_extraclean \
|
||||
scst_local scst_local_install scst_local_uninstall scst_local_clean scst_local_extraclean \
|
||||
mvsas mvsas_install mvsas_uninstall mvsas_clean mvsas_extraclean \
|
||||
debug2perf, debug2release, perf2debug, release2debug
|
||||
debug2perf, debug2release, perf2debug, release2debug \
|
||||
enable_proc disable_proc
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
Index: iscsi-scst/kernel/Makefile
|
||||
===================================================================
|
||||
--- iscsi-scst/kernel/Makefile (revision 544)
|
||||
+++ iscsi-scst/kernel/Makefile (working copy)
|
||||
@@ -23,9 +23,9 @@
|
||||
EXTRA_CFLAGS += -I$(src)/../include -I$(SCST_INC_DIR)
|
||||
EXTRA_CFLAGS += -Wextra -Wno-unused-parameter -Wno-missing-field-initializers
|
||||
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_TRACING
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_ISCSI_DEBUG_DIGEST_FAILURES
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
Index: iscsi-scst/kernel/Makefile
|
||||
===================================================================
|
||||
--- iscsi-scst/kernel/Makefile (revision 544)
|
||||
+++ iscsi-scst/kernel/Makefile (working copy)
|
||||
@@ -23,9 +23,9 @@
|
||||
EXTRA_CFLAGS += -I$(src)/../include -I$(SCST_INC_DIR)
|
||||
EXTRA_CFLAGS += -Wextra -Wno-unused-parameter -Wno-missing-field-initializers
|
||||
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
-#EXTRA_CFLAGS += -DCONFIG_SCST_TRACING
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
+EXTRA_CFLAGS += -DCONFIG_SCST_TRACING
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_ISCSI_DEBUG_DIGEST_FAILURES
|
||||
|
||||
+40
-3
@@ -14,6 +14,7 @@ SCST_DIR := $(shell pwd)/../scst/src
|
||||
SBINDIR := /usr/local/sbin
|
||||
INITDIR := /etc/init.d
|
||||
RCDIR := /etc/rc.d
|
||||
KMOD := $(shell pwd)/kernel
|
||||
|
||||
ifeq ($(KVER),)
|
||||
ifeq ($(KDIR),)
|
||||
@@ -29,7 +30,7 @@ endif
|
||||
all: include/iscsi_scst_itf_ver.h progs mods
|
||||
|
||||
mods: Modules.symvers Module.symvers
|
||||
$(MAKE) -C $(KDIR) SCST_INC_DIR=$(SCST_INC_DIR) SUBDIRS=$(shell pwd)/kernel modules
|
||||
$(MAKE) -C $(KDIR) SCST_INC_DIR=$(SCST_INC_DIR) SUBDIRS=$(KMOD) modules
|
||||
|
||||
progs:
|
||||
$(MAKE) -C usr
|
||||
@@ -79,11 +80,47 @@ endif
|
||||
|
||||
clean:
|
||||
$(MAKE) -C usr clean
|
||||
$(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd)/kernel clean
|
||||
$(MAKE) -C $(KDIR) SUBDIRS=$(KMOD) clean
|
||||
rm -f kernel/Modules.symvers kernel/Module.symvers \
|
||||
kernel/Module.markers kernel/modules.order \
|
||||
include/iscsi_scst_itf_ver.h
|
||||
|
||||
extraclean: clean
|
||||
|
||||
.PHONY: all mods progs install clean extraclean
|
||||
debug2release:
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ $(KMOD)/Makefile
|
||||
@cmp $(KMOD)/Makefile $(KMOD)/Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm $(KMOD)/Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/"EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/ $(KMOD)/Makefile
|
||||
@cmp $(KMOD)/Makefile $(KMOD)/Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm $(KMOD)/Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ $(KMOD)/Makefile
|
||||
@cmp $(KMOD)/Makefile $(KMOD)/Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm $(KMOD)/Makefile.aa; echo "sed failed"; false; fi
|
||||
rm $(KMOD)/Makefile.aa
|
||||
|
||||
release2debug:
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ $(KMOD)/Makefile
|
||||
@cmp $(KMOD)/Makefile $(KMOD)/Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm $(KMOD)/Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/ $(KMOD)/Makefile
|
||||
@cmp $(KMOD)/Makefile $(KMOD)/Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm $(KMOD)/Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ $(KMOD)/Makefile
|
||||
@cmp $(KMOD)/Makefile $(KMOD)/Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm $(KMOD)/Makefile.aa; echo "sed failed"; false; fi
|
||||
rm $(KMOD)/Makefile.aa
|
||||
|
||||
debug2perf:
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ $(KMOD)/Makefile
|
||||
@cmp $(KMOD)/Makefile $(KMOD)/Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm $(KMOD)/Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ $(KMOD)/Makefile
|
||||
@cmp $(KMOD)/Makefile $(KMOD)/Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm $(KMOD)/Makefile.aa; echo "sed failed"; false; fi
|
||||
rm $(KMOD)/Makefile.aa
|
||||
|
||||
perf2debug:
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ $(KMOD)/Makefile
|
||||
@cmp $(KMOD)/Makefile $(KMOD)/Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm $(KMOD)/Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ $(KMOD)/Makefile
|
||||
@cmp $(KMOD)/Makefile $(KMOD)/Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm $(KMOD)/Makefile.aa; echo "sed failed"; false; fi
|
||||
rm $(KMOD)/Makefile.aa
|
||||
|
||||
disable_proc:
|
||||
|
||||
enable_proc:
|
||||
|
||||
.PHONY: all mods progs install clean extraclean debug2release release2debug debug2perf perf2debug disable_proc enable_proc
|
||||
|
||||
@@ -13,10 +13,12 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
#include "iscsi.h"
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
#define ISCSI_PROC_VERSION_NAME "version"
|
||||
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
@@ -25,7 +27,7 @@
|
||||
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
static struct scst_proc_log iscsi_proc_local_trace_tbl[] =
|
||||
static struct scst_trace_log iscsi_local_trace_tbl[] =
|
||||
{
|
||||
{ TRACE_D_READ, "d_read" },
|
||||
{ TRACE_D_WRITE, "d_write" },
|
||||
@@ -44,7 +46,7 @@ static int iscsi_log_info_show(struct seq_file *seq, void *v)
|
||||
TRACE_ENTRY();
|
||||
|
||||
res = scst_proc_log_entry_read(seq, trace_flag,
|
||||
iscsi_proc_local_trace_tbl);
|
||||
iscsi_local_trace_tbl);
|
||||
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
@@ -58,7 +60,7 @@ static ssize_t iscsi_proc_log_entry_write(struct file *file,
|
||||
TRACE_ENTRY();
|
||||
|
||||
res = scst_proc_log_entry_write(file, buf, length, &trace_flag,
|
||||
ISCSI_DEFAULT_LOG_FLAGS, iscsi_proc_local_trace_tbl);
|
||||
ISCSI_DEFAULT_LOG_FLAGS, iscsi_local_trace_tbl);
|
||||
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
@@ -231,6 +233,8 @@ err:
|
||||
goto out;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
/* target_mutex supposed to be locked */
|
||||
static int add_conn(struct iscsi_target *target, void __user *ptr)
|
||||
{
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "iscsi.h"
|
||||
#include "digest.h"
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
|
||||
static void print_conn_state(char *p, size_t size, struct iscsi_conn *conn)
|
||||
{
|
||||
int printed = 0;
|
||||
@@ -111,6 +113,8 @@ void conn_info_show(struct seq_file *seq, struct iscsi_session *session)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
/* target_mutex supposed to be locked */
|
||||
struct iscsi_conn *conn_lookup(struct iscsi_session *session, u16 cid)
|
||||
{
|
||||
|
||||
@@ -3256,9 +3256,11 @@ static int __init iscsi_init(void)
|
||||
|
||||
iscsi_template_registered = 1;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
err = iscsi_procfs_init();
|
||||
if (err < 0)
|
||||
goto out_reg_tmpl;
|
||||
#endif
|
||||
|
||||
num = max((int)num_online_cpus(), 2);
|
||||
|
||||
@@ -3274,10 +3276,14 @@ out:
|
||||
return err;
|
||||
|
||||
out_thr:
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
iscsi_procfs_exit();
|
||||
#endif
|
||||
iscsi_stop_threads();
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
out_reg_tmpl:
|
||||
#endif
|
||||
scst_unregister_target_template(&iscsi_template);
|
||||
|
||||
out_kmem:
|
||||
@@ -3305,7 +3311,9 @@ static void __exit iscsi_exit(void)
|
||||
|
||||
unregister_chrdev(ctr_major, ctr_name);
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
iscsi_procfs_exit();
|
||||
#endif
|
||||
event_exit();
|
||||
|
||||
kmem_cache_destroy(iscsi_cmnd_cache);
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#define __ISCSI_H__
|
||||
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/net.h>
|
||||
#include <net/sock.h>
|
||||
@@ -439,7 +438,10 @@ extern void __mark_conn_closed(struct iscsi_conn *, int);
|
||||
|
||||
extern void mark_conn_closed(struct iscsi_conn *);
|
||||
extern void iscsi_make_conn_wr_active(struct iscsi_conn *);
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
extern void conn_info_show(struct seq_file *, struct iscsi_session *);
|
||||
#endif
|
||||
|
||||
/* nthread.c */
|
||||
extern int iscsi_send(struct iscsi_conn *conn);
|
||||
@@ -463,8 +465,10 @@ extern void target_del_all(void);
|
||||
extern const struct seq_operations iscsi_seq_op;
|
||||
|
||||
/* config.c */
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
extern int iscsi_procfs_init(void);
|
||||
extern void iscsi_procfs_exit(void);
|
||||
#endif
|
||||
|
||||
/* session.c */
|
||||
extern const struct file_operations session_seq_fops;
|
||||
|
||||
@@ -311,6 +311,8 @@ int session_del(struct iscsi_target *target, u64 sid)
|
||||
return session_free(session, true);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
|
||||
/* target_mutex supposed to be locked */
|
||||
static void iscsi_session_info_show(struct seq_file *seq,
|
||||
struct iscsi_target *target)
|
||||
@@ -345,3 +347,5 @@ const struct file_operations session_seq_fops = {
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
Index: qla2x00t/qla2x00-target/Makefile
|
||||
===================================================================
|
||||
--- qla2x00t/qla2x00-target/Makefile (revision 545)
|
||||
+++ qla2x00t/qla2x00-target/Makefile (working copy)
|
||||
@@ -37,9 +37,9 @@ INSTALL_DIR := /lib/modules/$(shell unam
|
||||
|
||||
EXTRA_CFLAGS += -W -Wno-unused-parameter -Wno-missing-field-initializers
|
||||
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_TRACING
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
#EXTRA_CFLAGS += -DCONFIG_QLA_TGT_DEBUG_WORK_IN_THREAD
|
||||
|
||||
ifeq ($(KVER),)
|
||||
@@ -1,17 +0,0 @@
|
||||
Index: qla2x00t/qla2x00-target/Makefile
|
||||
===================================================================
|
||||
--- qla2x00t/qla2x00-target/Makefile (revision 545)
|
||||
+++ qla2x00t/qla2x00-target/Makefile (working copy)
|
||||
@@ -37,9 +37,9 @@ INSTALL_DIR := /lib/modules/$(shell unam
|
||||
|
||||
EXTRA_CFLAGS += -W -Wno-unused-parameter -Wno-missing-field-initializers
|
||||
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
-#EXTRA_CFLAGS += -DCONFIG_SCST_TRACING
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
+EXTRA_CFLAGS += -DCONFIG_SCST_TRACING
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
#EXTRA_CFLAGS += -DCONFIG_QLA_TGT_DEBUG_WORK_IN_THREAD
|
||||
|
||||
ifeq ($(KVER),)
|
||||
@@ -103,4 +103,46 @@ clean:
|
||||
|
||||
extraclean: clean
|
||||
|
||||
.PHONY: all tgt install uninstall clean extraclean
|
||||
debug2release:
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/"EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
|
||||
release2debug:
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
|
||||
debug2perf:
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
|
||||
perf2debug:
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
|
||||
disable_proc:
|
||||
sed -c -i.aa s/"^#define CONFIG_SCST_PROC"/"\/* #define CONFIG_SCST_PROC *\/"/ ../qla_attr.c
|
||||
@cmp ../qla_attr.c ../qla_attr.c.aa >/dev/null; if [[ $$? = 0 ]]; then rm ../qla_attr.c.aa; echo "sed failed"; false; fi
|
||||
rm ../qla_attr.c.aa
|
||||
|
||||
enable_proc:
|
||||
sed -c -i.aa s/"\/\* #define CONFIG_SCST_PROC \*\/"/"#define CONFIG_SCST_PROC"/ ../qla_attr.c
|
||||
@cmp ../qla_attr.c ../qla_attr.c.aa >/dev/null; if [[ $$? = 0 ]]; then rm ../qla_attr.c.aa; echo "sed failed"; false; fi
|
||||
rm ../qla_attr.c.aa
|
||||
|
||||
.PHONY: all tgt install uninstall clean extraclean debug2perf debug2release perf2debug release2debug disable_proc enable_proc
|
||||
|
||||
+375
-133
@@ -29,7 +29,6 @@
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#include <scst.h>
|
||||
@@ -46,7 +45,7 @@
|
||||
* including rings related fields,
|
||||
*
|
||||
* - Or access to target mode variables from struct q2t_tgt doesn't
|
||||
* cross those functions boundaries, except tgt_shutdown, which
|
||||
* cross those functions boundaries, except tgt_stop, which
|
||||
* additionally protected by irq_cmd_count.
|
||||
*/
|
||||
|
||||
@@ -65,7 +64,7 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static int q2x_target_detect(struct scst_tgt_template *templ);
|
||||
static int q2t_target_detect(struct scst_tgt_template *templ);
|
||||
static int q2t_target_release(struct scst_tgt *scst_tgt);
|
||||
static int q2x_xmit_response(struct scst_cmd *scst_cmd);
|
||||
static int __q24_xmit_response(struct q2t_cmd *cmd, int xmit_type);
|
||||
@@ -96,10 +95,46 @@ static void q2t_clear_tgt_db(struct q2t_tgt *tgt, bool local_only);
|
||||
static void q2t_on_hw_pending_cmd_timeout(struct scst_cmd *scst_cmd);
|
||||
static int q2t_unreg_sess(struct q2t_sess *sess);
|
||||
|
||||
/** SYSFS **/
|
||||
|
||||
static ssize_t q2t_version_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf);
|
||||
|
||||
struct kobj_attribute q2t_version_attr =
|
||||
__ATTR(version, S_IRUGO, q2t_version_show, NULL);
|
||||
|
||||
static const struct attribute *q2t_attrs[] = {
|
||||
&q2t_version_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static ssize_t q2t_show_expl_conf_enabled(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buffer);
|
||||
static ssize_t q2t_store_expl_conf_enabled(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, const char *buffer, size_t size);
|
||||
|
||||
struct kobj_attribute q2t_expl_conf_attr =
|
||||
__ATTR(explicit_confirmation, S_IRUGO|S_IWUSR,
|
||||
q2t_show_expl_conf_enabled, q2t_store_expl_conf_enabled);
|
||||
|
||||
static const struct attribute *q2t_tgt_attrs[] = {
|
||||
&q2t_expl_conf_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static ssize_t q2t_enable_tgt(struct scst_tgt *tgt, const char *buf,
|
||||
size_t size);
|
||||
static bool q2t_is_tgt_enabled(struct scst_tgt *tgt);
|
||||
|
||||
/*
|
||||
* Global Variables
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
#define trace_flag q2t_trace_flag
|
||||
static unsigned long q2t_trace_flag = Q2T_DEFAULT_LOG_FLAGS;
|
||||
#endif
|
||||
|
||||
static struct scst_tgt_template tgt2x_template = {
|
||||
.name = "qla2x00tgt",
|
||||
.sg_tablesize = 0,
|
||||
@@ -112,19 +147,22 @@ static struct scst_tgt_template tgt2x_template = {
|
||||
.rdy_to_xfer_atomic = 1,
|
||||
#endif
|
||||
.max_hw_pending_time = Q2T_MAX_HW_PENDING_TIME,
|
||||
.detect = q2x_target_detect,
|
||||
.detect = q2t_target_detect,
|
||||
.release = q2t_target_release,
|
||||
.xmit_response = q2x_xmit_response,
|
||||
.rdy_to_xfer = q2t_rdy_to_xfer,
|
||||
.on_free_cmd = q2t_on_free_cmd,
|
||||
.task_mgmt_fn_done = q2t_task_mgmt_fn_done,
|
||||
.on_hw_pending_cmd_timeout = q2t_on_hw_pending_cmd_timeout,
|
||||
};
|
||||
|
||||
.enable_tgt = q2t_enable_tgt,
|
||||
.is_tgt_enabled = q2t_is_tgt_enabled,
|
||||
.tgtt_attrs = q2t_attrs,
|
||||
.tgt_attrs = q2t_tgt_attrs,
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
#define trace_flag q2t_trace_flag
|
||||
static unsigned long q2t_trace_flag = Q2T_DEFAULT_LOG_FLAGS;
|
||||
.default_trace_flags = Q2T_DEFAULT_LOG_FLAGS,
|
||||
.trace_flags = &trace_flag,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct kmem_cache *q2t_cmd_cachep;
|
||||
static struct kmem_cache *q2t_mgmt_cmd_cachep;
|
||||
@@ -224,7 +262,7 @@ static inline int q2t_issue_marker(scsi_qla_host_t *ha, int ha_locked)
|
||||
* Registers with initiator driver (but target mode isn't enabled till
|
||||
* it's turned on via sysfs)
|
||||
*/
|
||||
static int q2x_target_detect(struct scst_tgt_template *templ)
|
||||
static int q2t_target_detect(struct scst_tgt_template *tgtt)
|
||||
{
|
||||
int res;
|
||||
struct qla_tgt_data t = {
|
||||
@@ -253,6 +291,8 @@ static int q2x_target_detect(struct scst_tgt_template *templ)
|
||||
goto out;
|
||||
}
|
||||
|
||||
qla2xxx_add_targets();
|
||||
|
||||
PRINT_INFO("%s", "Target mode driver for QLogic 2x00 controller "
|
||||
"registered successfully");
|
||||
|
||||
@@ -622,7 +662,7 @@ static void q2t_fc_port_added(scsi_qla_host_t *ha, fc_port_t *fcport)
|
||||
if ((tgt == NULL) || (fcport->port_type != FCT_INITIATOR))
|
||||
goto out_unlock;
|
||||
|
||||
if (tgt->tgt_shutdown)
|
||||
if (tgt->tgt_stop)
|
||||
goto out_unlock;
|
||||
|
||||
spin_lock_irq(&ha->hardware_lock);
|
||||
@@ -686,7 +726,7 @@ static void q2t_fc_port_deleted(scsi_qla_host_t *ha, fc_port_t *fcport)
|
||||
|
||||
dev_loss_tmo = ha->port_down_retry_count + 5;
|
||||
|
||||
if (tgt->tgt_shutdown)
|
||||
if (tgt->tgt_stop)
|
||||
goto out_unlock;
|
||||
|
||||
spin_lock_irq(&ha->hardware_lock);
|
||||
@@ -747,15 +787,16 @@ static inline int test_tgt_sess_count(struct q2t_tgt *tgt)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Must be called under read locked q2t_unreg_rwsem */
|
||||
static int q2t_target_release(struct scst_tgt *scst_tgt)
|
||||
/* Must be called under tgt_host_action_mutex */
|
||||
static void q2t_target_stop(struct scst_tgt *scst_tgt)
|
||||
{
|
||||
int res = 0;
|
||||
struct q2t_tgt *tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt);
|
||||
scsi_qla_host_t *ha = tgt->ha;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
TRACE_DBG("Stopping target for host %ld(%p)", ha->host_no, ha);
|
||||
|
||||
/*
|
||||
* Mutex needed to sync with q2t_fc_port_[added,deleted].
|
||||
* Lock is needed, because we still can get an incoming packet.
|
||||
@@ -763,7 +804,7 @@ static int q2t_target_release(struct scst_tgt *scst_tgt)
|
||||
|
||||
mutex_lock(&ha->tgt_mutex);
|
||||
spin_lock_irq(&ha->hardware_lock);
|
||||
tgt->tgt_shutdown = 1;
|
||||
tgt->tgt_stop = 1;
|
||||
q2t_clear_tgt_db(tgt, false);
|
||||
spin_unlock_irq(&ha->hardware_lock);
|
||||
mutex_unlock(&ha->tgt_mutex);
|
||||
@@ -786,7 +827,7 @@ static int q2t_target_release(struct scst_tgt *scst_tgt)
|
||||
wait_event(tgt->waitQ, test_tgt_sess_count(tgt));
|
||||
|
||||
/* Big hammer */
|
||||
if (!ha->host_shutting_down)
|
||||
if (!ha->host_shutting_down && qla_tgt_mode_enabled(ha))
|
||||
qla2x00_disable_tgt_mode(ha);
|
||||
|
||||
/* Wait for sessions to clear out (just in case) */
|
||||
@@ -802,17 +843,35 @@ static int q2t_target_release(struct scst_tgt *scst_tgt)
|
||||
udelay(2);
|
||||
spin_lock_irq(&ha->hardware_lock);
|
||||
}
|
||||
scst_tgt_set_tgt_priv(scst_tgt, NULL);
|
||||
ha->tgt = NULL;
|
||||
spin_unlock_irq(&ha->hardware_lock);
|
||||
mutex_unlock(&ha->tgt_mutex);
|
||||
|
||||
TRACE_MGMT_DBG("Stop of tgt %p finished", tgt);
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Must be called under tgt_host_action_mutex */
|
||||
static int q2t_target_release(struct scst_tgt *scst_tgt)
|
||||
{
|
||||
struct q2t_tgt *tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt);
|
||||
scsi_qla_host_t *ha = tgt->ha;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
q2t_target_stop(scst_tgt);
|
||||
|
||||
ha->q2t_tgt = NULL;
|
||||
scst_tgt_set_tgt_priv(scst_tgt, NULL);
|
||||
|
||||
TRACE_MGMT_DBG("Release of tgt %p finished", tgt);
|
||||
|
||||
kfree(tgt);
|
||||
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
TRACE_EXIT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1238,7 +1297,7 @@ out:
|
||||
|
||||
uint32_t q2t_convert_to_fc_tm_status(int scst_mstatus)
|
||||
{
|
||||
int res;
|
||||
uint32_t res;
|
||||
|
||||
switch (scst_mstatus) {
|
||||
case SCST_MGMT_STATUS_SUCCESS:
|
||||
@@ -3039,7 +3098,7 @@ static int q2t_send_cmd_to_scst(scsi_qla_host_t *ha, atio_t *atio)
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
if (unlikely(tgt->tgt_shutdown)) {
|
||||
if (unlikely(tgt->tgt_stop)) {
|
||||
TRACE_MGMT_DBG("New command while device %p is shutting "
|
||||
"down", tgt);
|
||||
res = -EFAULT;
|
||||
@@ -4176,7 +4235,7 @@ static void q24_atio_pkt(scsi_qla_host_t *ha, atio7_entry_t *atio)
|
||||
atio, atio->entry_type, atio->entry_count);
|
||||
|
||||
/*
|
||||
* In tgt_shutdown mode we also should allow all requests to pass.
|
||||
* In tgt_stop mode we also should allow all requests to pass.
|
||||
* Otherwise, some commands can stuck.
|
||||
*/
|
||||
|
||||
@@ -4278,7 +4337,7 @@ static void q2t_response_pkt(scsi_qla_host_t *ha, response_t *pkt)
|
||||
pkt->handle);
|
||||
|
||||
/*
|
||||
* In tgt_shutdown mode we also should allow all requests to pass.
|
||||
* In tgt_stop mode we also should allow all requests to pass.
|
||||
* Otherwise, some commands can stuck.
|
||||
*/
|
||||
|
||||
@@ -4523,7 +4582,7 @@ static void q2t_async_event(uint16_t code, scsi_qla_host_t *ha,
|
||||
}
|
||||
|
||||
/*
|
||||
* In tgt_shutdown mode we also should allow all requests to pass.
|
||||
* In tgt_stop mode we also should allow all requests to pass.
|
||||
* Otherwise, some commands can stuck.
|
||||
*/
|
||||
|
||||
@@ -4696,7 +4755,7 @@ static struct q2t_sess *q2t_make_local_sess(scsi_qla_host_t *ha, atio_t *atio)
|
||||
if (rc != QLA_SUCCESS) {
|
||||
PRINT_ERROR("Failed to retrieve fcport information "
|
||||
"-- get_port_database() returned %x "
|
||||
"(loop_id=0x%04x)\n", rc, loop_id);
|
||||
"(loop_id=0x%04x)", rc, loop_id);
|
||||
goto out_free_fcport;
|
||||
}
|
||||
|
||||
@@ -4726,7 +4785,7 @@ static int q2t_exec_sess_work(struct q2t_tgt *tgt,
|
||||
mutex_lock(&ha->tgt_mutex);
|
||||
spin_lock_irq(&ha->hardware_lock);
|
||||
|
||||
if (tgt->tgt_shutdown)
|
||||
if (tgt->tgt_stop)
|
||||
goto send;
|
||||
|
||||
if (IS_FWI2_CAPABLE(ha)) {
|
||||
@@ -4751,7 +4810,7 @@ static int q2t_exec_sess_work(struct q2t_tgt *tgt,
|
||||
}
|
||||
|
||||
send:
|
||||
if (!tgt->tm_to_unknown && !tgt->tgt_shutdown && (sess != NULL)) {
|
||||
if (!tgt->tm_to_unknown && !tgt->tgt_stop && (sess != NULL)) {
|
||||
TRACE_MGMT_DBG("Sending work cmd %p to SCST", cmd);
|
||||
res = q2t_do_send_cmd_to_scst(ha, cmd, sess);
|
||||
} else {
|
||||
@@ -4891,11 +4950,135 @@ out_unlock:
|
||||
return;
|
||||
}
|
||||
|
||||
/* No lock held on entry, process context */
|
||||
/* Must be called under tgt_host_action_mutex */
|
||||
static int q2t_add_target(scsi_qla_host_t *ha)
|
||||
{
|
||||
int res, rc;
|
||||
char *wwn;
|
||||
int sg_tablesize;
|
||||
struct q2t_tgt *tgt;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
TRACE_DBG("Registering target for host %ld(%p)", ha->host_no, ha);
|
||||
|
||||
sBUG_ON((ha->q2t_tgt != NULL) || (ha->tgt != NULL));
|
||||
|
||||
tgt = kzalloc(sizeof(*tgt), GFP_KERNEL);
|
||||
if (tgt == NULL) {
|
||||
TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of tgt "
|
||||
"failed");
|
||||
res = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
tgt->ha = ha;
|
||||
init_waitqueue_head(&tgt->waitQ);
|
||||
INIT_LIST_HEAD(&tgt->sess_list);
|
||||
INIT_LIST_HEAD(&tgt->del_sess_list);
|
||||
init_timer(&tgt->sess_del_timer);
|
||||
tgt->sess_del_timer.data = (unsigned long)tgt;
|
||||
tgt->sess_del_timer.function = q2t_del_sess_timer_fn;
|
||||
spin_lock_init(&tgt->sess_work_lock);
|
||||
INIT_WORK(&tgt->sess_work, q2t_sess_work_fn);
|
||||
INIT_LIST_HEAD(&tgt->sess_works_list);
|
||||
spin_lock_init(&tgt->srr_lock);
|
||||
INIT_LIST_HEAD(&tgt->srr_ctio_list);
|
||||
INIT_LIST_HEAD(&tgt->srr_imm_list);
|
||||
INIT_WORK(&tgt->srr_work, q2t_handle_srr_work);
|
||||
|
||||
ha->q2t_tgt = tgt;
|
||||
|
||||
if (q2t_get_target_name(ha, &wwn) != 0)
|
||||
goto out_free;
|
||||
|
||||
tgt->scst_tgt = scst_register(&tgt2x_template, wwn);
|
||||
|
||||
kfree(wwn);
|
||||
|
||||
if (!tgt->scst_tgt) {
|
||||
PRINT_ERROR("qla2x00tgt(%ld): scst_register() "
|
||||
"failed for host %ld(%p)", ha->instance,
|
||||
ha->host_no, ha);
|
||||
res = -ENOMEM;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (IS_FWI2_CAPABLE(ha)) {
|
||||
PRINT_INFO("qla2400tgt(%ld): using 64 Bit PCI "
|
||||
"addressing", ha->instance);
|
||||
tgt->tgt_enable_64bit_addr = 1;
|
||||
/* 3 is reserved */
|
||||
sg_tablesize =
|
||||
QLA_MAX_SG_24XX(ha->request_q_length - 3);
|
||||
tgt->datasegs_per_cmd = DATASEGS_PER_COMMAND_24XX;
|
||||
tgt->datasegs_per_cont = DATASEGS_PER_CONT_24XX;
|
||||
} else {
|
||||
if (ha->flags.enable_64bit_addressing) {
|
||||
PRINT_INFO("qla2x00tgt(%ld): 64 Bit PCI "
|
||||
"addressing enabled", ha->instance);
|
||||
tgt->tgt_enable_64bit_addr = 1;
|
||||
/* 3 is reserved */
|
||||
sg_tablesize =
|
||||
QLA_MAX_SG64(ha->request_q_length - 3);
|
||||
tgt->datasegs_per_cmd = DATASEGS_PER_COMMAND64;
|
||||
tgt->datasegs_per_cont = DATASEGS_PER_CONT64;
|
||||
} else {
|
||||
PRINT_INFO("qla2x00tgt(%ld): Using 32 Bit "
|
||||
"PCI addressing", ha->instance);
|
||||
sg_tablesize =
|
||||
QLA_MAX_SG32(ha->request_q_length - 3);
|
||||
tgt->datasegs_per_cmd = DATASEGS_PER_COMMAND32;
|
||||
tgt->datasegs_per_cont = DATASEGS_PER_CONT32;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SCST_PROC
|
||||
rc = sysfs_create_link(scst_sysfs_get_tgt_kobj(tgt->scst_tgt),
|
||||
&ha->host->shost_dev.kobj, "host");
|
||||
if (rc != 0)
|
||||
PRINT_ERROR("Unable to create \"host\" link for target "
|
||||
"%s", scst_get_tgt_name(tgt->scst_tgt));
|
||||
#endif
|
||||
|
||||
scst_tgt_set_sg_tablesize(tgt->scst_tgt, sg_tablesize);
|
||||
scst_tgt_set_tgt_priv(tgt->scst_tgt, tgt);
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
|
||||
out_free:
|
||||
ha->q2t_tgt = NULL;
|
||||
kfree(tgt);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Must be called under tgt_host_action_mutex */
|
||||
static int q2t_remove_target(scsi_qla_host_t *ha)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
if ((ha->q2t_tgt == NULL) || (ha->tgt != NULL)) {
|
||||
PRINT_ERROR("qla2x00tgt(%ld): Can't remove "
|
||||
"existing target", ha->instance);
|
||||
}
|
||||
|
||||
TRACE_DBG("Unregistering target for host %ld(%p)", ha->host_no, ha);
|
||||
scst_unregister(ha->tgt->scst_tgt);
|
||||
/*
|
||||
* Free of tgt happens via callback q2t_target_release
|
||||
* called from scst_unregister, so we shouldn't touch
|
||||
* it again.
|
||||
*/
|
||||
|
||||
TRACE_EXIT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int q2t_host_action(scsi_qla_host_t *ha,
|
||||
qla2x_tgt_host_action_t action)
|
||||
qla2x_tgt_host_action_t action)
|
||||
{
|
||||
struct q2t_tgt *tgt = NULL;
|
||||
int res = 0;
|
||||
|
||||
TRACE_ENTRY();
|
||||
@@ -4903,14 +5086,21 @@ static int q2t_host_action(scsi_qla_host_t *ha,
|
||||
sBUG_ON(ha == NULL);
|
||||
|
||||
/* To sync with q2t_exit() */
|
||||
down_read(&q2t_unreg_rwsem);
|
||||
if (down_read_trylock(&q2t_unreg_rwsem) == 0)
|
||||
goto out;
|
||||
|
||||
mutex_lock(&ha->tgt_host_action_mutex);
|
||||
|
||||
switch (action) {
|
||||
case ADD_TARGET:
|
||||
res = q2t_add_target(ha);
|
||||
break;
|
||||
case REMOVE_TARGET:
|
||||
res = q2t_remove_target(ha);
|
||||
break;
|
||||
case ENABLE_TARGET_MODE:
|
||||
{
|
||||
fc_port_t *fcport;
|
||||
char *wwn;
|
||||
int sg_tablesize;
|
||||
|
||||
if (qla_tgt_mode_enabled(ha)) {
|
||||
PRINT_INFO("qla2x00tgt(%ld): Target mode already "
|
||||
@@ -4918,103 +5108,22 @@ static int q2t_host_action(scsi_qla_host_t *ha,
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ha->q2t_tgt == NULL) || (ha->tgt != NULL)) {
|
||||
PRINT_ERROR("qla2x00tgt(%ld): Can't enable target mode "
|
||||
"for not existing target", ha->instance);
|
||||
break;
|
||||
}
|
||||
|
||||
PRINT_INFO("qla2x00tgt(%ld): Enabling target mode",
|
||||
ha->instance);
|
||||
|
||||
if (ha->tgt != NULL)
|
||||
goto do_enable;
|
||||
|
||||
tgt = kzalloc(sizeof(*tgt), GFP_KERNEL);
|
||||
if (tgt == NULL) {
|
||||
TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of tgt "
|
||||
"failed");
|
||||
res = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
tgt->ha = ha;
|
||||
init_waitqueue_head(&tgt->waitQ);
|
||||
INIT_LIST_HEAD(&tgt->sess_list);
|
||||
INIT_LIST_HEAD(&tgt->del_sess_list);
|
||||
init_timer(&tgt->sess_del_timer);
|
||||
tgt->sess_del_timer.data = (unsigned long)tgt;
|
||||
tgt->sess_del_timer.function = q2t_del_sess_timer_fn;
|
||||
spin_lock_init(&tgt->sess_work_lock);
|
||||
INIT_WORK(&tgt->sess_work, q2t_sess_work_fn);
|
||||
INIT_LIST_HEAD(&tgt->sess_works_list);
|
||||
spin_lock_init(&tgt->srr_lock);
|
||||
INIT_LIST_HEAD(&tgt->srr_ctio_list);
|
||||
INIT_LIST_HEAD(&tgt->srr_imm_list);
|
||||
INIT_WORK(&tgt->srr_work, q2t_handle_srr_work);
|
||||
|
||||
if (q2t_get_target_name(ha, &wwn) != 0) {
|
||||
kfree(tgt);
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_lock(&ha->tgt_mutex);
|
||||
|
||||
tgt->scst_tgt = scst_register(&tgt2x_template, wwn);
|
||||
|
||||
/*
|
||||
* scst_tgt protected by tgt_mutex from not get freed before
|
||||
* been initialized
|
||||
*/
|
||||
|
||||
kfree(wwn);
|
||||
|
||||
if (!tgt->scst_tgt) {
|
||||
PRINT_ERROR("qla2x00tgt(%ld): scst_register() "
|
||||
"failed for host %ld(%p)", ha->instance,
|
||||
ha->host_no, ha);
|
||||
kfree(tgt);
|
||||
res = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (IS_FWI2_CAPABLE(ha)) {
|
||||
PRINT_INFO("qla2400tgt(%ld): using 64 Bit PCI "
|
||||
"addressing", ha->instance);
|
||||
tgt->tgt_enable_64bit_addr = 1;
|
||||
/* 3 is reserved */
|
||||
sg_tablesize =
|
||||
QLA_MAX_SG_24XX(ha->request_q_length - 3);
|
||||
tgt->datasegs_per_cmd = DATASEGS_PER_COMMAND_24XX;
|
||||
tgt->datasegs_per_cont = DATASEGS_PER_CONT_24XX;
|
||||
} else {
|
||||
if (ha->flags.enable_64bit_addressing) {
|
||||
PRINT_INFO("qla2x00tgt(%ld): 64 Bit PCI "
|
||||
"addressing enabled", ha->instance);
|
||||
tgt->tgt_enable_64bit_addr = 1;
|
||||
/* 3 is reserved */
|
||||
sg_tablesize =
|
||||
QLA_MAX_SG64(ha->request_q_length - 3);
|
||||
tgt->datasegs_per_cmd = DATASEGS_PER_COMMAND64;
|
||||
tgt->datasegs_per_cont = DATASEGS_PER_CONT64;
|
||||
} else {
|
||||
PRINT_INFO("qla2x00tgt(%ld): Using 32 Bit "
|
||||
"PCI addressing", ha->instance);
|
||||
sg_tablesize =
|
||||
QLA_MAX_SG32(ha->request_q_length - 3);
|
||||
tgt->datasegs_per_cmd = DATASEGS_PER_COMMAND32;
|
||||
tgt->datasegs_per_cont = DATASEGS_PER_CONT32;
|
||||
}
|
||||
}
|
||||
|
||||
scst_tgt_set_sg_tablesize(tgt->scst_tgt, sg_tablesize);
|
||||
scst_tgt_set_tgt_priv(tgt->scst_tgt, tgt);
|
||||
|
||||
spin_lock_irq(&ha->hardware_lock);
|
||||
ha->tgt = tgt;
|
||||
ha->tgt = ha->q2t_tgt;
|
||||
ha->tgt->tgt_stop = 0;
|
||||
spin_unlock_irq(&ha->hardware_lock);
|
||||
|
||||
mutex_unlock(&ha->tgt_mutex);
|
||||
|
||||
list_for_each_entry_rcu(fcport, &ha->fcports, list) {
|
||||
q2t_fc_port_added(ha, fcport);
|
||||
}
|
||||
|
||||
do_enable:
|
||||
TRACE_DBG("Enable tgt mode for host %ld(%ld,%p)",
|
||||
ha->host_no, ha->instance, ha);
|
||||
qla2x00_enable_tgt_mode(ha);
|
||||
@@ -5033,14 +5142,7 @@ do_enable:
|
||||
|
||||
sBUG_ON(ha->tgt == NULL);
|
||||
|
||||
TRACE_DBG("Unregistering target for host %ld(%p)",
|
||||
ha->host_no, ha);
|
||||
scst_unregister(ha->tgt->scst_tgt);
|
||||
/*
|
||||
* Free of tgt happens via callback q2t_target_release
|
||||
* called from scst_unregister, so we shouldn't touch
|
||||
* it again.
|
||||
*/
|
||||
q2t_target_stop(ha->tgt->scst_tgt);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -5050,12 +5152,137 @@ do_enable:
|
||||
break;
|
||||
}
|
||||
|
||||
up_read(&q2t_unreg_rwsem);
|
||||
mutex_unlock(&ha->tgt_host_action_mutex);
|
||||
|
||||
up_read(&q2t_unreg_rwsem);
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static ssize_t q2t_enable_tgt(struct scst_tgt *scst_tgt, const char *buffer,
|
||||
size_t size)
|
||||
{
|
||||
struct q2t_tgt *tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt);
|
||||
scsi_qla_host_t *ha = tgt->ha;
|
||||
int res = 0;
|
||||
|
||||
switch (buffer[0]) {
|
||||
case '0' :
|
||||
res = q2t_host_action(ha, DISABLE_TARGET_MODE);
|
||||
break;
|
||||
case '1' :
|
||||
res = q2t_host_action(ha, ENABLE_TARGET_MODE);
|
||||
break;
|
||||
default:
|
||||
PRINT_ERROR("%s: Requested action not understood: %s",
|
||||
__func__, buffer);
|
||||
res = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (res == 0)
|
||||
res = size;
|
||||
|
||||
if ((size > 1) && (buffer[1] == 'r')) {
|
||||
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
||||
qla2x00_wait_for_hba_online(ha);
|
||||
}
|
||||
|
||||
out:
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool q2t_is_tgt_enabled(struct scst_tgt *scst_tgt)
|
||||
{
|
||||
struct q2t_tgt *tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt);
|
||||
scsi_qla_host_t *ha = tgt->ha;
|
||||
|
||||
return qla_tgt_mode_enabled(ha);
|
||||
}
|
||||
|
||||
static ssize_t q2t_show_expl_conf_enabled(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buffer)
|
||||
{
|
||||
struct scst_tgt *scst_tgt;
|
||||
struct q2t_tgt *tgt;
|
||||
scsi_qla_host_t *ha;
|
||||
ssize_t size;
|
||||
|
||||
scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
|
||||
tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt);
|
||||
ha = tgt->ha;
|
||||
|
||||
size = scnprintf(buffer, PAGE_SIZE, "%d\n", ha->enable_explicit_conf);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t q2t_store_expl_conf_enabled(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, const char *buffer, size_t size)
|
||||
{
|
||||
struct scst_tgt *scst_tgt;
|
||||
struct q2t_tgt *tgt;
|
||||
scsi_qla_host_t *ha;
|
||||
unsigned long flags;
|
||||
|
||||
scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
|
||||
tgt = (struct q2t_tgt *)scst_tgt_get_tgt_priv(scst_tgt);
|
||||
ha = tgt->ha;
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
|
||||
switch (buffer[0]) {
|
||||
case '0' :
|
||||
ha->enable_explicit_conf = 0;
|
||||
PRINT_INFO("qla2xxx(%ld): explicit conformations disabled",
|
||||
ha->instance);
|
||||
break;
|
||||
case '1' :
|
||||
ha->enable_explicit_conf = 1;
|
||||
PRINT_INFO("qla2xxx(%ld): explicit conformations enabled",
|
||||
ha->instance);
|
||||
break;
|
||||
default:
|
||||
#if defined(QL_DEBUG_LEVEL_9) || defined(QL_DEBUG_LEVEL_11)
|
||||
PRINT_INFO("%s: Requested action not understood: %s",
|
||||
__func__, buffer);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t q2t_version_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
sprintf(buf, "%s\n", Q2T_VERSION_STRING);
|
||||
|
||||
#ifdef CONFIG_SCST_EXTRACHECKS
|
||||
strcat(buf, "EXTRACHECKS\n");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCST_TRACING
|
||||
strcat(buf, "TRACING\n");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCST_DEBUG
|
||||
strcat(buf, "DEBUG\n");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_QLA_TGT_DEBUG_WORK_IN_THREAD
|
||||
strcat(buf, "QLA_TGT_DEBUG_WORK_IN_THREAD\n");
|
||||
#endif
|
||||
|
||||
TRACE_EXIT();
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
|
||||
#define Q2T_PROC_LOG_ENTRY_NAME "trace_level"
|
||||
@@ -5194,6 +5421,8 @@ static void q2t_proc_log_entry_clean(struct scst_tgt_template *templ)
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
static int __init q2t_init(void)
|
||||
{
|
||||
int res = 0;
|
||||
@@ -5233,15 +5462,19 @@ static int __init q2t_init(void)
|
||||
* called via scst_register_target_template()
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
res = q2t_proc_log_entry_build(&tgt2x_template);
|
||||
if (res < 0)
|
||||
goto out_unreg_target2x;
|
||||
#endif
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
out_unreg_target2x:
|
||||
#endif
|
||||
scst_unregister_target_template(&tgt2x_template);
|
||||
qla2xxx_tgt_unregister_driver();
|
||||
|
||||
@@ -5266,17 +5499,26 @@ static void __exit q2t_exit(void)
|
||||
/* To sync with q2t_host_action() */
|
||||
down_write(&q2t_unreg_rwsem);
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
q2t_proc_log_entry_clean(&tgt2x_template);
|
||||
#endif
|
||||
|
||||
scst_unregister_target_template(&tgt2x_template);
|
||||
|
||||
up_write(&q2t_unreg_rwsem);
|
||||
|
||||
/*
|
||||
* Now we have everywhere target mode disabled and no possibilities
|
||||
* to call us through sysfs, so we can safely remove all the references
|
||||
* to our functions.
|
||||
*/
|
||||
qla2xxx_tgt_unregister_driver();
|
||||
|
||||
mempool_destroy(q2t_mgmt_cmd_mempool);
|
||||
kmem_cache_destroy(q2t_mgmt_cmd_cachep);
|
||||
kmem_cache_destroy(q2t_cmd_cachep);
|
||||
|
||||
/* Let's make lockdep happy */
|
||||
up_write(&q2t_unreg_rwsem);
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ struct q2t_tgt {
|
||||
* Protected by tgt_mutex AND hardware_lock for writing and tgt_mutex
|
||||
* OR hardware_lock for reading.
|
||||
*/
|
||||
unsigned long tgt_shutdown; /* the driver is being released */
|
||||
unsigned long tgt_stop; /* the driver is being stopped */
|
||||
|
||||
/* Count of sessions refering q2t_tgt. Protected by hardware_lock. */
|
||||
int sess_count;
|
||||
@@ -162,6 +162,8 @@ struct q2t_tgt {
|
||||
struct list_head srr_ctio_list;
|
||||
struct list_head srr_imm_list;
|
||||
struct work_struct srr_work;
|
||||
|
||||
struct list_head tgt_list_entry;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -129,6 +129,8 @@ qla2x00_send_enable_lun(scsi_qla_host_t *ha, bool enable)
|
||||
}
|
||||
}
|
||||
|
||||
extern void qla2xxx_add_targets(void);
|
||||
|
||||
#endif /* CONFIG_SCSI_QLA2XXX_TARGET */
|
||||
|
||||
#endif /* __QLA2X_TGT_H */
|
||||
|
||||
@@ -44,13 +44,13 @@
|
||||
* Must be changed on any change in any initiator visible interfaces or
|
||||
* data in the target add-on
|
||||
*/
|
||||
#define QLA2X_TARGET_MAGIC 264
|
||||
#define QLA2X_TARGET_MAGIC 265
|
||||
|
||||
/*
|
||||
* Must be changed on any change in any target visible interfaces or
|
||||
* data in the initiator
|
||||
*/
|
||||
#define QLA2X_INITIATOR_MAGIC 57217
|
||||
#define QLA2X_INITIATOR_MAGIC 57218
|
||||
|
||||
#define QLA2X00_COMMAND_COUNT_INIT 250
|
||||
#define QLA2X00_IMMED_NOTIFY_COUNT_INIT 250
|
||||
@@ -689,8 +689,10 @@ typedef struct {
|
||||
\********************************************************************/
|
||||
|
||||
typedef enum {
|
||||
DISABLE_TARGET_MODE = 0,
|
||||
ENABLE_TARGET_MODE = 1
|
||||
ADD_TARGET = 0,
|
||||
REMOVE_TARGET,
|
||||
DISABLE_TARGET_MODE,
|
||||
ENABLE_TARGET_MODE,
|
||||
} qla2x_tgt_host_action_t;
|
||||
|
||||
/* Changing it don't forget to change QLA2X_TARGET_MAGIC! */
|
||||
|
||||
+9
-1
@@ -96,6 +96,10 @@ static DEVICE_ATTR(class2_enabled,
|
||||
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
|
||||
|
||||
#define CONFIG_SCST_PROC
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
|
||||
static ssize_t
|
||||
qla2x00_show_tgt_enabled(struct device *dev,
|
||||
struct device_attribute *attr, char *buffer)
|
||||
@@ -208,6 +212,8 @@ static DEVICE_ATTR(explicit_conform_enabled,
|
||||
qla2x00_show_expl_conf_enabled,
|
||||
qla2x00_store_expl_conf_enabled);
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
static ssize_t
|
||||
qla2x00_show_resource_counts(struct device *dev,
|
||||
struct device_attribute *attr, char *buffer)
|
||||
@@ -377,7 +383,7 @@ out_free:
|
||||
gid = (struct gid_list_info *)id_iter;
|
||||
if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
|
||||
size += scnprintf(buffer+size, max_size-size,
|
||||
" %02x %02x%02x%02x\n",
|
||||
"%02x %02x%02x%02x\n",
|
||||
gid->loop_id_2100,
|
||||
gid->domain,
|
||||
gid->area,
|
||||
@@ -1332,8 +1338,10 @@ struct device_attribute *qla2x00_host_attrs[] = {
|
||||
&dev_attr_optrom_fw_version,
|
||||
&dev_attr_class2_enabled,
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
&dev_attr_target_mode_enabled,
|
||||
&dev_attr_explicit_conform_enabled,
|
||||
#endif
|
||||
&dev_attr_resource_counts,
|
||||
&dev_attr_port_database,
|
||||
#endif
|
||||
|
||||
+9
-3
@@ -2447,8 +2447,7 @@ typedef struct scsi_qla_host {
|
||||
* accessed from many contexts, including concurrently. Seems, the
|
||||
* original author of this code thought that if anything never deleted
|
||||
* from this list, it is always safe to travel over it without any
|
||||
* protection. Obviously, this isn't true. (The whole decision to keep
|
||||
* stale entries forever is quite questionable as well.) We will fix
|
||||
* protection. Obviously, this isn't true. We will fix
|
||||
* that making access to fcports list using RCU functions. This isn't
|
||||
* a complete solution, because it isn't clear if it's safe if some
|
||||
* function going over this list misses just added entry, but definitely
|
||||
@@ -2628,6 +2627,13 @@ typedef struct scsi_qla_host {
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
|
||||
struct mutex tgt_mutex;
|
||||
|
||||
struct mutex tgt_host_action_mutex;
|
||||
|
||||
/* Protected by tgt_host_action_mutex */
|
||||
struct q2t_tgt *q2t_tgt;
|
||||
|
||||
struct list_head ha_list_entry;
|
||||
|
||||
int saved_set;
|
||||
uint16_t saved_exchange_count;
|
||||
uint32_t saved_firmware_options_1;
|
||||
@@ -2635,7 +2641,7 @@ typedef struct scsi_qla_host {
|
||||
uint32_t saved_firmware_options_3;
|
||||
uint8_t saved_firmware_options[2];
|
||||
uint8_t saved_add_firmware_options[2];
|
||||
#endif
|
||||
#endif /* CONFIG_SCSI_QLA2XXX_TARGET */
|
||||
|
||||
struct scsi_qla_host *parent; /* holds pport */
|
||||
unsigned long vp_flags;
|
||||
|
||||
@@ -8,10 +8,6 @@
|
||||
#include "qla_def.h"
|
||||
#include "qla2x_tgt.h"
|
||||
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
|
||||
struct qla_tgt_data qla_target;
|
||||
#endif
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <scsi/scsi_tcq.h>
|
||||
|
||||
|
||||
+60
-9
@@ -25,6 +25,19 @@
|
||||
*/
|
||||
char qla2x00_version_str[40];
|
||||
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
|
||||
/*
|
||||
* Target mode add-on's callbacks
|
||||
*/
|
||||
struct qla_tgt_data qla_target;
|
||||
|
||||
/*
|
||||
* List of ha's and mutex protecting it.
|
||||
*/
|
||||
static LIST_HEAD(qla_ha_list);
|
||||
static DEFINE_MUTEX(qla_ha_list_mutex);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SRB allocation cache
|
||||
*/
|
||||
@@ -591,6 +604,7 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *ha)
|
||||
|
||||
return (return_status);
|
||||
}
|
||||
EXPORT_SYMBOL(qla2x00_wait_for_hba_online);
|
||||
|
||||
/*
|
||||
* qla2x00_wait_for_loop_ready
|
||||
@@ -1544,6 +1558,23 @@ qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time)
|
||||
return atomic_read(&ha->loop_state) == LOOP_READY;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
|
||||
void
|
||||
qla2xxx_add_targets(void)
|
||||
{
|
||||
scsi_qla_host_t *ha;
|
||||
|
||||
mutex_lock(&qla_ha_list_mutex);
|
||||
list_for_each_entry(ha, &qla_ha_list, ha_list_entry) {
|
||||
if (qla_target.tgt_host_action != NULL)
|
||||
qla_target.tgt_host_action(ha, ADD_TARGET);
|
||||
}
|
||||
mutex_unlock(&qla_ha_list_mutex);
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(qla2xxx_add_targets);
|
||||
#endif /* CONFIG_SCSI_QLA2XXX_TARGET */
|
||||
|
||||
/*
|
||||
* PCI driver interface
|
||||
*/
|
||||
@@ -1608,11 +1639,14 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
ha->parent = NULL;
|
||||
ha->bars = bars;
|
||||
ha->mem_only = mem_only;
|
||||
|
||||
spin_lock_init(&ha->hardware_lock);
|
||||
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
|
||||
mutex_init(&ha->tgt_mutex);
|
||||
mutex_init(&ha->tgt_host_action_mutex);
|
||||
qla_clear_tgt_mode(ha);
|
||||
#endif
|
||||
spin_lock_init(&ha->hardware_lock);
|
||||
|
||||
/* Set ISP-type information. */
|
||||
qla2x00_set_isp_flags(ha);
|
||||
@@ -1796,6 +1830,19 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no,
|
||||
ha->isp_ops->fw_version_str(ha, fw_str));
|
||||
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
|
||||
if (qla_target.tgt_host_action != NULL)
|
||||
qla_target.tgt_host_action(ha, ADD_TARGET);
|
||||
|
||||
/*
|
||||
* Must be after tgt_host_action() to not race with
|
||||
* qla2xxx_add_targets().
|
||||
*/
|
||||
mutex_lock(&qla_ha_list_mutex);
|
||||
list_add_tail(&ha->ha_list_entry, &qla_ha_list);
|
||||
mutex_unlock(&qla_ha_list_mutex);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
probe_failed:
|
||||
@@ -1838,14 +1885,18 @@ qla2x00_remove_one(struct pci_dev *pdev)
|
||||
ha = pci_get_drvdata(pdev);
|
||||
|
||||
#ifdef CONFIG_SCSI_QLA2XXX_TARGET
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
ha->host_shutting_down = 1;
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
}
|
||||
if (qla_target.tgt_host_action != NULL)
|
||||
qla_target.tgt_host_action(ha, DISABLE_TARGET_MODE);
|
||||
/*
|
||||
* Must be before tgt_host_action() to not race with
|
||||
* qla2xxx_add_targets().
|
||||
*/
|
||||
mutex_lock(&qla_ha_list_mutex);
|
||||
list_del(&ha->ha_list_entry);
|
||||
mutex_unlock(&qla_ha_list_mutex);
|
||||
|
||||
ha->host_shutting_down = 1;
|
||||
|
||||
if (qla_target.tgt_host_action != NULL)
|
||||
qla_target.tgt_host_action(ha, REMOVE_TARGET);
|
||||
#endif
|
||||
|
||||
/* Necessary to prevent races with it */
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
Index: scst/src/Makefile
|
||||
===================================================================
|
||||
--- scst/src/Makefile (revision 544)
|
||||
+++ scst/src/Makefile (working copy)
|
||||
@@ -117,7 +117,7 @@ EXTRA_CFLAGS += -I$(SCST_INC_DIR) -Wextr
|
||||
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_STRICT_SERIALIZING
|
||||
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_USE_EXPECTED_VALUES
|
||||
#EXTRA_CFLAGS += -DALLOW_PASSTHROUGH_IO_SUBMIT_IN_SIRQ
|
||||
@@ -127,7 +127,7 @@ EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECK
|
||||
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_TRACING
|
||||
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_TM -DCONFIG_SCST_TM_DBG_GO_OFFLINE
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_RETRY
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_OOM
|
||||
Index: scst/src/dev_handlers/Makefile
|
||||
===================================================================
|
||||
--- scst/src/dev_handlers/Makefile (revision 544)
|
||||
+++ scst/src/dev_handlers/Makefile (working copy)
|
||||
@@ -70,10 +70,10 @@ endif
|
||||
EXTRA_CFLAGS += -I$(SUBDIRS) -I$(SCST_INC_DIR) -Wextra -Wno-unused-parameter \
|
||||
-Wno-missing-field-initializers
|
||||
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_TRACING
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
|
||||
clean:
|
||||
rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend Modules.symvers \
|
||||
@@ -1,43 +0,0 @@
|
||||
Index: scst/src/Makefile
|
||||
===================================================================
|
||||
--- scst/src/Makefile (revision 544)
|
||||
+++ scst/src/Makefile (working copy)
|
||||
@@ -117,7 +117,7 @@ EXTRA_CFLAGS += -I$(SCST_INC_DIR) -Wextr
|
||||
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_STRICT_SERIALIZING
|
||||
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_USE_EXPECTED_VALUES
|
||||
#EXTRA_CFLAGS += -DALLOW_PASSTHROUGH_IO_SUBMIT_IN_SIRQ
|
||||
@@ -125,9 +125,9 @@ EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECK
|
||||
|
||||
#EXTRA_CFLAGS += -fno-inline
|
||||
|
||||
-#EXTRA_CFLAGS += -DCONFIG_SCST_TRACING
|
||||
+EXTRA_CFLAGS += -DCONFIG_SCST_TRACING
|
||||
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_TM -DCONFIG_SCST_TM_DBG_GO_OFFLINE
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_RETRY
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_OOM
|
||||
Index: scst/src/dev_handlers/Makefile
|
||||
===================================================================
|
||||
--- scst/src/dev_handlers/Makefile (revision 544)
|
||||
+++ scst/src/dev_handlers/Makefile (working copy)
|
||||
@@ -70,10 +70,10 @@ endif
|
||||
EXTRA_CFLAGS += -I$(SUBDIRS) -I$(SCST_INC_DIR) -Wextra -Wno-unused-parameter \
|
||||
-Wno-missing-field-initializers
|
||||
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS
|
||||
|
||||
-#EXTRA_CFLAGS += -DCONFIG_SCST_TRACING
|
||||
-EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
+EXTRA_CFLAGS += -DCONFIG_SCST_TRACING
|
||||
+#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
|
||||
clean:
|
||||
rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend Modules.symvers \
|
||||
+24
-6
@@ -22,19 +22,37 @@
|
||||
|
||||
SCST_DIR=src
|
||||
|
||||
all:
|
||||
all:
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
|
||||
install:
|
||||
install:
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
|
||||
uninstall:
|
||||
uninstall:
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
|
||||
clean:
|
||||
clean:
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
|
||||
extraclean:
|
||||
extraclean:
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
|
||||
debug2release:
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
|
||||
release2debug:
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
|
||||
debug2perf:
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
|
||||
perf2debug:
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
|
||||
disable_proc:
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
|
||||
enable_proc:
|
||||
cd $(SCST_DIR) && $(MAKE) $@
|
||||
|
||||
help:
|
||||
@@ -48,4 +66,4 @@ help:
|
||||
@echo " - be sure to compile qla against the correct initiator"
|
||||
@echo " driver. Read its README for details."
|
||||
|
||||
.PHONY: all install uninstall clean extraclean help
|
||||
.PHONY: all install uninstall clean extraclean help debug2release release2debug debug2perf perf2debug disable_proc enable_proc
|
||||
|
||||
+26
-19
@@ -63,16 +63,18 @@ them are optional, so, if you don't need the corresponding
|
||||
functionality, you may not apply them.
|
||||
|
||||
1. scst_exec_req_fifo-2.6.X.patch. This patch is necessary for
|
||||
pass-through dev handlers (scst_disk, scst_tape, etc.). Kernels <2.6.30
|
||||
need it, because in them scsi_do_req()/scsi_execute_async() work in LIFO
|
||||
order, instead of expected and required FIFO. So, SCST needs new
|
||||
functions scsi_do_req_fifo() or scsi_execute_async_fifo() to be added in
|
||||
the kernel. Kernels >=2.6.30 need it, because in them there is no
|
||||
functionality to execute commands with data in scatter-gather buffers.
|
||||
This patch adds the necessary functionality to the kernel. You may not
|
||||
patch your kernel if you don't need pass-through support. Alternatively,
|
||||
on kernels <2.6.30 you can define CONFIG_SCST_STRICT_SERIALIZING compile
|
||||
option during the compilation (see description below).
|
||||
pass-through dev handlers, because in the mainstream kernels
|
||||
scsi_do_req()/scsi_execute_async() work in LIFO order, instead of
|
||||
expected and required FIFO. So SCST needs new functions
|
||||
scsi_do_req_fifo() or scsi_execute_async_fifo() to be added in the
|
||||
kernel. This patch does that. You may not patch the kernel if you don't
|
||||
need the pass-through support. Alternatively, you can define
|
||||
CONFIG_SCST_STRICT_SERIALIZING compile option during the compilation
|
||||
(see description below). Unfortunately, the CONFIG_SCST_STRICT_SERIALIZING
|
||||
trick doesn't work on kernels starting from 2.6.30, because those
|
||||
kernels don't have the required functionality (scsi_execute_async())
|
||||
anymore. So, on them to have pass-through working you have to apply
|
||||
scst_exec_req_fifo-2.6.X.patch.
|
||||
|
||||
2. io_context-2.6.X.patch. This patch exports some IO context management
|
||||
functions from the kernel. For performance reasons SCST queues commands
|
||||
@@ -257,13 +259,13 @@ in/out in Makefile:
|
||||
support supplying expected values.
|
||||
|
||||
- CONFIG_SCST_DEBUG_TM - if defined, turns on task management functions
|
||||
debugging, when on LUN 0 in the default access control group some of the
|
||||
commands will be delayed for about 60 sec., so making the remote
|
||||
initiator send TM functions, eg ABORT TASK and TARGET RESET. Also
|
||||
define CONFIG_SCST_TM_DBG_GO_OFFLINE symbol in the Makefile if you
|
||||
want that the device eventually become completely unresponsive, or
|
||||
otherwise to circle around ABORTs and RESETs code. Needs CONFIG_SCST_DEBUG
|
||||
turned on.
|
||||
debugging, when on LUN 6 some of the commands will be delayed for
|
||||
about 60 sec., so making the remote initiator send TM functions, eg
|
||||
ABORT TASK and TARGET RESET. Also define
|
||||
CONFIG_SCST_TM_DBG_GO_OFFLINE symbol in the Makefile if you want that
|
||||
the device eventually become completely unresponsive, or otherwise to
|
||||
circle around ABORTs and RESETs code. Needs CONFIG_SCST_DEBUG turned
|
||||
on.
|
||||
|
||||
- CONFIG_SCST_STRICT_SERIALIZING - if defined, makes SCST send all commands to
|
||||
underlying SCSI device synchronously, one after one. This makes task
|
||||
@@ -275,8 +277,9 @@ in/out in Makefile:
|
||||
commands reliably if they sent asynchronously to a stateful device.
|
||||
Turned off by default, turn it on if you use stateful device(s) and
|
||||
need as much error recovery reliability as possible. As a side effect
|
||||
of CONFIG_SCST_STRICT_SERIALIZING, no kernel patching is necessary
|
||||
for pass-through device handlers (scst_disk, etc.).
|
||||
of CONFIG_SCST_STRICT_SERIALIZING, on kernels below 2.6.30 no kernel
|
||||
patching is necessary for pass-through device handlers (scst_disk,
|
||||
etc.).
|
||||
|
||||
- CONFIG_SCST_ALLOW_PASSTHROUGH_IO_SUBMIT_IN_SIRQ - if defined, it will be
|
||||
allowed to submit pass-through commands to real SCSI devices via the SCSI
|
||||
@@ -1121,4 +1124,8 @@ Thanks to:
|
||||
for UNH-iSCSI project (http://www.iol.unh.edu/consortiums/iscsi/index.html)
|
||||
on which interface between SCST core and target drivers was based.
|
||||
|
||||
* Daniel Debonzi <debonzi@linux.vnet.ibm.com> for a big part of SCST sysfs tree
|
||||
implementation
|
||||
|
||||
|
||||
Vladislav Bolkhovitin <vst@vlnb.net>, http://scst.sourceforge.net
|
||||
|
||||
+14
-9
@@ -180,13 +180,13 @@ your favorite kernel configuration Makefile target, e.g. "make xconfig":
|
||||
support supplying expected values.
|
||||
|
||||
- CONFIG_SCST_DEBUG_TM - if defined, turns on task management functions
|
||||
debugging, when on LUN 0 in the default access control group some of the
|
||||
commands will be delayed for about 60 sec., so making the remote
|
||||
initiator send TM functions, eg ABORT TASK and TARGET RESET. Also
|
||||
define CONFIG_SCST_TM_DBG_GO_OFFLINE symbol in the Makefile if you
|
||||
want that the device eventually become completely unresponsive, or
|
||||
otherwise to circle around ABORTs and RESETs code. Needs CONFIG_SCST_DEBUG
|
||||
turned on.
|
||||
debugging, when on LUN 6 some of the commands will be delayed for
|
||||
about 60 sec., so making the remote initiator send TM functions, eg
|
||||
ABORT TASK and TARGET RESET. Also define
|
||||
CONFIG_SCST_TM_DBG_GO_OFFLINE symbol in the Makefile if you want that
|
||||
the device eventually become completely unresponsive, or otherwise to
|
||||
circle around ABORTs and RESETs code. Needs CONFIG_SCST_DEBUG turned
|
||||
on.
|
||||
|
||||
- CONFIG_SCST_STRICT_SERIALIZING - if defined, makes SCST send all commands to
|
||||
underlying SCSI device synchronously, one after one. This makes task
|
||||
@@ -198,8 +198,9 @@ your favorite kernel configuration Makefile target, e.g. "make xconfig":
|
||||
commands reliably if they sent asynchronously to a stateful device.
|
||||
Turned off by default, turn it on if you use stateful device(s) and
|
||||
need as much error recovery reliability as possible. As a side effect
|
||||
of CONFIG_SCST_STRICT_SERIALIZING, no kernel patching is necessary
|
||||
for pass-through device handlers (scst_disk, etc.).
|
||||
of CONFIG_SCST_STRICT_SERIALIZING, on kernels below 2.6.30 no kernel
|
||||
patching is necessary for pass-through device handlers (scst_disk,
|
||||
etc.).
|
||||
|
||||
- CONFIG_SCST_ALLOW_PASSTHROUGH_IO_SUBMIT_IN_SIRQ - if defined, it will be
|
||||
allowed to submit pass-through commands to real SCSI devices via the SCSI
|
||||
@@ -1030,4 +1031,8 @@ Thanks to:
|
||||
|
||||
* Bart Van Assche <bart.vanassche@gmail.com> for a lot of help
|
||||
|
||||
* Daniel Debonzi <debonzi@linux.vnet.ibm.com> for a big part of SCST sysfs tree
|
||||
implementation
|
||||
|
||||
|
||||
Vladislav Bolkhovitin <vst@vlnb.net>, http://scst.sourceforge.net
|
||||
|
||||
+224
-33
@@ -25,9 +25,15 @@
|
||||
#include <linux/version.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
#define CONFIG_SCST_PROC
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#endif
|
||||
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
#include <scsi/scsi_eh.h>
|
||||
@@ -52,8 +58,13 @@ typedef _Bool bool;
|
||||
* and FIO_REV in usr/fileio/common.h as well.
|
||||
*/
|
||||
#define SCST_VERSION(a, b, c, d) (((a) << 24) + ((b) << 16) + ((c) << 8) + d)
|
||||
#define SCST_VERSION_CODE SCST_VERSION(1, 0, 2, 0)
|
||||
#define SCST_VERSION_STRING "1.0.2"
|
||||
#define SCST_VERSION_CODE SCST_VERSION(2, 0, 0, 0)
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
#define SCST_VERSION_STRING_SUFFIX "-procfs"
|
||||
#else
|
||||
#define SCST_VERSION_STRING_SUFFIX
|
||||
#endif
|
||||
#define SCST_VERSION_STRING "2.0.0-pre1" SCST_VERSION_STRING_SUFFIX
|
||||
#define SCST_INTERFACE_VERSION \
|
||||
SCST_VERSION_STRING "$Revision$" SCST_CONST_VERSION
|
||||
|
||||
@@ -455,11 +466,15 @@ enum scst_exec_context {
|
||||
|
||||
#define SCST_TGT_DEV_CLUST_POOL 11
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
|
||||
/*************************************************************
|
||||
** Name of the entry in /proc
|
||||
*************************************************************/
|
||||
#define SCST_PROC_ENTRY_NAME "scsi_tgt"
|
||||
|
||||
#endif
|
||||
|
||||
/*************************************************************
|
||||
** Activities suspending timeout
|
||||
*************************************************************/
|
||||
@@ -580,8 +595,10 @@ struct scst_tgt_template {
|
||||
unsigned xmit_response_atomic:1;
|
||||
unsigned rdy_to_xfer_atomic:1;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
/* True, if the template doesn't need the entry in /proc */
|
||||
unsigned no_proc_entry:1;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The maximum time in seconds cmd can stay inside the target
|
||||
@@ -784,6 +801,7 @@ struct scst_tgt_template {
|
||||
*/
|
||||
int (*report_aen) (struct scst_aen *aen);
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
/*
|
||||
* Those functions can be used to export the driver's statistics and
|
||||
* other infos to the world outside the kernel as well as to get some
|
||||
@@ -794,6 +812,26 @@ struct scst_tgt_template {
|
||||
int (*read_proc) (struct seq_file *seq, struct scst_tgt *tgt);
|
||||
int (*write_proc) (char *buffer, char **start, off_t offset,
|
||||
int length, int *eof, struct scst_tgt *tgt);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function allows to enable or disable particular target.
|
||||
* A disabled target doesn't receive and process any SCSI commands.
|
||||
*
|
||||
* SHOULD HAVE to avoid race when there are connected initiators,
|
||||
* while target not yet completed the initial configuration. In this
|
||||
* case the too early connected initiators would see not those devices,
|
||||
* which they intended to see.
|
||||
*/
|
||||
ssize_t (*enable_tgt) (struct scst_tgt *tgt, const char *buffer,
|
||||
size_t size);
|
||||
|
||||
/*
|
||||
* This function shows if particular target is enabled or not.
|
||||
*
|
||||
* SHOULD HAVE, see above why.
|
||||
*/
|
||||
bool (*is_tgt_enabled) (struct scst_tgt *tgt);
|
||||
|
||||
/*
|
||||
* Name of the template. Must be unique to identify
|
||||
@@ -809,7 +847,25 @@ struct scst_tgt_template {
|
||||
*/
|
||||
int threads_num;
|
||||
|
||||
/* Private, must be inited to 0 by memset() */
|
||||
/* Optional default log flags */
|
||||
const unsigned long default_trace_flags;
|
||||
|
||||
/* Optional pointer to trace flags */
|
||||
unsigned long *trace_flags;
|
||||
|
||||
/* Optional local trace table */
|
||||
struct scst_trace_log *trace_tbl;
|
||||
|
||||
/* Optional local trace table help string */
|
||||
const char *trace_tbl_help;
|
||||
|
||||
/* Optional sysfs attributes */
|
||||
const struct attribute **tgtt_attrs;
|
||||
|
||||
/* Optional sysfs target attributes */
|
||||
const struct attribute **tgt_attrs;
|
||||
|
||||
/** Private, must be inited to 0 by memset() **/
|
||||
|
||||
/* List of targets per template, protected by scst_mutex */
|
||||
struct list_head tgt_list;
|
||||
@@ -817,11 +873,22 @@ struct scst_tgt_template {
|
||||
/* List entry of global templates list */
|
||||
struct list_head scst_template_list_entry;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
/* The pointer to the /proc directory entry */
|
||||
struct proc_dir_entry *proc_tgt_root;
|
||||
#endif
|
||||
|
||||
/* Set if tgtt_kobj was initialized */
|
||||
unsigned int tgtt_kobj_initialized:1;
|
||||
|
||||
struct kobject tgtt_kobj; /* kobject for this struct */
|
||||
|
||||
struct completion tgtt_kobj_release_cmpl;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
/* Device number in /proc */
|
||||
int proc_dev_num;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct scst_dev_type {
|
||||
@@ -836,8 +903,10 @@ struct scst_dev_type {
|
||||
unsigned exec_atomic:1;
|
||||
unsigned dev_done_atomic:1;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
/* Set, if no /proc files should be automatically created by SCST */
|
||||
unsigned no_proc:1;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Should be set, if exec() is synchronous. This is a hint to SCST core
|
||||
@@ -948,6 +1017,7 @@ struct scst_dev_type {
|
||||
/* Called when tgt_dev (session) is detaching from the dev handler */
|
||||
void (*detach_tgt) (struct scst_tgt_dev *tgt_dev);
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
/*
|
||||
* Those functions can be used to export the handler's statistics and
|
||||
* other infos to the world outside the kernel as well as to get some
|
||||
@@ -958,6 +1028,7 @@ struct scst_dev_type {
|
||||
int (*read_proc) (struct seq_file *seq, struct scst_dev_type *dev_type);
|
||||
int (*write_proc) (char *buffer, char **start, off_t offset,
|
||||
int length, int *eof, struct scst_dev_type *dev_type);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Name of the dev handler. Must be unique. MUST HAVE.
|
||||
@@ -972,15 +1043,48 @@ struct scst_dev_type {
|
||||
*/
|
||||
int threads_num;
|
||||
|
||||
/* Optional default log flags */
|
||||
const unsigned long default_trace_flags;
|
||||
|
||||
/* Optional pointer to trace flags */
|
||||
unsigned long *trace_flags;
|
||||
|
||||
/* Optional local trace table */
|
||||
struct scst_trace_log *trace_tbl;
|
||||
|
||||
/* Optional local trace table help string */
|
||||
const char *trace_tbl_help;
|
||||
|
||||
/* Optional sysfs attributes */
|
||||
const struct attribute **devt_attrs;
|
||||
|
||||
/* Optional sysfs device attributes */
|
||||
const struct attribute **dev_attrs;
|
||||
|
||||
/* Pointer to dev handler's private data */
|
||||
void *devt_priv;
|
||||
|
||||
/* Pointer to parent dev type in the sysfs hierarchy */
|
||||
struct scst_dev_type *parent;
|
||||
|
||||
struct module *module;
|
||||
|
||||
/* private: */
|
||||
/** Private, must be inited to 0 by memset() **/
|
||||
|
||||
/* list entry in scst_dev_type_list */
|
||||
struct list_head dev_type_list_entry;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
/* The pointer to the /proc directory entry */
|
||||
struct proc_dir_entry *proc_dev_type_root;
|
||||
#endif
|
||||
|
||||
unsigned int devt_kobj_initialized:1;
|
||||
|
||||
struct kobject devt_kobj; /* main handlers/driver */
|
||||
|
||||
/* To wait until devt_kobj released */
|
||||
struct completion devt_kobj_release_compl;
|
||||
};
|
||||
|
||||
struct scst_tgt {
|
||||
@@ -992,6 +1096,8 @@ struct scst_tgt {
|
||||
|
||||
struct scst_tgt_template *tgtt; /* corresponding target template */
|
||||
|
||||
struct scst_acg *default_acg; /* The default acg for this target. */
|
||||
|
||||
/*
|
||||
* Maximum SG table size. Needed here, since different cards on the
|
||||
* same target template can have different SG table limitations.
|
||||
@@ -1017,11 +1123,26 @@ struct scst_tgt {
|
||||
/* Used to wait until session finished to unregister */
|
||||
wait_queue_head_t unreg_waitQ;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
/* Device number in /proc */
|
||||
int proc_num;
|
||||
#endif
|
||||
|
||||
/* Name of the target */
|
||||
char *tgt_name;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
/* Name on the default security group ("Default_target_name") */
|
||||
char *default_group_name;
|
||||
#endif
|
||||
|
||||
/* Set if tgt_kobj was initialized */
|
||||
unsigned int tgt_kobj_initialized:1;
|
||||
|
||||
struct kobject tgt_kobj; /* main targets/target kobject */
|
||||
struct kobject *tgt_sess_kobj; /* target/sessions/ */
|
||||
struct kobject *tgt_luns_kobj; /* target/luns/ */
|
||||
struct kobject *tgt_ini_grp_kobj; /* target/ini_groups/ */
|
||||
};
|
||||
|
||||
/* Hash size and hash fn for hash based lun translation */
|
||||
@@ -1144,6 +1265,11 @@ struct scst_session {
|
||||
/* Used if scst_unregister_session() called in wait mode */
|
||||
struct completion *shutdown_compl;
|
||||
|
||||
/* Set if sess_kobj was initialized */
|
||||
unsigned int sess_kobj_initialized:1;
|
||||
|
||||
struct kobject sess_kobj; /* kobject for this struct */
|
||||
|
||||
/*
|
||||
* Functions and data for user callbacks from scst_register_session()
|
||||
* and scst_unregister_session()
|
||||
@@ -1636,7 +1762,7 @@ struct scst_device {
|
||||
int virt_id;
|
||||
|
||||
/* Pointer to virtual device name, for convenience only */
|
||||
const char *virt_name;
|
||||
char *virt_name;
|
||||
|
||||
/* List entry in global devices list */
|
||||
struct list_head dev_list_entry;
|
||||
@@ -1655,6 +1781,15 @@ struct scst_device {
|
||||
|
||||
/* Device number */
|
||||
int dev_num;
|
||||
|
||||
/* Set if tgt_kobj was initialized */
|
||||
unsigned int dev_kobj_initialized:1;
|
||||
|
||||
struct kobject dev_kobj; /* kobject for this struct */
|
||||
struct kobject *dev_exp_kobj; /* exported groups */
|
||||
|
||||
/* Export number in the dev's sysfs list. Protected by scst_mutex */
|
||||
int dev_exported_lun_num;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1766,15 +1901,25 @@ struct scst_tgt_dev {
|
||||
*/
|
||||
struct scst_acg_dev {
|
||||
struct scst_device *dev; /* corresponding device */
|
||||
uint64_t lun; /* device's LUN in this acg */
|
||||
unsigned int rd_only:1; /* if != 0, then read only */
|
||||
struct scst_acg *acg; /* parent acg */
|
||||
|
||||
/* list entry in dev->dev_acg_dev_list */
|
||||
uint64_t lun; /* device's LUN in this acg */
|
||||
|
||||
/* If set, the corresponding LU is read only */
|
||||
unsigned int rd_only:1;
|
||||
|
||||
/* Set if acg_dev_kobj was initialized */
|
||||
unsigned int acg_dev_kobj_initialized:1;
|
||||
|
||||
struct scst_acg *acg; /* parent acg */
|
||||
|
||||
/* List entry in dev->dev_acg_dev_list */
|
||||
struct list_head dev_acg_dev_list_entry;
|
||||
|
||||
/* list entry in acg->acg_dev_list */
|
||||
/* List entry in acg->acg_dev_list */
|
||||
struct list_head acg_dev_list_entry;
|
||||
|
||||
/* kobject for this structure */
|
||||
struct kobject acg_dev_kobj;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1797,8 +1942,10 @@ struct scst_acg {
|
||||
/* Name of this acg */
|
||||
const char *acg_name;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
/* The pointer to the /proc directory entry */
|
||||
struct proc_dir_entry *acg_proc_root;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1895,8 +2042,7 @@ void scst_unregister(struct scst_tgt *tgt);
|
||||
* this function will block until the session registration is completed.
|
||||
* initiator_name - remote initiator's name, any NULL-terminated string,
|
||||
* e.g. iSCSI name, which used as the key to found appropriate access
|
||||
* control group. Could be NULL, then "default" group is used.
|
||||
* The groups are set up via /proc interface.
|
||||
* control group. Could be NULL, then the default target's LUNs are used.
|
||||
* data - any target driver supplied data
|
||||
* result_fn - pointer to the function that will be
|
||||
* asynchronously called when session initialization finishes.
|
||||
@@ -2852,7 +2998,7 @@ static inline struct scatterlist *sg_next(struct scatterlist *sg)
|
||||
return sg;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* __BACKPORT_LINUX_SCATTERLIST_H_TO_2_6_23__ */
|
||||
|
||||
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) */
|
||||
|
||||
@@ -3012,49 +3158,44 @@ int scst_get_cmd_abnormal_done_state(const struct scst_cmd *cmd);
|
||||
*/
|
||||
void scst_set_cmd_abnormal_done_state(struct scst_cmd *cmd);
|
||||
|
||||
struct scst_trace_log {
|
||||
unsigned int val;
|
||||
const char *token;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
|
||||
/*
|
||||
* Returns target driver's root entry in SCST's /proc hierarchy.
|
||||
* The driver can create own files/directories here, which should
|
||||
* be deleted in the driver's release().
|
||||
*/
|
||||
static inline struct proc_dir_entry *scst_proc_get_tgt_root(
|
||||
struct scst_tgt_template *vtt)
|
||||
{
|
||||
return vtt->proc_tgt_root;
|
||||
}
|
||||
struct proc_dir_entry *scst_proc_get_tgt_root(
|
||||
struct scst_tgt_template *vtt);
|
||||
|
||||
/*
|
||||
* Returns device handler's root entry in SCST's /proc hierarchy.
|
||||
* The driver can create own files/directories here, which should
|
||||
* be deleted in the driver's detach()/release().
|
||||
*/
|
||||
static inline struct proc_dir_entry *scst_proc_get_dev_type_root(
|
||||
struct scst_dev_type *dtt)
|
||||
{
|
||||
return dtt->proc_dev_type_root;
|
||||
}
|
||||
struct proc_dir_entry *scst_proc_get_dev_type_root(
|
||||
struct scst_dev_type *dtt);
|
||||
|
||||
/**
|
||||
** Two library functions and the structure to help the drivers
|
||||
** that use scst_debug.* facilities manage "trace_level" /proc entry.
|
||||
** The functions service "standard" log levels and allow to work
|
||||
** with driver specific levels, which should be passed inside as
|
||||
** NULL-terminated array of struct scst_proc_log's, where:
|
||||
** NULL-terminated array of struct scst_trace_log's, where:
|
||||
** - val - the level's numeric value
|
||||
** - token - its string representation
|
||||
**/
|
||||
|
||||
struct scst_proc_log {
|
||||
unsigned int val;
|
||||
const char *token;
|
||||
};
|
||||
|
||||
int scst_proc_log_entry_read(struct seq_file *seq, unsigned long log_level,
|
||||
const struct scst_proc_log *tbl);
|
||||
|
||||
const struct scst_trace_log *tbl);
|
||||
int scst_proc_log_entry_write(struct file *file, const char __user *buf,
|
||||
unsigned long length, unsigned long *log_level,
|
||||
unsigned long default_level, const struct scst_proc_log *tbl);
|
||||
unsigned long default_level, const struct scst_trace_log *tbl);
|
||||
|
||||
/*
|
||||
* helper data structure and function to create proc entry.
|
||||
@@ -3080,6 +3221,56 @@ struct proc_dir_entry *scst_create_proc_entry(struct proc_dir_entry *root,
|
||||
.release = single_release, \
|
||||
},
|
||||
|
||||
#else /* CONFIG_SCST_PROC */
|
||||
|
||||
/*
|
||||
* Returns target driver's root sysfs kobject.
|
||||
* The driver can create own files/directories/links here.
|
||||
*/
|
||||
static inline struct kobject *scst_sysfs_get_tgtt_kobj(
|
||||
struct scst_tgt_template *tgtt)
|
||||
{
|
||||
return &tgtt->tgtt_kobj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns target's root sysfs kobject.
|
||||
* The driver can create own files/directories/links here.
|
||||
*/
|
||||
static inline struct kobject *scst_sysfs_get_tgt_kobj(
|
||||
struct scst_tgt *tgt)
|
||||
{
|
||||
return &tgt->tgt_kobj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns device handler's root sysfs kobject.
|
||||
* The driver can create own files/directories/links here.
|
||||
*/
|
||||
static inline struct kobject *scst_sysfs_get_devt_kobj(
|
||||
struct scst_dev_type *devt)
|
||||
{
|
||||
return &devt->devt_kobj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns device's root sysfs kobject.
|
||||
* The driver can create own files/directories/links here.
|
||||
*/
|
||||
static inline struct kobject *scst_sysfs_get_dev_kobj(
|
||||
struct scst_device *dev)
|
||||
{
|
||||
return &dev->dev_kobj;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
/* Returns target name */
|
||||
static inline const char *scst_get_tgt_name(const struct scst_tgt *tgt)
|
||||
{
|
||||
return tgt->tgt_name;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds and deletes (stops) num of global SCST's threads. Returns 0 on
|
||||
* success, error code otherwise.
|
||||
|
||||
@@ -131,6 +131,11 @@ enum scst_cmd_queue_type {
|
||||
*************************************************************/
|
||||
#define SCST_DEFAULT_ACG_NAME "Default"
|
||||
|
||||
/*************************************************************
|
||||
** Default suffix for targets with NULL names
|
||||
*************************************************************/
|
||||
#define SCST_DEFAULT_TGT_NAME_SUFFIX "_target_"
|
||||
|
||||
/*************************************************************
|
||||
** Sense manipulation and examination
|
||||
*************************************************************/
|
||||
@@ -331,4 +336,9 @@ enum scst_cmd_queue_type {
|
||||
|
||||
#define SCST_MAX_OTHER_TIMEOUT (14000 * HZ)
|
||||
|
||||
/*************************************************************
|
||||
** Misc constants
|
||||
*************************************************************/
|
||||
#define SCST_SYSFS_BLOCK_SIZE (PAGE_SIZE - 64)
|
||||
|
||||
#endif /* __SCST_CONST_H */
|
||||
|
||||
+58
-2
@@ -33,12 +33,12 @@ ifneq ($(PATCHLEVEL),)
|
||||
SCST_INC_DIR := $(SUBDIRS)/../include
|
||||
|
||||
obj-m := scst.o
|
||||
scst-objs := scst_main.o scst_targ.o scst_lib.o scst_mem.o scst_proc.o
|
||||
|
||||
scst-y += scst_main.o
|
||||
scst-y += scst_targ.o
|
||||
scst-y += scst_lib.o
|
||||
scst-y += scst_proc.o
|
||||
#scst-y += scst_sysfs.o
|
||||
scst-y += scst_mem.o
|
||||
scst-y += scst_debug.o
|
||||
obj-$(CONFIG_SCST) += scst.o dev_handlers/
|
||||
@@ -149,4 +149,60 @@ clean:
|
||||
|
||||
extraclean: clean
|
||||
|
||||
.PHONY: all install uninstall clean extraclean
|
||||
debug2release:
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/"EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
cd $(DEV_HANDLERS_DIR) && $(MAKE) $@
|
||||
|
||||
release2debug:
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
cd $(DEV_HANDLERS_DIR) && $(MAKE) $@
|
||||
|
||||
debug2perf:
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
cd $(DEV_HANDLERS_DIR) && $(MAKE) $@
|
||||
|
||||
perf2debug:
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
cd $(DEV_HANDLERS_DIR) && $(MAKE) $@
|
||||
|
||||
disable_proc:
|
||||
sed -c -i.aa s/"^#define CONFIG_SCST_PROC"/"\/* #define CONFIG_SCST_PROC *\/"/ ../include/scst.h
|
||||
@cmp ../include/scst.h ../include/scst.h.aa >/dev/null; if [[ $$? = 0 ]]; then rm ../include/scst.h.aa; echo "sed failed"; false; fi
|
||||
rm ../include/scst.h.aa
|
||||
sed -c -i.aa s/"^scst-y += scst_proc.o"/"#scst\-y += scst_proc.o"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#scst\-y += scst_sysfs.o"/"scst\-y += scst_sysfs.o"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
|
||||
enable_proc:
|
||||
sed -c -i.aa s/"\/\* #define CONFIG_SCST_PROC \*\/"/"#define CONFIG_SCST_PROC"/ ../include/scst.h
|
||||
@cmp ../include/scst.h ../include/scst.h.aa >/dev/null; if [[ $$? = 0 ]]; then rm ../include/scst.h.aa; echo "sed failed"; false; fi
|
||||
rm ../include/scst.h.aa
|
||||
sed -c -i.aa s/"#scst\-y += scst_proc.o"/"scst\-y += scst_proc.o"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^scst\-y += scst_sysfs.o"/"#scst\-y += scst_sysfs.o"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
|
||||
.PHONY: all install uninstall clean extraclean debug2release release2debug debug2perf perf2debug disable_proc enable_proc
|
||||
|
||||
@@ -82,4 +82,36 @@ clean:
|
||||
|
||||
extraclean: clean
|
||||
|
||||
.PHONY: all install uninstall clean extraclean
|
||||
debug2release:
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/"EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
|
||||
release2debug:
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_TRACING"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
|
||||
debug2perf:
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
|
||||
perf2debug:
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/"EXTRA_CFLAGS += \-DCONFIG_SCST_EXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/"EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
|
||||
.PHONY: all install uninstall clean extraclean debug2release release2debug debug2perf perf2debug
|
||||
|
||||
@@ -28,17 +28,6 @@
|
||||
|
||||
#define CDROM_NAME "dev_cdrom"
|
||||
|
||||
#define CDROM_TYPE { \
|
||||
.name = CDROM_NAME, \
|
||||
.type = TYPE_ROM, \
|
||||
.parse_atomic = 1, \
|
||||
.dev_done_atomic = 1, \
|
||||
.attach = cdrom_attach, \
|
||||
.detach = cdrom_detach, \
|
||||
.parse = cdrom_parse, \
|
||||
.dev_done = cdrom_done, \
|
||||
}
|
||||
|
||||
#define CDROM_DEF_BLOCK_SHIFT 11
|
||||
|
||||
struct cdrom_params {
|
||||
@@ -50,7 +39,20 @@ static void cdrom_detach(struct scst_device *);
|
||||
static int cdrom_parse(struct scst_cmd *);
|
||||
static int cdrom_done(struct scst_cmd *);
|
||||
|
||||
static struct scst_dev_type cdrom_devtype = CDROM_TYPE;
|
||||
static struct scst_dev_type cdrom_devtype = {
|
||||
.name = CDROM_NAME,
|
||||
.type = TYPE_ROM,
|
||||
.parse_atomic = 1,
|
||||
.dev_done_atomic = 1,
|
||||
.attach = cdrom_attach,
|
||||
.detach = cdrom_detach,
|
||||
.parse = cdrom_parse,
|
||||
.dev_done = cdrom_done,
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
.default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
|
||||
.trace_flags = &trace_flag,
|
||||
#endif
|
||||
};
|
||||
|
||||
/**************************************************************
|
||||
* Function: cdrom_attach
|
||||
@@ -150,9 +152,7 @@ static int cdrom_attach(struct scst_device *dev)
|
||||
res = scst_obtain_device_parameters(dev);
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("Failed to obtain control parameters for device "
|
||||
"%d:%d:%d:%d", dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel, dev->scsi_dev->id,
|
||||
dev->scsi_dev->lun);
|
||||
"%s", dev->virt_name);
|
||||
goto out_free_buf;
|
||||
}
|
||||
|
||||
@@ -274,23 +274,29 @@ static int __init cdrom_init(void)
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
res = scst_dev_handler_build_std_proc(&cdrom_devtype);
|
||||
if (res != 0)
|
||||
goto out_err;
|
||||
#endif
|
||||
|
||||
out:
|
||||
TRACE_EXIT();
|
||||
return res;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
out_err:
|
||||
scst_unregister_dev_driver(&cdrom_devtype);
|
||||
goto out;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __exit cdrom_exit(void)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
scst_dev_handler_destroy_std_proc(&cdrom_devtype);
|
||||
#endif
|
||||
scst_unregister_dev_driver(&cdrom_devtype);
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
|
||||
@@ -27,17 +27,6 @@
|
||||
|
||||
#define CHANGER_NAME "dev_changer"
|
||||
|
||||
#define CHANGER_TYPE { \
|
||||
.name = CHANGER_NAME, \
|
||||
.type = TYPE_MEDIUM_CHANGER, \
|
||||
.parse_atomic = 1, \
|
||||
/* .dev_done_atomic = 1, */ \
|
||||
.attach = changer_attach, \
|
||||
/* .detach = changer_detach, */ \
|
||||
.parse = changer_parse, \
|
||||
/* .dev_done = changer_done */ \
|
||||
}
|
||||
|
||||
#define CHANGER_RETRIES 2
|
||||
#define READ_CAP_LEN 8
|
||||
|
||||
@@ -46,7 +35,20 @@ static int changer_attach(struct scst_device *);
|
||||
static int changer_parse(struct scst_cmd *);
|
||||
/* static int changer_done(struct scst_cmd *); */
|
||||
|
||||
static struct scst_dev_type changer_devtype = CHANGER_TYPE;
|
||||
static struct scst_dev_type changer_devtype = {
|
||||
.name = CHANGER_NAME,
|
||||
.type = TYPE_MEDIUM_CHANGER,
|
||||
.parse_atomic = 1,
|
||||
/* .dev_done_atomic = 1, */
|
||||
.attach = changer_attach,
|
||||
/* .detach = changer_detach, */
|
||||
.parse = changer_parse,
|
||||
/* .dev_done = changer_done */
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
.default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
|
||||
.trace_flags = &trace_flag,
|
||||
#endif
|
||||
};
|
||||
|
||||
/**************************************************************
|
||||
* Function: changer_attach
|
||||
@@ -101,9 +103,7 @@ static int changer_attach(struct scst_device *dev)
|
||||
res = scst_obtain_device_parameters(dev);
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("Failed to obtain control parameters for device "
|
||||
"%d:%d:%d:%d", dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel, dev->scsi_dev->id,
|
||||
dev->scsi_dev->lun);
|
||||
"%s", dev->virt_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -202,23 +202,28 @@ static int __init changer_init(void)
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
res = scst_dev_handler_build_std_proc(&changer_devtype);
|
||||
if (res != 0)
|
||||
goto out_err;
|
||||
#endif
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
out_err:
|
||||
scst_unregister_dev_driver(&changer_devtype);
|
||||
goto out;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __exit changer_exit(void)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
scst_dev_handler_destroy_std_proc(&changer_devtype);
|
||||
#endif
|
||||
scst_unregister_dev_driver(&changer_devtype);
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
#define __SCST_DEV_HANDLER_H
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <scsi/scsi_eh.h>
|
||||
#include "scst_debug.h"
|
||||
|
||||
@@ -12,8 +10,6 @@
|
||||
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
|
||||
#define DEV_HANDLER_LOG_ENTRY_NAME "trace_level"
|
||||
|
||||
#ifdef CONFIG_SCST_DEBUG
|
||||
#define SCST_DEFAULT_DEV_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_PID | \
|
||||
TRACE_LINE | TRACE_FUNCTION | TRACE_MGMT | TRACE_MGMT_MINOR | \
|
||||
@@ -26,6 +22,10 @@
|
||||
static unsigned long dh_trace_flag = SCST_DEFAULT_DEV_LOG_FLAGS;
|
||||
#define trace_flag dh_trace_flag
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
|
||||
#define DEV_HANDLER_LOG_ENTRY_NAME "trace_level"
|
||||
|
||||
#ifndef trace_log_tbl
|
||||
#define trace_log_tbl NULL
|
||||
#endif
|
||||
@@ -57,8 +57,13 @@ static ssize_t scst_dev_handler_proc_log_entry_write(struct file *file,
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
#endif /* defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) */
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
|
||||
static int scst_dev_handler_build_std_proc(struct scst_dev_type *dev_type)
|
||||
{
|
||||
int res = 0;
|
||||
@@ -69,14 +74,20 @@ static int scst_dev_handler_build_std_proc(struct scst_dev_type *dev_type)
|
||||
|
||||
root = scst_proc_get_dev_type_root(dev_type);
|
||||
if (root) {
|
||||
/* create the proc file entry for the device */
|
||||
dev_handler_log_proc_data.data = (void *)dev_type->name;
|
||||
/* Create the proc file entry for the device */
|
||||
/* Workaround to keep /proc ABI intact */
|
||||
const char *name;
|
||||
if (strcmp(dev_type->name, "vdisk_fileio") == 0)
|
||||
name = "vdisk";
|
||||
else
|
||||
name = dev_type->name;
|
||||
dev_handler_log_proc_data.data = (void *)name;
|
||||
p = scst_create_proc_entry(root, DEV_HANDLER_LOG_ENTRY_NAME,
|
||||
&dev_handler_log_proc_data);
|
||||
if (p == NULL) {
|
||||
PRINT_ERROR("Not enough memory to register dev "
|
||||
"handler %s entry %s in /proc",
|
||||
dev_type->name, DEV_HANDLER_LOG_ENTRY_NAME);
|
||||
name, DEV_HANDLER_LOG_ENTRY_NAME);
|
||||
res = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -110,4 +121,6 @@ static struct scst_proc_data dev_handler_log_proc_data = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
#endif /* __SCST_DEV_HANDLER_H */
|
||||
|
||||
@@ -33,31 +33,6 @@
|
||||
# define DISK_NAME "dev_disk"
|
||||
# define DISK_PERF_NAME "dev_disk_perf"
|
||||
|
||||
#define DISK_TYPE { \
|
||||
.name = DISK_NAME, \
|
||||
.type = TYPE_DISK, \
|
||||
.parse_atomic = 1, \
|
||||
.dev_done_atomic = 1, \
|
||||
.exec_atomic = 1, \
|
||||
.attach = disk_attach, \
|
||||
.detach = disk_detach, \
|
||||
.parse = disk_parse, \
|
||||
.dev_done = disk_done, \
|
||||
}
|
||||
|
||||
#define DISK_PERF_TYPE { \
|
||||
.name = DISK_PERF_NAME, \
|
||||
.type = TYPE_DISK, \
|
||||
.parse_atomic = 1, \
|
||||
.dev_done_atomic = 1, \
|
||||
.exec_atomic = 1, \
|
||||
.attach = disk_attach, \
|
||||
.detach = disk_detach, \
|
||||
.parse = disk_parse, \
|
||||
.dev_done = disk_done, \
|
||||
.exec = disk_exec, \
|
||||
}
|
||||
|
||||
#define DISK_DEF_BLOCK_SHIFT 9
|
||||
|
||||
struct disk_params {
|
||||
@@ -70,8 +45,38 @@ static int disk_parse(struct scst_cmd *cmd);
|
||||
static int disk_done(struct scst_cmd *cmd);
|
||||
static int disk_exec(struct scst_cmd *cmd);
|
||||
|
||||
static struct scst_dev_type disk_devtype = DISK_TYPE;
|
||||
static struct scst_dev_type disk_devtype_perf = DISK_PERF_TYPE;
|
||||
static struct scst_dev_type disk_devtype = {
|
||||
.name = DISK_NAME,
|
||||
.type = TYPE_DISK,
|
||||
.parse_atomic = 1,
|
||||
.dev_done_atomic = 1,
|
||||
.exec_atomic = 1,
|
||||
.attach = disk_attach,
|
||||
.detach = disk_detach,
|
||||
.parse = disk_parse,
|
||||
.dev_done = disk_done,
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
.default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
|
||||
.trace_flags = &trace_flag,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct scst_dev_type disk_devtype_perf = {
|
||||
.name = DISK_PERF_NAME,
|
||||
.type = TYPE_DISK,
|
||||
.parse_atomic = 1,
|
||||
.dev_done_atomic = 1,
|
||||
.exec_atomic = 1,
|
||||
.attach = disk_attach,
|
||||
.detach = disk_detach,
|
||||
.parse = disk_parse,
|
||||
.dev_done = disk_done,
|
||||
.exec = disk_exec,
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
.default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
|
||||
.trace_flags = &trace_flag,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int __init init_scst_disk_driver(void)
|
||||
{
|
||||
@@ -85,31 +90,35 @@ static int __init init_scst_disk_driver(void)
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
res = scst_dev_handler_build_std_proc(&disk_devtype);
|
||||
if (res != 0)
|
||||
goto out_unreg1;
|
||||
|
||||
disk_devtype_perf.module = THIS_MODULE;
|
||||
|
||||
res = scst_register_dev_driver(&disk_devtype_perf);
|
||||
if (res < 0)
|
||||
goto out_unreg1_err1;
|
||||
goto out_unreg;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
res = scst_dev_handler_build_std_proc(&disk_devtype);
|
||||
if (res != 0)
|
||||
goto out_unreg1;
|
||||
|
||||
res = scst_dev_handler_build_std_proc(&disk_devtype_perf);
|
||||
if (res != 0)
|
||||
goto out_unreg2;
|
||||
#endif
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
out_unreg2:
|
||||
scst_dev_handler_destroy_std_proc(&disk_devtype_perf);
|
||||
|
||||
out_unreg1_err1:
|
||||
scst_dev_handler_destroy_std_proc(&disk_devtype);
|
||||
|
||||
out_unreg1:
|
||||
scst_unregister_dev_driver(&disk_devtype_perf);
|
||||
#endif
|
||||
|
||||
out_unreg:
|
||||
scst_unregister_dev_driver(&disk_devtype);
|
||||
goto out;
|
||||
}
|
||||
@@ -117,10 +126,14 @@ out_unreg1:
|
||||
static void __exit exit_scst_disk_driver(void)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
scst_dev_handler_destroy_std_proc(&disk_devtype_perf);
|
||||
scst_unregister_dev_driver(&disk_devtype_perf);
|
||||
scst_dev_handler_destroy_std_proc(&disk_devtype);
|
||||
#endif
|
||||
scst_unregister_dev_driver(&disk_devtype_perf);
|
||||
scst_unregister_dev_driver(&disk_devtype);
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
@@ -226,9 +239,7 @@ static int disk_attach(struct scst_device *dev)
|
||||
res = scst_obtain_device_parameters(dev);
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("Failed to obtain control parameters for device "
|
||||
"%d:%d:%d:%d", dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel, dev->scsi_dev->id,
|
||||
dev->scsi_dev->lun);
|
||||
"%s", dev->virt_name);
|
||||
goto out_free_buf;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,31 +33,6 @@
|
||||
# define MODISK_NAME "dev_modisk"
|
||||
# define MODISK_PERF_NAME "dev_modisk_perf"
|
||||
|
||||
#define MODISK_TYPE { \
|
||||
.name = MODISK_NAME, \
|
||||
.type = TYPE_MOD, \
|
||||
.parse_atomic = 1, \
|
||||
.dev_done_atomic = 1, \
|
||||
.exec_atomic = 1, \
|
||||
.attach = modisk_attach, \
|
||||
.detach = modisk_detach, \
|
||||
.parse = modisk_parse, \
|
||||
.dev_done = modisk_done, \
|
||||
}
|
||||
|
||||
#define MODISK_PERF_TYPE { \
|
||||
.name = MODISK_PERF_NAME, \
|
||||
.type = TYPE_MOD, \
|
||||
.parse_atomic = 1, \
|
||||
.dev_done_atomic = 1, \
|
||||
.exec_atomic = 1, \
|
||||
.attach = modisk_attach, \
|
||||
.detach = modisk_detach, \
|
||||
.parse = modisk_parse, \
|
||||
.dev_done = modisk_done, \
|
||||
.exec = modisk_exec, \
|
||||
}
|
||||
|
||||
#define MODISK_DEF_BLOCK_SHIFT 10
|
||||
|
||||
struct modisk_params {
|
||||
@@ -70,8 +45,38 @@ static int modisk_parse(struct scst_cmd *);
|
||||
static int modisk_done(struct scst_cmd *);
|
||||
static int modisk_exec(struct scst_cmd *);
|
||||
|
||||
static struct scst_dev_type modisk_devtype = MODISK_TYPE;
|
||||
static struct scst_dev_type modisk_devtype_perf = MODISK_PERF_TYPE;
|
||||
static struct scst_dev_type modisk_devtype = {
|
||||
.name = MODISK_NAME,
|
||||
.type = TYPE_MOD,
|
||||
.parse_atomic = 1,
|
||||
.dev_done_atomic = 1,
|
||||
.exec_atomic = 1,
|
||||
.attach = modisk_attach,
|
||||
.detach = modisk_detach,
|
||||
.parse = modisk_parse,
|
||||
.dev_done = modisk_done,
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
.default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
|
||||
.trace_flags = &trace_flag,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct scst_dev_type modisk_devtype_perf = {
|
||||
.name = MODISK_PERF_NAME,
|
||||
.type = TYPE_MOD,
|
||||
.parse_atomic = 1,
|
||||
.dev_done_atomic = 1,
|
||||
.exec_atomic = 1,
|
||||
.attach = modisk_attach,
|
||||
.detach = modisk_detach,
|
||||
.parse = modisk_parse,
|
||||
.dev_done = modisk_done,
|
||||
.exec = modisk_exec,
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
.default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
|
||||
.trace_flags = &trace_flag,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int __init init_scst_modisk_driver(void)
|
||||
{
|
||||
@@ -85,31 +90,35 @@ static int __init init_scst_modisk_driver(void)
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
res = scst_dev_handler_build_std_proc(&modisk_devtype);
|
||||
if (res != 0)
|
||||
goto out_unreg1;
|
||||
|
||||
modisk_devtype_perf.module = THIS_MODULE;
|
||||
|
||||
res = scst_register_dev_driver(&modisk_devtype_perf);
|
||||
if (res < 0)
|
||||
goto out_unreg1_err1;
|
||||
goto out_unreg;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
res = scst_dev_handler_build_std_proc(&modisk_devtype);
|
||||
if (res != 0)
|
||||
goto out_unreg1;
|
||||
|
||||
res = scst_dev_handler_build_std_proc(&modisk_devtype_perf);
|
||||
if (res != 0)
|
||||
goto out_unreg2;
|
||||
#endif
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
out_unreg2:
|
||||
scst_dev_handler_destroy_std_proc(&modisk_devtype_perf);
|
||||
|
||||
out_unreg1_err1:
|
||||
scst_dev_handler_destroy_std_proc(&modisk_devtype);
|
||||
|
||||
out_unreg1:
|
||||
scst_unregister_dev_driver(&modisk_devtype_perf);
|
||||
#endif
|
||||
|
||||
out_unreg:
|
||||
scst_unregister_dev_driver(&modisk_devtype);
|
||||
goto out;
|
||||
}
|
||||
@@ -117,10 +126,14 @@ out_unreg1:
|
||||
static void __exit exit_scst_modisk_driver(void)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
scst_dev_handler_destroy_std_proc(&modisk_devtype_perf);
|
||||
scst_unregister_dev_driver(&modisk_devtype_perf);
|
||||
scst_dev_handler_destroy_std_proc(&modisk_devtype);
|
||||
#endif
|
||||
scst_unregister_dev_driver(&modisk_devtype_perf);
|
||||
scst_unregister_dev_driver(&modisk_devtype);
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
@@ -242,9 +255,7 @@ static int modisk_attach(struct scst_device *dev)
|
||||
res = scst_obtain_device_parameters(dev);
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("Failed to obtain control parameters for device "
|
||||
"%d:%d:%d:%d: %x", dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel, dev->scsi_dev->id,
|
||||
dev->scsi_dev->lun, res);
|
||||
"%s: %x", dev->virt_name, res);
|
||||
goto out_free_buf;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,26 +27,28 @@
|
||||
|
||||
#define PROCESSOR_NAME "dev_processor"
|
||||
|
||||
#define PROCESSOR_TYPE { \
|
||||
.name = PROCESSOR_NAME, \
|
||||
.type = TYPE_PROCESSOR, \
|
||||
.parse_atomic = 1, \
|
||||
/* .dev_done_atomic = 1,*/ \
|
||||
.attach = processor_attach, \
|
||||
/* .detach = processor_detach,*/ \
|
||||
.parse = processor_parse, \
|
||||
/* .dev_done = processor_done*/ \
|
||||
}
|
||||
|
||||
#define PROCESSOR_RETRIES 2
|
||||
#define READ_CAP_LEN 8
|
||||
#define PROCESSOR_RETRIES 2
|
||||
#define READ_CAP_LEN 8
|
||||
|
||||
static int processor_attach(struct scst_device *);
|
||||
/*static void processor_detach(struct scst_device *);*/
|
||||
static int processor_parse(struct scst_cmd *);
|
||||
/*static int processor_done(struct scst_cmd *);*/
|
||||
|
||||
static struct scst_dev_type processor_devtype = PROCESSOR_TYPE;
|
||||
static struct scst_dev_type processor_devtype = {
|
||||
.name = PROCESSOR_NAME,
|
||||
.type = TYPE_PROCESSOR,
|
||||
.parse_atomic = 1,
|
||||
/* .dev_done_atomic = 1,*/
|
||||
.attach = processor_attach,
|
||||
/* .detach = processor_detach,*/
|
||||
.parse = processor_parse,
|
||||
/* .dev_done = processor_done*/
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
.default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
|
||||
.trace_flags = &trace_flag,
|
||||
#endif
|
||||
};
|
||||
|
||||
/**************************************************************
|
||||
* Function: processor_attach
|
||||
@@ -101,9 +103,7 @@ static int processor_attach(struct scst_device *dev)
|
||||
res = scst_obtain_device_parameters(dev);
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("Failed to obtain control parameters for device "
|
||||
"%d:%d:%d:%d", dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel, dev->scsi_dev->id,
|
||||
dev->scsi_dev->lun);
|
||||
"%s", dev->virt_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -202,23 +202,28 @@ static int __init processor_init(void)
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
res = scst_dev_handler_build_std_proc(&processor_devtype);
|
||||
if (res != 0)
|
||||
goto out_err;
|
||||
#endif
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
out_err:
|
||||
scst_unregister_dev_driver(&processor_devtype);
|
||||
goto out;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __exit processor_exit(void)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
scst_dev_handler_destroy_std_proc(&processor_devtype);
|
||||
#endif
|
||||
scst_unregister_dev_driver(&processor_devtype);
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
|
||||
@@ -27,26 +27,28 @@
|
||||
|
||||
#define RAID_NAME "dev_raid"
|
||||
|
||||
#define RAID_TYPE { \
|
||||
.name = RAID_NAME, \
|
||||
.type = TYPE_RAID, \
|
||||
.parse_atomic = 1, \
|
||||
/* .dev_done_atomic = 1,*/ \
|
||||
.attach = raid_attach, \
|
||||
/* .detach = raid_detach,*/ \
|
||||
.parse = raid_parse, \
|
||||
/* .dev_done = raid_done*/ \
|
||||
}
|
||||
|
||||
#define RAID_RETRIES 2
|
||||
#define READ_CAP_LEN 8
|
||||
#define RAID_RETRIES 2
|
||||
#define READ_CAP_LEN 8
|
||||
|
||||
static int raid_attach(struct scst_device *);
|
||||
/* static void raid_detach(struct scst_device *); */
|
||||
static int raid_parse(struct scst_cmd *);
|
||||
/* static int raid_done(struct scst_cmd *); */
|
||||
|
||||
static struct scst_dev_type raid_devtype = RAID_TYPE;
|
||||
static struct scst_dev_type raid_devtype = {
|
||||
.name = RAID_NAME,
|
||||
.type = TYPE_RAID,
|
||||
.parse_atomic = 1,
|
||||
/* .dev_done_atomic = 1,*/
|
||||
.attach = raid_attach,
|
||||
/* .detach = raid_detach,*/
|
||||
.parse = raid_parse,
|
||||
/* .dev_done = raid_done,*/
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
.default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
|
||||
.trace_flags = &trace_flag,
|
||||
#endif
|
||||
};
|
||||
|
||||
/**************************************************************
|
||||
* Function: raid_attach
|
||||
@@ -101,9 +103,7 @@ static int raid_attach(struct scst_device *dev)
|
||||
res = scst_obtain_device_parameters(dev);
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("Failed to obtain control parameters for device "
|
||||
"%d:%d:%d:%d", dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel, dev->scsi_dev->id,
|
||||
dev->scsi_dev->lun);
|
||||
"%s", dev->virt_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -202,23 +202,29 @@ static int __init raid_init(void)
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
res = scst_dev_handler_build_std_proc(&raid_devtype);
|
||||
if (res != 0)
|
||||
goto out_err;
|
||||
#endif
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
out_err:
|
||||
scst_unregister_dev_driver(&raid_devtype);
|
||||
goto out;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __exit raid_exit(void)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
scst_dev_handler_destroy_std_proc(&raid_devtype);
|
||||
#endif
|
||||
scst_unregister_dev_driver(&raid_devtype);
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
|
||||
@@ -33,37 +33,12 @@
|
||||
# define TAPE_NAME "dev_tape"
|
||||
# define TAPE_PERF_NAME "dev_tape_perf"
|
||||
|
||||
#define TAPE_TYPE { \
|
||||
.name = TAPE_NAME, \
|
||||
.type = TYPE_TAPE, \
|
||||
.parse_atomic = 1, \
|
||||
.dev_done_atomic = 1, \
|
||||
.exec_atomic = 1, \
|
||||
.attach = tape_attach, \
|
||||
.detach = tape_detach, \
|
||||
.parse = tape_parse, \
|
||||
.dev_done = tape_done, \
|
||||
}
|
||||
|
||||
#define TAPE_PERF_TYPE { \
|
||||
.name = TAPE_PERF_NAME, \
|
||||
.type = TYPE_TAPE, \
|
||||
.parse_atomic = 1, \
|
||||
.dev_done_atomic = 1, \
|
||||
.exec_atomic = 1, \
|
||||
.attach = tape_attach, \
|
||||
.detach = tape_detach, \
|
||||
.parse = tape_parse, \
|
||||
.dev_done = tape_done, \
|
||||
.exec = tape_exec, \
|
||||
}
|
||||
|
||||
#define TAPE_RETRIES 2
|
||||
#define TAPE_RETRIES 2
|
||||
|
||||
#define TAPE_DEF_BLOCK_SIZE 512
|
||||
|
||||
/* The fixed bit in READ/WRITE/VERIFY */
|
||||
#define SILI_BIT 2
|
||||
#define SILI_BIT 2
|
||||
|
||||
struct tape_params {
|
||||
int block_size;
|
||||
@@ -75,8 +50,38 @@ static int tape_parse(struct scst_cmd *);
|
||||
static int tape_done(struct scst_cmd *);
|
||||
static int tape_exec(struct scst_cmd *);
|
||||
|
||||
static struct scst_dev_type tape_devtype = TAPE_TYPE;
|
||||
static struct scst_dev_type tape_devtype_perf = TAPE_PERF_TYPE;
|
||||
static struct scst_dev_type tape_devtype = {
|
||||
.name = TAPE_NAME,
|
||||
.type = TYPE_TAPE,
|
||||
.parse_atomic = 1,
|
||||
.dev_done_atomic = 1,
|
||||
.exec_atomic = 1,
|
||||
.attach = tape_attach,
|
||||
.detach = tape_detach,
|
||||
.parse = tape_parse,
|
||||
.dev_done = tape_done,
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
.default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
|
||||
.trace_flags = &trace_flag,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct scst_dev_type tape_devtype_perf = {
|
||||
.name = TAPE_PERF_NAME,
|
||||
.type = TYPE_TAPE,
|
||||
.parse_atomic = 1,
|
||||
.dev_done_atomic = 1,
|
||||
.exec_atomic = 1,
|
||||
.attach = tape_attach,
|
||||
.detach = tape_detach,
|
||||
.parse = tape_parse,
|
||||
.dev_done = tape_done,
|
||||
.exec = tape_exec,
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
.default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
|
||||
.trace_flags = &trace_flag,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int __init init_scst_tape_driver(void)
|
||||
{
|
||||
@@ -90,31 +95,35 @@ static int __init init_scst_tape_driver(void)
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
res = scst_dev_handler_build_std_proc(&tape_devtype);
|
||||
if (res != 0)
|
||||
goto out_unreg1;
|
||||
|
||||
tape_devtype_perf.module = THIS_MODULE;
|
||||
|
||||
res = scst_register_dev_driver(&tape_devtype_perf);
|
||||
if (res < 0)
|
||||
goto out_unreg1_err1;
|
||||
goto out_unreg;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
res = scst_dev_handler_build_std_proc(&tape_devtype);
|
||||
if (res != 0)
|
||||
goto out_unreg1;
|
||||
|
||||
res = scst_dev_handler_build_std_proc(&tape_devtype_perf);
|
||||
if (res != 0)
|
||||
goto out_unreg2;
|
||||
#endif
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
out_unreg2:
|
||||
scst_dev_handler_destroy_std_proc(&tape_devtype_perf);
|
||||
|
||||
out_unreg1_err1:
|
||||
scst_dev_handler_destroy_std_proc(&tape_devtype);
|
||||
|
||||
out_unreg1:
|
||||
scst_unregister_dev_driver(&tape_devtype_perf);
|
||||
#endif
|
||||
|
||||
out_unreg:
|
||||
scst_unregister_dev_driver(&tape_devtype);
|
||||
goto out;
|
||||
}
|
||||
@@ -122,10 +131,14 @@ out_unreg1:
|
||||
static void __exit exit_scst_tape_driver(void)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
scst_dev_handler_destroy_std_proc(&tape_devtype_perf);
|
||||
scst_unregister_dev_driver(&tape_devtype_perf);
|
||||
scst_dev_handler_destroy_std_proc(&tape_devtype);
|
||||
#endif
|
||||
scst_unregister_dev_driver(&tape_devtype_perf);
|
||||
scst_unregister_dev_driver(&tape_devtype);
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
@@ -226,9 +239,7 @@ static int tape_attach(struct scst_device *dev)
|
||||
res = scst_obtain_device_parameters(dev);
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("Failed to obtain control parameters for device "
|
||||
"%d:%d:%d:%d", dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel, dev->scsi_dev->id,
|
||||
dev->scsi_dev->lun);
|
||||
"%s", dev->virt_name);
|
||||
goto out_free_buf;
|
||||
}
|
||||
|
||||
|
||||
@@ -180,8 +180,13 @@ static long dev_user_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
static int dev_user_release(struct inode *inode, struct file *file);
|
||||
static int dev_user_exit_dev(struct scst_user_dev *dev);
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
static int dev_user_read_proc(struct seq_file *seq,
|
||||
struct scst_dev_type *dev_type);
|
||||
#endif
|
||||
|
||||
static int dev_usr_parse(struct scst_cmd *cmd);
|
||||
|
||||
/** Data **/
|
||||
|
||||
@@ -199,6 +204,19 @@ static const struct file_operations dev_user_fops = {
|
||||
.release = dev_user_release,
|
||||
};
|
||||
|
||||
static struct scst_dev_type dev_user_devtype = {
|
||||
.name = DEV_USER_NAME,
|
||||
.type = -1,
|
||||
.parse = dev_usr_parse,
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
.read_proc = dev_user_read_proc,
|
||||
#endif
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
.default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS,
|
||||
.trace_flags = &trace_flag,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct class *dev_user_sysfs_class;
|
||||
|
||||
static DEFINE_SPINLOCK(dev_list_lock);
|
||||
@@ -2489,13 +2507,11 @@ static int dev_user_attach_tgt(struct scst_tgt_dev *tgt_dev)
|
||||
sizeof(ucmd->user_cmd.sess.initiator_name)-1);
|
||||
ucmd->user_cmd.sess.initiator_name[
|
||||
sizeof(ucmd->user_cmd.sess.initiator_name)-1] = '\0';
|
||||
if (tgt_dev->sess->tgt->default_group_name != NULL) {
|
||||
strncpy(ucmd->user_cmd.sess.target_name,
|
||||
&tgt_dev->sess->tgt->default_group_name[sizeof(SCST_DEFAULT_ACG_NAME)],
|
||||
sizeof(ucmd->user_cmd.sess.target_name)-1);
|
||||
ucmd->user_cmd.sess.target_name[
|
||||
sizeof(ucmd->user_cmd.sess.target_name)-1] = '\0';
|
||||
}
|
||||
strncpy(ucmd->user_cmd.sess.target_name,
|
||||
tgt_dev->sess->tgt->tgt_name,
|
||||
sizeof(ucmd->user_cmd.sess.target_name)-1);
|
||||
ucmd->user_cmd.sess.target_name[
|
||||
sizeof(ucmd->user_cmd.sess.target_name)-1] = '\0';
|
||||
|
||||
TRACE_MGMT_DBG("Preparing ATTACH_SESS %p (h %d, sess_h %llx, LUN %llx, "
|
||||
"threads_num %d, rd_only %d, initiator %s, target %s)",
|
||||
@@ -2758,7 +2774,9 @@ static int dev_user_register_dev(struct file *file,
|
||||
dev->devtype.parse_atomic = 1;
|
||||
dev->devtype.exec_atomic = 0; /* no point to make it 1 */
|
||||
dev->devtype.dev_done_atomic = 1;
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
dev->devtype.no_proc = 1;
|
||||
#endif
|
||||
dev->devtype.attach = dev_user_attach;
|
||||
dev->devtype.detach = dev_user_detach;
|
||||
dev->devtype.attach_tgt = dev_user_attach_tgt;
|
||||
@@ -2767,6 +2785,8 @@ static int dev_user_register_dev(struct file *file,
|
||||
dev->devtype.on_free_cmd = dev_user_on_free_cmd;
|
||||
dev->devtype.task_mgmt_fn = dev_user_task_mgmt_fn;
|
||||
|
||||
dev->devtype.parent = &dev_user_devtype;
|
||||
|
||||
init_completion(&dev->cleanup_cmpl);
|
||||
dev->block = block;
|
||||
dev->def_block = block;
|
||||
@@ -3200,16 +3220,6 @@ static int dev_usr_parse(struct scst_cmd *cmd)
|
||||
return SCST_CMD_STATE_DEFAULT;
|
||||
}
|
||||
|
||||
/* Needed only for /proc support */
|
||||
#define USR_TYPE { \
|
||||
.name = DEV_USER_NAME, \
|
||||
.type = -1, \
|
||||
.parse = dev_usr_parse, \
|
||||
.read_proc = dev_user_read_proc, \
|
||||
}
|
||||
|
||||
static struct scst_dev_type dev_user_devtype = USR_TYPE;
|
||||
|
||||
static int dev_user_exit_dev(struct scst_user_dev *dev)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
@@ -3351,7 +3361,7 @@ out:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
/*
|
||||
* Called when a file in the /proc/scsi_tgt/scst_user is read
|
||||
*/
|
||||
@@ -3389,6 +3399,7 @@ static int dev_user_read_proc(struct seq_file *seq, struct scst_dev_type *dev_ty
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
static inline int test_cleanup_list(void)
|
||||
{
|
||||
@@ -3522,16 +3533,22 @@ static int __init init_scst_user(void)
|
||||
if (res < 0)
|
||||
goto out_cache1;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
res = scst_dev_handler_build_std_proc(&dev_user_devtype);
|
||||
if (res != 0)
|
||||
goto out_unreg;
|
||||
#endif
|
||||
|
||||
dev_user_sysfs_class = class_create(THIS_MODULE, DEV_USER_NAME);
|
||||
if (IS_ERR(dev_user_sysfs_class)) {
|
||||
PRINT_ERROR("%s", "Unable create sysfs class for SCST user "
|
||||
"space handler");
|
||||
res = PTR_ERR(dev_user_sysfs_class);
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
goto out_proc;
|
||||
#else
|
||||
goto out_unreg;
|
||||
#endif
|
||||
}
|
||||
|
||||
res = register_chrdev(DEV_USER_MAJOR, DEV_USER_NAME, &dev_user_fops);
|
||||
@@ -3586,8 +3603,10 @@ out_chrdev:
|
||||
out_class:
|
||||
class_destroy(dev_user_sysfs_class);
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
out_proc:
|
||||
scst_dev_handler_destroy_std_proc(&dev_user_devtype);
|
||||
#endif
|
||||
|
||||
out_unreg:
|
||||
scst_unregister_dev_driver(&dev_user_devtype);
|
||||
@@ -3618,7 +3637,9 @@ static void __exit exit_scst_user(void)
|
||||
#endif
|
||||
class_destroy(dev_user_sysfs_class);
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
scst_dev_handler_destroy_std_proc(&dev_user_devtype);
|
||||
#endif
|
||||
scst_unregister_virtual_dev_driver(&dev_user_devtype);
|
||||
|
||||
kmem_cache_destroy(user_get_cmd_cachep);
|
||||
|
||||
+1546
-502
File diff suppressed because it is too large
Load Diff
+89
-67
@@ -57,11 +57,11 @@ static void scst_alloc_set_UA(struct scst_tgt_dev *tgt_dev,
|
||||
const uint8_t *sense, int sense_len, int flags);
|
||||
static void scst_free_all_UA(struct scst_tgt_dev *tgt_dev);
|
||||
static void scst_release_space(struct scst_cmd *cmd);
|
||||
static void scst_sess_free_tgt_devs(struct scst_session *sess);
|
||||
static void scst_unblock_cmds(struct scst_device *dev);
|
||||
static void scst_clear_reservation(struct scst_tgt_dev *tgt_dev);
|
||||
static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
|
||||
struct scst_acg_dev *acg_dev);
|
||||
static void scst_tgt_retry_timer_fn(unsigned long arg);
|
||||
|
||||
#ifdef CONFIG_SCST_DEBUG_TM
|
||||
static void tm_dbg_init_tgt_dev(struct scst_tgt_dev *tgt_dev,
|
||||
@@ -1244,6 +1244,44 @@ restart1:
|
||||
return;
|
||||
}
|
||||
|
||||
struct scst_tgt *scst_alloc_tgt(struct scst_tgt_template *tgtt)
|
||||
{
|
||||
struct scst_tgt *tgt;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
tgt = kzalloc(sizeof(*tgt), GFP_KERNEL);
|
||||
if (tgt == NULL) {
|
||||
TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of tgt failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&tgt->sess_list);
|
||||
init_waitqueue_head(&tgt->unreg_waitQ);
|
||||
tgt->tgtt = tgtt;
|
||||
tgt->sg_tablesize = tgtt->sg_tablesize;
|
||||
spin_lock_init(&tgt->tgt_lock);
|
||||
INIT_LIST_HEAD(&tgt->retry_cmd_list);
|
||||
atomic_set(&tgt->finished_cmds, 0);
|
||||
init_timer(&tgt->retry_timer);
|
||||
tgt->retry_timer.data = (unsigned long)tgt;
|
||||
tgt->retry_timer.function = scst_tgt_retry_timer_fn;
|
||||
|
||||
out:
|
||||
TRACE_EXIT_HRES((unsigned long)tgt);
|
||||
return tgt;
|
||||
}
|
||||
|
||||
void scst_free_tgt(struct scst_tgt *tgt)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
kfree(tgt);
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Called under scst_mutex and suspended activity */
|
||||
int scst_alloc_device(gfp_t gfp_mask, struct scst_device **out_dev)
|
||||
{
|
||||
@@ -1310,6 +1348,7 @@ void scst_free_device(struct scst_device *dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
kfree(dev->virt_name);
|
||||
__exit_io_context(dev->dev_io_ctx);
|
||||
|
||||
kfree(dev);
|
||||
@@ -1356,6 +1395,16 @@ out:
|
||||
return res;
|
||||
}
|
||||
|
||||
void scst_acg_dev_destroy(struct scst_acg_dev *acg_dev)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
kmem_cache_free(scst_acgd_cachep, acg_dev);
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
/* The activity supposed to be suspended and scst_mutex held */
|
||||
static void scst_free_acg_dev(struct scst_acg_dev *acg_dev)
|
||||
{
|
||||
@@ -1366,7 +1415,11 @@ static void scst_free_acg_dev(struct scst_acg_dev *acg_dev)
|
||||
list_del(&acg_dev->acg_dev_list_entry);
|
||||
list_del(&acg_dev->dev_acg_dev_list_entry);
|
||||
|
||||
kmem_cache_free(scst_acgd_cachep, acg_dev);
|
||||
if (acg_dev->acg_dev_kobj_initialized) {
|
||||
kobject_del(&acg_dev->acg_dev_kobj);
|
||||
kobject_put(&acg_dev->acg_dev_kobj);
|
||||
} else
|
||||
scst_acg_dev_destroy(acg_dev);
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
@@ -1505,16 +1558,8 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
|
||||
if (sess->tgt->tgtt->unchecked_isa_dma || ini_unchecked_isa_dma)
|
||||
scst_sgv_pool_use_dma(tgt_dev);
|
||||
|
||||
if (dev->scsi_dev != NULL) {
|
||||
TRACE_MGMT_DBG("host=%d, channel=%d, id=%d, lun=%d, "
|
||||
"SCST lun=%lld", dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel, dev->scsi_dev->id,
|
||||
dev->scsi_dev->lun,
|
||||
(long long unsigned int)tgt_dev->lun);
|
||||
} else {
|
||||
TRACE_MGMT_DBG("Virtual device %s on SCST lun=%lld",
|
||||
dev->virt_name, (long long unsigned int)tgt_dev->lun);
|
||||
}
|
||||
TRACE_MGMT_DBG("Device %s on SCST lun=%lld",
|
||||
dev->virt_name, (long long unsigned int)tgt_dev->lun);
|
||||
|
||||
spin_lock_init(&tgt_dev->tgt_dev_lock);
|
||||
INIT_LIST_HEAD(&tgt_dev->UA_list);
|
||||
@@ -1750,7 +1795,7 @@ out_free:
|
||||
* scst_mutex supposed to be held, there must not be parallel activity in this
|
||||
* session.
|
||||
*/
|
||||
static void scst_sess_free_tgt_devs(struct scst_session *sess)
|
||||
void scst_sess_free_tgt_devs(struct scst_session *sess)
|
||||
{
|
||||
int i;
|
||||
struct scst_tgt_dev *tgt_dev, *t;
|
||||
@@ -1811,20 +1856,9 @@ int scst_acg_add_dev(struct scst_acg *acg, struct scst_device *dev,
|
||||
if (gen_scst_report_luns_changed)
|
||||
scst_report_luns_changed(acg);
|
||||
|
||||
if (dev->virt_name != NULL) {
|
||||
PRINT_INFO("Added device %s to group %s (LUN %lld, "
|
||||
"rd_only %d)", dev->virt_name, acg->acg_name,
|
||||
(long long unsigned int)lun,
|
||||
read_only);
|
||||
} else {
|
||||
PRINT_INFO("Added device %d:%d:%d:%d to group %s (LUN "
|
||||
"%lld, rd_only %d)",
|
||||
dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel, dev->scsi_dev->id,
|
||||
dev->scsi_dev->lun, acg->acg_name,
|
||||
(long long unsigned int)lun,
|
||||
read_only);
|
||||
}
|
||||
PRINT_INFO("Added device %s to group %s (LUN %lld, "
|
||||
"rd_only %d)", dev->virt_name, acg->acg_name,
|
||||
(long long unsigned int)lun, read_only);
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
@@ -1872,15 +1906,8 @@ int scst_acg_remove_dev(struct scst_acg *acg, struct scst_device *dev,
|
||||
if (gen_scst_report_luns_changed)
|
||||
scst_report_luns_changed(acg);
|
||||
|
||||
if (dev->virt_name != NULL) {
|
||||
PRINT_INFO("Removed device %s from group %s",
|
||||
dev->virt_name, acg->acg_name);
|
||||
} else {
|
||||
PRINT_INFO("Removed device %d:%d:%d:%d from group %s",
|
||||
dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel, dev->scsi_dev->id,
|
||||
dev->scsi_dev->lun, acg->acg_name);
|
||||
}
|
||||
PRINT_INFO("Removed device %s from group %s", dev->virt_name,
|
||||
acg->acg_name);
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
@@ -2158,9 +2185,7 @@ static void scst_send_release(struct scst_device *dev)
|
||||
req = scsi_allocate_request(scsi_dev, GFP_KERNEL);
|
||||
if (req == NULL) {
|
||||
PRINT_ERROR("Allocation of scsi_request failed: unable "
|
||||
"to RELEASE device %d:%d:%d:%d",
|
||||
scsi_dev->host->host_no, scsi_dev->channel,
|
||||
scsi_dev->id, scsi_dev->lun);
|
||||
"to RELEASE device %s", dev->virt_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -2347,10 +2372,21 @@ void scst_free_session(struct scst_session *sess)
|
||||
|
||||
scst_sess_free_tgt_devs(sess);
|
||||
|
||||
/* Called under lock to protect from too early tgt release */
|
||||
wake_up_all(&sess->tgt->unreg_waitQ);
|
||||
|
||||
mutex_unlock(&scst_mutex);
|
||||
|
||||
scst_sess_sysfs_put(sess);
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
void scst_release_session(struct scst_session *sess)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
kfree(sess->initiator_name);
|
||||
kmem_cache_free(scst_sess_cachep, sess);
|
||||
|
||||
@@ -2611,7 +2647,7 @@ void scst_check_retries(struct scst_tgt *tgt)
|
||||
return;
|
||||
}
|
||||
|
||||
void scst_tgt_retry_timer_fn(unsigned long arg)
|
||||
static void scst_tgt_retry_timer_fn(unsigned long arg)
|
||||
{
|
||||
struct scst_tgt *tgt = (struct scst_tgt *)arg;
|
||||
unsigned long flags;
|
||||
@@ -3992,11 +4028,8 @@ int scst_obtain_device_parameters(struct scst_device *dev)
|
||||
dev->tst = buffer[4+2] >> 5;
|
||||
q = buffer[4+3] >> 4;
|
||||
if (q > SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER) {
|
||||
PRINT_ERROR("Too big QUEUE ALG %x, dev "
|
||||
"%d:%d:%d:%d", dev->queue_alg,
|
||||
dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel,
|
||||
dev->scsi_dev->id, dev->scsi_dev->lun);
|
||||
PRINT_ERROR("Too big QUEUE ALG %x, dev %s",
|
||||
dev->queue_alg, dev->virt_name);
|
||||
}
|
||||
dev->queue_alg = q;
|
||||
dev->swp = (buffer[4+4] & 0x8) >> 3;
|
||||
@@ -4011,12 +4044,10 @@ int scst_obtain_device_parameters(struct scst_device *dev)
|
||||
dev->has_own_order_mgmt = !dev->queue_alg;
|
||||
|
||||
TRACE(TRACE_SCSI|TRACE_MGMT_MINOR,
|
||||
"Device %d:%d:%d:%d: TST %x, "
|
||||
"Device %s: TST %x, "
|
||||
"QUEUE ALG %x, SWP %x, TAS %x, D_SENSE %d"
|
||||
"has_own_order_mgmt %d",
|
||||
dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel, dev->scsi_dev->id,
|
||||
dev->scsi_dev->lun, dev->tst, dev->queue_alg,
|
||||
dev->virt_name, dev->tst, dev->queue_alg,
|
||||
dev->swp, dev->tas, dev->d_sense,
|
||||
dev->has_own_order_mgmt);
|
||||
|
||||
@@ -4037,16 +4068,13 @@ int scst_obtain_device_parameters(struct scst_device *dev)
|
||||
SCST_SENSE_KEY_VALID,
|
||||
ILLEGAL_REQUEST, 0, 0)) {
|
||||
TRACE(TRACE_SCSI|TRACE_MGMT_MINOR,
|
||||
"Device %d:%d:%d:%d doesn't "
|
||||
"Device %s doesn't "
|
||||
"support control mode page, "
|
||||
"using defaults: TST %x, "
|
||||
"QUEUE ALG %x, SWP %x, "
|
||||
"TAS %x, D_SENSE %d, "
|
||||
"has_own_order_mgmt %d ",
|
||||
dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel,
|
||||
dev->scsi_dev->id,
|
||||
dev->scsi_dev->lun,
|
||||
dev->virt_name,
|
||||
dev->tst, dev->queue_alg,
|
||||
dev->swp, dev->tas,
|
||||
dev->d_sense,
|
||||
@@ -4057,23 +4085,16 @@ int scst_obtain_device_parameters(struct scst_device *dev)
|
||||
sizeof(sense_buffer),
|
||||
SCST_SENSE_KEY_VALID,
|
||||
NOT_READY, 0, 0)) {
|
||||
TRACE(TRACE_SCSI,
|
||||
"Device %d:%d:%d:%d not ready",
|
||||
dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel,
|
||||
dev->scsi_dev->id,
|
||||
dev->scsi_dev->lun);
|
||||
TRACE(TRACE_SCSI, "Device %s not ready",
|
||||
dev->virt_name);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
TRACE(TRACE_SCSI|TRACE_MGMT_MINOR,
|
||||
"Internal MODE SENSE to "
|
||||
"device %d:%d:%d:%d failed: %x",
|
||||
dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel,
|
||||
dev->scsi_dev->id,
|
||||
dev->scsi_dev->lun, res);
|
||||
"device %s failed: %x",
|
||||
dev->virt_name, res);
|
||||
PRINT_BUFF_FLAG(TRACE_SCSI|TRACE_MGMT_MINOR,
|
||||
"MODE SENSE sense",
|
||||
sense_buffer, sizeof(sense_buffer));
|
||||
@@ -5053,7 +5074,7 @@ static const int tm_dbg_on_state_num_passes[] = { 5, 1, 0x7ffffff };
|
||||
static void tm_dbg_init_tgt_dev(struct scst_tgt_dev *tgt_dev,
|
||||
struct scst_acg_dev *acg_dev)
|
||||
{
|
||||
if ((acg_dev->acg == scst_default_acg) && (acg_dev->lun == 0)) {
|
||||
if (acg_dev->lun == 6) {
|
||||
unsigned long flags;
|
||||
|
||||
if (tm_dbg_tgt_dev != NULL)
|
||||
@@ -5065,8 +5086,9 @@ static void tm_dbg_init_tgt_dev(struct scst_tgt_dev *tgt_dev,
|
||||
tm_dbg_on_state_passes =
|
||||
tm_dbg_on_state_num_passes[tm_dbg_state];
|
||||
tm_dbg_tgt_dev = tgt_dev;
|
||||
PRINT_INFO("LUN 0 connected from initiator %s is under "
|
||||
PRINT_INFO("LUN %lld connected from initiator %s is under "
|
||||
"TM debugging (tgt_dev %p)",
|
||||
(unsigned long long)tgt_dev->lun,
|
||||
tgt_dev->sess->initiator_name, tgt_dev);
|
||||
spin_unlock_irqrestore(&scst_tm_dbg_lock, flags);
|
||||
}
|
||||
|
||||
+261
-77
@@ -102,7 +102,9 @@ struct kmem_cache *scst_sess_cachep;
|
||||
struct kmem_cache *scst_acgd_cachep;
|
||||
|
||||
struct list_head scst_acg_list;
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
struct scst_acg *scst_default_acg;
|
||||
#endif
|
||||
|
||||
spinlock_t scst_init_lock;
|
||||
wait_queue_head_t scst_init_cmd_list_waitQ;
|
||||
@@ -188,21 +190,21 @@ int __scst_register_target_template(struct scst_tgt_template *vtt,
|
||||
}
|
||||
|
||||
if (!vtt->detect) {
|
||||
PRINT_ERROR("Target driver %s doesn't have a "
|
||||
PRINT_ERROR("Target driver %s must have "
|
||||
"detect() method.", vtt->name);
|
||||
res = -EINVAL;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (!vtt->release) {
|
||||
PRINT_ERROR("Target driver %s doesn't have a "
|
||||
PRINT_ERROR("Target driver %s must have "
|
||||
"release() method.", vtt->name);
|
||||
res = -EINVAL;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (!vtt->xmit_response) {
|
||||
PRINT_ERROR("Target driver %s doesn't have a "
|
||||
PRINT_ERROR("Target driver %s must have "
|
||||
"xmit_response() method.", vtt->name);
|
||||
res = -EINVAL;
|
||||
goto out_err;
|
||||
@@ -216,26 +218,40 @@ int __scst_register_target_template(struct scst_tgt_template *vtt,
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (!vtt->enable_tgt || !vtt->is_tgt_enabled) {
|
||||
PRINT_WARNING("Target driver %s doesn't have enable_tgt() "
|
||||
"and/or is_tgt_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);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
if (!vtt->no_proc_entry) {
|
||||
res = scst_build_proc_target_dir_entries(vtt);
|
||||
if (res < 0)
|
||||
goto out_err;
|
||||
}
|
||||
#endif
|
||||
|
||||
res = scst_create_tgtt_sysfs(vtt);
|
||||
if (res)
|
||||
goto out_sysfs_err;
|
||||
|
||||
if (vtt->rdy_to_xfer == NULL)
|
||||
vtt->rdy_to_xfer_atomic = 1;
|
||||
|
||||
if (mutex_lock_interruptible(&m) != 0)
|
||||
goto out_err;
|
||||
goto out_sysfs_err;
|
||||
|
||||
if (mutex_lock_interruptible(&scst_mutex) != 0)
|
||||
goto out_m_up;
|
||||
goto out_m_err;
|
||||
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);
|
||||
mutex_unlock(&scst_mutex);
|
||||
goto out_cleanup;
|
||||
goto out_m_err;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&scst_mutex);
|
||||
@@ -246,7 +262,7 @@ int __scst_register_target_template(struct scst_tgt_template *vtt,
|
||||
if (res < 0) {
|
||||
PRINT_ERROR("%s", "The detect() routine failed");
|
||||
res = -EINVAL;
|
||||
goto out_cleanup;
|
||||
goto out_m_err;
|
||||
}
|
||||
|
||||
mutex_lock(&scst_mutex);
|
||||
@@ -263,12 +279,15 @@ out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
|
||||
out_cleanup:
|
||||
scst_cleanup_proc_target_dir_entries(vtt);
|
||||
|
||||
out_m_up:
|
||||
out_m_err:
|
||||
mutex_unlock(&m);
|
||||
|
||||
out_sysfs_err:
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
scst_cleanup_proc_target_dir_entries(vtt);
|
||||
#endif
|
||||
scst_tgtt_sysfs_put(vtt);
|
||||
|
||||
out_err:
|
||||
PRINT_ERROR("Failed to register target template %s", vtt->name);
|
||||
goto out;
|
||||
@@ -293,7 +312,7 @@ void scst_unregister_target_template(struct scst_tgt_template *vtt)
|
||||
}
|
||||
if (!found) {
|
||||
PRINT_ERROR("Target driver %s isn't registered", vtt->name);
|
||||
goto out_up;
|
||||
goto out_err_up;
|
||||
}
|
||||
|
||||
restart:
|
||||
@@ -305,15 +324,23 @@ restart:
|
||||
}
|
||||
list_del(&vtt->scst_template_list_entry);
|
||||
|
||||
PRINT_INFO("Target template %s unregistered successfully", vtt->name);
|
||||
|
||||
out_up:
|
||||
mutex_unlock(&scst_mutex);
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
scst_cleanup_proc_target_dir_entries(vtt);
|
||||
#endif
|
||||
|
||||
scst_tgtt_sysfs_put(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);
|
||||
|
||||
@@ -325,24 +352,12 @@ struct scst_tgt *scst_register(struct scst_tgt_template *vtt,
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
tgt = kzalloc(sizeof(*tgt), GFP_KERNEL);
|
||||
tgt = scst_alloc_tgt(vtt);
|
||||
if (tgt == NULL) {
|
||||
TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of tgt failed");
|
||||
rc = -ENOMEM;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&tgt->sess_list);
|
||||
init_waitqueue_head(&tgt->unreg_waitQ);
|
||||
tgt->tgtt = vtt;
|
||||
tgt->sg_tablesize = vtt->sg_tablesize;
|
||||
spin_lock_init(&tgt->tgt_lock);
|
||||
INIT_LIST_HEAD(&tgt->retry_cmd_list);
|
||||
atomic_set(&tgt->finished_cmds, 0);
|
||||
init_timer(&tgt->retry_timer);
|
||||
tgt->retry_timer.data = (unsigned long)tgt;
|
||||
tgt->retry_timer.function = scst_tgt_retry_timer_fn;
|
||||
|
||||
rc = scst_suspend_activity(true);
|
||||
if (rc != 0)
|
||||
goto out_free_tgt_err;
|
||||
@@ -353,25 +368,72 @@ struct scst_tgt *scst_register(struct scst_tgt_template *vtt,
|
||||
}
|
||||
|
||||
if (target_name != NULL) {
|
||||
int len = strlen(target_name) + 1 +
|
||||
strlen(SCST_DEFAULT_ACG_NAME) + 1;
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
int len = strlen(target_name) +
|
||||
strlen(SCST_DEFAULT_ACG_NAME) + 1 + 1;
|
||||
|
||||
tgt->default_group_name = kmalloc(len, GFP_KERNEL);
|
||||
if (tgt->default_group_name == NULL) {
|
||||
TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of default "
|
||||
"group name failed");
|
||||
TRACE(TRACE_OUT_OF_MEM, "Allocation of default "
|
||||
"group name failed (tgt %s)", target_name);
|
||||
rc = -ENOMEM;
|
||||
goto out_unlock_resume;
|
||||
}
|
||||
sprintf(tgt->default_group_name, "%s_%s", SCST_DEFAULT_ACG_NAME,
|
||||
target_name);
|
||||
#endif
|
||||
|
||||
tgt->tgt_name = kmalloc(strlen(target_name) + 1, GFP_KERNEL);
|
||||
if (tgt->tgt_name == NULL) {
|
||||
TRACE(TRACE_OUT_OF_MEM, "Allocation of tgt name %s failed",
|
||||
target_name);
|
||||
rc = -ENOMEM;
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
goto out_free_def_name;
|
||||
#else
|
||||
goto out_unlock_resume;
|
||||
#endif
|
||||
}
|
||||
strcpy(tgt->tgt_name, target_name);
|
||||
} else {
|
||||
static int tgt_num; /* protected by scst_mutex */
|
||||
int len = strlen(vtt->name) +
|
||||
strlen(SCST_DEFAULT_TGT_NAME_SUFFIX) + 11 + 1;
|
||||
|
||||
tgt->tgt_name = kmalloc(len, GFP_KERNEL);
|
||||
if (tgt->tgt_name == NULL) {
|
||||
TRACE(TRACE_OUT_OF_MEM, "Allocation of tgt name failed "
|
||||
"(template name %s)", vtt->name);
|
||||
rc = -ENOMEM;
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
goto out_free_def_name;
|
||||
#else
|
||||
goto out_unlock_resume;
|
||||
#endif
|
||||
}
|
||||
sprintf(tgt->tgt_name, "%s%s%d", vtt->name,
|
||||
SCST_DEFAULT_TGT_NAME_SUFFIX, tgt_num++);
|
||||
}
|
||||
|
||||
tgt->default_acg = scst_alloc_add_acg(tgt->tgt_name);
|
||||
if (tgt->default_acg == NULL)
|
||||
goto out_free_tgt_name;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
rc = scst_build_proc_target_entries(tgt);
|
||||
if (rc < 0)
|
||||
goto out_free_name;
|
||||
else
|
||||
list_add_tail(&tgt->tgt_list_entry, &vtt->tgt_list);
|
||||
goto out_free_acg;
|
||||
#endif
|
||||
|
||||
rc = scst_create_tgt_sysfs(tgt);
|
||||
if (rc < 0)
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
goto out_clean_proc;
|
||||
#else
|
||||
goto out_free_acg;
|
||||
#endif
|
||||
|
||||
list_add_tail(&tgt->tgt_list_entry, &vtt->tgt_list);
|
||||
|
||||
mutex_unlock(&scst_mutex);
|
||||
scst_resume_activity();
|
||||
@@ -383,8 +445,21 @@ out:
|
||||
TRACE_EXIT();
|
||||
return tgt;
|
||||
|
||||
out_free_name:
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
out_clean_proc:
|
||||
scst_cleanup_proc_target_entries(tgt);
|
||||
#endif
|
||||
|
||||
out_free_acg:
|
||||
scst_destroy_acg(tgt->default_acg);
|
||||
|
||||
out_free_tgt_name:
|
||||
kfree(tgt->tgt_name);
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
out_free_def_name:
|
||||
kfree(tgt->default_group_name);
|
||||
#endif
|
||||
|
||||
out_unlock_resume:
|
||||
mutex_unlock(&scst_mutex);
|
||||
@@ -393,7 +468,7 @@ out_resume_free:
|
||||
scst_resume_activity();
|
||||
|
||||
out_free_tgt_err:
|
||||
kfree(tgt);
|
||||
scst_tgt_sysfs_put(tgt);
|
||||
tgt = NULL;
|
||||
|
||||
out_err:
|
||||
@@ -449,20 +524,31 @@ again:
|
||||
|
||||
list_del(&tgt->tgt_list_entry);
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
scst_cleanup_proc_target_entries(tgt);
|
||||
|
||||
kfree(tgt->default_group_name);
|
||||
#endif
|
||||
|
||||
mutex_unlock(&scst_mutex);
|
||||
scst_resume_activity();
|
||||
|
||||
/*
|
||||
* It should be before freeing of tgt_name, because acg_name
|
||||
* points to it.
|
||||
*/
|
||||
scst_destroy_acg(tgt->default_acg);
|
||||
|
||||
kfree(tgt->tgt_name);
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
kfree(tgt->default_group_name);
|
||||
#endif
|
||||
|
||||
del_timer_sync(&tgt->retry_timer);
|
||||
|
||||
scst_tgt_sysfs_put(tgt);
|
||||
|
||||
PRINT_INFO("Target %p for template %s unregistered successfully",
|
||||
tgt, vtt->name);
|
||||
|
||||
kfree(tgt);
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
@@ -654,9 +740,21 @@ static int scst_register_device(struct scsi_device *scsidp)
|
||||
|
||||
dev->type = scsidp->type;
|
||||
|
||||
dev->virt_name = kmalloc(50, GFP_KERNEL);
|
||||
if (dev->virt_name == NULL) {
|
||||
PRINT_ERROR("%s", "Unable to alloc device name");
|
||||
res = -ENOMEM;
|
||||
goto out_free_dev;
|
||||
}
|
||||
snprintf(dev->virt_name, 50, "%d:%d:%d:%d", scsidp->host->host_no,
|
||||
scsidp->channel, scsidp->id, scsidp->lun);
|
||||
|
||||
dev->rq_disk = alloc_disk(1);
|
||||
if (dev->rq_disk == NULL) {
|
||||
PRINT_ERROR("Unable to alloc disk object for device %s",
|
||||
dev->virt_name);
|
||||
res = -ENOMEM;
|
||||
/* virt_name will be freed in scst_free_dev() */
|
||||
goto out_free_dev;
|
||||
}
|
||||
dev->rq_disk->major = SCST_MAJOR;
|
||||
@@ -665,6 +763,10 @@ static int scst_register_device(struct scsi_device *scsidp)
|
||||
|
||||
list_add_tail(&dev->dev_list_entry, &scst_dev_list);
|
||||
|
||||
res = scst_create_device_sysfs(dev);
|
||||
if (res != 0)
|
||||
goto out_free;
|
||||
|
||||
list_for_each_entry(dt, &scst_dev_type_list, dev_type_list_entry) {
|
||||
if (dt->type == scsidp->type) {
|
||||
res = scst_assign_dev_handler(dev, dt);
|
||||
@@ -686,9 +788,9 @@ out_err:
|
||||
"type %d", scsidp->host->host_no, scsidp->channel,
|
||||
scsidp->id, scsidp->lun, scsidp->type);
|
||||
} else {
|
||||
PRINT_ERROR("Failed to to scsi%d, channel %d, id %d, lun %d, "
|
||||
"type %d", scsidp->host->host_no, scsidp->channel,
|
||||
scsidp->id, scsidp->lun, scsidp->type);
|
||||
PRINT_ERROR("Failed to attach to scsi%d, channel %d, id %d, "
|
||||
"lun %d, type %d", scsidp->host->host_no,
|
||||
scsidp->channel, scsidp->id, scsidp->lun, scsidp->type);
|
||||
}
|
||||
|
||||
TRACE_EXIT_RES(res);
|
||||
@@ -699,7 +801,7 @@ out_free:
|
||||
put_disk(dev->rq_disk);
|
||||
|
||||
out_free_dev:
|
||||
scst_free_device(dev);
|
||||
scst_device_sysfs_put(dev);
|
||||
goto out_up;
|
||||
}
|
||||
|
||||
@@ -735,7 +837,7 @@ static void scst_unregister_device(struct scsi_device *scsidp)
|
||||
scst_assign_dev_handler(dev, &scst_null_devtype);
|
||||
|
||||
put_disk(dev->rq_disk);
|
||||
scst_free_device(dev);
|
||||
scst_device_sysfs_put(dev);
|
||||
|
||||
PRINT_INFO("Detached from scsi%d, channel %d, id %d, lun %d, type %d",
|
||||
scsidp->host->host_no, scsidp->channel, scsidp->id,
|
||||
@@ -754,7 +856,7 @@ static int scst_dev_handler_check(struct scst_dev_type *dev_handler)
|
||||
int res = 0;
|
||||
|
||||
if (dev_handler->parse == NULL) {
|
||||
PRINT_ERROR("scst dev_type driver %s doesn't have a "
|
||||
PRINT_ERROR("scst dev handler %s must have "
|
||||
"parse() method.", dev_handler->name);
|
||||
res = -EINVAL;
|
||||
goto out;
|
||||
@@ -816,13 +918,25 @@ int scst_register_virtual_device(struct scst_dev_type *dev_handler,
|
||||
|
||||
dev->type = dev_handler->type;
|
||||
dev->scsi_dev = NULL;
|
||||
dev->virt_name = dev_name;
|
||||
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_release;
|
||||
}
|
||||
dev->virt_id = scst_virt_dev_last_id++;
|
||||
|
||||
list_add_tail(&dev->dev_list_entry, &scst_dev_list);
|
||||
|
||||
res = dev->virt_id;
|
||||
|
||||
rc = scst_create_device_sysfs(dev);
|
||||
if (rc != 0) {
|
||||
res = rc;
|
||||
goto out_free_del;
|
||||
}
|
||||
|
||||
rc = scst_assign_dev_handler(dev, dev_handler);
|
||||
if (rc != 0) {
|
||||
res = rc;
|
||||
@@ -847,7 +961,9 @@ out:
|
||||
|
||||
out_free_del:
|
||||
list_del(&dev->dev_list_entry);
|
||||
scst_free_device(dev);
|
||||
|
||||
out_release:
|
||||
scst_device_sysfs_put(dev);
|
||||
goto out_up;
|
||||
}
|
||||
EXPORT_SYMBOL(scst_register_virtual_device);
|
||||
@@ -877,8 +993,7 @@ void scst_unregister_virtual_device(int id)
|
||||
list_del(&dev->dev_list_entry);
|
||||
|
||||
list_for_each_entry_safe(acg_dev, aa, &dev->dev_acg_dev_list,
|
||||
dev_acg_dev_list_entry)
|
||||
{
|
||||
dev_acg_dev_list_entry) {
|
||||
scst_acg_remove_dev(acg_dev->acg, dev, true);
|
||||
}
|
||||
|
||||
@@ -887,7 +1002,7 @@ void scst_unregister_virtual_device(int id)
|
||||
PRINT_INFO("Detached from virtual device %s (id %d)",
|
||||
dev->virt_name, dev->virt_id);
|
||||
|
||||
scst_free_device(dev);
|
||||
scst_device_sysfs_put(dev);
|
||||
|
||||
out_unblock:
|
||||
mutex_unlock(&scst_mutex);
|
||||
@@ -959,9 +1074,17 @@ int __scst_register_dev_driver(struct scst_dev_type *dev_type,
|
||||
if (exist)
|
||||
goto out_up;
|
||||
|
||||
res = scst_build_proc_dev_handler_dir_entries(dev_type);
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
if (!dev_type->no_proc) {
|
||||
res = scst_build_proc_dev_handler_dir_entries(dev_type);
|
||||
if (res < 0)
|
||||
goto out_up;
|
||||
}
|
||||
#endif
|
||||
|
||||
res = scst_create_devt_sysfs(dev_type);
|
||||
if (res < 0)
|
||||
goto out_up;
|
||||
goto out_free;
|
||||
|
||||
list_add_tail(&dev_type->dev_type_list_entry, &scst_dev_type_list);
|
||||
|
||||
@@ -984,6 +1107,13 @@ out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
|
||||
out_free:
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
if (!dev_type->no_proc)
|
||||
scst_cleanup_proc_dev_handler_dir_entries(dev_type);
|
||||
#endif
|
||||
scst_devt_sysfs_put(dev_type);
|
||||
|
||||
out_up:
|
||||
mutex_unlock(&scst_mutex);
|
||||
|
||||
@@ -1032,7 +1162,11 @@ void scst_unregister_dev_driver(struct scst_dev_type *dev_type)
|
||||
mutex_unlock(&scst_mutex);
|
||||
scst_resume_activity();
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
scst_cleanup_proc_dev_handler_dir_entries(dev_type);
|
||||
#endif
|
||||
|
||||
scst_devt_sysfs_put(dev_type);
|
||||
|
||||
PRINT_INFO("Device handler \"%s\" for type %d unloaded",
|
||||
dev_type->name, dev_type->type);
|
||||
@@ -1066,11 +1200,17 @@ int __scst_register_virtual_dev_driver(struct scst_dev_type *dev_type,
|
||||
if (res != 0)
|
||||
goto out_err;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
if (!dev_type->no_proc) {
|
||||
res = scst_build_proc_dev_handler_dir_entries(dev_type);
|
||||
if (res < 0)
|
||||
goto out_err;
|
||||
}
|
||||
#endif
|
||||
|
||||
res = scst_create_devt_sysfs(dev_type);
|
||||
if (res < 0)
|
||||
goto out_free;
|
||||
|
||||
if (dev_type->type != -1) {
|
||||
PRINT_INFO("Virtual device handler %s for type %d "
|
||||
@@ -1085,6 +1225,14 @@ out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
|
||||
out_free:
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
if (!dev_type->no_proc)
|
||||
scst_cleanup_proc_dev_handler_dir_entries(dev_type);
|
||||
#endif
|
||||
|
||||
scst_devt_sysfs_put(dev_type);
|
||||
|
||||
out_err:
|
||||
PRINT_ERROR("Failed to register virtual device handler \"%s\"",
|
||||
dev_type->name);
|
||||
@@ -1096,8 +1244,12 @@ void scst_unregister_virtual_dev_driver(struct scst_dev_type *dev_type)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
if (!dev_type->no_proc)
|
||||
scst_cleanup_proc_dev_handler_dir_entries(dev_type);
|
||||
#endif
|
||||
|
||||
scst_devt_sysfs_put(dev_type);
|
||||
|
||||
PRINT_INFO("Device handler \"%s\" unloaded", dev_type->name);
|
||||
|
||||
@@ -1272,7 +1424,10 @@ int scst_assign_dev_handler(struct scst_device *dev,
|
||||
if (dev->handler == handler)
|
||||
goto out;
|
||||
|
||||
if (dev->handler && dev->handler->detach_tgt) {
|
||||
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)",
|
||||
@@ -1282,7 +1437,7 @@ int scst_assign_dev_handler(struct scst_device *dev,
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->handler && dev->handler->detach) {
|
||||
if (dev->handler->detach) {
|
||||
TRACE_DBG("%s", "Calling dev handler's detach()");
|
||||
dev->handler->detach(dev);
|
||||
TRACE_DBG("%s", "Old handler's detach() returned");
|
||||
@@ -1290,26 +1445,34 @@ int scst_assign_dev_handler(struct scst_device *dev,
|
||||
|
||||
scst_stop_dev_threads(dev);
|
||||
|
||||
scst_devt_dev_sysfs_put(dev);
|
||||
|
||||
assign:
|
||||
dev->handler = handler;
|
||||
|
||||
if (handler) {
|
||||
res = scst_create_dev_threads(dev);
|
||||
if (res != 0)
|
||||
goto out_null;
|
||||
}
|
||||
if (handler == NULL)
|
||||
goto out;
|
||||
|
||||
if (handler && handler->attach) {
|
||||
res = scst_create_devt_dev_sysfs(dev);
|
||||
if (res != 0)
|
||||
goto out_null;
|
||||
|
||||
res = scst_create_dev_threads(dev);
|
||||
if (res != 0)
|
||||
goto out_remove_sysfs;
|
||||
|
||||
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_thr_null;
|
||||
}
|
||||
goto out_thr_null;
|
||||
}
|
||||
|
||||
if (handler && handler->attach_tgt) {
|
||||
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)",
|
||||
@@ -1326,14 +1489,6 @@ int scst_assign_dev_handler(struct scst_device *dev,
|
||||
}
|
||||
}
|
||||
|
||||
out_thr_null:
|
||||
if (res != 0)
|
||||
scst_stop_dev_threads(dev);
|
||||
|
||||
out_null:
|
||||
if (res != 0)
|
||||
dev->handler = &scst_null_devtype;
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
@@ -1341,8 +1496,7 @@ out:
|
||||
out_err_detach_tgt:
|
||||
if (handler && handler->detach_tgt) {
|
||||
list_for_each_entry(tgt_dev, &attached_tgt_devs,
|
||||
extra_tgt_dev_list_entry)
|
||||
{
|
||||
extra_tgt_dev_list_entry) {
|
||||
TRACE_DBG("Calling handler's detach_tgt(%p)",
|
||||
tgt_dev);
|
||||
handler->detach_tgt(tgt_dev);
|
||||
@@ -1354,7 +1508,16 @@ out_err_detach_tgt:
|
||||
handler->detach(dev);
|
||||
TRACE_DBG("%s", "Handler's detach() returned");
|
||||
}
|
||||
goto out_null;
|
||||
|
||||
out_thr_null:
|
||||
scst_stop_dev_threads(dev);
|
||||
|
||||
out_remove_sysfs:
|
||||
scst_devt_dev_sysfs_put(dev);
|
||||
|
||||
out_null:
|
||||
dev->handler = &scst_null_devtype;
|
||||
goto out;
|
||||
}
|
||||
|
||||
int scst_global_threads_count(void)
|
||||
@@ -1830,6 +1993,10 @@ static int __init init_scst(void)
|
||||
goto out_destroy_sense_mempool;
|
||||
}
|
||||
|
||||
res = scst_sysfs_init();
|
||||
if (res != 0)
|
||||
goto out_destroy_aen_mempool;
|
||||
|
||||
if (scst_max_cmd_mem == 0) {
|
||||
struct sysinfo si;
|
||||
si_meminfo(&si);
|
||||
@@ -1857,17 +2024,23 @@ static int __init init_scst(void)
|
||||
res = scst_sgv_pools_init(
|
||||
((uint64_t)scst_max_cmd_mem << 10) >> (PAGE_SHIFT - 10), 0);
|
||||
if (res != 0)
|
||||
goto out_destroy_aen_mempool;
|
||||
goto out_sysfs_cleanup;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
scst_default_acg = scst_alloc_add_acg(SCST_DEFAULT_ACG_NAME);
|
||||
if (scst_default_acg == NULL) {
|
||||
res = -ENOMEM;
|
||||
goto out_destroy_sgv_pool;
|
||||
}
|
||||
#endif
|
||||
|
||||
res = scsi_register_interface(&scst_interface);
|
||||
if (res != 0)
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
goto out_free_acg;
|
||||
#else
|
||||
goto out_destroy_sgv_pool;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < (int)ARRAY_SIZE(scst_tasklets); i++) {
|
||||
spin_lock_init(&scst_tasklets[i].tasklet_lock);
|
||||
@@ -1884,10 +2057,11 @@ static int __init init_scst(void)
|
||||
if (res < 0)
|
||||
goto out_thread_free;
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
res = scst_proc_init_module();
|
||||
if (res != 0)
|
||||
goto out_thread_free;
|
||||
|
||||
#endif
|
||||
|
||||
PRINT_INFO("SCST version %s loaded successfully (max mem for "
|
||||
"commands %dMB, per device %dMB)", SCST_VERSION_STRING,
|
||||
@@ -1904,12 +2078,17 @@ out_thread_free:
|
||||
|
||||
scsi_unregister_interface(&scst_interface);
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
out_free_acg:
|
||||
scst_destroy_acg(scst_default_acg);
|
||||
#endif
|
||||
|
||||
out_destroy_sgv_pool:
|
||||
scst_sgv_pools_deinit();
|
||||
|
||||
out_sysfs_cleanup:
|
||||
scst_sysfs_cleanup();
|
||||
|
||||
out_destroy_aen_mempool:
|
||||
mempool_destroy(scst_aen_mempool);
|
||||
|
||||
@@ -1963,12 +2142,17 @@ static void __exit exit_scst(void)
|
||||
|
||||
/* ToDo: unregister_cpu_notifier() */
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
scst_proc_cleanup_module();
|
||||
#endif
|
||||
scst_sysfs_cleanup();
|
||||
|
||||
scst_stop_all_threads();
|
||||
|
||||
scsi_unregister_interface(&scst_interface);
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
scst_destroy_acg(scst_default_acg);
|
||||
#endif
|
||||
|
||||
scst_sgv_pools_deinit();
|
||||
|
||||
|
||||
+127
-29
@@ -36,7 +36,7 @@
|
||||
/* Max pages freed from a pool per shrinking iteration */
|
||||
#define MAX_PAGES_PER_POOL 50
|
||||
|
||||
static struct sgv_pool sgv_norm_clust_pool, sgv_norm_pool, sgv_dma_pool;
|
||||
static struct sgv_pool *sgv_norm_clust_pool, *sgv_norm_pool, *sgv_dma_pool;
|
||||
|
||||
static atomic_t sgv_pages_total = ATOMIC_INIT(0);
|
||||
|
||||
@@ -78,7 +78,7 @@ static inline bool sgv_pool_clustered(const struct sgv_pool *pool)
|
||||
void scst_sgv_pool_use_norm(struct scst_tgt_dev *tgt_dev)
|
||||
{
|
||||
tgt_dev->gfp_mask = __GFP_NOWARN;
|
||||
tgt_dev->pool = &sgv_norm_pool;
|
||||
tgt_dev->pool = sgv_norm_pool;
|
||||
clear_bit(SCST_TGT_DEV_CLUST_POOL, &tgt_dev->tgt_dev_flags);
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ void scst_sgv_pool_use_norm_clust(struct scst_tgt_dev *tgt_dev)
|
||||
{
|
||||
TRACE_MEM("%s", "Use clustering");
|
||||
tgt_dev->gfp_mask = __GFP_NOWARN;
|
||||
tgt_dev->pool = &sgv_norm_clust_pool;
|
||||
tgt_dev->pool = sgv_norm_clust_pool;
|
||||
set_bit(SCST_TGT_DEV_CLUST_POOL, &tgt_dev->tgt_dev_flags);
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ void scst_sgv_pool_use_dma(struct scst_tgt_dev *tgt_dev)
|
||||
{
|
||||
TRACE_MEM("%s", "Use ISA DMA memory");
|
||||
tgt_dev->gfp_mask = __GFP_NOWARN | GFP_DMA;
|
||||
tgt_dev->pool = &sgv_dma_pool;
|
||||
tgt_dev->pool = sgv_dma_pool;
|
||||
clear_bit(SCST_TGT_DEV_CLUST_POOL, &tgt_dev->tgt_dev_flags);
|
||||
}
|
||||
|
||||
@@ -1292,7 +1292,7 @@ static void sgv_pool_init_cache(struct sgv_pool *pool, int cache_num)
|
||||
}
|
||||
|
||||
/* Must be called under sgv_pools_mutex */
|
||||
int sgv_pool_init(struct sgv_pool *pool, const char *name,
|
||||
static int sgv_pool_init(struct sgv_pool *pool, const char *name,
|
||||
enum sgv_clustering_types clustering_type, int single_alloc_pages,
|
||||
int purge_interval)
|
||||
{
|
||||
@@ -1436,7 +1436,7 @@ void sgv_pool_flush(struct sgv_pool *pool)
|
||||
}
|
||||
EXPORT_SYMBOL(sgv_pool_flush);
|
||||
|
||||
void sgv_pool_deinit(struct sgv_pool *pool)
|
||||
static void sgv_pool_deinit_put(struct sgv_pool *pool)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1458,6 +1458,10 @@ void sgv_pool_deinit(struct sgv_pool *pool)
|
||||
pool->caches[i] = NULL;
|
||||
}
|
||||
|
||||
scst_sgv_sysfs_put(pool);
|
||||
|
||||
/* pool can be dead here */
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
@@ -1511,6 +1515,10 @@ struct sgv_pool *sgv_pool_create(const char *name,
|
||||
if (rc != 0)
|
||||
goto out_free_unlock;
|
||||
|
||||
rc = scst_create_sgv_sysfs(pool);
|
||||
if (rc != 0)
|
||||
goto out_err_unlock_put;
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&sgv_pools_mutex);
|
||||
|
||||
@@ -1523,14 +1531,18 @@ out_free_unlock:
|
||||
out_err_unlock:
|
||||
pool = NULL;
|
||||
goto out_unlock;
|
||||
|
||||
out_err_unlock_put:
|
||||
mutex_unlock(&sgv_pools_mutex);
|
||||
sgv_pool_deinit_put(pool);
|
||||
goto out_err_unlock;
|
||||
}
|
||||
EXPORT_SYMBOL(sgv_pool_create);
|
||||
|
||||
static void sgv_pool_destroy(struct sgv_pool *pool)
|
||||
void sgv_pool_destroy(struct sgv_pool *pool)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
sgv_pool_deinit(pool);
|
||||
kfree(pool);
|
||||
|
||||
TRACE_EXIT();
|
||||
@@ -1551,7 +1563,7 @@ void sgv_pool_put(struct sgv_pool *pool)
|
||||
TRACE_MEM("Decrementing sgv pool %p ref (new value %d)",
|
||||
pool, atomic_read(&pool->sgv_pool_ref)-1);
|
||||
if (atomic_dec_and_test(&pool->sgv_pool_ref))
|
||||
sgv_pool_destroy(pool);
|
||||
sgv_pool_deinit_put(pool);
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(sgv_pool_put);
|
||||
@@ -1570,7 +1582,7 @@ EXPORT_SYMBOL(sgv_pool_del);
|
||||
/* Both parameters in pages */
|
||||
int scst_sgv_pools_init(unsigned long mem_hwmark, unsigned long mem_lwmark)
|
||||
{
|
||||
int res;
|
||||
int res = 0;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
@@ -1579,23 +1591,20 @@ int scst_sgv_pools_init(unsigned long mem_hwmark, unsigned long mem_lwmark)
|
||||
|
||||
sgv_evaluate_local_max_pages();
|
||||
|
||||
mutex_lock(&sgv_pools_mutex);
|
||||
sgv_norm_pool = sgv_pool_create("sgv", sgv_no_clustering, 0, false, 0);
|
||||
if (sgv_norm_pool == NULL)
|
||||
goto out_err;
|
||||
|
||||
res = sgv_pool_init(&sgv_norm_pool, "sgv", sgv_no_clustering, 0, 0);
|
||||
if (res != 0)
|
||||
goto out_unlock;
|
||||
|
||||
res = sgv_pool_init(&sgv_norm_clust_pool, "sgv-clust",
|
||||
sgv_full_clustering, 0, 0);
|
||||
if (res != 0)
|
||||
sgv_norm_clust_pool = sgv_pool_create("sgv-clust",
|
||||
sgv_full_clustering, 0, false, 0);
|
||||
if (sgv_norm_clust_pool == NULL)
|
||||
goto out_free_norm;
|
||||
|
||||
res = sgv_pool_init(&sgv_dma_pool, "sgv-dma", sgv_no_clustering, 0, 0);
|
||||
if (res != 0)
|
||||
sgv_dma_pool = sgv_pool_create("sgv-dma", sgv_no_clustering, 0,
|
||||
false, 0);
|
||||
if (sgv_dma_pool == NULL)
|
||||
goto out_free_clust;
|
||||
|
||||
mutex_unlock(&sgv_pools_mutex);
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23))
|
||||
sgv_shrinker = set_shrinker(DEFAULT_SEEKS, sgv_shrink);
|
||||
#else
|
||||
@@ -1609,13 +1618,13 @@ out:
|
||||
return res;
|
||||
|
||||
out_free_clust:
|
||||
sgv_pool_deinit(&sgv_norm_clust_pool);
|
||||
sgv_pool_deinit_put(sgv_norm_clust_pool);
|
||||
|
||||
out_free_norm:
|
||||
sgv_pool_deinit(&sgv_norm_pool);
|
||||
sgv_pool_deinit_put(sgv_norm_pool);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&sgv_pools_mutex);
|
||||
out_err:
|
||||
res = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1629,9 +1638,9 @@ void scst_sgv_pools_deinit(void)
|
||||
unregister_shrinker(&sgv_shrinker);
|
||||
#endif
|
||||
|
||||
sgv_pool_deinit(&sgv_dma_pool);
|
||||
sgv_pool_deinit(&sgv_norm_pool);
|
||||
sgv_pool_deinit(&sgv_norm_clust_pool);
|
||||
sgv_pool_deinit_put(sgv_dma_pool);
|
||||
sgv_pool_deinit_put(sgv_norm_pool);
|
||||
sgv_pool_deinit_put(sgv_norm_clust_pool);
|
||||
|
||||
flush_scheduled_work();
|
||||
|
||||
@@ -1639,6 +1648,8 @@ void scst_sgv_pools_deinit(void)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
|
||||
static void sgv_do_proc_read(struct seq_file *seq, const struct sgv_pool *pool)
|
||||
{
|
||||
int i, total = 0, hit = 0, merged = 0, allocated = 0;
|
||||
@@ -1730,3 +1741,90 @@ int sgv_procinfo_show(struct seq_file *seq, void *v)
|
||||
TRACE_EXIT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
ssize_t sgv_sysfs_stat_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct sgv_pool *pool;
|
||||
int i, total = 0, hit = 0, merged = 0, allocated = 0;
|
||||
int oa, om, res;
|
||||
|
||||
pool = container_of(kobj, struct sgv_pool, sgv_kobj);
|
||||
|
||||
for (i = 0; i < SGV_POOL_ELEMENTS; i++) {
|
||||
int t;
|
||||
|
||||
hit += atomic_read(&pool->cache_acc[i].hit_alloc);
|
||||
total += atomic_read(&pool->cache_acc[i].total_alloc);
|
||||
|
||||
t = atomic_read(&pool->cache_acc[i].total_alloc) -
|
||||
atomic_read(&pool->cache_acc[i].hit_alloc);
|
||||
allocated += t * (1 << i);
|
||||
merged += atomic_read(&pool->cache_acc[i].merged);
|
||||
}
|
||||
|
||||
res = sprintf(buf, "%-30s %-11s %-11s %-11s %-11s", "Name", "Hit", "Total",
|
||||
"% merged", "Cached (P/I/O)");
|
||||
|
||||
res += sprintf(&buf[res], "\n%-30s %-11d %-11d %-11d %d/%d/%d\n",
|
||||
pool->name, hit, total,
|
||||
(allocated != 0) ? merged*100/allocated : 0,
|
||||
pool->cached_pages, pool->inactive_cached_pages,
|
||||
pool->cached_entries);
|
||||
|
||||
for (i = 0; i < SGV_POOL_ELEMENTS; i++) {
|
||||
int t = atomic_read(&pool->cache_acc[i].total_alloc) -
|
||||
atomic_read(&pool->cache_acc[i].hit_alloc);
|
||||
allocated = t * (1 << i);
|
||||
merged = atomic_read(&pool->cache_acc[i].merged);
|
||||
|
||||
res += sprintf(&buf[res], " %-28s %-11d %-11d %d\n",
|
||||
pool->cache_names[i],
|
||||
atomic_read(&pool->cache_acc[i].hit_alloc),
|
||||
atomic_read(&pool->cache_acc[i].total_alloc),
|
||||
(allocated != 0) ? merged*100/allocated : 0);
|
||||
}
|
||||
|
||||
allocated = atomic_read(&pool->big_pages);
|
||||
merged = atomic_read(&pool->big_merged);
|
||||
oa = atomic_read(&pool->other_pages);
|
||||
om = atomic_read(&pool->other_merged);
|
||||
|
||||
res += sprintf(&buf[res], " %-40s %d/%-9d %d/%d\n", "big/other",
|
||||
atomic_read(&pool->big_alloc), atomic_read(&pool->other_alloc),
|
||||
(allocated != 0) ? merged*100/allocated : 0,
|
||||
(oa != 0) ? om/oa : 0);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
ssize_t sgv_sysfs_global_stat_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
struct sgv_pool *pool;
|
||||
int inactive_pages = 0, res;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
spin_lock_bh(&sgv_pools_lock);
|
||||
list_for_each_entry(pool, &sgv_active_pools_list,
|
||||
sgv_active_pools_list_entry) {
|
||||
inactive_pages += pool->inactive_cached_pages;
|
||||
}
|
||||
spin_unlock_bh(&sgv_pools_lock);
|
||||
|
||||
res = sprintf(buf, "%-42s %d/%d\n%-42s %d/%d\n%-42s %d/%d\n"
|
||||
"%-42s %-11d\n",
|
||||
"Inactive/active pages", inactive_pages,
|
||||
atomic_read(&sgv_pages_total) - inactive_pages,
|
||||
"Hi/lo watermarks [pages]", sgv_hi_wmk, sgv_lo_wmk,
|
||||
"Hi watermark releases/failures",
|
||||
atomic_read(&sgv_releases_on_hiwmk),
|
||||
atomic_read(&sgv_releases_on_hiwmk_failed),
|
||||
"Other allocs", atomic_read(&sgv_other_total_alloc));
|
||||
|
||||
TRACE_EXIT();
|
||||
return res;
|
||||
}
|
||||
|
||||
+17
-11
@@ -17,7 +17,6 @@
|
||||
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
#define SGV_POOL_ELEMENTS 11
|
||||
|
||||
@@ -77,8 +76,9 @@ struct sgv_pool {
|
||||
|
||||
int purge_interval;
|
||||
|
||||
/* Protected by sgv_pool_lock */
|
||||
/* Protected by sgv_pool_lock, if necessary */
|
||||
unsigned int purge_work_scheduled:1;
|
||||
unsigned int sgv_kobj_initialized:1;
|
||||
|
||||
/* Protected by sgv_pool_lock */
|
||||
struct list_head sorted_recycling_list;
|
||||
@@ -114,22 +114,28 @@ struct sgv_pool {
|
||||
struct mm_struct *owner_mm;
|
||||
|
||||
struct list_head sgv_pools_list_entry;
|
||||
};
|
||||
|
||||
int sgv_pool_init(struct sgv_pool *pool, const char *name,
|
||||
enum sgv_clustering_types clustering_type, int single_alloc_pages,
|
||||
int purge_interval);
|
||||
void sgv_pool_deinit(struct sgv_pool *pool);
|
||||
struct kobject sgv_kobj;
|
||||
};
|
||||
|
||||
static inline struct scatterlist *sgv_pool_sg(struct sgv_pool_obj *obj)
|
||||
{
|
||||
return obj->sg_entries;
|
||||
}
|
||||
|
||||
extern int scst_sgv_pools_init(unsigned long mem_hwmark,
|
||||
unsigned long mem_lwmark);
|
||||
extern void scst_sgv_pools_deinit(void);
|
||||
extern int sgv_procinfo_show(struct seq_file *seq, void *v);
|
||||
int scst_sgv_pools_init(unsigned long mem_hwmark, unsigned long mem_lwmark);
|
||||
void scst_sgv_pools_deinit(void);
|
||||
|
||||
void sgv_pool_destroy(struct sgv_pool *pool);
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
int sgv_procinfo_show(struct seq_file *seq, void *v);
|
||||
#endif
|
||||
|
||||
ssize_t sgv_sysfs_stat_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf);
|
||||
ssize_t sgv_sysfs_global_stat_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf);
|
||||
|
||||
void scst_sgv_pool_use_norm(struct scst_tgt_dev *tgt_dev);
|
||||
void scst_sgv_pool_use_norm_clust(struct scst_tgt_dev *tgt_dev);
|
||||
|
||||
+108
-2
@@ -35,6 +35,10 @@
|
||||
|
||||
#include "scst_debug.h"
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
void sgv_pool_destroy(struct sgv_pool *pool);
|
||||
#endif
|
||||
|
||||
#define SCST_MAJOR 177
|
||||
|
||||
#define TRACE_RTRY 0x80000000
|
||||
@@ -146,7 +150,9 @@ extern struct list_head scst_dev_type_list;
|
||||
extern wait_queue_head_t scst_dev_cmd_waitQ;
|
||||
|
||||
extern struct list_head scst_acg_list;
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
extern struct scst_acg *scst_default_acg;
|
||||
#endif
|
||||
|
||||
extern spinlock_t scst_init_lock;
|
||||
extern struct list_head scst_init_cmd_list;
|
||||
@@ -287,6 +293,12 @@ void scst_del_dev_threads(struct scst_device *dev, int num);
|
||||
|
||||
int scst_queue_retry_cmd(struct scst_cmd *cmd, int finished_cmds);
|
||||
|
||||
static inline void scst_tgtt_cleanup(struct scst_tgt_template *tgtt) { }
|
||||
static inline void scst_devt_cleanup(struct scst_dev_type *devt) { }
|
||||
|
||||
struct scst_tgt *scst_alloc_tgt(struct scst_tgt_template *tgtt);
|
||||
void scst_free_tgt(struct scst_tgt *tgt);
|
||||
|
||||
int scst_alloc_device(gfp_t gfp_mask, struct scst_device **out_dev);
|
||||
void scst_free_device(struct scst_device *dev);
|
||||
|
||||
@@ -298,6 +310,7 @@ struct scst_acg *scst_find_acg(const struct scst_session *sess);
|
||||
void scst_check_reassign_sessions(void);
|
||||
|
||||
int scst_sess_alloc_tgt_devs(struct scst_session *sess);
|
||||
void scst_sess_free_tgt_devs(struct scst_session *sess);
|
||||
void scst_nexus_loss(struct scst_tgt_dev *tgt_dev, bool queue_UA);
|
||||
|
||||
int scst_acg_add_dev(struct scst_acg *acg, struct scst_device *dev,
|
||||
@@ -305,6 +318,8 @@ int scst_acg_add_dev(struct scst_acg *acg, struct scst_device *dev,
|
||||
int scst_acg_remove_dev(struct scst_acg *acg, struct scst_device *dev,
|
||||
bool gen_scst_report_luns_changed);
|
||||
|
||||
void scst_acg_dev_destroy(struct scst_acg_dev *acg_dev);
|
||||
|
||||
int scst_acg_add_name(struct scst_acg *acg, const char *name);
|
||||
int scst_acg_remove_name(struct scst_acg *acg, const char *name, bool reassign);
|
||||
void __scst_acg_remove_acn(struct scst_acn *n);
|
||||
@@ -320,6 +335,7 @@ int scst_assign_dev_handler(struct scst_device *dev,
|
||||
struct scst_session *scst_alloc_session(struct scst_tgt *tgt, gfp_t gfp_mask,
|
||||
const char *initiator_name);
|
||||
void scst_free_session(struct scst_session *sess);
|
||||
void scst_release_session(struct scst_session *sess);
|
||||
void scst_free_session_callback(struct scst_session *sess);
|
||||
|
||||
struct scst_cmd *scst_alloc_cmd(gfp_t gfp_mask);
|
||||
@@ -331,7 +347,6 @@ static inline void scst_destroy_cmd(struct scst_cmd *cmd)
|
||||
}
|
||||
|
||||
void scst_check_retries(struct scst_tgt *tgt);
|
||||
void scst_tgt_retry_timer_fn(unsigned long arg);
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
|
||||
int scst_alloc_request(struct scst_cmd *cmd);
|
||||
@@ -360,7 +375,7 @@ static inline int scst_exec_req(struct scsi_device *sdev,
|
||||
return scsi_execute_async(sdev, cmd, cmd_len, data_direction, (void *)sgl,
|
||||
bufflen, nents, timeout, retries, privdata, done, gfp);
|
||||
#elif !defined(SCSI_EXEC_REQ_FIFO_DEFINED)
|
||||
WARN_ON_ONCE(1);
|
||||
WARN_ON();
|
||||
return -1;
|
||||
#else
|
||||
return scsi_execute_async_fifo(sdev, cmd, cmd_len, data_direction,
|
||||
@@ -399,6 +414,7 @@ struct scst_mgmt_cmd *scst_alloc_mgmt_cmd(gfp_t gfp_mask);
|
||||
void scst_free_mgmt_cmd(struct scst_mgmt_cmd *mcmd);
|
||||
void scst_done_cmd_mgmt(struct scst_cmd *cmd);
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
/* /proc support */
|
||||
int scst_proc_init_module(void);
|
||||
void scst_proc_cleanup_module(void);
|
||||
@@ -408,6 +424,96 @@ int scst_build_proc_target_entries(struct scst_tgt *vtt);
|
||||
void scst_cleanup_proc_target_entries(struct scst_tgt *vtt);
|
||||
int scst_build_proc_dev_handler_dir_entries(struct scst_dev_type *dev_type);
|
||||
void scst_cleanup_proc_dev_handler_dir_entries(struct scst_dev_type *dev_type);
|
||||
#endif
|
||||
|
||||
/* sysfs support */
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
static inline int scst_sysfs_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void scst_sysfs_cleanup(void) { }
|
||||
|
||||
static inline int scst_create_tgtt_sysfs(struct scst_tgt_template *tgtt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void scst_tgtt_sysfs_put(struct scst_tgt_template *tgtt)
|
||||
{
|
||||
scst_tgtt_cleanup(tgtt);
|
||||
}
|
||||
|
||||
static inline int scst_create_tgt_sysfs(struct scst_tgt *tgt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void scst_tgt_sysfs_put(struct scst_tgt *tgt)
|
||||
{
|
||||
scst_free_tgt(tgt);
|
||||
}
|
||||
|
||||
static inline int scst_create_sess_sysfs(struct scst_session *sess)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void scst_sess_sysfs_put(struct scst_session *sess)
|
||||
{
|
||||
scst_release_session(sess);
|
||||
}
|
||||
|
||||
static inline int scst_create_sgv_sysfs(struct sgv_pool *pool)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void scst_sgv_sysfs_put(struct sgv_pool *pool)
|
||||
{
|
||||
sgv_pool_destroy(pool);
|
||||
}
|
||||
|
||||
static inline int scst_create_devt_sysfs(struct scst_dev_type *devt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void scst_devt_sysfs_put(struct scst_dev_type *devt)
|
||||
{
|
||||
scst_devt_cleanup(devt);
|
||||
}
|
||||
|
||||
static inline int scst_create_device_sysfs(struct scst_device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void scst_device_sysfs_put(struct scst_device *dev)
|
||||
{
|
||||
scst_free_device(dev);
|
||||
}
|
||||
|
||||
static inline int scst_create_devt_dev_sysfs(struct scst_device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void scst_devt_dev_sysfs_put(struct scst_device *dev) { }
|
||||
|
||||
#else /* CONFIG_SCST_PROC */
|
||||
|
||||
int scst_sysfs_init(void);
|
||||
void scst_sysfs_cleanup(void);
|
||||
int scst_create_tgtt_sysfs(struct scst_tgt_template *tgtt);
|
||||
void scst_tgtt_sysfs_put(struct scst_tgt_template *tgtt);
|
||||
int scst_create_tgt_sysfs(struct scst_tgt *tgt);
|
||||
void scst_tgt_sysfs_put(struct scst_tgt *tgt);
|
||||
int scst_create_sess_sysfs(struct scst_session *sess);
|
||||
void scst_sess_sysfs_put(struct scst_session *sess);
|
||||
int scst_create_sgv_sysfs(struct sgv_pool *pool);
|
||||
void scst_sgv_sysfs_put(struct sgv_pool *pool);
|
||||
int scst_create_devt_sysfs(struct scst_dev_type *devt);
|
||||
void scst_devt_sysfs_put(struct scst_dev_type *devt);
|
||||
int scst_create_device_sysfs(struct scst_device *dev);
|
||||
void scst_device_sysfs_put(struct scst_device *dev);
|
||||
int scst_create_devt_dev_sysfs(struct scst_device *dev);
|
||||
void scst_devt_dev_sysfs_put(struct scst_device *dev);
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
int scst_get_cdb_len(const uint8_t *cdb);
|
||||
|
||||
|
||||
+44
-16
@@ -92,7 +92,7 @@ static struct proc_dir_entry *scst_proc_groups_root;
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
static struct scst_proc_data scst_log_proc_data;
|
||||
|
||||
static struct scst_proc_log scst_proc_trace_tbl[] =
|
||||
static struct scst_trace_log scst_proc_trace_tbl[] =
|
||||
{
|
||||
{ TRACE_OUT_OF_MEM, "out_of_mem" },
|
||||
{ TRACE_MINOR, "minor" },
|
||||
@@ -112,7 +112,7 @@ static struct scst_proc_log scst_proc_trace_tbl[] =
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static struct scst_proc_log scst_proc_local_trace_tbl[] =
|
||||
static struct scst_trace_log scst_proc_local_trace_tbl[] =
|
||||
{
|
||||
{ TRACE_RTRY, "retry" },
|
||||
{ TRACE_SCSI_SERIALIZING, "scsi_serializing" },
|
||||
@@ -242,13 +242,13 @@ static DEFINE_MUTEX(scst_log_mutex);
|
||||
|
||||
int scst_proc_log_entry_write(struct file *file, const char __user *buf,
|
||||
unsigned long length, unsigned long *log_level,
|
||||
unsigned long default_level, const struct scst_proc_log *tbl)
|
||||
unsigned long default_level, const struct scst_trace_log *tbl)
|
||||
{
|
||||
int res = length;
|
||||
int action;
|
||||
unsigned long level = 0, oldlevel;
|
||||
char *buffer, *p, *e;
|
||||
const struct scst_proc_log *t;
|
||||
const struct scst_trace_log *t;
|
||||
char *data = (char *)PDE(file->f_dentry->d_inode)->data;
|
||||
|
||||
TRACE_ENTRY();
|
||||
@@ -1375,17 +1375,23 @@ int scst_build_proc_dev_handler_dir_entries(struct scst_dev_type *dev_type)
|
||||
{
|
||||
int res = 0;
|
||||
struct proc_dir_entry *p;
|
||||
const char *name; /* workaround to keep /proc ABI intact */
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
sBUG_ON(dev_type->proc_dev_type_root);
|
||||
|
||||
if (strcmp(dev_type->name, "vdisk_fileio") == 0)
|
||||
name = "vdisk";
|
||||
else
|
||||
name = dev_type->name;
|
||||
|
||||
/* create the proc directory entry for the dev type handler */
|
||||
dev_type->proc_dev_type_root = proc_mkdir(dev_type->name,
|
||||
dev_type->proc_dev_type_root = proc_mkdir(name,
|
||||
scst_proc_scsi_tgt);
|
||||
if (dev_type->proc_dev_type_root == NULL) {
|
||||
PRINT_ERROR("Not enough memory to register dev handler dir "
|
||||
"%s in /proc/%s", dev_type->name, SCST_PROC_ENTRY_NAME);
|
||||
"%s in /proc/%s", name, SCST_PROC_ENTRY_NAME);
|
||||
goto out_nomem;
|
||||
}
|
||||
|
||||
@@ -1398,7 +1404,7 @@ int scst_build_proc_dev_handler_dir_entries(struct scst_dev_type *dev_type)
|
||||
PRINT_ERROR("Not enough memory to register dev "
|
||||
"handler entry %s in /proc/%s/%s",
|
||||
SCST_PROC_DEV_HANDLER_TYPE_ENTRY_NAME,
|
||||
SCST_PROC_ENTRY_NAME, dev_type->name);
|
||||
SCST_PROC_ENTRY_NAME, name);
|
||||
goto out_remove;
|
||||
}
|
||||
}
|
||||
@@ -1407,12 +1413,12 @@ int scst_build_proc_dev_handler_dir_entries(struct scst_dev_type *dev_type)
|
||||
/* create the proc file entry for the dev type handler */
|
||||
scst_dev_handler_proc_data.data = (void *)dev_type;
|
||||
p = scst_create_proc_entry(dev_type->proc_dev_type_root,
|
||||
dev_type->name,
|
||||
name,
|
||||
&scst_dev_handler_proc_data);
|
||||
if (p == NULL) {
|
||||
PRINT_ERROR("Not enough memory to register dev "
|
||||
"handler entry %s in /proc/%s/%s", dev_type->name,
|
||||
SCST_PROC_ENTRY_NAME, dev_type->name);
|
||||
"handler entry %s in /proc/%s/%s", name,
|
||||
SCST_PROC_ENTRY_NAME, name);
|
||||
goto out_remove1;
|
||||
}
|
||||
}
|
||||
@@ -1427,7 +1433,7 @@ out_remove1:
|
||||
dev_type->proc_dev_type_root);
|
||||
|
||||
out_remove:
|
||||
remove_proc_entry(dev_type->name, scst_proc_scsi_tgt);
|
||||
remove_proc_entry(name, scst_proc_scsi_tgt);
|
||||
|
||||
out_nomem:
|
||||
res = -ENOMEM;
|
||||
@@ -1436,17 +1442,25 @@ out_nomem:
|
||||
|
||||
void scst_cleanup_proc_dev_handler_dir_entries(struct scst_dev_type *dev_type)
|
||||
{
|
||||
/* Workaround to keep /proc ABI intact */
|
||||
const char *name;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
sBUG_ON(dev_type->proc_dev_type_root == NULL);
|
||||
|
||||
if (strcmp(dev_type->name, "vdisk_fileio") == 0)
|
||||
name = "vdisk";
|
||||
else
|
||||
name = dev_type->name;
|
||||
|
||||
if (dev_type->type >= 0) {
|
||||
remove_proc_entry(SCST_PROC_DEV_HANDLER_TYPE_ENTRY_NAME,
|
||||
dev_type->proc_dev_type_root);
|
||||
}
|
||||
if (dev_type->read_proc || dev_type->write_proc)
|
||||
remove_proc_entry(dev_type->name, dev_type->proc_dev_type_root);
|
||||
remove_proc_entry(dev_type->name, scst_proc_scsi_tgt);
|
||||
remove_proc_entry(name, dev_type->proc_dev_type_root);
|
||||
remove_proc_entry(name, scst_proc_scsi_tgt);
|
||||
dev_type->proc_dev_type_root = NULL;
|
||||
|
||||
TRACE_EXIT();
|
||||
@@ -2428,11 +2442,11 @@ static struct scst_proc_data scst_groups_devices_proc_data = {
|
||||
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
|
||||
static int scst_proc_read_tlb(const struct scst_proc_log *tbl,
|
||||
static int scst_proc_read_tlb(const struct scst_trace_log *tbl,
|
||||
struct seq_file *seq,
|
||||
unsigned long log_level, int *first)
|
||||
{
|
||||
const struct scst_proc_log *t = tbl;
|
||||
const struct scst_trace_log *t = tbl;
|
||||
int res = 0;
|
||||
|
||||
while (t->token) {
|
||||
@@ -2446,7 +2460,7 @@ static int scst_proc_read_tlb(const struct scst_proc_log *tbl,
|
||||
}
|
||||
|
||||
int scst_proc_log_entry_read(struct seq_file *seq, unsigned long log_level,
|
||||
const struct scst_proc_log *tbl)
|
||||
const struct scst_trace_log *tbl)
|
||||
{
|
||||
int res = 0, first = 1;
|
||||
|
||||
@@ -2641,3 +2655,17 @@ int scst_single_seq_open(struct inode *inode, struct file *file)
|
||||
return single_open(file, pdata->show, PDE(inode)->data);
|
||||
}
|
||||
EXPORT_SYMBOL(scst_single_seq_open);
|
||||
|
||||
struct proc_dir_entry *scst_proc_get_tgt_root(
|
||||
struct scst_tgt_template *vtt)
|
||||
{
|
||||
return vtt->proc_tgt_root;
|
||||
}
|
||||
EXPORT_SYMBOL(scst_proc_get_tgt_root);
|
||||
|
||||
struct proc_dir_entry *scst_proc_get_dev_type_root(
|
||||
struct scst_dev_type *dtt)
|
||||
{
|
||||
return dtt->proc_dev_type_root;
|
||||
}
|
||||
EXPORT_SYMBOL(scst_proc_get_dev_type_root);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+23
-2
@@ -5356,6 +5356,7 @@ out:
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
/* scst_mutex supposed to be held */
|
||||
static struct scst_acg *scst_find_acg_by_name(const char *acg_name)
|
||||
{
|
||||
@@ -5376,6 +5377,7 @@ out:
|
||||
TRACE_EXIT_HRES(res);
|
||||
return res;
|
||||
}
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
/* Must be called under scst_mitex */
|
||||
struct scst_acg *scst_find_acg(const struct scst_session *sess)
|
||||
@@ -5386,10 +5388,19 @@ struct scst_acg *scst_find_acg(const struct scst_session *sess)
|
||||
|
||||
if (sess->initiator_name)
|
||||
acg = scst_find_acg_by_name_wild(sess->initiator_name);
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
if ((acg == NULL) && (sess->tgt->default_group_name != NULL))
|
||||
acg = scst_find_acg_by_name(sess->tgt->default_group_name);
|
||||
if (acg == NULL) {
|
||||
if (list_empty(&sess->tgt->default_acg->acg_dev_list))
|
||||
acg = scst_default_acg;
|
||||
else
|
||||
acg = sess->tgt->default_acg;
|
||||
}
|
||||
#else
|
||||
if (acg == NULL)
|
||||
acg = scst_default_acg;
|
||||
acg = sess->tgt->default_acg;
|
||||
#endif
|
||||
|
||||
TRACE_EXIT_HRES((unsigned long)acg);
|
||||
return acg;
|
||||
@@ -5397,7 +5408,7 @@ struct scst_acg *scst_find_acg(const struct scst_session *sess)
|
||||
|
||||
static int scst_init_session(struct scst_session *sess)
|
||||
{
|
||||
int res = 0;
|
||||
int res = 0, rc;
|
||||
struct scst_cmd *cmd;
|
||||
struct scst_mgmt_cmd *mcmd, *tm;
|
||||
int mwake = 0;
|
||||
@@ -5418,6 +5429,11 @@ static int scst_init_session(struct scst_session *sess)
|
||||
|
||||
res = scst_sess_alloc_tgt_devs(sess);
|
||||
|
||||
/* Let's always create session's sysfs to simplify error recovery */
|
||||
rc = scst_create_sess_sysfs(sess);
|
||||
if (res == 0)
|
||||
res = rc;
|
||||
|
||||
mutex_unlock(&scst_mutex);
|
||||
|
||||
if (sess->init_result_fn) {
|
||||
@@ -5454,7 +5470,12 @@ restart:
|
||||
&scst_active_mgmt_cmd_list);
|
||||
mwake = 1;
|
||||
}
|
||||
|
||||
spin_unlock(&scst_mcmd_lock);
|
||||
/*
|
||||
* In case of an error at this point the caller target driver supposed
|
||||
* to already call this sess's unregistration.
|
||||
*/
|
||||
sess->init_phase = SCST_SESS_IPH_READY;
|
||||
spin_unlock_irq(&sess->sess_list_lock);
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
Index: usr/fileio/Makefile
|
||||
===================================================================
|
||||
--- usr/fileio/Makefile (revision 324)
|
||||
+++ usr/fileio/Makefile (working copy)
|
||||
@@ -30,9 +30,9 @@ CFLAGS += -O2 -Wall -Wextra -Wno-unused-
|
||||
PROGS = fileio_tgt
|
||||
LIBS = -lpthread
|
||||
|
||||
-CFLAGS += -DEXTRACHECKS
|
||||
+#CFLAGS += -DEXTRACHECKS
|
||||
#CFLAGS += -DTRACING
|
||||
-CFLAGS += -DDEBUG -g -W -Wno-unused-parameter
|
||||
+#CFLAGS += -DDEBUG -g -W -Wno-unused-parameter
|
||||
|
||||
#CFLAGS += -DDEBUG_NOMEM
|
||||
#CFLAGS += -DDEBUG_SENSE
|
||||
@@ -1,17 +0,0 @@
|
||||
Index: usr/fileio/Makefile
|
||||
===================================================================
|
||||
--- usr/fileio/Makefile (revision 324)
|
||||
+++ usr/fileio/Makefile (working copy)
|
||||
@@ -30,9 +30,9 @@ CFLAGS += -O2 -Wall -Wextra -Wno-unused-
|
||||
PROGS = fileio_tgt
|
||||
LIBS = -lpthread
|
||||
|
||||
-CFLAGS += -DEXTRACHECKS
|
||||
-#CFLAGS += -DTRACING
|
||||
-CFLAGS += -DDEBUG -g -W -Wno-unused-parameter
|
||||
+#CFLAGS += -DEXTRACHECKS
|
||||
+CFLAGS += -DTRACING
|
||||
+#CFLAGS += -DDEBUG -g -W -Wno-unused-parameter
|
||||
|
||||
#CFLAGS += -DDEBUG_NOMEM
|
||||
#CFLAGS += -DDEBUG_SENSE
|
||||
+35
-2
@@ -32,7 +32,8 @@ LIBS = -lpthread
|
||||
|
||||
CFLAGS += -DEXTRACHECKS
|
||||
#CFLAGS += -DTRACING
|
||||
CFLAGS += -DDEBUG -g -W -Wno-unused-parameter
|
||||
CFLAGS += -DDEBUG -g
|
||||
CFLAGS += -W -Wno-unused-parameter
|
||||
|
||||
#CFLAGS += -DDEBUG_NOMEM
|
||||
#CFLAGS += -DDEBUG_SENSE
|
||||
@@ -78,4 +79,36 @@ clean:
|
||||
|
||||
extraclean: clean
|
||||
|
||||
.PHONY: all install uninstall clean extraclean
|
||||
debug2release:
|
||||
sed -c -i.aa s/"^CFLAGS += \-DEXTRACHECKS"/"#CFLAGS += \-DEXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#CFLAGS += \-DTRACING"/"CFLAGS += \-DTRACING"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^CFLAGS += \-DDEBUG -g"/"#CFLAGS += \-DDEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
|
||||
release2debug:
|
||||
sed -c -i.aa s/"#CFLAGS += \-DEXTRACHECKS"/"CFLAGS += \-DEXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^CFLAGS += \-DTRACING"/"#CFLAGS += \-DTRACING"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#CFLAGS += \-DDEBUG -g"/"CFLAGS += \-DDEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
|
||||
debug2perf:
|
||||
sed -c -i.aa s/"^CFLAGS += \-DEXTRACHECKS"/"#CFLAGS += \-DEXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"^CFLAGS += \-DDEBUG -g"/"#CFLAGS += \-DDEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
|
||||
perf2debug:
|
||||
sed -c -i.aa s/"#CFLAGS += \-DEXTRACHECKS"/"CFLAGS += \-DEXTRACHECKS"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
sed -c -i.aa s/"#CFLAGS += \-DDEBUG -g"/"CFLAGS += \-DDEBUG -g"/ Makefile
|
||||
@cmp Makefile Makefile.aa >/dev/null; if [[ $$? = 0 ]]; then rm Makefile.aa; echo "sed failed"; false; fi
|
||||
rm Makefile.aa
|
||||
|
||||
.PHONY: all install uninstall clean extraclean debug2release release2debug debug2perf perf2debug
|
||||
|
||||
Reference in New Issue
Block a user