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:
Vladislav Bolkhovitin
2009-10-21 16:49:52 +00:00
parent a09d341a0c
commit 82b04b2a00
50 changed files with 5314 additions and 1360 deletions
+52 -26
View File
@@ -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
-16
View File
@@ -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
-17
View File
@@ -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
View File
@@ -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
+9 -5
View File
@@ -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)
{
+4
View File
@@ -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)
{
+8
View File
@@ -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);
+5 -1
View File
@@ -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;
+4
View File
@@ -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 */
-16
View File
@@ -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),)
-17
View File
@@ -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),)
+43 -1
View File
@@ -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
View File
@@ -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;
}
+3 -1
View File
@@ -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;
};
/*
+2
View File
@@ -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 */
+6 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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;
-4
View File
@@ -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
View File
@@ -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 */
-39
View File
@@ -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 \
-43
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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.
+10
View File
@@ -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
View File
@@ -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
+33 -1
View File
@@ -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
+21 -15
View File
@@ -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;
+21 -16
View File
@@ -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;
+20 -7
View File
@@ -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 */
+50 -39
View File
@@ -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;
}
+50 -39
View File
@@ -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;
}
+23 -18
View File
@@ -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;
+23 -17
View File
@@ -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;
+52 -41
View File
@@ -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;
}
+39 -18
View File
@@ -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);
File diff suppressed because it is too large Load Diff
+89 -67
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
-16
View File
@@ -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
-17
View File
@@ -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
View File
@@ -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